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 9 #include "llvm/ExecutionEngine/Orc/Layer.h" 10 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" 16 17 #define DEBUG_TYPE "orc" 18 19 namespace llvm { 20 namespace orc { 21 22 IRLayer::~IRLayer() = default; 23 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)), 29 std::move(RT)); 30 } 31 32 IRMaterializationUnit::IRMaterializationUnit( 33 ExecutionSession &ES, const IRSymbolMapper::ManglingOptions &MO, 34 ThreadSafeModule TSM) 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 SymbolFlags[MangledName] = JITSymbolFlags::fromGlobalValue(G); 80 SymbolToDefinition[MangledName] = &G; 81 } 82 83 // If we need an init symbol for this module then create one. 84 if (!llvm::empty(getStaticInitGVs(M))) { 85 size_t Counter = 0; 86 87 do { 88 std::string InitSymbolName; 89 raw_string_ostream(InitSymbolName) 90 << "$." << M.getModuleIdentifier() << ".__inits." << Counter++; 91 InitSymbol = ES.intern(InitSymbolName); 92 } while (SymbolFlags.count(InitSymbol)); 93 94 SymbolFlags[InitSymbol] = JITSymbolFlags::MaterializationSideEffectsOnly; 95 } 96 }); 97 } 98 99 IRMaterializationUnit::IRMaterializationUnit( 100 ThreadSafeModule TSM, Interface I, 101 SymbolNameToDefinitionMap SymbolToDefinition) 102 : MaterializationUnit(std::move(I)), TSM(std::move(TSM)), 103 SymbolToDefinition(std::move(SymbolToDefinition)) {} 104 105 StringRef IRMaterializationUnit::getName() const { 106 if (TSM) 107 return TSM.withModuleDo( 108 [](const Module &M) -> StringRef { return M.getModuleIdentifier(); }); 109 return "<null module>"; 110 } 111 112 void IRMaterializationUnit::discard(const JITDylib &JD, 113 const SymbolStringPtr &Name) { 114 LLVM_DEBUG(JD.getExecutionSession().runSessionLocked([&]() { 115 dbgs() << "In " << JD.getName() << " discarding " << *Name << " from MU@" 116 << this << " (" << getName() << ")\n"; 117 });); 118 119 auto I = SymbolToDefinition.find(Name); 120 assert(I != SymbolToDefinition.end() && 121 "Symbol not provided by this MU, or previously discarded"); 122 assert(!I->second->isDeclaration() && 123 "Discard should only apply to definitions"); 124 I->second->setLinkage(GlobalValue::AvailableExternallyLinkage); 125 SymbolToDefinition.erase(I); 126 } 127 128 BasicIRLayerMaterializationUnit::BasicIRLayerMaterializationUnit( 129 IRLayer &L, const IRSymbolMapper::ManglingOptions &MO, ThreadSafeModule TSM) 130 : IRMaterializationUnit(L.getExecutionSession(), MO, std::move(TSM)), L(L) { 131 } 132 133 void BasicIRLayerMaterializationUnit::materialize( 134 std::unique_ptr<MaterializationResponsibility> R) { 135 136 // Throw away the SymbolToDefinition map: it's not usable after we hand 137 // off the module. 138 SymbolToDefinition.clear(); 139 140 // If cloneToNewContextOnEmit is set, clone the module now. 141 if (L.getCloneToNewContextOnEmit()) 142 TSM = cloneToNewContext(TSM); 143 144 #ifndef NDEBUG 145 auto &ES = R->getTargetJITDylib().getExecutionSession(); 146 auto &N = R->getTargetJITDylib().getName(); 147 #endif // NDEBUG 148 149 LLVM_DEBUG(ES.runSessionLocked( 150 [&]() { dbgs() << "Emitting, for " << N << ", " << *this << "\n"; });); 151 L.emit(std::move(R), std::move(TSM)); 152 LLVM_DEBUG(ES.runSessionLocked([&]() { 153 dbgs() << "Finished emitting, for " << N << ", " << *this << "\n"; 154 });); 155 } 156 157 char ObjectLayer::ID; 158 159 ObjectLayer::ObjectLayer(ExecutionSession &ES) : ES(ES) {} 160 161 ObjectLayer::~ObjectLayer() = default; 162 163 Error ObjectLayer::add(ResourceTrackerSP RT, std::unique_ptr<MemoryBuffer> O, 164 MaterializationUnit::Interface I) { 165 assert(RT && "RT can not be null"); 166 auto &JD = RT->getJITDylib(); 167 return JD.define(std::make_unique<BasicObjectLayerMaterializationUnit>( 168 *this, std::move(O), std::move(I)), 169 std::move(RT)); 170 } 171 172 Error ObjectLayer::add(ResourceTrackerSP RT, std::unique_ptr<MemoryBuffer> O) { 173 auto I = getObjectFileInterface(getExecutionSession(), O->getMemBufferRef()); 174 if (!I) 175 return I.takeError(); 176 return add(std::move(RT), std::move(O), std::move(*I)); 177 } 178 179 Error ObjectLayer::add(JITDylib &JD, std::unique_ptr<MemoryBuffer> O) { 180 auto I = getObjectFileInterface(getExecutionSession(), O->getMemBufferRef()); 181 if (!I) 182 return I.takeError(); 183 return add(JD, std::move(O), std::move(*I)); 184 } 185 186 Expected<std::unique_ptr<BasicObjectLayerMaterializationUnit>> 187 BasicObjectLayerMaterializationUnit::Create(ObjectLayer &L, 188 std::unique_ptr<MemoryBuffer> O) { 189 190 auto ObjInterface = 191 getObjectFileInterface(L.getExecutionSession(), O->getMemBufferRef()); 192 193 if (!ObjInterface) 194 return ObjInterface.takeError(); 195 196 return std::unique_ptr<BasicObjectLayerMaterializationUnit>( 197 new BasicObjectLayerMaterializationUnit(L, std::move(O), 198 std::move(*ObjInterface))); 199 } 200 201 BasicObjectLayerMaterializationUnit::BasicObjectLayerMaterializationUnit( 202 ObjectLayer &L, std::unique_ptr<MemoryBuffer> O, Interface I) 203 : MaterializationUnit(std::move(I)), L(L), O(std::move(O)) {} 204 205 StringRef BasicObjectLayerMaterializationUnit::getName() const { 206 if (O) 207 return O->getBufferIdentifier(); 208 return "<null object>"; 209 } 210 211 void BasicObjectLayerMaterializationUnit::materialize( 212 std::unique_ptr<MaterializationResponsibility> R) { 213 L.emit(std::move(R), std::move(O)); 214 } 215 216 void BasicObjectLayerMaterializationUnit::discard(const JITDylib &JD, 217 const SymbolStringPtr &Name) { 218 // This is a no-op for object files: Having removed 'Name' from SymbolFlags 219 // the symbol will be dead-stripped by the JIT linker. 220 } 221 222 } // End namespace orc. 223 } // End namespace llvm. 224