1 //===----- LLJIT.h -- An ORC-based JIT for compiling LLVM IR ----*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for 3Bdetails. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // An ORC-based JIT for compiling LLVM IR. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_EXECUTIONENGINE_ORC_LLJIT_H 15 #define LLVM_EXECUTIONENGINE_ORC_LLJIT_H 16 17 #include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h" 18 #include "llvm/ExecutionEngine/Orc/CompileUtils.h" 19 #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h" 20 #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h" 21 #include "llvm/ExecutionEngine/Orc/IRTransformLayer.h" 22 #include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h" 23 #include "llvm/ExecutionEngine/Orc/ObjectTransformLayer.h" 24 #include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h" 25 #include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h" 26 #include "llvm/Support/ThreadPool.h" 27 28 namespace llvm { 29 namespace orc { 30 31 /// A pre-fabricated ORC JIT stack that can serve as an alternative to MCJIT. 32 class LLJIT { 33 public: 34 35 /// Destruct this instance. If a multi-threaded instance, waits for all 36 /// compile threads to complete. 37 ~LLJIT(); 38 39 /// Create an LLJIT instance. 40 /// If NumCompileThreads is not equal to zero, creates a multi-threaded 41 /// LLJIT with the given number of compile threads. 42 static Expected<std::unique_ptr<LLJIT>> 43 Create(JITTargetMachineBuilder JTMB, DataLayout DL, 44 unsigned NumCompileThreads = 0); 45 46 /// Returns the ExecutionSession for this instance. getExecutionSession()47 ExecutionSession &getExecutionSession() { return *ES; } 48 49 /// Returns a reference to the JITDylib representing the JIT'd main program. getMainJITDylib()50 JITDylib &getMainJITDylib() { return Main; } 51 52 /// Create a new JITDylib with the given name and return a reference to it. createJITDylib(std::string Name)53 JITDylib &createJITDylib(std::string Name) { 54 return ES->createJITDylib(std::move(Name)); 55 } 56 57 /// Convenience method for defining an absolute symbol. 58 Error defineAbsolute(StringRef Name, JITEvaluatedSymbol Address); 59 60 /// Convenience method for defining an 61 62 /// Adds an IR module to the given JITDylib. 63 Error addIRModule(JITDylib &JD, ThreadSafeModule TSM); 64 65 /// Adds an IR module to the Main JITDylib. addIRModule(ThreadSafeModule TSM)66 Error addIRModule(ThreadSafeModule TSM) { 67 return addIRModule(Main, std::move(TSM)); 68 } 69 70 /// Adds an object file to the given JITDylib. 71 Error addObjectFile(JITDylib &JD, std::unique_ptr<MemoryBuffer> Obj); 72 73 /// Adds an object file to the given JITDylib. addObjectFile(std::unique_ptr<MemoryBuffer> Obj)74 Error addObjectFile(std::unique_ptr<MemoryBuffer> Obj) { 75 return addObjectFile(Main, std::move(Obj)); 76 } 77 78 /// Look up a symbol in JITDylib JD by the symbol's linker-mangled name (to 79 /// look up symbols based on their IR name use the lookup function instead). 80 Expected<JITEvaluatedSymbol> lookupLinkerMangled(JITDylib &JD, 81 StringRef Name); 82 83 /// Look up a symbol in the main JITDylib by the symbol's linker-mangled name 84 /// (to look up symbols based on their IR name use the lookup function 85 /// instead). lookupLinkerMangled(StringRef Name)86 Expected<JITEvaluatedSymbol> lookupLinkerMangled(StringRef Name) { 87 return lookupLinkerMangled(Main, Name); 88 } 89 90 /// Look up a symbol in JITDylib JD based on its IR symbol name. lookup(JITDylib & JD,StringRef UnmangledName)91 Expected<JITEvaluatedSymbol> lookup(JITDylib &JD, StringRef UnmangledName) { 92 return lookupLinkerMangled(JD, mangle(UnmangledName)); 93 } 94 95 /// Look up a symbol in the main JITDylib based on its IR symbol name. lookup(StringRef UnmangledName)96 Expected<JITEvaluatedSymbol> lookup(StringRef UnmangledName) { 97 return lookup(Main, UnmangledName); 98 } 99 100 /// Runs all not-yet-run static constructors. runConstructors()101 Error runConstructors() { return CtorRunner.run(); } 102 103 /// Runs all not-yet-run static destructors. runDestructors()104 Error runDestructors() { return DtorRunner.run(); } 105 106 /// Returns a reference to the ObjLinkingLayer getObjLinkingLayer()107 RTDyldObjectLinkingLayer &getObjLinkingLayer() { return ObjLinkingLayer; } 108 109 protected: 110 111 /// Create an LLJIT instance with a single compile thread. 112 LLJIT(std::unique_ptr<ExecutionSession> ES, std::unique_ptr<TargetMachine> TM, 113 DataLayout DL); 114 115 /// Create an LLJIT instance with multiple compile threads. 116 LLJIT(std::unique_ptr<ExecutionSession> ES, JITTargetMachineBuilder JTMB, 117 DataLayout DL, unsigned NumCompileThreads); 118 119 std::string mangle(StringRef UnmangledName); 120 121 Error applyDataLayout(Module &M); 122 123 void recordCtorDtors(Module &M); 124 125 std::unique_ptr<ExecutionSession> ES; 126 JITDylib &Main; 127 128 DataLayout DL; 129 std::unique_ptr<ThreadPool> CompileThreads; 130 131 RTDyldObjectLinkingLayer ObjLinkingLayer; 132 IRCompileLayer CompileLayer; 133 134 CtorDtorRunner CtorRunner, DtorRunner; 135 }; 136 137 /// An extended version of LLJIT that supports lazy function-at-a-time 138 /// compilation of LLVM IR. 139 class LLLazyJIT : public LLJIT { 140 public: 141 142 /// Create an LLLazyJIT instance. 143 /// If NumCompileThreads is not equal to zero, creates a multi-threaded 144 /// LLLazyJIT with the given number of compile threads. 145 static Expected<std::unique_ptr<LLLazyJIT>> 146 Create(JITTargetMachineBuilder JTMB, DataLayout DL, 147 JITTargetAddress ErrorAddr, unsigned NumCompileThreads = 0); 148 149 /// Set an IR transform (e.g. pass manager pipeline) to run on each function 150 /// when it is compiled. setLazyCompileTransform(IRTransformLayer::TransformFunction Transform)151 void setLazyCompileTransform(IRTransformLayer::TransformFunction Transform) { 152 TransformLayer.setTransform(std::move(Transform)); 153 } 154 155 /// Sets the partition function. 156 void setPartitionFunction(CompileOnDemandLayer::PartitionFunction Partition)157 setPartitionFunction(CompileOnDemandLayer::PartitionFunction Partition) { 158 CODLayer.setPartitionFunction(std::move(Partition)); 159 } 160 161 /// Add a module to be lazily compiled to JITDylib JD. 162 Error addLazyIRModule(JITDylib &JD, ThreadSafeModule M); 163 164 /// Add a module to be lazily compiled to the main JITDylib. addLazyIRModule(ThreadSafeModule M)165 Error addLazyIRModule(ThreadSafeModule M) { 166 return addLazyIRModule(Main, std::move(M)); 167 } 168 169 private: 170 171 // Create a single-threaded LLLazyJIT instance. 172 LLLazyJIT(std::unique_ptr<ExecutionSession> ES, 173 std::unique_ptr<TargetMachine> TM, DataLayout DL, 174 std::unique_ptr<LazyCallThroughManager> LCTMgr, 175 std::function<std::unique_ptr<IndirectStubsManager>()> ISMBuilder); 176 177 // Create a multi-threaded LLLazyJIT instance. 178 LLLazyJIT(std::unique_ptr<ExecutionSession> ES, JITTargetMachineBuilder JTMB, 179 DataLayout DL, unsigned NumCompileThreads, 180 std::unique_ptr<LazyCallThroughManager> LCTMgr, 181 std::function<std::unique_ptr<IndirectStubsManager>()> ISMBuilder); 182 183 std::unique_ptr<LazyCallThroughManager> LCTMgr; 184 std::function<std::unique_ptr<IndirectStubsManager>()> ISMBuilder; 185 186 IRTransformLayer TransformLayer; 187 CompileOnDemandLayer CODLayer; 188 }; 189 190 } // End namespace orc 191 } // End namespace llvm 192 193 #endif // LLVM_EXECUTIONENGINE_ORC_LLJIT_H 194