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 = 45 TSM.withModuleDo([&](Module &M) { return applyDataLayout(M); })) 46 return Err; 47 48 return CompileLayer->add(JD, std::move(TSM), ES->allocateVModule()); 49 } 50 51 Error LLJIT::addObjectFile(JITDylib &JD, std::unique_ptr<MemoryBuffer> Obj) { 52 assert(Obj && "Can not add null object"); 53 54 return ObjLinkingLayer->add(JD, std::move(Obj), ES->allocateVModule()); 55 } 56 57 Expected<JITEvaluatedSymbol> LLJIT::lookupLinkerMangled(JITDylib &JD, 58 StringRef Name) { 59 return ES->lookup(JITDylibSearchList({{&JD, true}}), ES->intern(Name)); 60 } 61 62 std::unique_ptr<ObjectLayer> 63 LLJIT::createObjectLinkingLayer(LLJITBuilderState &S, ExecutionSession &ES) { 64 65 // If the config state provided an ObjectLinkingLayer factory then use it. 66 if (S.CreateObjectLinkingLayer) 67 return S.CreateObjectLinkingLayer(ES, S.JTMB->getTargetTriple()); 68 69 // Otherwise default to creating an RTDyldObjectLinkingLayer that constructs 70 // a new SectionMemoryManager for each object. 71 auto GetMemMgr = []() { return std::make_unique<SectionMemoryManager>(); }; 72 auto ObjLinkingLayer = 73 std::make_unique<RTDyldObjectLinkingLayer>(ES, std::move(GetMemMgr)); 74 75 if (S.JTMB->getTargetTriple().isOSBinFormatCOFF()) 76 ObjLinkingLayer->setOverrideObjectFlagsWithResponsibilityFlags(true); 77 78 // FIXME: Explicit conversion to std::unique_ptr<ObjectLayer> added to silence 79 // errors from some GCC / libstdc++ bots. Remove this conversion (i.e. 80 // just return ObjLinkingLayer) once those bots are upgraded. 81 return std::unique_ptr<ObjectLayer>(std::move(ObjLinkingLayer)); 82 } 83 84 Expected<IRCompileLayer::CompileFunction> 85 LLJIT::createCompileFunction(LLJITBuilderState &S, 86 JITTargetMachineBuilder JTMB) { 87 88 /// If there is a custom compile function creator set then use it. 89 if (S.CreateCompileFunction) 90 return S.CreateCompileFunction(std::move(JTMB)); 91 92 // Otherwise default to creating a SimpleCompiler, or ConcurrentIRCompiler, 93 // depending on the number of threads requested. 94 if (S.NumCompileThreads > 0) 95 return ConcurrentIRCompiler(std::move(JTMB)); 96 97 auto TM = JTMB.createTargetMachine(); 98 if (!TM) 99 return TM.takeError(); 100 101 return TMOwningSimpleCompiler(std::move(*TM)); 102 } 103 104 LLJIT::LLJIT(LLJITBuilderState &S, Error &Err) 105 : ES(S.ES ? std::move(S.ES) : std::make_unique<ExecutionSession>()), 106 Main(this->ES->getMainJITDylib()), DL(""), CtorRunner(Main), 107 DtorRunner(Main) { 108 109 ErrorAsOutParameter _(&Err); 110 111 ObjLinkingLayer = createObjectLinkingLayer(S, *ES); 112 113 if (auto DLOrErr = S.JTMB->getDefaultDataLayoutForTarget()) 114 DL = std::move(*DLOrErr); 115 else { 116 Err = DLOrErr.takeError(); 117 return; 118 } 119 120 { 121 auto CompileFunction = createCompileFunction(S, std::move(*S.JTMB)); 122 if (!CompileFunction) { 123 Err = CompileFunction.takeError(); 124 return; 125 } 126 CompileLayer = std::make_unique<IRCompileLayer>( 127 *ES, *ObjLinkingLayer, std::move(*CompileFunction)); 128 } 129 130 if (S.NumCompileThreads > 0) { 131 CompileLayer->setCloneToNewContextOnEmit(true); 132 CompileThreads = std::make_unique<ThreadPool>(S.NumCompileThreads); 133 ES->setDispatchMaterialization( 134 [this](JITDylib &JD, std::unique_ptr<MaterializationUnit> MU) { 135 // FIXME: Switch to move capture once we have c++14. 136 auto SharedMU = std::shared_ptr<MaterializationUnit>(std::move(MU)); 137 auto Work = [SharedMU, &JD]() { SharedMU->doMaterialize(JD); }; 138 CompileThreads->async(std::move(Work)); 139 }); 140 } 141 } 142 143 std::string LLJIT::mangle(StringRef UnmangledName) { 144 std::string MangledName; 145 { 146 raw_string_ostream MangledNameStream(MangledName); 147 Mangler::getNameWithPrefix(MangledNameStream, UnmangledName, DL); 148 } 149 return MangledName; 150 } 151 152 Error LLJIT::applyDataLayout(Module &M) { 153 if (M.getDataLayout().isDefault()) 154 M.setDataLayout(DL); 155 156 if (M.getDataLayout() != DL) 157 return make_error<StringError>( 158 "Added modules have incompatible data layouts", 159 inconvertibleErrorCode()); 160 161 return Error::success(); 162 } 163 164 void LLJIT::recordCtorDtors(Module &M) { 165 CtorRunner.add(getConstructors(M)); 166 DtorRunner.add(getDestructors(M)); 167 } 168 169 Error LLLazyJITBuilderState::prepareForConstruction() { 170 if (auto Err = LLJITBuilderState::prepareForConstruction()) 171 return Err; 172 TT = JTMB->getTargetTriple(); 173 return Error::success(); 174 } 175 176 Error LLLazyJIT::addLazyIRModule(JITDylib &JD, ThreadSafeModule TSM) { 177 assert(TSM && "Can not add null module"); 178 179 if (auto Err = TSM.withModuleDo([&](Module &M) -> Error { 180 if (auto Err = applyDataLayout(M)) 181 return Err; 182 183 recordCtorDtors(M); 184 return Error::success(); 185 })) 186 return Err; 187 188 return CODLayer->add(JD, std::move(TSM), ES->allocateVModule()); 189 } 190 191 LLLazyJIT::LLLazyJIT(LLLazyJITBuilderState &S, Error &Err) : LLJIT(S, Err) { 192 193 // If LLJIT construction failed then bail out. 194 if (Err) 195 return; 196 197 ErrorAsOutParameter _(&Err); 198 199 /// Take/Create the lazy-compile callthrough manager. 200 if (S.LCTMgr) 201 LCTMgr = std::move(S.LCTMgr); 202 else { 203 if (auto LCTMgrOrErr = createLocalLazyCallThroughManager( 204 S.TT, *ES, S.LazyCompileFailureAddr)) 205 LCTMgr = std::move(*LCTMgrOrErr); 206 else { 207 Err = LCTMgrOrErr.takeError(); 208 return; 209 } 210 } 211 212 // Take/Create the indirect stubs manager builder. 213 auto ISMBuilder = std::move(S.ISMBuilder); 214 215 // If none was provided, try to build one. 216 if (!ISMBuilder) 217 ISMBuilder = createLocalIndirectStubsManagerBuilder(S.TT); 218 219 // No luck. Bail out. 220 if (!ISMBuilder) { 221 Err = make_error<StringError>("Could not construct " 222 "IndirectStubsManagerBuilder for target " + 223 S.TT.str(), 224 inconvertibleErrorCode()); 225 return; 226 } 227 228 // Create the transform layer. 229 TransformLayer = std::make_unique<IRTransformLayer>(*ES, *CompileLayer); 230 231 // Create the COD layer. 232 CODLayer = std::make_unique<CompileOnDemandLayer>( 233 *ES, *TransformLayer, *LCTMgr, std::move(ISMBuilder)); 234 235 if (S.NumCompileThreads > 0) 236 CODLayer->setCloneToNewContextOnEmit(true); 237 } 238 239 } // End namespace orc. 240 } // End namespace llvm. 241