This optimization makes MANY phi nodes that all have the same incoming value.
authorChris Lattner <sabre@nondot.org>
Sun, 14 Nov 2004 19:29:34 +0000 (19:29 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 14 Nov 2004 19:29:34 +0000 (19:29 +0000)
If this happens, detect it early instead of relying on instcombine to notice
it later.  This can be a big speedup, because PHI nodes can have many
incoming values.

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

lib/Transforms/Scalar/InstructionCombining.cpp

index eaadbb4801c8010c979f8b0b9ac1e2ef93fce8b8..50a26c18c95ac2b38c6960c6da40c52e6e0c14de 100644 (file)
@@ -3456,21 +3456,37 @@ Instruction *InstCombiner::FoldPHIArgOpIntoPHI(PHINode &PN) {
   PHINode *NewPN = new PHINode(FirstInst->getOperand(0)->getType(),
                                PN.getName()+".in");
   NewPN->op_reserve(PN.getNumOperands());
-  InsertNewInstBefore(NewPN, PN);
+
+  Value *InVal = FirstInst->getOperand(0);
+  NewPN->addIncoming(InVal, PN.getIncomingBlock(0));
 
   // Add all operands to the new PHI.
-  for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i)
-    NewPN->addIncoming(cast<Instruction>(PN.getIncomingValue(i))->getOperand(0),
-                       PN.getIncomingBlock(i));
+  for (unsigned i = 1, e = PN.getNumIncomingValues(); i != e; ++i) {
+    Value *NewInVal = cast<Instruction>(PN.getIncomingValue(i))->getOperand(0);
+    if (NewInVal != InVal)
+      InVal = 0;
+    NewPN->addIncoming(NewInVal, PN.getIncomingBlock(i));
+  }
+
+  Value *PhiVal;
+  if (InVal) {
+    // The new PHI unions all of the same values together.  This is really
+    // common, so we handle it intelligently here for compile-time speed.
+    PhiVal = InVal;
+    delete NewPN;
+  } else {
+    InsertNewInstBefore(NewPN, PN);
+    PhiVal = NewPN;
+  }
   
   // Insert and return the new operation.
   if (isa<CastInst>(FirstInst))
-    return new CastInst(NewPN, PN.getType());
+    return new CastInst(PhiVal, PN.getType());
   else if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(FirstInst))
-    return BinaryOperator::create(BinOp->getOpcode(), NewPN, ConstantOp);
+    return BinaryOperator::create(BinOp->getOpcode(), PhiVal, ConstantOp);
   else
     return new ShiftInst(cast<ShiftInst>(FirstInst)->getOpcode(),
-                         NewPN, ConstantOp);
+                         PhiVal, ConstantOp);
 }
 
 // PHINode simplification