--- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/IfNode.java 2017-03-20 17:40:25.000000000 -0700 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/IfNode.java 2017-03-20 17:40:25.000000000 -0700 @@ -29,9 +29,7 @@ import java.util.Arrays; import java.util.Iterator; import java.util.List; -import java.util.Map; -import org.graalvm.compiler.core.common.CollectionsFactory; import org.graalvm.compiler.core.common.calc.Condition; import org.graalvm.compiler.core.common.type.IntegerStamp; import org.graalvm.compiler.core.common.type.Stamp; @@ -50,12 +48,16 @@ import org.graalvm.compiler.nodes.calc.CompareNode; import org.graalvm.compiler.nodes.calc.ConditionalNode; import org.graalvm.compiler.nodes.calc.IntegerBelowNode; +import org.graalvm.compiler.nodes.calc.IntegerEqualsNode; import org.graalvm.compiler.nodes.calc.IntegerLessThanNode; import org.graalvm.compiler.nodes.calc.IsNullNode; +import org.graalvm.compiler.nodes.calc.NormalizeCompareNode; import org.graalvm.compiler.nodes.java.InstanceOfNode; import org.graalvm.compiler.nodes.spi.LIRLowerable; import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool; import org.graalvm.compiler.nodes.util.GraphUtil; +import org.graalvm.util.EconomicMap; +import org.graalvm.util.Equivalence; import jdk.vm.ci.meta.Constant; import jdk.vm.ci.meta.ConstantReflectionProvider; @@ -273,6 +275,11 @@ if (merge.usages().count() != 1 || merge.phis().count() != 1) { return false; } + + if (trueSuccessor().anchored().isNotEmpty() || falseSuccessor().anchored().isNotEmpty()) { + return false; + } + PhiNode phi = merge.phis().first(); ValueNode falseValue = phi.valueAt(falseEnd); ValueNode trueValue = phi.valueAt(trueEnd); @@ -558,7 +565,7 @@ } else if (distinct == 1) { ValueNode trueValue = singlePhi.valueAt(trueEnd); ValueNode falseValue = singlePhi.valueAt(falseEnd); - ConditionalNode conditional = canonicalizeConditionalCascade(trueValue, falseValue); + ValueNode conditional = canonicalizeConditionalCascade(trueValue, falseValue); if (conditional != null) { singlePhi.setValueAt(trueEnd, conditional); removeThroughFalseBranch(tool); @@ -595,12 +602,12 @@ AbstractBeginNode trueBegin = trueSuccessor(); graph().removeSplitPropagate(this, trueBegin, tool); tool.addToWorkList(trueBegin); - if (condition() != null && condition().isAlive() && condition().hasNoUsages()) { - GraphUtil.killWithUnusedFloatingInputs(condition()); + if (condition() != null) { + GraphUtil.tryKillUnused(condition()); } } - private ConditionalNode canonicalizeConditionalCascade(ValueNode trueValue, ValueNode falseValue) { + private ValueNode canonicalizeConditionalCascade(ValueNode trueValue, ValueNode falseValue) { if (trueValue.getStackKind() != falseValue.getStackKind()) { return null; } @@ -624,21 +631,39 @@ } else { return null; } - boolean negateConditionalCondition; - ValueNode otherValue; + boolean negateConditionalCondition = false; + ValueNode otherValue = null; if (constant == conditional.trueValue()) { otherValue = conditional.falseValue(); negateConditionalCondition = false; } else if (constant == conditional.falseValue()) { otherValue = conditional.trueValue(); 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)); + if (otherValue != null) { + if (otherValue.isConstant() && graph().allowShortCircuitOr()) { + double shortCutProbability = probability(trueSuccessor()); + LogicNode newCondition = LogicNode.or(condition(), negateCondition, conditional.condition(), negateConditionalCondition, shortCutProbability); + return graph().unique(new ConditionalNode(newCondition, constant, otherValue)); + } + } else if (!negateCondition && constant.isJavaConstant() && conditional.trueValue().isJavaConstant() && conditional.falseValue().isJavaConstant()) { + IntegerLessThanNode lessThan = null; + IntegerEqualsNode equals = null; + if (condition() instanceof IntegerLessThanNode && conditional.condition() instanceof IntegerEqualsNode && constant.asJavaConstant().asLong() == -1 && + conditional.trueValue().asJavaConstant().asLong() == 0 && conditional.falseValue().asJavaConstant().asLong() == 1) { + lessThan = (IntegerLessThanNode) condition(); + equals = (IntegerEqualsNode) conditional.condition(); + } else if (condition() instanceof IntegerEqualsNode && conditional.condition() instanceof IntegerLessThanNode && constant.asJavaConstant().asLong() == 0 && + conditional.trueValue().asJavaConstant().asLong() == -1 && conditional.falseValue().asJavaConstant().asLong() == 1) { + lessThan = (IntegerLessThanNode) conditional.condition(); + equals = (IntegerEqualsNode) condition(); + } + if (lessThan != null) { + assert equals != null; + if ((lessThan.getX() == equals.getX() && lessThan.getY() == equals.getY()) || (lessThan.getX() == equals.getY() && lessThan.getY() == equals.getX())) { + return graph().unique(new NormalizeCompareNode(lessThan.getX(), lessThan.getY(), false)); + } + } } } return null; @@ -652,6 +677,11 @@ * @param tool */ private boolean splitIfAtPhi(SimplifierTool tool) { + if (graph().getGuardsStage().areFrameStatesAtSideEffects()) { + // Disabled until we make sure we have no FrameState-less merges at this stage + return false; + } + if (!(predecessor() instanceof MergeNode)) { return false; } @@ -738,6 +768,7 @@ end.safeDelete(); } } + transferProxies(trueSuccessor(), trueMerge); transferProxies(falseSuccessor(), falseMerge); @@ -792,7 +823,7 @@ @SuppressWarnings("unchecked") private static LogicNode computeCondition(SimplifierTool tool, LogicNode condition, PhiNode phi, Node value) { if (condition instanceof ShortCircuitOrNode) { - if (condition.graph().getGuardsStage().areDeoptsFixed()) { + if (condition.graph().getGuardsStage().areDeoptsFixed() && condition.graph().allowShortCircuitOr()) { ShortCircuitOrNode orNode = (ShortCircuitOrNode) condition; LogicNode resultX = computeCondition(tool, orNode.x, phi, value); LogicNode resultY = computeCondition(tool, orNode.y, phi, value); @@ -972,7 +1003,7 @@ List falseEnds = new ArrayList<>(mergePredecessors.size()); List trueEnds = new ArrayList<>(mergePredecessors.size()); - Map phiValues = CollectionsFactory.newMap(mergePredecessors.size()); + EconomicMap phiValues = EconomicMap.create(Equivalence.IDENTITY, mergePredecessors.size()); AbstractBeginNode oldFalseSuccessor = falseSuccessor(); AbstractBeginNode oldTrueSuccessor = trueSuccessor(); @@ -1111,7 +1142,7 @@ * @param oldMerge the merge being removed * @param phiValues the values of the phi at the merge, keyed by the merge ends */ - private void connectEnds(List ends, Map phiValues, AbstractBeginNode successor, AbstractMergeNode oldMerge, SimplifierTool tool) { + private void connectEnds(List ends, EconomicMap phiValues, AbstractBeginNode successor, AbstractMergeNode oldMerge, SimplifierTool tool) { if (!ends.isEmpty()) { if (ends.size() == 1) { AbstractEndNode end = ends.get(0); @@ -1184,4 +1215,21 @@ public AbstractBeginNode getSuccessor(boolean result) { return result ? this.trueSuccessor() : this.falseSuccessor(); } + + @Override + public boolean setProbability(AbstractBeginNode successor, double value) { + if (successor == this.trueSuccessor()) { + this.setTrueSuccessorProbability(value); + return true; + } else if (successor == this.falseSuccessor()) { + this.setTrueSuccessorProbability(1.0 - value); + return true; + } + return false; + } + + @Override + public int getSuccessorCount() { + return 2; + } }