summaryrefslogtreecommitdiff
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.cpp104
1 files changed, 77 insertions, 27 deletions
diff --git a/llvm/lib/ProfileData/SampleProfWriter.cpp b/llvm/lib/ProfileData/SampleProfWriter.cpp
index 71dba6281f76..535f87968104 100644
--- a/llvm/lib/ProfileData/SampleProfWriter.cpp
+++ b/llvm/lib/ProfileData/SampleProfWriter.cpp
@@ -46,9 +46,11 @@ std::error_code SampleProfileWriter::writeFuncProfiles(
// Sort the ProfileMap by total samples.
typedef std::pair<StringRef, const FunctionSamples *> NameFunctionSamples;
std::vector<NameFunctionSamples> V;
- for (const auto &I : ProfileMap)
- V.push_back(std::make_pair(I.getKey(), &I.second));
-
+ for (const auto &I : ProfileMap) {
+ assert(I.getKey() == I.second.getNameWithContext() &&
+ "Inconsistent profile map");
+ V.push_back(std::make_pair(I.second.getNameWithContext(), &I.second));
+ }
llvm::stable_sort(
V, [](const NameFunctionSamples &A, const NameFunctionSamples &B) {
if (A.second->getTotalSamples() == B.second->getTotalSamples())
@@ -147,7 +149,7 @@ std::error_code SampleProfileWriterExtBinaryBase::write(
std::error_code
SampleProfileWriterExtBinaryBase::writeSample(const FunctionSamples &S) {
uint64_t Offset = OutputStream->tell();
- StringRef Name = S.getName();
+ StringRef Name = S.getNameWithContext();
FuncOffsetTable[Name] = Offset - SecLBRProfileStart;
encodeULEB128(S.getHeadSamples(), *OutputStream);
return writeBody(S);
@@ -160,9 +162,11 @@ std::error_code SampleProfileWriterExtBinaryBase::writeFuncOffsetTable() {
encodeULEB128(FuncOffsetTable.size(), OS);
// Write out FuncOffsetTable.
- for (auto entry : FuncOffsetTable) {
- writeNameIdx(entry.first);
- encodeULEB128(entry.second, OS);
+ for (auto Entry : FuncOffsetTable) {
+ if (std::error_code EC =
+ writeNameIdx(Entry.first, FunctionSamples::ProfileIsCS))
+ return EC;
+ encodeULEB128(Entry.second, OS);
}
FuncOffsetTable.clear();
return sampleprof_error::success;
@@ -170,12 +174,17 @@ std::error_code SampleProfileWriterExtBinaryBase::writeFuncOffsetTable() {
std::error_code SampleProfileWriterExtBinaryBase::writeFuncMetadata(
const StringMap<FunctionSamples> &Profiles) {
- if (!FunctionSamples::ProfileIsProbeBased)
+ if (!FunctionSamples::ProfileIsProbeBased && !FunctionSamples::ProfileIsCS)
return sampleprof_error::success;
auto &OS = *OutputStream;
for (const auto &Entry : Profiles) {
- writeNameIdx(Entry.first());
- encodeULEB128(Entry.second.getFunctionHash(), OS);
+ if (std::error_code EC = writeNameIdx(Entry.second.getNameWithContext(),
+ FunctionSamples::ProfileIsCS))
+ return EC;
+ if (FunctionSamples::ProfileIsProbeBased)
+ encodeULEB128(Entry.second.getFunctionHash(), OS);
+ if (FunctionSamples::ProfileIsCS)
+ encodeULEB128(Entry.second.getContext().getAllAttributes(), OS);
}
return sampleprof_error::success;
}
@@ -201,9 +210,22 @@ std::error_code SampleProfileWriterExtBinaryBase::writeNameTable() {
std::error_code SampleProfileWriterExtBinaryBase::writeNameTableSection(
const StringMap<FunctionSamples> &ProfileMap) {
for (const auto &I : ProfileMap) {
- addName(I.first());
+ assert(I.first() == I.second.getNameWithContext() &&
+ "Inconsistent profile map");
+ addName(I.second.getNameWithContext(), FunctionSamples::ProfileIsCS);
addNames(I.second);
}
+
+ // If NameTable contains ".__uniq." suffix, set SecFlagUniqSuffix flag
+ // so compiler won't strip the suffix during profile matching after
+ // seeing the flag in the profile.
+ for (const auto &I : NameTable) {
+ if (I.first.find(FunctionSamples::UniqSuffix) != StringRef::npos) {
+ addSectionFlag(SecNameTable, SecNameTableFlags::SecFlagUniqSuffix);
+ break;
+ }
+ }
+
if (auto EC = writeNameTable())
return EC;
return sampleprof_error::success;
@@ -226,6 +248,12 @@ std::error_code SampleProfileWriterExtBinaryBase::writeOneSection(
setToCompressSection(SecProfileSymbolList);
if (Type == SecFuncMetadata && FunctionSamples::ProfileIsProbeBased)
addSectionFlag(SecFuncMetadata, SecFuncMetadataFlags::SecFlagIsProbeBased);
+ if (Type == SecProfSummary && FunctionSamples::ProfileIsCS)
+ addSectionFlag(SecProfSummary, SecProfSummaryFlags::SecFlagFullContext);
+ if (Type == SecFuncMetadata && FunctionSamples::ProfileIsCS)
+ addSectionFlag(SecFuncMetadata, SecFuncMetadataFlags::SecFlagHasAttribute);
+ if (Type == SecProfSummary && FunctionSamples::ProfileIsFS)
+ addSectionFlag(SecProfSummary, SecProfSummaryFlags::SecFlagFSDiscriminator);
uint64_t SectionStart = markSectionStart(Type, LayoutIdx);
switch (Type) {
@@ -364,6 +392,7 @@ std::error_code SampleProfileWriterText::writeSample(const FunctionSamples &S) {
OS << "[" << S.getNameWithContext() << "]:" << S.getTotalSamples();
else
OS << S.getName() << ":" << S.getTotalSamples();
+
if (Indent == 0)
OS << ":" << S.getHeadSamples();
OS << "\n";
@@ -407,20 +436,35 @@ std::error_code SampleProfileWriterText::writeSample(const FunctionSamples &S) {
OS.indent(Indent + 1);
OS << "!CFGChecksum: " << S.getFunctionHash() << "\n";
}
+ if (FunctionSamples::ProfileIsCS) {
+ OS.indent(Indent + 1);
+ OS << "!Attributes: " << S.getContext().getAllAttributes() << "\n";
+ }
}
return sampleprof_error::success;
}
-std::error_code SampleProfileWriterBinary::writeNameIdx(StringRef FName) {
- const auto &ret = NameTable.find(FName);
- if (ret == NameTable.end())
+std::error_code SampleProfileWriterBinary::writeNameIdx(StringRef FName,
+ bool IsContextName) {
+ std::string BracketedName;
+ if (IsContextName) {
+ BracketedName = "[" + FName.str() + "]";
+ FName = StringRef(BracketedName);
+ }
+
+ const auto &Ret = NameTable.find(FName);
+ if (Ret == NameTable.end())
return sampleprof_error::truncated_name_table;
- encodeULEB128(ret->second, *OutputStream);
+ encodeULEB128(Ret->second, *OutputStream);
return sampleprof_error::success;
}
-void SampleProfileWriterBinary::addName(StringRef FName) {
+void SampleProfileWriterBinary::addName(StringRef FName, bool IsContextName) {
+ if (IsContextName) {
+ auto It = BracketedContextStr.insert("[" + FName.str() + "]");
+ FName = StringRef(*It.first);
+ }
NameTable.insert(std::make_pair(FName, 0));
}
@@ -481,9 +525,11 @@ std::error_code SampleProfileWriterCompactBinary::writeFuncOffsetTable() {
encodeULEB128(FuncOffsetTable.size(), OS);
// Write out FuncOffsetTable.
- for (auto entry : FuncOffsetTable) {
- writeNameIdx(entry.first);
- encodeULEB128(entry.second, OS);
+ for (auto Entry : FuncOffsetTable) {
+ if (std::error_code EC =
+ writeNameIdx(Entry.first, FunctionSamples::ProfileIsCS))
+ return EC;
+ encodeULEB128(Entry.second, OS);
}
return sampleprof_error::success;
}
@@ -520,7 +566,9 @@ std::error_code SampleProfileWriterBinary::writeHeader(
// Generate the name table for all the functions referenced in the profile.
for (const auto &I : ProfileMap) {
- addName(I.first());
+ assert(I.first() == I.second.getNameWithContext() &&
+ "Inconsistent profile map");
+ addName(I.first(), FunctionSamples::ProfileIsCS);
addNames(I.second);
}
@@ -635,7 +683,8 @@ std::error_code SampleProfileWriterBinary::writeSummary() {
std::error_code SampleProfileWriterBinary::writeBody(const FunctionSamples &S) {
auto &OS = *OutputStream;
- if (std::error_code EC = writeNameIdx(S.getName()))
+ if (std::error_code EC =
+ writeNameIdx(S.getNameWithContext(), FunctionSamples::ProfileIsCS))
return EC;
encodeULEB128(S.getTotalSamples(), OS);
@@ -709,7 +758,7 @@ SampleProfileWriter::create(StringRef Filename, SampleProfileFormat Format) {
Format == SPF_Compact_Binary)
OS.reset(new raw_fd_ostream(Filename, EC, sys::fs::OF_None));
else
- OS.reset(new raw_fd_ostream(Filename, EC, sys::fs::OF_Text));
+ OS.reset(new raw_fd_ostream(Filename, EC, sys::fs::OF_TextWithCRLF));
if (EC)
return EC;
@@ -729,6 +778,11 @@ SampleProfileWriter::create(std::unique_ptr<raw_ostream> &OS,
std::error_code EC;
std::unique_ptr<SampleProfileWriter> Writer;
+ // Currently only Text and Extended Binary format are supported for CSSPGO.
+ if ((FunctionSamples::ProfileIsCS || FunctionSamples::ProfileIsProbeBased) &&
+ (Format == SPF_Binary || Format == SPF_Compact_Binary))
+ return sampleprof_error::unsupported_writing_format;
+
if (Format == SPF_Binary)
Writer.reset(new SampleProfileWriterRawBinary(OS));
else if (Format == SPF_Ext_Binary)
@@ -752,9 +806,5 @@ SampleProfileWriter::create(std::unique_ptr<raw_ostream> &OS,
void SampleProfileWriter::computeSummary(
const StringMap<FunctionSamples> &ProfileMap) {
SampleProfileSummaryBuilder Builder(ProfileSummaryBuilder::DefaultCutoffs);
- for (const auto &I : ProfileMap) {
- const FunctionSamples &Profile = I.second;
- Builder.addRecord(Profile);
- }
- Summary = Builder.getSummary();
+ Summary = Builder.computeSummaryForProfiles(ProfileMap);
}