LCOV - code coverage report
Current view: top level - include/llvm/ExecutionEngine/Orc - CompileOnDemandLayer.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 175 191 91.6 %
Date: 2018-06-17 00:07:59 Functions: 48 59 81.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- CompileOnDemandLayer.h - Compile each function on demand -*- C++ -*-===//
       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             : // JIT layer for breaking up modules and inserting callbacks to allow
      11             : // individual functions to be compiled on demand.
      12             : //
      13             : //===----------------------------------------------------------------------===//
      14             : 
      15             : #ifndef LLVM_EXECUTIONENGINE_ORC_COMPILEONDEMANDLAYER_H
      16             : #define LLVM_EXECUTIONENGINE_ORC_COMPILEONDEMANDLAYER_H
      17             : 
      18             : #include "llvm/ADT/APInt.h"
      19             : #include "llvm/ADT/STLExtras.h"
      20             : #include "llvm/ADT/StringRef.h"
      21             : #include "llvm/ADT/Twine.h"
      22             : #include "llvm/ExecutionEngine/JITSymbol.h"
      23             : #include "llvm/ExecutionEngine/Orc/Core.h"
      24             : #include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
      25             : #include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
      26             : #include "llvm/ExecutionEngine/Orc/OrcError.h"
      27             : #include "llvm/ExecutionEngine/RuntimeDyld.h"
      28             : #include "llvm/IR/Attributes.h"
      29             : #include "llvm/IR/Constant.h"
      30             : #include "llvm/IR/Constants.h"
      31             : #include "llvm/IR/DataLayout.h"
      32             : #include "llvm/IR/Function.h"
      33             : #include "llvm/IR/GlobalAlias.h"
      34             : #include "llvm/IR/GlobalValue.h"
      35             : #include "llvm/IR/GlobalVariable.h"
      36             : #include "llvm/IR/Instruction.h"
      37             : #include "llvm/IR/Mangler.h"
      38             : #include "llvm/IR/Module.h"
      39             : #include "llvm/IR/Type.h"
      40             : #include "llvm/Support/Casting.h"
      41             : #include "llvm/Support/raw_ostream.h"
      42             : #include "llvm/Transforms/Utils/ValueMapper.h"
      43             : #include <algorithm>
      44             : #include <cassert>
      45             : #include <functional>
      46             : #include <iterator>
      47             : #include <list>
      48             : #include <memory>
      49             : #include <set>
      50             : #include <string>
      51             : #include <utility>
      52             : #include <vector>
      53             : 
      54             : namespace llvm {
      55             : 
      56             : class Value;
      57             : 
      58             : namespace orc {
      59             : 
      60             : /// Compile-on-demand layer.
      61             : ///
      62             : ///   When a module is added to this layer a stub is created for each of its
      63             : /// function definitions. The stubs and other global values are immediately
      64             : /// added to the layer below. When a stub is called it triggers the extraction
      65             : /// of the function body from the original module. The extracted body is then
      66             : /// compiled and executed.
      67             : template <typename BaseLayerT,
      68             :           typename CompileCallbackMgrT = JITCompileCallbackManager,
      69             :           typename IndirectStubsMgrT = IndirectStubsManager>
      70             : class CompileOnDemandLayer {
      71             : private:
      72             :   template <typename MaterializerFtor>
      73             :   class LambdaMaterializer final : public ValueMaterializer {
      74             :   public:
      75          20 :     LambdaMaterializer(MaterializerFtor M) : M(std::move(M)) {}
      76             : 
      77          51 :     Value *materialize(Value *V) final { return M(V); }
      78             : 
      79             :   private:
      80             :     MaterializerFtor M;
      81             :   };
      82             : 
      83             :   template <typename MaterializerFtor>
      84             :   LambdaMaterializer<MaterializerFtor>
      85             :   createLambdaMaterializer(MaterializerFtor M) {
      86             :     return LambdaMaterializer<MaterializerFtor>(std::move(M));
      87             :   }
      88             : 
      89             :   // Provide type-erasure for the Modules and MemoryManagers.
      90             :   template <typename ResourceT>
      91             :   class ResourceOwner {
      92             :   public:
      93             :     ResourceOwner() = default;
      94             :     ResourceOwner(const ResourceOwner &) = delete;
      95             :     ResourceOwner &operator=(const ResourceOwner &) = delete;
      96             :     virtual ~ResourceOwner() = default;
      97             : 
      98             :     virtual ResourceT& getResource() const = 0;
      99             :   };
     100             : 
     101             :   template <typename ResourceT, typename ResourcePtrT>
     102             :   class ResourceOwnerImpl : public ResourceOwner<ResourceT> {
     103             :   public:
     104             :     ResourceOwnerImpl(ResourcePtrT ResourcePtr)
     105             :       : ResourcePtr(std::move(ResourcePtr)) {}
     106             : 
     107             :     ResourceT& getResource() const override { return *ResourcePtr; }
     108             : 
     109             :   private:
     110             :     ResourcePtrT ResourcePtr;
     111             :   };
     112             : 
     113             :   template <typename ResourceT, typename ResourcePtrT>
     114             :   std::unique_ptr<ResourceOwner<ResourceT>>
     115             :   wrapOwnership(ResourcePtrT ResourcePtr) {
     116             :     using RO = ResourceOwnerImpl<ResourceT, ResourcePtrT>;
     117             :     return llvm::make_unique<RO>(std::move(ResourcePtr));
     118             :   }
     119             : 
     120             :   class StaticGlobalRenamer {
     121             :   public:
     122           8 :     StaticGlobalRenamer() = default;
     123             :     StaticGlobalRenamer(StaticGlobalRenamer &&) = default;
     124             :     StaticGlobalRenamer &operator=(StaticGlobalRenamer &&) = default;
     125             : 
     126           9 :     void rename(Module &M) {
     127          32 :       for (auto &F : M)
     128             :         if (F.hasLocalLinkage())
     129           6 :           F.setName("$static." + Twine(NextId++));
     130          17 :       for (auto &G : M.globals())
     131             :         if (G.hasLocalLinkage())
     132           6 :           G.setName("$static." + Twine(NextId++));
     133           9 :     }
     134             : 
     135             :   private:
     136             :     unsigned NextId = 0;
     137             :   };
     138             : 
     139         120 :   struct LogicalDylib {
     140          29 :     struct SourceModuleEntry {
     141             :       std::unique_ptr<Module> SourceMod;
     142             :       std::set<Function*> StubsToClone;
     143             :     };
     144             : 
     145             :     using SourceModulesList = std::vector<SourceModuleEntry>;
     146             :     using SourceModuleHandle = typename SourceModulesList::size_type;
     147             : 
     148             :     LogicalDylib() = default;
     149             : 
     150           8 :     LogicalDylib(VModuleKey K, std::shared_ptr<SymbolResolver> BackingResolver,
     151             :                  std::unique_ptr<IndirectStubsMgrT> StubsMgr)
     152             :         : K(std::move(K)), BackingResolver(std::move(BackingResolver)),
     153           8 :           StubsMgr(std::move(StubsMgr)) {}
     154             : 
     155           9 :     SourceModuleHandle addSourceModule(std::unique_ptr<Module> M) {
     156           9 :       SourceModuleHandle H = SourceModules.size();
     157          18 :       SourceModules.push_back(SourceModuleEntry());
     158           9 :       SourceModules.back().SourceMod = std::move(M);
     159           9 :       return H;
     160             :     }
     161             : 
     162             :     Module& getSourceModule(SourceModuleHandle H) {
     163          32 :       return *SourceModules[H].SourceMod;
     164             :     }
     165             : 
     166             :     std::set<Function*>& getStubsToClone(SourceModuleHandle H) {
     167          29 :       return SourceModules[H].StubsToClone;
     168             :     }
     169             : 
     170          34 :     JITSymbol findSymbol(BaseLayerT &BaseLayer, const std::string &Name,
     171             :                          bool ExportedSymbolsOnly) {
     172          68 :       if (auto Sym = StubsMgr->findStub(Name, ExportedSymbolsOnly))
     173          11 :         return Sym;
     174          39 :       for (auto BLK : BaseLayerVModuleKeys)
     175          16 :         if (auto Sym = BaseLayer.findSymbolIn(BLK, Name, ExportedSymbolsOnly))
     176          14 :           return Sym;
     177          16 :         else if (auto Err = Sym.takeError())
     178             :           return std::move(Err);
     179             :       return nullptr;
     180             :     }
     181             : 
     182           0 :     Error removeModulesFromBaseLayer(BaseLayerT &BaseLayer) {
     183          28 :       for (auto &BLK : BaseLayerVModuleKeys)
     184          20 :         if (auto Err = BaseLayer.removeModule(BLK))
     185             :           return Err;
     186             :       return Error::success();
     187             :     }
     188             : 
     189             :     VModuleKey K;
     190             :     std::shared_ptr<SymbolResolver> BackingResolver;
     191             :     std::unique_ptr<IndirectStubsMgrT> StubsMgr;
     192             :     StaticGlobalRenamer StaticRenamer;
     193             :     SourceModulesList SourceModules;
     194             :     std::vector<VModuleKey> BaseLayerVModuleKeys;
     195             :   };
     196             : 
     197             : public:
     198             : 
     199             :   /// Module partitioning functor.
     200             :   using PartitioningFtor = std::function<std::set<Function*>(Function&)>;
     201             : 
     202             :   /// Builder for IndirectStubsManagers.
     203             :   using IndirectStubsManagerBuilderT =
     204             :       std::function<std::unique_ptr<IndirectStubsMgrT>()>;
     205             : 
     206             :   using SymbolResolverGetter =
     207             :       std::function<std::shared_ptr<SymbolResolver>(VModuleKey K)>;
     208             : 
     209             :   using SymbolResolverSetter =
     210             :       std::function<void(VModuleKey K, std::shared_ptr<SymbolResolver> R)>;
     211             : 
     212             :   /// Construct a compile-on-demand layer instance.
     213          12 :   CompileOnDemandLayer(ExecutionSession &ES, BaseLayerT &BaseLayer,
     214             :                        SymbolResolverGetter GetSymbolResolver,
     215             :                        SymbolResolverSetter SetSymbolResolver,
     216             :                        PartitioningFtor Partition,
     217             :                        CompileCallbackMgrT &CallbackMgr,
     218             :                        IndirectStubsManagerBuilderT CreateIndirectStubsManager,
     219             :                        bool CloneStubsIntoPartitions = true)
     220             :       : ES(ES), BaseLayer(BaseLayer),
     221             :         GetSymbolResolver(std::move(GetSymbolResolver)),
     222             :         SetSymbolResolver(std::move(SetSymbolResolver)),
     223             :         Partition(std::move(Partition)), CompileCallbackMgr(CallbackMgr),
     224             :         CreateIndirectStubsManager(std::move(CreateIndirectStubsManager)),
     225          36 :         CloneStubsIntoPartitions(CloneStubsIntoPartitions) {}
     226             : 
     227          12 :   ~CompileOnDemandLayer() {
     228             :     // FIXME: Report error on log.
     229          26 :     while (!LogicalDylibs.empty())
     230          14 :       consumeError(removeModule(LogicalDylibs.begin()->first));
     231          12 :   }
     232             : 
     233             :   /// Add a module to the compile-on-demand layer.
     234           8 :   Error addModule(VModuleKey K, std::unique_ptr<Module> M) {
     235             : 
     236             :     assert(!LogicalDylibs.count(K) && "VModuleKey K already in use");
     237          24 :     auto I = LogicalDylibs.insert(
     238             :         LogicalDylibs.end(),
     239             :         std::make_pair(K, LogicalDylib(K, GetSymbolResolver(K),
     240             :                                        CreateIndirectStubsManager())));
     241             : 
     242           8 :     return addLogicalModule(I->second, std::move(M));
     243             :   }
     244             : 
     245             :   /// Add extra modules to an existing logical module.
     246           1 :   Error addExtraModule(VModuleKey K, std::unique_ptr<Module> M) {
     247           1 :     return addLogicalModule(LogicalDylibs[K], std::move(M));
     248             :   }
     249             : 
     250             :   /// Remove the module represented by the given key.
     251             :   ///
     252             :   ///   This will remove all modules in the layers below that were derived from
     253             :   /// the module represented by K.
     254           8 :   Error removeModule(VModuleKey K) {
     255             :     auto I = LogicalDylibs.find(K);
     256             :     assert(I != LogicalDylibs.end() && "VModuleKey K not valid here");
     257           8 :     auto Err = I->second.removeModulesFromBaseLayer(BaseLayer);
     258             :     LogicalDylibs.erase(I);
     259           8 :     return Err;
     260             :   }
     261             : 
     262             :   /// Search for the given named symbol.
     263             :   /// @param Name The name of the symbol to search for.
     264             :   /// @param ExportedSymbolsOnly If true, search only for exported symbols.
     265             :   /// @return A handle for the given named symbol, if it exists.
     266          22 :   JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly) {
     267          29 :     for (auto &KV : LogicalDylibs) {
     268          15 :       if (auto Sym = KV.second.StubsMgr->findStub(Name, ExportedSymbolsOnly))
     269           8 :         return Sym;
     270          21 :       if (auto Sym = findSymbolIn(KV.first, Name, ExportedSymbolsOnly))
     271           0 :         return Sym;
     272           7 :       else if (auto Err = Sym.takeError())
     273             :         return std::move(Err);
     274             :     }
     275          28 :     return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
     276             :   }
     277             : 
     278             :   /// Get the address of a symbol provided by this layer, or some layer
     279             :   ///        below this one.
     280           8 :   JITSymbol findSymbolIn(VModuleKey K, const std::string &Name,
     281             :                          bool ExportedSymbolsOnly) {
     282             :     assert(LogicalDylibs.count(K) && "VModuleKey K is not valid here");
     283           8 :     return LogicalDylibs[K].findSymbol(BaseLayer, Name, ExportedSymbolsOnly);
     284             :   }
     285             : 
     286             :   /// Update the stub for the given function to point at FnBodyAddr.
     287             :   /// This can be used to support re-optimization.
     288             :   /// @return true if the function exists and the stub is updated, false
     289             :   ///         otherwise.
     290             :   //
     291             :   // FIXME: We should track and free associated resources (unused compile
     292             :   //        callbacks, uncompiled IR, and no-longer-needed/reachable function
     293             :   //        implementations).
     294             :   Error updatePointer(std::string FuncName, JITTargetAddress FnBodyAddr) {
     295             :     //Find out which logical dylib contains our symbol
     296             :     auto LDI = LogicalDylibs.begin();
     297             :     for (auto LDE = LogicalDylibs.end(); LDI != LDE; ++LDI) {
     298             :       if (auto LMResources =
     299             :             LDI->getLogicalModuleResourcesForSymbol(FuncName, false)) {
     300             :         Module &SrcM = LMResources->SourceModule->getResource();
     301             :         std::string CalledFnName = mangle(FuncName, SrcM.getDataLayout());
     302             :         if (auto Err = LMResources->StubsMgr->updatePointer(CalledFnName,
     303             :                                                             FnBodyAddr))
     304             :           return Err;
     305             :         return Error::success();
     306             :       }
     307             :     }
     308             :     return make_error<JITSymbolNotFound>(FuncName);
     309             :   }
     310             : 
     311             : private:
     312           9 :   Error addLogicalModule(LogicalDylib &LD, std::unique_ptr<Module> SrcMPtr) {
     313             : 
     314             :     // Rename all static functions / globals to $static.X :
     315             :     // This will unique the names across all modules in the logical dylib,
     316             :     // simplifying symbol lookup.
     317          18 :     LD.StaticRenamer.rename(*SrcMPtr);
     318             : 
     319             :     // Bump the linkage and rename any anonymous/privote members in SrcM to
     320             :     // ensure that everything will resolve properly after we partition SrcM.
     321           9 :     makeAllSymbolsExternallyAccessible(*SrcMPtr);
     322             : 
     323             :     // Create a logical module handle for SrcM within the logical dylib.
     324             :     Module &SrcM = *SrcMPtr;
     325           9 :     auto LMId = LD.addSourceModule(std::move(SrcMPtr));
     326             : 
     327             :     // Create stub functions.
     328           9 :     const DataLayout &DL = SrcM.getDataLayout();
     329             :     {
     330           9 :       typename IndirectStubsMgrT::StubInitsMap StubInits;
     331          32 :       for (auto &F : SrcM) {
     332             :         // Skip declarations.
     333          23 :         if (F.isDeclaration())
     334          11 :           continue;
     335             : 
     336             :         // Skip weak functions for which we already have definitions.
     337          18 :         auto MangledName = mangle(F.getName(), DL);
     338          18 :         if (F.hasWeakLinkage() || F.hasLinkOnceLinkage()) {
     339           6 :           if (auto Sym = LD.findSymbol(BaseLayer, MangledName, false))
     340           1 :             continue;
     341           2 :           else if (auto Err = Sym.takeError())
     342             :             return std::move(Err);
     343             :         }
     344             : 
     345             :         // Record all functions defined by this module.
     346          17 :         if (CloneStubsIntoPartitions)
     347          32 :           LD.getStubsToClone(LMId).insert(&F);
     348             : 
     349             :         // Create a callback, associate it with the stub for the function,
     350             :         // and set the compile action to compile the partition containing the
     351             :         // function.
     352          16 :         auto CompileAction = [this, &LD, LMId, &F]() -> JITTargetAddress {
     353          32 :           if (auto FnImplAddrOrErr = this->extractAndCompile(LD, LMId, F))
     354          16 :             return *FnImplAddrOrErr;
     355             :           else {
     356             :             // FIXME: Report error, return to 'abort' or something similar.
     357           0 :             consumeError(FnImplAddrOrErr.takeError());
     358           0 :             return 0;
     359             :           }
     360             :         };
     361          51 :         if (auto CCAddr =
     362          17 :                 CompileCallbackMgr.getCompileCallback(std::move(CompileAction)))
     363             :           StubInits[MangledName] =
     364          34 :               std::make_pair(*CCAddr, JITSymbolFlags::fromGlobalValue(F));
     365             :         else
     366             :           return CCAddr.takeError();
     367             :       }
     368             : 
     369          18 :       if (auto Err = LD.StubsMgr->createStubs(StubInits))
     370             :         return Err;
     371             :     }
     372             : 
     373             :     // If this module doesn't contain any globals, aliases, or module flags then
     374             :     // we can bail out early and avoid the overhead of creating and managing an
     375             :     // empty globals module.
     376          21 :     if (SrcM.global_empty() && SrcM.alias_empty() &&
     377           6 :         !SrcM.getModuleFlagsMetadata())
     378             :       return Error::success();
     379             : 
     380             :     // Create the GlobalValues module.
     381          20 :     auto GVsM = llvm::make_unique<Module>((SrcM.getName() + ".globals").str(),
     382             :                                           SrcM.getContext());
     383           4 :     GVsM->setDataLayout(DL);
     384             : 
     385           4 :     ValueToValueMapTy VMap;
     386             : 
     387             :     // Clone global variable decls.
     388          12 :     for (auto &GV : SrcM.globals())
     389          16 :       if (!GV.isDeclaration() && !VMap.count(&GV))
     390           7 :         cloneGlobalVariableDecl(*GVsM, GV, &VMap);
     391             : 
     392             :     // And the aliases.
     393           6 :     for (auto &A : SrcM.aliases())
     394           4 :       if (!VMap.count(&A))
     395           2 :         cloneGlobalAliasDecl(*GVsM, A, VMap);
     396             : 
     397             :     // Clone the module flags.
     398           4 :     cloneModuleFlagsMetadata(*GVsM, SrcM, VMap);
     399             : 
     400             :     // Now we need to clone the GV and alias initializers.
     401             : 
     402             :     // Initializers may refer to functions declared (but not defined) in this
     403             :     // module. Build a materializer to clone decls on demand.
     404             :     auto Materializer = createLambdaMaterializer(
     405          20 :       [&LD, &GVsM](Value *V) -> Value* {
     406             :         if (auto *F = dyn_cast<Function>(V)) {
     407             :           // Decls in the original module just get cloned.
     408           2 :           if (F->isDeclaration())
     409           0 :             return cloneFunctionDecl(*GVsM, *F);
     410             : 
     411             :           // Definitions in the original module (which we have emitted stubs
     412             :           // for at this point) get turned into a constant alias to the stub
     413             :           // instead.
     414           2 :           const DataLayout &DL = GVsM->getDataLayout();
     415           2 :           std::string FName = mangle(F->getName(), DL);
     416           2 :           unsigned PtrBitWidth = DL.getPointerTypeSizeInBits(F->getType());
     417           2 :           JITTargetAddress StubAddr =
     418           6 :             LD.StubsMgr->findStub(FName, false).getAddress();
     419             : 
     420           2 :           ConstantInt *StubAddrCI =
     421           4 :             ConstantInt::get(GVsM->getContext(), APInt(PtrBitWidth, StubAddr));
     422           2 :           Constant *Init = ConstantExpr::getCast(Instruction::IntToPtr,
     423             :                                                  StubAddrCI, F->getType());
     424           2 :           return GlobalAlias::create(F->getFunctionType(),
     425             :                                      F->getType()->getAddressSpace(),
     426           4 :                                      F->getLinkage(), F->getName(),
     427           2 :                                      Init, GVsM.get());
     428             :         }
     429             :         // else....
     430             :         return nullptr;
     431             :       });
     432             : 
     433             :     // Clone the global variable initializers.
     434          12 :     for (auto &GV : SrcM.globals())
     435           8 :       if (!GV.isDeclaration())
     436           7 :         moveGlobalVariableInitializer(GV, VMap, &Materializer);
     437             : 
     438             :     // Clone the global alias initializers.
     439           6 :     for (auto &A : SrcM.aliases()) {
     440           2 :       auto *NewA = cast<GlobalAlias>(VMap[&A]);
     441             :       assert(NewA && "Alias not cloned?");
     442           2 :       Value *Init = MapValue(A.getAliasee(), VMap, RF_None, nullptr,
     443             :                              &Materializer);
     444           2 :       NewA->setAliasee(cast<Constant>(Init));
     445             :     }
     446             : 
     447             :     // Build a resolver for the globals module and add it to the base layer.
     448           2 :     auto LegacyLookup = [this, &LD](const std::string &Name) -> JITSymbol {
     449           2 :       if (auto Sym = LD.StubsMgr->findStub(Name, false))
     450           0 :         return Sym;
     451             : 
     452           2 :       if (auto Sym = LD.findSymbol(BaseLayer, Name, false))
     453           0 :         return Sym;
     454           1 :       else if (auto Err = Sym.takeError())
     455             :         return std::move(Err);
     456             : 
     457             :       return nullptr;
     458             :     };
     459             : 
     460           8 :     auto GVsResolver = createSymbolResolver(
     461             :         [&LD, LegacyLookup](SymbolFlagsMap &SymbolFlags,
     462           6 :                             const SymbolNameSet &Symbols) {
     463           6 :           auto NotFoundViaLegacyLookup =
     464             :               lookupFlagsWithLegacyFn(SymbolFlags, Symbols, LegacyLookup);
     465             : 
     466           3 :           if (!NotFoundViaLegacyLookup) {
     467           0 :             logAllUnhandledErrors(NotFoundViaLegacyLookup.takeError(), errs(),
     468             :                                   "CODLayer/GVsResolver flags lookup failed: ");
     469             :             SymbolFlags.clear();
     470           0 :             return SymbolNameSet();
     471             :           }
     472             : 
     473             :           return LD.BackingResolver->lookupFlags(SymbolFlags,
     474           3 :                                                  *NotFoundViaLegacyLookup);
     475             :         },
     476             :         [this, &LD,
     477             :          LegacyLookup](std::shared_ptr<AsynchronousSymbolQuery> Query,
     478           0 :                        SymbolNameSet Symbols) {
     479           0 :           auto NotFoundViaLegacyLookup =
     480             :               lookupWithLegacyFn(ES, *Query, Symbols, LegacyLookup);
     481           0 :           return LD.BackingResolver->lookup(Query, NotFoundViaLegacyLookup);
     482             :         });
     483             : 
     484           8 :     SetSymbolResolver(LD.K, std::move(GVsResolver));
     485             : 
     486          12 :     if (auto Err = BaseLayer.addModule(LD.K, std::move(GVsM)))
     487             :       return Err;
     488             : 
     489           4 :     LD.BaseLayerVModuleKeys.push_back(LD.K);
     490             : 
     491             :     return Error::success();
     492             :   }
     493             : 
     494          52 :   static std::string mangle(StringRef Name, const DataLayout &DL) {
     495             :     std::string MangledName;
     496             :     {
     497          52 :       raw_string_ostream MangledNameStream(MangledName);
     498          52 :       Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
     499             :     }
     500          52 :     return MangledName;
     501             :   }
     502             : 
     503             :   Expected<JITTargetAddress>
     504          16 :   extractAndCompile(LogicalDylib &LD,
     505             :                     typename LogicalDylib::SourceModuleHandle LMId,
     506             :                     Function &F) {
     507             :     Module &SrcM = LD.getSourceModule(LMId);
     508             : 
     509             :     // If F is a declaration we must already have compiled it.
     510          16 :     if (F.isDeclaration())
     511             :       return 0;
     512             : 
     513             :     // Grab the name of the function being called here.
     514          16 :     std::string CalledFnName = mangle(F.getName(), SrcM.getDataLayout());
     515             : 
     516             :     JITTargetAddress CalledAddr = 0;
     517             :     auto Part = Partition(F);
     518          32 :     if (auto PartKeyOrErr = emitPartition(LD, LMId, Part)) {
     519             :       auto &PartKey = *PartKeyOrErr;
     520          32 :       for (auto *SubF : Part) {
     521          16 :         std::string FnName = mangle(SubF->getName(), SrcM.getDataLayout());
     522          32 :         if (auto FnBodySym = BaseLayer.findSymbolIn(PartKey, FnName, false)) {
     523          32 :           if (auto FnBodyAddrOrErr = FnBodySym.getAddress()) {
     524          16 :             JITTargetAddress FnBodyAddr = *FnBodyAddrOrErr;
     525             : 
     526             :             // If this is the function we're calling record the address so we can
     527             :             // return it from this function.
     528          16 :             if (SubF == &F)
     529             :               CalledAddr = FnBodyAddr;
     530             : 
     531             :             // Update the function body pointer for the stub.
     532          48 :             if (auto EC = LD.StubsMgr->updatePointer(FnName, FnBodyAddr))
     533             :               return 0;
     534             : 
     535             :           } else
     536             :             return FnBodyAddrOrErr.takeError();
     537           0 :         } else if (auto Err = FnBodySym.takeError())
     538             :           return std::move(Err);
     539             :         else
     540           0 :           llvm_unreachable("Function not emitted for partition");
     541             :       }
     542             : 
     543          16 :       LD.BaseLayerVModuleKeys.push_back(PartKey);
     544             :     } else
     545             :       return PartKeyOrErr.takeError();
     546             : 
     547             :     return CalledAddr;
     548             :   }
     549             : 
     550             :   template <typename PartitionT>
     551             :   Expected<VModuleKey>
     552          16 :   emitPartition(LogicalDylib &LD,
     553             :                 typename LogicalDylib::SourceModuleHandle LMId,
     554             :                 const PartitionT &Part) {
     555          16 :     Module &SrcM = LD.getSourceModule(LMId);
     556             : 
     557             :     // Create the module.
     558             :     std::string NewName = SrcM.getName();
     559          32 :     for (auto *F : Part) {
     560             :       NewName += ".";
     561          16 :       NewName += F->getName();
     562             :     }
     563             : 
     564          32 :     auto M = llvm::make_unique<Module>(NewName, SrcM.getContext());
     565          16 :     M->setDataLayout(SrcM.getDataLayout());
     566          16 :     ValueToValueMapTy VMap;
     567             : 
     568             :     auto Materializer = createLambdaMaterializer([&LD, &LMId,
     569          79 :                                                   &M](Value *V) -> Value * {
     570             :       if (auto *GV = dyn_cast<GlobalVariable>(V))
     571           6 :         return cloneGlobalVariableDecl(*M, *GV);
     572             : 
     573             :       if (auto *F = dyn_cast<Function>(V)) {
     574             :         // Check whether we want to clone an available_externally definition.
     575          13 :         if (!LD.getStubsToClone(LMId).count(F))
     576           7 :           return cloneFunctionDecl(*M, *F);
     577             : 
     578             :         // Ok - we want an inlinable stub. For that to work we need a decl
     579             :         // for the stub pointer.
     580           6 :         auto *StubPtr = createImplPointer(*F->getType(), *M,
     581          12 :                                           F->getName() + "$stub_ptr", nullptr);
     582           6 :         auto *ClonedF = cloneFunctionDecl(*M, *F);
     583           6 :         makeStub(*ClonedF, *StubPtr);
     584             :         ClonedF->setLinkage(GlobalValue::AvailableExternallyLinkage);
     585             :         ClonedF->addFnAttr(Attribute::AlwaysInline);
     586           6 :         return ClonedF;
     587             :       }
     588             : 
     589             :       if (auto *A = dyn_cast<GlobalAlias>(V)) {
     590           2 :         auto *Ty = A->getValueType();
     591           2 :         if (Ty->isFunctionTy())
     592           1 :           return Function::Create(cast<FunctionType>(Ty),
     593           2 :                                   GlobalValue::ExternalLinkage, A->getName(),
     594             :                                   M.get());
     595             : 
     596           1 :         return new GlobalVariable(*M, Ty, false, GlobalValue::ExternalLinkage,
     597           2 :                                   nullptr, A->getName(), nullptr,
     598             :                                   GlobalValue::NotThreadLocal,
     599           1 :                                   A->getType()->getAddressSpace());
     600             :       }
     601             : 
     602             :       return nullptr;
     603             :     });
     604             : 
     605             :     // Create decls in the new module.
     606          32 :     for (auto *F : Part)
     607          16 :       cloneFunctionDecl(*M, *F, &VMap);
     608             : 
     609             :     // Move the function bodies.
     610          32 :     for (auto *F : Part)
     611          16 :       moveFunctionBody(*F, VMap, &Materializer);
     612             : 
     613          16 :     auto K = ES.allocateVModule();
     614             : 
     615          22 :     auto LegacyLookup = [this, &LD](const std::string &Name) -> JITSymbol {
     616          22 :       return LD.findSymbol(BaseLayer, Name, false);
     617             :     };
     618             : 
     619             :     // Create memory manager and symbol resolver.
     620          32 :     auto Resolver = createSymbolResolver(
     621             :         [&LD, LegacyLookup](SymbolFlagsMap &SymbolFlags,
     622          32 :                             const SymbolNameSet &Symbols) {
     623          32 :           auto NotFoundViaLegacyLookup =
     624             :               lookupFlagsWithLegacyFn(SymbolFlags, Symbols, LegacyLookup);
     625          16 :           if (!NotFoundViaLegacyLookup) {
     626           0 :             logAllUnhandledErrors(NotFoundViaLegacyLookup.takeError(), errs(),
     627             :                                   "CODLayer/SubResolver flags lookup failed: ");
     628             :             SymbolFlags.clear();
     629           0 :             return SymbolNameSet();
     630             :           }
     631             :           return LD.BackingResolver->lookupFlags(SymbolFlags,
     632          16 :                                                  *NotFoundViaLegacyLookup);
     633             :         },
     634             :         [this, &LD, LegacyLookup](std::shared_ptr<AsynchronousSymbolQuery> Q,
     635          33 :                                   SymbolNameSet Symbols) {
     636          11 :           auto NotFoundViaLegacyLookup =
     637             :               lookupWithLegacyFn(ES, *Q, Symbols, LegacyLookup);
     638             :           return LD.BackingResolver->lookup(Q,
     639          55 :                                             std::move(NotFoundViaLegacyLookup));
     640             :         });
     641          16 :     SetSymbolResolver(K, std::move(Resolver));
     642             : 
     643          48 :     if (auto Err = BaseLayer.addModule(std::move(K), std::move(M)))
     644             :       return std::move(Err);
     645             : 
     646             :     return K;
     647             :   }
     648             : 
     649             :   ExecutionSession &ES;
     650             :   BaseLayerT &BaseLayer;
     651             :   SymbolResolverGetter GetSymbolResolver;
     652             :   SymbolResolverSetter SetSymbolResolver;
     653             :   PartitioningFtor Partition;
     654             :   CompileCallbackMgrT &CompileCallbackMgr;
     655             :   IndirectStubsManagerBuilderT CreateIndirectStubsManager;
     656             : 
     657             :   std::map<VModuleKey, LogicalDylib> LogicalDylibs;
     658             :   bool CloneStubsIntoPartitions;
     659             : };
     660             : 
     661             : } // end namespace orc
     662             : 
     663             : } // end namespace llvm
     664             : 
     665             : #endif // LLVM_EXECUTIONENGINE_ORC_COMPILEONDEMANDLAYER_H

Generated by: LCOV version 1.13