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 IRMaterializationUnit::IRMaterializationUnit( 55 std::unique_ptr<Module> M, SymbolFlagsMap SymbolFlags, 56 SymbolNameToDefinitionMap SymbolToDefinition) 57 : MaterializationUnit(std::move(SymbolFlags)), M(std::move(M)), 58 SymbolToDefinition(std::move(SymbolToDefinition)) {} 59 60 void IRMaterializationUnit::discard(const VSO &V, SymbolStringPtr Name) { 61 auto I = SymbolToDefinition.find(Name); 62 assert(I != SymbolToDefinition.end() && 63 "Symbol not provided by this MU, or previously discarded"); 64 assert(!I->second->isDeclaration() && 65 "Discard should only apply to definitions"); 66 I->second->setLinkage(GlobalValue::AvailableExternallyLinkage); 67 SymbolToDefinition.erase(I); 68 } 69 70 BasicIRLayerMaterializationUnit::BasicIRLayerMaterializationUnit( 71 IRLayer &L, VModuleKey K, std::unique_ptr<Module> M) 72 : IRMaterializationUnit(L.getExecutionSession(), std::move(M)), 73 L(L), K(std::move(K)) {} 74 75 void BasicIRLayerMaterializationUnit::materialize( 76 MaterializationResponsibility R) { 77 L.emit(std::move(R), std::move(K), std::move(M)); 78 } 79 80 ObjectLayer::ObjectLayer(ExecutionSession &ES) : ES(ES) {} 81 82 ObjectLayer::~ObjectLayer() {} 83 84 Error ObjectLayer::add(VSO &V, VModuleKey K, std::unique_ptr<MemoryBuffer> O) { 85 return V.define(llvm::make_unique<BasicObjectLayerMaterializationUnit>( 86 *this, std::move(K), std::move(O))); 87 } 88 89 BasicObjectLayerMaterializationUnit::BasicObjectLayerMaterializationUnit( 90 ObjectLayer &L, VModuleKey K, std::unique_ptr<MemoryBuffer> O) 91 : MaterializationUnit(SymbolFlagsMap()), L(L), K(std::move(K)), 92 O(std::move(O)) { 93 94 auto &ES = L.getExecutionSession(); 95 auto Obj = cantFail( 96 object::ObjectFile::createObjectFile(this->O->getMemBufferRef())); 97 98 for (auto &Sym : Obj->symbols()) { 99 if (!(Sym.getFlags() & object::BasicSymbolRef::SF_Undefined) && 100 (Sym.getFlags() & object::BasicSymbolRef::SF_Exported)) { 101 auto InternedName = 102 ES.getSymbolStringPool().intern(cantFail(Sym.getName())); 103 SymbolFlags[InternedName] = JITSymbolFlags::fromObjectSymbol(Sym); 104 } 105 } 106 } 107 108 void BasicObjectLayerMaterializationUnit::materialize( 109 MaterializationResponsibility R) { 110 L.emit(std::move(R), std::move(K), std::move(O)); 111 } 112 113 void BasicObjectLayerMaterializationUnit::discard(const VSO &V, 114 SymbolStringPtr Name) { 115 // FIXME: Support object file level discard. This could be done by building a 116 // filter to pass to the object layer along with the object itself. 117 } 118 119 } // End namespace orc. 120 } // End namespace llvm. 121