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 9 #include "llvm/CodeGen/CalcSpillWeights.h" 10 #include "llvm/ADT/SmallPtrSet.h" 11 #include "llvm/CodeGen/LiveInterval.h" 12 #include "llvm/CodeGen/LiveIntervals.h" 13 #include "llvm/CodeGen/MachineFunction.h" 14 #include "llvm/CodeGen/MachineInstr.h" 15 #include "llvm/CodeGen/MachineLoopInfo.h" 16 #include "llvm/CodeGen/MachineOperand.h" 17 #include "llvm/CodeGen/MachineRegisterInfo.h" 18 #include "llvm/CodeGen/TargetInstrInfo.h" 19 #include "llvm/CodeGen/TargetRegisterInfo.h" 20 #include "llvm/CodeGen/TargetSubtargetInfo.h" 21 #include "llvm/CodeGen/VirtRegMap.h" 22 #include "llvm/Support/Debug.h" 23 #include "llvm/Support/raw_ostream.h" 24 #include <cassert> 25 #include <tuple> 26 27 using namespace llvm; 28 29 #define DEBUG_TYPE "calcspillweights" 30 31 void VirtRegAuxInfo::calculateSpillWeightsAndHints() { 32 LLVM_DEBUG(dbgs() << "********** Compute Spill Weights **********\n" 33 << "********** Function: " << MF.getName() << '\n'); 34 35 MachineRegisterInfo &MRI = MF.getRegInfo(); 36 for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) { 37 unsigned Reg = Register::index2VirtReg(I); 38 if (MRI.reg_nodbg_empty(Reg)) 39 continue; 40 calculateSpillWeightAndHint(LIS.getInterval(Reg)); 41 } 42 } 43 44 // Return the preferred allocation register for reg, given a COPY instruction. 45 static Register copyHint(const MachineInstr *MI, unsigned Reg, 46 const TargetRegisterInfo &TRI, 47 const MachineRegisterInfo &MRI) { 48 unsigned Sub, HSub; 49 Register HReg; 50 if (MI->getOperand(0).getReg() == Reg) { 51 Sub = MI->getOperand(0).getSubReg(); 52 HReg = MI->getOperand(1).getReg(); 53 HSub = MI->getOperand(1).getSubReg(); 54 } else { 55 Sub = MI->getOperand(1).getSubReg(); 56 HReg = MI->getOperand(0).getReg(); 57 HSub = MI->getOperand(0).getSubReg(); 58 } 59 60 if (!HReg) 61 return 0; 62 63 if (Register::isVirtualRegister(HReg)) 64 return Sub == HSub ? HReg : Register(); 65 66 const TargetRegisterClass *rc = MRI.getRegClass(Reg); 67 Register CopiedPReg = (HSub ? TRI.getSubReg(HReg, HSub) : HReg); 68 if (rc->contains(CopiedPReg)) 69 return CopiedPReg; 70 71 // Check if reg:sub matches so that a super register could be hinted. 72 if (Sub) 73 return TRI.getMatchingSuperReg(CopiedPReg, Sub, rc); 74 75 return 0; 76 } 77 78 // Check if all values in LI are rematerializable 79 static bool isRematerializable(const LiveInterval &LI, 80 const LiveIntervals &LIS, 81 VirtRegMap *VRM, 82 const TargetInstrInfo &TII) { 83 unsigned Reg = LI.reg(); 84 unsigned Original = VRM ? VRM->getOriginal(Reg) : 0; 85 for (LiveInterval::const_vni_iterator I = LI.vni_begin(), E = LI.vni_end(); 86 I != E; ++I) { 87 const VNInfo *VNI = *I; 88 if (VNI->isUnused()) 89 continue; 90 if (VNI->isPHIDef()) 91 return false; 92 93 MachineInstr *MI = LIS.getInstructionFromIndex(VNI->def); 94 assert(MI && "Dead valno in interval"); 95 96 // Trace copies introduced by live range splitting. The inline 97 // spiller can rematerialize through these copies, so the spill 98 // weight must reflect this. 99 if (VRM) { 100 while (MI->isFullCopy()) { 101 // The copy destination must match the interval register. 102 if (MI->getOperand(0).getReg() != Reg) 103 return false; 104 105 // Get the source register. 106 Reg = MI->getOperand(1).getReg(); 107 108 // If the original (pre-splitting) registers match this 109 // copy came from a split. 110 if (!Register::isVirtualRegister(Reg) || 111 VRM->getOriginal(Reg) != Original) 112 return false; 113 114 // Follow the copy live-in value. 115 const LiveInterval &SrcLI = LIS.getInterval(Reg); 116 LiveQueryResult SrcQ = SrcLI.Query(VNI->def); 117 VNI = SrcQ.valueIn(); 118 assert(VNI && "Copy from non-existing value"); 119 if (VNI->isPHIDef()) 120 return false; 121 MI = LIS.getInstructionFromIndex(VNI->def); 122 assert(MI && "Dead valno in interval"); 123 } 124 } 125 126 if (!TII.isTriviallyReMaterializable(*MI, LIS.getAliasAnalysis())) 127 return false; 128 } 129 return true; 130 } 131 132 void VirtRegAuxInfo::calculateSpillWeightAndHint(LiveInterval &LI) { 133 float Weight = weightCalcHelper(LI); 134 // Check if unspillable. 135 if (Weight < 0) 136 return; 137 LI.setWeight(Weight); 138 } 139 140 float VirtRegAuxInfo::futureWeight(LiveInterval &LI, SlotIndex Start, 141 SlotIndex End) { 142 return weightCalcHelper(LI, &Start, &End); 143 } 144 145 float VirtRegAuxInfo::weightCalcHelper(LiveInterval &LI, SlotIndex *Start, 146 SlotIndex *End) { 147 MachineRegisterInfo &MRI = MF.getRegInfo(); 148 const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo(); 149 MachineBasicBlock *MBB = nullptr; 150 MachineLoop *Loop = nullptr; 151 bool IsExiting = false; 152 float TotalWeight = 0; 153 unsigned NumInstr = 0; // Number of instructions using LI 154 SmallPtrSet<MachineInstr *, 8> Visited; 155 156 std::pair<Register, Register> TargetHint = MRI.getRegAllocationHint(LI.reg()); 157 158 if (LI.isSpillable() && VRM) { 159 Register Reg = LI.reg(); 160 Register Original = VRM->getOriginal(Reg); 161 const LiveInterval &OrigInt = LIS.getInterval(Original); 162 // li comes from a split of OrigInt. If OrigInt was marked 163 // as not spillable, make sure the new interval is marked 164 // as not spillable as well. 165 if (!OrigInt.isSpillable()) 166 LI.markNotSpillable(); 167 } 168 169 // Don't recompute spill weight for an unspillable register. 170 bool IsSpillable = LI.isSpillable(); 171 172 bool IsLocalSplitArtifact = Start && End; 173 174 // Do not update future local split artifacts. 175 bool ShouldUpdateLI = !IsLocalSplitArtifact; 176 177 if (IsLocalSplitArtifact) { 178 MachineBasicBlock *localMBB = LIS.getMBBFromIndex(*End); 179 assert(localMBB == LIS.getMBBFromIndex(*Start) && 180 "start and end are expected to be in the same basic block"); 181 182 // Local split artifact will have 2 additional copy instructions and they 183 // will be in the same BB. 184 // localLI = COPY other 185 // ... 186 // other = COPY localLI 187 TotalWeight += LiveIntervals::getSpillWeight(true, false, &MBFI, localMBB); 188 TotalWeight += LiveIntervals::getSpillWeight(false, true, &MBFI, localMBB); 189 190 NumInstr += 2; 191 } 192 193 // CopyHint is a sortable hint derived from a COPY instruction. 194 struct CopyHint { 195 const Register Reg; 196 const float Weight; 197 CopyHint(Register R, float W) : Reg(R), Weight(W) {} 198 bool operator<(const CopyHint &Rhs) const { 199 // Always prefer any physreg hint. 200 if (Reg.isPhysical() != Rhs.Reg.isPhysical()) 201 return Reg.isPhysical(); 202 if (Weight != Rhs.Weight) 203 return (Weight > Rhs.Weight); 204 return Reg.id() < Rhs.Reg.id(); // Tie-breaker. 205 } 206 }; 207 208 std::set<CopyHint> CopyHints; 209 DenseMap<unsigned, float> Hint; 210 for (MachineRegisterInfo::reg_instr_nodbg_iterator 211 I = MRI.reg_instr_nodbg_begin(LI.reg()), 212 E = MRI.reg_instr_nodbg_end(); 213 I != E;) { 214 MachineInstr *MI = &*(I++); 215 216 // For local split artifacts, we are interested only in instructions between 217 // the expected start and end of the range. 218 SlotIndex SI = LIS.getInstructionIndex(*MI); 219 if (IsLocalSplitArtifact && ((SI < *Start) || (SI > *End))) 220 continue; 221 222 NumInstr++; 223 if (MI->isIdentityCopy() || MI->isImplicitDef()) 224 continue; 225 if (!Visited.insert(MI).second) 226 continue; 227 228 float Weight = 1.0f; 229 if (IsSpillable) { 230 // Get loop info for mi. 231 if (MI->getParent() != MBB) { 232 MBB = MI->getParent(); 233 Loop = Loops.getLoopFor(MBB); 234 IsExiting = Loop ? Loop->isLoopExiting(MBB) : false; 235 } 236 237 // Calculate instr weight. 238 bool Reads, Writes; 239 std::tie(Reads, Writes) = MI->readsWritesVirtualRegister(LI.reg()); 240 Weight = LiveIntervals::getSpillWeight(Writes, Reads, &MBFI, *MI); 241 242 // Give extra weight to what looks like a loop induction variable update. 243 if (Writes && IsExiting && LIS.isLiveOutOfMBB(LI, MBB)) 244 Weight *= 3; 245 246 TotalWeight += Weight; 247 } 248 249 // Get allocation hints from copies. 250 if (!MI->isCopy()) 251 continue; 252 Register HintReg = copyHint(MI, LI.reg(), TRI, MRI); 253 if (!HintReg) 254 continue; 255 // Force hweight onto the stack so that x86 doesn't add hidden precision, 256 // making the comparison incorrectly pass (i.e., 1 > 1 == true??). 257 // 258 // FIXME: we probably shouldn't use floats at all. 259 volatile float HWeight = Hint[HintReg] += Weight; 260 if (HintReg.isVirtual() || MRI.isAllocatable(HintReg)) 261 CopyHints.insert(CopyHint(HintReg, HWeight)); 262 } 263 264 // Pass all the sorted copy hints to mri. 265 if (ShouldUpdateLI && CopyHints.size()) { 266 // Remove a generic hint if previously added by target. 267 if (TargetHint.first == 0 && TargetHint.second) 268 MRI.clearSimpleHint(LI.reg()); 269 270 std::set<Register> HintedRegs; 271 for (auto &Hint : CopyHints) { 272 if (!HintedRegs.insert(Hint.Reg).second || 273 (TargetHint.first != 0 && Hint.Reg == TargetHint.second)) 274 // Don't add the same reg twice or the target-type hint again. 275 continue; 276 MRI.addRegAllocationHint(LI.reg(), Hint.Reg); 277 } 278 279 // Weakly boost the spill weight of hinted registers. 280 TotalWeight *= 1.01F; 281 } 282 283 // If the live interval was already unspillable, leave it that way. 284 if (!IsSpillable) 285 return -1.0; 286 287 // Mark li as unspillable if all live ranges are tiny and the interval 288 // is not live at any reg mask. If the interval is live at a reg mask 289 // spilling may be required. 290 if (ShouldUpdateLI && LI.isZeroLength(LIS.getSlotIndexes()) && 291 !LI.isLiveAtIndexes(LIS.getRegMaskSlots())) { 292 LI.markNotSpillable(); 293 return -1.0; 294 } 295 296 // If all of the definitions of the interval are re-materializable, 297 // it is a preferred candidate for spilling. 298 // FIXME: this gets much more complicated once we support non-trivial 299 // re-materialization. 300 if (isRematerializable(LI, LIS, VRM, *MF.getSubtarget().getInstrInfo())) 301 TotalWeight *= 0.5F; 302 303 if (IsLocalSplitArtifact) 304 return normalize(TotalWeight, Start->distance(*End), NumInstr); 305 return normalize(TotalWeight, LI.getSize(), NumInstr); 306 } 307