LLVM  10.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 llvm {
16 namespace orc {
17 
19 
20  if (!JTMB) {
21  if (auto JTMBOrErr = JITTargetMachineBuilder::detectHost())
22  JTMB = std::move(*JTMBOrErr);
23  else
24  return JTMBOrErr.takeError();
25  }
26 
27  return Error::success();
28 }
29 
31  if (CompileThreads)
32  CompileThreads->wait();
33 }
34 
36  auto InternedName = ES->intern(Name);
37  SymbolMap Symbols({{InternedName, Sym}});
38  return Main.define(absoluteSymbols(std::move(Symbols)));
39 }
40 
42  assert(TSM && "Can not add null module");
43 
44  if (auto Err =
45  TSM.withModuleDo([&](Module &M) { return applyDataLayout(M); }))
46  return Err;
47 
48  return CompileLayer->add(JD, std::move(TSM), ES->allocateVModule());
49 }
50 
51 Error LLJIT::addObjectFile(JITDylib &JD, std::unique_ptr<MemoryBuffer> Obj) {
52  assert(Obj && "Can not add null object");
53 
54  return ObjLinkingLayer->add(JD, std::move(Obj), ES->allocateVModule());
55 }
56 
58  StringRef Name) {
59  return ES->lookup(JITDylibSearchList({{&JD, true}}), ES->intern(Name));
60 }
61 
62 std::unique_ptr<ObjectLayer>
64 
65  // If the config state provided an ObjectLinkingLayer factory then use it.
67  return S.CreateObjectLinkingLayer(ES, S.JTMB->getTargetTriple());
68 
69  // Otherwise default to creating an RTDyldObjectLinkingLayer that constructs
70  // a new SectionMemoryManager for each object.
71  auto GetMemMgr = []() { return std::make_unique<SectionMemoryManager>(); };
72  auto ObjLinkingLayer =
73  std::make_unique<RTDyldObjectLinkingLayer>(ES, std::move(GetMemMgr));
74 
75  if (S.JTMB->getTargetTriple().isOSBinFormatCOFF())
76  ObjLinkingLayer->setOverrideObjectFlagsWithResponsibilityFlags(true);
77 
78  // FIXME: Explicit conversion to std::unique_ptr<ObjectLayer> added to silence
79  // errors from some GCC / libstdc++ bots. Remove this conversion (i.e.
80  // just return ObjLinkingLayer) once those bots are upgraded.
81  return std::unique_ptr<ObjectLayer>(std::move(ObjLinkingLayer));
82 }
83 
87 
88  /// If there is a custom compile function creator set then use it.
90  return S.CreateCompileFunction(std::move(JTMB));
91 
92  // Otherwise default to creating a SimpleCompiler, or ConcurrentIRCompiler,
93  // depending on the number of threads requested.
94  if (S.NumCompileThreads > 0)
95  return ConcurrentIRCompiler(std::move(JTMB));
96 
97  auto TM = JTMB.createTargetMachine();
98  if (!TM)
99  return TM.takeError();
100 
101  return TMOwningSimpleCompiler(std::move(*TM));
102 }
103 
105  : ES(S.ES ? std::move(S.ES) : std::make_unique<ExecutionSession>()),
106  Main(this->ES->getMainJITDylib()), DL(""), CtorRunner(Main),
107  DtorRunner(Main) {
108 
109  ErrorAsOutParameter _(&Err);
110 
112 
113  if (auto DLOrErr = S.JTMB->getDefaultDataLayoutForTarget())
114  DL = std::move(*DLOrErr);
115  else {
116  Err = DLOrErr.takeError();
117  return;
118  }
119 
120  {
121  auto CompileFunction = createCompileFunction(S, std::move(*S.JTMB));
122  if (!CompileFunction) {
123  Err = CompileFunction.takeError();
124  return;
125  }
126  CompileLayer = std::make_unique<IRCompileLayer>(
127  *ES, *ObjLinkingLayer, std::move(*CompileFunction));
128  }
129 
130  if (S.NumCompileThreads > 0) {
131  CompileLayer->setCloneToNewContextOnEmit(true);
132  CompileThreads = std::make_unique<ThreadPool>(S.NumCompileThreads);
133  ES->setDispatchMaterialization(
134  [this](JITDylib &JD, std::unique_ptr<MaterializationUnit> MU) {
135  // FIXME: Switch to move capture once we have c++14.
136  auto SharedMU = std::shared_ptr<MaterializationUnit>(std::move(MU));
137  auto Work = [SharedMU, &JD]() { SharedMU->doMaterialize(JD); };
138  CompileThreads->async(std::move(Work));
139  });
140  }
141 }
142 
143 std::string LLJIT::mangle(StringRef UnmangledName) {
144  std::string MangledName;
145  {
146  raw_string_ostream MangledNameStream(MangledName);
147  Mangler::getNameWithPrefix(MangledNameStream, UnmangledName, DL);
148  }
149  return MangledName;
150 }
151 
153  if (M.getDataLayout().isDefault())
154  M.setDataLayout(DL);
155 
156  if (M.getDataLayout() != DL)
157  return make_error<StringError>(
158  "Added modules have incompatible data layouts",
160 
161  return Error::success();
162 }
163 
167 }
168 
171  return Err;
172  TT = JTMB->getTargetTriple();
173  return Error::success();
174 }
175 
177  assert(TSM && "Can not add null module");
178 
179  if (auto Err = TSM.withModuleDo([&](Module &M) -> Error {
180  if (auto Err = applyDataLayout(M))
181  return Err;
182 
183  recordCtorDtors(M);
184  return Error::success();
185  }))
186  return Err;
187 
188  return CODLayer->add(JD, std::move(TSM), ES->allocateVModule());
189 }
190 
191 LLLazyJIT::LLLazyJIT(LLLazyJITBuilderState &S, Error &Err) : LLJIT(S, Err) {
192 
193  // If LLJIT construction failed then bail out.
194  if (Err)
195  return;
196 
197  ErrorAsOutParameter _(&Err);
198 
199  /// Take/Create the lazy-compile callthrough manager.
200  if (S.LCTMgr)
201  LCTMgr = std::move(S.LCTMgr);
202  else {
203  if (auto LCTMgrOrErr = createLocalLazyCallThroughManager(
204  S.TT, *ES, S.LazyCompileFailureAddr))
205  LCTMgr = std::move(*LCTMgrOrErr);
206  else {
207  Err = LCTMgrOrErr.takeError();
208  return;
209  }
210  }
211 
212  // Take/Create the indirect stubs manager builder.
213  auto ISMBuilder = std::move(S.ISMBuilder);
214 
215  // If none was provided, try to build one.
216  if (!ISMBuilder)
218 
219  // No luck. Bail out.
220  if (!ISMBuilder) {
221  Err = make_error<StringError>("Could not construct "
222  "IndirectStubsManagerBuilder for target " +
223  S.TT.str(),
225  return;
226  }
227 
228  // Create the transform layer.
229  TransformLayer = std::make_unique<IRTransformLayer>(*ES, *CompileLayer);
230 
231  // Create the COD layer.
232  CODLayer = std::make_unique<CompileOnDemandLayer>(
233  *ES, *TransformLayer, *LCTMgr, std::move(ISMBuilder));
234 
235  if (S.NumCompileThreads > 0)
236  CODLayer->setCloneToNewContextOnEmit(true);
237 }
238 
239 } // End namespace orc.
240 } // End namespace llvm.
A SimpleCompiler that owns its TargetMachine.
Definition: CompileUtils.h:60
static Expected< IRCompileLayer::CompileFunction > createCompileFunction(LLJITBuilderState &S, JITTargetMachineBuilder JTMB)
Definition: LLJIT.cpp:85
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.
Error defineAbsolute(StringRef Name, JITEvaluatedSymbol Address)
Convenience method for defining an absolute symbol.
Definition: LLJIT.cpp:35
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:104
auto withModuleDo(Func &&F) -> decltype(F(std::declval< Module &>()))
Locks the associated ThreadSafeContext and calls the given function on the contained Module...
std::unique_ptr< ExecutionSession > ES
Definition: LLJIT.h:194
Error addIRModule(JITDylib &JD, ThreadSafeModule TSM)
Adds an IR module to the given JITDylib.
Definition: LLJIT.cpp:41
void setDataLayout(StringRef Desc)
Set the data layout.
Definition: Module.cpp:363
Error addLazyIRModule(JITDylib &JD, ThreadSafeModule M)
Add a module to be lazily compiled to JITDylib JD.
Definition: LLJIT.cpp:176
std::unique_ptr< AbsoluteSymbolsMaterializationUnit > absoluteSymbols(SymbolMap Symbols, VModuleKey K=VModuleKey())
Create an AbsoluteSymbolsMaterializationUnit with the given symbols.
Definition: Core.h:362
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:76
std::vector< std::pair< JITDylib *, bool > > JITDylibSearchList
A list of (JITDylib*, bool) pairs.
Definition: Core.h:59
Tagged union holding either a T or a Error.
Definition: yaml2obj.h:21
void add(iterator_range< CtorDtorIterator > CtorDtors)
CtorDtorRunner DtorRunner
Definition: LLJIT.h:145
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:365
static Expected< JITTargetMachineBuilder > detectHost()
Create a JITTargetMachineBuilder for the host system.
std::string mangle(StringRef UnmangledName)
Definition: LLJIT.cpp:143
std::unique_ptr< IRCompileLayer > CompileLayer
Definition: LLJIT.h:143
CompileFunctionCreator CreateCompileFunction
Definition: LLJIT.h:197
An LLVM Module together with a shared ThreadSafeContext.
CtorDtorRunner CtorRunner
Definition: LLJIT.h:145
ObjectLinkingLayerCreator CreateObjectLinkingLayer
Definition: LLJIT.h:196
std::unique_ptr< ThreadPool > CompileThreads
Definition: LLJIT.h:140
std::unique_ptr< ExecutionSession > ES
Definition: LLJIT.h:136
static ErrorSuccess success()
Create a success value.
Definition: Error.h:326
void recordCtorDtors(Module &M)
Definition: LLJIT.cpp:164
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:246
An ExecutionSession represents a running JIT program.
Definition: Core.h:761
std::unique_ptr< ObjectLayer > ObjLinkingLayer
Definition: LLJIT.h:142
Represents a symbol that has been evaluated to an address already.
Definition: JITSymbol.h:190
Helper for Errors used as out-parameters.
Definition: Error.h:1035
Expected< std::unique_ptr< TargetMachine > > createTargetMachine()
Create a TargetMachine.
Expected< JITEvaluatedSymbol > lookupLinkerMangled(JITDylib &JD, StringRef Name)
Look up a symbol in JITDylib JD by the symbol&#39;s linker-mangled name (to look up symbols based on thei...
Definition: LLJIT.cpp:57
Error addObjectFile(JITDylib &JD, std::unique_ptr< MemoryBuffer > Obj)
Adds an object file to the given JITDylib.
Definition: LLJIT.cpp:51
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:152
~LLJIT()
Destruct this instance.
Definition: LLJIT.cpp:30
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
std::unique_ptr< LazyCallThroughManager > LCTMgr
Definition: LLJIT.h:287
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:503
Error prepareForConstruction()
Called prior to JIT class construcion to fix up defaults.
Definition: LLJIT.cpp:18
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
JITTargetAddress LazyCompileFailureAddr
Definition: LLJIT.h:286
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:139
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:63
Optional< JITTargetMachineBuilder > JTMB
Definition: LLJIT.h:195
IndirectStubsManagerBuilderFunction ISMBuilder
Definition: LLJIT.h:288
#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
A utility class for building TargetMachines for JITs.