changeset 16259:639e8085323a

JavaDoc for Canonicalizable
author Lukas Stadler <lukas.stadler@oracle.com>
date Fri, 27 Jun 2014 10:14:00 +0200
parents 3a463b85b195
children 96fbf0582b08
files graal/com.oracle.graal.graph/src/com/oracle/graal/graph/spi/Canonicalizable.java
diffstat 1 files changed, 79 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/spi/Canonicalizable.java	Thu Jun 26 17:29:37 2014 +0200
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/spi/Canonicalizable.java	Fri Jun 27 10:14:00 2014 +0200
@@ -22,15 +22,70 @@
  */
 package com.oracle.graal.graph.spi;
 
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 
+/**
+ * Nodes can implement {@link Canonicalizable} or one of the two sub-interfaces {@link Unary} and
+ * {@link Binary} to provide local optimizations like constant folding and strength reduction.
+ * Implementations should return a replacement that is always semantically correct for the given
+ * inputs, or "this" if they do not see an opportunity for improvement.<br/>
+ * <br/>
+ * <b>Implementations of {@link Canonicalizable#canonical(CanonicalizerTool)} or the equivalent
+ * methods of the two sub-interfaces must not have any side effects.</b><br/>
+ * They are not allowed to change inputs, successors or properties of any node (including the
+ * current one) and they also cannot add new nodes to the graph.<br/>
+ * <br/>
+ * In addition to pre-existing nodes they can return newly created nodes, which will be added to the
+ * graph automatically if (and only if) the effects of the canonicalization are committed.
+ * Non-cyclic graphs (DAGs) of newly created nodes (i.e., one newly created node with an input to
+ * another newly created node) will be handled correctly.
+ */
 public interface Canonicalizable {
 
+    /**
+     * Implementations of this method can provide local optimizations like constant folding and
+     * strength reduction. Implementations should look at the properties and inputs of the current
+     * node and determine if there is a more optimal and always semantically correct replacement.<br/>
+     * The return value determines the effect that the canonicalization will have:
+     * <ul>
+     * <li>Returning an pre-existing node will replace the current node with the given one.</li>
+     * <li>Returning a newly created node (that was not yet added to the graph) will replace the
+     * current node with the given one, after adding it to the graph. If both the replacement and
+     * the replacee are anchored in control flow (fixed nodes), the replacement will be added to the
+     * control flow. It is invalid to replace a non-fixed node with a newly created fixed node
+     * (because its placement in the control flow cannot be determined without scheduling).</li>
+     * <li>Returning {@code null} will delete the current node and replace it with {@code null} at
+     * all usages. Note that it is not necessary to delete floating nodes that have no more usages
+     * this way - they will be deleted automatically.</li>
+     * </ul>
+     *
+     * @param tool provides access to runtime interfaces like {@link MetaAccessProvider}
+     */
     Node canonical(CanonicalizerTool tool);
 
+    /**
+     * This sub-interface of {@link Canonicalizable} is intended for nodes that have exactly one
+     * input. It has an additional {@link #canonical(CanonicalizerTool, Node)} method that looks at
+     * the given input instead of the current input of the node - which can be used to ask
+     * "what if this input is change to this node" - questions.
+     *
+     * @param <T> the common supertype of all inputs of this node
+     */
     public interface Unary<T extends Node> extends Canonicalizable {
+
+        /**
+         * Similar to {@link Canonicalizable#canonical(CanonicalizerTool)}, except that
+         * implementations should act as if the current input of the node was the given one, i.e.,
+         * they should never look at the inputs via the this pointer.
+         */
         Node canonical(CanonicalizerTool tool, T forValue);
 
+        /**
+         * Gets the current value of the input, so that calling
+         * {@link #canonical(CanonicalizerTool, Node)} with the value returned from this method
+         * should behave exactly like {@link Canonicalizable#canonical(CanonicalizerTool)}.
+         */
         T getValue();
 
         default Node canonical(CanonicalizerTool tool) {
@@ -38,11 +93,35 @@
         }
     }
 
+    /**
+     * This sub-interface of {@link Canonicalizable} is intended for nodes that have exactly two
+     * inputs. It has an additional {@link #canonical(CanonicalizerTool, Node, Node)} method that
+     * looks at the given inputs instead of the current inputs of the node - which can be used to
+     * ask "what if this input is change to this node" - questions.
+     *
+     * @param <T> the common supertype of all inputs of this node
+     */
     public interface Binary<T extends Node> extends Canonicalizable {
+
+        /**
+         * Similar to {@link Canonicalizable#canonical(CanonicalizerTool)}, except that
+         * implementations should act as if the current input of the node was the given one, i.e.,
+         * they should never look at the inputs via the this pointer.
+         */
         Node canonical(CanonicalizerTool tool, T forX, T forY);
 
+        /**
+         * Gets the current value of the input, so that calling
+         * {@link #canonical(CanonicalizerTool, Node, Node)} with the value returned from this
+         * method should behave exactly like {@link Canonicalizable#canonical(CanonicalizerTool)}.
+         */
         T getX();
 
+        /**
+         * Gets the current value of the input, so that calling
+         * {@link #canonical(CanonicalizerTool, Node, Node)} with the value returned from this
+         * method should behave exactly like {@link Canonicalizable#canonical(CanonicalizerTool)}.
+         */
         T getY();
 
         default Node canonical(CanonicalizerTool tool) {