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 if (G.getComdat() && 81 G.getComdat()->getSelectionKind() != Comdat::NoDeduplicate) 82 SymbolFlags[MangledName] |= JITSymbolFlags::Weak; 83 SymbolToDefinition[MangledName] = &G; 84 } 85 86 // If we need an init symbol for this module then create one. 87 if (!getStaticInitGVs(M).empty()) { 88 size_t Counter = 0; 89 90 do { 91 std::string InitSymbolName; 92 raw_string_ostream(InitSymbolName) 93 << "$." << M.getModuleIdentifier() << ".__inits." << Counter++; 94 InitSymbol = ES.intern(InitSymbolName); 95 } while (SymbolFlags.count(InitSymbol)); 96 97 SymbolFlags[InitSymbol] = JITSymbolFlags::MaterializationSideEffectsOnly; 98 } 99 }); 100 } 101 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)) {} 107 108 StringRef IRMaterializationUnit::getName() const { 109 if (TSM) 110 return TSM.withModuleDo( 111 [](const Module &M) -> StringRef { return M.getModuleIdentifier(); }); 112 return "<null module>"; 113 } 114 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"; 120 });); 121 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); 133 } 134 135 BasicIRLayerMaterializationUnit::BasicIRLayerMaterializationUnit( 136 IRLayer &L, const IRSymbolMapper::ManglingOptions &MO, ThreadSafeModule TSM) 137 : IRMaterializationUnit(L.getExecutionSession(), MO, std::move(TSM)), L(L) { 138 } 139 140 void BasicIRLayerMaterializationUnit::materialize( 141 std::unique_ptr<MaterializationResponsibility> R) { 142 143 // Throw away the SymbolToDefinition map: it's not usable after we hand 144 // off the module. 145 SymbolToDefinition.clear(); 146 147 // If cloneToNewContextOnEmit is set, clone the module now. 148 if (L.getCloneToNewContextOnEmit()) 149 TSM = cloneToNewContext(TSM); 150 151 #ifndef NDEBUG 152 auto &ES = R->getTargetJITDylib().getExecutionSession(); 153 auto &N = R->getTargetJITDylib().getName(); 154 #endif // NDEBUG 155 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"; 161 });); 162 } 163 164 char ObjectLayer::ID; 165 166 ObjectLayer::ObjectLayer(ExecutionSession &ES) : ES(ES) {} 167 168 ObjectLayer::~ObjectLayer() = default; 169 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)), 176 std::move(RT)); 177 } 178 179 Error ObjectLayer::add(ResourceTrackerSP RT, std::unique_ptr<MemoryBuffer> O) { 180 auto I = getObjectFileInterface(getExecutionSession(), O->getMemBufferRef()); 181 if (!I) 182 return I.takeError(); 183 return add(std::move(RT), std::move(O), std::move(*I)); 184 } 185 186 Error ObjectLayer::add(JITDylib &JD, std::unique_ptr<MemoryBuffer> O) { 187 auto I = getObjectFileInterface(getExecutionSession(), O->getMemBufferRef()); 188 if (!I) 189 return I.takeError(); 190 return add(JD, std::move(O), std::move(*I)); 191 } 192 193 Expected<std::unique_ptr<BasicObjectLayerMaterializationUnit>> 194 BasicObjectLayerMaterializationUnit::Create(ObjectLayer &L, 195 std::unique_ptr<MemoryBuffer> O) { 196 197 auto ObjInterface = 198 getObjectFileInterface(L.getExecutionSession(), O->getMemBufferRef()); 199 200 if (!ObjInterface) 201 return ObjInterface.takeError(); 202 203 return std::make_unique<BasicObjectLayerMaterializationUnit>( 204 L, std::move(O), std::move(*ObjInterface)); 205 } 206 207 BasicObjectLayerMaterializationUnit::BasicObjectLayerMaterializationUnit( 208 ObjectLayer &L, std::unique_ptr<MemoryBuffer> O, Interface I) 209 : MaterializationUnit(std::move(I)), L(L), O(std::move(O)) {} 210 211 StringRef BasicObjectLayerMaterializationUnit::getName() const { 212 if (O) 213 return O->getBufferIdentifier(); 214 return "<null object>"; 215 } 216 217 void BasicObjectLayerMaterializationUnit::materialize( 218 std::unique_ptr<MaterializationResponsibility> R) { 219 L.emit(std::move(R), std::move(O)); 220 } 221 222 void BasicObjectLayerMaterializationUnit::discard(const JITDylib &JD, 223 const SymbolStringPtr &Name) { 224 // This is a no-op for object files: Having removed 'Name' from SymbolFlags 225 // the symbol will be dead-stripped by the JIT linker. 226 } 227 228 } // End namespace orc. 229 } // End namespace llvm. 230