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");
45 TSM
.withModuleDo([&](Module
&M
) { return applyDataLayout(M
); }))
48 return CompileLayer
->add(JD
, std::move(TSM
), ES
->allocateVModule());
51 Error
LLJIT::addObjectFile(JITDylib
&JD
, std::unique_ptr
<MemoryBuffer
> Obj
) {
52 assert(Obj
&& "Can not add null object");
54 return ObjLinkingLayer
->add(JD
, std::move(Obj
), ES
->allocateVModule());
57 Expected
<JITEvaluatedSymbol
> LLJIT::lookupLinkerMangled(JITDylib
&JD
,
59 return ES
->lookup(JITDylibSearchList({{&JD
, true}}), ES
->intern(Name
));
62 std::unique_ptr
<ObjectLayer
>
63 LLJIT::createObjectLinkingLayer(LLJITBuilderState
&S
, ExecutionSession
&ES
) {
65 // If the config state provided an ObjectLinkingLayer factory then use it.
66 if (S
.CreateObjectLinkingLayer
)
67 return S
.CreateObjectLinkingLayer(ES
, S
.JTMB
->getTargetTriple());
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
));
75 if (S
.JTMB
->getTargetTriple().isOSBinFormatCOFF())
76 ObjLinkingLayer
->setOverrideObjectFlagsWithResponsibilityFlags(true);
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
));
84 Expected
<IRCompileLayer::CompileFunction
>
85 LLJIT::createCompileFunction(LLJITBuilderState
&S
,
86 JITTargetMachineBuilder JTMB
) {
88 /// If there is a custom compile function creator set then use it.
89 if (S
.CreateCompileFunction
)
90 return S
.CreateCompileFunction(std::move(JTMB
));
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
));
97 auto TM
= JTMB
.createTargetMachine();
99 return TM
.takeError();
101 return TMOwningSimpleCompiler(std::move(*TM
));
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
),
109 ErrorAsOutParameter
_(&Err
);
111 ObjLinkingLayer
= createObjectLinkingLayer(S
, *ES
);
113 if (auto DLOrErr
= S
.JTMB
->getDefaultDataLayoutForTarget())
114 DL
= std::move(*DLOrErr
);
116 Err
= DLOrErr
.takeError();
121 auto CompileFunction
= createCompileFunction(S
, std::move(*S
.JTMB
));
122 if (!CompileFunction
) {
123 Err
= CompileFunction
.takeError();
126 CompileLayer
= std::make_unique
<IRCompileLayer
>(
127 *ES
, *ObjLinkingLayer
, std::move(*CompileFunction
));
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
));
143 std::string
LLJIT::mangle(StringRef UnmangledName
) {
144 std::string MangledName
;
146 raw_string_ostream
MangledNameStream(MangledName
);
147 Mangler::getNameWithPrefix(MangledNameStream
, UnmangledName
, DL
);
152 Error
LLJIT::applyDataLayout(Module
&M
) {
153 if (M
.getDataLayout().isDefault())
156 if (M
.getDataLayout() != DL
)
157 return make_error
<StringError
>(
158 "Added modules have incompatible data layouts",
159 inconvertibleErrorCode());
161 return Error::success();
164 void LLJIT::recordCtorDtors(Module
&M
) {
165 CtorRunner
.add(getConstructors(M
));
166 DtorRunner
.add(getDestructors(M
));
169 Error
LLLazyJITBuilderState::prepareForConstruction() {
170 if (auto Err
= LLJITBuilderState::prepareForConstruction())
172 TT
= JTMB
->getTargetTriple();
173 return Error::success();
176 Error
LLLazyJIT::addLazyIRModule(JITDylib
&JD
, ThreadSafeModule TSM
) {
177 assert(TSM
&& "Can not add null module");
179 if (auto Err
= TSM
.withModuleDo([&](Module
&M
) -> Error
{
180 if (auto Err
= applyDataLayout(M
))
184 return Error::success();
188 return CODLayer
->add(JD
, std::move(TSM
), ES
->allocateVModule());
191 LLLazyJIT::LLLazyJIT(LLLazyJITBuilderState
&S
, Error
&Err
) : LLJIT(S
, Err
) {
193 // If LLJIT construction failed then bail out.
197 ErrorAsOutParameter
_(&Err
);
199 /// Take/Create the lazy-compile callthrough manager.
201 LCTMgr
= std::move(S
.LCTMgr
);
203 if (auto LCTMgrOrErr
= createLocalLazyCallThroughManager(
204 S
.TT
, *ES
, S
.LazyCompileFailureAddr
))
205 LCTMgr
= std::move(*LCTMgrOrErr
);
207 Err
= LCTMgrOrErr
.takeError();
212 // Take/Create the indirect stubs manager builder.
213 auto ISMBuilder
= std::move(S
.ISMBuilder
);
215 // If none was provided, try to build one.
217 ISMBuilder
= createLocalIndirectStubsManagerBuilder(S
.TT
);
219 // No luck. Bail out.
221 Err
= make_error
<StringError
>("Could not construct "
222 "IndirectStubsManagerBuilder for target " +
224 inconvertibleErrorCode());
228 // Create the transform layer.
229 TransformLayer
= std::make_unique
<IRTransformLayer
>(*ES
, *CompileLayer
);
231 // Create the COD layer.
232 CODLayer
= std::make_unique
<CompileOnDemandLayer
>(
233 *ES
, *TransformLayer
, *LCTMgr
, std::move(ISMBuilder
));
235 if (S
.NumCompileThreads
> 0)
236 CODLayer
->setCloneToNewContextOnEmit(true);
239 } // End namespace orc.
240 } // End namespace llvm.