1 //===--------- LLJIT.cpp - An ORC-based JIT for compiling LLVM IR ---------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "llvm/ExecutionEngine/Orc/LLJIT.h" 10 #include "llvm/ExecutionEngine/Orc/OrcError.h" 11 #include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h" 12 #include "llvm/ExecutionEngine/SectionMemoryManager.h" 13 #include "llvm/IR/Mangler.h" 14 15 namespace llvm { 16 namespace orc { 17 18 Error LLJITBuilderState::prepareForConstruction() { 19 20 if (!JTMB) { 21 if (auto JTMBOrErr = JITTargetMachineBuilder::detectHost()) 22 JTMB = std::move(*JTMBOrErr); 23 else 24 return JTMBOrErr.takeError(); 25 } 26 27 return Error::success(); 28 } 29 30 LLJIT::~LLJIT() { 31 if (CompileThreads) 32 CompileThreads->wait(); 33 } 34 35 Error LLJIT::defineAbsolute(StringRef Name, JITEvaluatedSymbol Sym) { 36 auto InternedName = ES->intern(Name); 37 SymbolMap Symbols({{InternedName, Sym}}); 38 return Main.define(absoluteSymbols(std::move(Symbols))); 39 } 40 41 Error LLJIT::addIRModule(JITDylib &JD, ThreadSafeModule TSM) { 42 assert(TSM && "Can not add null module"); 43 44 if (auto Err = applyDataLayout(*TSM.getModule())) 45 return Err; 46 47 return CompileLayer->add(JD, std::move(TSM), ES->allocateVModule()); 48 } 49 50 Error LLJIT::addObjectFile(JITDylib &JD, std::unique_ptr<MemoryBuffer> Obj) { 51 assert(Obj && "Can not add null object"); 52 53 return ObjLinkingLayer->add(JD, std::move(Obj), ES->allocateVModule()); 54 } 55 56 Expected<JITEvaluatedSymbol> LLJIT::lookupLinkerMangled(JITDylib &JD, 57 StringRef Name) { 58 return ES->lookup(JITDylibSearchList({{&JD, true}}), ES->intern(Name)); 59 } 60 61 std::unique_ptr<ObjectLayer> 62 LLJIT::createObjectLinkingLayer(LLJITBuilderState &S, ExecutionSession &ES) { 63 64 // If the config state provided an ObjectLinkingLayer factory then use it. 65 if (S.CreateObjectLinkingLayer) 66 return S.CreateObjectLinkingLayer(ES); 67 68 // Otherwise default to creating an RTDyldObjectLinkingLayer that constructs 69 // a new SectionMemoryManager for each object. 70 auto GetMemMgr = []() { return llvm::make_unique<SectionMemoryManager>(); }; 71 return llvm::make_unique<RTDyldObjectLinkingLayer>(ES, std::move(GetMemMgr)); 72 } 73 74 Expected<IRCompileLayer::CompileFunction> 75 LLJIT::createCompileFunction(LLJITBuilderState &S, 76 JITTargetMachineBuilder JTMB) { 77 78 /// If there is a custom compile function creator set then use it. 79 if (S.CreateCompileFunction) 80 return S.CreateCompileFunction(std::move(JTMB)); 81 82 // Otherwise default to creating a SimpleCompiler, or ConcurrentIRCompiler, 83 // depending on the number of threads requested. 84 if (S.NumCompileThreads > 0) 85 return ConcurrentIRCompiler(std::move(JTMB)); 86 87 auto TM = JTMB.createTargetMachine(); 88 if (!TM) 89 return TM.takeError(); 90 91 return TMOwningSimpleCompiler(std::move(*TM)); 92 } 93 94 LLJIT::LLJIT(LLJITBuilderState &S, Error &Err) 95 : ES(S.ES ? std::move(S.ES) : llvm::make_unique<ExecutionSession>()), 96 Main(this->ES->getMainJITDylib()), DL(""), CtorRunner(Main), 97 DtorRunner(Main) { 98 99 ErrorAsOutParameter _(&Err); 100 101 ObjLinkingLayer = createObjectLinkingLayer(S, *ES); 102 103 if (auto DLOrErr = S.JTMB->getDefaultDataLayoutForTarget()) 104 DL = std::move(*DLOrErr); 105 else { 106 Err = DLOrErr.takeError(); 107 return; 108 } 109 110 { 111 auto CompileFunction = createCompileFunction(S, std::move(*S.JTMB)); 112 if (!CompileFunction) { 113 Err = CompileFunction.takeError(); 114 return; 115 } 116 CompileLayer = llvm::make_unique<IRCompileLayer>( 117 *ES, *ObjLinkingLayer, std::move(*CompileFunction)); 118 } 119 120 if (S.NumCompileThreads > 0) { 121 CompileLayer->setCloneToNewContextOnEmit(true); 122 CompileThreads = llvm::make_unique<ThreadPool>(S.NumCompileThreads); 123 ES->setDispatchMaterialization( 124 [this](JITDylib &JD, std::unique_ptr<MaterializationUnit> MU) { 125 // FIXME: Switch to move capture once we have c++14. 126 auto SharedMU = std::shared_ptr<MaterializationUnit>(std::move(MU)); 127 auto Work = [SharedMU, &JD]() { SharedMU->doMaterialize(JD); }; 128 CompileThreads->async(std::move(Work)); 129 }); 130 } 131 } 132 133 std::string LLJIT::mangle(StringRef UnmangledName) { 134 std::string MangledName; 135 { 136 raw_string_ostream MangledNameStream(MangledName); 137 Mangler::getNameWithPrefix(MangledNameStream, UnmangledName, DL); 138 } 139 return MangledName; 140 } 141 142 Error LLJIT::applyDataLayout(Module &M) { 143 if (M.getDataLayout().isDefault()) 144 M.setDataLayout(DL); 145 146 if (M.getDataLayout() != DL) 147 return make_error<StringError>( 148 "Added modules have incompatible data layouts", 149 inconvertibleErrorCode()); 150 151 return Error::success(); 152 } 153 154 void LLJIT::recordCtorDtors(Module &M) { 155 CtorRunner.add(getConstructors(M)); 156 DtorRunner.add(getDestructors(M)); 157 } 158 159 Error LLLazyJITBuilderState::prepareForConstruction() { 160 if (auto Err = LLJITBuilderState::prepareForConstruction()) 161 return Err; 162 TT = JTMB->getTargetTriple(); 163 return Error::success(); 164 } 165 166 Error LLLazyJIT::addLazyIRModule(JITDylib &JD, ThreadSafeModule TSM) { 167 assert(TSM && "Can not add null module"); 168 169 if (auto Err = applyDataLayout(*TSM.getModule())) 170 return Err; 171 172 recordCtorDtors(*TSM.getModule()); 173 174 return CODLayer->add(JD, std::move(TSM), ES->allocateVModule()); 175 } 176 177 LLLazyJIT::LLLazyJIT(LLLazyJITBuilderState &S, Error &Err) : LLJIT(S, Err) { 178 179 // If LLJIT construction failed then bail out. 180 if (Err) 181 return; 182 183 ErrorAsOutParameter _(&Err); 184 185 /// Take/Create the lazy-compile callthrough manager. 186 if (S.LCTMgr) 187 LCTMgr = std::move(S.LCTMgr); 188 else { 189 if (auto LCTMgrOrErr = createLocalLazyCallThroughManager( 190 S.TT, *ES, S.LazyCompileFailureAddr)) 191 LCTMgr = std::move(*LCTMgrOrErr); 192 else { 193 Err = LCTMgrOrErr.takeError(); 194 return; 195 } 196 } 197 198 // Take/Create the indirect stubs manager builder. 199 auto ISMBuilder = std::move(S.ISMBuilder); 200 201 // If none was provided, try to build one. 202 if (!ISMBuilder) 203 ISMBuilder = createLocalIndirectStubsManagerBuilder(S.TT); 204 205 // No luck. Bail out. 206 if (!ISMBuilder) { 207 Err = make_error<StringError>("Could not construct " 208 "IndirectStubsManagerBuilder for target " + 209 S.TT.str(), 210 inconvertibleErrorCode()); 211 return; 212 } 213 214 // Create the transform layer. 215 TransformLayer = llvm::make_unique<IRTransformLayer>(*ES, *CompileLayer); 216 217 // Create the COD layer. 218 CODLayer = llvm::make_unique<CompileOnDemandLayer>( 219 *ES, *TransformLayer, *LCTMgr, std::move(ISMBuilder)); 220 221 if (S.NumCompileThreads > 0) 222 CODLayer->setCloneToNewContextOnEmit(true); 223 } 224 225 } // End namespace orc. 226 } // End namespace llvm. 227