LLVM  10.0.0svn
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 #ifndef LLVM_LIB_TARGET_AMDGPU_GCNREGPRESSURE_H
10 #define LLVM_LIB_TARGET_AMDGPU_GCNREGPRESSURE_H
11 
12 #include "AMDGPUSubtarget.h"
13 #include "llvm/ADT/DenseMap.h"
18 #include "llvm/MC/LaneBitmask.h"
19 #include "llvm/Support/Debug.h"
20 #include <algorithm>
21 #include <limits>
22 
23 namespace llvm {
24 
25 class MachineRegisterInfo;
26 class raw_ostream;
27 
29  enum RegKind {
37  };
38 
40  clear();
41  }
42 
43  bool empty() const { return getSGPRNum() == 0 && getVGPRNum() == 0; }
44 
45  void clear() { std::fill(&Value[0], &Value[TOTAL_KINDS], 0); }
46 
47  unsigned getSGPRNum() const { return Value[SGPR32]; }
48  unsigned getVGPRNum() const { return std::max(Value[VGPR32], Value[AGPR32]); }
49 
50  unsigned getVGPRTuplesWeight() const { return std::max(Value[VGPR_TUPLE],
51  Value[AGPR_TUPLE]); }
52  unsigned getSGPRTuplesWeight() const { return Value[SGPR_TUPLE]; }
53 
54  unsigned getOccupancy(const GCNSubtarget &ST) const {
55  return std::min(ST.getOccupancyWithNumSGPRs(getSGPRNum()),
57  }
58 
59  void inc(unsigned Reg,
60  LaneBitmask PrevMask,
61  LaneBitmask NewMask,
62  const MachineRegisterInfo &MRI);
63 
64  bool higherOccupancy(const GCNSubtarget &ST, const GCNRegPressure& O) const {
65  return getOccupancy(ST) > O.getOccupancy(ST);
66  }
67 
68  bool less(const GCNSubtarget &ST, const GCNRegPressure& O,
69  unsigned MaxOccupancy = std::numeric_limits<unsigned>::max()) const;
70 
71  bool operator==(const GCNRegPressure &O) const {
72  return std::equal(&Value[0], &Value[TOTAL_KINDS], O.Value);
73  }
74 
75  bool operator!=(const GCNRegPressure &O) const {
76  return !(*this == O);
77  }
78 
79  void print(raw_ostream &OS, const GCNSubtarget *ST = nullptr) const;
80  void dump() const { print(dbgs()); }
81 
82 private:
83  unsigned Value[TOTAL_KINDS];
84 
85  static unsigned getRegKind(unsigned Reg, const MachineRegisterInfo &MRI);
86 
87  friend GCNRegPressure max(const GCNRegPressure &P1,
88  const GCNRegPressure &P2);
89 };
90 
91 inline GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2) {
92  GCNRegPressure Res;
93  for (unsigned I = 0; I < GCNRegPressure::TOTAL_KINDS; ++I)
94  Res.Value[I] = std::max(P1.Value[I], P2.Value[I]);
95  return Res;
96 }
97 
98 class GCNRPTracker {
99 public:
101 
102 protected:
106  const MachineInstr *LastTrackedMI = nullptr;
107  mutable const MachineRegisterInfo *MRI = nullptr;
108 
109  GCNRPTracker(const LiveIntervals &LIS_) : LIS(LIS_) {}
110 
111  void reset(const MachineInstr &MI, const LiveRegSet *LiveRegsCopy,
112  bool After);
113 
114 public:
115  // live regs for the current state
116  const decltype(LiveRegs) &getLiveRegs() const { return LiveRegs; }
117  const MachineInstr *getLastTrackedMI() const { return LastTrackedMI; }
118 
119  void clearMaxPressure() { MaxPressure.clear(); }
120 
121  // returns MaxPressure, resetting it
122  decltype(MaxPressure) moveMaxPressure() {
123  auto Res = MaxPressure;
124  MaxPressure.clear();
125  return Res;
126  }
127 
128  decltype(LiveRegs) moveLiveRegs() {
129  return std::move(LiveRegs);
130  }
131 
132  static void printLiveRegs(raw_ostream &OS, const LiveRegSet& LiveRegs,
133  const MachineRegisterInfo &MRI);
134 };
135 
137 public:
139 
140  // reset tracker to the point just below MI
141  // filling live regs upon this point using LIS
142  void reset(const MachineInstr &MI, const LiveRegSet *LiveRegs = nullptr);
143 
144  // move to the state just above the MI
145  void recede(const MachineInstr &MI);
146 
147  // checks whether the tracker's state after receding MI corresponds
148  // to reported by LIS
149  bool isValid() const;
150 };
151 
153  // Last position of reset or advanceBeforeNext
155 
157 
158 public:
160 
161  const MachineBasicBlock::const_iterator getNext() const { return NextMI; }
162 
163  // Reset tracker to the point before the MI
164  // filling live regs upon this point using LIS.
165  // Returns false if block is empty except debug values.
166  bool reset(const MachineInstr &MI, const LiveRegSet *LiveRegs = nullptr);
167 
168  // Move to the state right before the next MI. Returns false if reached
169  // end of the block.
170  bool advanceBeforeNext();
171 
172  // Move to the state at the MI, advanceBeforeNext has to be called first.
173  void advanceToNext();
174 
175  // Move to the state at the next MI. Returns false if reached end of block.
176  bool advance();
177 
178  // Advance instructions until before End.
179  bool advance(MachineBasicBlock::const_iterator End);
180 
181  // Reset to Begin and advance to End.
182  bool advance(MachineBasicBlock::const_iterator Begin,
184  const LiveRegSet *LiveRegsCopy = nullptr);
185 };
186 
188  SlotIndex SI,
189  const LiveIntervals &LIS,
190  const MachineRegisterInfo &MRI);
191 
193  const LiveIntervals &LIS,
194  const MachineRegisterInfo &MRI);
195 
196 /// creates a map MachineInstr -> LiveRegSet
197 /// R - range of iterators on instructions
198 /// After - upon entry or exit of every instruction
199 /// Note: there is no entry in the map for instructions with empty live reg set
200 /// Complexity = O(NumVirtRegs * averageLiveRangeSegmentsPerReg * lg(R))
201 template <typename Range>
203 getLiveRegMap(Range &&R, bool After, LiveIntervals &LIS) {
204  std::vector<SlotIndex> Indexes;
205  Indexes.reserve(std::distance(R.begin(), R.end()));
206  auto &SII = *LIS.getSlotIndexes();
207  for (MachineInstr *I : R) {
208  auto SI = SII.getInstructionIndex(*I);
209  Indexes.push_back(After ? SI.getDeadSlot() : SI.getBaseIndex());
210  }
211  std::sort(Indexes.begin(), Indexes.end());
212 
213  auto &MRI = (*R.begin())->getParent()->getParent()->getRegInfo();
215  SmallVector<SlotIndex, 32> LiveIdxs, SRLiveIdxs;
216  for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
217  auto Reg = Register::index2VirtReg(I);
218  if (!LIS.hasInterval(Reg))
219  continue;
220  auto &LI = LIS.getInterval(Reg);
221  LiveIdxs.clear();
222  if (!LI.findIndexesLiveAt(Indexes, std::back_inserter(LiveIdxs)))
223  continue;
224  if (!LI.hasSubRanges()) {
225  for (auto SI : LiveIdxs)
226  LiveRegMap[SII.getInstructionFromIndex(SI)][Reg] =
227  MRI.getMaxLaneMaskForVReg(Reg);
228  } else
229  for (const auto &S : LI.subranges()) {
230  // constrain search for subranges by indexes live at main range
231  SRLiveIdxs.clear();
232  S.findIndexesLiveAt(LiveIdxs, std::back_inserter(SRLiveIdxs));
233  for (auto SI : SRLiveIdxs)
234  LiveRegMap[SII.getInstructionFromIndex(SI)][Reg] |= S.LaneMask;
235  }
236  }
237  return LiveRegMap;
238 }
239 
241  const LiveIntervals &LIS) {
242  return getLiveRegs(LIS.getInstructionIndex(MI).getDeadSlot(), LIS,
243  MI.getParent()->getParent()->getRegInfo());
244 }
245 
247  const LiveIntervals &LIS) {
248  return getLiveRegs(LIS.getInstructionIndex(MI).getBaseIndex(), LIS,
249  MI.getParent()->getParent()->getRegInfo());
250 }
251 
252 template <typename Range>
254  Range &&LiveRegs) {
255  GCNRegPressure Res;
256  for (const auto &RM : LiveRegs)
257  Res.inc(RM.first, LaneBitmask::getNone(), RM.second, MRI);
258  return Res;
259 }
260 
261 bool isEqual(const GCNRPTracker::LiveRegSet &S1,
262  const GCNRPTracker::LiveRegSet &S2);
263 
264 void printLivesAt(SlotIndex SI,
265  const LiveIntervals &LIS,
266  const MachineRegisterInfo &MRI);
267 
268 } // end namespace llvm
269 
270 #endif // LLVM_LIB_TARGET_AMDGPU_GCNREGPRESSURE_H
A common definition of LaneBitmask for use in TableGen and CodeGen.
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
AMDGPU specific subclass of TargetSubtarget.
SlotIndex getBaseIndex() const
Returns the base index for associated with this index.
Definition: SlotIndexes.h:241
This class represents lattice values for constants.
Definition: AllocatorList.h:23
decltype(MaxPressure) moveMaxPressure()
unsigned getSGPRTuplesWeight() const
GCNRPTracker(const LiveIntervals &LIS_)
GCNRPTracker::LiveRegSet getLiveRegs(SlotIndex SI, const LiveIntervals &LIS, const MachineRegisterInfo &MRI)
unsigned Reg
friend GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
static unsigned index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
Definition: Register.h:83
const LiveIntervals & LIS
decltype(LiveRegs) moveLiveRegs()
bool operator!=(const GCNRegPressure &O) const
decltype(LiveRegs) const & getLiveRegs() const
SlotIndex getDeadSlot() const
Returns the dead def kill slot for the current instruction.
Definition: SlotIndexes.h:259
unsigned getOccupancy(const GCNSubtarget &ST) const
static constexpr LaneBitmask getNone()
Definition: LaneBitmask.h:82
bool hasInterval(Register Reg) const
void inc(unsigned Reg, LaneBitmask PrevMask, LaneBitmask NewMask, const MachineRegisterInfo &MRI)
unsigned getVGPRTuplesWeight() const
GCNRPTracker::LiveRegSet getLiveRegsBefore(const MachineInstr &MI, const LiveIntervals &LIS)
const MachineBasicBlock::const_iterator getNext() const
bool less(const GCNSubtarget &ST, const GCNRegPressure &O, unsigned MaxOccupancy=std::numeric_limits< unsigned >::max()) const
unsigned const MachineRegisterInfo * MRI
const MachineInstr * getLastTrackedMI() const
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
unsigned getSGPRNum() const
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...
LiveInterval & getInterval(Register Reg)
GCNRPTracker::LiveRegSet getLiveRegsAfter(const MachineInstr &MI, const LiveIntervals &LIS)
void sort(IteratorTy Start, IteratorTy End)
Definition: STLExtras.h:1095
GCNUpwardRPTracker(const LiveIntervals &LIS_)
void printLivesAt(SlotIndex SI, const LiveIntervals &LIS, const MachineRegisterInfo &MRI)
unsigned getVGPRNum() const
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:837
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
bool higherOccupancy(const GCNSubtarget &ST, const GCNRegPressure &O) const
unsigned getOccupancyWithNumSGPRs(unsigned SGPRs) const
Return the maximum number of waves per SIMD for kernels using SGPRs SGPRs.
SlotIndex getInstructionIndex(const MachineInstr &Instr) const
Returns the base index of the given instruction.
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:255
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
GCNRegPressure getRegPressure(const MachineRegisterInfo &MRI, Range &&LiveRegs)
Representation of each machine instruction.
Definition: MachineInstr.h:63
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
#define I(x, y, z)
Definition: MD5.cpp:58
SlotIndexes * getSlotIndexes() const
LaneBitmask getLiveLaneMask(unsigned Reg, SlotIndex SI, const LiveIntervals &LIS, const MachineRegisterInfo &MRI)
bool operator==(const GCNRegPressure &O) const
void print(raw_ostream &OS, const GCNSubtarget *ST=nullptr) const
LLVM Value Representation.
Definition: Value.h:74
static const Function * getParent(const Value *V)
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:45
bool isEqual(const GCNRPTracker::LiveRegSet &S1, const GCNRPTracker::LiveRegSet &S2)
IRTranslator LLVM IR MI
GCNRegPressure MaxPressure
GCNDownwardRPTracker(const LiveIntervals &LIS_)
unsigned getOccupancyWithNumVGPRs(unsigned VGPRs) const
Return the maximum number of waves per SIMD for kernels using VGPRs VGPRs.
SlotIndex - An opaque wrapper around machine indexes.
Definition: SlotIndexes.h:83