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 AndricError BlockIndexer::visit(BufferExtents &) { return Error::success(); } 20*b5893f02SDimitry Andric visit(WallclockRecord & R)21*b5893f02SDimitry AndricError 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 AndricError 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 AndricError 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 AndricError 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 AndricError 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 AndricError 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 AndricError 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 AndricError 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 AndricError 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 AndricError 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 AndricError 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 AndricError 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