LLVM 18.0.0git
GCNRegPressure.h
Go to the documentation of this file.
1//===- GCNRegPressure.h -----------------------------------------*- 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 GCNRegPressure class, which tracks registry pressure
11/// by bookkeeping number of SGPR/VGPRs used, weights for large SGPR/VGPRs. It
12/// also implements a compare function, which compares different register
13/// pressures, and declares one with max occupancy as winner.
14///
15//===----------------------------------------------------------------------===//
16
17#ifndef LLVM_LIB_TARGET_AMDGPU_GCNREGPRESSURE_H
18#define LLVM_LIB_TARGET_AMDGPU_GCNREGPRESSURE_H
19
20#include "GCNSubtarget.h"
22#include <algorithm>
23
24namespace llvm {
25
26class MachineRegisterInfo;
27class raw_ostream;
28class SlotIndex;
29
31 enum RegKind {
39 };
40
42 clear();
43 }
44
45 bool empty() const { return getSGPRNum() == 0 && getVGPRNum(false) == 0; }
46
47 void clear() { std::fill(&Value[0], &Value[TOTAL_KINDS], 0); }
48
49 unsigned getSGPRNum() const { return Value[SGPR32]; }
50 unsigned getVGPRNum(bool UnifiedVGPRFile) const {
51 if (UnifiedVGPRFile) {
52 return Value[AGPR32] ? alignTo(Value[VGPR32], 4) + Value[AGPR32]
54 }
55 return std::max(Value[VGPR32], Value[AGPR32]);
56 }
57 unsigned getAGPRNum() const { return Value[AGPR32]; }
58
59 unsigned getVGPRTuplesWeight() const { return std::max(Value[VGPR_TUPLE],
60 Value[AGPR_TUPLE]); }
61 unsigned getSGPRTuplesWeight() const { return Value[SGPR_TUPLE]; }
62
63 unsigned getOccupancy(const GCNSubtarget &ST) const {
64 return std::min(ST.getOccupancyWithNumSGPRs(getSGPRNum()),
65 ST.getOccupancyWithNumVGPRs(getVGPRNum(ST.hasGFX90AInsts())));
66 }
67
68 void inc(unsigned Reg,
69 LaneBitmask PrevMask,
70 LaneBitmask NewMask,
72
73 bool higherOccupancy(const GCNSubtarget &ST, const GCNRegPressure& O) const {
74 return getOccupancy(ST) > O.getOccupancy(ST);
75 }
76
77 bool less(const GCNSubtarget &ST, const GCNRegPressure& O,
78 unsigned MaxOccupancy = std::numeric_limits<unsigned>::max()) const;
79
80 bool operator==(const GCNRegPressure &O) const {
81 return std::equal(&Value[0], &Value[TOTAL_KINDS], O.Value);
82 }
83
84 bool operator!=(const GCNRegPressure &O) const {
85 return !(*this == O);
86 }
87
88 void dump() const;
89
90private:
91 unsigned Value[TOTAL_KINDS];
92
93 static unsigned getRegKind(Register Reg, const MachineRegisterInfo &MRI);
94
95 friend GCNRegPressure max(const GCNRegPressure &P1,
96 const GCNRegPressure &P2);
97
98 friend Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST);
99};
100
101inline GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2) {
102 GCNRegPressure Res;
103 for (unsigned I = 0; I < GCNRegPressure::TOTAL_KINDS; ++I)
104 Res.Value[I] = std::max(P1.Value[I], P2.Value[I]);
105 return Res;
106}
107
109public:
111
112protected:
116 const MachineInstr *LastTrackedMI = nullptr;
117 mutable const MachineRegisterInfo *MRI = nullptr;
118
119 GCNRPTracker(const LiveIntervals &LIS_) : LIS(LIS_) {}
120
121 void reset(const MachineInstr &MI, const LiveRegSet *LiveRegsCopy,
122 bool After);
123
124public:
125 // live regs for the current state
126 const decltype(LiveRegs) &getLiveRegs() const { return LiveRegs; }
127 const MachineInstr *getLastTrackedMI() const { return LastTrackedMI; }
128
130
132
133 decltype(LiveRegs) moveLiveRegs() {
134 return std::move(LiveRegs);
135 }
136};
137
138GCNRPTracker::LiveRegSet getLiveRegs(SlotIndex SI, const LiveIntervals &LIS,
139 const MachineRegisterInfo &MRI);
140
142public:
144
145 // reset tracker and set live register set to the specified value.
146 void reset(const MachineRegisterInfo &MRI_, const LiveRegSet &LiveRegs_);
147
148 // reset tracker at the specified slot index.
151 }
152
153 // reset tracker to the end of the MBB.
155 reset(MBB.getParent()->getRegInfo(),
157 }
158
159 // reset tracker to the point just after MI (in program order).
160 void reset(const MachineInstr &MI) {
161 reset(MI.getMF()->getRegInfo(), LIS.getInstructionIndex(MI).getDeadSlot());
162 }
163
164 // move to the state just before the MI (in program order).
165 void recede(const MachineInstr &MI);
166
167 // checks whether the tracker's state after receding MI corresponds
168 // to reported by LIS.
169 bool isValid() const;
170
171 const GCNRegPressure &getMaxPressure() const { return MaxPressure; }
172
174
178 return RP;
179 }
180};
181
183 // Last position of reset or advanceBeforeNext
185
187
188public:
190
192
193 // Return MaxPressure and clear it.
195 auto Res = MaxPressure;
197 return Res;
198 }
199
200 // Reset tracker to the point before the MI
201 // filling live regs upon this point using LIS.
202 // Returns false if block is empty except debug values.
203 bool reset(const MachineInstr &MI, const LiveRegSet *LiveRegs = nullptr);
204
205 // Move to the state right before the next MI or after the end of MBB.
206 // Returns false if reached end of the block.
207 bool advanceBeforeNext();
208
209 // Move to the state at the MI, advanceBeforeNext has to be called first.
210 void advanceToNext();
211
212 // Move to the state at the next MI. Returns false if reached end of block.
213 bool advance();
214
215 // Advance instructions until before End.
217
218 // Reset to Begin and advance to End.
221 const LiveRegSet *LiveRegsCopy = nullptr);
222};
223
224LaneBitmask getLiveLaneMask(unsigned Reg,
225 SlotIndex SI,
226 const LiveIntervals &LIS,
227 const MachineRegisterInfo &MRI);
228
229LaneBitmask getLiveLaneMask(const LiveInterval &LI, SlotIndex SI,
230 const MachineRegisterInfo &MRI);
231
232GCNRPTracker::LiveRegSet getLiveRegs(SlotIndex SI, const LiveIntervals &LIS,
233 const MachineRegisterInfo &MRI);
234
235/// creates a map MachineInstr -> LiveRegSet
236/// R - range of iterators on instructions
237/// After - upon entry or exit of every instruction
238/// Note: there is no entry in the map for instructions with empty live reg set
239/// Complexity = O(NumVirtRegs * averageLiveRangeSegmentsPerReg * lg(R))
240template <typename Range>
241DenseMap<MachineInstr*, GCNRPTracker::LiveRegSet>
242getLiveRegMap(Range &&R, bool After, LiveIntervals &LIS) {
243 std::vector<SlotIndex> Indexes;
244 Indexes.reserve(std::distance(R.begin(), R.end()));
245 auto &SII = *LIS.getSlotIndexes();
246 for (MachineInstr *I : R) {
247 auto SI = SII.getInstructionIndex(*I);
248 Indexes.push_back(After ? SI.getDeadSlot() : SI.getBaseIndex());
249 }
250 llvm::sort(Indexes);
251
252 auto &MRI = (*R.begin())->getParent()->getParent()->getRegInfo();
254 SmallVector<SlotIndex, 32> LiveIdxs, SRLiveIdxs;
255 for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
257 if (!LIS.hasInterval(Reg))
258 continue;
259 auto &LI = LIS.getInterval(Reg);
260 LiveIdxs.clear();
261 if (!LI.findIndexesLiveAt(Indexes, std::back_inserter(LiveIdxs)))
262 continue;
263 if (!LI.hasSubRanges()) {
264 for (auto SI : LiveIdxs)
265 LiveRegMap[SII.getInstructionFromIndex(SI)][Reg] =
266 MRI.getMaxLaneMaskForVReg(Reg);
267 } else
268 for (const auto &S : LI.subranges()) {
269 // constrain search for subranges by indexes live at main range
270 SRLiveIdxs.clear();
271 S.findIndexesLiveAt(LiveIdxs, std::back_inserter(SRLiveIdxs));
272 for (auto SI : SRLiveIdxs)
273 LiveRegMap[SII.getInstructionFromIndex(SI)][Reg] |= S.LaneMask;
274 }
275 }
276 return LiveRegMap;
277}
278
280 const LiveIntervals &LIS) {
282 MI.getParent()->getParent()->getRegInfo());
283}
284
286 const LiveIntervals &LIS) {
288 MI.getParent()->getParent()->getRegInfo());
289}
290
291template <typename Range>
293 Range &&LiveRegs) {
294 GCNRegPressure Res;
295 for (const auto &RM : LiveRegs)
296 Res.inc(RM.first, LaneBitmask::getNone(), RM.second, MRI);
297 return Res;
298}
299
300bool isEqual(const GCNRPTracker::LiveRegSet &S1,
301 const GCNRPTracker::LiveRegSet &S2);
302
303Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST = nullptr);
304
305Printable print(const GCNRPTracker::LiveRegSet &LiveRegs,
306 const MachineRegisterInfo &MRI);
307
308Printable reportMismatch(const GCNRPTracker::LiveRegSet &LISLR,
309 const GCNRPTracker::LiveRegSet &TrackedL,
310 const TargetRegisterInfo *TRI, StringRef Pfx = " ");
311
313 static char ID;
314
315public:
317
318 bool runOnMachineFunction(MachineFunction &MF) override;
319
320 void getAnalysisUsage(AnalysisUsage &AU) const override {
322 AU.setPreservesAll();
324 }
325};
326
327} // end namespace llvm
328
329#endif // LLVM_LIB_TARGET_AMDGPU_GCNREGPRESSURE_H
unsigned const MachineRegisterInfo * MRI
MachineBasicBlock & MBB
static const Function * getParent(const Value *V)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
bool End
Definition: ELF_riscv.cpp:478
AMD GCN specific subclass of TargetSubtarget.
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition: MD5.cpp:58
unsigned const TargetRegisterInfo * TRI
unsigned Reg
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
void setPreservesAll()
Set by analyses that do not transform their input at all.
GCNRegPressure moveMaxPressure()
MachineBasicBlock::const_iterator getNext() const
GCNDownwardRPTracker(const LiveIntervals &LIS_)
bool reset(const MachineInstr &MI, const LiveRegSet *LiveRegs=nullptr)
GCNRegPressure getPressure() const
const decltype(LiveRegs) & getLiveRegs() const
const MachineInstr * LastTrackedMI
decltype(LiveRegs) moveLiveRegs()
GCNRegPressure CurPressure
DenseMap< unsigned, LaneBitmask > LiveRegSet
GCNRPTracker(const LiveIntervals &LIS_)
GCNRegPressure MaxPressure
void reset(const MachineInstr &MI, const LiveRegSet *LiveRegsCopy, bool After)
const MachineInstr * getLastTrackedMI() const
const MachineRegisterInfo * MRI
const LiveIntervals & LIS
GCNUpwardRPTracker(const LiveIntervals &LIS_)
GCNRegPressure getMaxPressureAndReset()
void reset(const MachineRegisterInfo &MRI, SlotIndex SI)
void recede(const MachineInstr &MI)
void reset(const MachineRegisterInfo &MRI_, const LiveRegSet &LiveRegs_)
const GCNRegPressure & getMaxPressure() const
void reset(const MachineBasicBlock &MBB)
void reset(const MachineInstr &MI)
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:652
bool hasInterval(Register Reg) const
SlotIndexes * getSlotIndexes() const
SlotIndex getInstructionIndex(const MachineInstr &Instr) const
Returns the base index of the given instruction.
LiveInterval & getInterval(Register Reg)
A set of live virtual registers and physical register units.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
Representation of each machine instruction.
Definition: MachineInstr.h:68
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Simple wrapper around std::function<void(raw_ostream&)>.
Definition: Printable.h:38
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
static Register index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
Definition: Register.h:84
SlotIndex - An opaque wrapper around machine indexes.
Definition: SlotIndexes.h:68
SlotIndex getDeadSlot() const
Returns the dead def kill slot for the current instruction.
Definition: SlotIndexes.h:245
SlotIndex getBaseIndex() const
Returns the base index for associated with this index.
Definition: SlotIndexes.h:227
SlotIndex getMBBEndIdx(unsigned Num) const
Returns the last index in the given basic block number.
Definition: SlotIndexes.h:462
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1200
LLVM Value Representation.
Definition: Value.h:74
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
bool isEqual(const GCNRPTracker::LiveRegSet &S1, const GCNRPTracker::LiveRegSet &S2)
GCNRegPressure getRegPressure(const MachineRegisterInfo &MRI, Range &&LiveRegs)
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr)
GCNRPTracker::LiveRegSet getLiveRegs(SlotIndex SI, const LiveIntervals &LIS, const MachineRegisterInfo &MRI)
GCNRPTracker::LiveRegSet getLiveRegsAfter(const MachineInstr &MI, const LiveIntervals &LIS)
void sort(IteratorTy Start, IteratorTy End)
Definition: STLExtras.h:1651
LaneBitmask getLiveLaneMask(unsigned Reg, SlotIndex SI, const LiveIntervals &LIS, const MachineRegisterInfo &MRI)
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition: Alignment.h:155
DenseMap< MachineInstr *, GCNRPTracker::LiveRegSet > getLiveRegMap(Range &&R, bool After, LiveIntervals &LIS)
creates a map MachineInstr -> LiveRegSet R - range of iterators on instructions After - upon entry or...
GCNRPTracker::LiveRegSet getLiveRegsBefore(const MachineInstr &MI, const LiveIntervals &LIS)
Printable reportMismatch(const GCNRPTracker::LiveRegSet &LISLR, const GCNRPTracker::LiveRegSet &TrackedL, const TargetRegisterInfo *TRI, StringRef Pfx=" ")
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
bool operator!=(const GCNRegPressure &O) const
unsigned getVGPRTuplesWeight() const
unsigned getOccupancy(const GCNSubtarget &ST) const
unsigned getVGPRNum(bool UnifiedVGPRFile) const
friend GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
void inc(unsigned Reg, LaneBitmask PrevMask, LaneBitmask NewMask, const MachineRegisterInfo &MRI)
bool higherOccupancy(const GCNSubtarget &ST, const GCNRegPressure &O) const
unsigned getAGPRNum() const
unsigned getSGPRNum() const
bool less(const GCNSubtarget &ST, const GCNRegPressure &O, unsigned MaxOccupancy=std::numeric_limits< unsigned >::max()) const
unsigned getSGPRTuplesWeight() const
bool operator==(const GCNRegPressure &O) const
friend Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST)
static constexpr LaneBitmask getNone()
Definition: LaneBitmask.h:81