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;