RegisterPressure.cpp revision d71efffdcffc4204e75238f940df41fb24979a7d
1//===-- RegisterPressure.cpp - Dynamic Register Pressure ------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the RegisterPressure class which can be used to track
11// MachineInstr level register pressure.
12//
13//===----------------------------------------------------------------------===//
14
15#include "llvm/CodeGen/RegisterPressure.h"
16#include "llvm/CodeGen/LiveInterval.h"
17#include "llvm/CodeGen/LiveIntervalAnalysis.h"
18#include "llvm/CodeGen/MachineRegisterInfo.h"
19#include "llvm/CodeGen/RegisterClassInfo.h"
20#include "llvm/Support/Debug.h"
21#include "llvm/Support/raw_ostream.h"
22#include "llvm/Target/TargetMachine.h"
23
24using namespace llvm;
25
26/// Increase pressure for each pressure set provided by TargetRegisterInfo.
27static void increaseSetPressure(std::vector<unsigned> &CurrSetPressure,
28                                std::vector<unsigned> &MaxSetPressure,
29                                const int *PSet, unsigned Weight) {
30  for (; *PSet != -1; ++PSet) {
31    CurrSetPressure[*PSet] += Weight;
32    if (&CurrSetPressure != &MaxSetPressure
33        && CurrSetPressure[*PSet] > MaxSetPressure[*PSet]) {
34      MaxSetPressure[*PSet] = CurrSetPressure[*PSet];
35    }
36  }
37}
38
39/// Decrease pressure for each pressure set provided by TargetRegisterInfo.
40static void decreaseSetPressure(std::vector<unsigned> &CurrSetPressure,
41                                const int *PSet, unsigned Weight) {
42  for (; *PSet != -1; ++PSet) {
43    assert(CurrSetPressure[*PSet] >= Weight && "register pressure underflow");
44    CurrSetPressure[*PSet] -= Weight;
45  }
46}
47
48/// Directly increase pressure only within this RegisterPressure result.
49void RegisterPressure::increase(unsigned Reg, const TargetRegisterInfo *TRI,
50                                const MachineRegisterInfo *MRI) {
51  if (TargetRegisterInfo::isVirtualRegister(Reg)) {
52    const TargetRegisterClass *RC = MRI->getRegClass(Reg);
53    increaseSetPressure(MaxSetPressure, MaxSetPressure,
54                        TRI->getRegClassPressureSets(RC),
55                        TRI->getRegClassWeight(RC).RegWeight);
56  }
57  else {
58    increaseSetPressure(MaxSetPressure, MaxSetPressure,
59                        TRI->getRegUnitPressureSets(Reg),
60                        TRI->getRegUnitWeight(Reg));
61  }
62}
63
64/// Directly decrease pressure only within this RegisterPressure result.
65void RegisterPressure::decrease(unsigned Reg, const TargetRegisterInfo *TRI,
66                                const MachineRegisterInfo *MRI) {
67  if (TargetRegisterInfo::isVirtualRegister(Reg)) {
68    const TargetRegisterClass *RC = MRI->getRegClass(Reg);
69    decreaseSetPressure(MaxSetPressure, TRI->getRegClassPressureSets(RC),
70                        TRI->getRegClassWeight(RC).RegWeight);
71  }
72  else {
73    decreaseSetPressure(MaxSetPressure, TRI->getRegUnitPressureSets(Reg),
74                        TRI->getRegUnitWeight(Reg));
75  }
76}
77
78#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
79void llvm::dumpRegSetPressure(ArrayRef<unsigned> SetPressure,
80                              const TargetRegisterInfo *TRI) {
81  bool Empty = true;
82  for (unsigned i = 0, e = SetPressure.size(); i < e; ++i) {
83    if (SetPressure[i] != 0) {
84      dbgs() << TRI->getRegPressureSetName(i) << "=" << SetPressure[i] << '\n';
85      Empty = false;
86    }
87  }
88  if (Empty)
89    dbgs() << "\n";
90}
91
92void RegisterPressure::dump(const TargetRegisterInfo *TRI) const {
93  dbgs() << "Max Pressure: ";
94  dumpRegSetPressure(MaxSetPressure, TRI);
95  dbgs() << "Live In: ";
96  for (unsigned i = 0, e = LiveInRegs.size(); i < e; ++i)
97    dbgs() << PrintReg(LiveInRegs[i], TRI) << " ";
98  dbgs() << '\n';
99  dbgs() << "Live Out: ";
100  for (unsigned i = 0, e = LiveOutRegs.size(); i < e; ++i)
101    dbgs() << PrintReg(LiveOutRegs[i], TRI) << " ";
102  dbgs() << '\n';
103}
104
105void RegPressureTracker::dump() const {
106  if (!isTopClosed() || !isBottomClosed()) {
107    dbgs() << "Curr Pressure: ";
108    dumpRegSetPressure(CurrSetPressure, TRI);
109  }
110  P.dump(TRI);
111}
112#endif
113
114/// Increase the current pressure as impacted by these registers and bump
115/// the high water mark if needed.
116void RegPressureTracker::increaseRegPressure(ArrayRef<unsigned> Regs) {
117  for (unsigned I = 0, E = Regs.size(); I != E; ++I) {
118    if (TargetRegisterInfo::isVirtualRegister(Regs[I])) {
119      const TargetRegisterClass *RC = MRI->getRegClass(Regs[I]);
120      increaseSetPressure(CurrSetPressure, P.MaxSetPressure,
121                          TRI->getRegClassPressureSets(RC),
122                          TRI->getRegClassWeight(RC).RegWeight);
123    }
124    else {
125      increaseSetPressure(CurrSetPressure, P.MaxSetPressure,
126                          TRI->getRegUnitPressureSets(Regs[I]),
127                          TRI->getRegUnitWeight(Regs[I]));
128    }
129  }
130}
131
132/// Simply decrease the current pressure as impacted by these registers.
133void RegPressureTracker::decreaseRegPressure(ArrayRef<unsigned> Regs) {
134  for (unsigned I = 0, E = Regs.size(); I != E; ++I) {
135    if (TargetRegisterInfo::isVirtualRegister(Regs[I])) {
136      const TargetRegisterClass *RC = MRI->getRegClass(Regs[I]);
137      decreaseSetPressure(CurrSetPressure,
138                          TRI->getRegClassPressureSets(RC),
139                          TRI->getRegClassWeight(RC).RegWeight);
140    }
141    else {
142      decreaseSetPressure(CurrSetPressure, TRI->getRegUnitPressureSets(Regs[I]),
143                          TRI->getRegUnitWeight(Regs[I]));
144    }
145  }
146}
147
148/// Clear the result so it can be used for another round of pressure tracking.
149void IntervalPressure::reset() {
150  TopIdx = BottomIdx = SlotIndex();
151  MaxSetPressure.clear();
152  LiveInRegs.clear();
153  LiveOutRegs.clear();
154}
155
156/// Clear the result so it can be used for another round of pressure tracking.
157void RegionPressure::reset() {
158  TopPos = BottomPos = MachineBasicBlock::const_iterator();
159  MaxSetPressure.clear();
160  LiveInRegs.clear();
161  LiveOutRegs.clear();
162}
163
164/// If the current top is not less than or equal to the next index, open it.
165/// We happen to need the SlotIndex for the next top for pressure update.
166void IntervalPressure::openTop(SlotIndex NextTop) {
167  if (TopIdx <= NextTop)
168    return;
169  TopIdx = SlotIndex();
170  LiveInRegs.clear();
171}
172
173/// If the current top is the previous instruction (before receding), open it.
174void RegionPressure::openTop(MachineBasicBlock::const_iterator PrevTop) {
175  if (TopPos != PrevTop)
176    return;
177  TopPos = MachineBasicBlock::const_iterator();
178  LiveInRegs.clear();
179}
180
181/// If the current bottom is not greater than the previous index, open it.
182void IntervalPressure::openBottom(SlotIndex PrevBottom) {
183  if (BottomIdx > PrevBottom)
184    return;
185  BottomIdx = SlotIndex();
186  LiveInRegs.clear();
187}
188
189/// If the current bottom is the previous instr (before advancing), open it.
190void RegionPressure::openBottom(MachineBasicBlock::const_iterator PrevBottom) {
191  if (BottomPos != PrevBottom)
192    return;
193  BottomPos = MachineBasicBlock::const_iterator();
194  LiveInRegs.clear();
195}
196
197const LiveInterval *RegPressureTracker::getInterval(unsigned Reg) const {
198  if (TargetRegisterInfo::isVirtualRegister(Reg))
199    return &LIS->getInterval(Reg);
200  return LIS->getCachedRegUnit(Reg);
201}
202
203/// Setup the RegPressureTracker.
204///
205/// TODO: Add support for pressure without LiveIntervals.
206void RegPressureTracker::init(const MachineFunction *mf,
207                              const RegisterClassInfo *rci,
208                              const LiveIntervals *lis,
209                              const MachineBasicBlock *mbb,
210                              MachineBasicBlock::const_iterator pos,
211                              bool ShouldTrackUntiedDefs)
212{
213  MF = mf;
214  TRI = MF->getTarget().getRegisterInfo();
215  RCI = rci;
216  MRI = &MF->getRegInfo();
217  MBB = mbb;
218  TrackUntiedDefs = ShouldTrackUntiedDefs;
219
220  if (RequireIntervals) {
221    assert(lis && "IntervalPressure requires LiveIntervals");
222    LIS = lis;
223  }
224
225  CurrPos = pos;
226  CurrSetPressure.assign(TRI->getNumRegPressureSets(), 0);
227  LiveThruPressure.clear();
228
229  if (RequireIntervals)
230    static_cast<IntervalPressure&>(P).reset();
231  else
232    static_cast<RegionPressure&>(P).reset();
233  P.MaxSetPressure = CurrSetPressure;
234
235  LiveRegs.PhysRegs.clear();
236  LiveRegs.PhysRegs.setUniverse(TRI->getNumRegs());
237  LiveRegs.VirtRegs.clear();
238  LiveRegs.VirtRegs.setUniverse(MRI->getNumVirtRegs());
239  UntiedDefs.clear();
240  if (TrackUntiedDefs)
241    UntiedDefs.setUniverse(MRI->getNumVirtRegs());
242}
243
244/// Does this pressure result have a valid top position and live ins.
245bool RegPressureTracker::isTopClosed() const {
246  if (RequireIntervals)
247    return static_cast<IntervalPressure&>(P).TopIdx.isValid();
248  return (static_cast<RegionPressure&>(P).TopPos ==
249          MachineBasicBlock::const_iterator());
250}
251
252/// Does this pressure result have a valid bottom position and live outs.
253bool RegPressureTracker::isBottomClosed() const {
254  if (RequireIntervals)
255    return static_cast<IntervalPressure&>(P).BottomIdx.isValid();
256  return (static_cast<RegionPressure&>(P).BottomPos ==
257          MachineBasicBlock::const_iterator());
258}
259
260
261SlotIndex RegPressureTracker::getCurrSlot() const {
262  MachineBasicBlock::const_iterator IdxPos = CurrPos;
263  while (IdxPos != MBB->end() && IdxPos->isDebugValue())
264    ++IdxPos;
265  if (IdxPos == MBB->end())
266    return LIS->getMBBEndIdx(MBB);
267  return LIS->getInstructionIndex(IdxPos).getRegSlot();
268}
269
270/// Set the boundary for the top of the region and summarize live ins.
271void RegPressureTracker::closeTop() {
272  if (RequireIntervals)
273    static_cast<IntervalPressure&>(P).TopIdx = getCurrSlot();
274  else
275    static_cast<RegionPressure&>(P).TopPos = CurrPos;
276
277  assert(P.LiveInRegs.empty() && "inconsistent max pressure result");
278  P.LiveInRegs.reserve(LiveRegs.PhysRegs.size() + LiveRegs.VirtRegs.size());
279  P.LiveInRegs.append(LiveRegs.PhysRegs.begin(), LiveRegs.PhysRegs.end());
280  for (SparseSet<unsigned>::const_iterator I =
281         LiveRegs.VirtRegs.begin(), E = LiveRegs.VirtRegs.end(); I != E; ++I)
282    P.LiveInRegs.push_back(*I);
283  std::sort(P.LiveInRegs.begin(), P.LiveInRegs.end());
284  P.LiveInRegs.erase(std::unique(P.LiveInRegs.begin(), P.LiveInRegs.end()),
285                     P.LiveInRegs.end());
286}
287
288/// Set the boundary for the bottom of the region and summarize live outs.
289void RegPressureTracker::closeBottom() {
290  if (RequireIntervals)
291    static_cast<IntervalPressure&>(P).BottomIdx = getCurrSlot();
292  else
293    static_cast<RegionPressure&>(P).BottomPos = CurrPos;
294
295  assert(P.LiveOutRegs.empty() && "inconsistent max pressure result");
296  P.LiveOutRegs.reserve(LiveRegs.PhysRegs.size() + LiveRegs.VirtRegs.size());
297  P.LiveOutRegs.append(LiveRegs.PhysRegs.begin(), LiveRegs.PhysRegs.end());
298  for (SparseSet<unsigned>::const_iterator I =
299         LiveRegs.VirtRegs.begin(), E = LiveRegs.VirtRegs.end(); I != E; ++I)
300    P.LiveOutRegs.push_back(*I);
301  std::sort(P.LiveOutRegs.begin(), P.LiveOutRegs.end());
302  P.LiveOutRegs.erase(std::unique(P.LiveOutRegs.begin(), P.LiveOutRegs.end()),
303                      P.LiveOutRegs.end());
304}
305
306/// Finalize the region boundaries and record live ins and live outs.
307void RegPressureTracker::closeRegion() {
308  if (!isTopClosed() && !isBottomClosed()) {
309    assert(LiveRegs.PhysRegs.empty() && LiveRegs.VirtRegs.empty() &&
310           "no region boundary");
311    return;
312  }
313  if (!isBottomClosed())
314    closeBottom();
315  else if (!isTopClosed())
316    closeTop();
317  // If both top and bottom are closed, do nothing.
318}
319
320/// The register tracker is unaware of global liveness so ignores normal
321/// live-thru ranges. However, two-address or coalesced chains can also lead
322/// to live ranges with no holes. Count these to inform heuristics that we
323/// can never drop below this pressure.
324void RegPressureTracker::initLiveThru(const RegPressureTracker &RPTracker) {
325  LiveThruPressure.assign(TRI->getNumRegPressureSets(), 0);
326  assert(isBottomClosed() && "need bottom-up tracking to intialize.");
327  for (unsigned i = 0, e = P.LiveOutRegs.size(); i < e; ++i) {
328    unsigned Reg = P.LiveOutRegs[i];
329    if (TargetRegisterInfo::isVirtualRegister(Reg)
330        && !RPTracker.hasUntiedDef(Reg)) {
331      const TargetRegisterClass *RC = MRI->getRegClass(Reg);
332      increaseSetPressure(LiveThruPressure, LiveThruPressure,
333                          TRI->getRegClassPressureSets(RC),
334                          TRI->getRegClassWeight(RC).RegWeight);
335    }
336  }
337}
338
339/// \brief Convenient wrapper for checking membership in RegisterOperands.
340static bool containsReg(ArrayRef<unsigned> Regs, unsigned Reg) {
341  return std::find(Regs.begin(), Regs.end(), Reg) != Regs.end();
342}
343
344/// Collect this instruction's unique uses and defs into SmallVectors for
345/// processing defs and uses in order.
346class RegisterOperands {
347  const TargetRegisterInfo *TRI;
348  const MachineRegisterInfo *MRI;
349
350public:
351  SmallVector<unsigned, 8> Uses;
352  SmallVector<unsigned, 8> Defs;
353  SmallVector<unsigned, 8> DeadDefs;
354
355  RegisterOperands(const TargetRegisterInfo *tri,
356                   const MachineRegisterInfo *mri): TRI(tri), MRI(mri) {}
357
358  /// Push this operand's register onto the correct vector.
359  void collect(const MachineOperand &MO) {
360    if (!MO.isReg() || !MO.getReg())
361      return;
362    if (MO.readsReg())
363      pushRegUnits(MO.getReg(), Uses);
364    if (MO.isDef()) {
365      if (MO.isDead())
366        pushRegUnits(MO.getReg(), DeadDefs);
367      else
368        pushRegUnits(MO.getReg(), Defs);
369    }
370  }
371
372protected:
373  void pushRegUnits(unsigned Reg, SmallVectorImpl<unsigned> &Regs) {
374    if (TargetRegisterInfo::isVirtualRegister(Reg)) {
375      if (containsReg(Regs, Reg))
376        return;
377      Regs.push_back(Reg);
378    }
379    else if (MRI->isAllocatable(Reg)) {
380      for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units) {
381        if (containsReg(Regs, *Units))
382          continue;
383        Regs.push_back(*Units);
384      }
385    }
386  }
387};
388
389/// Collect physical and virtual register operands.
390static void collectOperands(const MachineInstr *MI,
391                            RegisterOperands &RegOpers) {
392  for (ConstMIBundleOperands OperI(MI); OperI.isValid(); ++OperI)
393    RegOpers.collect(*OperI);
394
395  // Remove redundant physreg dead defs.
396  SmallVectorImpl<unsigned>::iterator I =
397    std::remove_if(RegOpers.DeadDefs.begin(), RegOpers.DeadDefs.end(),
398                   std::bind1st(std::ptr_fun(containsReg), RegOpers.Defs));
399  RegOpers.DeadDefs.erase(I, RegOpers.DeadDefs.end());
400}
401
402/// Force liveness of registers.
403void RegPressureTracker::addLiveRegs(ArrayRef<unsigned> Regs) {
404  for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
405    if (LiveRegs.insert(Regs[i]))
406      increaseRegPressure(Regs[i]);
407  }
408}
409
410/// Add Reg to the live in set and increase max pressure.
411void RegPressureTracker::discoverLiveIn(unsigned Reg) {
412  assert(!LiveRegs.contains(Reg) && "avoid bumping max pressure twice");
413  if (containsReg(P.LiveInRegs, Reg))
414    return;
415
416  // At live in discovery, unconditionally increase the high water mark.
417  P.LiveInRegs.push_back(Reg);
418  P.increase(Reg, TRI, MRI);
419}
420
421/// Add Reg to the live out set and increase max pressure.
422void RegPressureTracker::discoverLiveOut(unsigned Reg) {
423  assert(!LiveRegs.contains(Reg) && "avoid bumping max pressure twice");
424  if (containsReg(P.LiveOutRegs, Reg))
425    return;
426
427  // At live out discovery, unconditionally increase the high water mark.
428  P.LiveOutRegs.push_back(Reg);
429  P.increase(Reg, TRI, MRI);
430}
431
432/// Recede across the previous instruction.
433bool RegPressureTracker::recede() {
434  // Check for the top of the analyzable region.
435  if (CurrPos == MBB->begin()) {
436    closeRegion();
437    return false;
438  }
439  if (!isBottomClosed())
440    closeBottom();
441
442  // Open the top of the region using block iterators.
443  if (!RequireIntervals && isTopClosed())
444    static_cast<RegionPressure&>(P).openTop(CurrPos);
445
446  // Find the previous instruction.
447  do
448    --CurrPos;
449  while (CurrPos != MBB->begin() && CurrPos->isDebugValue());
450
451  if (CurrPos->isDebugValue()) {
452    closeRegion();
453    return false;
454  }
455  SlotIndex SlotIdx;
456  if (RequireIntervals)
457    SlotIdx = LIS->getInstructionIndex(CurrPos).getRegSlot();
458
459  // Open the top of the region using slot indexes.
460  if (RequireIntervals && isTopClosed())
461    static_cast<IntervalPressure&>(P).openTop(SlotIdx);
462
463  RegisterOperands RegOpers(TRI, MRI);
464  collectOperands(CurrPos, RegOpers);
465
466  // Boost pressure for all dead defs together.
467  increaseRegPressure(RegOpers.DeadDefs);
468  decreaseRegPressure(RegOpers.DeadDefs);
469
470  // Kill liveness at live defs.
471  // TODO: consider earlyclobbers?
472  for (unsigned i = 0, e = RegOpers.Defs.size(); i < e; ++i) {
473    unsigned Reg = RegOpers.Defs[i];
474    if (LiveRegs.erase(Reg))
475      decreaseRegPressure(Reg);
476    else
477      discoverLiveOut(Reg);
478  }
479
480  // Generate liveness for uses.
481  for (unsigned i = 0, e = RegOpers.Uses.size(); i < e; ++i) {
482    unsigned Reg = RegOpers.Uses[i];
483    if (!LiveRegs.contains(Reg)) {
484      // Adjust liveouts if LiveIntervals are available.
485      if (RequireIntervals) {
486        const LiveInterval *LI = getInterval(Reg);
487        if (LI && !LI->killedAt(SlotIdx))
488          discoverLiveOut(Reg);
489      }
490      increaseRegPressure(Reg);
491      LiveRegs.insert(Reg);
492    }
493  }
494  if (TrackUntiedDefs) {
495    for (unsigned i = 0, e = RegOpers.Defs.size(); i < e; ++i) {
496      unsigned Reg = RegOpers.Defs[i];
497      if (TargetRegisterInfo::isVirtualRegister(Reg) && !LiveRegs.contains(Reg))
498        UntiedDefs.insert(Reg);
499    }
500  }
501  return true;
502}
503
504/// Advance across the current instruction.
505bool RegPressureTracker::advance() {
506  assert(!TrackUntiedDefs && "unsupported mode");
507
508  // Check for the bottom of the analyzable region.
509  if (CurrPos == MBB->end()) {
510    closeRegion();
511    return false;
512  }
513  if (!isTopClosed())
514    closeTop();
515
516  SlotIndex SlotIdx;
517  if (RequireIntervals)
518    SlotIdx = getCurrSlot();
519
520  // Open the bottom of the region using slot indexes.
521  if (isBottomClosed()) {
522    if (RequireIntervals)
523      static_cast<IntervalPressure&>(P).openBottom(SlotIdx);
524    else
525      static_cast<RegionPressure&>(P).openBottom(CurrPos);
526  }
527
528  RegisterOperands RegOpers(TRI, MRI);
529  collectOperands(CurrPos, RegOpers);
530
531  for (unsigned i = 0, e = RegOpers.Uses.size(); i < e; ++i) {
532    unsigned Reg = RegOpers.Uses[i];
533    // Discover live-ins.
534    bool isLive = LiveRegs.contains(Reg);
535    if (!isLive)
536      discoverLiveIn(Reg);
537    // Kill liveness at last uses.
538    bool lastUse = false;
539    if (RequireIntervals) {
540      const LiveInterval *LI = getInterval(Reg);
541      lastUse = LI && LI->killedAt(SlotIdx);
542    }
543    else {
544      // Allocatable physregs are always single-use before register rewriting.
545      lastUse = !TargetRegisterInfo::isVirtualRegister(Reg);
546    }
547    if (lastUse && isLive) {
548      LiveRegs.erase(Reg);
549      decreaseRegPressure(Reg);
550    }
551    else if (!lastUse && !isLive)
552      increaseRegPressure(Reg);
553  }
554
555  // Generate liveness for defs.
556  for (unsigned i = 0, e = RegOpers.Defs.size(); i < e; ++i) {
557    unsigned Reg = RegOpers.Defs[i];
558    if (LiveRegs.insert(Reg))
559      increaseRegPressure(Reg);
560  }
561
562  // Boost pressure for all dead defs together.
563  increaseRegPressure(RegOpers.DeadDefs);
564  decreaseRegPressure(RegOpers.DeadDefs);
565
566  // Find the next instruction.
567  do
568    ++CurrPos;
569  while (CurrPos != MBB->end() && CurrPos->isDebugValue());
570  return true;
571}
572
573/// Find the max change in excess pressure across all sets.
574static void computeExcessPressureDelta(ArrayRef<unsigned> OldPressureVec,
575                                       ArrayRef<unsigned> NewPressureVec,
576                                       RegPressureDelta &Delta,
577                                       const RegisterClassInfo *RCI,
578                                       ArrayRef<unsigned> LiveThruPressureVec) {
579  int ExcessUnits = 0;
580  unsigned PSetID = ~0U;
581  for (unsigned i = 0, e = OldPressureVec.size(); i < e; ++i) {
582    unsigned POld = OldPressureVec[i];
583    unsigned PNew = NewPressureVec[i];
584    int PDiff = (int)PNew - (int)POld;
585    if (!PDiff) // No change in this set in the common case.
586      continue;
587    // Only consider change beyond the limit.
588    unsigned Limit = RCI->getRegPressureSetLimit(i);
589    if (!LiveThruPressureVec.empty())
590      Limit += LiveThruPressureVec[i];
591
592    if (Limit > POld) {
593      if (Limit > PNew)
594        PDiff = 0;            // Under the limit
595      else
596        PDiff = PNew - Limit; // Just exceeded limit.
597    }
598    else if (Limit > PNew)
599      PDiff = Limit - POld;   // Just obeyed limit.
600
601    if (PDiff) {
602      ExcessUnits = PDiff;
603      PSetID = i;
604      break;
605    }
606  }
607  Delta.Excess.PSetID = PSetID;
608  Delta.Excess.UnitIncrease = ExcessUnits;
609}
610
611/// Find the max change in max pressure that either surpasses a critical PSet
612/// limit or exceeds the current MaxPressureLimit.
613///
614/// FIXME: comparing each element of the old and new MaxPressure vectors here is
615/// silly. It's done now to demonstrate the concept but will go away with a
616/// RegPressureTracker API change to work with pressure differences.
617static void computeMaxPressureDelta(ArrayRef<unsigned> OldMaxPressureVec,
618                                    ArrayRef<unsigned> NewMaxPressureVec,
619                                    ArrayRef<PressureElement> CriticalPSets,
620                                    ArrayRef<unsigned> MaxPressureLimit,
621                                    RegPressureDelta &Delta) {
622  Delta.CriticalMax = PressureElement();
623  Delta.CurrentMax = PressureElement();
624
625  unsigned CritIdx = 0, CritEnd = CriticalPSets.size();
626  for (unsigned i = 0, e = OldMaxPressureVec.size(); i < e; ++i) {
627    unsigned POld = OldMaxPressureVec[i];
628    unsigned PNew = NewMaxPressureVec[i];
629    if (PNew == POld) // No change in this set in the common case.
630      continue;
631
632    if (!Delta.CriticalMax.isValid()) {
633      while (CritIdx != CritEnd && CriticalPSets[CritIdx].PSetID < i)
634        ++CritIdx;
635
636      if (CritIdx != CritEnd && CriticalPSets[CritIdx].PSetID == i) {
637        int PDiff = (int)PNew - (int)CriticalPSets[CritIdx].UnitIncrease;
638        if (PDiff > 0) {
639          Delta.CriticalMax.PSetID = i;
640          Delta.CriticalMax.UnitIncrease = PDiff;
641        }
642      }
643    }
644    // Find the first increase above MaxPressureLimit.
645    // (Ignores negative MDiff).
646    if (!Delta.CurrentMax.isValid()) {
647      int MDiff = (int)PNew - (int)MaxPressureLimit[i];
648      if (MDiff > 0) {
649        Delta.CurrentMax.PSetID = i;
650        Delta.CurrentMax.UnitIncrease = MDiff;
651        if (CritIdx == CritEnd || Delta.CriticalMax.isValid())
652          break;
653      }
654    }
655  }
656}
657
658/// Record the upward impact of a single instruction on current register
659/// pressure. Unlike the advance/recede pressure tracking interface, this does
660/// not discover live in/outs.
661///
662/// This is intended for speculative queries. It leaves pressure inconsistent
663/// with the current position, so must be restored by the caller.
664void RegPressureTracker::bumpUpwardPressure(const MachineInstr *MI) {
665  assert(!MI->isDebugValue() && "Expect a nondebug instruction.");
666
667  // Account for register pressure similar to RegPressureTracker::recede().
668  RegisterOperands RegOpers(TRI, MRI);
669  collectOperands(MI, RegOpers);
670
671  // Boost max pressure for all dead defs together.
672  // Since CurrSetPressure and MaxSetPressure
673  increaseRegPressure(RegOpers.DeadDefs);
674  decreaseRegPressure(RegOpers.DeadDefs);
675
676  // Kill liveness at live defs.
677  for (unsigned i = 0, e = RegOpers.Defs.size(); i < e; ++i) {
678    unsigned Reg = RegOpers.Defs[i];
679    if (!containsReg(RegOpers.Uses, Reg))
680      decreaseRegPressure(Reg);
681  }
682  // Generate liveness for uses.
683  for (unsigned i = 0, e = RegOpers.Uses.size(); i < e; ++i) {
684    unsigned Reg = RegOpers.Uses[i];
685    if (!LiveRegs.contains(Reg))
686      increaseRegPressure(Reg);
687  }
688}
689
690/// Consider the pressure increase caused by traversing this instruction
691/// bottom-up. Find the pressure set with the most change beyond its pressure
692/// limit based on the tracker's current pressure, and return the change in
693/// number of register units of that pressure set introduced by this
694/// instruction.
695///
696/// This assumes that the current LiveOut set is sufficient.
697///
698/// FIXME: This is expensive for an on-the-fly query. We need to cache the
699/// result per-SUnit with enough information to adjust for the current
700/// scheduling position. But this works as a proof of concept.
701void RegPressureTracker::
702getMaxUpwardPressureDelta(const MachineInstr *MI, RegPressureDelta &Delta,
703                          ArrayRef<PressureElement> CriticalPSets,
704                          ArrayRef<unsigned> MaxPressureLimit) {
705  // Snapshot Pressure.
706  // FIXME: The snapshot heap space should persist. But I'm planning to
707  // summarize the pressure effect so we don't need to snapshot at all.
708  std::vector<unsigned> SavedPressure = CurrSetPressure;
709  std::vector<unsigned> SavedMaxPressure = P.MaxSetPressure;
710
711  bumpUpwardPressure(MI);
712
713  computeExcessPressureDelta(SavedPressure, CurrSetPressure, Delta, RCI,
714                             LiveThruPressure);
715  computeMaxPressureDelta(SavedMaxPressure, P.MaxSetPressure, CriticalPSets,
716                          MaxPressureLimit, Delta);
717  assert(Delta.CriticalMax.UnitIncrease >= 0 &&
718         Delta.CurrentMax.UnitIncrease >= 0 && "cannot decrease max pressure");
719
720  // Restore the tracker's state.
721  P.MaxSetPressure.swap(SavedMaxPressure);
722  CurrSetPressure.swap(SavedPressure);
723}
724
725/// Helper to find a vreg use between two indices [PriorUseIdx, NextUseIdx).
726static bool findUseBetween(unsigned Reg,
727                           SlotIndex PriorUseIdx, SlotIndex NextUseIdx,
728                           const MachineRegisterInfo *MRI,
729                           const LiveIntervals *LIS) {
730  for (MachineRegisterInfo::use_nodbg_iterator
731         UI = MRI->use_nodbg_begin(Reg), UE = MRI->use_nodbg_end();
732         UI != UE; UI.skipInstruction()) {
733      const MachineInstr* MI = &*UI;
734      if (MI->isDebugValue())
735        continue;
736      SlotIndex InstSlot = LIS->getInstructionIndex(MI).getRegSlot();
737      if (InstSlot >= PriorUseIdx && InstSlot < NextUseIdx)
738        return true;
739  }
740  return false;
741}
742
743/// Record the downward impact of a single instruction on current register
744/// pressure. Unlike the advance/recede pressure tracking interface, this does
745/// not discover live in/outs.
746///
747/// This is intended for speculative queries. It leaves pressure inconsistent
748/// with the current position, so must be restored by the caller.
749void RegPressureTracker::bumpDownwardPressure(const MachineInstr *MI) {
750  assert(!MI->isDebugValue() && "Expect a nondebug instruction.");
751
752  // Account for register pressure similar to RegPressureTracker::recede().
753  RegisterOperands RegOpers(TRI, MRI);
754  collectOperands(MI, RegOpers);
755
756  // Kill liveness at last uses. Assume allocatable physregs are single-use
757  // rather than checking LiveIntervals.
758  SlotIndex SlotIdx;
759  if (RequireIntervals)
760    SlotIdx = LIS->getInstructionIndex(MI).getRegSlot();
761
762  for (unsigned i = 0, e = RegOpers.Uses.size(); i < e; ++i) {
763    unsigned Reg = RegOpers.Uses[i];
764    if (RequireIntervals) {
765      // FIXME: allow the caller to pass in the list of vreg uses that remain
766      // to be bottom-scheduled to avoid searching uses at each query.
767      SlotIndex CurrIdx = getCurrSlot();
768      const LiveInterval *LI = getInterval(Reg);
769      if (LI && LI->killedAt(SlotIdx)
770          && !findUseBetween(Reg, CurrIdx, SlotIdx, MRI, LIS)) {
771        decreaseRegPressure(Reg);
772      }
773    }
774    else if (!TargetRegisterInfo::isVirtualRegister(Reg)) {
775      // Allocatable physregs are always single-use before register rewriting.
776      decreaseRegPressure(Reg);
777    }
778  }
779
780  // Generate liveness for defs.
781  increaseRegPressure(RegOpers.Defs);
782
783  // Boost pressure for all dead defs together.
784  increaseRegPressure(RegOpers.DeadDefs);
785  decreaseRegPressure(RegOpers.DeadDefs);
786}
787
788/// Consider the pressure increase caused by traversing this instruction
789/// top-down. Find the register class with the most change in its pressure limit
790/// based on the tracker's current pressure, and return the number of excess
791/// register units of that pressure set introduced by this instruction.
792///
793/// This assumes that the current LiveIn set is sufficient.
794void RegPressureTracker::
795getMaxDownwardPressureDelta(const MachineInstr *MI, RegPressureDelta &Delta,
796                            ArrayRef<PressureElement> CriticalPSets,
797                            ArrayRef<unsigned> MaxPressureLimit) {
798  // Snapshot Pressure.
799  std::vector<unsigned> SavedPressure = CurrSetPressure;
800  std::vector<unsigned> SavedMaxPressure = P.MaxSetPressure;
801
802  bumpDownwardPressure(MI);
803
804  computeExcessPressureDelta(SavedPressure, CurrSetPressure, Delta, RCI,
805                             LiveThruPressure);
806  computeMaxPressureDelta(SavedMaxPressure, P.MaxSetPressure, CriticalPSets,
807                          MaxPressureLimit, Delta);
808  assert(Delta.CriticalMax.UnitIncrease >= 0 &&
809         Delta.CurrentMax.UnitIncrease >= 0 && "cannot decrease max pressure");
810
811  // Restore the tracker's state.
812  P.MaxSetPressure.swap(SavedMaxPressure);
813  CurrSetPressure.swap(SavedPressure);
814}
815
816/// Get the pressure of each PSet after traversing this instruction bottom-up.
817void RegPressureTracker::
818getUpwardPressure(const MachineInstr *MI,
819                  std::vector<unsigned> &PressureResult,
820                  std::vector<unsigned> &MaxPressureResult) {
821  // Snapshot pressure.
822  PressureResult = CurrSetPressure;
823  MaxPressureResult = P.MaxSetPressure;
824
825  bumpUpwardPressure(MI);
826
827  // Current pressure becomes the result. Restore current pressure.
828  P.MaxSetPressure.swap(MaxPressureResult);
829  CurrSetPressure.swap(PressureResult);
830}
831
832/// Get the pressure of each PSet after traversing this instruction top-down.
833void RegPressureTracker::
834getDownwardPressure(const MachineInstr *MI,
835                    std::vector<unsigned> &PressureResult,
836                    std::vector<unsigned> &MaxPressureResult) {
837  // Snapshot pressure.
838  PressureResult = CurrSetPressure;
839  MaxPressureResult = P.MaxSetPressure;
840
841  bumpDownwardPressure(MI);
842
843  // Current pressure becomes the result. Restore current pressure.
844  P.MaxSetPressure.swap(MaxPressureResult);
845  CurrSetPressure.swap(PressureResult);
846}
847