diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -102,7 +102,7 @@ // Default filename used for profile generation. std::string getDefaultProfileGenName() { - return DebugInfoCorrelate ? "default_%p.proflite" : "default_%m.profraw"; + return DebugInfoCorrelate ? "default_%m.proflite" : "default_%m.profraw"; } class EmitAssemblyHelper { diff --git a/compiler-rt/lib/profile/InstrProfilingMerge.c b/compiler-rt/lib/profile/InstrProfilingMerge.c --- a/compiler-rt/lib/profile/InstrProfilingMerge.c +++ b/compiler-rt/lib/profile/InstrProfilingMerge.c @@ -47,7 +47,6 @@ COMPILER_RT_VISIBILITY int __llvm_profile_check_compatibility(const char *ProfileData, uint64_t ProfileSize) { - /* Check profile header only for now */ __llvm_profile_header *Header = (__llvm_profile_header *)ProfileData; __llvm_profile_data *SrcDataStart, *SrcDataEnd, *SrcData, *DstData; SrcDataStart = @@ -102,13 +101,6 @@ COMPILER_RT_VISIBILITY int __llvm_profile_merge_from_buffer(const char *ProfileData, uint64_t ProfileSize) { - if (__llvm_profile_get_version() & VARIANT_MASK_DBG_CORRELATE) { - PROF_ERR( - "%s\n", - "Debug info correlation does not support profile merging at runtime. " - "Instead, merge raw profiles using the llvm-profdata tool."); - return 1; - } if (__llvm_profile_get_version() & VARIANT_MASK_TEMPORAL_PROF) { PROF_ERR("%s\n", "Temporal profiles do not support profile merging at runtime. " @@ -118,7 +110,8 @@ __llvm_profile_data *SrcDataStart, *SrcDataEnd, *SrcData, *DstData; __llvm_profile_header *Header = (__llvm_profile_header *)ProfileData; - char *SrcCountersStart; + char *SrcCountersStart, *DstCounter; + const char *SrcCountersEnd, *SrcCounter; const char *SrcNameStart; const char *SrcValueProfDataStart, *SrcValueProfData; uintptr_t CountersDelta = Header->CountersDelta; @@ -128,14 +121,32 @@ Header->BinaryIdsSize); SrcDataEnd = SrcDataStart + Header->NumData; SrcCountersStart = (char *)SrcDataEnd; - SrcNameStart = SrcCountersStart + - Header->NumCounters * __llvm_profile_counter_entry_size(); + SrcCountersEnd = SrcCountersStart + + Header->NumCounters * __llvm_profile_counter_entry_size(); + SrcNameStart = SrcCountersEnd; SrcValueProfDataStart = SrcNameStart + Header->NamesSize + __llvm_profile_get_num_padding_bytes(Header->NamesSize); if (SrcNameStart < SrcCountersStart) return 1; + // Merge counters by iterating the entire counter section when debug info + // correlation is enabled. + if (__llvm_profile_get_version() & VARIANT_MASK_DBG_CORRELATE) { + for (SrcCounter = SrcCountersStart, + DstCounter = __llvm_profile_begin_counters(); + SrcCounter < SrcCountersEnd;) { + if (__llvm_profile_get_version() & VARIANT_MASK_BYTE_COVERAGE) { + *DstCounter &= *SrcCounter; + } else { + *(uint64_t *)DstCounter += *(uint64_t *)SrcCounter; + } + SrcCounter += __llvm_profile_counter_entry_size(); + DstCounter += __llvm_profile_counter_entry_size(); + } + return 0; + } + for (SrcData = SrcDataStart, DstData = (__llvm_profile_data *)__llvm_profile_begin_data(), SrcValueProfData = SrcValueProfDataStart; 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 @@ -18,3 +18,23 @@ // RUN: llvm-profdata merge -o %t.cov.normal.profdata %t.cov.profraw // RUN: diff <(llvm-profdata show --all-functions --counts %t.cov.normal.profdata) <(llvm-profdata show --all-functions --counts %t.cov.profdata) + +// Test debug info correlate with online merging. + +// RUN: env LLVM_PROFILE_FILE=%t-1.profraw %run %t.normal +// RUN: env LLVM_PROFILE_FILE=%t-2.profraw %run %t.normal +// RUN: llvm-profdata merge -o %t.normal.profdata %t-1.profraw %t-2.profraw + +// RUN: rm -rf %t.profdir && mkdir %t.profdir +// RUN: env LLVM_PROFILE_FILE=%t.profdir/%m.proflite %run %t +// RUN: env LLVM_PROFILE_FILE=%t.profdir/%m.proflite %run %t +// RUN: llvm-profdata merge -o %t.profdata --debug-info=%t.dSYM %t.profdir/ + +// RUN: diff <(llvm-profdata show --all-functions --counts %t.normal.profdata) <(llvm-profdata show --all-functions --counts %t.profdata) + +// RUN: rm -rf %t.profdir && mkdir %t.profdir +// RUN: env LLVM_PROFILE_FILE=%t.profdir/%m.cov.proflite %run %t.cov +// RUN: env LLVM_PROFILE_FILE=%t.profdir/%m.cov.proflite %run %t.cov +// RUN: llvm-profdata merge -o %t.cov.profdata --debug-info=%t.cov.dSYM %t.profdir/ + +// RUN: diff <(llvm-profdata show --all-functions --counts %t.cov.normal.profdata) <(llvm-profdata show --all-functions --counts %t.cov.profdata) 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 @@ -24,3 +24,23 @@ // RUN: llvm-profdata merge -o %t.cov.normal.profdata %t.cov.profraw // RUN: diff <(llvm-profdata show --all-functions --counts %t.cov.normal.profdata) <(llvm-profdata show --all-functions --counts %t.cov.profdata) + +// Test debug info correlate with online merging. + +// RUN: env LLVM_PROFILE_FILE=%t-1.profraw %run %t.normal +// RUN: env LLVM_PROFILE_FILE=%t-2.profraw %run %t.normal +// RUN: llvm-profdata merge -o %t.normal.profdata %t-1.profraw %t-2.profraw + +// RUN: rm -rf %t.profdir && mkdir %t.profdir +// RUN: env LLVM_PROFILE_FILE=%t.profdir/%m.proflite %run %t +// RUN: env LLVM_PROFILE_FILE=%t.profdir/%m.proflite %run %t +// RUN: llvm-profdata merge -o %t.profdata --debug-info=%t %t.profdir/ + +// RUN: diff <(llvm-profdata show --all-functions --counts %t.normal.profdata) <(llvm-profdata show --all-functions --counts %t.profdata) + +// RUN: rm -rf %t.profdir && mkdir %t.profdir +// RUN: env LLVM_PROFILE_FILE=%t.profdir/%m.cov.proflite %run %t.cov +// RUN: env LLVM_PROFILE_FILE=%t.profdir/%m.cov.proflite %run %t.cov +// RUN: llvm-profdata merge -o %t.cov.profdata --debug-info=%t.cov %t.profdir/ + +// RUN: diff <(llvm-profdata show --all-functions --counts %t.cov.normal.profdata) <(llvm-profdata show --all-functions --counts %t.cov.profdata) diff --git a/compiler-rt/test/profile/instrprof-merge-empty-data.test b/compiler-rt/test/profile/instrprof-merge-empty-data.test new file mode 100644 --- /dev/null +++ b/compiler-rt/test/profile/instrprof-merge-empty-data.test @@ -0,0 +1,14 @@ +// Test online merging with empty data section. +// RUN: rm -rf %t.dir && split-file %s %t.dir && cd %t.dir +// RUN: %clangxx_profgen -fcoverage-mapping -o %t main.c -fprofile-list=funlist +// RUN: LLVM_PROFILE_FILE='a%m.profraw' %t +// RUN: LLVM_PROFILE_FILE='a%m.profraw' %t 2>&1 | FileCheck %s --allow-empty + +// CHECK-NOT: LLVM Profile Error + +//--- main.c +int main() {} + +//--- funlist +[clang] +default:skip diff --git a/compiler-rt/test/profile/instrprof-merge-error.c b/compiler-rt/test/profile/instrprof-merge-error.c --- a/compiler-rt/test/profile/instrprof-merge-error.c +++ b/compiler-rt/test/profile/instrprof-merge-error.c @@ -1,11 +1,5 @@ // RUN: rm -rf %t; mkdir %t -// RUN: %clang_pgogen -o %t/dbg -g -mllvm --debug-info-correlate -mllvm --disable-vp=true %s -// RUN: env LLVM_PROFILE_FILE=%t/dbg_%m.profdata %run %t/dbg 2>&1 | count 0 -// RUN: env LLVM_PROFILE_FILE=%t/dbg_%m.profdata %run %t/dbg 2>&1 | FileCheck %s --check-prefix=DBG - -// DBG: Debug info correlation does not support profile merging at runtime. - // RUN: %clang_pgogen -o %t/timeprof -mllvm -pgo-temporal-instrumentation %s // RUN: env LLVM_PROFILE_FILE=%t/timeprof_%m.profdata %run %t/timeprof 2>&1 | count 0 // RUN: env LLVM_PROFILE_FILE=%t/timeprof_%m.profdata %run %t/timeprof 2>&1 | FileCheck %s --check-prefix=TIMEPROF