1 //===-- R600MachineScheduler.h - R600 Scheduler Interface -*- 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 /// \file 11 /// \brief R600 Machine Scheduler interface 12 // 13 //===----------------------------------------------------------------------===// 14 15 #ifndef R600MACHINESCHEDULER_H_ 16 #define R600MACHINESCHEDULER_H_ 17 18 #include "R600InstrInfo.h" 19 #include "llvm/CodeGen/MachineScheduler.h" 20 #include "llvm/Support/Debug.h" 21 #include "llvm/ADT/PriorityQueue.h" 22 23 using namespace llvm; 24 25 namespace llvm { 26 27 class CompareSUnit { 28 public: 29 bool operator()(const SUnit *S1, const SUnit *S2) { 30 return S1->getDepth() > S2->getDepth(); 31 } 32 }; 33 34 class R600SchedStrategy : public MachineSchedStrategy { 35 36 const ScheduleDAGMI *DAG; 37 const R600InstrInfo *TII; 38 const R600RegisterInfo *TRI; 39 MachineRegisterInfo *MRI; 40 41 enum InstQueue { 42 QAlu = 1, 43 QFetch = 2, 44 QOther = 4 45 }; 46 47 enum InstKind { 48 IDAlu, 49 IDFetch, 50 IDOther, 51 IDLast 52 }; 53 54 enum AluKind { 55 AluAny, 56 AluT_X, 57 AluT_Y, 58 AluT_Z, 59 AluT_W, 60 AluT_XYZW, 61 AluDiscarded, // LLVM Instructions that are going to be eliminated 62 AluLast 63 }; 64 65 ReadyQueue *Available[IDLast], *Pending[IDLast]; 66 std::multiset<SUnit *, CompareSUnit> AvailableAlus[AluLast]; 67 68 InstKind CurInstKind; 69 int CurEmitted; 70 InstKind NextInstKind; 71 72 int InstKindLimit[IDLast]; 73 74 int OccupedSlotsMask; 75 76 public: 77 R600SchedStrategy() : 78 DAG(0), TII(0), TRI(0), MRI(0) { 79 Available[IDAlu] = new ReadyQueue(QAlu, "AAlu"); 80 Available[IDFetch] = new ReadyQueue(QFetch, "AFetch"); 81 Available[IDOther] = new ReadyQueue(QOther, "AOther"); 82 Pending[IDAlu] = new ReadyQueue(QAlu<<4, "PAlu"); 83 Pending[IDFetch] = new ReadyQueue(QFetch<<4, "PFetch"); 84 Pending[IDOther] = new ReadyQueue(QOther<<4, "POther"); 85 } 86 87 virtual ~R600SchedStrategy() { 88 for (unsigned I = 0; I < IDLast; ++I) { 89 delete Available[I]; 90 delete Pending[I]; 91 } 92 } 93 94 virtual void initialize(ScheduleDAGMI *dag); 95 virtual SUnit *pickNode(bool &IsTopNode); 96 virtual void schedNode(SUnit *SU, bool IsTopNode); 97 virtual void releaseTopNode(SUnit *SU); 98 virtual void releaseBottomNode(SUnit *SU); 99 100 private: 101 std::vector<MachineInstr *> InstructionsGroupCandidate; 102 103 int getInstKind(SUnit *SU); 104 bool regBelongsToClass(unsigned Reg, const TargetRegisterClass *RC) const; 105 AluKind getAluKind(SUnit *SU) const; 106 void LoadAlu(); 107 bool isAvailablesAluEmpty() const; 108 SUnit *AttemptFillSlot (unsigned Slot); 109 void PrepareNextSlot(); 110 SUnit *PopInst(std::multiset<SUnit *, CompareSUnit> &Q); 111 112 void AssignSlot(MachineInstr *MI, unsigned Slot); 113 SUnit* pickAlu(); 114 SUnit* pickOther(int QID); 115 void MoveUnits(ReadyQueue *QSrc, ReadyQueue *QDst); 116 }; 117 118 } // namespace llvm 119 120 #endif /* R600MACHINESCHEDULER_H_ */ 121