diff options
Diffstat (limited to 'lib/CodeGen/LiveVariables.cpp')
-rw-r--r-- | lib/CodeGen/LiveVariables.cpp | 48 |
1 files changed, 29 insertions, 19 deletions
diff --git a/lib/CodeGen/LiveVariables.cpp b/lib/CodeGen/LiveVariables.cpp index 16a79bb54e..bfc2d08528 100644 --- a/lib/CodeGen/LiveVariables.cpp +++ b/lib/CodeGen/LiveVariables.cpp @@ -656,35 +656,45 @@ void LiveVariables::analyzePHINodes(const MachineFunction& Fn) { .push_back(BBI->getOperand(i).getReg()); } +bool LiveVariables::VarInfo::isLiveIn(const MachineBasicBlock &MBB, + unsigned Reg, + MachineRegisterInfo &MRI) { + unsigned Num = MBB.getNumber(); + + // Reg is live-through. + if (AliveBlocks.test(Num)) + return true; + + // Registers defined in MBB cannot be live in. + const MachineInstr *Def = MRI.getVRegDef(Reg); + if (Def && Def->getParent() == &MBB) + return false; + + // Reg was not defined in MBB, was it killed here? + return findKill(&MBB); +} + /// addNewBlock - Add a new basic block BB as an empty succcessor to DomBB. All /// variables that are live out of DomBB will be marked as passing live through /// BB. void LiveVariables::addNewBlock(MachineBasicBlock *BB, - MachineBasicBlock *DomBB) { + MachineBasicBlock *DomBB, + MachineBasicBlock *SuccBB) { const unsigned NumNew = BB->getNumber(); - const unsigned NumDom = DomBB->getNumber(); + + // All registers used by PHI nodes in SuccBB must be live through BB. + for (MachineBasicBlock::const_iterator BBI = SuccBB->begin(), + BBE = SuccBB->end(); + BBI != BBE && BBI->getOpcode() == TargetInstrInfo::PHI; ++BBI) + for (unsigned i = 1, e = BBI->getNumOperands(); i != e; i += 2) + if (BBI->getOperand(i+1).getMBB() == BB) + getVarInfo(BBI->getOperand(i).getReg()).AliveBlocks.set(NumNew); // Update info for all live variables for (unsigned Reg = TargetRegisterInfo::FirstVirtualRegister, E = MRI->getLastVirtReg()+1; Reg != E; ++Reg) { VarInfo &VI = getVarInfo(Reg); - - // Anything live through DomBB is also live through BB. - if (VI.AliveBlocks.test(NumDom)) { + if (!VI.AliveBlocks.test(NumNew) && VI.isLiveIn(*SuccBB, Reg, *MRI)) VI.AliveBlocks.set(NumNew); - continue; - } - - // Variables not defined in DomBB cannot be live out. - const MachineInstr *Def = MRI->getVRegDef(Reg); - if (!Def || Def->getParent() != DomBB) - continue; - - // Killed by DomBB? - if (VI.findKill(DomBB)) - continue; - - // This register is defined in DomBB and live out - VI.AliveBlocks.set(NumNew); } } |