@@ -152,6 +152,54 @@ DISubprogram *llvm::CollectDebugInfoForCloning(const Function &F,
152152 return SPClonedWithinModule;
153153}
154154
155+ bool llvm::BuildDebugInfoMDMap (DenseMap<const Metadata *, TrackingMDRef> &MD,
156+ CloneFunctionChangeType Changes,
157+ DebugInfoFinder &DIFinder,
158+ DISubprogram *SPClonedWithinModule) {
159+ bool ModuleLevelChanges = Changes > CloneFunctionChangeType::LocalChangesOnly;
160+ if (Changes < CloneFunctionChangeType::DifferentModule &&
161+ DIFinder.subprogram_count () > 0 ) {
162+ // Turn on module-level changes, since we need to clone (some of) the
163+ // debug info metadata.
164+ //
165+ // FIXME: Metadata effectively owned by a function should be made
166+ // local, and only that local metadata should be cloned.
167+ ModuleLevelChanges = true ;
168+
169+ auto mapToSelfIfNew = [&MD](MDNode *N) {
170+ // Avoid clobbering an existing mapping.
171+ (void )MD.try_emplace (N, N);
172+ };
173+
174+ // Avoid cloning types, compile units, and (other) subprograms.
175+ SmallPtrSet<const DISubprogram *, 16 > MappedToSelfSPs;
176+ for (DISubprogram *ISP : DIFinder.subprograms ()) {
177+ if (ISP != SPClonedWithinModule) {
178+ mapToSelfIfNew (ISP);
179+ MappedToSelfSPs.insert (ISP);
180+ }
181+ }
182+
183+ // If a subprogram isn't going to be cloned skip its lexical blocks as well.
184+ for (DIScope *S : DIFinder.scopes ()) {
185+ auto *LScope = dyn_cast<DILocalScope>(S);
186+ if (LScope && MappedToSelfSPs.count (LScope->getSubprogram ()))
187+ mapToSelfIfNew (S);
188+ }
189+
190+ for (DICompileUnit *CU : DIFinder.compile_units ())
191+ mapToSelfIfNew (CU);
192+
193+ for (DIType *Type : DIFinder.types ())
194+ mapToSelfIfNew (Type);
195+ } else {
196+ assert (!SPClonedWithinModule &&
197+ " Subprogram should be in DIFinder->subprogram_count()..." );
198+ }
199+
200+ return ModuleLevelChanges;
201+ }
202+
155203// Clone OldFunc into NewFunc, transforming the old arguments into references to
156204// VMap values.
157205void llvm::CloneFunctionInto (Function *NewFunc, const Function *OldFunc,
@@ -210,45 +258,8 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
210258 DISubprogram *SPClonedWithinModule =
211259 CollectDebugInfoForCloning (*OldFunc, Changes, DIFinder);
212260
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- }
261+ ModuleLevelChanges =
262+ BuildDebugInfoMDMap (VMap.MD (), Changes, DIFinder, SPClonedWithinModule);
252263
253264 const auto RemapFlag = ModuleLevelChanges ? RF_None : RF_NoModuleLevelChanges;
254265 // Duplicate the metadata that is attached to the cloned function.
0 commit comments