[Alignment][NFC] Use Align with TargetLowering::setMinFunctionAlignment
[llvm-core.git] / include / llvm / ExecutionEngine / Orc / CompileOnDemandLayer.h
blob7946b5b7b209b3f8f39345c3b4effab55ecd408d
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.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_EXECUTIONENGINE_ORC_COMPILEONDEMANDLAYER_H
15 #define LLVM_EXECUTIONENGINE_ORC_COMPILEONDEMANDLAYER_H
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>
57 namespace llvm {
59 class Value;
61 namespace orc {
63 class ExtractingIRMaterializationUnit;
65 class CompileOnDemandLayer : public IRLayer {
66 friend class PartitioningIRMaterializationUnit;
68 public:
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 /// 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;
101 private:
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; }
110 private:
111 JITDylib &ImplD;
112 std::unique_ptr<IndirectStubsManager> ISMgr;
115 using PerDylibResourcesMap = std::map<const JITDylib *, PerDylibResources>;
117 PerDylibResources &getPerDylibResources(JITDylib &TargetD);
119 void cleanUpModule(Module &M);
121 void expandPartition(GlobalValueSet &Partition);
123 void emitPartition(MaterializationResponsibility R, ThreadSafeModule TSM,
124 IRMaterializationUnit::SymbolNameToDefinitionMap Defs);
126 mutable std::mutex CODLayerMutex;
128 IRLayer &BaseLayer;
129 LazyCallThroughManager &LCTMgr;
130 IndirectStubsManagerBuilder BuildIndirectStubsManager;
131 PerDylibResourcesMap DylibResources;
132 PartitionFunction Partition = compileRequested;
133 SymbolLinkagePromoter PromoteSymbols;
134 ImplSymbolMap *AliaseeImpls = nullptr;
137 /// Compile-on-demand layer.
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.
144 template <typename BaseLayerT,
145 typename CompileCallbackMgrT = JITCompileCallbackManager,
146 typename IndirectStubsMgrT = IndirectStubsManager>
147 class LegacyCompileOnDemandLayer {
148 private:
149 template <typename MaterializerFtor>
150 class LambdaMaterializer final : public ValueMaterializer {
151 public:
152 LambdaMaterializer(MaterializerFtor M) : M(std::move(M)) {}
154 Value *materialize(Value *V) final { return M(V); }
156 private:
157 MaterializerFtor M;
160 template <typename MaterializerFtor>
161 LambdaMaterializer<MaterializerFtor>
162 createLambdaMaterializer(MaterializerFtor M) {
163 return LambdaMaterializer<MaterializerFtor>(std::move(M));
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;
175 virtual ResourceT& getResource() const = 0;
178 template <typename ResourceT, typename ResourcePtrT>
179 class ResourceOwnerImpl : public ResourceOwner<ResourceT> {
180 public:
181 ResourceOwnerImpl(ResourcePtrT ResourcePtr)
182 : ResourcePtr(std::move(ResourcePtr)) {}
184 ResourceT& getResource() const override { return *ResourcePtr; }
186 private:
187 ResourcePtrT ResourcePtr;
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));
197 struct LogicalDylib {
198 struct SourceModuleEntry {
199 std::unique_ptr<Module> SourceMod;
200 std::set<Function*> StubsToClone;
203 using SourceModulesList = std::vector<SourceModuleEntry>;
204 using SourceModuleHandle = typename SourceModulesList::size_type;
206 LogicalDylib() = default;
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)) {}
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;
220 Module& getSourceModule(SourceModuleHandle H) {
221 return *SourceModules[H].SourceMod;
224 std::set<Function*>& getStubsToClone(SourceModuleHandle H) {
225 return SourceModules[H].StubsToClone;
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;
240 Error removeModulesFromBaseLayer(BaseLayerT &BaseLayer) {
241 for (auto &BLK : BaseLayerVModuleKeys)
242 if (auto Err = BaseLayer.removeModule(BLK))
243 return Err;
244 return Error::success();
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;
255 public:
257 /// Module partitioning functor.
258 using PartitioningFtor = std::function<std::set<Function*>(Function&)>;
260 /// Builder for IndirectStubsManagers.
261 using IndirectStubsManagerBuilderT =
262 std::function<std::unique_ptr<IndirectStubsMgrT>()>;
264 using SymbolResolverGetter =
265 std::function<std::shared_ptr<SymbolResolver>(VModuleKey K)>;
267 using SymbolResolverSetter =
268 std::function<void(VModuleKey K, std::shared_ptr<SymbolResolver> R)>;
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");
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) {}
298 ~LegacyCompileOnDemandLayer() {
299 // FIXME: Report error on log.
300 while (!LogicalDylibs.empty())
301 consumeError(removeModule(LogicalDylibs.begin()->first));
304 /// Add a module to the compile-on-demand layer.
305 Error addModule(VModuleKey K, std::unique_ptr<Module> M) {
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())));
313 return addLogicalModule(I->second, std::move(M));
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));
321 /// Remove the module represented by the given key.
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;
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);
346 return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
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);
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.
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();
379 return make_error<JITSymbolNotFound>(FuncName);
382 private:
383 Error addLogicalModule(LogicalDylib &LD, std::unique_ptr<Module> SrcMPtr) {
385 // Rename anonymous globals and promote linkage to ensure that everything
386 // will resolve properly after we partition SrcM.
387 LD.PromoteSymbols(*SrcMPtr);
389 // Create a logical module handle for SrcM within the logical dylib.
390 Module &SrcM = *SrcMPtr;
391 auto LMId = LD.addSourceModule(std::move(SrcMPtr));
393 // Create stub functions.
394 const DataLayout &DL = SrcM.getDataLayout();
396 typename IndirectStubsMgrT::StubInitsMap StubInits;
397 for (auto &F : SrcM) {
398 // Skip declarations.
399 if (F.isDeclaration())
400 continue;
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);
411 // Record all functions defined by this module.
412 if (CloneStubsIntoPartitions)
413 LD.getStubsToClone(LMId).insert(&F);
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;
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();
435 if (auto Err = LD.StubsMgr->createStubs(StubInits))
436 return Err;
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();
446 // Create the GlobalValues module.
447 auto GVsM = std::make_unique<Module>((SrcM.getName() + ".globals").str(),
448 SrcM.getContext());
449 GVsM->setDataLayout(DL);
451 ValueToValueMapTy VMap;
453 // Clone global variable decls.
454 for (auto &GV : SrcM.globals())
455 if (!GV.isDeclaration() && !VMap.count(&GV))
456 cloneGlobalVariableDecl(*GVsM, GV, &VMap);
458 // And the aliases.
459 for (auto &A : SrcM.aliases())
460 if (!VMap.count(&A))
461 cloneGlobalAliasDecl(*GVsM, A, VMap);
463 // Clone the module flags.
464 cloneModuleFlagsMetadata(*GVsM, SrcM, VMap);
466 // Now we need to clone the GV and alias initializers.
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);
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();
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());
495 // else....
496 return nullptr;
499 // Clone the global variable initializers.
500 for (auto &GV : SrcM.globals())
501 if (!GV.isDeclaration())
502 moveGlobalVariableInitializer(GV, VMap, &Materializer);
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));
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;
518 if (auto Sym = LD.findSymbol(BaseLayer, Name, false))
519 return Sym;
520 else if (auto Err = Sym.takeError())
521 return std::move(Err);
523 return nullptr;
526 auto GVsResolver = createSymbolResolver(
527 [&LD, LegacyLookup](const SymbolNameSet &Symbols) {
528 auto RS = getResponsibilitySetWithLegacyFn(Symbols, LegacyLookup);
530 if (!RS) {
531 logAllUnhandledErrors(
532 RS.takeError(), errs(),
533 "CODLayer/GVsResolver responsibility set lookup failed: ");
534 return SymbolNameSet();
537 if (RS->size() == Symbols.size())
538 return *RS;
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);
547 for (auto &S : RS2)
548 (*RS).insert(S);
550 return *RS;
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);
560 SetSymbolResolver(LD.K, std::move(GVsResolver));
562 if (auto Err = BaseLayer.addModule(LD.K, std::move(GVsM)))
563 return Err;
565 LD.BaseLayerVModuleKeys.push_back(LD.K);
567 return Error::success();
570 static std::string mangle(StringRef Name, const DataLayout &DL) {
571 std::string MangledName;
573 raw_string_ostream MangledNameStream(MangledName);
574 Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
576 return MangledName;
579 Expected<JITTargetAddress>
580 extractAndCompile(LogicalDylib &LD,
581 typename LogicalDylib::SourceModuleHandle LMId,
582 Function &F) {
583 Module &SrcM = LD.getSourceModule(LMId);
585 // If F is a declaration we must already have compiled it.
586 if (F.isDeclaration())
587 return 0;
589 // Grab the name of the function being called here.
590 std::string CalledFnName = mangle(F.getName(), SrcM.getDataLayout());
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;
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;
607 // Update the function body pointer for the stub.
608 if (auto EC = LD.StubsMgr->updatePointer(FnName, FnBodyAddr))
609 return 0;
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");
619 LD.BaseLayerVModuleKeys.push_back(PartKey);
620 } else
621 return PartKeyOrErr.takeError();
623 return CalledAddr;
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);
633 // Create the module.
634 std::string NewName = SrcM.getName();
635 for (auto *F : Part) {
636 NewName += ".";
637 NewName += F->getName();
640 auto M = std::make_unique<Module>(NewName, SrcM.getContext());
641 M->setDataLayout(SrcM.getDataLayout());
642 ValueToValueMapTy VMap;
644 auto Materializer = createLambdaMaterializer([&LD, &LMId,
645 &M](Value *V) -> Value * {
646 if (auto *GV = dyn_cast<GlobalVariable>(V))
647 return cloneGlobalVariableDecl(*M, *GV);
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);
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;
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());
672 return new GlobalVariable(*M, Ty, false, GlobalValue::ExternalLinkage,
673 nullptr, A->getName(), nullptr,
674 GlobalValue::NotThreadLocal,
675 A->getType()->getAddressSpace());
678 return nullptr;
681 // Create decls in the new module.
682 for (auto *F : Part)
683 cloneFunctionDecl(*M, *F, &VMap);
685 // Move the function bodies.
686 for (auto *F : Part)
687 moveFunctionBody(*F, VMap, &Materializer);
689 auto K = ES.allocateVModule();
691 auto LegacyLookup = [this, &LD](const std::string &Name) -> JITSymbol {
692 return LD.findSymbol(BaseLayer, Name, false);
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();
706 if (RS->size() == Symbols.size())
707 return *RS;
709 SymbolNameSet NotFoundViaLegacyLookup;
710 for (auto &S : Symbols)
711 if (!RS->count(S))
712 NotFoundViaLegacyLookup.insert(S);
714 auto RS2 =
715 LD.BackingResolver->getResponsibilitySet(NotFoundViaLegacyLookup);
717 for (auto &S : RS2)
718 (*RS).insert(S);
720 return *RS;
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));
729 SetSymbolResolver(K, std::move(Resolver));
731 if (auto Err = BaseLayer.addModule(std::move(K), std::move(M)))
732 return std::move(Err);
734 return K;
737 ExecutionSession &ES;
738 BaseLayerT &BaseLayer;
739 SymbolResolverGetter GetSymbolResolver;
740 SymbolResolverSetter SetSymbolResolver;
741 PartitioningFtor Partition;
742 CompileCallbackMgrT &CompileCallbackMgr;
743 IndirectStubsManagerBuilderT CreateIndirectStubsManager;
745 std::map<VModuleKey, LogicalDylib> LogicalDylibs;
746 bool CloneStubsIntoPartitions;
749 template <typename BaseLayerT, typename CompileCallbackMgrT,
750 typename IndirectStubsMgrT>
751 LegacyCompileOnDemandLayer<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) {}
766 } // end namespace orc
767 } // end namespace llvm
769 #endif // LLVM_EXECUTIONENGINE_ORC_COMPILEONDEMANDLAYER_H