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

Generated by: LCOV version 1.13