Skip to content

Commit 9e89d10

Browse files
[memprof] Add MemProf format Version 3 (#93608)
This patch adds Version 3 for development purposes. For now, this patch adds V3 as a copy of V2. For the most part, this patch adds "case Version3:" wherever "case Version2:" appears. One exception is writeMemProfV3, which is copied from writeMemProfV2 but updated to write out memprof::Version3 to the MemProf header. We'll incrementally modify writeMemProfV3 in subsequent patches.
1 parent c108c1e commit 9e89d10

File tree

6 files changed

+70
-3
lines changed

6 files changed

+70
-3
lines changed

llvm/include/llvm/ProfileData/MemProf.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,12 @@ enum IndexedVersion : uint64_t {
2828
Version1 = 1,
2929
// Version 2: Added a call stack table.
3030
Version2 = 2,
31+
// Version 3: Under development.
32+
Version3 = 3,
3133
};
3234

3335
constexpr uint64_t MinimumSupportedVersion = Version0;
34-
constexpr uint64_t MaximumSupportedVersion = Version2;
36+
constexpr uint64_t MaximumSupportedVersion = Version3;
3537

3638
// Verify that the minimum and maximum satisfy the obvious constraint.
3739
static_assert(MinimumSupportedVersion <= MaximumSupportedVersion);

llvm/lib/ProfileData/InstrProfReader.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1212,7 +1212,8 @@ Error IndexedMemProfReader::deserialize(const unsigned char *Start,
12121212
const uint64_t FirstWord =
12131213
support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
12141214

1215-
if (FirstWord == memprof::Version1 || FirstWord == memprof::Version2) {
1215+
if (FirstWord == memprof::Version1 || FirstWord == memprof::Version2 ||
1216+
FirstWord == memprof::Version3) {
12161217
// Everything is good. We can proceed to deserialize the rest.
12171218
Version = static_cast<memprof::IndexedVersion>(FirstWord);
12181219
} else if (FirstWord >= 24) {
@@ -1559,6 +1560,7 @@ IndexedMemProfReader::getMemProfRecord(const uint64_t FuncNameHash) const {
15591560
"MemProfCallStackTable must not be available");
15601561
return getMemProfRecordV0(IndexedRecord, *MemProfFrameTable);
15611562
case memprof::Version2:
1563+
case memprof::Version3:
15621564
assert(MemProfFrameTable && "MemProfFrameTable must be available");
15631565
assert(MemProfCallStackTable && "MemProfCallStackTable must be available");
15641566
return getMemProfRecordV2(IndexedRecord, *MemProfFrameTable,

llvm/lib/ProfileData/InstrProfWriter.cpp

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,56 @@ static Error writeMemProfV2(ProfOStream &OS,
617617
return Error::success();
618618
}
619619

620+
// Write out MemProf Version3 as follows:
621+
// uint64_t Version
622+
// uint64_t RecordTableOffset = RecordTableGenerator.Emit
623+
// uint64_t FramePayloadOffset = Offset for the frame payload
624+
// uint64_t FrameTableOffset = FrameTableGenerator.Emit
625+
// uint64_t CallStackPayloadOffset = Offset for the call stack payload
626+
// uint64_t CallStackTableOffset = CallStackTableGenerator.Emit
627+
// uint64_t Num schema entries
628+
// uint64_t Schema entry 0
629+
// uint64_t Schema entry 1
630+
// ....
631+
// uint64_t Schema entry N - 1
632+
// OnDiskChainedHashTable MemProfRecordData
633+
// OnDiskChainedHashTable MemProfFrameData
634+
// OnDiskChainedHashTable MemProfCallStackData
635+
static Error writeMemProfV3(ProfOStream &OS,
636+
memprof::IndexedMemProfData &MemProfData,
637+
bool MemProfFullSchema) {
638+
OS.write(memprof::Version3);
639+
uint64_t HeaderUpdatePos = OS.tell();
640+
OS.write(0ULL); // Reserve space for the memprof record table offset.
641+
OS.write(0ULL); // Reserve space for the memprof frame payload offset.
642+
OS.write(0ULL); // Reserve space for the memprof frame table offset.
643+
OS.write(0ULL); // Reserve space for the memprof call stack payload offset.
644+
OS.write(0ULL); // Reserve space for the memprof call stack table offset.
645+
646+
auto Schema = memprof::getHotColdSchema();
647+
if (MemProfFullSchema)
648+
Schema = memprof::getFullSchema();
649+
writeMemProfSchema(OS, Schema);
650+
651+
uint64_t RecordTableOffset = writeMemProfRecords(OS, MemProfData.RecordData,
652+
&Schema, memprof::Version3);
653+
654+
uint64_t FramePayloadOffset = OS.tell();
655+
uint64_t FrameTableOffset = writeMemProfFrames(OS, MemProfData.FrameData);
656+
657+
uint64_t CallStackPayloadOffset = OS.tell();
658+
uint64_t CallStackTableOffset =
659+
writeMemProfCallStacks(OS, MemProfData.CallStackData);
660+
661+
uint64_t Header[] = {
662+
RecordTableOffset, FramePayloadOffset, FrameTableOffset,
663+
CallStackPayloadOffset, CallStackTableOffset,
664+
};
665+
OS.patch({{HeaderUpdatePos, Header, std::size(Header)}});
666+
667+
return Error::success();
668+
}
669+
620670
// Write out the MemProf data in a requested version.
621671
static Error writeMemProf(ProfOStream &OS,
622672
memprof::IndexedMemProfData &MemProfData,
@@ -629,6 +679,8 @@ static Error writeMemProf(ProfOStream &OS,
629679
return writeMemProfV1(OS, MemProfData);
630680
case memprof::Version2:
631681
return writeMemProfV2(OS, MemProfData, MemProfFullSchema);
682+
case memprof::Version3:
683+
return writeMemProfV3(OS, MemProfData, MemProfFullSchema);
632684
}
633685

634686
return make_error<InstrProfError>(

llvm/lib/ProfileData/MemProf.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ size_t IndexedAllocationInfo::serializedSize(const MemProfSchema &Schema,
5252
case Version1:
5353
return serializedSizeV0(*this, Schema);
5454
case Version2:
55+
case Version3:
5556
return serializedSizeV2(*this, Schema);
5657
}
5758
llvm_unreachable("unsupported MemProf version");
@@ -95,6 +96,7 @@ size_t IndexedMemProfRecord::serializedSize(const MemProfSchema &Schema,
9596
case Version1:
9697
return serializedSizeV0(*this, Schema);
9798
case Version2:
99+
case Version3:
98100
return serializedSizeV2(*this, Schema);
99101
}
100102
llvm_unreachable("unsupported MemProf version");
@@ -149,6 +151,7 @@ void IndexedMemProfRecord::serialize(const MemProfSchema &Schema,
149151
serializeV0(*this, Schema, OS);
150152
return;
151153
case Version2:
154+
case Version3:
152155
serializeV2(*this, Schema, OS);
153156
return;
154157
}
@@ -239,6 +242,7 @@ IndexedMemProfRecord::deserialize(const MemProfSchema &Schema,
239242
case Version1:
240243
return deserializeV0(Schema, Ptr);
241244
case Version2:
245+
case Version3:
242246
return deserializeV2(Schema, Ptr);
243247
}
244248
llvm_unreachable("unsupported MemProf version");

llvm/test/tools/llvm-profdata/memprof-merge-versions.test

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ RUN: llvm-profdata show %t.prof.v2 | FileCheck %s
1919
RUN: llvm-profdata merge %t.proftext %p/Inputs/basic.memprofraw --memprof-version=2 --memprof-full-schema --profiled-binary %p/Inputs/basic.memprofexe -o %t.prof.v2
2020
RUN: llvm-profdata show %t.prof.v2 | FileCheck %s
2121

22+
RUN: llvm-profdata merge %t.proftext %p/Inputs/basic.memprofraw --memprof-version=3 --profiled-binary %p/Inputs/basic.memprofexe -o %t.prof.v3
23+
RUN: llvm-profdata show %t.prof.v3 | FileCheck %s
24+
25+
RUN: llvm-profdata merge %t.proftext %p/Inputs/basic.memprofraw --memprof-version=3 --memprof-full-schema --profiled-binary %p/Inputs/basic.memprofexe -o %t.prof.v3
26+
RUN: llvm-profdata show %t.prof.v3 | FileCheck %s
27+
2228
For now we only check the validity of the instrumented profile since we don't
2329
have a way to display the contents of the memprof indexed format yet.
2430

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,8 @@ cl::opt<memprof::IndexedVersion> MemProfVersionRequested(
306306
cl::init(memprof::Version0),
307307
cl::values(clEnumValN(memprof::Version0, "0", "version 0"),
308308
clEnumValN(memprof::Version1, "1", "version 1"),
309-
clEnumValN(memprof::Version2, "2", "version 2")));
309+
clEnumValN(memprof::Version2, "2", "version 2"),
310+
clEnumValN(memprof::Version3, "3", "version 3")));
310311

311312
cl::opt<bool> MemProfFullSchema(
312313
"memprof-full-schema", cl::Hidden, cl::sub(MergeSubcommand),

0 commit comments

Comments
 (0)