168c9b8d6SLang Hames //===----- CompileOnDemandLayer.cpp - Lazily emit IR on first call --------===//
268c9b8d6SLang Hames //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
668c9b8d6SLang Hames //
768c9b8d6SLang Hames //===----------------------------------------------------------------------===//
868c9b8d6SLang Hames
968c9b8d6SLang Hames #include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h"
101df947abSLang Hames #include "llvm/ADT/Hashing.h"
1185fb9976SLang Hames #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
1268c9b8d6SLang Hames #include "llvm/IR/Mangler.h"
1368c9b8d6SLang Hames #include "llvm/IR/Module.h"
141df947abSLang Hames #include "llvm/Support/FormatVariadic.h"
15367ec775SSimon Pilgrim #include <string>
1668c9b8d6SLang Hames
1768c9b8d6SLang Hames using namespace llvm;
1868c9b8d6SLang Hames using namespace llvm::orc;
1968c9b8d6SLang Hames
extractSubModule(ThreadSafeModule & TSM,StringRef Suffix,GVPredicate ShouldExtract)2098440293SLang Hames static ThreadSafeModule extractSubModule(ThreadSafeModule &TSM,
2198440293SLang Hames StringRef Suffix,
2298440293SLang Hames GVPredicate ShouldExtract) {
236a94134bSLang Hames
2498440293SLang Hames auto DeleteExtractedDefs = [](GlobalValue &GV) {
2598440293SLang Hames // Bump the linkage: this global will be provided by the external module.
2698440293SLang Hames GV.setLinkage(GlobalValue::ExternalLinkage);
276a94134bSLang Hames
2898440293SLang Hames // Delete the definition in the source module.
297bd89707SLang Hames if (isa<Function>(GV)) {
308d76c711SLang Hames auto &F = cast<Function>(GV);
317bd89707SLang Hames F.deleteBody();
327bd89707SLang Hames F.setPersonalityFn(nullptr);
337bd89707SLang Hames } else if (isa<GlobalVariable>(GV)) {
348d76c711SLang Hames cast<GlobalVariable>(GV).setInitializer(nullptr);
3598440293SLang Hames } else if (isa<GlobalAlias>(GV)) {
3698440293SLang Hames // We need to turn deleted aliases into function or variable decls based
3798440293SLang Hames // on the type of their aliasee.
3898440293SLang Hames auto &A = cast<GlobalAlias>(GV);
3998440293SLang Hames Constant *Aliasee = A.getAliasee();
4098440293SLang Hames assert(A.hasName() && "Anonymous alias?");
4198440293SLang Hames assert(Aliasee->hasName() && "Anonymous aliasee");
42adcd0268SBenjamin Kramer std::string AliasName = std::string(A.getName());
4398440293SLang Hames
4498440293SLang Hames if (isa<Function>(Aliasee)) {
4598440293SLang Hames auto *F = cloneFunctionDecl(*A.getParent(), *cast<Function>(Aliasee));
4698440293SLang Hames A.replaceAllUsesWith(F);
4798440293SLang Hames A.eraseFromParent();
4898440293SLang Hames F->setName(AliasName);
4998440293SLang Hames } else if (isa<GlobalVariable>(Aliasee)) {
5098440293SLang Hames auto *G = cloneGlobalVariableDecl(*A.getParent(),
5198440293SLang Hames *cast<GlobalVariable>(Aliasee));
5298440293SLang Hames A.replaceAllUsesWith(G);
5398440293SLang Hames A.eraseFromParent();
5498440293SLang Hames G->setName(AliasName);
5598440293SLang Hames } else
5698440293SLang Hames llvm_unreachable("Alias to unsupported type");
577bd89707SLang Hames } else
587bd89707SLang Hames llvm_unreachable("Unsupported global type");
598d76c711SLang Hames };
608d76c711SLang Hames
61809e9d1eSLang Hames auto NewTSM = cloneToNewContext(TSM, ShouldExtract, DeleteExtractedDefs);
62809e9d1eSLang Hames NewTSM.withModuleDo([&](Module &M) {
638d76c711SLang Hames M.setModuleIdentifier((M.getModuleIdentifier() + Suffix).str());
64809e9d1eSLang Hames });
658d76c711SLang Hames
66809e9d1eSLang Hames return NewTSM;
6768c9b8d6SLang Hames }
6868c9b8d6SLang Hames
6968c9b8d6SLang Hames namespace llvm {
7068c9b8d6SLang Hames namespace orc {
7168c9b8d6SLang Hames
7298440293SLang Hames class PartitioningIRMaterializationUnit : public IRMaterializationUnit {
7368c9b8d6SLang Hames public:
PartitioningIRMaterializationUnit(ExecutionSession & ES,const IRSymbolMapper::ManglingOptions & MO,ThreadSafeModule TSM,CompileOnDemandLayer & Parent)74ce2207abSLang Hames PartitioningIRMaterializationUnit(ExecutionSession &ES,
7585fb9976SLang Hames const IRSymbolMapper::ManglingOptions &MO,
760aec49c8SLang Hames ThreadSafeModule TSM,
77ce2207abSLang Hames CompileOnDemandLayer &Parent)
780aec49c8SLang Hames : IRMaterializationUnit(ES, MO, std::move(TSM)), Parent(Parent) {}
79fd0c1e71SLang Hames
PartitioningIRMaterializationUnit(ThreadSafeModule TSM,Interface I,SymbolNameToDefinitionMap SymbolToDefinition,CompileOnDemandLayer & Parent)8098440293SLang Hames PartitioningIRMaterializationUnit(
81*ae73f3fdSLang Hames ThreadSafeModule TSM, Interface I,
82*ae73f3fdSLang Hames SymbolNameToDefinitionMap SymbolToDefinition,
83079df9abSLang Hames CompileOnDemandLayer &Parent)
84*ae73f3fdSLang Hames : IRMaterializationUnit(std::move(TSM), std::move(I),
8568c9b8d6SLang Hames std::move(SymbolToDefinition)),
86fd0c1e71SLang Hames Parent(Parent) {}
8768c9b8d6SLang Hames
8868c9b8d6SLang Hames private:
materialize(std::unique_ptr<MaterializationResponsibility> R)897dcd0042SLang Hames void materialize(std::unique_ptr<MaterializationResponsibility> R) override {
9098440293SLang Hames Parent.emitPartition(std::move(R), std::move(TSM),
9198440293SLang Hames std::move(SymbolToDefinition));
9268c9b8d6SLang Hames }
9368c9b8d6SLang Hames
discard(const JITDylib & V,const SymbolStringPtr & Name)94cb5702c3SLang Hames void discard(const JITDylib &V, const SymbolStringPtr &Name) override {
9568c9b8d6SLang Hames // All original symbols were materialized by the CODLayer and should be
9668c9b8d6SLang Hames // final. The function bodies provided by M should never be overridden.
9768c9b8d6SLang Hames llvm_unreachable("Discard should never be called on an "
9868c9b8d6SLang Hames "ExtractingIRMaterializationUnit");
9968c9b8d6SLang Hames }
10068c9b8d6SLang Hames
1017bd89707SLang Hames mutable std::mutex SourceModuleMutex;
102079df9abSLang Hames CompileOnDemandLayer &Parent;
10368c9b8d6SLang Hames };
10468c9b8d6SLang Hames
105079df9abSLang Hames Optional<CompileOnDemandLayer::GlobalValueSet>
compileRequested(GlobalValueSet Requested)106079df9abSLang Hames CompileOnDemandLayer::compileRequested(GlobalValueSet Requested) {
107c55cf4afSBill Wendling return std::move(Requested);
10898440293SLang Hames }
10998440293SLang Hames
110079df9abSLang Hames Optional<CompileOnDemandLayer::GlobalValueSet>
compileWholeModule(GlobalValueSet Requested)111079df9abSLang Hames CompileOnDemandLayer::compileWholeModule(GlobalValueSet Requested) {
11298440293SLang Hames return None;
11398440293SLang Hames }
11498440293SLang Hames
CompileOnDemandLayer(ExecutionSession & ES,IRLayer & BaseLayer,LazyCallThroughManager & LCTMgr,IndirectStubsManagerBuilder BuildIndirectStubsManager)115079df9abSLang Hames CompileOnDemandLayer::CompileOnDemandLayer(
116d8048675SLang Hames ExecutionSession &ES, IRLayer &BaseLayer, LazyCallThroughManager &LCTMgr,
1178d76c711SLang Hames IndirectStubsManagerBuilder BuildIndirectStubsManager)
118ce2207abSLang Hames : IRLayer(ES, BaseLayer.getManglingOptions()), BaseLayer(BaseLayer),
119ce2207abSLang Hames LCTMgr(LCTMgr),
1208d76c711SLang Hames BuildIndirectStubsManager(std::move(BuildIndirectStubsManager)) {}
12168c9b8d6SLang Hames
setPartitionFunction(PartitionFunction Partition)122079df9abSLang Hames void CompileOnDemandLayer::setPartitionFunction(PartitionFunction Partition) {
12398440293SLang Hames this->Partition = std::move(Partition);
12468c9b8d6SLang Hames }
12568c9b8d6SLang Hames
setImplMap(ImplSymbolMap * Imp)126f5c40cb9SPraveen Velliengiri void CompileOnDemandLayer::setImplMap(ImplSymbolMap *Imp) {
127f5c40cb9SPraveen Velliengiri this->AliaseeImpls = Imp;
128f5c40cb9SPraveen Velliengiri }
emit(std::unique_ptr<MaterializationResponsibility> R,ThreadSafeModule TSM)1297dcd0042SLang Hames void CompileOnDemandLayer::emit(
1307dcd0042SLang Hames std::unique_ptr<MaterializationResponsibility> R, ThreadSafeModule TSM) {
131809e9d1eSLang Hames assert(TSM && "Null module");
13298440293SLang Hames
13368c9b8d6SLang Hames auto &ES = getExecutionSession();
13468c9b8d6SLang Hames
135809e9d1eSLang Hames // Sort the callables and non-callables, build re-exports and lodge the
13698440293SLang Hames // actual module with the implementation dylib.
1377dcd0042SLang Hames auto &PDR = getPerDylibResources(R->getTargetJITDylib());
13868c9b8d6SLang Hames
13998440293SLang Hames SymbolAliasMap NonCallables;
14098440293SLang Hames SymbolAliasMap Callables;
141809e9d1eSLang Hames TSM.withModuleDo([&](Module &M) {
142809e9d1eSLang Hames // First, do some cleanup on the module:
143809e9d1eSLang Hames cleanUpModule(M);
144ce2207abSLang Hames });
145809e9d1eSLang Hames
1467dcd0042SLang Hames for (auto &KV : R->getSymbols()) {
147ce2207abSLang Hames auto &Name = KV.first;
148ce2207abSLang Hames auto &Flags = KV.second;
14998440293SLang Hames if (Flags.isCallable())
15098440293SLang Hames Callables[Name] = SymbolAliasMapEntry(Name, Flags);
15198440293SLang Hames else
15298440293SLang Hames NonCallables[Name] = SymbolAliasMapEntry(Name, Flags);
15368c9b8d6SLang Hames }
15468c9b8d6SLang Hames
15598440293SLang Hames // Create a partitioning materialization unit and lodge it with the
15698440293SLang Hames // implementation dylib.
15798440293SLang Hames if (auto Err = PDR.getImplDylib().define(
1580eaee545SJonas Devlieghere std::make_unique<PartitioningIRMaterializationUnit>(
1590aec49c8SLang Hames ES, *getManglingOptions(), std::move(TSM), *this))) {
16068c9b8d6SLang Hames ES.reportError(std::move(Err));
1617dcd0042SLang Hames R->failMaterialization();
16268c9b8d6SLang Hames return;
16368c9b8d6SLang Hames }
16468c9b8d6SLang Hames
165a7b8393fSLang Hames if (!NonCallables.empty())
1660aec49c8SLang Hames if (auto Err =
1677dcd0042SLang Hames R->replace(reexports(PDR.getImplDylib(), std::move(NonCallables),
1680aec49c8SLang Hames JITDylibLookupFlags::MatchAllSymbols))) {
1690aec49c8SLang Hames getExecutionSession().reportError(std::move(Err));
1700aec49c8SLang Hames R->failMaterialization();
1710aec49c8SLang Hames return;
1720aec49c8SLang Hames }
1730aec49c8SLang Hames if (!Callables.empty()) {
1740aec49c8SLang Hames if (auto Err = R->replace(
1750aec49c8SLang Hames lazyReexports(LCTMgr, PDR.getISManager(), PDR.getImplDylib(),
1760aec49c8SLang Hames std::move(Callables), AliaseeImpls))) {
1770aec49c8SLang Hames getExecutionSession().reportError(std::move(Err));
1780aec49c8SLang Hames R->failMaterialization();
1790aec49c8SLang Hames return;
1800aec49c8SLang Hames }
1810aec49c8SLang Hames }
18268c9b8d6SLang Hames }
18368c9b8d6SLang Hames
184079df9abSLang Hames CompileOnDemandLayer::PerDylibResources &
getPerDylibResources(JITDylib & TargetD)185079df9abSLang Hames CompileOnDemandLayer::getPerDylibResources(JITDylib &TargetD) {
1861ea8d125SLang Hames std::lock_guard<std::mutex> Lock(CODLayerMutex);
1871ea8d125SLang Hames
188d8048675SLang Hames auto I = DylibResources.find(&TargetD);
189d8048675SLang Hames if (I == DylibResources.end()) {
1904fc68b9bSLang Hames auto &ImplD =
19185fb9976SLang Hames getExecutionSession().createBareJITDylib(TargetD.getName() + ".impl");
192c66f8900SLang Hames JITDylibSearchOrder NewLinkOrder;
193c66f8900SLang Hames TargetD.withLinkOrderDo([&](const JITDylibSearchOrder &TargetLinkOrder) {
194c66f8900SLang Hames NewLinkOrder = TargetLinkOrder;
19585fb9976SLang Hames });
19685fb9976SLang Hames
197c66f8900SLang Hames assert(!NewLinkOrder.empty() && NewLinkOrder.front().first == &TargetD &&
198c66f8900SLang Hames NewLinkOrder.front().second ==
199c66f8900SLang Hames JITDylibLookupFlags::MatchAllSymbols &&
20023cb2e7fSLang Hames "TargetD must be at the front of its own search order and match "
20123cb2e7fSLang Hames "non-exported symbol");
202c66f8900SLang Hames NewLinkOrder.insert(std::next(NewLinkOrder.begin()),
203674df13bSLang Hames {&ImplD, JITDylibLookupFlags::MatchAllSymbols});
204c66f8900SLang Hames ImplD.setLinkOrder(NewLinkOrder, false);
205c66f8900SLang Hames TargetD.setLinkOrder(std::move(NewLinkOrder), false);
20685fb9976SLang Hames
207d8048675SLang Hames PerDylibResources PDR(ImplD, BuildIndirectStubsManager());
208d8048675SLang Hames I = DylibResources.insert(std::make_pair(&TargetD, std::move(PDR))).first;
209d8048675SLang Hames }
210d8048675SLang Hames
211d8048675SLang Hames return I->second;
21268c9b8d6SLang Hames }
21368c9b8d6SLang Hames
cleanUpModule(Module & M)214079df9abSLang Hames void CompileOnDemandLayer::cleanUpModule(Module &M) {
21598440293SLang Hames for (auto &F : M.functions()) {
21698440293SLang Hames if (F.isDeclaration())
21798440293SLang Hames continue;
21898440293SLang Hames
21998440293SLang Hames if (F.hasAvailableExternallyLinkage()) {
22098440293SLang Hames F.deleteBody();
22198440293SLang Hames F.setPersonalityFn(nullptr);
22298440293SLang Hames continue;
22398440293SLang Hames }
22498440293SLang Hames }
22598440293SLang Hames }
22698440293SLang Hames
expandPartition(GlobalValueSet & Partition)227079df9abSLang Hames void CompileOnDemandLayer::expandPartition(GlobalValueSet &Partition) {
22898440293SLang Hames // Expands the partition to ensure the following rules hold:
22998440293SLang Hames // (1) If any alias is in the partition, its aliasee is also in the partition.
23098440293SLang Hames // (2) If any aliasee is in the partition, its aliases are also in the
23198440293SLang Hames // partiton.
23298440293SLang Hames // (3) If any global variable is in the partition then all global variables
23398440293SLang Hames // are in the partition.
23498440293SLang Hames assert(!Partition.empty() && "Unexpected empty partition");
23598440293SLang Hames
23698440293SLang Hames const Module &M = *(*Partition.begin())->getParent();
23798440293SLang Hames bool ContainsGlobalVariables = false;
23898440293SLang Hames std::vector<const GlobalValue *> GVsToAdd;
23998440293SLang Hames
24098440293SLang Hames for (auto *GV : Partition)
24198440293SLang Hames if (isa<GlobalAlias>(GV))
24298440293SLang Hames GVsToAdd.push_back(
24398440293SLang Hames cast<GlobalValue>(cast<GlobalAlias>(GV)->getAliasee()));
24498440293SLang Hames else if (isa<GlobalVariable>(GV))
24598440293SLang Hames ContainsGlobalVariables = true;
24698440293SLang Hames
24798440293SLang Hames for (auto &A : M.aliases())
24898440293SLang Hames if (Partition.count(cast<GlobalValue>(A.getAliasee())))
24998440293SLang Hames GVsToAdd.push_back(&A);
25098440293SLang Hames
25198440293SLang Hames if (ContainsGlobalVariables)
25298440293SLang Hames for (auto &G : M.globals())
25398440293SLang Hames GVsToAdd.push_back(&G);
25498440293SLang Hames
25598440293SLang Hames for (auto *GV : GVsToAdd)
25698440293SLang Hames Partition.insert(GV);
25798440293SLang Hames }
25898440293SLang Hames
emitPartition(std::unique_ptr<MaterializationResponsibility> R,ThreadSafeModule TSM,IRMaterializationUnit::SymbolNameToDefinitionMap Defs)259079df9abSLang Hames void CompileOnDemandLayer::emitPartition(
2607dcd0042SLang Hames std::unique_ptr<MaterializationResponsibility> R, ThreadSafeModule TSM,
26198440293SLang Hames IRMaterializationUnit::SymbolNameToDefinitionMap Defs) {
26298440293SLang Hames
26398440293SLang Hames // FIXME: Need a 'notify lazy-extracting/emitting' callback to tie the
26498440293SLang Hames // extracted module key, extracted module, and source module key
26598440293SLang Hames // together. This could be used, for example, to provide a specific
26698440293SLang Hames // memory manager instance to the linking layer.
26798440293SLang Hames
26898440293SLang Hames auto &ES = getExecutionSession();
26998440293SLang Hames GlobalValueSet RequestedGVs;
2707dcd0042SLang Hames for (auto &Name : R->getRequestedSymbols()) {
2717dcd0042SLang Hames if (Name == R->getInitializerSymbol())
27285fb9976SLang Hames TSM.withModuleDo([&](Module &M) {
27385fb9976SLang Hames for (auto &GV : getStaticInitGVs(M))
27485fb9976SLang Hames RequestedGVs.insert(&GV);
27585fb9976SLang Hames });
27685fb9976SLang Hames else {
27798440293SLang Hames assert(Defs.count(Name) && "No definition for symbol");
27898440293SLang Hames RequestedGVs.insert(Defs[Name]);
27998440293SLang Hames }
28085fb9976SLang Hames }
28198440293SLang Hames
282809e9d1eSLang Hames /// Perform partitioning with the context lock held, since the partition
283809e9d1eSLang Hames /// function is allowed to access the globals to compute the partition.
284809e9d1eSLang Hames auto GVsToExtract =
285809e9d1eSLang Hames TSM.withModuleDo([&](Module &M) { return Partition(RequestedGVs); });
28698440293SLang Hames
28798440293SLang Hames // Take a 'None' partition to mean the whole module (as opposed to an empty
28898440293SLang Hames // partition, which means "materialize nothing"). Emit the whole module
28998440293SLang Hames // unmodified to the base layer.
29098440293SLang Hames if (GVsToExtract == None) {
29198440293SLang Hames Defs.clear();
2928b94274fSLang Hames BaseLayer.emit(std::move(R), std::move(TSM));
29398440293SLang Hames return;
29498440293SLang Hames }
29598440293SLang Hames
29698440293SLang Hames // If the partition is empty, return the whole module to the symbol table.
29798440293SLang Hames if (GVsToExtract->empty()) {
2980aec49c8SLang Hames if (auto Err =
2997dcd0042SLang Hames R->replace(std::make_unique<PartitioningIRMaterializationUnit>(
300*ae73f3fdSLang Hames std::move(TSM),
301*ae73f3fdSLang Hames MaterializationUnit::Interface(R->getSymbols(),
302*ae73f3fdSLang Hames R->getInitializerSymbol()),
3030aec49c8SLang Hames std::move(Defs), *this))) {
3040aec49c8SLang Hames getExecutionSession().reportError(std::move(Err));
3050aec49c8SLang Hames R->failMaterialization();
3060aec49c8SLang Hames return;
3070aec49c8SLang Hames }
30898440293SLang Hames return;
30998440293SLang Hames }
31098440293SLang Hames
311bf6603e9SLang Hames // Ok -- we actually need to partition the symbols. Promote the symbol
312809e9d1eSLang Hames // linkages/names, expand the partition to include any required symbols
313809e9d1eSLang Hames // (i.e. symbols that can't be separated from our partition), and
314809e9d1eSLang Hames // then extract the partition.
315809e9d1eSLang Hames //
316809e9d1eSLang Hames // FIXME: We apply this promotion once per partitioning. It's safe, but
317809e9d1eSLang Hames // overkill.
318809e9d1eSLang Hames auto ExtractedTSM =
319809e9d1eSLang Hames TSM.withModuleDo([&](Module &M) -> Expected<ThreadSafeModule> {
320809e9d1eSLang Hames auto PromotedGlobals = PromoteSymbols(M);
321bf6603e9SLang Hames if (!PromotedGlobals.empty()) {
3221df947abSLang Hames
323809e9d1eSLang Hames MangleAndInterner Mangle(ES, M.getDataLayout());
324bf6603e9SLang Hames SymbolFlagsMap SymbolFlags;
3251df947abSLang Hames IRSymbolMapper::add(ES, *getManglingOptions(),
3261df947abSLang Hames PromotedGlobals, SymbolFlags);
3271df947abSLang Hames
3287dcd0042SLang Hames if (auto Err = R->defineMaterializing(SymbolFlags))
329c55cf4afSBill Wendling return std::move(Err);
330bf6603e9SLang Hames }
331bf6603e9SLang Hames
33298440293SLang Hames expandPartition(*GVsToExtract);
33398440293SLang Hames
3341df947abSLang Hames // Submodule name is given by hashing the names of the globals.
3351df947abSLang Hames std::string SubModuleName;
3361df947abSLang Hames {
3371df947abSLang Hames std::vector<const GlobalValue*> HashGVs;
3381df947abSLang Hames HashGVs.reserve(GVsToExtract->size());
3391df947abSLang Hames for (auto *GV : *GVsToExtract)
3401df947abSLang Hames HashGVs.push_back(GV);
3411df947abSLang Hames llvm::sort(HashGVs, [](const GlobalValue *LHS, const GlobalValue *RHS) {
3421df947abSLang Hames return LHS->getName() < RHS->getName();
3431df947abSLang Hames });
3441df947abSLang Hames hash_code HC(0);
3451df947abSLang Hames for (auto *GV : HashGVs) {
3461df947abSLang Hames assert(GV->hasName() && "All GVs to extract should be named by now");
3471df947abSLang Hames auto GVName = GV->getName();
3481df947abSLang Hames HC = hash_combine(HC, hash_combine_range(GVName.begin(), GVName.end()));
3491df947abSLang Hames }
3501df947abSLang Hames raw_string_ostream(SubModuleName)
3511df947abSLang Hames << ".submodule."
3521df947abSLang Hames << formatv(sizeof(size_t) == 8 ? "{0:x16}" : "{0:x8}",
3531df947abSLang Hames static_cast<size_t>(HC))
3541df947abSLang Hames << ".ll";
3551df947abSLang Hames }
3561df947abSLang Hames
35798440293SLang Hames // Extract the requested partiton (plus any necessary aliases) and
35898440293SLang Hames // put the rest back into the impl dylib.
35998440293SLang Hames auto ShouldExtract = [&](const GlobalValue &GV) -> bool {
36098440293SLang Hames return GVsToExtract->count(&GV);
36198440293SLang Hames };
36298440293SLang Hames
3631df947abSLang Hames return extractSubModule(TSM, SubModuleName , ShouldExtract);
364809e9d1eSLang Hames });
365809e9d1eSLang Hames
366809e9d1eSLang Hames if (!ExtractedTSM) {
367809e9d1eSLang Hames ES.reportError(ExtractedTSM.takeError());
3687dcd0042SLang Hames R->failMaterialization();
369809e9d1eSLang Hames return;
370809e9d1eSLang Hames }
371809e9d1eSLang Hames
3720aec49c8SLang Hames if (auto Err = R->replace(std::make_unique<PartitioningIRMaterializationUnit>(
3730aec49c8SLang Hames ES, *getManglingOptions(), std::move(TSM), *this))) {
3740aec49c8SLang Hames ES.reportError(std::move(Err));
3750aec49c8SLang Hames R->failMaterialization();
3760aec49c8SLang Hames return;
3770aec49c8SLang Hames }
378809e9d1eSLang Hames BaseLayer.emit(std::move(R), std::move(*ExtractedTSM));
37968c9b8d6SLang Hames }
38068c9b8d6SLang Hames
38168c9b8d6SLang Hames } // end namespace orc
38268c9b8d6SLang Hames } // end namespace llvm
383