LLVM  13.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  assert(RT && "RT can not be null");
27  auto &JD = RT->getJITDylib();
28  return JD.define(std::make_unique<BasicIRLayerMaterializationUnit>(
29  *this, *getManglingOptions(), std::move(TSM)),
30  std::move(RT));
31 }
32 
35  ThreadSafeModule TSM)
36  : MaterializationUnit(SymbolFlagsMap(), nullptr), TSM(std::move(TSM)) {
37 
38  assert(this->TSM && "Module must not be null");
39 
40  MangleAndInterner Mangle(ES, this->TSM.getModuleUnlocked()->getDataLayout());
41  this->TSM.withModuleDo([&](Module &M) {
42  for (auto &G : M.global_values()) {
43  // Skip globals that don't generate symbols.
44 
45  if (!G.hasName() || G.isDeclaration() || G.hasLocalLinkage() ||
46  G.hasAvailableExternallyLinkage() || G.hasAppendingLinkage())
47  continue;
48 
49  // thread locals generate different symbols depending on whether or not
50  // emulated TLS is enabled.
51  if (G.isThreadLocal() && MO.EmulatedTLS) {
52  auto &GV = cast<GlobalVariable>(G);
53 
54  auto Flags = JITSymbolFlags::fromGlobalValue(GV);
55 
56  auto EmuTLSV = Mangle(("__emutls_v." + GV.getName()).str());
57  SymbolFlags[EmuTLSV] = Flags;
58  SymbolToDefinition[EmuTLSV] = &GV;
59 
60  // If this GV has a non-zero initializer we'll need to emit an
61  // __emutls.t symbol too.
62  if (GV.hasInitializer()) {
63  const auto *InitVal = GV.getInitializer();
64 
65  // Skip zero-initializers.
66  if (isa<ConstantAggregateZero>(InitVal))
67  continue;
68  const auto *InitIntValue = dyn_cast<ConstantInt>(InitVal);
69  if (InitIntValue && InitIntValue->isZero())
70  continue;
71 
72  auto EmuTLST = Mangle(("__emutls_t." + GV.getName()).str());
73  SymbolFlags[EmuTLST] = Flags;
74  }
75  continue;
76  }
77 
78  // Otherwise we just need a normal linker mangling.
79  auto MangledName = Mangle(G.getName());
81  SymbolToDefinition[MangledName] = &G;
82  }
83 
84  // If we need an init symbol for this module then create one.
86  size_t Counter = 0;
87 
88  do {
89  std::string InitSymbolName;
90  raw_string_ostream(InitSymbolName)
91  << "$." << M.getModuleIdentifier() << ".__inits." << Counter++;
92  InitSymbol = ES.intern(InitSymbolName);
93  } while (SymbolFlags.count(InitSymbol));
94 
96  }
97  });
98 }
99 
100 IRMaterializationUnit::IRMaterializationUnit(
102  SymbolStringPtr InitSymbol, SymbolNameToDefinitionMap SymbolToDefinition)
103  : MaterializationUnit(std::move(SymbolFlags), std::move(InitSymbol)),
104  TSM(std::move(TSM)), SymbolToDefinition(std::move(SymbolToDefinition)) {}
105 
107  if (TSM)
108  return TSM.withModuleDo(
109  [](const Module &M) -> StringRef { return M.getModuleIdentifier(); });
110  return "<null module>";
111 }
112 
113 void IRMaterializationUnit::discard(const JITDylib &JD,
114  const SymbolStringPtr &Name) {
116  dbgs() << "In " << JD.getName() << " discarding " << *Name << " from MU@"
117  << this << " (" << getName() << ")\n";
118  }););
119 
120  auto I = SymbolToDefinition.find(Name);
121  assert(I != SymbolToDefinition.end() &&
122  "Symbol not provided by this MU, or previously discarded");
123  assert(!I->second->isDeclaration() &&
124  "Discard should only apply to definitions");
125  I->second->setLinkage(GlobalValue::AvailableExternallyLinkage);
126  SymbolToDefinition.erase(I);
127 }
128 
131  : IRMaterializationUnit(L.getExecutionSession(), MO, std::move(TSM)), L(L) {
132 }
133 
134 void BasicIRLayerMaterializationUnit::materialize(
135  std::unique_ptr<MaterializationResponsibility> R) {
136 
137  // Throw away the SymbolToDefinition map: it's not usable after we hand
138  // off the module.
139  SymbolToDefinition.clear();
140 
141  // If cloneToNewContextOnEmit is set, clone the module now.
144 
145 #ifndef NDEBUG
146  auto &ES = R->getTargetJITDylib().getExecutionSession();
147  auto &N = R->getTargetJITDylib().getName();
148 #endif // NDEBUG
149 
150  LLVM_DEBUG(ES.runSessionLocked(
151  [&]() { dbgs() << "Emitting, for " << N << ", " << *this << "\n"; }););
152  L.emit(std::move(R), std::move(TSM));
153  LLVM_DEBUG(ES.runSessionLocked([&]() {
154  dbgs() << "Finished emitting, for " << N << ", " << *this << "\n";
155  }););
156 }
157 
158 char ObjectLayer::ID;
159 
161 
163 
164 Error ObjectLayer::add(ResourceTrackerSP RT, std::unique_ptr<MemoryBuffer> O) {
165  assert(RT && "RT can not be null");
167  if (!ObjMU)
168  return ObjMU.takeError();
169  auto &JD = RT->getJITDylib();
170  return JD.define(std::move(*ObjMU), std::move(RT));
171 }
172 
175  std::unique_ptr<MemoryBuffer> O) {
176  auto ObjSymInfo =
177  getObjectSymbolInfo(L.getExecutionSession(), O->getMemBufferRef());
178 
179  if (!ObjSymInfo)
180  return ObjSymInfo.takeError();
181 
182  auto &SymbolFlags = ObjSymInfo->first;
183  auto &InitSymbol = ObjSymInfo->second;
184 
185  return std::unique_ptr<BasicObjectLayerMaterializationUnit>(
188 }
189 
191  ObjectLayer &L, std::unique_ptr<MemoryBuffer> O, SymbolFlagsMap SymbolFlags,
192  SymbolStringPtr InitSymbol)
193  : MaterializationUnit(std::move(SymbolFlags), std::move(InitSymbol)), L(L),
194  O(std::move(O)) {}
195 
197  if (O)
198  return O->getBufferIdentifier();
199  return "<null object>";
200 }
201 
202 void BasicObjectLayerMaterializationUnit::materialize(
203  std::unique_ptr<MaterializationResponsibility> R) {
204  L.emit(std::move(R), std::move(O));
205 }
206 
207 void BasicObjectLayerMaterializationUnit::discard(const JITDylib &JD,
208  const SymbolStringPtr &Name) {
209  // This is a no-op for object files: Having removed 'Name' from SymbolFlags
210  // the symbol will be dead-stripped by the JIT linker.
211 }
212 
213 } // End namespace orc.
214 } // End namespace llvm.
llvm
Definition: AllocatorList.h:23
llvm::orc::JITDylib
A symbol table that supports asynchoronous symbol queries.
Definition: Core.h:894
M
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Definition: README.txt:252
llvm::orc::IRMaterializationUnit
IRMaterializationUnit is a convenient base class for MaterializationUnits wrapping LLVM IR.
Definition: Layer.h:31
llvm::raw_string_ostream
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:614
llvm::orc::SymbolStringPtr
Pointer to a pooled string representing a symbol name.
Definition: SymbolStringPool.h:50
llvm::orc::IRMaterializationUnit::TSM
ThreadSafeModule TSM
Definition: Layer.h:57
llvm::DenseMapBase::count
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
llvm::orc::IRLayer::getManglingOptions
const IRSymbolMapper::ManglingOptions *& getManglingOptions() const
Get the mangling options for this layer.
Definition: Layer.h:79
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:42
llvm::orc::ThreadSafeModule::getModuleUnlocked
Module * getModuleUnlocked()
Get a raw pointer to the contained module without locking the context.
Definition: ThreadSafeModule.h:147
llvm::orc::getObjectSymbolInfo
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
Layer.h
llvm::MachO::SymbolFlags
SymbolFlags
Symbol flags.
Definition: Symbol.h:25
llvm::orc::MaterializationUnit
A MaterializationUnit represents a set of symbol definitions that can be materialized as a group,...
Definition: Core.h:636
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:122
ExecutionUtils.h
DebugUtils.h
MachO.h
Constants.h
llvm::JITSymbolFlags::MaterializationSideEffectsOnly
@ MaterializationSideEffectsOnly
Definition: JITSymbol.h:87
llvm::orc::BasicObjectLayerMaterializationUnit::getName
StringRef getName() const override
Return the buffer's identifier as the name for this MaterializationUnit.
Definition: Layer.cpp:196
llvm::orc::ExecutionSession::intern
SymbolStringPtr intern(StringRef SymName)
Add a symbol name to the SymbolStringPool and return a pointer to it.
Definition: Core.h:1276
llvm::orc::ObjectLayer::getExecutionSession
ExecutionSession & getExecutionSession()
Returns the execution session for this layer.
Definition: Layer.h:142
llvm::orc::ExecutionSession::runSessionLocked
decltype(auto) runSessionLocked(Func &&F)
Run the given lambda with the session mutex locked.
Definition: Core.h:1289
llvm::orc::ObjectLayer
Interface for Layers that accept object files.
Definition: Layer.h:134
llvm::orc::ObjectLayer::ID
static char ID
Definition: Layer.h:136
llvm::orc::IRMaterializationUnit::IRMaterializationUnit
IRMaterializationUnit(ExecutionSession &ES, const IRSymbolMapper::ManglingOptions &MO, ThreadSafeModule TSM)
Create an IRMaterializationLayer.
Definition: Layer.cpp:33
llvm::orc::getStaticInitGVs
iterator_range< StaticInitGVIterator > getStaticInitGVs(Module &M)
Create an iterator range over the GlobalValues that contribute to static initialization.
Definition: ExecutionUtils.h:140
llvm::orc::IRLayer::add
virtual Error add(ResourceTrackerSP RT, ThreadSafeModule TSM)
Add a MaterializatinoUnit representing the given IR to the JITDylib targeted by the given tracker.
Definition: Layer.cpp:25
llvm::orc::IRLayer::emit
virtual void emit(std::unique_ptr< MaterializationResponsibility > R, ThreadSafeModule TSM)=0
Emit should materialize the given IR.
G
const DataFlowGraph & G
Definition: RDFGraph.cpp:202
llvm::orc::ObjectLayer::~ObjectLayer
virtual ~ObjectLayer()
Definition: Layer.cpp:162
llvm::RISCVFenceField::O
@ O
Definition: RISCVBaseInfo.h:179
llvm::orc::BasicObjectLayerMaterializationUnit::Create
static Expected< std::unique_ptr< BasicObjectLayerMaterializationUnit > > Create(ObjectLayer &L, std::unique_ptr< MemoryBuffer > O)
Definition: Layer.cpp:174
llvm::orc::BasicObjectLayerMaterializationUnit::BasicObjectLayerMaterializationUnit
BasicObjectLayerMaterializationUnit(ObjectLayer &L, std::unique_ptr< MemoryBuffer > O, SymbolFlagsMap SymbolFlags, SymbolStringPtr InitSymbol)
Definition: Layer.cpp:190
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
llvm::DenseMap< SymbolStringPtr, JITSymbolFlags >
I
#define I(x, y, z)
Definition: MD5.cpp:59
llvm::orc::ResourceTrackerSP
uint8_t IntrusiveRefCntPtr< ResourceTracker > ResourceTrackerSP
Definition: Core.h:45
llvm::orc::ObjectLayer::add
virtual Error add(ResourceTrackerSP RT, std::unique_ptr< MemoryBuffer > O)
Adds a MaterializationUnit representing the given IR to the given JITDylib.
Definition: Layer.cpp:164
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::move
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1540
ObjectFile.h
llvm::orc::IRLayer::getCloneToNewContextOnEmit
bool getCloneToNewContextOnEmit() const
Returns the current value of the CloneToNewContextOnEmit flag.
Definition: Layer.h:97
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
llvm::orc::ThreadSafeModule::withModuleDo
decltype(auto) withModuleDo(Func &&F)
Locks the associated ThreadSafeContext and calls the given function on the contained Module.
Definition: ThreadSafeModule.h:133
llvm::orc::ObjectLayer::emit
virtual void emit(std::unique_ptr< MaterializationResponsibility > R, std::unique_ptr< MemoryBuffer > O)=0
Emit should materialize the given IR.
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm::orc::BasicIRLayerMaterializationUnit::BasicIRLayerMaterializationUnit
BasicIRLayerMaterializationUnit(IRLayer &L, const IRSymbolMapper::ManglingOptions &MO, ThreadSafeModule TSM)
Definition: Layer.cpp:129
llvm::GlobalValue::AvailableExternallyLinkage
@ AvailableExternallyLinkage
Available for inspection, not emission.
Definition: GlobalValue.h:49
llvm::orc::MangleAndInterner
Mangles symbol names then uniques them in the context of an ExecutionSession.
Definition: Mangling.h:26
llvm::orc::IRSymbolMapper::ManglingOptions
Definition: Mangling.h:41
llvm::empty
constexpr bool empty(const T &RangeOrContainer)
Test whether RangeOrContainer is empty. Similar to C++17 std::empty.
Definition: STLExtras.h:254
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:52
std
Definition: BitVector.h:838
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
llvm::orc::ExecutionSession
An ExecutionSession represents a running JIT program.
Definition: Core.h:1252
llvm::orc::IRLayer::~IRLayer
virtual ~IRLayer()
Definition: Layer.cpp:23
llvm::JITSymbolFlags::fromGlobalValue
static JITSymbolFlags fromGlobalValue(const GlobalValue &GV)
Construct a JITSymbolFlags value based on the flags of the given global value.
Definition: JITSymbol.cpp:22
llvm::orc::JITDylib::define
Error define(std::unique_ptr< MaterializationUnitType > &&MU, ResourceTrackerSP RT=nullptr)
Define all symbols provided by the materialization unit to be part of this JITDylib.
Definition: Core.h:1552
N
#define N
llvm::orc::JITDylib::getExecutionSession
ExecutionSession & getExecutionSession() const
Get a reference to the ExecutionSession for this JITDylib.
Definition: Core.h:914
llvm::Module::getDataLayout
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
Definition: Module.cpp:397
llvm::orc::ThreadSafeModule
An LLVM Module together with a shared ThreadSafeContext.
Definition: ThreadSafeModule.h:77
llvm::orc::IRMaterializationUnit::SymbolToDefinition
SymbolNameToDefinitionMap SymbolToDefinition
Definition: Layer.h:58
llvm::orc::ObjectLayer::ObjectLayer
ObjectLayer(ExecutionSession &ES)
Definition: Layer.cpp:160
llvm::orc::MaterializationUnit::SymbolFlags
SymbolFlagsMap SymbolFlags
Definition: Core.h:677
llvm::orc::IRMaterializationUnit::SymbolNameToDefinitionMap
std::map< SymbolStringPtr, GlobalValue * > SymbolNameToDefinitionMap
Definition: Layer.h:33
llvm::orc::IRMaterializationUnit::getName
StringRef getName() const override
Return the ModuleIdentifier as the name for this MaterializationUnit.
Definition: Layer.cpp:106
llvm::orc::IRLayer
Interface for layers that accept LLVM IR.
Definition: Layer.h:68
Debug.h
llvm::orc::cloneToNewContext
ThreadSafeModule cloneToNewContext(const ThreadSafeModule &TSMW, GVPredicate ShouldCloneDef=GVPredicate(), GVModifier UpdateClonedDefSource=GVModifier())
Clones the given module on to a new context.
Definition: ThreadSafeModule.cpp:18
llvm::orc::MaterializationUnit::InitSymbol
SymbolStringPtr InitSymbol
Definition: Core.h:678