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