123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- //===----- KaleidoscopeJIT.h - A simple JIT for Kaleidoscope ----*- C++ -*-===//
- //
- // The LLVM Compiler Infrastructure
- //
- // This file is distributed under the University of Illinois Open Source
- // License. See LICENSE.TXT for details.
- //
- //===----------------------------------------------------------------------===//
- //
- // Contains a simple JIT definition for use in the kaleidoscope tutorials.
- //
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H
- #define LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H
- #include "llvm/ExecutionEngine/ExecutionEngine.h"
- #include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
- #include "llvm/ExecutionEngine/Orc/CompileUtils.h"
- #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
- #include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
- #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
- #include "llvm/IR/Mangler.h"
- #include "llvm/Support/DynamicLibrary.h"
- namespace llvm {
- namespace orc {
- class KaleidoscopeJIT {
- public:
- typedef ObjectLinkingLayer<> ObjLayerT;
- typedef IRCompileLayer<ObjLayerT> CompileLayerT;
- typedef CompileLayerT::ModuleSetHandleT ModuleHandleT;
- KaleidoscopeJIT()
- : TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()),
- CompileLayer(ObjectLayer, SimpleCompiler(*TM)) {
- llvm::sys::DynamicLibrary::LoadLibraryPermanently(nullptr);
- }
- TargetMachine &getTargetMachine() { return *TM; }
- ModuleHandleT addModule(std::unique_ptr<Module> M) {
- // We need a memory manager to allocate memory and resolve symbols for this
- // new module. Create one that resolves symbols by looking back into the
- // JIT.
- auto Resolver = createLambdaResolver(
- [&](const std::string &Name) {
- if (auto Sym = findMangledSymbol(Name))
- return RuntimeDyld::SymbolInfo(Sym.getAddress(), Sym.getFlags());
- return RuntimeDyld::SymbolInfo(nullptr);
- },
- [](const std::string &S) { return nullptr; });
- auto H = CompileLayer.addModuleSet(singletonSet(std::move(M)),
- make_unique<SectionMemoryManager>(),
- std::move(Resolver));
- ModuleHandles.push_back(H);
- return H;
- }
- void removeModule(ModuleHandleT H) {
- ModuleHandles.erase(
- std::find(ModuleHandles.begin(), ModuleHandles.end(), H));
- CompileLayer.removeModuleSet(H);
- }
- JITSymbol findSymbol(const std::string Name) {
- return findMangledSymbol(mangle(Name));
- }
- private:
- std::string mangle(const std::string &Name) {
- std::string MangledName;
- {
- raw_string_ostream MangledNameStream(MangledName);
- Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
- }
- return MangledName;
- }
- template <typename T> static std::vector<T> singletonSet(T t) {
- std::vector<T> Vec;
- Vec.push_back(std::move(t));
- return Vec;
- }
- JITSymbol findMangledSymbol(const std::string &Name) {
- // Search modules in reverse order: from last added to first added.
- // This is the opposite of the usual search order for dlsym, but makes more
- // sense in a REPL where we want to bind to the newest available definition.
- for (auto H : make_range(ModuleHandles.rbegin(), ModuleHandles.rend()))
- if (auto Sym = CompileLayer.findSymbolIn(H, Name, true))
- return Sym;
- // If we can't find the symbol in the JIT, try looking in the host process.
- if (auto SymAddr = RTDyldMemoryManager::getSymbolAddressInProcess(Name))
- return JITSymbol(SymAddr, JITSymbolFlags::Exported);
- return nullptr;
- }
- std::unique_ptr<TargetMachine> TM;
- const DataLayout DL;
- ObjLayerT ObjectLayer;
- CompileLayerT CompileLayer;
- std::vector<ModuleHandleT> ModuleHandles;
- };
- } // End namespace orc.
- } // End namespace llvm
- #endif // LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H
|