Skip to content

Commit 9040dd4

Browse files
[memprof] Improve the way we express Frames in YAML (#119629)
This patch does two things: - During deserialization, we accept a function name for Frame as an alternative to the usual GUID expressed as a hexadecimal number. - During serialization, we print a GUID of Frame as a 16-digit hexadecimal number prefixed with 0x in the usual way. (Without this patch, we print a decimal number, which is not customary.) The patch uses a machinery called "normalization" in YAML I/O, which lets us serialize and deserialize into an alternative data structure. For our use case, we have an alternative Frame data structure, which is identical to "struct Frame" except that Function is of type GUIDHex64 instead of GlobalValue::GUID. This alternative type supports the two bullet points above without modifying "struct Frame" at all.
1 parent 9f1e9f6 commit 9040dd4

File tree

4 files changed

+42
-15
lines changed

4 files changed

+42
-15
lines changed

llvm/include/llvm/ProfileData/MemProfYAML.h

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,36 @@ template <> struct ScalarTraits<memprof::GUIDHex64> {
5252
};
5353

5454
template <> struct MappingTraits<memprof::Frame> {
55+
// Essentially the same as memprof::Frame except that Function is of type
56+
// memprof::GUIDHex64 instead of GlobalValue::GUID. This class helps in two
57+
// ways. During serialization, we print Function as a 16-digit hexadecimal
58+
// number. During deserialization, we accept a function name as an
59+
// alternative to the usual GUID expressed as a hexadecimal number.
60+
class FrameWithHex64 {
61+
public:
62+
FrameWithHex64(IO &) {}
63+
FrameWithHex64(IO &, const memprof::Frame &F)
64+
: Function(F.Function), LineOffset(F.LineOffset), Column(F.Column),
65+
IsInlineFrame(F.IsInlineFrame) {}
66+
memprof::Frame denormalize(IO &) {
67+
return memprof::Frame(Function, LineOffset, Column, IsInlineFrame);
68+
}
69+
70+
memprof::GUIDHex64 Function = 0;
71+
static_assert(std::is_same_v<decltype(Function.value),
72+
decltype(memprof::Frame::Function)>);
73+
decltype(memprof::Frame::LineOffset) LineOffset = 0;
74+
decltype(memprof::Frame::Column) Column = 0;
75+
decltype(memprof::Frame::IsInlineFrame) IsInlineFrame = false;
76+
};
77+
5578
static void mapping(IO &Io, memprof::Frame &F) {
56-
Io.mapRequired("Function", F.Function);
57-
Io.mapRequired("LineOffset", F.LineOffset);
58-
Io.mapRequired("Column", F.Column);
59-
Io.mapRequired("IsInlineFrame", F.IsInlineFrame);
79+
MappingNormalization<FrameWithHex64, memprof::Frame> Keys(Io, F);
80+
81+
Io.mapRequired("Function", Keys->Function);
82+
Io.mapRequired("LineOffset", Keys->LineOffset);
83+
Io.mapRequired("Column", Keys->Column);
84+
Io.mapRequired("IsInlineFrame", Keys->IsInlineFrame);
6085

6186
// Assert that the definition of Frame matches what we expect. The
6287
// structured bindings below detect changes to the number of fields.

llvm/test/tools/llvm-profdata/memprof-yaml.test

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,24 +11,24 @@ HeapProfileRecords:
1111
- GUID: 0xdeadbeef12345678
1212
AllocSites:
1313
- Callstack:
14-
- { Function: 100, LineOffset: 11, Column: 10, IsInlineFrame: true }
15-
- { Function: 200, LineOffset: 22, Column: 20, IsInlineFrame: false }
14+
- { Function: 0x1111111111111111, LineOffset: 11, Column: 10, IsInlineFrame: true }
15+
- { Function: 0x2222222222222222, LineOffset: 22, Column: 20, IsInlineFrame: false }
1616
MemInfoBlock:
1717
AllocCount: 111
1818
TotalSize: 222
1919
TotalLifetime: 333
2020
TotalLifetimeAccessDensity: 444
2121
- Callstack:
22-
- { Function: 300, LineOffset: 33, Column: 30, IsInlineFrame: false }
23-
- { Function: 400, LineOffset: 44, Column: 40, IsInlineFrame: true }
22+
- { Function: 0x3333333333333333, LineOffset: 33, Column: 30, IsInlineFrame: false }
23+
- { Function: 0x4444444444444444, LineOffset: 44, Column: 40, IsInlineFrame: true }
2424
MemInfoBlock:
2525
AllocCount: 555
2626
TotalSize: 666
2727
TotalLifetime: 777
2828
TotalLifetimeAccessDensity: 888
2929
CallSites:
30-
- - { Function: 500, LineOffset: 55, Column: 50, IsInlineFrame: true }
31-
- { Function: 600, LineOffset: 66, Column: 60, IsInlineFrame: false }
32-
- - { Function: 700, LineOffset: 77, Column: 70, IsInlineFrame: true }
33-
- { Function: 800, LineOffset: 88, Column: 80, IsInlineFrame: false }
30+
- - { Function: 0x5555555555555555, LineOffset: 55, Column: 50, IsInlineFrame: true }
31+
- { Function: 0x6666666666666666, LineOffset: 66, Column: 60, IsInlineFrame: false }
32+
- - { Function: 0x7777777777777777, LineOffset: 77, Column: 70, IsInlineFrame: true }
33+
- { Function: 0x8888888888888888, LineOffset: 88, Column: 80, IsInlineFrame: false }
3434
...

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3307,7 +3307,9 @@ static int showMemProfProfile(ShowFormat SFormat, raw_fd_ostream &OS) {
33073307

33083308
auto Reader = std::move(ReaderOrErr.get());
33093309
memprof::AllMemProfData Data = Reader->getAllMemProfData();
3310-
yaml::Output Yout(OS);
3310+
// Construct yaml::Output with the maximum column width of 80 so that each
3311+
// Frame fits in one line.
3312+
yaml::Output Yout(OS, nullptr, 80);
33113313
Yout << Data;
33123314

33133315
return 0;

llvm/unittests/ProfileData/MemProfTest.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -804,11 +804,11 @@ template <typename T> std::string serializeInYAML(T &Val) {
804804
}
805805

806806
TEST(MemProf, YAMLWriterFrame) {
807-
Frame F(11, 22, 33, true);
807+
Frame F(0x0123456789abcdefULL, 22, 33, true);
808808

809809
std::string Out = serializeInYAML(F);
810810
EXPECT_EQ(Out, R"YAML(---
811-
{ Function: 11, LineOffset: 22, Column: 33, IsInlineFrame: true }
811+
{ Function: 0x0123456789abcdef, LineOffset: 22, Column: 33, IsInlineFrame: true }
812812
...
813813
)YAML");
814814
}

0 commit comments

Comments
 (0)