RegisterPressure: Move LiveInRegs/LiveOutRegs from RegisterPressure to PressureTracker
[oota-llvm.git] / lib / CodeGen / RegisterPressure.cpp
index 092ecdd9bb256e185ee6671412dd01df9aa7c3e8..5a0b221c803427fe27b2889c43198827a1212921 100644 (file)
@@ -19,7 +19,6 @@
 #include "llvm/CodeGen/RegisterClassInfo.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetMachine.h"
 
 using namespace llvm;
 
@@ -41,7 +40,7 @@ static void decreaseSetPressure(std::vector<unsigned> &CurrSetPressure,
   }
 }
 
-#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+LLVM_DUMP_METHOD
 void llvm::dumpRegSetPressure(ArrayRef<unsigned> SetPressure,
                               const TargetRegisterInfo *TRI) {
   bool Empty = true;
@@ -55,27 +54,38 @@ void llvm::dumpRegSetPressure(ArrayRef<unsigned> SetPressure,
     dbgs() << "\n";
 }
 
+LLVM_DUMP_METHOD
 void RegisterPressure::dump(const TargetRegisterInfo *TRI) const {
   dbgs() << "Max Pressure: ";
   dumpRegSetPressure(MaxSetPressure, TRI);
+}
+
+LLVM_DUMP_METHOD
+void RegPressureTracker::dump() const {
+  if (!isTopClosed() || !isBottomClosed()) {
+    dbgs() << "Curr Pressure: ";
+    dumpRegSetPressure(CurrSetPressure, TRI);
+  }
+  P.dump(TRI);
   dbgs() << "Live In: ";
   for (unsigned i = 0, e = LiveInRegs.size(); i < e; ++i)
-    dbgs() << PrintReg(LiveInRegs[i], TRI) << " ";
+    dbgs() << PrintVRegOrUnit(LiveInRegs[i], TRI) << " ";
   dbgs() << '\n';
   dbgs() << "Live Out: ";
   for (unsigned i = 0, e = LiveOutRegs.size(); i < e; ++i)
-    dbgs() << PrintReg(LiveOutRegs[i], TRI) << " ";
+    dbgs() << PrintVRegOrUnit(LiveOutRegs[i], TRI) << " ";
   dbgs() << '\n';
 }
 
-void RegPressureTracker::dump() const {
-  if (!isTopClosed() || !isBottomClosed()) {
-    dbgs() << "Curr Pressure: ";
-    dumpRegSetPressure(CurrSetPressure, TRI);
+void PressureDiff::dump(const TargetRegisterInfo &TRI) const {
+  for (const PressureChange &Change : *this) {
+    if (!Change.isValid() || Change.getUnitInc() == 0)
+      continue;
+    dbgs() << "    " << TRI.getRegPressureSetName(Change.getPSet())
+           << " " << Change.getUnitInc();
   }
-  P.dump(TRI);
+  dbgs() << '\n';
 }
-#endif
 
 /// Increase the current pressure as impacted by these registers and bump
 /// the high water mark if needed.
@@ -102,16 +112,12 @@ void RegPressureTracker::decreaseRegPressure(ArrayRef<unsigned> RegUnits) {
 void IntervalPressure::reset() {
   TopIdx = BottomIdx = SlotIndex();
   MaxSetPressure.clear();
-  LiveInRegs.clear();
-  LiveOutRegs.clear();
 }
 
 /// Clear the result so it can be used for another round of pressure tracking.
 void RegionPressure::reset() {
   TopPos = BottomPos = MachineBasicBlock::const_iterator();
   MaxSetPressure.clear();
-  LiveInRegs.clear();
-  LiveOutRegs.clear();
 }
 
 /// If the current top is not less than or equal to the next index, open it.
@@ -120,7 +126,6 @@ void IntervalPressure::openTop(SlotIndex NextTop) {
   if (TopIdx <= NextTop)
     return;
   TopIdx = SlotIndex();
-  LiveInRegs.clear();
 }
 
 /// If the current top is the previous instruction (before receding), open it.
@@ -128,7 +133,6 @@ void RegionPressure::openTop(MachineBasicBlock::const_iterator PrevTop) {
   if (TopPos != PrevTop)
     return;
   TopPos = MachineBasicBlock::const_iterator();
-  LiveInRegs.clear();
 }
 
 /// If the current bottom is not greater than the previous index, open it.
@@ -136,7 +140,6 @@ void IntervalPressure::openBottom(SlotIndex PrevBottom) {
   if (BottomIdx > PrevBottom)
     return;
   BottomIdx = SlotIndex();
-  LiveInRegs.clear();
 }
 
 /// If the current bottom is the previous instr (before advancing), open it.
@@ -144,7 +147,6 @@ void RegionPressure::openBottom(MachineBasicBlock::const_iterator PrevBottom) {
   if (BottomPos != PrevBottom)
     return;
   BottomPos = MachineBasicBlock::const_iterator();
-  LiveInRegs.clear();
 }
 
 const LiveRange *RegPressureTracker::getLiveRange(unsigned Reg) const {
@@ -154,8 +156,8 @@ const LiveRange *RegPressureTracker::getLiveRange(unsigned Reg) const {
 }
 
 void RegPressureTracker::reset() {
-  MBB = 0;
-  LIS = 0;
+  MBB = nullptr;
+  LIS = nullptr;
 
   CurrSetPressure.clear();
   LiveThruPressure.clear();
@@ -165,6 +167,8 @@ void RegPressureTracker::reset() {
     static_cast<IntervalPressure&>(P).reset();
   else
     static_cast<RegionPressure&>(P).reset();
+  LiveInRegs.clear();
+  LiveOutRegs.clear();
 
   LiveRegs.PhysRegs.clear();
   LiveRegs.VirtRegs.clear();
@@ -184,7 +188,7 @@ void RegPressureTracker::init(const MachineFunction *mf,
   reset();
 
   MF = mf;
-  TRI = MF->getTarget().getRegisterInfo();
+  TRI = MF->getSubtarget().getRegisterInfo();
   RCI = rci;
   MRI = &MF->getRegInfo();
   MBB = mbb;
@@ -239,15 +243,10 @@ void RegPressureTracker::closeTop() {
   else
     static_cast<RegionPressure&>(P).TopPos = CurrPos;
 
-  assert(P.LiveInRegs.empty() && "inconsistent max pressure result");
-  P.LiveInRegs.reserve(LiveRegs.PhysRegs.size() + LiveRegs.VirtRegs.size());
-  P.LiveInRegs.append(LiveRegs.PhysRegs.begin(), LiveRegs.PhysRegs.end());
-  for (SparseSet<unsigned>::const_iterator I =
-         LiveRegs.VirtRegs.begin(), E = LiveRegs.VirtRegs.end(); I != E; ++I)
-    P.LiveInRegs.push_back(*I);
-  std::sort(P.LiveInRegs.begin(), P.LiveInRegs.end());
-  P.LiveInRegs.erase(std::unique(P.LiveInRegs.begin(), P.LiveInRegs.end()),
-                     P.LiveInRegs.end());
+  assert(LiveInRegs.empty() && "inconsistent max pressure result");
+  LiveInRegs.reserve(LiveRegs.PhysRegs.size() + LiveRegs.VirtRegs.size());
+  LiveInRegs.append(LiveRegs.PhysRegs.begin(), LiveRegs.PhysRegs.end());
+  LiveInRegs.append(LiveRegs.VirtRegs.begin(), LiveRegs.VirtRegs.end());
 }
 
 /// Set the boundary for the bottom of the region and summarize live outs.
@@ -257,15 +256,10 @@ void RegPressureTracker::closeBottom() {
   else
     static_cast<RegionPressure&>(P).BottomPos = CurrPos;
 
-  assert(P.LiveOutRegs.empty() && "inconsistent max pressure result");
-  P.LiveOutRegs.reserve(LiveRegs.PhysRegs.size() + LiveRegs.VirtRegs.size());
-  P.LiveOutRegs.append(LiveRegs.PhysRegs.begin(), LiveRegs.PhysRegs.end());
-  for (SparseSet<unsigned>::const_iterator I =
-         LiveRegs.VirtRegs.begin(), E = LiveRegs.VirtRegs.end(); I != E; ++I)
-    P.LiveOutRegs.push_back(*I);
-  std::sort(P.LiveOutRegs.begin(), P.LiveOutRegs.end());
-  P.LiveOutRegs.erase(std::unique(P.LiveOutRegs.begin(), P.LiveOutRegs.end()),
-                      P.LiveOutRegs.end());
+  assert(LiveOutRegs.empty() && "inconsistent max pressure result");
+  LiveOutRegs.reserve(LiveRegs.PhysRegs.size() + LiveRegs.VirtRegs.size());
+  LiveOutRegs.append(LiveRegs.PhysRegs.begin(), LiveRegs.PhysRegs.end());
+  LiveOutRegs.append(LiveRegs.VirtRegs.begin(), LiveRegs.VirtRegs.end());
 }
 
 /// Finalize the region boundaries and record live ins and live outs.
@@ -289,8 +283,8 @@ void RegPressureTracker::closeRegion() {
 void RegPressureTracker::initLiveThru(const RegPressureTracker &RPTracker) {
   LiveThruPressure.assign(TRI->getNumRegPressureSets(), 0);
   assert(isBottomClosed() && "need bottom-up tracking to intialize.");
-  for (unsigned i = 0, e = P.LiveOutRegs.size(); i < e; ++i) {
-    unsigned Reg = P.LiveOutRegs[i];
+  for (unsigned i = 0, e = LiveOutRegs.size(); i < e; ++i) {
+    unsigned Reg = LiveOutRegs[i];
     if (TargetRegisterInfo::isVirtualRegister(Reg)
         && !RPTracker.hasUntiedDef(Reg)) {
       increaseSetPressure(LiveThruPressure, MRI->getPressureSets(Reg));
@@ -304,6 +298,7 @@ static bool containsReg(ArrayRef<unsigned> RegUnits, unsigned RegUnit) {
   return std::find(RegUnits.begin(), RegUnits.end(), RegUnit) != RegUnits.end();
 }
 
+namespace {
 /// Collect this instruction's unique uses and defs into SmallVectors for
 /// processing defs and uses in order.
 ///
@@ -354,6 +349,7 @@ protected:
     }
   }
 };
+} // namespace
 
 /// Collect physical and virtual register operands.
 static void collectOperands(const MachineInstr *MI,
@@ -429,22 +425,22 @@ void RegPressureTracker::addLiveRegs(ArrayRef<unsigned> Regs) {
 /// Add Reg to the live in set and increase max pressure.
 void RegPressureTracker::discoverLiveIn(unsigned Reg) {
   assert(!LiveRegs.contains(Reg) && "avoid bumping max pressure twice");
-  if (containsReg(P.LiveInRegs, Reg))
+  if (containsReg(LiveInRegs, Reg))
     return;
 
   // At live in discovery, unconditionally increase the high water mark.
-  P.LiveInRegs.push_back(Reg);
+  LiveInRegs.push_back(Reg);
   increaseSetPressure(P.MaxSetPressure, MRI->getPressureSets(Reg));
 }
 
 /// Add Reg to the live out set and increase max pressure.
 void RegPressureTracker::discoverLiveOut(unsigned Reg) {
   assert(!LiveRegs.contains(Reg) && "avoid bumping max pressure twice");
-  if (containsReg(P.LiveOutRegs, Reg))
+  if (containsReg(LiveOutRegs, Reg))
     return;
 
   // At live out discovery, unconditionally increase the high water mark.
-  P.LiveOutRegs.push_back(Reg);
+  LiveOutRegs.push_back(Reg);
   increaseSetPressure(P.MaxSetPressure, MRI->getPressureSets(Reg));
 }
 
@@ -481,8 +477,11 @@ bool RegPressureTracker::recede(SmallVectorImpl<unsigned> *LiveUses,
     SlotIdx = LIS->getInstructionIndex(CurrPos).getRegSlot();
 
   // Open the top of the region using slot indexes.
-  if (RequireIntervals && isTopClosed())
-    static_cast<IntervalPressure&>(P).openTop(SlotIdx);
+  if (isTopClosed()) {
+    if (RequireIntervals)
+      static_cast<IntervalPressure&>(P).openTop(SlotIdx);
+    LiveInRegs.clear();
+  }
 
   RegisterOperands RegOpers(TRI, MRI);
   collectOperands(CurrPos, RegOpers);
@@ -506,7 +505,13 @@ bool RegPressureTracker::recede(SmallVectorImpl<unsigned> *LiveUses,
         DeadDef = LRQ.isDeadDef();
       }
     }
-    if (!DeadDef) {
+    if (DeadDef) {
+      // LiveIntervals knows this is a dead even though it's MachineOperand is
+      // not flagged as such. Since this register will not be recorded as
+      // live-out, increase its PDiff value to avoid underflowing pressure.
+      if (PDiff)
+        PDiff->addPressureChange(Reg, false, MRI);
+    } else {
       if (LiveRegs.erase(Reg))
         decreaseRegPressure(Reg);
       else
@@ -565,6 +570,7 @@ bool RegPressureTracker::advance() {
       static_cast<IntervalPressure&>(P).openBottom(SlotIdx);
     else
       static_cast<RegionPressure&>(P).openBottom(CurrPos);
+    LiveOutRegs.clear();
   }
 
   RegisterOperands RegOpers(TRI, MRI);
@@ -742,9 +748,11 @@ void RegPressureTracker::bumpUpwardPressure(const MachineInstr *MI) {
 ///
 /// This assumes that the current LiveOut set is sufficient.
 ///
-/// FIXME: This is expensive for an on-the-fly query. We need to cache the
-/// result per-SUnit with enough information to adjust for the current
-/// scheduling position. But this works as a proof of concept.
+/// This is expensive for an on-the-fly query because it calls
+/// bumpUpwardPressure to recompute the pressure sets based on current
+/// liveness. This mainly exists to verify correctness, e.g. with
+/// -verify-misched. getUpwardPressureDelta is the fast version of this query
+/// that uses the per-SUnit cache of the PressureDiff.
 void RegPressureTracker::
 getMaxUpwardPressureDelta(const MachineInstr *MI, PressureDiff *PDiff,
                           RegPressureDelta &Delta,
@@ -777,6 +785,8 @@ getMaxUpwardPressureDelta(const MachineInstr *MI, PressureDiff *PDiff,
   RegPressureDelta Delta2;
   getUpwardPressureDelta(MI, *PDiff, Delta2, CriticalPSets, MaxPressureLimit);
   if (Delta != Delta2) {
+    dbgs() << "PDiff: ";
+    PDiff->dump(*TRI);
     dbgs() << "DELTA: " << *MI;
     if (Delta.Excess.isValid())
       dbgs() << "Excess1 " << TRI->getRegPressureSetName(Delta.Excess.getPSet())
@@ -801,10 +811,8 @@ getMaxUpwardPressureDelta(const MachineInstr *MI, PressureDiff *PDiff,
 #endif
 }
 
-/// This is a prototype of the fast version of querying register pressure that
-/// does not directly depend on current liveness. It's still slow because we
-/// recompute pressure change on-the-fly. This implementation only exists to
-/// prove correctness.
+/// This is the fast version of querying register pressure that does not
+/// directly depend on current liveness.
 ///
 /// @param Delta captures information needed for heuristics.
 ///
@@ -876,9 +884,9 @@ static bool findUseBetween(unsigned Reg,
                            SlotIndex PriorUseIdx, SlotIndex NextUseIdx,
                            const MachineRegisterInfo *MRI,
                            const LiveIntervals *LIS) {
-  for (MachineRegisterInfo::use_nodbg_iterator
-         UI = MRI->use_nodbg_begin(Reg), UE = MRI->use_nodbg_end();
-         UI != UE; UI.skipInstruction()) {
+  for (MachineRegisterInfo::use_instr_nodbg_iterator
+       UI = MRI->use_instr_nodbg_begin(Reg),
+       UE = MRI->use_instr_nodbg_end(); UI != UE; ++UI) {
       const MachineInstr* MI = &*UI;
       if (MI->isDebugValue())
         continue;
@@ -942,6 +950,11 @@ void RegPressureTracker::bumpDownwardPressure(const MachineInstr *MI) {
 /// register units of that pressure set introduced by this instruction.
 ///
 /// This assumes that the current LiveIn set is sufficient.
+///
+/// This is expensive for an on-the-fly query because it calls
+/// bumpDownwardPressure to recompute the pressure sets based on current
+/// liveness. We don't yet have a fast version of downward pressure tracking
+/// analogous to getUpwardPressureDelta.
 void RegPressureTracker::
 getMaxDownwardPressureDelta(const MachineInstr *MI, RegPressureDelta &Delta,
                             ArrayRef<PressureChange> CriticalPSets,