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 @@ -102,17 +102,10 @@ 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; - } - __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; @@ -122,14 +115,36 @@ Header->BinaryIdsSize); SrcDataEnd = SrcDataStart + Header->DataSize; SrcCountersStart = (char *)SrcDataEnd; - SrcNameStart = SrcCountersStart + - Header->CountersSize * __llvm_profile_counter_entry_size(); + SrcCountersEnd = SrcCountersStart + + Header->CountersSize * __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 when there is no data section and debug info correlation is + // enabled. + if (Header->DataSize == 0) { + if (!(__llvm_profile_get_version() & VARIANT_MASK_DBG_CORRELATE)) { + PROF_ERR("%s\n", "Missing profile data section."); + return 1; + } + 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,19 @@ // RUN: llvm-profdata merge -o %t.cov.normal.profdata %t.cov.profraw // RUN: diff %t.cov.normal.profdata %t.cov.profdata + +// Test debug info correlate with online merging. + +// RUN: rm -rf %t.profdir && mkdir %t.profdir +// 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.profdir/%m.proflite %run %t +// RUN: llvm-profdata merge -o %t.profdata --debug-info=%t.dSYM %t.profdir/ + +// RUN: diff %t.normal.profdata %t.profdata + +// RUN: rm -rf %t.profdir && mkdir %t.profdir +// RUN: %clang_pgogen -o %t.cov -g -mllvm --debug-info-correlate -mllvm -pgo-function-entry-coverage -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.profdir/%m.cov.proflite %run %t.cov +// RUN: llvm-profdata merge -o %t.cov.profdata --debug-info=%t.cov.dSYM %t.profdir/ + +// RUN: diff %t.cov.normal.profdata %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,19 @@ // RUN: llvm-profdata merge -o %t.cov.normal.profdata %t.cov.profraw // RUN: diff <(llvm-profdata show %t.cov.normal.profdata) <(llvm-profdata show %t.cov.profdata) + +// Test debug info correlate with online merging. + +// RUN: rm -rf %t.profdir && mkdir %t.profdir +// 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.profdir/%m.proflite %run %t +// RUN: llvm-profdata merge -o %t.profdata --debug-info=%t %t.profdir/ + +// RUN: diff <(llvm-profdata show %t.normal.profdata) <(llvm-profdata show %t.profdata) + +// RUN: rm -rf %t.profdir && mkdir %t.profdir +// RUN: %clang_pgogen -o %t.cov -g -mllvm --debug-info-correlate -mllvm -pgo-function-entry-coverage -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.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 %t.cov.normal.profdata) <(llvm-profdata show %t.cov.profdata)