Skip to content

Commit

Permalink
Reland "[InstrProf][compiler-rt] Enable MC/DC Support in LLVM Source-…
Browse files Browse the repository at this point in the history
…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
  • Loading branch information
evodius96 committed Oct 30, 2023
1 parent dc8c2a7 commit f95b2f1
Show file tree
Hide file tree
Showing 52 changed files with 1,441 additions and 174 deletions.
4 changes: 2 additions & 2 deletions clang/lib/Driver/ToolChains/Darwin.cpp
Expand Up @@ -1400,7 +1400,7 @@ void Darwin::addProfileRTLibs(const ArgList &Args,
addExportedSymbol(CmdArgs, "_reset_fn_list");
}

// Align __llvm_prf_{cnts,data} sections to the maximum expected page
// Align __llvm_prf_{cnts,bits,data} sections to the maximum expected page
// alignment. This allows profile counters to be mmap()'d to disk. Note that
// it's not enough to just page-align __llvm_prf_cnts: the following section
// must also be page-aligned so that its data is not clobbered by mmap().
Expand All @@ -1410,7 +1410,7 @@ void Darwin::addProfileRTLibs(const ArgList &Args,
// extra alignment also allows the same binary to be used with/without sync
// enabled.
if (!ForGCOV) {
for (auto IPSK : {llvm::IPSK_cnts, llvm::IPSK_data}) {
for (auto IPSK : {llvm::IPSK_cnts, llvm::IPSK_bitmap, llvm::IPSK_data}) {
addSectalignToPage(
Args, CmdArgs, "__DATA",
llvm::getInstrProfSectionName(IPSK, llvm::Triple::MachO,
Expand Down
2 changes: 1 addition & 1 deletion clang/test/Driver/darwin-ld.c
Expand Up @@ -336,7 +336,7 @@
// RUN: FileCheck -check-prefix=PROFILE_SECTALIGN %s < %t.log
// RUN: %clang -target arm64-apple-ios12 -fprofile-instr-generate -### %t.o 2> %t.log
// RUN: FileCheck -check-prefix=PROFILE_SECTALIGN %s < %t.log
// PROFILE_SECTALIGN: "-sectalign" "__DATA" "__llvm_prf_cnts" "0x4000" "-sectalign" "__DATA" "__llvm_prf_data" "0x4000"
// PROFILE_SECTALIGN: "-sectalign" "__DATA" "__llvm_prf_cnts" "0x4000" "-sectalign" "__DATA" "__llvm_prf_bits" "0x4000" "-sectalign" "__DATA" "__llvm_prf_data" "0x4000"

// RUN: %clang -target x86_64-apple-darwin12 -fprofile-instr-generate --coverage -### %t.o 2> %t.log
// RUN: FileCheck -check-prefix=NO_PROFILE_EXPORT %s < %t.log
Expand Down
22 changes: 18 additions & 4 deletions compiler-rt/include/profile/InstrProfData.inc
Expand Up @@ -76,6 +76,7 @@ INSTR_PROF_DATA(const uint64_t, llvm::Type::getInt64Ty(Ctx), FuncHash, \
ConstantInt::get(llvm::Type::getInt64Ty(Ctx), \
Inc->getHash()->getZExtValue()))
INSTR_PROF_DATA(const IntPtrT, IntPtrTy, CounterPtr, RelativeCounterPtr)
INSTR_PROF_DATA(const IntPtrT, IntPtrTy, BitmapPtr, RelativeBitmapPtr)
/* This is used to map function pointers for the indirect call targets to
* function name hashes during the conversion from raw to merged profile
* data.
Expand All @@ -87,7 +88,9 @@ INSTR_PROF_DATA(IntPtrT, llvm::Type::getInt8PtrTy(Ctx), Values, \
INSTR_PROF_DATA(const uint32_t, llvm::Type::getInt32Ty(Ctx), NumCounters, \
ConstantInt::get(llvm::Type::getInt32Ty(Ctx), NumCounters))
INSTR_PROF_DATA(const uint16_t, Int16ArrayTy, NumValueSites[IPVK_Last+1], \
ConstantArray::get(Int16ArrayTy, Int16ArrayVals))
ConstantArray::get(Int16ArrayTy, Int16ArrayVals)) \
INSTR_PROF_DATA(const uint32_t, llvm::Type::getInt32Ty(Ctx), NumBitmapBytes, \
ConstantInt::get(llvm::Type::getInt32Ty(Ctx), NumBitmapBytes))
#undef INSTR_PROF_DATA
/* INSTR_PROF_DATA end. */

Expand Down Expand Up @@ -132,9 +135,13 @@ INSTR_PROF_RAW_HEADER(uint64_t, NumData, NumData)
INSTR_PROF_RAW_HEADER(uint64_t, PaddingBytesBeforeCounters, PaddingBytesBeforeCounters)
INSTR_PROF_RAW_HEADER(uint64_t, NumCounters, NumCounters)
INSTR_PROF_RAW_HEADER(uint64_t, PaddingBytesAfterCounters, PaddingBytesAfterCounters)
INSTR_PROF_RAW_HEADER(uint64_t, NumBitmapBytes, NumBitmapBytes)
INSTR_PROF_RAW_HEADER(uint64_t, PaddingBytesAfterBitmapBytes, PaddingBytesAfterBitmapBytes)
INSTR_PROF_RAW_HEADER(uint64_t, NamesSize, NamesSize)
INSTR_PROF_RAW_HEADER(uint64_t, CountersDelta,
(uintptr_t)CountersBegin - (uintptr_t)DataBegin)
INSTR_PROF_RAW_HEADER(uint64_t, BitmapDelta,
(uintptr_t)BitmapBegin - (uintptr_t)DataBegin)
INSTR_PROF_RAW_HEADER(uint64_t, NamesDelta, (uintptr_t)NamesBegin)
INSTR_PROF_RAW_HEADER(uint64_t, ValueKindLast, IPVK_Last)
#undef INSTR_PROF_RAW_HEADER
Expand Down Expand Up @@ -267,6 +274,9 @@ INSTR_PROF_SECT_ENTRY(IPSK_data, \
INSTR_PROF_SECT_ENTRY(IPSK_cnts, \
INSTR_PROF_QUOTE(INSTR_PROF_CNTS_COMMON), \
INSTR_PROF_CNTS_COFF, "__DATA,")
INSTR_PROF_SECT_ENTRY(IPSK_bitmap, \
INSTR_PROF_QUOTE(INSTR_PROF_BITS_COMMON), \
INSTR_PROF_BITS_COFF, "__DATA,")
INSTR_PROF_SECT_ENTRY(IPSK_name, \
INSTR_PROF_QUOTE(INSTR_PROF_NAME_COMMON), \
INSTR_PROF_NAME_COFF, "__DATA,")
Expand Down Expand Up @@ -645,11 +655,11 @@ serializeValueProfDataFrom(ValueProfRecordClosure *Closure,
(uint64_t)'f' << 16 | (uint64_t)'R' << 8 | (uint64_t)129

/* Raw profile format version (start from 1). */
#define INSTR_PROF_RAW_VERSION 8
#define INSTR_PROF_RAW_VERSION 9
/* Indexed profile format version (start from 1). */
#define INSTR_PROF_INDEX_VERSION 10
#define INSTR_PROF_INDEX_VERSION 11
/* Coverage mapping format version (start from 0). */
#define INSTR_PROF_COVMAP_VERSION 5
#define INSTR_PROF_COVMAP_VERSION 6

/* Profile version is always of type uint64_t. Reserve the upper 32 bits in the
* version for other variants of profile. We set the 8th most significant bit
Expand Down Expand Up @@ -686,6 +696,7 @@ serializeValueProfDataFrom(ValueProfRecordClosure *Closure,
#define INSTR_PROF_DATA_COMMON __llvm_prf_data
#define INSTR_PROF_NAME_COMMON __llvm_prf_names
#define INSTR_PROF_CNTS_COMMON __llvm_prf_cnts
#define INSTR_PROF_BITS_COMMON __llvm_prf_bits
#define INSTR_PROF_VALS_COMMON __llvm_prf_vals
#define INSTR_PROF_VNODES_COMMON __llvm_prf_vnds
#define INSTR_PROF_COVMAP_COMMON __llvm_covmap
Expand All @@ -697,6 +708,7 @@ serializeValueProfDataFrom(ValueProfRecordClosure *Closure,
#define INSTR_PROF_DATA_COFF ".lprfd$M"
#define INSTR_PROF_NAME_COFF ".lprfn$M"
#define INSTR_PROF_CNTS_COFF ".lprfc$M"
#define INSTR_PROF_BITS_COFF ".lprfb$M"
#define INSTR_PROF_VALS_COFF ".lprfv$M"
#define INSTR_PROF_VNODES_COFF ".lprfnd$M"
#define INSTR_PROF_COVMAP_COFF ".lcovmap$M"
Expand All @@ -708,6 +720,7 @@ serializeValueProfDataFrom(ValueProfRecordClosure *Closure,
#define INSTR_PROF_DATA_SECT_NAME INSTR_PROF_DATA_COFF
#define INSTR_PROF_NAME_SECT_NAME INSTR_PROF_NAME_COFF
#define INSTR_PROF_CNTS_SECT_NAME INSTR_PROF_CNTS_COFF
#define INSTR_PROF_BITS_SECT_NAME INSTR_PROF_BITS_COFF
/* Array of pointers. Each pointer points to a list
* of value nodes associated with one value site.
*/
Expand All @@ -722,6 +735,7 @@ serializeValueProfDataFrom(ValueProfRecordClosure *Closure,
#define INSTR_PROF_DATA_SECT_NAME INSTR_PROF_QUOTE(INSTR_PROF_DATA_COMMON)
#define INSTR_PROF_NAME_SECT_NAME INSTR_PROF_QUOTE(INSTR_PROF_NAME_COMMON)
#define INSTR_PROF_CNTS_SECT_NAME INSTR_PROF_QUOTE(INSTR_PROF_CNTS_COMMON)
#define INSTR_PROF_BITS_SECT_NAME INSTR_PROF_QUOTE(INSTR_PROF_BITS_COMMON)
/* Array of pointers. Each pointer points to a list
* of value nodes associated with one value site.
*/
Expand Down
4 changes: 4 additions & 0 deletions compiler-rt/lib/profile/InstrProfiling.c
Expand Up @@ -60,6 +60,10 @@ COMPILER_RT_VISIBILITY void __llvm_profile_reset_counters(void) {
(__llvm_profile_get_version() & VARIANT_MASK_BYTE_COVERAGE) ? 0xFF : 0;
memset(I, ResetValue, E - I);

I = __llvm_profile_begin_bitmap();
E = __llvm_profile_end_bitmap();
memset(I, 0x0, E - I);

const __llvm_profile_data *DataBegin = __llvm_profile_begin_data();
const __llvm_profile_data *DataEnd = __llvm_profile_end_data();
const __llvm_profile_data *DI;
Expand Down
25 changes: 16 additions & 9 deletions compiler-rt/lib/profile/InstrProfiling.h
Expand Up @@ -88,6 +88,8 @@ const char *__llvm_profile_begin_names(void);
const char *__llvm_profile_end_names(void);
char *__llvm_profile_begin_counters(void);
char *__llvm_profile_end_counters(void);
char *__llvm_profile_begin_bitmap(void);
char *__llvm_profile_end_bitmap(void);
ValueProfNode *__llvm_profile_begin_vnodes();
ValueProfNode *__llvm_profile_end_vnodes();
uint32_t *__llvm_profile_begin_orderfile();
Expand All @@ -101,20 +103,20 @@ void __llvm_profile_reset_counters(void);
/*!
* \brief Merge profile data from buffer.
*
* Read profile data form buffer \p Profile and merge with in-process profile
* counters. The client is expected to have checked or already knows the profile
* data in the buffer matches the in-process counter structure before calling
* it. Returns 0 (success) if the profile data is valid. Upon reading
* invalid/corrupted profile data, returns 1 (failure).
* Read profile data from buffer \p Profile and merge with in-process profile
* counters and bitmaps. The client is expected to have checked or already
* know the profile data in the buffer matches the in-process counter
* structure before calling it. Returns 0 (success) if the profile data is
* valid. Upon reading invalid/corrupted profile data, returns 1 (failure).
*/
int __llvm_profile_merge_from_buffer(const char *Profile, uint64_t Size);

/*! \brief Check if profile in buffer matches the current binary.
*
* Returns 0 (success) if the profile data in buffer \p Profile with size
* \p Size was generated by the same binary and therefore matches
* structurally the in-process counters. If the profile data in buffer is
* not compatible, the interface returns 1 (failure).
* structurally the in-process counters and bitmaps. If the profile data in
* buffer is not compatible, the interface returns 1 (failure).
*/
int __llvm_profile_check_compatibility(const char *Profile,
uint64_t Size);
Expand Down Expand Up @@ -276,6 +278,10 @@ uint64_t __llvm_profile_get_num_counters(const char *Begin, const char *End);
/*! \brief Get the size of the profile counters section in bytes. */
uint64_t __llvm_profile_get_counters_size(const char *Begin, const char *End);

/*! \brief Get the number of bytes in the profile bitmap section. */
uint64_t __llvm_profile_get_num_bitmap_bytes(const char *Begin,
const char *End);

/* ! \brief Given the sizes of the data and counter information, return the
* number of padding bytes before and after the counters, and after the names,
* in the raw profile.
Expand All @@ -286,8 +292,9 @@ uint64_t __llvm_profile_get_counters_size(const char *Begin, const char *End);
* needed to achieve that.
*/
void __llvm_profile_get_padding_sizes_for_counters(
uint64_t DataSize, uint64_t CountersSize, uint64_t NamesSize,
uint64_t *PaddingBytesBeforeCounters, uint64_t *PaddingBytesAfterCounters,
uint64_t DataSize, uint64_t CountersSize, uint64_t NumBitmapBytes,
uint64_t NamesSize, uint64_t *PaddingBytesBeforeCounters,
uint64_t *PaddingBytesAfterCounters, uint64_t *PaddingBytesAfterBitmap,
uint64_t *PaddingBytesAfterNames);

/*!
Expand Down
42 changes: 31 additions & 11 deletions compiler-rt/lib/profile/InstrProfilingBuffer.c
Expand Up @@ -43,11 +43,14 @@ uint64_t __llvm_profile_get_size_for_buffer(void) {
const __llvm_profile_data *DataEnd = __llvm_profile_end_data();
const char *CountersBegin = __llvm_profile_begin_counters();
const char *CountersEnd = __llvm_profile_end_counters();
const char *BitmapBegin = __llvm_profile_begin_bitmap();
const char *BitmapEnd = __llvm_profile_end_bitmap();
const char *NamesBegin = __llvm_profile_begin_names();
const char *NamesEnd = __llvm_profile_end_names();

return __llvm_profile_get_size_for_buffer_internal(
DataBegin, DataEnd, CountersBegin, CountersEnd, NamesBegin, NamesEnd);
DataBegin, DataEnd, CountersBegin, CountersEnd, BitmapBegin, BitmapEnd,
NamesBegin, NamesEnd);
}

COMPILER_RT_VISIBILITY
Expand Down Expand Up @@ -83,6 +86,12 @@ uint64_t __llvm_profile_get_counters_size(const char *Begin, const char *End) {
__llvm_profile_counter_entry_size();
}

COMPILER_RT_VISIBILITY
uint64_t __llvm_profile_get_num_bitmap_bytes(const char *Begin,
const char *End) {
return (End - Begin);
}

/// Calculate the number of padding bytes needed to add to \p Offset in order
/// for (\p Offset + Padding) to be page-aligned.
static uint64_t calculateBytesNeededToPageAlign(uint64_t Offset) {
Expand All @@ -102,13 +111,16 @@ static int needsCounterPadding(void) {

COMPILER_RT_VISIBILITY
void __llvm_profile_get_padding_sizes_for_counters(
uint64_t DataSize, uint64_t CountersSize, uint64_t NamesSize,
uint64_t *PaddingBytesBeforeCounters, uint64_t *PaddingBytesAfterCounters,
uint64_t DataSize, uint64_t CountersSize, uint64_t NumBitmapBytes,
uint64_t NamesSize, uint64_t *PaddingBytesBeforeCounters,
uint64_t *PaddingBytesAfterCounters, uint64_t *PaddingBytesAfterBitmapBytes,
uint64_t *PaddingBytesAfterNames) {
if (!needsCounterPadding()) {
*PaddingBytesBeforeCounters = 0;
*PaddingBytesAfterCounters =
__llvm_profile_get_num_padding_bytes(CountersSize);
*PaddingBytesAfterBitmapBytes =
__llvm_profile_get_num_padding_bytes(NumBitmapBytes);
*PaddingBytesAfterNames = __llvm_profile_get_num_padding_bytes(NamesSize);
return;
}
Expand All @@ -118,31 +130,37 @@ void __llvm_profile_get_padding_sizes_for_counters(
*PaddingBytesBeforeCounters =
calculateBytesNeededToPageAlign(sizeof(__llvm_profile_header) + DataSize);
*PaddingBytesAfterCounters = calculateBytesNeededToPageAlign(CountersSize);
*PaddingBytesAfterBitmapBytes =
calculateBytesNeededToPageAlign(NumBitmapBytes);
*PaddingBytesAfterNames = calculateBytesNeededToPageAlign(NamesSize);
}

COMPILER_RT_VISIBILITY
uint64_t __llvm_profile_get_size_for_buffer_internal(
const __llvm_profile_data *DataBegin, const __llvm_profile_data *DataEnd,
const char *CountersBegin, const char *CountersEnd, const char *NamesBegin,
const char *NamesEnd) {
const char *CountersBegin, const char *CountersEnd, const char *BitmapBegin,
const char *BitmapEnd, const char *NamesBegin, const char *NamesEnd) {
/* Match logic in __llvm_profile_write_buffer(). */
const uint64_t NamesSize = (NamesEnd - NamesBegin) * sizeof(char);
uint64_t DataSize = __llvm_profile_get_data_size(DataBegin, DataEnd);
uint64_t CountersSize =
__llvm_profile_get_counters_size(CountersBegin, CountersEnd);
const uint64_t NumBitmapBytes =
__llvm_profile_get_num_bitmap_bytes(BitmapBegin, BitmapEnd);

/* Determine how much padding is needed before/after the counters and after
* the names. */
uint64_t PaddingBytesBeforeCounters, PaddingBytesAfterCounters,
PaddingBytesAfterNames;
PaddingBytesAfterNames, PaddingBytesAfterBitmapBytes;
__llvm_profile_get_padding_sizes_for_counters(
DataSize, CountersSize, NamesSize, &PaddingBytesBeforeCounters,
&PaddingBytesAfterCounters, &PaddingBytesAfterNames);
DataSize, CountersSize, NumBitmapBytes, NamesSize,
&PaddingBytesBeforeCounters, &PaddingBytesAfterCounters,
&PaddingBytesAfterBitmapBytes, &PaddingBytesAfterNames);

return sizeof(__llvm_profile_header) + __llvm_write_binary_ids(NULL) +
DataSize + PaddingBytesBeforeCounters + CountersSize +
PaddingBytesAfterCounters + NamesSize + PaddingBytesAfterNames;
PaddingBytesAfterCounters + NumBitmapBytes +
PaddingBytesAfterBitmapBytes + NamesSize + PaddingBytesAfterNames;
}

COMPILER_RT_VISIBILITY
Expand All @@ -160,9 +178,11 @@ COMPILER_RT_VISIBILITY int __llvm_profile_write_buffer(char *Buffer) {
COMPILER_RT_VISIBILITY int __llvm_profile_write_buffer_internal(
char *Buffer, const __llvm_profile_data *DataBegin,
const __llvm_profile_data *DataEnd, const char *CountersBegin,
const char *CountersEnd, const char *NamesBegin, const char *NamesEnd) {
const char *CountersEnd, const char *BitmapBegin, const char *BitmapEnd,
const char *NamesBegin, const char *NamesEnd) {
ProfDataWriter BufferWriter;
initBufferWriter(&BufferWriter, Buffer);
return lprofWriteDataImpl(&BufferWriter, DataBegin, DataEnd, CountersBegin,
CountersEnd, 0, NamesBegin, NamesEnd, 0);
CountersEnd, BitmapBegin, BitmapEnd, 0, NamesBegin,
NamesEnd, 0);
}
50 changes: 46 additions & 4 deletions compiler-rt/lib/profile/InstrProfilingFile.c
Expand Up @@ -108,21 +108,30 @@ static int mmapForContinuousMode(uint64_t CurrentFileOffset, FILE *File) {
const __llvm_profile_data *DataEnd = __llvm_profile_end_data();
const char *CountersBegin = __llvm_profile_begin_counters();
const char *CountersEnd = __llvm_profile_end_counters();
const char *BitmapBegin = __llvm_profile_begin_bitmap();
const char *BitmapEnd = __llvm_profile_end_bitmap();
const char *NamesBegin = __llvm_profile_begin_names();
const char *NamesEnd = __llvm_profile_end_names();
const uint64_t NamesSize = (NamesEnd - NamesBegin) * sizeof(char);
uint64_t DataSize = __llvm_profile_get_data_size(DataBegin, DataEnd);
uint64_t CountersSize =
__llvm_profile_get_counters_size(CountersBegin, CountersEnd);
uint64_t NumBitmapBytes =
__llvm_profile_get_num_bitmap_bytes(BitmapBegin, BitmapEnd);

/* Check that the counter and data sections in this image are
/* Check that the counter, bitmap, and data sections in this image are
* page-aligned. */
unsigned PageSize = getpagesize();
if ((intptr_t)CountersBegin % PageSize != 0) {
PROF_ERR("Counters section not page-aligned (start = %p, pagesz = %u).\n",
CountersBegin, PageSize);
return 1;
}
if ((intptr_t)BitmapBegin % PageSize != 0) {
PROF_ERR("Bitmap section not page-aligned (start = %p, pagesz = %u).\n",
BitmapBegin, PageSize);
return 1;
}
if ((intptr_t)DataBegin % PageSize != 0) {
PROF_ERR("Data section not page-aligned (start = %p, pagesz = %u).\n",
DataBegin, PageSize);
Expand All @@ -132,10 +141,11 @@ static int mmapForContinuousMode(uint64_t CurrentFileOffset, FILE *File) {
/* Determine how much padding is needed before/after the counters and
* after the names. */
uint64_t PaddingBytesBeforeCounters, PaddingBytesAfterCounters,
PaddingBytesAfterNames;
PaddingBytesAfterNames, PaddingBytesAfterBitmapBytes;
__llvm_profile_get_padding_sizes_for_counters(
DataSize, CountersSize, NamesSize, &PaddingBytesBeforeCounters,
&PaddingBytesAfterCounters, &PaddingBytesAfterNames);
DataSize, CountersSize, NumBitmapBytes, NamesSize,
&PaddingBytesBeforeCounters, &PaddingBytesAfterCounters,
&PaddingBytesAfterBitmapBytes, &PaddingBytesAfterNames);

uint64_t PageAlignedCountersLength = CountersSize + PaddingBytesAfterCounters;
uint64_t FileOffsetToCounters = CurrentFileOffset +
Expand All @@ -155,6 +165,31 @@ static int mmapForContinuousMode(uint64_t CurrentFileOffset, FILE *File) {
FileOffsetToCounters);
return 1;
}

/* Also mmap MCDC bitmap bytes. If there aren't any bitmap bytes, mmap()
* will fail with EINVAL. */
if (NumBitmapBytes == 0)
return 0;

uint64_t PageAlignedBitmapLength =
NumBitmapBytes + PaddingBytesAfterBitmapBytes;
uint64_t FileOffsetToBitmap =
CurrentFileOffset + sizeof(__llvm_profile_header) + DataSize +
PaddingBytesBeforeCounters + CountersSize + PaddingBytesAfterCounters;
void *BitmapMmap =
mmap((void *)BitmapBegin, PageAlignedBitmapLength, PROT_READ | PROT_WRITE,
MAP_FIXED | MAP_SHARED, Fileno, FileOffsetToBitmap);
if (BitmapMmap != BitmapBegin) {
PROF_ERR(
"Continuous counter sync mode is enabled, but mmap() failed (%s).\n"
" - BitmapBegin: %p\n"
" - PageAlignedBitmapLength: %" PRIu64 "\n"
" - Fileno: %d\n"
" - FileOffsetToBitmap: %" PRIu64 "\n",
strerror(errno), BitmapBegin, PageAlignedBitmapLength, Fileno,
FileOffsetToBitmap);
return 1;
}
return 0;
}
#elif defined(__ELF__) || defined(_WIN32)
Expand Down Expand Up @@ -197,6 +232,8 @@ static int mmapForContinuousMode(uint64_t CurrentFileOffset, FILE *File) {
const __llvm_profile_data *DataEnd = __llvm_profile_end_data();
const char *CountersBegin = __llvm_profile_begin_counters();
const char *CountersEnd = __llvm_profile_end_counters();
const char *BitmapBegin = __llvm_profile_begin_bitmap();
const char *BitmapEnd = __llvm_profile_end_bitmap();
uint64_t DataSize = __llvm_profile_get_data_size(DataBegin, DataEnd);
/* Get the file size. */
uint64_t FileSize = 0;
Expand All @@ -218,6 +255,11 @@ static int mmapForContinuousMode(uint64_t CurrentFileOffset, FILE *File) {

/* Return the memory allocated for counters to OS. */
lprofReleaseMemoryPagesToOS((uintptr_t)CountersBegin, (uintptr_t)CountersEnd);

/* BIAS MODE not supported yet for Bitmap (MCDC). */

/* Return the memory allocated for counters to OS. */
lprofReleaseMemoryPagesToOS((uintptr_t)BitmapBegin, (uintptr_t)BitmapEnd);
return 0;
}
#else
Expand Down

0 comments on commit f95b2f1

Please sign in to comment.