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