31#define DEBUG_TYPE "calcspillweights"
34 LLVM_DEBUG(
dbgs() <<
"********** Compute Spill Weights **********\n"
35 <<
"********** Function: " << MF.getName() <<
'\n');
38 for (
unsigned I = 0, E =
MRI.getNumVirtRegs();
I != E; ++
I) {
40 if (
MRI.reg_nodbg_empty(Reg))
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();
57 Sub =
MI->getOperand(1).getSubReg();
58 HReg =
MI->getOperand(0).getReg();
59 HSub =
MI->getOperand(0).getSubReg();
75 return TRI.getMatchingSuperReg(CopiedPReg,
Sub, RC);
86 Register Original = VRM.getOriginal(Reg);
96 assert(
MI &&
"Dead valno in interval");
101 while (
TII.isFullCopyInstr(*
MI)) {
103 if (
MI->getOperand(0).getReg() != Reg)
107 Reg =
MI->getOperand(1).getReg();
111 if (!Reg.isVirtual() || VRM.getOriginal(Reg) != Original)
118 assert(VNI &&
"Copy from non-existing value");
121 MI = LIS.getInstructionFromIndex(VNI->
def);
122 assert(
MI &&
"Dead valno in interval");
125 if (!
TII.isTriviallyReMaterializable(*
MI))
131bool VirtRegAuxInfo::isLiveAtStatepointVarArg(
LiveInterval &LI) {
134 MachineInstr *MI = MO.getParent();
135 if (MI->getOpcode() != TargetOpcode::STATEPOINT)
137 return StatepointOpers(MI).getVarIdx() <= MO.getOperandNo();
153 if (
MI->isInlineAsm() &&
MI->mayFoldInlineAsmRegOp(
MI->getOperandNo(&MO)))
166 float TotalWeight = 0;
167 unsigned NumInstr = 0;
170 std::pair<unsigned, Register> TargetHint =
MRI.getRegAllocationHint(LI.
reg());
174 Register Original = VRM.getOriginal(Reg);
175 const LiveInterval &OrigInt = LIS.getInterval(Original);
186 bool IsLocalSplitArtifact = Start && End;
189 bool ShouldUpdateLI = !IsLocalSplitArtifact;
191 if (IsLocalSplitArtifact) {
193 assert(LocalMBB == LIS.getMBBFromIndex(*Start) &&
194 "start and end are expected to be in the same basic block");
214 CopyHint(
Register R,
float W,
bool IsCSR)
215 :
Reg(R), Weight(W), IsCSR(IsCSR) {}
216 bool operator<(
const CopyHint &Rhs)
const {
218 if (Reg.isPhysical() != Rhs.Reg.isPhysical())
219 return Reg.isPhysical();
220 if (Weight != Rhs.Weight)
221 return (Weight > Rhs.Weight);
223 if (Reg.isPhysical() && IsCSR != Rhs.IsCSR)
225 return Reg.id() < Rhs.Reg.id();
229 bool IsExiting =
false;
232 I =
MRI.reg_instr_nodbg_begin(LI.
reg()),
233 E =
MRI.reg_instr_nodbg_end();
240 if (IsLocalSplitArtifact && ((
SI < *Start) || (
SI > *End)))
244 bool identityCopy =
false;
245 auto DestSrc =
TII.isCopyInstr(*
MI);
249 identityCopy = DestRegOp->
getReg() == SrcRegOp->
getReg() &&
253 if (identityCopy ||
MI->isImplicitDef())
260 if (
TII.isUnspillableTerminator(
MI) &&
261 MI->definesRegister(LI.
reg(),
nullptr)) {
270 if (
MI->getParent() !=
MBB) {
271 MBB =
MI->getParent();
278 std::tie(Reads, Writes) =
MI->readsWritesVirtualRegister(LI.
reg());
282 if (Writes && IsExiting && LIS.isLiveOutOfMBB(LI,
MBB))
285 TotalWeight += Weight;
289 if (!
TII.isCopyInstr(*
MI))
292 if (HintReg && (HintReg.
isVirtual() ||
MRI.isAllocatable(HintReg)))
293 Hint[HintReg] += Weight;
297 if (ShouldUpdateLI && Hint.
size()) {
299 if (TargetHint.first == 0 && TargetHint.second)
300 MRI.clearSimpleHint(LI.
reg());
305 for (
const auto &[Reg, Weight] : Hint) {
309 Reg.isPhysical() ?
TRI.isCalleeSavedPhysReg(Reg, MF) :
false);
312 for (
const auto &[Reg,
_, __] : RegHints)
313 MRI.addRegAllocationHint(LI.
reg(), Reg);
316 TotalWeight *= 1.01F;
331 if (ShouldUpdateLI && LI.
isZeroLength(LIS.getSlotIndexes()) &&
347 TotalWeight *=
TRI.getSpillWeightScaleFactor(RC);
349 if (IsLocalSplitArtifact)
350 return normalize(TotalWeight, Start->distance(*End), NumInstr);
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool canMemFoldInlineAsm(LiveInterval &LI, const MachineRegisterInfo &MRI)
const HexagonInstrInfo * TII
Register const TargetRegisterInfo * TRI
Promote Memory to Register
This file defines the SmallPtrSet class.
LiveInterval - This class represents the liveness of a register, or stack slot.
void markNotSpillable()
markNotSpillable - Mark interval as not spillable
bool isSpillable() const
isSpillable - Can this interval be spilled?
LLVM_ABI unsigned getSize() const
getSize - Returns the sum of sizes of all the LiveRange's.
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
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.
VNInfoList::const_iterator const_vni_iterator
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.
Wrapper class representing physical registers. Should be passed by value.
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.
static Register index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
MCRegister asMCReg() const
Utility to check-convert this value to a MCRegister.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
SlotIndex - An opaque wrapper around machine indexes.
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.
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...
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.
virtual float normalize(float UseDefFreq, unsigned Size, unsigned NumInstr)
Weight normalization function.
static bool isRematerializable(const LiveInterval &LI, const LiveIntervals &LIS, const VirtRegMap &VRM, const TargetInstrInfo &TII)
Determine if all values in LI are rematerializable.
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
This is an optimization pass for GlobalISel generic memory operations.
bool operator<(int64_t V1, const APSInt &V2)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
@ 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,...