[llvm-commits] [llvm] r132022 - /llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp

Evan Cheng evan.cheng at apple.com
Tue May 24 16:12:57 PDT 2011


Author: evancheng
Date: Tue May 24 18:12:57 2011
New Revision: 132022

URL: http://llvm.org/viewvc/llvm-project?rev=132022&view=rev
Log:
Fix LoopUnswitch bug. RewriteLoopBodyWithConditionConstant can delete a dead
case of a switch instruction. Back off this optimization when this would
eliminate all of the predecessors to the latch.

Sorry, I am unable to reduce a reasonably sized test case.

rdar://9486843

Modified:
    llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp

Modified: llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp?rev=132022&r1=132021&r2=132022&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp Tue May 24 18:12:57 2011
@@ -786,8 +786,13 @@
   // If this is the edge to the header block for a loop, remove the loop and
   // promote all subloops.
   if (Loop *BBLoop = LI->getLoopFor(BB)) {
-    if (BBLoop->getLoopLatch() == BB)
+    if (BBLoop->getLoopLatch() == BB) {
       RemoveLoopFromHierarchy(BBLoop);
+      if (currentLoop == BBLoop) {
+        currentLoop = 0;
+        redoLoop = false;
+      }
+    }
   }
 
   // Remove the block from the loop info, which removes it from any loops it
@@ -859,7 +864,6 @@
   
   // FOLD boolean conditions (X|LIC), (X&LIC).  Fold conditional branches,
   // selects, switches.
-  std::vector<User*> Users(LIC->use_begin(), LIC->use_end());
   std::vector<Instruction*> Worklist;
   LLVMContext &Context = Val->getContext();
 
@@ -875,13 +879,14 @@
       Replacement = ConstantInt::get(Type::getInt1Ty(Val->getContext()), 
                                      !cast<ConstantInt>(Val)->getZExtValue());
     
-    for (unsigned i = 0, e = Users.size(); i != e; ++i)
-      if (Instruction *U = cast<Instruction>(Users[i])) {
-        if (!L->contains(U))
-          continue;
-        U->replaceUsesOfWith(LIC, Replacement);
-        Worklist.push_back(U);
-      }
+    for (Value::use_iterator UI = LIC->use_begin(), E = LIC->use_end();
+         UI != E; ++UI) {
+      Instruction *U = cast<Instruction>(*UI);
+      if (!L->contains(U))
+        continue;
+      U->replaceUsesOfWith(LIC, Replacement);
+      Worklist.push_back(U);
+    }
     SimplifyCode(Worklist, L);
     return;
   }
@@ -889,8 +894,9 @@
   // Otherwise, we don't know the precise value of LIC, but we do know that it
   // is certainly NOT "Val".  As such, simplify any uses in the loop that we
   // can.  This case occurs when we unswitch switch statements.
-  for (unsigned i = 0, e = Users.size(); i != e; ++i) {
-    Instruction *U = cast<Instruction>(Users[i]);
+  for (Value::use_iterator UI = LIC->use_begin(), E = LIC->use_end();
+       UI != E; ++UI) {
+    Instruction *U = cast<Instruction>(*UI);
     if (!L->contains(U))
       continue;
 
@@ -910,12 +916,27 @@
     // successor if they become single-entry, those PHI nodes may
     // be in the Users list.
         
+    BasicBlock *Switch = SI->getParent();
+    BasicBlock *SISucc = SI->getSuccessor(DeadCase);
+    BasicBlock *Latch = L->getLoopLatch();
+    // If the DeadCase successor dominates all of the predecessors of the
+    // loop latch, then the transformation isn't safe since it will delete
+    // the predecessor edges to the latch.
+    if (Latch) {
+      bool DominateAll = true;
+      for (pred_iterator PI = pred_begin(Latch), PE = pred_end(Latch);
+           DominateAll && PI != PE; ++PI)
+        if (!DT->dominates(SISucc, *PI))
+          DominateAll = false;
+      if (DominateAll)
+        continue;
+    }
+
     // 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 a dead code path.
-    BasicBlock *Switch = SI->getParent();
-    SplitEdge(Switch, SI->getSuccessor(DeadCase), this);
+    SplitEdge(Switch, SISucc, this);
     // Compute the successors instead of relying on the return value
     // of SplitEdge, since it may have split the switch successor
     // after PHI nodes.





More information about the llvm-commits mailing list