xref: /freebsd/contrib/llvm-project/llvm/lib/Target/AMDGPU/GCNIterativeScheduler.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
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