@@ -137,6 +137,29 @@ void llvm::CloneFunctionAttributesInto(Function *NewFunc,
137137 OldAttrs.getRetAttrs (), NewArgAttrs));
138138}
139139
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+
140163// Clone OldFunc into NewFunc, transforming the old arguments into references to
141164// VMap values.
142165void llvm::CloneFunctionInto (Function *NewFunc, const Function *OldFunc,
@@ -169,44 +192,42 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
169192 // duplicate instructions and then freeze them in the MD map. We also record
170193 // information about dbg.value and dbg.declare to avoid duplicating the
171194 // types.
172- std::optional< DebugInfoFinder> DIFinder;
195+ DebugInfoFinder DIFinder;
173196
174197 // Track the subprogram attachment that needs to be cloned to fine-tune the
175198 // mapping within the same module.
176- DISubprogram *SPClonedWithinModule = nullptr ;
177199 if (Changes < CloneFunctionChangeType::DifferentModule) {
200+ // Need to find subprograms, types, and compile units.
201+
178202 assert ((NewFunc->getParent () == nullptr ||
179203 NewFunc->getParent () == OldFunc->getParent ()) &&
180204 " 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);
188205 } else {
206+ // Need to find all the compile units.
207+
189208 assert ((NewFunc->getParent () == nullptr ||
190209 NewFunc->getParent () != OldFunc->getParent ()) &&
191210 " Expected NewFunc to have different parents, or no parent" );
192211
193212 if (Changes == CloneFunctionChangeType::DifferentModule) {
194213 assert (NewFunc->getParent () &&
195214 " Need parent of new function to maintain debug info invariants" );
196-
197- // Need to find all the compile units.
198- DIFinder.emplace ();
199215 }
200216 }
201217
218+ DISubprogram *SPClonedWithinModule =
219+ ProcessSubprogramAttachment (*OldFunc, Changes, DIFinder);
220+
202221 // Loop over all of the basic blocks in the function, cloning them as
203222 // appropriate. Note that we save BE this way in order to handle cloning of
204223 // recursive functions into themselves.
205224 for (const BasicBlock &BB : *OldFunc) {
206225
207226 // 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 );
210231
211232 // Add basic block mapping.
212233 VMap[&BB] = CBB;
@@ -229,7 +250,7 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
229250 }
230251
231252 if (Changes < CloneFunctionChangeType::DifferentModule &&
232- DIFinder-> subprogram_count () > 0 ) {
253+ DIFinder. subprogram_count () > 0 ) {
233254 // Turn on module-level changes, since we need to clone (some of) the
234255 // debug info metadata.
235256 //
@@ -244,24 +265,24 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
244265
245266 // Avoid cloning types, compile units, and (other) subprograms.
246267 SmallPtrSet<const DISubprogram *, 16 > MappedToSelfSPs;
247- for (DISubprogram *ISP : DIFinder-> subprograms ()) {
268+ for (DISubprogram *ISP : DIFinder. subprograms ()) {
248269 if (ISP != SPClonedWithinModule) {
249270 mapToSelfIfNew (ISP);
250271 MappedToSelfSPs.insert (ISP);
251272 }
252273 }
253274
254275 // 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 ()) {
256277 auto *LScope = dyn_cast<DILocalScope>(S);
257278 if (LScope && MappedToSelfSPs.count (LScope->getSubprogram ()))
258279 mapToSelfIfNew (S);
259280 }
260281
261- for (DICompileUnit *CU : DIFinder-> compile_units ())
282+ for (DICompileUnit *CU : DIFinder. compile_units ())
262283 mapToSelfIfNew (CU);
263284
264- for (DIType *Type : DIFinder-> types ())
285+ for (DIType *Type : DIFinder. types ())
265286 mapToSelfIfNew (Type);
266287 } else {
267288 assert (!SPClonedWithinModule &&
@@ -315,7 +336,7 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
315336 SmallPtrSet<const void *, 8 > Visited;
316337 for (auto *Operand : NMD->operands ())
317338 Visited.insert (Operand);
318- for (auto *Unit : DIFinder-> compile_units ()) {
339+ for (auto *Unit : DIFinder. compile_units ()) {
319340 MDNode *MappedUnit =
320341 MapMetadata (Unit, VMap, RF_None, TypeMapper, Materializer);
321342 if (Visited.insert (MappedUnit).second )
0 commit comments