1 //===-------------------- Layer.cpp - Layer interfaces --------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "llvm/ExecutionEngine/Orc/Layer.h" 11 #include "llvm/IR/Mangler.h" 12 #include "llvm/Object/ObjectFile.h" 13 #include "llvm/Support/MemoryBuffer.h" 14 15 namespace llvm { 16 namespace orc { 17 18 MangleAndInterner::MangleAndInterner(ExecutionSession &ES, const DataLayout &DL) 19 : ES(ES), DL(DL) {} 20 21 SymbolStringPtr MangleAndInterner::operator()(StringRef Name) { 22 std::string MangledName; 23 { 24 raw_string_ostream MangledNameStream(MangledName); 25 Mangler::getNameWithPrefix(MangledNameStream, Name, DL); 26 } 27 return ES.getSymbolStringPool().intern(MangledName); 28 } 29 30 IRLayer::IRLayer(ExecutionSession &ES) : ES(ES) {} 31 IRLayer::~IRLayer() {} 32 33 Error IRLayer::add(VSO &V, VModuleKey K, std::unique_ptr<Module> M) { 34 return V.define(llvm::make_unique<BasicIRLayerMaterializationUnit>( 35 *this, std::move(K), std::move(M))); 36 } 37 38 IRMaterializationUnit::IRMaterializationUnit(ExecutionSession &ES, 39 std::unique_ptr<Module> M) 40 : MaterializationUnit(SymbolFlagsMap()), M(std::move(M)) { 41 42 MangleAndInterner Mangle(ES, this->M->getDataLayout()); 43 for (auto &G : this->M->global_values()) { 44 if (G.hasName() && !G.isDeclaration() && 45 !G.hasLocalLinkage() && 46 !G.hasAvailableExternallyLinkage()) { 47 auto MangledName = Mangle(G.getName()); 48 SymbolFlags[MangledName] = JITSymbolFlags::fromGlobalValue(G); 49 SymbolToDefinition[MangledName] = &G; 50 } 51 } 52 } 53 54 void IRMaterializationUnit::discard(const VSO &V, SymbolStringPtr Name) { 55 auto I = SymbolToDefinition.find(Name); 56 assert(I != SymbolToDefinition.end() && 57 "Symbol not provided by this MU, or previously discarded"); 58 assert(!I->second->isDeclaration() && 59 "Discard should only apply to definitions"); 60 I->second->setLinkage(GlobalValue::AvailableExternallyLinkage); 61 SymbolToDefinition.erase(I); 62 } 63 64 BasicIRLayerMaterializationUnit::BasicIRLayerMaterializationUnit( 65 IRLayer &L, VModuleKey K, std::unique_ptr<Module> M) 66 : IRMaterializationUnit(L.getExecutionSession(), std::move(M)), 67 L(L), K(std::move(K)) {} 68 69 void BasicIRLayerMaterializationUnit::materialize( 70 MaterializationResponsibility R) { 71 L.emit(std::move(R), std::move(K), std::move(M)); 72 } 73 74 ObjectLayer::ObjectLayer(ExecutionSession &ES) : ES(ES) {} 75 76 ObjectLayer::~ObjectLayer() {} 77 78 Error ObjectLayer::add(VSO &V, VModuleKey K, std::unique_ptr<MemoryBuffer> O) { 79 return V.define(llvm::make_unique<BasicObjectLayerMaterializationUnit>( 80 *this, std::move(K), std::move(O))); 81 } 82 83 BasicObjectLayerMaterializationUnit::BasicObjectLayerMaterializationUnit( 84 ObjectLayer &L, VModuleKey K, std::unique_ptr<MemoryBuffer> O) 85 : MaterializationUnit(SymbolFlagsMap()), L(L), K(std::move(K)), 86 O(std::move(O)) { 87 88 auto &ES = L.getExecutionSession(); 89 auto Obj = cantFail( 90 object::ObjectFile::createObjectFile(this->O->getMemBufferRef())); 91 92 for (auto &Sym : Obj->symbols()) { 93 if (!(Sym.getFlags() & object::BasicSymbolRef::SF_Undefined) && 94 (Sym.getFlags() & object::BasicSymbolRef::SF_Exported)) { 95 auto InternedName = 96 ES.getSymbolStringPool().intern(cantFail(Sym.getName())); 97 SymbolFlags[InternedName] = JITSymbolFlags::fromObjectSymbol(Sym); 98 } 99 } 100 } 101 102 void BasicObjectLayerMaterializationUnit::materialize( 103 MaterializationResponsibility R) { 104 L.emit(std::move(R), std::move(K), std::move(O)); 105 } 106 107 void BasicObjectLayerMaterializationUnit::discard(const VSO &V, 108 SymbolStringPtr Name) { 109 // FIXME: Support object file level discard. This could be done by building a 110 // filter to pass to the object layer along with the object itself. 111 } 112 113 } // End namespace orc. 114 } // End namespace llvm. 115