xref: /freebsd-src/contrib/llvm-project/llvm/lib/CodeGen/CalcSpillWeights.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- CalcSpillWeights.cpp -----------------------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "llvm/CodeGen/CalcSpillWeights.h"
100b57cec5SDimitry Andric #include "llvm/ADT/SmallPtrSet.h"
115f757f3fSDimitry Andric #include "llvm/ADT/SmallSet.h"
120b57cec5SDimitry Andric #include "llvm/CodeGen/LiveInterval.h"
130b57cec5SDimitry Andric #include "llvm/CodeGen/LiveIntervals.h"
140b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
150b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
160b57cec5SDimitry Andric #include "llvm/CodeGen/MachineLoopInfo.h"
170b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
180b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
190eae32dcSDimitry Andric #include "llvm/CodeGen/StackMaps.h"
200b57cec5SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h"
210b57cec5SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
220b57cec5SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
230b57cec5SDimitry Andric #include "llvm/CodeGen/VirtRegMap.h"
240b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
251a4b8325SDimitry Andric #include "llvm/Support/MathExtras.h"
260b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
270b57cec5SDimitry Andric #include <cassert>
280b57cec5SDimitry Andric #include <tuple>
290b57cec5SDimitry Andric 
300b57cec5SDimitry Andric using namespace llvm;
310b57cec5SDimitry Andric 
320b57cec5SDimitry Andric #define DEBUG_TYPE "calcspillweights"
330b57cec5SDimitry Andric 
34e8d8bef9SDimitry Andric void VirtRegAuxInfo::calculateSpillWeightsAndHints() {
350b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "********** Compute Spill Weights **********\n"
360b57cec5SDimitry Andric                     << "********** Function: " << MF.getName() << '\n');
370b57cec5SDimitry Andric 
380b57cec5SDimitry Andric   MachineRegisterInfo &MRI = MF.getRegInfo();
39e8d8bef9SDimitry Andric   for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
400eae32dcSDimitry Andric     Register Reg = Register::index2VirtReg(I);
410b57cec5SDimitry Andric     if (MRI.reg_nodbg_empty(Reg))
420b57cec5SDimitry Andric       continue;
43e8d8bef9SDimitry Andric     calculateSpillWeightAndHint(LIS.getInterval(Reg));
440b57cec5SDimitry Andric   }
450b57cec5SDimitry Andric }
460b57cec5SDimitry Andric 
470b57cec5SDimitry Andric // Return the preferred allocation register for reg, given a COPY instruction.
4804eeddc0SDimitry Andric Register VirtRegAuxInfo::copyHint(const MachineInstr *MI, unsigned Reg,
49e8d8bef9SDimitry Andric                                   const TargetRegisterInfo &TRI,
50e8d8bef9SDimitry Andric                                   const MachineRegisterInfo &MRI) {
51e8d8bef9SDimitry Andric   unsigned Sub, HSub;
52e8d8bef9SDimitry Andric   Register HReg;
53e8d8bef9SDimitry Andric   if (MI->getOperand(0).getReg() == Reg) {
54e8d8bef9SDimitry Andric     Sub = MI->getOperand(0).getSubReg();
55e8d8bef9SDimitry Andric     HReg = MI->getOperand(1).getReg();
56e8d8bef9SDimitry Andric     HSub = MI->getOperand(1).getSubReg();
570b57cec5SDimitry Andric   } else {
58e8d8bef9SDimitry Andric     Sub = MI->getOperand(1).getSubReg();
59e8d8bef9SDimitry Andric     HReg = MI->getOperand(0).getReg();
60e8d8bef9SDimitry Andric     HSub = MI->getOperand(0).getSubReg();
610b57cec5SDimitry Andric   }
620b57cec5SDimitry Andric 
63e8d8bef9SDimitry Andric   if (!HReg)
640b57cec5SDimitry Andric     return 0;
650b57cec5SDimitry Andric 
66bdd1243dSDimitry Andric   if (HReg.isVirtual())
67e8d8bef9SDimitry Andric     return Sub == HSub ? HReg : Register();
680b57cec5SDimitry Andric 
690eae32dcSDimitry Andric   const TargetRegisterClass *RC = MRI.getRegClass(Reg);
70e8d8bef9SDimitry Andric   MCRegister CopiedPReg = HSub ? TRI.getSubReg(HReg, HSub) : HReg.asMCReg();
710eae32dcSDimitry Andric   if (RC->contains(CopiedPReg))
720b57cec5SDimitry Andric     return CopiedPReg;
730b57cec5SDimitry Andric 
740b57cec5SDimitry Andric   // Check if reg:sub matches so that a super register could be hinted.
75e8d8bef9SDimitry Andric   if (Sub)
760eae32dcSDimitry Andric     return TRI.getMatchingSuperReg(CopiedPReg, Sub, RC);
770b57cec5SDimitry Andric 
780b57cec5SDimitry Andric   return 0;
790b57cec5SDimitry Andric }
800b57cec5SDimitry Andric 
810b57cec5SDimitry Andric // Check if all values in LI are rematerializable
8204eeddc0SDimitry Andric bool VirtRegAuxInfo::isRematerializable(const LiveInterval &LI,
8304eeddc0SDimitry Andric                                         const LiveIntervals &LIS,
84e8d8bef9SDimitry Andric                                         const VirtRegMap &VRM,
850b57cec5SDimitry Andric                                         const TargetInstrInfo &TII) {
860eae32dcSDimitry Andric   Register Reg = LI.reg();
870eae32dcSDimitry Andric   Register Original = VRM.getOriginal(Reg);
880b57cec5SDimitry Andric   for (LiveInterval::const_vni_iterator I = LI.vni_begin(), E = LI.vni_end();
890b57cec5SDimitry Andric        I != E; ++I) {
900b57cec5SDimitry Andric     const VNInfo *VNI = *I;
910b57cec5SDimitry Andric     if (VNI->isUnused())
920b57cec5SDimitry Andric       continue;
930b57cec5SDimitry Andric     if (VNI->isPHIDef())
940b57cec5SDimitry Andric       return false;
950b57cec5SDimitry Andric 
960b57cec5SDimitry Andric     MachineInstr *MI = LIS.getInstructionFromIndex(VNI->def);
970b57cec5SDimitry Andric     assert(MI && "Dead valno in interval");
980b57cec5SDimitry Andric 
990b57cec5SDimitry Andric     // Trace copies introduced by live range splitting.  The inline
1000b57cec5SDimitry Andric     // spiller can rematerialize through these copies, so the spill
1010b57cec5SDimitry Andric     // weight must reflect this.
1025f757f3fSDimitry Andric     while (TII.isFullCopyInstr(*MI)) {
1030b57cec5SDimitry Andric       // The copy destination must match the interval register.
1040b57cec5SDimitry Andric       if (MI->getOperand(0).getReg() != Reg)
1050b57cec5SDimitry Andric         return false;
1060b57cec5SDimitry Andric 
1070b57cec5SDimitry Andric       // Get the source register.
1080b57cec5SDimitry Andric       Reg = MI->getOperand(1).getReg();
1090b57cec5SDimitry Andric 
1100b57cec5SDimitry Andric       // If the original (pre-splitting) registers match this
1110b57cec5SDimitry Andric       // copy came from a split.
112bdd1243dSDimitry Andric       if (!Reg.isVirtual() || VRM.getOriginal(Reg) != Original)
1130b57cec5SDimitry Andric         return false;
1140b57cec5SDimitry Andric 
1150b57cec5SDimitry Andric       // Follow the copy live-in value.
1160b57cec5SDimitry Andric       const LiveInterval &SrcLI = LIS.getInterval(Reg);
1170b57cec5SDimitry Andric       LiveQueryResult SrcQ = SrcLI.Query(VNI->def);
1180b57cec5SDimitry Andric       VNI = SrcQ.valueIn();
1190b57cec5SDimitry Andric       assert(VNI && "Copy from non-existing value");
1200b57cec5SDimitry Andric       if (VNI->isPHIDef())
1210b57cec5SDimitry Andric         return false;
1220b57cec5SDimitry Andric       MI = LIS.getInstructionFromIndex(VNI->def);
1230b57cec5SDimitry Andric       assert(MI && "Dead valno in interval");
1240b57cec5SDimitry Andric     }
1250b57cec5SDimitry Andric 
126fcaf7f86SDimitry Andric     if (!TII.isTriviallyReMaterializable(*MI))
1270b57cec5SDimitry Andric       return false;
1280b57cec5SDimitry Andric   }
1290b57cec5SDimitry Andric   return true;
1300b57cec5SDimitry Andric }
1310b57cec5SDimitry Andric 
132fe6060f1SDimitry Andric bool VirtRegAuxInfo::isLiveAtStatepointVarArg(LiveInterval &LI) {
133fe6060f1SDimitry Andric   return any_of(VRM.getRegInfo().reg_operands(LI.reg()),
134fe6060f1SDimitry Andric                 [](MachineOperand &MO) {
135fe6060f1SDimitry Andric     MachineInstr *MI = MO.getParent();
136fe6060f1SDimitry Andric     if (MI->getOpcode() != TargetOpcode::STATEPOINT)
137fe6060f1SDimitry Andric       return false;
13806c3fb27SDimitry Andric     return StatepointOpers(MI).getVarIdx() <= MO.getOperandNo();
139fe6060f1SDimitry Andric   });
140fe6060f1SDimitry Andric }
141fe6060f1SDimitry Andric 
142e8d8bef9SDimitry Andric void VirtRegAuxInfo::calculateSpillWeightAndHint(LiveInterval &LI) {
143e8d8bef9SDimitry Andric   float Weight = weightCalcHelper(LI);
1440b57cec5SDimitry Andric   // Check if unspillable.
145e8d8bef9SDimitry Andric   if (Weight < 0)
1460b57cec5SDimitry Andric     return;
147e8d8bef9SDimitry Andric   LI.setWeight(Weight);
1480b57cec5SDimitry Andric }
1490b57cec5SDimitry Andric 
1505f757f3fSDimitry Andric static bool canMemFoldInlineAsm(LiveInterval &LI,
1515f757f3fSDimitry Andric                                 const MachineRegisterInfo &MRI) {
1525f757f3fSDimitry Andric   for (const MachineOperand &MO : MRI.reg_operands(LI.reg())) {
1535f757f3fSDimitry Andric     const MachineInstr *MI = MO.getParent();
1545f757f3fSDimitry Andric     if (MI->isInlineAsm() && MI->mayFoldInlineAsmRegOp(MI->getOperandNo(&MO)))
1555f757f3fSDimitry Andric       return true;
1565f757f3fSDimitry Andric   }
1575f757f3fSDimitry Andric 
1585f757f3fSDimitry Andric   return false;
1595f757f3fSDimitry Andric }
1605f757f3fSDimitry Andric 
161e8d8bef9SDimitry Andric float VirtRegAuxInfo::weightCalcHelper(LiveInterval &LI, SlotIndex *Start,
162e8d8bef9SDimitry Andric                                        SlotIndex *End) {
163e8d8bef9SDimitry Andric   MachineRegisterInfo &MRI = MF.getRegInfo();
164e8d8bef9SDimitry Andric   const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
165e8d8bef9SDimitry Andric   const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
166e8d8bef9SDimitry Andric   MachineBasicBlock *MBB = nullptr;
167e8d8bef9SDimitry Andric   float TotalWeight = 0;
168e8d8bef9SDimitry Andric   unsigned NumInstr = 0; // Number of instructions using LI
169e8d8bef9SDimitry Andric   SmallPtrSet<MachineInstr *, 8> Visited;
1700b57cec5SDimitry Andric 
17106c3fb27SDimitry Andric   std::pair<unsigned, Register> TargetHint = MRI.getRegAllocationHint(LI.reg());
172e8d8bef9SDimitry Andric 
173e8d8bef9SDimitry Andric   if (LI.isSpillable()) {
174e8d8bef9SDimitry Andric     Register Reg = LI.reg();
175e8d8bef9SDimitry Andric     Register Original = VRM.getOriginal(Reg);
176e8d8bef9SDimitry Andric     const LiveInterval &OrigInt = LIS.getInterval(Original);
177e8d8bef9SDimitry Andric     // li comes from a split of OrigInt. If OrigInt was marked
178e8d8bef9SDimitry Andric     // as not spillable, make sure the new interval is marked
179e8d8bef9SDimitry Andric     // as not spillable as well.
180e8d8bef9SDimitry Andric     if (!OrigInt.isSpillable())
181e8d8bef9SDimitry Andric       LI.markNotSpillable();
182e8d8bef9SDimitry Andric   }
1830b57cec5SDimitry Andric 
1840b57cec5SDimitry Andric   // Don't recompute spill weight for an unspillable register.
185e8d8bef9SDimitry Andric   bool IsSpillable = LI.isSpillable();
1860b57cec5SDimitry Andric 
187e8d8bef9SDimitry Andric   bool IsLocalSplitArtifact = Start && End;
1880b57cec5SDimitry Andric 
1890b57cec5SDimitry Andric   // Do not update future local split artifacts.
190e8d8bef9SDimitry Andric   bool ShouldUpdateLI = !IsLocalSplitArtifact;
1910b57cec5SDimitry Andric 
192e8d8bef9SDimitry Andric   if (IsLocalSplitArtifact) {
1930eae32dcSDimitry Andric     MachineBasicBlock *LocalMBB = LIS.getMBBFromIndex(*End);
1940eae32dcSDimitry Andric     assert(LocalMBB == LIS.getMBBFromIndex(*Start) &&
1950b57cec5SDimitry Andric            "start and end are expected to be in the same basic block");
1960b57cec5SDimitry Andric 
1970b57cec5SDimitry Andric     // Local split artifact will have 2 additional copy instructions and they
1980b57cec5SDimitry Andric     // will be in the same BB.
1990b57cec5SDimitry Andric     // localLI = COPY other
2000b57cec5SDimitry Andric     // ...
2010b57cec5SDimitry Andric     // other   = COPY localLI
2020eae32dcSDimitry Andric     TotalWeight += LiveIntervals::getSpillWeight(true, false, &MBFI, LocalMBB);
2030eae32dcSDimitry Andric     TotalWeight += LiveIntervals::getSpillWeight(false, true, &MBFI, LocalMBB);
2040b57cec5SDimitry Andric 
205e8d8bef9SDimitry Andric     NumInstr += 2;
2060b57cec5SDimitry Andric   }
2070b57cec5SDimitry Andric 
2080b57cec5SDimitry Andric   // CopyHint is a sortable hint derived from a COPY instruction.
2090b57cec5SDimitry Andric   struct CopyHint {
210e8d8bef9SDimitry Andric     const Register Reg;
211e8d8bef9SDimitry Andric     const float Weight;
212e8d8bef9SDimitry Andric     CopyHint(Register R, float W) : Reg(R), Weight(W) {}
213e8d8bef9SDimitry Andric     bool operator<(const CopyHint &Rhs) const {
2140b57cec5SDimitry Andric       // Always prefer any physreg hint.
215e8d8bef9SDimitry Andric       if (Reg.isPhysical() != Rhs.Reg.isPhysical())
216e8d8bef9SDimitry Andric         return Reg.isPhysical();
217e8d8bef9SDimitry Andric       if (Weight != Rhs.Weight)
218e8d8bef9SDimitry Andric         return (Weight > Rhs.Weight);
219e8d8bef9SDimitry Andric       return Reg.id() < Rhs.Reg.id(); // Tie-breaker.
2200b57cec5SDimitry Andric     }
2210b57cec5SDimitry Andric   };
2220b57cec5SDimitry Andric 
2235f757f3fSDimitry Andric   bool IsExiting = false;
224e8d8bef9SDimitry Andric   std::set<CopyHint> CopyHints;
225e8d8bef9SDimitry Andric   DenseMap<unsigned, float> Hint;
2265ffd83dbSDimitry Andric   for (MachineRegisterInfo::reg_instr_nodbg_iterator
227e8d8bef9SDimitry Andric            I = MRI.reg_instr_nodbg_begin(LI.reg()),
228e8d8bef9SDimitry Andric            E = MRI.reg_instr_nodbg_end();
2290b57cec5SDimitry Andric        I != E;) {
230e8d8bef9SDimitry Andric     MachineInstr *MI = &*(I++);
2310b57cec5SDimitry Andric 
2320b57cec5SDimitry Andric     // For local split artifacts, we are interested only in instructions between
2330b57cec5SDimitry Andric     // the expected start and end of the range.
234e8d8bef9SDimitry Andric     SlotIndex SI = LIS.getInstructionIndex(*MI);
235e8d8bef9SDimitry Andric     if (IsLocalSplitArtifact && ((SI < *Start) || (SI > *End)))
2360b57cec5SDimitry Andric       continue;
2370b57cec5SDimitry Andric 
238e8d8bef9SDimitry Andric     NumInstr++;
2395f757f3fSDimitry Andric     bool identityCopy = false;
2405f757f3fSDimitry Andric     auto DestSrc = TII.isCopyInstr(*MI);
2415f757f3fSDimitry Andric     if (DestSrc) {
2425f757f3fSDimitry Andric       const MachineOperand *DestRegOp = DestSrc->Destination;
2435f757f3fSDimitry Andric       const MachineOperand *SrcRegOp = DestSrc->Source;
2445f757f3fSDimitry Andric       identityCopy = DestRegOp->getReg() == SrcRegOp->getReg() &&
2455f757f3fSDimitry Andric                      DestRegOp->getSubReg() == SrcRegOp->getSubReg();
2465f757f3fSDimitry Andric     }
2475f757f3fSDimitry Andric 
2485f757f3fSDimitry Andric     if (identityCopy || MI->isImplicitDef())
2490b57cec5SDimitry Andric       continue;
250e8d8bef9SDimitry Andric     if (!Visited.insert(MI).second)
2510b57cec5SDimitry Andric       continue;
2520b57cec5SDimitry Andric 
253e8d8bef9SDimitry Andric     // For terminators that produce values, ask the backend if the register is
254e8d8bef9SDimitry Andric     // not spillable.
255*0fca6ea1SDimitry Andric     if (TII.isUnspillableTerminator(MI) &&
256*0fca6ea1SDimitry Andric         MI->definesRegister(LI.reg(), /*TRI=*/nullptr)) {
257e8d8bef9SDimitry Andric       LI.markNotSpillable();
258e8d8bef9SDimitry Andric       return -1.0f;
259e8d8bef9SDimitry Andric     }
260e8d8bef9SDimitry Andric 
2611a4b8325SDimitry Andric     // Force Weight onto the stack so that x86 doesn't add hidden precision,
2621a4b8325SDimitry Andric     // similar to HWeight below.
2631a4b8325SDimitry Andric     stack_float_t Weight = 1.0f;
264e8d8bef9SDimitry Andric     if (IsSpillable) {
2650b57cec5SDimitry Andric       // Get loop info for mi.
266e8d8bef9SDimitry Andric       if (MI->getParent() != MBB) {
267e8d8bef9SDimitry Andric         MBB = MI->getParent();
2685f757f3fSDimitry Andric         const MachineLoop *Loop = Loops.getLoopFor(MBB);
269e8d8bef9SDimitry Andric         IsExiting = Loop ? Loop->isLoopExiting(MBB) : false;
2700b57cec5SDimitry Andric       }
2710b57cec5SDimitry Andric 
2720b57cec5SDimitry Andric       // Calculate instr weight.
273e8d8bef9SDimitry Andric       bool Reads, Writes;
274e8d8bef9SDimitry Andric       std::tie(Reads, Writes) = MI->readsWritesVirtualRegister(LI.reg());
275e8d8bef9SDimitry Andric       Weight = LiveIntervals::getSpillWeight(Writes, Reads, &MBFI, *MI);
2760b57cec5SDimitry Andric 
2770b57cec5SDimitry Andric       // Give extra weight to what looks like a loop induction variable update.
278e8d8bef9SDimitry Andric       if (Writes && IsExiting && LIS.isLiveOutOfMBB(LI, MBB))
279e8d8bef9SDimitry Andric         Weight *= 3;
2800b57cec5SDimitry Andric 
281e8d8bef9SDimitry Andric       TotalWeight += Weight;
2820b57cec5SDimitry Andric     }
2830b57cec5SDimitry Andric 
2840b57cec5SDimitry Andric     // Get allocation hints from copies.
2855f757f3fSDimitry Andric     if (!TII.isCopyInstr(*MI))
2860b57cec5SDimitry Andric       continue;
287e8d8bef9SDimitry Andric     Register HintReg = copyHint(MI, LI.reg(), TRI, MRI);
288e8d8bef9SDimitry Andric     if (!HintReg)
2890b57cec5SDimitry Andric       continue;
2901a4b8325SDimitry Andric     // Force HWeight onto the stack so that x86 doesn't add hidden precision,
2910b57cec5SDimitry Andric     // making the comparison incorrectly pass (i.e., 1 > 1 == true??).
2921a4b8325SDimitry Andric     stack_float_t HWeight = Hint[HintReg] += Weight;
293e8d8bef9SDimitry Andric     if (HintReg.isVirtual() || MRI.isAllocatable(HintReg))
294e8d8bef9SDimitry Andric       CopyHints.insert(CopyHint(HintReg, HWeight));
2950b57cec5SDimitry Andric   }
2960b57cec5SDimitry Andric 
2970b57cec5SDimitry Andric   // Pass all the sorted copy hints to mri.
298e8d8bef9SDimitry Andric   if (ShouldUpdateLI && CopyHints.size()) {
2990b57cec5SDimitry Andric     // Remove a generic hint if previously added by target.
3000b57cec5SDimitry Andric     if (TargetHint.first == 0 && TargetHint.second)
301e8d8bef9SDimitry Andric       MRI.clearSimpleHint(LI.reg());
3020b57cec5SDimitry Andric 
303bdd1243dSDimitry Andric     SmallSet<Register, 4> HintedRegs;
304fcaf7f86SDimitry Andric     for (const auto &Hint : CopyHints) {
3050b57cec5SDimitry Andric       if (!HintedRegs.insert(Hint.Reg).second ||
3060b57cec5SDimitry Andric           (TargetHint.first != 0 && Hint.Reg == TargetHint.second))
3070b57cec5SDimitry Andric         // Don't add the same reg twice or the target-type hint again.
3080b57cec5SDimitry Andric         continue;
309e8d8bef9SDimitry Andric       MRI.addRegAllocationHint(LI.reg(), Hint.Reg);
3100b57cec5SDimitry Andric     }
3110b57cec5SDimitry Andric 
3120b57cec5SDimitry Andric     // Weakly boost the spill weight of hinted registers.
313e8d8bef9SDimitry Andric     TotalWeight *= 1.01F;
3140b57cec5SDimitry Andric   }
3150b57cec5SDimitry Andric 
3160b57cec5SDimitry Andric   // If the live interval was already unspillable, leave it that way.
317e8d8bef9SDimitry Andric   if (!IsSpillable)
3180b57cec5SDimitry Andric     return -1.0;
3190b57cec5SDimitry Andric 
3200b57cec5SDimitry Andric   // Mark li as unspillable if all live ranges are tiny and the interval
3210b57cec5SDimitry Andric   // is not live at any reg mask.  If the interval is live at a reg mask
322fe6060f1SDimitry Andric   // spilling may be required. If li is live as use in statepoint instruction
323fe6060f1SDimitry Andric   // spilling may be required due to if we mark interval with use in statepoint
324fe6060f1SDimitry Andric   // as not spillable we are risky to end up with no register to allocate.
325fe6060f1SDimitry Andric   // At the same time STATEPOINT instruction is perfectly fine to have this
326fe6060f1SDimitry Andric   // operand on stack, so spilling such interval and folding its load from stack
327fe6060f1SDimitry Andric   // into instruction itself makes perfect sense.
328e8d8bef9SDimitry Andric   if (ShouldUpdateLI && LI.isZeroLength(LIS.getSlotIndexes()) &&
329fe6060f1SDimitry Andric       !LI.isLiveAtIndexes(LIS.getRegMaskSlots()) &&
3305f757f3fSDimitry Andric       !isLiveAtStatepointVarArg(LI) && !canMemFoldInlineAsm(LI, MRI)) {
331e8d8bef9SDimitry Andric     LI.markNotSpillable();
3320b57cec5SDimitry Andric     return -1.0;
3330b57cec5SDimitry Andric   }
3340b57cec5SDimitry Andric 
3350b57cec5SDimitry Andric   // If all of the definitions of the interval are re-materializable,
3360b57cec5SDimitry Andric   // it is a preferred candidate for spilling.
3370b57cec5SDimitry Andric   // FIXME: this gets much more complicated once we support non-trivial
3380b57cec5SDimitry Andric   // re-materialization.
339e8d8bef9SDimitry Andric   if (isRematerializable(LI, LIS, VRM, *MF.getSubtarget().getInstrInfo()))
340e8d8bef9SDimitry Andric     TotalWeight *= 0.5F;
3410b57cec5SDimitry Andric 
342e8d8bef9SDimitry Andric   if (IsLocalSplitArtifact)
343e8d8bef9SDimitry Andric     return normalize(TotalWeight, Start->distance(*End), NumInstr);
344e8d8bef9SDimitry Andric   return normalize(TotalWeight, LI.getSize(), NumInstr);
3450b57cec5SDimitry Andric }
346