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 visit(BufferExtents &)18Error BlockIndexer::visit(BufferExtents &) { return Error::success(); } 19 visit(WallclockRecord & R)20Error BlockIndexer::visit(WallclockRecord &R) { 21 CurrentBlock.Records.push_back(&R); 22 CurrentBlock.WallclockTime = &R; 23 return Error::success(); 24 } 25 visit(NewCPUIDRecord & R)26Error BlockIndexer::visit(NewCPUIDRecord &R) { 27 CurrentBlock.Records.push_back(&R); 28 return Error::success(); 29 } 30 visit(TSCWrapRecord & R)31Error BlockIndexer::visit(TSCWrapRecord &R) { 32 CurrentBlock.Records.push_back(&R); 33 return Error::success(); 34 } 35 visit(CustomEventRecord & R)36Error BlockIndexer::visit(CustomEventRecord &R) { 37 CurrentBlock.Records.push_back(&R); 38 return Error::success(); 39 } 40 visit(CustomEventRecordV5 & R)41Error BlockIndexer::visit(CustomEventRecordV5 &R) { 42 CurrentBlock.Records.push_back(&R); 43 return Error::success(); 44 } 45 visit(TypedEventRecord & R)46Error BlockIndexer::visit(TypedEventRecord &R) { 47 CurrentBlock.Records.push_back(&R); 48 return Error::success(); 49 } 50 visit(CallArgRecord & R)51Error BlockIndexer::visit(CallArgRecord &R) { 52 CurrentBlock.Records.push_back(&R); 53 return Error::success(); 54 } 55 visit(PIDRecord & R)56Error BlockIndexer::visit(PIDRecord &R) { 57 CurrentBlock.ProcessID = R.pid(); 58 CurrentBlock.Records.push_back(&R); 59 return Error::success(); 60 } 61 visit(NewBufferRecord & R)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(&R); 69 return Error::success(); 70 } 71 visit(EndBufferRecord & R)72Error BlockIndexer::visit(EndBufferRecord &R) { 73 CurrentBlock.Records.push_back(&R); 74 return Error::success(); 75 } 76 visit(FunctionRecord & R)77Error BlockIndexer::visit(FunctionRecord &R) { 78 CurrentBlock.Records.push_back(&R); 79 return Error::success(); 80 } 81 flush()82Error 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