LLVM 22.0.0git
RegisterClassInfo.cpp
Go to the documentation of this file.
1//===- RegisterClassInfo.cpp - Dynamic Register Class Info ----------------===//
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// This file implements the RegisterClassInfo class which provides dynamic
10// information about target register classes. Callee-saved vs. caller-saved and
11// reserved registers depend on calling conventions and other dynamic
12// information, so some things cannot be determined statically.
13//
14//===----------------------------------------------------------------------===//
15
17#include "llvm/ADT/ArrayRef.h"
18#include "llvm/ADT/BitVector.h"
26#include "llvm/Support/Debug.h"
28#include <algorithm>
29#include <cassert>
30#include <cstdint>
31
32using namespace llvm;
33
34#define DEBUG_TYPE "regalloc"
35
37StressRA("stress-regalloc", cl::Hidden, cl::init(0), cl::value_desc("N"),
38 cl::desc("Limit all regclasses to N registers"));
39
41
43 bool Rev) {
44 bool Update = false;
45 MF = &mf;
46
47 auto &STI = MF->getSubtarget();
48
49 // Allocate new array the first time we see a new target.
50 if (STI.getRegisterInfo() != TRI || Reverse != Rev) {
51 Reverse = Rev;
52 TRI = STI.getRegisterInfo();
53 RegClass.reset(new RCInfo[TRI->getNumRegClasses()]);
54 Update = true;
55 }
56
57 // Test if CSRs have changed from the previous function.
58 const MachineRegisterInfo &MRI = MF->getRegInfo();
59 const MCPhysReg *CSR = MRI.getCalleeSavedRegs();
60 bool CSRChanged = true;
61 if (!Update) {
62 CSRChanged = false;
63 size_t LastSize = LastCalleeSavedRegs.size();
64 for (unsigned I = 0;; ++I) {
65 if (CSR[I] == 0) {
66 CSRChanged = I != LastSize;
67 break;
68 }
69 if (I >= LastSize) {
70 CSRChanged = true;
71 break;
72 }
73 if (CSR[I] != LastCalleeSavedRegs[I]) {
74 CSRChanged = true;
75 break;
76 }
77 }
78 }
79
80 // Get the callee saved registers.
81 if (CSRChanged) {
82 LastCalleeSavedRegs.clear();
83 // Build a CSRAlias map. Every CSR alias saves the last
84 // overlapping CSR.
85 CalleeSavedAliases.assign(TRI->getNumRegUnits(), 0);
86 for (const MCPhysReg *I = CSR; *I; ++I) {
87 for (MCRegUnit U : TRI->regunits(*I))
88 CalleeSavedAliases[U] = *I;
89 LastCalleeSavedRegs.push_back(*I);
90 }
91
92 Update = true;
93 }
94
95 // Even if CSR list is same, we could have had a different allocation order
96 // if ignoreCSRForAllocationOrder is evaluated differently.
97 BitVector CSRHintsForAllocOrder(TRI->getNumRegs());
98 for (const MCPhysReg *I = CSR; *I; ++I)
99 for (MCRegAliasIterator AI(*I, TRI, true); AI.isValid(); ++AI)
100 CSRHintsForAllocOrder[(*AI).id()] =
101 STI.ignoreCSRForAllocationOrder(mf, *AI);
102 if (IgnoreCSRForAllocOrder != CSRHintsForAllocOrder) {
103 Update = true;
104 IgnoreCSRForAllocOrder = CSRHintsForAllocOrder;
105 }
106
107 RegCosts = TRI->getRegisterCosts(*MF);
108
109 // Different reserved registers?
110 const BitVector &RR = MF->getRegInfo().getReservedRegs();
111 if (RR != Reserved) {
112 Update = true;
113 Reserved = RR;
114 }
115
116 // Invalidate cached information from previous function.
117 if (Update) {
118 unsigned NumPSets = TRI->getNumRegPressureSets();
119 PSetLimits.reset(new unsigned[NumPSets]);
120 std::fill(&PSetLimits[0], &PSetLimits[NumPSets], 0);
121 ++Tag;
122 }
123}
124
125/// compute - Compute the preferred allocation order for RC with reserved
126/// registers filtered out. Volatile registers come first followed by CSR
127/// aliases ordered according to the CSR order specified by the target.
128void RegisterClassInfo::compute(const TargetRegisterClass *RC) const {
129 assert(RC && "no register class given");
130 RCInfo &RCI = RegClass[RC->getID()];
131 auto &STI = MF->getSubtarget();
132
133 // Raw register count, including all reserved regs.
134 unsigned NumRegs = RC->getNumRegs();
135
136 if (!RCI.Order)
137 RCI.Order.reset(new MCPhysReg[NumRegs]);
138
139 unsigned N = 0;
141 uint8_t MinCost = uint8_t(~0u);
142 uint8_t LastCost = uint8_t(~0u);
143 unsigned LastCostChange = 0;
144
145 // FIXME: Once targets reserve registers instead of removing them from the
146 // allocation order, we can simply use begin/end here.
147 ArrayRef<MCPhysReg> RawOrder = RC->getRawAllocationOrder(*MF, Reverse);
148 std::vector<MCPhysReg> ReverseOrder;
149 if (Reverse) {
150 llvm::append_range(ReverseOrder, reverse(RawOrder));
151 RawOrder = ArrayRef<MCPhysReg>(ReverseOrder);
152 }
153 for (unsigned PhysReg : RawOrder) {
154 // Remove reserved registers from the allocation order.
155 if (Reserved.test(PhysReg))
156 continue;
157 uint8_t Cost = RegCosts[PhysReg];
158 MinCost = std::min(MinCost, Cost);
159
160 if (getLastCalleeSavedAlias(PhysReg) &&
161 !STI.ignoreCSRForAllocationOrder(*MF, PhysReg))
162 // PhysReg aliases a CSR, save it for later.
163 CSRAlias.push_back(PhysReg);
164 else {
165 if (Cost != LastCost)
166 LastCostChange = N;
167 RCI.Order[N++] = PhysReg;
168 LastCost = Cost;
169 }
170 }
171 RCI.NumRegs = N + CSRAlias.size();
172 assert(RCI.NumRegs <= NumRegs && "Allocation order larger than regclass");
173
174 // CSR aliases go after the volatile registers, preserve the target's order.
175 for (unsigned PhysReg : CSRAlias) {
176 uint8_t Cost = RegCosts[PhysReg];
177 if (Cost != LastCost)
178 LastCostChange = N;
179 RCI.Order[N++] = PhysReg;
180 LastCost = Cost;
181 }
182
183 // Register allocator stress test. Clip register class to N registers.
184 if (StressRA && RCI.NumRegs > StressRA)
185 RCI.NumRegs = StressRA;
186
187 // Check if RC is a proper sub-class.
188 if (const TargetRegisterClass *Super =
189 TRI->getLargestLegalSuperClass(RC, *MF))
190 if (Super != RC && getNumAllocatableRegs(Super) > RCI.NumRegs)
191 RCI.ProperSubClass = true;
192
193 RCI.MinCost = MinCost;
194 RCI.LastCostChange = LastCostChange;
195
196 LLVM_DEBUG({
197 dbgs() << "AllocationOrder(" << TRI->getRegClassName(RC) << ") = [";
198 for (unsigned I = 0; I != RCI.NumRegs; ++I)
199 dbgs() << ' ' << printReg(RCI.Order[I], TRI);
200 dbgs() << (RCI.ProperSubClass ? " ] (sub-class)\n" : " ]\n");
201 });
202
203 // RCI is now up-to-date.
204 RCI.Tag = Tag;
205}
206
207/// This is not accurate because two overlapping register sets may have some
208/// nonoverlapping reserved registers. However, computing the allocation order
209/// for all register classes would be too expensive.
210unsigned RegisterClassInfo::computePSetLimit(unsigned Idx) const {
211 const TargetRegisterClass *RC = nullptr;
212 unsigned NumRCUnits = 0;
213 for (const TargetRegisterClass *C : TRI->regclasses()) {
214 const int *PSetID = TRI->getRegClassPressureSets(C);
215 for (; *PSetID != -1; ++PSetID) {
216 if ((unsigned)*PSetID == Idx)
217 break;
218 }
219 if (*PSetID == -1)
220 continue;
221
222 // Found a register class that counts against this pressure set.
223 // For efficiency, only compute the set order for the largest set.
224 unsigned NUnits = TRI->getRegClassWeight(C).WeightLimit;
225 if (!RC || NUnits > NumRCUnits) {
226 RC = C;
227 NumRCUnits = NUnits;
228 }
229 }
230 assert(RC && "Failed to find register class");
231 compute(RC);
232 unsigned NAllocatableRegs = getNumAllocatableRegs(RC);
233 unsigned RegPressureSetLimit = TRI->getRegPressureSetLimit(*MF, Idx);
234 // If all the regs are reserved, return raw RegPressureSetLimit.
235 // One example is VRSAVERC in PowerPC.
236 // Avoid returning zero, getRegPressureSetLimit(Idx) assumes computePSetLimit
237 // return non-zero value.
238 if (NAllocatableRegs == 0)
239 return RegPressureSetLimit;
240 unsigned NReserved = RC->getNumRegs() - NAllocatableRegs;
241 return RegPressureSetLimit - TRI->getRegClassWeight(RC).RegWeight * NReserved;
242}
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements the BitVector class.
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
#define I(x, y, z)
Definition: MD5.cpp:58
static cl::opt< unsigned > StressRA("stress-regalloc", cl::Hidden, cl::init(0), cl::value_desc("N"), cl::desc("Limit all regclasses to N registers"))
This file defines the SmallVector class.
#define LLVM_DEBUG(...)
Definition: Debug.h:119
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
bool test(unsigned Idx) const
Definition: BitVector.h:461
MCRegAliasIterator enumerates all registers aliasing Reg.
unsigned getNumRegUnits() const
Return the number of (native) register units in the target.
iterator_range< MCRegUnitIterator > regunits(MCRegister Reg) const
Returns an iterator range over all regunits for Reg.
unsigned getNumRegs() const
Return the number of registers this target has (useful for sizing arrays holding per register informa...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
const BitVector & getReservedRegs() const
getReservedRegs - Returns a reference to the frozen set of reserved registers.
unsigned getNumAllocatableRegs(const TargetRegisterClass *RC) const
getNumAllocatableRegs - Returns the number of actually allocatable registers in RC in the current fun...
LLVM_ABI void runOnMachineFunction(const MachineFunction &MF, bool Rev=false)
runOnFunction - Prepare to answer questions about MF.
MCRegister getLastCalleeSavedAlias(MCRegister PhysReg) const
getLastCalleeSavedAlias - Returns the last callee saved register that overlaps PhysReg,...
LLVM_ABI RegisterClassInfo()
LLVM_ABI unsigned computePSetLimit(unsigned Idx) const
This is not accurate because two overlapping register sets may have some nonoverlapping reserved regi...
size_t size() const
Definition: SmallVector.h:79
void push_back(const T &Elt)
Definition: SmallVector.h:414
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
unsigned getNumRegs() const
Return the number of registers in this class.
unsigned getID() const
Return the register class ID number.
ArrayRef< MCPhysReg > getRawAllocationOrder(const MachineFunction &MF, bool Rev=false) const
Returns the preferred order for allocating registers from this register class in MF.
virtual unsigned getNumRegPressureSets() const =0
Get the number of dimensions of register pressure.
iterator_range< regclass_iterator > regclasses() const
ArrayRef< uint8_t > getRegisterCosts(const MachineFunction &MF) const
Get a list of cost values for all registers that correspond to the index returned by RegisterCostTabl...
unsigned getNumRegClasses() const
virtual const int * getRegClassPressureSets(const TargetRegisterClass *RC) const =0
Get the dimensions of register pressure impacted by this register class.
virtual const RegClassWeight & getRegClassWeight(const TargetRegisterClass *RC) const =0
Get the weight in units of pressure for this register class.
virtual const TargetRegisterClass * getLargestLegalSuperClass(const TargetRegisterClass *RC, const MachineFunction &) const
Returns the largest super class of RC that is legal to use in the current sub-target and has the same...
virtual unsigned getRegPressureSetLimit(const MachineFunction &MF, unsigned Idx) const =0
Get the register unit pressure limit for this dimension.
const char * getRegClassName(const TargetRegisterClass *Class) const
Returns the name of the register class.
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:444
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Definition: STLExtras.h:2155
auto reverse(ContainerTy &&C)
Definition: STLExtras.h:428
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:207
InstructionCost Cost
LLVM_ABI Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
#define N