xref: /freebsd/contrib/llvm-project/llvm/lib/Target/AMDGPU/GCNSchedStrategy.h (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
1*0b57cec5SDimitry Andric //===-- GCNSchedStrategy.h - GCN Scheduler Strategy -*- C++ -*-------------===//
2*0b57cec5SDimitry Andric //
3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0b57cec5SDimitry Andric //
7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8*0b57cec5SDimitry Andric //
9*0b57cec5SDimitry Andric /// \file
10*0b57cec5SDimitry Andric //
11*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
12*0b57cec5SDimitry Andric 
13*0b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_AMDGPU_GCNSCHEDSTRATEGY_H
14*0b57cec5SDimitry Andric #define LLVM_LIB_TARGET_AMDGPU_GCNSCHEDSTRATEGY_H
15*0b57cec5SDimitry Andric 
16*0b57cec5SDimitry Andric #include "GCNRegPressure.h"
17*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineScheduler.h"
18*0b57cec5SDimitry Andric 
19*0b57cec5SDimitry Andric namespace llvm {
20*0b57cec5SDimitry Andric 
21*0b57cec5SDimitry Andric class SIMachineFunctionInfo;
22*0b57cec5SDimitry Andric class SIRegisterInfo;
23*0b57cec5SDimitry Andric class GCNSubtarget;
24*0b57cec5SDimitry Andric 
25*0b57cec5SDimitry Andric /// This is a minimal scheduler strategy.  The main difference between this
26*0b57cec5SDimitry Andric /// and the GenericScheduler is that GCNSchedStrategy uses different
27*0b57cec5SDimitry Andric /// heuristics to determine excess/critical pressure sets.  Its goal is to
28*0b57cec5SDimitry Andric /// maximize kernel occupancy (i.e. maximum number of waves per simd).
29*0b57cec5SDimitry Andric class GCNMaxOccupancySchedStrategy final : public GenericScheduler {
30*0b57cec5SDimitry Andric   friend class GCNScheduleDAGMILive;
31*0b57cec5SDimitry Andric 
32*0b57cec5SDimitry Andric   SUnit *pickNodeBidirectional(bool &IsTopNode);
33*0b57cec5SDimitry Andric 
34*0b57cec5SDimitry Andric   void pickNodeFromQueue(SchedBoundary &Zone, const CandPolicy &ZonePolicy,
35*0b57cec5SDimitry Andric                          const RegPressureTracker &RPTracker,
36*0b57cec5SDimitry Andric                          SchedCandidate &Cand);
37*0b57cec5SDimitry Andric 
38*0b57cec5SDimitry Andric   void initCandidate(SchedCandidate &Cand, SUnit *SU,
39*0b57cec5SDimitry Andric                      bool AtTop, const RegPressureTracker &RPTracker,
40*0b57cec5SDimitry Andric                      const SIRegisterInfo *SRI,
41*0b57cec5SDimitry Andric                      unsigned SGPRPressure, unsigned VGPRPressure);
42*0b57cec5SDimitry Andric 
43*0b57cec5SDimitry Andric   unsigned SGPRExcessLimit;
44*0b57cec5SDimitry Andric   unsigned VGPRExcessLimit;
45*0b57cec5SDimitry Andric   unsigned SGPRCriticalLimit;
46*0b57cec5SDimitry Andric   unsigned VGPRCriticalLimit;
47*0b57cec5SDimitry Andric 
48*0b57cec5SDimitry Andric   unsigned TargetOccupancy;
49*0b57cec5SDimitry Andric 
50*0b57cec5SDimitry Andric   MachineFunction *MF;
51*0b57cec5SDimitry Andric 
52*0b57cec5SDimitry Andric public:
53*0b57cec5SDimitry Andric   GCNMaxOccupancySchedStrategy(const MachineSchedContext *C);
54*0b57cec5SDimitry Andric 
55*0b57cec5SDimitry Andric   SUnit *pickNode(bool &IsTopNode) override;
56*0b57cec5SDimitry Andric 
57*0b57cec5SDimitry Andric   void initialize(ScheduleDAGMI *DAG) override;
58*0b57cec5SDimitry Andric 
59*0b57cec5SDimitry Andric   void setTargetOccupancy(unsigned Occ) { TargetOccupancy = Occ; }
60*0b57cec5SDimitry Andric };
61*0b57cec5SDimitry Andric 
62*0b57cec5SDimitry Andric class GCNScheduleDAGMILive final : public ScheduleDAGMILive {
63*0b57cec5SDimitry Andric 
64*0b57cec5SDimitry Andric   const GCNSubtarget &ST;
65*0b57cec5SDimitry Andric 
66*0b57cec5SDimitry Andric   SIMachineFunctionInfo &MFI;
67*0b57cec5SDimitry Andric 
68*0b57cec5SDimitry Andric   // Occupancy target at the beginning of function scheduling cycle.
69*0b57cec5SDimitry Andric   unsigned StartingOccupancy;
70*0b57cec5SDimitry Andric 
71*0b57cec5SDimitry Andric   // Minimal real occupancy recorder for the function.
72*0b57cec5SDimitry Andric   unsigned MinOccupancy;
73*0b57cec5SDimitry Andric 
74*0b57cec5SDimitry Andric   // Scheduling stage number.
75*0b57cec5SDimitry Andric   unsigned Stage;
76*0b57cec5SDimitry Andric 
77*0b57cec5SDimitry Andric   // Current region index.
78*0b57cec5SDimitry Andric   size_t RegionIdx;
79*0b57cec5SDimitry Andric 
80*0b57cec5SDimitry Andric   // Vector of regions recorder for later rescheduling
81*0b57cec5SDimitry Andric   SmallVector<std::pair<MachineBasicBlock::iterator,
82*0b57cec5SDimitry Andric                         MachineBasicBlock::iterator>, 32> Regions;
83*0b57cec5SDimitry Andric 
84*0b57cec5SDimitry Andric   // Region live-in cache.
85*0b57cec5SDimitry Andric   SmallVector<GCNRPTracker::LiveRegSet, 32> LiveIns;
86*0b57cec5SDimitry Andric 
87*0b57cec5SDimitry Andric   // Region pressure cache.
88*0b57cec5SDimitry Andric   SmallVector<GCNRegPressure, 32> Pressure;
89*0b57cec5SDimitry Andric 
90*0b57cec5SDimitry Andric   // Temporary basic block live-in cache.
91*0b57cec5SDimitry Andric   DenseMap<const MachineBasicBlock*, GCNRPTracker::LiveRegSet> MBBLiveIns;
92*0b57cec5SDimitry Andric 
93*0b57cec5SDimitry Andric   DenseMap<MachineInstr *, GCNRPTracker::LiveRegSet> BBLiveInMap;
94*0b57cec5SDimitry Andric   DenseMap<MachineInstr *, GCNRPTracker::LiveRegSet> getBBLiveInMap() const;
95*0b57cec5SDimitry Andric 
96*0b57cec5SDimitry Andric   // Return current region pressure.
97*0b57cec5SDimitry Andric   GCNRegPressure getRealRegPressure() const;
98*0b57cec5SDimitry Andric 
99*0b57cec5SDimitry Andric   // Compute and cache live-ins and pressure for all regions in block.
100*0b57cec5SDimitry Andric   void computeBlockPressure(const MachineBasicBlock *MBB);
101*0b57cec5SDimitry Andric 
102*0b57cec5SDimitry Andric 
103*0b57cec5SDimitry Andric public:
104*0b57cec5SDimitry Andric   GCNScheduleDAGMILive(MachineSchedContext *C,
105*0b57cec5SDimitry Andric                        std::unique_ptr<MachineSchedStrategy> S);
106*0b57cec5SDimitry Andric 
107*0b57cec5SDimitry Andric   void schedule() override;
108*0b57cec5SDimitry Andric 
109*0b57cec5SDimitry Andric   void finalizeSchedule() override;
110*0b57cec5SDimitry Andric };
111*0b57cec5SDimitry Andric 
112*0b57cec5SDimitry Andric } // End namespace llvm
113*0b57cec5SDimitry Andric 
114*0b57cec5SDimitry Andric #endif // GCNSCHEDSTRATEGY_H
115