1*b5893f02SDimitry Andric //===- BlockIndexer.cpp - FDR Block Indexing VIsitor ----------------------===//
2*b5893f02SDimitry Andric //
3*b5893f02SDimitry Andric //                     The LLVM Compiler Infrastructure
4*b5893f02SDimitry Andric //
5*b5893f02SDimitry Andric // This file is distributed under the University of Illinois Open Source
6*b5893f02SDimitry Andric // License. See LICENSE.TXT for details.
7*b5893f02SDimitry Andric //
8*b5893f02SDimitry Andric //===----------------------------------------------------------------------===//
9*b5893f02SDimitry Andric //
10*b5893f02SDimitry Andric // An implementation of the RecordVisitor which generates a mapping between a
11*b5893f02SDimitry Andric // thread and a range of records representing a block.
12*b5893f02SDimitry Andric //
13*b5893f02SDimitry Andric //===----------------------------------------------------------------------===//
14*b5893f02SDimitry Andric #include "llvm/XRay/BlockIndexer.h"
15*b5893f02SDimitry Andric 
16*b5893f02SDimitry Andric namespace llvm {
17*b5893f02SDimitry Andric namespace xray {
18*b5893f02SDimitry Andric 
visit(BufferExtents &)19*b5893f02SDimitry Andric Error BlockIndexer::visit(BufferExtents &) { return Error::success(); }
20*b5893f02SDimitry Andric 
visit(WallclockRecord & R)21*b5893f02SDimitry Andric Error BlockIndexer::visit(WallclockRecord &R) {
22*b5893f02SDimitry Andric   CurrentBlock.Records.push_back(&R);
23*b5893f02SDimitry Andric   CurrentBlock.WallclockTime = &R;
24*b5893f02SDimitry Andric   return Error::success();
25*b5893f02SDimitry Andric }
26*b5893f02SDimitry Andric 
visit(NewCPUIDRecord & R)27*b5893f02SDimitry Andric Error BlockIndexer::visit(NewCPUIDRecord &R) {
28*b5893f02SDimitry Andric   CurrentBlock.Records.push_back(&R);
29*b5893f02SDimitry Andric   return Error::success();
30*b5893f02SDimitry Andric }
31*b5893f02SDimitry Andric 
visit(TSCWrapRecord & R)32*b5893f02SDimitry Andric Error BlockIndexer::visit(TSCWrapRecord &R) {
33*b5893f02SDimitry Andric   CurrentBlock.Records.push_back(&R);
34*b5893f02SDimitry Andric   return Error::success();
35*b5893f02SDimitry Andric }
36*b5893f02SDimitry Andric 
visit(CustomEventRecord & R)37*b5893f02SDimitry Andric Error BlockIndexer::visit(CustomEventRecord &R) {
38*b5893f02SDimitry Andric   CurrentBlock.Records.push_back(&R);
39*b5893f02SDimitry Andric   return Error::success();
40*b5893f02SDimitry Andric }
41*b5893f02SDimitry Andric 
visit(CustomEventRecordV5 & R)42*b5893f02SDimitry Andric Error BlockIndexer::visit(CustomEventRecordV5 &R) {
43*b5893f02SDimitry Andric   CurrentBlock.Records.push_back(&R);
44*b5893f02SDimitry Andric   return Error::success();
45*b5893f02SDimitry Andric }
46*b5893f02SDimitry Andric 
visit(TypedEventRecord & R)47*b5893f02SDimitry Andric Error BlockIndexer::visit(TypedEventRecord &R) {
48*b5893f02SDimitry Andric   CurrentBlock.Records.push_back(&R);
49*b5893f02SDimitry Andric   return Error::success();
50*b5893f02SDimitry Andric }
51*b5893f02SDimitry Andric 
visit(CallArgRecord & R)52*b5893f02SDimitry Andric Error BlockIndexer::visit(CallArgRecord &R) {
53*b5893f02SDimitry Andric   CurrentBlock.Records.push_back(&R);
54*b5893f02SDimitry Andric   return Error::success();
55*b5893f02SDimitry Andric }
56*b5893f02SDimitry Andric 
visit(PIDRecord & R)57*b5893f02SDimitry Andric Error BlockIndexer::visit(PIDRecord &R) {
58*b5893f02SDimitry Andric   CurrentBlock.ProcessID = R.pid();
59*b5893f02SDimitry Andric   CurrentBlock.Records.push_back(&R);
60*b5893f02SDimitry Andric   return Error::success();
61*b5893f02SDimitry Andric }
62*b5893f02SDimitry Andric 
visit(NewBufferRecord & R)63*b5893f02SDimitry Andric Error BlockIndexer::visit(NewBufferRecord &R) {
64*b5893f02SDimitry Andric   if (!CurrentBlock.Records.empty())
65*b5893f02SDimitry Andric     if (auto E = flush())
66*b5893f02SDimitry Andric       return E;
67*b5893f02SDimitry Andric 
68*b5893f02SDimitry Andric   CurrentBlock.ThreadID = R.tid();
69*b5893f02SDimitry Andric   CurrentBlock.Records.push_back(&R);
70*b5893f02SDimitry Andric   return Error::success();
71*b5893f02SDimitry Andric }
72*b5893f02SDimitry Andric 
visit(EndBufferRecord & R)73*b5893f02SDimitry Andric Error BlockIndexer::visit(EndBufferRecord &R) {
74*b5893f02SDimitry Andric   CurrentBlock.Records.push_back(&R);
75*b5893f02SDimitry Andric   return Error::success();
76*b5893f02SDimitry Andric }
77*b5893f02SDimitry Andric 
visit(FunctionRecord & R)78*b5893f02SDimitry Andric Error BlockIndexer::visit(FunctionRecord &R) {
79*b5893f02SDimitry Andric   CurrentBlock.Records.push_back(&R);
80*b5893f02SDimitry Andric   return Error::success();
81*b5893f02SDimitry Andric }
82*b5893f02SDimitry Andric 
flush()83*b5893f02SDimitry Andric Error BlockIndexer::flush() {
84*b5893f02SDimitry Andric   Index::iterator It;
85*b5893f02SDimitry Andric   std::tie(It, std::ignore) =
86*b5893f02SDimitry Andric       Indices.insert({{CurrentBlock.ProcessID, CurrentBlock.ThreadID}, {}});
87*b5893f02SDimitry Andric   It->second.push_back({CurrentBlock.ProcessID, CurrentBlock.ThreadID,
88*b5893f02SDimitry Andric                         CurrentBlock.WallclockTime,
89*b5893f02SDimitry Andric                         std::move(CurrentBlock.Records)});
90*b5893f02SDimitry Andric   CurrentBlock.ProcessID = 0;
91*b5893f02SDimitry Andric   CurrentBlock.ThreadID = 0;
92*b5893f02SDimitry Andric   CurrentBlock.Records = {};
93*b5893f02SDimitry Andric   CurrentBlock.WallclockTime = nullptr;
94*b5893f02SDimitry Andric   return Error::success();
95*b5893f02SDimitry Andric }
96*b5893f02SDimitry Andric 
97*b5893f02SDimitry Andric } // namespace xray
98*b5893f02SDimitry Andric } // namespace llvm
99