Home | History | Annotate | Line # | Download | only in AMDGPU
      1 //===-- GCNSchedStrategy.h - GCN Scheduler Strategy -*- C++ -*-------------===//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 //
      9 /// \file
     10 //
     11 //===----------------------------------------------------------------------===//
     12 
     13 #ifndef LLVM_LIB_TARGET_AMDGPU_GCNSCHEDSTRATEGY_H
     14 #define LLVM_LIB_TARGET_AMDGPU_GCNSCHEDSTRATEGY_H
     15 
     16 #include "GCNRegPressure.h"
     17 #include "llvm/CodeGen/MachineScheduler.h"
     18 
     19 namespace llvm {
     20 
     21 class SIMachineFunctionInfo;
     22 class SIRegisterInfo;
     23 class GCNSubtarget;
     24 
     25 /// This is a minimal scheduler strategy.  The main difference between this
     26 /// and the GenericScheduler is that GCNSchedStrategy uses different
     27 /// heuristics to determine excess/critical pressure sets.  Its goal is to
     28 /// maximize kernel occupancy (i.e. maximum number of waves per simd).
     29 class GCNMaxOccupancySchedStrategy final : public GenericScheduler {
     30   friend class GCNScheduleDAGMILive;
     31 
     32   SUnit *pickNodeBidirectional(bool &IsTopNode);
     33 
     34   void pickNodeFromQueue(SchedBoundary &Zone, const CandPolicy &ZonePolicy,
     35                          const RegPressureTracker &RPTracker,
     36                          SchedCandidate &Cand);
     37 
     38   void initCandidate(SchedCandidate &Cand, SUnit *SU,
     39                      bool AtTop, const RegPressureTracker &RPTracker,
     40                      const SIRegisterInfo *SRI,
     41                      unsigned SGPRPressure, unsigned VGPRPressure);
     42 
     43   std::vector<unsigned> Pressure;
     44   std::vector<unsigned> MaxPressure;
     45 
     46   unsigned SGPRExcessLimit;
     47   unsigned VGPRExcessLimit;
     48   unsigned SGPRCriticalLimit;
     49   unsigned VGPRCriticalLimit;
     50 
     51   unsigned TargetOccupancy;
     52 
     53   // schedule() have seen a clustered memory operation. Set it to false
     54   // before a region scheduling to know if the region had such clusters.
     55   bool HasClusteredNodes;
     56 
     57   // schedule() have seen a an excess register pressure and had to track
     58   // register pressure for actual scheduling heuristics.
     59   bool HasExcessPressure;
     60 
     61   MachineFunction *MF;
     62 
     63 public:
     64   GCNMaxOccupancySchedStrategy(const MachineSchedContext *C);
     65 
     66   SUnit *pickNode(bool &IsTopNode) override;
     67 
     68   void initialize(ScheduleDAGMI *DAG) override;
     69 
     70   void setTargetOccupancy(unsigned Occ) { TargetOccupancy = Occ; }
     71 };
     72 
     73 class GCNScheduleDAGMILive final : public ScheduleDAGMILive {
     74 
     75   enum : unsigned {
     76     Collect,
     77     InitialSchedule,
     78     UnclusteredReschedule,
     79     ClusteredLowOccupancyReschedule,
     80     LastStage = ClusteredLowOccupancyReschedule
     81   };
     82 
     83   const GCNSubtarget &ST;
     84 
     85   SIMachineFunctionInfo &MFI;
     86 
     87   // Occupancy target at the beginning of function scheduling cycle.
     88   unsigned StartingOccupancy;
     89 
     90   // Minimal real occupancy recorder for the function.
     91   unsigned MinOccupancy;
     92 
     93   // Scheduling stage number.
     94   unsigned Stage;
     95 
     96   // Current region index.
     97   size_t RegionIdx;
     98 
     99   // Vector of regions recorder for later rescheduling
    100   SmallVector<std::pair<MachineBasicBlock::iterator,
    101                         MachineBasicBlock::iterator>, 32> Regions;
    102 
    103   // Records if a region is not yet scheduled, or schedule has been reverted,
    104   // or we generally desire to reschedule it.
    105   BitVector RescheduleRegions;
    106 
    107   // Record regions which use clustered loads/stores.
    108   BitVector RegionsWithClusters;
    109 
    110   // Record regions with high register pressure.
    111   BitVector RegionsWithHighRP;
    112 
    113   // Region live-in cache.
    114   SmallVector<GCNRPTracker::LiveRegSet, 32> LiveIns;
    115 
    116   // Region pressure cache.
    117   SmallVector<GCNRegPressure, 32> Pressure;
    118 
    119   // Temporary basic block live-in cache.
    120   DenseMap<const MachineBasicBlock*, GCNRPTracker::LiveRegSet> MBBLiveIns;
    121 
    122   DenseMap<MachineInstr *, GCNRPTracker::LiveRegSet> BBLiveInMap;
    123   DenseMap<MachineInstr *, GCNRPTracker::LiveRegSet> getBBLiveInMap() const;
    124 
    125   // Return current region pressure.
    126   GCNRegPressure getRealRegPressure() const;
    127 
    128   // Compute and cache live-ins and pressure for all regions in block.
    129   void computeBlockPressure(const MachineBasicBlock *MBB);
    130 
    131 
    132 public:
    133   GCNScheduleDAGMILive(MachineSchedContext *C,
    134                        std::unique_ptr<MachineSchedStrategy> S);
    135 
    136   void schedule() override;
    137 
    138   void finalizeSchedule() override;
    139 };
    140 
    141 } // End namespace llvm
    142 
    143 #endif // GCNSCHEDSTRATEGY_H
    144