aboutsummaryrefslogtreecommitdiff
path: root/llvm/unittests/ProfileData/InstrProfTest.cpp
diff options
context:
space:
mode:
authorKazu Hirata <kazu@google.com>2024-04-24 16:25:35 -0700
committerGitHub <noreply@github.com>2024-04-24 16:25:35 -0700
commit4c8ec8f8bc3fb4dda4fd36c3b2ad745bd3451970 (patch)
tree3384d9cefc7483edb02684c76014451f3d37c76c /llvm/unittests/ProfileData/InstrProfTest.cpp
parenta10d67f9fb559d0c35a12b2d26974636bbf642c0 (diff)
downloadllvm-4c8ec8f8bc3fb4dda4fd36c3b2ad745bd3451970.zip
llvm-4c8ec8f8bc3fb4dda4fd36c3b2ad745bd3451970.tar.gz
llvm-4c8ec8f8bc3fb4dda4fd36c3b2ad745bd3451970.tar.bz2
[memprof] Reduce schema for Version2 (#89876)
Curently, the compiler only uses several fields of MemoryInfoBlock. Serializing all fields into the indexed MemProf file simply wastes storage. This patch limits the schema down to four fields for Version2 by default. It retains the old behavior of serializing all fields via: llvm-profdata merge --memprof-version=2 --memprof-full-schema This patch reduces the size of the indexed MemProf profile I have by 40% (1.6GB down to 1.0GB).
Diffstat (limited to 'llvm/unittests/ProfileData/InstrProfTest.cpp')
-rw-r--r--llvm/unittests/ProfileData/InstrProfTest.cpp142
1 files changed, 109 insertions, 33 deletions
diff --git a/llvm/unittests/ProfileData/InstrProfTest.cpp b/llvm/unittests/ProfileData/InstrProfTest.cpp
index 73ba0a2..edc427d 100644
--- a/llvm/unittests/ProfileData/InstrProfTest.cpp
+++ b/llvm/unittests/ProfileData/InstrProfTest.cpp
@@ -370,12 +370,31 @@ static CallStackIdMapTy getCallStackMapping() {
return Mapping;
}
+// Populate all of the fields of MIB.
+MemInfoBlock makeFullMIB() {
+ MemInfoBlock MIB;
+#define MIBEntryDef(NameTag, Name, Type) MIB.NameTag;
+#include "llvm/ProfileData/MIBEntryDef.inc"
+#undef MIBEntryDef
+ return MIB;
+}
+
+// Populate those fields returned by getHotColdSchema.
+MemInfoBlock makePartialMIB() {
+ MemInfoBlock MIB;
+ MIB.AllocCount = 1;
+ MIB.TotalSize = 5;
+ MIB.TotalLifetime = 10;
+ MIB.TotalLifetimeAccessDensity = 23;
+ return MIB;
+}
+
IndexedMemProfRecord makeRecord(
std::initializer_list<std::initializer_list<::llvm::memprof::FrameId>>
AllocFrames,
std::initializer_list<std::initializer_list<::llvm::memprof::FrameId>>
CallSiteFrames,
- const MemInfoBlock &Block = MemInfoBlock()) {
+ const MemInfoBlock &Block = makeFullMIB()) {
llvm::memprof::IndexedMemProfRecord MR;
for (const auto &Frames : AllocFrames)
MR.AllocSites.emplace_back(Frames, llvm::memprof::hashCallStack(Frames),
@@ -388,7 +407,7 @@ IndexedMemProfRecord makeRecord(
IndexedMemProfRecord
makeRecordV2(std::initializer_list<::llvm::memprof::CallStackId> AllocFrames,
std::initializer_list<::llvm::memprof::CallStackId> CallSiteFrames,
- const MemInfoBlock &Block = MemInfoBlock()) {
+ const MemInfoBlock &Block) {
llvm::memprof::IndexedMemProfRecord MR;
for (const auto &CSId : AllocFrames)
// We don't populate IndexedAllocationInfo::CallStack because we use it only
@@ -476,15 +495,56 @@ TEST_F(InstrProfTest, test_memprof_v0) {
EXPECT_THAT(WantRecord, EqualsRecord(Record));
}
-TEST_F(InstrProfTest, test_memprof_v2) {
+struct CallStackIdConverter {
+ std::optional<memprof::FrameId> LastUnmappedFrameId;
+ std::optional<memprof::CallStackId> LastUnmappedCSId;
+
+ const FrameIdMapTy &IdToFrameMap;
+ const CallStackIdMapTy &CSIdToCallStackMap;
+
+ CallStackIdConverter() = delete;
+ CallStackIdConverter(const FrameIdMapTy &IdToFrameMap,
+ const CallStackIdMapTy &CSIdToCallStackMap)
+ : IdToFrameMap(IdToFrameMap), CSIdToCallStackMap(CSIdToCallStackMap) {}
+
+ llvm::SmallVector<memprof::Frame>
+ operator()(::llvm::memprof::CallStackId CSId) {
+ auto IdToFrameCallback = [&](const memprof::FrameId Id) {
+ auto Iter = IdToFrameMap.find(Id);
+ if (Iter == IdToFrameMap.end()) {
+ LastUnmappedFrameId = Id;
+ return memprof::Frame(0, 0, 0, false);
+ }
+ return Iter->second;
+ };
+
+ llvm::SmallVector<memprof::Frame> Frames;
+ auto CSIter = CSIdToCallStackMap.find(CSId);
+ if (CSIter == CSIdToCallStackMap.end()) {
+ LastUnmappedCSId = CSId;
+ } else {
+ const ::llvm::SmallVector<::llvm::memprof::FrameId> &CS =
+ CSIter->getSecond();
+ Frames.reserve(CS.size());
+ for (::llvm::memprof::FrameId Id : CS)
+ Frames.push_back(IdToFrameCallback(Id));
+ }
+ return Frames;
+ }
+};
+
+TEST_F(InstrProfTest, test_memprof_v2_full_schema) {
+ const MemInfoBlock MIB = makeFullMIB();
+
Writer.setMemProfVersionRequested(memprof::Version2);
+ Writer.setMemProfFullSchema(true);
ASSERT_THAT_ERROR(Writer.mergeProfileKind(InstrProfKind::MemProf),
Succeeded());
const IndexedMemProfRecord IndexedMR = makeRecordV2(
/*AllocFrames=*/{0x111, 0x222},
- /*CallSiteFrames=*/{0x333});
+ /*CallSiteFrames=*/{0x333}, MIB);
const FrameIdMapTy IdToFrameMap = getFrameMapping();
const auto CSIdToCallStackMap = getCallStackMapping();
for (const auto &I : IdToFrameMap) {
@@ -502,38 +562,54 @@ TEST_F(InstrProfTest, test_memprof_v2) {
ASSERT_THAT_ERROR(RecordOr.takeError(), Succeeded());
const memprof::MemProfRecord &Record = RecordOr.get();
- std::optional<memprof::FrameId> LastUnmappedFrameId;
- auto IdToFrameCallback = [&](const memprof::FrameId Id) {
- auto Iter = IdToFrameMap.find(Id);
- if (Iter == IdToFrameMap.end()) {
- LastUnmappedFrameId = Id;
- return memprof::Frame(0, 0, 0, false);
- }
- return Iter->second;
- };
+ CallStackIdConverter CSIdConv(IdToFrameMap, CSIdToCallStackMap);
- std::optional<::llvm::memprof::CallStackId> LastUnmappedCSId;
- auto CSIdToCallStackCallback = [&](::llvm::memprof::CallStackId CSId) {
- llvm::SmallVector<memprof::Frame> Frames;
- auto CSIter = CSIdToCallStackMap.find(CSId);
- if (CSIter == CSIdToCallStackMap.end()) {
- LastUnmappedCSId = CSId;
- } else {
- const ::llvm::SmallVector<::llvm::memprof::FrameId> &CS =
- CSIter->getSecond();
- Frames.reserve(CS.size());
- for (::llvm::memprof::FrameId Id : CS)
- Frames.push_back(IdToFrameCallback(Id));
- }
- return Frames;
- };
+ const ::llvm::memprof::MemProfRecord WantRecord =
+ IndexedMR.toMemProfRecord(CSIdConv);
+ ASSERT_EQ(CSIdConv.LastUnmappedFrameId, std::nullopt)
+ << "could not map frame id: " << *CSIdConv.LastUnmappedFrameId;
+ ASSERT_EQ(CSIdConv.LastUnmappedCSId, std::nullopt)
+ << "could not map call stack id: " << *CSIdConv.LastUnmappedCSId;
+ EXPECT_THAT(WantRecord, EqualsRecord(Record));
+}
+
+TEST_F(InstrProfTest, test_memprof_v2_partial_schema) {
+ const MemInfoBlock MIB = makePartialMIB();
+
+ Writer.setMemProfVersionRequested(memprof::Version2);
+ Writer.setMemProfFullSchema(false);
+
+ ASSERT_THAT_ERROR(Writer.mergeProfileKind(InstrProfKind::MemProf),
+ Succeeded());
+
+ const IndexedMemProfRecord IndexedMR = makeRecordV2(
+ /*AllocFrames=*/{0x111, 0x222},
+ /*CallSiteFrames=*/{0x333}, MIB);
+ const FrameIdMapTy IdToFrameMap = getFrameMapping();
+ const auto CSIdToCallStackMap = getCallStackMapping();
+ for (const auto &I : IdToFrameMap) {
+ Writer.addMemProfFrame(I.first, I.getSecond(), Err);
+ }
+ for (const auto &I : CSIdToCallStackMap) {
+ Writer.addMemProfCallStack(I.first, I.getSecond(), Err);
+ }
+ Writer.addMemProfRecord(/*Id=*/0x9999, IndexedMR);
+
+ auto Profile = Writer.writeBuffer();
+ readProfile(std::move(Profile));
+
+ auto RecordOr = Reader->getMemProfRecord(0x9999);
+ ASSERT_THAT_ERROR(RecordOr.takeError(), Succeeded());
+ const memprof::MemProfRecord &Record = RecordOr.get();
+
+ CallStackIdConverter CSIdConv(IdToFrameMap, CSIdToCallStackMap);
const ::llvm::memprof::MemProfRecord WantRecord =
- IndexedMR.toMemProfRecord(CSIdToCallStackCallback);
- ASSERT_EQ(LastUnmappedFrameId, std::nullopt)
- << "could not map frame id: " << *LastUnmappedFrameId;
- ASSERT_EQ(LastUnmappedCSId, std::nullopt)
- << "could not map call stack id: " << *LastUnmappedCSId;
+ IndexedMR.toMemProfRecord(CSIdConv);
+ ASSERT_EQ(CSIdConv.LastUnmappedFrameId, std::nullopt)
+ << "could not map frame id: " << *CSIdConv.LastUnmappedFrameId;
+ ASSERT_EQ(CSIdConv.LastUnmappedCSId, std::nullopt)
+ << "could not map call stack id: " << *CSIdConv.LastUnmappedCSId;
EXPECT_THAT(WantRecord, EqualsRecord(Record));
}