LLVM 24.0.0git
CalcSpillWeights.cpp
Go to the documentation of this file.
1//===- CalcSpillWeights.cpp -----------------------------------------------===//
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
24#include "llvm/Support/Debug.h"
27#include <cassert>
28#include <tuple>
29
30using namespace llvm;
31
32#define DEBUG_TYPE "calcspillweights"
33
34bool VirtRegAuxInfo::getCachedOptimizeForSize() {
35 if (!CachedOptForSize.has_value())
36 CachedOptForSize = PSI && llvm::shouldOptimizeForSize(&MF, PSI, &MBFI);
37 return *CachedOptForSize;
38}
39
41 LLVM_DEBUG(dbgs() << "********** Compute Spill Weights **********\n"
42 << "********** Function: " << MF.getName() << '\n');
43
44 MachineRegisterInfo &MRI = MF.getRegInfo();
45 for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
47 if (MRI.reg_nodbg_empty(Reg))
48 continue;
49 calculateSpillWeightAndHint(LIS.getInterval(Reg));
50 }
51}
52
53// Return the preferred allocation register for reg, given a COPY instruction.
56 const MachineRegisterInfo &MRI) {
57 unsigned Sub, HSub;
58 Register HReg;
59 if (MI->getOperand(0).getReg() == Reg) {
60 Sub = MI->getOperand(0).getSubReg();
61 HReg = MI->getOperand(1).getReg();
62 HSub = MI->getOperand(1).getSubReg();
63 } else {
64 Sub = MI->getOperand(1).getSubReg();
65 HReg = MI->getOperand(0).getReg();
66 HSub = MI->getOperand(0).getSubReg();
67 }
68
69 if (!HReg)
70 return 0;
71
72 if (HReg.isVirtual())
73 return Sub == HSub ? HReg : Register();
74
75 const TargetRegisterClass *RC = MRI.getRegClass(Reg);
76 MCRegister CopiedPReg = HSub ? TRI.getSubReg(HReg, HSub) : HReg.asMCReg();
77 if (RC->contains(CopiedPReg))
78 return CopiedPReg;
79
80 // Check if reg:sub matches so that a super register could be hinted.
81 if (Sub)
82 return TRI.getMatchingSuperReg(CopiedPReg, Sub, RC);
83
84 return Register();
85}
86
87// Check if all values in LI are rematerializable
89 const LiveIntervals &LIS,
90 const VirtRegMap &VRM,
91 const MachineRegisterInfo &MRI,
92 const TargetInstrInfo &TII) {
93 Register Reg = LI.reg();
94 Register Original = VRM.getOriginal(Reg);
97 I != E; ++I) {
98 const VNInfo *VNI = *I;
99 const VNInfo *OrigVNI = VNI;
100 if (VNI->isUnused())
101 continue;
102 if (VNI->isPHIDef())
103 return false;
104
105 MachineInstr *MI = LIS.getInstructionFromIndex(VNI->def);
106 assert(MI && "Dead valno in interval");
107
108 // Trace copies introduced by live range splitting. The inline
109 // spiller can rematerialize through these copies, so the spill
110 // weight must reflect this.
111 while (TII.isFullCopyInstr(*MI)) {
112 // The copy destination must match the interval register.
113 if (MI->getOperand(0).getReg() != Reg)
114 return false;
115
116 // Get the source register.
117 Reg = MI->getOperand(1).getReg();
118
119 // If the original (pre-splitting) registers match this
120 // copy came from a split.
121 if (!Reg.isVirtual() || VRM.getOriginal(Reg) != Original)
122 return false;
123
124 // Follow the copy live-in value.
125 const LiveInterval &SrcLI = LIS.getInterval(Reg);
126 LiveQueryResult SrcQ = SrcLI.Query(VNI->def);
127 VNI = SrcQ.valueIn();
128 assert(VNI && "Copy from non-existing value");
129 if (VNI->isPHIDef())
130 return false;
131 MI = LIS.getInstructionFromIndex(VNI->def);
132 assert(MI && "Dead valno in interval");
133 }
134
135 if (!TII.isReMaterializable(*MI))
136 return false;
137
138 VNIDefs[OrigVNI->id] = MI;
139 }
140
141 // If MI has register uses, it will only be rematerializable if its uses are
142 // also live at the indices it will be rematerialized at.
143 for (MachineOperand &MO : MRI.reg_nodbg_operands(LI.reg())) {
144 if (!MO.readsReg())
145 continue;
146 SlotIndex UseIdx = LIS.getInstructionIndex(*MO.getParent());
147 MachineInstr *Def = VNIDefs[LI.getVNInfoAt(UseIdx)->id];
148 assert(Def && "Use with no def");
149 if (!allUsesAvailableAt(Def, UseIdx, LIS, MRI, TII))
150 return false;
151 }
152
153 return true;
154}
155
157 SlotIndex UseIdx,
158 const LiveIntervals &LIS,
159 const MachineRegisterInfo &MRI,
160 const TargetInstrInfo &TII) {
161 SlotIndex OrigIdx = LIS.getInstructionIndex(*MI).getRegSlot(true);
162 UseIdx = std::max(UseIdx, UseIdx.getRegSlot(true));
163 for (const MachineOperand &MO : MI->operands()) {
164 if (!MO.isReg() || !MO.getReg() || !MO.readsReg())
165 continue;
166
167 // We can't remat physreg uses, unless it is a constant or target wants
168 // to ignore this use.
169 if (MO.getReg().isPhysical()) {
170 if (MRI.isConstantPhysReg(MO.getReg()) ||
171 TII.isIgnorableUse(*MI, MI->getOperandNo(&MO)))
172 continue;
173 return false;
174 }
175
176 const LiveInterval &li = LIS.getInterval(MO.getReg());
177 const VNInfo *OVNI = li.getVNInfoAt(OrigIdx);
178 if (!OVNI)
179 continue;
180
181 // Don't allow rematerialization immediately after the original def.
182 // It would be incorrect if OrigMI redefines the register.
183 // See PR14098.
184 if (SlotIndex::isSameInstr(OrigIdx, UseIdx))
185 return false;
186
187 if (OVNI != li.getVNInfoAt(UseIdx))
188 return false;
189
190 // Check that subrange is live at UseIdx.
191 if (li.hasSubRanges()) {
193 unsigned SubReg = MO.getSubReg();
194 LaneBitmask LM = SubReg ? TRI->getSubRegIndexLaneMask(SubReg)
195 : MRI.getMaxLaneMaskForVReg(MO.getReg());
196 for (const LiveInterval::SubRange &SR : li.subranges()) {
197 if ((SR.LaneMask & LM).none())
198 continue;
199 if (!SR.liveAt(UseIdx))
200 return false;
201 // Early exit if all used lanes are checked. No need to continue.
202 LM &= ~SR.LaneMask;
203 if (LM.none())
204 break;
205 }
206 }
207 }
208 return true;
209}
210
211bool VirtRegAuxInfo::isLiveAtStatepointVarArg(LiveInterval &LI) {
212 return any_of(VRM.getRegInfo().reg_operands(LI.reg()),
213 [](MachineOperand &MO) {
214 MachineInstr *MI = MO.getParent();
215 if (MI->getOpcode() != TargetOpcode::STATEPOINT)
216 return false;
217 return StatepointOpers(MI).getVarIdx() <= MO.getOperandNo();
218 });
219}
220
222 float Weight = weightCalcHelper(LI);
223 // Check if unspillable.
224 if (Weight < 0)
225 return;
226 LI.setWeight(Weight);
227}
228
230 const MachineRegisterInfo &MRI) {
231 for (const MachineOperand &MO : MRI.reg_operands(LI.reg())) {
232 const MachineInstr *MI = MO.getParent();
233 if (MI->isInlineAsm() && MI->mayFoldInlineAsmRegOp(MI->getOperandNo(&MO)))
234 return true;
235 }
236
237 return false;
238}
239
241 MachineRegisterInfo &MRI = MF.getRegInfo();
242 const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
243 const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
244 MachineBasicBlock *MBB = nullptr;
245 float TotalWeight = 0;
246 unsigned NumInstr = 0; // Number of instructions using LI
248
249 std::pair<unsigned, Register> TargetHint = MRI.getRegAllocationHint(LI.reg());
250
251 if (LI.isSpillable()) {
252 Register Reg = LI.reg();
253 Register Original = VRM.getOriginal(Reg);
254 const LiveInterval &OrigInt = LIS.getInterval(Original);
255 // li comes from a split of OrigInt. If OrigInt was marked
256 // as not spillable, make sure the new interval is marked
257 // as not spillable as well.
258 if (!OrigInt.isSpillable())
259 LI.markNotSpillable();
260 }
261
262 // Don't recompute spill weight for an unspillable register.
263 bool IsSpillable = LI.isSpillable();
264
265 // CopyHint is a sortable hint derived from a COPY instruction.
266 struct CopyHint {
267 Register Reg;
268 float Weight;
269 bool IsCSR;
270 CopyHint(Register R, float W, bool IsCSR)
271 : Reg(R), Weight(W), IsCSR(IsCSR) {}
272 bool operator<(const CopyHint &Rhs) const {
273 // Always prefer any physreg hint.
274 if (Reg.isPhysical() != Rhs.Reg.isPhysical())
275 return Reg.isPhysical();
276 if (Weight != Rhs.Weight)
277 return (Weight > Rhs.Weight);
278 // Prefer non-CSR to CSR.
279 if (Reg.isPhysical() && IsCSR != Rhs.IsCSR)
280 return !IsCSR;
281 return Reg.id() < Rhs.Reg.id(); // Tie-breaker.
282 }
283 };
284
285 bool IsExiting = false;
288 I = MRI.reg_instr_nodbg_begin(LI.reg()),
289 E = MRI.reg_instr_nodbg_end();
290 I != E;) {
291 MachineInstr *MI = &*(I++);
292
293 NumInstr++;
294 bool identityCopy = false;
295 auto DestSrc = TII.isCopyInstr(*MI);
296 if (DestSrc) {
297 const MachineOperand *DestRegOp = DestSrc->Destination;
298 const MachineOperand *SrcRegOp = DestSrc->Source;
299 identityCopy = DestRegOp->getReg() == SrcRegOp->getReg() &&
300 DestRegOp->getSubReg() == SrcRegOp->getSubReg();
301 }
302
303 if (identityCopy || MI->isImplicitDef())
304 continue;
305 if (!Visited.insert(MI).second)
306 continue;
307
308 // For terminators that produce values, ask the backend if the register is
309 // not spillable.
310 if (TII.isUnspillableTerminator(MI) &&
311 MI->definesRegister(LI.reg(), /*TRI=*/nullptr)) {
312 LI.markNotSpillable();
313 return -1.0f;
314 }
315
316 // Force Weight onto the stack so that x86 doesn't add hidden precision.
317 stack_float_t Weight = 1.0f;
318 if (IsSpillable) {
319 // Get loop info for mi.
320 if (MI->getParent() != MBB) {
321 MBB = MI->getParent();
322 const MachineLoop *Loop = Loops.getLoopFor(MBB);
323 IsExiting = Loop ? Loop->isLoopExiting(MBB) : false;
324 }
325
326 // Calculate instr weight.
327 bool Reads, Writes;
328 std::tie(Reads, Writes) = MI->readsWritesVirtualRegister(LI.reg());
329 Weight = LiveIntervals::getSpillWeight(Writes, Reads, &MBFI, *MI,
330 getCachedOptimizeForSize());
331
332 // Give extra weight to what looks like a loop induction variable update.
333 if (Writes && IsExiting && LIS.isLiveOutOfMBB(LI, MBB))
334 Weight *= 3;
335
336 TotalWeight += Weight;
337 }
338
339 // Get allocation hints from copies.
340 if (!TII.isCopyInstr(*MI))
341 continue;
342 Register HintReg = copyHint(MI, LI.reg(), TRI, MRI);
343 if (HintReg && (HintReg.isVirtual() || MRI.isAllocatable(HintReg)))
344 Hint[HintReg] += Weight;
345 }
346
347 // Pass all the sorted copy hints to mri.
348 if (Hint.size()) {
349 // Remove a generic hint if previously added by target.
350 if (TargetHint.first == 0 && TargetHint.second)
351 MRI.clearSimpleHint(LI.reg());
352
353 // Don't add the target-type hint again.
354 Register SkipReg = TargetHint.first != 0 ? TargetHint.second : Register();
356 for (const auto &[Reg, Weight] : Hint) {
357 if (Reg != SkipReg)
358 RegHints.emplace_back(
359 Reg, Weight,
360 Reg.isPhysical() ? TRI.isCalleeSavedPhysReg(Reg, MF) : false);
361 }
362 sort(RegHints);
363 for (const auto &[Reg, _, __] : RegHints)
364 MRI.addRegAllocationHint(LI.reg(), Reg);
365
366 // Weakly boost the spill weight of hinted registers.
367 TotalWeight *= 1.01F;
368 }
369
370 // If the live interval was already unspillable, leave it that way.
371 if (!IsSpillable)
372 return -1.0;
373
374 // Mark li as unspillable if all live ranges are tiny and the interval
375 // is not live at any reg mask. If the interval is live at a reg mask
376 // spilling may be required. If li is live as use in statepoint instruction
377 // spilling may be required due to if we mark interval with use in statepoint
378 // as not spillable we are risky to end up with no register to allocate.
379 // At the same time STATEPOINT instruction is perfectly fine to have this
380 // operand on stack, so spilling such interval and folding its load from stack
381 // into instruction itself makes perfect sense.
382 if (LI.isZeroLength(LIS.getSlotIndexes()) &&
383 !LI.isLiveAtIndexes(LIS.getRegMaskSlots()) &&
384 !isLiveAtStatepointVarArg(LI) && !canMemFoldInlineAsm(LI, MRI)) {
385 LI.markNotSpillable();
386 return -1.0;
387 }
388
389 // If all of the definitions of the interval are re-materializable,
390 // it is a preferred candidate for spilling.
391 // FIXME: this gets much more complicated once we support non-trivial
392 // re-materialization.
393 if (isRematerializable(LI, LIS, VRM, MRI, *MF.getSubtarget().getInstrInfo()))
394 TotalWeight *= 0.5F;
395
396 // Finally, we scale the weight by the scale factor of register class.
397 const TargetRegisterClass *RC = MRI.getRegClass(LI.reg());
398 TotalWeight *= TRI.getSpillWeightScaleFactor(RC);
399
400 return normalize(TotalWeight, LI.getSize(), NumInstr);
401}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock & MBB
static bool canMemFoldInlineAsm(LiveInterval &LI, const MachineRegisterInfo &MRI)
const HexagonInstrInfo * TII
#define _
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition MD5.cpp:57
Register Reg
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
This file defines the SmallPtrSet class.
#define LLVM_DEBUG(...)
Definition Debug.h:119
A live range for subregisters.
LiveInterval - This class represents the liveness of a register, or stack slot.
void markNotSpillable()
markNotSpillable - Mark interval as not spillable
Register reg() const
bool isSpillable() const
isSpillable - Can this interval be spilled?
bool hasSubRanges() const
Returns true if subregister liveness information is available.
LLVM_ABI unsigned getSize() const
getSize - Returns the sum of sizes of all the LiveRange's.
iterator_range< subrange_iterator > subranges()
void setWeight(float Value)
static LLVM_ABI float getSpillWeight(bool isDef, bool isUse, const MachineBlockFrequencyInfo *MBFI, const MachineInstr &MI, ProfileSummaryInfo *PSI=nullptr)
Calculate the spill weight to assign to a single instruction.
Result of a LiveRange query.
VNInfo * valueIn() const
Return the value that is live-in to the instruction.
LLVM_ABI bool isLiveAtIndexes(ArrayRef< SlotIndex > Slots) const
vni_iterator vni_begin()
bool isZeroLength(SlotIndexes *Indexes) const
Returns true if the live range is zero length, i.e.
LiveQueryResult Query(SlotIndex Idx) const
Query Liveness at Idx.
vni_iterator vni_end()
VNInfoList::const_iterator const_vni_iterator
VNInfo * getVNInfoAt(SlotIndex Idx) const
getVNInfoAt - Return the VNInfo that is live at Idx, or NULL.
bool isLoopExiting(const BlockT *BB) const
True if terminator in the block can branch to another block that is outside of the current loop.
Represents a single loop in the control flow graph.
Definition LoopInfo.h:40
bool contains(MCRegister Reg) const
contains - Return true if the specified register is included in this register class.
MCRegister getSubReg(MCRegister Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo.
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:41
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
unsigned getSubReg() const
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
iterator_range< reg_iterator > reg_operands(Register Reg) const
static reg_instr_nodbg_iterator reg_instr_nodbg_end()
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
defusechain_instr_iterator< true, true, true, true > reg_instr_nodbg_iterator
reg_instr_nodbg_iterator/reg_instr_nodbg_begin/reg_instr_nodbg_end - Walk all defs and uses of the sp...
bool reg_nodbg_empty(Register RegNo) const
reg_nodbg_empty - Return true if the only instructions using or defining Reg are Debug instructions.
bool isAllocatable(MCRegister PhysReg) const
isAllocatable - Returns true when PhysReg belongs to an allocatable register class and it hasn't been...
std::pair< unsigned, Register > getRegAllocationHint(Register VReg) const
getRegAllocationHint - Return the register allocation hint for the specified virtual register.
const TargetRegisterInfo * getTargetRegisterInfo() const
LLVM_ABI LaneBitmask getMaxLaneMaskForVReg(Register Reg) const
Returns a mask covering all bits that can appear in lane masks of subregisters of the virtual registe...
void addRegAllocationHint(Register VReg, Register PrefReg)
addRegAllocationHint - Add a register allocation hint to the hints vector for VReg.
LLVM_ABI bool isConstantPhysReg(MCRegister PhysReg) const
Returns true if PhysReg is unallocatable and constant throughout the function.
iterator_range< reg_nodbg_iterator > reg_nodbg_operands(Register Reg) const
void clearSimpleHint(Register VReg)
reg_instr_nodbg_iterator reg_instr_nodbg_begin(Register RegNo) const
unsigned getNumVirtRegs() const
getNumVirtRegs - Return the number of virtual registers created.
Wrapper class representing virtual and physical registers.
Definition Register.h:20
static Register index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
Definition Register.h:72
MCRegister asMCReg() const
Utility to check-convert this value to a MCRegister.
Definition Register.h:107
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
Definition Register.h:79
SlotIndex - An opaque wrapper around machine indexes.
Definition SlotIndexes.h:66
static bool isSameInstr(SlotIndex A, SlotIndex B)
isSameInstr - Return true if A and B refer to the same instruction.
SlotIndex getRegSlot(bool EC=false) const
Returns the register use/def slot in the current instruction for a normal or early-clobber def.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
reference emplace_back(ArgTypes &&... Args)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
TargetInstrInfo - Interface to description of machine instruction set.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
VNInfo - Value Number Information.
bool isUnused() const
Returns true if this value is unused.
unsigned id
The ID number of this value.
SlotIndex def
The index of the defining instruction.
bool isPHIDef() const
Returns true if this value is defined by a PHI instruction (or was, PHI instructions may have been el...
LLVM_ABI float weightCalcHelper(LiveInterval &LI)
Helper function for weight calculations.
static LLVM_ABI bool allUsesAvailableAt(const MachineInstr *MI, SlotIndex UseIdx, const LiveIntervals &LIS, const MachineRegisterInfo &MRI, const TargetInstrInfo &TII)
LLVM_ABI void calculateSpillWeightsAndHints()
Compute spill weights and allocation hints for all virtual register live intervals.
static LLVM_ABI bool isRematerializable(const LiveInterval &LI, const LiveIntervals &LIS, const VirtRegMap &VRM, const MachineRegisterInfo &MRI, const TargetInstrInfo &TII)
Determine if all values in LI are rematerializable.
virtual float normalize(float UseDefFreq, unsigned Size, unsigned NumInstr)
Weight normalization function.
static LLVM_ABI Register copyHint(const MachineInstr *MI, Register Reg, const TargetRegisterInfo &TRI, const MachineRegisterInfo &MRI)
Return the preferred allocation register for reg, given a COPY instruction.
LLVM_ABI void calculateSpillWeightAndHint(LiveInterval &LI)
(re)compute li's spill weight and allocation hint.
MachineRegisterInfo & getRegInfo() const
Definition VirtRegMap.h:80
This is an optimization pass for GlobalISel generic memory operations.
bool operator<(int64_t V1, const APSInt &V2)
Definition APSInt.h:360
LLVM_ABI bool shouldOptimizeForSize(const MachineFunction *MF, ProfileSummaryInfo *PSI, const MachineBlockFrequencyInfo *BFI, PGSOQueryType QueryType=PGSOQueryType::Other)
Returns true if machine function MF is suggested to be size-optimized based on the profile.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1746
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1636
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
@ Sub
Subtraction of integers.
float stack_float_t
Type to force float point values onto the stack, so that x86 doesn't add hidden precision,...
Definition MathExtras.h:816
MCRegisterClass TargetRegisterClass
Definition FastISel.h:58
constexpr bool none() const
Definition LaneBitmask.h:52