Please use GitHub pull requests for new patches. Avoid migrating existing patches. Phabricator shutdown timeline
Changeset View
Changeset View
Standalone View
Standalone View
llvm/include/llvm/ProfileData/SampleProfWriter.h
Show All 36 Lines | |||||
/// Sample-based profile writer. Base class. | /// Sample-based profile writer. Base class. | ||||
class SampleProfileWriter { | class SampleProfileWriter { | ||||
public: | public: | ||||
virtual ~SampleProfileWriter() = default; | virtual ~SampleProfileWriter() = default; | ||||
/// Write sample profiles in \p S. | /// Write sample profiles in \p S. | ||||
/// | /// | ||||
/// \returns status code of the file update operation. | /// \returns status code of the file update operation. | ||||
snehasish: Perhaps specify that this is in bytes either in the variable name or a comment? | |||||
Clarified comment in constructor huangjd: Clarified comment in constructor | |||||
virtual std::error_code writeSample(const FunctionSamples &S) = 0; | virtual std::error_code writeSample(const FunctionSamples &S) = 0; | ||||
/// Write all the sample profiles in the given map of samples. | /// Write all the sample profiles in the given map of samples. | ||||
/// | /// | ||||
/// \returns status code of the file update operation. | /// \returns status code of the file update operation. | ||||
virtual std::error_code write(const SampleProfileMap &ProfileMap); | virtual std::error_code write(const SampleProfileMap &ProfileMap); | ||||
raw_ostream &getOutputStream() { return *OutputStream; } | raw_ostream &getOutputStream() { return *OutputStream; } | ||||
Show All 10 Lines | public: | ||||
create(std::unique_ptr<raw_ostream> &OS, SampleProfileFormat Format); | create(std::unique_ptr<raw_ostream> &OS, SampleProfileFormat Format); | ||||
virtual void setProfileSymbolList(ProfileSymbolList *PSL) {} | virtual void setProfileSymbolList(ProfileSymbolList *PSL) {} | ||||
virtual void setToCompressAllSections() {} | virtual void setToCompressAllSections() {} | ||||
virtual void setUseMD5() {} | virtual void setUseMD5() {} | ||||
virtual void setPartialProfile() {} | virtual void setPartialProfile() {} | ||||
virtual void resetSecLayout(SectionLayout SL) {} | virtual void resetSecLayout(SectionLayout SL) {} | ||||
/// Clear all states associated with a specific profile, but not states set | |||||
/// from llvm-profdata command line arguments. Ignore transient states (those | |||||
/// always being set by write() before use). Call this to reuse the profile | |||||
It looks like derived classes must always call this function. Can you add a comment here for the future? Maybe something like // This function must always be called by the overridden implementation? snehasish: It looks like derived classes must always call this function. Can you add a comment here for… | |||||
It is not called by derived classes. It is called by llvm-profdata if the writer needs to be reused huangjd: It is not called by derived classes. It is called by llvm-profdata if the writer needs to be… | |||||
My comment was to add some documentation for future implementations which derive from SampleProfileWriter. For example, in this patch SampleProfileWriterText::reset calls SampleProfileWriter::reset(OS) on L110. I hope that clarifies the suggestion. snehasish: My comment was to add some documentation for future implementations which derive from… | |||||
/// writer on different profile map data. | |||||
/// Derived class should first call base class reset if overriding it. | |||||
virtual void reset(std::unique_ptr<raw_ostream> &OS) { | |||||
OutputStream = std::move(OS); | |||||
Summary.reset(); | |||||
} | |||||
protected: | protected: | ||||
SampleProfileWriter(std::unique_ptr<raw_ostream> &OS) | SampleProfileWriter(std::unique_ptr<raw_ostream> &OS) | ||||
: OutputStream(std::move(OS)) {} | : OutputStream(std::move(OS)) {} | ||||
/// Write a file header for the profile file. | /// Write a file header for the profile file. | ||||
virtual std::error_code writeHeader(const SampleProfileMap &ProfileMap) = 0; | virtual std::error_code writeHeader(const SampleProfileMap &ProfileMap) = 0; | ||||
// Write function profiles to the profile file. | // Write function profiles to the profile file. | ||||
Show All 12 Lines | protected: | ||||
SampleProfileFormat Format = SPF_None; | SampleProfileFormat Format = SPF_None; | ||||
}; | }; | ||||
/// Sample-based profile writer (text format). | /// Sample-based profile writer (text format). | ||||
class SampleProfileWriterText : public SampleProfileWriter { | class SampleProfileWriterText : public SampleProfileWriter { | ||||
public: | public: | ||||
std::error_code writeSample(const FunctionSamples &S) override; | std::error_code writeSample(const FunctionSamples &S) override; | ||||
void reset(std::unique_ptr<raw_ostream> &OS) override { | |||||
SampleProfileWriter::reset(OS); | |||||
Indent = 0; | |||||
} | |||||
protected: | protected: | ||||
SampleProfileWriterText(std::unique_ptr<raw_ostream> &OS) | SampleProfileWriterText(std::unique_ptr<raw_ostream> &OS) | ||||
: SampleProfileWriter(OS), Indent(0) {} | : SampleProfileWriter(OS), Indent(0) {} | ||||
std::error_code writeHeader(const SampleProfileMap &ProfileMap) override { | std::error_code writeHeader(const SampleProfileMap &ProfileMap) override { | ||||
return sampleprof_error::success; | return sampleprof_error::success; | ||||
} | } | ||||
Show All 11 Lines | |||||
/// Sample-based profile writer (binary format). | /// Sample-based profile writer (binary format). | ||||
class SampleProfileWriterBinary : public SampleProfileWriter { | class SampleProfileWriterBinary : public SampleProfileWriter { | ||||
public: | public: | ||||
SampleProfileWriterBinary(std::unique_ptr<raw_ostream> &OS) | SampleProfileWriterBinary(std::unique_ptr<raw_ostream> &OS) | ||||
: SampleProfileWriter(OS) {} | : SampleProfileWriter(OS) {} | ||||
std::error_code writeSample(const FunctionSamples &S) override; | std::error_code writeSample(const FunctionSamples &S) override; | ||||
void reset(std::unique_ptr<raw_ostream> &OS) override { | |||||
SampleProfileWriter::reset(OS); | |||||
NameTable.clear(); | |||||
} | |||||
protected: | protected: | ||||
virtual MapVector<StringRef, uint32_t> &getNameTable() { return NameTable; } | virtual MapVector<StringRef, uint32_t> &getNameTable() { return NameTable; } | ||||
virtual std::error_code writeMagicIdent(SampleProfileFormat Format); | virtual std::error_code writeMagicIdent(SampleProfileFormat Format); | ||||
virtual std::error_code writeNameTable(); | virtual std::error_code writeNameTable(); | ||||
std::error_code writeHeader(const SampleProfileMap &ProfileMap) override; | std::error_code writeHeader(const SampleProfileMap &ProfileMap) override; | ||||
std::error_code writeSummary(); | std::error_code writeSummary(); | ||||
virtual std::error_code writeContextIdx(const SampleContext &Context); | virtual std::error_code writeContextIdx(const SampleContext &Context); | ||||
std::error_code writeNameIdx(StringRef FName); | std::error_code writeNameIdx(StringRef FName); | ||||
▲ Show 20 Lines • Show All 85 Lines • ▼ Show 20 Lines | for (auto &Entry : SectionHdrLayout) { | ||||
assert(Entry.Flags == 0 && | assert(Entry.Flags == 0 && | ||||
"resetSecLayout has to be called before any flag setting"); | "resetSecLayout has to be called before any flag setting"); | ||||
} | } | ||||
#endif | #endif | ||||
SecLayout = SL; | SecLayout = SL; | ||||
SectionHdrLayout = ExtBinaryHdrLayoutTable[SL]; | SectionHdrLayout = ExtBinaryHdrLayoutTable[SL]; | ||||
} | } | ||||
void reset(std::unique_ptr<raw_ostream> &OS) override { | |||||
SampleProfileWriterBinary::reset(OS); | |||||
SecHdrTable.clear(); | |||||
CSNameTable.clear(); | |||||
} | |||||
protected: | protected: | ||||
uint64_t markSectionStart(SecType Type, uint32_t LayoutIdx); | uint64_t markSectionStart(SecType Type, uint32_t LayoutIdx); | ||||
std::error_code addNewSection(SecType Sec, uint32_t LayoutIdx, | std::error_code addNewSection(SecType Sec, uint32_t LayoutIdx, | ||||
uint64_t SectionStart); | uint64_t SectionStart); | ||||
template <class SecFlagType> | template <class SecFlagType> | ||||
void addSectionFlag(SecType Type, SecFlagType Flag) { | void addSectionFlag(SecType Type, SecFlagType Flag) { | ||||
for (auto &Entry : SectionHdrLayout) { | for (auto &Entry : SectionHdrLayout) { | ||||
if (Entry.Type == Type) | if (Entry.Type == Type) | ||||
▲ Show 20 Lines • Show All 139 Lines • ▼ Show 20 Lines | |||||
// function offset table without reading Part3 first. | // function offset table without reading Part3 first. | ||||
class SampleProfileWriterCompactBinary : public SampleProfileWriterBinary { | class SampleProfileWriterCompactBinary : public SampleProfileWriterBinary { | ||||
using SampleProfileWriterBinary::SampleProfileWriterBinary; | using SampleProfileWriterBinary::SampleProfileWriterBinary; | ||||
public: | public: | ||||
std::error_code writeSample(const FunctionSamples &S) override; | std::error_code writeSample(const FunctionSamples &S) override; | ||||
std::error_code write(const SampleProfileMap &ProfileMap) override; | std::error_code write(const SampleProfileMap &ProfileMap) override; | ||||
void reset(std::unique_ptr<raw_ostream> &OS) override { | |||||
SampleProfileWriterBinary::reset(OS); | |||||
FuncOffsetTable.clear(); | |||||
} | |||||
protected: | protected: | ||||
/// The table mapping from function name to the offset of its FunctionSample | /// The table mapping from function name to the offset of its FunctionSample | ||||
/// towards profile start. | /// towards profile start. | ||||
MapVector<StringRef, uint64_t> FuncOffsetTable; | MapVector<StringRef, uint64_t> FuncOffsetTable; | ||||
/// The offset of the slot to be filled with the offset of FuncOffsetTable | /// The offset of the slot to be filled with the offset of FuncOffsetTable | ||||
/// towards profile start. | /// towards profile start. | ||||
uint64_t TableOffset; | uint64_t TableOffset; | ||||
std::error_code writeNameTable() override; | std::error_code writeNameTable() override; | ||||
std::error_code writeHeader(const SampleProfileMap &ProfileMap) override; | std::error_code writeHeader(const SampleProfileMap &ProfileMap) override; | ||||
std::error_code writeFuncOffsetTable(); | std::error_code writeFuncOffsetTable(); | ||||
}; | }; | ||||
namespace { | |||||
/// When combining multiple profiles, user may want to use different strategies | |||||
/// to reduce function count other than dropping the least sampled first, so | |||||
/// this class can be extended to satisfy such need. | |||||
class FunctionPruningStrategy { | |||||
std::vector<NameFunctionSamples> Functions; | |||||
public: | |||||
SampleProfileMap &ProfileMap; | |||||
FunctionPruningStrategy(SampleProfileMap &ProfileMap) | |||||
: ProfileMap(ProfileMap) { | |||||
sortFuncProfiles(ProfileMap, Functions); | |||||
} | |||||
void Erase(size_t NumToRemove) { | |||||
assert(NumToRemove <= Functions.size()); | |||||
llvm::for_each( | |||||
llvm::make_range(Functions.begin() + Functions.size() - NumToRemove, | |||||
Functions.end()), | |||||
[&](const NameFunctionSamples &E) { ProfileMap.erase(E.first); }); | |||||
Functions.resize(Functions.size() - NumToRemove); | |||||
} | |||||
}; | |||||
} // namespace | |||||
} // end namespace sampleprof | } // end namespace sampleprof | ||||
} // end namespace llvm | } // end namespace llvm | ||||
#endif // LLVM_PROFILEDATA_SAMPLEPROFWRITER_H | #endif // LLVM_PROFILEDATA_SAMPLEPROFWRITER_H |
Perhaps specify that this is in bytes either in the variable name or a comment?