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

Generated by: LCOV version 1.13