LCOV - code coverage report
Current view: top level - lib/ExecutionEngine/Orc - Layer.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 59 70 84.3 %
Date: 2018-10-20 13:21:21 Functions: 15 20 75.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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/Object/ObjectFile.h"
      12             : #include "llvm/Support/Debug.h"
      13             : 
      14             : #define DEBUG_TYPE "orc"
      15             : 
      16             : namespace llvm {
      17             : namespace orc {
      18             : 
      19          41 : IRLayer::IRLayer(ExecutionSession &ES) : ES(ES) {}
      20          38 : IRLayer::~IRLayer() {}
      21             : 
      22          16 : Error IRLayer::add(JITDylib &JD, ThreadSafeModule TSM, VModuleKey K) {
      23          16 :   return JD.define(llvm::make_unique<BasicIRLayerMaterializationUnit>(
      24          16 :       *this, std::move(K), std::move(TSM)));
      25             : }
      26             : 
      27          52 : IRMaterializationUnit::IRMaterializationUnit(ExecutionSession &ES,
      28          52 :                                              ThreadSafeModule TSM, VModuleKey K)
      29         104 :     : MaterializationUnit(SymbolFlagsMap(), std::move(K)), TSM(std::move(TSM)) {
      30             : 
      31             :   assert(this->TSM && "Module must not be null");
      32             : 
      33          52 :   MangleAndInterner Mangle(ES, this->TSM.getModule()->getDataLayout());
      34         299 :   for (auto &G : this->TSM.getModule()->global_values()) {
      35         279 :     if (G.hasName() && !G.isDeclaration() && !G.hasLocalLinkage() &&
      36         281 :         !G.hasAvailableExternallyLinkage() && !G.hasAppendingLinkage()) {
      37          83 :       auto MangledName = Mangle(G.getName());
      38          83 :       SymbolFlags[MangledName] = JITSymbolFlags::fromGlobalValue(G);
      39          83 :       SymbolToDefinition[MangledName] = &G;
      40             :     }
      41             :   }
      42          52 : }
      43             : 
      44           0 : IRMaterializationUnit::IRMaterializationUnit(
      45             :     ThreadSafeModule TSM, VModuleKey K, SymbolFlagsMap SymbolFlags,
      46           0 :     SymbolNameToDefinitionMap SymbolToDefinition)
      47             :     : MaterializationUnit(std::move(SymbolFlags), std::move(K)),
      48           0 :       TSM(std::move(TSM)), SymbolToDefinition(std::move(SymbolToDefinition)) {}
      49             : 
      50           0 : StringRef IRMaterializationUnit::getName() const {
      51           0 :   if (TSM.getModule())
      52           0 :     return TSM.getModule()->getModuleIdentifier();
      53           0 :   return "<null module>";
      54             : }
      55             : 
      56           1 : void IRMaterializationUnit::discard(const JITDylib &JD,
      57             :                                     const SymbolStringPtr &Name) {
      58             :   LLVM_DEBUG(JD.getExecutionSession().runSessionLocked([&]() {
      59             :     dbgs() << "In " << JD.getName() << " discarding " << *Name << " from MU@"
      60             :            << this << " (" << getName() << ")\n";
      61             :   }););
      62             : 
      63             :   auto I = SymbolToDefinition.find(Name);
      64             :   assert(I != SymbolToDefinition.end() &&
      65             :          "Symbol not provided by this MU, or previously discarded");
      66             :   assert(!I->second->isDeclaration() &&
      67             :          "Discard should only apply to definitions");
      68           1 :   I->second->setLinkage(GlobalValue::AvailableExternallyLinkage);
      69             :   SymbolToDefinition.erase(I);
      70           1 : }
      71             : 
      72          16 : BasicIRLayerMaterializationUnit::BasicIRLayerMaterializationUnit(
      73          16 :     IRLayer &L, VModuleKey K, ThreadSafeModule TSM)
      74             :     : IRMaterializationUnit(L.getExecutionSession(), std::move(TSM),
      75             :                             std::move(K)),
      76          32 :       L(L), K(std::move(K)) {}
      77             : 
      78          15 : void BasicIRLayerMaterializationUnit::materialize(
      79             :     MaterializationResponsibility R) {
      80             : 
      81             :   // Throw away the SymbolToDefinition map: it's not usable after we hand
      82             :   // off the module.
      83             :   SymbolToDefinition.clear();
      84             : 
      85             :   // If cloneToNewContextOnEmit is set, clone the module now.
      86          15 :   if (L.getCloneToNewContextOnEmit())
      87           2 :     TSM = cloneToNewContext(TSM);
      88             : 
      89             : #ifndef NDEBUG
      90             :   auto &ES = R.getTargetJITDylib().getExecutionSession();
      91             : #endif // NDEBUG
      92             : 
      93          15 :   auto Lock = TSM.getContextLock();
      94             :   LLVM_DEBUG(ES.runSessionLocked([&]() {
      95             :     dbgs() << "Emitting, for " << R.getTargetJITDylib().getName() << ", "
      96             :            << *this << "\n";
      97             :   }););
      98          30 :   L.emit(std::move(R), std::move(TSM));
      99             :   LLVM_DEBUG(ES.runSessionLocked([&]() {
     100             :     dbgs() << "Finished emitting, for " << R.getTargetJITDylib().getName()
     101             :            << ", " << *this << "\n";
     102             :   }););
     103          15 : }
     104             : 
     105          17 : ObjectLayer::ObjectLayer(ExecutionSession &ES) : ES(ES) {}
     106             : 
     107          16 : ObjectLayer::~ObjectLayer() {}
     108             : 
     109           6 : Error ObjectLayer::add(JITDylib &JD, std::unique_ptr<MemoryBuffer> O,
     110             :                        VModuleKey K) {
     111             :   auto ObjMU = BasicObjectLayerMaterializationUnit::Create(*this, std::move(K),
     112          18 :                                                            std::move(O));
     113           6 :   if (!ObjMU)
     114             :     return ObjMU.takeError();
     115           5 :   return JD.define(std::move(*ObjMU));
     116             : }
     117             : 
     118             : Expected<std::unique_ptr<BasicObjectLayerMaterializationUnit>>
     119           6 : BasicObjectLayerMaterializationUnit::Create(ObjectLayer &L, VModuleKey K,
     120             :                                             std::unique_ptr<MemoryBuffer> O) {
     121             :   auto SymbolFlags =
     122          12 :       getObjectSymbolFlags(L.getExecutionSession(), O->getMemBufferRef());
     123             : 
     124           6 :   if (!SymbolFlags)
     125             :     return SymbolFlags.takeError();
     126             : 
     127           5 :   return std::unique_ptr<BasicObjectLayerMaterializationUnit>(
     128             :       new BasicObjectLayerMaterializationUnit(L, K, std::move(O),
     129           5 :                                               std::move(*SymbolFlags)));
     130             : }
     131             : 
     132           5 : BasicObjectLayerMaterializationUnit::BasicObjectLayerMaterializationUnit(
     133             :     ObjectLayer &L, VModuleKey K, std::unique_ptr<MemoryBuffer> O,
     134           5 :     SymbolFlagsMap SymbolFlags)
     135             :     : MaterializationUnit(std::move(SymbolFlags), std::move(K)), L(L),
     136          10 :       O(std::move(O)) {}
     137             : 
     138           0 : StringRef BasicObjectLayerMaterializationUnit::getName() const {
     139           0 :   if (O)
     140           0 :     return O->getBufferIdentifier();
     141           0 :   return "<null object>";
     142             : }
     143             : 
     144           5 : void BasicObjectLayerMaterializationUnit::materialize(
     145             :     MaterializationResponsibility R) {
     146          10 :   L.emit(std::move(R), std::move(O));
     147           5 : }
     148             : 
     149           1 : void BasicObjectLayerMaterializationUnit::discard(const JITDylib &JD,
     150             :                                                   const SymbolStringPtr &Name) {
     151             :   // FIXME: Support object file level discard. This could be done by building a
     152             :   //        filter to pass to the object layer along with the object itself.
     153           1 : }
     154             : 
     155           6 : Expected<SymbolFlagsMap> getObjectSymbolFlags(ExecutionSession &ES,
     156             :                                               MemoryBufferRef ObjBuffer) {
     157          12 :   auto Obj = object::ObjectFile::createObjectFile(ObjBuffer);
     158             : 
     159           6 :   if (!Obj)
     160             :     return Obj.takeError();
     161             : 
     162             :   SymbolFlagsMap SymbolFlags;
     163          23 :   for (auto &Sym : (*Obj)->symbols()) {
     164             :     // Skip symbols not defined in this object file.
     165          18 :     if (Sym.getFlags() & object::BasicSymbolRef::SF_Undefined)
     166          12 :       continue;
     167             : 
     168             :     // Skip symbols that are not global.
     169          13 :     if (!(Sym.getFlags() & object::BasicSymbolRef::SF_Global))
     170             :       continue;
     171             : 
     172             :     auto Name = Sym.getName();
     173           6 :     if (!Name)
     174             :       return Name.takeError();
     175           6 :     auto InternedName = ES.intern(*Name);
     176           6 :     auto SymFlags = JITSymbolFlags::fromObjectSymbol(Sym);
     177           6 :     if (!SymFlags)
     178             :       return SymFlags.takeError();
     179           6 :     SymbolFlags[InternedName] = std::move(*SymFlags);
     180             :   }
     181             : 
     182             :   return SymbolFlags;
     183             : }
     184             : 
     185             : } // End namespace orc.
     186             : } // End namespace llvm.

Generated by: LCOV version 1.13