1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 02:52:53 +02:00

RegisterPressure: allocatable physreg uses are always kills

This property was already used in the code path when no liveness
intervals are present. Unfortunately the code path that uses liveness
intervals tried to query a cached live interval for an allocatable
physreg, those are usually not computed so a conservative default was
used.

This doesn't affect any of the lit testcases. This is a foreclosure to
upcoming changes which should be NFC but without this patch this tidbit
wouldn't be NFC.

llvm-svn: 250596
This commit is contained in:
Matthias Braun 2015-10-17 00:46:57 +00:00
parent 24b9e3b760
commit 894abcd9d3
2 changed files with 29 additions and 25 deletions

View File

@ -418,6 +418,8 @@ public:
protected:
const LiveRange *getLiveRange(unsigned Reg) const;
bool isLastUse(unsigned VRegOrUnit, SlotIndex Pos) const;
void increaseRegPressure(ArrayRef<unsigned> Regs);
void decreaseRegPressure(ArrayRef<unsigned> Regs);

View File

@ -561,6 +561,17 @@ bool RegPressureTracker::recede(SmallVectorImpl<unsigned> *LiveUses,
return true;
}
bool RegPressureTracker::isLastUse(unsigned VRegOrUnit, SlotIndex Pos) const {
// Allocatable physregs are always single-use before register rewriting.
if (!TargetRegisterInfo::isVirtualRegister(VRegOrUnit))
return true;
// Without liveness information we conservatively assume "no last use".
if (!RequireIntervals)
return false;
const LiveRange *LR = getLiveRange(VRegOrUnit);
return LR && LR->Query(Pos).isKill();
}
/// Advance across the current instruction.
bool RegPressureTracker::advance() {
assert(!TrackUntiedDefs && "unsupported mode");
@ -595,21 +606,15 @@ bool RegPressureTracker::advance() {
if (!isLive)
discoverLiveIn(Reg);
// Kill liveness at last uses.
bool lastUse = false;
if (RequireIntervals) {
const LiveRange *LR = getLiveRange(Reg);
lastUse = LR && LR->Query(SlotIdx).isKill();
}
else {
// Allocatable physregs are always single-use before register rewriting.
lastUse = !TargetRegisterInfo::isVirtualRegister(Reg);
}
if (lastUse && isLive) {
LiveRegs.erase(Reg);
decreaseRegPressure(Reg);
}
else if (!lastUse && !isLive)
if (isLastUse(Reg, SlotIdx)) {
if (isLive) {
LiveRegs.erase(Reg);
decreaseRegPressure(Reg);
}
} else if(!isLive) {
// We discovered a live which was not last used here, adjust pressure.
increaseRegPressure(Reg);
}
}
// Generate liveness for defs.
@ -924,21 +929,18 @@ void RegPressureTracker::bumpDownwardPressure(const MachineInstr *MI) {
for (unsigned i = 0, e = RegOpers.Uses.size(); i < e; ++i) {
unsigned Reg = RegOpers.Uses[i];
if (RequireIntervals) {
bool IsLastUse = isLastUse(Reg, SlotIdx);
// We had a last use at MIs position. To know the situation for the current
// position we have to check if there exist other uses in between.
if (IsLastUse && TargetRegisterInfo::isVirtualRegister(Reg)) {
SlotIndex CurrIdx = getCurrSlot();
// FIXME: allow the caller to pass in the list of vreg uses that remain
// to be bottom-scheduled to avoid searching uses at each query.
SlotIndex CurrIdx = getCurrSlot();
const LiveRange *LR = getLiveRange(Reg);
if (LR) {
LiveQueryResult LRQ = LR->Query(SlotIdx);
if (LRQ.isKill() && !findUseBetween(Reg, CurrIdx, SlotIdx, *MRI, LIS))
decreaseRegPressure(Reg);
}
if (findUseBetween(Reg, CurrIdx, SlotIdx, *MRI, LIS))
IsLastUse = false;
}
else if (!TargetRegisterInfo::isVirtualRegister(Reg)) {
// Allocatable physregs are always single-use before register rewriting.
if (IsLastUse)
decreaseRegPressure(Reg);
}
}
// Generate liveness for defs.