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/STLExtras.h" |
19 | #include "llvm/ADT/StringRef.h" |
20 | #include "llvm/ExecutionEngine/JITSymbol.h" |
21 | #include "llvm/ExecutionEngine/Orc/IndirectionUtils.h" |
22 | #include "llvm/ExecutionEngine/Orc/Layer.h" |
23 | #include "llvm/ExecutionEngine/Orc/LazyReexports.h" |
24 | #include "llvm/ExecutionEngine/Orc/Shared/OrcError.h" |
25 | #include "llvm/ExecutionEngine/Orc/Speculation.h" |
26 | #include "llvm/ExecutionEngine/RuntimeDyld.h" |
27 | #include "llvm/IR/Attributes.h" |
28 | #include "llvm/IR/Constant.h" |
29 | #include "llvm/IR/Constants.h" |
30 | #include "llvm/IR/DataLayout.h" |
31 | #include "llvm/IR/Function.h" |
32 | #include "llvm/IR/GlobalAlias.h" |
33 | #include "llvm/IR/GlobalValue.h" |
34 | #include "llvm/IR/GlobalVariable.h" |
35 | #include "llvm/IR/Instruction.h" |
36 | #include "llvm/IR/Mangler.h" |
37 | #include "llvm/IR/Module.h" |
38 | #include "llvm/IR/Type.h" |
39 | #include "llvm/Support/Casting.h" |
40 | #include "llvm/Support/raw_ostream.h" |
41 | #include "llvm/Transforms/Utils/ValueMapper.h" |
42 | #include <algorithm> |
43 | #include <cassert> |
44 | #include <functional> |
45 | #include <iterator> |
46 | #include <list> |
47 | #include <memory> |
48 | #include <optional> |
49 | #include <set> |
50 | #include <utility> |
51 | |
52 | namespace llvm { |
53 | namespace orc { |
54 | |
55 | class CompileOnDemandLayer : public IRLayer { |
56 | friend class PartitioningIRMaterializationUnit; |
57 | |
58 | public: |
59 | /// Builder for IndirectStubsManagers. |
60 | using IndirectStubsManagerBuilder = |
61 | std::function<std::unique_ptr<IndirectStubsManager>()>; |
62 | |
63 | using GlobalValueSet = std::set<const GlobalValue *>; |
64 | |
65 | /// Partitioning function. |
66 | using PartitionFunction = |
67 | std::function<std::optional<GlobalValueSet>(GlobalValueSet Requested)>; |
68 | |
69 | /// Off-the-shelf partitioning which compiles all requested symbols (usually |
70 | /// a single function at a time). |
71 | static std::optional<GlobalValueSet> |
72 | compileRequested(GlobalValueSet Requested); |
73 | |
74 | /// Off-the-shelf partitioning which compiles whole modules whenever any |
75 | /// symbol in them is requested. |
76 | static std::optional<GlobalValueSet> |
77 | compileWholeModule(GlobalValueSet Requested); |
78 | |
79 | /// Construct a CompileOnDemandLayer. |
80 | CompileOnDemandLayer(ExecutionSession &ES, IRLayer &BaseLayer, |
81 | LazyCallThroughManager &LCTMgr, |
82 | IndirectStubsManagerBuilder BuildIndirectStubsManager); |
83 | |
84 | /// Sets the partition function. |
85 | void setPartitionFunction(PartitionFunction Partition); |
86 | |
87 | /// Sets the ImplSymbolMap |
88 | void setImplMap(ImplSymbolMap *Imp); |
89 | |
90 | /// Emits the given module. This should not be called by clients: it will be |
91 | /// called by the JIT when a definition added via the add method is requested. |
92 | void emit(std::unique_ptr<MaterializationResponsibility> R, |
93 | ThreadSafeModule TSM) override; |
94 | |
95 | private: |
96 | struct PerDylibResources { |
97 | public: |
98 | PerDylibResources(JITDylib &ImplD, |
99 | std::unique_ptr<IndirectStubsManager> ISMgr) |
100 | : ImplD(ImplD), ISMgr(std::move(ISMgr)) {} |
101 | JITDylib &getImplDylib() { return ImplD; } |
102 | IndirectStubsManager &getISManager() { return *ISMgr; } |
103 | |
104 | private: |
105 | JITDylib &ImplD; |
106 | std::unique_ptr<IndirectStubsManager> ISMgr; |
107 | }; |
108 | |
109 | using PerDylibResourcesMap = std::map<const JITDylib *, PerDylibResources>; |
110 | |
111 | PerDylibResources &getPerDylibResources(JITDylib &TargetD); |
112 | |
113 | void cleanUpModule(Module &M); |
114 | |
115 | void expandPartition(GlobalValueSet &Partition); |
116 | |
117 | void emitPartition(std::unique_ptr<MaterializationResponsibility> R, |
118 | ThreadSafeModule TSM, |
119 | IRMaterializationUnit::SymbolNameToDefinitionMap Defs); |
120 | |
121 | mutable std::mutex CODLayerMutex; |
122 | |
123 | IRLayer &BaseLayer; |
124 | LazyCallThroughManager &LCTMgr; |
125 | IndirectStubsManagerBuilder BuildIndirectStubsManager; |
126 | PerDylibResourcesMap DylibResources; |
127 | PartitionFunction Partition = compileRequested; |
128 | SymbolLinkagePromoter PromoteSymbols; |
129 | ImplSymbolMap *AliaseeImpls = nullptr; |
130 | }; |
131 | |
132 | } // end namespace orc |
133 | } // end namespace llvm |
134 | |
135 | #endif // LLVM_EXECUTIONENGINE_ORC_COMPILEONDEMANDLAYER_H |
136 | |