xref: /netbsd-src/external/apache2/llvm/dist/llvm/lib/ExecutionEngine/Orc/Layer.cpp (revision 82d56013d7b633d116a93943de88e08335357a7c)
17330f729Sjoerg //===-------------------- Layer.cpp - Layer interfaces --------------------===//
27330f729Sjoerg //
37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information.
57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67330f729Sjoerg //
77330f729Sjoerg //===----------------------------------------------------------------------===//
87330f729Sjoerg 
97330f729Sjoerg #include "llvm/ExecutionEngine/Orc/Layer.h"
10*82d56013Sjoerg 
11*82d56013Sjoerg #include "llvm/ExecutionEngine/Orc/DebugUtils.h"
12*82d56013Sjoerg #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
13*82d56013Sjoerg #include "llvm/IR/Constants.h"
14*82d56013Sjoerg #include "llvm/Object/MachO.h"
157330f729Sjoerg #include "llvm/Object/ObjectFile.h"
167330f729Sjoerg #include "llvm/Support/Debug.h"
177330f729Sjoerg 
187330f729Sjoerg #define DEBUG_TYPE "orc"
197330f729Sjoerg 
207330f729Sjoerg namespace llvm {
217330f729Sjoerg namespace orc {
227330f729Sjoerg 
~IRLayer()237330f729Sjoerg IRLayer::~IRLayer() {}
247330f729Sjoerg 
add(ResourceTrackerSP RT,ThreadSafeModule TSM)25*82d56013Sjoerg Error IRLayer::add(ResourceTrackerSP RT, ThreadSafeModule TSM) {
26*82d56013Sjoerg   assert(RT && "RT can not be null");
27*82d56013Sjoerg   auto &JD = RT->getJITDylib();
287330f729Sjoerg   return JD.define(std::make_unique<BasicIRLayerMaterializationUnit>(
29*82d56013Sjoerg                        *this, *getManglingOptions(), std::move(TSM)),
30*82d56013Sjoerg                    std::move(RT));
317330f729Sjoerg }
327330f729Sjoerg 
IRMaterializationUnit(ExecutionSession & ES,const IRSymbolMapper::ManglingOptions & MO,ThreadSafeModule TSM)33*82d56013Sjoerg IRMaterializationUnit::IRMaterializationUnit(
34*82d56013Sjoerg     ExecutionSession &ES, const IRSymbolMapper::ManglingOptions &MO,
35*82d56013Sjoerg     ThreadSafeModule TSM)
36*82d56013Sjoerg     : MaterializationUnit(SymbolFlagsMap(), nullptr), TSM(std::move(TSM)) {
377330f729Sjoerg 
387330f729Sjoerg   assert(this->TSM && "Module must not be null");
397330f729Sjoerg 
407330f729Sjoerg   MangleAndInterner Mangle(ES, this->TSM.getModuleUnlocked()->getDataLayout());
417330f729Sjoerg   this->TSM.withModuleDo([&](Module &M) {
427330f729Sjoerg     for (auto &G : M.global_values()) {
43*82d56013Sjoerg       // Skip globals that don't generate symbols.
44*82d56013Sjoerg 
45*82d56013Sjoerg       if (!G.hasName() || G.isDeclaration() || G.hasLocalLinkage() ||
46*82d56013Sjoerg           G.hasAvailableExternallyLinkage() || G.hasAppendingLinkage())
47*82d56013Sjoerg         continue;
48*82d56013Sjoerg 
49*82d56013Sjoerg       // thread locals generate different symbols depending on whether or not
50*82d56013Sjoerg       // emulated TLS is enabled.
51*82d56013Sjoerg       if (G.isThreadLocal() && MO.EmulatedTLS) {
52*82d56013Sjoerg         auto &GV = cast<GlobalVariable>(G);
53*82d56013Sjoerg 
54*82d56013Sjoerg         auto Flags = JITSymbolFlags::fromGlobalValue(GV);
55*82d56013Sjoerg 
56*82d56013Sjoerg         auto EmuTLSV = Mangle(("__emutls_v." + GV.getName()).str());
57*82d56013Sjoerg         SymbolFlags[EmuTLSV] = Flags;
58*82d56013Sjoerg         SymbolToDefinition[EmuTLSV] = &GV;
59*82d56013Sjoerg 
60*82d56013Sjoerg         // If this GV has a non-zero initializer we'll need to emit an
61*82d56013Sjoerg         // __emutls.t symbol too.
62*82d56013Sjoerg         if (GV.hasInitializer()) {
63*82d56013Sjoerg           const auto *InitVal = GV.getInitializer();
64*82d56013Sjoerg 
65*82d56013Sjoerg           // Skip zero-initializers.
66*82d56013Sjoerg           if (isa<ConstantAggregateZero>(InitVal))
67*82d56013Sjoerg             continue;
68*82d56013Sjoerg           const auto *InitIntValue = dyn_cast<ConstantInt>(InitVal);
69*82d56013Sjoerg           if (InitIntValue && InitIntValue->isZero())
70*82d56013Sjoerg             continue;
71*82d56013Sjoerg 
72*82d56013Sjoerg           auto EmuTLST = Mangle(("__emutls_t." + GV.getName()).str());
73*82d56013Sjoerg           SymbolFlags[EmuTLST] = Flags;
74*82d56013Sjoerg         }
75*82d56013Sjoerg         continue;
76*82d56013Sjoerg       }
77*82d56013Sjoerg 
78*82d56013Sjoerg       // Otherwise we just need a normal linker mangling.
797330f729Sjoerg       auto MangledName = Mangle(G.getName());
807330f729Sjoerg       SymbolFlags[MangledName] = JITSymbolFlags::fromGlobalValue(G);
817330f729Sjoerg       SymbolToDefinition[MangledName] = &G;
827330f729Sjoerg     }
83*82d56013Sjoerg 
84*82d56013Sjoerg     // If we need an init symbol for this module then create one.
85*82d56013Sjoerg     if (!llvm::empty(getStaticInitGVs(M))) {
86*82d56013Sjoerg       size_t Counter = 0;
87*82d56013Sjoerg 
88*82d56013Sjoerg       do {
89*82d56013Sjoerg         std::string InitSymbolName;
90*82d56013Sjoerg         raw_string_ostream(InitSymbolName)
91*82d56013Sjoerg             << "$." << M.getModuleIdentifier() << ".__inits." << Counter++;
92*82d56013Sjoerg         InitSymbol = ES.intern(InitSymbolName);
93*82d56013Sjoerg       } while (SymbolFlags.count(InitSymbol));
94*82d56013Sjoerg 
95*82d56013Sjoerg       SymbolFlags[InitSymbol] = JITSymbolFlags::MaterializationSideEffectsOnly;
967330f729Sjoerg     }
977330f729Sjoerg   });
987330f729Sjoerg }
997330f729Sjoerg 
IRMaterializationUnit(ThreadSafeModule TSM,SymbolFlagsMap SymbolFlags,SymbolStringPtr InitSymbol,SymbolNameToDefinitionMap SymbolToDefinition)1007330f729Sjoerg IRMaterializationUnit::IRMaterializationUnit(
101*82d56013Sjoerg     ThreadSafeModule TSM, SymbolFlagsMap SymbolFlags,
102*82d56013Sjoerg     SymbolStringPtr InitSymbol, SymbolNameToDefinitionMap SymbolToDefinition)
103*82d56013Sjoerg     : MaterializationUnit(std::move(SymbolFlags), std::move(InitSymbol)),
1047330f729Sjoerg       TSM(std::move(TSM)), SymbolToDefinition(std::move(SymbolToDefinition)) {}
1057330f729Sjoerg 
getName() const1067330f729Sjoerg StringRef IRMaterializationUnit::getName() const {
1077330f729Sjoerg   if (TSM)
1087330f729Sjoerg     return TSM.withModuleDo(
1097330f729Sjoerg         [](const Module &M) -> StringRef { return M.getModuleIdentifier(); });
1107330f729Sjoerg   return "<null module>";
1117330f729Sjoerg }
1127330f729Sjoerg 
discard(const JITDylib & JD,const SymbolStringPtr & Name)1137330f729Sjoerg void IRMaterializationUnit::discard(const JITDylib &JD,
1147330f729Sjoerg                                     const SymbolStringPtr &Name) {
1157330f729Sjoerg   LLVM_DEBUG(JD.getExecutionSession().runSessionLocked([&]() {
1167330f729Sjoerg     dbgs() << "In " << JD.getName() << " discarding " << *Name << " from MU@"
1177330f729Sjoerg            << this << " (" << getName() << ")\n";
1187330f729Sjoerg   }););
1197330f729Sjoerg 
1207330f729Sjoerg   auto I = SymbolToDefinition.find(Name);
1217330f729Sjoerg   assert(I != SymbolToDefinition.end() &&
1227330f729Sjoerg          "Symbol not provided by this MU, or previously discarded");
1237330f729Sjoerg   assert(!I->second->isDeclaration() &&
1247330f729Sjoerg          "Discard should only apply to definitions");
1257330f729Sjoerg   I->second->setLinkage(GlobalValue::AvailableExternallyLinkage);
1267330f729Sjoerg   SymbolToDefinition.erase(I);
1277330f729Sjoerg }
1287330f729Sjoerg 
BasicIRLayerMaterializationUnit(IRLayer & L,const IRSymbolMapper::ManglingOptions & MO,ThreadSafeModule TSM)1297330f729Sjoerg BasicIRLayerMaterializationUnit::BasicIRLayerMaterializationUnit(
130*82d56013Sjoerg     IRLayer &L, const IRSymbolMapper::ManglingOptions &MO, ThreadSafeModule TSM)
131*82d56013Sjoerg     : IRMaterializationUnit(L.getExecutionSession(), MO, std::move(TSM)), L(L) {
132*82d56013Sjoerg }
1337330f729Sjoerg 
materialize(std::unique_ptr<MaterializationResponsibility> R)1347330f729Sjoerg void BasicIRLayerMaterializationUnit::materialize(
135*82d56013Sjoerg     std::unique_ptr<MaterializationResponsibility> R) {
1367330f729Sjoerg 
1377330f729Sjoerg   // Throw away the SymbolToDefinition map: it's not usable after we hand
1387330f729Sjoerg   // off the module.
1397330f729Sjoerg   SymbolToDefinition.clear();
1407330f729Sjoerg 
1417330f729Sjoerg   // If cloneToNewContextOnEmit is set, clone the module now.
1427330f729Sjoerg   if (L.getCloneToNewContextOnEmit())
1437330f729Sjoerg     TSM = cloneToNewContext(TSM);
1447330f729Sjoerg 
1457330f729Sjoerg #ifndef NDEBUG
146*82d56013Sjoerg   auto &ES = R->getTargetJITDylib().getExecutionSession();
147*82d56013Sjoerg   auto &N = R->getTargetJITDylib().getName();
1487330f729Sjoerg #endif // NDEBUG
1497330f729Sjoerg 
1507330f729Sjoerg   LLVM_DEBUG(ES.runSessionLocked(
1517330f729Sjoerg       [&]() { dbgs() << "Emitting, for " << N << ", " << *this << "\n"; }););
1527330f729Sjoerg   L.emit(std::move(R), std::move(TSM));
1537330f729Sjoerg   LLVM_DEBUG(ES.runSessionLocked([&]() {
1547330f729Sjoerg     dbgs() << "Finished emitting, for " << N << ", " << *this << "\n";
1557330f729Sjoerg   }););
1567330f729Sjoerg }
1577330f729Sjoerg 
158*82d56013Sjoerg char ObjectLayer::ID;
159*82d56013Sjoerg 
ObjectLayer(ExecutionSession & ES)1607330f729Sjoerg ObjectLayer::ObjectLayer(ExecutionSession &ES) : ES(ES) {}
1617330f729Sjoerg 
~ObjectLayer()1627330f729Sjoerg ObjectLayer::~ObjectLayer() {}
1637330f729Sjoerg 
add(ResourceTrackerSP RT,std::unique_ptr<MemoryBuffer> O)164*82d56013Sjoerg Error ObjectLayer::add(ResourceTrackerSP RT, std::unique_ptr<MemoryBuffer> O) {
165*82d56013Sjoerg   assert(RT && "RT can not be null");
166*82d56013Sjoerg   auto ObjMU = BasicObjectLayerMaterializationUnit::Create(*this, std::move(O));
1677330f729Sjoerg   if (!ObjMU)
1687330f729Sjoerg     return ObjMU.takeError();
169*82d56013Sjoerg   auto &JD = RT->getJITDylib();
170*82d56013Sjoerg   return JD.define(std::move(*ObjMU), std::move(RT));
1717330f729Sjoerg }
1727330f729Sjoerg 
1737330f729Sjoerg Expected<std::unique_ptr<BasicObjectLayerMaterializationUnit>>
Create(ObjectLayer & L,std::unique_ptr<MemoryBuffer> O)174*82d56013Sjoerg BasicObjectLayerMaterializationUnit::Create(ObjectLayer &L,
1757330f729Sjoerg                                             std::unique_ptr<MemoryBuffer> O) {
176*82d56013Sjoerg   auto ObjSymInfo =
177*82d56013Sjoerg       getObjectSymbolInfo(L.getExecutionSession(), O->getMemBufferRef());
1787330f729Sjoerg 
179*82d56013Sjoerg   if (!ObjSymInfo)
180*82d56013Sjoerg     return ObjSymInfo.takeError();
181*82d56013Sjoerg 
182*82d56013Sjoerg   auto &SymbolFlags = ObjSymInfo->first;
183*82d56013Sjoerg   auto &InitSymbol = ObjSymInfo->second;
1847330f729Sjoerg 
1857330f729Sjoerg   return std::unique_ptr<BasicObjectLayerMaterializationUnit>(
186*82d56013Sjoerg       new BasicObjectLayerMaterializationUnit(
187*82d56013Sjoerg           L, std::move(O), std::move(SymbolFlags), std::move(InitSymbol)));
1887330f729Sjoerg }
1897330f729Sjoerg 
BasicObjectLayerMaterializationUnit(ObjectLayer & L,std::unique_ptr<MemoryBuffer> O,SymbolFlagsMap SymbolFlags,SymbolStringPtr InitSymbol)1907330f729Sjoerg BasicObjectLayerMaterializationUnit::BasicObjectLayerMaterializationUnit(
191*82d56013Sjoerg     ObjectLayer &L, std::unique_ptr<MemoryBuffer> O, SymbolFlagsMap SymbolFlags,
192*82d56013Sjoerg     SymbolStringPtr InitSymbol)
193*82d56013Sjoerg     : MaterializationUnit(std::move(SymbolFlags), std::move(InitSymbol)), L(L),
1947330f729Sjoerg       O(std::move(O)) {}
1957330f729Sjoerg 
getName() const1967330f729Sjoerg StringRef BasicObjectLayerMaterializationUnit::getName() const {
1977330f729Sjoerg   if (O)
1987330f729Sjoerg     return O->getBufferIdentifier();
1997330f729Sjoerg   return "<null object>";
2007330f729Sjoerg }
2017330f729Sjoerg 
materialize(std::unique_ptr<MaterializationResponsibility> R)2027330f729Sjoerg void BasicObjectLayerMaterializationUnit::materialize(
203*82d56013Sjoerg     std::unique_ptr<MaterializationResponsibility> R) {
2047330f729Sjoerg   L.emit(std::move(R), std::move(O));
2057330f729Sjoerg }
2067330f729Sjoerg 
discard(const JITDylib & JD,const SymbolStringPtr & Name)2077330f729Sjoerg void BasicObjectLayerMaterializationUnit::discard(const JITDylib &JD,
2087330f729Sjoerg                                                   const SymbolStringPtr &Name) {
209*82d56013Sjoerg   // This is a no-op for object files: Having removed 'Name' from SymbolFlags
210*82d56013Sjoerg   // the symbol will be dead-stripped by the JIT linker.
2117330f729Sjoerg }
2127330f729Sjoerg 
2137330f729Sjoerg } // End namespace orc.
2147330f729Sjoerg } // End namespace llvm.
215