blob: ac71a5e7673e1a9120ab0305106419145a04c3b7 [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
Lang Hames079df9a2018-10-15 22:56:10 +000024 // IRCompileLayer::CompileFunction) are not moveable.
Lang Hamesf0a3fd882018-09-26 16:26:59 +000025 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
Lang Hames8b942742018-10-16 20:13:06 +000068 return CompileLayer.add(JD, std::move(TSM), ES->allocateVModule());
Lang Hames6a941342018-06-26 21:35:48 +000069}
70
Lang Hames37a66412018-08-28 20:20:31 +000071Error LLJIT::addObjectFile(JITDylib &JD, std::unique_ptr<MemoryBuffer> Obj) {
72 assert(Obj && "Can not add null object");
73
Lang Hames8b942742018-10-16 20:13:06 +000074 return ObjLinkingLayer.add(JD, std::move(Obj), ES->allocateVModule());
Lang Hames37a66412018-08-28 20:20:31 +000075}
76
Lang Hamesd5f56c52018-08-17 21:18:18 +000077Expected<JITEvaluatedSymbol> LLJIT::lookupLinkerMangled(JITDylib &JD,
Lang Hames6a941342018-06-26 21:35:48 +000078 StringRef Name) {
Lang Hames7899ccb2018-10-13 21:53:40 +000079 return ES->lookup({&JD}, ES->intern(Name));
Lang Hames6a941342018-06-26 21:35:48 +000080}
81
82LLJIT::LLJIT(std::unique_ptr<ExecutionSession> ES,
83 std::unique_ptr<TargetMachine> TM, DataLayout DL)
Lang Hames8b813952018-09-27 21:13:07 +000084 : ES(std::move(ES)), Main(this->ES->getMainJITDylib()), DL(std::move(DL)),
Lang Hames8b942742018-10-16 20:13:06 +000085 ObjLinkingLayer(
86 *this->ES,
87 []() { return llvm::make_unique<SectionMemoryManager>(); }),
Lang Hames8b813952018-09-27 21:13:07 +000088 CompileLayer(*this->ES, ObjLinkingLayer,
89 TMOwningSimpleCompiler(std::move(TM))),
Lang Hamesfd0c1e712018-07-20 18:31:50 +000090 CtorRunner(Main), DtorRunner(Main) {}
Lang Hames6a941342018-06-26 21:35:48 +000091
Lang Hames8b813952018-09-27 21:13:07 +000092LLJIT::LLJIT(std::unique_ptr<ExecutionSession> ES, JITTargetMachineBuilder JTMB,
93 DataLayout DL, unsigned NumCompileThreads)
94 : ES(std::move(ES)), Main(this->ES->getMainJITDylib()), DL(std::move(DL)),
Lang Hames8b942742018-10-16 20:13:06 +000095 ObjLinkingLayer(
96 *this->ES,
97 []() { return llvm::make_unique<SectionMemoryManager>(); }),
Lang Hames8b813952018-09-27 21:13:07 +000098 CompileLayer(*this->ES, ObjLinkingLayer,
Lang Hames9f342d92018-10-15 22:36:22 +000099 ConcurrentIRCompiler(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 Hames6a941342018-06-26 21:35:48 +0000120std::string LLJIT::mangle(StringRef UnmangledName) {
121 std::string MangledName;
122 {
123 raw_string_ostream MangledNameStream(MangledName);
124 Mangler::getNameWithPrefix(MangledNameStream, UnmangledName, DL);
125 }
126 return MangledName;
127}
128
Lang Hames6a941342018-06-26 21:35:48 +0000129Error LLJIT::applyDataLayout(Module &M) {
130 if (M.getDataLayout().isDefault())
131 M.setDataLayout(DL);
132
133 if (M.getDataLayout() != DL)
134 return make_error<StringError>(
135 "Added modules have incompatible data layouts",
136 inconvertibleErrorCode());
137
138 return Error::success();
139}
140
141void LLJIT::recordCtorDtors(Module &M) {
142 CtorRunner.add(getConstructors(M));
143 DtorRunner.add(getDestructors(M));
144}
145
146Expected<std::unique_ptr<LLLazyJIT>>
Lang Hamesf0a3fd882018-09-26 16:26:59 +0000147 LLLazyJIT::Create(JITTargetMachineBuilder JTMB, DataLayout DL,
148 unsigned NumCompileThreads) {
Lang Hames7c481432018-09-10 22:08:57 +0000149 auto ES = llvm::make_unique<ExecutionSession>();
150
Lang Hamesf0a3fd882018-09-26 16:26:59 +0000151 const Triple &TT = JTMB.getTargetTriple();
Lang Hames6a941342018-06-26 21:35:48 +0000152
Lang Hamesd8048672018-09-26 05:08:29 +0000153 auto LCTMgr = createLocalLazyCallThroughManager(TT, *ES, 0);
154 if (!LCTMgr)
155 return LCTMgr.takeError();
Lang Hames6a941342018-06-26 21:35:48 +0000156
157 auto ISMBuilder = createLocalIndirectStubsManagerBuilder(TT);
158 if (!ISMBuilder)
159 return make_error<StringError>(
160 std::string("No indirect stubs manager builder for ") + TT.str(),
161 inconvertibleErrorCode());
162
Lang Hamesf0a3fd882018-09-26 16:26:59 +0000163 if (NumCompileThreads == 0) {
164 auto TM = JTMB.createTargetMachine();
165 if (!TM)
166 return TM.takeError();
167 return std::unique_ptr<LLLazyJIT>(
168 new LLLazyJIT(std::move(ES), std::move(*TM), std::move(DL),
169 std::move(*LCTMgr), std::move(ISMBuilder)));
170 }
171
172 return std::unique_ptr<LLLazyJIT>(new LLLazyJIT(
173 std::move(ES), std::move(JTMB), std::move(DL), NumCompileThreads,
174 std::move(*LCTMgr), std::move(ISMBuilder)));
Lang Hames6a941342018-06-26 21:35:48 +0000175}
176
Lang Hames8d76c712018-09-26 01:24:12 +0000177Error LLLazyJIT::addLazyIRModule(JITDylib &JD, ThreadSafeModule TSM) {
178 assert(TSM && "Can not add null module");
Lang Hames6a941342018-06-26 21:35:48 +0000179
Lang Hames8d76c712018-09-26 01:24:12 +0000180 if (auto Err = applyDataLayout(*TSM.getModule()))
Lang Hames6a941342018-06-26 21:35:48 +0000181 return Err;
182
Lang Hames8d76c712018-09-26 01:24:12 +0000183 recordCtorDtors(*TSM.getModule());
Lang Hames6a941342018-06-26 21:35:48 +0000184
Lang Hames8b942742018-10-16 20:13:06 +0000185 return CODLayer.add(JD, std::move(TSM), ES->allocateVModule());
Lang Hames6a941342018-06-26 21:35:48 +0000186}
187
188LLLazyJIT::LLLazyJIT(
189 std::unique_ptr<ExecutionSession> ES, std::unique_ptr<TargetMachine> TM,
Lang Hamesd8048672018-09-26 05:08:29 +0000190 DataLayout DL, std::unique_ptr<LazyCallThroughManager> LCTMgr,
Lang Hames6a941342018-06-26 21:35:48 +0000191 std::function<std::unique_ptr<IndirectStubsManager>()> ISMBuilder)
192 : LLJIT(std::move(ES), std::move(TM), std::move(DL)),
Lang Hamesd8048672018-09-26 05:08:29 +0000193 LCTMgr(std::move(LCTMgr)), TransformLayer(*this->ES, CompileLayer),
194 CODLayer(*this->ES, TransformLayer, *this->LCTMgr,
195 std::move(ISMBuilder)) {}
Lang Hames6a941342018-06-26 21:35:48 +0000196
Lang Hamesf0a3fd882018-09-26 16:26:59 +0000197LLLazyJIT::LLLazyJIT(
198 std::unique_ptr<ExecutionSession> ES, JITTargetMachineBuilder JTMB,
199 DataLayout DL, unsigned NumCompileThreads,
200 std::unique_ptr<LazyCallThroughManager> LCTMgr,
201 std::function<std::unique_ptr<IndirectStubsManager>()> ISMBuilder)
202 : LLJIT(std::move(ES), std::move(JTMB), std::move(DL), NumCompileThreads),
203 LCTMgr(std::move(LCTMgr)), TransformLayer(*this->ES, CompileLayer),
204 CODLayer(*this->ES, TransformLayer, *this->LCTMgr,
Lang Hames8b813952018-09-27 21:13:07 +0000205 std::move(ISMBuilder)) {
206 CODLayer.setCloneToNewContextOnEmit(true);
207}
Lang Hamesf0a3fd882018-09-26 16:26:59 +0000208
Lang Hames6a941342018-06-26 21:35:48 +0000209} // End namespace orc.
210} // End namespace llvm.