changeset 20826:a4aa2116cfe0

Support node canonicalization when not all usages of a node are known yet
author Christian Wimmer <christian.wimmer@oracle.com>
date Wed, 08 Apr 2015 22:07:50 -0700
parents 854b0b6854f4
children 5bf195ce816a
files graal/com.oracle.graal.graph/src/com/oracle/graal/graph/spi/CanonicalizerTool.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/SnippetAnchorNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ClassGetHubNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HubGetClassNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/KlassLayoutHelperNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractMergeNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConditionAnchorNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopExitNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IntegerSwitchNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MemoryAnchorNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnboxNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ArrayEqualsNode.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/PureFunctionMacroNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualizerToolImpl.java
diffstat 22 files changed, 56 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/spi/CanonicalizerTool.java	Wed Apr 08 22:05:40 2015 -0700
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/spi/CanonicalizerTool.java	Wed Apr 08 22:07:50 2015 -0700
@@ -23,6 +23,7 @@
 package com.oracle.graal.graph.spi;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
 
 public interface CanonicalizerTool {
 
@@ -31,4 +32,11 @@
     ConstantReflectionProvider getConstantReflection();
 
     boolean canonicalizeReads();
+
+    /**
+     * If this method returns false, not all {@link Node#usages() usages of a node} are yet
+     * available. So a node must not be canonicalized base on, e.g., information returned from
+     * {@link Node#hasNoUsages()}.
+     */
+    boolean allUsagesAvailable();
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/SnippetAnchorNode.java	Wed Apr 08 22:05:40 2015 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/SnippetAnchorNode.java	Wed Apr 08 22:07:50 2015 -0700
@@ -42,7 +42,7 @@
         AbstractBeginNode prevBegin = AbstractBeginNode.prevBegin(this);
         replaceAtUsages(InputType.Anchor, prevBegin);
         replaceAtUsages(InputType.Guard, prevBegin);
-        if (hasNoUsages()) {
+        if (tool.allUsagesAvailable() && hasNoUsages()) {
             graph().removeFixed(this);
         }
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ClassGetHubNode.java	Wed Apr 08 22:05:40 2015 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ClassGetHubNode.java	Wed Apr 08 22:07:50 2015 -0700
@@ -57,7 +57,7 @@
 
     @Override
     public Node canonical(CanonicalizerTool tool) {
-        if (hasNoUsages()) {
+        if (tool.allUsagesAvailable() && hasNoUsages()) {
             return null;
         } else {
             if (clazz.isConstant()) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HubGetClassNode.java	Wed Apr 08 22:05:40 2015 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HubGetClassNode.java	Wed Apr 08 22:07:50 2015 -0700
@@ -53,7 +53,7 @@
 
     @Override
     public Node canonical(CanonicalizerTool tool) {
-        if (hasNoUsages()) {
+        if (tool.allUsagesAvailable() && hasNoUsages()) {
             return null;
         } else {
             MetaAccessProvider metaAccess = tool.getMetaAccess();
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/KlassLayoutHelperNode.java	Wed Apr 08 22:05:40 2015 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/KlassLayoutHelperNode.java	Wed Apr 08 22:07:50 2015 -0700
@@ -80,7 +80,7 @@
 
     @Override
     public Node canonical(CanonicalizerTool tool) {
-        if (hasNoUsages()) {
+        if (tool.allUsagesAvailable() && hasNoUsages()) {
             return null;
         } else {
             if (klass.isConstant()) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractMergeNode.java	Wed Apr 08 22:05:40 2015 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractMergeNode.java	Wed Apr 08 22:07:50 2015 -0700
@@ -227,7 +227,7 @@
                 end.safeDelete();
             }
             for (PhiNode phi : phis) {
-                if (phi.isAlive() && phi.hasNoUsages()) {
+                if (tool.allUsagesAvailable() && phi.isAlive() && phi.hasNoUsages()) {
                     GraphUtil.killWithUnusedFloatingInputs(phi);
                 }
             }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConditionAnchorNode.java	Wed Apr 08 22:05:40 2015 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConditionAnchorNode.java	Wed Apr 08 22:07:50 2015 -0700
@@ -76,7 +76,7 @@
                 return new ValueAnchorNode(null);
             }
         }
-        if (this.hasNoUsages()) {
+        if (tool.allUsagesAvailable() && this.hasNoUsages()) {
             return null;
         }
         return this;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java	Wed Apr 08 22:05:40 2015 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java	Wed Apr 08 22:07:50 2015 -0700
@@ -178,7 +178,7 @@
             }
             return;
         }
-        if (trueSuccessor().hasNoUsages() && falseSuccessor().hasNoUsages()) {
+        if (tool.allUsagesAvailable() && trueSuccessor().hasNoUsages() && falseSuccessor().hasNoUsages()) {
 
             pushNodesThroughIf(tool);
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopExitNode.java	Wed Apr 08 22:05:40 2015 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopExitNode.java	Wed Apr 08 22:07:50 2015 -0700
@@ -45,7 +45,7 @@
     @Override
     public void simplify(SimplifierTool tool) {
         Node prev = this.predecessor();
-        while (prev instanceof BeginNode && prev.hasNoUsages()) {
+        while (tool.allUsagesAvailable() && prev instanceof BeginNode && prev.hasNoUsages()) {
             AbstractBeginNode begin = (AbstractBeginNode) prev;
             prev = prev.predecessor();
             graph().removeFixed(begin);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IntegerSwitchNode.java	Wed Apr 08 22:05:40 2015 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IntegerSwitchNode.java	Wed Apr 08 22:07:50 2015 -0700
@@ -98,6 +98,15 @@
         gen.emitSwitch(this);
     }
 
+    public AbstractBeginNode successorAtKey(int key) {
+        for (int i = 0; i < keyCount(); i++) {
+            if (keys[i] == key) {
+                return blockSuccessor(keySuccessorIndex(i));
+            }
+        }
+        return blockSuccessor(keySuccessorIndex(keyCount()));
+    }
+
     @Override
     public void simplify(SimplifierTool tool) {
         if (blockSuccessorCount() == 1) {
@@ -105,20 +114,15 @@
             graph().removeSplitPropagate(this, defaultSuccessor());
         } else if (value() instanceof ConstantNode) {
             int constant = value().asJavaConstant().asInt();
-
-            int survivingEdge = keySuccessorIndex(keyCount());
-            for (int i = 0; i < keyCount(); i++) {
-                if (keys[i] == constant) {
-                    survivingEdge = keySuccessorIndex(i);
+            AbstractBeginNode survivingSuccessor = successorAtKey(constant);
+            for (Node successor : successors()) {
+                if (successor != survivingSuccessor) {
+                    tool.deleteBranch(successor);
                 }
             }
-            for (int i = 0; i < blockSuccessorCount(); i++) {
-                if (i != survivingEdge) {
-                    tool.deleteBranch(blockSuccessor(i));
-                }
-            }
-            tool.addToWorkList(blockSuccessor(survivingEdge));
-            graph().removeSplit(this, blockSuccessor(survivingEdge));
+            tool.addToWorkList(survivingSuccessor);
+            graph().removeSplit(this, survivingSuccessor);
+
         } else if (value().stamp() instanceof IntegerStamp) {
             IntegerStamp integerStamp = (IntegerStamp) value().stamp();
             if (!integerStamp.isUnrestricted()) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MemoryAnchorNode.java	Wed Apr 08 22:05:40 2015 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MemoryAnchorNode.java	Wed Apr 08 22:07:50 2015 -0700
@@ -45,7 +45,7 @@
 
     @Override
     public Node canonical(CanonicalizerTool tool) {
-        return hasNoUsages() ? null : this;
+        return tool.allUsagesAvailable() && hasNoUsages() ? null : this;
     }
 
     @NodeIntrinsic
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Wed Apr 08 22:05:40 2015 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Wed Apr 08 22:07:50 2015 -0700
@@ -71,7 +71,7 @@
 
     @Override
     public Node canonical(CanonicalizerTool tool) {
-        if (hasNoUsages()) {
+        if (tool.allUsagesAvailable() && hasNoUsages()) {
             if (getGuard() != null && !(getGuard() instanceof FixedNode)) {
                 // The guard is necessary even if the read goes away.
                 return new ValueAnchorNode((ValueNode) getGuard());
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnboxNode.java	Wed Apr 08 22:05:40 2015 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnboxNode.java	Wed Apr 08 22:07:50 2015 -0700
@@ -79,7 +79,7 @@
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) {
-        if (hasNoUsages() && StampTool.isPointerNonNull(forValue)) {
+        if (tool.allUsagesAvailable() && hasNoUsages() && StampTool.isPointerNonNull(forValue)) {
             return null;
         }
         ValueNode synonym = findSynonym(tool.getMetaAccess(), tool.getConstantReflection(), forValue, boxingKind);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java	Wed Apr 08 22:05:40 2015 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java	Wed Apr 08 22:07:50 2015 -0700
@@ -67,7 +67,7 @@
                 break;
             }
         }
-        if (hasNoUsages() && next() instanceof FixedAccessNode) {
+        if (tool.allUsagesAvailable() && hasNoUsages() && next() instanceof FixedAccessNode) {
             FixedAccessNode currentNext = (FixedAccessNode) next();
             if (currentNext.getGuard() == anchored) {
                 GraphUtil.removeFixedWithUnusedInputs(this);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java	Wed Apr 08 22:05:40 2015 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java	Wed Apr 08 22:07:50 2015 -0700
@@ -80,7 +80,7 @@
             if (result != null) {
                 return result;
             }
-            Assumptions assumptions = graph().getAssumptions();
+            Assumptions assumptions = graph() == null ? null : graph().getAssumptions();
             if (assumptions != null) {
                 AssumptionResult<ResolvedJavaType> leafConcreteSubtype = stampType.findLeafConcreteSubtype();
                 if (leafConcreteSubtype != null) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java	Wed Apr 08 22:05:40 2015 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java	Wed Apr 08 22:07:50 2015 -0700
@@ -60,7 +60,7 @@
     }
 
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forObject) {
-        if (hasNoUsages() && !isVolatile() && (isStatic() || StampTool.isPointerNonNull(forObject.stamp()))) {
+        if (tool.allUsagesAvailable() && hasNoUsages() && !isVolatile() && (isStatic() || StampTool.isPointerNonNull(forObject.stamp()))) {
             return null;
         }
         MetaAccessProvider metaAccess = tool.getMetaAccess();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java	Wed Apr 08 22:05:40 2015 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java	Wed Apr 08 22:07:50 2015 -0700
@@ -521,6 +521,11 @@
             return canonicalizeReads;
         }
 
+        @Override
+        public boolean allUsagesAvailable() {
+            return true;
+        }
+
         public void deleteBranch(Node branch) {
             branch.predecessor().replaceFirstSuccessor(branch, null);
             GraphUtil.killCFG(branch, this);
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java	Wed Apr 08 22:05:40 2015 -0700
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java	Wed Apr 08 22:07:50 2015 -0700
@@ -416,6 +416,11 @@
             public boolean canonicalizeReads() {
                 return canonicalizeReads;
             }
+
+            @Override
+            public boolean allUsagesAvailable() {
+                return true;
+            }
         }
     }
 
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ArrayEqualsNode.java	Wed Apr 08 22:05:40 2015 -0700
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ArrayEqualsNode.java	Wed Apr 08 22:07:50 2015 -0700
@@ -63,7 +63,7 @@
 
     @Override
     public Node canonical(CanonicalizerTool tool) {
-        if (hasNoUsages()) {
+        if (tool.allUsagesAvailable() && hasNoUsages()) {
             return null;
         }
         if (GraphUtil.unproxify(array1) == GraphUtil.unproxify(array2)) {
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/PureFunctionMacroNode.java	Wed Apr 08 22:05:40 2015 -0700
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/PureFunctionMacroNode.java	Wed Apr 08 22:07:50 2015 -0700
@@ -50,7 +50,7 @@
 
     @Override
     public Node canonical(CanonicalizerTool tool) {
-        if (hasNoUsages()) {
+        if (tool.allUsagesAvailable() && hasNoUsages()) {
             return null;
         } else {
             ValueNode param = arguments.get(0);
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java	Wed Apr 08 22:05:40 2015 -0700
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java	Wed Apr 08 22:07:50 2015 -0700
@@ -236,7 +236,7 @@
 
     @Override
     public Node canonical(CanonicalizerTool tool) {
-        if (hasNoUsages()) {
+        if (tool.allUsagesAvailable() && hasNoUsages()) {
             return null;
         } else {
             return this;
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualizerToolImpl.java	Wed Apr 08 22:05:40 2015 -0700
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualizerToolImpl.java	Wed Apr 08 22:07:50 2015 -0700
@@ -200,4 +200,9 @@
     public boolean canonicalizeReads() {
         return false;
     }
+
+    @Override
+    public boolean allUsagesAvailable() {
+        return true;
+    }
 }