blob: dd687a930c79a41bb9078e06d31429d32948a6be [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).
Matt Arsenault462403a2019-05-08 22:10:04 +000029class GCNMaxOccupancySchedStrategy final : 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
Matt Arsenaultf54daff2019-09-05 22:44:06 +000043 std::vector<unsigned> Pressure;
44 std::vector<unsigned> MaxPressure;
45
Stanislav Mekhanoshin582a5232017-02-15 17:19:50 +000046 unsigned SGPRExcessLimit;
47 unsigned VGPRExcessLimit;
48 unsigned SGPRCriticalLimit;
49 unsigned VGPRCriticalLimit;
Tom Stellard0d23ebe2016-08-29 19:42:52 +000050
Stanislav Mekhanoshin357d3db2017-02-28 19:20:33 +000051 unsigned TargetOccupancy;
52
53 MachineFunction *MF;
54
Tom Stellard0d23ebe2016-08-29 19:42:52 +000055public:
56 GCNMaxOccupancySchedStrategy(const MachineSchedContext *C);
57
58 SUnit *pickNode(bool &IsTopNode) override;
Stanislav Mekhanoshin582a5232017-02-15 17:19:50 +000059
60 void initialize(ScheduleDAGMI *DAG) override;
Valery Pykhtinfd4c4102017-03-21 13:15:46 +000061
62 void setTargetOccupancy(unsigned Occ) { TargetOccupancy = Occ; }
Stanislav Mekhanoshin582a5232017-02-15 17:19:50 +000063};
64
Matt Arsenault462403a2019-05-08 22:10:04 +000065class GCNScheduleDAGMILive final : public ScheduleDAGMILive {
Stanislav Mekhanoshin282e8e42017-02-28 17:22:39 +000066
Tom Stellard5bfbae52018-07-11 20:59:01 +000067 const GCNSubtarget &ST;
Stanislav Mekhanoshin357d3db2017-02-28 19:20:33 +000068
Stanislav Mekhanoshind4b500c2018-05-31 05:36:04 +000069 SIMachineFunctionInfo &MFI;
Stanislav Mekhanoshin357d3db2017-02-28 19:20:33 +000070
Hiroshi Inouee9dea6e2017-07-13 06:48:39 +000071 // Occupancy target at the beginning of function scheduling cycle.
Stanislav Mekhanoshin357d3db2017-02-28 19:20:33 +000072 unsigned StartingOccupancy;
73
74 // Minimal real occupancy recorder for the function.
75 unsigned MinOccupancy;
76
77 // Scheduling stage number.
78 unsigned Stage;
79
Stanislav Mekhanoshinb1086072017-05-16 16:11:26 +000080 // Current region index.
81 size_t RegionIdx;
82
Austin Kerbow83e52142019-04-24 23:32:21 +000083 // Vector of regions recorder for later rescheduling
Stanislav Mekhanoshinb933c3f2017-03-28 21:48:54 +000084 SmallVector<std::pair<MachineBasicBlock::iterator,
85 MachineBasicBlock::iterator>, 32> Regions;
Stanislav Mekhanoshin357d3db2017-02-28 19:20:33 +000086
Stanislav Mekhanoshinb1086072017-05-16 16:11:26 +000087 // Region live-in cache.
88 SmallVector<GCNRPTracker::LiveRegSet, 32> LiveIns;
Stanislav Mekhanoshin282e8e42017-02-28 17:22:39 +000089
Stanislav Mekhanoshinb1086072017-05-16 16:11:26 +000090 // Region pressure cache.
91 SmallVector<GCNRegPressure, 32> Pressure;
92
93 // Temporary basic block live-in cache.
94 DenseMap<const MachineBasicBlock*, GCNRPTracker::LiveRegSet> MBBLiveIns;
Stanislav Mekhanoshin282e8e42017-02-28 17:22:39 +000095
Valery Pykhtin7e854e12019-06-18 11:43:17 +000096 DenseMap<MachineInstr *, GCNRPTracker::LiveRegSet> BBLiveInMap;
97 DenseMap<MachineInstr *, GCNRPTracker::LiveRegSet> getBBLiveInMap() const;
98
Stanislav Mekhanoshin464cecf2017-05-16 15:43:52 +000099 // Return current region pressure.
100 GCNRegPressure getRealRegPressure() const;
Stanislav Mekhanoshin282e8e42017-02-28 17:22:39 +0000101
Stanislav Mekhanoshinb1086072017-05-16 16:11:26 +0000102 // Compute and cache live-ins and pressure for all regions in block.
103 void computeBlockPressure(const MachineBasicBlock *MBB);
104
105
Stanislav Mekhanoshin582a5232017-02-15 17:19:50 +0000106public:
107 GCNScheduleDAGMILive(MachineSchedContext *C,
Stanislav Mekhanoshin357d3db2017-02-28 19:20:33 +0000108 std::unique_ptr<MachineSchedStrategy> S);
109
Stanislav Mekhanoshin582a5232017-02-15 17:19:50 +0000110 void schedule() override;
Stanislav Mekhanoshin282e8e42017-02-28 17:22:39 +0000111
112 void finalizeSchedule() override;
Tom Stellard0d23ebe2016-08-29 19:42:52 +0000113};
114
115} // End namespace llvm
116
117#endif // GCNSCHEDSTRATEGY_H