< prev index next >

src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/FixReadsPhase.java

Print this page

        

@@ -26,19 +26,21 @@
 
 import jdk.internal.vm.compiler.collections.EconomicMap;
 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;
 import org.graalvm.compiler.debug.CounterKey;
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.graph.Node;
 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;
 import org.graalvm.compiler.nodes.BinaryOpLogicNode;
 import org.graalvm.compiler.nodes.ConstantNode;

@@ -66,19 +68,22 @@
 import org.graalvm.compiler.nodes.memory.FloatingAccessNode;
 import org.graalvm.compiler.nodes.memory.FloatingReadNode;
 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;
 import org.graalvm.compiler.phases.schedule.SchedulePhase;
 import org.graalvm.compiler.phases.schedule.SchedulePhase.SchedulingStrategy;
 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;
 
 /**
  * This phase lowers {@link FloatingReadNode FloatingReadNodes} into corresponding fixed reads.

@@ -134,23 +139,73 @@
             }
         }
 
     }
 
-    protected static class RawConditionalEliminationVisitor implements RecursiveVisitor<Integer> {
+    public static class RawConditionalEliminationVisitor implements RecursiveVisitor<Integer> {
 
         protected final NodeMap<StampElement> stampMap;
         protected final NodeStack undoOperations;
         private final ScheduleResult schedule;
         private final StructuredGraph graph;
         private final MetaAccessProvider metaAccess;
         private final boolean replaceConstantInputs;
         private final BlockMap<Integer> blockActionStart;
         private final EconomicMap<MergeNode, EconomicMap<ValueNode, Stamp>> 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;
             this.metaAccess = metaAccess;
             blockActionStart = new BlockMap<>(schedule.getCFG());

@@ -324,12 +379,26 @@
             }
             return blockToNodeMap.get(node);
         }
 
         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);
             }
         }
 
         protected boolean checkReplaceWithConstant(Stamp newStamp, ValueNode node) {

@@ -344,14 +413,35 @@
             }
             return false;
         }
 
         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);
             }
         }
 
         protected void processIntegerSwitch(IntegerSwitchNode node) {

@@ -467,10 +557,14 @@
             undoOperations.push(originalNode);
         }
 
         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);
             }
             return currentStamp.getStamp();
< prev index next >