# HG changeset patch # User Thomas Wuerthinger # Date 1424629917 -3600 # Node ID 9a749d774c73eb5ef37a74a6509b1245c23476b6 # Parent 34462e7f027879b428f381d4133135c37a201740 Refactor ConvertDeoptimizeToGuardPhase. diff -r 34462e7f0278 -r 9a749d774c73 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractBeginNode.java --- 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; } diff -r 34462e7f0278 -r 9a749d774c73 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConvertDeoptimizeToGuardPhase.java --- 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 { 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 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 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; diff -r 34462e7f0278 -r 9a749d774c73 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java --- 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) { diff -r 34462e7f0278 -r 9a749d774c73 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCacheImpl.java --- 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);