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