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   MachineFunction *MF;
54 
55 public:
56   GCNMaxOccupancySchedStrategy(const MachineSchedContext *C);
57 
58   SUnit *pickNode(bool &IsTopNode) override;
59 
60   void initialize(ScheduleDAGMI *DAG) override;
61 
62   void setTargetOccupancy(unsigned Occ) { TargetOccupancy = Occ; }
63 };
64 
65 class GCNScheduleDAGMILive final : public ScheduleDAGMILive {
66 
67   enum : unsigned {
68     Collect,
69     InitialSchedule,
70     UnclusteredReschedule,
71     ClusteredLowOccupancyReschedule,
72     LastStage = ClusteredLowOccupancyReschedule
73   };
74 
75   const GCNSubtarget &ST;
76 
77   SIMachineFunctionInfo &MFI;
78 
79   // Occupancy target at the beginning of function scheduling cycle.
80   unsigned StartingOccupancy;
81 
82   // Minimal real occupancy recorder for the function.
83   unsigned MinOccupancy;
84 
85   // Scheduling stage number.
86   unsigned Stage;
87 
88   // Current region index.
89   size_t RegionIdx;
90 
91   // Vector of regions recorder for later rescheduling
92   SmallVector<std::pair<MachineBasicBlock::iterator,
93                         MachineBasicBlock::iterator>, 32> Regions;
94 
95   // Records if a region is not yet scheduled, or schedule has been reverted,
96   // or we generally desire to reschedule it.
97   BitVector RescheduleRegions;
98 
99   // Region live-in cache.
100   SmallVector<GCNRPTracker::LiveRegSet, 32> LiveIns;
101 
102   // Region pressure cache.
103   SmallVector<GCNRegPressure, 32> Pressure;
104 
105   // Temporary basic block live-in cache.
106   DenseMap<const MachineBasicBlock*, GCNRPTracker::LiveRegSet> MBBLiveIns;
107 
108   DenseMap<MachineInstr *, GCNRPTracker::LiveRegSet> BBLiveInMap;
109   DenseMap<MachineInstr *, GCNRPTracker::LiveRegSet> getBBLiveInMap() const;
110 
111   // Return current region pressure.
112   GCNRegPressure getRealRegPressure() const;
113 
114   // Compute and cache live-ins and pressure for all regions in block.
115   void computeBlockPressure(const MachineBasicBlock *MBB);
116 
117 
118 public:
119   GCNScheduleDAGMILive(MachineSchedContext *C,
120                        std::unique_ptr<MachineSchedStrategy> S);
121 
122   void schedule() override;
123 
124   void finalizeSchedule() override;
125 };
126 
127 } // End namespace llvm
128 
129 #endif // GCNSCHEDSTRATEGY_H
130