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