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

Owen Anderson resistor at mac.com
Mon Jun 26 00:44:50 PDT 2006



Changes in directory llvm/lib/Transforms/Scalar:

LoopUnswitch.cpp updated: 1.40 -> 1.41
---
Log message:

Make LoopUnswitch able to unswitch loops with live-out values by taking advantage
of LCSSA.  This results several times the number of unswitchings occurring on
tests such and timberwolfmc, unix-tbl, and ldecod.


---
Diffs of the changes:  (+63 -53)

 LoopUnswitch.cpp |  116 +++++++++++++++++++++++++++++--------------------------
 1 files changed, 63 insertions(+), 53 deletions(-)


Index: llvm/lib/Transforms/Scalar/LoopUnswitch.cpp
diff -u llvm/lib/Transforms/Scalar/LoopUnswitch.cpp:1.40 llvm/lib/Transforms/Scalar/LoopUnswitch.cpp:1.41
--- llvm/lib/Transforms/Scalar/LoopUnswitch.cpp:1.40	Tue Jun 13 23:46:17 2006
+++ llvm/lib/Transforms/Scalar/LoopUnswitch.cpp	Mon Jun 26 02:44:36 2006
@@ -208,31 +208,6 @@
   return Changed;
 }
 
-
-/// LoopValuesUsedOutsideLoop - Return true if there are any values defined in
-/// the loop that are used by instructions outside of it.
-static bool LoopValuesUsedOutsideLoop(Loop *L) {
-  // We will be doing lots of "loop contains block" queries.  Loop::contains is
-  // linear time, use a set to speed this up.
-  std::set<BasicBlock*> LoopBlocks;
-
-  for (Loop::block_iterator BB = L->block_begin(), E = L->block_end();
-       BB != E; ++BB)
-    LoopBlocks.insert(*BB);
-  
-  for (Loop::block_iterator BB = L->block_begin(), E = L->block_end();
-       BB != E; ++BB) {
-    for (BasicBlock::iterator I = (*BB)->begin(), E = (*BB)->end(); I != E; ++I)
-      for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); UI != E;
-           ++UI) {
-        BasicBlock *UserBB = cast<Instruction>(*UI)->getParent();
-        if (!LoopBlocks.count(UserBB))
-          return true;
-      }
-  }
-  return false;
-}
-
 /// isTrivialLoopExitBlock - Check to see if all paths from BB either:
 ///   1. Exit the loop with no side effects.
 ///   2. Branch to the latch block with no side-effects.
@@ -391,17 +366,7 @@
                     << L->getBlocks().size() << "\n");
     return false;
   }
-    
-  // If this loop has live-out values, we can't unswitch it. We need something
-  // like loop-closed SSA form in order to know how to insert PHI nodes for
-  // these values.
-  if (LoopValuesUsedOutsideLoop(L)) {
-    DEBUG(std::cerr << "NOT unswitching loop %" << L->getHeader()->getName()
-                    << ", a loop value is used outside loop!  Cost: "
-                    << Cost << "\n");
-    return false;
-  }
-   
+  
   // If this is a trivial condition to unswitch (which results in no code
   // duplication), do it now.
   Constant *CondVal;
@@ -456,18 +421,6 @@
     // If the successor only has a single pred, split the top of the successor
     // block.
     assert(SP == BB && "CFG broken");
-    
-    // If this block has a single predecessor, remove any phi nodes.  Unswitch
-    // expect that, after split the edges from inside the loop to the exit
-    // block, that there will be no phi nodes in the new exit block.  Single
-    // entry phi nodes break this assumption.
-    BasicBlock::iterator I = Succ->begin();
-    while (PHINode *PN = dyn_cast<PHINode>(I)) {
-      PN->replaceAllUsesWith(PN->getIncomingValue(0));
-      PN->eraseFromParent();
-      I = Succ->begin();
-    }
-    
     return SplitBlock(Succ, Succ->begin());
   } else {
     // Otherwise, if BB has a single successor, split it at the bottom of the
@@ -616,8 +569,8 @@
   ExitBlocks.erase(std::unique(ExitBlocks.begin(), ExitBlocks.end()),
                    ExitBlocks.end());
   
-  // Split all of the edges from inside the loop to their exit blocks.  This
-  // unswitching trivial: no phi nodes to update.
+  // Split all of the edges from inside the loop to their exit blocks.  Update
+  // the appropriate Phi nodes as we do so.
   unsigned NumBlocks = L->getBlocks().size();
   
   for (unsigned i = 0, e = ExitBlocks.size(); i != e; ++i) {
@@ -627,8 +580,42 @@
     for (unsigned j = 0, e = Preds.size(); j != e; ++j) {
       assert(L->contains(Preds[j]) &&
              "All preds of loop exit blocks must be the same loop!");
-      SplitEdge(Preds[j], ExitBlock);
-    }
+      BasicBlock* MiddleBlock = SplitEdge(Preds[j], ExitBlock);
+      BasicBlock* StartBlock = Preds[j];
+      BasicBlock* EndBlock;
+      if (MiddleBlock->getSinglePredecessor() == ExitBlock) {
+        EndBlock = MiddleBlock;
+        MiddleBlock = EndBlock->getSinglePredecessor();;
+      } else {
+        EndBlock = ExitBlock;
+      }
+      
+      std::set<PHINode*> InsertedPHIs;
+      PHINode* OldLCSSA = 0;
+      for (BasicBlock::iterator I = EndBlock->begin();
+           (OldLCSSA = dyn_cast<PHINode>(I)); ++I) {
+        Value* OldValue = OldLCSSA->getIncomingValueForBlock(MiddleBlock);
+        PHINode* NewLCSSA = new PHINode(OldLCSSA->getType(),
+                                        OldLCSSA->getName() + ".us-lcssa",
+                                        MiddleBlock->getTerminator());
+        NewLCSSA->addIncoming(OldValue, StartBlock);
+        OldLCSSA->setIncomingValue(OldLCSSA->getBasicBlockIndex(MiddleBlock),
+                                   NewLCSSA);
+        InsertedPHIs.insert(NewLCSSA);
+      }
+
+      Instruction* InsertPt = EndBlock->begin();
+      while (dyn_cast<PHINode>(InsertPt)) ++InsertPt;
+      for (BasicBlock::iterator I = MiddleBlock->begin();
+         (OldLCSSA = dyn_cast<PHINode>(I)) && InsertedPHIs.count(OldLCSSA) == 0;
+         ++I) {
+        PHINode *NewLCSSA = new PHINode(OldLCSSA->getType(),
+                                        OldLCSSA->getName() + ".us-lcssa",
+                                        InsertPt);
+        OldLCSSA->replaceAllUsesWith(NewLCSSA);
+        NewLCSSA->addIncoming(OldLCSSA, MiddleBlock);
+      }
+    }    
   }
   
   // The exit blocks may have been changed due to edge splitting, recompute.
@@ -967,7 +954,30 @@
               // Found a dead case value.  Don't remove PHI nodes in the 
               // successor if they become single-entry, those PHI nodes may
               // be in the Users list.
-              SI->getSuccessor(i)->removePredecessor(SI->getParent(), true);
+              
+              // FIXME: This is a hack.  We need to keep the successor around
+              // and hooked up so as to preserve the loop structure, because
+              // trying to update it is complicated.  So instead we preserve the
+              // loop structure and put the block on an dead code path.
+              
+              BasicBlock* Old = SI->getParent();
+              BasicBlock* Split = SplitBlock(Old, SI);
+              
+              Instruction* OldTerm = Old->getTerminator();
+              BranchInst* Branch = new BranchInst(Split,
+                                        SI->getSuccessor(i),
+                                        ConstantBool::True,
+                                        OldTerm);
+              
+              Old->getTerminator()->eraseFromParent();
+              
+              for (BasicBlock::iterator II = SI->getSuccessor(i)->begin(),
+                   IE = SI->getSuccessor(i)->end(); II != IE; ++II) {
+                if (isa<PHINode>(*II)) {
+                  (*II).replaceUsesOfWith(Split, Old);
+                }
+              }
+
               SI->removeCase(i);
               break;
             }






More information about the llvm-commits mailing list