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