5
5
#include < string>
6
6
#include < vector>
7
7
8
+ #include " llvm/ADT/SmallVector.h"
8
9
#include " llvm/ProfileData/MemProfData.inc"
10
+ #include " llvm/ProfileData/ProfileCommon.h"
11
+ #include " llvm/Support/Endian.h"
12
+ #include " llvm/Support/EndianStream.h"
9
13
#include " llvm/Support/raw_ostream.h"
10
14
11
15
namespace llvm {
12
16
namespace memprof {
13
17
18
+ enum class Meta : uint64_t {
19
+ Start = 0 ,
20
+ #define MIBEntryDef (NameTag, Name, Type ) NameTag,
21
+ #include " llvm/ProfileData/MIBEntryDef.inc"
22
+ #undef MIBEntryDef
23
+ Size
24
+ };
25
+
26
+ using MemProfSchema = llvm::SmallVector<Meta, static_cast <int >(Meta::Size)>;
27
+
28
+ // Holds the actual MemInfoBlock data with all fields. Contents may be read or
29
+ // written partially by providing an appropriate schema to the serialize and
30
+ // deserialize methods.
31
+ struct PortableMemInfoBlock {
32
+ PortableMemInfoBlock () = default ;
33
+ explicit PortableMemInfoBlock (const MemInfoBlock &Block) {
34
+ #define MIBEntryDef (NameTag, Name, Type ) Name = Block.Name;
35
+ #include " llvm/ProfileData/MIBEntryDef.inc"
36
+ #undef MIBEntryDef
37
+ }
38
+
39
+ PortableMemInfoBlock (const MemProfSchema &Schema, const unsigned char *Ptr) {
40
+ deserialize (Schema, Ptr);
41
+ }
42
+
43
+ // Read the contents of \p Ptr based on the \p Schema to populate the
44
+ // MemInfoBlock member.
45
+ void deserialize (const MemProfSchema &Schema, const unsigned char *Ptr) {
46
+ using namespace support ;
47
+
48
+ for (const Meta Id : Schema) {
49
+ switch (Id) {
50
+ #define MIBEntryDef (NameTag, Name, Type ) \
51
+ case Meta::Name: { \
52
+ Name = endian::readNext<Type, little, unaligned>(Ptr); \
53
+ } break ;
54
+ #include " llvm/ProfileData/MIBEntryDef.inc"
55
+ #undef MIBEntryDef
56
+ default :
57
+ llvm_unreachable (" Unknown meta type id, is the profile collected from "
58
+ " a newer version of the runtime?" );
59
+ }
60
+ }
61
+ }
62
+
63
+ // Write the contents of the MemInfoBlock based on the \p Schema provided to
64
+ // the raw_ostream \p OS.
65
+ void serialize (const MemProfSchema &Schema, raw_ostream &OS) const {
66
+ using namespace support ;
67
+
68
+ endian::Writer LE (OS, little);
69
+ for (const Meta Id : Schema) {
70
+ switch (Id) {
71
+ #define MIBEntryDef (NameTag, Name, Type ) \
72
+ case Meta::Name: { \
73
+ LE.write <Type>(Name); \
74
+ } break ;
75
+ #include " llvm/ProfileData/MIBEntryDef.inc"
76
+ #undef MIBEntryDef
77
+ default :
78
+ llvm_unreachable (" Unknown meta type id, invalid input?" );
79
+ }
80
+ }
81
+ }
82
+
83
+ // Print out the contents of the MemInfoBlock in YAML format.
84
+ void printYAML (raw_ostream &OS) const {
85
+ OS << " MemInfoBlock:\n " ;
86
+ #define MIBEntryDef (NameTag, Name, Type ) \
87
+ OS << " " << #Name << " : " << Name << " \n " ;
88
+ #include " llvm/ProfileData/MIBEntryDef.inc"
89
+ #undef MIBEntryDef
90
+ }
91
+
92
+ // Define getters for each type which can be called by analyses.
93
+ #define MIBEntryDef (NameTag, Name, Type ) \
94
+ Type get##Name() const { return Name; }
95
+ #include " llvm/ProfileData/MIBEntryDef.inc"
96
+ #undef MIBEntryDef
97
+
98
+ void clear () { *this = PortableMemInfoBlock (); }
99
+
100
+ // Returns the full schema currently in use.
101
+ static MemProfSchema getSchema () {
102
+ MemProfSchema List;
103
+ #define MIBEntryDef (NameTag, Name, Type ) List.push_back(Meta::Name);
104
+ #include " llvm/ProfileData/MIBEntryDef.inc"
105
+ #undef MIBEntryDef
106
+ return List;
107
+ }
108
+
109
+ bool operator ==(const PortableMemInfoBlock &Other) const {
110
+ #define MIBEntryDef (NameTag, Name, Type ) \
111
+ if (Other.get ##Name () != get##Name ()) \
112
+ return false ;
113
+ #include " llvm/ProfileData/MIBEntryDef.inc"
114
+ #undef MIBEntryDef
115
+ return true ;
116
+ }
117
+
118
+ bool operator !=(const PortableMemInfoBlock &Other) const {
119
+ return !operator ==(Other);
120
+ }
121
+
122
+ static constexpr size_t serializedSize () {
123
+ size_t Result = 0 ;
124
+ #define MIBEntryDef (NameTag, Name, Type ) Result += sizeof (Type);
125
+ #include " llvm/ProfileData/MIBEntryDef.inc"
126
+ #undef MIBEntryDef
127
+ return Result;
128
+ }
129
+
130
+ private:
131
+ #define MIBEntryDef (NameTag, Name, Type ) Type Name = Type();
132
+ #include " llvm/ProfileData/MIBEntryDef.inc"
133
+ #undef MIBEntryDef
134
+ };
135
+
14
136
struct MemProfRecord {
15
137
struct Frame {
16
138
std::string Function;
@@ -24,14 +146,11 @@ struct MemProfRecord {
24
146
};
25
147
26
148
std::vector<Frame> CallStack;
27
- // TODO: Replace this with the entry format described in the RFC so
28
- // that the InstrProfRecord reader and writer do not have to be concerned
29
- // about backwards compat.
30
- MemInfoBlock Info;
149
+ PortableMemInfoBlock Info;
31
150
32
151
void clear () {
33
152
CallStack.clear ();
34
- Info = MemInfoBlock ();
153
+ Info. clear ();
35
154
}
36
155
37
156
// Prints out the contents of the memprof record in YAML.
@@ -47,45 +166,7 @@ struct MemProfRecord {
47
166
<< " Inline: " << Frame.IsInlineFrame << " \n " ;
48
167
}
49
168
50
- OS << " MemInfoBlock:\n " ;
51
-
52
- // TODO: Replace this once the format is updated to be version agnostic.
53
- OS << " "
54
- << " AllocCount: " << Info.AllocCount << " \n " ;
55
- OS << " "
56
- << " TotalAccessCount: " << Info.TotalAccessCount << " \n " ;
57
- OS << " "
58
- << " MinAccessCount: " << Info.MinAccessCount << " \n " ;
59
- OS << " "
60
- << " MaxAccessCount: " << Info.MaxAccessCount << " \n " ;
61
- OS << " "
62
- << " TotalSize: " << Info.TotalSize << " \n " ;
63
- OS << " "
64
- << " MinSize: " << Info.MinSize << " \n " ;
65
- OS << " "
66
- << " MaxSize: " << Info.MaxSize << " \n " ;
67
- OS << " "
68
- << " AllocTimestamp: " << Info.AllocTimestamp << " \n " ;
69
- OS << " "
70
- << " DeallocTimestamp: " << Info.DeallocTimestamp << " \n " ;
71
- OS << " "
72
- << " TotalLifetime: " << Info.TotalLifetime << " \n " ;
73
- OS << " "
74
- << " MinLifetime: " << Info.MinLifetime << " \n " ;
75
- OS << " "
76
- << " MaxLifetime: " << Info.MaxLifetime << " \n " ;
77
- OS << " "
78
- << " AllocCpuId: " << Info.AllocCpuId << " \n " ;
79
- OS << " "
80
- << " DeallocCpuId: " << Info.DeallocCpuId << " \n " ;
81
- OS << " "
82
- << " NumMigratedCpu: " << Info.NumMigratedCpu << " \n " ;
83
- OS << " "
84
- << " NumLifetimeOverlaps: " << Info.NumLifetimeOverlaps << " \n " ;
85
- OS << " "
86
- << " NumSameAllocCpu: " << Info.NumSameAllocCpu << " \n " ;
87
- OS << " "
88
- << " NumSameDeallocCpu: " << Info.NumSameDeallocCpu << " \n " ;
169
+ Info.printYAML (OS);
89
170
}
90
171
};
91
172
0 commit comments