Skip to content

[MemProf] Update the DISubprogram linkageName for clones #145385

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 24, 2025

Conversation

teresajohnson
Copy link
Contributor

This corrects the debug information for the cloned functions so that it
contains the correct linkage name.

This corrects the debug information for the cloned functions so that it
contains the correct linkage name.
@llvmbot llvmbot added LTO Link time optimization (regular/full LTO or ThinLTO) llvm:transforms labels Jun 23, 2025
@llvmbot
Copy link
Member

llvmbot commented Jun 23, 2025

@llvm/pr-subscribers-llvm-transforms

Author: Teresa Johnson (teresajohnson)

Changes

This corrects the debug information for the cloned functions so that it
contains the correct linkage name.


Full diff: https://github.com/llvm/llvm-project/pull/145385.diff

3 Files Affected:

  • (modified) llvm/lib/Transforms/IPO/MemProfContextDisambiguation.cpp (+6)
  • (modified) llvm/test/ThinLTO/X86/memprof-basic.ll (+16-3)
  • (modified) llvm/test/Transforms/MemProfContextDisambiguation/basic.ll (+16-3)
diff --git a/llvm/lib/Transforms/IPO/MemProfContextDisambiguation.cpp b/llvm/lib/Transforms/IPO/MemProfContextDisambiguation.cpp
index 10120dd0e10c1..c0f84456d2b27 100644
--- a/llvm/lib/Transforms/IPO/MemProfContextDisambiguation.cpp
+++ b/llvm/lib/Transforms/IPO/MemProfContextDisambiguation.cpp
@@ -4001,6 +4001,9 @@ ModuleCallsiteContextGraph::cloneFunctionForCallsite(
   std::string Name = getMemProfFuncName(Func.func()->getName(), CloneNo);
   assert(!Func.func()->getParent()->getFunction(Name));
   NewFunc->setName(Name);
+  if (auto *SP = NewFunc->getSubprogram())
+    SP->replaceLinkageName(
+        MDString::get(NewFunc->getParent()->getContext(), Name));
   for (auto &Inst : CallsWithMetadataInFunc) {
     // This map always has the initial version in it.
     assert(Inst.cloneNo() == 0);
@@ -4939,6 +4942,9 @@ static SmallVector<std::unique_ptr<ValueToValueMapTy>, 4> createFunctionClones(
       PrevF->eraseFromParent();
     } else
       NewF->setName(Name);
+    if (auto *SP = NewF->getSubprogram())
+      SP->replaceLinkageName(
+          MDString::get(NewF->getParent()->getContext(), Name));
     ORE.emit(OptimizationRemark(DEBUG_TYPE, "MemprofClone", &F)
              << "created clone " << ore::NV("NewFunction", NewF));
 
diff --git a/llvm/test/ThinLTO/X86/memprof-basic.ll b/llvm/test/ThinLTO/X86/memprof-basic.ll
index 9c1f77bcd569c..72d282fe7bef5 100644
--- a/llvm/test/ThinLTO/X86/memprof-basic.ll
+++ b/llvm/test/ThinLTO/X86/memprof-basic.ll
@@ -100,7 +100,7 @@ declare void @_ZdaPv()
 
 declare i32 @sleep()
 
-define internal ptr @_Z3barv() #0 {
+define internal ptr @_Z3barv() #0 !dbg !15 {
 entry:
   %call = call ptr @_Znam(i64 0), !memprof !2, !callsite !7
   ret ptr null
@@ -125,6 +125,9 @@ uselistorder ptr @_Z3foov, { 1, 0 }
 
 attributes #0 = { noinline optnone }
 
+!llvm.dbg.cu = !{!13}
+!llvm.module.flags = !{!20, !21}
+
 !0 = !{i64 8632435727821051414}
 !1 = !{i64 -3421689549917153178}
 !2 = !{!3, !5}
@@ -138,7 +141,15 @@ attributes #0 = { noinline optnone }
 !10 = !{i64 123, i64 100}
 !11 = !{i64 456, i64 200}
 !12 = !{i64 789, i64 300}
-
+!13 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !14, producer: "clang version 21.0.0git (git@github.com:llvm/llvm-project.git e391301e0e4d9183fe06e69602e87b0bc889aeda)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
+!14 = !DIFile(filename: "basic.cc", directory: "", checksumkind: CSK_MD5, checksum: "8636c46e81402013b9d54e8307d2f149")
+!15 = distinct !DISubprogram(name: "bar", linkageName: "_Z3barv", scope: !14, file: !14, line: 1, type: !16, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !13)
+!16 = !DISubroutineType(types: !17)
+!17 = !{!18}
+!18 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !19, size: 64)
+!19 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char)
+!20 = !{i32 7, !"Dwarf Version", i32 5}
+!21 = !{i32 2, !"Debug Info Version", i32 3}
 
 ; DUMP: CCG before cloning:
 ; DUMP: Callsite Context Graph:
@@ -301,7 +312,7 @@ attributes #0 = { noinline optnone }
 ; IR:   call {{.*}} @_Z3barv()
 ; IR: define internal {{.*}} @_Z3foov()
 ; IR:   call {{.*}} @_Z3bazv()
-; IR: define internal {{.*}} @_Z3barv.memprof.1()
+; IR: define internal {{.*}} @_Z3barv.memprof.1() {{.*}} !dbg ![[SP:[0-9]+]]
 ; IR:   call {{.*}} @_Znam(i64 0) #[[COLD:[0-9]+]]
 ; IR: define internal {{.*}} @_Z3bazv.memprof.1()
 ; IR:   call {{.*}} @_Z3barv.memprof.1()
@@ -309,6 +320,8 @@ attributes #0 = { noinline optnone }
 ; IR:   call {{.*}} @_Z3bazv.memprof.1()
 ; IR: attributes #[[NOTCOLD]] = { "memprof"="notcold" }
 ; IR: attributes #[[COLD]] = { "memprof"="cold" }
+;; Make sure the clone's linkageName was updated.
+; IR: ![[SP]] = distinct !DISubprogram(name: "bar", linkageName: "_Z3barv.memprof.1"
 
 
 ; STATS: 1 memprof-context-disambiguation - Number of cold static allocations (possibly cloned)
diff --git a/llvm/test/Transforms/MemProfContextDisambiguation/basic.ll b/llvm/test/Transforms/MemProfContextDisambiguation/basic.ll
index a21f407f85650..323df12f6335c 100644
--- a/llvm/test/Transforms/MemProfContextDisambiguation/basic.ll
+++ b/llvm/test/Transforms/MemProfContextDisambiguation/basic.ll
@@ -71,7 +71,7 @@ declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i1 immarg) #1
 ; Function Attrs: nobuiltin
 declare void @_ZdaPv() #2
 
-define internal ptr @_Z3barv() #3 {
+define internal ptr @_Z3barv() #3 !dbg !15 {
 entry:
   %call = call noalias noundef nonnull ptr @_Znam(i64 noundef 10) #6, !memprof !2, !callsite !7
   ret ptr null
@@ -103,6 +103,9 @@ attributes #4 = { "stack-protector-buffer-size"="8" }
 attributes #5 = { noinline }
 attributes #6 = { builtin }
 
+!llvm.dbg.cu = !{!13}
+!llvm.module.flags = !{!20, !21}
+
 !0 = !{i64 8632435727821051414}
 !1 = !{i64 -3421689549917153178}
 !2 = !{!3, !5}
@@ -116,7 +119,15 @@ attributes #6 = { builtin }
 !10 = !{i64 123, i64 100}
 !11 = !{i64 456, i64 200}
 !12 = !{i64 789, i64 300}
-
+!13 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !14, producer: "clang version 21.0.0git (git@github.com:llvm/llvm-project.git e391301e0e4d9183fe06e69602e87b0bc889aeda)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
+!14 = !DIFile(filename: "basic.cc", directory: "", checksumkind: CSK_MD5, checksum: "8636c46e81402013b9d54e8307d2f149")
+!15 = distinct !DISubprogram(name: "bar", linkageName: "_Z3barv", scope: !14, file: !14, line: 1, type: !16, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !13)
+!16 = !DISubroutineType(types: !17)
+!17 = !{!18}
+!18 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !19, size: 64)
+!19 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char)
+!20 = !{i32 7, !"Dwarf Version", i32 5}
+!21 = !{i32 2, !"Debug Info Version", i32 3}
 
 ; DUMP: CCG before cloning:
 ; DUMP: Callsite Context Graph:
@@ -270,7 +281,7 @@ attributes #6 = { builtin }
 ; IR:   call {{.*}} @_Z3barv()
 ; IR: define internal {{.*}} @_Z3foov()
 ; IR:   call {{.*}} @_Z3bazv()
-; IR: define internal {{.*}} @_Z3barv.memprof.1()
+; IR: define internal {{.*}} @_Z3barv.memprof.1() {{.*}} !dbg ![[SP:[0-9]+]]
 ; IR:   call {{.*}} @_Znam(i64 noundef 10) #[[COLD:[0-9]+]]
 ; IR: define internal {{.*}} @_Z3bazv.memprof.1()
 ; IR:   call {{.*}} @_Z3barv.memprof.1()
@@ -278,6 +289,8 @@ attributes #6 = { builtin }
 ; IR:   call {{.*}} @_Z3bazv.memprof.1()
 ; IR: attributes #[[NOTCOLD]] = { builtin "memprof"="notcold" }
 ; IR: attributes #[[COLD]] = { builtin "memprof"="cold" }
+;; Make sure the clone's linkageName was updated.
+; IR: ![[SP]] = distinct !DISubprogram(name: "bar", linkageName: "_Z3barv.memprof.1"
 
 
 ; STATS: 1 memprof-context-disambiguation - Number of cold static allocations (possibly cloned)

@llvmbot
Copy link
Member

llvmbot commented Jun 23, 2025

@llvm/pr-subscribers-lto

Author: Teresa Johnson (teresajohnson)

Changes

This corrects the debug information for the cloned functions so that it
contains the correct linkage name.


Full diff: https://github.com/llvm/llvm-project/pull/145385.diff

3 Files Affected:

  • (modified) llvm/lib/Transforms/IPO/MemProfContextDisambiguation.cpp (+6)
  • (modified) llvm/test/ThinLTO/X86/memprof-basic.ll (+16-3)
  • (modified) llvm/test/Transforms/MemProfContextDisambiguation/basic.ll (+16-3)
diff --git a/llvm/lib/Transforms/IPO/MemProfContextDisambiguation.cpp b/llvm/lib/Transforms/IPO/MemProfContextDisambiguation.cpp
index 10120dd0e10c1..c0f84456d2b27 100644
--- a/llvm/lib/Transforms/IPO/MemProfContextDisambiguation.cpp
+++ b/llvm/lib/Transforms/IPO/MemProfContextDisambiguation.cpp
@@ -4001,6 +4001,9 @@ ModuleCallsiteContextGraph::cloneFunctionForCallsite(
   std::string Name = getMemProfFuncName(Func.func()->getName(), CloneNo);
   assert(!Func.func()->getParent()->getFunction(Name));
   NewFunc->setName(Name);
+  if (auto *SP = NewFunc->getSubprogram())
+    SP->replaceLinkageName(
+        MDString::get(NewFunc->getParent()->getContext(), Name));
   for (auto &Inst : CallsWithMetadataInFunc) {
     // This map always has the initial version in it.
     assert(Inst.cloneNo() == 0);
@@ -4939,6 +4942,9 @@ static SmallVector<std::unique_ptr<ValueToValueMapTy>, 4> createFunctionClones(
       PrevF->eraseFromParent();
     } else
       NewF->setName(Name);
+    if (auto *SP = NewF->getSubprogram())
+      SP->replaceLinkageName(
+          MDString::get(NewF->getParent()->getContext(), Name));
     ORE.emit(OptimizationRemark(DEBUG_TYPE, "MemprofClone", &F)
              << "created clone " << ore::NV("NewFunction", NewF));
 
diff --git a/llvm/test/ThinLTO/X86/memprof-basic.ll b/llvm/test/ThinLTO/X86/memprof-basic.ll
index 9c1f77bcd569c..72d282fe7bef5 100644
--- a/llvm/test/ThinLTO/X86/memprof-basic.ll
+++ b/llvm/test/ThinLTO/X86/memprof-basic.ll
@@ -100,7 +100,7 @@ declare void @_ZdaPv()
 
 declare i32 @sleep()
 
-define internal ptr @_Z3barv() #0 {
+define internal ptr @_Z3barv() #0 !dbg !15 {
 entry:
   %call = call ptr @_Znam(i64 0), !memprof !2, !callsite !7
   ret ptr null
@@ -125,6 +125,9 @@ uselistorder ptr @_Z3foov, { 1, 0 }
 
 attributes #0 = { noinline optnone }
 
+!llvm.dbg.cu = !{!13}
+!llvm.module.flags = !{!20, !21}
+
 !0 = !{i64 8632435727821051414}
 !1 = !{i64 -3421689549917153178}
 !2 = !{!3, !5}
@@ -138,7 +141,15 @@ attributes #0 = { noinline optnone }
 !10 = !{i64 123, i64 100}
 !11 = !{i64 456, i64 200}
 !12 = !{i64 789, i64 300}
-
+!13 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !14, producer: "clang version 21.0.0git (git@github.com:llvm/llvm-project.git e391301e0e4d9183fe06e69602e87b0bc889aeda)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
+!14 = !DIFile(filename: "basic.cc", directory: "", checksumkind: CSK_MD5, checksum: "8636c46e81402013b9d54e8307d2f149")
+!15 = distinct !DISubprogram(name: "bar", linkageName: "_Z3barv", scope: !14, file: !14, line: 1, type: !16, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !13)
+!16 = !DISubroutineType(types: !17)
+!17 = !{!18}
+!18 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !19, size: 64)
+!19 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char)
+!20 = !{i32 7, !"Dwarf Version", i32 5}
+!21 = !{i32 2, !"Debug Info Version", i32 3}
 
 ; DUMP: CCG before cloning:
 ; DUMP: Callsite Context Graph:
@@ -301,7 +312,7 @@ attributes #0 = { noinline optnone }
 ; IR:   call {{.*}} @_Z3barv()
 ; IR: define internal {{.*}} @_Z3foov()
 ; IR:   call {{.*}} @_Z3bazv()
-; IR: define internal {{.*}} @_Z3barv.memprof.1()
+; IR: define internal {{.*}} @_Z3barv.memprof.1() {{.*}} !dbg ![[SP:[0-9]+]]
 ; IR:   call {{.*}} @_Znam(i64 0) #[[COLD:[0-9]+]]
 ; IR: define internal {{.*}} @_Z3bazv.memprof.1()
 ; IR:   call {{.*}} @_Z3barv.memprof.1()
@@ -309,6 +320,8 @@ attributes #0 = { noinline optnone }
 ; IR:   call {{.*}} @_Z3bazv.memprof.1()
 ; IR: attributes #[[NOTCOLD]] = { "memprof"="notcold" }
 ; IR: attributes #[[COLD]] = { "memprof"="cold" }
+;; Make sure the clone's linkageName was updated.
+; IR: ![[SP]] = distinct !DISubprogram(name: "bar", linkageName: "_Z3barv.memprof.1"
 
 
 ; STATS: 1 memprof-context-disambiguation - Number of cold static allocations (possibly cloned)
diff --git a/llvm/test/Transforms/MemProfContextDisambiguation/basic.ll b/llvm/test/Transforms/MemProfContextDisambiguation/basic.ll
index a21f407f85650..323df12f6335c 100644
--- a/llvm/test/Transforms/MemProfContextDisambiguation/basic.ll
+++ b/llvm/test/Transforms/MemProfContextDisambiguation/basic.ll
@@ -71,7 +71,7 @@ declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i1 immarg) #1
 ; Function Attrs: nobuiltin
 declare void @_ZdaPv() #2
 
-define internal ptr @_Z3barv() #3 {
+define internal ptr @_Z3barv() #3 !dbg !15 {
 entry:
   %call = call noalias noundef nonnull ptr @_Znam(i64 noundef 10) #6, !memprof !2, !callsite !7
   ret ptr null
@@ -103,6 +103,9 @@ attributes #4 = { "stack-protector-buffer-size"="8" }
 attributes #5 = { noinline }
 attributes #6 = { builtin }
 
+!llvm.dbg.cu = !{!13}
+!llvm.module.flags = !{!20, !21}
+
 !0 = !{i64 8632435727821051414}
 !1 = !{i64 -3421689549917153178}
 !2 = !{!3, !5}
@@ -116,7 +119,15 @@ attributes #6 = { builtin }
 !10 = !{i64 123, i64 100}
 !11 = !{i64 456, i64 200}
 !12 = !{i64 789, i64 300}
-
+!13 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !14, producer: "clang version 21.0.0git (git@github.com:llvm/llvm-project.git e391301e0e4d9183fe06e69602e87b0bc889aeda)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
+!14 = !DIFile(filename: "basic.cc", directory: "", checksumkind: CSK_MD5, checksum: "8636c46e81402013b9d54e8307d2f149")
+!15 = distinct !DISubprogram(name: "bar", linkageName: "_Z3barv", scope: !14, file: !14, line: 1, type: !16, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !13)
+!16 = !DISubroutineType(types: !17)
+!17 = !{!18}
+!18 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !19, size: 64)
+!19 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char)
+!20 = !{i32 7, !"Dwarf Version", i32 5}
+!21 = !{i32 2, !"Debug Info Version", i32 3}
 
 ; DUMP: CCG before cloning:
 ; DUMP: Callsite Context Graph:
@@ -270,7 +281,7 @@ attributes #6 = { builtin }
 ; IR:   call {{.*}} @_Z3barv()
 ; IR: define internal {{.*}} @_Z3foov()
 ; IR:   call {{.*}} @_Z3bazv()
-; IR: define internal {{.*}} @_Z3barv.memprof.1()
+; IR: define internal {{.*}} @_Z3barv.memprof.1() {{.*}} !dbg ![[SP:[0-9]+]]
 ; IR:   call {{.*}} @_Znam(i64 noundef 10) #[[COLD:[0-9]+]]
 ; IR: define internal {{.*}} @_Z3bazv.memprof.1()
 ; IR:   call {{.*}} @_Z3barv.memprof.1()
@@ -278,6 +289,8 @@ attributes #6 = { builtin }
 ; IR:   call {{.*}} @_Z3bazv.memprof.1()
 ; IR: attributes #[[NOTCOLD]] = { builtin "memprof"="notcold" }
 ; IR: attributes #[[COLD]] = { builtin "memprof"="cold" }
+;; Make sure the clone's linkageName was updated.
+; IR: ![[SP]] = distinct !DISubprogram(name: "bar", linkageName: "_Z3barv.memprof.1"
 
 
 ; STATS: 1 memprof-context-disambiguation - Number of cold static allocations (possibly cloned)

@teresajohnson teresajohnson requested a review from snehasish June 23, 2025 18:47
Copy link
Contributor

@snehasish snehasish left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm, failures seem unrelated.

Also since you asked about function specialization earlier. Perhaps this code needs to be updated?

@teresajohnson teresajohnson merged commit 90a6819 into llvm:main Jun 24, 2025
9 of 10 checks passed
@teresajohnson
Copy link
Contributor Author

lgtm, failures seem unrelated.

Also since you asked about function specialization earlier. Perhaps this code needs to be updated?

Yes, that looks like another case where this was missed.

DrSergei pushed a commit to DrSergei/llvm-project that referenced this pull request Jun 24, 2025
This corrects the debug information for the cloned functions so that it
contains the correct linkage name.
anthonyhatran pushed a commit to anthonyhatran/llvm-project that referenced this pull request Jun 26, 2025
This corrects the debug information for the cloned functions so that it
contains the correct linkage name.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
llvm:transforms LTO Link time optimization (regular/full LTO or ThinLTO)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants