diff options
Diffstat (limited to 'lib/CodeGen/RegAllocLocal.cpp')
| -rw-r--r-- | lib/CodeGen/RegAllocLocal.cpp | 27 | 
1 files changed, 17 insertions, 10 deletions
diff --git a/lib/CodeGen/RegAllocLocal.cpp b/lib/CodeGen/RegAllocLocal.cpp index 04303cff5bfa7..194fc14848bc0 100644 --- a/lib/CodeGen/RegAllocLocal.cpp +++ b/lib/CodeGen/RegAllocLocal.cpp @@ -671,8 +671,10 @@ void RALocal::ComputeLocalLiveness(MachineBasicBlock& MBB) {    // Live-out (of the function) registers contain return values of the function,    // so we need to make sure they are alive at return time. -  if (!MBB.empty() && MBB.back().getDesc().isReturn()) { -    MachineInstr* Ret = &MBB.back(); +  MachineBasicBlock::iterator Ret = MBB.getFirstTerminator(); +  bool BBEndsInReturn = (Ret != MBB.end() && Ret->getDesc().isReturn()); + +  if (BBEndsInReturn)      for (MachineRegisterInfo::liveout_iterator           I = MF->getRegInfo().liveout_begin(),           E = MF->getRegInfo().liveout_end(); I != E; ++I) @@ -680,7 +682,6 @@ void RALocal::ComputeLocalLiveness(MachineBasicBlock& MBB) {          Ret->addOperand(MachineOperand::CreateReg(*I, false, true));          LastUseDef[*I] = std::make_pair(Ret, Ret->getNumOperands()-1);        } -  }    // Finally, loop over the final use/def of each reg     // in the block and determine if it is dead. @@ -696,7 +697,10 @@ void RALocal::ComputeLocalLiveness(MachineBasicBlock& MBB) {      bool usedOutsideBlock = isPhysReg ? false :               UsedInMultipleBlocks.test(MO.getReg() -                                        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        // 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 @@ -704,7 +708,7 @@ void RALocal::ComputeLocalLiveness(MachineBasicBlock& MBB) {        // happens.        bool UsedByDebugValueOnly = false;        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:          // - used in another block          // - used in the same block before it is defined (loop) @@ -714,6 +718,7 @@ void RALocal::ComputeLocalLiveness(MachineBasicBlock& MBB) {              UsedByDebugValueOnly = true;              continue;            } +            // A non-DBG_VALUE use means we can leave DBG_VALUE uses alone.            UsedInMultipleBlocks.set(MO.getReg() -                                      TargetRegisterInfo::FirstVirtualRegister); @@ -721,6 +726,8 @@ void RALocal::ComputeLocalLiveness(MachineBasicBlock& MBB) {            UsedByDebugValueOnly = false;            break;          } +      } +        if (UsedByDebugValueOnly)          for (MachineRegisterInfo::reg_iterator UI = MRI.reg_begin(MO.getReg()),               UE = MRI.reg_end(); UI != UE; ++UI) @@ -730,16 +737,16 @@ void RALocal::ComputeLocalLiveness(MachineBasicBlock& MBB) {              UI.getOperand().setReg(0U);      } -    // Physical registers and those that are not live-out of the block -    // are killed/dead at their last use/def within this block. -    if (isPhysReg || !usedOutsideBlock) { +    // Physical registers and those that are not live-out of the block are +    // killed/dead at their last use/def within this block. +    if (isPhysReg || !usedOutsideBlock || BBEndsInReturn)        if (MO.isUse()) {          // Don't mark uses that are tied to defs as kills.          if (!MI->isRegTiedToDefOperand(idx))            MO.setIsKill(true); -      } else +      } else {          MO.setIsDead(true); -    } +      }    }  }  | 
