Skip to content

Commit cb23baa

Browse files
Snehasish Kumaramharc
andcommitted
[DebugInfo] Preserve line and column number when merging debug info.
This patch introduces a new option `-preserve-merged-debug-info` to preserve an arbitrary version of debug information when DILocations are merged. This is intended to be used in production environments from which sample based profiles are derived such as AutoFDO and MemProf. With this patch we have see a 0.2% improvement on an internal workload at Google when generating AutoFDO profiles. It also significantly improves the ability for MemProf by preserving debug info for merged call instructions used in the contextual profile. Co-authored-by: Krzysztof Pszeniczny <[email protected]>
1 parent 6ce41db commit cb23baa

File tree

2 files changed

+80
-0
lines changed

2 files changed

+80
-0
lines changed

llvm/lib/IR/DebugInfoMetadata.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "llvm/IR/IntrinsicInst.h"
2222
#include "llvm/IR/Type.h"
2323
#include "llvm/IR/Value.h"
24+
#include "llvm/Support/CommandLine.h"
2425

2526
#include <numeric>
2627
#include <optional>
@@ -34,6 +35,12 @@ cl::opt<bool> EnableFSDiscriminator(
3435
cl::desc("Enable adding flow sensitive discriminators"));
3536
} // namespace llvm
3637

38+
// When true, preserves line and column number by picking one of the merged
39+
// location info in a deterministic manner to assist sample based PGO.
40+
static cl::opt<bool> PreserveMergedDebugInfo(
41+
"preserve-merged-debug-info", cl::init(false), cl::Hidden,
42+
cl::desc("Preserve line and column number when merging locations."));
43+
3744
uint32_t DIType::getAlignInBits() const {
3845
return (getTag() == dwarf::DW_TAG_LLVM_ptrauth_type ? 0 : SubclassData32);
3946
}
@@ -125,6 +132,14 @@ DILocation *DILocation::getMergedLocation(DILocation *LocA, DILocation *LocB) {
125132
if (LocA == LocB)
126133
return LocA;
127134

135+
if (PreserveMergedDebugInfo) {
136+
auto A = std::make_tuple(LocA->getLine(), LocA->getColumn(),
137+
LocA->getDiscriminator());
138+
auto B = std::make_tuple(LocB->getLine(), LocB->getColumn(),
139+
LocB->getDiscriminator());
140+
return A < B ? LocA : LocB;
141+
}
142+
128143
LLVMContext &C = LocA->getContext();
129144

130145
using LocVec = SmallVector<const DILocation *>;
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
; RUN: opt %s -passes=simplifycfg -hoist-common-insts -preserve-merged-debug-info -S | FileCheck %s
2+
; CHECK: tail call i32 @bar{{.*!dbg !}}[[TAG:[0-9]+]]
3+
; CHECK: ![[TAG]] = !DILocation(line: 9, column: 16, scope: !9)
4+
5+
; ModuleID = '../llvm/test/DebugInfo/Inputs/debug-info-merge-call.c'
6+
source_filename = "../llvm/test/DebugInfo/Inputs/debug-info-merge-call.c"
7+
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
8+
target triple = "x86_64-unknown-linux-gnu"
9+
10+
; Function Attrs: nounwind uwtable
11+
define dso_local i32 @test(i32 noundef %n) local_unnamed_addr #0 !dbg !9 {
12+
entry:
13+
%call = tail call i32 @foo(i32 noundef %n) #2, !dbg !12
14+
%cmp1 = icmp sgt i32 %n, 100, !dbg !13
15+
br i1 %cmp1, label %if.then, label %if.else, !dbg !13
16+
17+
if.then: ; preds = %entry
18+
%call2 = tail call i32 @bar(i32 noundef %n) #2, !dbg !14
19+
%add = add nsw i32 %call2, %call, !dbg !15
20+
br label %if.end, !dbg !16
21+
22+
if.else: ; preds = %entry
23+
%call4 = tail call i32 @bar(i32 noundef %n) #2, !dbg !17
24+
br label %if.end
25+
26+
if.end: ; preds = %if.else, %if.then
27+
%r.0 = phi i32 [ %add, %if.then ], [ %call4, %if.else ], !dbg !18
28+
ret i32 %r.0, !dbg !19
29+
}
30+
31+
declare !dbg !20 i32 @foo(i32 noundef) local_unnamed_addr #1
32+
33+
declare !dbg !21 i32 @bar(i32 noundef) local_unnamed_addr #1
34+
35+
attributes #0 = { nounwind uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
36+
attributes #1 = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
37+
attributes #2 = { nounwind }
38+
39+
!llvm.dbg.cu = !{!0}
40+
!llvm.module.flags = !{!2, !3, !4, !5, !6, !7}
41+
!llvm.ident = !{!8}
42+
43+
!0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, producer: "clang version 21.0.0git ([email protected]:snehasish/llvm-project.git 6ce41db6b0275d060d6e60f88b96a1657024345c)", isOptimized: true, runtimeVersion: 0, emissionKind: LineTablesOnly, splitDebugInlining: false, nameTableKind: None)
44+
!1 = !DIFile(filename: "../llvm/test/DebugInfo/Inputs/debug-info-merge-call.c", directory: "/usr/local/google/home/snehasishk/working/llvm-project/build-assert", checksumkind: CSK_MD5, checksum: "ac1be6c40dad11691922d600f9d55c55")
45+
!2 = !{i32 7, !"Dwarf Version", i32 5}
46+
!3 = !{i32 2, !"Debug Info Version", i32 3}
47+
!4 = !{i32 1, !"wchar_size", i32 4}
48+
!5 = !{i32 8, !"PIC Level", i32 2}
49+
!6 = !{i32 7, !"PIE Level", i32 2}
50+
!7 = !{i32 7, !"uwtable", i32 2}
51+
!8 = !{!"clang version 21.0.0git ([email protected]:snehasish/llvm-project.git 6ce41db6b0275d060d6e60f88b96a1657024345c)"}
52+
!9 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 5, type: !10, scopeLine: 5, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0)
53+
!10 = !DISubroutineType(types: !11)
54+
!11 = !{}
55+
!12 = !DILocation(line: 7, column: 13, scope: !9)
56+
!13 = !DILocation(line: 8, column: 8, scope: !9)
57+
!14 = !DILocation(line: 9, column: 16, scope: !9)
58+
!15 = !DILocation(line: 9, column: 14, scope: !9)
59+
!16 = !DILocation(line: 10, column: 3, scope: !9)
60+
!17 = !DILocation(line: 11, column: 10, scope: !9)
61+
!18 = !DILocation(line: 0, scope: !9)
62+
!19 = !DILocation(line: 13, column: 3, scope: !9)
63+
!20 = !DISubprogram(name: "foo", scope: !1, file: !1, line: 2, type: !10, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized)
64+
!21 = !DISubprogram(name: "bar", scope: !1, file: !1, line: 1, type: !10, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized)
65+

0 commit comments

Comments
 (0)