Skip to content

Commit a415938

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 0a1795f commit a415938

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
@@ -136,6 +136,29 @@ void llvm::CloneFunctionAttributesInto(Function *NewFunc,
136136
OldAttrs.getRetAttrs(), NewArgAttrs));
137137
}
138138

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

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

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

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

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

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

230251
if (Changes < CloneFunctionChangeType::DifferentModule &&
231-
DIFinder->subprogram_count() > 0) {
252+
DIFinder.subprogram_count() > 0) {
232253
// Turn on module-level changes, since we need to clone (some of) the
233254
// debug info metadata.
234255
//
@@ -243,24 +264,24 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
243264

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

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

260-
for (DICompileUnit *CU : DIFinder->compile_units())
281+
for (DICompileUnit *CU : DIFinder.compile_units())
261282
mapToSelfIfNew(CU);
262283

263-
for (DIType *Type : DIFinder->types())
284+
for (DIType *Type : DIFinder.types())
264285
mapToSelfIfNew(Type);
265286
} else {
266287
assert(!SPClonedWithinModule &&
@@ -314,7 +335,7 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
314335
SmallPtrSet<const void *, 8> Visited;
315336
for (auto *Operand : NMD->operands())
316337
Visited.insert(Operand);
317-
for (auto *Unit : DIFinder->compile_units()) {
338+
for (auto *Unit : DIFinder.compile_units()) {
318339
MDNode *MappedUnit =
319340
MapMetadata(Unit, VMap, RF_None, TypeMapper, Materializer);
320341
if (Visited.insert(MappedUnit).second)

0 commit comments

Comments
 (0)