blob: 62027314621efb79e3a80b07b949c27f3e2e17bd [file] [log] [blame]
Lang Hames6a941342018-06-26 21:35:48 +00001//===--------- LLJIT.cpp - An ORC-based JIT for compiling LLVM IR ---------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Lang Hames6a941342018-06-26 21:35:48 +00006//
7//===----------------------------------------------------------------------===//
8
9#include "llvm/ExecutionEngine/Orc/LLJIT.h"
10#include "llvm/ExecutionEngine/Orc/OrcError.h"
11#include "llvm/ExecutionEngine/SectionMemoryManager.h"
12#include "llvm/IR/Mangler.h"
13
Lang Hamesf0a3fd882018-09-26 16:26:59 +000014namespace {
15
16 // A SimpleCompiler that owns its TargetMachine.
17 class TMOwningSimpleCompiler : public llvm::orc::SimpleCompiler {
18 public:
19 TMOwningSimpleCompiler(std::unique_ptr<llvm::TargetMachine> TM)
20 : llvm::orc::SimpleCompiler(*TM), TM(std::move(TM)) {}
21 private:
22 // FIXME: shared because std::functions (and thus
Lang Hames079df9a2018-10-15 22:56:10 +000023 // IRCompileLayer::CompileFunction) are not moveable.
Lang Hamesf0a3fd882018-09-26 16:26:59 +000024 std::shared_ptr<llvm::TargetMachine> TM;
25 };
26
27} // end anonymous namespace
28
Lang Hames6a941342018-06-26 21:35:48 +000029namespace llvm {
30namespace orc {
31
Lang Hamesf0a3fd882018-09-26 16:26:59 +000032LLJIT::~LLJIT() {
33 if (CompileThreads)
34 CompileThreads->wait();
35}
36
Lang Hames6a941342018-06-26 21:35:48 +000037Expected<std::unique_ptr<LLJIT>>
Lang Hamesf0a3fd882018-09-26 16:26:59 +000038LLJIT::Create(JITTargetMachineBuilder JTMB, DataLayout DL,
39 unsigned NumCompileThreads) {
40
41 if (NumCompileThreads == 0) {
42 // If NumCompileThreads == 0 then create a single-threaded LLJIT instance.
43 auto TM = JTMB.createTargetMachine();
44 if (!TM)
45 return TM.takeError();
46 return std::unique_ptr<LLJIT>(new LLJIT(llvm::make_unique<ExecutionSession>(),
47 std::move(*TM), std::move(DL)));
48 }
49
Lang Hames7c481432018-09-10 22:08:57 +000050 return std::unique_ptr<LLJIT>(new LLJIT(llvm::make_unique<ExecutionSession>(),
Lang Hamesf0a3fd882018-09-26 16:26:59 +000051 std::move(JTMB), std::move(DL),
52 NumCompileThreads));
Lang Hames6a941342018-06-26 21:35:48 +000053}
54
55Error LLJIT::defineAbsolute(StringRef Name, JITEvaluatedSymbol Sym) {
Lang Hames71d781c2018-09-30 23:18:24 +000056 auto InternedName = ES->intern(Name);
Lang Hames6a941342018-06-26 21:35:48 +000057 SymbolMap Symbols({{InternedName, Sym}});
58 return Main.define(absoluteSymbols(std::move(Symbols)));
59}
60
Lang Hames8d76c712018-09-26 01:24:12 +000061Error LLJIT::addIRModule(JITDylib &JD, ThreadSafeModule TSM) {
62 assert(TSM && "Can not add null module");
Lang Hames6a941342018-06-26 21:35:48 +000063
Lang Hames8d76c712018-09-26 01:24:12 +000064 if (auto Err = applyDataLayout(*TSM.getModule()))
Lang Hames6a941342018-06-26 21:35:48 +000065 return Err;
66
Lang Hames8b942742018-10-16 20:13:06 +000067 return CompileLayer.add(JD, std::move(TSM), ES->allocateVModule());
Lang Hames6a941342018-06-26 21:35:48 +000068}
69
Lang Hames37a66412018-08-28 20:20:31 +000070Error LLJIT::addObjectFile(JITDylib &JD, std::unique_ptr<MemoryBuffer> Obj) {
71 assert(Obj && "Can not add null object");
72
Lang Hames8b942742018-10-16 20:13:06 +000073 return ObjLinkingLayer.add(JD, std::move(Obj), ES->allocateVModule());
Lang Hames37a66412018-08-28 20:20:31 +000074}
75
Lang Hamesd5f56c52018-08-17 21:18:18 +000076Expected<JITEvaluatedSymbol> LLJIT::lookupLinkerMangled(JITDylib &JD,
Lang Hames6a941342018-06-26 21:35:48 +000077 StringRef Name) {
Lang Hames23cb2e72018-10-23 23:01:39 +000078 return ES->lookup(JITDylibSearchList({{&JD, true}}), ES->intern(Name));
Lang Hames6a941342018-06-26 21:35:48 +000079}
80
81LLJIT::LLJIT(std::unique_ptr<ExecutionSession> ES,
82 std::unique_ptr<TargetMachine> TM, DataLayout DL)
Lang Hames8b813952018-09-27 21:13:07 +000083 : ES(std::move(ES)), Main(this->ES->getMainJITDylib()), DL(std::move(DL)),
Lang Hames8b942742018-10-16 20:13:06 +000084 ObjLinkingLayer(
85 *this->ES,
86 []() { return llvm::make_unique<SectionMemoryManager>(); }),
Lang Hames8b813952018-09-27 21:13:07 +000087 CompileLayer(*this->ES, ObjLinkingLayer,
88 TMOwningSimpleCompiler(std::move(TM))),
Lang Hamesfd0c1e712018-07-20 18:31:50 +000089 CtorRunner(Main), DtorRunner(Main) {}
Lang Hames6a941342018-06-26 21:35:48 +000090
Lang Hames8b813952018-09-27 21:13:07 +000091LLJIT::LLJIT(std::unique_ptr<ExecutionSession> ES, JITTargetMachineBuilder JTMB,
92 DataLayout DL, unsigned NumCompileThreads)
93 : ES(std::move(ES)), Main(this->ES->getMainJITDylib()), DL(std::move(DL)),
Lang Hames8b942742018-10-16 20:13:06 +000094 ObjLinkingLayer(
95 *this->ES,
96 []() { return llvm::make_unique<SectionMemoryManager>(); }),
Lang Hames8b813952018-09-27 21:13:07 +000097 CompileLayer(*this->ES, ObjLinkingLayer,
Lang Hames9f342d92018-10-15 22:36:22 +000098 ConcurrentIRCompiler(std::move(JTMB))),
Lang Hamesf0a3fd882018-09-26 16:26:59 +000099 CtorRunner(Main), DtorRunner(Main) {
100 assert(NumCompileThreads != 0 &&
101 "Multithreaded LLJIT instance can not be created with 0 threads");
102
Lang Hames8b813952018-09-27 21:13:07 +0000103 // Move modules to new contexts when they're emitted so that we can compile
104 // them in parallel.
105 CompileLayer.setCloneToNewContextOnEmit(true);
106
107 // Create a thread pool to compile on and set the execution session
108 // dispatcher to use the thread pool.
Lang Hamesf0a3fd882018-09-26 16:26:59 +0000109 CompileThreads = llvm::make_unique<ThreadPool>(NumCompileThreads);
Lang Hames8b813952018-09-27 21:13:07 +0000110 this->ES->setDispatchMaterialization(
111 [this](JITDylib &JD, std::unique_ptr<MaterializationUnit> MU) {
112 // FIXME: Switch to move capture once we have c++14.
113 auto SharedMU = std::shared_ptr<MaterializationUnit>(std::move(MU));
114 auto Work = [SharedMU, &JD]() { SharedMU->doMaterialize(JD); };
115 CompileThreads->async(std::move(Work));
116 });
Lang Hamesf0a3fd882018-09-26 16:26:59 +0000117}
118
Lang Hames6a941342018-06-26 21:35:48 +0000119std::string LLJIT::mangle(StringRef UnmangledName) {
120 std::string MangledName;
121 {
122 raw_string_ostream MangledNameStream(MangledName);
123 Mangler::getNameWithPrefix(MangledNameStream, UnmangledName, DL);
124 }
125 return MangledName;
126}
127
Lang Hames6a941342018-06-26 21:35:48 +0000128Error LLJIT::applyDataLayout(Module &M) {
129 if (M.getDataLayout().isDefault())
130 M.setDataLayout(DL);
131
132 if (M.getDataLayout() != DL)
133 return make_error<StringError>(
134 "Added modules have incompatible data layouts",
135 inconvertibleErrorCode());
136
137 return Error::success();
138}
139
140void LLJIT::recordCtorDtors(Module &M) {
141 CtorRunner.add(getConstructors(M));
142 DtorRunner.add(getDestructors(M));
143}
144
145Expected<std::unique_ptr<LLLazyJIT>>
Lang Hames23cb2e72018-10-23 23:01:39 +0000146LLLazyJIT::Create(JITTargetMachineBuilder JTMB, DataLayout DL,
147 JITTargetAddress ErrorAddr, unsigned NumCompileThreads) {
Lang Hames7c481432018-09-10 22:08:57 +0000148 auto ES = llvm::make_unique<ExecutionSession>();
149
Lang Hamesf0a3fd882018-09-26 16:26:59 +0000150 const Triple &TT = JTMB.getTargetTriple();
Lang Hames6a941342018-06-26 21:35:48 +0000151
Lang Hames23cb2e72018-10-23 23:01:39 +0000152 auto LCTMgr = createLocalLazyCallThroughManager(TT, *ES, ErrorAddr);
Lang Hamesd8048672018-09-26 05:08:29 +0000153 if (!LCTMgr)
154 return LCTMgr.takeError();
Lang Hames6a941342018-06-26 21:35:48 +0000155
156 auto ISMBuilder = createLocalIndirectStubsManagerBuilder(TT);
157 if (!ISMBuilder)
158 return make_error<StringError>(
159 std::string("No indirect stubs manager builder for ") + TT.str(),
160 inconvertibleErrorCode());
161
Lang Hamesf0a3fd882018-09-26 16:26:59 +0000162 if (NumCompileThreads == 0) {
163 auto TM = JTMB.createTargetMachine();
164 if (!TM)
165 return TM.takeError();
166 return std::unique_ptr<LLLazyJIT>(
167 new LLLazyJIT(std::move(ES), std::move(*TM), std::move(DL),
168 std::move(*LCTMgr), std::move(ISMBuilder)));
169 }
170
171 return std::unique_ptr<LLLazyJIT>(new LLLazyJIT(
172 std::move(ES), std::move(JTMB), std::move(DL), NumCompileThreads,
173 std::move(*LCTMgr), std::move(ISMBuilder)));
Lang Hames6a941342018-06-26 21:35:48 +0000174}
175
Lang Hames8d76c712018-09-26 01:24:12 +0000176Error LLLazyJIT::addLazyIRModule(JITDylib &JD, ThreadSafeModule TSM) {
177 assert(TSM && "Can not add null module");
Lang Hames6a941342018-06-26 21:35:48 +0000178
Lang Hames8d76c712018-09-26 01:24:12 +0000179 if (auto Err = applyDataLayout(*TSM.getModule()))
Lang Hames6a941342018-06-26 21:35:48 +0000180 return Err;
181
Lang Hames8d76c712018-09-26 01:24:12 +0000182 recordCtorDtors(*TSM.getModule());
Lang Hames6a941342018-06-26 21:35:48 +0000183
Lang Hames8b942742018-10-16 20:13:06 +0000184 return CODLayer.add(JD, std::move(TSM), ES->allocateVModule());
Lang Hames6a941342018-06-26 21:35:48 +0000185}
186
187LLLazyJIT::LLLazyJIT(
188 std::unique_ptr<ExecutionSession> ES, std::unique_ptr<TargetMachine> TM,
Lang Hamesd8048672018-09-26 05:08:29 +0000189 DataLayout DL, std::unique_ptr<LazyCallThroughManager> LCTMgr,
Lang Hames6a941342018-06-26 21:35:48 +0000190 std::function<std::unique_ptr<IndirectStubsManager>()> ISMBuilder)
191 : LLJIT(std::move(ES), std::move(TM), std::move(DL)),
Lang Hamesd8048672018-09-26 05:08:29 +0000192 LCTMgr(std::move(LCTMgr)), TransformLayer(*this->ES, CompileLayer),
193 CODLayer(*this->ES, TransformLayer, *this->LCTMgr,
194 std::move(ISMBuilder)) {}
Lang Hames6a941342018-06-26 21:35:48 +0000195
Lang Hamesf0a3fd882018-09-26 16:26:59 +0000196LLLazyJIT::LLLazyJIT(
197 std::unique_ptr<ExecutionSession> ES, JITTargetMachineBuilder JTMB,
198 DataLayout DL, unsigned NumCompileThreads,
199 std::unique_ptr<LazyCallThroughManager> LCTMgr,
200 std::function<std::unique_ptr<IndirectStubsManager>()> ISMBuilder)
201 : LLJIT(std::move(ES), std::move(JTMB), std::move(DL), NumCompileThreads),
202 LCTMgr(std::move(LCTMgr)), TransformLayer(*this->ES, CompileLayer),
203 CODLayer(*this->ES, TransformLayer, *this->LCTMgr,
Lang Hames8b813952018-09-27 21:13:07 +0000204 std::move(ISMBuilder)) {
205 CODLayer.setCloneToNewContextOnEmit(true);
206}
Lang Hamesf0a3fd882018-09-26 16:26:59 +0000207
Lang Hames6a941342018-06-26 21:35:48 +0000208} // End namespace orc.
209} // End namespace llvm.