1 //===- GCNIterativeScheduler.h - GCN Scheduler ------------------*- 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 /// This file defines the class GCNIterativeScheduler, which uses an iterative 11 /// approach to find a best schedule for GCN architecture. It basically makes 12 /// use of various lightweight schedules, scores them, chooses best one based on 13 /// their scores, and finally implements the chosen one. 14 /// 15 //===----------------------------------------------------------------------===// 16 17 #ifndef LLVM_LIB_TARGET_AMDGPU_GCNITERATIVESCHEDULER_H 18 #define LLVM_LIB_TARGET_AMDGPU_GCNITERATIVESCHEDULER_H 19 20 #include "GCNRegPressure.h" 21 #include "llvm/CodeGen/MachineScheduler.h" 22 23 namespace llvm { 24 25 class MachineInstr; 26 class SUnit; 27 class raw_ostream; 28 29 class GCNIterativeScheduler : public ScheduleDAGMILive { 30 using BaseClass = ScheduleDAGMILive; 31 32 public: 33 enum StrategyKind { 34 SCHEDULE_MINREGONLY, 35 SCHEDULE_MINREGFORCED, 36 SCHEDULE_LEGACYMAXOCCUPANCY, 37 SCHEDULE_ILP 38 }; 39 40 GCNIterativeScheduler(MachineSchedContext *C, 41 StrategyKind S); 42 43 void schedule() override; 44 45 void enterRegion(MachineBasicBlock *BB, 46 MachineBasicBlock::iterator Begin, 47 MachineBasicBlock::iterator End, 48 unsigned RegionInstrs) override; 49 50 void finalizeSchedule() override; 51 52 protected: 53 using ScheduleRef = ArrayRef<const SUnit *>; 54 55 struct TentativeSchedule { 56 std::vector<MachineInstr *> Schedule; 57 GCNRegPressure MaxPressure; 58 }; 59 60 struct Region { 61 // Fields except for BestSchedule are supposed to reflect current IR state 62 // `const` fields are to emphasize they shouldn't change for any schedule. 63 MachineBasicBlock::iterator Begin; 64 // End is either a boundary instruction or end of basic block 65 const MachineBasicBlock::iterator End; 66 const unsigned NumRegionInstrs; 67 GCNRegPressure MaxPressure; 68 69 // best schedule for the region so far (not scheduled yet) 70 std::unique_ptr<TentativeSchedule> BestSchedule; 71 }; 72 73 SpecificBumpPtrAllocator<Region> Alloc; 74 std::vector<Region*> Regions; 75 76 MachineSchedContext *Context; 77 const StrategyKind Strategy; 78 mutable GCNUpwardRPTracker UPTracker; 79 80 class BuildDAG; 81 class OverrideLegacyStrategy; 82 83 template <typename Range> 84 GCNRegPressure getSchedulePressure(const Region &R, 85 Range &&Schedule) const; 86 87 GCNRegPressure getRegionPressure(MachineBasicBlock::iterator Begin, 88 MachineBasicBlock::iterator End) const; 89 getRegionPressure(const Region & R)90 GCNRegPressure getRegionPressure(const Region &R) const { 91 return getRegionPressure(R.Begin, R.End); 92 } 93 94 void setBestSchedule(Region &R, 95 ScheduleRef Schedule, 96 const GCNRegPressure &MaxRP = GCNRegPressure()); 97 98 void scheduleBest(Region &R); 99 100 std::vector<MachineInstr*> detachSchedule(ScheduleRef Schedule) const; 101 102 void sortRegionsByPressure(unsigned TargetOcc); 103 104 template <typename Range> 105 void scheduleRegion(Region &R, Range &&Schedule, 106 const GCNRegPressure &MaxRP = GCNRegPressure()); 107 108 unsigned tryMaximizeOccupancy(unsigned TargetOcc = 109 std::numeric_limits<unsigned>::max()); 110 111 void scheduleLegacyMaxOccupancy(bool TryMaximizeOccupancy = true); 112 void scheduleMinReg(bool force = false); 113 void scheduleILP(bool TryMaximizeOccupancy = true); 114 115 void printRegions(raw_ostream &OS) const; 116 void printSchedResult(raw_ostream &OS, 117 const Region *R, 118 const GCNRegPressure &RP) const; 119 void printSchedRP(raw_ostream &OS, 120 const GCNRegPressure &Before, 121 const GCNRegPressure &After) const; 122 }; 123 124 } // end namespace llvm 125 126 #endif // LLVM_LIB_TARGET_AMDGPU_GCNITERATIVESCHEDULER_H 127