[llvm-commits] CVS: llvm/lib/Transforms/Scalar/IndVarSimplify.cpp

Owen Anderson resistor at mac.com
Wed Jul 12 14:29:26 PDT 2006



Changes in directory llvm/lib/Transforms/Scalar:

IndVarSimplify.cpp updated: 1.85 -> 1.86
---
Log message:

IndVars now (correctly) preserves LCSSA form.


---
Diffs of the changes:  (+31 -15)

 IndVarSimplify.cpp |   46 +++++++++++++++++++++++++++++++---------------
 1 files changed, 31 insertions(+), 15 deletions(-)


Index: llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
diff -u llvm/lib/Transforms/Scalar/IndVarSimplify.cpp:1.85 llvm/lib/Transforms/Scalar/IndVarSimplify.cpp:1.86
--- llvm/lib/Transforms/Scalar/IndVarSimplify.cpp:1.85	Tue Jul 11 02:25:33 2006
+++ llvm/lib/Transforms/Scalar/IndVarSimplify.cpp	Wed Jul 12 16:29:14 2006
@@ -79,6 +79,7 @@
       AU.addRequired<ScalarEvolution>();
       AU.addRequired<LoopInfo>();
       AU.addPreservedID(LoopSimplifyID);
+      AU.addPreservedID(LCSSAID);
       AU.setPreservesCFG();
     }
   private:
@@ -325,20 +326,8 @@
             for (Value::use_iterator UI = I->use_begin(), E = I->use_end();
                  UI != E; ++UI) {
               Instruction *User = cast<Instruction>(*UI);
-              if (!L->contains(User->getParent())) {
-                // If this is a PHI node in the exit block and we're inserting,
-                // into the exit block, it must have a single entry.  In this
-                // case, we can't insert the code after the PHI and have the PHI
-                // still use it.  Instead, don't insert the the PHI.
-                if (PHINode *PN = dyn_cast<PHINode>(User)) {
-                  // FIXME: This is a case where LCSSA pessimizes code, this
-                  // should be fixed better.
-                  if (PN->getNumOperands() == 2 && 
-                      PN->getParent() == BlockToInsertInto)
-                    continue;
-                }
+              if (!L->contains(User->getParent()))
                 ExtraLoopUsers.push_back(User);
-              }
             }
             
             if (!ExtraLoopUsers.empty()) {
@@ -358,8 +347,35 @@
 
                 // Rewrite any users of the computed value outside of the loop
                 // with the newly computed value.
-                for (unsigned i = 0, e = ExtraLoopUsers.size(); i != e; ++i)
-                  ExtraLoopUsers[i]->replaceUsesOfWith(I, NewVal);
+                for (unsigned i = 0, e = ExtraLoopUsers.size(); i != e; ++i) {
+                  PHINode* PN = dyn_cast<PHINode>(ExtraLoopUsers[i]);
+                  if (PN && !L->contains(PN->getParent())) {
+                     // We're dealing with an LCSSA Phi.  Handle it specially.
+                    Instruction* LCSSAInsertPt = BlockToInsertInto->begin();
+                    
+                    Instruction* NewInstr = dyn_cast<Instruction>(NewVal);
+                    if (NewInstr && !isa<PHINode>(NewInstr) &&
+                        !L->contains(NewInstr->getParent()))
+                      for (unsigned j = 0; j < NewInstr->getNumOperands(); ++j){
+                        Instruction* PredI = 
+                                 dyn_cast<Instruction>(NewInstr->getOperand(j));
+                        if (PredI && L->contains(PredI->getParent())) {
+                          PHINode* NewLCSSA = new PHINode(PredI->getType(),
+                                                    PredI->getName() + ".lcssa",
+                                                    LCSSAInsertPt);
+                          NewLCSSA->addIncoming(PredI, 
+                                     BlockToInsertInto->getSinglePredecessor());
+                        
+                          NewInstr->replaceUsesOfWith(PredI, NewLCSSA);
+                        }
+                      }
+                    
+                    PN->replaceAllUsesWith(NewVal);
+                    PN->eraseFromParent();
+                  } else {
+                    ExtraLoopUsers[i]->replaceUsesOfWith(I, NewVal);
+                  }
+                }
 
                 // If this instruction is dead now, schedule it to be removed.
                 if (I->use_empty())






More information about the llvm-commits mailing list