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 auto &Flags = SymbolFlags[MangledName]; 80 Flags = JITSymbolFlags::fromGlobalValue(G); 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 98 SymbolFlags[InitSymbol] = JITSymbolFlags::MaterializationSideEffectsOnly; 99 } 100 }); 101 } 102 103 IRMaterializationUnit::IRMaterializationUnit( 104 ThreadSafeModule TSM, Interface I, 105 SymbolNameToDefinitionMap SymbolToDefinition) 106 : MaterializationUnit(std::move(I)), TSM(std::move(TSM)), 107 SymbolToDefinition(std::move(SymbolToDefinition)) {} 108 109 StringRef IRMaterializationUnit::getName() const { 110 if (TSM) 111 return TSM.withModuleDo( 112 [](const Module &M) -> StringRef { return M.getModuleIdentifier(); }); 113 return "<null module>"; 114 } 115 116 void IRMaterializationUnit::discard(const JITDylib &JD, 117 const SymbolStringPtr &Name) { 118 LLVM_DEBUG(JD.getExecutionSession().runSessionLocked([&]() { 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 136 BasicIRLayerMaterializationUnit::BasicIRLayerMaterializationUnit( 137 IRLayer &L, const IRSymbolMapper::ManglingOptions &MO, ThreadSafeModule TSM) 138 : IRMaterializationUnit(L.getExecutionSession(), MO, std::move(TSM)), L(L) { 139 } 140 141 void 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. 146 SymbolToDefinition.clear(); 147 148 // If cloneToNewContextOnEmit is set, clone the module now. 149 if (L.getCloneToNewContextOnEmit()) 150 TSM = cloneToNewContext(TSM); 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 } 164 165 char ObjectLayer::ID; 166 167 ObjectLayer::ObjectLayer(ExecutionSession &ES) : ES(ES) {} 168 169 ObjectLayer::~ObjectLayer() = default; 170 171 Error ObjectLayer::add(ResourceTrackerSP RT, std::unique_ptr<MemoryBuffer> O, 172 MaterializationUnit::Interface I) { 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 180 Error 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 187 Error 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 194 Expected<std::unique_ptr<BasicObjectLayerMaterializationUnit>> 195 BasicObjectLayerMaterializationUnit::Create(ObjectLayer &L, 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 208 BasicObjectLayerMaterializationUnit::BasicObjectLayerMaterializationUnit( 209 ObjectLayer &L, std::unique_ptr<MemoryBuffer> O, Interface I) 210 : MaterializationUnit(std::move(I)), L(L), O(std::move(O)) {} 211 212 StringRef BasicObjectLayerMaterializationUnit::getName() const { 213 if (O) 214 return O->getBufferIdentifier(); 215 return "<null object>"; 216 } 217 218 void BasicObjectLayerMaterializationUnit::materialize( 219 std::unique_ptr<MaterializationResponsibility> R) { 220 L.emit(std::move(R), std::move(O)); 221 } 222 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. 227 } 228 229 } // End namespace orc. 230 } // End namespace llvm. 231