1//===- SampleProfWriter.h - Write LLVM sample profile data ------*- C++ -*-===// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7//===----------------------------------------------------------------------===// 9// This file contains definitions needed for writing sample profiles. 11//===----------------------------------------------------------------------===// 12#ifndef LLVM_PROFILEDATA_SAMPLEPROFWRITER_H 13#define LLVM_PROFILEDATA_SAMPLEPROFWRITER_H 24#include <system_error> 31// The layout splits profile with inlined functions from profile without 32// inlined functions. When Thinlto is enabled, ThinLTO postlink phase only 33// has to load profile with inlined functions and can skip the other part. 38/// When writing a profile with size limit, user may want to use a different 39/// strategy to reduce function count other than dropping functions with fewest 40/// samples first. In this case a class implementing the same interfaces should 41/// be provided to SampleProfileWriter::writeWithSizeLimit(). 48 /// \p ProfileMap A reference to the original profile map. It will be modified 50 /// \p OutputSizeLimit Size limit in bytes of the output profile. This is 51 /// necessary to estimate how many functions to remove. 57 /// SampleProfileWriter::writeWithSizeLimit() calls this after every write 58 /// iteration if the output size still exceeds the limit. This function 59 /// should erase some functions from the profile map so that the writer tries 60 /// to write the profile again with fewer functions. At least 1 entry from the 61 /// profile map must be erased. 63 /// \p CurrentOutputSize Number of bytes in the output if current profile map 65virtualvoidErase(
size_t CurrentOutputSize) = 0;
69 std::vector<NameFunctionSamples> SortedFunctions;
75 /// In this default implementation, functions with fewest samples are dropped 76 /// first. Since the exact size of the output cannot be easily calculated due 77 /// to compression, we use a heuristic to remove as many functions as 78 /// necessary but not too many, aiming to minimize the number of write 80 /// Empirically, functions with larger total sample count contain linearly 81 /// more sample entries, meaning it takes linearly more space to write them. 82 /// The cumulative length is therefore quadratic if all functions are sorted 83 /// by total sample count. 84 /// TODO: Find better heuristic. 85voidErase(
size_t CurrentOutputSize)
override;
88/// Sample-based profile writer. Base class. 93 /// Write sample profiles in \p S. 95 /// \returns status code of the file update operation. 98 /// Write all the sample profiles in the given map of samples. 100 /// \returns status code of the file update operation. 103 /// Write sample profiles up to given size limit, using the pruning strategy 104 /// to drop some functions if necessary. 106 /// \returns status code of the file update operation. 107template <
typename FunctionPruningStrategy = DefaultFunctionPruningStrategy>
109size_t OutputSizeLimit) {
116 /// Profile writer factory. 118 /// Create a new file writer based on the value of \p Format. 122 /// Create a new stream writer based on the value of \p Format. 137 /// Write a file header for the profile file. 140// Write function profiles to the profile file. 144size_t OutputSizeLimit,
147 /// For writeWithSizeLimit in text mode, each newline takes 1 additional byte 148 /// on Windows when actually written to the file, but not written to a memory 149 /// buffer. This needs to be accounted for when rewriting the profile. 152 /// Output stream where to emit the profile to. 158 /// Compute summary for this profile. 165/// Sample-based profile writer (text format). 180 MarkFlatProfiles =
true;
184 /// Indent level to use when writing. 186 /// This is used when printing inlined callees. 189 /// If set, writes metadata "!Flat" to functions without inlined functions. 190 /// This flag is for manual inspection only, it has no effect for the profile 191 /// reader because a text sample profile is read sequentially and functions 192 /// cannot be skipped. 193bool MarkFlatProfiles =
false;
200/// Sample-based profile writer (binary format). 218 std::set<FunctionId> &V);
236const std::array<SmallVector<SecHdrTableEntry, 8>,
NumOfLayout>
238// Note that SecFuncOffsetTable section is written after SecLBRProfile 239// in the profile, but is put before SecLBRProfile in SectionHdrLayout. 240// This is because sample reader follows the order in SectionHdrLayout 241// to read each section. To read function profiles on demand, sample 242// reader need to get the offset of each function profile first. 255// profile with inlined functions 256// for next two sections 259// profile without inlined functions 260// for next two sections 276// Set to use MD5 to represent string in NameTable. 280// MD5 will be stored as plain uint64_t instead of variable-length 281// quantity format in NameTable section. 285// Set the profile to be partial. It means the profile is for 286// common/shared code. The common profile is usually merged from 287// profiles collected from running other targets. 303// Make sure resetSecLayout is called before any flag setting. 306"resetSecLayout has to be called before any flag setting");
317template <
class SecFlagType>
320if (Entry.Type ==
Type)
324template <
class SecFlagType>
331// placeholder for subclasses to dispatch their own section writers. 333// Verify the SecLayout is supported by the format. 336// specify the order to write sections. 339// Dispatch section writer for each section. \p LayoutIdx is the sequence 340// number indicating where the section is located in SectionHdrLayout. 344// Helper function to write name table. 353// Functions to write various kinds of sections. 359// Specifiy the order of sections in section header table. Note 360// the order of sections in SecHdrTable may be different that the 361// order in SectionHdrLayout. sample Reader will follow the order 362// in SectionHdrLayout to read each section. 366// Save the start of SecLBRProfile so we can compute the offset to the 367// start of SecLBRProfile for each Function's Profile and will keep it 368// in FuncOffsetTable. 372void allocSecHdrTable();
373 std::error_code writeSecHdrTable();
375 std::error_code compressAndOutput();
377// We will swap the raw_ostream held by LocalBufStream and that 378// held by OutputStream if we try to add a section which needs 379// compression. After the swap, all the data written to output 380// will be temporarily buffered into the underlying raw_string_ostream 381// originally held by LocalBufStream. After the data writing for the 382// section is completed, compress the data in the local buffer, 383// swap the raw_ostream back and write the compressed data to the 385 std::unique_ptr<raw_ostream> LocalBufStream;
386// The location where the output stream starts. 388// The location in the output stream where the SecHdrTable should be 391// The table contains SecHdrTableEntry entries in order of how they are 392// populated in the writer. It may be different from the order in 393// SectionHdrLayout which specifies the sequence in which sections will 395 std::vector<SecHdrTableEntry> SecHdrTable;
397// FuncOffsetTable maps function context to its profile offset in 398// SecLBRProfile section. It is used to load function profile on demand. 400// Whether to use MD5 to represent string. 403 /// CSNameTable maps function context to its offset in SecCSNameTable section. 404 /// The offset will be used everywhere where the context is referenced. 421 std::error_code writeCustomSection(
SecTypeType)
override{
427"Unsupported layout");
431}
// end namespace sampleprof 432}
// end namespace llvm 434#endif// LLVM_PROFILEDATA_SAMPLEPROFWRITER_H Provides ErrorOr<T> smart pointer.
This file implements a map that provides insertion order iteration.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Represents either an error or a value T.
This class implements a map that also provides access to all stored values in a deterministic order.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
The instances of the Type class are immutable: once they are created, they are never changed.
This class implements an extremely fast bulk output stream that can only output to a stream.
void Erase(size_t CurrentOutputSize) override
In this default implementation, functions with fewest samples are dropped first.
This class represents a function that is read from a sample profile.
When writing a profile with size limit, user may want to use a different strategy to reduce function ...
virtual void Erase(size_t CurrentOutputSize)=0
SampleProfileWriter::writeWithSizeLimit() calls this after every write iteration if the output size s...
virtual ~FunctionPruningStrategy()=default
FunctionPruningStrategy(SampleProfileMap &ProfileMap, size_t OutputSizeLimit)
ProfileMap A reference to the original profile map.
SampleProfileMap & ProfileMap
Representation of the samples collected for a function.
ProfileSymbolList records the list of function symbols shown up in the binary used to generate the pr...
This class provides operator overloads to the map container using MD5 as the key type,...
Sample-based profile writer (binary format).
SampleProfileWriterBinary(std::unique_ptr< raw_ostream > &OS)
void stablizeNameTable(MapVector< FunctionId, uint32_t > &NameTable, std::set< FunctionId > &V)
virtual void addContext(const SampleContext &Context)
virtual std::error_code writeNameTable()
virtual std::error_code writeMagicIdent(SampleProfileFormat Format)
std::error_code writeSummary()
MapVector< FunctionId, uint32_t > NameTable
void addNames(const FunctionSamples &S)
virtual std::error_code writeContextIdx(const SampleContext &Context)
std::error_code writeSample(const FunctionSamples &S) override
Write samples of a top-level function to a binary file.
std::error_code writeHeader(const SampleProfileMap &ProfileMap) override
Write a file header for the profile file.
virtual MapVector< FunctionId, uint32_t > & getNameTable()
std::error_code writeBody(const FunctionSamples &S)
std::error_code writeNameIdx(FunctionId FName)
void addName(FunctionId FName)
std::error_code writeNameTableSection(const SampleProfileMap &ProfileMap)
void setUseCtxSplitLayout() override
SmallVector< SecHdrTableEntry, 8 > SectionHdrLayout
void setUseMD5() override
std::error_code writeFuncMetadata(const SampleProfileMap &Profiles)
void setToCompressSection(SecType Type)
virtual std::error_code writeCustomSection(SecType Type)=0
virtual std::error_code writeOneSection(SecType Type, uint32_t LayoutIdx, const SampleProfileMap &ProfileMap)
std::error_code writeFuncOffsetTable()
std::error_code writeCSNameTableSection()
std::error_code writeCSNameIdx(const SampleContext &Context)
virtual void verifySecLayout(SectionLayout SL)=0
void setProfileSymbolList(ProfileSymbolList *PSL) override
void setPartialProfile() override
virtual std::error_code writeSections(const SampleProfileMap &ProfileMap)=0
std::error_code writeNameTable() override
void resetSecLayout(SectionLayout SL)
void addSectionFlag(SecType Type, SecFlagType Flag)
std::error_code writeProfileSymbolListSection()
uint64_t markSectionStart(SecType Type, uint32_t LayoutIdx)
Return the current position and prepare to use it as the start position of a section given the sectio...
void addContext(const SampleContext &Context) override
std::error_code addNewSection(SecType Sec, uint32_t LayoutIdx, uint64_t SectionStart)
Add a new section into section header table given the section type Type, its position LayoutIdx in Se...
void setToCompressAllSections() override
void addSectionFlag(uint32_t SectionIdx, SecFlagType Flag)
uint64_t SecLBRProfileStart
std::error_code write(const SampleProfileMap &ProfileMap) override
Write all the sample profiles in the given map of samples.
std::error_code writeContextIdx(const SampleContext &Context) override
std::error_code writeSample(const FunctionSamples &S) override
Write samples of a top-level function to a binary file.
SampleProfileWriterExtBinary(std::unique_ptr< raw_ostream > &OS)
Sample-based profile writer (text format).
SampleProfileWriterText(std::unique_ptr< raw_ostream > &OS)
std::error_code writeHeader(const SampleProfileMap &ProfileMap) override
Write a file header for the profile file.
void setUseCtxSplitLayout() override
std::error_code writeSample(const FunctionSamples &S) override
Write samples to a text file.
Sample-based profile writer. Base class.
virtual void setUseCtxSplitLayout()
SampleProfileWriter(std::unique_ptr< raw_ostream > &OS)
std::unique_ptr< ProfileSummary > Summary
Profile summary.
virtual std::error_code writeSample(const FunctionSamples &S)=0
Write sample profiles in S.
SampleProfileFormat Format
Profile format.
std::error_code writeWithSizeLimitInternal(SampleProfileMap &ProfileMap, size_t OutputSizeLimit, FunctionPruningStrategy *Strategy)
raw_ostream & getOutputStream()
void computeSummary(const SampleProfileMap &ProfileMap)
Compute summary for this profile.
virtual void setPartialProfile()
virtual std::error_code writeFuncProfiles(const SampleProfileMap &ProfileMap)
std::unique_ptr< raw_ostream > OutputStream
Output stream where to emit the profile to.
virtual void setToCompressAllSections()
std::error_code writeWithSizeLimit(SampleProfileMap &ProfileMap, size_t OutputSizeLimit)
Write sample profiles up to given size limit, using the pruning strategy to drop some functions if ne...
virtual void setProfileSymbolList(ProfileSymbolList *PSL)
size_t LineCount
For writeWithSizeLimit in text mode, each newline takes 1 additional byte on Windows when actually wr...
static ErrorOr< std::unique_ptr< SampleProfileWriter > > create(StringRef Filename, SampleProfileFormat Format)
Profile writer factory.
virtual std::error_code writeHeader(const SampleProfileMap &ProfileMap)=0
Write a file header for the profile file.
virtual ~SampleProfileWriter()=default
virtual std::error_code write(const SampleProfileMap &ProfileMap)
Write all the sample profiles in the given map of samples.
static void addSecFlag(SecHdrTableEntry &Entry, SecFlagType Flag)
const std::array< SmallVector< SecHdrTableEntry, 8 >, NumOfLayout > ExtBinaryHdrLayoutTable
@ SecFlagPartial
SecFlagPartial means the profile is for common/shared code.
This is an optimization pass for GlobalISel generic memory operations.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Implement std::hash so that hash_code can be used in STL containers.