//===-------------------- Layer.cpp - Layer interfaces --------------------===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #include "llvm/ExecutionEngine/Orc/Layer.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/MemoryBuffer.h" namespace llvm { namespace orc { IRLayer::IRLayer(ExecutionSession &ES) : ES(ES) {} IRLayer::~IRLayer() {} Error IRLayer::add(VSO &V, VModuleKey K, std::unique_ptr<Module> M) { return V.define(llvm::make_unique<BasicIRLayerMaterializationUnit>( *this, std::move(K), std::move(M))); } IRMaterializationUnit::IRMaterializationUnit(ExecutionSession &ES, std::unique_ptr<Module> M) : MaterializationUnit(SymbolFlagsMap()), M(std::move(M)) { MangleAndInterner Mangle(ES, this->M->getDataLayout()); for (auto &G : this->M->global_values()) { if (G.hasName() && !G.isDeclaration() && !G.hasLocalLinkage() && !G.hasAvailableExternallyLinkage() && !G.hasAppendingLinkage()) { auto MangledName = Mangle(G.getName()); SymbolFlags[MangledName] = JITSymbolFlags::fromGlobalValue(G); SymbolToDefinition[MangledName] = &G; } } } IRMaterializationUnit::IRMaterializationUnit( std::unique_ptr<Module> M, SymbolFlagsMap SymbolFlags, SymbolNameToDefinitionMap SymbolToDefinition) : MaterializationUnit(std::move(SymbolFlags)), M(std::move(M)), SymbolToDefinition(std::move(SymbolToDefinition)) {} void IRMaterializationUnit::discard(const VSO &V, SymbolStringPtr Name) { auto I = SymbolToDefinition.find(Name); assert(I != SymbolToDefinition.end() && "Symbol not provided by this MU, or previously discarded"); assert(!I->second->isDeclaration() && "Discard should only apply to definitions"); I->second->setLinkage(GlobalValue::AvailableExternallyLinkage); SymbolToDefinition.erase(I); } BasicIRLayerMaterializationUnit::BasicIRLayerMaterializationUnit( IRLayer &L, VModuleKey K, std::unique_ptr<Module> M) : IRMaterializationUnit(L.getExecutionSession(), std::move(M)), L(L), K(std::move(K)) {} void BasicIRLayerMaterializationUnit::materialize( MaterializationResponsibility R) { L.emit(std::move(R), std::move(K), std::move(M)); } ObjectLayer::ObjectLayer(ExecutionSession &ES) : ES(ES) {} ObjectLayer::~ObjectLayer() {} Error ObjectLayer::add(VSO &V, VModuleKey K, std::unique_ptr<MemoryBuffer> O) { return V.define(llvm::make_unique<BasicObjectLayerMaterializationUnit>( *this, std::move(K), std::move(O))); } BasicObjectLayerMaterializationUnit::BasicObjectLayerMaterializationUnit( ObjectLayer &L, VModuleKey K, std::unique_ptr<MemoryBuffer> O) : MaterializationUnit(SymbolFlagsMap()), L(L), K(std::move(K)), O(std::move(O)) { auto &ES = L.getExecutionSession(); auto Obj = cantFail( object::ObjectFile::createObjectFile(this->O->getMemBufferRef())); for (auto &Sym : Obj->symbols()) { if (!(Sym.getFlags() & object::BasicSymbolRef::SF_Undefined) && (Sym.getFlags() & object::BasicSymbolRef::SF_Exported)) { auto InternedName = ES.getSymbolStringPool().intern(cantFail(Sym.getName())); SymbolFlags[InternedName] = JITSymbolFlags::fromObjectSymbol(Sym); } } } void BasicObjectLayerMaterializationUnit::materialize( MaterializationResponsibility R) { L.emit(std::move(R), std::move(K), std::move(O)); } void BasicObjectLayerMaterializationUnit::discard(const VSO &V, SymbolStringPtr Name) { // FIXME: Support object file level discard. This could be done by building a // filter to pass to the object layer along with the object itself. } } // End namespace orc. } // End namespace llvm.