--- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/FixReadsPhase.java 2019-03-12 08:10:02.371746867 +0100 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/FixReadsPhase.java 2019-03-12 08:10:02.007744509 +0100 @@ -28,6 +28,7 @@ import jdk.internal.vm.compiler.collections.MapCursor; import org.graalvm.compiler.core.common.GraalOptions; import org.graalvm.compiler.core.common.cfg.BlockMap; +import org.graalvm.compiler.core.common.spi.ConstantFieldProvider; import org.graalvm.compiler.core.common.type.FloatStamp; import org.graalvm.compiler.core.common.type.Stamp; import org.graalvm.compiler.core.common.type.StampFactory; @@ -37,6 +38,7 @@ import org.graalvm.compiler.graph.NodeMap; import org.graalvm.compiler.graph.NodeStack; import org.graalvm.compiler.graph.Position; +import org.graalvm.compiler.graph.spi.CanonicalizerTool; import org.graalvm.compiler.nodeinfo.InputType; import org.graalvm.compiler.nodes.AbstractBeginNode; import org.graalvm.compiler.nodes.AbstractMergeNode; @@ -68,6 +70,7 @@ import org.graalvm.compiler.nodes.memory.MemoryAccess; import org.graalvm.compiler.nodes.memory.MemoryPhiNode; import org.graalvm.compiler.nodes.util.GraphUtil; +import org.graalvm.compiler.options.OptionValues; import org.graalvm.compiler.phases.BasePhase; import org.graalvm.compiler.phases.Phase; import org.graalvm.compiler.phases.graph.ScheduledNodeIterator; @@ -76,7 +79,9 @@ import org.graalvm.compiler.phases.tiers.LowTierContext; import org.graalvm.compiler.phases.tiers.PhaseContext; +import jdk.vm.ci.meta.Assumptions; import jdk.vm.ci.meta.Constant; +import jdk.vm.ci.meta.ConstantReflectionProvider; import jdk.vm.ci.meta.MetaAccessProvider; import jdk.vm.ci.meta.TriState; @@ -136,7 +141,7 @@ } - protected static class RawConditionalEliminationVisitor implements RecursiveVisitor { + public static class RawConditionalEliminationVisitor implements RecursiveVisitor { protected final NodeMap stampMap; protected final NodeStack undoOperations; @@ -147,8 +152,58 @@ private final BlockMap blockActionStart; private final EconomicMap> endMaps; private final DebugContext debug; + private final RawCanonicalizerTool rawCanonicalizerTool = new RawCanonicalizerTool(); - protected RawConditionalEliminationVisitor(StructuredGraph graph, ScheduleResult schedule, MetaAccessProvider metaAccess, boolean replaceInputsWithConstants) { + private class RawCanonicalizerTool implements NodeView, CanonicalizerTool { + + @Override + public Assumptions getAssumptions() { + return graph.getAssumptions(); + } + + @Override + public MetaAccessProvider getMetaAccess() { + return metaAccess; + } + + @Override + public ConstantReflectionProvider getConstantReflection() { + return null; + } + + @Override + public ConstantFieldProvider getConstantFieldProvider() { + return null; + } + + @Override + public boolean canonicalizeReads() { + return false; + } + + @Override + public boolean allUsagesAvailable() { + return true; + } + + @Override + public Integer smallestCompareWidth() { + return null; + } + + @Override + public OptionValues getOptions() { + return graph.getOptions(); + } + + @Override + public Stamp stamp(ValueNode node) { + return getBestStamp(node); + } + + } + + public RawConditionalEliminationVisitor(StructuredGraph graph, ScheduleResult schedule, MetaAccessProvider metaAccess, boolean replaceInputsWithConstants) { this.graph = graph; this.debug = graph.getDebug(); this.schedule = schedule; @@ -326,8 +381,22 @@ } protected void processUnary(UnaryNode node) { - Stamp newStamp = node.foldStamp(getBestStamp(node.getValue())); + ValueNode value = node.getValue(); + Stamp bestStamp = getBestStamp(value); + Stamp newStamp = node.foldStamp(bestStamp); if (!checkReplaceWithConstant(newStamp, node)) { + if (!bestStamp.equals(value.stamp(NodeView.DEFAULT))) { + ValueNode newNode = node.canonical(rawCanonicalizerTool); + if (newNode != node) { + // Canonicalization successfully triggered. + if (newNode != null && !newNode.isAlive()) { + newNode = graph.addWithoutUniqueWithInputs(newNode); + } + node.replaceAndDelete(newNode); + GraphUtil.tryKillUnused(value); + return; + } + } registerNewValueStamp(node, newStamp); } } @@ -346,10 +415,31 @@ } protected void processBinary(BinaryNode node) { - Stamp xStamp = getBestStamp(node.getX()); - Stamp yStamp = getBestStamp(node.getY()); + + ValueNode x = node.getX(); + ValueNode y = node.getY(); + + Stamp xStamp = getBestStamp(x); + Stamp yStamp = getBestStamp(y); Stamp newStamp = node.foldStamp(xStamp, yStamp); if (!checkReplaceWithConstant(newStamp, node)) { + + if (!xStamp.equals(x.stamp(NodeView.DEFAULT)) || !yStamp.equals(y.stamp(NodeView.DEFAULT))) { + // At least one of the inputs has an improved stamp => attempt to canonicalize + // based on that improvement. + ValueNode newNode = node.canonical(rawCanonicalizerTool); + if (newNode != node) { + // Canonicalization successfully triggered. + if (newNode != null && !newNode.isAlive()) { + newNode = graph.addWithoutUniqueWithInputs(newNode); + } + node.replaceAndDelete(newNode); + GraphUtil.tryKillUnused(x); + GraphUtil.tryKillUnused(y); + return; + } + } + registerNewValueStamp(node, newStamp); } } @@ -469,6 +559,10 @@ protected Stamp getBestStamp(ValueNode value) { ValueNode originalNode = value; + if (!value.isAlive()) { + return value.stamp(NodeView.DEFAULT); + } + StampElement currentStamp = stampMap.getAndGrow(originalNode); if (currentStamp == null) { return value.stamp(NodeView.DEFAULT);