1 //===-------------------- Layer.cpp - Layer interfaces --------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "llvm/ExecutionEngine/Orc/Layer.h"
11 #include "llvm/ExecutionEngine/Orc/DebugUtils.h"
12 #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
13 #include "llvm/ExecutionEngine/Orc/ObjectFileInterface.h"
14 #include "llvm/IR/Constants.h"
15 #include "llvm/Support/Debug.h"
17 #define DEBUG_TYPE "orc"
22 IRLayer::~IRLayer() = default;
24 Error
IRLayer::add(ResourceTrackerSP RT
, ThreadSafeModule TSM
) {
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
)),
32 IRMaterializationUnit::IRMaterializationUnit(
33 ExecutionSession
&ES
, const IRSymbolMapper::ManglingOptions
&MO
,
35 : MaterializationUnit(Interface()), TSM(std::move(TSM
)) {
37 assert(this->TSM
&& "Module must not be null");
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.
44 if (!G
.hasName() || G
.isDeclaration() || G
.hasLocalLinkage() ||
45 G
.hasAvailableExternallyLinkage() || G
.hasAppendingLinkage())
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
);
53 auto Flags
= JITSymbolFlags::fromGlobalValue(GV
);
55 auto EmuTLSV
= Mangle(("__emutls_v." + GV
.getName()).str());
56 SymbolFlags
[EmuTLSV
] = Flags
;
57 SymbolToDefinition
[EmuTLSV
] = &GV
;
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();
64 // Skip zero-initializers.
65 if (isa
<ConstantAggregateZero
>(InitVal
))
67 const auto *InitIntValue
= dyn_cast
<ConstantInt
>(InitVal
);
68 if (InitIntValue
&& InitIntValue
->isZero())
71 auto EmuTLST
= Mangle(("__emutls_t." + GV
.getName()).str());
72 SymbolFlags
[EmuTLST
] = Flags
;
77 // Otherwise we just need a normal linker mangling.
78 auto MangledName
= Mangle(G
.getName());
79 SymbolFlags
[MangledName
] = JITSymbolFlags::fromGlobalValue(G
);
81 G
.getComdat()->getSelectionKind() != Comdat::NoDeduplicate
)
82 SymbolFlags
[MangledName
] |= JITSymbolFlags::Weak
;
83 SymbolToDefinition
[MangledName
] = &G
;
86 // If we need an init symbol for this module then create one.
87 if (!getStaticInitGVs(M
).empty()) {
91 std::string InitSymbolName
;
92 raw_string_ostream(InitSymbolName
)
93 << "$." << M
.getModuleIdentifier() << ".__inits." << Counter
++;
94 InitSymbol
= ES
.intern(InitSymbolName
);
95 } while (SymbolFlags
.count(InitSymbol
));
97 SymbolFlags
[InitSymbol
] = JITSymbolFlags::MaterializationSideEffectsOnly
;
102 IRMaterializationUnit::IRMaterializationUnit(
103 ThreadSafeModule TSM
, Interface I
,
104 SymbolNameToDefinitionMap SymbolToDefinition
)
105 : MaterializationUnit(std::move(I
)), TSM(std::move(TSM
)),
106 SymbolToDefinition(std::move(SymbolToDefinition
)) {}
108 StringRef
IRMaterializationUnit::getName() const {
110 return TSM
.withModuleDo(
111 [](const Module
&M
) -> StringRef
{ return M
.getModuleIdentifier(); });
112 return "<null module>";
115 void IRMaterializationUnit::discard(const JITDylib
&JD
,
116 const SymbolStringPtr
&Name
) {
117 LLVM_DEBUG(JD
.getExecutionSession().runSessionLocked([&]() {
118 dbgs() << "In " << JD
.getName() << " discarding " << *Name
<< " from MU@"
119 << this << " (" << getName() << ")\n";
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
);
135 BasicIRLayerMaterializationUnit::BasicIRLayerMaterializationUnit(
136 IRLayer
&L
, const IRSymbolMapper::ManglingOptions
&MO
, ThreadSafeModule TSM
)
137 : IRMaterializationUnit(L
.getExecutionSession(), MO
, std::move(TSM
)), L(L
) {
140 void BasicIRLayerMaterializationUnit::materialize(
141 std::unique_ptr
<MaterializationResponsibility
> R
) {
143 // Throw away the SymbolToDefinition map: it's not usable after we hand
145 SymbolToDefinition
.clear();
147 // If cloneToNewContextOnEmit is set, clone the module now.
148 if (L
.getCloneToNewContextOnEmit())
149 TSM
= cloneToNewContext(TSM
);
152 auto &ES
= R
->getTargetJITDylib().getExecutionSession();
153 auto &N
= R
->getTargetJITDylib().getName();
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";
164 char ObjectLayer::ID
;
166 ObjectLayer::ObjectLayer(ExecutionSession
&ES
) : ES(ES
) {}
168 ObjectLayer::~ObjectLayer() = default;
170 Error
ObjectLayer::add(ResourceTrackerSP RT
, std::unique_ptr
<MemoryBuffer
> O
,
171 MaterializationUnit::Interface I
) {
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
)),
179 Error
ObjectLayer::add(ResourceTrackerSP RT
, std::unique_ptr
<MemoryBuffer
> O
) {
180 auto I
= getObjectFileInterface(getExecutionSession(), O
->getMemBufferRef());
182 return I
.takeError();
183 return add(std::move(RT
), std::move(O
), std::move(*I
));
186 Error
ObjectLayer::add(JITDylib
&JD
, std::unique_ptr
<MemoryBuffer
> O
) {
187 auto I
= getObjectFileInterface(getExecutionSession(), O
->getMemBufferRef());
189 return I
.takeError();
190 return add(JD
, std::move(O
), std::move(*I
));
193 Expected
<std::unique_ptr
<BasicObjectLayerMaterializationUnit
>>
194 BasicObjectLayerMaterializationUnit::Create(ObjectLayer
&L
,
195 std::unique_ptr
<MemoryBuffer
> O
) {
198 getObjectFileInterface(L
.getExecutionSession(), O
->getMemBufferRef());
201 return ObjInterface
.takeError();
203 return std::unique_ptr
<BasicObjectLayerMaterializationUnit
>(
204 new BasicObjectLayerMaterializationUnit(L
, std::move(O
),
205 std::move(*ObjInterface
)));
208 BasicObjectLayerMaterializationUnit::BasicObjectLayerMaterializationUnit(
209 ObjectLayer
&L
, std::unique_ptr
<MemoryBuffer
> O
, Interface I
)
210 : MaterializationUnit(std::move(I
)), L(L
), O(std::move(O
)) {}
212 StringRef
BasicObjectLayerMaterializationUnit::getName() const {
214 return O
->getBufferIdentifier();
215 return "<null object>";
218 void BasicObjectLayerMaterializationUnit::materialize(
219 std::unique_ptr
<MaterializationResponsibility
> R
) {
220 L
.emit(std::move(R
), std::move(O
));
223 void 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.
229 } // End namespace orc.
230 } // End namespace llvm.