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
@@ -116,15 +125,22 @@ struct PortableMemInfoBlock {
116
125
117
126
// Define getters for each type which can be called by analyses.
118
127
#define MIBEntryDef (NameTag, Name, Type ) \
119
- Type get##Name() const { return Name; }
128
+ Type get##Name() const { \
129
+ assert (Schema[llvm::to_underlying (Meta::Name)]); \
130
+ return Name; \
131
+ }
120
132
#include " llvm/ProfileData/MIBEntryDef.inc"
121
133
#undef MIBEntryDef
122
134
123
135
void clear () { *this = PortableMemInfoBlock (); }
124
136
125
137
bool operator ==(const PortableMemInfoBlock &Other) const {
138
+ if (Other.Schema != Schema)
139
+ return false ;
140
+
126
141
#define MIBEntryDef (NameTag, Name, Type ) \
127
- if (Other.get ##Name () != get##Name ()) \
142
+ if (Schema[llvm::to_underlying (Meta::Name)] && \
143
+ Other.get ##Name () != get##Name ()) \
128
144
return false ;
129
145
#include " llvm/ProfileData/MIBEntryDef.inc"
130
146
#undef MIBEntryDef
@@ -155,6 +171,9 @@ struct PortableMemInfoBlock {
155
171
}
156
172
157
173
private:
174
+ // The set of available fields, indexed by Meta::Name.
175
+ std::bitset<llvm::to_underlying(Meta::Size)> Schema;
176
+
158
177
#define MIBEntryDef (NameTag, Name, Type ) Type Name = Type();
159
178
#include " llvm/ProfileData/MIBEntryDef.inc"
160
179
#undef MIBEntryDef
@@ -296,8 +315,9 @@ struct IndexedAllocationInfo {
296
315
297
316
IndexedAllocationInfo () = default ;
298
317
IndexedAllocationInfo (ArrayRef<FrameId> CS, CallStackId CSId,
299
- const MemInfoBlock &MB)
300
- : CallStack(CS.begin(), CS.end()), CSId(CSId), Info(MB) {}
318
+ const MemInfoBlock &MB,
319
+ const MemProfSchema &Schema = getFullSchema())
320
+ : CallStack(CS.begin(), CS.end()), CSId(CSId), Info(MB, Schema) {}
301
321
302
322
// Returns the size in bytes when this allocation info struct is serialized.
303
323
size_t serializedSize (const MemProfSchema &Schema,
0 commit comments