summaryrefslogtreecommitdiffstats
path: root/llvm/lib/ProfileData/SampleProfWriter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/ProfileData/SampleProfWriter.cpp')
-rw-r--r--llvm/lib/ProfileData/SampleProfWriter.cpp102
1 files changed, 84 insertions, 18 deletions
diff --git a/llvm/lib/ProfileData/SampleProfWriter.cpp b/llvm/lib/ProfileData/SampleProfWriter.cpp
index 068ce5bf959..03446367665 100644
--- a/llvm/lib/ProfileData/SampleProfWriter.cpp
+++ b/llvm/lib/ProfileData/SampleProfWriter.cpp
@@ -21,6 +21,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ProfileData/ProfileCommon.h"
#include "llvm/ProfileData/SampleProf.h"
+#include "llvm/Support/Compression.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/EndianStream.h"
#include "llvm/Support/ErrorOr.h"
@@ -72,21 +73,58 @@ SampleProfileWriter::write(const StringMap<FunctionSamples> &ProfileMap) {
return sampleprof_error::success;
}
+SecHdrTableEntry &
+SampleProfileWriterExtBinaryBase::getEntryInLayout(SecType Type) {
+ auto SecIt = std::find_if(
+ SectionLayout.begin(), SectionLayout.end(),
+ [=](const auto &Entry) -> bool { return Entry.Type == Type; });
+ return *SecIt;
+}
+
/// Return the current position and prepare to use it as the start
/// position of a section.
-uint64_t SampleProfileWriterExtBinaryBase::markSectionStart() {
- return OutputStream->tell();
+uint64_t SampleProfileWriterExtBinaryBase::markSectionStart(SecType Type) {
+ uint64_t SectionStart = OutputStream->tell();
+ auto &Entry = getEntryInLayout(Type);
+ // Use LocalBuf as a temporary output for writting data.
+ if (hasSecFlag(Entry, SecFlagCompress))
+ LocalBufStream.swap(OutputStream);
+ return SectionStart;
+}
+
+std::error_code SampleProfileWriterExtBinaryBase::compressAndOutput() {
+ if (!llvm::zlib::isAvailable())
+ return sampleprof_error::zlib_unavailable;
+ std::string &UncompressedStrings =
+ static_cast<raw_string_ostream *>(LocalBufStream.get())->str();
+ if (UncompressedStrings.size() == 0)
+ return sampleprof_error::success;
+ auto &OS = *OutputStream;
+ SmallString<128> CompressedStrings;
+ llvm::Error E = zlib::compress(UncompressedStrings, CompressedStrings,
+ zlib::BestSizeCompression);
+ if (E)
+ return sampleprof_error::compress_failed;
+ encodeULEB128(UncompressedStrings.size(), OS);
+ encodeULEB128(CompressedStrings.size(), OS);
+ OS << CompressedStrings.str();
+ UncompressedStrings.clear();
+ return sampleprof_error::success;
}
-/// Add a new section into section header table. Return the position
-/// of SectionEnd.
-uint64_t
-SampleProfileWriterExtBinaryBase::addNewSection(SecType Sec,
+/// Add a new section into section header table.
+std::error_code
+SampleProfileWriterExtBinaryBase::addNewSection(SecType Type,
uint64_t SectionStart) {
- uint64_t SectionEnd = OutputStream->tell();
- SecHdrTable.push_back(
- {Sec, 0, SectionStart - FileStart, SectionEnd - SectionStart});
- return SectionEnd;
+ auto Entry = getEntryInLayout(Type);
+ if (hasSecFlag(Entry, SecFlagCompress)) {
+ LocalBufStream.swap(OutputStream);
+ if (std::error_code EC = compressAndOutput())
+ return EC;
+ }
+ SecHdrTable.push_back({Type, Entry.Flags, SectionStart - FileStart,
+ OutputStream->tell() - SectionStart});
+ return sampleprof_error::success;
}
std::error_code SampleProfileWriterExtBinaryBase::write(
@@ -94,6 +132,8 @@ std::error_code SampleProfileWriterExtBinaryBase::write(
if (std::error_code EC = writeHeader(ProfileMap))
return EC;
+ std::string LocalBuf;
+ LocalBufStream = std::make_unique<raw_string_ostream>(LocalBuf);
if (std::error_code EC = writeSections(ProfileMap))
return EC;
@@ -105,28 +145,38 @@ std::error_code SampleProfileWriterExtBinaryBase::write(
std::error_code SampleProfileWriterExtBinary::writeSections(
const StringMap<FunctionSamples> &ProfileMap) {
- uint64_t SectionStart = markSectionStart();
+ uint64_t SectionStart = markSectionStart(SecProfSummary);
computeSummary(ProfileMap);
if (auto EC = writeSummary())
return EC;
- SectionStart = addNewSection(SecProfSummary, SectionStart);
+ if (std::error_code EC = addNewSection(SecProfSummary, SectionStart))
+ return EC;
// Generate the name table for all the functions referenced in the profile.
+ SectionStart = markSectionStart(SecNameTable);
for (const auto &I : ProfileMap) {
addName(I.first());
addNames(I.second);
}
writeNameTable();
- SectionStart = addNewSection(SecNameTable, SectionStart);
+ if (std::error_code EC = addNewSection(SecNameTable, SectionStart))
+ return EC;
+ SectionStart = markSectionStart(SecLBRProfile);
if (std::error_code EC = writeFuncProfiles(ProfileMap))
return EC;
- SectionStart = addNewSection(SecLBRProfile, SectionStart);
+ if (std::error_code EC = addNewSection(SecLBRProfile, SectionStart))
+ return EC;
+
+ if (ProfSymList && ProfSymList->toCompress())
+ setToCompressSection(SecProfileSymbolList);
+ SectionStart = markSectionStart(SecProfileSymbolList);
if (ProfSymList && ProfSymList->size() > 0)
if (std::error_code EC = ProfSymList->write(*OutputStream))
return EC;
- addNewSection(SecProfileSymbolList, SectionStart);
+ if (std::error_code EC = addNewSection(SecProfileSymbolList, SectionStart))
+ return EC;
return sampleprof_error::success;
}
@@ -308,6 +358,23 @@ std::error_code SampleProfileWriterBinary::writeHeader(
return sampleprof_error::success;
}
+void SampleProfileWriterExtBinaryBase::setToCompressAllSections() {
+ for (auto &Entry : SectionLayout)
+ addSecFlags(Entry, SecFlagCompress);
+}
+
+void SampleProfileWriterExtBinaryBase::setToCompressSection(SecType Type) {
+ addSectionFlags(Type, SecFlagCompress);
+}
+
+void SampleProfileWriterExtBinaryBase::addSectionFlags(SecType Type,
+ SecFlags Flags) {
+ for (auto &Entry : SectionLayout) {
+ if (Entry.Type == Type)
+ addSecFlags(Entry, Flags);
+ }
+}
+
void SampleProfileWriterExtBinaryBase::allocSecHdrTable() {
support::endian::Writer Writer(*OutputStream, support::little);
@@ -342,9 +409,9 @@ std::error_code SampleProfileWriterExtBinaryBase::writeSecHdrTable() {
// to adjust the order in SecHdrTable to be consistent with
// SectionLayout when we write SecHdrTable to the memory.
for (uint32_t i = 0; i < SectionLayout.size(); i++) {
- uint32_t idx = IndexMap[static_cast<uint32_t>(SectionLayout[i])];
+ uint32_t idx = IndexMap[static_cast<uint32_t>(SectionLayout[i].Type)];
Writer.write(static_cast<uint64_t>(SecHdrTable[idx].Type));
- Writer.write(static_cast<uint64_t>(SecHdrTable[idx].Flag));
+ Writer.write(static_cast<uint64_t>(SecHdrTable[idx].Flags));
Writer.write(static_cast<uint64_t>(SecHdrTable[idx].Offset));
Writer.write(static_cast<uint64_t>(SecHdrTable[idx].Size));
}
@@ -362,7 +429,6 @@ std::error_code SampleProfileWriterExtBinaryBase::writeHeader(
FileStart = OS.tell();
writeMagicIdent(Format);
- initSectionLayout();
allocSecHdrTable();
return sampleprof_error::success;
}
OpenPOWER on IntegriCloud