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