LLVM 22.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
23#include "llvm/Support/Debug.h"
26#include <cassert>
27#include <tuple>
28
29using namespace llvm;
30
31#define DEBUG_TYPE "calcspillweights"
32
34 LLVM_DEBUG(dbgs() << "********** Compute Spill Weights **********\n"
35 << "********** Function: " << MF.getName() << '\n');
36
37 MachineRegisterInfo &MRI = MF.getRegInfo();
38 for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
40 if (MRI.reg_nodbg_empty(Reg))
41 continue;
42 calculateSpillWeightAndHint(LIS.getInterval(Reg));
43 }
44}
45
46// Return the preferred allocation register for reg, given a COPY instruction.
49 const MachineRegisterInfo &MRI) {
50 unsigned Sub, HSub;
51 Register HReg;
52 if (MI->getOperand(0).getReg() == Reg) {
53 Sub = MI->getOperand(0).getSubReg();
54 HReg = MI->getOperand(1).getReg();
55 HSub = MI->getOperand(1).getSubReg();
56 } else {
57 Sub = MI->getOperand(1).getSubReg();
58 HReg = MI->getOperand(0).getReg();
59 HSub = MI->getOperand(0).getSubReg();
60 }
61
62 if (!HReg)
63 return 0;
64
65 if (HReg.isVirtual())
66 return Sub == HSub ? HReg : Register();
67
68 const TargetRegisterClass *RC = MRI.getRegClass(Reg);
69 MCRegister CopiedPReg = HSub ? TRI.getSubReg(HReg, HSub) : HReg.asMCReg();
70 if (RC->contains(CopiedPReg))
71 return CopiedPReg;
72
73 // Check if reg:sub matches so that a super register could be hinted.
74 if (Sub)
75 return TRI.getMatchingSuperReg(CopiedPReg, Sub, RC);
76
77 return Register();
78}
79
80// Check if all values in LI are rematerializable
82 const LiveIntervals &LIS,
83 const VirtRegMap &VRM,
85 const TargetInstrInfo &TII) {
86 Register Reg = LI.reg();
87 Register Original = VRM.getOriginal(Reg);
90 I != E; ++I) {
91 const VNInfo *VNI = *I;
92 const VNInfo *OrigVNI = VNI;
93 if (VNI->isUnused())
94 continue;
95 if (VNI->isPHIDef())
96 return false;
97
98 MachineInstr *MI = LIS.getInstructionFromIndex(VNI->def);
99 assert(MI && "Dead valno in interval");
100
101 // Trace copies introduced by live range splitting. The inline
102 // spiller can rematerialize through these copies, so the spill
103 // weight must reflect this.
104 while (TII.isFullCopyInstr(*MI)) {
105 // The copy destination must match the interval register.
106 if (MI->getOperand(0).getReg() != Reg)
107 return false;
108
109 // Get the source register.
110 Reg = MI->getOperand(1).getReg();
111
112 // If the original (pre-splitting) registers match this
113 // copy came from a split.
114 if (!Reg.isVirtual() || VRM.getOriginal(Reg) != Original)
115 return false;
116
117 // Follow the copy live-in value.
118 const LiveInterval &SrcLI = LIS.getInterval(Reg);
119 LiveQueryResult SrcQ = SrcLI.Query(VNI->def);
120 VNI = SrcQ.valueIn();
121 assert(VNI && "Copy from non-existing value");
122 if (VNI->isPHIDef())
123 return false;
124 MI = LIS.getInstructionFromIndex(VNI->def);
125 assert(MI && "Dead valno in interval");
126 }
127
128 if (!TII.isReMaterializable(*MI))
129 return false;
130
131 VNIDefs[OrigVNI->id] = MI;
132 }
133
134 // If MI has register uses, it will only be rematerializable if its uses are
135 // also live at the indices it will be rematerialized at.
136 for (MachineOperand &MO : MRI.reg_nodbg_operands(LI.reg())) {
137 if (!MO.readsReg())
138 continue;
139 SlotIndex UseIdx = LIS.getInstructionIndex(*MO.getParent());
140 MachineInstr *Def = VNIDefs[LI.getVNInfoAt(UseIdx)->id];
141 assert(Def && "Use with no def");
142 if (!allUsesAvailableAt(Def, UseIdx, LIS, MRI, TII))
143 return false;
144 }
145
146 return true;
147}
148
150 SlotIndex UseIdx,
151 const LiveIntervals &LIS,
153 const TargetInstrInfo &TII) {
154 SlotIndex OrigIdx = LIS.getInstructionIndex(*MI).getRegSlot(true);
155 UseIdx = std::max(UseIdx, UseIdx.getRegSlot(true));
156 for (const MachineOperand &MO : MI->operands()) {
157 if (!MO.isReg() || !MO.getReg() || !MO.readsReg())
158 continue;
159
160 // We can't remat physreg uses, unless it is a constant or target wants
161 // to ignore this use.
162 if (MO.getReg().isPhysical()) {
163 if (MRI.isConstantPhysReg(MO.getReg()) || TII.isIgnorableUse(MO))
164 continue;
165 return false;
166 }
167
168 const LiveInterval &li = LIS.getInterval(MO.getReg());
169 const VNInfo *OVNI = li.getVNInfoAt(OrigIdx);
170 if (!OVNI)
171 continue;
172
173 // Don't allow rematerialization immediately after the original def.
174 // It would be incorrect if OrigMI redefines the register.
175 // See PR14098.
176 if (SlotIndex::isSameInstr(OrigIdx, UseIdx))
177 return false;
178
179 if (OVNI != li.getVNInfoAt(UseIdx))
180 return false;
181
182 // Check that subrange is live at UseIdx.
183 if (li.hasSubRanges()) {
184 const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo();
185 unsigned SubReg = MO.getSubReg();
186 LaneBitmask LM = SubReg ? TRI->getSubRegIndexLaneMask(SubReg)
187 : MRI.getMaxLaneMaskForVReg(MO.getReg());
188 for (const LiveInterval::SubRange &SR : li.subranges()) {
189 if ((SR.LaneMask & LM).none())
190 continue;
191 if (!SR.liveAt(UseIdx))
192 return false;
193 // Early exit if all used lanes are checked. No need to continue.
194 LM &= ~SR.LaneMask;
195 if (LM.none())
196 break;
197 }
198 }
199 }
200 return true;
201}
202
203bool VirtRegAuxInfo::isLiveAtStatepointVarArg(LiveInterval &LI) {
204 return any_of(VRM.getRegInfo().reg_operands(LI.reg()),
205 [](MachineOperand &MO) {
206 MachineInstr *MI = MO.getParent();
207 if (MI->getOpcode() != TargetOpcode::STATEPOINT)
208 return false;
209 return StatepointOpers(MI).getVarIdx() <= MO.getOperandNo();
210 });
211}
212
214 float Weight = weightCalcHelper(LI);
215 // Check if unspillable.
216 if (Weight < 0)
217 return;
218 LI.setWeight(Weight);
219}
220
222 const MachineRegisterInfo &MRI) {
223 for (const MachineOperand &MO : MRI.reg_operands(LI.reg())) {
224 const MachineInstr *MI = MO.getParent();
225 if (MI->isInlineAsm() && MI->mayFoldInlineAsmRegOp(MI->getOperandNo(&MO)))
226 return true;
227 }
228
229 return false;
230}
231
233 SlotIndex *End) {
234 MachineRegisterInfo &MRI = MF.getRegInfo();
235 const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
236 const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
237 MachineBasicBlock *MBB = nullptr;
238 float TotalWeight = 0;
239 unsigned NumInstr = 0; // Number of instructions using LI
241
242 std::pair<unsigned, Register> TargetHint = MRI.getRegAllocationHint(LI.reg());
243
244 if (LI.isSpillable()) {
245 Register Reg = LI.reg();
246 Register Original = VRM.getOriginal(Reg);
247 const LiveInterval &OrigInt = LIS.getInterval(Original);
248 // li comes from a split of OrigInt. If OrigInt was marked
249 // as not spillable, make sure the new interval is marked
250 // as not spillable as well.
251 if (!OrigInt.isSpillable())
252 LI.markNotSpillable();
253 }
254
255 // Don't recompute spill weight for an unspillable register.
256 bool IsSpillable = LI.isSpillable();
257
258 bool IsLocalSplitArtifact = Start && End;
259
260 // Do not update future local split artifacts.
261 bool ShouldUpdateLI = !IsLocalSplitArtifact;
262
263 if (IsLocalSplitArtifact) {
264 MachineBasicBlock *LocalMBB = LIS.getMBBFromIndex(*End);
265 assert(LocalMBB == LIS.getMBBFromIndex(*Start) &&
266 "start and end are expected to be in the same basic block");
267
268 // Local split artifact will have 2 additional copy instructions and they
269 // will be in the same BB.
270 // localLI = COPY other
271 // ...
272 // other = COPY localLI
273 TotalWeight +=
274 LiveIntervals::getSpillWeight(true, false, &MBFI, LocalMBB, PSI);
275 TotalWeight +=
276 LiveIntervals::getSpillWeight(false, true, &MBFI, LocalMBB, PSI);
277
278 NumInstr += 2;
279 }
280
281 // CopyHint is a sortable hint derived from a COPY instruction.
282 struct CopyHint {
283 Register Reg;
284 float Weight;
285 bool IsCSR;
286 CopyHint(Register R, float W, bool IsCSR)
287 : Reg(R), Weight(W), IsCSR(IsCSR) {}
288 bool operator<(const CopyHint &Rhs) const {
289 // Always prefer any physreg hint.
290 if (Reg.isPhysical() != Rhs.Reg.isPhysical())
291 return Reg.isPhysical();
292 if (Weight != Rhs.Weight)
293 return (Weight > Rhs.Weight);
294 // Prefer non-CSR to CSR.
295 if (Reg.isPhysical() && IsCSR != Rhs.IsCSR)
296 return !IsCSR;
297 return Reg.id() < Rhs.Reg.id(); // Tie-breaker.
298 }
299 };
300
301 bool IsExiting = false;
304 I = MRI.reg_instr_nodbg_begin(LI.reg()),
305 E = MRI.reg_instr_nodbg_end();
306 I != E;) {
307 MachineInstr *MI = &*(I++);
308
309 // For local split artifacts, we are interested only in instructions between
310 // the expected start and end of the range.
311 SlotIndex SI = LIS.getInstructionIndex(*MI);
312 if (IsLocalSplitArtifact && ((SI < *Start) || (SI > *End)))
313 continue;
314
315 NumInstr++;
316 bool identityCopy = false;
317 auto DestSrc = TII.isCopyInstr(*MI);
318 if (DestSrc) {
319 const MachineOperand *DestRegOp = DestSrc->Destination;
320 const MachineOperand *SrcRegOp = DestSrc->Source;
321 identityCopy = DestRegOp->getReg() == SrcRegOp->getReg() &&
322 DestRegOp->getSubReg() == SrcRegOp->getSubReg();
323 }
324
325 if (identityCopy || MI->isImplicitDef())
326 continue;
327 if (!Visited.insert(MI).second)
328 continue;
329
330 // For terminators that produce values, ask the backend if the register is
331 // not spillable.
332 if (TII.isUnspillableTerminator(MI) &&
333 MI->definesRegister(LI.reg(), /*TRI=*/nullptr)) {
334 LI.markNotSpillable();
335 return -1.0f;
336 }
337
338 // Force Weight onto the stack so that x86 doesn't add hidden precision.
339 stack_float_t Weight = 1.0f;
340 if (IsSpillable) {
341 // Get loop info for mi.
342 if (MI->getParent() != MBB) {
343 MBB = MI->getParent();
344 const MachineLoop *Loop = Loops.getLoopFor(MBB);
345 IsExiting = Loop ? Loop->isLoopExiting(MBB) : false;
346 }
347
348 // Calculate instr weight.
349 bool Reads, Writes;
350 std::tie(Reads, Writes) = MI->readsWritesVirtualRegister(LI.reg());
351 Weight = LiveIntervals::getSpillWeight(Writes, Reads, &MBFI, *MI, PSI);
352
353 // Give extra weight to what looks like a loop induction variable update.
354 if (Writes && IsExiting && LIS.isLiveOutOfMBB(LI, MBB))
355 Weight *= 3;
356
357 TotalWeight += Weight;
358 }
359
360 // Get allocation hints from copies.
361 if (!TII.isCopyInstr(*MI))
362 continue;
363 Register HintReg = copyHint(MI, LI.reg(), TRI, MRI);
364 if (HintReg && (HintReg.isVirtual() || MRI.isAllocatable(HintReg)))
365 Hint[HintReg] += Weight;
366 }
367
368 // Pass all the sorted copy hints to mri.
369 if (ShouldUpdateLI && Hint.size()) {
370 // Remove a generic hint if previously added by target.
371 if (TargetHint.first == 0 && TargetHint.second)
372 MRI.clearSimpleHint(LI.reg());
373
374 // Don't add the target-type hint again.
375 Register SkipReg = TargetHint.first != 0 ? TargetHint.second : Register();
377 for (const auto &[Reg, Weight] : Hint) {
378 if (Reg != SkipReg)
379 RegHints.emplace_back(
380 Reg, Weight,
381 Reg.isPhysical() ? TRI.isCalleeSavedPhysReg(Reg, MF) : false);
382 }
383 sort(RegHints);
384 for (const auto &[Reg, _, __] : RegHints)
385 MRI.addRegAllocationHint(LI.reg(), Reg);
386
387 // Weakly boost the spill weight of hinted registers.
388 TotalWeight *= 1.01F;
389 }
390
391 // If the live interval was already unspillable, leave it that way.
392 if (!IsSpillable)
393 return -1.0;
394
395 // Mark li as unspillable if all live ranges are tiny and the interval
396 // is not live at any reg mask. If the interval is live at a reg mask
397 // spilling may be required. If li is live as use in statepoint instruction
398 // spilling may be required due to if we mark interval with use in statepoint
399 // as not spillable we are risky to end up with no register to allocate.
400 // At the same time STATEPOINT instruction is perfectly fine to have this
401 // operand on stack, so spilling such interval and folding its load from stack
402 // into instruction itself makes perfect sense.
403 if (ShouldUpdateLI && LI.isZeroLength(LIS.getSlotIndexes()) &&
404 !LI.isLiveAtIndexes(LIS.getRegMaskSlots()) &&
405 !isLiveAtStatepointVarArg(LI) && !canMemFoldInlineAsm(LI, MRI)) {
406 LI.markNotSpillable();
407 return -1.0;
408 }
409
410 // If all of the definitions of the interval are re-materializable,
411 // it is a preferred candidate for spilling.
412 // FIXME: this gets much more complicated once we support non-trivial
413 // re-materialization.
414 if (isRematerializable(LI, LIS, VRM, MRI, *MF.getSubtarget().getInstrInfo()))
415 TotalWeight *= 0.5F;
416
417 // Finally, we scale the weight by the scale factor of register class.
418 const TargetRegisterClass *RC = MRI.getRegClass(LI.reg());
419 TotalWeight *= TRI.getSpillWeightScaleFactor(RC);
420
421 if (IsLocalSplitArtifact)
422 return normalize(TotalWeight, Start->distance(*End), NumInstr);
423 return normalize(TotalWeight, LI.getSize(), NumInstr);
424}
unsigned SubReg
unsigned const MachineRegisterInfo * MRI
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:58
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:114
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
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:33
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
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...
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:67
MCRegister asMCReg() const
Utility to check-convert this value to a MCRegister.
Definition Register.h:102
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
Definition Register.h:74
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.
bool contains(Register Reg) const
Return true if the specified register is included in this register class.
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...
static bool allUsesAvailableAt(const MachineInstr *MI, SlotIndex UseIdx, const LiveIntervals &LIS, const MachineRegisterInfo &MRI, const TargetInstrInfo &TII)
float weightCalcHelper(LiveInterval &LI, SlotIndex *Start=nullptr, SlotIndex *End=nullptr)
Helper function for weight calculations.
void calculateSpillWeightsAndHints()
Compute spill weights and allocation hints for all virtual register live intervals.
static 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 Register copyHint(const MachineInstr *MI, Register Reg, const TargetRegisterInfo &TRI, const MachineRegisterInfo &MRI)
Return the preferred allocation register for reg, given a COPY instruction.
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:362
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:1712
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1624
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:207
@ 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:797
constexpr bool none() const
Definition LaneBitmask.h:52