[llvm-commits] [llvm] r79411 - in /llvm/trunk: lib/Transforms/Utils/SSI.cpp test/Transforms/SSI/2009-08-19-UnreachableBB2.ll

Nick Lewycky nicholas at mxc.ca
Wed Aug 19 00:16:57 PDT 2009


Author: nicholas
Date: Wed Aug 19 02:16:57 2009
New Revision: 79411

URL: http://llvm.org/viewvc/llvm-project?rev=79411&view=rev
Log:
Fix up PHI nodes correctly in the presence of unreachable BBs, part two. Also
delete a newed pointer, and improve readability a little bit.

Added:
    llvm/trunk/test/Transforms/SSI/2009-08-19-UnreachableBB2.ll
Modified:
    llvm/trunk/lib/Transforms/Utils/SSI.cpp

Modified: llvm/trunk/lib/Transforms/Utils/SSI.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SSI.cpp?rev=79411&r1=79410&r2=79411&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Utils/SSI.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/SSI.cpp Wed Aug 19 02:16:57 2009
@@ -226,10 +226,9 @@
     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 @@
       }
     }
   }
+
+  delete defined;
 }
 
 /// Substitute any use in this instruction for the last definition of
@@ -307,16 +308,16 @@
 /// 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 @@
       }
     }
   }
+
+  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

Added: llvm/trunk/test/Transforms/SSI/2009-08-19-UnreachableBB2.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SSI/2009-08-19-UnreachableBB2.ll?rev=79411&view=auto

==============================================================================
--- llvm/trunk/test/Transforms/SSI/2009-08-19-UnreachableBB2.ll (added)
+++ llvm/trunk/test/Transforms/SSI/2009-08-19-UnreachableBB2.ll Wed Aug 19 02:16:57 2009
@@ -0,0 +1,22 @@
+; RUN: llvm-as < %s | opt -ssi-everything -disable-output
+
+define void @foo() {
+entry:
+	%tmp0 = load i64* undef, align 4		; <i64> [#uses=3]
+	br i1 undef, label %end_stmt_playback, label %bb16
+
+readJournalHdr.exit:		; No predecessors!
+	br label %end_stmt_playback
+
+bb16:		; preds = %bb7
+	%tmp1 = icmp slt i64 0, %tmp0		; <i1> [#uses=1]
+	br i1 %tmp1, label %bb16, label %bb17
+
+bb17:		; preds = %bb16
+	store i64 %tmp0, i64* undef, align 4
+	br label %end_stmt_playback
+
+end_stmt_playback:		; preds = %bb17, %readJournalHdr.exit, %bb6, %bb2
+	store i64 %tmp0, i64* undef, align 4
+	ret void
+}





More information about the llvm-commits mailing list