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
15namespace llvm {
16namespace xray {
17
18Error BlockIndexer::visit(BufferExtents &) { return Error::success(); }
19
20Error BlockIndexer::visit(WallclockRecord &R) {
21 CurrentBlock.Records.push_back(x: &R);
22 CurrentBlock.WallclockTime = &R;
23 return Error::success();
24}
25
26Error BlockIndexer::visit(NewCPUIDRecord &R) {
27 CurrentBlock.Records.push_back(x: &R);
28 return Error::success();
29}
30
31Error BlockIndexer::visit(TSCWrapRecord &R) {
32 CurrentBlock.Records.push_back(x: &R);
33 return Error::success();
34}
35
36Error BlockIndexer::visit(CustomEventRecord &R) {
37 CurrentBlock.Records.push_back(x: &R);
38 return Error::success();
39}
40
41Error BlockIndexer::visit(CustomEventRecordV5 &R) {
42 CurrentBlock.Records.push_back(x: &R);
43 return Error::success();
44}
45
46Error BlockIndexer::visit(TypedEventRecord &R) {
47 CurrentBlock.Records.push_back(x: &R);
48 return Error::success();
49}
50
51Error BlockIndexer::visit(CallArgRecord &R) {
52 CurrentBlock.Records.push_back(x: &R);
53 return Error::success();
54}
55
56Error BlockIndexer::visit(PIDRecord &R) {
57 CurrentBlock.ProcessID = R.pid();
58 CurrentBlock.Records.push_back(x: &R);
59 return Error::success();
60}
61
62Error 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(x: &R);
69 return Error::success();
70}
71
72Error BlockIndexer::visit(EndBufferRecord &R) {
73 CurrentBlock.Records.push_back(x: &R);
74 return Error::success();
75}
76
77Error BlockIndexer::visit(FunctionRecord &R) {
78 CurrentBlock.Records.push_back(x: &R);
79 return Error::success();
80}
81
82Error BlockIndexer::flush() {
83 Index::iterator It;
84 std::tie(args&: It, args: std::ignore) =
85 Indices.insert(KV: {{CurrentBlock.ProcessID, CurrentBlock.ThreadID}, {}});
86 It->second.push_back(x: {.ProcessID: CurrentBlock.ProcessID, .ThreadID: CurrentBlock.ThreadID,
87 .WallclockTime: CurrentBlock.WallclockTime,
88 .Records: 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