blob: 89a302ca02f8f9aed0bb7efd48963d3eb5540761 [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) {
Lang Hames71d781c2018-09-30 23:18:24 +000057 auto InternedName = ES->intern(Name);
Lang Hames6a941342018-06-26 21:35:48 +000058 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 Hames71d781c2018-09-30 23:18:24 +000081 return llvm::orc::lookup({&JD}, ES->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 Hames8b813952018-09-27 21:13:07 +000086 : ES(std::move(ES)), Main(this->ES->getMainJITDylib()), DL(std::move(DL)),
Lang Hames6a941342018-06-26 21:35:48 +000087 ObjLinkingLayer(*this->ES,
Lang Hamesfd0c1e712018-07-20 18:31:50 +000088 [this](VModuleKey K) { return getMemoryManager(K); }),
Lang Hames8b813952018-09-27 21:13:07 +000089 CompileLayer(*this->ES, ObjLinkingLayer,
90 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 Hames8b813952018-09-27 21:13:07 +000093LLJIT::LLJIT(std::unique_ptr<ExecutionSession> ES, JITTargetMachineBuilder JTMB,
94 DataLayout DL, unsigned NumCompileThreads)
95 : ES(std::move(ES)), Main(this->ES->getMainJITDylib()), DL(std::move(DL)),
Lang Hamesf0a3fd882018-09-26 16:26:59 +000096 ObjLinkingLayer(*this->ES,
97 [this](VModuleKey K) { return getMemoryManager(K); }),
Lang Hames8b813952018-09-27 21:13:07 +000098 CompileLayer(*this->ES, ObjLinkingLayer,
99 MultiThreadedSimpleCompiler(std::move(JTMB))),
Lang Hamesf0a3fd882018-09-26 16:26:59 +0000100 CtorRunner(Main), DtorRunner(Main) {
101 assert(NumCompileThreads != 0 &&
102 "Multithreaded LLJIT instance can not be created with 0 threads");
103
Lang Hames8b813952018-09-27 21:13:07 +0000104 // Move modules to new contexts when they're emitted so that we can compile
105 // them in parallel.
106 CompileLayer.setCloneToNewContextOnEmit(true);
107
108 // Create a thread pool to compile on and set the execution session
109 // dispatcher to use the thread pool.
Lang Hamesf0a3fd882018-09-26 16:26:59 +0000110 CompileThreads = llvm::make_unique<ThreadPool>(NumCompileThreads);
Lang Hames8b813952018-09-27 21:13:07 +0000111 this->ES->setDispatchMaterialization(
112 [this](JITDylib &JD, std::unique_ptr<MaterializationUnit> MU) {
113 // FIXME: Switch to move capture once we have c++14.
114 auto SharedMU = std::shared_ptr<MaterializationUnit>(std::move(MU));
115 auto Work = [SharedMU, &JD]() { SharedMU->doMaterialize(JD); };
116 CompileThreads->async(std::move(Work));
117 });
Lang Hamesf0a3fd882018-09-26 16:26:59 +0000118}
119
Lang Hamesbf985252018-09-06 19:39:26 +0000120std::unique_ptr<RuntimeDyld::MemoryManager>
Lang Hamesfd0c1e712018-07-20 18:31:50 +0000121LLJIT::getMemoryManager(VModuleKey K) {
122 return llvm::make_unique<SectionMemoryManager>();
Lang Hames6a941342018-06-26 21:35:48 +0000123}
124
125std::string LLJIT::mangle(StringRef UnmangledName) {
126 std::string MangledName;
127 {
128 raw_string_ostream MangledNameStream(MangledName);
129 Mangler::getNameWithPrefix(MangledNameStream, UnmangledName, DL);
130 }
131 return MangledName;
132}
133
Lang Hames6a941342018-06-26 21:35:48 +0000134Error LLJIT::applyDataLayout(Module &M) {
135 if (M.getDataLayout().isDefault())
136 M.setDataLayout(DL);
137
138 if (M.getDataLayout() != DL)
139 return make_error<StringError>(
140 "Added modules have incompatible data layouts",
141 inconvertibleErrorCode());
142
143 return Error::success();
144}
145
146void LLJIT::recordCtorDtors(Module &M) {
147 CtorRunner.add(getConstructors(M));
148 DtorRunner.add(getDestructors(M));
149}
150
151Expected<std::unique_ptr<LLLazyJIT>>
Lang Hamesf0a3fd882018-09-26 16:26:59 +0000152 LLLazyJIT::Create(JITTargetMachineBuilder JTMB, DataLayout DL,
153 unsigned NumCompileThreads) {
Lang Hames7c481432018-09-10 22:08:57 +0000154 auto ES = llvm::make_unique<ExecutionSession>();
155
Lang Hamesf0a3fd882018-09-26 16:26:59 +0000156 const Triple &TT = JTMB.getTargetTriple();
Lang Hames6a941342018-06-26 21:35:48 +0000157
Lang Hamesd8048672018-09-26 05:08:29 +0000158 auto LCTMgr = createLocalLazyCallThroughManager(TT, *ES, 0);
159 if (!LCTMgr)
160 return LCTMgr.takeError();
Lang Hames6a941342018-06-26 21:35:48 +0000161
162 auto ISMBuilder = createLocalIndirectStubsManagerBuilder(TT);
163 if (!ISMBuilder)
164 return make_error<StringError>(
165 std::string("No indirect stubs manager builder for ") + TT.str(),
166 inconvertibleErrorCode());
167
Lang Hamesf0a3fd882018-09-26 16:26:59 +0000168 if (NumCompileThreads == 0) {
169 auto TM = JTMB.createTargetMachine();
170 if (!TM)
171 return TM.takeError();
172 return std::unique_ptr<LLLazyJIT>(
173 new LLLazyJIT(std::move(ES), std::move(*TM), std::move(DL),
174 std::move(*LCTMgr), std::move(ISMBuilder)));
175 }
176
177 return std::unique_ptr<LLLazyJIT>(new LLLazyJIT(
178 std::move(ES), std::move(JTMB), std::move(DL), NumCompileThreads,
179 std::move(*LCTMgr), std::move(ISMBuilder)));
Lang Hames6a941342018-06-26 21:35:48 +0000180}
181
Lang Hames8d76c712018-09-26 01:24:12 +0000182Error LLLazyJIT::addLazyIRModule(JITDylib &JD, ThreadSafeModule TSM) {
183 assert(TSM && "Can not add null module");
Lang Hames6a941342018-06-26 21:35:48 +0000184
Lang Hames8d76c712018-09-26 01:24:12 +0000185 if (auto Err = applyDataLayout(*TSM.getModule()))
Lang Hames6a941342018-06-26 21:35:48 +0000186 return Err;
187
Lang Hamesc5192f752018-09-27 19:27:20 +0000188 PromoteSymbols(*TSM.getModule());
Lang Hames6a941342018-06-26 21:35:48 +0000189
Lang Hames8d76c712018-09-26 01:24:12 +0000190 recordCtorDtors(*TSM.getModule());
Lang Hames6a941342018-06-26 21:35:48 +0000191
192 auto K = ES->allocateVModule();
Lang Hames8d76c712018-09-26 01:24:12 +0000193 return CODLayer.add(JD, K, std::move(TSM));
Lang Hames6a941342018-06-26 21:35:48 +0000194}
195
196LLLazyJIT::LLLazyJIT(
197 std::unique_ptr<ExecutionSession> ES, std::unique_ptr<TargetMachine> TM,
Lang Hamesd8048672018-09-26 05:08:29 +0000198 DataLayout DL, std::unique_ptr<LazyCallThroughManager> LCTMgr,
Lang Hames6a941342018-06-26 21:35:48 +0000199 std::function<std::unique_ptr<IndirectStubsManager>()> ISMBuilder)
200 : LLJIT(std::move(ES), std::move(TM), std::move(DL)),
Lang Hamesd8048672018-09-26 05:08:29 +0000201 LCTMgr(std::move(LCTMgr)), TransformLayer(*this->ES, CompileLayer),
202 CODLayer(*this->ES, TransformLayer, *this->LCTMgr,
203 std::move(ISMBuilder)) {}
Lang Hames6a941342018-06-26 21:35:48 +0000204
Lang Hamesf0a3fd882018-09-26 16:26:59 +0000205LLLazyJIT::LLLazyJIT(
206 std::unique_ptr<ExecutionSession> ES, JITTargetMachineBuilder JTMB,
207 DataLayout DL, unsigned NumCompileThreads,
208 std::unique_ptr<LazyCallThroughManager> LCTMgr,
209 std::function<std::unique_ptr<IndirectStubsManager>()> ISMBuilder)
210 : LLJIT(std::move(ES), std::move(JTMB), std::move(DL), NumCompileThreads),
211 LCTMgr(std::move(LCTMgr)), TransformLayer(*this->ES, CompileLayer),
212 CODLayer(*this->ES, TransformLayer, *this->LCTMgr,
Lang Hames8b813952018-09-27 21:13:07 +0000213 std::move(ISMBuilder)) {
214 CODLayer.setCloneToNewContextOnEmit(true);
215}
Lang Hamesf0a3fd882018-09-26 16:26:59 +0000216
Lang Hames6a941342018-06-26 21:35:48 +0000217} // End namespace orc.
218} // End namespace llvm.