1 //===--------------------- InstructionInfoView.cpp --------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// \file 9 /// 10 /// This file implements the InstructionInfoView API. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #include "Views/InstructionInfoView.h" 15 #include "llvm/Support/FormattedStream.h" 16 17 namespace llvm { 18 namespace mca { 19 20 void InstructionInfoView::printView(raw_ostream &OS) const { 21 std::string Buffer; 22 raw_string_ostream TempStream(Buffer); 23 std::string Instruction; 24 raw_string_ostream InstrStream(Instruction); 25 26 if (!Source.size()) 27 return; 28 29 IIVDVec IIVD(Source.size()); 30 collectData(IIVD); 31 32 TempStream << "\n\nInstruction Info:\n"; 33 TempStream << "[1]: #uOps\n[2]: Latency\n[3]: RThroughput\n" 34 << "[4]: MayLoad\n[5]: MayStore\n[6]: HasSideEffects (U)\n"; 35 if (PrintEncodings) { 36 TempStream << "[7]: Encoding Size\n"; 37 TempStream << "\n[1] [2] [3] [4] [5] [6] [7] " 38 << "Encodings: Instructions:\n"; 39 } else { 40 TempStream << "\n[1] [2] [3] [4] [5] [6] Instructions:\n"; 41 } 42 43 for (auto I : enumerate(zip(IIVD, Source))) { 44 const InstructionInfoViewData &IIVDEntry = std::get<0>(I.value()); 45 46 TempStream << ' ' << IIVDEntry.NumMicroOpcodes << " "; 47 if (IIVDEntry.NumMicroOpcodes < 10) 48 TempStream << " "; 49 else if (IIVDEntry.NumMicroOpcodes < 100) 50 TempStream << ' '; 51 TempStream << IIVDEntry.Latency << " "; 52 if (IIVDEntry.Latency < 10) 53 TempStream << " "; 54 else if (IIVDEntry.Latency < 100) 55 TempStream << ' '; 56 57 if (IIVDEntry.RThroughput.hasValue()) { 58 double RT = IIVDEntry.RThroughput.getValue(); 59 TempStream << format("%.2f", RT) << ' '; 60 if (RT < 10.0) 61 TempStream << " "; 62 else if (RT < 100.0) 63 TempStream << ' '; 64 } else { 65 TempStream << " - "; 66 } 67 TempStream << (IIVDEntry.mayLoad ? " * " : " "); 68 TempStream << (IIVDEntry.mayStore ? " * " : " "); 69 TempStream << (IIVDEntry.hasUnmodeledSideEffects ? " U " : " "); 70 71 if (PrintEncodings) { 72 StringRef Encoding(CE.getEncoding(I.index())); 73 unsigned EncodingSize = Encoding.size(); 74 TempStream << " " << EncodingSize 75 << (EncodingSize < 10 ? " " : " "); 76 TempStream.flush(); 77 formatted_raw_ostream FOS(TempStream); 78 for (unsigned i = 0, e = Encoding.size(); i != e; ++i) 79 FOS << format("%02x ", (uint8_t)Encoding[i]); 80 FOS.PadToColumn(30); 81 FOS.flush(); 82 } 83 84 const MCInst &Inst = std::get<1>(I.value()); 85 MCIP.printInst(&Inst, 0, "", STI, InstrStream); 86 InstrStream.flush(); 87 88 // Consume any tabs or spaces at the beginning of the string. 89 StringRef Str(Instruction); 90 Str = Str.ltrim(); 91 TempStream << Str << '\n'; 92 Instruction = ""; 93 } 94 95 TempStream.flush(); 96 OS << Buffer; 97 } 98 99 void InstructionInfoView::collectData( 100 MutableArrayRef<InstructionInfoViewData> IIVD) const { 101 const MCSchedModel &SM = STI.getSchedModel(); 102 for (auto I : zip(Source, IIVD)) { 103 const MCInst &Inst = std::get<0>(I); 104 InstructionInfoViewData &IIVDEntry = std::get<1>(I); 105 const MCInstrDesc &MCDesc = MCII.get(Inst.getOpcode()); 106 107 // Obtain the scheduling class information from the instruction. 108 unsigned SchedClassID = MCDesc.getSchedClass(); 109 unsigned CPUID = SM.getProcessorID(); 110 111 // Try to solve variant scheduling classes. 112 while (SchedClassID && SM.getSchedClassDesc(SchedClassID)->isVariant()) 113 SchedClassID = STI.resolveVariantSchedClass(SchedClassID, &Inst, CPUID); 114 115 const MCSchedClassDesc &SCDesc = *SM.getSchedClassDesc(SchedClassID); 116 IIVDEntry.NumMicroOpcodes = SCDesc.NumMicroOps; 117 IIVDEntry.Latency = MCSchedModel::computeInstrLatency(STI, SCDesc); 118 // Add extra latency due to delays in the forwarding data paths. 119 IIVDEntry.Latency += MCSchedModel::getForwardingDelayCycles( 120 STI.getReadAdvanceEntries(SCDesc)); 121 IIVDEntry.RThroughput = MCSchedModel::getReciprocalThroughput(STI, SCDesc); 122 IIVDEntry.mayLoad = MCDesc.mayLoad(); 123 IIVDEntry.mayStore = MCDesc.mayStore(); 124 IIVDEntry.hasUnmodeledSideEffects = MCDesc.hasUnmodeledSideEffects(); 125 } 126 } 127 } // namespace mca. 128 } // namespace llvm 129