LLVM 17.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
131 // returns MaxPressure, resetting it
133 auto Res = MaxPressure;
135 return Res;
136 }
137
138 decltype(LiveRegs) moveLiveRegs() {
139 return std::move(LiveRegs);
140 }
141};
142
144public:
146
147 // reset tracker to the point just below MI
148 // filling live regs upon this point using LIS
149 void reset(const MachineInstr &MI, const LiveRegSet *LiveRegs = nullptr);
150
151 // move to the state just above the MI
152 void recede(const MachineInstr &MI);
153
154 // checks whether the tracker's state after receding MI corresponds
155 // to reported by LIS
156 bool isValid() const;
157};
158
160 // Last position of reset or advanceBeforeNext
162
164
165public:
167
169
170 // Reset tracker to the point before the MI
171 // filling live regs upon this point using LIS.
172 // Returns false if block is empty except debug values.
173 bool reset(const MachineInstr &MI, const LiveRegSet *LiveRegs = nullptr);
174
175 // Move to the state right before the next MI or after the end of MBB.
176 // Returns false if reached end of the block.
177 bool advanceBeforeNext();
178
179 // Move to the state at the MI, advanceBeforeNext has to be called first.
180 void advanceToNext();
181
182 // Move to the state at the next MI. Returns false if reached end of block.
183 bool advance();
184
185 // Advance instructions until before End.
187
188 // Reset to Begin and advance to End.
191 const LiveRegSet *LiveRegsCopy = nullptr);
192};
193
194LaneBitmask getLiveLaneMask(unsigned Reg,
195 SlotIndex SI,
196 const LiveIntervals &LIS,
197 const MachineRegisterInfo &MRI);
198
200 const LiveIntervals &LIS,
201 const MachineRegisterInfo &MRI);
202
203/// creates a map MachineInstr -> LiveRegSet
204/// R - range of iterators on instructions
205/// After - upon entry or exit of every instruction
206/// Note: there is no entry in the map for instructions with empty live reg set
207/// Complexity = O(NumVirtRegs * averageLiveRangeSegmentsPerReg * lg(R))
208template <typename Range>
209DenseMap<MachineInstr*, GCNRPTracker::LiveRegSet>
210getLiveRegMap(Range &&R, bool After, LiveIntervals &LIS) {
211 std::vector<SlotIndex> Indexes;
212 Indexes.reserve(std::distance(R.begin(), R.end()));
213 auto &SII = *LIS.getSlotIndexes();
214 for (MachineInstr *I : R) {
215 auto SI = SII.getInstructionIndex(*I);
216 Indexes.push_back(After ? SI.getDeadSlot() : SI.getBaseIndex());
217 }
218 llvm::sort(Indexes);
219
220 auto &MRI = (*R.begin())->getParent()->getParent()->getRegInfo();
222 SmallVector<SlotIndex, 32> LiveIdxs, SRLiveIdxs;
223 for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
225 if (!LIS.hasInterval(Reg))
226 continue;
227 auto &LI = LIS.getInterval(Reg);
228 LiveIdxs.clear();
229 if (!LI.findIndexesLiveAt(Indexes, std::back_inserter(LiveIdxs)))
230 continue;
231 if (!LI.hasSubRanges()) {
232 for (auto SI : LiveIdxs)
233 LiveRegMap[SII.getInstructionFromIndex(SI)][Reg] =
234 MRI.getMaxLaneMaskForVReg(Reg);
235 } else
236 for (const auto &S : LI.subranges()) {
237 // constrain search for subranges by indexes live at main range
238 SRLiveIdxs.clear();
239 S.findIndexesLiveAt(LiveIdxs, std::back_inserter(SRLiveIdxs));
240 for (auto SI : SRLiveIdxs)
241 LiveRegMap[SII.getInstructionFromIndex(SI)][Reg] |= S.LaneMask;
242 }
243 }
244 return LiveRegMap;
245}
246
248 const LiveIntervals &LIS) {
250 MI.getParent()->getParent()->getRegInfo());
251}
252
254 const LiveIntervals &LIS) {
256 MI.getParent()->getParent()->getRegInfo());
257}
258
259template <typename Range>
261 Range &&LiveRegs) {
262 GCNRegPressure Res;
263 for (const auto &RM : LiveRegs)
264 Res.inc(RM.first, LaneBitmask::getNone(), RM.second, MRI);
265 return Res;
266}
267
268bool isEqual(const GCNRPTracker::LiveRegSet &S1,
269 const GCNRPTracker::LiveRegSet &S2);
270
271Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST = nullptr);
272
273Printable print(const GCNRPTracker::LiveRegSet &LiveRegs,
274 const MachineRegisterInfo &MRI);
275
276Printable reportMismatch(const GCNRPTracker::LiveRegSet &LISLR,
277 const GCNRPTracker::LiveRegSet &TrackedL,
278 const TargetRegisterInfo *TRI);
279
280} // end namespace llvm
281
282#endif // LLVM_LIB_TARGET_AMDGPU_GCNREGPRESSURE_H
unsigned const MachineRegisterInfo * MRI
static const Function * getParent(const Value *V)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
bool End
Definition: ELF_riscv.cpp:464
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
@ SI
MachineBasicBlock::const_iterator getNext() const
GCNDownwardRPTracker(const LiveIntervals &LIS_)
bool reset(const MachineInstr &MI, const LiveRegSet *LiveRegs=nullptr)
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
decltype(MaxPressure) moveMaxPressure()
const MachineRegisterInfo * MRI
const LiveIntervals & LIS
GCNUpwardRPTracker(const LiveIntervals &LIS_)
void reset(const MachineInstr &MI, const LiveRegSet *LiveRegs=nullptr)
void recede(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.
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 getDeadSlot() const
Returns the dead def kill slot for the current instruction.
Definition: SlotIndexes.h:264
SlotIndex getBaseIndex() const
Returns the base index for associated with this index.
Definition: SlotIndexes.h:246
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
bool isEqual(const GCNRPTracker::LiveRegSet &S1, const GCNRPTracker::LiveRegSet &S2)
GCNRegPressure getRegPressure(const MachineRegisterInfo &MRI, Range &&LiveRegs)
GCNRPTracker::LiveRegSet getLiveRegs(SlotIndex SI, const LiveIntervals &LIS, const MachineRegisterInfo &MRI)
GCNRPTracker::LiveRegSet getLiveRegsAfter(const MachineInstr &MI, const LiveIntervals &LIS)
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr)
void sort(IteratorTy Start, IteratorTy End)
Definition: STLExtras.h:1744
LaneBitmask getLiveLaneMask(unsigned Reg, SlotIndex SI, const LiveIntervals &LIS, const MachineRegisterInfo &MRI)
Printable reportMismatch(const GCNRPTracker::LiveRegSet &LISLR, const GCNRPTracker::LiveRegSet &TrackedL, const TargetRegisterInfo *TRI)
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition: Alignment.h:155
Expected< ExpressionValue > max(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
Definition: FileCheck.cpp:334
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)
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