blob: 0a0faaa681c30057e845dfe5bcc10b136cbddafd [file] [log] [blame]
Lang Hames6a941342018-06-26 21:35:48 +00001//===--------- 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
Lang Hamesf0a3fd882018-09-26 16:26:59 +000015namespace {
16
17 // A SimpleCompiler that owns its TargetMachine.
18 class TMOwningSimpleCompiler : public llvm::orc::SimpleCompiler {
19 public:
20 TMOwningSimpleCompiler(std::unique_ptr<llvm::TargetMachine> TM)
21 : llvm::orc::SimpleCompiler(*TM), TM(std::move(TM)) {}
22 private:
23 // FIXME: shared because std::functions (and thus
24 // IRCompileLayer2::CompileFunction) are not moveable.
25 std::shared_ptr<llvm::TargetMachine> TM;
26 };
27
28} // end anonymous namespace
29
Lang Hames6a941342018-06-26 21:35:48 +000030namespace llvm {
31namespace orc {
32
Lang Hamesf0a3fd882018-09-26 16:26:59 +000033LLJIT::~LLJIT() {
34 if (CompileThreads)
35 CompileThreads->wait();
36}
37
Lang Hames6a941342018-06-26 21:35:48 +000038Expected<std::unique_ptr<LLJIT>>
Lang Hamesf0a3fd882018-09-26 16:26:59 +000039LLJIT::Create(JITTargetMachineBuilder JTMB, DataLayout DL,
40 unsigned NumCompileThreads) {
41
42 if (NumCompileThreads == 0) {
43 // If NumCompileThreads == 0 then create a single-threaded LLJIT instance.
44 auto TM = JTMB.createTargetMachine();
45 if (!TM)
46 return TM.takeError();
47 return std::unique_ptr<LLJIT>(new LLJIT(llvm::make_unique<ExecutionSession>(),
48 std::move(*TM), std::move(DL)));
49 }
50
Lang Hames7c481432018-09-10 22:08:57 +000051 return std::unique_ptr<LLJIT>(new LLJIT(llvm::make_unique<ExecutionSession>(),
Lang Hamesf0a3fd882018-09-26 16:26:59 +000052 std::move(JTMB), std::move(DL),
53 NumCompileThreads));
Lang Hames6a941342018-06-26 21:35:48 +000054}
55
56Error LLJIT::defineAbsolute(StringRef Name, JITEvaluatedSymbol Sym) {
57 auto InternedName = ES->getSymbolStringPool().intern(Name);
58 SymbolMap Symbols({{InternedName, Sym}});
59 return Main.define(absoluteSymbols(std::move(Symbols)));
60}
61
Lang Hames8d76c712018-09-26 01:24:12 +000062Error LLJIT::addIRModule(JITDylib &JD, ThreadSafeModule TSM) {
63 assert(TSM && "Can not add null module");
Lang Hames6a941342018-06-26 21:35:48 +000064
Lang Hames8d76c712018-09-26 01:24:12 +000065 if (auto Err = applyDataLayout(*TSM.getModule()))
Lang Hames6a941342018-06-26 21:35:48 +000066 return Err;
67
68 auto K = ES->allocateVModule();
Lang Hames8d76c712018-09-26 01:24:12 +000069 return CompileLayer.add(JD, K, std::move(TSM));
Lang Hames6a941342018-06-26 21:35:48 +000070}
71
Lang Hames37a66412018-08-28 20:20:31 +000072Error LLJIT::addObjectFile(JITDylib &JD, std::unique_ptr<MemoryBuffer> Obj) {
73 assert(Obj && "Can not add null object");
74
75 auto K = ES->allocateVModule();
76 return ObjLinkingLayer.add(JD, K, std::move(Obj));
77}
78
Lang Hamesd5f56c52018-08-17 21:18:18 +000079Expected<JITEvaluatedSymbol> LLJIT::lookupLinkerMangled(JITDylib &JD,
Lang Hames6a941342018-06-26 21:35:48 +000080 StringRef Name) {
Lang Hamesd5f56c52018-08-17 21:18:18 +000081 return llvm::orc::lookup({&JD}, ES->getSymbolStringPool().intern(Name));
Lang Hames6a941342018-06-26 21:35:48 +000082}
83
84LLJIT::LLJIT(std::unique_ptr<ExecutionSession> ES,
85 std::unique_ptr<TargetMachine> TM, DataLayout DL)
Lang Hamesd5f56c52018-08-17 21:18:18 +000086 : ES(std::move(ES)), Main(this->ES->createJITDylib("main")),
Lang Hamesf0a3fd882018-09-26 16:26:59 +000087 DL(std::move(DL)),
Lang Hames6a941342018-06-26 21:35:48 +000088 ObjLinkingLayer(*this->ES,
Lang Hamesfd0c1e712018-07-20 18:31:50 +000089 [this](VModuleKey K) { return getMemoryManager(K); }),
Lang Hamesf0a3fd882018-09-26 16:26:59 +000090 CompileLayer(*this->ES, ObjLinkingLayer, TMOwningSimpleCompiler(std::move(TM))),
Lang Hamesfd0c1e712018-07-20 18:31:50 +000091 CtorRunner(Main), DtorRunner(Main) {}
Lang Hames6a941342018-06-26 21:35:48 +000092
Lang Hamesf0a3fd882018-09-26 16:26:59 +000093LLJIT::LLJIT(std::unique_ptr<ExecutionSession> ES,
94 JITTargetMachineBuilder JTMB, DataLayout DL,
95 unsigned NumCompileThreads)
96 : ES(std::move(ES)), Main(this->ES->createJITDylib("main")),
97 DL(std::move(DL)),
98 ObjLinkingLayer(*this->ES,
99 [this](VModuleKey K) { return getMemoryManager(K); }),
100 CompileLayer(*this->ES, ObjLinkingLayer, MultiThreadedSimpleCompiler(std::move(JTMB))),
101 CtorRunner(Main), DtorRunner(Main) {
102 assert(NumCompileThreads != 0 &&
103 "Multithreaded LLJIT instance can not be created with 0 threads");
104
105 CompileThreads = llvm::make_unique<ThreadPool>(NumCompileThreads);
106 this->ES->setDispatchMaterialization([this](JITDylib &JD, std::unique_ptr<MaterializationUnit> MU) {
107 // FIXME: Switch to move capture once we have c++14.
108 auto SharedMU = std::shared_ptr<MaterializationUnit>(std::move(MU));
109 auto Work = [SharedMU, &JD]() {
110 SharedMU->doMaterialize(JD);
111 };
112 CompileThreads->async(std::move(Work));
113 });
114}
115
Lang Hamesbf985252018-09-06 19:39:26 +0000116std::unique_ptr<RuntimeDyld::MemoryManager>
Lang Hamesfd0c1e712018-07-20 18:31:50 +0000117LLJIT::getMemoryManager(VModuleKey K) {
118 return llvm::make_unique<SectionMemoryManager>();
Lang Hames6a941342018-06-26 21:35:48 +0000119}
120
121std::string LLJIT::mangle(StringRef UnmangledName) {
122 std::string MangledName;
123 {
124 raw_string_ostream MangledNameStream(MangledName);
125 Mangler::getNameWithPrefix(MangledNameStream, UnmangledName, DL);
126 }
127 return MangledName;
128}
129
Lang Hames6a941342018-06-26 21:35:48 +0000130Error LLJIT::applyDataLayout(Module &M) {
131 if (M.getDataLayout().isDefault())
132 M.setDataLayout(DL);
133
134 if (M.getDataLayout() != DL)
135 return make_error<StringError>(
136 "Added modules have incompatible data layouts",
137 inconvertibleErrorCode());
138
139 return Error::success();
140}
141
142void LLJIT::recordCtorDtors(Module &M) {
143 CtorRunner.add(getConstructors(M));
144 DtorRunner.add(getDestructors(M));
145}
146
147Expected<std::unique_ptr<LLLazyJIT>>
Lang Hamesf0a3fd882018-09-26 16:26:59 +0000148 LLLazyJIT::Create(JITTargetMachineBuilder JTMB, DataLayout DL,
149 unsigned NumCompileThreads) {
Lang Hames7c481432018-09-10 22:08:57 +0000150 auto ES = llvm::make_unique<ExecutionSession>();
151
Lang Hamesf0a3fd882018-09-26 16:26:59 +0000152 const Triple &TT = JTMB.getTargetTriple();
Lang Hames6a941342018-06-26 21:35:48 +0000153
Lang Hamesd8048672018-09-26 05:08:29 +0000154 auto LCTMgr = createLocalLazyCallThroughManager(TT, *ES, 0);
155 if (!LCTMgr)
156 return LCTMgr.takeError();
Lang Hames6a941342018-06-26 21:35:48 +0000157
158 auto ISMBuilder = createLocalIndirectStubsManagerBuilder(TT);
159 if (!ISMBuilder)
160 return make_error<StringError>(
161 std::string("No indirect stubs manager builder for ") + TT.str(),
162 inconvertibleErrorCode());
163
Lang Hamesf0a3fd882018-09-26 16:26:59 +0000164 if (NumCompileThreads == 0) {
165 auto TM = JTMB.createTargetMachine();
166 if (!TM)
167 return TM.takeError();
168 return std::unique_ptr<LLLazyJIT>(
169 new LLLazyJIT(std::move(ES), std::move(*TM), std::move(DL),
170 std::move(*LCTMgr), std::move(ISMBuilder)));
171 }
172
173 return std::unique_ptr<LLLazyJIT>(new LLLazyJIT(
174 std::move(ES), std::move(JTMB), std::move(DL), NumCompileThreads,
175 std::move(*LCTMgr), std::move(ISMBuilder)));
Lang Hames6a941342018-06-26 21:35:48 +0000176}
177
Lang Hames8d76c712018-09-26 01:24:12 +0000178Error LLLazyJIT::addLazyIRModule(JITDylib &JD, ThreadSafeModule TSM) {
179 assert(TSM && "Can not add null module");
Lang Hames6a941342018-06-26 21:35:48 +0000180
Lang Hames8d76c712018-09-26 01:24:12 +0000181 if (auto Err = applyDataLayout(*TSM.getModule()))
Lang Hames6a941342018-06-26 21:35:48 +0000182 return Err;
183
Lang Hames8d76c712018-09-26 01:24:12 +0000184 makeAllSymbolsExternallyAccessible(*TSM.getModule());
Lang Hames6a941342018-06-26 21:35:48 +0000185
Lang Hames8d76c712018-09-26 01:24:12 +0000186 recordCtorDtors(*TSM.getModule());
Lang Hames6a941342018-06-26 21:35:48 +0000187
188 auto K = ES->allocateVModule();
Lang Hames8d76c712018-09-26 01:24:12 +0000189 return CODLayer.add(JD, K, std::move(TSM));
Lang Hames6a941342018-06-26 21:35:48 +0000190}
191
192LLLazyJIT::LLLazyJIT(
193 std::unique_ptr<ExecutionSession> ES, std::unique_ptr<TargetMachine> TM,
Lang Hamesd8048672018-09-26 05:08:29 +0000194 DataLayout DL, std::unique_ptr<LazyCallThroughManager> LCTMgr,
Lang Hames6a941342018-06-26 21:35:48 +0000195 std::function<std::unique_ptr<IndirectStubsManager>()> ISMBuilder)
196 : LLJIT(std::move(ES), std::move(TM), std::move(DL)),
Lang Hamesd8048672018-09-26 05:08:29 +0000197 LCTMgr(std::move(LCTMgr)), TransformLayer(*this->ES, CompileLayer),
198 CODLayer(*this->ES, TransformLayer, *this->LCTMgr,
199 std::move(ISMBuilder)) {}
Lang Hames6a941342018-06-26 21:35:48 +0000200
Lang Hamesf0a3fd882018-09-26 16:26:59 +0000201LLLazyJIT::LLLazyJIT(
202 std::unique_ptr<ExecutionSession> ES, JITTargetMachineBuilder JTMB,
203 DataLayout DL, unsigned NumCompileThreads,
204 std::unique_ptr<LazyCallThroughManager> LCTMgr,
205 std::function<std::unique_ptr<IndirectStubsManager>()> ISMBuilder)
206 : LLJIT(std::move(ES), std::move(JTMB), std::move(DL), NumCompileThreads),
207 LCTMgr(std::move(LCTMgr)), TransformLayer(*this->ES, CompileLayer),
208 CODLayer(*this->ES, TransformLayer, *this->LCTMgr,
209 std::move(ISMBuilder)) {}
210
Lang Hames6a941342018-06-26 21:35:48 +0000211} // End namespace orc.
212} // End namespace llvm.