diff options
Diffstat (limited to 'llvm/tools/llvm-mca/Views/TimelineView.cpp')
| -rw-r--r-- | llvm/tools/llvm-mca/Views/TimelineView.cpp | 68 |
1 files changed, 29 insertions, 39 deletions
diff --git a/llvm/tools/llvm-mca/Views/TimelineView.cpp b/llvm/tools/llvm-mca/Views/TimelineView.cpp index cf5b48e811b8..c8b481bc7ce6 100644 --- a/llvm/tools/llvm-mca/Views/TimelineView.cpp +++ b/llvm/tools/llvm-mca/Views/TimelineView.cpp @@ -20,10 +20,10 @@ namespace mca { TimelineView::TimelineView(const MCSubtargetInfo &sti, MCInstPrinter &Printer, llvm::ArrayRef<llvm::MCInst> S, unsigned Iterations, unsigned Cycles) - : STI(sti), MCIP(Printer), Source(S), CurrentCycle(0), + : InstructionView(sti, Printer, S), CurrentCycle(0), MaxCycle(Cycles == 0 ? 80 : Cycles), LastCycle(0), WaitTime(S.size()), UsedBuffer(S.size()) { - unsigned NumInstructions = Source.size(); + unsigned NumInstructions = getSource().size(); assert(Iterations && "Invalid number of iterations specified!"); NumInstructions *= Iterations; Timeline.resize(NumInstructions); @@ -40,10 +40,10 @@ TimelineView::TimelineView(const MCSubtargetInfo &sti, MCInstPrinter &Printer, void TimelineView::onReservedBuffers(const InstRef &IR, ArrayRef<unsigned> Buffers) { - if (IR.getSourceIndex() >= Source.size()) + if (IR.getSourceIndex() >= getSource().size()) return; - const MCSchedModel &SM = STI.getSchedModel(); + const MCSchedModel &SM = getSubTargetInfo().getSchedModel(); std::pair<unsigned, int> BufferInfo = {0, -1}; for (const unsigned Buffer : Buffers) { const MCProcResourceDesc &MCDesc = *SM.getProcResource(Buffer); @@ -70,7 +70,7 @@ void TimelineView::onEvent(const HWInstructionEvent &Event) { // Update the WaitTime entry which corresponds to this Index. assert(TVEntry.CycleDispatched >= 0 && "Invalid TVEntry found!"); unsigned CycleDispatched = static_cast<unsigned>(TVEntry.CycleDispatched); - WaitTimeEntry &WTEntry = WaitTime[Index % Source.size()]; + WaitTimeEntry &WTEntry = WaitTime[Index % getSource().size()]; WTEntry.CyclesSpentInSchedulerQueue += TVEntry.CycleIssued - CycleDispatched; assert(CycleDispatched <= TVEntry.CycleReady && @@ -133,7 +133,7 @@ void TimelineView::printWaitTimeEntry(formatted_raw_ostream &OS, const WaitTimeEntry &Entry, unsigned SourceIndex, unsigned Executions) const { - bool PrintingTotals = SourceIndex == Source.size(); + bool PrintingTotals = SourceIndex == getSource().size(); unsigned CumulativeExecutions = PrintingTotals ? Timeline.size() : Executions; if (!PrintingTotals) @@ -164,7 +164,8 @@ void TimelineView::printWaitTimeEntry(formatted_raw_ostream &OS, OS.PadToColumn(27); if (!PrintingTotals) tryChangeColor(OS, Entry.CyclesSpentAfterWBAndBeforeRetire, - CumulativeExecutions, STI.getSchedModel().MicroOpBufferSize); + CumulativeExecutions, + getSubTargetInfo().getSchedModel().MicroOpBufferSize); OS << format("%.1f", floor((AverageTime3 * 10) + 0.5) / 10); if (OS.has_colors()) @@ -181,33 +182,19 @@ void TimelineView::printAverageWaitTimes(raw_ostream &OS) const { "[3]: Average time elapsed from WB until retire stage\n\n" " [0] [1] [2] [3]\n"; OS << Header; - - // Use a different string stream for printing instructions. - std::string Instruction; - raw_string_ostream InstrStream(Instruction); - formatted_raw_ostream FOS(OS); - unsigned Executions = Timeline.size() / Source.size(); + unsigned Executions = Timeline.size() / getSource().size(); unsigned IID = 0; - for (const MCInst &Inst : Source) { + for (const MCInst &Inst : getSource()) { printWaitTimeEntry(FOS, WaitTime[IID], IID, Executions); - // Append the instruction info at the end of the line. - MCIP.printInst(&Inst, 0, "", STI, InstrStream); - InstrStream.flush(); - - // Consume any tabs or spaces at the beginning of the string. - StringRef Str(Instruction); - Str = Str.ltrim(); - FOS << " " << Str << '\n'; + FOS << " " << printInstructionString(Inst) << '\n'; FOS.flush(); - Instruction = ""; - ++IID; } // If the timeline contains more than one instruction, // let's also print global averages. - if (Source.size() != 1) { + if (getSource().size() != 1) { WaitTimeEntry TotalWaitTime = std::accumulate( WaitTime.begin(), WaitTime.end(), WaitTimeEntry{0, 0, 0}, [](const WaitTimeEntry &A, const WaitTimeEntry &B) { @@ -220,7 +207,7 @@ void TimelineView::printAverageWaitTimes(raw_ostream &OS) const { printWaitTimeEntry(FOS, TotalWaitTime, IID, Executions); FOS << " " << "<total>" << '\n'; - InstrStream.flush(); + FOS.flush(); } } @@ -292,11 +279,8 @@ void TimelineView::printTimeline(raw_ostream &OS) const { printTimelineHeader(FOS, LastCycle); FOS.flush(); - // Use a different string stream for the instruction. - std::string Instruction; - raw_string_ostream InstrStream(Instruction); - unsigned IID = 0; + ArrayRef<llvm::MCInst> Source = getSource(); const unsigned Iterations = Timeline.size() / Source.size(); for (unsigned Iteration = 0; Iteration < Iterations; ++Iteration) { for (const MCInst &Inst : Source) { @@ -306,20 +290,26 @@ void TimelineView::printTimeline(raw_ostream &OS) const { unsigned SourceIndex = IID % Source.size(); printTimelineViewEntry(FOS, Entry, Iteration, SourceIndex); - // Append the instruction info at the end of the line. - MCIP.printInst(&Inst, 0, "", STI, InstrStream); - InstrStream.flush(); - - // Consume any tabs or spaces at the beginning of the string. - StringRef Str(Instruction); - Str = Str.ltrim(); - FOS << " " << Str << '\n'; + FOS << " " << printInstructionString(Inst) << '\n'; FOS.flush(); - Instruction = ""; ++IID; } } } + +json::Value TimelineView::toJSON() const { + json::Array TimelineInfo; + + for (const TimelineViewEntry &TLE : Timeline) { + TimelineInfo.push_back( + json::Object({{"CycleDispatched", TLE.CycleDispatched}, + {"CycleReady", TLE.CycleReady}, + {"CycleIssued", TLE.CycleIssued}, + {"CycleExecuted", TLE.CycleExecuted}, + {"CycleRetired", TLE.CycleRetired}})); + } + return json::Object({{"TimelineInfo", std::move(TimelineInfo)}}); +} } // namespace mca } // namespace llvm |
