Mercurial > hg > truffle
diff graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java @ 7530:5e3d1a68664e
applied mx eclipseformat to all Java files
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Wed, 23 Jan 2013 16:34:57 +0100 |
parents | 95a685941e10 |
children | 9e2cbc932853 |
line wrap: on
line diff
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java Wed Jan 23 16:34:38 2013 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java Wed Jan 23 16:34:57 2013 +0100 @@ -37,8 +37,8 @@ /** * This class is a phase that looks for opportunities for tail duplication. The static method - * {@link #tailDuplicate(MergeNode, TailDuplicationDecision, List)} can also be used to drive tail duplication from - * other places, e.g., inlining. + * {@link #tailDuplicate(MergeNode, TailDuplicationDecision, List)} can also be used to drive tail + * duplication from other places, e.g., inlining. */ public class TailDuplicationPhase extends Phase { @@ -52,24 +52,28 @@ private static final DebugMetric metricDuplicationOtherPerformed = Debug.metric("DuplicationOtherPerformed"); /** - * This interface is used by tail duplication to let clients decide if tail duplication should be performed. + * This interface is used by tail duplication to let clients decide if tail duplication should + * be performed. */ public interface TailDuplicationDecision { /** - * Queries if tail duplication should be performed at the given merge. If this method returns true then the tail - * duplication will be performed, because all other checks have happened before. - * + * Queries if tail duplication should be performed at the given merge. If this method + * returns true then the tail duplication will be performed, because all other checks have + * happened before. + * * @param merge The merge at which tail duplication can be performed. - * @param fixedNodeCount The size of the set of fixed nodes that forms the base for the duplicated set of nodes. + * @param fixedNodeCount The size of the set of fixed nodes that forms the base for the + * duplicated set of nodes. * @return true if the tail duplication should be performed, false otherwise. */ boolean doTransform(MergeNode merge, int fixedNodeCount); } /** - * A tail duplication decision closure that employs the default algorithm: Check if there are any phis on the merge - * whose stamps improve and that have usages within the duplicated set of fixed nodes. + * A tail duplication decision closure that employs the default algorithm: Check if there are + * any phis on the merge whose stamps improve and that have usages within the duplicated set of + * fixed nodes. */ public static final TailDuplicationDecision DEFAULT_DECISION = new TailDuplicationDecision() { @@ -122,7 +126,8 @@ @Override protected void run(StructuredGraph graph) { - // A snapshot is taken here, so that new MergeNode instances aren't considered for tail duplication. + // A snapshot is taken here, so that new MergeNode instances aren't considered for tail + // duplication. for (MergeNode merge : graph.getNodes(MergeNode.class).snapshot()) { if (!(merge instanceof LoopBeginNode) && merge.probability() >= GraalOptions.TailDuplicationProbability) { tailDuplicate(merge, DEFAULT_DECISION, null); @@ -131,18 +136,20 @@ } /** - * This method attempts to duplicate the tail of the given merge. The merge must not be a {@link LoopBeginNode}. If - * the merge is eligible for duplication (at least one fixed node in its tail, no {@link MonitorEnterNode}/ - * {@link MonitorExitNode}, non-null {@link MergeNode#stateAfter()}) then the decision callback is used to determine - * whether the tail duplication should actually be performed. If replacements is non-null, then this list of + * This method attempts to duplicate the tail of the given merge. The merge must not be a + * {@link LoopBeginNode}. If the merge is eligible for duplication (at least one fixed node in + * its tail, no {@link MonitorEnterNode}/ {@link MonitorExitNode}, non-null + * {@link MergeNode#stateAfter()}) then the decision callback is used to determine whether the + * tail duplication should actually be performed. If replacements is non-null, then this list of * {@link PiNode}s is used to replace one value per merge end. - * + * * @param merge The merge whose tail should be duplicated. - * @param decision A callback that can make the final decision if tail duplication should occur or not. - * @param replacements A list of {@link PiNode}s, or null. If this list is non-null then its size needs to match the - * merge's end count. Each entry can either be null or a {@link PiNode}, and is used to replace - * {@link PiNode#object()} with the {@link PiNode} in the duplicated branch that corresponds to the - * entry. + * @param decision A callback that can make the final decision if tail duplication should occur + * or not. + * @param replacements A list of {@link PiNode}s, or null. If this list is non-null then its + * size needs to match the merge's end count. Each entry can either be null or a + * {@link PiNode}, and is used to replace {@link PiNode#object()} with the + * {@link PiNode} in the duplicated branch that corresponds to the entry. */ public static void tailDuplicate(MergeNode merge, TailDuplicationDecision decision, List<PiNode> replacements) { assert !(merge instanceof LoopBeginNode); @@ -159,7 +166,8 @@ } if (containsMonitor) { // cannot currently be handled - // TODO (ls) re-evaluate this limitation after changes to the lock representation and the LIR generator + // TODO (ls) re-evaluate this limitation after changes to the lock representation and + // the LIR generator metricDuplicationMonitors.increment(); } else if (fixedCount > 1) { if (fixed instanceof EndNode && !(((EndNode) fixed).merge() instanceof LoopBeginNode)) { @@ -191,10 +199,10 @@ /** * Initializes the tail duplication operation without actually performing any work. - * + * * @param merge The merge whose tail should be duplicated. - * @param replacements A list of replacement {@link PiNode}s, or null. If this is non-null, then the size of the - * list needs to match the number of end nodes at the merge. + * @param replacements A list of replacement {@link PiNode}s, or null. If this is non-null, + * then the size of the list needs to match the number of end nodes at the merge. */ public DuplicationOperation(MergeNode merge, List<PiNode> replacements) { this.merge = merge; @@ -205,8 +213,8 @@ /** * Performs the actual tail duplication: * <ul> - * <li>Creates a new {@link ValueAnchorNode} at the beginning of the duplicated area, an transfers all - * dependencies from the merge to this anchor.</li> + * <li>Creates a new {@link ValueAnchorNode} at the beginning of the duplicated area, an + * transfers all dependencies from the merge to this anchor.</li> * <li>Determines the set of fixed nodes to be duplicated.</li> * <li>Creates the new merge at the bottom of the duplicated area.</li> * <li>Determines the complete set of duplicated nodes.</li> @@ -218,7 +226,8 @@ ValueAnchorNode anchor = addValueAnchor(); - // determine the fixed nodes that should be duplicated (currently: all nodes up until the first control + // determine the fixed nodes that should be duplicated (currently: all nodes up until + // the first control // split, end node, deopt or return. ArrayList<FixedNode> fixedNodes = new ArrayList<>(); FixedNode fixed = merge.next(); @@ -257,7 +266,8 @@ } mergeAfter.addForwardEnd((EndNode) duplicates.get(endAfter)); - // re-wire the duplicated ValueAnchorNode to the predecessor of the corresponding EndNode + // re-wire the duplicated ValueAnchorNode to the predecessor of the corresponding + // EndNode FixedNode anchorDuplicate = (FixedNode) duplicates.get(anchor); ((FixedWithNextNode) forwardEnd.predecessor()).setNext(anchorDuplicate); // move dependencies on the ValueAnchorNode to the previous BeginNode @@ -282,7 +292,8 @@ forwardEnd.safeDelete(); } for (PhiNode phi : phiSnapshot) { - // these phis should go away, but they still need to be anchored to a merge to be valid... + // these phis should go away, but they still need to be anchored to a merge to be + // valid... if (phi.isAlive()) { phi.setMerge(mergeAfter); } @@ -291,9 +302,9 @@ } /** - * Inserts a new ValueAnchorNode after the merge and transfers all dependency-usages (not phis) to this - * ValueAnchorNode. - * + * Inserts a new ValueAnchorNode after the merge and transfers all dependency-usages (not + * phis) to this ValueAnchorNode. + * * @return The new {@link ValueAnchorNode} that was created. */ private ValueAnchorNode addValueAnchor() { @@ -310,12 +321,14 @@ } /** - * Given a set of fixed nodes, this method determines the set of fixed and floating nodes that needs to be - * duplicated, i.e., all nodes that due to data flow and other dependencies needs to be duplicated. - * + * Given a set of fixed nodes, this method determines the set of fixed and floating nodes + * that needs to be duplicated, i.e., all nodes that due to data flow and other dependencies + * needs to be duplicated. + * * @param fixedNodes The set of fixed nodes that should be duplicated. - * @param stateAfter The frame state of the merge that follows the set of fixed nodes. All {@link ValueNode}s - * reachable from this state are considered to be reachable from within the duplicated set of nodes. + * @param stateAfter The frame state of the merge that follows the set of fixed nodes. All + * {@link ValueNode}s reachable from this state are considered to be reachable + * from within the duplicated set of nodes. * @return The set of nodes that need to be duplicated. */ private HashSet<Node> buildDuplicatedNodeSet(final ArrayList<FixedNode> fixedNodes, FrameState stateAfter) { @@ -325,7 +338,8 @@ final Deque<Node> worklist = new ArrayDeque<>(); // Build the set of nodes that have (transitive) usages within the duplicatedNodes. - // This is achieved by iterating all nodes that are reachable via inputs from the the fixed nodes. + // This is achieved by iterating all nodes that are reachable via inputs from the the + // fixed nodes. aboveBound.markAll(fixedNodes); worklist.addAll(fixedNodes); @@ -342,7 +356,8 @@ if (node instanceof PhiNode && !fixedNodes.contains(((PhiNode) node).merge())) { // stop iterating: phis belonging to outside merges are known to be outside. } else if (node instanceof FixedNode) { - // stop iterating: fixed nodes within the given set are traversal roots anyway, and all other + // stop iterating: fixed nodes within the given set are traversal roots + // anyway, and all other // fixed nodes are known to be outside. } else if (!aboveBound.isMarked(node)) { worklist.add(node); @@ -362,7 +377,8 @@ } // Build the set of nodes that have (transitive) inputs within the duplicatedNodes. - // This is achieved by iterating all nodes that are reachable via usages from the fixed nodes. + // This is achieved by iterating all nodes that are reachable via usages from the fixed + // nodes. belowBound.markAll(fixedNodes); worklist.addAll(fixedNodes); @@ -378,7 +394,8 @@ if (usage instanceof PhiNode && !fixedNodes.contains(((PhiNode) usage).merge())) { // stop iterating: phis belonging to outside merges are known to be outside. } else if (usage instanceof FixedNode) { - // stop iterating: fixed nodes within the given set are traversal roots anyway, and all other + // stop iterating: fixed nodes within the given set are traversal roots + // anyway, and all other // fixed nodes are known to be outside. } else if (!belowBound.isMarked(usage)) { worklist.add(usage); @@ -397,11 +414,11 @@ } /** - * Creates a new merge and end node construct at the end of the duplicated area. While it is useless in itself - * (merge with only one end) it simplifies the later duplication step. - * - * @param successor The successor of the duplicated set of nodes, i.e., the first node that should not be - * duplicated. + * Creates a new merge and end node construct at the end of the duplicated area. While it is + * useless in itself (merge with only one end) it simplifies the later duplication step. + * + * @param successor The successor of the duplicated set of nodes, i.e., the first node that + * should not be duplicated. * @param stateAfterMerge The frame state that should be used for the merge. * @return The newly created end node. */ @@ -420,21 +437,26 @@ /** * Expands the set of nodes to be duplicated by looking at a number of conditions: * <ul> - * <li>{@link ValueNode}s that have usages on the outside need to be replaced with phis for the outside usages.</li> - * <li>Non-{@link ValueNode} nodes that have outside usages (frame states, virtual object states, ...) need to - * be cloned immediately for the outside usages.</li> - * <li>Nodes that have a {@link StampFactory#extension()} or {@link StampFactory#condition()} stamp need to be - * cloned immediately for the outside usages.</li> - * <li>Dependencies into the duplicated nodes will be replaced with dependencies on the merge.</li> - * <li>Outside non-{@link ValueNode}s with usages within the duplicated set of nodes need to also be duplicated. - * </li> - * <li>Outside {@link ValueNode}s with {@link StampFactory#extension()} or {@link StampFactory#condition()} - * stamps that have usages within the duplicated set of nodes need to also be duplicated.</li> + * <li>{@link ValueNode}s that have usages on the outside need to be replaced with phis for + * the outside usages.</li> + * <li>Non-{@link ValueNode} nodes that have outside usages (frame states, virtual object + * states, ...) need to be cloned immediately for the outside usages.</li> + * <li>Nodes that have a {@link StampFactory#extension()} or + * {@link StampFactory#condition()} stamp need to be cloned immediately for the outside + * usages.</li> + * <li>Dependencies into the duplicated nodes will be replaced with dependencies on the + * merge.</li> + * <li>Outside non-{@link ValueNode}s with usages within the duplicated set of nodes need to + * also be duplicated.</li> + * <li>Outside {@link ValueNode}s with {@link StampFactory#extension()} or + * {@link StampFactory#condition()} stamps that have usages within the duplicated set of + * nodes need to also be duplicated.</li> * </ul> - * + * * @param duplicatedNodes The set of duplicated nodes that will be modified (expanded). - * @param newBottomMerge The merge that follows the duplicated set of nodes. It will be used for newly created - * phis and to as a target for dependencies that pointed into the duplicated set of nodes. + * @param newBottomMerge The merge that follows the duplicated set of nodes. It will be used + * for newly created phis and to as a target for dependencies that pointed into + * the duplicated set of nodes. */ private void expandDuplicated(HashSet<Node> duplicatedNodes, MergeNode newBottomMerge) { Deque<Node> worklist = new ArrayDeque<>(duplicatedNodes); @@ -468,7 +490,8 @@ // clone the offending node to the outside Node newOutsideClone = duplicated.copyWithInputs(); replaceUsagesOutside(duplicated, newOutsideClone, duplicatedNodes); - // this might cause other nodes to have outside usages, we need to look at those as well + // this might cause other nodes to have outside usages, we need to look at + // those as well for (Node input : newOutsideClone.inputs()) { if (duplicatedNodes.contains(input)) { worklist.add(input); @@ -498,10 +521,12 @@ } /** - * Moves all depdendencies that point outside the duplicated area to the supplied value anchor node. - * + * Moves all depdendencies that point outside the duplicated area to the supplied value + * anchor node. + * * @param duplicatedNodes The set of duplicated nodes. - * @param anchor The node that will be the new target for all dependencies that point outside the duplicated set of nodes. + * @param anchor The node that will be the new target for all dependencies that point + * outside the duplicated set of nodes. */ private static void retargetDependencies(HashSet<Node> duplicatedNodes, ValueAnchorNode anchor) { for (Node node : duplicatedNodes) { @@ -520,7 +545,7 @@ /** * Checks if the given node has usages that are not within the given set of nodes. - * + * * @param node The node whose usages are checked. * @param nodeSet The set of nodes that are considered to be "within". * @return true if the given node has usages on the outside, false otherwise. @@ -535,8 +560,9 @@ } /** - * Replaces the given node with the given replacement at all usages that are not within the given set of nodes. - * + * Replaces the given node with the given replacement at all usages that are not within the + * given set of nodes. + * * @param node The node to be replaced at outside usages. * @param replacement The node that replaced the given node at outside usages. * @param nodeSet The set of nodes that are considered to be "within".