LLVM 20.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
14#include "llvm/IR/Constants.h"
15#include "llvm/Support/Debug.h"
16
17#define DEBUG_TYPE "orc"
18
19namespace llvm {
20namespace orc {
21
22IRLayer::~IRLayer() = default;
23
25 assert(RT && "RT can not be null");
26 auto &JD = RT->getJITDylib();
27 return JD.define(std::make_unique<BasicIRLayerMaterializationUnit>(
28 *this, *getManglingOptions(), std::move(TSM)),
29 std::move(RT));
30}
31
35 : MaterializationUnit(Interface()), TSM(std::move(TSM)) {
36
37 assert(this->TSM && "Module must not be null");
38
39 MangleAndInterner Mangle(ES, this->TSM.getModuleUnlocked()->getDataLayout());
40 this->TSM.withModuleDo([&](Module &M) {
41 for (auto &G : M.global_values()) {
42 // Skip globals that don't generate symbols.
43
44 if (!G.hasName() || G.isDeclaration() || G.hasLocalLinkage() ||
45 G.hasAvailableExternallyLinkage() || G.hasAppendingLinkage())
46 continue;
47
48 // thread locals generate different symbols depending on whether or not
49 // emulated TLS is enabled.
50 if (G.isThreadLocal() && MO.EmulatedTLS) {
51 auto &GV = cast<GlobalVariable>(G);
52
53 auto Flags = JITSymbolFlags::fromGlobalValue(GV);
54
55 auto EmuTLSV = Mangle(("__emutls_v." + GV.getName()).str());
56 SymbolFlags[EmuTLSV] = Flags;
57 SymbolToDefinition[EmuTLSV] = &GV;
58
59 // If this GV has a non-zero initializer we'll need to emit an
60 // __emutls.t symbol too.
61 if (GV.hasInitializer()) {
62 const auto *InitVal = GV.getInitializer();
63
64 // Skip zero-initializers.
65 if (isa<ConstantAggregateZero>(InitVal))
66 continue;
67 const auto *InitIntValue = dyn_cast<ConstantInt>(InitVal);
68 if (InitIntValue && InitIntValue->isZero())
69 continue;
70
71 auto EmuTLST = Mangle(("__emutls_t." + GV.getName()).str());
72 SymbolFlags[EmuTLST] = Flags;
73 }
74 continue;
75 }
76
77 // Otherwise we just need a normal linker mangling.
78 auto MangledName = Mangle(G.getName());
80 if (G.getComdat() &&
81 G.getComdat()->getSelectionKind() != Comdat::NoDeduplicate)
82 SymbolFlags[MangledName] |= JITSymbolFlags::Weak;
83 SymbolToDefinition[MangledName] = &G;
84 }
85
86 // If we need an init symbol for this module then create one.
87 if (!getStaticInitGVs(M).empty()) {
88 size_t Counter = 0;
89
90 do {
91 std::string InitSymbolName;
92 raw_string_ostream(InitSymbolName)
93 << "$." << M.getModuleIdentifier() << ".__inits." << Counter++;
94 InitSymbol = ES.intern(InitSymbolName);
95 } while (SymbolFlags.count(InitSymbol));
96
98 }
99 });
100}
101
102IRMaterializationUnit::IRMaterializationUnit(
104 SymbolNameToDefinitionMap SymbolToDefinition)
105 : MaterializationUnit(std::move(I)), TSM(std::move(TSM)),
106 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
115void 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 // According to the IR verifier, "Declaration[s] may not be in a Comdat!"
129 // Remove it, if this is a GlobalObject.
130 if (auto *GO = dyn_cast<GlobalObject>(I->second))
131 GO->setComdat(nullptr);
132 SymbolToDefinition.erase(I);
133}
134
137 : IRMaterializationUnit(L.getExecutionSession(), MO, std::move(TSM)), L(L) {
138}
139
140void BasicIRLayerMaterializationUnit::materialize(
141 std::unique_ptr<MaterializationResponsibility> R) {
142
143 // Throw away the SymbolToDefinition map: it's not usable after we hand
144 // off the module.
146
147 // If cloneToNewContextOnEmit is set, clone the module now.
150
151#ifndef NDEBUG
152 auto &ES = R->getTargetJITDylib().getExecutionSession();
153 auto &N = R->getTargetJITDylib().getName();
154#endif // NDEBUG
155
156 LLVM_DEBUG(ES.runSessionLocked(
157 [&]() { dbgs() << "Emitting, for " << N << ", " << *this << "\n"; }););
158 L.emit(std::move(R), std::move(TSM));
159 LLVM_DEBUG(ES.runSessionLocked([&]() {
160 dbgs() << "Finished emitting, for " << N << ", " << *this << "\n";
161 }););
162}
164char ObjectLayer::ID;
165
167
168ObjectLayer::~ObjectLayer() = default;
169
170Error ObjectLayer::add(ResourceTrackerSP RT, std::unique_ptr<MemoryBuffer> O,
172 assert(RT && "RT can not be null");
173 auto &JD = RT->getJITDylib();
174 return JD.define(std::make_unique<BasicObjectLayerMaterializationUnit>(
175 *this, std::move(O), std::move(I)),
176 std::move(RT));
177}
178
179Error ObjectLayer::add(ResourceTrackerSP RT, std::unique_ptr<MemoryBuffer> O) {
180 auto I = getObjectFileInterface(getExecutionSession(), O->getMemBufferRef());
181 if (!I)
182 return I.takeError();
183 return add(std::move(RT), std::move(O), std::move(*I));
184}
185
186Error ObjectLayer::add(JITDylib &JD, std::unique_ptr<MemoryBuffer> O) {
187 auto I = getObjectFileInterface(getExecutionSession(), O->getMemBufferRef());
188 if (!I)
189 return I.takeError();
190 return add(JD, std::move(O), std::move(*I));
191}
192
195 std::unique_ptr<MemoryBuffer> O) {
196
197 auto ObjInterface =
198 getObjectFileInterface(L.getExecutionSession(), O->getMemBufferRef());
199
200 if (!ObjInterface)
201 return ObjInterface.takeError();
202
203 return std::make_unique<BasicObjectLayerMaterializationUnit>(
204 L, std::move(O), std::move(*ObjInterface));
205}
206
208 ObjectLayer &L, std::unique_ptr<MemoryBuffer> O, Interface I)
209 : MaterializationUnit(std::move(I)), L(L), O(std::move(O)) {}
210
212 if (O)
213 return O->getBufferIdentifier();
214 return "<null object>";
215}
216
217void BasicObjectLayerMaterializationUnit::materialize(
218 std::unique_ptr<MaterializationResponsibility> R) {
219 L.emit(std::move(R), std::move(O));
220}
221
222void BasicObjectLayerMaterializationUnit::discard(const JITDylib &JD,
223 const SymbolStringPtr &Name) {
224 // This is a no-op for object files: Having removed 'Name' from SymbolFlags
225 // the symbol will be dead-stripped by the JIT linker.
226}
227
228} // End namespace orc.
229} // End namespace llvm.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
#define LLVM_DEBUG(...)
Definition: Debug.h:106
std::string Name
#define I(x, y, z)
Definition: MD5.cpp:58
#define G(x, y, z)
Definition: MD5.cpp:56
if(PassOpts->AAPipeline)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
@ NoDeduplicate
No deduplication is performed.
Definition: Comdat.h:39
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:152
Lightweight error class with error context and mandatory checking.
Definition: Error.h:160
Tagged union holding either a T or a Error.
Definition: Error.h:481
@ AvailableExternallyLinkage
Available for inspection, not emission.
Definition: GlobalValue.h:53
static JITSymbolFlags fromGlobalValue(const GlobalValue &GV)
Construct a JITSymbolFlags value based on the flags of the given global value.
Definition: JITSymbol.cpp:22
@ MaterializationSideEffectsOnly
Definition: JITSymbol.h:87
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
Definition: Module.h:294
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
BasicIRLayerMaterializationUnit(IRLayer &L, const IRSymbolMapper::ManglingOptions &MO, ThreadSafeModule TSM)
Definition: Layer.cpp:135
static Expected< std::unique_ptr< BasicObjectLayerMaterializationUnit > > Create(ObjectLayer &L, std::unique_ptr< MemoryBuffer > O)
Create using the default object interface builder function.
Definition: Layer.cpp:194
BasicObjectLayerMaterializationUnit(ObjectLayer &L, std::unique_ptr< MemoryBuffer > O, Interface I)
Definition: Layer.cpp:207
StringRef getName() const override
Return the buffer's identifier as the name for this MaterializationUnit.
Definition: Layer.cpp:211
An ExecutionSession represents a running JIT program.
Definition: Core.h:1339
SymbolStringPtr intern(StringRef SymName)
Add a symbol name to the SymbolStringPool and return a pointer to it.
Definition: Core.h:1393
decltype(auto) runSessionLocked(Func &&F)
Run the given lambda with the session mutex locked.
Definition: Core.h:1403
Interface for layers that accept LLVM IR.
Definition: Layer.h:67
virtual void emit(std::unique_ptr< MaterializationResponsibility > R, ThreadSafeModule TSM)=0
Emit should materialize the given IR.
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:24
const IRSymbolMapper::ManglingOptions *& getManglingOptions() const
Get the mangling options for this layer.
Definition: Layer.h:78
bool getCloneToNewContextOnEmit() const
Returns the current value of the CloneToNewContextOnEmit flag.
Definition: Layer.h:96
IRMaterializationUnit is a convenient base class for MaterializationUnits wrapping LLVM IR.
Definition: Layer.h:31
StringRef getName() const override
Return the ModuleIdentifier as the name for this MaterializationUnit.
Definition: Layer.cpp:108
SymbolNameToDefinitionMap SymbolToDefinition
Definition: Layer.h:57
IRMaterializationUnit(ExecutionSession &ES, const IRSymbolMapper::ManglingOptions &MO, ThreadSafeModule TSM)
Create an IRMaterializationLayer.
Definition: Layer.cpp:32
ThreadSafeModule TSM
Definition: Layer.h:56
std::map< SymbolStringPtr, GlobalValue * > SymbolNameToDefinitionMap
Definition: Layer.h:33
Represents a JIT'd dynamic library.
Definition: Core.h:897
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:1822
ExecutionSession & getExecutionSession() const
Get a reference to the ExecutionSession for this JITDylib.
Definition: Core.h:916
Mangles symbol names then uniques them in the context of an ExecutionSession.
Definition: Mangling.h:26
A MaterializationUnit represents a set of symbol definitions that can be materialized as a group,...
Interface for Layers that accept object files.
Definition: Layer.h:133
ObjectLayer(ExecutionSession &ES)
Definition: Layer.cpp:166
virtual void emit(std::unique_ptr< MaterializationResponsibility > R, std::unique_ptr< MemoryBuffer > O)=0
Emit should materialize the given IR.
static char ID
Definition: Layer.h:135
virtual Error add(ResourceTrackerSP RT, std::unique_ptr< MemoryBuffer > O, MaterializationUnit::Interface I)
Adds a MaterializationUnit for the object file in the given memory buffer to the JITDylib for the giv...
Definition: Layer.cpp:170
ExecutionSession & getExecutionSession()
Returns the execution session for this layer.
Definition: Layer.h:141
Pointer to a pooled string representing a symbol name.
An LLVM Module together with a shared ThreadSafeContext.
Module * getModuleUnlocked()
Get a raw pointer to the contained module without locking the context.
decltype(auto) withModuleDo(Func &&F)
Locks the associated ThreadSafeContext and calls the given function on the contained Module.
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:661
iterator_range< StaticInitGVIterator > getStaticInitGVs(Module &M)
Create an iterator range over the GlobalValues that contribute to static initialization.
Expected< MaterializationUnit::Interface > getObjectFileInterface(ExecutionSession &ES, MemoryBufferRef ObjBuffer)
Returns a MaterializationUnit::Interface for the object file contained in the given buffer,...
ThreadSafeModule cloneToNewContext(const ThreadSafeModule &TSMW, GVPredicate ShouldCloneDef=GVPredicate(), GVModifier UpdateClonedDefSource=GVModifier())
Clones the given module on to a new context.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
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:1873
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:858
#define N