[compiler-rt] [llvm] [MC/DC][Coverage] Enable profile correlation for MC/DC (PR #136437)
Ellis Hoag via llvm-commits
llvm-commits at lists.llvm.org
Fri May 1 11:31:32 PDT 2026
================
@@ -361,102 +377,223 @@ 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) {
- 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))
- 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;
- }
- 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();
- }
+void DwarfInstrProfCorrelator<IntPtrT>::addCountersToDataProbe(
+ InstrProfCorrelator::CorrelationData *Data, const DWARFDie &Die,
+ const bool UnlimitedWarnings, int &NumSuppressedWarnings) {
+ using RawProfData = RawInstrProf::ProfileData<IntPtrT>;
+ 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 there is no function and no counter, assume it was dead-stripped
- if (!FunctionPtr && !CounterPtr)
- 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()));
+ 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 there is no function and no counter, assume it was dead-stripped
+ if (!FunctionPtr && !CounterPtr)
+ 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()));
+ }
+ return;
+ }
+ 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;
+ }
+ 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 (const char *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;
+ // Try to find appropriate probe.
+ for (InstrProfCorrelator::Probe &Probe : Data->Probes) {
+ if (Probe.FunctionName == *FunctionName) {
+ Probe.LinkageName = P.LinkageName;
+ Probe.CFGHash = P.CFGHash;
+ Probe.CounterOffset = P.CounterOffset;
+ Probe.NumCounters = P.NumCounters;
+ Probe.FilePath = P.FilePath;
+ Probe.LineNumber = P.LineNumber;
+ return;
}
- return;
}
----------------
ellishg wrote:
This is new. Can you elaborate on why we are searching for a probe with the same name? This might need to be a separate PR since it impact all debug info correlation, not just MC/DC. Also, if we really need to search existing probes, we should consider using a map from function name to probe.
https://github.com/llvm/llvm-project/pull/136437
More information about the llvm-commits
mailing list