diff options
Diffstat (limited to 'llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h')
-rw-r--r-- | llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h | 174 |
1 files changed, 145 insertions, 29 deletions
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h b/llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h index c048ff3d55226..96f8e169e7dcc 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h @@ -21,6 +21,7 @@ #include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h" #include "llvm/ExecutionEngine/Orc/ObjectTransformLayer.h" #include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h" +#include "llvm/Support/Debug.h" #include "llvm/Support/ThreadPool.h" namespace llvm { @@ -35,8 +36,22 @@ class LLLazyJITBuilderState; class LLJIT { template <typename, typename, typename> friend class LLJITBuilderSetters; + friend void setUpGenericLLVMIRPlatform(LLJIT &J); + public: - static Expected<std::unique_ptr<LLJIT>> Create(LLJITBuilderState &S); + /// Initializer support for LLJIT. + class PlatformSupport { + public: + virtual ~PlatformSupport(); + + virtual Error initialize(JITDylib &JD) = 0; + + virtual Error deinitialize(JITDylib &JD) = 0; + + protected: + static void setInitTransform(LLJIT &J, + IRTransformLayer::TransformFunction T); + }; /// Destruct this instance. If a multi-threaded instance, waits for all /// compile threads to complete. @@ -45,11 +60,14 @@ public: /// Returns the ExecutionSession for this instance. ExecutionSession &getExecutionSession() { return *ES; } + /// Returns a reference to the triple for this instance. + const Triple &getTargetTriple() const { return TT; } + /// Returns a reference to the DataLayout for this instance. const DataLayout &getDataLayout() const { return DL; } /// Returns a reference to the JITDylib representing the JIT'd main program. - JITDylib &getMainJITDylib() { return Main; } + JITDylib &getMainJITDylib() { return *Main; } /// Returns the JITDylib with the given name, or nullptr if no JITDylib with /// that name exists. @@ -63,19 +81,32 @@ public: /// input or elsewhere in the environment then the client should check /// (e.g. by calling getJITDylibByName) that the given name is not already in /// use. - JITDylib &createJITDylib(std::string Name) { + Expected<JITDylib &> createJITDylib(std::string Name) { return ES->createJITDylib(std::move(Name)); } - /// Convenience method for defining an absolute symbol. - Error defineAbsolute(StringRef Name, JITEvaluatedSymbol Address); + /// A convenience method for defining MUs in LLJIT's Main JITDylib. This can + /// be useful for succinctly defining absolute symbols, aliases and + /// re-exports. + template <typename MUType> + Error define(std::unique_ptr<MUType> &&MU) { + return Main->define(std::move(MU)); + } + + /// A convenience method for defining MUs in LLJIT's Main JITDylib. This can + /// be usedful for succinctly defining absolute symbols, aliases and + /// re-exports. + template <typename MUType> + Error define(std::unique_ptr<MUType> &MU) { + return Main->define(MU); + } /// Adds an IR module to the given JITDylib. Error addIRModule(JITDylib &JD, ThreadSafeModule TSM); /// Adds an IR module to the Main JITDylib. Error addIRModule(ThreadSafeModule TSM) { - return addIRModule(Main, std::move(TSM)); + return addIRModule(*Main, std::move(TSM)); } /// Adds an object file to the given JITDylib. @@ -83,19 +114,26 @@ public: /// Adds an object file to the given JITDylib. Error addObjectFile(std::unique_ptr<MemoryBuffer> Obj) { - return addObjectFile(Main, std::move(Obj)); + return addObjectFile(*Main, std::move(Obj)); } /// Look up a symbol in JITDylib JD by the symbol's linker-mangled name (to /// look up symbols based on their IR name use the lookup function instead). Expected<JITEvaluatedSymbol> lookupLinkerMangled(JITDylib &JD, - StringRef Name); + SymbolStringPtr Name); + + /// Look up a symbol in JITDylib JD by the symbol's linker-mangled name (to + /// look up symbols based on their IR name use the lookup function instead). + Expected<JITEvaluatedSymbol> lookupLinkerMangled(JITDylib &JD, + StringRef Name) { + return lookupLinkerMangled(JD, ES->intern(Name)); + } /// Look up a symbol in the main JITDylib by the symbol's linker-mangled name /// (to look up symbols based on their IR name use the lookup function /// instead). Expected<JITEvaluatedSymbol> lookupLinkerMangled(StringRef Name) { - return lookupLinkerMangled(Main, Name); + return lookupLinkerMangled(*Main, Name); } /// Look up a symbol in JITDylib JD based on its IR symbol name. @@ -105,14 +143,36 @@ public: /// Look up a symbol in the main JITDylib based on its IR symbol name. Expected<JITEvaluatedSymbol> lookup(StringRef UnmangledName) { - return lookup(Main, UnmangledName); + return lookup(*Main, UnmangledName); + } + + /// Set the PlatformSupport instance. + void setPlatformSupport(std::unique_ptr<PlatformSupport> PS) { + this->PS = std::move(PS); } - /// Runs all not-yet-run static constructors. - Error runConstructors() { return CtorRunner.run(); } + /// Get the PlatformSupport instance. + PlatformSupport *getPlatformSupport() { return PS.get(); } + + /// Run the initializers for the given JITDylib. + Error initialize(JITDylib &JD) { + DEBUG_WITH_TYPE("orc", { + dbgs() << "LLJIT running initializers for JITDylib \"" << JD.getName() + << "\"\n"; + }); + assert(PS && "PlatformSupport must be set to run initializers."); + return PS->initialize(JD); + } - /// Runs all not-yet-run static destructors. - Error runDestructors() { return DtorRunner.run(); } + /// Run the deinitializers for the given JITDylib. + Error deinitialize(JITDylib &JD) { + DEBUG_WITH_TYPE("orc", { + dbgs() << "LLJIT running deinitializers for JITDylib \"" << JD.getName() + << "\"\n"; + }); + assert(PS && "PlatformSupport must be set to run initializers."); + return PS->deinitialize(JD); + } /// Returns a reference to the ObjLinkingLayer ObjectLayer &getObjLinkingLayer() { return *ObjLinkingLayer; } @@ -120,33 +180,48 @@ public: /// Returns a reference to the object transform layer. ObjectTransformLayer &getObjTransformLayer() { return ObjTransformLayer; } + /// Returns a reference to the IR transform layer. + IRTransformLayer &getIRTransformLayer() { return *TransformLayer; } + + /// Returns a reference to the IR compile layer. + IRCompileLayer &getIRCompileLayer() { return *CompileLayer; } + + /// Returns a linker-mangled version of UnmangledName. + std::string mangle(StringRef UnmangledName) const; + + /// Returns an interned, linker-mangled version of UnmangledName. + SymbolStringPtr mangleAndIntern(StringRef UnmangledName) const { + return ES->intern(mangle(UnmangledName)); + } + protected: static std::unique_ptr<ObjectLayer> createObjectLinkingLayer(LLJITBuilderState &S, ExecutionSession &ES); - static Expected<IRCompileLayer::CompileFunction> + static Expected<std::unique_ptr<IRCompileLayer::IRCompiler>> createCompileFunction(LLJITBuilderState &S, JITTargetMachineBuilder JTMB); /// Create an LLJIT instance with a single compile thread. LLJIT(LLJITBuilderState &S, Error &Err); - std::string mangle(StringRef UnmangledName); - Error applyDataLayout(Module &M); void recordCtorDtors(Module &M); std::unique_ptr<ExecutionSession> ES; - JITDylib &Main; + std::unique_ptr<PlatformSupport> PS; + + JITDylib *Main = nullptr; DataLayout DL; + Triple TT; std::unique_ptr<ThreadPool> CompileThreads; std::unique_ptr<ObjectLayer> ObjLinkingLayer; ObjectTransformLayer ObjTransformLayer; std::unique_ptr<IRCompileLayer> CompileLayer; - - CtorDtorRunner CtorRunner, DtorRunner; + std::unique_ptr<IRTransformLayer> TransformLayer; + std::unique_ptr<IRTransformLayer> InitHelperTransformLayer; }; /// An extended version of LLJIT that supports lazy function-at-a-time @@ -156,12 +231,6 @@ class LLLazyJIT : public LLJIT { public: - /// Set an IR transform (e.g. pass manager pipeline) to run on each function - /// when it is compiled. - void setLazyCompileTransform(IRTransformLayer::TransformFunction Transform) { - TransformLayer->setTransform(std::move(Transform)); - } - /// Sets the partition function. void setPartitionFunction(CompileOnDemandLayer::PartitionFunction Partition) { @@ -173,7 +242,7 @@ public: /// Add a module to be lazily compiled to the main JITDylib. Error addLazyIRModule(ThreadSafeModule M) { - return addLazyIRModule(Main, std::move(M)); + return addLazyIRModule(*Main, std::move(M)); } private: @@ -182,7 +251,6 @@ private: LLLazyJIT(LLLazyJITBuilderState &S, Error &Err); std::unique_ptr<LazyCallThroughManager> LCTMgr; - std::unique_ptr<IRTransformLayer> TransformLayer; std::unique_ptr<CompileOnDemandLayer> CODLayer; }; @@ -192,13 +260,17 @@ public: ExecutionSession &, const Triple &TT)>; using CompileFunctionCreator = - std::function<Expected<IRCompileLayer::CompileFunction>( + std::function<Expected<std::unique_ptr<IRCompileLayer::IRCompiler>>( JITTargetMachineBuilder JTMB)>; + using PlatformSetupFunction = std::function<Error(LLJIT &J)>; + std::unique_ptr<ExecutionSession> ES; Optional<JITTargetMachineBuilder> JTMB; + Optional<DataLayout> DL; ObjectLinkingLayerCreator CreateObjectLinkingLayer; CompileFunctionCreator CreateCompileFunction; + PlatformSetupFunction SetUpPlatform; unsigned NumCompileThreads = 0; /// Called prior to JIT class construcion to fix up defaults. @@ -208,6 +280,13 @@ public: template <typename JITType, typename SetterImpl, typename State> class LLJITBuilderSetters { public: + + /// Set an ExecutionSession for this instance. + SetterImpl &setExecutionSession(std::unique_ptr<ExecutionSession> ES) { + impl().ES = std::move(ES); + return impl(); + } + /// Set the JITTargetMachineBuilder for this instance. /// /// If this method is not called, JITTargetMachineBuilder::detectHost will be @@ -223,6 +302,13 @@ public: return impl().JTMB; } + /// Set a DataLayout for this instance. If no data layout is specified then + /// the target's default data layout will be used. + SetterImpl &setDataLayout(Optional<DataLayout> DL) { + impl().DL = std::move(DL); + return impl(); + } + /// Set an ObjectLinkingLayer creation function. /// /// If this method is not called, a default creation function will be used @@ -245,6 +331,16 @@ public: return impl(); } + /// Set up an PlatformSetupFunction. + /// + /// If this method is not called then setUpGenericLLVMIRPlatform + /// will be used to configure the JIT's platform support. + SetterImpl & + setPlatformSetUp(LLJITBuilderState::PlatformSetupFunction SetUpPlatform) { + impl().SetUpPlatform = std::move(SetUpPlatform); + return impl(); + } + /// Set the number of compile threads to use. /// /// If set to zero, compilation will be performed on the execution thread when @@ -333,6 +429,26 @@ class LLLazyJITBuilder public LLLazyJITBuilderSetters<LLLazyJIT, LLLazyJITBuilder, LLLazyJITBuilderState> {}; +/// Configure the LLJIT instance to scrape modules for llvm.global_ctors and +/// llvm.global_dtors variables and (if present) build initialization and +/// deinitialization functions. Platform specific initialization configurations +/// should be preferred where available. +void setUpGenericLLVMIRPlatform(LLJIT &J); + +/// Configure the LLJIT instance to use MachOPlatform support. +/// +/// Warning: MachOPlatform *requires* that LLJIT be configured to use +/// ObjectLinkingLayer (default on platforms supported by JITLink). If +/// MachOPlatform is used with RTDyldObjectLinkingLayer it will result in +/// undefined behavior). +/// +/// MachOPlatform installs an ObjectLinkingLayer plugin to scrape initializers +/// from the __mod_inits section. It also provides interposes for the dlfcn +/// functions (dlopen, dlclose, dlsym, dlerror) that work for JITDylibs as +/// well as regular libraries (JITDylibs will be preferenced, so make sure +/// your JITDylib names do not shadow any real library paths). +Error setUpMachOPlatform(LLJIT &J); + } // End namespace orc } // End namespace llvm |