summaryrefslogtreecommitdiffstats
path: root/llvm/lib/ProfileData/SampleProfReader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/ProfileData/SampleProfReader.cpp')
-rw-r--r--llvm/lib/ProfileData/SampleProfReader.cpp102
1 files changed, 81 insertions, 21 deletions
diff --git a/llvm/lib/ProfileData/SampleProfReader.cpp b/llvm/lib/ProfileData/SampleProfReader.cpp
index 6d00404b0bb..cf3e56728e2 100644
--- a/llvm/lib/ProfileData/SampleProfReader.cpp
+++ b/llvm/lib/ProfileData/SampleProfReader.cpp
@@ -439,7 +439,9 @@ SampleProfileReaderBinary::readProfile(FunctionSamples &FProfile) {
return sampleprof_error::success;
}
-std::error_code SampleProfileReaderBinary::readFuncProfile() {
+std::error_code
+SampleProfileReaderBinary::readFuncProfile(const uint8_t *Start) {
+ Data = Start;
auto NumHeadSamples = readNumber<uint64_t>();
if (std::error_code EC = NumHeadSamples.getError())
return EC;
@@ -461,7 +463,7 @@ std::error_code SampleProfileReaderBinary::readFuncProfile() {
std::error_code SampleProfileReaderBinary::read() {
while (!at_eof()) {
- if (std::error_code EC = readFuncProfile())
+ if (std::error_code EC = readFuncProfile(Data))
return EC;
}
@@ -483,13 +485,15 @@ SampleProfileReaderExtBinary::readOneSection(const uint8_t *Start,
return EC;
break;
case SecLBRProfile:
- while (Data < Start + Size) {
- if (std::error_code EC = readFuncProfile())
- return EC;
- }
+ if (std::error_code EC = readFuncProfiles())
+ return EC;
break;
case SecProfileSymbolList:
- if (std::error_code EC = readProfileSymbolList(Size))
+ if (std::error_code EC = readProfileSymbolList())
+ return EC;
+ break;
+ case SecFuncOffsetTable:
+ if (std::error_code EC = readFuncOffsetTable())
return EC;
break;
default:
@@ -498,15 +502,65 @@ SampleProfileReaderExtBinary::readOneSection(const uint8_t *Start,
return sampleprof_error::success;
}
-std::error_code
-SampleProfileReaderExtBinary::readProfileSymbolList(uint64_t Size) {
+void SampleProfileReaderExtBinary::collectFuncsFrom(const Module &M) {
+ UseAllFuncs = false;
+ FuncsToUse.clear();
+ for (auto &F : M)
+ FuncsToUse.insert(FunctionSamples::getCanonicalFnName(F));
+}
+
+std::error_code SampleProfileReaderExtBinary::readFuncOffsetTable() {
+ auto Size = readNumber<uint64_t>();
+ if (std::error_code EC = Size.getError())
+ return EC;
+
+ FuncOffsetTable.reserve(*Size);
+ for (uint32_t I = 0; I < *Size; ++I) {
+ auto FName(readStringFromTable());
+ if (std::error_code EC = FName.getError())
+ return EC;
+
+ auto Offset = readNumber<uint64_t>();
+ if (std::error_code EC = Offset.getError())
+ return EC;
+
+ FuncOffsetTable[*FName] = *Offset;
+ }
+ return sampleprof_error::success;
+}
+
+std::error_code SampleProfileReaderExtBinary::readFuncProfiles() {
+ const uint8_t *Start = Data;
+ if (UseAllFuncs) {
+ while (Data < End) {
+ if (std::error_code EC = readFuncProfile(Data))
+ return EC;
+ }
+ assert(Data == End && "More data is read than expected");
+ return sampleprof_error::success;
+ }
+
+ for (auto Name : FuncsToUse) {
+ auto iter = FuncOffsetTable.find(Name);
+ if (iter == FuncOffsetTable.end())
+ continue;
+ const uint8_t *FuncProfileAddr = Start + iter->second;
+ assert(FuncProfileAddr < End && "out of LBRProfile section");
+ if (std::error_code EC = readFuncProfile(FuncProfileAddr))
+ return EC;
+ }
+ Data = End;
+ return sampleprof_error::success;
+}
+
+std::error_code SampleProfileReaderExtBinary::readProfileSymbolList() {
if (!ProfSymList)
ProfSymList = std::make_unique<ProfileSymbolList>();
- if (std::error_code EC = ProfSymList->read(Data, Size))
+ if (std::error_code EC = ProfSymList->read(Data, End - Data))
return EC;
- Data = Data + Size;
+ Data = End;
return sampleprof_error::success;
}
@@ -600,9 +654,9 @@ std::error_code SampleProfileReaderCompactBinary::read() {
for (auto Offset : OffsetsToUse) {
const uint8_t *SavedData = Data;
- Data = reinterpret_cast<const uint8_t *>(Buffer->getBufferStart()) +
- Offset;
- if (std::error_code EC = readFuncProfile())
+ if (std::error_code EC = readFuncProfile(
+ reinterpret_cast<const uint8_t *>(Buffer->getBufferStart()) +
+ Offset))
return EC;
Data = SavedData;
}
@@ -719,8 +773,16 @@ uint64_t SampleProfileReaderExtBinaryBase::getSectionSize(SecType Type) {
}
uint64_t SampleProfileReaderExtBinaryBase::getFileSize() {
- auto &LastEntry = SecHdrTable.back();
- return LastEntry.Offset + LastEntry.Size;
+ // Sections in SecHdrTable is not necessarily in the same order as
+ // sections in the profile because section like FuncOffsetTable needs
+ // to be written after section LBRProfile but needs to be read before
+ // section LBRProfile, so we cannot simply use the last entry in
+ // SecHdrTable to calculate the file size.
+ uint64_t FileSize = 0;
+ for (auto &Entry : SecHdrTable) {
+ FileSize = std::max(Entry.Offset + Entry.Size, FileSize);
+ }
+ return FileSize;
}
bool SampleProfileReaderExtBinaryBase::dumpSectionInfo(raw_ostream &OS) {
@@ -812,13 +874,11 @@ std::error_code SampleProfileReaderCompactBinary::readFuncOffsetTable() {
return sampleprof_error::success;
}
-void SampleProfileReaderCompactBinary::collectFuncsToUse(const Module &M) {
+void SampleProfileReaderCompactBinary::collectFuncsFrom(const Module &M) {
UseAllFuncs = false;
FuncsToUse.clear();
- for (auto &F : M) {
- StringRef CanonName = FunctionSamples::getCanonicalFnName(F);
- FuncsToUse.insert(CanonName);
- }
+ for (auto &F : M)
+ FuncsToUse.insert(FunctionSamples::getCanonicalFnName(F));
}
std::error_code SampleProfileReaderBinary::readSummaryEntry(
OpenPOWER on IntegriCloud