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;
};
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.
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; }
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
}
};
-/// \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);
+ }
}
};
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();
// 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();
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;
MaxPressureLimit);
assert(isBottomClosed() && "Uninitialized pressure tracker");
- return getMaxUpwardPressureDelta(MI, 0, Delta, CriticalPSets,
+ return getMaxUpwardPressureDelta(MI, nullptr, Delta, CriticalPSets,
MaxPressureLimit);
}
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);
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