summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/ProfileData/SampleProf.cpp55
-rw-r--r--llvm/lib/ProfileData/SampleProfReader.cpp84
-rw-r--r--llvm/lib/ProfileData/SampleProfWriter.cpp102
3 files changed, 158 insertions, 83 deletions
diff --git a/llvm/lib/ProfileData/SampleProf.cpp b/llvm/lib/ProfileData/SampleProf.cpp
index e94848df24e..2150c5d5a70 100644
--- a/llvm/lib/ProfileData/SampleProf.cpp
+++ b/llvm/lib/ProfileData/SampleProf.cpp
@@ -15,7 +15,6 @@
#include "llvm/Config/llvm-config.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/Support/Compiler.h"
-#include "llvm/Support/Compression.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
@@ -198,66 +197,34 @@ FunctionSamples::findFunctionSamples(const DILocation *DIL) const {
LLVM_DUMP_METHOD void FunctionSamples::dump() const { print(dbgs(), 0); }
#endif
-std::error_code ProfileSymbolList::read(uint64_t CompressSize,
- uint64_t UncompressSize,
- const uint8_t *Data) {
+std::error_code ProfileSymbolList::read(const uint8_t *Data,
+ uint64_t ListSize) {
const char *ListStart = reinterpret_cast<const char *>(Data);
- // CompressSize being non-zero means the profile is compressed and
- // needs to be uncompressed first.
- if (CompressSize) {
- if (!llvm::zlib::isAvailable())
- return sampleprof_error::zlib_unavailable;
-
- StringRef CompressedStrings(reinterpret_cast<const char *>(Data),
- CompressSize);
- char *Buffer = Allocator.Allocate<char>(UncompressSize);
- size_t UCSize = UncompressSize;
- llvm::Error E = zlib::uncompress(CompressedStrings, Buffer, UCSize);
- if (E)
- return sampleprof_error::uncompress_failed;
- ListStart = Buffer;
- }
-
uint64_t Size = 0;
- while (Size < UncompressSize) {
+ while (Size < ListSize) {
StringRef Str(ListStart + Size);
add(Str);
Size += Str.size() + 1;
}
+ if (Size != ListSize)
+ return sampleprof_error::malformed;
return sampleprof_error::success;
}
std::error_code ProfileSymbolList::write(raw_ostream &OS) {
- // Sort the symbols before doing compression. It will make the
- // compression much more effective.
+ // Sort the symbols before output. If doing compression.
+ // It will make the compression much more effective.
std::vector<StringRef> SortedList;
SortedList.insert(SortedList.begin(), Syms.begin(), Syms.end());
llvm::sort(SortedList);
- std::string UncompressedStrings;
+ std::string OutputString;
for (auto &Sym : SortedList) {
- UncompressedStrings.append(Sym.str());
- UncompressedStrings.append(1, '\0');
+ OutputString.append(Sym.str());
+ OutputString.append(1, '\0');
}
- if (ToCompress) {
- if (!llvm::zlib::isAvailable())
- return sampleprof_error::zlib_unavailable;
- 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();
- } else {
- encodeULEB128(UncompressedStrings.size(), OS);
- // If profile symbol list is not compressed, we will still save
- // a compressed size value, but the value of the size is 0.
- encodeULEB128(0, OS);
- OS << UncompressedStrings;
- }
+ OS << OutputString;
return sampleprof_error::success;
}
diff --git a/llvm/lib/ProfileData/SampleProfReader.cpp b/llvm/lib/ProfileData/SampleProfReader.cpp
index 07272ebac0a..075bd9412b0 100644
--- a/llvm/lib/ProfileData/SampleProfReader.cpp
+++ b/llvm/lib/ProfileData/SampleProfReader.cpp
@@ -26,6 +26,7 @@
#include "llvm/IR/ProfileSummary.h"
#include "llvm/ProfileData/ProfileCommon.h"
#include "llvm/ProfileData/SampleProf.h"
+#include "llvm/Support/Compression.h"
#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/LEB128.h"
#include "llvm/Support/LineIterator.h"
@@ -471,6 +472,7 @@ std::error_code
SampleProfileReaderExtBinary::readOneSection(const uint8_t *Start,
uint64_t Size, SecType Type) {
Data = Start;
+ End = Start + Size;
switch (Type) {
case SecProfSummary:
if (std::error_code EC = readSummary())
@@ -487,7 +489,7 @@ SampleProfileReaderExtBinary::readOneSection(const uint8_t *Start,
}
break;
case SecProfileSymbolList:
- if (std::error_code EC = readProfileSymbolList())
+ if (std::error_code EC = readProfileSymbolList(Size))
return EC;
break;
default:
@@ -496,27 +498,43 @@ SampleProfileReaderExtBinary::readOneSection(const uint8_t *Start,
return sampleprof_error::success;
}
-std::error_code SampleProfileReaderExtBinary::readProfileSymbolList() {
- auto UncompressSize = readNumber<uint64_t>();
- if (std::error_code EC = UncompressSize.getError())
- return EC;
+std::error_code
+SampleProfileReaderExtBinary::readProfileSymbolList(uint64_t Size) {
+ if (!ProfSymList)
+ ProfSymList = std::make_unique<ProfileSymbolList>();
- auto CompressSize = readNumber<uint64_t>();
- if (std::error_code EC = CompressSize.getError())
+ if (std::error_code EC = ProfSymList->read(Data, Size))
return EC;
- if (!ProfSymList)
- ProfSymList = std::make_unique<ProfileSymbolList>();
+ Data = Data + Size;
+ return sampleprof_error::success;
+}
- if (std::error_code EC =
- ProfSymList->read(*CompressSize, *UncompressSize, Data))
+std::error_code SampleProfileReaderExtBinaryBase::decompressSection(
+ const uint8_t *SecStart, const uint64_t SecSize,
+ const uint8_t *&DecompressBuf, uint64_t &DecompressBufSize) {
+ Data = SecStart;
+ End = SecStart + SecSize;
+ auto DecompressSize = readNumber<uint64_t>();
+ if (std::error_code EC = DecompressSize.getError())
return EC;
+ DecompressBufSize = *DecompressSize;
- // CompressSize is zero only when ProfileSymbolList is not compressed.
- if (*CompressSize == 0)
- Data = Data + *UncompressSize;
- else
- Data = Data + *CompressSize;
+ auto CompressSize = readNumber<uint64_t>();
+ if (std::error_code EC = CompressSize.getError())
+ return EC;
+
+ if (!llvm::zlib::isAvailable())
+ return sampleprof_error::zlib_unavailable;
+
+ StringRef CompressedStrings(reinterpret_cast<const char *>(Data),
+ *CompressSize);
+ char *Buffer = Allocator.Allocate<char>(DecompressBufSize);
+ llvm::Error E =
+ zlib::uncompress(CompressedStrings, Buffer, DecompressBufSize);
+ if (E)
+ return sampleprof_error::uncompress_failed;
+ DecompressBuf = reinterpret_cast<const uint8_t *>(Buffer);
return sampleprof_error::success;
}
@@ -528,11 +546,35 @@ std::error_code SampleProfileReaderExtBinaryBase::read() {
// Skip empty section.
if (!Entry.Size)
continue;
+
const uint8_t *SecStart = BufStart + Entry.Offset;
- if (std::error_code EC = readOneSection(SecStart, Entry.Size, Entry.Type))
+ uint64_t SecSize = Entry.Size;
+
+ // If the section is compressed, decompress it into a buffer
+ // DecompressBuf before reading the actual data. The pointee of
+ // 'Data' will be changed to buffer hold by DecompressBuf
+ // temporarily when reading the actual data.
+ bool isCompressed = hasSecFlag(Entry, SecFlagCompress);
+ if (isCompressed) {
+ const uint8_t *DecompressBuf;
+ uint64_t DecompressBufSize;
+ if (std::error_code EC = decompressSection(
+ SecStart, SecSize, DecompressBuf, DecompressBufSize))
+ return EC;
+ SecStart = DecompressBuf;
+ SecSize = DecompressBufSize;
+ }
+
+ if (std::error_code EC = readOneSection(SecStart, SecSize, Entry.Type))
return EC;
- if (Data != SecStart + Entry.Size)
+ if (Data != SecStart + SecSize)
return sampleprof_error::malformed;
+
+ // Change the pointee of 'Data' from DecompressBuf to original Buffer.
+ if (isCompressed) {
+ Data = BufStart + Entry.Offset;
+ End = BufStart + Buffer->getBufferSize();
+ }
}
return sampleprof_error::success;
@@ -621,10 +663,10 @@ std::error_code SampleProfileReaderExtBinaryBase::readSecHdrTableEntry() {
return EC;
Entry.Type = static_cast<SecType>(*Type);
- auto Flag = readUnencodedNumber<uint64_t>();
- if (std::error_code EC = Flag.getError())
+ auto Flags = readUnencodedNumber<uint64_t>();
+ if (std::error_code EC = Flags.getError())
return EC;
- Entry.Flag = *Flag;
+ Entry.Flags = *Flags;
auto Offset = readUnencodedNumber<uint64_t>();
if (std::error_code EC = Offset.getError())
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