LLVM 22.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());
79 auto &Flags = SymbolFlags[MangledName];
81 if (G.getComdat() &&
82 G.getComdat()->getSelectionKind() != Comdat::NoDeduplicate)
83 Flags |= JITSymbolFlags::Weak;
84 SymbolToDefinition[MangledName] = &G;
85 }
86
87 // If we need an init symbol for this module then create one.
88 if (!getStaticInitGVs(M).empty()) {
89 size_t Counter = 0;
90
91 do {
92 std::string InitSymbolName;
93 raw_string_ostream(InitSymbolName)
94 << "$." << M.getModuleIdentifier() << ".__inits." << Counter++;
95 InitSymbol = ES.intern(InitSymbolName);
96 } while (SymbolFlags.count(InitSymbol));
97
99 }
100 });
101}
102
103IRMaterializationUnit::IRMaterializationUnit(
105 SymbolNameToDefinitionMap SymbolToDefinition)
106 : MaterializationUnit(std::move(I)), TSM(std::move(TSM)),
107 SymbolToDefinition(std::move(SymbolToDefinition)) {}
108
110 if (TSM)
111 return TSM.withModuleDo(
112 [](const Module &M) -> StringRef { return M.getModuleIdentifier(); });
113 return "<null module>";
114}
115
116void IRMaterializationUnit::discard(const JITDylib &JD,
117 const SymbolStringPtr &Name) {
119 dbgs() << "In " << JD.getName() << " discarding " << *Name << " from MU@"
120 << this << " (" << getName() << ")\n";
121 }););
122
123 auto I = SymbolToDefinition.find(Name);
124 assert(I != SymbolToDefinition.end() &&
125 "Symbol not provided by this MU, or previously discarded");
126 assert(!I->second->isDeclaration() &&
127 "Discard should only apply to definitions");
128 I->second->setLinkage(GlobalValue::AvailableExternallyLinkage);
129 // According to the IR verifier, "Declaration[s] may not be in a Comdat!"
130 // Remove it, if this is a GlobalObject.
131 if (auto *GO = dyn_cast<GlobalObject>(I->second))
132 GO->setComdat(nullptr);
133 SymbolToDefinition.erase(I);
134}
135
138 : IRMaterializationUnit(L.getExecutionSession(), MO, std::move(TSM)), L(L) {
139}
140
141void BasicIRLayerMaterializationUnit::materialize(
142 std::unique_ptr<MaterializationResponsibility> R) {
143
144 // Throw away the SymbolToDefinition map: it's not usable after we hand
145 // off the module.
147
148 // If cloneToNewContextOnEmit is set, clone the module now.
151
152#ifndef NDEBUG
153 auto &ES = R->getTargetJITDylib().getExecutionSession();
154 auto &N = R->getTargetJITDylib().getName();
155#endif // NDEBUG
156
157 LLVM_DEBUG(ES.runSessionLocked(
158 [&]() { dbgs() << "Emitting, for " << N << ", " << *this << "\n"; }););
159 L.emit(std::move(R), std::move(TSM));
160 LLVM_DEBUG(ES.runSessionLocked([&]() {
161 dbgs() << "Finished emitting, for " << N << ", " << *this << "\n";
162 }););
163}
165char ObjectLayer::ID;
166
168
169ObjectLayer::~ObjectLayer() = default;
170
171Error ObjectLayer::add(ResourceTrackerSP RT, std::unique_ptr<MemoryBuffer> O,
173 assert(RT && "RT can not be null");
174 auto &JD = RT->getJITDylib();
175 return JD.define(std::make_unique<BasicObjectLayerMaterializationUnit>(
176 *this, std::move(O), std::move(I)),
177 std::move(RT));
178}
179
180Error ObjectLayer::add(ResourceTrackerSP RT, std::unique_ptr<MemoryBuffer> O) {
181 auto I = getObjectFileInterface(getExecutionSession(), O->getMemBufferRef());
182 if (!I)
183 return I.takeError();
184 return add(std::move(RT), std::move(O), std::move(*I));
185}
186
187Error ObjectLayer::add(JITDylib &JD, std::unique_ptr<MemoryBuffer> O) {
188 auto I = getObjectFileInterface(getExecutionSession(), O->getMemBufferRef());
189 if (!I)
190 return I.takeError();
191 return add(JD, std::move(O), std::move(*I));
192}
193
196 std::unique_ptr<MemoryBuffer> O) {
197
198 auto ObjInterface =
199 getObjectFileInterface(L.getExecutionSession(), O->getMemBufferRef());
200
201 if (!ObjInterface)
202 return ObjInterface.takeError();
203
204 return std::make_unique<BasicObjectLayerMaterializationUnit>(
205 L, std::move(O), std::move(*ObjInterface));
206}
207
209 ObjectLayer &L, std::unique_ptr<MemoryBuffer> O, Interface I)
210 : MaterializationUnit(std::move(I)), L(L), O(std::move(O)) {}
211
213 if (O)
214 return O->getBufferIdentifier();
215 return "<null object>";
216}
217
218void BasicObjectLayerMaterializationUnit::materialize(
219 std::unique_ptr<MaterializationResponsibility> R) {
220 L.emit(std::move(R), std::move(O));
221}
222
223void BasicObjectLayerMaterializationUnit::discard(const JITDylib &JD,
224 const SymbolStringPtr &Name) {
225 // This is a no-op for object files: Having removed 'Name' from SymbolFlags
226 // the symbol will be dead-stripped by the JIT linker.
227}
228
229} // End namespace orc.
230} // End namespace llvm.
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
std::string Name
#define I(x, y, z)
Definition: MD5.cpp:58
#define G(x, y, z)
Definition: MD5.cpp:56
if(PassOpts->AAPipeline)
#define LLVM_DEBUG(...)
Definition: Debug.h:119
@ NoDeduplicate
No deduplication is performed.
Definition: Comdat.h:40
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:173
Lightweight error class with error context and mandatory checking.
Definition: Error.h:159
Tagged union holding either a T or a Error.
Definition: Error.h:485
@ AvailableExternallyLinkage
Available for inspection, not emission.
Definition: GlobalValue.h:54
static LLVM_ABI 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:88
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
Definition: Module.h:278
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:55
BasicIRLayerMaterializationUnit(IRLayer &L, const IRSymbolMapper::ManglingOptions &MO, ThreadSafeModule TSM)
Definition: Layer.cpp:136
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:195
BasicObjectLayerMaterializationUnit(ObjectLayer &L, std::unique_ptr< MemoryBuffer > O, Interface I)
Definition: Layer.cpp:208
StringRef getName() const override
Return the buffer's identifier as the name for this MaterializationUnit.
Definition: Layer.cpp:212
An ExecutionSession represents a running JIT program.
Definition: Core.h:1355
SymbolStringPtr intern(StringRef SymName)
Add a symbol name to the SymbolStringPool and return a pointer to it.
Definition: Core.h:1409
decltype(auto) runSessionLocked(Func &&F)
Run the given lambda with the session mutex locked.
Definition: Core.h:1419
Interface for layers that accept LLVM IR.
Definition: Layer.h:68
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:79
bool getCloneToNewContextOnEmit() const
Returns the current value of the CloneToNewContextOnEmit flag.
Definition: Layer.h:97
IRMaterializationUnit is a convenient base class for MaterializationUnits wrapping LLVM IR.
Definition: Layer.h:32
StringRef getName() const override
Return the ModuleIdentifier as the name for this MaterializationUnit.
Definition: Layer.cpp:109
SymbolNameToDefinitionMap SymbolToDefinition
Definition: Layer.h:58
IRMaterializationUnit(ExecutionSession &ES, const IRSymbolMapper::ManglingOptions &MO, ThreadSafeModule TSM)
Create an IRMaterializationLayer.
Definition: Layer.cpp:32
ThreadSafeModule TSM
Definition: Layer.h:57
std::map< SymbolStringPtr, GlobalValue * > SymbolNameToDefinitionMap
Definition: Layer.h:34
Represents a JIT'd dynamic library.
Definition: Core.h:902
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:1882
ExecutionSession & getExecutionSession() const
Get a reference to the ExecutionSession for this JITDylib.
Definition: Core.h:921
Mangles symbol names then uniques them in the context of an ExecutionSession.
Definition: Mangling.h:27
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:134
ObjectLayer(ExecutionSession &ES)
Definition: Layer.cpp:167
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:136
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:171
ExecutionSession & getExecutionSession()
Returns the execution session for this layer.
Definition: Layer.h:142
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:662
iterator_range< StaticInitGVIterator > getStaticInitGVs(Module &M)
Create an iterator range over the GlobalValues that contribute to static initialization.
LLVM_ABI Expected< MaterializationUnit::Interface > getObjectFileInterface(ExecutionSession &ES, MemoryBufferRef ObjBuffer)
Returns a MaterializationUnit::Interface for the object file contained in the given buffer,...
LLVM_ABI 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:1886
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:856
#define N