aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/ProfileData/InstrProfCorrelator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/ProfileData/InstrProfCorrelator.cpp')
-rw-r--r--llvm/lib/ProfileData/InstrProfCorrelator.cpp165
1 files changed, 105 insertions, 60 deletions
diff --git a/llvm/lib/ProfileData/InstrProfCorrelator.cpp b/llvm/lib/ProfileData/InstrProfCorrelator.cpp
index c822d81f8bef..24d828f69c71 100644
--- a/llvm/lib/ProfileData/InstrProfCorrelator.cpp
+++ b/llvm/lib/ProfileData/InstrProfCorrelator.cpp
@@ -16,21 +16,28 @@
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
#include "llvm/Object/MachO.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/WithColor.h"
#include <optional>
#define DEBUG_TYPE "correlator"
using namespace llvm;
-/// Get the __llvm_prf_cnts section.
-Expected<object::SectionRef> getCountersSection(const object::ObjectFile &Obj) {
+/// Get profile section.
+Expected<object::SectionRef> getInstrProfSection(const object::ObjectFile &Obj,
+ InstrProfSectKind IPSK) {
+ Triple::ObjectFormatType ObjFormat = Obj.getTripleObjectFormat();
+ std::string ExpectedSectionName =
+ getInstrProfSectionName(IPSK, ObjFormat,
+ /*AddSegmentInfo=*/false);
for (auto &Section : Obj.sections())
if (auto SectionName = Section.getName())
- if (SectionName.get() == INSTR_PROF_CNTS_SECT_NAME)
+ if (SectionName.get() == ExpectedSectionName)
return Section;
return make_error<InstrProfError>(
instrprof_error::unable_to_correlate_profile,
- "could not find counter section (" INSTR_PROF_CNTS_SECT_NAME ")");
+ "could not find section (" + Twine(ExpectedSectionName) + ")");
}
const char *InstrProfCorrelator::FunctionNameAttributeName = "Function Name";
@@ -40,7 +47,7 @@ const char *InstrProfCorrelator::NumCountersAttributeName = "Num Counters";
llvm::Expected<std::unique_ptr<InstrProfCorrelator::Context>>
InstrProfCorrelator::Context::get(std::unique_ptr<MemoryBuffer> Buffer,
const object::ObjectFile &Obj) {
- auto CountersSection = getCountersSection(Obj);
+ auto CountersSection = getInstrProfSection(Obj, IPSK_cnts);
if (auto Err = CountersSection.takeError())
return std::move(Err);
auto C = std::make_unique<Context>();
@@ -52,30 +59,35 @@ InstrProfCorrelator::Context::get(std::unique_ptr<MemoryBuffer> Buffer,
}
llvm::Expected<std::unique_ptr<InstrProfCorrelator>>
-InstrProfCorrelator::get(StringRef DebugInfoFilename) {
- auto DsymObjectsOrErr =
- object::MachOObjectFile::findDsymObjectMembers(DebugInfoFilename);
- if (auto Err = DsymObjectsOrErr.takeError())
- return std::move(Err);
- if (!DsymObjectsOrErr->empty()) {
- // TODO: Enable profile correlation when there are multiple objects in a
- // dSYM bundle.
- if (DsymObjectsOrErr->size() > 1)
- return make_error<InstrProfError>(
- instrprof_error::unable_to_correlate_profile,
- "using multiple objects is not yet supported");
- DebugInfoFilename = *DsymObjectsOrErr->begin();
- }
- auto BufferOrErr =
- errorOrToExpected(MemoryBuffer::getFile(DebugInfoFilename));
- if (auto Err = BufferOrErr.takeError())
- return std::move(Err);
+InstrProfCorrelator::get(StringRef Filename, ProfCorrelatorKind FileKind) {
+ if (FileKind == DEBUG_INFO) {
+ auto DsymObjectsOrErr =
+ object::MachOObjectFile::findDsymObjectMembers(Filename);
+ if (auto Err = DsymObjectsOrErr.takeError())
+ return std::move(Err);
+ if (!DsymObjectsOrErr->empty()) {
+ // TODO: Enable profile correlation when there are multiple objects in a
+ // dSYM bundle.
+ if (DsymObjectsOrErr->size() > 1)
+ return make_error<InstrProfError>(
+ instrprof_error::unable_to_correlate_profile,
+ "using multiple objects is not yet supported");
+ Filename = *DsymObjectsOrErr->begin();
+ }
+ auto BufferOrErr = errorOrToExpected(MemoryBuffer::getFile(Filename));
+ if (auto Err = BufferOrErr.takeError())
+ return std::move(Err);
- return get(std::move(*BufferOrErr));
+ return get(std::move(*BufferOrErr), FileKind);
+ }
+ return make_error<InstrProfError>(
+ instrprof_error::unable_to_correlate_profile,
+ "unsupported correlation kind (only DWARF debug info is supported)");
}
llvm::Expected<std::unique_ptr<InstrProfCorrelator>>
-InstrProfCorrelator::get(std::unique_ptr<MemoryBuffer> Buffer) {
+InstrProfCorrelator::get(std::unique_ptr<MemoryBuffer> Buffer,
+ ProfCorrelatorKind FileKind) {
auto BinOrErr = object::createBinary(*Buffer);
if (auto Err = BinOrErr.takeError())
return std::move(Err);
@@ -86,9 +98,11 @@ InstrProfCorrelator::get(std::unique_ptr<MemoryBuffer> Buffer) {
return std::move(Err);
auto T = Obj->makeTriple();
if (T.isArch64Bit())
- return InstrProfCorrelatorImpl<uint64_t>::get(std::move(*CtxOrErr), *Obj);
+ return InstrProfCorrelatorImpl<uint64_t>::get(std::move(*CtxOrErr), *Obj,
+ FileKind);
if (T.isArch32Bit())
- return InstrProfCorrelatorImpl<uint32_t>::get(std::move(*CtxOrErr), *Obj);
+ return InstrProfCorrelatorImpl<uint32_t>::get(std::move(*CtxOrErr), *Obj,
+ FileKind);
}
return make_error<InstrProfError>(
instrprof_error::unable_to_correlate_profile, "not an object file");
@@ -130,29 +144,33 @@ template <class IntPtrT>
llvm::Expected<std::unique_ptr<InstrProfCorrelatorImpl<IntPtrT>>>
InstrProfCorrelatorImpl<IntPtrT>::get(
std::unique_ptr<InstrProfCorrelator::Context> Ctx,
- const object::ObjectFile &Obj) {
- if (Obj.isELF() || Obj.isMachO()) {
- auto DICtx = DWARFContext::create(Obj);
- return std::make_unique<DwarfInstrProfCorrelator<IntPtrT>>(std::move(DICtx),
- std::move(Ctx));
+ const object::ObjectFile &Obj, ProfCorrelatorKind FileKind) {
+ if (FileKind == DEBUG_INFO) {
+ if (Obj.isELF() || Obj.isMachO()) {
+ auto DICtx = DWARFContext::create(Obj);
+ return std::make_unique<DwarfInstrProfCorrelator<IntPtrT>>(
+ std::move(DICtx), std::move(Ctx));
+ }
+ return make_error<InstrProfError>(
+ instrprof_error::unable_to_correlate_profile,
+ "unsupported debug info format (only DWARF is supported)");
}
return make_error<InstrProfError>(
instrprof_error::unable_to_correlate_profile,
- "unsupported debug info format (only DWARF is supported)");
+ "unsupported correlation file type (only DWARF is supported)");
}
template <class IntPtrT>
-Error InstrProfCorrelatorImpl<IntPtrT>::correlateProfileData() {
+Error InstrProfCorrelatorImpl<IntPtrT>::correlateProfileData(int MaxWarnings) {
assert(Data.empty() && Names.empty() && NamesVec.empty());
- correlateProfileDataImpl();
- if (Data.empty() || NamesVec.empty())
+ correlateProfileDataImpl(MaxWarnings);
+ if (this->Data.empty())
return make_error<InstrProfError>(
instrprof_error::unable_to_correlate_profile,
- "could not find any profile metadata in debug info");
- auto Result =
- collectPGOFuncNameStrings(NamesVec, /*doCompression=*/false, Names);
- CounterOffsets.clear();
- NamesVec.clear();
+ "could not find any profile data metadata in correlated file");
+ Error Result = correlateProfileNameImpl();
+ this->CounterOffsets.clear();
+ this->NamesVec.clear();
return Result;
}
@@ -180,13 +198,14 @@ template <> struct yaml::SequenceElementTraits<InstrProfCorrelator::Probe> {
};
template <class IntPtrT>
-Error InstrProfCorrelatorImpl<IntPtrT>::dumpYaml(raw_ostream &OS) {
+Error InstrProfCorrelatorImpl<IntPtrT>::dumpYaml(int MaxWarnings,
+ raw_ostream &OS) {
InstrProfCorrelator::CorrelationData Data;
- correlateProfileDataImpl(&Data);
+ correlateProfileDataImpl(MaxWarnings, &Data);
if (Data.Probes.empty())
return make_error<InstrProfError>(
instrprof_error::unable_to_correlate_profile,
- "could not find any profile metadata in debug info");
+ "could not find any profile data metadata in debug info");
yaml::Output YamlOS(OS);
YamlOS << Data;
return Error::success();
@@ -207,11 +226,15 @@ void InstrProfCorrelatorImpl<IntPtrT>::addProbe(StringRef FunctionName,
// 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>(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),
});
NamesVec.push_back(FunctionName.str());
}
@@ -260,7 +283,10 @@ bool DwarfInstrProfCorrelator<IntPtrT>::isDIEOfProbe(const DWARFDie &Die) {
template <class IntPtrT>
void DwarfInstrProfCorrelator<IntPtrT>::correlateProfileDataImpl(
- InstrProfCorrelator::CorrelationData *Data) {
+ 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;
@@ -297,28 +323,30 @@ void DwarfInstrProfCorrelator<IntPtrT>::correlateProfileDataImpl(
}
}
if (!FunctionName || !CFGHash || !CounterPtr || !NumCounters) {
- LLVM_DEBUG(dbgs() << "Incomplete DIE for probe\n\tFunctionName: "
- << FunctionName << "\n\tCFGHash: " << CFGHash
- << "\n\tCounterPtr: " << CounterPtr
- << "\n\tNumCounters: " << NumCounters);
- LLVM_DEBUG(Die.dump(dbgs()));
+ 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) {
- LLVM_DEBUG(
- dbgs() << "CounterPtr out of range for probe\n\tFunction Name: "
- << FunctionName << "\n\tExpected: [0x"
- << Twine::utohexstr(CountersStart) << ", 0x"
- << Twine::utohexstr(CountersEnd) << ")\n\tActual: 0x"
- << Twine::utohexstr(*CounterPtr));
- LLVM_DEBUG(Die.dump(dbgs()));
+ 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) {
- LLVM_DEBUG(dbgs() << "Could not find address of " << *FunctionName
- << "\n");
+ if (!FunctionPtr && (UnlimitedWarnings || ++NumSuppressedWarnings < 1)) {
+ WithColor::warning() << format("Could not find address of function %s\n",
+ *FunctionName);
LLVM_DEBUG(Die.dump(dbgs()));
}
IntPtrT CounterOffset = *CounterPtr - CountersStart;
@@ -348,4 +376,21 @@ void DwarfInstrProfCorrelator<IntPtrT>::correlateProfileDataImpl(
for (auto &CU : DICtx->dwo_units())
for (const auto &Entry : CU->dies())
maybeAddProbe(DWARFDie(CU.get(), &Entry));
+
+ if (!UnlimitedWarnings && NumSuppressedWarnings > 0)
+ WithColor::warning() << format("Suppressed %d additional warnings\n",
+ NumSuppressedWarnings);
+}
+
+template <class IntPtrT>
+Error DwarfInstrProfCorrelator<IntPtrT>::correlateProfileNameImpl() {
+ if (this->NamesVec.empty()) {
+ return make_error<InstrProfError>(
+ instrprof_error::unable_to_correlate_profile,
+ "could not find any profile name metadata in debug info");
+ }
+ auto Result =
+ collectGlobalObjectNameStrings(this->NamesVec,
+ /*doCompression=*/false, this->Names);
+ return Result;
}