[llvm-commits] [llvm] r43777 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/phi-merge.ll
Chris Lattner
sabre at nondot.org
Tue Nov 6 13:52:08 PST 2007
Author: lattner
Date: Tue Nov 6 15:52:06 2007
New Revision: 43777
URL: http://llvm.org/viewvc/llvm-project?rev=43777&view=rev
Log:
Implement PR1777 by detecting dependent phis that
all compute the same value.
Added:
llvm/trunk/test/Transforms/InstCombine/phi-merge.ll
Modified:
llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=43777&r1=43776&r2=43777&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Tue Nov 6 15:52:06 2007
@@ -8551,6 +8551,34 @@
return false;
}
+/// PHIsEqualValue - Return true if this phi node is always equal to
+/// NonPhiInVal. This happens with mutually cyclic phi nodes like:
+/// z = some value; x = phi (y, z); y = phi (x, z)
+static bool PHIsEqualValue(PHINode *PN, Value *NonPhiInVal,
+ SmallPtrSet<PHINode*, 16> &ValueEqualPHIs) {
+ // See if we already saw this PHI node.
+ if (!ValueEqualPHIs.insert(PN))
+ return true;
+
+ // Don't scan crazily complex things.
+ if (ValueEqualPHIs.size() == 16)
+ return false;
+
+ // Scan the operands to see if they are either phi nodes or are equal to
+ // the value.
+ for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
+ Value *Op = PN->getIncomingValue(i);
+ if (PHINode *OpPN = dyn_cast<PHINode>(Op)) {
+ if (!PHIsEqualValue(OpPN, NonPhiInVal, ValueEqualPHIs))
+ return false;
+ } else if (Op != NonPhiInVal)
+ return false;
+ }
+
+ return true;
+}
+
+
// PHINode simplification
//
Instruction *InstCombiner::visitPHINode(PHINode &PN) {
@@ -8592,6 +8620,40 @@
}
}
+ // We sometimes end up with phi cycles that non-obviously end up being the
+ // same value, for example:
+ // z = some value; x = phi (y, z); y = phi (x, z)
+ // where the phi nodes don't necessarily need to be in the same block. Do a
+ // quick check to see if the PHI node only contains a single non-phi value, if
+ // so, scan to see if the phi cycle is actually equal to that value.
+ {
+ unsigned InValNo = 0, NumOperandVals = PN.getNumIncomingValues();
+ // Scan for the first non-phi operand.
+ while (InValNo != NumOperandVals &&
+ isa<PHINode>(PN.getIncomingValue(InValNo)))
+ ++InValNo;
+
+ if (InValNo != NumOperandVals) {
+ Value *NonPhiInVal = PN.getOperand(InValNo);
+
+ // Scan the rest of the operands to see if there are any conflicts, if so
+ // there is no need to recursively scan other phis.
+ for (++InValNo; InValNo != NumOperandVals; ++InValNo) {
+ Value *OpVal = PN.getIncomingValue(InValNo);
+ if (OpVal != NonPhiInVal && !isa<PHINode>(OpVal))
+ break;
+ }
+
+ // If we scanned over all operands, then we have one unique value plus
+ // phi values. Scan PHI nodes to see if they all merge in each other or
+ // the value.
+ if (InValNo == NumOperandVals) {
+ SmallPtrSet<PHINode*, 16> ValueEqualPHIs;
+ if (PHIsEqualValue(&PN, NonPhiInVal, ValueEqualPHIs))
+ return ReplaceInstUsesWith(PN, NonPhiInVal);
+ }
+ }
+ }
return 0;
}
Added: llvm/trunk/test/Transforms/InstCombine/phi-merge.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/phi-merge.ll?rev=43777&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/phi-merge.ll (added)
+++ llvm/trunk/test/Transforms/InstCombine/phi-merge.ll Tue Nov 6 15:52:06 2007
@@ -0,0 +1,31 @@
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep {phi i32}
+; PR1777
+
+declare i1 @rrr()
+
+define i1 @zxcv() {
+entry:
+%a = alloca i32
+%i = ptrtoint i32* %a to i32
+%b = call i1 @rrr()
+br i1 %b, label %one, label %two
+
+one:
+%x = phi i32 [%i, %entry], [%y, %two]
+%c = call i1 @rrr()
+br i1 %c, label %two, label %end
+
+two:
+%y = phi i32 [%i, %entry], [%x, %one]
+%d = call i1 @rrr()
+br i1 %d, label %one, label %end
+
+end:
+%f = phi i32 [ %x, %one], [%y, %two]
+; Change the %f to %i, and the optimizer suddenly becomes a lot smarter
+; even though %f must equal %i at this point
+%g = inttoptr i32 %f to i32*
+store i32 10, i32* %g
+%z = call i1 @rrr()
+ret i1 %z
+}
More information about the llvm-commits
mailing list