aboutsummaryrefslogtreecommitdiff
path: root/llvm/unittests/ProfileData/MemProfTest.cpp
diff options
context:
space:
mode:
authorKazu Hirata <kazu@google.com>2024-05-15 17:53:28 -0700
committerGitHub <noreply@github.com>2024-05-15 17:53:28 -0700
commit26fabdded34f8cea490060a70188a07ad6b76b8b (patch)
tree950e488b0083b66a2fbaf9eca0bee143f3815a77 /llvm/unittests/ProfileData/MemProfTest.cpp
parentc6e787f771d1f9d6a846b2d9b8db6adcd87e8dba (diff)
downloadllvm-26fabdded34f8cea490060a70188a07ad6b76b8b.zip
llvm-26fabdded34f8cea490060a70188a07ad6b76b8b.tar.gz
llvm-26fabdded34f8cea490060a70188a07ad6b76b8b.tar.bz2
[memprof] Pass FrameIdConverter and CallStackIdConverter by reference (#92327)
CallStackIdConverter sets LastUnmappedId when a mapping failure occurs. Now, since toMemProfRecord takes an instance of CallStackIdConverter by value, namely std::function, the caller of toMemProfRecord never receives the mapping failure that occurs inside toMemProfRecord. The same problem applies to FrameIdConverter. The patch fixes the problem by passing FrameIdConverter and CallStackIdConverter by reference, namely llvm::function_ref. While I am it, this patch deletes the copy constructor and copy assignment operator to avoid accidental copies.
Diffstat (limited to 'llvm/unittests/ProfileData/MemProfTest.cpp')
-rw-r--r--llvm/unittests/ProfileData/MemProfTest.cpp66
1 files changed, 66 insertions, 0 deletions
diff --git a/llvm/unittests/ProfileData/MemProfTest.cpp b/llvm/unittests/ProfileData/MemProfTest.cpp
index 8b97866..a913718 100644
--- a/llvm/unittests/ProfileData/MemProfTest.cpp
+++ b/llvm/unittests/ProfileData/MemProfTest.cpp
@@ -596,4 +596,70 @@ TEST(MemProf, IndexedMemProfRecordToMemProfRecord) {
EXPECT_EQ(Record.CallSites[1][0].hash(), F2.hash());
EXPECT_EQ(Record.CallSites[1][1].hash(), F4.hash());
}
+
+using FrameIdMapTy =
+ llvm::DenseMap<::llvm::memprof::FrameId, ::llvm::memprof::Frame>;
+using CallStackIdMapTy =
+ llvm::DenseMap<::llvm::memprof::CallStackId,
+ ::llvm::SmallVector<::llvm::memprof::FrameId>>;
+
+// Populate those fields returned by getHotColdSchema.
+MemInfoBlock makePartialMIB() {
+ MemInfoBlock MIB;
+ MIB.AllocCount = 1;
+ MIB.TotalSize = 5;
+ MIB.TotalLifetime = 10;
+ MIB.TotalLifetimeAccessDensity = 23;
+ return MIB;
+}
+
+TEST(MemProf, MissingCallStackId) {
+ // Use a non-existent CallStackId to trigger a mapping error in
+ // toMemProfRecord.
+ llvm::memprof::IndexedAllocationInfo AI({}, 0xdeadbeefU, makePartialMIB(),
+ llvm::memprof::getHotColdSchema());
+
+ IndexedMemProfRecord IndexedMR;
+ IndexedMR.AllocSites.push_back(AI);
+
+ // Create empty maps.
+ const FrameIdMapTy IdToFrameMap;
+ const CallStackIdMapTy CSIdToCallStackMap;
+ llvm::memprof::FrameIdConverter<decltype(IdToFrameMap)> FrameIdConv(
+ IdToFrameMap);
+ llvm::memprof::CallStackIdConverter<decltype(CSIdToCallStackMap)> CSIdConv(
+ CSIdToCallStackMap, FrameIdConv);
+
+ // We are only interested in errors, not the return value.
+ (void)IndexedMR.toMemProfRecord(CSIdConv);
+
+ ASSERT_TRUE(CSIdConv.LastUnmappedId.has_value());
+ EXPECT_EQ(*CSIdConv.LastUnmappedId, 0xdeadbeefU);
+ EXPECT_EQ(FrameIdConv.LastUnmappedId, std::nullopt);
+}
+
+TEST(MemProf, MissingFrameId) {
+ llvm::memprof::IndexedAllocationInfo AI({}, 0x222, makePartialMIB(),
+ llvm::memprof::getHotColdSchema());
+
+ IndexedMemProfRecord IndexedMR;
+ IndexedMR.AllocSites.push_back(AI);
+
+ // An empty map to trigger a mapping error.
+ const FrameIdMapTy IdToFrameMap;
+ CallStackIdMapTy CSIdToCallStackMap;
+ CSIdToCallStackMap.insert({0x222, {2, 3}});
+
+ llvm::memprof::FrameIdConverter<decltype(IdToFrameMap)> FrameIdConv(
+ IdToFrameMap);
+ llvm::memprof::CallStackIdConverter<decltype(CSIdToCallStackMap)> CSIdConv(
+ CSIdToCallStackMap, FrameIdConv);
+
+ // We are only interested in errors, not the return value.
+ (void)IndexedMR.toMemProfRecord(CSIdConv);
+
+ EXPECT_EQ(CSIdConv.LastUnmappedId, std::nullopt);
+ ASSERT_TRUE(FrameIdConv.LastUnmappedId.has_value());
+ EXPECT_EQ(*FrameIdConv.LastUnmappedId, 3U);
+}
} // namespace