30#define DEBUG_TYPE "calcspillweights"
33 LLVM_DEBUG(
dbgs() <<
"********** Compute Spill Weights **********\n"
34 <<
"********** Function: " << MF.
getName() <<
'\n');
37 for (
unsigned I = 0,
E =
MRI.getNumVirtRegs();
I !=
E; ++
I) {
39 if (
MRI.reg_nodbg_empty(Reg))
51 if (
MI->getOperand(0).getReg() == Reg) {
52 Sub =
MI->getOperand(0).getSubReg();
53 HReg =
MI->getOperand(1).getReg();
54 HSub =
MI->getOperand(1).getSubReg();
56 Sub =
MI->getOperand(1).getSubReg();
57 HReg =
MI->getOperand(0).getReg();
58 HSub =
MI->getOperand(0).getSubReg();
65 return Sub == HSub ? HReg :
Register();
74 return TRI.getMatchingSuperReg(CopiedPReg, Sub, RC);
95 assert(
MI &&
"Dead valno in interval");
100 while (
MI->isFullCopy()) {
102 if (
MI->getOperand(0).getReg() != Reg)
106 Reg =
MI->getOperand(1).getReg();
110 if (!Reg.isVirtual() || VRM.
getOriginal(Reg) != Original)
117 assert(VNI &&
"Copy from non-existing value");
121 assert(
MI &&
"Dead valno in interval");
124 if (!
TII.isTriviallyReMaterializable(*
MI))
130bool VirtRegAuxInfo::isLiveAtStatepointVarArg(
LiveInterval &LI) {
133 MachineInstr *MI = MO.getParent();
134 if (MI->getOpcode() != TargetOpcode::STATEPOINT)
136 return StatepointOpers(MI).getVarIdx() <= MO.getOperandNo();
155 bool IsExiting =
false;
156 float TotalWeight = 0;
157 unsigned NumInstr = 0;
160 std::pair<unsigned, Register> TargetHint =
MRI.getRegAllocationHint(LI.
reg());
176 bool IsLocalSplitArtifact = Start && End;
179 bool ShouldUpdateLI = !IsLocalSplitArtifact;
181 if (IsLocalSplitArtifact) {
184 "start and end are expected to be in the same basic block");
201 CopyHint(
Register R,
float W) :
Reg(R), Weight(W) {}
202 bool operator<(
const CopyHint &Rhs)
const {
204 if (
Reg.isPhysical() != Rhs.Reg.isPhysical())
205 return Reg.isPhysical();
206 if (Weight != Rhs.Weight)
207 return (Weight > Rhs.Weight);
208 return Reg.id() < Rhs.Reg.id();
212 std::set<CopyHint> CopyHints;
215 I =
MRI.reg_instr_nodbg_begin(LI.
reg()),
216 E =
MRI.reg_instr_nodbg_end();
223 if (IsLocalSplitArtifact && ((
SI < *Start) || (
SI > *End)))
227 if (
MI->isIdentityCopy() ||
MI->isImplicitDef())
234 if (
TII.isUnspillableTerminator(
MI) &&
MI->definesRegister(LI.
reg())) {
242 if (
MI->getParent() !=
MBB) {
243 MBB =
MI->getParent();
250 std::tie(Reads, Writes) =
MI->readsWritesVirtualRegister(LI.
reg());
257 TotalWeight += Weight;
270 volatile float HWeight = Hint[HintReg] += Weight;
272 CopyHints.
insert(CopyHint(HintReg, HWeight));
276 if (ShouldUpdateLI && CopyHints.size()) {
278 if (TargetHint.first == 0 && TargetHint.second)
279 MRI.clearSimpleHint(LI.
reg());
282 for (
const auto &Hint : CopyHints) {
283 if (!HintedRegs.
insert(Hint.Reg).second ||
284 (TargetHint.first != 0 && Hint.Reg == TargetHint.second))
287 MRI.addRegAllocationHint(LI.
reg(), Hint.Reg);
291 TotalWeight *= 1.01F;
308 !isLiveAtStatepointVarArg(LI)) {
320 if (IsLocalSplitArtifact)
321 return normalize(TotalWeight, Start->distance(*End), NumInstr);
unsigned const MachineRegisterInfo * MRI
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const HexagonInstrInfo * TII
unsigned const TargetRegisterInfo * TRI
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallPtrSet class.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
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?
unsigned getSize() const
getSize - Returns the sum of sizes of all the LiveRange's.
void setWeight(float Value)
MachineInstr * getInstructionFromIndex(SlotIndex index) const
Returns the instruction associated with the given index.
SlotIndexes * getSlotIndexes() const
SlotIndex getInstructionIndex(const MachineInstr &Instr) const
Returns the base index of the given instruction.
ArrayRef< SlotIndex > getRegMaskSlots() const
Returns a sorted array of slot indices of all instructions with register mask operands.
LiveInterval & getInterval(Register Reg)
static float getSpillWeight(bool isDef, bool isUse, const MachineBlockFrequencyInfo *MBFI, const MachineInstr &MI)
Calculate the spill weight to assign to a single instruction.
bool isLiveOutOfMBB(const LiveRange &LR, const MachineBasicBlock *mbb) const
MachineBasicBlock * getMBBFromIndex(SlotIndex index) const
Result of a LiveRange query.
VNInfo * valueIn() const
Return the value that is live-in to the instruction.
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.
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.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Representation of each machine instruction.
MachineLoop * getLoopFor(const MachineBasicBlock *BB) const
Return the innermost loop that BB lives in.
MachineOperand class - Representation of each machine instruction operand.
defusechain_iterator - This class provides iterator support for machine operands in the function that...
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
iterator_range< reg_iterator > reg_operands(Register Reg) const
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.
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.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
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...
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
virtual const TargetInstrInfo * getInstrInfo() const
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...
static Register copyHint(const MachineInstr *MI, unsigned Reg, const TargetRegisterInfo &TRI, const MachineRegisterInfo &MRI)
Return the preferred allocation register for reg, given a COPY instruction.
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.
void calculateSpillWeightAndHint(LiveInterval &LI)
(re)compute li's spill weight and allocation hint.
Register getOriginal(Register VirtReg) const
getOriginal - Return the original virtual register that VirtReg descends from through splitting.
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.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.