- Insert new instructions before DomBlock's terminator,
authorChris Lattner <sabre@nondot.org>
Tue, 14 Dec 2010 08:46:09 +0000 (08:46 +0000)
committerChris Lattner <sabre@nondot.org>
Tue, 14 Dec 2010 08:46:09 +0000 (08:46 +0000)
   which is simpler than finding a place to insert in BB.
 - Don't perform the 'if condition hoisting' xform on certain
   i1 PHIs, as it interferes with switch formation.

This re-fixes "example 7", without breaking the world hopefully.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@121764 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Utils/SimplifyCFG.cpp
test/Transforms/SimplifyCFG/PhiEliminate.ll
test/Transforms/SimplifyCFG/switch_create.ll

index 1fbbb42b60e9893ec5e99b07bf5494e8ec2cd134..bbdde4b51f49501f23ce7fb4e9e874663fc2b10a 100644 (file)
@@ -1168,11 +1168,11 @@ static bool FoldTwoEntryPHINode(PHINode *PN, const TargetData *TD) {
   // that need to be moved to the dominating block.
   SmallPtrSet<Instruction*, 4> AggressiveInsts;
   
-  BasicBlock::iterator AfterPHIIt = BB->begin();
-  while (isa<PHINode>(AfterPHIIt)) {
-    PHINode *PN = cast<PHINode>(AfterPHIIt++);
+  for (BasicBlock::iterator II = BB->begin(); isa<PHINode>(II);) {
+    PHINode *PN = cast<PHINode>(II++);
     if (Value *V = SimplifyInstruction(PN, TD)) {
       PN->replaceAllUsesWith(V);
+      PN->eraseFromParent();
       continue;
     }
     
@@ -1186,6 +1186,14 @@ static bool FoldTwoEntryPHINode(PHINode *PN, const TargetData *TD) {
   PN = dyn_cast<PHINode>(BB->begin());
   if (PN == 0) return true;
   
+  // Don't fold i1 branches on PHIs which contain binary operators.  These can
+  // often be turned into switches and other things.
+  if (PN->getType()->isIntegerTy(1) &&
+      (isa<BinaryOperator>(PN->getIncomingValue(0)) ||
+       isa<BinaryOperator>(PN->getIncomingValue(1)) ||
+       isa<BinaryOperator>(IfCond)))
+    return false;
+  
   // If we all PHI nodes are promotable, check to make sure that all
   // instructions in the predecessor blocks can be promoted as well.  If
   // not, we won't be able to get rid of the control flow, so it's not
@@ -1224,15 +1232,16 @@ static bool FoldTwoEntryPHINode(PHINode *PN, const TargetData *TD) {
       
   // If we can still promote the PHI nodes after this gauntlet of tests,
   // do all of the PHI's now.
-
+  Instruction *InsertPt = DomBlock->getTerminator();
+  
   // Move all 'aggressive' instructions, which are defined in the
   // conditional parts of the if's up to the dominating block.
   if (IfBlock1)
-    DomBlock->getInstList().splice(DomBlock->getTerminator(),
+    DomBlock->getInstList().splice(InsertPt,
                                    IfBlock1->getInstList(), IfBlock1->begin(),
                                    IfBlock1->getTerminator());
   if (IfBlock2)
-    DomBlock->getInstList().splice(DomBlock->getTerminator(),
+    DomBlock->getInstList().splice(InsertPt,
                                    IfBlock2->getInstList(), IfBlock2->begin(),
                                    IfBlock2->getTerminator());
   
@@ -1241,7 +1250,7 @@ static bool FoldTwoEntryPHINode(PHINode *PN, const TargetData *TD) {
     Value *TrueVal  = PN->getIncomingValue(PN->getIncomingBlock(0) == IfFalse);
     Value *FalseVal = PN->getIncomingValue(PN->getIncomingBlock(0) == IfTrue);
     
-    Value *NV = SelectInst::Create(IfCond, TrueVal, FalseVal, "", AfterPHIIt);
+    Value *NV = SelectInst::Create(IfCond, TrueVal, FalseVal, "", InsertPt);
     PN->replaceAllUsesWith(NV);
     NV->takeName(PN);
     PN->eraseFromParent();
index 73cf466a4f7486852c866f1ed2cd30831700182d..d5ce9a7e6bc842a0c2928e6660616d5c338a0fce 100644 (file)
@@ -11,20 +11,6 @@ declare void @use(i1)
 
 declare void @use.upgrd.1(i32)
 
-define void @test2(i1 %c, i1 %d, i32 %V, i32 %V2) {
-; <label>:0
-        br i1 %d, label %X, label %F
-X:              ; preds = %0
-        br i1 %c, label %T, label %F
-T:              ; preds = %X
-        br label %F
-F:              ; preds = %T, %X, %0
-        %B1 = phi i1 [ true, %0 ], [ false, %T ], [ false, %X ]         ; <i1> [#uses=1]
-        %I7 = phi i32 [ %V, %0 ], [ %V2, %T ], [ %V2, %X ]              ; <i32> [#uses=1]
-        call void @use( i1 %B1 )
-        call void @use.upgrd.1( i32 %I7 )
-        ret void
-}
 
 define void @test(i1 %c, i32 %V, i32 %V2) {
 ; <label>:0
index 8d051b49f0b6dab1df4121c73c49ee32f23a1354..0169eb7039f539a645c82cadc8f7aeb01811889a 100644 (file)
@@ -253,21 +253,21 @@ lor.end:                                          ; preds = %lor.rhs, %lor.lhs.f
   ret i32 %conv46
   
 ; CHECK: @test9
-; HECK:   %cmp = icmp ult i8 %c, 33
-; HECK:   br i1 %cmp, label %lor.end, label %switch.early.test
-
-; HECK: switch.early.test:
-; HECK:   switch i8 %c, label %lor.rhs [
-; HECK:     i8 46, label %lor.end
-; HECK:     i8 44, label %lor.end
-; HECK:     i8 58, label %lor.end
-; HECK:     i8 59, label %lor.end
-; HECK:     i8 60, label %lor.end
-; HECK:     i8 62, label %lor.end
-; HECK:     i8 34, label %lor.end
-; HECK:     i8 92, label %lor.end
-; HECK:     i8 39, label %lor.end
-; HECK:   ]
+; CHECK:   %cmp = icmp ult i8 %c, 33
+; CHECK:   br i1 %cmp, label %lor.end, label %switch.early.test
+
+; CHECK: switch.early.test:
+; CHECK:   switch i8 %c, label %lor.rhs [
+; CHECK:     i8 92, label %lor.end
+; CHECK:     i8 62, label %lor.end
+; CHECK:     i8 60, label %lor.end
+; CHECK:     i8 59, label %lor.end
+; CHECK:     i8 58, label %lor.end
+; CHECK:     i8 46, label %lor.end
+; CHECK:     i8 44, label %lor.end
+; CHECK:     i8 34, label %lor.end
+; CHECK:     i8 39, label %lor.end
+; CHECK:   ]
 }
 
 define i32 @test10(i32 %mode, i1 %Cond) {
@@ -351,4 +351,4 @@ malformed:
   ret void
 ; CHECK: @test12
 
-}
+}
\ No newline at end of file