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 
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 Error LLJITBuilderState::prepareForConstruction() {
34 
35  if (!JTMB) {
36  if (auto JTMBOrErr = JITTargetMachineBuilder::detectHost())
37  JTMB = std::move(*JTMBOrErr);
38  else
39  return JTMBOrErr.takeError();
40  }
41 
42  return Error::success();
43 }
44 
45 LLJIT::~LLJIT() {
46  if (CompileThreads)
47  CompileThreads->wait();
48 }
49 
50 Error LLJIT::defineAbsolute(StringRef Name, JITEvaluatedSymbol Sym) {
51  auto InternedName = ES->intern(Name);
52  SymbolMap Symbols({{InternedName, Sym}});
53  return Main.define(absoluteSymbols(std::move(Symbols)));
54 }
55 
56 Error LLJIT::addIRModule(JITDylib &JD, ThreadSafeModule TSM) {
57  assert(TSM && "Can not add null module");
58 
59  if (auto Err = applyDataLayout(*TSM.getModule()))
60  return Err;
61 
62  return CompileLayer->add(JD, std::move(TSM), ES->allocateVModule());
63 }
64 
65 Error LLJIT::addObjectFile(JITDylib &JD, std::unique_ptr<MemoryBuffer> Obj) {
66  assert(Obj && "Can not add null object");
67 
68  return ObjLinkingLayer->add(JD, std::move(Obj), ES->allocateVModule());
69 }
70 
71 Expected<JITEvaluatedSymbol> LLJIT::lookupLinkerMangled(JITDylib &JD,
72  StringRef Name) {
73  return ES->lookup(JITDylibSearchList({{&JD, true}}), ES->intern(Name));
74 }
75 
76 std::unique_ptr<ObjectLayer>
77 LLJIT::createObjectLinkingLayer(LLJITBuilderState &S, ExecutionSession &ES) {
78 
79  // If the config state provided an ObjectLinkingLayer factory then use it.
81  return S.CreateObjectLinkingLayer(ES);
82 
83  // Otherwise default to creating an RTDyldObjectLinkingLayer that constructs
84  // a new SectionMemoryManager for each object.
85  auto GetMemMgr = []() { return llvm::make_unique<SectionMemoryManager>(); };
86  return llvm::make_unique<RTDyldObjectLinkingLayer>(ES, std::move(GetMemMgr));
87 }
88 
89 LLJIT::LLJIT(LLJITBuilderState &S, Error &Err)
90  : ES(S.ES ? std::move(S.ES) : llvm::make_unique<ExecutionSession>()),
91  Main(this->ES->getMainJITDylib()), DL(""), CtorRunner(Main),
92  DtorRunner(Main) {
93 
94  ErrorAsOutParameter _(&Err);
95 
97 
98  if (S.NumCompileThreads > 0) {
99 
100  // Configure multi-threaded.
101 
102  if (auto DLOrErr = S.JTMB->getDefaultDataLayoutForTarget())
103  DL = std::move(*DLOrErr);
104  else {
105  Err = DLOrErr.takeError();
106  return;
107  }
108 
109  {
110  auto TmpCompileLayer = llvm::make_unique<IRCompileLayer>(
111  *ES, *ObjLinkingLayer, ConcurrentIRCompiler(std::move(*S.JTMB)));
112 
113  TmpCompileLayer->setCloneToNewContextOnEmit(true);
114  CompileLayer = std::move(TmpCompileLayer);
115  }
116 
117  CompileThreads = llvm::make_unique<ThreadPool>(S.NumCompileThreads);
118  ES->setDispatchMaterialization(
119  [this](JITDylib &JD, std::unique_ptr<MaterializationUnit> MU) {
120  // FIXME: Switch to move capture once we have c++14.
121  auto SharedMU = std::shared_ptr<MaterializationUnit>(std::move(MU));
122  auto Work = [SharedMU, &JD]() { SharedMU->doMaterialize(JD); };
123  CompileThreads->async(std::move(Work));
124  });
125  } else {
126 
127  // Configure single-threaded.
128 
129  auto TM = S.JTMB->createTargetMachine();
130  if (!TM) {
131  Err = TM.takeError();
132  return;
133  }
134 
135  DL = (*TM)->createDataLayout();
136 
137  CompileLayer = llvm::make_unique<IRCompileLayer>(
138  *ES, *ObjLinkingLayer, TMOwningSimpleCompiler(std::move(*TM)));
139  }
140 }
141 
142 std::string LLJIT::mangle(StringRef UnmangledName) {
143  std::string MangledName;
144  {
145  raw_string_ostream MangledNameStream(MangledName);
146  Mangler::getNameWithPrefix(MangledNameStream, UnmangledName, DL);
147  }
148  return MangledName;
149 }
150 
152  if (M.getDataLayout().isDefault())
153  M.setDataLayout(DL);
154 
155  if (M.getDataLayout() != DL)
156  return make_error<StringError>(
157  "Added modules have incompatible data layouts",
159 
160  return Error::success();
161 }
162 
166 }
167 
170  return Err;
171  TT = JTMB->getTargetTriple();
172  return Error::success();
173 }
174 
176  assert(TSM && "Can not add null module");
177 
178  if (auto Err = applyDataLayout(*TSM.getModule()))
179  return Err;
180 
181  recordCtorDtors(*TSM.getModule());
182 
183  return CODLayer->add(JD, std::move(TSM), ES->allocateVModule());
184 }
185 
186 LLLazyJIT::LLLazyJIT(LLLazyJITBuilderState &S, Error &Err) : LLJIT(S, Err) {
187 
188  // If LLJIT construction failed then bail out.
189  if (Err)
190  return;
191 
192  ErrorAsOutParameter _(&Err);
193 
194  /// Take/Create the lazy-compile callthrough manager.
195  if (S.LCTMgr)
196  LCTMgr = std::move(S.LCTMgr);
197  else {
198  if (auto LCTMgrOrErr = createLocalLazyCallThroughManager(
199  S.TT, *ES, S.LazyCompileFailureAddr))
200  LCTMgr = std::move(*LCTMgrOrErr);
201  else {
202  Err = LCTMgrOrErr.takeError();
203  return;
204  }
205  }
206 
207  // Take/Create the indirect stubs manager builder.
208  auto ISMBuilder = std::move(S.ISMBuilder);
209 
210  // If none was provided, try to build one.
211  if (!ISMBuilder)
213 
214  // No luck. Bail out.
215  if (!ISMBuilder) {
216  Err = make_error<StringError>("Could not construct "
217  "IndirectStubsManagerBuilder for target " +
218  S.TT.str(),
220  return;
221  }
222 
223  // Create the transform layer.
224  TransformLayer = llvm::make_unique<IRTransformLayer>(*ES, *CompileLayer);
225 
226  // Create the COD layer.
227  CODLayer = llvm::make_unique<CompileOnDemandLayer>(
228  *ES, *TransformLayer, *LCTMgr, std::move(ISMBuilder));
229 
230  if (S.NumCompileThreads > 0)
231  CODLayer->setCloneToNewContextOnEmit(true);
232 }
233 
234 } // End namespace orc.
235 } // End namespace llvm.
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:65
amdgpu Simplify well known AMD library false FunctionCallee Value const Twine & Name
LLJIT(LLJITBuilderState &S, Error &Err)
Create an LLJIT instance with a single compile thread.
Definition: LLJIT.cpp:89
void setDataLayout(StringRef Desc)
Set the data layout.
Definition: Module.cpp:363
std::enable_if<!std::is_array< T >::value, std::unique_ptr< T > >::type make_unique(Args &&... args)
Constructs a new T() with the given args and returns a unique_ptr<T> which owns the object...
Definition: STLExtras.h:1403
Error addLazyIRModule(JITDylib &JD, ThreadSafeModule M)
Add a module to be lazily compiled to JITDylib JD.
Definition: LLJIT.cpp:175
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:59
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:33
void add(iterator_range< CtorDtorIterator > CtorDtors)
CtorDtorRunner DtorRunner
Definition: LLJIT.h:131
CreateObjectLinkingLayerFunction CreateObjectLinkingLayer
Definition: LLJIT.h:178
iterator_range< CtorDtorIterator > getDestructors(const Module &M)
Create an iterator range over the entries of the llvm.global_ctors array.
const std::string & str() const
Definition: Triple.h:361
Module * getModule()
Get the module wrapped by this ThreadSafeModule.
std::string mangle(StringRef UnmangledName)
Definition: LLJIT.cpp:142
std::unique_ptr< IRCompileLayer > CompileLayer
Definition: LLJIT.h:129
An LLVM Module together with a shared ThreadSafeContext.
CtorDtorRunner CtorRunner
Definition: LLJIT.h:131
std::unique_ptr< ThreadPool > CompileThreads
Definition: LLJIT.h:126
std::unique_ptr< ExecutionSession > ES
Definition: LLJIT.h:122
static ErrorSuccess success()
Create a success value.
Definition: Error.h:326
void recordCtorDtors(Module &M)
Definition: LLJIT.cpp:163
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:245
An ExecutionSession represents a running JIT program.
Definition: Core.h:696
std::unique_ptr< ObjectLayer > ObjLinkingLayer
Definition: LLJIT.h:128
Represents a symbol that has been evaluated to an address already.
Definition: JITSymbol.h:208
Helper for Errors used as out-parameters.
Definition: Error.h:1021
success
Parameters (see the expansion example below): (the builder, addr, loaded, new_val, ordering, /* OUT.
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:151
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
std::unique_ptr< LazyCallThroughManager > LCTMgr
Definition: LLJIT.h:257
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:482
Error prepareForConstruction()
Called prior to JIT class construcion to fix up defaults.
Definition: LLJIT.cpp:33
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
JITTargetAddress LazyCompileFailureAddr
Definition: LLJIT.h:256
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
DataLayout DL
Definition: LLJIT.h:125
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
static std::unique_ptr< ObjectLayer > createObjectLinkingLayer(LLJITBuilderState &S, ExecutionSession &ES)
Definition: LLJIT.cpp:77
Optional< JITTargetMachineBuilder > JTMB
Definition: LLJIT.h:177
IndirectStubsManagerBuilderFunction ISMBuilder
Definition: LLJIT.h:258
#define _
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