1*0b57cec5SDimitry Andric //===--------------------- InstructionInfoView.cpp --------------*- C++ -*-===// 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 /// \file 9*0b57cec5SDimitry Andric /// 10*0b57cec5SDimitry Andric /// This file implements the InstructionInfoView API. 11*0b57cec5SDimitry Andric /// 12*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 13*0b57cec5SDimitry Andric 14*0b57cec5SDimitry Andric #include "Views/InstructionInfoView.h" 15*0b57cec5SDimitry Andric 16*0b57cec5SDimitry Andric namespace llvm { 17*0b57cec5SDimitry Andric namespace mca { 18*0b57cec5SDimitry Andric 19*0b57cec5SDimitry Andric void InstructionInfoView::printView(raw_ostream &OS) const { 20*0b57cec5SDimitry Andric std::string Buffer; 21*0b57cec5SDimitry Andric raw_string_ostream TempStream(Buffer); 22*0b57cec5SDimitry Andric const MCSchedModel &SM = STI.getSchedModel(); 23*0b57cec5SDimitry Andric 24*0b57cec5SDimitry Andric std::string Instruction; 25*0b57cec5SDimitry Andric raw_string_ostream InstrStream(Instruction); 26*0b57cec5SDimitry Andric 27*0b57cec5SDimitry Andric TempStream << "\n\nInstruction Info:\n"; 28*0b57cec5SDimitry Andric TempStream << "[1]: #uOps\n[2]: Latency\n[3]: RThroughput\n" 29*0b57cec5SDimitry Andric << "[4]: MayLoad\n[5]: MayStore\n[6]: HasSideEffects (U)\n\n"; 30*0b57cec5SDimitry Andric 31*0b57cec5SDimitry Andric TempStream << "[1] [2] [3] [4] [5] [6] Instructions:\n"; 32*0b57cec5SDimitry Andric for (const MCInst &Inst : Source) { 33*0b57cec5SDimitry Andric const MCInstrDesc &MCDesc = MCII.get(Inst.getOpcode()); 34*0b57cec5SDimitry Andric 35*0b57cec5SDimitry Andric // Obtain the scheduling class information from the instruction. 36*0b57cec5SDimitry Andric unsigned SchedClassID = MCDesc.getSchedClass(); 37*0b57cec5SDimitry Andric unsigned CPUID = SM.getProcessorID(); 38*0b57cec5SDimitry Andric 39*0b57cec5SDimitry Andric // Try to solve variant scheduling classes. 40*0b57cec5SDimitry Andric while (SchedClassID && SM.getSchedClassDesc(SchedClassID)->isVariant()) 41*0b57cec5SDimitry Andric SchedClassID = STI.resolveVariantSchedClass(SchedClassID, &Inst, CPUID); 42*0b57cec5SDimitry Andric 43*0b57cec5SDimitry Andric const MCSchedClassDesc &SCDesc = *SM.getSchedClassDesc(SchedClassID); 44*0b57cec5SDimitry Andric unsigned NumMicroOpcodes = SCDesc.NumMicroOps; 45*0b57cec5SDimitry Andric unsigned Latency = MCSchedModel::computeInstrLatency(STI, SCDesc); 46*0b57cec5SDimitry Andric // Add extra latency due to delays in the forwarding data paths. 47*0b57cec5SDimitry Andric Latency += MCSchedModel::getForwardingDelayCycles( 48*0b57cec5SDimitry Andric STI.getReadAdvanceEntries(SCDesc)); 49*0b57cec5SDimitry Andric Optional<double> RThroughput = 50*0b57cec5SDimitry Andric MCSchedModel::getReciprocalThroughput(STI, SCDesc); 51*0b57cec5SDimitry Andric 52*0b57cec5SDimitry Andric TempStream << ' ' << NumMicroOpcodes << " "; 53*0b57cec5SDimitry Andric if (NumMicroOpcodes < 10) 54*0b57cec5SDimitry Andric TempStream << " "; 55*0b57cec5SDimitry Andric else if (NumMicroOpcodes < 100) 56*0b57cec5SDimitry Andric TempStream << ' '; 57*0b57cec5SDimitry Andric TempStream << Latency << " "; 58*0b57cec5SDimitry Andric if (Latency < 10) 59*0b57cec5SDimitry Andric TempStream << " "; 60*0b57cec5SDimitry Andric else if (Latency < 100) 61*0b57cec5SDimitry Andric TempStream << ' '; 62*0b57cec5SDimitry Andric 63*0b57cec5SDimitry Andric if (RThroughput.hasValue()) { 64*0b57cec5SDimitry Andric double RT = RThroughput.getValue(); 65*0b57cec5SDimitry Andric TempStream << format("%.2f", RT) << ' '; 66*0b57cec5SDimitry Andric if (RT < 10.0) 67*0b57cec5SDimitry Andric TempStream << " "; 68*0b57cec5SDimitry Andric else if (RT < 100.0) 69*0b57cec5SDimitry Andric TempStream << ' '; 70*0b57cec5SDimitry Andric } else { 71*0b57cec5SDimitry Andric TempStream << " - "; 72*0b57cec5SDimitry Andric } 73*0b57cec5SDimitry Andric TempStream << (MCDesc.mayLoad() ? " * " : " "); 74*0b57cec5SDimitry Andric TempStream << (MCDesc.mayStore() ? " * " : " "); 75*0b57cec5SDimitry Andric TempStream << (MCDesc.hasUnmodeledSideEffects() ? " U " : " "); 76*0b57cec5SDimitry Andric 77*0b57cec5SDimitry Andric MCIP.printInst(&Inst, InstrStream, "", STI); 78*0b57cec5SDimitry Andric InstrStream.flush(); 79*0b57cec5SDimitry Andric 80*0b57cec5SDimitry Andric // Consume any tabs or spaces at the beginning of the string. 81*0b57cec5SDimitry Andric StringRef Str(Instruction); 82*0b57cec5SDimitry Andric Str = Str.ltrim(); 83*0b57cec5SDimitry Andric TempStream << " " << Str << '\n'; 84*0b57cec5SDimitry Andric Instruction = ""; 85*0b57cec5SDimitry Andric } 86*0b57cec5SDimitry Andric 87*0b57cec5SDimitry Andric TempStream.flush(); 88*0b57cec5SDimitry Andric OS << Buffer; 89*0b57cec5SDimitry Andric } 90*0b57cec5SDimitry Andric } // namespace mca. 91*0b57cec5SDimitry Andric } // namespace llvm 92