Home | History | Annotate | Download | only in R600
      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