InstructionInfoView.cpp revision 360784
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
17namespace llvm {
18namespace mca {
19
20void InstructionInfoView::printView(raw_ostream &OS) const {
21  std::string Buffer;
22  raw_string_ostream TempStream(Buffer);
23  const MCSchedModel &SM = STI.getSchedModel();
24
25  std::string Instruction;
26  raw_string_ostream InstrStream(Instruction);
27
28  TempStream << "\n\nInstruction Info:\n";
29  TempStream << "[1]: #uOps\n[2]: Latency\n[3]: RThroughput\n"
30             << "[4]: MayLoad\n[5]: MayStore\n[6]: HasSideEffects (U)\n";
31  if (PrintEncodings) {
32    TempStream << "[7]: Encoding Size\n";
33    TempStream << "\n[1]    [2]    [3]    [4]    [5]    [6]    [7]    "
34               << "Encodings:                    Instructions:\n";
35  } else {
36    TempStream << "\n[1]    [2]    [3]    [4]    [5]    [6]    Instructions:\n";
37  }
38
39  for (unsigned I = 0, E = Source.size(); I < E; ++I) {
40    const MCInst &Inst = Source[I];
41    const MCInstrDesc &MCDesc = MCII.get(Inst.getOpcode());
42
43    // Obtain the scheduling class information from the instruction.
44    unsigned SchedClassID = MCDesc.getSchedClass();
45    unsigned CPUID = SM.getProcessorID();
46
47    // Try to solve variant scheduling classes.
48    while (SchedClassID && SM.getSchedClassDesc(SchedClassID)->isVariant())
49      SchedClassID = STI.resolveVariantSchedClass(SchedClassID, &Inst, CPUID);
50
51    const MCSchedClassDesc &SCDesc = *SM.getSchedClassDesc(SchedClassID);
52    unsigned NumMicroOpcodes = SCDesc.NumMicroOps;
53    unsigned Latency = MCSchedModel::computeInstrLatency(STI, SCDesc);
54    // Add extra latency due to delays in the forwarding data paths.
55    Latency += MCSchedModel::getForwardingDelayCycles(
56        STI.getReadAdvanceEntries(SCDesc));
57    Optional<double> RThroughput =
58        MCSchedModel::getReciprocalThroughput(STI, SCDesc);
59
60    TempStream << ' ' << NumMicroOpcodes << "    ";
61    if (NumMicroOpcodes < 10)
62      TempStream << "  ";
63    else if (NumMicroOpcodes < 100)
64      TempStream << ' ';
65    TempStream << Latency << "   ";
66    if (Latency < 10)
67      TempStream << "  ";
68    else if (Latency < 100)
69      TempStream << ' ';
70
71    if (RThroughput.hasValue()) {
72      double RT = RThroughput.getValue();
73      TempStream << format("%.2f", RT) << ' ';
74      if (RT < 10.0)
75        TempStream << "  ";
76      else if (RT < 100.0)
77        TempStream << ' ';
78    } else {
79      TempStream << " -     ";
80    }
81    TempStream << (MCDesc.mayLoad() ? " *     " : "       ");
82    TempStream << (MCDesc.mayStore() ? " *     " : "       ");
83    TempStream << (MCDesc.hasUnmodeledSideEffects() ? " U     " : "       ");
84
85    if (PrintEncodings) {
86      StringRef Encoding(CE.getEncoding(I));
87      unsigned EncodingSize = Encoding.size();
88      TempStream << " " << EncodingSize
89                 << (EncodingSize < 10 ? "     " : "    ");
90      TempStream.flush();
91      formatted_raw_ostream FOS(TempStream);
92      for (unsigned i = 0, e = Encoding.size(); i != e; ++i)
93        FOS << format("%02x ", (uint8_t)Encoding[i]);
94      FOS.PadToColumn(30);
95      FOS.flush();
96    }
97
98    MCIP.printInst(&Inst, 0, "", STI, InstrStream);
99    InstrStream.flush();
100
101    // Consume any tabs or spaces at the beginning of the string.
102    StringRef Str(Instruction);
103    Str = Str.ltrim();
104    TempStream << Str << '\n';
105    Instruction = "";
106  }
107
108  TempStream.flush();
109  OS << Buffer;
110}
111} // namespace mca.
112} // namespace llvm
113