1//===-- llvm/MC/MCSchedule.h - 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 classes used to describe a subtarget's machine model 11// for scheduling and other instruction cost heuristics. 12// 13//===----------------------------------------------------------------------===// 14 15#ifndef LLVM_MC_MCSCHEDMODEL_H 16#define LLVM_MC_MCSCHEDMODEL_H 17 18#include "llvm/Support/DataTypes.h" 19#include <cassert> 20 21namespace llvm { 22 23struct InstrItinerary; 24 25/// Define a kind of processor resource that will be modeled by the scheduler. 26struct MCProcResourceDesc { 27#ifndef NDEBUG 28 const char *Name; 29#endif 30 unsigned NumUnits; // Number of resource of this kind 31 unsigned SuperIdx; // Index of the resources kind that contains this kind. 32 33 // Buffered resources may be consumed at some indeterminate cycle after 34 // dispatch (e.g. for instructions that may issue out-of-order). Unbuffered 35 // resources always consume their resource some fixed number of cycles after 36 // dispatch (e.g. for instruction interlocking that may stall the pipeline). 37 bool IsBuffered; 38 39 bool operator==(const MCProcResourceDesc &Other) const { 40 return NumUnits == Other.NumUnits && SuperIdx == Other.SuperIdx 41 && IsBuffered == Other.IsBuffered; 42 } 43}; 44 45/// Identify one of the processor resource kinds consumed by a particular 46/// scheduling class for the specified number of cycles. 47struct MCWriteProcResEntry { 48 unsigned ProcResourceIdx; 49 unsigned Cycles; 50 51 bool operator==(const MCWriteProcResEntry &Other) const { 52 return ProcResourceIdx == Other.ProcResourceIdx && Cycles == Other.Cycles; 53 } 54}; 55 56/// Specify the latency in cpu cycles for a particular scheduling class and def 57/// index. Also identify the WriteResources of this def. When the operand 58/// expands to a sequence of writes, this ID is the last write in the sequence. 59struct MCWriteLatencyEntry { 60 unsigned Cycles; 61 unsigned WriteResourceID; 62 63 bool operator==(const MCWriteLatencyEntry &Other) const { 64 return Cycles == Other.Cycles && WriteResourceID == Other.WriteResourceID; 65 } 66}; 67 68/// Specify the number of cycles allowed after instruction issue before a 69/// particular use operand reads its registers. This effectively reduces the 70/// write's latency. Here we allow negative cycles for corner cases where 71/// latency increases. This rule only applies when the entry's WriteResource 72/// matches the write's WriteResource. 73/// 74/// MCReadAdvanceEntries are sorted first by operand index (UseIdx), then by 75/// WriteResourceIdx. 76struct MCReadAdvanceEntry { 77 unsigned UseIdx; 78 unsigned WriteResourceID; 79 int Cycles; 80 81 bool operator==(const MCReadAdvanceEntry &Other) const { 82 return UseIdx == Other.UseIdx && WriteResourceID == Other.WriteResourceID 83 && Cycles == Other.Cycles; 84 } 85}; 86 87/// Summarize the scheduling resources required for an instruction of a 88/// particular scheduling class. 89/// 90/// Defined as an aggregate struct for creating tables with initializer lists. 91struct MCSchedClassDesc { 92 static const unsigned short InvalidNumMicroOps = UINT16_MAX; 93 static const unsigned short VariantNumMicroOps = UINT16_MAX - 1; 94 95#ifndef NDEBUG 96 const char* Name; 97#endif 98 unsigned short NumMicroOps; 99 bool BeginGroup; 100 bool EndGroup; 101 unsigned WriteProcResIdx; // First index into WriteProcResTable. 102 unsigned NumWriteProcResEntries; 103 unsigned WriteLatencyIdx; // First index into WriteLatencyTable. 104 unsigned NumWriteLatencyEntries; 105 unsigned ReadAdvanceIdx; // First index into ReadAdvanceTable. 106 unsigned NumReadAdvanceEntries; 107 108 bool isValid() const { 109 return NumMicroOps != InvalidNumMicroOps; 110 } 111 bool isVariant() const { 112 return NumMicroOps == VariantNumMicroOps; 113 } 114}; 115 116/// Machine model for scheduling, bundling, and heuristics. 117/// 118/// The machine model directly provides basic information about the 119/// microarchitecture to the scheduler in the form of properties. It also 120/// optionally refers to scheduler resource tables and itinerary 121/// tables. Scheduler resource tables model the latency and cost for each 122/// instruction type. Itinerary tables are an independant mechanism that 123/// provides a detailed reservation table describing each cycle of instruction 124/// execution. Subtargets may define any or all of the above categories of data 125/// depending on the type of CPU and selected scheduler. 126class MCSchedModel { 127public: 128 static MCSchedModel DefaultSchedModel; // For unknown processors. 129 130 // IssueWidth is the maximum number of instructions that may be scheduled in 131 // the same per-cycle group. 132 unsigned IssueWidth; 133 static const unsigned DefaultIssueWidth = 1; 134 135 // MinLatency is the minimum latency between a register write 136 // followed by a data dependent read. This determines which 137 // instructions may be scheduled in the same per-cycle group. This 138 // is distinct from *expected* latency, which determines the likely 139 // critical path but does not guarantee a pipeline 140 // hazard. MinLatency can always be overridden by the number of 141 // InstrStage cycles. 142 // 143 // (-1) Standard in-order processor. 144 // Use InstrItinerary OperandCycles as MinLatency. 145 // If no OperandCycles exist, then use the cycle of the last InstrStage. 146 // 147 // (0) Out-of-order processor, or in-order with bundled dependencies. 148 // RAW dependencies may be dispatched in the same cycle. 149 // Optional InstrItinerary OperandCycles provides expected latency. 150 // 151 // (>0) In-order processor with variable latencies. 152 // Use the greater of this value or the cycle of the last InstrStage. 153 // Optional InstrItinerary OperandCycles provides expected latency. 154 // TODO: can't yet specify both min and expected latency per operand. 155 int MinLatency; 156 static const unsigned DefaultMinLatency = -1; 157 158 // LoadLatency is the expected latency of load instructions. 159 // 160 // If MinLatency >= 0, this may be overriden for individual load opcodes by 161 // InstrItinerary OperandCycles. 162 unsigned LoadLatency; 163 static const unsigned DefaultLoadLatency = 4; 164 165 // HighLatency is the expected latency of "very high latency" operations. 166 // See TargetInstrInfo::isHighLatencyDef(). 167 // By default, this is set to an arbitrarily high number of cycles 168 // likely to have some impact on scheduling heuristics. 169 // If MinLatency >= 0, this may be overriden by InstrItinData OperandCycles. 170 unsigned HighLatency; 171 static const unsigned DefaultHighLatency = 10; 172 173 // MispredictPenalty is the typical number of extra cycles the processor 174 // takes to recover from a branch misprediction. 175 unsigned MispredictPenalty; 176 static const unsigned DefaultMispredictPenalty = 10; 177 178private: 179 unsigned ProcID; 180 const MCProcResourceDesc *ProcResourceTable; 181 const MCSchedClassDesc *SchedClassTable; 182 unsigned NumProcResourceKinds; 183 unsigned NumSchedClasses; 184 // Instruction itinerary tables used by InstrItineraryData. 185 friend class InstrItineraryData; 186 const InstrItinerary *InstrItineraries; 187 188public: 189 // Default's must be specified as static const literals so that tablegenerated 190 // target code can use it in static initializers. The defaults need to be 191 // initialized in this default ctor because some clients directly instantiate 192 // MCSchedModel instead of using a generated itinerary. 193 MCSchedModel(): IssueWidth(DefaultIssueWidth), 194 MinLatency(DefaultMinLatency), 195 LoadLatency(DefaultLoadLatency), 196 HighLatency(DefaultHighLatency), 197 MispredictPenalty(DefaultMispredictPenalty), 198 ProcID(0), ProcResourceTable(0), SchedClassTable(0), 199 NumProcResourceKinds(0), NumSchedClasses(0), 200 InstrItineraries(0) { 201 (void)NumProcResourceKinds; 202 (void)NumSchedClasses; 203 } 204 205 // Table-gen driven ctor. 206 MCSchedModel(unsigned iw, int ml, unsigned ll, unsigned hl, unsigned mp, 207 unsigned pi, const MCProcResourceDesc *pr, 208 const MCSchedClassDesc *sc, unsigned npr, unsigned nsc, 209 const InstrItinerary *ii): 210 IssueWidth(iw), MinLatency(ml), LoadLatency(ll), HighLatency(hl), 211 MispredictPenalty(mp), ProcID(pi), ProcResourceTable(pr), 212 SchedClassTable(sc), NumProcResourceKinds(npr), NumSchedClasses(nsc), 213 InstrItineraries(ii) {} 214 215 unsigned getProcessorID() const { return ProcID; } 216 217 /// Does this machine model include instruction-level scheduling. 218 bool hasInstrSchedModel() const { return SchedClassTable; } 219 220 const MCProcResourceDesc *getProcResource(unsigned ProcResourceIdx) const { 221 assert(hasInstrSchedModel() && "No scheduling machine model"); 222 223 assert(ProcResourceIdx < NumProcResourceKinds && "bad proc resource idx"); 224 return &ProcResourceTable[ProcResourceIdx]; 225 } 226 227 const MCSchedClassDesc *getSchedClassDesc(unsigned SchedClassIdx) const { 228 assert(hasInstrSchedModel() && "No scheduling machine model"); 229 230 assert(SchedClassIdx < NumSchedClasses && "bad scheduling class idx"); 231 return &SchedClassTable[SchedClassIdx]; 232 } 233}; 234 235} // End llvm namespace 236 237#endif 238