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