forked from OSchip/llvm-project
RegisterPressure: Expose RegisterOperands API
Previously the RegisterOperands have only been used internally in RegisterPressure.cpp. However this datastructure can be useful for other tasks as well and allows refactoring of PDiff initialisation out of RPTracker::recede(). This patch: - Exposes RegisterOperands as public API - Splits RPTracker::recede() into a part that skips DebugValues and maintains the region borders, and the core that changes register pressure when given a set of RegisterOperands. - This allows to move the PDiff initialisation out recede() into a method of the PressureDiffs class. - The upcoming subregister scheduling code will also use RegisterOperands to avoid pushing more unrelated functionality into recede()/advance(). Differential Revision: http://reviews.llvm.org/D15473 llvm-svn: 257535
This commit is contained in:
parent
9aae445e09
commit
b505c76c9a
|
@ -141,6 +141,28 @@ public:
|
|||
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.
|
||||
class PressureDiffs {
|
||||
PressureDiff *PDiffArray;
|
||||
|
@ -161,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
|
||||
|
@ -329,8 +355,17 @@ public:
|
|||
void setPos(MachineBasicBlock::const_iterator Pos) { CurrPos = Pos; }
|
||||
|
||||
/// Recede across the previous instruction.
|
||||
void recede(SmallVectorImpl<unsigned> *LiveUses = nullptr,
|
||||
PressureDiff *PDiff = nullptr);
|
||||
void recede(SmallVectorImpl<unsigned> *LiveUses = nullptr);
|
||||
|
||||
/// Recede across the previous instruction.
|
||||
/// 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.
|
||||
void advance();
|
||||
|
|
|
@ -313,21 +313,6 @@ static bool containsReg(ArrayRef<unsigned> RegUnits, unsigned RegUnit) {
|
|||
|
||||
namespace {
|
||||
|
||||
/// List of register defined and used by a machine instruction.
|
||||
class RegisterOperands {
|
||||
public:
|
||||
SmallVector<unsigned, 8> Uses;
|
||||
SmallVector<unsigned, 8> Defs;
|
||||
SmallVector<unsigned, 8> DeadDefs;
|
||||
|
||||
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);
|
||||
};
|
||||
|
||||
/// Collect this instruction's unique uses and defs into SmallVectors for
|
||||
/// processing defs and uses in order.
|
||||
///
|
||||
|
@ -385,9 +370,11 @@ class RegisterOperandsCollector {
|
|||
}
|
||||
}
|
||||
|
||||
friend class RegisterOperands;
|
||||
friend class llvm::RegisterOperands;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
void RegisterOperands::collect(const MachineInstr &MI,
|
||||
const TargetRegisterInfo &TRI,
|
||||
const MachineRegisterInfo &MRI,
|
||||
|
@ -417,8 +404,6 @@ void RegisterOperands::detectDeadDefs(const MachineInstr &MI,
|
|||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
/// Initialize an array of N PressureDiffs.
|
||||
void PressureDiffs::init(unsigned N) {
|
||||
Size = N;
|
||||
|
@ -431,6 +416,18 @@ void PressureDiffs::init(unsigned N) {
|
|||
PDiffArray = reinterpret_cast<PressureDiff*>(calloc(N, sizeof(PressureDiff)));
|
||||
}
|
||||
|
||||
void PressureDiffs::addInstruction(unsigned Idx,
|
||||
const RegisterOperands &RegOpers,
|
||||
const MachineRegisterInfo &MRI) {
|
||||
PressureDiff &PDiff = (*this)[Idx];
|
||||
assert(!PDiff.begin()->isValid() && "stale PDiff");
|
||||
for (unsigned Reg : RegOpers.Defs)
|
||||
PDiff.addPressureChange(Reg, true, &MRI);
|
||||
|
||||
for (unsigned Reg : RegOpers.Uses)
|
||||
PDiff.addPressureChange(Reg, false, &MRI);
|
||||
}
|
||||
|
||||
/// Add a change in pressure to the pressure diff of a given instruction.
|
||||
void PressureDiff::addPressureChange(unsigned RegUnit, bool IsDec,
|
||||
const MachineRegisterInfo *MRI) {
|
||||
|
@ -467,18 +464,6 @@ void PressureDiff::addPressureChange(unsigned RegUnit, bool IsDec,
|
|||
}
|
||||
}
|
||||
|
||||
/// Record the pressure difference induced by the given operand list.
|
||||
static void collectPDiff(PressureDiff &PDiff, RegisterOperands &RegOpers,
|
||||
const MachineRegisterInfo *MRI) {
|
||||
assert(!PDiff.begin()->isValid() && "stale PDiff");
|
||||
|
||||
for (unsigned Reg : RegOpers.Defs)
|
||||
PDiff.addPressureChange(Reg, true, MRI);
|
||||
|
||||
for (unsigned Reg : RegOpers.Uses)
|
||||
PDiff.addPressureChange(Reg, false, MRI);
|
||||
}
|
||||
|
||||
/// Force liveness of registers.
|
||||
void RegPressureTracker::addLiveRegs(ArrayRef<unsigned> Regs) {
|
||||
for (unsigned Reg : Regs) {
|
||||
|
@ -514,39 +499,10 @@ void RegPressureTracker::discoverLiveOut(unsigned Reg) {
|
|||
/// registers that are both defined and used by the instruction. If a pressure
|
||||
/// difference pointer is provided record the changes is pressure caused by this
|
||||
/// instruction independent of liveness.
|
||||
void RegPressureTracker::recede(SmallVectorImpl<unsigned> *LiveUses,
|
||||
PressureDiff *PDiff) {
|
||||
assert(CurrPos != MBB->begin());
|
||||
if (!isBottomClosed())
|
||||
closeBottom();
|
||||
|
||||
// Open the top of the region using block iterators.
|
||||
if (!RequireIntervals && isTopClosed())
|
||||
static_cast<RegionPressure&>(P).openTop(CurrPos);
|
||||
|
||||
// Find the previous instruction.
|
||||
do
|
||||
--CurrPos;
|
||||
while (CurrPos != MBB->begin() && CurrPos->isDebugValue());
|
||||
void RegPressureTracker::recede(const RegisterOperands &RegOpers,
|
||||
SmallVectorImpl<unsigned> *LiveUses) {
|
||||
assert(!CurrPos->isDebugValue());
|
||||
|
||||
SlotIndex SlotIdx;
|
||||
if (RequireIntervals)
|
||||
SlotIdx = LIS->getInstructionIndex(CurrPos).getRegSlot();
|
||||
|
||||
// Open the top of the region using slot indexes.
|
||||
if (RequireIntervals && isTopClosed())
|
||||
static_cast<IntervalPressure&>(P).openTop(SlotIdx);
|
||||
|
||||
const MachineInstr &MI = *CurrPos;
|
||||
RegisterOperands RegOpers;
|
||||
RegOpers.collect(MI, *TRI, *MRI);
|
||||
if (RequireIntervals)
|
||||
RegOpers.detectDeadDefs(MI, *LIS);
|
||||
|
||||
if (PDiff)
|
||||
collectPDiff(*PDiff, RegOpers, MRI);
|
||||
|
||||
// Boost pressure for all dead defs together.
|
||||
increaseRegPressure(RegOpers.DeadDefs);
|
||||
decreaseRegPressure(RegOpers.DeadDefs);
|
||||
|
@ -560,6 +516,10 @@ void RegPressureTracker::recede(SmallVectorImpl<unsigned> *LiveUses,
|
|||
discoverLiveOut(Reg);
|
||||
}
|
||||
|
||||
SlotIndex SlotIdx;
|
||||
if (RequireIntervals)
|
||||
SlotIdx = LIS->getInstructionIndex(CurrPos).getRegSlot();
|
||||
|
||||
// Generate liveness for uses.
|
||||
for (unsigned Reg : RegOpers.Uses) {
|
||||
if (!LiveRegs.contains(Reg)) {
|
||||
|
@ -586,6 +546,41 @@ void RegPressureTracker::recede(SmallVectorImpl<unsigned> *LiveUses,
|
|||
}
|
||||
}
|
||||
|
||||
void RegPressureTracker::recedeSkipDebugValues() {
|
||||
assert(CurrPos != MBB->begin());
|
||||
if (!isBottomClosed())
|
||||
closeBottom();
|
||||
|
||||
// Open the top of the region using block iterators.
|
||||
if (!RequireIntervals && isTopClosed())
|
||||
static_cast<RegionPressure&>(P).openTop(CurrPos);
|
||||
|
||||
// Find the previous instruction.
|
||||
do
|
||||
--CurrPos;
|
||||
while (CurrPos != MBB->begin() && CurrPos->isDebugValue());
|
||||
|
||||
SlotIndex SlotIdx;
|
||||
if (RequireIntervals)
|
||||
SlotIdx = LIS->getInstructionIndex(CurrPos).getRegSlot();
|
||||
|
||||
// Open the top of the region using slot indexes.
|
||||
if (RequireIntervals && isTopClosed())
|
||||
static_cast<IntervalPressure&>(P).openTop(SlotIdx);
|
||||
}
|
||||
|
||||
void RegPressureTracker::recede(SmallVectorImpl<unsigned> *LiveUses) {
|
||||
recedeSkipDebugValues();
|
||||
|
||||
const MachineInstr &MI = *CurrPos;
|
||||
RegisterOperands RegOpers;
|
||||
RegOpers.collect(MI, *TRI, *MRI);
|
||||
if (RequireIntervals)
|
||||
RegOpers.detectDeadDefs(MI, *LIS);
|
||||
|
||||
recede(RegOpers, LiveUses);
|
||||
}
|
||||
|
||||
/// Advance across the current instruction.
|
||||
void RegPressureTracker::advance() {
|
||||
assert(!TrackUntiedDefs && "unsupported mode");
|
||||
|
|
|
@ -896,11 +896,16 @@ void ScheduleDAGInstrs::buildSchedGraph(AliasAnalysis *AA,
|
|||
assert(SU && "No SUnit mapped to this MI");
|
||||
|
||||
if (RPTracker) {
|
||||
PressureDiff *PDiff = PDiffs ? &(*PDiffs)[SU->NodeNum] : nullptr;
|
||||
RPTracker->recede(/*LiveUses=*/nullptr, PDiff);
|
||||
assert(RPTracker->getPos() == std::prev(MII) &&
|
||||
"RPTracker can't find MI");
|
||||
collectVRegUses(SU);
|
||||
|
||||
RegisterOperands RegOpers;
|
||||
RegOpers.collect(*MI, *TRI, MRI);
|
||||
if (PDiffs != nullptr)
|
||||
PDiffs->addInstruction(SU->NodeNum, RegOpers, MRI);
|
||||
|
||||
RPTracker->recedeSkipDebugValues();
|
||||
assert(&*RPTracker->getPos() == MI && "RPTracker in sync");
|
||||
RPTracker->recede(RegOpers);
|
||||
}
|
||||
|
||||
assert(
|
||||
|
|
Loading…
Reference in New Issue