@@ -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.
141164void 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