changeset 13941:a55d85c207be

Move stamp inference in its own class, and make it extensible via the ValueAndStampProxy interface
author Christian Wimmer <christian.wimmer@oracle.com>
date Wed, 12 Feb 2014 10:25:16 -0800
parents c0309792b0cd
children 1ee27cd07ed0
files graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ProxyNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/ValueAndStampProxy.java graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/InferStamps.java graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeVerificationPhase.java
diffstat 5 files changed, 133 insertions(+), 66 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ProxyNode.java	Wed Feb 12 10:24:11 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ProxyNode.java	Wed Feb 12 10:25:16 2014 -0800
@@ -36,7 +36,7 @@
  * loop.
  */
 @NodeInfo(nameTemplate = "{p#type/s}Proxy")
-public class ProxyNode extends FloatingNode implements IterableNodeType, ValueNumberable, Canonicalizable, Virtualizable, ValueProxy, GuardingNode {
+public class ProxyNode extends FloatingNode implements IterableNodeType, ValueNumberable, Canonicalizable, Virtualizable, ValueAndStampProxy, GuardingNode {
 
     @Input(notDataflow = true) private AbstractBeginNode proxyPoint;
     @Input private ValueNode value;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/ValueAndStampProxy.java	Wed Feb 12 10:25:16 2014 -0800
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.nodes.spi;
+
+/**
+ * This interface marks nodes whose result is the same as one of their inputs, and whose stamp is
+ * the same as one of their inputs.
+ * 
+ * For some algorithms it is necessary or advantageous to see through these proxies.
+ */
+public interface ValueAndStampProxy extends ValueProxy {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/InferStamps.java	Wed Feb 12 10:25:16 2014 -0800
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.phases.graph;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+
+public class InferStamps {
+
+    /**
+     * Infer the stamps for all Object nodes in the graph, to make the stamps as precise as
+     * possible. For example, this propagates the word-type through phi functions. To handle phi
+     * functions at loop headers, the stamp inference is called until a fix point is reached.
+     * <p>
+     * This method can be used when it is needed that stamps are inferred before the first run of
+     * the canonicalizer. For example, word type rewriting must run before the first run of the
+     * canonicalizer because many nodes are not prepared to see the word type during
+     * canonicalization.
+     */
+    public static void inferStamps(StructuredGraph graph) {
+        /*
+         * We want to make the stamps more precise. For cyclic phi functions, this means we have to
+         * ignore the initial stamp because the imprecise stamp would always propagate around the
+         * cycle. We therefore set the stamp to an illegal stamp, which is automatically ignored
+         * when the phi function performs the "meet" operator on its input stamps.
+         */
+        for (Node n : graph.getNodes()) {
+            if (n instanceof PhiNode || n instanceof ValueAndStampProxy) {
+                ValueNode node = (ValueNode) n;
+                if (node.kind() == Kind.Object) {
+                    assert !(node.stamp() instanceof IllegalStamp) : "We assume all Phi and Proxy stamps are legal before the analysis";
+                    node.setStamp(StampFactory.illegal(node.kind()));
+                }
+            }
+        }
+
+        boolean stampChanged;
+        do {
+            stampChanged = false;
+            /*
+             * We could use GraphOrder.forwardGraph() to process the nodes in a defined order and
+             * propagate long def-use chains in fewer iterations. However, measurements showed that
+             * we have few iterations anyway, and the overhead of computing the order is much higher
+             * than the benefit.
+             */
+            for (Node n : graph.getNodes()) {
+                if (n instanceof ValueNode) {
+                    ValueNode node = (ValueNode) n;
+                    if (node.kind() == Kind.Object) {
+                        stampChanged |= node.inferStamp();
+                    }
+                }
+            }
+        } while (stampChanged);
+
+        /*
+         * Check that all the illegal stamps we introduced above are correctly replaced with real
+         * stamps again.
+         */
+        assert checkNoIllegalStamp(graph);
+    }
+
+    private static boolean checkNoIllegalStamp(StructuredGraph graph) {
+        for (Node n : graph.getNodes()) {
+            if (n instanceof PhiNode || n instanceof ValueAndStampProxy) {
+                ValueNode node = (ValueNode) n;
+                assert !(node.stamp() instanceof IllegalStamp) : "Stamp is illegal after analysis. This is not necessarily an error, but a condition that we want to investigate (and then maybe relax or remove the assertion).";
+            }
+        }
+        return true;
+    }
+
+}
--- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java	Wed Feb 12 10:24:11 2014 -0800
+++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java	Wed Feb 12 10:25:16 2014 -0800
@@ -36,6 +36,7 @@
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.nodes.util.*;
 import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.graph.*;
 import com.oracle.graal.word.*;
 import com.oracle.graal.word.Word.Opcode;
 import com.oracle.graal.word.Word.Operation;
@@ -63,7 +64,7 @@
 
     @Override
     protected void run(StructuredGraph graph) {
-        inferStamps(graph);
+        InferStamps.inferStamps(graph);
 
         for (Node n : graph.getNodes()) {
             if (n instanceof ValueNode) {
@@ -77,68 +78,6 @@
     }
 
     /**
-     * Infer the stamps for all Object nodes in the graph, to make the stamps as precise as
-     * possible. For example, this propagates the word-type through phi functions. To handle phi
-     * functions at loop headers, the stamp inference is called until a fix point is reached.
-     * <p>
-     * Note that we cannot rely on the normal canonicalizer to propagate stamps: The word type
-     * rewriting must run before the first run of the canonicalizer because many nodes are not
-     * prepared to see the word type during canonicalization.
-     */
-    protected void inferStamps(StructuredGraph graph) {
-        /*
-         * We want to make the stamps more precise. For cyclic phi functions, this means we have to
-         * ignore the initial stamp because the imprecise stamp would always propagate around the
-         * cycle. We therefore set the stamp to an illegal stamp, which is automatically ignored
-         * when the phi function performs the "meet" operator on its input stamps.
-         */
-        for (Node n : graph.getNodes()) {
-            if (n instanceof PhiNode || n instanceof ProxyNode) {
-                ValueNode node = (ValueNode) n;
-                if (node.kind() == Kind.Object) {
-                    assert !(node.stamp() instanceof IllegalStamp) : "We assume all Phi and Proxy stamps are legal before the analysis";
-                    node.setStamp(StampFactory.illegal(node.kind()));
-                }
-            }
-        }
-
-        boolean stampChanged;
-        do {
-            stampChanged = false;
-            /*
-             * We could use GraphOrder.forwardGraph() to process the nodes in a defined order and
-             * propagate long def-use chains in fewer iterations. However, measurements showed that
-             * we have few iterations anyway, and the overhead of computing the order is much higher
-             * than the benefit.
-             */
-            for (Node n : graph.getNodes()) {
-                if (n instanceof ValueNode) {
-                    ValueNode node = (ValueNode) n;
-                    if (node.kind() == Kind.Object) {
-                        stampChanged |= node.inferStamp();
-                    }
-                }
-            }
-        } while (stampChanged);
-
-        /*
-         * Check that all the illegal stamps we introduced above are correctly replaced with real
-         * stamps again.
-         */
-        assert checkNoIllegalStamp(graph);
-    }
-
-    private static boolean checkNoIllegalStamp(StructuredGraph graph) {
-        for (Node n : graph.getNodes()) {
-            if (n instanceof PhiNode || n instanceof ProxyNode) {
-                ValueNode node = (ValueNode) n;
-                assert !(node.stamp() instanceof IllegalStamp) : "Stamp is illegal after analysis. This is not necessarily an error, but a condition that we want to investigate (and then maybe relax or remove the assertion).";
-            }
-        }
-        return true;
-    }
-
-    /**
      * Change the stamp for word nodes from the object stamp ({@link WordBase} or anything extending
      * or implementing that interface) to the primitive word stamp.
      */
--- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeVerificationPhase.java	Wed Feb 12 10:24:11 2014 -0800
+++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeVerificationPhase.java	Wed Feb 12 10:25:16 2014 -0800
@@ -32,6 +32,7 @@
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.util.*;
 import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.graph.*;
 import com.oracle.graal.word.*;
 import com.oracle.graal.word.Word.Operation;
 
@@ -58,7 +59,7 @@
          * modifies the stamp of nodes, we copy the graph before running the verification.
          */
         StructuredGraph graph = inputGraph.copy();
-        wordAccess.inferStamps(graph);
+        InferStamps.inferStamps(graph);
 
         for (ValueNode node : graph.getNodes().filter(ValueNode.class)) {
             if (!node.recordsUsages()) {
@@ -81,7 +82,6 @@
                 } else if (usage instanceof StoreIndexedNode) {
                     verify(!isWord(node) || ((StoreIndexedNode) usage).array() != node, node, usage, "cannot store to word value");
                     verify(!isWord(node) || ((StoreIndexedNode) usage).index() != node, node, usage, "cannot use word value as index");
-                    verify(!isWord(node) || ((StoreIndexedNode) usage).value() != node, node, usage, "cannot store word value to array");
                 } else if (usage instanceof MethodCallTargetNode) {
                     MethodCallTargetNode callTarget = (MethodCallTargetNode) usage;
                     verifyInvoke(node, callTarget);