summaryrefslogtreecommitdiff
path: root/lib/CodeGen/LiveVariables.cpp
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2009-11-10 22:01:05 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2009-11-10 22:01:05 +0000
commitf235f13931835b3335f3f2ff2d3060381b93626c (patch)
tree3388d35b748a3c11118e4f20203141a6c76599e3 /lib/CodeGen/LiveVariables.cpp
parente35e3c33dc5533dd1e8ab7d9f4039cc1429d56aa (diff)
downloadllvm-f235f13931835b3335f3f2ff2d3060381b93626c.tar.gz
llvm-f235f13931835b3335f3f2ff2d3060381b93626c.tar.bz2
llvm-f235f13931835b3335f3f2ff2d3060381b93626c.tar.xz
Teach PHIElimination to split critical edges when -split-phi-edges is enabled.
Critical edges leading to a PHI node are split when the PHI source variable is live out from the predecessor block. This help the coalescer eliminate more PHI joins. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@86725 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/LiveVariables.cpp')
-rw-r--r--lib/CodeGen/LiveVariables.cpp40
1 files changed, 40 insertions, 0 deletions
diff --git a/lib/CodeGen/LiveVariables.cpp b/lib/CodeGen/LiveVariables.cpp
index 96c655c1a9..1580667222 100644
--- a/lib/CodeGen/LiveVariables.cpp
+++ b/lib/CodeGen/LiveVariables.cpp
@@ -50,6 +50,14 @@ void LiveVariables::getAnalysisUsage(AnalysisUsage &AU) const {
MachineFunctionPass::getAnalysisUsage(AU);
}
+MachineInstr *
+LiveVariables::VarInfo::findKill(const MachineBasicBlock *MBB) const {
+ for (unsigned i = 0, e = Kills.size(); i != e; ++i)
+ if (Kills[i]->getParent() == MBB)
+ return Kills[i];
+ return NULL;
+}
+
void LiveVariables::VarInfo::dump() const {
errs() << " Alive in blocks: ";
for (SparseBitVector<>::iterator I = AliveBlocks.begin(),
@@ -641,3 +649,35 @@ void LiveVariables::analyzePHINodes(const MachineFunction& Fn) {
PHIVarInfo[BBI->getOperand(i + 1).getMBB()->getNumber()]
.push_back(BBI->getOperand(i).getReg());
}
+
+void LiveVariables::addNewBlock(MachineBasicBlock *A, MachineBasicBlock *B) {
+ unsigned NumA = A->getNumber();
+ unsigned NumB = B->getNumber();
+
+ // Update info for all live variables
+ for (unsigned i = 0, e = VirtRegInfo.size(); i != e; ++i) {
+ VarInfo &VI = VirtRegInfo[i];
+
+ // Anything live through B is also live through A.
+ if (VI.AliveBlocks.test(NumB)) {
+ VI.AliveBlocks.set(NumA);
+ continue;
+ }
+
+ // If we're not killed in B, we are not live in
+ if (!VI.findKill(B))
+ continue;
+
+ unsigned Reg = i+TargetRegisterInfo::FirstVirtualRegister;
+
+ // 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;
+ }
+ }
+ }
+}