Skip to content

Commit f95b2f1

Browse files
committed
Reland "[InstrProf][compiler-rt] Enable MC/DC Support in LLVM Source-based Code Coverage (1/3)"
Part 1 of 3. This includes the LLVM back-end processing and profile reading/writing components. compiler-rt changes are included. Differential Revision: https://reviews.llvm.org/D138846
1 parent dc8c2a7 commit f95b2f1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+1441
-174
lines changed

clang/lib/Driver/ToolChains/Darwin.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1400,7 +1400,7 @@ void Darwin::addProfileRTLibs(const ArgList &Args,
14001400
addExportedSymbol(CmdArgs, "_reset_fn_list");
14011401
}
14021402

1403-
// Align __llvm_prf_{cnts,data} sections to the maximum expected page
1403+
// Align __llvm_prf_{cnts,bits,data} sections to the maximum expected page
14041404
// alignment. This allows profile counters to be mmap()'d to disk. Note that
14051405
// it's not enough to just page-align __llvm_prf_cnts: the following section
14061406
// must also be page-aligned so that its data is not clobbered by mmap().
@@ -1410,7 +1410,7 @@ void Darwin::addProfileRTLibs(const ArgList &Args,
14101410
// extra alignment also allows the same binary to be used with/without sync
14111411
// enabled.
14121412
if (!ForGCOV) {
1413-
for (auto IPSK : {llvm::IPSK_cnts, llvm::IPSK_data}) {
1413+
for (auto IPSK : {llvm::IPSK_cnts, llvm::IPSK_bitmap, llvm::IPSK_data}) {
14141414
addSectalignToPage(
14151415
Args, CmdArgs, "__DATA",
14161416
llvm::getInstrProfSectionName(IPSK, llvm::Triple::MachO,

clang/test/Driver/darwin-ld.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@
336336
// RUN: FileCheck -check-prefix=PROFILE_SECTALIGN %s < %t.log
337337
// RUN: %clang -target arm64-apple-ios12 -fprofile-instr-generate -### %t.o 2> %t.log
338338
// RUN: FileCheck -check-prefix=PROFILE_SECTALIGN %s < %t.log
339-
// PROFILE_SECTALIGN: "-sectalign" "__DATA" "__llvm_prf_cnts" "0x4000" "-sectalign" "__DATA" "__llvm_prf_data" "0x4000"
339+
// PROFILE_SECTALIGN: "-sectalign" "__DATA" "__llvm_prf_cnts" "0x4000" "-sectalign" "__DATA" "__llvm_prf_bits" "0x4000" "-sectalign" "__DATA" "__llvm_prf_data" "0x4000"
340340

341341
// RUN: %clang -target x86_64-apple-darwin12 -fprofile-instr-generate --coverage -### %t.o 2> %t.log
342342
// RUN: FileCheck -check-prefix=NO_PROFILE_EXPORT %s < %t.log

compiler-rt/include/profile/InstrProfData.inc

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ INSTR_PROF_DATA(const uint64_t, llvm::Type::getInt64Ty(Ctx), FuncHash, \
7676
ConstantInt::get(llvm::Type::getInt64Ty(Ctx), \
7777
Inc->getHash()->getZExtValue()))
7878
INSTR_PROF_DATA(const IntPtrT, IntPtrTy, CounterPtr, RelativeCounterPtr)
79+
INSTR_PROF_DATA(const IntPtrT, IntPtrTy, BitmapPtr, RelativeBitmapPtr)
7980
/* This is used to map function pointers for the indirect call targets to
8081
* function name hashes during the conversion from raw to merged profile
8182
* data.
@@ -87,7 +88,9 @@ INSTR_PROF_DATA(IntPtrT, llvm::Type::getInt8PtrTy(Ctx), Values, \
8788
INSTR_PROF_DATA(const uint32_t, llvm::Type::getInt32Ty(Ctx), NumCounters, \
8889
ConstantInt::get(llvm::Type::getInt32Ty(Ctx), NumCounters))
8990
INSTR_PROF_DATA(const uint16_t, Int16ArrayTy, NumValueSites[IPVK_Last+1], \
90-
ConstantArray::get(Int16ArrayTy, Int16ArrayVals))
91+
ConstantArray::get(Int16ArrayTy, Int16ArrayVals)) \
92+
INSTR_PROF_DATA(const uint32_t, llvm::Type::getInt32Ty(Ctx), NumBitmapBytes, \
93+
ConstantInt::get(llvm::Type::getInt32Ty(Ctx), NumBitmapBytes))
9194
#undef INSTR_PROF_DATA
9295
/* INSTR_PROF_DATA end. */
9396

@@ -132,9 +135,13 @@ INSTR_PROF_RAW_HEADER(uint64_t, NumData, NumData)
132135
INSTR_PROF_RAW_HEADER(uint64_t, PaddingBytesBeforeCounters, PaddingBytesBeforeCounters)
133136
INSTR_PROF_RAW_HEADER(uint64_t, NumCounters, NumCounters)
134137
INSTR_PROF_RAW_HEADER(uint64_t, PaddingBytesAfterCounters, PaddingBytesAfterCounters)
138+
INSTR_PROF_RAW_HEADER(uint64_t, NumBitmapBytes, NumBitmapBytes)
139+
INSTR_PROF_RAW_HEADER(uint64_t, PaddingBytesAfterBitmapBytes, PaddingBytesAfterBitmapBytes)
135140
INSTR_PROF_RAW_HEADER(uint64_t, NamesSize, NamesSize)
136141
INSTR_PROF_RAW_HEADER(uint64_t, CountersDelta,
137142
(uintptr_t)CountersBegin - (uintptr_t)DataBegin)
143+
INSTR_PROF_RAW_HEADER(uint64_t, BitmapDelta,
144+
(uintptr_t)BitmapBegin - (uintptr_t)DataBegin)
138145
INSTR_PROF_RAW_HEADER(uint64_t, NamesDelta, (uintptr_t)NamesBegin)
139146
INSTR_PROF_RAW_HEADER(uint64_t, ValueKindLast, IPVK_Last)
140147
#undef INSTR_PROF_RAW_HEADER
@@ -267,6 +274,9 @@ INSTR_PROF_SECT_ENTRY(IPSK_data, \
267274
INSTR_PROF_SECT_ENTRY(IPSK_cnts, \
268275
INSTR_PROF_QUOTE(INSTR_PROF_CNTS_COMMON), \
269276
INSTR_PROF_CNTS_COFF, "__DATA,")
277+
INSTR_PROF_SECT_ENTRY(IPSK_bitmap, \
278+
INSTR_PROF_QUOTE(INSTR_PROF_BITS_COMMON), \
279+
INSTR_PROF_BITS_COFF, "__DATA,")
270280
INSTR_PROF_SECT_ENTRY(IPSK_name, \
271281
INSTR_PROF_QUOTE(INSTR_PROF_NAME_COMMON), \
272282
INSTR_PROF_NAME_COFF, "__DATA,")
@@ -645,11 +655,11 @@ serializeValueProfDataFrom(ValueProfRecordClosure *Closure,
645655
(uint64_t)'f' << 16 | (uint64_t)'R' << 8 | (uint64_t)129
646656

647657
/* Raw profile format version (start from 1). */
648-
#define INSTR_PROF_RAW_VERSION 8
658+
#define INSTR_PROF_RAW_VERSION 9
649659
/* Indexed profile format version (start from 1). */
650-
#define INSTR_PROF_INDEX_VERSION 10
660+
#define INSTR_PROF_INDEX_VERSION 11
651661
/* Coverage mapping format version (start from 0). */
652-
#define INSTR_PROF_COVMAP_VERSION 5
662+
#define INSTR_PROF_COVMAP_VERSION 6
653663

654664
/* Profile version is always of type uint64_t. Reserve the upper 32 bits in the
655665
* version for other variants of profile. We set the 8th most significant bit
@@ -686,6 +696,7 @@ serializeValueProfDataFrom(ValueProfRecordClosure *Closure,
686696
#define INSTR_PROF_DATA_COMMON __llvm_prf_data
687697
#define INSTR_PROF_NAME_COMMON __llvm_prf_names
688698
#define INSTR_PROF_CNTS_COMMON __llvm_prf_cnts
699+
#define INSTR_PROF_BITS_COMMON __llvm_prf_bits
689700
#define INSTR_PROF_VALS_COMMON __llvm_prf_vals
690701
#define INSTR_PROF_VNODES_COMMON __llvm_prf_vnds
691702
#define INSTR_PROF_COVMAP_COMMON __llvm_covmap
@@ -697,6 +708,7 @@ serializeValueProfDataFrom(ValueProfRecordClosure *Closure,
697708
#define INSTR_PROF_DATA_COFF ".lprfd$M"
698709
#define INSTR_PROF_NAME_COFF ".lprfn$M"
699710
#define INSTR_PROF_CNTS_COFF ".lprfc$M"
711+
#define INSTR_PROF_BITS_COFF ".lprfb$M"
700712
#define INSTR_PROF_VALS_COFF ".lprfv$M"
701713
#define INSTR_PROF_VNODES_COFF ".lprfnd$M"
702714
#define INSTR_PROF_COVMAP_COFF ".lcovmap$M"
@@ -708,6 +720,7 @@ serializeValueProfDataFrom(ValueProfRecordClosure *Closure,
708720
#define INSTR_PROF_DATA_SECT_NAME INSTR_PROF_DATA_COFF
709721
#define INSTR_PROF_NAME_SECT_NAME INSTR_PROF_NAME_COFF
710722
#define INSTR_PROF_CNTS_SECT_NAME INSTR_PROF_CNTS_COFF
723+
#define INSTR_PROF_BITS_SECT_NAME INSTR_PROF_BITS_COFF
711724
/* Array of pointers. Each pointer points to a list
712725
* of value nodes associated with one value site.
713726
*/
@@ -722,6 +735,7 @@ serializeValueProfDataFrom(ValueProfRecordClosure *Closure,
722735
#define INSTR_PROF_DATA_SECT_NAME INSTR_PROF_QUOTE(INSTR_PROF_DATA_COMMON)
723736
#define INSTR_PROF_NAME_SECT_NAME INSTR_PROF_QUOTE(INSTR_PROF_NAME_COMMON)
724737
#define INSTR_PROF_CNTS_SECT_NAME INSTR_PROF_QUOTE(INSTR_PROF_CNTS_COMMON)
738+
#define INSTR_PROF_BITS_SECT_NAME INSTR_PROF_QUOTE(INSTR_PROF_BITS_COMMON)
725739
/* Array of pointers. Each pointer points to a list
726740
* of value nodes associated with one value site.
727741
*/

compiler-rt/lib/profile/InstrProfiling.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ COMPILER_RT_VISIBILITY void __llvm_profile_reset_counters(void) {
6060
(__llvm_profile_get_version() & VARIANT_MASK_BYTE_COVERAGE) ? 0xFF : 0;
6161
memset(I, ResetValue, E - I);
6262

63+
I = __llvm_profile_begin_bitmap();
64+
E = __llvm_profile_end_bitmap();
65+
memset(I, 0x0, E - I);
66+
6367
const __llvm_profile_data *DataBegin = __llvm_profile_begin_data();
6468
const __llvm_profile_data *DataEnd = __llvm_profile_end_data();
6569
const __llvm_profile_data *DI;

compiler-rt/lib/profile/InstrProfiling.h

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ const char *__llvm_profile_begin_names(void);
8888
const char *__llvm_profile_end_names(void);
8989
char *__llvm_profile_begin_counters(void);
9090
char *__llvm_profile_end_counters(void);
91+
char *__llvm_profile_begin_bitmap(void);
92+
char *__llvm_profile_end_bitmap(void);
9193
ValueProfNode *__llvm_profile_begin_vnodes();
9294
ValueProfNode *__llvm_profile_end_vnodes();
9395
uint32_t *__llvm_profile_begin_orderfile();
@@ -101,20 +103,20 @@ void __llvm_profile_reset_counters(void);
101103
/*!
102104
* \brief Merge profile data from buffer.
103105
*
104-
* Read profile data form buffer \p Profile and merge with in-process profile
105-
* counters. The client is expected to have checked or already knows the profile
106-
* data in the buffer matches the in-process counter structure before calling
107-
* it. Returns 0 (success) if the profile data is valid. Upon reading
108-
* invalid/corrupted profile data, returns 1 (failure).
106+
* Read profile data from buffer \p Profile and merge with in-process profile
107+
* counters and bitmaps. The client is expected to have checked or already
108+
* know the profile data in the buffer matches the in-process counter
109+
* structure before calling it. Returns 0 (success) if the profile data is
110+
* valid. Upon reading invalid/corrupted profile data, returns 1 (failure).
109111
*/
110112
int __llvm_profile_merge_from_buffer(const char *Profile, uint64_t Size);
111113

112114
/*! \brief Check if profile in buffer matches the current binary.
113115
*
114116
* Returns 0 (success) if the profile data in buffer \p Profile with size
115117
* \p Size was generated by the same binary and therefore matches
116-
* structurally the in-process counters. If the profile data in buffer is
117-
* not compatible, the interface returns 1 (failure).
118+
* structurally the in-process counters and bitmaps. If the profile data in
119+
* buffer is not compatible, the interface returns 1 (failure).
118120
*/
119121
int __llvm_profile_check_compatibility(const char *Profile,
120122
uint64_t Size);
@@ -276,6 +278,10 @@ uint64_t __llvm_profile_get_num_counters(const char *Begin, const char *End);
276278
/*! \brief Get the size of the profile counters section in bytes. */
277279
uint64_t __llvm_profile_get_counters_size(const char *Begin, const char *End);
278280

281+
/*! \brief Get the number of bytes in the profile bitmap section. */
282+
uint64_t __llvm_profile_get_num_bitmap_bytes(const char *Begin,
283+
const char *End);
284+
279285
/* ! \brief Given the sizes of the data and counter information, return the
280286
* number of padding bytes before and after the counters, and after the names,
281287
* in the raw profile.
@@ -286,8 +292,9 @@ uint64_t __llvm_profile_get_counters_size(const char *Begin, const char *End);
286292
* needed to achieve that.
287293
*/
288294
void __llvm_profile_get_padding_sizes_for_counters(
289-
uint64_t DataSize, uint64_t CountersSize, uint64_t NamesSize,
290-
uint64_t *PaddingBytesBeforeCounters, uint64_t *PaddingBytesAfterCounters,
295+
uint64_t DataSize, uint64_t CountersSize, uint64_t NumBitmapBytes,
296+
uint64_t NamesSize, uint64_t *PaddingBytesBeforeCounters,
297+
uint64_t *PaddingBytesAfterCounters, uint64_t *PaddingBytesAfterBitmap,
291298
uint64_t *PaddingBytesAfterNames);
292299

293300
/*!

compiler-rt/lib/profile/InstrProfilingBuffer.c

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,14 @@ uint64_t __llvm_profile_get_size_for_buffer(void) {
4343
const __llvm_profile_data *DataEnd = __llvm_profile_end_data();
4444
const char *CountersBegin = __llvm_profile_begin_counters();
4545
const char *CountersEnd = __llvm_profile_end_counters();
46+
const char *BitmapBegin = __llvm_profile_begin_bitmap();
47+
const char *BitmapEnd = __llvm_profile_end_bitmap();
4648
const char *NamesBegin = __llvm_profile_begin_names();
4749
const char *NamesEnd = __llvm_profile_end_names();
4850

4951
return __llvm_profile_get_size_for_buffer_internal(
50-
DataBegin, DataEnd, CountersBegin, CountersEnd, NamesBegin, NamesEnd);
52+
DataBegin, DataEnd, CountersBegin, CountersEnd, BitmapBegin, BitmapEnd,
53+
NamesBegin, NamesEnd);
5154
}
5255

5356
COMPILER_RT_VISIBILITY
@@ -83,6 +86,12 @@ uint64_t __llvm_profile_get_counters_size(const char *Begin, const char *End) {
8386
__llvm_profile_counter_entry_size();
8487
}
8588

89+
COMPILER_RT_VISIBILITY
90+
uint64_t __llvm_profile_get_num_bitmap_bytes(const char *Begin,
91+
const char *End) {
92+
return (End - Begin);
93+
}
94+
8695
/// Calculate the number of padding bytes needed to add to \p Offset in order
8796
/// for (\p Offset + Padding) to be page-aligned.
8897
static uint64_t calculateBytesNeededToPageAlign(uint64_t Offset) {
@@ -102,13 +111,16 @@ static int needsCounterPadding(void) {
102111

103112
COMPILER_RT_VISIBILITY
104113
void __llvm_profile_get_padding_sizes_for_counters(
105-
uint64_t DataSize, uint64_t CountersSize, uint64_t NamesSize,
106-
uint64_t *PaddingBytesBeforeCounters, uint64_t *PaddingBytesAfterCounters,
114+
uint64_t DataSize, uint64_t CountersSize, uint64_t NumBitmapBytes,
115+
uint64_t NamesSize, uint64_t *PaddingBytesBeforeCounters,
116+
uint64_t *PaddingBytesAfterCounters, uint64_t *PaddingBytesAfterBitmapBytes,
107117
uint64_t *PaddingBytesAfterNames) {
108118
if (!needsCounterPadding()) {
109119
*PaddingBytesBeforeCounters = 0;
110120
*PaddingBytesAfterCounters =
111121
__llvm_profile_get_num_padding_bytes(CountersSize);
122+
*PaddingBytesAfterBitmapBytes =
123+
__llvm_profile_get_num_padding_bytes(NumBitmapBytes);
112124
*PaddingBytesAfterNames = __llvm_profile_get_num_padding_bytes(NamesSize);
113125
return;
114126
}
@@ -118,31 +130,37 @@ void __llvm_profile_get_padding_sizes_for_counters(
118130
*PaddingBytesBeforeCounters =
119131
calculateBytesNeededToPageAlign(sizeof(__llvm_profile_header) + DataSize);
120132
*PaddingBytesAfterCounters = calculateBytesNeededToPageAlign(CountersSize);
133+
*PaddingBytesAfterBitmapBytes =
134+
calculateBytesNeededToPageAlign(NumBitmapBytes);
121135
*PaddingBytesAfterNames = calculateBytesNeededToPageAlign(NamesSize);
122136
}
123137

124138
COMPILER_RT_VISIBILITY
125139
uint64_t __llvm_profile_get_size_for_buffer_internal(
126140
const __llvm_profile_data *DataBegin, const __llvm_profile_data *DataEnd,
127-
const char *CountersBegin, const char *CountersEnd, const char *NamesBegin,
128-
const char *NamesEnd) {
141+
const char *CountersBegin, const char *CountersEnd, const char *BitmapBegin,
142+
const char *BitmapEnd, const char *NamesBegin, const char *NamesEnd) {
129143
/* Match logic in __llvm_profile_write_buffer(). */
130144
const uint64_t NamesSize = (NamesEnd - NamesBegin) * sizeof(char);
131145
uint64_t DataSize = __llvm_profile_get_data_size(DataBegin, DataEnd);
132146
uint64_t CountersSize =
133147
__llvm_profile_get_counters_size(CountersBegin, CountersEnd);
148+
const uint64_t NumBitmapBytes =
149+
__llvm_profile_get_num_bitmap_bytes(BitmapBegin, BitmapEnd);
134150

135151
/* Determine how much padding is needed before/after the counters and after
136152
* the names. */
137153
uint64_t PaddingBytesBeforeCounters, PaddingBytesAfterCounters,
138-
PaddingBytesAfterNames;
154+
PaddingBytesAfterNames, PaddingBytesAfterBitmapBytes;
139155
__llvm_profile_get_padding_sizes_for_counters(
140-
DataSize, CountersSize, NamesSize, &PaddingBytesBeforeCounters,
141-
&PaddingBytesAfterCounters, &PaddingBytesAfterNames);
156+
DataSize, CountersSize, NumBitmapBytes, NamesSize,
157+
&PaddingBytesBeforeCounters, &PaddingBytesAfterCounters,
158+
&PaddingBytesAfterBitmapBytes, &PaddingBytesAfterNames);
142159

143160
return sizeof(__llvm_profile_header) + __llvm_write_binary_ids(NULL) +
144161
DataSize + PaddingBytesBeforeCounters + CountersSize +
145-
PaddingBytesAfterCounters + NamesSize + PaddingBytesAfterNames;
162+
PaddingBytesAfterCounters + NumBitmapBytes +
163+
PaddingBytesAfterBitmapBytes + NamesSize + PaddingBytesAfterNames;
146164
}
147165

148166
COMPILER_RT_VISIBILITY
@@ -160,9 +178,11 @@ COMPILER_RT_VISIBILITY int __llvm_profile_write_buffer(char *Buffer) {
160178
COMPILER_RT_VISIBILITY int __llvm_profile_write_buffer_internal(
161179
char *Buffer, const __llvm_profile_data *DataBegin,
162180
const __llvm_profile_data *DataEnd, const char *CountersBegin,
163-
const char *CountersEnd, const char *NamesBegin, const char *NamesEnd) {
181+
const char *CountersEnd, const char *BitmapBegin, const char *BitmapEnd,
182+
const char *NamesBegin, const char *NamesEnd) {
164183
ProfDataWriter BufferWriter;
165184
initBufferWriter(&BufferWriter, Buffer);
166185
return lprofWriteDataImpl(&BufferWriter, DataBegin, DataEnd, CountersBegin,
167-
CountersEnd, 0, NamesBegin, NamesEnd, 0);
186+
CountersEnd, BitmapBegin, BitmapEnd, 0, NamesBegin,
187+
NamesEnd, 0);
168188
}

compiler-rt/lib/profile/InstrProfilingFile.c

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,21 +108,30 @@ static int mmapForContinuousMode(uint64_t CurrentFileOffset, FILE *File) {
108108
const __llvm_profile_data *DataEnd = __llvm_profile_end_data();
109109
const char *CountersBegin = __llvm_profile_begin_counters();
110110
const char *CountersEnd = __llvm_profile_end_counters();
111+
const char *BitmapBegin = __llvm_profile_begin_bitmap();
112+
const char *BitmapEnd = __llvm_profile_end_bitmap();
111113
const char *NamesBegin = __llvm_profile_begin_names();
112114
const char *NamesEnd = __llvm_profile_end_names();
113115
const uint64_t NamesSize = (NamesEnd - NamesBegin) * sizeof(char);
114116
uint64_t DataSize = __llvm_profile_get_data_size(DataBegin, DataEnd);
115117
uint64_t CountersSize =
116118
__llvm_profile_get_counters_size(CountersBegin, CountersEnd);
119+
uint64_t NumBitmapBytes =
120+
__llvm_profile_get_num_bitmap_bytes(BitmapBegin, BitmapEnd);
117121

118-
/* Check that the counter and data sections in this image are
122+
/* Check that the counter, bitmap, and data sections in this image are
119123
* page-aligned. */
120124
unsigned PageSize = getpagesize();
121125
if ((intptr_t)CountersBegin % PageSize != 0) {
122126
PROF_ERR("Counters section not page-aligned (start = %p, pagesz = %u).\n",
123127
CountersBegin, PageSize);
124128
return 1;
125129
}
130+
if ((intptr_t)BitmapBegin % PageSize != 0) {
131+
PROF_ERR("Bitmap section not page-aligned (start = %p, pagesz = %u).\n",
132+
BitmapBegin, PageSize);
133+
return 1;
134+
}
126135
if ((intptr_t)DataBegin % PageSize != 0) {
127136
PROF_ERR("Data section not page-aligned (start = %p, pagesz = %u).\n",
128137
DataBegin, PageSize);
@@ -132,10 +141,11 @@ static int mmapForContinuousMode(uint64_t CurrentFileOffset, FILE *File) {
132141
/* Determine how much padding is needed before/after the counters and
133142
* after the names. */
134143
uint64_t PaddingBytesBeforeCounters, PaddingBytesAfterCounters,
135-
PaddingBytesAfterNames;
144+
PaddingBytesAfterNames, PaddingBytesAfterBitmapBytes;
136145
__llvm_profile_get_padding_sizes_for_counters(
137-
DataSize, CountersSize, NamesSize, &PaddingBytesBeforeCounters,
138-
&PaddingBytesAfterCounters, &PaddingBytesAfterNames);
146+
DataSize, CountersSize, NumBitmapBytes, NamesSize,
147+
&PaddingBytesBeforeCounters, &PaddingBytesAfterCounters,
148+
&PaddingBytesAfterBitmapBytes, &PaddingBytesAfterNames);
139149

140150
uint64_t PageAlignedCountersLength = CountersSize + PaddingBytesAfterCounters;
141151
uint64_t FileOffsetToCounters = CurrentFileOffset +
@@ -155,6 +165,31 @@ static int mmapForContinuousMode(uint64_t CurrentFileOffset, FILE *File) {
155165
FileOffsetToCounters);
156166
return 1;
157167
}
168+
169+
/* Also mmap MCDC bitmap bytes. If there aren't any bitmap bytes, mmap()
170+
* will fail with EINVAL. */
171+
if (NumBitmapBytes == 0)
172+
return 0;
173+
174+
uint64_t PageAlignedBitmapLength =
175+
NumBitmapBytes + PaddingBytesAfterBitmapBytes;
176+
uint64_t FileOffsetToBitmap =
177+
CurrentFileOffset + sizeof(__llvm_profile_header) + DataSize +
178+
PaddingBytesBeforeCounters + CountersSize + PaddingBytesAfterCounters;
179+
void *BitmapMmap =
180+
mmap((void *)BitmapBegin, PageAlignedBitmapLength, PROT_READ | PROT_WRITE,
181+
MAP_FIXED | MAP_SHARED, Fileno, FileOffsetToBitmap);
182+
if (BitmapMmap != BitmapBegin) {
183+
PROF_ERR(
184+
"Continuous counter sync mode is enabled, but mmap() failed (%s).\n"
185+
" - BitmapBegin: %p\n"
186+
" - PageAlignedBitmapLength: %" PRIu64 "\n"
187+
" - Fileno: %d\n"
188+
" - FileOffsetToBitmap: %" PRIu64 "\n",
189+
strerror(errno), BitmapBegin, PageAlignedBitmapLength, Fileno,
190+
FileOffsetToBitmap);
191+
return 1;
192+
}
158193
return 0;
159194
}
160195
#elif defined(__ELF__) || defined(_WIN32)
@@ -197,6 +232,8 @@ static int mmapForContinuousMode(uint64_t CurrentFileOffset, FILE *File) {
197232
const __llvm_profile_data *DataEnd = __llvm_profile_end_data();
198233
const char *CountersBegin = __llvm_profile_begin_counters();
199234
const char *CountersEnd = __llvm_profile_end_counters();
235+
const char *BitmapBegin = __llvm_profile_begin_bitmap();
236+
const char *BitmapEnd = __llvm_profile_end_bitmap();
200237
uint64_t DataSize = __llvm_profile_get_data_size(DataBegin, DataEnd);
201238
/* Get the file size. */
202239
uint64_t FileSize = 0;
@@ -218,6 +255,11 @@ static int mmapForContinuousMode(uint64_t CurrentFileOffset, FILE *File) {
218255

219256
/* Return the memory allocated for counters to OS. */
220257
lprofReleaseMemoryPagesToOS((uintptr_t)CountersBegin, (uintptr_t)CountersEnd);
258+
259+
/* BIAS MODE not supported yet for Bitmap (MCDC). */
260+
261+
/* Return the memory allocated for counters to OS. */
262+
lprofReleaseMemoryPagesToOS((uintptr_t)BitmapBegin, (uintptr_t)BitmapEnd);
221263
return 0;
222264
}
223265
#else

0 commit comments

Comments
 (0)