text: //===-- GCNSchedStrategy.h - GCN Scheduler Strategy -*- C++ -*-------------===//
  //
  //                     The LLVM Compiler Infrastructure
  //
  // This file is distributed under the University of Illinois Open Source
  // License. See LICENSE.TXT for details.
  //
  //===----------------------------------------------------------------------===//
  //
  /// \file
  //
  //===----------------------------------------------------------------------===//
  
  #ifndef LLVM_LIB_TARGET_AMDGPU_GCNSCHEDSTRATEGY_H
  #define LLVM_LIB_TARGET_AMDGPU_GCNSCHEDSTRATEGY_H
  
  #include "GCNRegPressure.h"
  #include "llvm/CodeGen/MachineScheduler.h"
  
  namespace llvm {
  
  class SIMachineFunctionInfo;
  class SIRegisterInfo;
  class SISubtarget;
  
  /// This is a minimal scheduler strategy.  The main difference between this
  /// and the GenericScheduler is that GCNSchedStrategy uses different
  /// heuristics to determine excess/critical pressure sets.  Its goal is to
  /// maximize kernel occupancy (i.e. maximum number of waves per simd).
  class GCNMaxOccupancySchedStrategy : public GenericScheduler {
    friend class GCNScheduleDAGMILive;
  
    SUnit *pickNodeBidirectional(bool &IsTopNode);
  
    void pickNodeFromQueue(SchedBoundary &Zone, const CandPolicy &ZonePolicy,
                           const RegPressureTracker &RPTracker,
                           SchedCandidate &Cand);
  
    void initCandidate(SchedCandidate &Cand, SUnit *SU,
                       bool AtTop, const RegPressureTracker &RPTracker,
                       const SIRegisterInfo *SRI,
                       unsigned SGPRPressure, unsigned VGPRPressure);
  
    unsigned SGPRExcessLimit;
    unsigned VGPRExcessLimit;
    unsigned SGPRCriticalLimit;
    unsigned VGPRCriticalLimit;
  
    unsigned TargetOccupancy;
  
    MachineFunction *MF;
  
  public:
    GCNMaxOccupancySchedStrategy(const MachineSchedContext *C);
  
    SUnit *pickNode(bool &IsTopNode) override;
  
    void initialize(ScheduleDAGMI *DAG) override;
  
    void setTargetOccupancy(unsigned Occ) { TargetOccupancy = Occ; }
  };
  
  class GCNScheduleDAGMILive : public ScheduleDAGMILive {
  
    const SISubtarget &ST;
  
    const SIMachineFunctionInfo &MFI;
  
    // Occupancy target at the beginning of function scheduling cycle.
    unsigned StartingOccupancy;
  
    // Minimal real occupancy recorder for the function.
    unsigned MinOccupancy;
  
    // Scheduling stage number.
    unsigned Stage;
  
    // Current region index.
    size_t RegionIdx;
  
    // Vecor of regions recorder for later rescheduling
    SmallVector<std::pair<MachineBasicBlock::iterator,
                          MachineBasicBlock::iterator>, 32> Regions;
  
    // Region live-in cache.
    SmallVector<GCNRPTracker::LiveRegSet, 32> LiveIns;
  
    // Region pressure cache.
    SmallVector<GCNRegPressure, 32> Pressure;
  
    // Temporary basic block live-in cache.
    DenseMap<const MachineBasicBlock*, GCNRPTracker::LiveRegSet> MBBLiveIns;
  
    // Return current region pressure.
    GCNRegPressure getRealRegPressure() const;
  
    // Compute and cache live-ins and pressure for all regions in block.
    void computeBlockPressure(const MachineBasicBlock *MBB);
  
  
  public:
    GCNScheduleDAGMILive(MachineSchedContext *C,
                         std::unique_ptr<MachineSchedStrategy> S);
  
    void schedule() override;
  
    void finalizeSchedule() override;
  };
  
  } // End namespace llvm
  
  #endif // GCNSCHEDSTRATEGY_H
  