diff --git a/compiler-rt/test/profile/Darwin/instrprof-debug-info-correlate.c b/compiler-rt/test/profile/Darwin/instrprof-debug-info-correlate.c --- a/compiler-rt/test/profile/Darwin/instrprof-debug-info-correlate.c +++ b/compiler-rt/test/profile/Darwin/instrprof-debug-info-correlate.c @@ -1,33 +1,12 @@ // REQUIRES: zlib // Value profiling is currently not supported in lightweight mode. -// RUN: %clang_pgogen -o %t.normal -mllvm --disable-vp=true %s -// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t.normal -// RUN: llvm-profdata merge -o %t.normal.profdata %t.profraw - -// RUN: %clang_pgogen -o %t -g -mllvm --debug-info-correlate -mllvm --disable-vp=true %s +// RUN: %clang_pgogen -o %t -g -mllvm --debug-info-correlate -mllvm --disable-vp=true %S/../Inputs/instrprof-debug-info-correlate-main.cpp %S/../Inputs/instrprof-debug-info-correlate-foo.cpp // RUN: env LLVM_PROFILE_FILE=%t.proflite %run %t // RUN: llvm-profdata merge -o %t.profdata --debug-info=%t.dSYM %t.proflite -// RUN: diff %t.normal.profdata %t.profdata - -int foo(int a) { - if (a % 2) - return 4 * a + 1; - return 0; -} - -int bar(int a) { - while (a > 100) - a /= 2; - return a; -} - -typedef int (*FP)(int); -FP Fps[3] = {foo, bar}; +// RUN: %clang_pgogen -o %t.normal -mllvm --disable-vp=true %S/../Inputs/instrprof-debug-info-correlate-main.cpp %S/../Inputs/instrprof-debug-info-correlate-foo.cpp +// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t.normal +// RUN: llvm-profdata merge -o %t.normal.profdata %t.profraw -int main() { - for (int i = 0; i < 5; i++) - Fps[i % 2](i); - return 0; -} +// RUN: diff %t.normal.profdata %t.profdata diff --git a/compiler-rt/test/profile/Inputs/instrprof-debug-info-correlate-bar.h b/compiler-rt/test/profile/Inputs/instrprof-debug-info-correlate-bar.h new file mode 100644 --- /dev/null +++ b/compiler-rt/test/profile/Inputs/instrprof-debug-info-correlate-bar.h @@ -0,0 +1,7 @@ +int foo(int); + +inline int bar(int a) { + while (a > 100) + a /= 2; + return a; +} diff --git a/compiler-rt/test/profile/Inputs/instrprof-debug-info-correlate-foo.cpp b/compiler-rt/test/profile/Inputs/instrprof-debug-info-correlate-foo.cpp new file mode 100644 --- /dev/null +++ b/compiler-rt/test/profile/Inputs/instrprof-debug-info-correlate-foo.cpp @@ -0,0 +1,7 @@ +#include "instrprof-debug-info-correlate-bar.h" + +int foo(int a) { + if (a % 2) + return 4 * a + 1; + return bar(a); +} diff --git a/compiler-rt/test/profile/Inputs/instrprof-debug-info-correlate-main.cpp b/compiler-rt/test/profile/Inputs/instrprof-debug-info-correlate-main.cpp new file mode 100644 --- /dev/null +++ b/compiler-rt/test/profile/Inputs/instrprof-debug-info-correlate-main.cpp @@ -0,0 +1,10 @@ +#include "instrprof-debug-info-correlate-bar.h" + +typedef int (*FP)(int); +FP Fps[2] = {foo, bar}; + +int main() { + for (int i = 0; i < 5; i++) + Fps[i % 2](i); + return 0; +} diff --git a/compiler-rt/test/profile/Linux/instrprof-debug-info-correlate.c b/compiler-rt/test/profile/Linux/instrprof-debug-info-correlate.c --- a/compiler-rt/test/profile/Linux/instrprof-debug-info-correlate.c +++ b/compiler-rt/test/profile/Linux/instrprof-debug-info-correlate.c @@ -1,33 +1,12 @@ // REQUIRES: zlib // Value profiling is currently not supported in lightweight mode. -// RUN: %clang_pgogen -o %t.normal -mllvm --disable-vp=true %s -// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t.normal -// RUN: llvm-profdata merge -o %t.normal.profdata %t.profraw - -// RUN: %clang_pgogen -o %t -g -mllvm --debug-info-correlate -mllvm --disable-vp=true %s +// RUN: %clang_pgogen -o %t -g -mllvm --debug-info-correlate -mllvm --disable-vp=true %S/../Inputs/instrprof-debug-info-correlate-main.cpp %S/../Inputs/instrprof-debug-info-correlate-foo.cpp // RUN: env LLVM_PROFILE_FILE=%t.proflite %run %t // RUN: llvm-profdata merge -o %t.profdata --debug-info=%t %t.proflite -// RUN: diff %t.normal.profdata %t.profdata - -int foo(int a) { - if (a % 2) - return 4 * a + 1; - return 0; -} - -int bar(int a) { - while (a > 100) - a /= 2; - return a; -} - -typedef int (*FP)(int); -FP Fps[3] = {foo, bar}; +// RUN: %clang_pgogen -o %t.normal -mllvm --disable-vp=true %S/../Inputs/instrprof-debug-info-correlate-main.cpp %S/../Inputs/instrprof-debug-info-correlate-foo.cpp +// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t.normal +// RUN: llvm-profdata merge -o %t.normal.profdata %t.profraw -int main() { - for (int i = 0; i < 5; i++) - Fps[i % 2](i); - return 0; -} +// RUN: diff %t.normal.profdata %t.profdata diff --git a/llvm/include/llvm/ProfileData/InstrProfCorrelator.h b/llvm/include/llvm/ProfileData/InstrProfCorrelator.h --- a/llvm/include/llvm/ProfileData/InstrProfCorrelator.h +++ b/llvm/include/llvm/ProfileData/InstrProfCorrelator.h @@ -12,6 +12,7 @@ #ifndef LLVM_PROFILEDATA_INSTRPROFCORRELATOR_H #define LLVM_PROFILEDATA_INSTRPROFCORRELATOR_H +#include "llvm/ADT/DenseSet.h" #include "llvm/DebugInfo/DWARF/DWARFContext.h" #include "llvm/Object/Binary.h" #include "llvm/Object/ObjectFile.h" @@ -110,6 +111,7 @@ std::unique_ptr Ctx) : InstrProfCorrelator(Kind, std::move(Ctx)){}; std::vector Names; + llvm::DenseSet CounterOffsets; // Byte-swap the value if necessary. template T maybeSwap(T Value) const { diff --git a/llvm/lib/ProfileData/InstrProfCorrelator.cpp b/llvm/lib/ProfileData/InstrProfCorrelator.cpp --- a/llvm/lib/ProfileData/InstrProfCorrelator.cpp +++ b/llvm/lib/ProfileData/InstrProfCorrelator.cpp @@ -129,6 +129,7 @@ correlateProfileDataImpl(); auto Result = collectPGOFuncNameStrings(Names, /*doCompression=*/true, CompressedNames); + CounterOffsets.clear(); Names.clear(); return Result; } @@ -139,6 +140,9 @@ IntPtrT CounterOffset, IntPtrT FunctionPtr, uint32_t NumCounters) { + // Check if a probe was already added for this counter offset. + if (!CounterOffsets.insert(CounterOffset).second) + return; Data.push_back({ maybeSwap(IndexedInstrProf::ComputeHash(FunctionName)), maybeSwap(CFGHash),