aboutsummaryrefslogtreecommitdiff
path: root/llvm/unittests/ProfileData/MemProfTest.cpp
diff options
context:
space:
mode:
authorSnehasish Kumar <snehasishk@google.com>2022-02-11 16:28:33 -0800
committerSnehasish Kumar <snehasishk@google.com>2022-02-14 09:53:45 -0800
commit43c2348c5b926df6bdbc5b70efaa35ecdefe12d5 (patch)
treeecd3def2c1d2ef0043c2eb5bbfb3ac7982730867 /llvm/unittests/ProfileData/MemProfTest.cpp
parent14cc41a0206a85d350767f8aff6e02bd4e7dd5d6 (diff)
downloadllvm-43c2348c5b926df6bdbc5b70efaa35ecdefe12d5.zip
llvm-43c2348c5b926df6bdbc5b70efaa35ecdefe12d5.tar.gz
llvm-43c2348c5b926df6bdbc5b70efaa35ecdefe12d5.tar.bz2
[memprof] Extend the index prof format to include memory profiles.
This patch adds support for optional memory profile information to be included with and indexed profile. The indexed profile header adds a new field which points to the offset of the memory profile section (if present) in the indexed profile. For users who do not utilize this feature the only overhead is a 64-bit offset in the header. The memory profile section contains (1) profile metadata describing the information recorded for each entry (2) an on-disk hashtable containing the profile records indexed via llvm::md5(function_name). We chose to introduce a separate hash table instead of the existing one since the indexing for the instrumented fdo hash table is based on a CFG hash which itself is perturbed by memprof instrumentation. Differential Revision: https://reviews.llvm.org/D118653
Diffstat (limited to 'llvm/unittests/ProfileData/MemProfTest.cpp')
-rw-r--r--llvm/unittests/ProfileData/MemProfTest.cpp60
1 files changed, 55 insertions, 5 deletions
diff --git a/llvm/unittests/ProfileData/MemProfTest.cpp b/llvm/unittests/ProfileData/MemProfTest.cpp
index 38dc863..dc79317 100644
--- a/llvm/unittests/ProfileData/MemProfTest.cpp
+++ b/llvm/unittests/ProfileData/MemProfTest.cpp
@@ -89,8 +89,8 @@ const DILineInfoSpecifier specifier() {
DILineInfoSpecifier::FunctionNameKind::LinkageName);
}
-MATCHER_P4(FrameContains, Function, LineOffset, Column, Inline, "") {
- const std::string ExpectedHash = std::to_string(llvm::MD5Hash(Function));
+MATCHER_P4(FrameContains, FunctionName, LineOffset, Column, Inline, "") {
+ const uint64_t ExpectedHash = llvm::Function::getGUID(FunctionName);
if (arg.Function != ExpectedHash) {
*result_listener << "Hash mismatch";
return false;
@@ -103,6 +103,22 @@ MATCHER_P4(FrameContains, Function, LineOffset, Column, Inline, "") {
return false;
}
+MATCHER_P(EqualsRecord, Want, "") {
+ if (arg == Want)
+ return true;
+
+ std::string Explanation;
+ llvm::raw_string_ostream OS(Explanation);
+ OS << "\n Want: \n";
+ Want.print(OS);
+ OS << "\n Got: \n";
+ arg.print(OS);
+ OS.flush();
+
+ *result_listener << Explanation;
+ return false;
+}
+
MemProfSchema getFullSchema() {
MemProfSchema Schema;
#define MIBEntryDef(NameTag, Name, Type) Schema.push_back(Meta::Name);
@@ -179,9 +195,43 @@ TEST(MemProf, PortableWrapper) {
// Here we compare directly with the actual counts instead of MemInfoBlock
// members. Since the MemInfoBlock struct is packed and the EXPECT_EQ macros
// take a reference to the params, this results in unaligned accesses.
- EXPECT_EQ(1, ReadBlock.getAllocCount());
- EXPECT_EQ(7, ReadBlock.getTotalAccessCount());
- EXPECT_EQ(3, ReadBlock.getAllocCpuId());
+ EXPECT_EQ(1UL, ReadBlock.getAllocCount());
+ EXPECT_EQ(7ULL, ReadBlock.getTotalAccessCount());
+ EXPECT_EQ(3UL, ReadBlock.getAllocCpuId());
}
+TEST(MemProf, RecordSerializationRoundTrip) {
+ const MemProfSchema Schema = getFullSchema();
+
+ llvm::SmallVector<MemProfRecord, 3> Records;
+ MemProfRecord MR;
+
+ MemInfoBlock Info(/*size=*/16, /*access_count=*/7, /*alloc_timestamp=*/1000,
+ /*dealloc_timestamp=*/2000, /*alloc_cpu=*/3,
+ /*dealloc_cpu=*/4);
+
+ MR.Info = PortableMemInfoBlock(Info);
+ MR.CallStack.push_back({0x123, 1, 2, false});
+ MR.CallStack.push_back({0x345, 3, 4, false});
+ Records.push_back(MR);
+
+ MR.clear();
+ MR.Info = PortableMemInfoBlock(Info);
+ MR.CallStack.push_back({0x567, 5, 6, false});
+ MR.CallStack.push_back({0x789, 7, 8, false});
+ Records.push_back(MR);
+
+ std::string Buffer;
+ llvm::raw_string_ostream OS(Buffer);
+ serializeRecords(Records, Schema, OS);
+ OS.flush();
+
+ const llvm::SmallVector<MemProfRecord, 4> GotRecords = deserializeRecords(
+ Schema, reinterpret_cast<const unsigned char *>(Buffer.data()));
+
+ ASSERT_TRUE(!GotRecords.empty());
+ EXPECT_EQ(GotRecords.size(), Records.size());
+ EXPECT_THAT(GotRecords[0], EqualsRecord(Records[0]));
+ EXPECT_THAT(GotRecords[1], EqualsRecord(Records[1]));
+}
} // namespace