-
Notifications
You must be signed in to change notification settings - Fork 13.3k
[MC/DC][Coverage] Enable profile correlation for MC/DC #136437
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
When using the `-fcoverage-mcdc` option in profile correlation mode MC/DC coverage is not actually collected. In binary profile correlation mode this completes elements of a vector of per-function profile data structures called `Data` with BitmapPtr and NumBitmapBytes values that are taken from profile data section in the same way as it is done for Counters. In debug info correlation mode this adds new `Profile Bitmap Type` DIEs to DWARFContext. These entries contain FunctionName and NumBitmapBits for functions. They are used by `correlateProfileDataImpl()` function to obtain BitmapPtr and NumBitmapBytes values to complete the corresponding elements of the vector of per-function profile data structures called `Data`. Creating and reading these new DIEs occur in the same way as it is done for DIEs of the type `Profile Data Type`. Fixes llvm#97385
Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be notified. If you wish to, you can add reviewers by using the "Reviewers" section on this page. If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers. If you have further questions, they may be answered by the LLVM GitHub User Guide. You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums. |
@llvm/pr-subscribers-pgo @llvm/pr-subscribers-llvm-transforms Author: Roman Beliaev (belyaevrd) ChangesWhen using the In binary profile correlation mode this completes elements of a vector of per-function profile data structures called In debug info correlation mode this adds new Fixes #97385 Patch is 27.95 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/136437.diff 8 Files Affected:
diff --git a/compiler-rt/lib/profile/InstrProfilingWriter.c b/compiler-rt/lib/profile/InstrProfilingWriter.c
index 633fdb9661162..4d453bc8d74b4 100644
--- a/compiler-rt/lib/profile/InstrProfilingWriter.c
+++ b/compiler-rt/lib/profile/InstrProfilingWriter.c
@@ -320,6 +320,7 @@ COMPILER_RT_VISIBILITY int lprofWriteDataImpl(
/* The data and names sections are omitted in lightweight mode. */
if (NumData == 0 && NamesSize == 0) {
Header.CountersDelta = 0;
+ Header.BitmapDelta = 0;
Header.NamesDelta = 0;
}
diff --git a/compiler-rt/test/profile/Inputs/instrprof-mcdc-correlation.cpp b/compiler-rt/test/profile/Inputs/instrprof-mcdc-correlation.cpp
new file mode 100644
index 0000000000000..acc63f0375cbd
--- /dev/null
+++ b/compiler-rt/test/profile/Inputs/instrprof-mcdc-correlation.cpp
@@ -0,0 +1,14 @@
+void test(bool a, bool b, bool c, bool d) {
+ if ((a && b) || (c && d))
+ ;
+ if (b && c)
+ ;
+}
+
+int main() {
+ test(true, true, true, true);
+ test(true, true, false, true);
+ test(true, false, true, true);
+ (void)0;
+ return 0;
+}
diff --git a/compiler-rt/test/profile/instrprof-mcdc-correlation.c b/compiler-rt/test/profile/instrprof-mcdc-correlation.c
new file mode 100644
index 0000000000000..e915f27c7b80a
--- /dev/null
+++ b/compiler-rt/test/profile/instrprof-mcdc-correlation.c
@@ -0,0 +1,21 @@
+// REQUIRES: linux || windows
+// Default
+// RUN: %clang -o %t.normal -fprofile-instr-generate -fcoverage-mapping -fcoverage-mcdc %S/Inputs/instrprof-mcdc-correlation.cpp
+// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t.normal
+// RUN: llvm-profdata merge -o %t.normal.profdata %t.profraw
+// RUN: llvm-profdata show --all-functions --counts --text %t.normal.profdata > %t.normal.profdata.show
+
+// With -profile-correlate=binary flag
+// RUN: %clang -o %t-1.exe -fprofile-instr-generate -fcoverage-mapping -fcoverage-mcdc -mllvm -profile-correlate=binary %S/Inputs/instrprof-mcdc-correlation.cpp
+// RUN: env LLVM_PROFILE_FILE=%t-1.profraw %run %t-1.exe
+// RUN: llvm-profdata merge -o %t-1.profdata --binary-file=%t-1.exe %t-1.profraw
+// RUN: llvm-profdata show --all-functions --counts --text %t-1.profdata > %t-1.profdata.show
+
+// With -profile-correlate=debug-info flag
+// RUN: %clang -o %t-2.exe -fprofile-instr-generate -fcoverage-mapping -fcoverage-mcdc -mllvm -profile-correlate=debug-info -g %S/Inputs/instrprof-mcdc-correlation.cpp
+// RUN: env LLVM_PROFILE_FILE=%t-2.profraw %run %t-2.exe
+// RUN: llvm-profdata merge -o %t-2.profdata --debug-info=%t-2.exe %t-2.profraw
+// RUN: llvm-profdata show --all-functions --counts --text %t-2.profdata > %t-2.profdata.show
+
+// RUN: diff %t.normal.profdata.show %t-1.profdata.show
+// RUN: diff %t.normal.profdata.show %t-2.profdata.show
diff --git a/llvm/include/llvm/ProfileData/InstrProfCorrelator.h b/llvm/include/llvm/ProfileData/InstrProfCorrelator.h
index ed8642495cd74..1c800ae22cd3c 100644
--- a/llvm/include/llvm/ProfileData/InstrProfCorrelator.h
+++ b/llvm/include/llvm/ProfileData/InstrProfCorrelator.h
@@ -68,6 +68,7 @@ class InstrProfCorrelator {
static const char *FunctionNameAttributeName;
static const char *CFGHashAttributeName;
static const char *NumCountersAttributeName;
+ static const char *NumBitmapBitsAttributeName;
enum InstrProfCorrelatorKind { CK_32Bit, CK_64Bit };
InstrProfCorrelatorKind getKind() const { return Kind; }
@@ -82,6 +83,9 @@ class InstrProfCorrelator {
/// The address range of the __llvm_prf_cnts section.
uint64_t CountersSectionStart;
uint64_t CountersSectionEnd;
+ /// The address range of the __llvm_prf_bits section.
+ uint64_t BitmapSectionStart;
+ uint64_t BitmapSectionEnd;
/// The pointer points to start/end of profile data/name sections if
/// FileKind is Binary.
const char *DataStart;
@@ -104,7 +108,9 @@ class InstrProfCorrelator {
std::optional<std::string> LinkageName;
yaml::Hex64 CFGHash;
yaml::Hex64 CounterOffset;
+ yaml::Hex64 BitmapOffset;
uint32_t NumCounters;
+ uint32_t NumBitmapBytes;
std::optional<std::string> FilePath;
std::optional<int> LineNumber;
};
@@ -158,8 +164,9 @@ class InstrProfCorrelatorImpl : public InstrProfCorrelator {
Error dumpYaml(int MaxWarnings, raw_ostream &OS) override;
void addDataProbe(uint64_t FunctionName, uint64_t CFGHash,
- IntPtrT CounterOffset, IntPtrT FunctionPtr,
- uint32_t NumCounters);
+ IntPtrT CounterOffset, IntPtrT BitmapOffset,
+ IntPtrT FunctionPtr, uint32_t NumCounters,
+ uint32_t NumBitmapBytes);
// Byte-swap the value if necessary.
template <class T> T maybeSwap(T Value) const {
@@ -171,6 +178,7 @@ class InstrProfCorrelatorImpl : public InstrProfCorrelator {
std::unique_ptr<InstrProfCorrelator::Context> Ctx)
: InstrProfCorrelator(Kind, std::move(Ctx)){};
llvm::DenseSet<IntPtrT> CounterOffsets;
+ llvm::DenseSet<IntPtrT> BitmapOffsets;
};
/// DwarfInstrProfCorrelator - A child of InstrProfCorrelatorImpl that takes
@@ -190,8 +198,8 @@ class DwarfInstrProfCorrelator : public InstrProfCorrelatorImpl<IntPtrT> {
std::optional<uint64_t> getLocation(const DWARFDie &Die) const;
/// Returns true if the provided DIE symbolizes an instrumentation probe
- /// symbol.
- static bool isDIEOfProbe(const DWARFDie &Die);
+ /// symbol of the necessary type.
+ static bool isDIEOfProbe(const DWARFDie &Die, const StringRef &Prefix);
/// Iterate over DWARF DIEs to find those that symbolize instrumentation
/// probes and construct the ProfileData vector and Names string.
diff --git a/llvm/include/llvm/ProfileData/InstrProfReader.h b/llvm/include/llvm/ProfileData/InstrProfReader.h
index f1010b312ee56..02f49d08cf29d 100644
--- a/llvm/include/llvm/ProfileData/InstrProfReader.h
+++ b/llvm/include/llvm/ProfileData/InstrProfReader.h
@@ -470,7 +470,8 @@ class RawInstrProfReader : public InstrProfReader {
bool atEnd() const { return Data == DataEnd; }
void advanceData() {
- // `CountersDelta` is a constant zero when using debug info correlation.
+ // `CountersDelta` and `BitmapDelta` are constant zero when using debug info
+ // correlation.
if (!Correlator && !BIDFetcherCorrelator) {
// The initial CountersDelta is the in-memory address difference between
// the data and counts sections:
diff --git a/llvm/lib/ProfileData/InstrProfCorrelator.cpp b/llvm/lib/ProfileData/InstrProfCorrelator.cpp
index d92107f93dc56..7d6d320f92b16 100644
--- a/llvm/lib/ProfileData/InstrProfCorrelator.cpp
+++ b/llvm/lib/ProfileData/InstrProfCorrelator.cpp
@@ -51,6 +51,7 @@ Expected<object::SectionRef> getInstrProfSection(const object::ObjectFile &Obj,
const char *InstrProfCorrelator::FunctionNameAttributeName = "Function Name";
const char *InstrProfCorrelator::CFGHashAttributeName = "CFG Hash";
const char *InstrProfCorrelator::NumCountersAttributeName = "Num Counters";
+const char *InstrProfCorrelator::NumBitmapBitsAttributeName = "Num BitmapBits";
llvm::Expected<std::unique_ptr<InstrProfCorrelator::Context>>
InstrProfCorrelator::Context::get(std::unique_ptr<MemoryBuffer> Buffer,
@@ -81,6 +82,17 @@ InstrProfCorrelator::Context::get(std::unique_ptr<MemoryBuffer> Buffer,
C->Buffer = std::move(Buffer);
C->CountersSectionStart = CountersSection->getAddress();
C->CountersSectionEnd = C->CountersSectionStart + CountersSection->getSize();
+
+ auto BitmapSection = getInstrProfSection(Obj, IPSK_bitmap);
+ if (auto E = BitmapSection.takeError()) {
+ // It is not an error if NumBitmapBytes of each function is zero.
+ consumeError(std::move(E));
+ C->BitmapSectionStart = 0;
+ C->BitmapSectionEnd = 0;
+ } else {
+ C->BitmapSectionStart = BitmapSection->getAddress();
+ C->BitmapSectionEnd = C->BitmapSectionStart + BitmapSection->getSize();
+ }
// In COFF object file, there's a null byte at the beginning of the counter
// section which doesn't exist in raw profile.
if (Obj.getTripleObjectFormat() == Triple::COFF)
@@ -236,6 +248,7 @@ Error InstrProfCorrelatorImpl<IntPtrT>::correlateProfileData(int MaxWarnings) {
"could not find any profile data metadata in correlated file");
Error Result = correlateProfileNameImpl();
this->CounterOffsets.clear();
+ this->BitmapOffsets.clear();
this->NamesVec.clear();
return Result;
}
@@ -253,7 +266,9 @@ template <> struct yaml::MappingTraits<InstrProfCorrelator::Probe> {
io.mapOptional("Linkage Name", P.LinkageName);
io.mapRequired("CFG Hash", P.CFGHash);
io.mapRequired("Counter Offset", P.CounterOffset);
+ io.mapRequired("Bitmap Offset", P.BitmapOffset);
io.mapRequired("Num Counters", P.NumCounters);
+ io.mapRequired("Num BitmapBytes", P.NumBitmapBytes);
io.mapOptional("File", P.FilePath);
io.mapOptional("Line", P.LineNumber);
}
@@ -281,8 +296,10 @@ template <class IntPtrT>
void InstrProfCorrelatorImpl<IntPtrT>::addDataProbe(uint64_t NameRef,
uint64_t CFGHash,
IntPtrT CounterOffset,
+ IntPtrT BitmapOffset,
IntPtrT FunctionPtr,
- uint32_t NumCounters) {
+ uint32_t NumCounters,
+ uint32_t NumBitmapBytes) {
// Check if a probe was already added for this counter offset.
if (!CounterOffsets.insert(CounterOffset).second)
return;
@@ -292,15 +309,13 @@ void InstrProfCorrelatorImpl<IntPtrT>::addDataProbe(uint64_t NameRef,
// In this mode, CounterPtr actually stores the section relative address
// of the counter.
maybeSwap<IntPtrT>(CounterOffset),
- // TODO: MC/DC is not yet supported.
- /*BitmapOffset=*/maybeSwap<IntPtrT>(0),
+ maybeSwap<IntPtrT>(BitmapOffset),
maybeSwap<IntPtrT>(FunctionPtr),
// TODO: Value profiling is not yet supported.
/*ValuesPtr=*/maybeSwap<IntPtrT>(0),
maybeSwap<uint32_t>(NumCounters),
/*NumValueSites=*/{maybeSwap<uint16_t>(0), maybeSwap<uint16_t>(0)},
- // TODO: MC/DC is not yet supported.
- /*NumBitmapBytes=*/maybeSwap<uint32_t>(0),
+ maybeSwap<uint32_t>(NumBitmapBytes),
});
}
@@ -331,7 +346,8 @@ DwarfInstrProfCorrelator<IntPtrT>::getLocation(const DWARFDie &Die) const {
}
template <class IntPtrT>
-bool DwarfInstrProfCorrelator<IntPtrT>::isDIEOfProbe(const DWARFDie &Die) {
+bool DwarfInstrProfCorrelator<IntPtrT>::isDIEOfProbe(const DWARFDie &Die,
+ const StringRef &Prefix) {
const auto &ParentDie = Die.getParent();
if (!Die.isValid() || !ParentDie.isValid() || Die.isNULL())
return false;
@@ -342,106 +358,199 @@ bool DwarfInstrProfCorrelator<IntPtrT>::isDIEOfProbe(const DWARFDie &Die) {
if (!Die.hasChildren())
return false;
if (const char *Name = Die.getName(DINameKind::ShortName))
- return StringRef(Name).starts_with(getInstrProfCountersVarPrefix());
+ return StringRef(Name).starts_with(Prefix);
return false;
}
template <class IntPtrT>
void DwarfInstrProfCorrelator<IntPtrT>::correlateProfileDataImpl(
int MaxWarnings, InstrProfCorrelator::CorrelationData *Data) {
+ using RawProfData = RawInstrProf::ProfileData<IntPtrT>;
bool UnlimitedWarnings = (MaxWarnings == 0);
// -N suppressed warnings means we can emit up to N (unsuppressed) warnings
int NumSuppressedWarnings = -MaxWarnings;
- auto maybeAddProbe = [&](DWARFDie Die) {
- if (!isDIEOfProbe(Die))
+ auto maybeAddProbe = [&](DWARFDie Die, const StringRef &Prefix) {
+ if (!isDIEOfProbe(Die, Prefix))
return;
- std::optional<const char *> FunctionName;
- std::optional<uint64_t> CFGHash;
- std::optional<uint64_t> CounterPtr = getLocation(Die);
- auto FnDie = Die.getParent();
- auto FunctionPtr = dwarf::toAddress(FnDie.find(dwarf::DW_AT_low_pc));
- std::optional<uint64_t> NumCounters;
- for (const DWARFDie &Child : Die.children()) {
- if (Child.getTag() != dwarf::DW_TAG_LLVM_annotation)
- continue;
- auto AnnotationFormName = Child.find(dwarf::DW_AT_name);
- auto AnnotationFormValue = Child.find(dwarf::DW_AT_const_value);
- if (!AnnotationFormName || !AnnotationFormValue)
- continue;
- auto AnnotationNameOrErr = AnnotationFormName->getAsCString();
- if (auto Err = AnnotationNameOrErr.takeError()) {
- consumeError(std::move(Err));
- continue;
+ if (Prefix == getInstrProfCountersVarPrefix()) {
+ std::optional<const char *> FunctionName;
+ std::optional<uint64_t> CFGHash;
+ std::optional<uint64_t> CounterPtr = getLocation(Die);
+ auto FnDie = Die.getParent();
+ auto FunctionPtr = dwarf::toAddress(FnDie.find(dwarf::DW_AT_low_pc));
+ std::optional<uint64_t> NumCounters;
+ for (const DWARFDie &Child : Die.children()) {
+ if (Child.getTag() != dwarf::DW_TAG_LLVM_annotation)
+ continue;
+ auto AnnotationFormName = Child.find(dwarf::DW_AT_name);
+ auto AnnotationFormValue = Child.find(dwarf::DW_AT_const_value);
+ if (!AnnotationFormName || !AnnotationFormValue)
+ continue;
+ auto AnnotationNameOrErr = AnnotationFormName->getAsCString();
+ if (auto Err = AnnotationNameOrErr.takeError()) {
+ consumeError(std::move(Err));
+ continue;
+ }
+ StringRef AnnotationName = *AnnotationNameOrErr;
+ if (AnnotationName == InstrProfCorrelator::FunctionNameAttributeName) {
+ if (auto EC =
+ AnnotationFormValue->getAsCString().moveInto(FunctionName))
+ consumeError(std::move(EC));
+ } else if (AnnotationName ==
+ InstrProfCorrelator::CFGHashAttributeName) {
+ CFGHash = AnnotationFormValue->getAsUnsignedConstant();
+ } else if (AnnotationName ==
+ InstrProfCorrelator::NumCountersAttributeName) {
+ NumCounters = AnnotationFormValue->getAsUnsignedConstant();
+ }
}
- StringRef AnnotationName = *AnnotationNameOrErr;
- if (AnnotationName == InstrProfCorrelator::FunctionNameAttributeName) {
- if (auto EC =
- AnnotationFormValue->getAsCString().moveInto(FunctionName))
- consumeError(std::move(EC));
- } else if (AnnotationName == InstrProfCorrelator::CFGHashAttributeName) {
- CFGHash = AnnotationFormValue->getAsUnsignedConstant();
- } else if (AnnotationName ==
- InstrProfCorrelator::NumCountersAttributeName) {
- NumCounters = AnnotationFormValue->getAsUnsignedConstant();
+ if (!FunctionName || !CFGHash || !CounterPtr || !NumCounters) {
+ if (UnlimitedWarnings || ++NumSuppressedWarnings < 1) {
+ WithColor::warning()
+ << "Incomplete DIE for function " << FunctionName
+ << ": CFGHash=" << CFGHash << " CounterPtr=" << CounterPtr
+ << " NumCounters=" << NumCounters << "\n";
+ LLVM_DEBUG(Die.dump(dbgs()));
+ }
+ return;
}
- }
- if (!FunctionName || !CFGHash || !CounterPtr || !NumCounters) {
- if (UnlimitedWarnings || ++NumSuppressedWarnings < 1) {
- WithColor::warning()
- << "Incomplete DIE for function " << FunctionName
- << ": CFGHash=" << CFGHash << " CounterPtr=" << CounterPtr
- << " NumCounters=" << NumCounters << "\n";
- LLVM_DEBUG(Die.dump(dbgs()));
+ uint64_t CountersStart = this->Ctx->CountersSectionStart;
+ uint64_t CountersEnd = this->Ctx->CountersSectionEnd;
+ if (*CounterPtr < CountersStart || *CounterPtr >= CountersEnd) {
+ if (UnlimitedWarnings || ++NumSuppressedWarnings < 1) {
+ WithColor::warning()
+ << format("CounterPtr out of range for function %s: Actual=0x%x "
+ "Expected=[0x%x, 0x%x)\n",
+ *FunctionName, *CounterPtr, CountersStart, CountersEnd);
+ LLVM_DEBUG(Die.dump(dbgs()));
+ }
+ return;
}
- return;
- }
- uint64_t CountersStart = this->Ctx->CountersSectionStart;
- uint64_t CountersEnd = this->Ctx->CountersSectionEnd;
- if (*CounterPtr < CountersStart || *CounterPtr >= CountersEnd) {
- if (UnlimitedWarnings || ++NumSuppressedWarnings < 1) {
+ if (!FunctionPtr && (UnlimitedWarnings || ++NumSuppressedWarnings < 1)) {
WithColor::warning()
- << format("CounterPtr out of range for function %s: Actual=0x%x "
- "Expected=[0x%x, 0x%x)\n",
- *FunctionName, *CounterPtr, CountersStart, CountersEnd);
+ << format("Could not find address of function %s\n", *FunctionName);
LLVM_DEBUG(Die.dump(dbgs()));
}
- return;
- }
- if (!FunctionPtr && (UnlimitedWarnings || ++NumSuppressedWarnings < 1)) {
- WithColor::warning() << format("Could not find address of function %s\n",
- *FunctionName);
- LLVM_DEBUG(Die.dump(dbgs()));
- }
- // In debug info correlation mode, the CounterPtr is an absolute address of
- // the counter, but it's expected to be relative later when iterating Data.
- IntPtrT CounterOffset = *CounterPtr - CountersStart;
- if (Data) {
- InstrProfCorrelator::Probe P;
- P.FunctionName = *FunctionName;
- if (auto Name = FnDie.getName(DINameKind::LinkageName))
- P.LinkageName = Name;
- P.CFGHash = *CFGHash;
- P.CounterOffset = CounterOffset;
- P.NumCounters = *NumCounters;
- auto FilePath = FnDie.getDeclFile(
- DILineInfoSpecifier::FileLineInfoKind::RelativeFilePath);
- if (!FilePath.empty())
- P.FilePath = FilePath;
- if (auto LineNumber = FnDie.getDeclLine())
- P.LineNumber = LineNumber;
- Data->Probes.push_back(P);
- } else {
- this->addDataProbe(IndexedInstrProf::ComputeHash(*FunctionName), *CFGHash,
- CounterOffset, FunctionPtr.value_or(0), *NumCounters);
- this->NamesVec.push_back(*FunctionName);
+ // In debug info correlation mode, the CounterPtr is an absolute address
+ // of the counter, but it's expected to be relative later when iterating
+ // Data.
+ IntPtrT CounterOffset = *CounterPtr - CountersStart;
+ if (Data) {
+ InstrProfCorrelator::Probe P;
+ P.FunctionName = *FunctionName;
+ if (auto Name = FnDie.getName(DINameKind::LinkageName))
+ P.LinkageName = Name;
+ P.CFGHash = *CFGHash;
+ P.CounterOffset = CounterOffset;
+ P.NumCounters = *NumCounters;
+ auto FilePath = FnDie.getDeclFile(
+ DILineInfoSpecifier::FileLineInfoKind::RelativeFilePath);
+ if (!FilePath.empty())
+ P.FilePath = FilePath;
+ if (auto LineNumber = FnDie.getDeclLine())
+ P.LineNumber = LineNumber;
+ Data->Probes.push_back(P);
+ } else {
+ this->addDataProbe(IndexedInstrProf::ComputeHash(*FunctionName),
+ *CFGHash, CounterOffset, 0, FunctionPtr.value_or(0),
+ *NumCounters, 0);
+ this->NamesVec.push_back(*FunctionName);
+ }
+ } else if (Prefix == getInstrProfBitmapVarPrefix()) {
+ std::optional<const char *> FunctionName;
+ std::optional<uint64_t> BitmapPtr = getLocation(Die);
+ uint64_t NumBitmapBytes;
+ for (const DWARFDie &Child : Die.children()) {
+ if (Child.getTag() != dwarf::DW_TAG_LLVM_annotation)
+ continue;
+ auto AnnotationFormName = Child.find(dwarf::DW_AT_name);
+ auto AnnotationFormValue = Child.find(dwarf::DW_AT_const_value);
+ if (!AnnotationFormName || !AnnotationFormValue)
+ continue;
+ auto AnnotationNameOrErr = AnnotationFormName->getAsCString();
+ if (auto Err = AnnotationNameOrErr.takeError()) {
+ consumeError(std::move(Err));
+ continue;
+ }
+ StringRef AnnotationName = *AnnotationNameOrErr;
+ if (AnnotationName == InstrProfCorrelator::FunctionNameAttributeName) {
+ if (auto EC =
+ AnnotationFormValue->getAsCString().moveInto(Fu...
[truncated]
|
Hello -- thank you for implementing this! I can review, if you like, but it would probably also be good to include @ellishg as well. |
When using the
-fcoverage-mcdc
option in profile correlation mode MC/DC coverage is not actually collected.In binary profile correlation mode this completes elements of a vector of per-function profile data structures called
Data
with BitmapPtr and NumBitmapBytes values that are taken from profile data section in the same way as it is done for Counters.In debug info correlation mode this adds new
Profile Bitmap Type
DIEs to DWARFContext. These entries contain FunctionName and NumBitmapBits for functions. They are used bycorrelateProfileDataImpl()
function to obtain BitmapPtr and NumBitmapBytes values to complete the corresponding elements of the vector of per-function profile data structures calledData
. Creating and reading these new DIEs occur in the same way as it is done for DIEs of the typeProfile Data Type
.Fixes #97385