LLVM  16.0.0git
MCSchedule.cpp
Go to the documentation of this file.
1 //===- MCSchedule.cpp - Scheduling ------------------------------*- 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 //
9 // This file defines the default scheduling model.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "llvm/MC/MCSchedule.h"
14 #include "llvm/MC/MCInst.h"
15 #include "llvm/MC/MCInstrDesc.h"
16 #include "llvm/MC/MCInstrInfo.h"
18 #include <optional>
19 #include <type_traits>
20 
21 using namespace llvm;
22 
23 static_assert(std::is_pod<MCSchedModel>::value,
24  "We shouldn't have a static constructor here");
25 const MCSchedModel MCSchedModel::Default = {DefaultIssueWidth,
26  DefaultMicroOpBufferSize,
27  DefaultLoopMicroOpBufferSize,
28  DefaultLoadLatency,
29  DefaultHighLatency,
30  DefaultMispredictPenalty,
31  false,
32  true,
33  0,
34  nullptr,
35  nullptr,
36  0,
37  0,
38  nullptr,
39  nullptr};
40 
42  const MCSchedClassDesc &SCDesc) {
43  int Latency = 0;
44  for (unsigned DefIdx = 0, DefEnd = SCDesc.NumWriteLatencyEntries;
45  DefIdx != DefEnd; ++DefIdx) {
46  // Lookup the definition's write latency in SubtargetInfo.
47  const MCWriteLatencyEntry *WLEntry =
48  STI.getWriteLatencyEntry(&SCDesc, DefIdx);
49  // Early exit if we found an invalid latency.
50  if (WLEntry->Cycles < 0)
51  return WLEntry->Cycles;
52  Latency = std::max(Latency, static_cast<int>(WLEntry->Cycles));
53  }
54  return Latency;
55 }
56 
58  unsigned SchedClass) const {
59  const MCSchedClassDesc &SCDesc = *getSchedClassDesc(SchedClass);
60  if (!SCDesc.isValid())
61  return 0;
62  if (!SCDesc.isVariant())
63  return MCSchedModel::computeInstrLatency(STI, SCDesc);
64 
65  llvm_unreachable("unsupported variant scheduling class");
66 }
67 
69  const MCInstrInfo &MCII,
70  const MCInst &Inst) const {
71  unsigned SchedClass = MCII.get(Inst.getOpcode()).getSchedClass();
72  const MCSchedClassDesc *SCDesc = getSchedClassDesc(SchedClass);
73  if (!SCDesc->isValid())
74  return 0;
75 
76  unsigned CPUID = getProcessorID();
77  while (SCDesc->isVariant()) {
78  SchedClass = STI.resolveVariantSchedClass(SchedClass, &Inst, &MCII, CPUID);
79  SCDesc = getSchedClassDesc(SchedClass);
80  }
81 
82  if (SchedClass)
83  return MCSchedModel::computeInstrLatency(STI, *SCDesc);
84 
85  llvm_unreachable("unsupported variant scheduling class");
86 }
87 
88 double
90  const MCSchedClassDesc &SCDesc) {
91  std::optional<double> Throughput;
92  const MCSchedModel &SM = STI.getSchedModel();
93  const MCWriteProcResEntry *I = STI.getWriteProcResBegin(&SCDesc);
94  const MCWriteProcResEntry *E = STI.getWriteProcResEnd(&SCDesc);
95  for (; I != E; ++I) {
96  if (!I->Cycles)
97  continue;
98  unsigned NumUnits = SM.getProcResource(I->ProcResourceIdx)->NumUnits;
99  double Temp = NumUnits * 1.0 / I->Cycles;
100  Throughput = Throughput ? std::min(Throughput.value(), Temp) : Temp;
101  }
102  if (Throughput)
103  return 1.0 / Throughput.value();
104 
105  // If no throughput value was calculated, assume that we can execute at the
106  // maximum issue width scaled by number of micro-ops for the schedule class.
107  return ((double)SCDesc.NumMicroOps) / SM.IssueWidth;
108 }
109 
110 double
112  const MCInstrInfo &MCII,
113  const MCInst &Inst) const {
114  unsigned SchedClass = MCII.get(Inst.getOpcode()).getSchedClass();
115  const MCSchedClassDesc *SCDesc = getSchedClassDesc(SchedClass);
116 
117  // If there's no valid class, assume that the instruction executes/completes
118  // at the maximum issue width.
119  if (!SCDesc->isValid())
120  return 1.0 / IssueWidth;
121 
122  unsigned CPUID = getProcessorID();
123  while (SCDesc->isVariant()) {
124  SchedClass = STI.resolveVariantSchedClass(SchedClass, &Inst, &MCII, CPUID);
125  SCDesc = getSchedClassDesc(SchedClass);
126  }
127 
128  if (SchedClass)
129  return MCSchedModel::getReciprocalThroughput(STI, *SCDesc);
130 
131  llvm_unreachable("unsupported variant scheduling class");
132 }
133 
134 double
136  const InstrItineraryData &IID) {
137  std::optional<double> Throughput;
138  const InstrStage *I = IID.beginStage(SchedClass);
139  const InstrStage *E = IID.endStage(SchedClass);
140  for (; I != E; ++I) {
141  if (!I->getCycles())
142  continue;
143  double Temp = countPopulation(I->getUnits()) * 1.0 / I->getCycles();
144  Throughput = Throughput ? std::min(Throughput.value(), Temp) : Temp;
145  }
146  if (Throughput)
147  return 1.0 / Throughput.value();
148 
149  // If there are no execution resources specified for this class, then assume
150  // that it can execute at the maximum default issue width.
151  return 1.0 / DefaultIssueWidth;
152 }
153 
154 unsigned
156  unsigned WriteResourceID) {
157  if (Entries.empty())
158  return 0;
159 
160  int DelayCycles = 0;
161  for (const MCReadAdvanceEntry &E : Entries) {
162  if (E.WriteResourceID != WriteResourceID)
163  continue;
164  DelayCycles = std::min(DelayCycles, E.Cycles);
165  }
166 
167  return std::abs(DelayCycles);
168 }
llvm::MCSubtargetInfo::getWriteProcResEnd
const MCWriteProcResEntry * getWriteProcResEnd(const MCSchedClassDesc *SC) const
Definition: MCSubtargetInfo.h:171
llvm::MCWriteLatencyEntry::Cycles
int16_t Cycles
Definition: MCSchedule.h:78
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::MCSchedClassDesc::NumWriteLatencyEntries
uint16_t NumWriteLatencyEntries
Definition: MCSchedule.h:123
llvm::Latency
@ Latency
Definition: SIMachineScheduler.h:34
MCInstrDesc.h
llvm::MCSubtargetInfo::getSchedModel
const MCSchedModel & getSchedModel() const
Get the machine model for this subtarget's CPU.
Definition: MCSubtargetInfo.h:163
llvm::MCInstrDesc::getSchedClass
unsigned getSchedClass() const
Return the scheduling class for this instruction.
Definition: MCInstrDesc.h:618
llvm::MCSchedModel::getForwardingDelayCycles
static unsigned getForwardingDelayCycles(ArrayRef< MCReadAdvanceEntry > Entries, unsigned WriteResourceIdx=0)
Returns the maximum forwarding delay for register reads dependent on writes of scheduling class Write...
Definition: MCSchedule.cpp:155
llvm::MCProcResourceDesc::NumUnits
unsigned NumUnits
Definition: MCSchedule.h:33
llvm::max
Expected< ExpressionValue > max(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
Definition: FileCheck.cpp:337
llvm::MCWriteProcResEntry
Identify one of the processor resource kinds consumed by a particular scheduling class for the specif...
Definition: MCSchedule.h:63
llvm::MCInst
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
llvm::InstrItineraryData::endStage
const InstrStage * endStage(unsigned ItinClassIndx) const
Return the last+1 stage of the itinerary.
Definition: MCInstrItineraries.h:141
llvm::MCSchedClassDesc::isValid
bool isValid() const
Definition: MCSchedule.h:127
llvm::MCSubtargetInfo::resolveVariantSchedClass
virtual unsigned resolveVariantSchedClass(unsigned SchedClass, const MCInst *MI, const MCInstrInfo *MCII, unsigned CPUID) const
Resolve a variant scheduling class for the given MCInst and CPU.
Definition: MCSubtargetInfo.h:220
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::MCSchedClassDesc::NumMicroOps
uint16_t NumMicroOps
Definition: MCSchedule.h:116
llvm::MCSchedClassDesc
Summarize the scheduling resources required for an instruction of a particular scheduling class.
Definition: MCSchedule.h:109
MCInstrInfo.h
MCInst.h
MCSubtargetInfo.h
llvm::MCSubtargetInfo::getWriteLatencyEntry
const MCWriteLatencyEntry * getWriteLatencyEntry(const MCSchedClassDesc *SC, unsigned DefIdx) const
Definition: MCSubtargetInfo.h:176
llvm::MCSchedModel::Default
static const MCSchedModel Default
Definition: MCSchedule.h:380
llvm::MCSchedModel::computeInstrLatency
static int computeInstrLatency(const MCSubtargetInfo &STI, const MCSchedClassDesc &SCDesc)
Returns the latency value for the scheduling class.
Definition: MCSchedule.cpp:41
llvm::countPopulation
unsigned countPopulation(T Value)
Count the number of set bits in a value.
Definition: MathExtras.h:501
MCSchedule.h
llvm::MCSchedModel::IssueWidth
unsigned IssueWidth
Definition: MCSchedule.h:256
llvm::MCWriteLatencyEntry
Specify the latency in cpu cycles for a particular scheduling class and def index.
Definition: MCSchedule.h:77
I
#define I(x, y, z)
Definition: MD5.cpp:58
llvm::MCSubtargetInfo::getWriteProcResBegin
const MCWriteProcResEntry * getWriteProcResBegin(const MCSchedClassDesc *SC) const
Return an iterator at the first process resource consumed by the given scheduling class.
Definition: MCSubtargetInfo.h:167
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: APInt.h:32
llvm::MCSchedModel::getProcessorID
unsigned getProcessorID() const
Definition: MCSchedule.h:317
llvm::min
Expected< ExpressionValue > min(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
Definition: FileCheck.cpp:357
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:143
llvm::InstrStage
These values represent a non-pipelined step in the execution of an instruction.
Definition: MCInstrItineraries.h:58
llvm::MCInstrInfo
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:26
llvm::MCSchedClassDesc::isVariant
bool isVariant() const
Definition: MCSchedule.h:130
llvm::MCSchedModel::getProcResource
const MCProcResourceDesc * getProcResource(unsigned ProcResourceIdx) const
Definition: MCSchedule.h:339
llvm::MCReadAdvanceEntry
Specify the number of cycles allowed after instruction issue before a particular use operand reads it...
Definition: MCSchedule.h:94
llvm::MCInst::getOpcode
unsigned getOpcode() const
Definition: MCInst.h:198
llvm::MCSchedModel
Machine model for scheduling, bundling, and heuristics.
Definition: MCSchedule.h:244
llvm::MCSchedModel::getReciprocalThroughput
static double getReciprocalThroughput(const MCSubtargetInfo &STI, const MCSchedClassDesc &SCDesc)
Definition: MCSchedule.cpp:89
llvm::MCSchedModel::getSchedClassDesc
const MCSchedClassDesc * getSchedClassDesc(unsigned SchedClassIdx) const
Definition: MCSchedule.h:346
llvm::MCInstrInfo::get
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
Definition: MCInstrInfo.h:63
llvm::InstrItineraryData::beginStage
const InstrStage * beginStage(unsigned ItinClassIndx) const
Return the first stage of the itinerary.
Definition: MCInstrItineraries.h:135
llvm::abs
APFloat abs(APFloat X)
Returns the absolute value of the argument.
Definition: APFloat.h:1297
llvm::MCSubtargetInfo
Generic base class for all target subtargets.
Definition: MCSubtargetInfo.h:76
llvm::MCSchedModel::DefaultIssueWidth
static const unsigned DefaultIssueWidth
Definition: MCSchedule.h:257
llvm::InstrItineraryData
Itinerary data supplied by a subtarget to be used by a target.
Definition: MCInstrItineraries.h:109