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