Skip to content

Commit e20b904

Browse files
authored
[PseudoProbe] Make probe discriminator compatible with dwarf base discriminator (#94506)
It's useful if the probe-based build can consume a dwarf based profile(e.g. the profile transition), before there is a conflict for the discriminator, this change tries to mitigate the issue by encoding the dwarf base discriminator into the probe discriminator. As the num of probe id(num of basic block and calls) starts from 1, there are some unused space. We try to reuse some bit of the probe id. The new encode rule is: - Use a bit to [28:28] to indicate whether dwarf base discriminator is encoded.(fortunately we can borrow this bit from the `PseudoProbeType`) - If the bit is set, use [15:3] for probe id, [18:16] for dwarf base discriminator. Otherwise, still use [18:3] for probe id. Note that these doesn't affect the original probe id capacity, we still prioritize probe id encoding, i.e. the base discriminator is not encoded when probe id is bigger than [15:3]. Then adjust `getBaseDiscriminatorFromDiscriminator` to use the base discriminator from the probe discriminator.
1 parent 11d643f commit e20b904

10 files changed

+67
-34
lines changed

llvm/include/llvm/IR/DebugInfoMetadata.h

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2147,13 +2147,20 @@ class DILocation : public MDNode {
21472147
static unsigned
21482148
getBaseDiscriminatorFromDiscriminator(unsigned D,
21492149
bool IsFSDiscriminator = false) {
2150-
// Return the probe id instead of zero for a pseudo probe discriminator.
2151-
// This should help differenciate callsites with same line numbers to
2152-
// achieve a decent AutoFDO profile under -fpseudo-probe-for-profiling,
2153-
// where the original callsite dwarf discriminator is overwritten by
2154-
// callsite probe information.
2155-
if (isPseudoProbeDiscriminator(D))
2150+
// Extract the dwarf base discriminator if it's encoded in the pseudo probe
2151+
// discriminator.
2152+
if (isPseudoProbeDiscriminator(D)) {
2153+
auto DwarfBaseDiscriminator =
2154+
PseudoProbeDwarfDiscriminator::extractDwarfBaseDiscriminator(D);
2155+
if (DwarfBaseDiscriminator)
2156+
return *DwarfBaseDiscriminator;
2157+
// Return the probe id instead of zero for a pseudo probe discriminator.
2158+
// This should help differenciate callsites with same line numbers to
2159+
// achieve a decent AutoFDO profile under -fpseudo-probe-for-profiling,
2160+
// where the original callsite dwarf discriminator is overwritten by
2161+
// callsite probe information.
21562162
return PseudoProbeDwarfDiscriminator::extractProbeIndex(D);
2163+
}
21572164

21582165
if (IsFSDiscriminator)
21592166
return getMaskedDiscriminator(D, getBaseDiscriminatorBits());

llvm/include/llvm/IR/PseudoProbe.h

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,26 +44,51 @@ struct PseudoProbeDwarfDiscriminator {
4444
// 32-bit integer which is organized as:
4545
// [2:0] - 0x7, this is reserved for regular discriminator,
4646
// see DWARF discriminator encoding rule
47-
// [18:3] - probe id
47+
// if the [28:28] bit is zero:
48+
// [18:3] for probe id.
49+
// else:
50+
// [15:3] for probe id, [18:16] for dwarf base discriminator.
4851
// [25:19] - probe distribution factor
49-
// [28:26] - probe type, see PseudoProbeType
50-
// [31:29] - reserved for probe attributes
51-
static uint32_t packProbeData(uint32_t Index, uint32_t Type, uint32_t Flags,
52-
uint32_t Factor) {
52+
// [27:26] - probe type, see PseudoProbeType
53+
// [28:28] - indicates whether dwarf base discriminator is encoded.
54+
// [30:29] - reserved for probe attributes
55+
static uint32_t
56+
packProbeData(uint32_t Index, uint32_t Type, uint32_t Flags, uint32_t Factor,
57+
std::optional<uint32_t> DwarfBaseDiscriminator) {
5358
assert(Index <= 0xFFFF && "Probe index too big to encode, exceeding 2^16");
54-
assert(Type <= 0x7 && "Probe type too big to encode, exceeding 7");
59+
assert(Type <= 0x3 && "Probe type too big to encode, exceeding 3");
5560
assert(Flags <= 0x7);
5661
assert(Factor <= 100 &&
5762
"Probe distribution factor too big to encode, exceeding 100");
58-
return (Index << 3) | (Factor << 19) | (Type << 26) | 0x7;
63+
uint32_t V = (Index << 3) | (Factor << 19) | (Type << 26) | 0x7;
64+
// If both the probe id and dwarf base discriminator is small, the probe id
65+
// space is shared with the dwarf base discriminator, this is to make the
66+
// probe-based build compatible with the dwarf-based profile.
67+
// Pack the dwarf base discriminator into [18:16] and set the [28:28] bit.
68+
if (Index <= 0x1FFF && DwarfBaseDiscriminator &&
69+
*DwarfBaseDiscriminator <= 0x7)
70+
V |= (1 << 28) | (*DwarfBaseDiscriminator << 16);
71+
return V;
5972
}
6073

6174
static uint32_t extractProbeIndex(uint32_t Value) {
75+
if (isDwarfBaseDiscriminatorEncoded(Value))
76+
return (Value >> 3) & 0x1FFF;
6277
return (Value >> 3) & 0xFFFF;
6378
}
6479

80+
static std::optional<uint32_t> extractDwarfBaseDiscriminator(uint32_t Value) {
81+
if (isDwarfBaseDiscriminatorEncoded(Value))
82+
return (Value >> 16) & 0x7;
83+
return std::nullopt;
84+
}
85+
86+
static bool isDwarfBaseDiscriminatorEncoded(uint32_t Value) {
87+
return Value & 0x10000000;
88+
}
89+
6590
static uint32_t extractProbeType(uint32_t Value) {
66-
return (Value >> 26) & 0x7;
91+
return (Value >> 26) & 0x3;
6792
}
6893

6994
static uint32_t extractProbeAttributes(uint32_t Value) {

llvm/lib/IR/PseudoProbe.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,13 +95,16 @@ void setProbeDistributionFactor(Instruction &Inst, float Factor) {
9595
PseudoProbeDwarfDiscriminator::extractProbeType(Discriminator);
9696
auto Attr = PseudoProbeDwarfDiscriminator::extractProbeAttributes(
9797
Discriminator);
98+
auto DwarfBaseDiscriminator =
99+
PseudoProbeDwarfDiscriminator::extractDwarfBaseDiscriminator(
100+
Discriminator);
98101
// Round small factors to 0 to avoid over-counting.
99102
uint32_t IntFactor =
100103
PseudoProbeDwarfDiscriminator::FullDistributionFactor;
101104
if (Factor < 1)
102105
IntFactor *= Factor;
103106
uint32_t V = PseudoProbeDwarfDiscriminator::packProbeData(
104-
Index, Type, Attr, IntFactor);
107+
Index, Type, Attr, IntFactor, DwarfBaseDiscriminator);
105108
DIL = DIL->cloneWithDiscriminator(V);
106109
Inst.setDebugLoc(DIL);
107110
}

llvm/lib/Transforms/IPO/SampleProfileProbe.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -431,8 +431,8 @@ void SampleProfileProber::instrumentOneFunc(Function &F, TargetMachine *TM) {
431431
// and type of a callsite probe. This gets rid of the dependency on
432432
// plumbing a customized metadata through the codegen pipeline.
433433
uint32_t V = PseudoProbeDwarfDiscriminator::packProbeData(
434-
Index, Type, 0,
435-
PseudoProbeDwarfDiscriminator::FullDistributionFactor);
434+
Index, Type, 0, PseudoProbeDwarfDiscriminator::FullDistributionFactor,
435+
DIL->getBaseDiscriminator());
436436
DIL = DIL->cloneWithDiscriminator(V);
437437
Call->setDebugLoc(DIL);
438438
}

llvm/test/Transforms/SampleProfile/pseudo-probe-discriminator.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ attributes #1 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "fra
6464

6565

6666
; PROBE: ![[CALL1]] = !DILocation(line: 4, column: 3, scope: ![[CALL1BLOCK:[0-9]+]])
67-
; PROBE: ![[CALL1BLOCK]] = !DILexicalBlockFile({{.*}} discriminator: 186646559)
67+
; PROBE: ![[CALL1BLOCK]] = !DILexicalBlockFile({{.*}} discriminator: 455147551)
6868
; PROBE: ![[CALL2]] = !DILocation(line: 4, column: 9, scope: ![[CALL2BLOCK:[0-9]+]])
69-
; PROBE: ![[CALL2BLOCK]] = !DILexicalBlockFile({{.*}} discriminator: 186646567)
69+
; PROBE: ![[CALL2BLOCK]] = !DILexicalBlockFile({{.*}} discriminator: 455344167)
7070
; PROBE: ![[INST]] = !DILocation(line: 4, column: 15, scope: ![[INSTBLOCK:[0-9]+]])
7171
; PROBE: ![[INSTBLOCK]] = !DILexicalBlockFile({{.*}} discriminator: 4)

llvm/test/Transforms/SampleProfile/pseudo-probe-emit-inline.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,13 @@ define dso_local i32 @entry() !dbg !14 {
4242
; CHECK-IL: ![[#SCOPE2:]] = distinct !DISubprogram(name: "foo"
4343
; CHECK-IL: ![[#DL1]] = !DILocation(line: 3, column: 1, scope: ![[#SCOPE1]], inlinedAt: ![[#INL1:]])
4444
; CHECK-IL: ![[#INL1]] = distinct !DILocation(line: 7, column: 3, scope: ![[#BL1:]])
45-
;; A discriminator of 186646551 which is 0xb200017 in hexdecimal, stands for a direct call probe
45+
;; A discriminator of 455082007 which is 0x1b200017 in hexdecimal, stands for a direct call probe
4646
;; with an index of 2 and a scale of 100%.
47-
; CHECK-IL: ![[#BL1]] = !DILexicalBlockFile(scope: ![[#SCOPE2]], file: !1, discriminator: 186646551)
47+
; CHECK-IL: ![[#BL1]] = !DILexicalBlockFile(scope: ![[#SCOPE2]], file: !1, discriminator: 455082007)
4848
; CHECK-IL: ![[#SCOPE3:]] = distinct !DISubprogram(name: "entry"
4949
; CHECK-IL: ![[#DL2]] = !DILocation(line: 7, column: 3, scope: ![[#SCOPE2]], inlinedAt: ![[#INL2:]])
5050
; CHECK-IL: ![[#INL2]] = distinct !DILocation(line: 11, column: 3, scope: ![[#BL2:]])
51-
; CHECK-IL: ![[#BL2]] = !DILexicalBlockFile(scope: ![[#SCOPE3]], file: !1, discriminator: 186646551)
51+
; CHECK-IL: ![[#BL2]] = !DILexicalBlockFile(scope: ![[#SCOPE3]], file: !1, discriminator: 455082007)
5252
; CHECK-IL: ![[#DL3]] = !DILocation(line: 3, column: 1, scope: ![[#SCOPE1]], inlinedAt: ![[#INL3:]])
5353
; CHECK-IL: ![[#INL3]] = distinct !DILocation(line: 7, column: 3, scope: ![[#BL1]], inlinedAt: ![[#INL2]])
5454

llvm/test/Transforms/SampleProfile/pseudo-probe-emit.ll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,13 +84,13 @@ entry:
8484
; CHECK-IL: ![[#REALLINE]] = !DILocation(line: 2, scope: ![[#DISC0:]])
8585
; CHECK-IL: ![[#DISC0]] = !DILexicalBlockFile(scope: ![[#FOO]], file: ![[#]], discriminator: 0)
8686
; CHECK-IL: ![[#PROBE0]] = !DILocation(line: 2, column: 20, scope: ![[#SCOPE0:]])
87-
;; A discriminator of 67108887 which is 0x7200017 in hexdecimal, stands for a direct call probe
87+
;; A discriminator of 387973143 which is 0x17200017 in hexdecimal, stands for a direct call probe
8888
;; with an index of 2.
89-
; CHECK-IL: ![[#SCOPE0]] = !DILexicalBlockFile(scope: ![[#]], file: ![[#]], discriminator: 119537687)
89+
; CHECK-IL: ![[#SCOPE0]] = !DILexicalBlockFile(scope: ![[#]], file: ![[#]], discriminator: 387973143)
9090
; CHECK-IL: ![[#PROBE1]] = !DILocation(line: 0, scope: ![[#SCOPE1:]])
91-
;; A discriminator of 186646559 which is 0xb20001f in hexdecimal, stands for a direct call probe
91+
;; A discriminator of 455082015 which is 0x1b20001f in hexdecimal, stands for a direct call probe
9292
;; with an index of 3.
93-
; CHECK-IL: ![[#SCOPE1]] = !DILexicalBlockFile(scope: ![[#]], file: ![[#]], discriminator: 186646559)
93+
; CHECK-IL: ![[#SCOPE1]] = !DILexicalBlockFile(scope: ![[#]], file: ![[#]], discriminator: 455082015)
9494

9595
; Check the generation of .pseudo_probe_desc section
9696
; CHECK-ASM: .section .pseudo_probe_desc,"G",@progbits,.pseudo_probe_desc_foo,comdat

llvm/test/Transforms/SampleProfile/pseudo-probe-inline.ll

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,6 @@ if.end:
106106
;YAML-NEXT: - Line: '1'
107107
;YAML-NEXT: - String: ':'
108108
;YAML-NEXT: - Column: '11'
109-
;YAML-NEXT: - String: .
110-
;YAML-NEXT: - Disc: '2'
111109
;YAML-NEXT: - String: ';'
112110
;YAML-NEXT: ...
113111
;YAML: --- !Analysis

llvm/test/Transforms/SampleProfile/pseudo-probe-profile.ll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,14 @@ attributes #0 = {"use-sample-profile"}
4040

4141
; CHECK: ![[PD1]] = !{!"branch_weights", i32 8, i32 7}
4242
; CHECK: ![[#PROBE1]] = !DILocation(line: 0, scope: ![[#SCOPE1:]])
43-
;; A discriminator of 119537695 which is 0x720001f in hexdecimal, stands for an indirect call probe
43+
;; A discriminator of 387973151 which is 0x1720001f in hexdecimal, stands for an indirect call probe
4444
;; with an index of 3.
45-
; CHECK: ![[#SCOPE1]] = !DILexicalBlockFile(scope: ![[#]], file: ![[#]], discriminator: 119537695)
45+
; CHECK: ![[#SCOPE1]] = !DILexicalBlockFile(scope: ![[#]], file: ![[#]], discriminator: 387973151)
4646
; CHECK: ![[PROF1]] = !{!"VP", i32 0, i64 7, i64 9191153033785521275, i64 5, i64 -1069303473483922844, i64 2}
47-
;; A discriminator of 119537711 which is 0x720002f in hexdecimal, stands for an indirect call probe
47+
;; A discriminator of 387973167 which is 0x1720002f in hexdecimal, stands for an indirect call probe
4848
;; with an index of 5.
4949
; CHECK: ![[#PROBE2]] = !DILocation(line: 0, scope: ![[#SCOPE2:]])
50-
; CHECK: ![[#SCOPE2]] = !DILexicalBlockFile(scope: ![[#]], file: ![[#]], discriminator: 119537711)
50+
; CHECK: ![[#SCOPE2]] = !DILexicalBlockFile(scope: ![[#]], file: ![[#]], discriminator: 387973167)
5151
; CHECK: ![[PROF2]] = !{!"VP", i32 0, i64 6, i64 -1069303473483922844, i64 4, i64 9191153033785521275, i64 2}
5252

5353
!llvm.module.flags = !{!9, !10}

llvm/test/Transforms/SampleProfile/pseudo-probe-verify.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,10 @@ bb24:
5454
ret void
5555
}
5656

57-
;; A discriminator of 186646583 which is 0xb200037 in hexdecimal, stands for a direct call probe
57+
;; A discriminator of 455082031 which is 0x1b200037 in hexdecimal, stands for a direct call probe
5858
;; with an index of 6 and a scale of -1%.
5959
; CHECK: ![[#PROBE6]] = !DILocation(line: 2, column: 20, scope: ![[#SCOPE:]])
60-
; CHECK: ![[#SCOPE]] = !DILexicalBlockFile(scope: ![[#]], file: ![[#]], discriminator: 186646575)
60+
; CHECK: ![[#SCOPE]] = !DILexicalBlockFile(scope: ![[#]], file: ![[#]], discriminator: 455082031)
6161

6262
!llvm.dbg.cu = !{!0}
6363
!llvm.module.flags = !{!9, !10}

0 commit comments

Comments
 (0)