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/IR/Constants.h"
14 #include "llvm/Object/MachO.h"
15 #include "llvm/Object/ObjectFile.h"
16 #include "llvm/Support/Debug.h"
18 #define DEBUG_TYPE "orc"
23 IRLayer::~IRLayer() {}
25 Error
IRLayer::add(ResourceTrackerSP RT
, ThreadSafeModule TSM
) {
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
)),
33 IRMaterializationUnit::IRMaterializationUnit(
34 ExecutionSession
&ES
, const IRSymbolMapper::ManglingOptions
&MO
,
36 : MaterializationUnit(SymbolFlagsMap(), nullptr), TSM(std::move(TSM
)) {
38 assert(this->TSM
&& "Module must not be null");
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.
45 if (!G
.hasName() || G
.isDeclaration() || G
.hasLocalLinkage() ||
46 G
.hasAvailableExternallyLinkage() || G
.hasAppendingLinkage())
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
);
54 auto Flags
= JITSymbolFlags::fromGlobalValue(GV
);
56 auto EmuTLSV
= Mangle(("__emutls_v." + GV
.getName()).str());
57 SymbolFlags
[EmuTLSV
] = Flags
;
58 SymbolToDefinition
[EmuTLSV
] = &GV
;
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();
65 // Skip zero-initializers.
66 if (isa
<ConstantAggregateZero
>(InitVal
))
68 const auto *InitIntValue
= dyn_cast
<ConstantInt
>(InitVal
);
69 if (InitIntValue
&& InitIntValue
->isZero())
72 auto EmuTLST
= Mangle(("__emutls_t." + GV
.getName()).str());
73 SymbolFlags
[EmuTLST
] = Flags
;
78 // Otherwise we just need a normal linker mangling.
79 auto MangledName
= Mangle(G
.getName());
80 SymbolFlags
[MangledName
] = JITSymbolFlags::fromGlobalValue(G
);
81 SymbolToDefinition
[MangledName
] = &G
;
84 // If we need an init symbol for this module then create one.
85 if (!llvm::empty(getStaticInitGVs(M
))) {
89 std::string InitSymbolName
;
90 raw_string_ostream(InitSymbolName
)
91 << "$." << M
.getModuleIdentifier() << ".__inits." << Counter
++;
92 InitSymbol
= ES
.intern(InitSymbolName
);
93 } while (SymbolFlags
.count(InitSymbol
));
95 SymbolFlags
[InitSymbol
] = JITSymbolFlags::MaterializationSideEffectsOnly
;
100 IRMaterializationUnit::IRMaterializationUnit(
101 ThreadSafeModule TSM
, SymbolFlagsMap SymbolFlags
,
102 SymbolStringPtr InitSymbol
, SymbolNameToDefinitionMap SymbolToDefinition
)
103 : MaterializationUnit(std::move(SymbolFlags
), std::move(InitSymbol
)),
104 TSM(std::move(TSM
)), SymbolToDefinition(std::move(SymbolToDefinition
)) {}
106 StringRef
IRMaterializationUnit::getName() const {
108 return TSM
.withModuleDo(
109 [](const Module
&M
) -> StringRef
{ return M
.getModuleIdentifier(); });
110 return "<null module>";
113 void IRMaterializationUnit::discard(const JITDylib
&JD
,
114 const SymbolStringPtr
&Name
) {
115 LLVM_DEBUG(JD
.getExecutionSession().runSessionLocked([&]() {
116 dbgs() << "In " << JD
.getName() << " discarding " << *Name
<< " from MU@"
117 << this << " (" << getName() << ")\n";
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
);
129 BasicIRLayerMaterializationUnit::BasicIRLayerMaterializationUnit(
130 IRLayer
&L
, const IRSymbolMapper::ManglingOptions
&MO
, ThreadSafeModule TSM
)
131 : IRMaterializationUnit(L
.getExecutionSession(), MO
, std::move(TSM
)), L(L
) {
134 void BasicIRLayerMaterializationUnit::materialize(
135 std::unique_ptr
<MaterializationResponsibility
> R
) {
137 // Throw away the SymbolToDefinition map: it's not usable after we hand
139 SymbolToDefinition
.clear();
141 // If cloneToNewContextOnEmit is set, clone the module now.
142 if (L
.getCloneToNewContextOnEmit())
143 TSM
= cloneToNewContext(TSM
);
146 auto &ES
= R
->getTargetJITDylib().getExecutionSession();
147 auto &N
= R
->getTargetJITDylib().getName();
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";
158 char ObjectLayer::ID
;
160 ObjectLayer::ObjectLayer(ExecutionSession
&ES
) : ES(ES
) {}
162 ObjectLayer::~ObjectLayer() {}
164 Error
ObjectLayer::add(ResourceTrackerSP RT
, std::unique_ptr
<MemoryBuffer
> O
) {
165 assert(RT
&& "RT can not be null");
166 auto ObjMU
= BasicObjectLayerMaterializationUnit::Create(*this, std::move(O
));
168 return ObjMU
.takeError();
169 auto &JD
= RT
->getJITDylib();
170 return JD
.define(std::move(*ObjMU
), std::move(RT
));
173 Expected
<std::unique_ptr
<BasicObjectLayerMaterializationUnit
>>
174 BasicObjectLayerMaterializationUnit::Create(ObjectLayer
&L
,
175 std::unique_ptr
<MemoryBuffer
> O
) {
177 getObjectSymbolInfo(L
.getExecutionSession(), O
->getMemBufferRef());
180 return ObjSymInfo
.takeError();
182 auto &SymbolFlags
= ObjSymInfo
->first
;
183 auto &InitSymbol
= ObjSymInfo
->second
;
185 return std::unique_ptr
<BasicObjectLayerMaterializationUnit
>(
186 new BasicObjectLayerMaterializationUnit(
187 L
, std::move(O
), std::move(SymbolFlags
), std::move(InitSymbol
)));
190 BasicObjectLayerMaterializationUnit::BasicObjectLayerMaterializationUnit(
191 ObjectLayer
&L
, std::unique_ptr
<MemoryBuffer
> O
, SymbolFlagsMap SymbolFlags
,
192 SymbolStringPtr InitSymbol
)
193 : MaterializationUnit(std::move(SymbolFlags
), std::move(InitSymbol
)), L(L
),
196 StringRef
BasicObjectLayerMaterializationUnit::getName() const {
198 return O
->getBufferIdentifier();
199 return "<null object>";
202 void BasicObjectLayerMaterializationUnit::materialize(
203 std::unique_ptr
<MaterializationResponsibility
> R
) {
204 L
.emit(std::move(R
), std::move(O
));
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.
213 } // End namespace orc.
214 } // End namespace llvm.