Skip to content

Commit 2f40b01

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 2f40b01

File tree

2 files changed

+50
-19
lines changed

2 files changed

+50
-19
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 & 19 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,23 +192,19 @@ 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");
@@ -194,19 +213,22 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
194213
assert(NewFunc->getParent() &&
195214
"Need parent of new function to maintain debug info invariants");
196215

197-
// Need to find all the compile units.
198-
DIFinder.emplace();
199216
}
200217
}
201218

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

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

211233
// Add basic block mapping.
212234
VMap[&BB] = CBB;
@@ -229,7 +251,7 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
229251
}
230252

231253
if (Changes < CloneFunctionChangeType::DifferentModule &&
232-
DIFinder->subprogram_count() > 0) {
254+
DIFinder.subprogram_count() > 0) {
233255
// Turn on module-level changes, since we need to clone (some of) the
234256
// debug info metadata.
235257
//
@@ -244,24 +266,24 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
244266

245267
// Avoid cloning types, compile units, and (other) subprograms.
246268
SmallPtrSet<const DISubprogram *, 16> MappedToSelfSPs;
247-
for (DISubprogram *ISP : DIFinder->subprograms()) {
269+
for (DISubprogram *ISP : DIFinder.subprograms()) {
248270
if (ISP != SPClonedWithinModule) {
249271
mapToSelfIfNew(ISP);
250272
MappedToSelfSPs.insert(ISP);
251273
}
252274
}
253275

254276
// If a subprogram isn't going to be cloned skip its lexical blocks as well.
255-
for (DIScope *S : DIFinder->scopes()) {
277+
for (DIScope *S : DIFinder.scopes()) {
256278
auto *LScope = dyn_cast<DILocalScope>(S);
257279
if (LScope && MappedToSelfSPs.count(LScope->getSubprogram()))
258280
mapToSelfIfNew(S);
259281
}
260282

261-
for (DICompileUnit *CU : DIFinder->compile_units())
283+
for (DICompileUnit *CU : DIFinder.compile_units())
262284
mapToSelfIfNew(CU);
263285

264-
for (DIType *Type : DIFinder->types())
286+
for (DIType *Type : DIFinder.types())
265287
mapToSelfIfNew(Type);
266288
} else {
267289
assert(!SPClonedWithinModule &&
@@ -315,7 +337,7 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
315337
SmallPtrSet<const void *, 8> Visited;
316338
for (auto *Operand : NMD->operands())
317339
Visited.insert(Operand);
318-
for (auto *Unit : DIFinder->compile_units()) {
340+
for (auto *Unit : DIFinder.compile_units()) {
319341
MDNode *MappedUnit =
320342
MapMetadata(Unit, VMap, RF_None, TypeMapper, Materializer);
321343
if (Visited.insert(MappedUnit).second)

0 commit comments

Comments
 (0)