From 2b011e7b506254c3ec7659b795c8db3a56ab367f Mon Sep 17 00:00:00 2001
From: Chris Lattner <sabre@nondot.org>
Date: Sat, 3 Nov 2001 21:08:59 +0000
Subject: [PATCH] Add new cleanup pass: //  1. PHI nodes with multiple entries
 for the same predecessor.  GCC sometimes //     generates code that looks
 like this: // //  bb7:  br bool %cond1004, label %bb8, label %bb8 //  bb8:
 %reg119 = phi uint [ 0, %bb7 ], [ 1, %bb7 ] // //     which is completely
 illegal LLVM code.  To compensate for this, we insert //     an extra basic
 block, and convert the code to look like this: // //  bb7: br bool %cond1004,
 label %bbX, label %bb8 //  bbX: br label bb8 //  bb8: %reg119 = phi uint [ 0,
 %bbX ], [ 1, %bb7 ] //

llvm-svn: 1114
---
 lib/Transforms/IPO/DeadTypeElimination.cpp | 80 ++++++++++++++++++++--
 1 file changed, 73 insertions(+), 7 deletions(-)

diff --git a/lib/Transforms/IPO/DeadTypeElimination.cpp b/lib/Transforms/IPO/DeadTypeElimination.cpp
index c83eba36110..79f8c0dc602 100644
--- a/lib/Transforms/IPO/DeadTypeElimination.cpp
+++ b/lib/Transforms/IPO/DeadTypeElimination.cpp
@@ -20,6 +20,7 @@
 #include "llvm/DerivedTypes.h"
 #include "llvm/iOther.h"
 #include "llvm/iMemory.h"
+#include "llvm/iTerminators.h"
 #include <map>
 #include <algorithm>
 
@@ -354,16 +355,54 @@ bool CleanupGCCOutput::doOneCleanupPass(Method *M) {
 
 
 
+// RefactorPredecessor - When we find out that a basic block is a repeated
+// predecessor in a PHI node, we have to refactor the method until there is at
+// most a single instance of a basic block in any predecessor list.
+//
+static inline void RefactorPredecessor(BasicBlock *BB, BasicBlock *Pred) {
+  Method *M = BB->getParent();
+  assert(find(BB->pred_begin(), BB->pred_end(), Pred) != BB->pred_end() &&
+         "Pred is not a predecessor of BB!");
+
+  // Create a new basic block, adding it to the end of the method.
+  BasicBlock *NewBB = new BasicBlock("", M);
+
+  // Add an unconditional branch to BB to the new block.
+  NewBB->getInstList().push_back(new BranchInst(BB));
+
+  // Get the terminator that causes a branch to BB from Pred.
+  TerminatorInst *TI = Pred->getTerminator();
+
+  // Find the first use of BB in the terminator...
+  User::op_iterator OI = find(TI->op_begin(), TI->op_end(), BB);
+  assert(OI != TI->op_end() && "Pred does not branch to BB!!!");
+
+  // Change the use of BB to point to the new stub basic block
+  *OI = NewBB;
+
+  // Now we need to loop through all of the PHI nodes in BB and convert their
+  // first incoming value for Pred to reference the new basic block instead.
+  //
+  for (BasicBlock::iterator I = BB->begin(); 
+       PHINode *PN = dyn_cast<PHINode>(*I); ++I) {
+    int BBIdx = PN->getBasicBlockIndex(Pred);
+    assert(BBIdx != -1 && "PHI node doesn't have an entry for Pred!");
+
+    // The value that used to look like it came from Pred now comes from NewBB
+    PN->setIncomingBlock((unsigned)BBIdx, NewBB);
+  }
+}
+
+
 // CheckIncomingValueFor - Make sure that the specified PHI node has an entry
 // for the provided basic block.  If it doesn't, add one and return true.
 //
-static inline bool CheckIncomingValueFor(PHINode *PN, BasicBlock *BB) {
-  unsigned NumArgs = PN->getNumIncomingValues();
-  for (unsigned i = 0; i < NumArgs; ++i)
-    if (PN->getIncomingBlock(i) == BB) return false;  // Already has value
+static inline void CheckIncomingValueFor(PHINode *PN, BasicBlock *BB) {
+  if (PN->getBasicBlockIndex(BB) != -1) return;  // Already has value
 
   Value      *NewVal = 0;
   const Type *Ty = PN->getType();
+
   if (const PointerType *PT = dyn_cast<PointerType>(Ty))
     NewVal = ConstPoolPointerNull::get(PT);
   else if (Ty == Type::BoolTy)
@@ -375,13 +414,24 @@ static inline bool CheckIncomingValueFor(PHINode *PN, BasicBlock *BB) {
 
   assert(NewVal && "Unknown PHI node type!");
   PN->addIncoming(NewVal, BB);
-  return true;
 } 
 
 // fixLocalProblems - Loop through the method and fix problems with the PHI
 // nodes in the current method.  The two problems that are handled are:
 //
-//  1. PHI nodes with multiple entries for the same predecessor.
+//  1. PHI nodes with multiple entries for the same predecessor.  GCC sometimes
+//     generates code that looks like this:
+//
+//  bb7:  br bool %cond1004, label %bb8, label %bb8
+//  bb8: %reg119 = phi uint [ 0, %bb7 ], [ 1, %bb7 ]
+//     
+//     which is completely illegal LLVM code.  To compensate for this, we insert
+//     an extra basic block, and convert the code to look like this:
+//
+//  bb7: br bool %cond1004, label %bbX, label %bb8
+//  bbX: br label bb8
+//  bb8: %reg119 = phi uint [ 0, %bbX ], [ 1, %bb7 ]
+//
 //
 //  2. PHI nodes with fewer arguments than predecessors.
 //     These can be generated by GCC if a variable is uninitalized over a path
@@ -404,6 +454,21 @@ static bool fixLocalProblems(Method *M) {
     if (isa<PHINode>(BB->front())) {
       const vector<BasicBlock*> Preds(BB->pred_begin(), BB->pred_end());
 
+      // Handle Problem #1.  Sort the list of predecessors so that it is easy to
+      // decide whether or not duplicate predecessors exist.
+      vector<BasicBlock*> SortedPreds(Preds);
+      sort(SortedPreds.begin(), SortedPreds.end());
+
+      // Loop over the predecessors, looking for adjacent BB's that are equal.
+      BasicBlock *LastOne = 0;
+      for (unsigned i = 0; i < Preds.size(); ++i) {
+        if (SortedPreds[i] == LastOne) {   // Found a duplicate.
+          RefactorPredecessor(BB, SortedPreds[i]);
+          Changed = true;
+        }
+        LastOne = SortedPreds[i];
+      }
+
       // Loop over all of the PHI nodes in the current BB.  These PHI nodes are
       // guaranteed to be at the beginning of the basic block.
       //
@@ -415,7 +480,8 @@ static bool fixLocalProblems(Method *M) {
           assert(PN->getNumIncomingValues() <= Preds.size() &&
                  "Can't handle extra arguments to PHI nodes!");
           for (unsigned i = 0; i < Preds.size(); ++i)
-            Changed |= CheckIncomingValueFor(PN, Preds[i]);
+            CheckIncomingValueFor(PN, Preds[i]);
+          Changed = true;
         }
       }
     }