diff options
Diffstat (limited to 'llvm/lib/ProfileData/SampleProfWriter.cpp')
| -rw-r--r-- | llvm/lib/ProfileData/SampleProfWriter.cpp | 104 |
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); } |
