LLVM: lib/ExecutionEngine/Orc/IRPartitionLayer.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
12
13using namespace llvm;
15
19
20 auto DeleteExtractedDefs = [](GlobalValue &GV) {
21
23
24
27 F.deleteBody();
28 F.setPersonalityFn(nullptr);
32
33
35 Constant *Aliasee = A.getAliasee();
36 assert(A.hasName() && "Anonymous alias?");
37 assert(Aliasee->hasName() && "Anonymous aliasee");
38 std::string AliasName = std::string(A.getName());
39
43 A.eraseFromParent();
44 F->setName(AliasName);
49 A.eraseFromParent();
50 G->setName(AliasName);
51 } else
53 } else
55 };
56
57 auto NewTSM = cloneToNewContext(TSM, ShouldExtract, DeleteExtractedDefs);
58 NewTSM.withModuleDo([&](Module &M) {
59 M.setModuleIdentifier((M.getModuleIdentifier() + Suffix).str());
60 });
61
62 return NewTSM;
63}
64
65namespace llvm {
66namespace orc {
67
69public:
75
82
83private:
84 void materialize(std::unique_ptr R) override {
85 Parent.emitPartition(std::move(R), std::move(TSM),
87 }
88
90
91
93 "ExtractingIRMaterializationUnit");
94 }
95
97};
98
99}
100}
101
104
106 this->Partition = Partition;
107}
108
109std::optionalIRPartitionLayer::GlobalValueSet
111 return std::move(Requested);
112}
113
114std::optionalIRPartitionLayer::GlobalValueSet
116 return std::nullopt;
117}
118
121 assert(TSM && "Null module");
122
125
126 cleanUpModule(M);
127 });
128
129
130 if (auto Err = R->replace(std::make_unique(
132 ES.reportError(std::move(Err));
133 R->failMaterialization();
134 return;
135 }
136}
137
138void IRPartitionLayer::cleanUpModule(Module &M) {
139 for (auto &F : M.functions()) {
140 if (F.isDeclaration())
141 continue;
142
143 if (F.hasAvailableExternallyLinkage()) {
144 F.deleteBody();
145 F.setPersonalityFn(nullptr);
146 continue;
147 }
148 }
149}
150
151void IRPartitionLayer::expandPartition(GlobalValueSet &Partition) {
152
153
154
155
156
157
158 assert(!Partition.empty() && "Unexpected empty partition");
159
160 const Module &M = *(*Partition.begin())->getParent();
161 bool ContainsGlobalVariables = false;
162 std::vector<const GlobalValue *> GVsToAdd;
163
164 for (const auto *GV : Partition)
166 GVsToAdd.push_back(
169 ContainsGlobalVariables = true;
170
171 for (auto &A : M.aliases())
173 GVsToAdd.push_back(&A);
174
175 if (ContainsGlobalVariables)
176 for (auto &G : M.globals())
177 GVsToAdd.push_back(&G);
178
179 for (const auto *GV : GVsToAdd)
180 Partition.insert(GV);
181}
182
183void IRPartitionLayer::emitPartition(
184 std::unique_ptr R, ThreadSafeModule TSM,
186
187
188
189
190
191
194 for (auto &Name : R->getRequestedSymbols()) {
195 if (Name == R->getInitializerSymbol())
198 RequestedGVs.insert(&GV);
199 });
200 else {
201 assert(Defs.count(Name) && "No definition for symbol");
202 RequestedGVs.insert(Defs[Name]);
203 }
204 }
205
206
207
208 auto GVsToExtract =
209 TSM.withModuleDo([&](Module &M) { return Partition(RequestedGVs); });
210
211
212
213
214 if (GVsToExtract == std::nullopt) {
215 Defs.clear();
216 BaseLayer.emit(std::move(R), std::move(TSM));
217 return;
218 }
219
220
221 if (GVsToExtract->empty()) {
222 if (auto Err =
223 R->replace(std::make_unique(
224 std::move(TSM),
225 MaterializationUnit::Interface(R->getSymbols(),
226 R->getInitializerSymbol()),
227 std::move(Defs), *this))) {
229 R->failMaterialization();
230 return;
231 }
232 return;
233 }
234
235
236
237
238
239
240
241
243 -> Expected {
244 auto PromotedGlobals = PromoteSymbols(M);
245 if (!PromotedGlobals.empty()) {
246
247 MangleAndInterner Mangle(ES, M.getDataLayout());
250 SymbolFlags);
251
252 if (auto Err = R->defineMaterializing(SymbolFlags))
253 return std::move(Err);
254 }
255
256 expandPartition(*GVsToExtract);
257
258
259 std::string SubModuleName;
260 {
261 std::vector<const GlobalValue *> HashGVs;
262 HashGVs.reserve(GVsToExtract->size());
264 llvm::sort(HashGVs, [](const GlobalValue *LHS, const GlobalValue *RHS) {
266 });
267 hash_code HC(0);
268 for (const auto *GV : HashGVs) {
269 assert(GV->hasName() && "All GVs to extract should be named by now");
270 auto GVName = GV->getName();
272 }
273 raw_string_ostream(SubModuleName)
274 << ".submodule."
275 << formatv(sizeof(size_t) == 8 ? "{0:x16}" : "{0:x8}",
276 static_cast<size_t>(HC))
277 << ".ll";
278 }
279
280
281
282 auto ShouldExtract = [&](const GlobalValue &GV) -> bool {
283 return GVsToExtract->count(&GV);
284 };
285
287 });
288
289 if (!ExtractedTSM) {
290 ES.reportError(ExtractedTSM.takeError());
291 R->failMaterialization();
292 return;
293 }
294
295 if (auto Err = R->replace(std::make_unique(
297 ES.reportError(std::move(Err));
298 R->failMaterialization();
299 return;
300 }
301 BaseLayer.emit(std::move(R), std::move(*ExtractedTSM));
302}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static ThreadSafeModule extractSubModule(ThreadSafeModule &TSM, StringRef Suffix, GVPredicate ShouldExtract)
Definition IRPartitionLayer.cpp:16
Machine Check Debug Module
This is an important base class in LLVM.
@ ExternalLinkage
Externally visible function.
A Module instance is used to store all the information related to an LLVM module.
StringRef - Represent a constant reference to a string, i.e.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
An ExecutionSession represents a running JIT program.
void reportError(Error Err)
Report a error for this execution session.
IRLayer(ExecutionSession &ES, const IRSymbolMapper::ManglingOptions *&MO)
ExecutionSession & getExecutionSession()
Returns the ExecutionSession for this layer.
const IRSymbolMapper::ManglingOptions *& getManglingOptions() const
Get the mangling options for this layer.
SymbolNameToDefinitionMap SymbolToDefinition
IRMaterializationUnit(ExecutionSession &ES, const IRSymbolMapper::ManglingOptions &MO, ThreadSafeModule TSM)
Create an IRMaterializationLayer.
std::map< SymbolStringPtr, GlobalValue * > SymbolNameToDefinitionMap
A layer that breaks up IR modules into smaller submodules that only contains looked up symbols.
std::function< std::optional< GlobalValueSet >(GlobalValueSet Requested)> PartitionFunction
Partitioning function.
void emit(std::unique_ptr< MaterializationResponsibility > R, ThreadSafeModule TSM) override
Emits the given module.
Definition IRPartitionLayer.cpp:119
static std::optional< GlobalValueSet > compileWholeModule(GlobalValueSet Requested)
Off-the-shelf partitioning which compiles whole modules whenever any symbol in them is requested.
Definition IRPartitionLayer.cpp:115
std::set< const GlobalValue * > GlobalValueSet
IRPartitionLayer(ExecutionSession &ES, IRLayer &BaseLayer)
Construct a IRPartitionLayer.
Definition IRPartitionLayer.cpp:102
void setPartitionFunction(PartitionFunction Partition)
Sets the partition function.
Definition IRPartitionLayer.cpp:105
static std::optional< GlobalValueSet > compileRequested(GlobalValueSet Requested)
Off-the-shelf partitioning which compiles all requested symbols (usually a single function at a time)...
Definition IRPartitionLayer.cpp:110
static LLVM_ABI void add(ExecutionSession &ES, const ManglingOptions &MO, ArrayRef< GlobalValue * > GVs, SymbolFlagsMap &SymbolFlags, SymbolNameToDefinitionMap *SymbolToDefinition=nullptr)
Add mangled symbols for the given GlobalValues to SymbolFlags.
Represents a JIT'd dynamic library.
PartitioningIRMaterializationUnit(ThreadSafeModule TSM, Interface I, SymbolNameToDefinitionMap SymbolToDefinition, IRPartitionLayer &Parent)
Definition IRPartitionLayer.cpp:76
PartitioningIRMaterializationUnit(ExecutionSession &ES, const IRSymbolMapper::ManglingOptions &MO, ThreadSafeModule TSM, IRPartitionLayer &Parent)
Definition IRPartitionLayer.cpp:70
Pointer to a pooled string representing a symbol name.
An LLVM Module together with a shared ThreadSafeContext.
decltype(auto) withModuleDo(Func &&F)
Locks the associated ThreadSafeContext and calls the given function on the contained Module.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
std::function< bool(const GlobalValue &)> GVPredicate
iterator_range< StaticInitGVIterator > getStaticInitGVs(Module &M)
Create an iterator range over the GlobalValues that contribute to static initialization.
LLVM_ABI GlobalVariable * cloneGlobalVariableDecl(Module &Dst, const GlobalVariable &GV, ValueToValueMapTy *VMap=nullptr)
Clone a global variable declaration into a new module.
LLVM_ABI Function * cloneFunctionDecl(Module &Dst, const Function &F, ValueToValueMapTy *VMap=nullptr)
Clone a function declaration into a new module.
LLVM_ABI ThreadSafeModule cloneToNewContext(const ThreadSafeModule &TSMW, GVPredicate ShouldCloneDef=GVPredicate(), GVModifier UpdateClonedDefSource=GVModifier())
Clones the given module on to a new context.
DenseMap< SymbolStringPtr, JITSymbolFlags > SymbolFlagsMap
A map from symbol names (as SymbolStringPtrs) to JITSymbolFlags.
This is an optimization pass for GlobalISel generic memory operations.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
void sort(IteratorTy Start, IteratorTy End)
bool isa(const From &Val)
isa - Return true if the parameter to the template is an instance of one of the template type argu...
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.
hash_code hash_combine(const Ts &...args)
Combine values into a single hash_code.
hash_code hash_combine_range(InputIteratorT first, InputIteratorT last)
Compute a hash_code for a sequence of values.
Implement std::hash so that hash_code can be used in STL containers.