changeset 19540:9a749d774c73

Refactor ConvertDeoptimizeToGuardPhase.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Sun, 22 Feb 2015 19:31:57 +0100
parents 34462e7f0278
children c66037cb9cd1
files graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractBeginNode.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConvertDeoptimizeToGuardPhase.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCacheImpl.java
diffstat 4 files changed, 72 insertions(+), 42 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractBeginNode.java	Sun Feb 22 17:50:30 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractBeginNode.java	Sun Feb 22 19:31:57 2015 +0100
@@ -33,7 +33,6 @@
 import com.oracle.graal.nodeinfo.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.util.*;
 
 @NodeInfo(allowedUsageTypes = {InputType.Guard, InputType.Anchor})
 public abstract class AbstractBeginNode extends FixedWithNextNode implements LIRLowerable, Simplifiable, GuardingNode, AnchoringNode, IterableNodeType {
@@ -64,8 +63,13 @@
     }
 
     public static AbstractBeginNode prevBegin(FixedNode from) {
-        for (AbstractBeginNode begin : GraphUtil.predecessorIterable(from).filter(AbstractBeginNode.class)) {
-            return begin;
+        Node next = from;
+        while (next != null) {
+            if (next instanceof AbstractBeginNode) {
+                AbstractBeginNode begin = (AbstractBeginNode) next;
+                return begin;
+            }
+            next = next.predecessor();
         }
         return null;
     }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConvertDeoptimizeToGuardPhase.java	Sun Feb 22 17:50:30 2015 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConvertDeoptimizeToGuardPhase.java	Sun Feb 22 19:31:57 2015 +0100
@@ -34,6 +34,7 @@
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.util.*;
 import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.tiers.*;
 
 /**
  * This phase will find branches which always end with a {@link DeoptimizeNode} and replace their
@@ -48,7 +49,7 @@
  * {@link DeoptimizeNode} as close to the {@link ControlSplitNode} as possible.
  *
  */
-public class ConvertDeoptimizeToGuardPhase extends Phase {
+public class ConvertDeoptimizeToGuardPhase extends BasePhase<PhaseContext> {
     private SimplifierTool simplifierTool = GraphUtil.getDefaultSimplifier(null, null, false);
 
     private static AbstractBeginNode findBeginNode(FixedNode startNode) {
@@ -56,7 +57,7 @@
     }
 
     @Override
-    protected void run(final StructuredGraph graph) {
+    protected void run(final StructuredGraph graph, PhaseContext context) {
         assert graph.hasValueProxies() : "ConvertDeoptimizeToGuardPhase always creates proxies";
         if (graph.getNodes(DeoptimizeNode.TYPE).isEmpty()) {
             return;
@@ -66,46 +67,71 @@
             visitDeoptBegin(AbstractBeginNode.prevBegin(d), d.action(), d.reason(), graph);
         }
 
-        for (FixedGuardNode fixedGuard : graph.getNodes(FixedGuardNode.TYPE)) {
-
-            AbstractBeginNode pred = AbstractBeginNode.prevBegin(fixedGuard);
-            if (pred instanceof AbstractMergeNode) {
-                AbstractMergeNode merge = (AbstractMergeNode) pred;
-                if (fixedGuard.condition() instanceof CompareNode) {
-                    CompareNode compare = (CompareNode) fixedGuard.condition();
-                    List<EndNode> mergePredecessors = merge.cfgPredecessors().snapshot();
-
-                    Constant[] xs = IfNode.constantValues(compare.getX(), merge, true);
-                    if (xs == null) {
-                        continue;
-                    }
-                    Constant[] ys = IfNode.constantValues(compare.getY(), merge, true);
-                    if (ys == null) {
-                        continue;
-                    }
-                    for (int i = 0; i < mergePredecessors.size(); ++i) {
-                        AbstractEndNode mergePredecessor = mergePredecessors.get(i);
-                        if (!mergePredecessor.isAlive()) {
-                            break;
-                        }
-                        if (xs[i] == null) {
-                            continue;
-                        }
-                        if (ys[i] == null) {
-                            continue;
-                        }
-                        if (xs[i] instanceof PrimitiveConstant && ys[i] instanceof PrimitiveConstant &&
-                                        compare.condition().foldCondition(xs[i], ys[i], null, compare.unorderedIsTrue()) == fixedGuard.isNegated()) {
-                            visitDeoptBegin(AbstractBeginNode.prevBegin(mergePredecessor), fixedGuard.getAction(), fixedGuard.getReason(), graph);
-                        }
-                    }
-                }
+        if (context != null) {
+            for (FixedGuardNode fixedGuard : graph.getNodes(FixedGuardNode.TYPE)) {
+                trySplitFixedGuard(fixedGuard, context);
             }
         }
 
         new DeadCodeEliminationPhase(Optional).apply(graph);
     }
 
+    private void trySplitFixedGuard(FixedGuardNode fixedGuard, PhaseContext context) {
+        LogicNode condition = fixedGuard.condition();
+        if (condition instanceof CompareNode) {
+            CompareNode compare = (CompareNode) condition;
+            ValueNode x = compare.getX();
+            ValuePhiNode xPhi = (x instanceof ValuePhiNode) ? (ValuePhiNode) x : null;
+            if (x instanceof ConstantNode || xPhi != null) {
+                ValueNode y = compare.getY();
+                ValuePhiNode yPhi = (y instanceof ValuePhiNode) ? (ValuePhiNode) y : null;
+                if (y instanceof ConstantNode || yPhi != null) {
+                    processFixedGuardAndPhis(fixedGuard, context, compare, x, xPhi, y, yPhi);
+                }
+            }
+        }
+    }
+
+    private void processFixedGuardAndPhis(FixedGuardNode fixedGuard, PhaseContext context, CompareNode compare, ValueNode x, ValuePhiNode xPhi, ValueNode y, ValuePhiNode yPhi) {
+        AbstractBeginNode pred = AbstractBeginNode.prevBegin(fixedGuard);
+        if (pred instanceof AbstractMergeNode) {
+            AbstractMergeNode merge = (AbstractMergeNode) pred;
+            if (xPhi != null && xPhi.merge() != merge) {
+                return;
+            }
+            if (yPhi != null && yPhi.merge() != merge) {
+                return;
+            }
+
+            processFixedGuardAndMerge(fixedGuard, context, compare, x, xPhi, y, yPhi, merge);
+        }
+    }
+
+    private void processFixedGuardAndMerge(FixedGuardNode fixedGuard, PhaseContext context, CompareNode compare, ValueNode x, ValuePhiNode xPhi, ValueNode y, ValuePhiNode yPhi, AbstractMergeNode merge) {
+        List<EndNode> mergePredecessors = merge.cfgPredecessors().snapshot();
+        for (int i = 0; i < mergePredecessors.size(); ++i) {
+            AbstractEndNode mergePredecessor = mergePredecessors.get(i);
+            if (!mergePredecessor.isAlive()) {
+                break;
+            }
+            Constant xs;
+            if (xPhi == null) {
+                xs = x.asConstant();
+            } else {
+                xs = xPhi.valueAt(mergePredecessor).asConstant();
+            }
+            Constant ys;
+            if (yPhi == null) {
+                ys = y.asConstant();
+            } else {
+                ys = yPhi.valueAt(mergePredecessor).asConstant();
+            }
+            if (xs != null && ys != null && compare.condition().foldCondition(xs, ys, context.getConstantReflection(), compare.unorderedIsTrue()) == fixedGuard.isNegated()) {
+                visitDeoptBegin(AbstractBeginNode.prevBegin(mergePredecessor), fixedGuard.getAction(), fixedGuard.getReason(), fixedGuard.graph());
+            }
+        }
+    }
+
     private void visitDeoptBegin(AbstractBeginNode deoptBegin, DeoptimizationAction deoptAction, DeoptimizationReason deoptReason, StructuredGraph graph) {
         if (deoptBegin instanceof AbstractMergeNode) {
             AbstractMergeNode mergeNode = (AbstractMergeNode) deoptBegin;
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Sun Feb 22 17:50:30 2015 +0100
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Sun Feb 22 19:31:57 2015 +0100
@@ -539,7 +539,7 @@
             }
             int sideEffectCount = 0;
             assert (sideEffectCount = graph.getNodes().filter(e -> hasSideEffect(e)).count()) >= 0;
-            new ConvertDeoptimizeToGuardPhase().apply(graph);
+            new ConvertDeoptimizeToGuardPhase().apply(graph, null);
             assert sideEffectCount == graph.getNodes().filter(e -> hasSideEffect(e)).count() : "deleted side effecting node";
 
             switch (frameStateProcessing) {
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCacheImpl.java	Sun Feb 22 17:50:30 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCacheImpl.java	Sun Feb 22 19:31:57 2015 +0100
@@ -147,7 +147,7 @@
             new ReplaceIntrinsicsPhase(providers.getReplacements()).apply(graph);
 
             // Convert deopt to guards.
-            new ConvertDeoptimizeToGuardPhase().apply(graph);
+            new ConvertDeoptimizeToGuardPhase().apply(graph, phaseContext);
 
             PartialEscapePhase partialEscapePhase = new PartialEscapePhase(false, canonicalizer);
 
@@ -175,7 +175,7 @@
                 }
 
                 // Convert deopt to guards.
-                new ConvertDeoptimizeToGuardPhase().apply(graph);
+                new ConvertDeoptimizeToGuardPhase().apply(graph, phaseContext);
 
                 new EarlyReadEliminationPhase(canonicalizer).apply(graph, phaseContext);