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