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