Skip to content

Commit 665e46c

Browse files
[llvm-profdata] Use semicolon as the delimiter for supplementary profiles. (#75080)
When merging instrFDO profiles with afdo profile as supplementary, instrFDO counters for static functions are stored with function's PGO name (with filename.cpp; prefix). - This pull request fixes the delimiter used when a PGO function name is 'normalized' for AFDO look-up.
1 parent 241fe83 commit 665e46c

File tree

6 files changed

+101
-14
lines changed

6 files changed

+101
-14
lines changed
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
// This is a regression test for supplementary profiles.
2+
3+
// What the test does:
4+
// - Generate raw profiles from an executable and convert it to indexed profiles.
5+
// - Merge indexed profiles with supplementary sample-pgo profiles
6+
// - Check that the block counters for function foo is scaled up.
7+
8+
// REQUIRES: lld-available
9+
10+
// Building the instrumented binary will fail because lld doesn't support
11+
// big-endian ELF for PPC (aka ABI 1).
12+
// ld.lld: error: /lib/../lib64/Scrt1.o: ABI version 1 is not supported
13+
// UNSUPPORTED: ppc && host-byteorder-big-endian
14+
15+
// This compiler-rt test aims to have test coverage for the IRPGO name format
16+
// of local-linkage functions during raw profile generation. The C++ functions
17+
// are simple with little optimization space so test outputs are more stable.
18+
// On the other hand, LLVM tests (like tools/llvm-profdata/suppl-instr-with-sample-static-func.test
19+
// or other suppl* test under tools/llvm-profdata dir) are more suitable for
20+
// more sophisticated cases (e.g., pseudo hot functions or profiles with discriminiators, etc).
21+
22+
// RUN: rm -rf %t && split-file %s %t && cd %t
23+
24+
// Use clangxx_pgogen for IR level instrumentation for C++.
25+
// The test case is constructed such that `-funique-internal-linkage-names` is
26+
// not used in instrPGO but used in static function names in SamplePGO.
27+
// RUN: %clangxx_pgogen -fuse-ld=lld -O2 main.cpp -o main
28+
// RUN: env LLVM_PROFILE_FILE=main.profraw %run ./main
29+
// RUN: llvm-profdata merge main.profraw -o main.profdata
30+
31+
// The function counters are not scaled up.
32+
// RUN: llvm-profdata show -all-functions -counts main.profdata | FileCheck %s --check-prefix=INSTR
33+
34+
// The instrPGO profile counter of function foo should be scaled up. Note the
35+
// scaling factor of a function is computed based on instrPGO profiles and
36+
// invariant to samplePGO profile counters.
37+
// RUN: llvm-profdata merge -supplement-instr-with-sample=sampleprof.proftext \
38+
// RUN: -suppl-min-size-threshold=0 -instr-prof-cold-threshold=1 \
39+
// RUN: main.profdata -o merge.profdata
40+
// RUN: llvm-profdata show -all-functions -counts merge.profdata | FileCheck %s --check-prefix=SUPPL
41+
42+
// INSTR: Counters:
43+
// INSTR: main:
44+
// INSTR: Counters: 1
45+
// INSTR: Block counts: [1]
46+
// INSTR: _Z3barv:
47+
// INSTR: Counters: 1
48+
// INSTR: Block counts: [2]
49+
// INSTR: main.cpp;_ZL3foov:
50+
// INSTR: Counters: 1
51+
// INSTR: Block counts: [1]
52+
53+
// INSTR: Functions shown: 3
54+
// INSTR: Total functions: 3
55+
56+
// SUPPL: Counters:
57+
// SUPPL: main:
58+
// SUPPL: Counters: 1
59+
// SUPPL: Block counts: [1]
60+
// SUPPL: _Z3barv:
61+
// SUPPL: Counters: 1
62+
// SUPPL: Block counts: [2]
63+
// SUPPL: main.cpp;_ZL3foov:
64+
// SUPPL: Counters: 1
65+
// SUPPL: Block counts: [3]
66+
67+
//--- main.cpp
68+
69+
// mark foo and bar as noinline so preinliner won't inlined them into main
70+
// before the instrumentation pass.
71+
__attribute__((noinline)) static void foo() {
72+
}
73+
74+
__attribute__((noinline)) void bar() {
75+
}
76+
77+
int main() {
78+
foo();
79+
bar();
80+
bar();
81+
return 0;
82+
}
83+
84+
//--- sampleprof.proftext
85+
_ZL3foov.__uniq.23343505234642233139497840575431302970:5:5
86+
1: 5

llvm/test/tools/llvm-profdata/Inputs/FUnique.proftext

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ main
1818
1
1919
0
2020

21-
test.c:_ZL3foom.__uniq.276699478366846449772231447066107882794
21+
test.c;_ZL3foom.__uniq.276699478366846449772231447066107882794
2222
# Func Hash:
2323
1124680652115249575
2424
# Num Counters:

llvm/test/tools/llvm-profdata/Inputs/NoFUnique.proftext

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ main
1818
1
1919
0
2020

21-
test.c:_ZL3foom
21+
test.c;_ZL3foom
2222
# Func Hash:
2323
1124680652115249575
2424
# Num Counters:

llvm/test/tools/llvm-profdata/Inputs/flatten_instr.proftext

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ foo
1414
40
1515
6000
1616

17-
bar.cc:bar
17+
bar.cc;bar
1818
# Func Hash:
1919
2222
2020
# Num Counters:

llvm/test/tools/llvm-profdata/suppl-instr-with-sample-flatten.test

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ RUN: -supplement-instr-with-sample=%p/Inputs/flatten_sample.proftext \
77
RUN: %p/Inputs/flatten_instr.proftext -o %t
88
RUN: llvm-profdata show %t -all-functions -counts | FileCheck %s --check-prefix=FLATTEN
99

10-
FLATTEN: bar.cc:bar:
11-
FLATTEN-NEXT: Hash: 0x00000000000008ae
12-
FLATTEN-NEXT: Counters: 10 <PseudoHot>
1310
FLATTEN: foo:
1411
FLATTEN-NEXT: Hash: 0x0000000000000457
1512
FLATTEN-NEXT: Counters: 5
1613
FLATTEN-NEXT: Block counts: [10000, 50, 2000, 40, 6000]
14+
FLATTEN: bar.cc;bar:
15+
FLATTEN-NEXT: Hash: 0x00000000000008ae
16+
FLATTEN-NEXT: Counters: 10 <PseudoHot>
1717
FLATTEN-NOT: goo:

llvm/tools/llvm-profdata/llvm-profdata.cpp

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -998,13 +998,14 @@ adjustInstrProfile(std::unique_ptr<WriterContext> &WC,
998998

999999
auto buildStaticFuncMap = [&StaticFuncMap,
10001000
SampleProfileHasFUnique](const StringRef Name) {
1001-
std::string Prefixes[] = {".cpp:", "cc:", ".c:", ".hpp:", ".h:"};
1001+
std::string FilePrefixes[] = {".cpp", "cc", ".c", ".hpp", ".h"};
10021002
size_t PrefixPos = StringRef::npos;
1003-
for (auto &Prefix : Prefixes) {
1004-
PrefixPos = Name.find_insensitive(Prefix);
1003+
for (auto &FilePrefix : FilePrefixes) {
1004+
std::string NamePrefix = FilePrefix + kGlobalIdentifierDelimiter;
1005+
PrefixPos = Name.find_insensitive(NamePrefix);
10051006
if (PrefixPos == StringRef::npos)
10061007
continue;
1007-
PrefixPos += Prefix.size();
1008+
PrefixPos += NamePrefix.size();
10081009
break;
10091010
}
10101011

@@ -1088,17 +1089,17 @@ adjustInstrProfile(std::unique_ptr<WriterContext> &WC,
10881089
//
10891090
// InstrProfile has two entries:
10901091
// foo
1091-
// bar.cc:bar
1092+
// bar.cc;bar
10921093
//
10931094
// After BuildMaxSampleMap, we should have the following in FlattenSampleMap:
10941095
// {"foo", {1000, 5000}}
1095-
// {"bar.cc:bar", {11000, 30000}}
1096+
// {"bar.cc;bar", {11000, 30000}}
10961097
//
10971098
// foo's has an entry count of 1000, and max body count of 5000.
1098-
// bar.cc:bar has an entry count of 11000 (sum two callsites of 1000 and
1099+
// bar.cc;bar has an entry count of 11000 (sum two callsites of 1000 and
10991100
// 10000), and max count of 30000 (from the callsite in line 8).
11001101
//
1101-
// Note that goo's count will remain in bar.cc:bar() as it does not have an
1102+
// Note that goo's count will remain in bar.cc;bar() as it does not have an
11021103
// entry in InstrProfile.
11031104
llvm::StringMap<std::pair<uint64_t, uint64_t>> FlattenSampleMap;
11041105
auto BuildMaxSampleMap = [&FlattenSampleMap, &StaticFuncMap,

0 commit comments

Comments
 (0)