# HG changeset patch # User Christian Wimmer # Date 1392229516 28800 # Node ID a55d85c207be539df53f89f11635352cdbfb6a84 # Parent c0309792b0cd2bdfcc4b5c18a9578bf94ea2f217 Move stamp inference in its own class, and make it extensible via the ValueAndStampProxy interface diff -r c0309792b0cd -r a55d85c207be graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ProxyNode.java --- 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; diff -r c0309792b0cd -r a55d85c207be graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/ValueAndStampProxy.java --- /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 { +} diff -r c0309792b0cd -r a55d85c207be graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/InferStamps.java --- /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. + *

+ * 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; + } + +} diff -r c0309792b0cd -r a55d85c207be graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java --- 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. - *

- * 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. */ diff -r c0309792b0cd -r a55d85c207be graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeVerificationPhase.java --- 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);