diff options
author | Mingming Liu <mingmingl@google.com> | 2024-01-04 15:03:18 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-04 15:03:18 -0800 |
commit | 665e46c2689cc4212345213db7d7e968b91dcc8b (patch) | |
tree | 8279c2c4625bb2d7837a17d8e6269d2c0274e5a5 | |
parent | 241fe83704476f81e3438e32b6d988ea123e624d (diff) | |
download | llvm-665e46c2689cc4212345213db7d7e968b91dcc8b.zip llvm-665e46c2689cc4212345213db7d7e968b91dcc8b.tar.gz llvm-665e46c2689cc4212345213db7d7e968b91dcc8b.tar.bz2 |
[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.
6 files changed, 101 insertions, 14 deletions
diff --git a/compiler-rt/test/profile/Linux/instrprof-instr-suppl.test b/compiler-rt/test/profile/Linux/instrprof-instr-suppl.test new file mode 100644 index 0000000..10650a3 --- /dev/null +++ b/compiler-rt/test/profile/Linux/instrprof-instr-suppl.test @@ -0,0 +1,86 @@ +// This is a regression test for supplementary profiles. + +// What the test does: +// - Generate raw profiles from an executable and convert it to indexed profiles. +// - Merge indexed profiles with supplementary sample-pgo profiles +// - Check that the block counters for function foo is scaled up. + +// REQUIRES: lld-available + +// Building the instrumented binary will fail because lld doesn't support +// big-endian ELF for PPC (aka ABI 1). +// ld.lld: error: /lib/../lib64/Scrt1.o: ABI version 1 is not supported +// UNSUPPORTED: ppc && host-byteorder-big-endian + +// This compiler-rt test aims to have test coverage for the IRPGO name format +// of local-linkage functions during raw profile generation. The C++ functions +// are simple with little optimization space so test outputs are more stable. +// On the other hand, LLVM tests (like tools/llvm-profdata/suppl-instr-with-sample-static-func.test +// or other suppl* test under tools/llvm-profdata dir) are more suitable for +// more sophisticated cases (e.g., pseudo hot functions or profiles with discriminiators, etc). + +// RUN: rm -rf %t && split-file %s %t && cd %t + +// Use clangxx_pgogen for IR level instrumentation for C++. +// The test case is constructed such that `-funique-internal-linkage-names` is +// not used in instrPGO but used in static function names in SamplePGO. +// RUN: %clangxx_pgogen -fuse-ld=lld -O2 main.cpp -o main +// RUN: env LLVM_PROFILE_FILE=main.profraw %run ./main +// RUN: llvm-profdata merge main.profraw -o main.profdata + +// The function counters are not scaled up. +// RUN: llvm-profdata show -all-functions -counts main.profdata | FileCheck %s --check-prefix=INSTR + +// The instrPGO profile counter of function foo should be scaled up. Note the +// scaling factor of a function is computed based on instrPGO profiles and +// invariant to samplePGO profile counters. +// RUN: llvm-profdata merge -supplement-instr-with-sample=sampleprof.proftext \ +// RUN: -suppl-min-size-threshold=0 -instr-prof-cold-threshold=1 \ +// RUN: main.profdata -o merge.profdata +// RUN: llvm-profdata show -all-functions -counts merge.profdata | FileCheck %s --check-prefix=SUPPL + +// INSTR: Counters: +// INSTR: main: +// INSTR: Counters: 1 +// INSTR: Block counts: [1] +// INSTR: _Z3barv: +// INSTR: Counters: 1 +// INSTR: Block counts: [2] +// INSTR: main.cpp;_ZL3foov: +// INSTR: Counters: 1 +// INSTR: Block counts: [1] + +// INSTR: Functions shown: 3 +// INSTR: Total functions: 3 + +// SUPPL: Counters: +// SUPPL: main: +// SUPPL: Counters: 1 +// SUPPL: Block counts: [1] +// SUPPL: _Z3barv: +// SUPPL: Counters: 1 +// SUPPL: Block counts: [2] +// SUPPL: main.cpp;_ZL3foov: +// SUPPL: Counters: 1 +// SUPPL: Block counts: [3] + +//--- main.cpp + +// mark foo and bar as noinline so preinliner won't inlined them into main +// before the instrumentation pass. +__attribute__((noinline)) static void foo() { +} + +__attribute__((noinline)) void bar() { +} + +int main() { + foo(); + bar(); + bar(); + return 0; +} + +//--- sampleprof.proftext +_ZL3foov.__uniq.23343505234642233139497840575431302970:5:5 + 1: 5 diff --git a/llvm/test/tools/llvm-profdata/Inputs/FUnique.proftext b/llvm/test/tools/llvm-profdata/Inputs/FUnique.proftext index be2c27d..da169b1 100644 --- a/llvm/test/tools/llvm-profdata/Inputs/FUnique.proftext +++ b/llvm/test/tools/llvm-profdata/Inputs/FUnique.proftext @@ -18,7 +18,7 @@ main 1 0 -test.c:_ZL3foom.__uniq.276699478366846449772231447066107882794 +test.c;_ZL3foom.__uniq.276699478366846449772231447066107882794 # Func Hash: 1124680652115249575 # Num Counters: diff --git a/llvm/test/tools/llvm-profdata/Inputs/NoFUnique.proftext b/llvm/test/tools/llvm-profdata/Inputs/NoFUnique.proftext index 7485a33..a3df42f 100644 --- a/llvm/test/tools/llvm-profdata/Inputs/NoFUnique.proftext +++ b/llvm/test/tools/llvm-profdata/Inputs/NoFUnique.proftext @@ -18,7 +18,7 @@ main 1 0 -test.c:_ZL3foom +test.c;_ZL3foom # Func Hash: 1124680652115249575 # Num Counters: diff --git a/llvm/test/tools/llvm-profdata/Inputs/flatten_instr.proftext b/llvm/test/tools/llvm-profdata/Inputs/flatten_instr.proftext index 8afee8f..e180099 100644 --- a/llvm/test/tools/llvm-profdata/Inputs/flatten_instr.proftext +++ b/llvm/test/tools/llvm-profdata/Inputs/flatten_instr.proftext @@ -14,7 +14,7 @@ foo 40 6000 -bar.cc:bar +bar.cc;bar # Func Hash: 2222 # Num Counters: diff --git a/llvm/test/tools/llvm-profdata/suppl-instr-with-sample-flatten.test b/llvm/test/tools/llvm-profdata/suppl-instr-with-sample-flatten.test index 2c569b5..4a394d7 100644 --- a/llvm/test/tools/llvm-profdata/suppl-instr-with-sample-flatten.test +++ b/llvm/test/tools/llvm-profdata/suppl-instr-with-sample-flatten.test @@ -7,11 +7,11 @@ RUN: -supplement-instr-with-sample=%p/Inputs/flatten_sample.proftext \ RUN: %p/Inputs/flatten_instr.proftext -o %t RUN: llvm-profdata show %t -all-functions -counts | FileCheck %s --check-prefix=FLATTEN -FLATTEN: bar.cc:bar: -FLATTEN-NEXT: Hash: 0x00000000000008ae -FLATTEN-NEXT: Counters: 10 <PseudoHot> FLATTEN: foo: FLATTEN-NEXT: Hash: 0x0000000000000457 FLATTEN-NEXT: Counters: 5 FLATTEN-NEXT: Block counts: [10000, 50, 2000, 40, 6000] +FLATTEN: bar.cc;bar: +FLATTEN-NEXT: Hash: 0x00000000000008ae +FLATTEN-NEXT: Counters: 10 <PseudoHot> FLATTEN-NOT: goo: diff --git a/llvm/tools/llvm-profdata/llvm-profdata.cpp b/llvm/tools/llvm-profdata/llvm-profdata.cpp index 12b81d4..77197d3 100644 --- a/llvm/tools/llvm-profdata/llvm-profdata.cpp +++ b/llvm/tools/llvm-profdata/llvm-profdata.cpp @@ -998,13 +998,14 @@ adjustInstrProfile(std::unique_ptr<WriterContext> &WC, auto buildStaticFuncMap = [&StaticFuncMap, SampleProfileHasFUnique](const StringRef Name) { - std::string Prefixes[] = {".cpp:", "cc:", ".c:", ".hpp:", ".h:"}; + std::string FilePrefixes[] = {".cpp", "cc", ".c", ".hpp", ".h"}; size_t PrefixPos = StringRef::npos; - for (auto &Prefix : Prefixes) { - PrefixPos = Name.find_insensitive(Prefix); + for (auto &FilePrefix : FilePrefixes) { + std::string NamePrefix = FilePrefix + kGlobalIdentifierDelimiter; + PrefixPos = Name.find_insensitive(NamePrefix); if (PrefixPos == StringRef::npos) continue; - PrefixPos += Prefix.size(); + PrefixPos += NamePrefix.size(); break; } @@ -1088,17 +1089,17 @@ adjustInstrProfile(std::unique_ptr<WriterContext> &WC, // // InstrProfile has two entries: // foo - // bar.cc:bar + // bar.cc;bar // // After BuildMaxSampleMap, we should have the following in FlattenSampleMap: // {"foo", {1000, 5000}} - // {"bar.cc:bar", {11000, 30000}} + // {"bar.cc;bar", {11000, 30000}} // // foo's has an entry count of 1000, and max body count of 5000. - // bar.cc:bar has an entry count of 11000 (sum two callsites of 1000 and + // bar.cc;bar has an entry count of 11000 (sum two callsites of 1000 and // 10000), and max count of 30000 (from the callsite in line 8). // - // Note that goo's count will remain in bar.cc:bar() as it does not have an + // Note that goo's count will remain in bar.cc;bar() as it does not have an // entry in InstrProfile. llvm::StringMap<std::pair<uint64_t, uint64_t>> FlattenSampleMap; auto BuildMaxSampleMap = [&FlattenSampleMap, &StaticFuncMap, |