LLVM  8.0.1
MCSchedule.cpp
Go to the documentation of this file.
1 //===- MCSchedule.cpp - Scheduling ------------------------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines the default scheduling model.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "llvm/MC/MCSchedule.h"
15 #include "llvm/MC/MCInst.h"
16 #include "llvm/MC/MCInstrDesc.h"
17 #include "llvm/MC/MCInstrInfo.h"
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, 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  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.getValue(), Temp) : Temp;
101  }
102  if (Throughput.hasValue())
103  return 1.0 / Throughput.getValue();
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, 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  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.getValue(), Temp) : Temp;
145  }
146  if (Throughput.hasValue())
147  return 1.0 / Throughput.getValue();
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 }
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
This class represents lattice values for constants.
Definition: AllocatorList.h:24
const InstrStage * beginStage(unsigned ItinClassIndx) const
Return the first stage of the itinerary.
unsigned IssueWidth
Definition: MCSchedule.h:256
unsigned getUnits() const
Returns the choice of FUs.
const MCProcResourceDesc * getProcResource(unsigned ProcResourceIdx) const
Definition: MCSchedule.h:339
unsigned getProcessorID() const
Definition: MCSchedule.h:317
const MCSchedClassDesc * getSchedClassDesc(unsigned SchedClassIdx) const
Definition: MCSchedule.h:346
const MCWriteLatencyEntry * getWriteLatencyEntry(const MCSchedClassDesc *SC, unsigned DefIdx) const
const MCWriteProcResEntry * getWriteProcResEnd(const MCSchedClassDesc *SC) const
const T & getValue() const LLVM_LVALUE_FUNCTION
Definition: Optional.h:161
Itinerary data supplied by a subtarget to be used by a target.
bool isValid() const
Definition: MCSchedule.h:127
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:161
Identify one of the processor resource kinds consumed by a particular scheduling class for the specif...
Definition: MCSchedule.h:64
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Summarize the scheduling resources required for an instruction of a particular scheduling class...
Definition: MCSchedule.h:110
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:24
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static const unsigned DefaultIssueWidth
Definition: MCSchedule.h:257
unsigned countPopulation(T Value)
Count the number of set bits in a value.
Definition: MathExtras.h:520
Specify the latency in cpu cycles for a particular scheduling class and def index.
Definition: MCSchedule.h:78
static const MCSchedModel Default
Definition: MCSchedule.h:375
unsigned getCycles() const
Returns the number of cycles the stage is occupied.
bool isVariant() const
Definition: MCSchedule.h:130
static double getReciprocalThroughput(const MCSubtargetInfo &STI, const MCSchedClassDesc &SCDesc)
Definition: MCSchedule.cpp:89
bool hasValue() const
Definition: Optional.h:165
static int computeInstrLatency(const MCSubtargetInfo &STI, const MCSchedClassDesc &SCDesc)
Returns the latency value for the scheduling class.
Definition: MCSchedule.cpp:41
These values represent a non-pipelined step in the execution of an instruction.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
Definition: MCInstrInfo.h:45
const InstrStage * endStage(unsigned ItinClassIndx) const
Return the last+1 stage of the itinerary.
#define I(x, y, z)
Definition: MD5.cpp:58
Generic base class for all target subtargets.
virtual unsigned resolveVariantSchedClass(unsigned SchedClass, const MCInst *MI, unsigned CPUID) const
Resolve a variant scheduling class for the given MCInst and CPU.
const MCWriteProcResEntry * getWriteProcResBegin(const MCSchedClassDesc *SC) const
Return an iterator at the first process resource consumed by the given scheduling class...
uint16_t NumWriteLatencyEntries
Definition: MCSchedule.h:123
unsigned getOpcode() const
Definition: MCInst.h:174
Machine model for scheduling, bundling, and heuristics.
Definition: MCSchedule.h:244
const MCSchedModel & getSchedModel() const
Get the machine model for this subtarget&#39;s CPU.