Skip to content

Commit cf2cf19

Browse files
committed
[Profile] Allow online merging with debug info correlation.
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
1 parent f0c5ce0 commit cf2cf19

File tree

5 files changed

+76
-18
lines changed

5 files changed

+76
-18
lines changed

clang/lib/CodeGen/BackendUtil.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ namespace {
102102

103103
// Default filename used for profile generation.
104104
std::string getDefaultProfileGenName() {
105-
return DebugInfoCorrelate ? "default_%p.proflite" : "default_%m.profraw";
105+
return DebugInfoCorrelate ? "default_%m.proflite" : "default_%m.profraw";
106106
}
107107

108108
class EmitAssemblyHelper {

compiler-rt/lib/profile/InstrProfilingMerge.c

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,16 @@ uint64_t lprofGetLoadModuleSignature(void) {
4747
COMPILER_RT_VISIBILITY
4848
int __llvm_profile_check_compatibility(const char *ProfileData,
4949
uint64_t ProfileSize) {
50-
/* Check profile header only for now */
5150
__llvm_profile_header *Header = (__llvm_profile_header *)ProfileData;
5251
__llvm_profile_data *SrcDataStart, *SrcDataEnd, *SrcData, *DstData;
52+
char *SrcCountersStart, *SrcCountersEnd;
5353
SrcDataStart =
5454
(__llvm_profile_data *)(ProfileData + sizeof(__llvm_profile_header) +
5555
Header->BinaryIdsSize);
5656
SrcDataEnd = SrcDataStart + Header->DataSize;
57+
SrcCountersStart = (char *)SrcDataEnd;
58+
SrcCountersEnd = SrcCountersStart +
59+
Header->CountersSize * __llvm_profile_counter_entry_size();
5760

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

78+
if (SrcCountersEnd - SrcCountersStart !=
79+
__llvm_profile_end_counters() - __llvm_profile_begin_counters()) {
80+
return 1;
81+
}
82+
7583
if (ProfileSize <
7684
sizeof(__llvm_profile_header) + Header->BinaryIdsSize +
7785
Header->DataSize * sizeof(__llvm_profile_data) + Header->NamesSize +
@@ -102,13 +110,6 @@ static uintptr_t signextIfWin64(void *V) {
102110
COMPILER_RT_VISIBILITY
103111
int __llvm_profile_merge_from_buffer(const char *ProfileData,
104112
uint64_t ProfileSize) {
105-
if (__llvm_profile_get_version() & VARIANT_MASK_DBG_CORRELATE) {
106-
PROF_ERR(
107-
"%s\n",
108-
"Debug info correlation does not support profile merging at runtime. "
109-
"Instead, merge raw profiles using the llvm-profdata tool.");
110-
return 1;
111-
}
112113
if (__llvm_profile_get_version() & VARIANT_MASK_TEMPORAL_PROF) {
113114
PROF_ERR("%s\n",
114115
"Temporal profiles do not support profile merging at runtime. "
@@ -118,7 +119,8 @@ int __llvm_profile_merge_from_buffer(const char *ProfileData,
118119

119120
__llvm_profile_data *SrcDataStart, *SrcDataEnd, *SrcData, *DstData;
120121
__llvm_profile_header *Header = (__llvm_profile_header *)ProfileData;
121-
char *SrcCountersStart;
122+
char *SrcCountersStart, *DstCounter;
123+
const char *SrcCountersEnd, *SrcCounter;
122124
const char *SrcNameStart;
123125
const char *SrcValueProfDataStart, *SrcValueProfData;
124126
uintptr_t CountersDelta = Header->CountersDelta;
@@ -128,14 +130,36 @@ int __llvm_profile_merge_from_buffer(const char *ProfileData,
128130
Header->BinaryIdsSize);
129131
SrcDataEnd = SrcDataStart + Header->DataSize;
130132
SrcCountersStart = (char *)SrcDataEnd;
131-
SrcNameStart = SrcCountersStart +
132-
Header->CountersSize * __llvm_profile_counter_entry_size();
133+
SrcCountersEnd = SrcCountersStart +
134+
Header->CountersSize * __llvm_profile_counter_entry_size();
135+
SrcNameStart = SrcCountersEnd;
133136
SrcValueProfDataStart =
134137
SrcNameStart + Header->NamesSize +
135138
__llvm_profile_get_num_padding_bytes(Header->NamesSize);
136139
if (SrcNameStart < SrcCountersStart)
137140
return 1;
138141

142+
// Merge counters when there is no data section and debug info correlation is
143+
// enabled.
144+
if (Header->DataSize == 0) {
145+
if (!(__llvm_profile_get_version() & VARIANT_MASK_DBG_CORRELATE)) {
146+
PROF_ERR("%s\n", "Missing profile data section.");
147+
return 1;
148+
}
149+
for (SrcCounter = SrcCountersStart,
150+
DstCounter = __llvm_profile_begin_counters();
151+
SrcCounter < SrcCountersEnd;) {
152+
if (__llvm_profile_get_version() & VARIANT_MASK_BYTE_COVERAGE) {
153+
*DstCounter &= *SrcCounter;
154+
} else {
155+
*(uint64_t *)DstCounter += *(uint64_t *)SrcCounter;
156+
}
157+
SrcCounter += __llvm_profile_counter_entry_size();
158+
DstCounter += __llvm_profile_counter_entry_size();
159+
}
160+
return 0;
161+
}
162+
139163
for (SrcData = SrcDataStart,
140164
DstData = (__llvm_profile_data *)__llvm_profile_begin_data(),
141165
SrcValueProfData = SrcValueProfDataStart;

compiler-rt/test/profile/Darwin/instrprof-debug-info-correlate.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,23 @@
1818
// RUN: llvm-profdata merge -o %t.cov.normal.profdata %t.cov.profraw
1919

2020
// RUN: diff <(llvm-profdata show --all-functions --counts %t.cov.normal.profdata) <(llvm-profdata show --all-functions --counts %t.cov.profdata)
21+
22+
// Test debug info correlate with online merging.
23+
24+
// RUN: env LLVM_PROFILE_FILE=%t-1.profraw %run %t.normal
25+
// RUN: env LLVM_PROFILE_FILE=%t-2.profraw %run %t.normal
26+
// RUN: llvm-profdata merge -o %t.normal.profdata %t-1.profraw %t-2.profraw
27+
28+
// RUN: rm -rf %t.profdir && mkdir %t.profdir
29+
// RUN: env LLVM_PROFILE_FILE=%t.profdir/%m.proflite %run %t
30+
// RUN: env LLVM_PROFILE_FILE=%t.profdir/%m.proflite %run %t
31+
// RUN: llvm-profdata merge -o %t.profdata --debug-info=%t.dSYM %t.profdir/
32+
33+
// RUN: diff <(llvm-profdata show --all-functions --counts %t.normal.profdata) <(llvm-profdata show --all-functions --counts %t.profdata)
34+
35+
// RUN: rm -rf %t.profdir && mkdir %t.profdir
36+
// RUN: env LLVM_PROFILE_FILE=%t.profdir/%m.cov.proflite %run %t.cov
37+
// RUN: env LLVM_PROFILE_FILE=%t.profdir/%m.cov.proflite %run %t.cov
38+
// RUN: llvm-profdata merge -o %t.cov.profdata --debug-info=%t.cov.dSYM %t.profdir/
39+
40+
// RUN: diff <(llvm-profdata show --all-functions --counts %t.cov.normal.profdata) <(llvm-profdata show --all-functions --counts %t.cov.profdata)

compiler-rt/test/profile/Linux/instrprof-debug-info-correlate.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,23 @@
2424
// RUN: llvm-profdata merge -o %t.cov.normal.profdata %t.cov.profraw
2525

2626
// RUN: diff <(llvm-profdata show --all-functions --counts %t.cov.normal.profdata) <(llvm-profdata show --all-functions --counts %t.cov.profdata)
27+
28+
// Test debug info correlate with online merging.
29+
30+
// RUN: env LLVM_PROFILE_FILE=%t-1.profraw %run %t.normal
31+
// RUN: env LLVM_PROFILE_FILE=%t-2.profraw %run %t.normal
32+
// RUN: llvm-profdata merge -o %t.normal.profdata %t-1.profraw %t-2.profraw
33+
34+
// RUN: rm -rf %t.profdir && mkdir %t.profdir
35+
// RUN: env LLVM_PROFILE_FILE=%t.profdir/%m.proflite %run %t
36+
// RUN: env LLVM_PROFILE_FILE=%t.profdir/%m.proflite %run %t
37+
// RUN: llvm-profdata merge -o %t.profdata --debug-info=%t %t.profdir/
38+
39+
// RUN: diff <(llvm-profdata show --all-functions --counts %t.normal.profdata) <(llvm-profdata show --all-functions --counts %t.profdata)
40+
41+
// RUN: rm -rf %t.profdir && mkdir %t.profdir
42+
// RUN: env LLVM_PROFILE_FILE=%t.profdir/%m.cov.proflite %run %t.cov
43+
// RUN: env LLVM_PROFILE_FILE=%t.profdir/%m.cov.proflite %run %t.cov
44+
// RUN: llvm-profdata merge -o %t.cov.profdata --debug-info=%t.cov %t.profdir/
45+
46+
// RUN: diff <(llvm-profdata show --all-functions --counts %t.cov.normal.profdata) <(llvm-profdata show --all-functions --counts %t.cov.profdata)

compiler-rt/test/profile/instrprof-merge-error.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,5 @@
11
// RUN: rm -rf %t; mkdir %t
22

3-
// RUN: %clang_pgogen -o %t/dbg -g -mllvm --debug-info-correlate -mllvm --disable-vp=true %s
4-
// RUN: env LLVM_PROFILE_FILE=%t/dbg_%m.profdata %run %t/dbg 2>&1 | count 0
5-
// RUN: env LLVM_PROFILE_FILE=%t/dbg_%m.profdata %run %t/dbg 2>&1 | FileCheck %s --check-prefix=DBG
6-
7-
// DBG: Debug info correlation does not support profile merging at runtime.
8-
93
// RUN: %clang_pgogen -o %t/timeprof -mllvm -pgo-temporal-instrumentation %s
104
// RUN: env LLVM_PROFILE_FILE=%t/timeprof_%m.profdata %run %t/timeprof 2>&1 | count 0
115
// RUN: env LLVM_PROFILE_FILE=%t/timeprof_%m.profdata %run %t/timeprof 2>&1 | FileCheck %s --check-prefix=TIMEPROF

0 commit comments

Comments
 (0)