Mercurial > hg > CbC > CbC_llvm
comparison lib/CodeGen/CalcSpillWeights.cpp @ 134:3a76565eade5 LLVM5.0.1
update 5.0.1
author | mir3636 |
---|---|
date | Sat, 17 Feb 2018 09:57:20 +0900 |
parents | 803732b1fca8 |
children | c2174574ed3a |
comparison
equal
deleted
inserted
replaced
133:c60214abe0e8 | 134:3a76565eade5 |
---|---|
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 | 9 |
10 #include "llvm/CodeGen/CalcSpillWeights.h" | 10 #include "llvm/CodeGen/CalcSpillWeights.h" |
11 #include "llvm/ADT/SmallPtrSet.h" | 11 #include "llvm/ADT/SmallPtrSet.h" |
12 #include "llvm/CodeGen/LiveInterval.h" | 12 #include "llvm/CodeGen/LiveInterval.h" |
13 #include "llvm/CodeGen/LiveIntervalAnalysis.h" | 13 #include "llvm/CodeGen/LiveIntervals.h" |
14 #include "llvm/CodeGen/MachineFunction.h" | 14 #include "llvm/CodeGen/MachineFunction.h" |
15 #include "llvm/CodeGen/MachineInstr.h" | 15 #include "llvm/CodeGen/MachineInstr.h" |
16 #include "llvm/CodeGen/MachineLoopInfo.h" | 16 #include "llvm/CodeGen/MachineLoopInfo.h" |
17 #include "llvm/CodeGen/MachineOperand.h" | 17 #include "llvm/CodeGen/MachineOperand.h" |
18 #include "llvm/CodeGen/MachineRegisterInfo.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" | |
19 #include "llvm/CodeGen/VirtRegMap.h" | 22 #include "llvm/CodeGen/VirtRegMap.h" |
20 #include "llvm/Support/Debug.h" | 23 #include "llvm/Support/Debug.h" |
21 #include "llvm/Support/raw_ostream.h" | 24 #include "llvm/Support/raw_ostream.h" |
22 #include "llvm/Target/TargetInstrInfo.h" | |
23 #include "llvm/Target/TargetRegisterInfo.h" | |
24 #include "llvm/Target/TargetSubtargetInfo.h" | |
25 #include <cassert> | 25 #include <cassert> |
26 #include <tuple> | 26 #include <tuple> |
27 | 27 |
28 using namespace llvm; | 28 using namespace llvm; |
29 | 29 |
68 | 68 |
69 if (TargetRegisterInfo::isVirtualRegister(hreg)) | 69 if (TargetRegisterInfo::isVirtualRegister(hreg)) |
70 return sub == hsub ? hreg : 0; | 70 return sub == hsub ? hreg : 0; |
71 | 71 |
72 const TargetRegisterClass *rc = mri.getRegClass(reg); | 72 const TargetRegisterClass *rc = mri.getRegClass(reg); |
73 | 73 if (!tri.enableMultipleCopyHints()) { |
74 // Only allow physreg hints in rc. | 74 // Only allow physreg hints in rc. |
75 if (sub == 0) | 75 if (sub == 0) |
76 return rc->contains(hreg) ? hreg : 0; | 76 return rc->contains(hreg) ? hreg : 0; |
77 | 77 |
78 // reg:sub should match the physreg hreg. | 78 // reg:sub should match the physreg hreg. |
79 return tri.getMatchingSuperReg(hreg, sub, rc); | 79 return tri.getMatchingSuperReg(hreg, sub, rc); |
80 } | |
81 | |
82 unsigned CopiedPReg = (hsub ? tri.getSubReg(hreg, hsub) : hreg); | |
83 if (rc->contains(CopiedPReg)) | |
84 return CopiedPReg; | |
85 | |
86 // Check if reg:sub matches so that a super register could be hinted. | |
87 if (sub) | |
88 return tri.getMatchingSuperReg(CopiedPReg, sub, rc); | |
89 | |
90 return 0; | |
80 } | 91 } |
81 | 92 |
82 // Check if all values in LI are rematerializable | 93 // Check if all values in LI are rematerializable |
83 static bool isRematerializable(const LiveInterval &LI, | 94 static bool isRematerializable(const LiveInterval &LI, |
84 const LiveIntervals &LIS, | 95 const LiveIntervals &LIS, |
155 bool isExiting = false; | 166 bool isExiting = false; |
156 float totalWeight = 0; | 167 float totalWeight = 0; |
157 unsigned numInstr = 0; // Number of instructions using li | 168 unsigned numInstr = 0; // Number of instructions using li |
158 SmallPtrSet<MachineInstr*, 8> visited; | 169 SmallPtrSet<MachineInstr*, 8> visited; |
159 | 170 |
160 // Find the best physreg hint and the best virtreg hint. | 171 std::pair<unsigned, unsigned> TargetHint = mri.getRegAllocationHint(li.reg); |
161 float bestPhys = 0, bestVirt = 0; | |
162 unsigned hintPhys = 0, hintVirt = 0; | |
163 | |
164 // Don't recompute a target specific hint. | |
165 bool noHint = mri.getRegAllocationHint(li.reg).first != 0; | |
166 | 172 |
167 // Don't recompute spill weight for an unspillable register. | 173 // Don't recompute spill weight for an unspillable register. |
168 bool Spillable = li.isSpillable(); | 174 bool Spillable = li.isSpillable(); |
169 | 175 |
170 bool localSplitArtifact = start && end; | 176 bool localSplitArtifact = start && end; |
186 totalWeight += LiveIntervals::getSpillWeight(false, true, &MBFI, localMBB); | 192 totalWeight += LiveIntervals::getSpillWeight(false, true, &MBFI, localMBB); |
187 | 193 |
188 numInstr += 2; | 194 numInstr += 2; |
189 } | 195 } |
190 | 196 |
197 // CopyHint is a sortable hint derived from a COPY instruction. | |
198 struct CopyHint { | |
199 unsigned Reg; | |
200 float Weight; | |
201 bool IsPhys; | |
202 unsigned HintOrder; | |
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); | |
211 | |
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); | |
216 | |
217 #if 0 // Should replace the HintOrder check, see above. | |
218 // (just for the purpose of maintaining the set) | |
219 return Reg < rhs.Reg; | |
220 #endif | |
221 } | |
222 }; | |
223 std::set<CopyHint> CopyHints; | |
224 | |
225 // Temporary: see comment for HintOrder above. | |
226 unsigned CopyHintOrder = 0; | |
191 for (MachineRegisterInfo::reg_instr_iterator | 227 for (MachineRegisterInfo::reg_instr_iterator |
192 I = mri.reg_instr_begin(li.reg), E = mri.reg_instr_end(); | 228 I = mri.reg_instr_begin(li.reg), E = mri.reg_instr_end(); |
193 I != E; ) { | 229 I != E; ) { |
194 MachineInstr *mi = &*(I++); | 230 MachineInstr *mi = &*(I++); |
195 | 231 |
225 | 261 |
226 totalWeight += weight; | 262 totalWeight += weight; |
227 } | 263 } |
228 | 264 |
229 // Get allocation hints from copies. | 265 // Get allocation hints from copies. |
230 if (noHint || !mi->isCopy()) | 266 if (!mi->isCopy() || |
267 (TargetHint.first != 0 && !tri.enableMultipleCopyHints())) | |
231 continue; | 268 continue; |
232 unsigned hint = copyHint(mi, li.reg, tri, mri); | 269 unsigned hint = copyHint(mi, li.reg, tri, mri); |
233 if (!hint) | 270 if (!hint) |
234 continue; | 271 continue; |
235 // Force hweight onto the stack so that x86 doesn't add hidden precision, | 272 // Force hweight onto the stack so that x86 doesn't add hidden precision, |
236 // making the comparison incorrectly pass (i.e., 1 > 1 == true??). | 273 // making the comparison incorrectly pass (i.e., 1 > 1 == true??). |
237 // | 274 // |
238 // FIXME: we probably shouldn't use floats at all. | 275 // FIXME: we probably shouldn't use floats at all. |
239 volatile float hweight = Hint[hint] += weight; | 276 volatile float hweight = Hint[hint] += weight; |
240 if (TargetRegisterInfo::isPhysicalRegister(hint)) { | 277 if (TargetRegisterInfo::isVirtualRegister(hint) || mri.isAllocatable(hint)) |
241 if (hweight > bestPhys && mri.isAllocatable(hint)) { | 278 CopyHints.insert(CopyHint(hint, hweight, tri.isPhysicalRegister(hint), |
242 bestPhys = hweight; | 279 (tri.enableMultipleCopyHints() ? hint : CopyHintOrder++))); |
243 hintPhys = hint; | 280 } |
244 } | 281 |
245 } else { | 282 Hint.clear(); |
246 if (hweight > bestVirt) { | 283 |
247 bestVirt = hweight; | 284 // Pass all the sorted copy hints to mri. |
248 hintVirt = hint; | 285 if (updateLI && CopyHints.size()) { |
249 } | 286 // Remove a generic hint if previously added by target. |
287 if (TargetHint.first == 0 && TargetHint.second) | |
288 mri.clearSimpleHint(li.reg); | |
289 | |
290 for (auto &Hint : CopyHints) { | |
291 if (TargetHint.first != 0 && Hint.Reg == TargetHint.second) | |
292 // Don't add again the target-type hint. | |
293 continue; | |
294 mri.addRegAllocationHint(li.reg, Hint.Reg); | |
295 if (!tri.enableMultipleCopyHints()) | |
296 break; | |
250 } | 297 } |
251 } | 298 |
252 | 299 // Weakly boost the spill weight of hinted registers. |
253 Hint.clear(); | 300 totalWeight *= 1.01F; |
254 | |
255 // Always prefer the physreg hint. | |
256 if (updateLI) { | |
257 if (unsigned hint = hintPhys ? hintPhys : hintVirt) { | |
258 mri.setRegAllocationHint(li.reg, 0, hint); | |
259 // Weakly boost the spill weight of hinted registers. | |
260 totalWeight *= 1.01F; | |
261 } | |
262 } | 301 } |
263 | 302 |
264 // If the live interval was already unspillable, leave it that way. | 303 // If the live interval was already unspillable, leave it that way. |
265 if (!Spillable) | 304 if (!Spillable) |
266 return -1.0; | 305 return -1.0; |