//===-- R600MachineScheduler.h - R600 Scheduler Interface -*- C++ -*-------===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // /// \file /// \brief R600 Machine Scheduler interface // //===----------------------------------------------------------------------===// #ifndef R600MACHINESCHEDULER_H_ #define R600MACHINESCHEDULER_H_ #include "R600InstrInfo.h" #include "llvm/CodeGen/MachineScheduler.h" #include "llvm/Support/Debug.h" #include "llvm/ADT/PriorityQueue.h" using namespace llvm; namespace llvm { class CompareSUnit { public: bool operator()(const SUnit *S1, const SUnit *S2) { return S1->getDepth() > S2->getDepth(); } }; class R600SchedStrategy : public MachineSchedStrategy { const ScheduleDAGMI *DAG; const R600InstrInfo *TII; const R600RegisterInfo *TRI; MachineRegisterInfo *MRI; enum InstQueue { QAlu = 1, QFetch = 2, QOther = 4 }; enum InstKind { IDAlu, IDFetch, IDOther, IDLast }; enum AluKind { AluAny, AluT_X, AluT_Y, AluT_Z, AluT_W, AluT_XYZW, AluDiscarded, // LLVM Instructions that are going to be eliminated AluLast }; ReadyQueue *Available[IDLast], *Pending[IDLast]; std::multiset AvailableAlus[AluLast]; InstKind CurInstKind; int CurEmitted; InstKind NextInstKind; int InstKindLimit[IDLast]; int OccupedSlotsMask; public: R600SchedStrategy() : DAG(0), TII(0), TRI(0), MRI(0) { Available[IDAlu] = new ReadyQueue(QAlu, "AAlu"); Available[IDFetch] = new ReadyQueue(QFetch, "AFetch"); Available[IDOther] = new ReadyQueue(QOther, "AOther"); Pending[IDAlu] = new ReadyQueue(QAlu<<4, "PAlu"); Pending[IDFetch] = new ReadyQueue(QFetch<<4, "PFetch"); Pending[IDOther] = new ReadyQueue(QOther<<4, "POther"); } virtual ~R600SchedStrategy() { for (unsigned I = 0; I < IDLast; ++I) { delete Available[I]; delete Pending[I]; } } virtual void initialize(ScheduleDAGMI *dag); virtual SUnit *pickNode(bool &IsTopNode); virtual void schedNode(SUnit *SU, bool IsTopNode); virtual void releaseTopNode(SUnit *SU); virtual void releaseBottomNode(SUnit *SU); private: SUnit *InstructionsGroupCandidate[4]; int getInstKind(SUnit *SU); bool regBelongsToClass(unsigned Reg, const TargetRegisterClass *RC) const; AluKind getAluKind(SUnit *SU) const; void LoadAlu(); bool isAvailablesAluEmpty() const; SUnit *AttemptFillSlot (unsigned Slot); void PrepareNextSlot(); SUnit *PopInst(std::multiset &Q); void AssignSlot(MachineInstr *MI, unsigned Slot); SUnit* pickAlu(); SUnit* pickOther(int QID); bool isBundleable(const MachineInstr& MI); void MoveUnits(ReadyQueue *QSrc, ReadyQueue *QDst); }; } // namespace llvm #endif /* R600MACHINESCHEDULER_H_ */