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