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 std::vector<std::unique_ptr<ScheduleDAGMutation>> SavedMutations; 81 82 class BuildDAG; 83 class OverrideLegacyStrategy; 84 85 template <typename Range> 86 GCNRegPressure getSchedulePressure(const Region &R, 87 Range &&Schedule) const; 88 89 GCNRegPressure getRegionPressure(MachineBasicBlock::iterator Begin, 90 MachineBasicBlock::iterator End) const; 91 getRegionPressure(const Region & R)92 GCNRegPressure getRegionPressure(const Region &R) const { 93 return getRegionPressure(R.Begin, R.End); 94 } 95 96 void swapIGLPMutations(const Region &R, bool IsReentry); 97 void setBestSchedule(Region &R, 98 ScheduleRef Schedule, 99 const GCNRegPressure &MaxRP = GCNRegPressure()); 100 101 void scheduleBest(Region &R); 102 103 std::vector<MachineInstr*> detachSchedule(ScheduleRef Schedule) const; 104 105 void sortRegionsByPressure(unsigned TargetOcc); 106 107 template <typename Range> 108 void scheduleRegion(Region &R, Range &&Schedule, 109 const GCNRegPressure &MaxRP = GCNRegPressure()); 110 111 unsigned tryMaximizeOccupancy(unsigned TargetOcc = 112 std::numeric_limits<unsigned>::max()); 113 114 void scheduleLegacyMaxOccupancy(bool TryMaximizeOccupancy = true); 115 void scheduleMinReg(bool force = false); 116 void scheduleILP(bool TryMaximizeOccupancy = true); 117 118 void printRegions(raw_ostream &OS) const; 119 void printSchedResult(raw_ostream &OS, 120 const Region *R, 121 const GCNRegPressure &RP) const; 122 void printSchedRP(raw_ostream &OS, 123 const GCNRegPressure &Before, 124 const GCNRegPressure &After) const; 125 }; 126 127 } // end namespace llvm 128 129 #endif // LLVM_LIB_TARGET_AMDGPU_GCNITERATIVESCHEDULER_H 130