Skip to content

Commit 08ddd2c

Browse files
[PGO] Add support for writing previous indexed format (#84505)
Enable temporary support to ease use of new llvm-profdata with slightly older indexed profiles after 16e74fd, which bumped the indexed format for type profiling.
1 parent 300a39b commit 08ddd2c

File tree

4 files changed

+102
-43
lines changed

4 files changed

+102
-43
lines changed

llvm/include/llvm/ProfileData/InstrProfWriter.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,18 @@ class InstrProfWriter {
6868
// Use raw pointer here for the incomplete type object.
6969
InstrProfRecordWriterTrait *InfoObj;
7070

71+
// Temporary support for writing the previous version of the format, to enable
72+
// some forward compatibility. Currently this suppresses the writing of the
73+
// new vtable names section and header fields.
74+
// TODO: Consider enabling this with future version changes as well, to ease
75+
// deployment of newer versions of llvm-profdata.
76+
bool WritePrevVersion = false;
77+
7178
public:
7279
InstrProfWriter(bool Sparse = false,
7380
uint64_t TemporalProfTraceReservoirSize = 0,
74-
uint64_t MaxTemporalProfTraceLength = 0);
81+
uint64_t MaxTemporalProfTraceLength = 0,
82+
bool WritePrevVersion = false);
7583
~InstrProfWriter();
7684

7785
StringMap<ProfilingData> &getProfileData() { return FunctionData; }

llvm/lib/ProfileData/InstrProfWriter.cpp

Lines changed: 73 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -181,10 +181,12 @@ class InstrProfRecordWriterTrait {
181181

182182
InstrProfWriter::InstrProfWriter(bool Sparse,
183183
uint64_t TemporalProfTraceReservoirSize,
184-
uint64_t MaxTemporalProfTraceLength)
184+
uint64_t MaxTemporalProfTraceLength,
185+
bool WritePrevVersion)
185186
: Sparse(Sparse), MaxTemporalProfTraceLength(MaxTemporalProfTraceLength),
186187
TemporalProfTraceReservoirSize(TemporalProfTraceReservoirSize),
187-
InfoObj(new InstrProfRecordWriterTrait()) {}
188+
InfoObj(new InstrProfRecordWriterTrait()),
189+
WritePrevVersion(WritePrevVersion) {}
188190

189191
InstrProfWriter::~InstrProfWriter() { delete InfoObj; }
190192

@@ -432,7 +434,13 @@ Error InstrProfWriter::writeImpl(ProfOStream &OS) {
432434
// Write the header.
433435
IndexedInstrProf::Header Header;
434436
Header.Magic = IndexedInstrProf::Magic;
435-
Header.Version = IndexedInstrProf::ProfVersion::CurrentVersion;
437+
Header.Version = WritePrevVersion
438+
? IndexedInstrProf::ProfVersion::Version11
439+
: IndexedInstrProf::ProfVersion::CurrentVersion;
440+
// The WritePrevVersion handling will either need to be removed or updated
441+
// if the version is advanced beyond 12.
442+
assert(IndexedInstrProf::ProfVersion::CurrentVersion ==
443+
IndexedInstrProf::ProfVersion::Version12);
436444
if (static_cast<bool>(ProfileKind & InstrProfKind::IRInstrumentation))
437445
Header.Version |= VARIANT_MASK_IR_PROF;
438446
if (static_cast<bool>(ProfileKind & InstrProfKind::ContextSensitive))
@@ -484,7 +492,8 @@ Error InstrProfWriter::writeImpl(ProfOStream &OS) {
484492
OS.write(0);
485493

486494
uint64_t VTableNamesOffset = OS.tell();
487-
OS.write(0);
495+
if (!WritePrevVersion)
496+
OS.write(0);
488497

489498
// Reserve space to write profile summary data.
490499
uint32_t NumEntries = ProfileSummaryBuilder::DefaultCutoffs.size();
@@ -608,27 +617,29 @@ Error InstrProfWriter::writeImpl(ProfOStream &OS) {
608617

609618
uint64_t VTableNamesSectionStart = OS.tell();
610619

611-
// Use a dummy (and uncompressed) string as compressed vtable names and get
612-
// the necessary profile format change in place for version 12.
613-
// TODO: Store the list of vtable names in InstrProfWriter and use the
614-
// real compressed name.
615-
std::string CompressedVTableNames = "VTableNames";
620+
if (!WritePrevVersion) {
621+
// Use a dummy (and uncompressed) string as compressed vtable names and get
622+
// the necessary profile format change in place for version 12.
623+
// TODO: Store the list of vtable names in InstrProfWriter and use the
624+
// real compressed name.
625+
std::string CompressedVTableNames = "VTableNames";
616626

617-
uint64_t CompressedStringLen = CompressedVTableNames.length();
627+
uint64_t CompressedStringLen = CompressedVTableNames.length();
618628

619-
// Record the length of compressed string.
620-
OS.write(CompressedStringLen);
629+
// Record the length of compressed string.
630+
OS.write(CompressedStringLen);
621631

622-
// Write the chars in compressed strings.
623-
for (auto &c : CompressedVTableNames)
624-
OS.writeByte(static_cast<uint8_t>(c));
632+
// Write the chars in compressed strings.
633+
for (auto &c : CompressedVTableNames)
634+
OS.writeByte(static_cast<uint8_t>(c));
625635

626-
// Pad up to a multiple of 8.
627-
// InstrProfReader would read bytes according to 'CompressedStringLen'.
628-
uint64_t PaddedLength = alignTo(CompressedStringLen, 8);
636+
// Pad up to a multiple of 8.
637+
// InstrProfReader would read bytes according to 'CompressedStringLen'.
638+
uint64_t PaddedLength = alignTo(CompressedStringLen, 8);
629639

630-
for (uint64_t K = CompressedStringLen; K < PaddedLength; K++) {
631-
OS.writeByte(0);
640+
for (uint64_t K = CompressedStringLen; K < PaddedLength; K++) {
641+
OS.writeByte(0);
642+
}
632643
}
633644

634645
uint64_t TemporalProfTracesSectionStart = 0;
@@ -662,26 +673,48 @@ Error InstrProfWriter::writeImpl(ProfOStream &OS) {
662673
}
663674
InfoObj->CSSummaryBuilder = nullptr;
664675

665-
// Now do the final patch:
666-
PatchItem PatchItems[] = {
667-
// Patch the Header.HashOffset field.
668-
{HashTableStartFieldOffset, &HashTableStart, 1},
669-
// Patch the Header.MemProfOffset (=0 for profiles without MemProf
670-
// data).
671-
{MemProfSectionOffset, &MemProfSectionStart, 1},
672-
// Patch the Header.BinaryIdSectionOffset.
673-
{BinaryIdSectionOffset, &BinaryIdSectionStart, 1},
674-
// Patch the Header.TemporalProfTracesOffset (=0 for profiles without
675-
// traces).
676-
{TemporalProfTracesOffset, &TemporalProfTracesSectionStart, 1},
677-
{VTableNamesOffset, &VTableNamesSectionStart, 1},
678-
// Patch the summary data.
679-
{SummaryOffset, reinterpret_cast<uint64_t *>(TheSummary.get()),
680-
(int)(SummarySize / sizeof(uint64_t))},
681-
{CSSummaryOffset, reinterpret_cast<uint64_t *>(TheCSSummary.get()),
682-
(int)CSSummarySize}};
683-
684-
OS.patch(PatchItems, std::size(PatchItems));
676+
if (!WritePrevVersion) {
677+
// Now do the final patch:
678+
PatchItem PatchItems[] = {
679+
// Patch the Header.HashOffset field.
680+
{HashTableStartFieldOffset, &HashTableStart, 1},
681+
// Patch the Header.MemProfOffset (=0 for profiles without MemProf
682+
// data).
683+
{MemProfSectionOffset, &MemProfSectionStart, 1},
684+
// Patch the Header.BinaryIdSectionOffset.
685+
{BinaryIdSectionOffset, &BinaryIdSectionStart, 1},
686+
// Patch the Header.TemporalProfTracesOffset (=0 for profiles without
687+
// traces).
688+
{TemporalProfTracesOffset, &TemporalProfTracesSectionStart, 1},
689+
{VTableNamesOffset, &VTableNamesSectionStart, 1},
690+
// Patch the summary data.
691+
{SummaryOffset, reinterpret_cast<uint64_t *>(TheSummary.get()),
692+
(int)(SummarySize / sizeof(uint64_t))},
693+
{CSSummaryOffset, reinterpret_cast<uint64_t *>(TheCSSummary.get()),
694+
(int)CSSummarySize}};
695+
696+
OS.patch(PatchItems, std::size(PatchItems));
697+
} else {
698+
// Now do the final patch:
699+
PatchItem PatchItems[] = {
700+
// Patch the Header.HashOffset field.
701+
{HashTableStartFieldOffset, &HashTableStart, 1},
702+
// Patch the Header.MemProfOffset (=0 for profiles without MemProf
703+
// data).
704+
{MemProfSectionOffset, &MemProfSectionStart, 1},
705+
// Patch the Header.BinaryIdSectionOffset.
706+
{BinaryIdSectionOffset, &BinaryIdSectionStart, 1},
707+
// Patch the Header.TemporalProfTracesOffset (=0 for profiles without
708+
// traces).
709+
{TemporalProfTracesOffset, &TemporalProfTracesSectionStart, 1},
710+
// Patch the summary data.
711+
{SummaryOffset, reinterpret_cast<uint64_t *>(TheSummary.get()),
712+
(int)(SummarySize / sizeof(uint64_t))},
713+
{CSSummaryOffset, reinterpret_cast<uint64_t *>(TheCSSummary.get()),
714+
(int)CSSummarySize}};
715+
716+
OS.patch(PatchItems, std::size(PatchItems));
717+
}
685718

686719
for (const auto &I : FunctionData)
687720
for (const auto &F : I.getValue())
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
Test the profile version.
2+
3+
RUN: llvm-profdata merge -o %t.profdata %p/Inputs/basic.proftext
4+
RUN: llvm-profdata show --profile-version %t.profdata | FileCheck %s
5+
CHECK: Profile version: 12
6+
7+
RUN: llvm-profdata merge -o %t.prev.profdata %p/Inputs/basic.proftext --write-prev-version
8+
RUN: llvm-profdata show --profile-version %t.prev.profdata | FileCheck %s --check-prefix=PREV
9+
PREV: Profile version: 11

llvm/tools/llvm-profdata/llvm-profdata.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,15 @@ cl::opt<bool> DropProfileSymbolList(
291291
cl::desc("Drop the profile symbol list when merging AutoFDO profiles "
292292
"(only meaningful for -sample)"));
293293

294+
// Temporary support for writing the previous version of the format, to enable
295+
// some forward compatibility.
296+
// TODO: Consider enabling this with future version changes as well, to ease
297+
// deployment of newer versions of llvm-profdata.
298+
cl::opt<bool> DoWritePrevVersion(
299+
"write-prev-version", cl::init(false), cl::Hidden,
300+
cl::desc("Write the previous version of indexed format, to enable "
301+
"some forward compatibility."));
302+
294303
// Options specific to overlap subcommand.
295304
cl::opt<std::string> BaseFilename(cl::Positional, cl::Required,
296305
cl::desc("<base profile file>"),
@@ -579,8 +588,8 @@ struct WriterContext {
579588
WriterContext(bool IsSparse, std::mutex &ErrLock,
580589
SmallSet<instrprof_error, 4> &WriterErrorCodes,
581590
uint64_t ReservoirSize = 0, uint64_t MaxTraceLength = 0)
582-
: Writer(IsSparse, ReservoirSize, MaxTraceLength), ErrLock(ErrLock),
583-
WriterErrorCodes(WriterErrorCodes) {}
591+
: Writer(IsSparse, ReservoirSize, MaxTraceLength, DoWritePrevVersion),
592+
ErrLock(ErrLock), WriterErrorCodes(WriterErrorCodes) {}
584593
};
585594

586595
/// Computer the overlap b/w profile BaseFilename and TestFileName,

0 commit comments

Comments
 (0)