@@ -152,6 +152,53 @@ DISubprogram *llvm::CollectDebugInfoForCloning(const Function &F,
152152 return SPClonedWithinModule;
153153}
154154
155+ bool llvm::BuildDebugInfoMDMap (MDMapT &MD, CloneFunctionChangeType Changes,
156+ DebugInfoFinder &DIFinder,
157+ DISubprogram *SPClonedWithinModule) {
158+ bool ModuleLevelChanges = Changes > CloneFunctionChangeType::LocalChangesOnly;
159+ if (Changes < CloneFunctionChangeType::DifferentModule &&
160+ DIFinder.subprogram_count () > 0 ) {
161+ // Turn on module-level changes, since we need to clone (some of) the
162+ // debug info metadata.
163+ //
164+ // FIXME: Metadata effectively owned by a function should be made
165+ // local, and only that local metadata should be cloned.
166+ ModuleLevelChanges = true ;
167+
168+ auto mapToSelfIfNew = [&MD](MDNode *N) {
169+ // Avoid clobbering an existing mapping.
170+ (void )MD.try_emplace (N, N);
171+ };
172+
173+ // Avoid cloning types, compile units, and (other) subprograms.
174+ SmallPtrSet<const DISubprogram *, 16 > MappedToSelfSPs;
175+ for (DISubprogram *ISP : DIFinder.subprograms ()) {
176+ if (ISP != SPClonedWithinModule) {
177+ mapToSelfIfNew (ISP);
178+ MappedToSelfSPs.insert (ISP);
179+ }
180+ }
181+
182+ // If a subprogram isn't going to be cloned skip its lexical blocks as well.
183+ for (DIScope *S : DIFinder.scopes ()) {
184+ auto *LScope = dyn_cast<DILocalScope>(S);
185+ if (LScope && MappedToSelfSPs.count (LScope->getSubprogram ()))
186+ mapToSelfIfNew (S);
187+ }
188+
189+ for (DICompileUnit *CU : DIFinder.compile_units ())
190+ mapToSelfIfNew (CU);
191+
192+ for (DIType *Type : DIFinder.types ())
193+ mapToSelfIfNew (Type);
194+ } else {
195+ assert (!SPClonedWithinModule &&
196+ " Subprogram should be in DIFinder->subprogram_count()..." );
197+ }
198+
199+ return ModuleLevelChanges;
200+ }
201+
155202// Clone OldFunc into NewFunc, transforming the old arguments into references to
156203// VMap values.
157204void llvm::CloneFunctionInto (Function *NewFunc, const Function *OldFunc,
@@ -210,45 +257,8 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
210257 DISubprogram *SPClonedWithinModule =
211258 CollectDebugInfoForCloning (*OldFunc, Changes, DIFinder);
212259
213- if (Changes < CloneFunctionChangeType::DifferentModule &&
214- DIFinder.subprogram_count () > 0 ) {
215- // Turn on module-level changes, since we need to clone (some of) the
216- // debug info metadata.
217- //
218- // FIXME: Metadata effectively owned by a function should be made
219- // local, and only that local metadata should be cloned.
220- ModuleLevelChanges = true ;
221-
222- auto mapToSelfIfNew = [&VMap](MDNode *N) {
223- // Avoid clobbering an existing mapping.
224- (void )VMap.MD ().try_emplace (N, N);
225- };
226-
227- // Avoid cloning types, compile units, and (other) subprograms.
228- SmallPtrSet<const DISubprogram *, 16 > MappedToSelfSPs;
229- for (DISubprogram *ISP : DIFinder.subprograms ()) {
230- if (ISP != SPClonedWithinModule) {
231- mapToSelfIfNew (ISP);
232- MappedToSelfSPs.insert (ISP);
233- }
234- }
235-
236- // If a subprogram isn't going to be cloned skip its lexical blocks as well.
237- for (DIScope *S : DIFinder.scopes ()) {
238- auto *LScope = dyn_cast<DILocalScope>(S);
239- if (LScope && MappedToSelfSPs.count (LScope->getSubprogram ()))
240- mapToSelfIfNew (S);
241- }
242-
243- for (DICompileUnit *CU : DIFinder.compile_units ())
244- mapToSelfIfNew (CU);
245-
246- for (DIType *Type : DIFinder.types ())
247- mapToSelfIfNew (Type);
248- } else {
249- assert (!SPClonedWithinModule &&
250- " Subprogram should be in DIFinder->subprogram_count()..." );
251- }
260+ ModuleLevelChanges =
261+ BuildDebugInfoMDMap (VMap.MD (), Changes, DIFinder, SPClonedWithinModule);
252262
253263 const auto RemapFlag = ModuleLevelChanges ? RF_None : RF_NoModuleLevelChanges;
254264 // Duplicate the metadata that is attached to the cloned function.
0 commit comments