1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-25 04:02:41 +01:00
llvm-mirror/include/llvm/XRay/FDRRecords.h
Chandler Carruth ae65e281f3 Update the file headers across all of the LLVM projects in the monorepo
to reflect the new license.

We understand that people may be surprised that we're moving the header
entirely to discuss the new license. We checked this carefully with the
Foundation's lawyer and we believe this is the correct approach.

Essentially, all code in the project is now made available by the LLVM
project under our new license, so you will see that the license headers
include that license only. Some of our contributors have contributed
code under our old license, and accordingly, we have retained a copy of
our old license notice in the top-level files in each project and
repository.

llvm-svn: 351636
2019-01-19 08:50:56 +00:00

450 lines
12 KiB
C++

//===- FDRRecords.h - XRay Flight Data Recorder Mode Records --------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Define types and operations on these types that represent the different kinds
// of records we encounter in XRay flight data recorder mode traces.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIB_XRAY_FDRRECORDS_H_
#define LLVM_LIB_XRAY_FDRRECORDS_H_
#include <cstdint>
#include <string>
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/DataExtractor.h"
#include "llvm/Support/Error.h"
#include "llvm/XRay/XRayRecord.h"
namespace llvm {
namespace xray {
class RecordVisitor;
class RecordInitializer;
class Record {
public:
enum class RecordKind {
RK_Metadata,
RK_Metadata_BufferExtents,
RK_Metadata_WallClockTime,
RK_Metadata_NewCPUId,
RK_Metadata_TSCWrap,
RK_Metadata_CustomEvent,
RK_Metadata_CustomEventV5,
RK_Metadata_CallArg,
RK_Metadata_PIDEntry,
RK_Metadata_NewBuffer,
RK_Metadata_EndOfBuffer,
RK_Metadata_TypedEvent,
RK_Metadata_LastMetadata,
RK_Function,
};
static StringRef kindToString(RecordKind K);
private:
const RecordKind T;
public:
Record(const Record &) = delete;
Record(Record &&) = delete;
Record &operator=(const Record &) = delete;
Record &operator=(Record &&) = delete;
explicit Record(RecordKind T) : T(T) {}
RecordKind getRecordType() const { return T; }
// Each Record should be able to apply an abstract visitor, and choose the
// appropriate function in the visitor to invoke, given its own type.
virtual Error apply(RecordVisitor &V) = 0;
virtual ~Record() = default;
};
class MetadataRecord : public Record {
public:
enum class MetadataType : unsigned {
Unknown,
BufferExtents,
WallClockTime,
NewCPUId,
TSCWrap,
CustomEvent,
CallArg,
PIDEntry,
NewBuffer,
EndOfBuffer,
TypedEvent,
};
protected:
static constexpr int kMetadataBodySize = 15;
friend class RecordInitializer;
private:
const MetadataType MT;
public:
explicit MetadataRecord(RecordKind T, MetadataType M) : Record(T), MT(M) {}
static bool classof(const Record *R) {
return R->getRecordType() >= RecordKind::RK_Metadata &&
R->getRecordType() <= RecordKind::RK_Metadata_LastMetadata;
}
MetadataType metadataType() const { return MT; }
virtual ~MetadataRecord() = default;
};
// What follows are specific Metadata record types which encapsulate the
// information associated with specific metadata record types in an FDR mode
// log.
class BufferExtents : public MetadataRecord {
uint64_t Size = 0;
friend class RecordInitializer;
public:
BufferExtents()
: MetadataRecord(RecordKind::RK_Metadata_BufferExtents,
MetadataType::BufferExtents) {}
explicit BufferExtents(uint64_t S)
: MetadataRecord(RecordKind::RK_Metadata_BufferExtents,
MetadataType::BufferExtents),
Size(S) {}
uint64_t size() const { return Size; }
Error apply(RecordVisitor &V) override;
static bool classof(const Record *R) {
return R->getRecordType() == RecordKind::RK_Metadata_BufferExtents;
}
};
class WallclockRecord : public MetadataRecord {
uint64_t Seconds = 0;
uint32_t Nanos = 0;
friend class RecordInitializer;
public:
WallclockRecord()
: MetadataRecord(RecordKind::RK_Metadata_WallClockTime,
MetadataType::WallClockTime) {}
explicit WallclockRecord(uint64_t S, uint32_t N)
: MetadataRecord(RecordKind::RK_Metadata_WallClockTime,
MetadataType::WallClockTime),
Seconds(S), Nanos(N) {}
uint64_t seconds() const { return Seconds; }
uint32_t nanos() const { return Nanos; }
Error apply(RecordVisitor &V) override;
static bool classof(const Record *R) {
return R->getRecordType() == RecordKind::RK_Metadata_WallClockTime;
}
};
class NewCPUIDRecord : public MetadataRecord {
uint16_t CPUId = 0;
uint64_t TSC = 0;
friend class RecordInitializer;
public:
NewCPUIDRecord()
: MetadataRecord(RecordKind::RK_Metadata_NewCPUId,
MetadataType::NewCPUId) {}
NewCPUIDRecord(uint16_t C, uint64_t T)
: MetadataRecord(RecordKind::RK_Metadata_NewCPUId,
MetadataType::NewCPUId),
CPUId(C), TSC(T) {}
uint16_t cpuid() const { return CPUId; }
uint64_t tsc() const { return TSC; }
Error apply(RecordVisitor &V) override;
static bool classof(const Record *R) {
return R->getRecordType() == RecordKind::RK_Metadata_NewCPUId;
}
};
class TSCWrapRecord : public MetadataRecord {
uint64_t BaseTSC = 0;
friend class RecordInitializer;
public:
TSCWrapRecord()
: MetadataRecord(RecordKind::RK_Metadata_TSCWrap, MetadataType::TSCWrap) {
}
explicit TSCWrapRecord(uint64_t B)
: MetadataRecord(RecordKind::RK_Metadata_TSCWrap, MetadataType::TSCWrap),
BaseTSC(B) {}
uint64_t tsc() const { return BaseTSC; }
Error apply(RecordVisitor &V) override;
static bool classof(const Record *R) {
return R->getRecordType() == RecordKind::RK_Metadata_TSCWrap;
}
};
class CustomEventRecord : public MetadataRecord {
int32_t Size = 0;
uint64_t TSC = 0;
uint16_t CPU = 0;
std::string Data{};
friend class RecordInitializer;
public:
CustomEventRecord()
: MetadataRecord(RecordKind::RK_Metadata_CustomEvent,
MetadataType::CustomEvent) {}
explicit CustomEventRecord(uint64_t S, uint64_t T, uint16_t C, std::string D)
: MetadataRecord(RecordKind::RK_Metadata_CustomEvent,
MetadataType::CustomEvent),
Size(S), TSC(T), CPU(C), Data(std::move(D)) {}
int32_t size() const { return Size; }
uint64_t tsc() const { return TSC; }
uint16_t cpu() const { return CPU; }
StringRef data() const { return Data; }
Error apply(RecordVisitor &V) override;
static bool classof(const Record *R) {
return R->getRecordType() == RecordKind::RK_Metadata_CustomEvent;
}
};
class CustomEventRecordV5 : public MetadataRecord {
int32_t Size = 0;
int32_t Delta = 0;
std::string Data{};
friend class RecordInitializer;
public:
CustomEventRecordV5()
: MetadataRecord(RecordKind::RK_Metadata_CustomEventV5,
MetadataType::CustomEvent) {}
explicit CustomEventRecordV5(int32_t S, int32_t D, std::string P)
: MetadataRecord(RecordKind::RK_Metadata_CustomEventV5,
MetadataType::CustomEvent),
Size(S), Delta(D), Data(std::move(P)) {}
int32_t size() const { return Size; }
int32_t delta() const { return Delta; }
StringRef data() const { return Data; }
Error apply(RecordVisitor &V) override;
static bool classof(const Record *R) {
return R->getRecordType() == RecordKind::RK_Metadata_CustomEventV5;
}
};
class TypedEventRecord : public MetadataRecord {
int32_t Size = 0;
int32_t Delta = 0;
uint16_t EventType = 0;
std::string Data{};
friend class RecordInitializer;
public:
TypedEventRecord()
: MetadataRecord(RecordKind::RK_Metadata_TypedEvent,
MetadataType::TypedEvent) {}
explicit TypedEventRecord(int32_t S, int32_t D, uint16_t E, std::string P)
: MetadataRecord(RecordKind::RK_Metadata_TypedEvent,
MetadataType::TypedEvent),
Size(S), Delta(D), Data(std::move(P)) {}
int32_t size() const { return Size; }
int32_t delta() const { return Delta; }
uint16_t eventType() const { return EventType; }
StringRef data() const { return Data; }
Error apply(RecordVisitor &V) override;
static bool classof(const Record *R) {
return R->getRecordType() == RecordKind::RK_Metadata_TypedEvent;
}
};
class CallArgRecord : public MetadataRecord {
uint64_t Arg;
friend class RecordInitializer;
public:
CallArgRecord()
: MetadataRecord(RecordKind::RK_Metadata_CallArg, MetadataType::CallArg) {
}
explicit CallArgRecord(uint64_t A)
: MetadataRecord(RecordKind::RK_Metadata_CallArg, MetadataType::CallArg),
Arg(A) {}
uint64_t arg() const { return Arg; }
Error apply(RecordVisitor &V) override;
static bool classof(const Record *R) {
return R->getRecordType() == RecordKind::RK_Metadata_CallArg;
}
};
class PIDRecord : public MetadataRecord {
int32_t PID = 0;
friend class RecordInitializer;
public:
PIDRecord()
: MetadataRecord(RecordKind::RK_Metadata_PIDEntry,
MetadataType::PIDEntry) {}
explicit PIDRecord(int32_t P)
: MetadataRecord(RecordKind::RK_Metadata_PIDEntry,
MetadataType::PIDEntry),
PID(P) {}
int32_t pid() const { return PID; }
Error apply(RecordVisitor &V) override;
static bool classof(const Record *R) {
return R->getRecordType() == RecordKind::RK_Metadata_PIDEntry;
}
};
class NewBufferRecord : public MetadataRecord {
int32_t TID = 0;
friend class RecordInitializer;
public:
NewBufferRecord()
: MetadataRecord(RecordKind::RK_Metadata_NewBuffer,
MetadataType::NewBuffer) {}
explicit NewBufferRecord(int32_t T)
: MetadataRecord(RecordKind::RK_Metadata_NewBuffer,
MetadataType::NewBuffer),
TID(T) {}
int32_t tid() const { return TID; }
Error apply(RecordVisitor &V) override;
static bool classof(const Record *R) {
return R->getRecordType() == RecordKind::RK_Metadata_NewBuffer;
}
};
class EndBufferRecord : public MetadataRecord {
public:
EndBufferRecord()
: MetadataRecord(RecordKind::RK_Metadata_EndOfBuffer,
MetadataType::EndOfBuffer) {}
Error apply(RecordVisitor &V) override;
static bool classof(const Record *R) {
return R->getRecordType() == RecordKind::RK_Metadata_EndOfBuffer;
}
};
class FunctionRecord : public Record {
RecordTypes Kind;
int32_t FuncId;
uint32_t Delta;
friend class RecordInitializer;
static constexpr unsigned kFunctionRecordSize = 8;
public:
FunctionRecord() : Record(RecordKind::RK_Function) {}
explicit FunctionRecord(RecordTypes K, int32_t F, uint32_t D)
: Record(RecordKind::RK_Function), Kind(K), FuncId(F), Delta(D) {}
// A function record is a concrete record type which has a number of common
// properties.
RecordTypes recordType() const { return Kind; }
int32_t functionId() const { return FuncId; }
uint32_t delta() const { return Delta; }
Error apply(RecordVisitor &V) override;
static bool classof(const Record *R) {
return R->getRecordType() == RecordKind::RK_Function;
}
};
class RecordVisitor {
public:
virtual ~RecordVisitor() = default;
// Support all specific kinds of records:
virtual Error visit(BufferExtents &) = 0;
virtual Error visit(WallclockRecord &) = 0;
virtual Error visit(NewCPUIDRecord &) = 0;
virtual Error visit(TSCWrapRecord &) = 0;
virtual Error visit(CustomEventRecord &) = 0;
virtual Error visit(CallArgRecord &) = 0;
virtual Error visit(PIDRecord &) = 0;
virtual Error visit(NewBufferRecord &) = 0;
virtual Error visit(EndBufferRecord &) = 0;
virtual Error visit(FunctionRecord &) = 0;
virtual Error visit(CustomEventRecordV5 &) = 0;
virtual Error visit(TypedEventRecord &) = 0;
};
class RecordInitializer : public RecordVisitor {
DataExtractor &E;
uint32_t &OffsetPtr;
uint16_t Version;
public:
static constexpr uint16_t DefaultVersion = 5u;
explicit RecordInitializer(DataExtractor &DE, uint32_t &OP, uint16_t V)
: RecordVisitor(), E(DE), OffsetPtr(OP), Version(V) {}
explicit RecordInitializer(DataExtractor &DE, uint32_t &OP)
: RecordInitializer(DE, OP, DefaultVersion) {}
Error visit(BufferExtents &) override;
Error visit(WallclockRecord &) override;
Error visit(NewCPUIDRecord &) override;
Error visit(TSCWrapRecord &) override;
Error visit(CustomEventRecord &) override;
Error visit(CallArgRecord &) override;
Error visit(PIDRecord &) override;
Error visit(NewBufferRecord &) override;
Error visit(EndBufferRecord &) override;
Error visit(FunctionRecord &) override;
Error visit(CustomEventRecordV5 &) override;
Error visit(TypedEventRecord &) override;
};
} // namespace xray
} // namespace llvm
#endif // LLVM_LIB_XRAY_FDRRECORDS_H_