LLVM  12.0.0git
Layer.cpp
Go to the documentation of this file.
1 //===-------------------- Layer.cpp - Layer interfaces --------------------===//
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 
10 
13 #include "llvm/IR/Constants.h"
14 #include "llvm/Object/MachO.h"
15 #include "llvm/Object/ObjectFile.h"
16 #include "llvm/Support/Debug.h"
17 
18 #define DEBUG_TYPE "orc"
19 
20 namespace llvm {
21 namespace orc {
22 
24 
26  return JD.define(std::make_unique<BasicIRLayerMaterializationUnit>(
27  *this, *getManglingOptions(), std::move(TSM), std::move(K)));
28 }
29 
33  : MaterializationUnit(SymbolFlagsMap(), nullptr, std::move(K)),
34  TSM(std::move(TSM)) {
35 
36  assert(this->TSM && "Module must not be null");
37 
38  MangleAndInterner Mangle(ES, this->TSM.getModuleUnlocked()->getDataLayout());
39  this->TSM.withModuleDo([&](Module &M) {
40  for (auto &G : M.global_values()) {
41  // Skip globals that don't generate symbols.
42 
43  if (!G.hasName() || G.isDeclaration() || G.hasLocalLinkage() ||
44  G.hasAvailableExternallyLinkage() || G.hasAppendingLinkage())
45  continue;
46 
47  // thread locals generate different symbols depending on whether or not
48  // emulated TLS is enabled.
49  if (G.isThreadLocal() && MO.EmulatedTLS) {
50  auto &GV = cast<GlobalVariable>(G);
51 
52  auto Flags = JITSymbolFlags::fromGlobalValue(GV);
53 
54  auto EmuTLSV = Mangle(("__emutls_v." + GV.getName()).str());
55  SymbolFlags[EmuTLSV] = Flags;
56  SymbolToDefinition[EmuTLSV] = &GV;
57 
58  // If this GV has a non-zero initializer we'll need to emit an
59  // __emutls.t symbol too.
60  if (GV.hasInitializer()) {
61  const auto *InitVal = GV.getInitializer();
62 
63  // Skip zero-initializers.
64  if (isa<ConstantAggregateZero>(InitVal))
65  continue;
66  const auto *InitIntValue = dyn_cast<ConstantInt>(InitVal);
67  if (InitIntValue && InitIntValue->isZero())
68  continue;
69 
70  auto EmuTLST = Mangle(("__emutls_t." + GV.getName()).str());
71  SymbolFlags[EmuTLST] = Flags;
72  }
73  continue;
74  }
75 
76  // Otherwise we just need a normal linker mangling.
77  auto MangledName = Mangle(G.getName());
79  SymbolToDefinition[MangledName] = &G;
80  }
81 
82  // If we need an init symbol for this module then create one.
83  if (!llvm::empty(getStaticInitGVs(M))) {
84  size_t Counter = 0;
85 
86  while (true) {
87  std::string InitSymbolName;
88  raw_string_ostream(InitSymbolName)
89  << "$." << M.getModuleIdentifier() << ".__inits." << Counter++;
90  InitSymbol = ES.intern(InitSymbolName);
92  continue;
95  break;
96  }
97  }
98  });
99 }
100 
104  : MaterializationUnit(std::move(SymbolFlags), std::move(InitSymbol),
105  std::move(K)),
106  TSM(std::move(TSM)), SymbolToDefinition(std::move(SymbolToDefinition)) {}
107 
109  if (TSM)
110  return TSM.withModuleDo(
111  [](const Module &M) -> StringRef { return M.getModuleIdentifier(); });
112  return "<null module>";
113 }
114 
115 void IRMaterializationUnit::discard(const JITDylib &JD,
116  const SymbolStringPtr &Name) {
118  dbgs() << "In " << JD.getName() << " discarding " << *Name << " from MU@"
119  << this << " (" << getName() << ")\n";
120  }););
121 
122  auto I = SymbolToDefinition.find(Name);
123  assert(I != SymbolToDefinition.end() &&
124  "Symbol not provided by this MU, or previously discarded");
125  assert(!I->second->isDeclaration() &&
126  "Discard should only apply to definitions");
127  I->second->setLinkage(GlobalValue::AvailableExternallyLinkage);
128  SymbolToDefinition.erase(I);
129 }
130 
133  VModuleKey K)
134  : IRMaterializationUnit(L.getExecutionSession(), MO, std::move(TSM),
135  std::move(K)),
136  L(L), K(std::move(K)) {}
137 
138 void BasicIRLayerMaterializationUnit::materialize(
140 
141  // Throw away the SymbolToDefinition map: it's not usable after we hand
142  // off the module.
143  SymbolToDefinition.clear();
144 
145  // If cloneToNewContextOnEmit is set, clone the module now.
148 
149 #ifndef NDEBUG
150  auto &ES = R.getTargetJITDylib().getExecutionSession();
151  auto &N = R.getTargetJITDylib().getName();
152 #endif // NDEBUG
153 
154  LLVM_DEBUG(ES.runSessionLocked(
155  [&]() { dbgs() << "Emitting, for " << N << ", " << *this << "\n"; }););
156  L.emit(std::move(R), std::move(TSM));
157  LLVM_DEBUG(ES.runSessionLocked([&]() {
158  dbgs() << "Finished emitting, for " << N << ", " << *this << "\n";
159  }););
160 }
161 
163 
165 
166 Error ObjectLayer::add(JITDylib &JD, std::unique_ptr<MemoryBuffer> O,
167  VModuleKey K) {
168  auto ObjMU = BasicObjectLayerMaterializationUnit::Create(*this, std::move(K),
169  std::move(O));
170  if (!ObjMU)
171  return ObjMU.takeError();
172  return JD.define(std::move(*ObjMU));
173 }
174 
177  std::unique_ptr<MemoryBuffer> O) {
178  auto ObjSymInfo =
179  getObjectSymbolInfo(L.getExecutionSession(), O->getMemBufferRef());
180 
181  if (!ObjSymInfo)
182  return ObjSymInfo.takeError();
183 
184  auto &SymbolFlags = ObjSymInfo->first;
185  auto &InitSymbol = ObjSymInfo->second;
186 
187  return std::unique_ptr<BasicObjectLayerMaterializationUnit>(
189  L, K, std::move(O), std::move(SymbolFlags), std::move(InitSymbol)));
190 }
191 
193  ObjectLayer &L, VModuleKey K, std::unique_ptr<MemoryBuffer> O,
195  : MaterializationUnit(std::move(SymbolFlags), std::move(InitSymbol),
196  std::move(K)),
197  L(L), O(std::move(O)) {}
198 
200  if (O)
201  return O->getBufferIdentifier();
202  return "<null object>";
203 }
204 
205 void BasicObjectLayerMaterializationUnit::materialize(
207  L.emit(std::move(R), std::move(O));
208 }
209 
210 void BasicObjectLayerMaterializationUnit::discard(const JITDylib &JD,
211  const SymbolStringPtr &Name) {
212  // This is a no-op for object files: Having removed 'Name' from SymbolFlags
213  // the symbol will be dead-stripped by the JIT linker.
214 }
215 
216 } // End namespace orc.
217 } // End namespace llvm.
bool getCloneToNewContextOnEmit() const
Returns the current value of the CloneToNewContextOnEmit flag.
Definition: Layer.h:95
iterator_range< StaticInitGVIterator > getStaticInitGVs(Module &M)
Create an iterator range over the GlobalValues that contribute to static initialization.
LLVM_NODISCARD std::enable_if_t< !is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type > dyn_cast(const Y &Val)
Definition: Casting.h:334
static JITSymbolFlags fromGlobalValue(const GlobalValue &GV)
Construct a JITSymbolFlags value based on the flags of the given global value.
Definition: JITSymbol.cpp:22
This class represents lattice values for constants.
Definition: AllocatorList.h:23
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:67
amdgpu Simplify well known AMD library false FunctionCallee Value const Twine & Name
StringRef getName() const override
Return the ModuleIdentifier as the name for this MaterializationUnit.
Definition: Layer.cpp:108
SymbolNameToDefinitionMap SymbolToDefinition
Definition: Layer.h:56
Available for inspection, not emission.
Definition: GlobalValue.h:49
StringRef getName() const override
Return the buffer&#39;s identifier as the name for this MaterializationUnit.
Definition: Layer.cpp:199
Materializes the given object file (represented by a MemoryBuffer instance) by calling &#39;emit&#39; on the ...
Definition: Layer.h:151
Definition: BitVector.h:959
SymbolStringPtr intern(StringRef SymName)
Add a symbol name to the SymbolStringPool and return a pointer to it.
Definition: Core.h:1107
const DataLayout & getDataLayout() const
Get the data layout for the module&#39;s target platform.
Definition: Module.cpp:397
Expected< std::pair< SymbolFlagsMap, SymbolStringPtr > > getObjectSymbolInfo(ExecutionSession &ES, MemoryBufferRef ObjBuffer)
Returns a SymbolFlagsMap for the object file represented by the given buffer, or an error if the buff...
Definition: Mangling.cpp:86
SymbolFlagsMap SymbolFlags
Definition: Core.h:590
Error define(std::unique_ptr< MaterializationUnitType > &&MU)
Define all symbols provided by the materialization unit to be part of this JITDylib.
Definition: Core.h:1311
SymbolFlags
Symbol flags.
Definition: Symbol.h:25
Mangles symbol names then uniques them in the context of an ExecutionSession.
Definition: Mangling.h:26
std::map< SymbolStringPtr, GlobalValue * > SymbolNameToDefinitionMap
Definition: Layer.h:31
Tagged union holding either a T or a Error.
Definition: APFloat.h:42
virtual Error add(JITDylib &JD, ThreadSafeModule TSM, VModuleKey K=VModuleKey())
Adds a MaterializationUnit representing the given IR to the given JITDylib.
Definition: Layer.cpp:25
Tracks responsibility for materialization, and mediates interactions between MaterializationUnits and...
Definition: Core.h:410
IRMaterializationUnit is a convenient base class for MaterializationUnits wrapping LLVM IR...
Definition: Layer.h:29
ExecutionSession & getExecutionSession()
Returns the execution session for this layer.
Definition: Layer.h:134
JITDylib & getTargetJITDylib() const
Returns the target JITDylib that these symbols are being materialized into.
Definition: Core.h:424
ExecutionSession & getExecutionSession() const
Get a reference to the ExecutionSession for this JITDylib.
Definition: Core.h:814
Pointer to a pooled string representing a symbol name.
virtual void emit(MaterializationResponsibility R, ThreadSafeModule TSM)=0
Emit should materialize the given IR.
ThreadSafeModule TSM
Definition: Layer.h:55
ObjectLayer(ExecutionSession &ES)
Definition: Layer.cpp:162
This file contains the declarations for the subclasses of Constant, which represent the different fla...
BasicIRLayerMaterializationUnit(IRLayer &L, const IRSymbolMapper::ManglingOptions &MO, ThreadSafeModule TSM, VModuleKey K)
Definition: Layer.cpp:131
An LLVM Module together with a shared ThreadSafeContext.
decltype(auto) withModuleDo(Func &&F)
Locks the associated ThreadSafeContext and calls the given function on the contained Module...
const std::string & getModuleIdentifier() const
Get the module identifier which is, essentially, the name of the module.
Definition: Module.h:219
virtual void emit(MaterializationResponsibility R, std::unique_ptr< MemoryBuffer > O)=0
Emit should materialize the given IR.
virtual Error add(JITDylib &JD, std::unique_ptr< MemoryBuffer > O, VModuleKey K=VModuleKey())
Adds a MaterializationUnit representing the given IR to the given JITDylib.
Definition: Layer.cpp:166
constexpr bool empty(const T &RangeOrContainer)
Test whether RangeOrContainer is empty. Similar to C++17 std::empty.
Definition: STLExtras.h:266
Interface for layers that accept LLVM IR.
Definition: Layer.h:66
A MaterializationUnit represents a set of symbol definitions that can be materialized as a group...
Definition: Core.h:552
This is the shared class of boolean and integer constants.
Definition: Constants.h:77
SymbolStringPtr InitSymbol
Definition: Core.h:591
const DataFlowGraph & G
Definition: RDFGraph.cpp:202
IRMaterializationUnit(ExecutionSession &ES, const IRSymbolMapper::ManglingOptions &MO, ThreadSafeModule TSM, VModuleKey K)
Create an IRMaterializationLayer.
Definition: Layer.cpp:30
An ExecutionSession represents a running JIT program.
Definition: Core.h:1088
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
const IRSymbolMapper::ManglingOptions *& getManglingOptions() const
Get the mangling options for this layer.
Definition: Layer.h:77
Module * getModuleUnlocked()
Get a raw pointer to the contained module without locking the context.
static Expected< std::unique_ptr< BasicObjectLayerMaterializationUnit > > Create(ObjectLayer &L, VModuleKey K, std::unique_ptr< MemoryBuffer > O)
Definition: Layer.cpp:176
uint8_t uint64_t VModuleKey
VModuleKey provides a unique identifier (allocated and managed by ExecutionSessions) for a module add...
Definition: Core.h:40
#define I(x, y, z)
Definition: MD5.cpp:59
#define N
const std::string & getName() const
Get the name for this JITDylib.
Definition: Core.h:811
ThreadSafeModule cloneToNewContext(ThreadSafeModule &TSMW, GVPredicate ShouldCloneDef=GVPredicate(), GVModifier UpdateClonedDefSource=GVModifier())
Clones the given module on to a new context.
virtual ~ObjectLayer()
Definition: Layer.cpp:164
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Definition: DenseMap.h:145
BasicObjectLayerMaterializationUnit(ObjectLayer &L, VModuleKey K, std::unique_ptr< MemoryBuffer > O, SymbolFlagsMap SymbolFlags, SymbolStringPtr InitSymbol)
Definition: Layer.cpp:192
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:521
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
virtual ~IRLayer()
Definition: Layer.cpp:23
Interface for Layers that accept object files.
Definition: Layer.h:128
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
decltype(auto) runSessionLocked(Func &&F)
Run the given lambda with the session mutex locked.
Definition: Core.h:1120
#define LLVM_DEBUG(X)
Definition: Debug.h:122
A symbol table that supports asynchoronous symbol queries.
Definition: Core.h:779
iterator_range< global_value_iterator > global_values()
Definition: Module.cpp:420