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