[memprof] Extend llvm-profdata to display MemProf profile summaries.
This commit adds initial support to llvm-profdata to read and print
summaries of raw memprof profiles.
Summary of changes:
* Refactor shared defs to MemProfData.inc
* Extend show_main to display memprof profile summaries.
* Add a simple raw memprof profile reader.
* Add a couple of tests to tools/llvm-profdata.
Differential Revision: https://reviews.llvm.org/D114286
GitOrigin-RevId: 7cca33b40f77c2d8bcd4241bcd0e4c45a0209683
diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt
index 7b415f0..2040871 100644
--- a/include/CMakeLists.txt
+++ b/include/CMakeLists.txt
@@ -23,6 +23,7 @@
if (COMPILER_RT_BUILD_MEMPROF)
set(MEMPROF_HEADERS
sanitizer/memprof_interface.h
+ profile/MemProfData.inc
)
endif(COMPILER_RT_BUILD_MEMPROF)
diff --git a/include/profile/MemProfData.inc b/include/profile/MemProfData.inc
new file mode 100644
index 0000000..d64227e
--- /dev/null
+++ b/include/profile/MemProfData.inc
@@ -0,0 +1,61 @@
+#ifndef MEMPROF_DATA_INC
+#define MEMPROF_DATA_INC
+/*===-- MemProfData.inc - MemProf profiling runtime structures -*- C++ -*-=== *\
+|*
+|* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+|* See https://llvm.org/LICENSE.txt for license information.
+|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+|*
+\*===----------------------------------------------------------------------===*/
+/*
+ * This is the main file that defines all the data structure, signature,
+ * constant literals that are shared across profiling runtime library,
+ * and host tools (reader/writer).
+ *
+ * This file has two identical copies. The primary copy lives in LLVM and
+ * the other one sits in compiler-rt/include/profile directory. To make changes
+ * in this file, first modify the primary copy and copy it over to compiler-rt.
+ * Testing of any change in this file can start only after the two copies are
+ * synced up.
+ *
+\*===----------------------------------------------------------------------===*/
+
+
+#ifdef _MSC_VER
+#define PACKED(__decl__) __pragma(pack(push,1)) __decl__ __pragma(pack(pop))
+#else
+#define PACKED(__decl__) __decl__ __attribute__((__packed__))
+#endif
+
+// A 64-bit magic number to uniquely identify the raw binary memprof profile file.
+#define MEMPROF_RAW_MAGIC_64 \
+ ((uint64_t)255 << 56 | (uint64_t)'m' << 48 | (uint64_t)'p' << 40 | (uint64_t)'r' << 32 | \
+ (uint64_t)'o' << 24 | (uint64_t)'f' << 16 | (uint64_t)'r' << 8 | (uint64_t)129)
+
+// The version number of the raw binary format.
+#define MEMPROF_RAW_VERSION 1ULL
+
+namespace llvm {
+namespace memprof {
+// A struct describing the header used for the raw binary memprof profile format.
+PACKED(struct Header {
+ uint64_t Magic;
+ uint64_t Version;
+ uint64_t TotalSize;
+ uint64_t SegmentOffset;
+ uint64_t MIBOffset;
+ uint64_t StackOffset;
+});
+
+// A struct describing the information necessary to describe a /proc/maps
+// segment entry for a particular binary/library identified by its build id.
+PACKED(struct SegmentEntry {
+ uint64_t Start;
+ uint64_t End;
+ uint64_t Offset;
+ uint8_t BuildId[32];
+});
+} // namespace memprof
+} // namespace llvm
+
+#endif
diff --git a/lib/memprof/CMakeLists.txt b/lib/memprof/CMakeLists.txt
index f797610..20d6992 100644
--- a/lib/memprof/CMakeLists.txt
+++ b/lib/memprof/CMakeLists.txt
@@ -46,6 +46,7 @@
)
include_directories(..)
+include_directories(../../include)
set(MEMPROF_CFLAGS ${SANITIZER_COMMON_CFLAGS})
set(MEMPROF_COMMON_DEFINITIONS "")
diff --git a/lib/memprof/memprof_rawprofile.cpp b/lib/memprof/memprof_rawprofile.cpp
index 96f315f..48e579c 100644
--- a/lib/memprof/memprof_rawprofile.cpp
+++ b/lib/memprof/memprof_rawprofile.cpp
@@ -1,5 +1,10 @@
-#include "memprof_rawprofile.h"
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
#include "memprof_meminfoblock.h"
+#include "memprof_rawprofile.h"
+#include "profile/MemProfData.inc"
#include "sanitizer_common/sanitizer_allocator_internal.h"
#include "sanitizer_common/sanitizer_linux.h"
#include "sanitizer_common/sanitizer_procmaps.h"
@@ -8,29 +13,12 @@
#include "sanitizer_common/sanitizer_stacktrace.h"
#include "sanitizer_common/sanitizer_vector.h"
-#include <stdlib.h>
-#include <string.h>
-
namespace __memprof {
using ::__sanitizer::Vector;
+using SegmentEntry = ::llvm::memprof::SegmentEntry;
+using Header = ::llvm::memprof::Header;
namespace {
-typedef struct __attribute__((__packed__)) {
- u64 start;
- u64 end;
- u64 offset;
- u8 buildId[32];
-} SegmentEntry;
-
-typedef struct __attribute__((__packed__)) {
- u64 magic;
- u64 version;
- u64 total_size;
- u64 segment_offset;
- u64 mib_offset;
- u64 stack_offset;
-} Header;
-
template <class T> char *WriteBytes(T Pod, char *&Buffer) {
*(T *)Buffer = Pod;
return Buffer + sizeof(T);
@@ -76,12 +64,12 @@
for (Layout.Reset(); Layout.Next(&segment);) {
if (segment.IsReadable() && segment.IsExecutable()) {
- SegmentEntry entry{};
- entry.start = segment.start;
- entry.end = segment.end;
- entry.offset = segment.offset;
- memcpy(entry.buildId, segment.uuid, sizeof(segment.uuid));
- memcpy(Ptr, &entry, sizeof(SegmentEntry));
+ SegmentEntry Entry{};
+ Entry.Start = segment.start;
+ Entry.End = segment.end;
+ Entry.Offset = segment.offset;
+ memcpy(Entry.BuildId, segment.uuid, sizeof(segment.uuid));
+ memcpy(Ptr, &Entry, sizeof(SegmentEntry));
Ptr += sizeof(SegmentEntry);
NumSegmentsRecorded++;
}
diff --git a/lib/memprof/memprof_rawprofile.h b/lib/memprof/memprof_rawprofile.h
index 052bac3..575104e 100644
--- a/lib/memprof/memprof_rawprofile.h
+++ b/lib/memprof/memprof_rawprofile.h
@@ -5,17 +5,10 @@
#include "sanitizer_common/sanitizer_procmaps.h"
namespace __memprof {
-
-// TODO: pull these in from MemProfData.inc
-#define MEMPROF_RAW_MAGIC_64 \
- (u64)255 << 56 | (u64)'m' << 48 | (u64)'p' << 40 | (u64)'r' << 32 | \
- (u64)'o' << 24 | (u64)'f' << 16 | (u64)'r' << 8 | (u64)129
-
-#define MEMPROF_RAW_VERSION 1ULL
-
+// Serialize the in-memory representation of the memprof profile to the raw
+// binary format. The format itself is documented memprof_rawprofile.cpp.
u64 SerializeToRawProfile(MIBMapTy &BlockCache, MemoryMappingLayoutBase &Layout,
char *&Buffer);
-
} // namespace __memprof
#endif // MEMPROF_RAWPROFILE_H_