# HG changeset patch # User Gilles Duboscq # Date 1382026685 -7200 # Node ID cfb89901214a94dd37227ea272cb8edc00bead6a # Parent b433297f21c4aed3a38d9a5cd12c88b13b7ea6ac Add canonicalizations for more diamond shapes to Conditional if one of the input of the Phi is also a conditional with constants diff -r b433297f21c4 -r cfb89901214a graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java Thu Oct 17 18:18:05 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java Thu Oct 17 18:18:05 2013 +0200 @@ -358,9 +358,9 @@ if (trueValue.kind() != Kind.Int && trueValue.kind() != Kind.Long) { return false; } - if (trueValue.isConstant() && falseValue.isConstant()) { - ConditionalNode materialize = graph().unique(new ConditionalNode(condition(), trueValue, falseValue)); - graph().replaceFloating(singlePhi, materialize); + ConditionalNode conditional = canonicalizeConditionalCascade(trueValue, falseValue); + if (conditional != null) { + graph().replaceFloating(singlePhi, conditional); removeEmptyIf(tool); return true; } @@ -371,6 +371,44 @@ return false; } + private ConditionalNode canonicalizeConditionalCascade(ValueNode trueValue, ValueNode falseValue) { + if (trueValue.isConstant() && falseValue.isConstant()) { + return graph().unique(new ConditionalNode(condition(), trueValue, falseValue)); + } else { + ConditionalNode conditional = null; + ValueNode constant = null; + boolean negateCondition; + if (trueValue instanceof ConditionalNode && falseValue.isConstant()) { + conditional = (ConditionalNode) trueValue; + constant = falseValue; + negateCondition = true; + } else if (falseValue instanceof ConditionalNode && trueValue.isConstant()) { + conditional = (ConditionalNode) falseValue; + constant = trueValue; + negateCondition = false; + } else { + return null; + } + boolean negateConditionalCondition; + ValueNode otherValue; + if (constant == conditional.x()) { + otherValue = conditional.y(); + negateConditionalCondition = false; + } else if (constant == conditional.y()) { + otherValue = conditional.x(); + negateConditionalCondition = true; + } else { + return null; + } + if (otherValue.isConstant()) { + double shortCutProbability = probability(trueSuccessor()); + LogicNode newCondition = LogicNode.or(condition(), negateCondition, conditional.condition(), negateConditionalCondition, shortCutProbability); + return graph().unique(new ConditionalNode(newCondition, constant, otherValue)); + } + } + return null; + } + /** * Tries to connect code that initializes a variable directly with the successors of an if * construct that switches on the variable. For example, the pseudo code below: