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