@@ -136,6 +136,29 @@ void llvm::CloneFunctionAttributesInto(Function *NewFunc,
136
136
OldAttrs.getRetAttrs (), NewArgAttrs));
137
137
}
138
138
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
+
139
162
// Clone OldFunc into NewFunc, transforming the old arguments into references to
140
163
// VMap values.
141
164
void llvm::CloneFunctionInto (Function *NewFunc, const Function *OldFunc,
@@ -168,44 +191,42 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
168
191
// duplicate instructions and then freeze them in the MD map. We also record
169
192
// information about dbg.value and dbg.declare to avoid duplicating the
170
193
// types.
171
- std::optional< DebugInfoFinder> DIFinder;
194
+ DebugInfoFinder DIFinder;
172
195
173
196
// Track the subprogram attachment that needs to be cloned to fine-tune the
174
197
// mapping within the same module.
175
- DISubprogram *SPClonedWithinModule = nullptr ;
176
198
if (Changes < CloneFunctionChangeType::DifferentModule) {
199
+ // Need to find subprograms, types, and compile units.
200
+
177
201
assert ((NewFunc->getParent () == nullptr ||
178
202
NewFunc->getParent () == OldFunc->getParent ()) &&
179
203
" 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);
187
204
} else {
205
+ // Need to find all the compile units.
206
+
188
207
assert ((NewFunc->getParent () == nullptr ||
189
208
NewFunc->getParent () != OldFunc->getParent ()) &&
190
209
" Expected NewFunc to have different parents, or no parent" );
191
210
192
211
if (Changes == CloneFunctionChangeType::DifferentModule) {
193
212
assert (NewFunc->getParent () &&
194
213
" Need parent of new function to maintain debug info invariants" );
195
-
196
- // Need to find all the compile units.
197
- DIFinder.emplace ();
198
214
}
199
215
}
200
216
217
+ DISubprogram *SPClonedWithinModule =
218
+ ProcessSubprogramAttachment (*OldFunc, Changes, DIFinder);
219
+
201
220
// Loop over all of the basic blocks in the function, cloning them as
202
221
// appropriate. Note that we save BE this way in order to handle cloning of
203
222
// recursive functions into themselves.
204
223
for (const BasicBlock &BB : *OldFunc) {
205
224
206
225
// 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 );
209
230
210
231
// Add basic block mapping.
211
232
VMap[&BB] = CBB;
@@ -228,7 +249,7 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
228
249
}
229
250
230
251
if (Changes < CloneFunctionChangeType::DifferentModule &&
231
- DIFinder-> subprogram_count () > 0 ) {
252
+ DIFinder. subprogram_count () > 0 ) {
232
253
// Turn on module-level changes, since we need to clone (some of) the
233
254
// debug info metadata.
234
255
//
@@ -243,24 +264,24 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
243
264
244
265
// Avoid cloning types, compile units, and (other) subprograms.
245
266
SmallPtrSet<const DISubprogram *, 16 > MappedToSelfSPs;
246
- for (DISubprogram *ISP : DIFinder-> subprograms ()) {
267
+ for (DISubprogram *ISP : DIFinder. subprograms ()) {
247
268
if (ISP != SPClonedWithinModule) {
248
269
mapToSelfIfNew (ISP);
249
270
MappedToSelfSPs.insert (ISP);
250
271
}
251
272
}
252
273
253
274
// 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 ()) {
255
276
auto *LScope = dyn_cast<DILocalScope>(S);
256
277
if (LScope && MappedToSelfSPs.count (LScope->getSubprogram ()))
257
278
mapToSelfIfNew (S);
258
279
}
259
280
260
- for (DICompileUnit *CU : DIFinder-> compile_units ())
281
+ for (DICompileUnit *CU : DIFinder. compile_units ())
261
282
mapToSelfIfNew (CU);
262
283
263
- for (DIType *Type : DIFinder-> types ())
284
+ for (DIType *Type : DIFinder. types ())
264
285
mapToSelfIfNew (Type);
265
286
} else {
266
287
assert (!SPClonedWithinModule &&
@@ -314,7 +335,7 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
314
335
SmallPtrSet<const void *, 8 > Visited;
315
336
for (auto *Operand : NMD->operands ())
316
337
Visited.insert (Operand);
317
- for (auto *Unit : DIFinder-> compile_units ()) {
338
+ for (auto *Unit : DIFinder. compile_units ()) {
318
339
MDNode *MappedUnit =
319
340
MapMetadata (Unit, VMap, RF_None, TypeMapper, Materializer);
320
341
if (Visited.insert (MappedUnit).second )
0 commit comments