Skip to content

Commit

Permalink
[Profile] Allow online merging with debug info correlation.
Browse files Browse the repository at this point in the history
When using debug info correlation, value profiling needs to be switched off.
So, we are only merging counter sections. In that case the existance of data
section is just used to provide an extra check in case of corrupted profile.

This patch performs counter merging by iterating the counter section by counter
size and add them together.

Reviewed By: ellis, MaskRay

Differential Revision: https://reviews.llvm.org/D157632
  • Loading branch information
ZequanWu committed Aug 14, 2023
1 parent f0c5ce0 commit cf2cf19
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 18 deletions.
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/BackendUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ namespace {

// 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 {
Expand Down
46 changes: 35 additions & 11 deletions compiler-rt/lib/profile/InstrProfilingMerge.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,16 @@ uint64_t lprofGetLoadModuleSignature(void) {
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;
char *SrcCountersStart, *SrcCountersEnd;
SrcDataStart =
(__llvm_profile_data *)(ProfileData + sizeof(__llvm_profile_header) +
Header->BinaryIdsSize);
SrcDataEnd = SrcDataStart + Header->DataSize;
SrcCountersStart = (char *)SrcDataEnd;
SrcCountersEnd = SrcCountersStart +
Header->CountersSize * __llvm_profile_counter_entry_size();

if (ProfileSize < sizeof(__llvm_profile_header))
return 1;
Expand All @@ -72,6 +75,11 @@ int __llvm_profile_check_compatibility(const char *ProfileData,
Header->ValueKindLast != IPVK_Last)
return 1;

if (SrcCountersEnd - SrcCountersStart !=
__llvm_profile_end_counters() - __llvm_profile_begin_counters()) {
return 1;
}

if (ProfileSize <
sizeof(__llvm_profile_header) + Header->BinaryIdsSize +
Header->DataSize * sizeof(__llvm_profile_data) + Header->NamesSize +
Expand Down Expand Up @@ -102,13 +110,6 @@ static uintptr_t signextIfWin64(void *V) {
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. "
Expand All @@ -118,7 +119,8 @@ int __llvm_profile_merge_from_buffer(const char *ProfileData,

__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;
Expand All @@ -128,14 +130,36 @@ int __llvm_profile_merge_from_buffer(const char *ProfileData,
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;
Expand Down
20 changes: 20 additions & 0 deletions compiler-rt/test/profile/Darwin/instrprof-debug-info-correlate.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
20 changes: 20 additions & 0 deletions compiler-rt/test/profile/Linux/instrprof-debug-info-correlate.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
6 changes: 0 additions & 6 deletions compiler-rt/test/profile/instrprof-merge-error.c
Original file line number Diff line number Diff line change
@@ -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
Expand Down

0 comments on commit cf2cf19

Please sign in to comment.