Skip to content

Commit d2f77eb

Browse files
authored
[MC/DC][Coverage] Introduce "Bitmap Bias" for continuous mode (#96126)
`counter_bias` is incompatible to Bitmap. The distance between Counters and Bitmap is different between on-memory sections and profraw image. Reference to `__llvm_profile_bitmap_bias` is generated only if `-fcoverge-mcdc` `-runtime-counter-relocation` are specified. The current implementation rejected their options. ``` Runtime counter relocation is presently not supported for MC/DC bitmaps ```
1 parent cc01c83 commit d2f77eb

File tree

6 files changed

+67
-17
lines changed

6 files changed

+67
-17
lines changed

compiler-rt/include/profile/InstrProfData.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -738,6 +738,7 @@ serializeValueProfDataFrom(ValueProfRecordClosure *Closure,
738738
#define INSTR_PROF_RAW_VERSION_VAR __llvm_profile_raw_version
739739
#define INSTR_PROF_PROFILE_RUNTIME_VAR __llvm_profile_runtime
740740
#define INSTR_PROF_PROFILE_COUNTER_BIAS_VAR __llvm_profile_counter_bias
741+
#define INSTR_PROF_PROFILE_BITMAP_BIAS_VAR __llvm_profile_bitmap_bias
741742
#define INSTR_PROF_PROFILE_SET_TIMESTAMP __llvm_profile_set_timestamp
742743
#define INSTR_PROF_PROFILE_SAMPLING_VAR __llvm_profile_sampling
743744

compiler-rt/lib/profile/InstrProfilingFile.c

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ static const int UseBiasVar = 0;
101101
static const char *FileOpenMode = "a+b";
102102
static void *BiasAddr = NULL;
103103
static void *BiasDefaultAddr = NULL;
104+
static void *BitmapBiasAddr = NULL;
105+
static void *BitmapBiasDefaultAddr = NULL;
104106
static int mmapForContinuousMode(uint64_t CurrentFileOffset, FILE *File) {
105107
/* Get the sizes of various profile data sections. Taken from
106108
* __llvm_profile_get_size_for_buffer(). */
@@ -199,11 +201,15 @@ static int mmapForContinuousMode(uint64_t CurrentFileOffset, FILE *File) {
199201
#define INSTR_PROF_PROFILE_COUNTER_BIAS_DEFAULT_VAR \
200202
INSTR_PROF_CONCAT(INSTR_PROF_PROFILE_COUNTER_BIAS_VAR, _default)
201203
COMPILER_RT_VISIBILITY intptr_t INSTR_PROF_PROFILE_COUNTER_BIAS_DEFAULT_VAR = 0;
204+
#define INSTR_PROF_PROFILE_BITMAP_BIAS_DEFAULT_VAR \
205+
INSTR_PROF_CONCAT(INSTR_PROF_PROFILE_BITMAP_BIAS_VAR, _default)
206+
COMPILER_RT_VISIBILITY intptr_t INSTR_PROF_PROFILE_BITMAP_BIAS_DEFAULT_VAR = 0;
202207

203208
/* This variable is a weak external reference which could be used to detect
204209
* whether or not the compiler defined this symbol. */
205210
#if defined(_MSC_VER)
206211
COMPILER_RT_VISIBILITY extern intptr_t INSTR_PROF_PROFILE_COUNTER_BIAS_VAR;
212+
COMPILER_RT_VISIBILITY extern intptr_t INSTR_PROF_PROFILE_BITMAP_BIAS_VAR;
207213
#if defined(_M_IX86) || defined(__i386__)
208214
#define WIN_SYM_PREFIX "_"
209215
#else
@@ -213,10 +219,17 @@ COMPILER_RT_VISIBILITY extern intptr_t INSTR_PROF_PROFILE_COUNTER_BIAS_VAR;
213219
linker, "/alternatename:" WIN_SYM_PREFIX INSTR_PROF_QUOTE( \
214220
INSTR_PROF_PROFILE_COUNTER_BIAS_VAR) "=" WIN_SYM_PREFIX \
215221
INSTR_PROF_QUOTE(INSTR_PROF_PROFILE_COUNTER_BIAS_DEFAULT_VAR))
222+
#pragma comment( \
223+
linker, "/alternatename:" WIN_SYM_PREFIX INSTR_PROF_QUOTE( \
224+
INSTR_PROF_PROFILE_BITMAP_BIAS_VAR) "=" WIN_SYM_PREFIX \
225+
INSTR_PROF_QUOTE(INSTR_PROF_PROFILE_BITMAP_BIAS_DEFAULT_VAR))
216226
#else
217227
COMPILER_RT_VISIBILITY extern intptr_t INSTR_PROF_PROFILE_COUNTER_BIAS_VAR
218228
__attribute__((weak, alias(INSTR_PROF_QUOTE(
219229
INSTR_PROF_PROFILE_COUNTER_BIAS_DEFAULT_VAR))));
230+
COMPILER_RT_VISIBILITY extern intptr_t INSTR_PROF_PROFILE_BITMAP_BIAS_VAR
231+
__attribute__((weak, alias(INSTR_PROF_QUOTE(
232+
INSTR_PROF_PROFILE_BITMAP_BIAS_DEFAULT_VAR))));
220233
#endif
221234
static const int ContinuousModeSupported = 1;
222235
static const int UseBiasVar = 1;
@@ -227,6 +240,9 @@ static const char *FileOpenMode = "w+b";
227240
* used and runtime provides a weak alias so we can check if it's defined. */
228241
static void *BiasAddr = &INSTR_PROF_PROFILE_COUNTER_BIAS_VAR;
229242
static void *BiasDefaultAddr = &INSTR_PROF_PROFILE_COUNTER_BIAS_DEFAULT_VAR;
243+
static void *BitmapBiasAddr = &INSTR_PROF_PROFILE_BITMAP_BIAS_VAR;
244+
static void *BitmapBiasDefaultAddr =
245+
&INSTR_PROF_PROFILE_BITMAP_BIAS_DEFAULT_VAR;
230246
static int mmapForContinuousMode(uint64_t CurrentFileOffset, FILE *File) {
231247
/* Get the sizes of various profile data sections. Taken from
232248
* __llvm_profile_get_size_for_buffer(). */
@@ -237,12 +253,18 @@ static int mmapForContinuousMode(uint64_t CurrentFileOffset, FILE *File) {
237253
const char *BitmapBegin = __llvm_profile_begin_bitmap();
238254
const char *BitmapEnd = __llvm_profile_end_bitmap();
239255
uint64_t DataSize = __llvm_profile_get_data_size(DataBegin, DataEnd);
256+
uint64_t CountersSize =
257+
__llvm_profile_get_counters_size(CountersBegin, CountersEnd);
258+
uint64_t NumBitmapBytes =
259+
__llvm_profile_get_num_bitmap_bytes(BitmapBegin, BitmapEnd);
240260
/* Get the file size. */
241261
uint64_t FileSize = 0;
242262
if (getProfileFileSizeForMerging(File, &FileSize))
243263
return 1;
244264

245265
int Fileno = fileno(File);
266+
uint64_t PaddingBytesAfterCounters =
267+
__llvm_profile_get_num_padding_bytes(CountersSize);
246268
uint64_t FileOffsetToCounters =
247269
sizeof(__llvm_profile_header) + __llvm_write_binary_ids(NULL) + DataSize;
248270

@@ -260,7 +282,17 @@ static int mmapForContinuousMode(uint64_t CurrentFileOffset, FILE *File) {
260282
/* Return the memory allocated for counters to OS. */
261283
lprofReleaseMemoryPagesToOS((uintptr_t)CountersBegin, (uintptr_t)CountersEnd);
262284

263-
/* BIAS MODE not supported yet for Bitmap (MCDC). */
285+
/* Also mmap MCDC bitmap bytes. If there aren't any bitmap bytes, mmap()
286+
* will fail with EINVAL. */
287+
if (NumBitmapBytes == 0)
288+
return 0;
289+
290+
/* Update profbm_bias. */
291+
uint64_t FileOffsetToBitmap =
292+
FileOffsetToCounters + CountersSize + PaddingBytesAfterCounters;
293+
/* Update the profile fields based on the current mapping. */
294+
INSTR_PROF_PROFILE_BITMAP_BIAS_VAR =
295+
(uintptr_t)Profile - (uintptr_t)BitmapBegin + FileOffsetToBitmap;
264296

265297
/* Return the memory allocated for counters to OS. */
266298
lprofReleaseMemoryPagesToOS((uintptr_t)BitmapBegin, (uintptr_t)BitmapEnd);
@@ -619,8 +651,10 @@ static void initializeProfileForContinuousMode(void) {
619651
PROF_ERR("%s\n", "continuous mode is unsupported on this platform");
620652
return;
621653
}
622-
if (UseBiasVar && BiasAddr == BiasDefaultAddr) {
623-
PROF_ERR("%s\n", "__llvm_profile_counter_bias is undefined");
654+
if (UseBiasVar && BiasAddr == BiasDefaultAddr &&
655+
BitmapBiasAddr == BitmapBiasDefaultAddr) {
656+
PROF_ERR("%s\n", "Neither __llvm_profile_counter_bias nor "
657+
"__llvm_profile_bitmap_bias is defined");
624658
return;
625659
}
626660

llvm/include/llvm/ProfileData/InstrProf.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,10 @@ inline StringRef getInstrProfCounterBiasVarName() {
174174
return INSTR_PROF_QUOTE(INSTR_PROF_PROFILE_COUNTER_BIAS_VAR);
175175
}
176176

177+
inline StringRef getInstrProfBitmapBiasVarName() {
178+
return INSTR_PROF_QUOTE(INSTR_PROF_PROFILE_BITMAP_BIAS_VAR);
179+
}
180+
177181
/// Return the marker used to separate PGO names during serialization.
178182
inline StringRef getInstrProfNameSeparator() { return "\01"; }
179183

llvm/include/llvm/ProfileData/InstrProfData.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -738,6 +738,7 @@ serializeValueProfDataFrom(ValueProfRecordClosure *Closure,
738738
#define INSTR_PROF_RAW_VERSION_VAR __llvm_profile_raw_version
739739
#define INSTR_PROF_PROFILE_RUNTIME_VAR __llvm_profile_runtime
740740
#define INSTR_PROF_PROFILE_COUNTER_BIAS_VAR __llvm_profile_counter_bias
741+
#define INSTR_PROF_PROFILE_BITMAP_BIAS_VAR __llvm_profile_bitmap_bias
741742
#define INSTR_PROF_PROFILE_SET_TIMESTAMP __llvm_profile_set_timestamp
742743
#define INSTR_PROF_PROFILE_SAMPLING_VAR __llvm_profile_sampling
743744

llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1192,18 +1192,22 @@ CallInst *InstrLowerer::getRMWOrCall(Value *Addr, Value *Val) {
11921192

11931193
Value *InstrLowerer::getBitmapAddress(InstrProfMCDCTVBitmapUpdate *I) {
11941194
auto *Bitmaps = getOrCreateRegionBitmaps(I);
1195-
IRBuilder<> Builder(I);
1196-
1197-
if (isRuntimeCounterRelocationEnabled()) {
1198-
LLVMContext &Ctx = M.getContext();
1199-
Ctx.diagnose(DiagnosticInfoPGOProfile(
1200-
M.getName().data(),
1201-
Twine("Runtime counter relocation is presently not supported for MC/DC "
1202-
"bitmaps."),
1203-
DS_Warning));
1204-
}
1195+
if (!isRuntimeCounterRelocationEnabled())
1196+
return Bitmaps;
12051197

1206-
return Bitmaps;
1198+
// Put BiasLI onto the entry block.
1199+
Type *Int64Ty = Type::getInt64Ty(M.getContext());
1200+
Function *Fn = I->getFunction();
1201+
IRBuilder<> EntryBuilder(&Fn->getEntryBlock().front());
1202+
auto *Bias = getOrCreateBiasVar(getInstrProfBitmapBiasVarName());
1203+
auto *BiasLI = EntryBuilder.CreateLoad(Int64Ty, Bias, "profbm_bias");
1204+
// Assume BiasLI invariant (in the function at least)
1205+
BiasLI->setMetadata(LLVMContext::MD_invariant_load,
1206+
MDNode::get(M.getContext(), std::nullopt));
1207+
1208+
// Add Bias to Bitmaps and put it before the intrinsic.
1209+
IRBuilder<> Builder(I);
1210+
return Builder.CreatePtrAdd(Bitmaps, BiasLI, "profbm_addr");
12071211
}
12081212

12091213
void InstrLowerer::lowerCover(InstrProfCoverInst *CoverInstruction) {

llvm/test/Instrumentation/InstrProfiling/mcdc.ll

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
; Check that MC/DC intrinsics are properly lowered
22
; RUN: opt < %s -passes=instrprof -S | FileCheck %s --check-prefixes=CHECK,BASIC
33
; RUN: opt < %s -passes=instrprof -S -instrprof-atomic-counter-update-all | FileCheck %s --check-prefixes=CHECK,ATOMIC
4-
; RUN: opt < %s -passes=instrprof -runtime-counter-relocation -S 2>&1 | FileCheck %s --check-prefix RELOC
5-
6-
; RELOC: Runtime counter relocation is presently not supported for MC/DC bitmaps
4+
; RUN: opt < %s -passes=instrprof -S -runtime-counter-relocation | FileCheck %s --check-prefixes=CHECK,RELOC
75

86
target triple = "x86_64-unknown-linux-gnu"
97

@@ -14,17 +12,23 @@ target triple = "x86_64-unknown-linux-gnu"
1412

1513
define dso_local void @test(i32 noundef %A) {
1614
entry:
15+
; RELOC: %profbm_bias = load i64, ptr @__llvm_profile_bitmap_bias, align 8, !invariant.load !0
16+
; RELOC: %profc_bias = load i64, ptr @__llvm_profile_counter_bias, align 8
1717
%A.addr = alloca i32, align 4
1818
%mcdc.addr = alloca i32, align 4
1919
call void @llvm.instrprof.cover(ptr @__profn_test, i64 99278, i32 5, i32 0)
2020
; BASIC: store i8 0, ptr @__profc_test, align 1
21+
; RELOC: %[[PROFC_INTADDR:.+]] = add i64 ptrtoint (ptr @__profc_test to i64), %profc_bias
22+
; RELOC: %[[PROFC_ADDR:.+]] = inttoptr i64 %[[PROFC_INTADDR]] to ptr
23+
; RELOC: store i8 0, ptr %[[PROFC_ADDR]], align 1
2124

2225
call void @llvm.instrprof.mcdc.parameters(ptr @__profn_test, i64 99278, i32 1)
2326
store i32 0, ptr %mcdc.addr, align 4
2427
%0 = load i32, ptr %A.addr, align 4
2528
%tobool = icmp ne i32 %0, 0
2629

2730
call void @llvm.instrprof.mcdc.tvbitmap.update(ptr @__profn_test, i64 99278, i32 0, ptr %mcdc.addr)
31+
; RELOC: [[PROFBM_ADDR:%.+]] = getelementptr i8, ptr @__profbm_test, i64 %profbm_bias
2832
; CHECK: %[[TEMP0:mcdc.*]] = load i32, ptr %mcdc.addr, align 4
2933
; CHECK-NEXT: %[[TEMP:[0-9]+]] = add i32 %[[TEMP0]], 0
3034
; CHECK-NEXT: %[[LAB4:[0-9]+]] = lshr i32 %[[TEMP]], 3
@@ -39,7 +43,9 @@ entry:
3943
; CHECK: define private void @[[RMW_OR]](ptr %[[ARGPTR:.+]], i8 %[[ARGVAL:.+]])
4044
; CHECK: %[[BITS:.+]] = load i8, ptr %[[ARGPTR]], align 1
4145
; BASIC-NEXT: %[[LAB11:[0-9]+]] = or i8 %[[BITS]], %[[ARGVAL]]
46+
; RELOC-NEXT: %[[LAB11:[0-9]+]] = or i8 %[[BITS]], %[[ARGVAL]]
4247
; BASIC-NEXT: store i8 %[[LAB11]], ptr %[[ARGPTR]], align 1
48+
; RELOC-NEXT: store i8 %[[LAB11]], ptr %[[ARGPTR]], align 1
4349
; ATOMIC-NEXT: %[[MASKED:.+]] = and i8 %[[BITS]], %[[ARGVAL]]
4450
; ATOMIC-NEXT: %[[SHOULDWRITE:.+]] = icmp ne i8 %[[MASKED]], %[[ARGVAL]]
4551
; ATOMIC-NEXT: br i1 %[[SHOULDWRITE]], label %[[WRITE:.+]], label %[[SKIP:.+]], !prof ![[MDPROF:[0-9]+]]

0 commit comments

Comments
 (0)