1*0b57cec5SDimitry Andric //===- FDRTraceExpander.cpp -----------------------------------------------===//
2*0b57cec5SDimitry Andric //
3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0b57cec5SDimitry Andric //
7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8*0b57cec5SDimitry Andric #include "llvm/XRay/FDRTraceExpander.h"
9*0b57cec5SDimitry Andric 
10*0b57cec5SDimitry Andric namespace llvm {
11*0b57cec5SDimitry Andric namespace xray {
12*0b57cec5SDimitry Andric 
resetCurrentRecord()13*0b57cec5SDimitry Andric void TraceExpander::resetCurrentRecord() {
14*0b57cec5SDimitry Andric   if (BuildingRecord)
15*0b57cec5SDimitry Andric     C(CurrentRecord);
16*0b57cec5SDimitry Andric   BuildingRecord = false;
17*0b57cec5SDimitry Andric   CurrentRecord.CallArgs.clear();
18*0b57cec5SDimitry Andric   CurrentRecord.Data.clear();
19*0b57cec5SDimitry Andric }
20*0b57cec5SDimitry Andric 
visit(BufferExtents &)21*0b57cec5SDimitry Andric Error TraceExpander::visit(BufferExtents &) {
22*0b57cec5SDimitry Andric   resetCurrentRecord();
23*0b57cec5SDimitry Andric   return Error::success();
24*0b57cec5SDimitry Andric }
25*0b57cec5SDimitry Andric 
visit(WallclockRecord &)26*0b57cec5SDimitry Andric Error TraceExpander::visit(WallclockRecord &) { return Error::success(); }
27*0b57cec5SDimitry Andric 
visit(NewCPUIDRecord & R)28*0b57cec5SDimitry Andric Error TraceExpander::visit(NewCPUIDRecord &R) {
29*0b57cec5SDimitry Andric   CPUId = R.cpuid();
30*0b57cec5SDimitry Andric   BaseTSC = R.tsc();
31*0b57cec5SDimitry Andric   return Error::success();
32*0b57cec5SDimitry Andric }
33*0b57cec5SDimitry Andric 
visit(TSCWrapRecord & R)34*0b57cec5SDimitry Andric Error TraceExpander::visit(TSCWrapRecord &R) {
35*0b57cec5SDimitry Andric   BaseTSC = R.tsc();
36*0b57cec5SDimitry Andric   return Error::success();
37*0b57cec5SDimitry Andric }
38*0b57cec5SDimitry Andric 
visit(CustomEventRecord & R)39*0b57cec5SDimitry Andric Error TraceExpander::visit(CustomEventRecord &R) {
40*0b57cec5SDimitry Andric   resetCurrentRecord();
41*0b57cec5SDimitry Andric   if (!IgnoringRecords) {
42*0b57cec5SDimitry Andric     CurrentRecord.TSC = R.tsc();
43*0b57cec5SDimitry Andric     CurrentRecord.CPU = R.cpu();
44*0b57cec5SDimitry Andric     CurrentRecord.PId = PID;
45*0b57cec5SDimitry Andric     CurrentRecord.TId = TID;
46*0b57cec5SDimitry Andric     CurrentRecord.Type = RecordTypes::CUSTOM_EVENT;
47*0b57cec5SDimitry Andric     CurrentRecord.Data = std::string(R.data());
48*0b57cec5SDimitry Andric     BuildingRecord = true;
49*0b57cec5SDimitry Andric   }
50*0b57cec5SDimitry Andric   return Error::success();
51*0b57cec5SDimitry Andric }
52*0b57cec5SDimitry Andric 
visit(CustomEventRecordV5 & R)53*0b57cec5SDimitry Andric Error TraceExpander::visit(CustomEventRecordV5 &R) {
54*0b57cec5SDimitry Andric   resetCurrentRecord();
55*0b57cec5SDimitry Andric   if (!IgnoringRecords) {
56*0b57cec5SDimitry Andric     BaseTSC += R.delta();
57*0b57cec5SDimitry Andric     CurrentRecord.TSC = BaseTSC;
58*0b57cec5SDimitry Andric     CurrentRecord.CPU = CPUId;
59*0b57cec5SDimitry Andric     CurrentRecord.PId = PID;
60*0b57cec5SDimitry Andric     CurrentRecord.TId = TID;
61*0b57cec5SDimitry Andric     CurrentRecord.Type = RecordTypes::CUSTOM_EVENT;
62*0b57cec5SDimitry Andric     CurrentRecord.Data = std::string(R.data());
63*0b57cec5SDimitry Andric     BuildingRecord = true;
64*0b57cec5SDimitry Andric   }
65*0b57cec5SDimitry Andric   return Error::success();
66*0b57cec5SDimitry Andric }
67*0b57cec5SDimitry Andric 
visit(TypedEventRecord & R)68*0b57cec5SDimitry Andric Error TraceExpander::visit(TypedEventRecord &R) {
69*0b57cec5SDimitry Andric   resetCurrentRecord();
70*0b57cec5SDimitry Andric   if (!IgnoringRecords) {
71*0b57cec5SDimitry Andric     BaseTSC += R.delta();
72*0b57cec5SDimitry Andric     CurrentRecord.TSC = BaseTSC;
73*0b57cec5SDimitry Andric     CurrentRecord.CPU = CPUId;
74*0b57cec5SDimitry Andric     CurrentRecord.PId = PID;
75*0b57cec5SDimitry Andric     CurrentRecord.TId = TID;
76*0b57cec5SDimitry Andric     CurrentRecord.RecordType = R.eventType();
77*0b57cec5SDimitry Andric     CurrentRecord.Type = RecordTypes::TYPED_EVENT;
78*0b57cec5SDimitry Andric     CurrentRecord.Data = std::string(R.data());
79*0b57cec5SDimitry Andric     BuildingRecord = true;
80*0b57cec5SDimitry Andric   }
81*0b57cec5SDimitry Andric   return Error::success();
82*0b57cec5SDimitry Andric }
83*0b57cec5SDimitry Andric 
visit(CallArgRecord & R)84*0b57cec5SDimitry Andric Error TraceExpander::visit(CallArgRecord &R) {
85*0b57cec5SDimitry Andric   CurrentRecord.CallArgs.push_back(R.arg());
86*0b57cec5SDimitry Andric   CurrentRecord.Type = RecordTypes::ENTER_ARG;
87*0b57cec5SDimitry Andric   return Error::success();
88*0b57cec5SDimitry Andric }
89*0b57cec5SDimitry Andric 
visit(PIDRecord & R)90*0b57cec5SDimitry Andric Error TraceExpander::visit(PIDRecord &R) {
91*0b57cec5SDimitry Andric   PID = R.pid();
92*0b57cec5SDimitry Andric   return Error::success();
93*0b57cec5SDimitry Andric }
94*0b57cec5SDimitry Andric 
visit(NewBufferRecord & R)95*0b57cec5SDimitry Andric Error TraceExpander::visit(NewBufferRecord &R) {
96*0b57cec5SDimitry Andric   if (IgnoringRecords)
97*0b57cec5SDimitry Andric     IgnoringRecords = false;
98*0b57cec5SDimitry Andric   TID = R.tid();
99*0b57cec5SDimitry Andric   if (LogVersion == 2)
100*0b57cec5SDimitry Andric     PID = R.tid();
101*0b57cec5SDimitry Andric   return Error::success();
102*0b57cec5SDimitry Andric }
103*0b57cec5SDimitry Andric 
visit(EndBufferRecord &)104*0b57cec5SDimitry Andric Error TraceExpander::visit(EndBufferRecord &) {
105*0b57cec5SDimitry Andric   IgnoringRecords = true;
106*0b57cec5SDimitry Andric   resetCurrentRecord();
107*0b57cec5SDimitry Andric   return Error::success();
108*0b57cec5SDimitry Andric }
109*0b57cec5SDimitry Andric 
visit(FunctionRecord & R)110*0b57cec5SDimitry Andric Error TraceExpander::visit(FunctionRecord &R) {
111*0b57cec5SDimitry Andric   resetCurrentRecord();
112*0b57cec5SDimitry Andric   if (!IgnoringRecords) {
113*0b57cec5SDimitry Andric     BaseTSC += R.delta();
114*0b57cec5SDimitry Andric     CurrentRecord.Type = R.recordType();
115*0b57cec5SDimitry Andric     CurrentRecord.FuncId = R.functionId();
116*0b57cec5SDimitry Andric     CurrentRecord.TSC = BaseTSC;
117*0b57cec5SDimitry Andric     CurrentRecord.PId = PID;
118*0b57cec5SDimitry Andric     CurrentRecord.TId = TID;
119*0b57cec5SDimitry Andric     CurrentRecord.CPU = CPUId;
120*0b57cec5SDimitry Andric     BuildingRecord = true;
121*0b57cec5SDimitry Andric   }
122*0b57cec5SDimitry Andric   return Error::success();
123*0b57cec5SDimitry Andric }
124*0b57cec5SDimitry Andric 
flush()125*0b57cec5SDimitry Andric Error TraceExpander::flush() {
126*0b57cec5SDimitry Andric   resetCurrentRecord();
127*0b57cec5SDimitry Andric   return Error::success();
128*0b57cec5SDimitry Andric }
129*0b57cec5SDimitry Andric 
130*0b57cec5SDimitry Andric } // namespace xray
131*0b57cec5SDimitry Andric } // namespace llvm
132