Skip to content

Commit e2b2ee8

Browse files
committed
[Utils] Extract ProcessSubprogramAttachment from CloneFunctionInto
Summary: Consolidate the logic in a single function. We do an extra pass over Instructions but this is necessary to untangle things and extract metadata cloning in a future diff. Test Plan: ninja check-llvm-unit
1 parent 4ed7bcb commit e2b2ee8

File tree

2 files changed

+50
-20
lines changed

2 files changed

+50
-20
lines changed

llvm/include/llvm/Transforms/Utils/Cloning.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,15 @@ void CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc,
207207
const char *NameSuffix = "",
208208
ClonedCodeInfo *CodeInfo = nullptr);
209209

210+
/// Process function's subprogram attachment to collect relevant debug
211+
/// information in DIFinder.
212+
///
213+
/// Returns DISubprogram of the cloned function when cloning into the same
214+
/// module or nullptr otherwise.
215+
DISubprogram *ProcessSubprogramAttachment(const Function &F,
216+
CloneFunctionChangeType Changes,
217+
DebugInfoFinder &DIFinder);
218+
210219
/// This class captures the data input to the InlineFunction call, and records
211220
/// the auxiliary results produced by it.
212221
class InlineFunctionInfo {

llvm/lib/Transforms/Utils/CloneFunction.cpp

Lines changed: 41 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,29 @@ void llvm::CloneFunctionAttributesInto(Function *NewFunc,
137137
OldAttrs.getRetAttrs(), NewArgAttrs));
138138
}
139139

140+
DISubprogram *llvm::ProcessSubprogramAttachment(const Function &F,
141+
CloneFunctionChangeType Changes,
142+
DebugInfoFinder &DIFinder) {
143+
DISubprogram *SPClonedWithinModule = nullptr;
144+
if (Changes < CloneFunctionChangeType::DifferentModule) {
145+
SPClonedWithinModule = F.getSubprogram();
146+
}
147+
if (SPClonedWithinModule)
148+
DIFinder.processSubprogram(SPClonedWithinModule);
149+
150+
const Module *M = F.getParent();
151+
if (Changes != CloneFunctionChangeType::ClonedModule && M) {
152+
// Inspect instructions to process e.g. DILexicalBlocks of inlined functions
153+
for (const auto &BB : F) {
154+
for (const auto &I : BB) {
155+
DIFinder.processInstruction(*M, I);
156+
}
157+
}
158+
}
159+
160+
return SPClonedWithinModule;
161+
}
162+
140163
// Clone OldFunc into NewFunc, transforming the old arguments into references to
141164
// VMap values.
142165
void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
@@ -169,44 +192,42 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
169192
// duplicate instructions and then freeze them in the MD map. We also record
170193
// information about dbg.value and dbg.declare to avoid duplicating the
171194
// types.
172-
std::optional<DebugInfoFinder> DIFinder;
195+
DebugInfoFinder DIFinder;
173196

174197
// Track the subprogram attachment that needs to be cloned to fine-tune the
175198
// mapping within the same module.
176-
DISubprogram *SPClonedWithinModule = nullptr;
177199
if (Changes < CloneFunctionChangeType::DifferentModule) {
200+
// Need to find subprograms, types, and compile units.
201+
178202
assert((NewFunc->getParent() == nullptr ||
179203
NewFunc->getParent() == OldFunc->getParent()) &&
180204
"Expected NewFunc to have the same parent, or no parent");
181-
182-
// Need to find subprograms, types, and compile units.
183-
DIFinder.emplace();
184-
185-
SPClonedWithinModule = OldFunc->getSubprogram();
186-
if (SPClonedWithinModule)
187-
DIFinder->processSubprogram(SPClonedWithinModule);
188205
} else {
206+
// Need to find all the compile units.
207+
189208
assert((NewFunc->getParent() == nullptr ||
190209
NewFunc->getParent() != OldFunc->getParent()) &&
191210
"Expected NewFunc to have different parents, or no parent");
192211

193212
if (Changes == CloneFunctionChangeType::DifferentModule) {
194213
assert(NewFunc->getParent() &&
195214
"Need parent of new function to maintain debug info invariants");
196-
197-
// Need to find all the compile units.
198-
DIFinder.emplace();
199215
}
200216
}
201217

218+
DISubprogram *SPClonedWithinModule =
219+
ProcessSubprogramAttachment(*OldFunc, Changes, DIFinder);
220+
202221
// Loop over all of the basic blocks in the function, cloning them as
203222
// appropriate. Note that we save BE this way in order to handle cloning of
204223
// recursive functions into themselves.
205224
for (const BasicBlock &BB : *OldFunc) {
206225

207226
// Create a new basic block and copy instructions into it!
208-
BasicBlock *CBB = CloneBasicBlock(&BB, VMap, NameSuffix, NewFunc, CodeInfo,
209-
DIFinder ? &*DIFinder : nullptr);
227+
// NOTE: don't pass DIFinder becase instructions' debug info was process in
228+
// ProcessSubprogramAttachment. This will be further cleaned up.
229+
BasicBlock *CBB =
230+
CloneBasicBlock(&BB, VMap, NameSuffix, NewFunc, CodeInfo, nullptr);
210231

211232
// Add basic block mapping.
212233
VMap[&BB] = CBB;
@@ -229,7 +250,7 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
229250
}
230251

231252
if (Changes < CloneFunctionChangeType::DifferentModule &&
232-
DIFinder->subprogram_count() > 0) {
253+
DIFinder.subprogram_count() > 0) {
233254
// Turn on module-level changes, since we need to clone (some of) the
234255
// debug info metadata.
235256
//
@@ -244,24 +265,24 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
244265

245266
// Avoid cloning types, compile units, and (other) subprograms.
246267
SmallPtrSet<const DISubprogram *, 16> MappedToSelfSPs;
247-
for (DISubprogram *ISP : DIFinder->subprograms()) {
268+
for (DISubprogram *ISP : DIFinder.subprograms()) {
248269
if (ISP != SPClonedWithinModule) {
249270
mapToSelfIfNew(ISP);
250271
MappedToSelfSPs.insert(ISP);
251272
}
252273
}
253274

254275
// If a subprogram isn't going to be cloned skip its lexical blocks as well.
255-
for (DIScope *S : DIFinder->scopes()) {
276+
for (DIScope *S : DIFinder.scopes()) {
256277
auto *LScope = dyn_cast<DILocalScope>(S);
257278
if (LScope && MappedToSelfSPs.count(LScope->getSubprogram()))
258279
mapToSelfIfNew(S);
259280
}
260281

261-
for (DICompileUnit *CU : DIFinder->compile_units())
282+
for (DICompileUnit *CU : DIFinder.compile_units())
262283
mapToSelfIfNew(CU);
263284

264-
for (DIType *Type : DIFinder->types())
285+
for (DIType *Type : DIFinder.types())
265286
mapToSelfIfNew(Type);
266287
} else {
267288
assert(!SPClonedWithinModule &&
@@ -315,7 +336,7 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
315336
SmallPtrSet<const void *, 8> Visited;
316337
for (auto *Operand : NMD->operands())
317338
Visited.insert(Operand);
318-
for (auto *Unit : DIFinder->compile_units()) {
339+
for (auto *Unit : DIFinder.compile_units()) {
319340
MDNode *MappedUnit =
320341
MapMetadata(Unit, VMap, RF_None, TypeMapper, Materializer);
321342
if (Visited.insert(MappedUnit).second)

0 commit comments

Comments
 (0)