diff --git a/include/llvm/CodeGen/RegisterPressure.h b/include/llvm/CodeGen/RegisterPressure.h index dd7ba86d193..e810f8c64bb 100644 --- a/include/llvm/CodeGen/RegisterPressure.h +++ b/include/llvm/CodeGen/RegisterPressure.h @@ -198,6 +198,10 @@ public: /// or if closeRegion() was explicitly invoked. RegisterPressure &getPressure() { return P; } + /// Get the register set pressure at the current position, which may be less + /// than the pressure across the traversed region. + std::vector &getRegSetPressureAtPos() { return CurrSetPressure; } + void discoverPhysLiveIn(unsigned Reg); void discoverPhysLiveOut(unsigned Reg); @@ -243,12 +247,32 @@ public: MaxPressureLimit); } + /// Get the pressure of each PSet after traversing this instruction bottom-up. + void getUpwardPressure(const MachineInstr *MI, + std::vector &PressureResult); + + /// Get the pressure of each PSet after traversing this instruction top-down. + void getDownwardPressure(const MachineInstr *MI, + std::vector &PressureResult); + + void getPressureAfterInst(const MachineInstr *MI, + std::vector &PressureResult) { + if (isTopClosed()) + return getUpwardPressure(MI, PressureResult); + + assert(isBottomClosed() && "Uninitialized pressure tracker"); + return getDownwardPressure(MI, PressureResult); + } + protected: void increasePhysRegPressure(ArrayRef Regs); void decreasePhysRegPressure(ArrayRef Regs); void increaseVirtRegPressure(ArrayRef Regs); void decreaseVirtRegPressure(ArrayRef Regs); + + void bumpUpwardPressure(const MachineInstr *MI); + void bumpDownwardPressure(const MachineInstr *MI); }; } // end namespace llvm diff --git a/lib/CodeGen/RegisterPressure.cpp b/lib/CodeGen/RegisterPressure.cpp index 63d319e209b..015d6735380 100644 --- a/lib/CodeGen/RegisterPressure.cpp +++ b/lib/CodeGen/RegisterPressure.cpp @@ -654,32 +654,18 @@ static void computeMaxPressureDelta(ArrayRef OldMaxPressureVec, } } -/// Consider the pressure increase caused by traversing this instruction -/// bottom-up. Find the pressure set with the most change beyond its pressure -/// limit based on the tracker's current pressure, and return the change in -/// number of register units of that pressure set introduced by this -/// instruction. +/// Record the upward impact of a single instruction on current register +/// pressure. Unlike the advance/recede pressure tracking interface, this does +/// not discover live in/outs. /// -/// 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. -void RegPressureTracker:: -getMaxUpwardPressureDelta(const MachineInstr *MI, RegPressureDelta &Delta, - ArrayRef CriticalPSets, - ArrayRef MaxPressureLimit) { +/// This is intended for speculative queries. It leaves pressure inconsistent +/// with the current position, so must be restored by the caller. +void RegPressureTracker::bumpUpwardPressure(const MachineInstr *MI) { // Account for register pressure similar to RegPressureTracker::recede(). PhysRegOperands PhysRegOpers; VirtRegOperands VirtRegOpers; collectOperands(MI, PhysRegOpers, VirtRegOpers, TRI, RCI); - // Snapshot Pressure. - // FIXME: The snapshot heap space should persist. But I'm planning to - // summarize the pressure effect so we don't need to snapshot at all. - std::vector SavedPressure = CurrSetPressure; - std::vector SavedMaxPressure = P.MaxSetPressure; - // Boost max pressure for all dead defs together. // Since CurrSetPressure and MaxSetPressure increasePhysRegPressure(PhysRegOpers.DeadDefs); @@ -708,6 +694,31 @@ getMaxUpwardPressureDelta(const MachineInstr *MI, RegPressureDelta &Delta, increaseVirtRegPressure(Reg); } } +} + +/// Consider the pressure increase caused by traversing this instruction +/// bottom-up. Find the pressure set with the most change beyond its pressure +/// limit based on the tracker's current pressure, and return the change in +/// number of register units of that pressure set introduced by this +/// instruction. +/// +/// 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. +void RegPressureTracker:: +getMaxUpwardPressureDelta(const MachineInstr *MI, RegPressureDelta &Delta, + ArrayRef CriticalPSets, + ArrayRef MaxPressureLimit) { + // Snapshot Pressure. + // FIXME: The snapshot heap space should persist. But I'm planning to + // summarize the pressure effect so we don't need to snapshot at all. + std::vector SavedPressure = CurrSetPressure; + std::vector SavedMaxPressure = P.MaxSetPressure; + + bumpUpwardPressure(MI); + computeExcessPressureDelta(SavedPressure, CurrSetPressure, Delta, TRI); computeMaxPressureDelta(SavedMaxPressure, P.MaxSetPressure, CriticalPSets, MaxPressureLimit, Delta); @@ -735,25 +746,18 @@ static bool findUseBetween(unsigned Reg, return false; } -/// Consider the pressure increase caused by traversing this instruction -/// top-down. Find the register class with the most change in its pressure limit -/// based on the tracker's current pressure, and return the number of excess -/// register units of that pressure set introduced by this instruction. +/// Record the downward impact of a single instruction on current register +/// pressure. Unlike the advance/recede pressure tracking interface, this does +/// not discover live in/outs. /// -/// This assumes that the current LiveIn set is sufficient. -void RegPressureTracker:: -getMaxDownwardPressureDelta(const MachineInstr *MI, RegPressureDelta &Delta, - ArrayRef CriticalPSets, - ArrayRef MaxPressureLimit) { +/// This is intended for speculative queries. It leaves pressure inconsistent +/// with the current position, so must be restored by the caller. +void RegPressureTracker::bumpDownwardPressure(const MachineInstr *MI) { // Account for register pressure similar to RegPressureTracker::recede(). PhysRegOperands PhysRegOpers; VirtRegOperands VirtRegOpers; collectOperands(MI, PhysRegOpers, VirtRegOpers, TRI, RCI); - // Snapshot Pressure. - std::vector SavedPressure = CurrSetPressure; - std::vector SavedMaxPressure = P.MaxSetPressure; - // Kill liveness at last uses. Assume allocatable physregs are single-use // rather than checking LiveIntervals. decreasePhysRegPressure(PhysRegOpers.Uses); @@ -781,6 +785,23 @@ getMaxDownwardPressureDelta(const MachineInstr *MI, RegPressureDelta &Delta, increaseVirtRegPressure(VirtRegOpers.DeadDefs); decreasePhysRegPressure(PhysRegOpers.DeadDefs); decreaseVirtRegPressure(VirtRegOpers.DeadDefs); +} + +/// Consider the pressure increase caused by traversing this instruction +/// top-down. Find the register class with the most change in its pressure limit +/// based on the tracker's current pressure, and return the number of excess +/// register units of that pressure set introduced by this instruction. +/// +/// This assumes that the current LiveIn set is sufficient. +void RegPressureTracker:: +getMaxDownwardPressureDelta(const MachineInstr *MI, RegPressureDelta &Delta, + ArrayRef CriticalPSets, + ArrayRef MaxPressureLimit) { + // Snapshot Pressure. + std::vector SavedPressure = CurrSetPressure; + std::vector SavedMaxPressure = P.MaxSetPressure; + + bumpDownwardPressure(MI); computeExcessPressureDelta(SavedPressure, CurrSetPressure, Delta, TRI); computeMaxPressureDelta(SavedMaxPressure, P.MaxSetPressure, CriticalPSets, @@ -792,3 +813,29 @@ getMaxDownwardPressureDelta(const MachineInstr *MI, RegPressureDelta &Delta, P.MaxSetPressure.swap(SavedMaxPressure); CurrSetPressure.swap(SavedPressure); } + +/// Get the pressure of each PSet after traversing this instruction bottom-up. +void RegPressureTracker:: +getUpwardPressure(const MachineInstr *MI, + std::vector &PressureResult) { + // Snapshot pressure. + PressureResult = CurrSetPressure; + + bumpUpwardPressure(MI); + + // Current pressure becomes the result. Restore current pressure. + CurrSetPressure.swap(PressureResult); +} + +/// Get the pressure of each PSet after traversing this instruction top-down. +void RegPressureTracker:: +getDownwardPressure(const MachineInstr *MI, + std::vector &PressureResult) { + // Snapshot pressure. + PressureResult = CurrSetPressure; + + bumpDownwardPressure(MI); + + // Current pressure becomes the result. Restore current pressure. + CurrSetPressure.swap(PressureResult); +}