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
21namespace llvm {
22
23class MachineInstr;
24class SUnit;
25class raw_ostream;
26
27class GCNIterativeScheduler : public ScheduleDAGMILive {
28  using BaseClass = ScheduleDAGMILive;
29
30public:
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
50protected:
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
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