1 //===- CompileOnDemandLayer.h - Compile each function on demand -*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // JIT layer for breaking up modules and inserting callbacks to allow
11 // individual functions to be compiled on demand.
13 //===----------------------------------------------------------------------===//
15 #ifndef LLVM_EXECUTIONENGINE_ORC_COMPILEONDEMANDLAYER_H
16 #define LLVM_EXECUTIONENGINE_ORC_COMPILEONDEMANDLAYER_H
18 #include "llvm/ADT/APInt.h"
19 #include "llvm/ADT/Optional.h"
20 #include "llvm/ADT/STLExtras.h"
21 #include "llvm/ADT/StringRef.h"
22 #include "llvm/ADT/Twine.h"
23 #include "llvm/ExecutionEngine/JITSymbol.h"
24 #include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
25 #include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
26 #include "llvm/ExecutionEngine/Orc/Layer.h"
27 #include "llvm/ExecutionEngine/Orc/LazyReexports.h"
28 #include "llvm/ExecutionEngine/Orc/Legacy.h"
29 #include "llvm/ExecutionEngine/Orc/OrcError.h"
30 #include "llvm/ExecutionEngine/RuntimeDyld.h"
31 #include "llvm/IR/Attributes.h"
32 #include "llvm/IR/Constant.h"
33 #include "llvm/IR/Constants.h"
34 #include "llvm/IR/DataLayout.h"
35 #include "llvm/IR/Function.h"
36 #include "llvm/IR/GlobalAlias.h"
37 #include "llvm/IR/GlobalValue.h"
38 #include "llvm/IR/GlobalVariable.h"
39 #include "llvm/IR/Instruction.h"
40 #include "llvm/IR/Mangler.h"
41 #include "llvm/IR/Module.h"
42 #include "llvm/IR/Type.h"
43 #include "llvm/Support/Casting.h"
44 #include "llvm/Support/raw_ostream.h"
45 #include "llvm/Transforms/Utils/ValueMapper.h"
63 class ExtractingIRMaterializationUnit;
65 class CompileOnDemandLayer : public IRLayer {
66 friend class PartitioningIRMaterializationUnit;
69 /// Builder for IndirectStubsManagers.
70 using IndirectStubsManagerBuilder =
71 std::function<std::unique_ptr<IndirectStubsManager>()>;
73 using GlobalValueSet = std::set<const GlobalValue *>;
75 /// Partitioning function.
76 using PartitionFunction =
77 std::function<Optional<GlobalValueSet>(GlobalValueSet Requested)>;
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);
83 /// Off-the-shelf partitioning which compiles whole modules whenever any
84 /// symbol in them is requested.
85 static Optional<GlobalValueSet> compileWholeModule(GlobalValueSet Requested);
87 /// Construct a CompileOnDemandLayer.
88 CompileOnDemandLayer(ExecutionSession &ES, IRLayer &BaseLayer,
89 LazyCallThroughManager &LCTMgr,
90 IndirectStubsManagerBuilder BuildIndirectStubsManager);
92 /// Sets the partition function.
93 void setPartitionFunction(PartitionFunction Partition);
95 /// Emits the given module. This should not be called by clients: it will be
96 /// called by the JIT when a definition added via the add method is requested.
97 void emit(MaterializationResponsibility R, ThreadSafeModule TSM) override;
100 struct PerDylibResources {
102 PerDylibResources(JITDylib &ImplD,
103 std::unique_ptr<IndirectStubsManager> ISMgr)
104 : ImplD(ImplD), ISMgr(std::move(ISMgr)) {}
105 JITDylib &getImplDylib() { return ImplD; }
106 IndirectStubsManager &getISManager() { return *ISMgr; }
110 std::unique_ptr<IndirectStubsManager> ISMgr;
113 using PerDylibResourcesMap = std::map<const JITDylib *, PerDylibResources>;
115 PerDylibResources &getPerDylibResources(JITDylib &TargetD);
117 void cleanUpModule(Module &M);
119 void expandPartition(GlobalValueSet &Partition);
121 void emitPartition(MaterializationResponsibility R, ThreadSafeModule TSM,
122 IRMaterializationUnit::SymbolNameToDefinitionMap Defs);
124 mutable std::mutex CODLayerMutex;
127 LazyCallThroughManager &LCTMgr;
128 IndirectStubsManagerBuilder BuildIndirectStubsManager;
129 PerDylibResourcesMap DylibResources;
130 PartitionFunction Partition = compileRequested;
131 SymbolLinkagePromoter PromoteSymbols;
134 /// Compile-on-demand layer.
136 /// When a module is added to this layer a stub is created for each of its
137 /// function definitions. The stubs and other global values are immediately
138 /// added to the layer below. When a stub is called it triggers the extraction
139 /// of the function body from the original module. The extracted body is then
140 /// compiled and executed.
141 template <typename BaseLayerT,
142 typename CompileCallbackMgrT = JITCompileCallbackManager,
143 typename IndirectStubsMgrT = IndirectStubsManager>
144 class LegacyCompileOnDemandLayer {
146 template <typename MaterializerFtor>
147 class LambdaMaterializer final : public ValueMaterializer {
149 LambdaMaterializer(MaterializerFtor M) : M(std::move(M)) {}
151 Value *materialize(Value *V) final { return M(V); }
157 template <typename MaterializerFtor>
158 LambdaMaterializer<MaterializerFtor>
159 createLambdaMaterializer(MaterializerFtor M) {
160 return LambdaMaterializer<MaterializerFtor>(std::move(M));
163 // Provide type-erasure for the Modules and MemoryManagers.
164 template <typename ResourceT>
165 class ResourceOwner {
167 ResourceOwner() = default;
168 ResourceOwner(const ResourceOwner &) = delete;
169 ResourceOwner &operator=(const ResourceOwner &) = delete;
170 virtual ~ResourceOwner() = default;
172 virtual ResourceT& getResource() const = 0;
175 template <typename ResourceT, typename ResourcePtrT>
176 class ResourceOwnerImpl : public ResourceOwner<ResourceT> {
178 ResourceOwnerImpl(ResourcePtrT ResourcePtr)
179 : ResourcePtr(std::move(ResourcePtr)) {}
181 ResourceT& getResource() const override { return *ResourcePtr; }
184 ResourcePtrT ResourcePtr;
187 template <typename ResourceT, typename ResourcePtrT>
188 std::unique_ptr<ResourceOwner<ResourceT>>
189 wrapOwnership(ResourcePtrT ResourcePtr) {
190 using RO = ResourceOwnerImpl<ResourceT, ResourcePtrT>;
191 return llvm::make_unique<RO>(std::move(ResourcePtr));
194 struct LogicalDylib {
195 struct SourceModuleEntry {
196 std::unique_ptr<Module> SourceMod;
197 std::set<Function*> StubsToClone;
200 using SourceModulesList = std::vector<SourceModuleEntry>;
201 using SourceModuleHandle = typename SourceModulesList::size_type;
203 LogicalDylib() = default;
205 LogicalDylib(VModuleKey K, std::shared_ptr<SymbolResolver> BackingResolver,
206 std::unique_ptr<IndirectStubsMgrT> StubsMgr)
207 : K(std::move(K)), BackingResolver(std::move(BackingResolver)),
208 StubsMgr(std::move(StubsMgr)) {}
210 SourceModuleHandle addSourceModule(std::unique_ptr<Module> M) {
211 SourceModuleHandle H = SourceModules.size();
212 SourceModules.push_back(SourceModuleEntry());
213 SourceModules.back().SourceMod = std::move(M);
217 Module& getSourceModule(SourceModuleHandle H) {
218 return *SourceModules[H].SourceMod;
221 std::set<Function*>& getStubsToClone(SourceModuleHandle H) {
222 return SourceModules[H].StubsToClone;
225 JITSymbol findSymbol(BaseLayerT &BaseLayer, const std::string &Name,
226 bool ExportedSymbolsOnly) {
227 if (auto Sym = StubsMgr->findStub(Name, ExportedSymbolsOnly))
229 for (auto BLK : BaseLayerVModuleKeys)
230 if (auto Sym = BaseLayer.findSymbolIn(BLK, Name, ExportedSymbolsOnly))
232 else if (auto Err = Sym.takeError())
233 return std::move(Err);
237 Error removeModulesFromBaseLayer(BaseLayerT &BaseLayer) {
238 for (auto &BLK : BaseLayerVModuleKeys)
239 if (auto Err = BaseLayer.removeModule(BLK))
241 return Error::success();
245 std::shared_ptr<SymbolResolver> BackingResolver;
246 std::unique_ptr<IndirectStubsMgrT> StubsMgr;
247 SymbolLinkagePromoter PromoteSymbols;
248 SourceModulesList SourceModules;
249 std::vector<VModuleKey> BaseLayerVModuleKeys;
254 /// Module partitioning functor.
255 using PartitioningFtor = std::function<std::set<Function*>(Function&)>;
257 /// Builder for IndirectStubsManagers.
258 using IndirectStubsManagerBuilderT =
259 std::function<std::unique_ptr<IndirectStubsMgrT>()>;
261 using SymbolResolverGetter =
262 std::function<std::shared_ptr<SymbolResolver>(VModuleKey K)>;
264 using SymbolResolverSetter =
265 std::function<void(VModuleKey K, std::shared_ptr<SymbolResolver> R)>;
267 /// Construct a compile-on-demand layer instance.
268 LegacyCompileOnDemandLayer(ExecutionSession &ES, BaseLayerT &BaseLayer,
269 SymbolResolverGetter GetSymbolResolver,
270 SymbolResolverSetter SetSymbolResolver,
271 PartitioningFtor Partition,
272 CompileCallbackMgrT &CallbackMgr,
273 IndirectStubsManagerBuilderT CreateIndirectStubsManager,
274 bool CloneStubsIntoPartitions = true)
275 : ES(ES), BaseLayer(BaseLayer),
276 GetSymbolResolver(std::move(GetSymbolResolver)),
277 SetSymbolResolver(std::move(SetSymbolResolver)),
278 Partition(std::move(Partition)), CompileCallbackMgr(CallbackMgr),
279 CreateIndirectStubsManager(std::move(CreateIndirectStubsManager)),
280 CloneStubsIntoPartitions(CloneStubsIntoPartitions) {}
282 ~LegacyCompileOnDemandLayer() {
283 // FIXME: Report error on log.
284 while (!LogicalDylibs.empty())
285 consumeError(removeModule(LogicalDylibs.begin()->first));
288 /// Add a module to the compile-on-demand layer.
289 Error addModule(VModuleKey K, std::unique_ptr<Module> M) {
291 assert(!LogicalDylibs.count(K) && "VModuleKey K already in use");
292 auto I = LogicalDylibs.insert(
294 std::make_pair(K, LogicalDylib(K, GetSymbolResolver(K),
295 CreateIndirectStubsManager())));
297 return addLogicalModule(I->second, std::move(M));
300 /// Add extra modules to an existing logical module.
301 Error addExtraModule(VModuleKey K, std::unique_ptr<Module> M) {
302 return addLogicalModule(LogicalDylibs[K], std::move(M));
305 /// Remove the module represented by the given key.
307 /// This will remove all modules in the layers below that were derived from
308 /// the module represented by K.
309 Error removeModule(VModuleKey K) {
310 auto I = LogicalDylibs.find(K);
311 assert(I != LogicalDylibs.end() && "VModuleKey K not valid here");
312 auto Err = I->second.removeModulesFromBaseLayer(BaseLayer);
313 LogicalDylibs.erase(I);
317 /// Search for the given named symbol.
318 /// @param Name The name of the symbol to search for.
319 /// @param ExportedSymbolsOnly If true, search only for exported symbols.
320 /// @return A handle for the given named symbol, if it exists.
321 JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly) {
322 for (auto &KV : LogicalDylibs) {
323 if (auto Sym = KV.second.StubsMgr->findStub(Name, ExportedSymbolsOnly))
325 if (auto Sym = findSymbolIn(KV.first, Name, ExportedSymbolsOnly))
327 else if (auto Err = Sym.takeError())
328 return std::move(Err);
330 return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
333 /// Get the address of a symbol provided by this layer, or some layer
335 JITSymbol findSymbolIn(VModuleKey K, const std::string &Name,
336 bool ExportedSymbolsOnly) {
337 assert(LogicalDylibs.count(K) && "VModuleKey K is not valid here");
338 return LogicalDylibs[K].findSymbol(BaseLayer, Name, ExportedSymbolsOnly);
341 /// Update the stub for the given function to point at FnBodyAddr.
342 /// This can be used to support re-optimization.
343 /// @return true if the function exists and the stub is updated, false
346 // FIXME: We should track and free associated resources (unused compile
347 // callbacks, uncompiled IR, and no-longer-needed/reachable function
349 Error updatePointer(std::string FuncName, JITTargetAddress FnBodyAddr) {
350 //Find out which logical dylib contains our symbol
351 auto LDI = LogicalDylibs.begin();
352 for (auto LDE = LogicalDylibs.end(); LDI != LDE; ++LDI) {
353 if (auto LMResources =
354 LDI->getLogicalModuleResourcesForSymbol(FuncName, false)) {
355 Module &SrcM = LMResources->SourceModule->getResource();
356 std::string CalledFnName = mangle(FuncName, SrcM.getDataLayout());
357 if (auto Err = LMResources->StubsMgr->updatePointer(CalledFnName,
360 return Error::success();
363 return make_error<JITSymbolNotFound>(FuncName);
367 Error addLogicalModule(LogicalDylib &LD, std::unique_ptr<Module> SrcMPtr) {
369 // Rename anonymous globals and promote linkage to ensure that everything
370 // will resolve properly after we partition SrcM.
371 LD.PromoteSymbols(*SrcMPtr);
373 // Create a logical module handle for SrcM within the logical dylib.
374 Module &SrcM = *SrcMPtr;
375 auto LMId = LD.addSourceModule(std::move(SrcMPtr));
377 // Create stub functions.
378 const DataLayout &DL = SrcM.getDataLayout();
380 typename IndirectStubsMgrT::StubInitsMap StubInits;
381 for (auto &F : SrcM) {
382 // Skip declarations.
383 if (F.isDeclaration())
386 // Skip weak functions for which we already have definitions.
387 auto MangledName = mangle(F.getName(), DL);
388 if (F.hasWeakLinkage() || F.hasLinkOnceLinkage()) {
389 if (auto Sym = LD.findSymbol(BaseLayer, MangledName, false))
391 else if (auto Err = Sym.takeError())
392 return std::move(Err);
395 // Record all functions defined by this module.
396 if (CloneStubsIntoPartitions)
397 LD.getStubsToClone(LMId).insert(&F);
399 // Create a callback, associate it with the stub for the function,
400 // and set the compile action to compile the partition containing the
402 auto CompileAction = [this, &LD, LMId, &F]() -> JITTargetAddress {
403 if (auto FnImplAddrOrErr = this->extractAndCompile(LD, LMId, F))
404 return *FnImplAddrOrErr;
406 // FIXME: Report error, return to 'abort' or something similar.
407 consumeError(FnImplAddrOrErr.takeError());
412 CompileCallbackMgr.getCompileCallback(std::move(CompileAction)))
413 StubInits[MangledName] =
414 std::make_pair(*CCAddr, JITSymbolFlags::fromGlobalValue(F));
416 return CCAddr.takeError();
419 if (auto Err = LD.StubsMgr->createStubs(StubInits))
423 // If this module doesn't contain any globals, aliases, or module flags then
424 // we can bail out early and avoid the overhead of creating and managing an
425 // empty globals module.
426 if (SrcM.global_empty() && SrcM.alias_empty() &&
427 !SrcM.getModuleFlagsMetadata())
428 return Error::success();
430 // Create the GlobalValues module.
431 auto GVsM = llvm::make_unique<Module>((SrcM.getName() + ".globals").str(),
433 GVsM->setDataLayout(DL);
435 ValueToValueMapTy VMap;
437 // Clone global variable decls.
438 for (auto &GV : SrcM.globals())
439 if (!GV.isDeclaration() && !VMap.count(&GV))
440 cloneGlobalVariableDecl(*GVsM, GV, &VMap);
443 for (auto &A : SrcM.aliases())
445 cloneGlobalAliasDecl(*GVsM, A, VMap);
447 // Clone the module flags.
448 cloneModuleFlagsMetadata(*GVsM, SrcM, VMap);
450 // Now we need to clone the GV and alias initializers.
452 // Initializers may refer to functions declared (but not defined) in this
453 // module. Build a materializer to clone decls on demand.
454 auto Materializer = createLambdaMaterializer(
455 [&LD, &GVsM](Value *V) -> Value* {
456 if (auto *F = dyn_cast<Function>(V)) {
457 // Decls in the original module just get cloned.
458 if (F->isDeclaration())
459 return cloneFunctionDecl(*GVsM, *F);
461 // Definitions in the original module (which we have emitted stubs
462 // for at this point) get turned into a constant alias to the stub
464 const DataLayout &DL = GVsM->getDataLayout();
465 std::string FName = mangle(F->getName(), DL);
466 unsigned PtrBitWidth = DL.getPointerTypeSizeInBits(F->getType());
467 JITTargetAddress StubAddr =
468 LD.StubsMgr->findStub(FName, false).getAddress();
470 ConstantInt *StubAddrCI =
471 ConstantInt::get(GVsM->getContext(), APInt(PtrBitWidth, StubAddr));
472 Constant *Init = ConstantExpr::getCast(Instruction::IntToPtr,
473 StubAddrCI, F->getType());
474 return GlobalAlias::create(F->getFunctionType(),
475 F->getType()->getAddressSpace(),
476 F->getLinkage(), F->getName(),
483 // Clone the global variable initializers.
484 for (auto &GV : SrcM.globals())
485 if (!GV.isDeclaration())
486 moveGlobalVariableInitializer(GV, VMap, &Materializer);
488 // Clone the global alias initializers.
489 for (auto &A : SrcM.aliases()) {
490 auto *NewA = cast<GlobalAlias>(VMap[&A]);
491 assert(NewA && "Alias not cloned?");
492 Value *Init = MapValue(A.getAliasee(), VMap, RF_None, nullptr,
494 NewA->setAliasee(cast<Constant>(Init));
497 // Build a resolver for the globals module and add it to the base layer.
498 auto LegacyLookup = [this, &LD](const std::string &Name) -> JITSymbol {
499 if (auto Sym = LD.StubsMgr->findStub(Name, false))
502 if (auto Sym = LD.findSymbol(BaseLayer, Name, false))
504 else if (auto Err = Sym.takeError())
505 return std::move(Err);
510 auto GVsResolver = createSymbolResolver(
511 [&LD, LegacyLookup](const SymbolNameSet &Symbols) {
512 auto RS = getResponsibilitySetWithLegacyFn(Symbols, LegacyLookup);
515 logAllUnhandledErrors(
516 RS.takeError(), errs(),
517 "CODLayer/GVsResolver responsibility set lookup failed: ");
518 return SymbolNameSet();
521 if (RS->size() == Symbols.size())
524 SymbolNameSet NotFoundViaLegacyLookup;
525 for (auto &S : Symbols)
527 NotFoundViaLegacyLookup.insert(S);
529 LD.BackingResolver->getResponsibilitySet(NotFoundViaLegacyLookup);
537 LegacyLookup](std::shared_ptr<AsynchronousSymbolQuery> Query,
538 SymbolNameSet Symbols) {
539 auto NotFoundViaLegacyLookup =
540 lookupWithLegacyFn(ES, *Query, Symbols, LegacyLookup);
541 return LD.BackingResolver->lookup(Query, NotFoundViaLegacyLookup);
544 SetSymbolResolver(LD.K, std::move(GVsResolver));
546 if (auto Err = BaseLayer.addModule(LD.K, std::move(GVsM)))
549 LD.BaseLayerVModuleKeys.push_back(LD.K);
551 return Error::success();
554 static std::string mangle(StringRef Name, const DataLayout &DL) {
555 std::string MangledName;
557 raw_string_ostream MangledNameStream(MangledName);
558 Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
563 Expected<JITTargetAddress>
564 extractAndCompile(LogicalDylib &LD,
565 typename LogicalDylib::SourceModuleHandle LMId,
567 Module &SrcM = LD.getSourceModule(LMId);
569 // If F is a declaration we must already have compiled it.
570 if (F.isDeclaration())
573 // Grab the name of the function being called here.
574 std::string CalledFnName = mangle(F.getName(), SrcM.getDataLayout());
576 JITTargetAddress CalledAddr = 0;
577 auto Part = Partition(F);
578 if (auto PartKeyOrErr = emitPartition(LD, LMId, Part)) {
579 auto &PartKey = *PartKeyOrErr;
580 for (auto *SubF : Part) {
581 std::string FnName = mangle(SubF->getName(), SrcM.getDataLayout());
582 if (auto FnBodySym = BaseLayer.findSymbolIn(PartKey, FnName, false)) {
583 if (auto FnBodyAddrOrErr = FnBodySym.getAddress()) {
584 JITTargetAddress FnBodyAddr = *FnBodyAddrOrErr;
586 // If this is the function we're calling record the address so we can
587 // return it from this function.
589 CalledAddr = FnBodyAddr;
591 // Update the function body pointer for the stub.
592 if (auto EC = LD.StubsMgr->updatePointer(FnName, FnBodyAddr))
596 return FnBodyAddrOrErr.takeError();
597 } else if (auto Err = FnBodySym.takeError())
598 return std::move(Err);
600 llvm_unreachable("Function not emitted for partition");
603 LD.BaseLayerVModuleKeys.push_back(PartKey);
605 return PartKeyOrErr.takeError();
610 template <typename PartitionT>
612 emitPartition(LogicalDylib &LD,
613 typename LogicalDylib::SourceModuleHandle LMId,
614 const PartitionT &Part) {
615 Module &SrcM = LD.getSourceModule(LMId);
617 // Create the module.
618 std::string NewName = SrcM.getName();
619 for (auto *F : Part) {
621 NewName += F->getName();
624 auto M = llvm::make_unique<Module>(NewName, SrcM.getContext());
625 M->setDataLayout(SrcM.getDataLayout());
626 ValueToValueMapTy VMap;
628 auto Materializer = createLambdaMaterializer([&LD, &LMId,
629 &M](Value *V) -> Value * {
630 if (auto *GV = dyn_cast<GlobalVariable>(V))
631 return cloneGlobalVariableDecl(*M, *GV);
633 if (auto *F = dyn_cast<Function>(V)) {
634 // Check whether we want to clone an available_externally definition.
635 if (!LD.getStubsToClone(LMId).count(F))
636 return cloneFunctionDecl(*M, *F);
638 // Ok - we want an inlinable stub. For that to work we need a decl
639 // for the stub pointer.
640 auto *StubPtr = createImplPointer(*F->getType(), *M,
641 F->getName() + "$stub_ptr", nullptr);
642 auto *ClonedF = cloneFunctionDecl(*M, *F);
643 makeStub(*ClonedF, *StubPtr);
644 ClonedF->setLinkage(GlobalValue::AvailableExternallyLinkage);
645 ClonedF->addFnAttr(Attribute::AlwaysInline);
649 if (auto *A = dyn_cast<GlobalAlias>(V)) {
650 auto *Ty = A->getValueType();
651 if (Ty->isFunctionTy())
652 return Function::Create(cast<FunctionType>(Ty),
653 GlobalValue::ExternalLinkage, A->getName(),
656 return new GlobalVariable(*M, Ty, false, GlobalValue::ExternalLinkage,
657 nullptr, A->getName(), nullptr,
658 GlobalValue::NotThreadLocal,
659 A->getType()->getAddressSpace());
665 // Create decls in the new module.
667 cloneFunctionDecl(*M, *F, &VMap);
669 // Move the function bodies.
671 moveFunctionBody(*F, VMap, &Materializer);
673 auto K = ES.allocateVModule();
675 auto LegacyLookup = [this, &LD](const std::string &Name) -> JITSymbol {
676 return LD.findSymbol(BaseLayer, Name, false);
679 // Create memory manager and symbol resolver.
680 auto Resolver = createSymbolResolver(
681 [&LD, LegacyLookup](const SymbolNameSet &Symbols) {
682 auto RS = getResponsibilitySetWithLegacyFn(Symbols, LegacyLookup);
684 logAllUnhandledErrors(
685 RS.takeError(), errs(),
686 "CODLayer/SubResolver responsibility set lookup failed: ");
687 return SymbolNameSet();
690 if (RS->size() == Symbols.size())
693 SymbolNameSet NotFoundViaLegacyLookup;
694 for (auto &S : Symbols)
696 NotFoundViaLegacyLookup.insert(S);
699 LD.BackingResolver->getResponsibilitySet(NotFoundViaLegacyLookup);
706 [this, &LD, LegacyLookup](std::shared_ptr<AsynchronousSymbolQuery> Q,
707 SymbolNameSet Symbols) {
708 auto NotFoundViaLegacyLookup =
709 lookupWithLegacyFn(ES, *Q, Symbols, LegacyLookup);
710 return LD.BackingResolver->lookup(Q,
711 std::move(NotFoundViaLegacyLookup));
713 SetSymbolResolver(K, std::move(Resolver));
715 if (auto Err = BaseLayer.addModule(std::move(K), std::move(M)))
716 return std::move(Err);
721 ExecutionSession &ES;
722 BaseLayerT &BaseLayer;
723 SymbolResolverGetter GetSymbolResolver;
724 SymbolResolverSetter SetSymbolResolver;
725 PartitioningFtor Partition;
726 CompileCallbackMgrT &CompileCallbackMgr;
727 IndirectStubsManagerBuilderT CreateIndirectStubsManager;
729 std::map<VModuleKey, LogicalDylib> LogicalDylibs;
730 bool CloneStubsIntoPartitions;
733 } // end namespace orc
735 } // end namespace llvm
737 #endif // LLVM_EXECUTIONENGINE_ORC_COMPILEONDEMANDLAYER_H