Index: llvm/tools/llvm-mca/Views/BottleneckAnalysis.cpp =================================================================== --- llvm/tools/llvm-mca/Views/BottleneckAnalysis.cpp +++ llvm/tools/llvm-mca/Views/BottleneckAnalysis.cpp @@ -288,17 +288,11 @@ const MCSubtargetInfo &STI, MCInstPrinter &MCIP, const MCInst &MCI, bool UseDifferentColor = false) { - std::string Instruction; - raw_string_ostream InstrStream(Instruction); - FOS.PadToColumn(14); - MCIP.printInst(&MCI, 0, "", STI, InstrStream); - InstrStream.flush(); - if (UseDifferentColor) FOS.changeColor(raw_ostream::CYAN, true, false); - FOS << StringRef(Instruction).ltrim(); + FOS << View::stringifyInstruction(MCIP, STI, MCI); if (UseDifferentColor) FOS.resetColor(); } Index: llvm/tools/llvm-mca/Views/InstructionInfoView.cpp =================================================================== --- llvm/tools/llvm-mca/Views/InstructionInfoView.cpp +++ llvm/tools/llvm-mca/Views/InstructionInfoView.cpp @@ -20,8 +20,6 @@ void InstructionInfoView::printView(raw_ostream &OS) const { std::string Buffer; raw_string_ostream TempStream(Buffer); - std::string Instruction; - raw_string_ostream InstrStream(Instruction); if (!Source.size()) return; @@ -82,14 +80,7 @@ } const MCInst &Inst = std::get<1>(I.value()); - 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(); - TempStream << Str << '\n'; - Instruction = ""; + TempStream << stringifyInstruction(MCIP, STI, Inst) << '\n'; } TempStream.flush(); Index: llvm/tools/llvm-mca/Views/ResourcePressureView.cpp =================================================================== --- llvm/tools/llvm-mca/Views/ResourcePressureView.cpp +++ llvm/tools/llvm-mca/Views/ResourcePressureView.cpp @@ -151,9 +151,6 @@ printColumnNames(FOS, STI.getSchedModel()); FOS << "Instructions:\n"; - std::string Instruction; - raw_string_ostream InstrStream(Instruction); - unsigned InstrIndex = 0; const unsigned Executions = LastInstructionIdx / Source.size() + 1; for (const MCInst &MCI : Source) { @@ -163,16 +160,7 @@ printResourcePressure(FOS, Usage / Executions, (J + 1) * 7); } - MCIP.printInst(&MCI, 0, "", STI, InstrStream); - InstrStream.flush(); - StringRef Str(Instruction); - - // Remove any tabs or spaces at the beginning of the instruction. - Str = Str.ltrim(); - - FOS << Str << '\n'; - Instruction = ""; - + FOS << stringifyInstruction(MCIP, STI, MCI) << '\n'; FOS.flush(); OS << Buffer; Buffer = ""; Index: llvm/tools/llvm-mca/Views/TimelineView.cpp =================================================================== --- llvm/tools/llvm-mca/Views/TimelineView.cpp +++ llvm/tools/llvm-mca/Views/TimelineView.cpp @@ -181,27 +181,13 @@ "[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 IID = 0; for (const MCInst &Inst : Source) { 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 << " " << stringifyInstruction(MCIP, STI, Inst) << '\n'; FOS.flush(); - Instruction = ""; - ++IID; } @@ -220,7 +206,7 @@ printWaitTimeEntry(FOS, TotalWaitTime, IID, Executions); FOS << " " << "" << '\n'; - InstrStream.flush(); + FOS.flush(); } } @@ -292,10 +278,6 @@ printTimelineHeader(FOS, LastCycle); FOS.flush(); - // Use a different string stream for the instruction. - std::string Instruction; - raw_string_ostream InstrStream(Instruction); - unsigned IID = 0; const unsigned Iterations = Timeline.size() / Source.size(); for (unsigned Iteration = 0; Iteration < Iterations; ++Iteration) { @@ -306,16 +288,8 @@ 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 << " " << stringifyInstruction(MCIP, STI, Inst) << '\n'; FOS.flush(); - Instruction = ""; ++IID; } Index: llvm/tools/llvm-mca/Views/View.h =================================================================== --- llvm/tools/llvm-mca/Views/View.h +++ llvm/tools/llvm-mca/Views/View.h @@ -15,6 +15,7 @@ #ifndef LLVM_TOOLS_LLVM_MCA_VIEW_H #define LLVM_TOOLS_LLVM_MCA_VIEW_H +#include "llvm/MC/MCInstPrinter.h" #include "llvm/MCA/HWEventListener.h" #include "llvm/Support/raw_ostream.h" @@ -22,7 +23,24 @@ namespace mca { class View : public HWEventListener { + static std::string InstructionString; + static raw_string_ostream InstrStream; + public: + // Return a reference to a string representing a given machine instruction. + // The result should be used or copied before the next call to + // stringifyInstruction() as it will overwrite the previous result. + static StringRef stringifyInstruction(llvm::MCInstPrinter &MCIP, + const llvm::MCSubtargetInfo &STI, + const llvm::MCInst &MCI) { + InstructionString = ""; + MCIP.printInst(&MCI, 0, "", STI, InstrStream); + InstrStream.flush(); + StringRef Str(InstructionString); + // Remove any tabs or spaces at the beginning of the instruction. + return Str.ltrim(); + } + virtual void printView(llvm::raw_ostream &OS) const = 0; virtual ~View() = default; void anchor() override; Index: llvm/tools/llvm-mca/Views/View.cpp =================================================================== --- llvm/tools/llvm-mca/Views/View.cpp +++ llvm/tools/llvm-mca/Views/View.cpp @@ -16,6 +16,9 @@ namespace llvm { namespace mca { +std::string View::InstructionString; +raw_string_ostream View::InstrStream(InstructionString); + void View::anchor() {} } // namespace mca } // namespace llvm