Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

254 lines
10 KiB

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