2
2
#define LLVM_PROFILEDATA_MEMPROF_H_
3
3
4
4
#include " llvm/ADT/MapVector.h"
5
+ #include " llvm/ADT/STLForwardCompat.h"
5
6
#include " llvm/ADT/STLFunctionalExtras.h"
6
7
#include " llvm/ADT/SmallVector.h"
7
8
#include " llvm/IR/GlobalValue.h"
10
11
#include " llvm/Support/EndianStream.h"
11
12
#include " llvm/Support/raw_ostream.h"
12
13
14
+ #include < bitset>
13
15
#include < cstdint>
14
16
#include < optional>
15
17
@@ -55,7 +57,10 @@ MemProfSchema getHotColdSchema();
55
57
// deserialize methods.
56
58
struct PortableMemInfoBlock {
57
59
PortableMemInfoBlock () = default ;
58
- explicit PortableMemInfoBlock (const MemInfoBlock &Block) {
60
+ explicit PortableMemInfoBlock (const MemInfoBlock &Block,
61
+ const MemProfSchema &IncomingSchema) {
62
+ for (const Meta Id : IncomingSchema)
63
+ Schema.set (llvm::to_underlying (Id));
59
64
#define MIBEntryDef (NameTag, Name, Type ) Name = Block.Name;
60
65
#include " llvm/ProfileData/MIBEntryDef.inc"
61
66
#undef MIBEntryDef
@@ -67,10 +72,12 @@ struct PortableMemInfoBlock {
67
72
68
73
// Read the contents of \p Ptr based on the \p Schema to populate the
69
74
// MemInfoBlock member.
70
- void deserialize (const MemProfSchema &Schema, const unsigned char *Ptr ) {
75
+ void deserialize (const MemProfSchema &IncomingSchema,
76
+ const unsigned char *Ptr ) {
71
77
using namespace support ;
72
78
73
- for (const Meta Id : Schema) {
79
+ Schema.reset ();
80
+ for (const Meta Id : IncomingSchema) {
74
81
switch (Id) {
75
82
#define MIBEntryDef (NameTag, Name, Type ) \
76
83
case Meta::Name: { \
@@ -82,6 +89,8 @@ struct PortableMemInfoBlock {
82
89
llvm_unreachable (" Unknown meta type id, is the profile collected from "
83
90
" a newer version of the runtime?" );
84
91
}
92
+
93
+ Schema.set (llvm::to_underlying (Id));
85
94
}
86
95
}
87
96
@@ -114,17 +123,29 @@ struct PortableMemInfoBlock {
114
123
#undef MIBEntryDef
115
124
}
116
125
126
+ // Return the schema, only for unit tests.
127
+ std::bitset<llvm::to_underlying(Meta::Size )> getSchema () const {
128
+ return Schema;
129
+ }
130
+
117
131
// Define getters for each type which can be called by analyses.
118
132
#define MIBEntryDef (NameTag, Name, Type ) \
119
- Type get##Name() const { return Name; }
133
+ Type get##Name() const { \
134
+ assert (Schema[llvm::to_underlying (Meta::Name)]); \
135
+ return Name; \
136
+ }
120
137
#include " llvm/ProfileData/MIBEntryDef.inc"
121
138
#undef MIBEntryDef
122
139
123
140
void clear () { *this = PortableMemInfoBlock (); }
124
141
125
142
bool operator ==(const PortableMemInfoBlock &Other) const {
143
+ if (Other.Schema != Schema)
144
+ return false ;
145
+
126
146
#define MIBEntryDef (NameTag, Name, Type ) \
127
- if (Other.get ##Name () != get##Name ()) \
147
+ if (Schema[llvm::to_underlying (Meta::Name)] && \
148
+ Other.get ##Name () != get##Name ()) \
128
149
return false ;
129
150
#include " llvm/ProfileData/MIBEntryDef.inc"
130
151
#undef MIBEntryDef
@@ -155,6 +176,9 @@ struct PortableMemInfoBlock {
155
176
}
156
177
157
178
private:
179
+ // The set of available fields, indexed by Meta::Name.
180
+ std::bitset<llvm::to_underlying(Meta::Size )> Schema;
181
+
158
182
#define MIBEntryDef (NameTag, Name, Type ) Type Name = Type();
159
183
#include " llvm/ProfileData/MIBEntryDef.inc"
160
184
#undef MIBEntryDef
@@ -296,8 +320,9 @@ struct IndexedAllocationInfo {
296
320
297
321
IndexedAllocationInfo () = default ;
298
322
IndexedAllocationInfo (ArrayRef<FrameId> CS, CallStackId CSId,
299
- const MemInfoBlock &MB)
300
- : CallStack(CS.begin(), CS.end()), CSId(CSId), Info(MB) {}
323
+ const MemInfoBlock &MB,
324
+ const MemProfSchema &Schema = getFullSchema())
325
+ : CallStack(CS.begin(), CS.end()), CSId(CSId), Info(MB, Schema) {}
301
326
302
327
// Returns the size in bytes when this allocation info struct is serialized.
303
328
size_t serializedSize (const MemProfSchema &Schema,
0 commit comments