1 //===--------- LLJIT.cpp - An ORC-based JIT for compiling LLVM IR ---------===// 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 details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "llvm/ExecutionEngine/Orc/LLJIT.h" 11 #include "llvm/ExecutionEngine/Orc/OrcError.h" 12 #include "llvm/ExecutionEngine/SectionMemoryManager.h" 13 #include "llvm/IR/Mangler.h" 14 15 namespace llvm { 16 namespace orc { 17 18 Expected<std::unique_ptr<LLJIT>> 19 LLJIT::Create(std::unique_ptr<ExecutionSession> ES, 20 std::unique_ptr<TargetMachine> TM, DataLayout DL) { 21 return std::unique_ptr<LLJIT>( 22 new LLJIT(std::move(ES), std::move(TM), std::move(DL))); 23 } 24 25 Error LLJIT::defineAbsolute(StringRef Name, JITEvaluatedSymbol Sym) { 26 auto InternedName = ES->getSymbolStringPool().intern(Name); 27 SymbolMap Symbols({{InternedName, Sym}}); 28 return Main.define(absoluteSymbols(std::move(Symbols))); 29 } 30 31 Error LLJIT::addIRModule(VSO &V, std::unique_ptr<Module> M) { 32 assert(M && "Can not add null module"); 33 34 if (auto Err = applyDataLayout(*M)) 35 return Err; 36 37 auto K = ES->allocateVModule(); 38 Resolvers[K] = createResolverFor(V); 39 return CompileLayer.add(V, K, std::move(M)); 40 } 41 42 Expected<JITEvaluatedSymbol> LLJIT::lookupLinkerMangled(VSO &V, 43 StringRef Name) { 44 return llvm::orc::lookup({&V}, ES->getSymbolStringPool().intern(Name)); 45 } 46 47 LLJIT::LLJIT(std::unique_ptr<ExecutionSession> ES, 48 std::unique_ptr<TargetMachine> TM, DataLayout DL) 49 : ES(std::move(ES)), Main(this->ES->createVSO("main")), TM(std::move(TM)), 50 DL(std::move(DL)), 51 ObjLinkingLayer(*this->ES, 52 [this](VModuleKey K) { return getRTDyldResources(K); }), 53 CompileLayer(*this->ES, ObjLinkingLayer, SimpleCompiler(*this->TM)), 54 CtorRunner(Main), DtorRunner(Main) { 55 VSOLookupOrder[&Main] = VSOList({&Main}); 56 } 57 58 std::shared_ptr<SymbolResolver> LLJIT::takeSymbolResolver(VModuleKey K) { 59 auto ResolverI = Resolvers.find(K); 60 assert(ResolverI != Resolvers.end() && "Missing resolver"); 61 auto Resolver = std::move(ResolverI->second); 62 Resolvers.erase(ResolverI); 63 return Resolver; 64 } 65 66 RTDyldObjectLinkingLayer2::Resources LLJIT::getRTDyldResources(VModuleKey K) { 67 return orc::RTDyldObjectLinkingLayer2::Resources( 68 {llvm::make_unique<SectionMemoryManager>(), takeSymbolResolver(K)}); 69 } 70 71 std::string LLJIT::mangle(StringRef UnmangledName) { 72 std::string MangledName; 73 { 74 raw_string_ostream MangledNameStream(MangledName); 75 Mangler::getNameWithPrefix(MangledNameStream, UnmangledName, DL); 76 } 77 return MangledName; 78 } 79 80 std::unique_ptr<SymbolResolver> LLJIT::createResolverFor(VSO &V) { 81 return createSymbolResolver( 82 [&](SymbolFlagsMap &Flags, const SymbolNameSet &Symbols) { 83 return V.lookupFlags(Flags, Symbols); 84 }, 85 [&, this](std::shared_ptr<AsynchronousSymbolQuery> Q, 86 SymbolNameSet Symbols) { 87 assert(VSOLookupOrder.count(&V) && "No VSO lookup order for V"); 88 SymbolNameSet Unresolved = std::move(Symbols); 89 for (auto *LV : VSOLookupOrder[&V]) 90 Unresolved = LV->lookup(Q, std::move(Unresolved)); 91 return Unresolved; 92 }); 93 } 94 95 Error LLJIT::applyDataLayout(Module &M) { 96 if (M.getDataLayout().isDefault()) 97 M.setDataLayout(DL); 98 99 if (M.getDataLayout() != DL) 100 return make_error<StringError>( 101 "Added modules have incompatible data layouts", 102 inconvertibleErrorCode()); 103 104 return Error::success(); 105 } 106 107 void LLJIT::recordCtorDtors(Module &M) { 108 CtorRunner.add(getConstructors(M)); 109 DtorRunner.add(getDestructors(M)); 110 } 111 112 Expected<std::unique_ptr<LLLazyJIT>> 113 LLLazyJIT::Create(std::unique_ptr<ExecutionSession> ES, 114 std::unique_ptr<TargetMachine> TM, DataLayout DL, 115 LLVMContext &Ctx) { 116 const Triple &TT = TM->getTargetTriple(); 117 118 auto CCMgr = createLocalCompileCallbackManager(TT, *ES, 0); 119 if (!CCMgr) 120 return make_error<StringError>( 121 std::string("No callback manager available for ") + TT.str(), 122 inconvertibleErrorCode()); 123 124 auto ISMBuilder = createLocalIndirectStubsManagerBuilder(TT); 125 if (!ISMBuilder) 126 return make_error<StringError>( 127 std::string("No indirect stubs manager builder for ") + TT.str(), 128 inconvertibleErrorCode()); 129 130 return std::unique_ptr<LLLazyJIT>( 131 new LLLazyJIT(std::move(ES), std::move(TM), std::move(DL), Ctx, 132 std::move(CCMgr), std::move(ISMBuilder))); 133 } 134 135 Error LLLazyJIT::addLazyIRModule(VSO &V, std::unique_ptr<Module> M) { 136 assert(M && "Can not add null module"); 137 138 if (auto Err = applyDataLayout(*M)) 139 return Err; 140 141 makeAllSymbolsExternallyAccessible(*M); 142 143 recordCtorDtors(*M); 144 145 auto K = ES->allocateVModule(); 146 setSymbolResolver(K, createResolverFor(V)); 147 return CODLayer.add(V, K, std::move(M)); 148 } 149 150 LLLazyJIT::LLLazyJIT( 151 std::unique_ptr<ExecutionSession> ES, std::unique_ptr<TargetMachine> TM, 152 DataLayout DL, LLVMContext &Ctx, 153 std::unique_ptr<JITCompileCallbackManager> CCMgr, 154 std::function<std::unique_ptr<IndirectStubsManager>()> ISMBuilder) 155 : LLJIT(std::move(ES), std::move(TM), std::move(DL)), 156 CCMgr(std::move(CCMgr)), TransformLayer(*this->ES, CompileLayer), 157 CODLayer(*this->ES, TransformLayer, *this->CCMgr, std::move(ISMBuilder), 158 [this](VModuleKey K) { return takeSymbolResolver(K); }, 159 [this](VModuleKey K, std::shared_ptr<SymbolResolver> R) { 160 setSymbolResolver(K, std::move(R)); 161 }, 162 [&]() -> LLVMContext & { return Ctx; }) {} 163 164 void LLLazyJIT::setSymbolResolver(VModuleKey K, 165 std::shared_ptr<SymbolResolver> R) { 166 assert(!Resolvers.count(K) && "Resolver already present for VModule K"); 167 Resolvers[K] = std::move(R); 168 } 169 170 } // End namespace orc. 171 } // End namespace llvm. 172