LLVM  9.0.0svn
LLJIT.cpp
Go to the documentation of this file.
1 //===--------- LLJIT.cpp - An ORC-based JIT for compiling LLVM IR ---------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 
12 #include "llvm/IR/Mangler.h"
13 
14 namespace {
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
23  // IRCompileLayer::CompileFunction) are not moveable.
24  std::shared_ptr<llvm::TargetMachine> TM;
25  };
26 
27 } // end anonymous namespace
28 
29 namespace llvm {
30 namespace orc {
31 
32 LLJIT::~LLJIT() {
33  if (CompileThreads)
34  CompileThreads->wait();
35 }
36 
38 LLJIT::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 
50  return std::unique_ptr<LLJIT>(new LLJIT(llvm::make_unique<ExecutionSession>(),
51  std::move(JTMB), std::move(DL),
52  NumCompileThreads));
53 }
54 
55 Error LLJIT::defineAbsolute(StringRef Name, JITEvaluatedSymbol Sym) {
56  auto InternedName = ES->intern(Name);
57  SymbolMap Symbols({{InternedName, Sym}});
58  return Main.define(absoluteSymbols(std::move(Symbols)));
59 }
60 
61 Error LLJIT::addIRModule(JITDylib &JD, ThreadSafeModule TSM) {
62  assert(TSM && "Can not add null module");
63 
64  if (auto Err = applyDataLayout(*TSM.getModule()))
65  return Err;
66 
67  return CompileLayer.add(JD, std::move(TSM), ES->allocateVModule());
68 }
69 
70 Error LLJIT::addObjectFile(JITDylib &JD, std::unique_ptr<MemoryBuffer> Obj) {
71  assert(Obj && "Can not add null object");
72 
73  return ObjLinkingLayer.add(JD, std::move(Obj), ES->allocateVModule());
74 }
75 
76 Expected<JITEvaluatedSymbol> LLJIT::lookupLinkerMangled(JITDylib &JD,
77  StringRef Name) {
78  return ES->lookup(JITDylibSearchList({{&JD, true}}), ES->intern(Name));
79 }
80 
81 LLJIT::LLJIT(std::unique_ptr<ExecutionSession> ES,
82  std::unique_ptr<TargetMachine> TM, DataLayout DL)
83  : ES(std::move(ES)), Main(this->ES->getMainJITDylib()), DL(std::move(DL)),
84  ObjLinkingLayer(
85  *this->ES,
86  []() { return llvm::make_unique<SectionMemoryManager>(); }),
88  TMOwningSimpleCompiler(std::move(TM))),
90 
91 LLJIT::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)),
95  *this->ES,
96  []() { return llvm::make_unique<SectionMemoryManager>(); }),
98  ConcurrentIRCompiler(std::move(JTMB))),
100  assert(NumCompileThreads != 0 &&
101  "Multithreaded LLJIT instance can not be created with 0 threads");
102 
103  // Move modules to new contexts when they're emitted so that we can compile
104  // them in parallel.
106 
107  // Create a thread pool to compile on and set the execution session
108  // dispatcher to use the thread pool.
109  CompileThreads = llvm::make_unique<ThreadPool>(NumCompileThreads);
110  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  });
117 }
118 
119 std::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 
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",
136 
137  return Error::success();
138 }
139 
143 }
144 
147  JITTargetAddress ErrorAddr, unsigned NumCompileThreads) {
148  auto ES = llvm::make_unique<ExecutionSession>();
149 
150  const Triple &TT = JTMB.getTargetTriple();
151 
152  auto LCTMgr = createLocalLazyCallThroughManager(TT, *ES, ErrorAddr);
153  if (!LCTMgr)
154  return LCTMgr.takeError();
155 
156  auto ISMBuilder = createLocalIndirectStubsManagerBuilder(TT);
157  if (!ISMBuilder)
158  return make_error<StringError>(
159  std::string("No indirect stubs manager builder for ") + TT.str(),
161 
162  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)));
174 }
175 
177  assert(TSM && "Can not add null module");
178 
179  if (auto Err = applyDataLayout(*TSM.getModule()))
180  return Err;
181 
182  recordCtorDtors(*TSM.getModule());
183 
184  return CODLayer.add(JD, std::move(TSM), ES->allocateVModule());
185 }
186 
187 LLLazyJIT::LLLazyJIT(
188  std::unique_ptr<ExecutionSession> ES, std::unique_ptr<TargetMachine> TM,
189  DataLayout DL, std::unique_ptr<LazyCallThroughManager> LCTMgr,
190  std::function<std::unique_ptr<IndirectStubsManager>()> ISMBuilder)
191  : LLJIT(std::move(ES), std::move(TM), std::move(DL)),
192  LCTMgr(std::move(LCTMgr)), TransformLayer(*this->ES, CompileLayer),
193  CODLayer(*this->ES, TransformLayer, *this->LCTMgr,
194  std::move(ISMBuilder)) {}
195 
196 LLLazyJIT::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,
204  std::move(ISMBuilder)) {
205  CODLayer.setCloneToNewContextOnEmit(true);
206 }
207 
208 } // End namespace orc.
209 } // End namespace llvm.
A parsed version of the target data layout string in and methods for querying it. ...
Definition: DataLayout.h:110
IRCompileLayer CompileLayer
Definition: LLJIT.h:131
This class represents lattice values for constants.
Definition: AllocatorList.h:23
std::function< std::unique_ptr< IndirectStubsManager >)> createLocalIndirectStubsManagerBuilder(const Triple &T)
Create a local indriect stubs manager builder.
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:64
amdgpu Simplify well known AMD library false FunctionCallee Value const Twine & Name
void setDataLayout(StringRef Desc)
Set the data layout.
Definition: Module.cpp:363
JITDylib & Main
Definition: LLJIT.h:125
Error addLazyIRModule(JITDylib &JD, ThreadSafeModule M)
Add a module to be lazily compiled to JITDylib JD.
Definition: LLJIT.cpp:176
RTDyldObjectLinkingLayer ObjLinkingLayer
Definition: LLJIT.h:130
std::unique_ptr< AbsoluteSymbolsMaterializationUnit > absoluteSymbols(SymbolMap Symbols, VModuleKey K=VModuleKey())
Create an AbsoluteSymbolsMaterializationUnit with the given symbols.
Definition: Core.h:331
Definition: BitVector.h:937
const DataLayout & getDataLayout() const
Get the data layout for the module&#39;s target platform.
Definition: Module.cpp:369
A thread-safe version of SimpleCompiler.
Definition: CompileUtils.h:107
std::vector< std::pair< JITDylib *, bool > > JITDylibSearchList
A list of (JITDylib*, bool) pairs.
Definition: Core.h:57
Tagged union holding either a T or a Error.
Definition: CachePruning.h:22
Simple compile functor: Takes a single IR module and returns an ObjectFile.
Definition: CompileUtils.h:41
void add(iterator_range< CtorDtorIterator > CtorDtors)
CtorDtorRunner DtorRunner
Definition: LLJIT.h:133
iterator_range< CtorDtorIterator > getDestructors(const Module &M)
Create an iterator range over the entries of the llvm.global_ctors array.
uint64_t JITTargetAddress
Represents an address in the target process&#39;s address space.
Definition: JITSymbol.h:40
Module * getModule()
Get the module wrapped by this ThreadSafeModule.
void setCloneToNewContextOnEmit(bool CloneToNewContextOnEmit)
Sets the CloneToNewContextOnEmit flag (false by default).
Definition: Layer.h:42
std::string mangle(StringRef UnmangledName)
Definition: LLJIT.cpp:119
LLJIT(std::unique_ptr< ExecutionSession > ES, std::unique_ptr< TargetMachine > TM, DataLayout DL)
Create an LLJIT instance with a single compile thread.
Definition: LLJIT.cpp:81
An LLVM Module together with a shared ThreadSafeContext.
CtorDtorRunner CtorRunner
Definition: LLJIT.h:133
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:43
std::unique_ptr< ThreadPool > CompileThreads
Definition: LLJIT.h:128
std::unique_ptr< ExecutionSession > ES
Definition: LLJIT.h:124
static ErrorSuccess success()
Create a success value.
Definition: Error.h:326
void recordCtorDtors(Module &M)
Definition: LLJIT.cpp:140
Expected< std::unique_ptr< LazyCallThroughManager > > createLocalLazyCallThroughManager(const Triple &T, ExecutionSession &ES, JITTargetAddress ErrorHandlerAddr)
Create a LocalLazyCallThroughManager from the given triple and execution session. ...
bool isDefault() const
Test if the DataLayout was constructed from an empty string.
Definition: DataLayout.h:233
A pre-fabricated ORC JIT stack that can serve as an alternative to MCJIT.
Definition: LLJIT.h:31
An extended version of LLJIT that supports lazy function-at-a-time compilation of LLVM IR...
Definition: LLJIT.h:138
Represents a symbol that has been evaluated to an address already.
Definition: JITSymbol.h:208
Expected< std::unique_ptr< TargetMachine > > createTargetMachine()
Create a TargetMachine.
iterator_range< CtorDtorIterator > getConstructors(const Module &M)
Create an iterator range over the entries of the llvm.global_ctors array.
Error applyDataLayout(Module &M)
Definition: LLJIT.cpp:128
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:482
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
void getNameWithPrefix(raw_ostream &OS, const GlobalValue *GV, bool CannotUsePrivateLabel) const
Print the appropriate prefix and the specified global variable&#39;s name.
Definition: Mangler.cpp:111
print Print MemDeps of function
DataLayout DL
Definition: LLJIT.h:127
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
JITDylib & getMainJITDylib()
Returns a reference to the JITDylib representing the JIT&#39;d main program.
Definition: LLJIT.h:49
static Expected< std::unique_ptr< LLLazyJIT > > Create(JITTargetMachineBuilder JTMB, DataLayout DL, JITTargetAddress ErrorAddr, unsigned NumCompileThreads=0)
Create an LLLazyJIT instance.
Definition: LLJIT.cpp:146
A symbol table that supports asynchoronous symbol queries.
Definition: Core.h:495
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition: Error.cpp:77
A utility class for building TargetMachines for JITs.