Merging r257940:
[oota-llvm.git] / include / llvm / CodeGen / RegisterPressure.h
index a801d1d1eee9bcf4ace6c10896d626159e62d223..9bbdf3e071bd641ceafb9cc220c06666e7f11f3b 100644 (file)
@@ -35,21 +35,6 @@ struct RegisterPressure {
   SmallVector<unsigned,8> LiveInRegs;
   SmallVector<unsigned,8> LiveOutRegs;
 
-  /// Increase register pressure for each pressure set impacted by this register
-  /// class. Normally called by RegPressureTracker, but may be called manually
-  /// to account for live through (global liveness).
-  ///
-  /// \param Reg is either a virtual register number or register unit number.
-  void increase(unsigned Reg, const TargetRegisterInfo *TRI,
-                const MachineRegisterInfo *MRI);
-
-  /// Decrease register pressure for each pressure set impacted by this register
-  /// class. This is only useful to account for spilling or rematerialization.
-  ///
-  /// \param Reg is either a virtual register number or register unit number.
-  void decrease(unsigned Reg, const TargetRegisterInfo *TRI,
-                const MachineRegisterInfo *MRI);
-
   void dump(const TargetRegisterInfo *TRI) const;
 };
 
@@ -140,16 +125,42 @@ class PressureDiff {
   enum { MaxPSets = 16 };
 
   PressureChange PressureChanges[MaxPSets];
-public:
+
   typedef PressureChange* iterator;
+  iterator nonconst_begin() { return &PressureChanges[0]; }
+  iterator nonconst_end() { return &PressureChanges[MaxPSets]; }
+
+public:
   typedef const PressureChange* const_iterator;
-  iterator begin() { return &PressureChanges[0]; }
-  iterator end() { return &PressureChanges[MaxPSets]; }
   const_iterator begin() const { return &PressureChanges[0]; }
   const_iterator end() const { return &PressureChanges[MaxPSets]; }
 
   void addPressureChange(unsigned RegUnit, bool IsDec,
                          const MachineRegisterInfo *MRI);
+
+  LLVM_DUMP_METHOD void dump(const TargetRegisterInfo &TRI) const;
+};
+
+/// List of registers defined and used by a machine instruction.
+class RegisterOperands {
+public:
+  /// List of virtual regiserts and register units read by the instruction.
+  SmallVector<unsigned, 8> Uses;
+  /// \brief List of virtual registers and register units defined by the
+  /// instruction which are not dead.
+  SmallVector<unsigned, 8> Defs;
+  /// \brief List of virtual registers and register units defined by the
+  /// instruction but dead.
+  SmallVector<unsigned, 8> DeadDefs;
+
+  /// Analyze the given instruction \p MI and fill in the Uses, Defs and
+  /// DeadDefs list based on the MachineOperand flags.
+  void collect(const MachineInstr &MI, const TargetRegisterInfo &TRI,
+               const MachineRegisterInfo &MRI, bool IgnoreDead = false);
+
+  /// Use liveness information to find dead defs not marked with a dead flag
+  /// and move them to the DeadDefs vector.
+  void detectDeadDefs(const MachineInstr &MI, const LiveIntervals &LIS);
 };
 
 /// Array of PressureDiffs.
@@ -158,7 +169,7 @@ class PressureDiffs {
   unsigned Size;
   unsigned Max;
 public:
-  PressureDiffs(): PDiffArray(0), Size(0), Max(0) {}
+  PressureDiffs(): PDiffArray(nullptr), Size(0), Max(0) {}
   ~PressureDiffs() { free(PDiffArray); }
 
   void clear() { Size = 0; }
@@ -172,6 +183,10 @@ public:
   const PressureDiff &operator[](unsigned Idx) const {
     return const_cast<PressureDiffs*>(this)->operator[](Idx);
   }
+  /// \brief Record pressure difference induced by the given operand list to
+  /// node with index \p Idx.
+  void addInstruction(unsigned Idx, const RegisterOperands &RegOpers,
+                      const MachineRegisterInfo &MRI);
 };
 
 /// Store the effects of a change in pressure on things that MI scheduler cares
@@ -204,30 +219,56 @@ struct RegPressureDelta {
   }
 };
 
-/// \brief A set of live virtual registers and physical register units.
+/// A set of live virtual registers and physical register units.
 ///
-/// Virtual and physical register numbers require separate sparse sets, but most
-/// of the RegisterPressureTracker handles them uniformly.
-struct LiveRegSet {
-  SparseSet<unsigned> PhysRegs;
-  SparseSet<unsigned, VirtReg2IndexFunctor> VirtRegs;
+/// This is a wrapper around a SparseSet which deals with mapping register unit
+/// and virtual register indexes to an index usable by the sparse set.
+class LiveRegSet {
+private:
+  SparseSet<unsigned> Regs;
+  unsigned NumRegUnits;
+
+  unsigned getSparseIndexFromReg(unsigned Reg) const {
+    if (TargetRegisterInfo::isVirtualRegister(Reg))
+      return TargetRegisterInfo::virtReg2Index(Reg) + NumRegUnits;
+    assert(Reg < NumRegUnits);
+    return Reg;
+  }
+  unsigned getRegFromSparseIndex(unsigned SparseIndex) const {
+    if (SparseIndex >= NumRegUnits)
+      return TargetRegisterInfo::index2VirtReg(SparseIndex-NumRegUnits);
+    return SparseIndex;
+  }
+
+public:
+  void clear();
+  void init(const MachineRegisterInfo &MRI);
 
   bool contains(unsigned Reg) const {
-    if (TargetRegisterInfo::isVirtualRegister(Reg))
-      return VirtRegs.count(Reg);
-    return PhysRegs.count(Reg);
+    unsigned SparseIndex = getSparseIndexFromReg(Reg);
+    return Regs.count(SparseIndex);
   }
 
   bool insert(unsigned Reg) {
-    if (TargetRegisterInfo::isVirtualRegister(Reg))
-      return VirtRegs.insert(Reg).second;
-    return PhysRegs.insert(Reg).second;
+    unsigned SparseIndex = getSparseIndexFromReg(Reg);
+    return Regs.insert(SparseIndex).second;
   }
 
   bool erase(unsigned Reg) {
-    if (TargetRegisterInfo::isVirtualRegister(Reg))
-      return VirtRegs.erase(Reg);
-    return PhysRegs.erase(Reg);
+    unsigned SparseIndex = getSparseIndexFromReg(Reg);
+    return Regs.erase(SparseIndex);
+  }
+
+  size_t size() const {
+    return Regs.size();
+  }
+
+  template<typename ContainerT>
+  void appendTo(ContainerT &To) const {
+    for (unsigned I : Regs) {
+      unsigned Reg = getRegFromSparseIndex(I);
+      To.push_back(Reg);
+    }
   }
 };
 
@@ -285,12 +326,12 @@ class RegPressureTracker {
 
 public:
   RegPressureTracker(IntervalPressure &rp) :
-    MF(0), TRI(0), RCI(0), LIS(0), MBB(0), P(rp), RequireIntervals(true),
-    TrackUntiedDefs(false) {}
+    MF(nullptr), TRI(nullptr), RCI(nullptr), LIS(nullptr), MBB(nullptr), P(rp),
+    RequireIntervals(true), TrackUntiedDefs(false) {}
 
   RegPressureTracker(RegionPressure &rp) :
-    MF(0), TRI(0), RCI(0), LIS(0), MBB(0), P(rp), RequireIntervals(false),
-    TrackUntiedDefs(false) {}
+    MF(nullptr), TRI(nullptr), RCI(nullptr), LIS(nullptr), MBB(nullptr), P(rp),
+    RequireIntervals(false), TrackUntiedDefs(false) {}
 
   void reset();
 
@@ -313,15 +354,21 @@ public:
   // position changes while pressure does not.
   void setPos(MachineBasicBlock::const_iterator Pos) { CurrPos = Pos; }
 
-  /// \brief Get the SlotIndex for the first nondebug instruction including or
-  /// after the current position.
-  SlotIndex getCurrSlot() const;
+  /// Recede across the previous instruction.
+  void recede(SmallVectorImpl<unsigned> *LiveUses = nullptr);
 
   /// Recede across the previous instruction.
-  bool recede(SmallVectorImpl<unsigned> *LiveUses = 0, PressureDiff *PDiff = 0);
+  /// This "low-level" variant assumes that recedeSkipDebugValues() was
+  /// called previously and takes precomputed RegisterOperands for the
+  /// instruction.
+  void recede(const RegisterOperands &RegOpers,
+              SmallVectorImpl<unsigned> *LiveUses = nullptr);
+
+  /// Recede until we find an instruction which is not a DebugValue.
+  void recedeSkipDebugValues();
 
   /// Advance across the current instruction.
-  bool advance();
+  void advance();
 
   /// Finalize the region boundaries and recored live ins and live outs.
   void closeRegion();
@@ -338,17 +385,15 @@ public:
   ArrayRef<unsigned> getLiveThru() const { return LiveThruPressure; }
 
   /// Get the resulting register pressure over the traversed region.
-  /// This result is complete if either advance() or recede() has returned true,
-  /// or if closeRegion() was explicitly invoked.
+  /// This result is complete if closeRegion() was explicitly invoked.
   RegisterPressure &getPressure() { return P; }
   const RegisterPressure &getPressure() const { return P; }
 
   /// Get the register set pressure at the current position, which may be less
   /// than the pressure across the traversed region.
-  std::vector<unsigned> &getRegSetPressureAtPos() { return CurrSetPressure; }
-
-  void discoverLiveOut(unsigned Reg);
-  void discoverLiveIn(unsigned Reg);
+  const std::vector<unsigned> &getRegSetPressureAtPos() const {
+    return CurrSetPressure;
+  }
 
   bool isTopClosed() const;
   bool isBottomClosed() const;
@@ -393,7 +438,7 @@ public:
                                          MaxPressureLimit);
 
     assert(isBottomClosed() && "Uninitialized pressure tracker");
-    return getMaxUpwardPressureDelta(MI, 0, Delta, CriticalPSets,
+    return getMaxUpwardPressureDelta(MI, nullptr, Delta, CriticalPSets,
                                      MaxPressureLimit);
   }
 
@@ -424,7 +469,12 @@ public:
   void dump() const;
 
 protected:
-  const LiveRange *getLiveRange(unsigned Reg) const;
+  void discoverLiveOut(unsigned Reg);
+  void discoverLiveIn(unsigned Reg);
+
+  /// \brief Get the SlotIndex for the first nondebug instruction including or
+  /// after the current position.
+  SlotIndex getCurrSlot() const;
 
   void increaseRegPressure(ArrayRef<unsigned> Regs);
   void decreaseRegPressure(ArrayRef<unsigned> Regs);
@@ -433,10 +483,8 @@ protected:
   void bumpDownwardPressure(const MachineInstr *MI);
 };
 
-#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
 void dumpRegSetPressure(ArrayRef<unsigned> SetPressure,
                         const TargetRegisterInfo *TRI);
-#endif
 } // end namespace llvm
 
 #endif