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 setTargetOccupancy(unsigned Occ)62 void setTargetOccupancy(unsigned Occ) { TargetOccupancy = Occ; } 63 }; 64 65 class GCNScheduleDAGMILive final : public ScheduleDAGMILive { 66 67 const GCNSubtarget &ST; 68 69 SIMachineFunctionInfo &MFI; 70 71 // Occupancy target at the beginning of function scheduling cycle. 72 unsigned StartingOccupancy; 73 74 // Minimal real occupancy recorder for the function. 75 unsigned MinOccupancy; 76 77 // Scheduling stage number. 78 unsigned Stage; 79 80 // Current region index. 81 size_t RegionIdx; 82 83 // Vector of regions recorder for later rescheduling 84 SmallVector<std::pair<MachineBasicBlock::iterator, 85 MachineBasicBlock::iterator>, 32> Regions; 86 87 // Region live-in cache. 88 SmallVector<GCNRPTracker::LiveRegSet, 32> LiveIns; 89 90 // Region pressure cache. 91 SmallVector<GCNRegPressure, 32> Pressure; 92 93 // Temporary basic block live-in cache. 94 DenseMap<const MachineBasicBlock*, GCNRPTracker::LiveRegSet> MBBLiveIns; 95 96 DenseMap<MachineInstr *, GCNRPTracker::LiveRegSet> BBLiveInMap; 97 DenseMap<MachineInstr *, GCNRPTracker::LiveRegSet> getBBLiveInMap() const; 98 99 // Return current region pressure. 100 GCNRegPressure getRealRegPressure() const; 101 102 // Compute and cache live-ins and pressure for all regions in block. 103 void computeBlockPressure(const MachineBasicBlock *MBB); 104 105 106 public: 107 GCNScheduleDAGMILive(MachineSchedContext *C, 108 std::unique_ptr<MachineSchedStrategy> S); 109 110 void schedule() override; 111 112 void finalizeSchedule() override; 113 }; 114 115 } // End namespace llvm 116 117 #endif // GCNSCHEDSTRATEGY_H 118