changeset 12407:53297646b011

Improve convert deoptimize to guard phase to recognize FixedGuardNode following MergeNode.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Mon, 14 Oct 2013 23:30:05 +0200
parents 11e4744f1e86
children a9837a03127e
files graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConvertDeoptimizeToGuardPhase.java
diffstat 2 files changed, 49 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java	Mon Oct 14 23:28:45 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java	Mon Oct 14 23:30:05 2013 +0200
@@ -462,8 +462,8 @@
         List<AbstractEndNode> mergePredecessors = merge.cfgPredecessors().snapshot();
         assert phi.valueCount() == merge.forwardEndCount();
 
-        Constant[] xs = constantValues(compare.x(), merge);
-        Constant[] ys = constantValues(compare.y(), merge);
+        Constant[] xs = constantValues(compare.x(), merge, false);
+        Constant[] ys = constantValues(compare.y(), merge, false);
         if (xs == null || ys == null) {
             return false;
         }
@@ -607,7 +607,7 @@
      * @return null if {@code node} is neither a {@link ConstantNode} nor a {@link PhiNode} whose
      *         input values are all constants
      */
-    private static Constant[] constantValues(ValueNode node, MergeNode merge) {
+    public static Constant[] constantValues(ValueNode node, MergeNode merge, boolean allowNull) {
         if (node.isConstant()) {
             Constant[] result = new Constant[merge.forwardEndCount()];
             Arrays.fill(result, node.asConstant());
@@ -620,7 +620,7 @@
                 Constant[] result = new Constant[merge.forwardEndCount()];
                 int i = 0;
                 for (ValueNode n : phi.values()) {
-                    if (!n.isConstant()) {
+                    if (!allowNull && !n.isConstant()) {
                         return null;
                     }
                     result[i++] = n.asConstant();
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConvertDeoptimizeToGuardPhase.java	Mon Oct 14 23:28:45 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConvertDeoptimizeToGuardPhase.java	Mon Oct 14 23:30:05 2013 +0200
@@ -24,9 +24,11 @@
 
 import java.util.*;
 
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.util.*;
 import com.oracle.graal.phases.*;
 
@@ -45,7 +47,7 @@
  */
 public class ConvertDeoptimizeToGuardPhase extends Phase {
 
-    private static AbstractBeginNode findBeginNode(Node startNode) {
+    private static AbstractBeginNode findBeginNode(FixedNode startNode) {
         Node n = startNode;
         while (true) {
             if (n instanceof AbstractBeginNode) {
@@ -64,16 +66,50 @@
 
         for (DeoptimizeNode d : graph.getNodes(DeoptimizeNode.class)) {
             assert d.isAlive();
-            visitDeoptBegin(findBeginNode(d), d, graph);
+            visitDeoptBegin(BeginNode.prevBegin(d), d.action(), d.reason(), graph);
+        }
+
+        for (FixedGuardNode fixedGuard : graph.getNodes(FixedGuardNode.class)) {
+
+            AbstractBeginNode pred = BeginNode.prevBegin(fixedGuard);
+            if (pred instanceof MergeNode) {
+                MergeNode merge = (MergeNode) pred;
+                if (fixedGuard.condition() instanceof CompareNode) {
+                    CompareNode compare = (CompareNode) fixedGuard.condition();
+                    List<AbstractEndNode> mergePredecessors = merge.cfgPredecessors().snapshot();
+
+                    Constant[] xs = IfNode.constantValues(compare.x(), merge, true);
+                    if (xs == null) {
+                        continue;
+                    }
+                    Constant[] ys = IfNode.constantValues(compare.y(), merge, true);
+                    if (ys == null) {
+                        continue;
+                    }
+                    for (int i = 0; i < mergePredecessors.size(); ++i) {
+                        AbstractEndNode mergePredecessor = mergePredecessors.get(i);
+                        if (xs[i] == null) {
+                            continue;
+                        }
+                        if (ys[i] == null) {
+                            continue;
+                        }
+                        if (xs[i].getKind() != Kind.Object && ys[i].getKind() != Kind.Object &&
+                                        compare.condition().foldCondition(xs[i], ys[i], null, compare.unorderedIsTrue()) == fixedGuard.isNegated()) {
+                            visitDeoptBegin(BeginNode.prevBegin(mergePredecessor), fixedGuard.getAction(), fixedGuard.getReason(), graph);
+                        }
+                    }
+                }
+            }
         }
 
         new DeadCodeEliminationPhase().apply(graph);
     }
 
-    private void visitDeoptBegin(AbstractBeginNode deoptBegin, DeoptimizeNode deopt, StructuredGraph graph) {
+    private void visitDeoptBegin(AbstractBeginNode deoptBegin, DeoptimizationAction deoptAction, DeoptimizationReason deoptReason, StructuredGraph graph) {
         if (deoptBegin instanceof MergeNode) {
             MergeNode mergeNode = (MergeNode) deoptBegin;
-            Debug.log("Visiting %s followed by %s", mergeNode, deopt);
+            Debug.log("Visiting %s", mergeNode);
             List<AbstractBeginNode> begins = new ArrayList<>();
             for (AbstractEndNode end : mergeNode.forwardEnds()) {
                 AbstractBeginNode newBeginNode = findBeginNode(end);
@@ -82,7 +118,7 @@
             }
             for (AbstractBeginNode begin : begins) {
                 assert !begin.isDeleted();
-                visitDeoptBegin(begin, deopt, graph);
+                visitDeoptBegin(begin, deoptAction, deoptReason, graph);
             }
             assert mergeNode.isDeleted();
             return;
@@ -90,7 +126,7 @@
             IfNode ifNode = (IfNode) deoptBegin.predecessor();
             AbstractBeginNode otherBegin = ifNode.trueSuccessor();
             LogicNode conditionNode = ifNode.condition();
-            FixedGuardNode guard = graph.add(new FixedGuardNode(conditionNode, deopt.reason(), deopt.action(), deoptBegin == ifNode.trueSuccessor()));
+            FixedGuardNode guard = graph.add(new FixedGuardNode(conditionNode, deoptReason, deoptAction, deoptBegin == ifNode.trueSuccessor()));
             FixedWithNextNode pred = (FixedWithNextNode) ifNode.predecessor();
             AbstractBeginNode survivingSuccessor;
             if (deoptBegin == ifNode.trueSuccessor()) {
@@ -115,7 +151,7 @@
                     }
                 }
             }
-            Debug.log("Converting %s on %-5s branch of %s to guard for remaining branch %s.", deopt, deoptBegin == ifNode.trueSuccessor() ? "true" : "false", ifNode, otherBegin);
+            Debug.log("Converting deopt on %-5s branch of %s to guard for remaining branch %s.", deoptBegin == ifNode.trueSuccessor() ? "true" : "false", ifNode, otherBegin);
             FixedNode next = pred.next();
             pred.setNext(guard);
             guard.setNext(next);
@@ -126,8 +162,8 @@
         FixedWithNextNode deoptPred = deoptBegin;
         FixedNode next = deoptPred.next();
 
-        if (next != deopt) {
-            DeoptimizeNode newDeoptNode = (DeoptimizeNode) deopt.clone(graph);
+        if (!(next instanceof DeoptimizeNode)) {
+            DeoptimizeNode newDeoptNode = graph.add(new DeoptimizeNode(deoptAction, deoptReason));
             deoptPred.setNext(newDeoptNode);
             assert deoptPred == newDeoptNode.predecessor();
             GraphUtil.killCFG(next);