blob: 8ff52a753b949927c5554ab416fafd67432d65d8 [file] [log] [blame]
Tom Stellard0d23ebe2016-08-29 19:42:52 +00001//===-- GCNSchedStrategy.h - GCN Scheduler Strategy -*- C++ -*-------------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Tom Stellard0d23ebe2016-08-29 19:42:52 +00006//
7//===----------------------------------------------------------------------===//
8//
9/// \file
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_LIB_TARGET_AMDGPU_GCNSCHEDSTRATEGY_H
14#define LLVM_LIB_TARGET_AMDGPU_GCNSCHEDSTRATEGY_H
15
Stanislav Mekhanoshin464cecf2017-05-16 15:43:52 +000016#include "GCNRegPressure.h"
Tom Stellard0d23ebe2016-08-29 19:42:52 +000017#include "llvm/CodeGen/MachineScheduler.h"
18
19namespace llvm {
20
Stanislav Mekhanoshin357d3db2017-02-28 19:20:33 +000021class SIMachineFunctionInfo;
Tom Stellard0d23ebe2016-08-29 19:42:52 +000022class SIRegisterInfo;
Tom Stellard5bfbae52018-07-11 20:59:01 +000023class GCNSubtarget;
Tom Stellard0d23ebe2016-08-29 19:42:52 +000024
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 : public GenericScheduler {
Stanislav Mekhanoshin582a5232017-02-15 17:19:50 +000030 friend class GCNScheduleDAGMILive;
Tom Stellard0d23ebe2016-08-29 19:42:52 +000031
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,
Stanislav Mekhanoshin582a5232017-02-15 17:19:50 +000041 unsigned SGPRPressure, unsigned VGPRPressure);
Tom Stellard0d23ebe2016-08-29 19:42:52 +000042
Stanislav Mekhanoshin582a5232017-02-15 17:19:50 +000043 unsigned SGPRExcessLimit;
44 unsigned VGPRExcessLimit;
45 unsigned SGPRCriticalLimit;
46 unsigned VGPRCriticalLimit;
Tom Stellard0d23ebe2016-08-29 19:42:52 +000047
Stanislav Mekhanoshin357d3db2017-02-28 19:20:33 +000048 unsigned TargetOccupancy;
49
50 MachineFunction *MF;
51
Tom Stellard0d23ebe2016-08-29 19:42:52 +000052public:
53 GCNMaxOccupancySchedStrategy(const MachineSchedContext *C);
54
55 SUnit *pickNode(bool &IsTopNode) override;
Stanislav Mekhanoshin582a5232017-02-15 17:19:50 +000056
57 void initialize(ScheduleDAGMI *DAG) override;
Valery Pykhtinfd4c4102017-03-21 13:15:46 +000058
59 void setTargetOccupancy(unsigned Occ) { TargetOccupancy = Occ; }
Stanislav Mekhanoshin582a5232017-02-15 17:19:50 +000060};
61
62class GCNScheduleDAGMILive : public ScheduleDAGMILive {
Stanislav Mekhanoshin282e8e42017-02-28 17:22:39 +000063
Tom Stellard5bfbae52018-07-11 20:59:01 +000064 const GCNSubtarget &ST;
Stanislav Mekhanoshin357d3db2017-02-28 19:20:33 +000065
Stanislav Mekhanoshind4b500c2018-05-31 05:36:04 +000066 SIMachineFunctionInfo &MFI;
Stanislav Mekhanoshin357d3db2017-02-28 19:20:33 +000067
Hiroshi Inouee9dea6e2017-07-13 06:48:39 +000068 // Occupancy target at the beginning of function scheduling cycle.
Stanislav Mekhanoshin357d3db2017-02-28 19:20:33 +000069 unsigned StartingOccupancy;
70
71 // Minimal real occupancy recorder for the function.
72 unsigned MinOccupancy;
73
74 // Scheduling stage number.
75 unsigned Stage;
76
Stanislav Mekhanoshinb1086072017-05-16 16:11:26 +000077 // Current region index.
78 size_t RegionIdx;
79
Stanislav Mekhanoshin357d3db2017-02-28 19:20:33 +000080 // Vecor of regions recorder for later rescheduling
Stanislav Mekhanoshinb933c3f2017-03-28 21:48:54 +000081 SmallVector<std::pair<MachineBasicBlock::iterator,
82 MachineBasicBlock::iterator>, 32> Regions;
Stanislav Mekhanoshin357d3db2017-02-28 19:20:33 +000083
Stanislav Mekhanoshinb1086072017-05-16 16:11:26 +000084 // Region live-in cache.
85 SmallVector<GCNRPTracker::LiveRegSet, 32> LiveIns;
Stanislav Mekhanoshin282e8e42017-02-28 17:22:39 +000086
Stanislav Mekhanoshinb1086072017-05-16 16:11:26 +000087 // Region pressure cache.
88 SmallVector<GCNRegPressure, 32> Pressure;
89
90 // Temporary basic block live-in cache.
91 DenseMap<const MachineBasicBlock*, GCNRPTracker::LiveRegSet> MBBLiveIns;
Stanislav Mekhanoshin282e8e42017-02-28 17:22:39 +000092
Stanislav Mekhanoshin464cecf2017-05-16 15:43:52 +000093 // Return current region pressure.
94 GCNRegPressure getRealRegPressure() const;
Stanislav Mekhanoshin282e8e42017-02-28 17:22:39 +000095
Stanislav Mekhanoshinb1086072017-05-16 16:11:26 +000096 // Compute and cache live-ins and pressure for all regions in block.
97 void computeBlockPressure(const MachineBasicBlock *MBB);
98
99
Stanislav Mekhanoshin582a5232017-02-15 17:19:50 +0000100public:
101 GCNScheduleDAGMILive(MachineSchedContext *C,
Stanislav Mekhanoshin357d3db2017-02-28 19:20:33 +0000102 std::unique_ptr<MachineSchedStrategy> S);
103
Stanislav Mekhanoshin582a5232017-02-15 17:19:50 +0000104 void schedule() override;
Stanislav Mekhanoshin282e8e42017-02-28 17:22:39 +0000105
106 void finalizeSchedule() override;
Tom Stellard0d23ebe2016-08-29 19:42:52 +0000107};
108
109} // End namespace llvm
110
111#endif // GCNSCHEDSTRATEGY_H