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 | |
90 | GCNRegPressure getRegionPressure(const Region &R) const { |
91 | return getRegionPressure(Begin: R.Begin, End: 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 | |