1 //=-- SystemZHazardRecognizer.h - SystemZ Hazard Recognizer -----*- 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 declares a hazard recognizer for the SystemZ scheduler. 11 // 12 // This class is used by the SystemZ scheduling strategy to maintain 13 // the state during scheduling, and provide cost functions for 14 // scheduling candidates. This includes: 15 // 16 // * Decoder grouping. A decoder group can maximally hold 3 uops, and 17 // instructions that always begin a new group should be scheduled when 18 // the current decoder group is empty. 19 // * Processor resources usage. It is beneficial to balance the use of 20 // resources. 21 // 22 // ===---------------------------------------------------------------------===// 23 24 #ifndef LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZHAZARDRECOGNIZER_H 25 #define LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZHAZARDRECOGNIZER_H 26 27 #include "SystemZSubtarget.h" 28 #include "llvm/CodeGen/MachineFunction.h" 29 #include "llvm/CodeGen/MachineScheduler.h" 30 #include "llvm/CodeGen/ScheduleHazardRecognizer.h" 31 #include "llvm/ADT/SmallVector.h" 32 #include "llvm/MC/MCInstrDesc.h" 33 #include "llvm/Support/raw_ostream.h" 34 #include <string> 35 36 namespace llvm { 37 38 /// SystemZHazardRecognizer maintains the state during scheduling. 39 class SystemZHazardRecognizer : public ScheduleHazardRecognizer { 40 41 ScheduleDAGMI *DAG; 42 const TargetSchedModel *SchedModel; 43 44 /// Keep track of the number of decoder slots used in the current 45 /// decoder group. 46 unsigned CurrGroupSize; 47 48 /// The tracking of resources here are quite similar to the common 49 /// code use of a critical resource. However, z13 differs in the way 50 /// that it has two processor sides which may be interesting to 51 /// model in the future (a work in progress). 52 53 /// Counters for the number of uops scheduled per processor 54 /// resource. 55 SmallVector<int, 0> ProcResourceCounters; 56 57 /// This is the resource with the greatest queue, which the 58 /// scheduler tries to avoid. 59 unsigned CriticalResourceIdx; 60 61 /// Return the number of decoder slots MI requires. 62 inline unsigned getNumDecoderSlots(SUnit *SU) const; 63 64 /// Return true if MI fits into current decoder group. 65 bool fitsIntoCurrentGroup(SUnit *SU) const; 66 67 /// Two decoder groups per cycle are formed (for z13), meaning 2x3 68 /// instructions. This function returns a number between 0 and 5, 69 /// representing the current decoder slot of the current cycle. 70 unsigned getCurrCycleIdx(); 71 72 /// LastFPdOpCycleIdx stores the numbeer returned by getCurrCycleIdx() 73 /// when a stalling operation is scheduled (which uses the FPd resource). 74 unsigned LastFPdOpCycleIdx; 75 76 /// A counter of decoder groups scheduled. 77 unsigned GrpCount; 78 79 unsigned getCurrGroupSize() {return CurrGroupSize;}; 80 81 /// Start next decoder group. 82 void nextGroup(bool DbgOutput = true); 83 84 /// Clear all counters for processor resources. 85 void clearProcResCounters(); 86 87 /// With the goal of alternating processor sides for stalling (FPd) 88 /// ops, return true if it seems good to schedule an FPd op next. 89 bool isFPdOpPreferred_distance(const SUnit *SU); 90 91 public: 92 SystemZHazardRecognizer(const MachineSchedContext *C); 93 94 void setDAG(ScheduleDAGMI *dag) { 95 DAG = dag; 96 SchedModel = dag->getSchedModel(); 97 } 98 99 HazardType getHazardType(SUnit *m, int Stalls = 0) override; 100 void Reset() override; 101 void EmitInstruction(SUnit *SU) override; 102 103 // Cost functions used by SystemZPostRASchedStrategy while 104 // evaluating candidates. 105 106 /// Return the cost of decoder grouping for SU. If SU must start a 107 /// new decoder group, this is negative if this fits the schedule or 108 /// positive if it would mean ending a group prematurely. For normal 109 /// instructions this returns 0. 110 int groupingCost(SUnit *SU) const; 111 112 /// Return the cost of SU in regards to processor resources usage. 113 /// A positive value means it would be better to wait with SU, while 114 /// a negative value means it would be good to schedule SU next. 115 int resourcesCost(SUnit *SU); 116 117 #ifndef NDEBUG 118 // Debug dumping. 119 std::string CurGroupDbg; // current group as text 120 void dumpSU(SUnit *SU, raw_ostream &OS) const; 121 void dumpCurrGroup(std::string Msg = "") const; 122 void dumpProcResourceCounters() const; 123 #endif 124 }; 125 126 } // namespace llvm 127 128 #endif /* LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZHAZARDRECOGNIZER_H */ 129