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