xref: /freebsd/contrib/llvm-project/llvm/lib/Target/AMDGPU/GCNSchedStrategy.h (revision 5ffd83dbcc34f10e07f6d3e968ae6365869615f4)
10b57cec5SDimitry Andric //===-- GCNSchedStrategy.h - GCN Scheduler Strategy -*- C++ -*-------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric /// \file
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_AMDGPU_GCNSCHEDSTRATEGY_H
140b57cec5SDimitry Andric #define LLVM_LIB_TARGET_AMDGPU_GCNSCHEDSTRATEGY_H
150b57cec5SDimitry Andric 
160b57cec5SDimitry Andric #include "GCNRegPressure.h"
170b57cec5SDimitry Andric #include "llvm/CodeGen/MachineScheduler.h"
180b57cec5SDimitry Andric 
190b57cec5SDimitry Andric namespace llvm {
200b57cec5SDimitry Andric 
210b57cec5SDimitry Andric class SIMachineFunctionInfo;
220b57cec5SDimitry Andric class SIRegisterInfo;
230b57cec5SDimitry Andric class GCNSubtarget;
240b57cec5SDimitry Andric 
250b57cec5SDimitry Andric /// This is a minimal scheduler strategy.  The main difference between this
260b57cec5SDimitry Andric /// and the GenericScheduler is that GCNSchedStrategy uses different
270b57cec5SDimitry Andric /// heuristics to determine excess/critical pressure sets.  Its goal is to
280b57cec5SDimitry Andric /// maximize kernel occupancy (i.e. maximum number of waves per simd).
290b57cec5SDimitry Andric class GCNMaxOccupancySchedStrategy final : public GenericScheduler {
300b57cec5SDimitry Andric   friend class GCNScheduleDAGMILive;
310b57cec5SDimitry Andric 
320b57cec5SDimitry Andric   SUnit *pickNodeBidirectional(bool &IsTopNode);
330b57cec5SDimitry Andric 
340b57cec5SDimitry Andric   void pickNodeFromQueue(SchedBoundary &Zone, const CandPolicy &ZonePolicy,
350b57cec5SDimitry Andric                          const RegPressureTracker &RPTracker,
360b57cec5SDimitry Andric                          SchedCandidate &Cand);
370b57cec5SDimitry Andric 
380b57cec5SDimitry Andric   void initCandidate(SchedCandidate &Cand, SUnit *SU,
390b57cec5SDimitry Andric                      bool AtTop, const RegPressureTracker &RPTracker,
400b57cec5SDimitry Andric                      const SIRegisterInfo *SRI,
410b57cec5SDimitry Andric                      unsigned SGPRPressure, unsigned VGPRPressure);
420b57cec5SDimitry Andric 
438bcb0991SDimitry Andric   std::vector<unsigned> Pressure;
448bcb0991SDimitry Andric   std::vector<unsigned> MaxPressure;
458bcb0991SDimitry Andric 
460b57cec5SDimitry Andric   unsigned SGPRExcessLimit;
470b57cec5SDimitry Andric   unsigned VGPRExcessLimit;
480b57cec5SDimitry Andric   unsigned SGPRCriticalLimit;
490b57cec5SDimitry Andric   unsigned VGPRCriticalLimit;
500b57cec5SDimitry Andric 
510b57cec5SDimitry Andric   unsigned TargetOccupancy;
520b57cec5SDimitry Andric 
530b57cec5SDimitry Andric   MachineFunction *MF;
540b57cec5SDimitry Andric 
550b57cec5SDimitry Andric public:
560b57cec5SDimitry Andric   GCNMaxOccupancySchedStrategy(const MachineSchedContext *C);
570b57cec5SDimitry Andric 
580b57cec5SDimitry Andric   SUnit *pickNode(bool &IsTopNode) override;
590b57cec5SDimitry Andric 
600b57cec5SDimitry Andric   void initialize(ScheduleDAGMI *DAG) override;
610b57cec5SDimitry Andric 
620b57cec5SDimitry Andric   void setTargetOccupancy(unsigned Occ) { TargetOccupancy = Occ; }
630b57cec5SDimitry Andric };
640b57cec5SDimitry Andric 
650b57cec5SDimitry Andric class GCNScheduleDAGMILive final : public ScheduleDAGMILive {
660b57cec5SDimitry Andric 
67*5ffd83dbSDimitry Andric   enum : unsigned {
68*5ffd83dbSDimitry Andric     Collect,
69*5ffd83dbSDimitry Andric     InitialSchedule,
70*5ffd83dbSDimitry Andric     UnclusteredReschedule,
71*5ffd83dbSDimitry Andric     ClusteredLowOccupancyReschedule,
72*5ffd83dbSDimitry Andric     LastStage = ClusteredLowOccupancyReschedule
73*5ffd83dbSDimitry Andric   };
74*5ffd83dbSDimitry Andric 
750b57cec5SDimitry Andric   const GCNSubtarget &ST;
760b57cec5SDimitry Andric 
770b57cec5SDimitry Andric   SIMachineFunctionInfo &MFI;
780b57cec5SDimitry Andric 
790b57cec5SDimitry Andric   // Occupancy target at the beginning of function scheduling cycle.
800b57cec5SDimitry Andric   unsigned StartingOccupancy;
810b57cec5SDimitry Andric 
820b57cec5SDimitry Andric   // Minimal real occupancy recorder for the function.
830b57cec5SDimitry Andric   unsigned MinOccupancy;
840b57cec5SDimitry Andric 
850b57cec5SDimitry Andric   // Scheduling stage number.
860b57cec5SDimitry Andric   unsigned Stage;
870b57cec5SDimitry Andric 
880b57cec5SDimitry Andric   // Current region index.
890b57cec5SDimitry Andric   size_t RegionIdx;
900b57cec5SDimitry Andric 
910b57cec5SDimitry Andric   // Vector of regions recorder for later rescheduling
920b57cec5SDimitry Andric   SmallVector<std::pair<MachineBasicBlock::iterator,
930b57cec5SDimitry Andric                         MachineBasicBlock::iterator>, 32> Regions;
940b57cec5SDimitry Andric 
95*5ffd83dbSDimitry Andric   // Records if a region is not yet scheduled, or schedule has been reverted,
96*5ffd83dbSDimitry Andric   // or we generally desire to reschedule it.
97*5ffd83dbSDimitry Andric   BitVector RescheduleRegions;
98*5ffd83dbSDimitry Andric 
990b57cec5SDimitry Andric   // Region live-in cache.
1000b57cec5SDimitry Andric   SmallVector<GCNRPTracker::LiveRegSet, 32> LiveIns;
1010b57cec5SDimitry Andric 
1020b57cec5SDimitry Andric   // Region pressure cache.
1030b57cec5SDimitry Andric   SmallVector<GCNRegPressure, 32> Pressure;
1040b57cec5SDimitry Andric 
1050b57cec5SDimitry Andric   // Temporary basic block live-in cache.
1060b57cec5SDimitry Andric   DenseMap<const MachineBasicBlock*, GCNRPTracker::LiveRegSet> MBBLiveIns;
1070b57cec5SDimitry Andric 
1080b57cec5SDimitry Andric   DenseMap<MachineInstr *, GCNRPTracker::LiveRegSet> BBLiveInMap;
1090b57cec5SDimitry Andric   DenseMap<MachineInstr *, GCNRPTracker::LiveRegSet> getBBLiveInMap() const;
1100b57cec5SDimitry Andric 
1110b57cec5SDimitry Andric   // Return current region pressure.
1120b57cec5SDimitry Andric   GCNRegPressure getRealRegPressure() const;
1130b57cec5SDimitry Andric 
1140b57cec5SDimitry Andric   // Compute and cache live-ins and pressure for all regions in block.
1150b57cec5SDimitry Andric   void computeBlockPressure(const MachineBasicBlock *MBB);
1160b57cec5SDimitry Andric 
1170b57cec5SDimitry Andric 
1180b57cec5SDimitry Andric public:
1190b57cec5SDimitry Andric   GCNScheduleDAGMILive(MachineSchedContext *C,
1200b57cec5SDimitry Andric                        std::unique_ptr<MachineSchedStrategy> S);
1210b57cec5SDimitry Andric 
1220b57cec5SDimitry Andric   void schedule() override;
1230b57cec5SDimitry Andric 
1240b57cec5SDimitry Andric   void finalizeSchedule() override;
1250b57cec5SDimitry Andric };
1260b57cec5SDimitry Andric 
1270b57cec5SDimitry Andric } // End namespace llvm
1280b57cec5SDimitry Andric 
1290b57cec5SDimitry Andric #endif // GCNSCHEDSTRATEGY_H
130