changeset 12486:cfb89901214a

Add canonicalizations for more diamond shapes to Conditional if one of the input of the Phi is also a conditional with constants
author Gilles Duboscq <duboscq@ssw.jku.at>
date Thu, 17 Oct 2013 18:18:05 +0200
parents b433297f21c4
children 28d7a11ba008
files graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java
diffstat 1 files changed, 41 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- 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: