1 //===--------- LLJIT.cpp - An ORC-based JIT for compiling LLVM IR ---------===//
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
7 //===----------------------------------------------------------------------===//
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"
18 Error LLJITBuilderState::prepareForConstruction() {
21 if (auto JTMBOrErr = JITTargetMachineBuilder::detectHost())
22 JTMB = std::move(*JTMBOrErr);
24 return JTMBOrErr.takeError();
27 return Error::success();
32 CompileThreads->wait();
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)));
41 Error LLJIT::addIRModule(JITDylib &JD, ThreadSafeModule TSM) {
42 assert(TSM && "Can not add null module");
44 if (auto Err = applyDataLayout(*TSM.getModule()))
47 return CompileLayer->add(JD, std::move(TSM), ES->allocateVModule());
50 Error LLJIT::addObjectFile(JITDylib &JD, std::unique_ptr<MemoryBuffer> Obj) {
51 assert(Obj && "Can not add null object");
53 return ObjLinkingLayer->add(JD, std::move(Obj), ES->allocateVModule());
56 Expected<JITEvaluatedSymbol> LLJIT::lookupLinkerMangled(JITDylib &JD,
58 return ES->lookup(JITDylibSearchList({{&JD, true}}), ES->intern(Name));
61 std::unique_ptr<ObjectLayer>
62 LLJIT::createObjectLinkingLayer(LLJITBuilderState &S, ExecutionSession &ES) {
64 // If the config state provided an ObjectLinkingLayer factory then use it.
65 if (S.CreateObjectLinkingLayer)
66 return S.CreateObjectLinkingLayer(ES);
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));
74 Expected<IRCompileLayer::CompileFunction>
75 LLJIT::createCompileFunction(LLJITBuilderState &S,
76 JITTargetMachineBuilder JTMB) {
78 /// If there is a custom compile function creator set then use it.
79 if (S.CreateCompileFunction)
80 return S.CreateCompileFunction(std::move(JTMB));
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));
87 auto TM = JTMB.createTargetMachine();
89 return TM.takeError();
91 return TMOwningSimpleCompiler(std::move(*TM));
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),
99 ErrorAsOutParameter _(&Err);
101 ObjLinkingLayer = createObjectLinkingLayer(S, *ES);
103 if (auto DLOrErr = S.JTMB->getDefaultDataLayoutForTarget())
104 DL = std::move(*DLOrErr);
106 Err = DLOrErr.takeError();
111 auto CompileFunction = createCompileFunction(S, std::move(*S.JTMB));
112 if (!CompileFunction) {
113 Err = CompileFunction.takeError();
116 CompileLayer = llvm::make_unique<IRCompileLayer>(
117 *ES, *ObjLinkingLayer, std::move(*CompileFunction));
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));
133 std::string LLJIT::mangle(StringRef UnmangledName) {
134 std::string MangledName;
136 raw_string_ostream MangledNameStream(MangledName);
137 Mangler::getNameWithPrefix(MangledNameStream, UnmangledName, DL);
142 Error LLJIT::applyDataLayout(Module &M) {
143 if (M.getDataLayout().isDefault())
146 if (M.getDataLayout() != DL)
147 return make_error<StringError>(
148 "Added modules have incompatible data layouts",
149 inconvertibleErrorCode());
151 return Error::success();
154 void LLJIT::recordCtorDtors(Module &M) {
155 CtorRunner.add(getConstructors(M));
156 DtorRunner.add(getDestructors(M));
159 Error LLLazyJITBuilderState::prepareForConstruction() {
160 if (auto Err = LLJITBuilderState::prepareForConstruction())
162 TT = JTMB->getTargetTriple();
163 return Error::success();
166 Error LLLazyJIT::addLazyIRModule(JITDylib &JD, ThreadSafeModule TSM) {
167 assert(TSM && "Can not add null module");
169 if (auto Err = applyDataLayout(*TSM.getModule()))
172 recordCtorDtors(*TSM.getModule());
174 return CODLayer->add(JD, std::move(TSM), ES->allocateVModule());
177 LLLazyJIT::LLLazyJIT(LLLazyJITBuilderState &S, Error &Err) : LLJIT(S, Err) {
179 // If LLJIT construction failed then bail out.
183 ErrorAsOutParameter _(&Err);
185 /// Take/Create the lazy-compile callthrough manager.
187 LCTMgr = std::move(S.LCTMgr);
189 if (auto LCTMgrOrErr = createLocalLazyCallThroughManager(
190 S.TT, *ES, S.LazyCompileFailureAddr))
191 LCTMgr = std::move(*LCTMgrOrErr);
193 Err = LCTMgrOrErr.takeError();
198 // Take/Create the indirect stubs manager builder.
199 auto ISMBuilder = std::move(S.ISMBuilder);
201 // If none was provided, try to build one.
203 ISMBuilder = createLocalIndirectStubsManagerBuilder(S.TT);
205 // No luck. Bail out.
207 Err = make_error<StringError>("Could not construct "
208 "IndirectStubsManagerBuilder for target " +
210 inconvertibleErrorCode());
214 // Create the transform layer.
215 TransformLayer = llvm::make_unique<IRTransformLayer>(*ES, *CompileLayer);
217 // Create the COD layer.
218 CODLayer = llvm::make_unique<CompileOnDemandLayer>(
219 *ES, *TransformLayer, *LCTMgr, std::move(ISMBuilder));
221 if (S.NumCompileThreads > 0)
222 CODLayer->setCloneToNewContextOnEmit(true);
225 } // End namespace orc.
226 } // End namespace llvm.