When checking if something's killed, don't rely simply on whether it's marked as

"used outside of the block". If the block ends in a return, then it won't be
used outside of it.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@98599 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Bill Wendling
2010-03-16 01:05:35 +00:00
parent 5f19c43161
commit 8fe347a8b5

View File

@@ -671,7 +671,8 @@ void RALocal::ComputeLocalLiveness(MachineBasicBlock& MBB) {
// Live-out (of the function) registers contain return values of the function, // Live-out (of the function) registers contain return values of the function,
// so we need to make sure they are alive at return time. // so we need to make sure they are alive at return time.
if (!MBB.empty() && MBB.back().getDesc().isReturn()) { bool BBEndsInReturn = !MBB.empty() && MBB.back().getDesc().isReturn();
if (BBEndsInReturn) {
MachineInstr* Ret = &MBB.back(); MachineInstr* Ret = &MBB.back();
for (MachineRegisterInfo::liveout_iterator for (MachineRegisterInfo::liveout_iterator
I = MF->getRegInfo().liveout_begin(), I = MF->getRegInfo().liveout_begin(),
@@ -696,7 +697,10 @@ void RALocal::ComputeLocalLiveness(MachineBasicBlock& MBB) {
bool usedOutsideBlock = isPhysReg ? false : bool usedOutsideBlock = isPhysReg ? false :
UsedInMultipleBlocks.test(MO.getReg() - UsedInMultipleBlocks.test(MO.getReg() -
TargetRegisterInfo::FirstVirtualRegister); TargetRegisterInfo::FirstVirtualRegister);
if (!isPhysReg && !usedOutsideBlock) {
// If the machine BB ends in a return instruction, then the value isn't used
// outside of the BB.
if (!isPhysReg && (!usedOutsideBlock || BBEndsInReturn)) {
// DBG_VALUE complicates this: if the only refs of a register outside // DBG_VALUE complicates this: if the only refs of a register outside
// this block are DBG_VALUE, we can't keep the reg live just for that, // this block are DBG_VALUE, we can't keep the reg live just for that,
// as it will cause the reg to be spilled at the end of this block when // as it will cause the reg to be spilled at the end of this block when
@@ -704,7 +708,7 @@ void RALocal::ComputeLocalLiveness(MachineBasicBlock& MBB) {
// happens. // happens.
bool UsedByDebugValueOnly = false; bool UsedByDebugValueOnly = false;
for (MachineRegisterInfo::reg_iterator UI = MRI.reg_begin(MO.getReg()), for (MachineRegisterInfo::reg_iterator UI = MRI.reg_begin(MO.getReg()),
UE = MRI.reg_end(); UI != UE; ++UI) UE = MRI.reg_end(); UI != UE; ++UI) {
// Two cases: // Two cases:
// - used in another block // - used in another block
// - used in the same block before it is defined (loop) // - used in the same block before it is defined (loop)
@@ -714,6 +718,7 @@ void RALocal::ComputeLocalLiveness(MachineBasicBlock& MBB) {
UsedByDebugValueOnly = true; UsedByDebugValueOnly = true;
continue; continue;
} }
// A non-DBG_VALUE use means we can leave DBG_VALUE uses alone. // A non-DBG_VALUE use means we can leave DBG_VALUE uses alone.
UsedInMultipleBlocks.set(MO.getReg() - UsedInMultipleBlocks.set(MO.getReg() -
TargetRegisterInfo::FirstVirtualRegister); TargetRegisterInfo::FirstVirtualRegister);
@@ -721,6 +726,8 @@ void RALocal::ComputeLocalLiveness(MachineBasicBlock& MBB) {
UsedByDebugValueOnly = false; UsedByDebugValueOnly = false;
break; break;
} }
}
if (UsedByDebugValueOnly) if (UsedByDebugValueOnly)
for (MachineRegisterInfo::reg_iterator UI = MRI.reg_begin(MO.getReg()), for (MachineRegisterInfo::reg_iterator UI = MRI.reg_begin(MO.getReg()),
UE = MRI.reg_end(); UI != UE; ++UI) UE = MRI.reg_end(); UI != UE; ++UI)
@@ -730,14 +737,14 @@ void RALocal::ComputeLocalLiveness(MachineBasicBlock& MBB) {
UI.getOperand().setReg(0U); UI.getOperand().setReg(0U);
} }
// Physical registers and those that are not live-out of the block // Physical registers and those that are not live-out of the block are
// are killed/dead at their last use/def within this block. // killed/dead at their last use/def within this block.
if (isPhysReg || !usedOutsideBlock) { if (isPhysReg || !usedOutsideBlock || BBEndsInReturn)
if (MO.isUse()) { if (MO.isUse()) {
// Don't mark uses that are tied to defs as kills. // Don't mark uses that are tied to defs as kills.
if (!MI->isRegTiedToDefOperand(idx)) if (!MI->isRegTiedToDefOperand(idx))
MO.setIsKill(true); MO.setIsKill(true);
} else } else {
MO.setIsDead(true); MO.setIsDead(true);
} }
} }