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