]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/include/llvm/XRay/FDRRecords.h
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / include / llvm / XRay / FDRRecords.h
1 //===- FDRRecords.h - XRay Flight Data Recorder Mode Records --------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // Define types and operations on these types that represent the different kinds
11 // of records we encounter in XRay flight data recorder mode traces.
12 //
13 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_LIB_XRAY_FDRRECORDS_H_
15 #define LLVM_LIB_XRAY_FDRRECORDS_H_
16
17 #include <cstdint>
18 #include <string>
19
20 #include "llvm/ADT/StringRef.h"
21 #include "llvm/Support/Casting.h"
22 #include "llvm/Support/DataExtractor.h"
23 #include "llvm/Support/Error.h"
24 #include "llvm/XRay/XRayRecord.h"
25
26 namespace llvm {
27 namespace xray {
28
29 class RecordVisitor;
30 class RecordInitializer;
31
32 class Record {
33 public:
34   enum class RecordKind {
35     RK_Metadata,
36     RK_Metadata_BufferExtents,
37     RK_Metadata_WallClockTime,
38     RK_Metadata_NewCPUId,
39     RK_Metadata_TSCWrap,
40     RK_Metadata_CustomEvent,
41     RK_Metadata_CustomEventV5,
42     RK_Metadata_CallArg,
43     RK_Metadata_PIDEntry,
44     RK_Metadata_NewBuffer,
45     RK_Metadata_EndOfBuffer,
46     RK_Metadata_TypedEvent,
47     RK_Metadata_LastMetadata,
48     RK_Function,
49   };
50
51   static StringRef kindToString(RecordKind K);
52
53 private:
54   const RecordKind T;
55
56 public:
57   Record(const Record &) = delete;
58   Record(Record &&) = delete;
59   Record &operator=(const Record &) = delete;
60   Record &operator=(Record &&) = delete;
61   explicit Record(RecordKind T) : T(T) {}
62
63   RecordKind getRecordType() const { return T; }
64
65   // Each Record should be able to apply an abstract visitor, and choose the
66   // appropriate function in the visitor to invoke, given its own type.
67   virtual Error apply(RecordVisitor &V) = 0;
68
69   virtual ~Record() = default;
70 };
71
72 class MetadataRecord : public Record {
73 public:
74   enum class MetadataType : unsigned {
75     Unknown,
76     BufferExtents,
77     WallClockTime,
78     NewCPUId,
79     TSCWrap,
80     CustomEvent,
81     CallArg,
82     PIDEntry,
83     NewBuffer,
84     EndOfBuffer,
85     TypedEvent,
86   };
87
88 protected:
89   static constexpr int kMetadataBodySize = 15;
90   friend class RecordInitializer;
91
92 private:
93   const MetadataType MT;
94
95 public:
96   explicit MetadataRecord(RecordKind T, MetadataType M) : Record(T), MT(M) {}
97
98   static bool classof(const Record *R) {
99     return R->getRecordType() >= RecordKind::RK_Metadata &&
100            R->getRecordType() <= RecordKind::RK_Metadata_LastMetadata;
101   }
102
103   MetadataType metadataType() const { return MT; }
104
105   virtual ~MetadataRecord() = default;
106 };
107
108 // What follows are specific Metadata record types which encapsulate the
109 // information associated with specific metadata record types in an FDR mode
110 // log.
111 class BufferExtents : public MetadataRecord {
112   uint64_t Size = 0;
113   friend class RecordInitializer;
114
115 public:
116   BufferExtents()
117       : MetadataRecord(RecordKind::RK_Metadata_BufferExtents,
118                        MetadataType::BufferExtents) {}
119
120   explicit BufferExtents(uint64_t S)
121       : MetadataRecord(RecordKind::RK_Metadata_BufferExtents,
122                        MetadataType::BufferExtents),
123         Size(S) {}
124
125   uint64_t size() const { return Size; }
126
127   Error apply(RecordVisitor &V) override;
128
129   static bool classof(const Record *R) {
130     return R->getRecordType() == RecordKind::RK_Metadata_BufferExtents;
131   }
132 };
133
134 class WallclockRecord : public MetadataRecord {
135   uint64_t Seconds = 0;
136   uint32_t Nanos = 0;
137   friend class RecordInitializer;
138
139 public:
140   WallclockRecord()
141       : MetadataRecord(RecordKind::RK_Metadata_WallClockTime,
142                        MetadataType::WallClockTime) {}
143
144   explicit WallclockRecord(uint64_t S, uint32_t N)
145       : MetadataRecord(RecordKind::RK_Metadata_WallClockTime,
146                        MetadataType::WallClockTime),
147         Seconds(S), Nanos(N) {}
148
149   uint64_t seconds() const { return Seconds; }
150   uint32_t nanos() const { return Nanos; }
151
152   Error apply(RecordVisitor &V) override;
153
154   static bool classof(const Record *R) {
155     return R->getRecordType() == RecordKind::RK_Metadata_WallClockTime;
156   }
157 };
158
159 class NewCPUIDRecord : public MetadataRecord {
160   uint16_t CPUId = 0;
161   uint64_t TSC = 0;
162   friend class RecordInitializer;
163
164 public:
165   NewCPUIDRecord()
166       : MetadataRecord(RecordKind::RK_Metadata_NewCPUId,
167                        MetadataType::NewCPUId) {}
168
169   NewCPUIDRecord(uint16_t C, uint64_t T)
170       : MetadataRecord(RecordKind::RK_Metadata_NewCPUId,
171                        MetadataType::NewCPUId),
172         CPUId(C), TSC(T) {}
173
174   uint16_t cpuid() const { return CPUId; }
175
176   uint64_t tsc() const { return TSC; }
177
178   Error apply(RecordVisitor &V) override;
179
180   static bool classof(const Record *R) {
181     return R->getRecordType() == RecordKind::RK_Metadata_NewCPUId;
182   }
183 };
184
185 class TSCWrapRecord : public MetadataRecord {
186   uint64_t BaseTSC = 0;
187   friend class RecordInitializer;
188
189 public:
190   TSCWrapRecord()
191       : MetadataRecord(RecordKind::RK_Metadata_TSCWrap, MetadataType::TSCWrap) {
192   }
193
194   explicit TSCWrapRecord(uint64_t B)
195       : MetadataRecord(RecordKind::RK_Metadata_TSCWrap, MetadataType::TSCWrap),
196         BaseTSC(B) {}
197
198   uint64_t tsc() const { return BaseTSC; }
199
200   Error apply(RecordVisitor &V) override;
201
202   static bool classof(const Record *R) {
203     return R->getRecordType() == RecordKind::RK_Metadata_TSCWrap;
204   }
205 };
206
207 class CustomEventRecord : public MetadataRecord {
208   int32_t Size = 0;
209   uint64_t TSC = 0;
210   uint16_t CPU = 0;
211   std::string Data{};
212   friend class RecordInitializer;
213
214 public:
215   CustomEventRecord()
216       : MetadataRecord(RecordKind::RK_Metadata_CustomEvent,
217                        MetadataType::CustomEvent) {}
218
219   explicit CustomEventRecord(uint64_t S, uint64_t T, uint16_t C, std::string D)
220       : MetadataRecord(RecordKind::RK_Metadata_CustomEvent,
221                        MetadataType::CustomEvent),
222         Size(S), TSC(T), CPU(C), Data(std::move(D)) {}
223
224   int32_t size() const { return Size; }
225   uint64_t tsc() const { return TSC; }
226   uint16_t cpu() const { return CPU; }
227   StringRef data() const { return Data; }
228
229   Error apply(RecordVisitor &V) override;
230
231   static bool classof(const Record *R) {
232     return R->getRecordType() == RecordKind::RK_Metadata_CustomEvent;
233   }
234 };
235
236 class CustomEventRecordV5 : public MetadataRecord {
237   int32_t Size = 0;
238   int32_t Delta = 0;
239   std::string Data{};
240   friend class RecordInitializer;
241
242 public:
243   CustomEventRecordV5()
244       : MetadataRecord(RecordKind::RK_Metadata_CustomEventV5,
245                        MetadataType::CustomEvent) {}
246
247   explicit CustomEventRecordV5(int32_t S, int32_t D, std::string P)
248       : MetadataRecord(RecordKind::RK_Metadata_CustomEventV5,
249                        MetadataType::CustomEvent),
250         Size(S), Delta(D), Data(std::move(P)) {}
251
252   int32_t size() const { return Size; }
253   int32_t delta() const { return Delta; }
254   StringRef data() const { return Data; }
255
256   Error apply(RecordVisitor &V) override;
257
258   static bool classof(const Record *R) {
259     return R->getRecordType() == RecordKind::RK_Metadata_CustomEventV5;
260   }
261 };
262
263 class TypedEventRecord : public MetadataRecord {
264   int32_t Size = 0;
265   int32_t Delta = 0;
266   uint16_t EventType = 0;
267   std::string Data{};
268   friend class RecordInitializer;
269
270 public:
271   TypedEventRecord()
272       : MetadataRecord(RecordKind::RK_Metadata_TypedEvent,
273                        MetadataType::TypedEvent) {}
274
275   explicit TypedEventRecord(int32_t S, int32_t D, uint16_t E, std::string P)
276       : MetadataRecord(RecordKind::RK_Metadata_TypedEvent,
277                        MetadataType::TypedEvent),
278         Size(S), Delta(D), Data(std::move(P)) {}
279
280   int32_t size() const { return Size; }
281   int32_t delta() const { return Delta; }
282   uint16_t eventType() const { return EventType; }
283   StringRef data() const { return Data; }
284
285   Error apply(RecordVisitor &V) override;
286
287   static bool classof(const Record *R) {
288     return R->getRecordType() == RecordKind::RK_Metadata_TypedEvent;
289   }
290 };
291
292 class CallArgRecord : public MetadataRecord {
293   uint64_t Arg;
294   friend class RecordInitializer;
295
296 public:
297   CallArgRecord()
298       : MetadataRecord(RecordKind::RK_Metadata_CallArg, MetadataType::CallArg) {
299   }
300
301   explicit CallArgRecord(uint64_t A)
302       : MetadataRecord(RecordKind::RK_Metadata_CallArg, MetadataType::CallArg),
303         Arg(A) {}
304
305   uint64_t arg() const { return Arg; }
306
307   Error apply(RecordVisitor &V) override;
308
309   static bool classof(const Record *R) {
310     return R->getRecordType() == RecordKind::RK_Metadata_CallArg;
311   }
312 };
313
314 class PIDRecord : public MetadataRecord {
315   int32_t PID = 0;
316   friend class RecordInitializer;
317
318 public:
319   PIDRecord()
320       : MetadataRecord(RecordKind::RK_Metadata_PIDEntry,
321                        MetadataType::PIDEntry) {}
322
323   explicit PIDRecord(int32_t P)
324       : MetadataRecord(RecordKind::RK_Metadata_PIDEntry,
325                        MetadataType::PIDEntry),
326         PID(P) {}
327
328   int32_t pid() const { return PID; }
329
330   Error apply(RecordVisitor &V) override;
331
332   static bool classof(const Record *R) {
333     return R->getRecordType() == RecordKind::RK_Metadata_PIDEntry;
334   }
335 };
336
337 class NewBufferRecord : public MetadataRecord {
338   int32_t TID = 0;
339   friend class RecordInitializer;
340
341 public:
342   NewBufferRecord()
343       : MetadataRecord(RecordKind::RK_Metadata_NewBuffer,
344                        MetadataType::NewBuffer) {}
345
346   explicit NewBufferRecord(int32_t T)
347       : MetadataRecord(RecordKind::RK_Metadata_NewBuffer,
348                        MetadataType::NewBuffer),
349         TID(T) {}
350
351   int32_t tid() const { return TID; }
352
353   Error apply(RecordVisitor &V) override;
354
355   static bool classof(const Record *R) {
356     return R->getRecordType() == RecordKind::RK_Metadata_NewBuffer;
357   }
358 };
359
360 class EndBufferRecord : public MetadataRecord {
361 public:
362   EndBufferRecord()
363       : MetadataRecord(RecordKind::RK_Metadata_EndOfBuffer,
364                        MetadataType::EndOfBuffer) {}
365
366   Error apply(RecordVisitor &V) override;
367
368   static bool classof(const Record *R) {
369     return R->getRecordType() == RecordKind::RK_Metadata_EndOfBuffer;
370   }
371 };
372
373 class FunctionRecord : public Record {
374   RecordTypes Kind;
375   int32_t FuncId;
376   uint32_t Delta;
377   friend class RecordInitializer;
378
379   static constexpr unsigned kFunctionRecordSize = 8;
380
381 public:
382   FunctionRecord() : Record(RecordKind::RK_Function) {}
383
384   explicit FunctionRecord(RecordTypes K, int32_t F, uint32_t D)
385       : Record(RecordKind::RK_Function), Kind(K), FuncId(F), Delta(D) {}
386
387   // A function record is a concrete record type which has a number of common
388   // properties.
389   RecordTypes recordType() const { return Kind; }
390   int32_t functionId() const { return FuncId; }
391   uint32_t delta() const { return Delta; }
392
393   Error apply(RecordVisitor &V) override;
394
395   static bool classof(const Record *R) {
396     return R->getRecordType() == RecordKind::RK_Function;
397   }
398 };
399
400 class RecordVisitor {
401 public:
402   virtual ~RecordVisitor() = default;
403
404   // Support all specific kinds of records:
405   virtual Error visit(BufferExtents &) = 0;
406   virtual Error visit(WallclockRecord &) = 0;
407   virtual Error visit(NewCPUIDRecord &) = 0;
408   virtual Error visit(TSCWrapRecord &) = 0;
409   virtual Error visit(CustomEventRecord &) = 0;
410   virtual Error visit(CallArgRecord &) = 0;
411   virtual Error visit(PIDRecord &) = 0;
412   virtual Error visit(NewBufferRecord &) = 0;
413   virtual Error visit(EndBufferRecord &) = 0;
414   virtual Error visit(FunctionRecord &) = 0;
415   virtual Error visit(CustomEventRecordV5 &) = 0;
416   virtual Error visit(TypedEventRecord &) = 0;
417 };
418
419 class RecordInitializer : public RecordVisitor {
420   DataExtractor &E;
421   uint32_t &OffsetPtr;
422   uint16_t Version;
423
424 public:
425   static constexpr uint16_t DefaultVersion = 5u;
426
427   explicit RecordInitializer(DataExtractor &DE, uint32_t &OP, uint16_t V)
428       : RecordVisitor(), E(DE), OffsetPtr(OP), Version(V) {}
429
430   explicit RecordInitializer(DataExtractor &DE, uint32_t &OP)
431       : RecordInitializer(DE, OP, DefaultVersion) {}
432
433   Error visit(BufferExtents &) override;
434   Error visit(WallclockRecord &) override;
435   Error visit(NewCPUIDRecord &) override;
436   Error visit(TSCWrapRecord &) override;
437   Error visit(CustomEventRecord &) override;
438   Error visit(CallArgRecord &) override;
439   Error visit(PIDRecord &) override;
440   Error visit(NewBufferRecord &) override;
441   Error visit(EndBufferRecord &) override;
442   Error visit(FunctionRecord &) override;
443   Error visit(CustomEventRecordV5 &) override;
444   Error visit(TypedEventRecord &) override;
445 };
446
447 } // namespace xray
448 } // namespace llvm
449
450 #endif // LLVM_LIB_XRAY_FDRRECORDS_H_