aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Transforms
diff options
context:
space:
mode:
authorNick Lewycky <nicholas@mxc.ca>2009-08-19 07:16:57 +0000
committerNick Lewycky <nicholas@mxc.ca>2009-08-19 07:16:57 +0000
commit08368ce9847309618a2c80222cba3b2c88f77f88 (patch)
treea7da2fb87ad4a57290740b5c79d637aebe9cb0c6 /lib/Transforms
parent5371aa2a1c9a4eeecffdb9ab7b2175732e49475b (diff)
downloadexternal_llvm-08368ce9847309618a2c80222cba3b2c88f77f88.zip
external_llvm-08368ce9847309618a2c80222cba3b2c88f77f88.tar.gz
external_llvm-08368ce9847309618a2c80222cba3b2c88f77f88.tar.bz2
Fix up PHI nodes correctly in the presence of unreachable BBs, part two. Also
delete a newed pointer, and improve readability a little bit. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@79411 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms')
-rw-r--r--lib/Transforms/Utils/SSI.cpp37
1 files changed, 30 insertions, 7 deletions
diff --git a/lib/Transforms/Utils/SSI.cpp b/lib/Transforms/Utils/SSI.cpp
index b4e6834..036dc36 100644
--- a/lib/Transforms/Utils/SSI.cpp
+++ b/lib/Transforms/Utils/SSI.cpp
@@ -226,10 +226,9 @@ void SSI::rename(BasicBlock *BB) {
for (BasicBlock::iterator begin = BB_succ->begin(),
notPhi = BB_succ->getFirstNonPHI(); begin != *notPhi; ++begin) {
Instruction *I = begin;
- PHINode *PN;
+ PHINode *PN = dyn_cast<PHINode>(I);
int position;
- if ((PN = dyn_cast<PHINode>(I)) && ((position
- = getPositionPhi(PN)) != -1)) {
+ if (PN && ((position = getPositionPhi(PN)) != -1)) {
PN->addIncoming(value_stack[position].back(), BB);
}
}
@@ -254,6 +253,8 @@ void SSI::rename(BasicBlock *BB) {
}
}
}
+
+ delete defined;
}
/// Substitute any use in this instruction for the last definition of
@@ -307,16 +308,16 @@ bool SSI::dominateAny(BasicBlock *BB, Instruction *value) {
/// as an operand of another phi function used in the same BasicBlock,
/// LLVM looks this as an error. So on the second phi, the first phi is called
/// P and the BasicBlock it incomes is B. This P will be replaced by the value
-/// it has for BasicBlock B.
+/// it has for BasicBlock B. It also includes undef values for predecessors
+/// that were not included in the phi.
///
void SSI::fixPhis() {
for (SmallPtrSet<PHINode *, 1>::iterator begin = phisToFix.begin(),
end = phisToFix.end(); begin != end; ++begin) {
PHINode *PN = *begin;
for (unsigned i = 0, e = PN->getNumIncomingValues(); i < e; ++i) {
- PHINode *PN_father;
- if ((PN_father = dyn_cast<PHINode>(PN->getIncomingValue(i))) &&
- PN->getParent() == PN_father->getParent() &&
+ PHINode *PN_father = dyn_cast<PHINode>(PN->getIncomingValue(i));
+ if (PN_father && PN->getParent() == PN_father->getParent() &&
!DT_->dominates(PN->getParent(), PN->getIncomingBlock(i))) {
BasicBlock *BB = PN->getIncomingBlock(i);
int pos = PN_father->getBasicBlockIndex(BB);
@@ -324,6 +325,28 @@ void SSI::fixPhis() {
}
}
}
+
+ for (DenseMapIterator<PHINode *, unsigned> begin = phis.begin(),
+ end = phis.end(); begin != end; ++begin) {
+ PHINode *PN = begin->first;
+ BasicBlock *BB = PN->getParent();
+ pred_iterator PI = pred_begin(BB), PE = pred_end(BB);
+ SmallVector<BasicBlock*, 8> Preds(PI, PE);
+ for (unsigned size = Preds.size();
+ PI != PE && PN->getNumIncomingValues() != size; ++PI) {
+ bool found = false;
+ for (unsigned i = 0, pn_end = PN->getNumIncomingValues();
+ i < pn_end; ++i) {
+ if (PN->getIncomingBlock(i) == *PI) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ PN->addIncoming(UndefValue::get(PN->getType()), *PI);
+ }
+ }
+ }
}
/// Return which variable (position on the vector of variables) this phi