Mercurial > hg > truffle
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) {