1 //===- CalcSpillWeights.cpp -----------------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "llvm/CodeGen/CalcSpillWeights.h"
11 #include "llvm/ADT/SmallPtrSet.h"
12 #include "llvm/CodeGen/LiveInterval.h"
13 #include "llvm/CodeGen/LiveIntervals.h"
14 #include "llvm/CodeGen/MachineFunction.h"
15 #include "llvm/CodeGen/MachineInstr.h"
16 #include "llvm/CodeGen/MachineLoopInfo.h"
17 #include "llvm/CodeGen/MachineOperand.h"
18 #include "llvm/CodeGen/MachineRegisterInfo.h"
19 #include "llvm/CodeGen/TargetInstrInfo.h"
20 #include "llvm/CodeGen/TargetRegisterInfo.h"
21 #include "llvm/CodeGen/TargetSubtargetInfo.h"
22 #include "llvm/CodeGen/VirtRegMap.h"
23 #include "llvm/Support/Debug.h"
24 #include "llvm/Support/raw_ostream.h"
30 #define DEBUG_TYPE "calcspillweights"
32 void llvm::calculateSpillWeightsAndHints(LiveIntervals
&LIS
,
35 const MachineLoopInfo
&MLI
,
36 const MachineBlockFrequencyInfo
&MBFI
,
37 VirtRegAuxInfo::NormalizingFn norm
) {
38 LLVM_DEBUG(dbgs() << "********** Compute Spill Weights **********\n"
39 << "********** Function: " << MF
.getName() << '\n');
41 MachineRegisterInfo
&MRI
= MF
.getRegInfo();
42 VirtRegAuxInfo
VRAI(MF
, LIS
, VRM
, MLI
, MBFI
, norm
);
43 for (unsigned i
= 0, e
= MRI
.getNumVirtRegs(); i
!= e
; ++i
) {
44 unsigned Reg
= TargetRegisterInfo::index2VirtReg(i
);
45 if (MRI
.reg_nodbg_empty(Reg
))
47 VRAI
.calculateSpillWeightAndHint(LIS
.getInterval(Reg
));
51 // Return the preferred allocation register for reg, given a COPY instruction.
52 static unsigned copyHint(const MachineInstr
*mi
, unsigned reg
,
53 const TargetRegisterInfo
&tri
,
54 const MachineRegisterInfo
&mri
) {
55 unsigned sub
, hreg
, hsub
;
56 if (mi
->getOperand(0).getReg() == reg
) {
57 sub
= mi
->getOperand(0).getSubReg();
58 hreg
= mi
->getOperand(1).getReg();
59 hsub
= mi
->getOperand(1).getSubReg();
61 sub
= mi
->getOperand(1).getSubReg();
62 hreg
= mi
->getOperand(0).getReg();
63 hsub
= mi
->getOperand(0).getSubReg();
69 if (TargetRegisterInfo::isVirtualRegister(hreg
))
70 return sub
== hsub
? hreg
: 0;
72 const TargetRegisterClass
*rc
= mri
.getRegClass(reg
);
73 if (!tri
.enableMultipleCopyHints()) {
74 // Only allow physreg hints in rc.
76 return rc
->contains(hreg
) ? hreg
: 0;
78 // reg:sub should match the physreg hreg.
79 return tri
.getMatchingSuperReg(hreg
, sub
, rc
);
82 unsigned CopiedPReg
= (hsub
? tri
.getSubReg(hreg
, hsub
) : hreg
);
83 if (rc
->contains(CopiedPReg
))
86 // Check if reg:sub matches so that a super register could be hinted.
88 return tri
.getMatchingSuperReg(CopiedPReg
, sub
, rc
);
93 // Check if all values in LI are rematerializable
94 static bool isRematerializable(const LiveInterval
&LI
,
95 const LiveIntervals
&LIS
,
97 const TargetInstrInfo
&TII
) {
98 unsigned Reg
= LI
.reg
;
99 unsigned Original
= VRM
? VRM
->getOriginal(Reg
) : 0;
100 for (LiveInterval::const_vni_iterator I
= LI
.vni_begin(), E
= LI
.vni_end();
102 const VNInfo
*VNI
= *I
;
108 MachineInstr
*MI
= LIS
.getInstructionFromIndex(VNI
->def
);
109 assert(MI
&& "Dead valno in interval");
111 // Trace copies introduced by live range splitting. The inline
112 // spiller can rematerialize through these copies, so the spill
113 // weight must reflect this.
115 while (MI
->isFullCopy()) {
116 // The copy destination must match the interval register.
117 if (MI
->getOperand(0).getReg() != Reg
)
120 // Get the source register.
121 Reg
= MI
->getOperand(1).getReg();
123 // If the original (pre-splitting) registers match this
124 // copy came from a split.
125 if (!TargetRegisterInfo::isVirtualRegister(Reg
) ||
126 VRM
->getOriginal(Reg
) != Original
)
129 // Follow the copy live-in value.
130 const LiveInterval
&SrcLI
= LIS
.getInterval(Reg
);
131 LiveQueryResult SrcQ
= SrcLI
.Query(VNI
->def
);
132 VNI
= SrcQ
.valueIn();
133 assert(VNI
&& "Copy from non-existing value");
136 MI
= LIS
.getInstructionFromIndex(VNI
->def
);
137 assert(MI
&& "Dead valno in interval");
141 if (!TII
.isTriviallyReMaterializable(*MI
, LIS
.getAliasAnalysis()))
147 void VirtRegAuxInfo::calculateSpillWeightAndHint(LiveInterval
&li
) {
148 float weight
= weightCalcHelper(li
);
149 // Check if unspillable.
155 float VirtRegAuxInfo::futureWeight(LiveInterval
&li
, SlotIndex start
,
157 return weightCalcHelper(li
, &start
, &end
);
160 float VirtRegAuxInfo::weightCalcHelper(LiveInterval
&li
, SlotIndex
*start
,
162 MachineRegisterInfo
&mri
= MF
.getRegInfo();
163 const TargetRegisterInfo
&tri
= *MF
.getSubtarget().getRegisterInfo();
164 MachineBasicBlock
*mbb
= nullptr;
165 MachineLoop
*loop
= nullptr;
166 bool isExiting
= false;
167 float totalWeight
= 0;
168 unsigned numInstr
= 0; // Number of instructions using li
169 SmallPtrSet
<MachineInstr
*, 8> visited
;
171 std::pair
<unsigned, unsigned> TargetHint
= mri
.getRegAllocationHint(li
.reg
);
173 // Don't recompute spill weight for an unspillable register.
174 bool Spillable
= li
.isSpillable();
176 bool localSplitArtifact
= start
&& end
;
178 // Do not update future local split artifacts.
179 bool updateLI
= !localSplitArtifact
;
181 if (localSplitArtifact
) {
182 MachineBasicBlock
*localMBB
= LIS
.getMBBFromIndex(*end
);
183 assert(localMBB
== LIS
.getMBBFromIndex(*start
) &&
184 "start and end are expected to be in the same basic block");
186 // Local split artifact will have 2 additional copy instructions and they
187 // will be in the same BB.
188 // localLI = COPY other
190 // other = COPY localLI
191 totalWeight
+= LiveIntervals::getSpillWeight(true, false, &MBFI
, localMBB
);
192 totalWeight
+= LiveIntervals::getSpillWeight(false, true, &MBFI
, localMBB
);
197 // CopyHint is a sortable hint derived from a COPY instruction.
203 CopyHint(unsigned R
, float W
, bool P
, unsigned HR
) :
204 Reg(R
), Weight(W
), IsPhys(P
), HintOrder(HR
) {}
205 bool operator<(const CopyHint
&rhs
) const {
206 // Always prefer any physreg hint.
207 if (IsPhys
!= rhs
.IsPhys
)
208 return (IsPhys
&& !rhs
.IsPhys
);
209 if (Weight
!= rhs
.Weight
)
210 return (Weight
> rhs
.Weight
);
212 // This is just a temporary way to achive NFC for targets that don't
213 // enable multiple copy hints. HintOrder should be removed when all
214 // targets return true in enableMultipleCopyHints().
215 return (HintOrder
< rhs
.HintOrder
);
217 #if 0 // Should replace the HintOrder check, see above.
218 // (just for the purpose of maintaining the set)
219 return Reg
< rhs
.Reg
;
223 std::set
<CopyHint
> CopyHints
;
225 // Temporary: see comment for HintOrder above.
226 unsigned CopyHintOrder
= 0;
227 for (MachineRegisterInfo::reg_instr_iterator
228 I
= mri
.reg_instr_begin(li
.reg
), E
= mri
.reg_instr_end();
230 MachineInstr
*mi
= &*(I
++);
232 // For local split artifacts, we are interested only in instructions between
233 // the expected start and end of the range.
234 SlotIndex si
= LIS
.getInstructionIndex(*mi
);
235 if (localSplitArtifact
&& ((si
< *start
) || (si
> *end
)))
239 if (mi
->isIdentityCopy() || mi
->isImplicitDef() || mi
->isDebugInstr())
241 if (!visited
.insert(mi
).second
)
246 // Get loop info for mi.
247 if (mi
->getParent() != mbb
) {
248 mbb
= mi
->getParent();
249 loop
= Loops
.getLoopFor(mbb
);
250 isExiting
= loop
? loop
->isLoopExiting(mbb
) : false;
253 // Calculate instr weight.
255 std::tie(reads
, writes
) = mi
->readsWritesVirtualRegister(li
.reg
);
256 weight
= LiveIntervals::getSpillWeight(writes
, reads
, &MBFI
, *mi
);
258 // Give extra weight to what looks like a loop induction variable update.
259 if (writes
&& isExiting
&& LIS
.isLiveOutOfMBB(li
, mbb
))
262 totalWeight
+= weight
;
265 // Get allocation hints from copies.
267 (TargetHint
.first
!= 0 && !tri
.enableMultipleCopyHints()))
269 unsigned hint
= copyHint(mi
, li
.reg
, tri
, mri
);
272 // Force hweight onto the stack so that x86 doesn't add hidden precision,
273 // making the comparison incorrectly pass (i.e., 1 > 1 == true??).
275 // FIXME: we probably shouldn't use floats at all.
276 volatile float hweight
= Hint
[hint
] += weight
;
277 if (TargetRegisterInfo::isVirtualRegister(hint
) || mri
.isAllocatable(hint
))
278 CopyHints
.insert(CopyHint(hint
, hweight
, tri
.isPhysicalRegister(hint
),
279 (tri
.enableMultipleCopyHints() ? hint
: CopyHintOrder
++)));
284 // Pass all the sorted copy hints to mri.
285 if (updateLI
&& CopyHints
.size()) {
286 // Remove a generic hint if previously added by target.
287 if (TargetHint
.first
== 0 && TargetHint
.second
)
288 mri
.clearSimpleHint(li
.reg
);
290 for (auto &Hint
: CopyHints
) {
291 if (TargetHint
.first
!= 0 && Hint
.Reg
== TargetHint
.second
)
292 // Don't add again the target-type hint.
294 mri
.addRegAllocationHint(li
.reg
, Hint
.Reg
);
295 if (!tri
.enableMultipleCopyHints())
299 // Weakly boost the spill weight of hinted registers.
300 totalWeight
*= 1.01F
;
303 // If the live interval was already unspillable, leave it that way.
307 // Mark li as unspillable if all live ranges are tiny and the interval
308 // is not live at any reg mask. If the interval is live at a reg mask
309 // spilling may be required.
310 if (updateLI
&& li
.isZeroLength(LIS
.getSlotIndexes()) &&
311 !li
.isLiveAtIndexes(LIS
.getRegMaskSlots())) {
312 li
.markNotSpillable();
316 // If all of the definitions of the interval are re-materializable,
317 // it is a preferred candidate for spilling.
318 // FIXME: this gets much more complicated once we support non-trivial
319 // re-materialization.
320 if (isRematerializable(li
, LIS
, VRM
, *MF
.getSubtarget().getInstrInfo()))
323 if (localSplitArtifact
)
324 return normalize(totalWeight
, start
->distance(*end
), numInstr
);
325 return normalize(totalWeight
, li
.getSize(), numInstr
);