Fix liveness calculation when splitting critical edges during PHI elimination.
- Edges are split before any phis are eliminated, so the code is SSA.
- Create a proper IR BasicBlock for the split edges.
- LiveVariables::addNewBlock now has same syntax as
MachineDominatorTree::addNewBlock. Algorithm calculates predecessor live-out
set rather than successor live-in set.
This feature still causes some miscompilations.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@86867 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/LiveVariables.cpp b/lib/CodeGen/LiveVariables.cpp
index 1580667..cba0371 100644
--- a/lib/CodeGen/LiveVariables.cpp
+++ b/lib/CodeGen/LiveVariables.cpp
@@ -650,34 +650,35 @@
.push_back(BBI->getOperand(i).getReg());
}
-void LiveVariables::addNewBlock(MachineBasicBlock *A, MachineBasicBlock *B) {
- unsigned NumA = A->getNumber();
- unsigned NumB = B->getNumber();
+/// 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) {
+ const unsigned NumNew = BB->getNumber();
+ const unsigned NumDom = DomBB->getNumber();
// Update info for all live variables
- for (unsigned i = 0, e = VirtRegInfo.size(); i != e; ++i) {
- VarInfo &VI = VirtRegInfo[i];
+ for (unsigned Reg = TargetRegisterInfo::FirstVirtualRegister,
+ E = MRI->getLastVirtReg()+1; Reg != E; ++Reg) {
+ VarInfo &VI = getVarInfo(Reg);
- // Anything live through B is also live through A.
- if (VI.AliveBlocks.test(NumB)) {
- VI.AliveBlocks.set(NumA);
+ // Anything live through DomBB is also live through BB.
+ if (VI.AliveBlocks.test(NumDom)) {
+ VI.AliveBlocks.set(NumNew);
continue;
}
- // If we're not killed in B, we are not live in
- if (!VI.findKill(B))
+ // Variables not defined in DomBB cannot be live out.
+ const MachineInstr *Def = MRI->getVRegDef(Reg);
+ if (!Def || Def->getParent() != DomBB)
continue;
- unsigned Reg = i+TargetRegisterInfo::FirstVirtualRegister;
+ // Killed by DomBB?
+ if (VI.findKill(DomBB))
+ continue;
- // Find a def outside B
- for (MachineRegisterInfo::def_iterator di = MRI->def_begin(Reg),
- de=MRI->def_end(); di != de; ++di) {
- if (di->getParent() != B) {
- // Reg was defined outside B and killed in B - it must be live in.
- VI.AliveBlocks.set(NumA);
- break;
- }
- }
+ // This register is defined in DomBB and live out
+ VI.AliveBlocks.set(NumNew);
}
}