GCNSchedStrategy.h revision 360784
1//===-- GCNSchedStrategy.h - GCN Scheduler Strategy -*- 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//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_LIB_TARGET_AMDGPU_GCNSCHEDSTRATEGY_H
14#define LLVM_LIB_TARGET_AMDGPU_GCNSCHEDSTRATEGY_H
15
16#include "GCNRegPressure.h"
17#include "llvm/CodeGen/MachineScheduler.h"
18
19namespace llvm {
20
21class SIMachineFunctionInfo;
22class SIRegisterInfo;
23class GCNSubtarget;
24
25/// This is a minimal scheduler strategy.  The main difference between this
26/// and the GenericScheduler is that GCNSchedStrategy uses different
27/// heuristics to determine excess/critical pressure sets.  Its goal is to
28/// maximize kernel occupancy (i.e. maximum number of waves per simd).
29class GCNMaxOccupancySchedStrategy final : public GenericScheduler {
30  friend class GCNScheduleDAGMILive;
31
32  SUnit *pickNodeBidirectional(bool &IsTopNode);
33
34  void pickNodeFromQueue(SchedBoundary &Zone, const CandPolicy &ZonePolicy,
35                         const RegPressureTracker &RPTracker,
36                         SchedCandidate &Cand);
37
38  void initCandidate(SchedCandidate &Cand, SUnit *SU,
39                     bool AtTop, const RegPressureTracker &RPTracker,
40                     const SIRegisterInfo *SRI,
41                     unsigned SGPRPressure, unsigned VGPRPressure);
42
43  std::vector<unsigned> Pressure;
44  std::vector<unsigned> MaxPressure;
45
46  unsigned SGPRExcessLimit;
47  unsigned VGPRExcessLimit;
48  unsigned SGPRCriticalLimit;
49  unsigned VGPRCriticalLimit;
50
51  unsigned TargetOccupancy;
52
53  MachineFunction *MF;
54
55public:
56  GCNMaxOccupancySchedStrategy(const MachineSchedContext *C);
57
58  SUnit *pickNode(bool &IsTopNode) override;
59
60  void initialize(ScheduleDAGMI *DAG) override;
61
62  void setTargetOccupancy(unsigned Occ) { TargetOccupancy = Occ; }
63};
64
65class GCNScheduleDAGMILive final : public ScheduleDAGMILive {
66
67  const GCNSubtarget &ST;
68
69  SIMachineFunctionInfo &MFI;
70
71  // Occupancy target at the beginning of function scheduling cycle.
72  unsigned StartingOccupancy;
73
74  // Minimal real occupancy recorder for the function.
75  unsigned MinOccupancy;
76
77  // Scheduling stage number.
78  unsigned Stage;
79
80  // Current region index.
81  size_t RegionIdx;
82
83  // Vector of regions recorder for later rescheduling
84  SmallVector<std::pair<MachineBasicBlock::iterator,
85                        MachineBasicBlock::iterator>, 32> Regions;
86
87  // Region live-in cache.
88  SmallVector<GCNRPTracker::LiveRegSet, 32> LiveIns;
89
90  // Region pressure cache.
91  SmallVector<GCNRegPressure, 32> Pressure;
92
93  // Temporary basic block live-in cache.
94  DenseMap<const MachineBasicBlock*, GCNRPTracker::LiveRegSet> MBBLiveIns;
95
96  DenseMap<MachineInstr *, GCNRPTracker::LiveRegSet> BBLiveInMap;
97  DenseMap<MachineInstr *, GCNRPTracker::LiveRegSet> getBBLiveInMap() const;
98
99  // Return current region pressure.
100  GCNRegPressure getRealRegPressure() const;
101
102  // Compute and cache live-ins and pressure for all regions in block.
103  void computeBlockPressure(const MachineBasicBlock *MBB);
104
105
106public:
107  GCNScheduleDAGMILive(MachineSchedContext *C,
108                       std::unique_ptr<MachineSchedStrategy> S);
109
110  void schedule() override;
111
112  void finalizeSchedule() override;
113};
114
115} // End namespace llvm
116
117#endif // GCNSCHEDSTRATEGY_H
118