# HG changeset patch # User Tom Rodriguez # Date 1446450362 28800 # Node ID 21c01c87ddfb3849b0c51329165fee1f9c705891 # Parent 85b76567ea2cba4b42175de9e29ff741bc166153 Be more conservative when moving tests upward diff -r 85b76567ea2c -r 21c01c87ddfb graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DominatorConditionalEliminationPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DominatorConditionalEliminationPhase.java Sun Nov 01 22:08:26 2015 -0800 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DominatorConditionalEliminationPhase.java Sun Nov 01 23:46:02 2015 -0800 @@ -31,6 +31,7 @@ import java.util.Deque; import java.util.Iterator; import java.util.List; +import java.util.function.BiConsumer; import java.util.function.Function; import jdk.vm.ci.meta.JavaConstant; @@ -70,7 +71,9 @@ import com.oracle.graal.nodes.ValueNode; import com.oracle.graal.nodes.calc.AndNode; import com.oracle.graal.nodes.calc.BinaryArithmeticNode; +import com.oracle.graal.nodes.calc.BinaryNode; import com.oracle.graal.nodes.calc.IntegerEqualsNode; +import com.oracle.graal.nodes.calc.UnaryNode; import com.oracle.graal.nodes.cfg.Block; import com.oracle.graal.nodes.cfg.ControlFlowGraph; import com.oracle.graal.nodes.extended.GuardingNode; @@ -372,6 +375,35 @@ registerCondition(condition, negated, guard, undoOperations); } + /** + * Checks for safe nodes when moving pending tests up. + */ + static class InputFilter implements BiConsumer { + boolean ok; + private ValueNode value; + + InputFilter(ValueNode value) { + this.value = value; + this.ok = true; + } + + public void accept(Node node, Node curNode) { + if (!(curNode instanceof ValueNode)) { + ok = false; + return; + } + ValueNode curValue = (ValueNode) curNode; + if (curValue.isConstant() || curValue == value) { + return; + } + if (curValue instanceof BinaryNode || curValue instanceof UnaryNode) { + curValue.acceptInputs(this); + } else { + ok = false; + } + } + } + private boolean foldPendingTest(DeoptimizingGuard thisGuard, ValueNode original, Stamp newStamp, GuardRewirer rewireGuardFunction) { for (PendingTest pending : pendingTests) { TriState result = TriState.UNKNOWN; @@ -379,9 +411,6 @@ UnaryOpLogicNode unaryLogicNode = (UnaryOpLogicNode) pending.condition; if (unaryLogicNode.getValue() == original) { result = unaryLogicNode.tryFold(newStamp); - if (result.isKnown()) { - Debug.log("unary %s %s %1s", result, newStamp, unaryLogicNode); - } } } else if (pending.condition instanceof BinaryOpLogicNode) { BinaryOpLogicNode binaryOpLogicNode = (BinaryOpLogicNode) pending.condition; @@ -398,7 +427,15 @@ } } if (result.isKnown()) { - if (foldGuard(thisGuard, pending.guard, result, rewireGuardFunction)) { + /* + * The test case be folded using the information available but the test can only + * be moved up if we're sure there's no schedule dependence. For now limit it to + * the original node and constants. + */ + InputFilter v = new InputFilter(original); + thisGuard.getCondition().acceptInputs(v); + if (v.ok && foldGuard(thisGuard, pending.guard, result, rewireGuardFunction)) { + Debug.log("foldPendingTest %s %s %1s", result, newStamp, pending.condition); return true; } }