summaryrefslogtreecommitdiff
path: root/llvm/tools/llvm-mca/Views/TimelineView.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/llvm-mca/Views/TimelineView.cpp')
-rw-r--r--llvm/tools/llvm-mca/Views/TimelineView.cpp68
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