changeset 16070:fa04403d1cb5

[inliner] documentation, more and better
author Miguel Garcia <miguel.m.garcia@oracle.com>
date Sat, 07 Jun 2014 14:23:10 +0200
parents 4291873b259b
children 8d0202b354fb 2023d6120416
files graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningPhase.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/elem/InlineableGraph.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/CallsiteHolderExplorable.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/InliningData.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/MethodInvocation.java
diffstat 5 files changed, 138 insertions(+), 69 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningPhase.java	Fri Jun 06 19:46:16 2014 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningPhase.java	Sat Jun 07 14:23:10 2014 +0200
@@ -29,9 +29,7 @@
 import com.oracle.graal.phases.common.*;
 import com.oracle.graal.phases.common.inlining.policy.GreedyInliningPolicy;
 import com.oracle.graal.phases.common.inlining.policy.InliningPolicy;
-import com.oracle.graal.phases.common.inlining.walker.CallsiteHolder;
 import com.oracle.graal.phases.common.inlining.walker.InliningData;
-import com.oracle.graal.phases.common.inlining.walker.MethodInvocation;
 import com.oracle.graal.phases.tiers.*;
 
 public class InliningPhase extends AbstractInliningPhase {
@@ -72,68 +70,11 @@
     }
 
     /**
-     * <p>
-     * The space of inlining decisions is explored depth-first with the help of a stack realized by
-     * {@link com.oracle.graal.phases.common.inlining.walker.InliningData}. At any point in time,
-     * its topmost element consist of:
-     * <ul>
-     * <li>
-     * one or more {@link CallsiteHolder}s of inlining candidates, all of them corresponding to a
-     * single callsite (details below). For example, "exact inline" leads to a single candidate.</li>
-     * <li>
-     * the callsite (for the targets above) is tracked as a {@link MethodInvocation}. The difference
-     * between {@link com.oracle.graal.phases.common.inlining.walker.MethodInvocation#totalGraphs()}
-     * and {@link MethodInvocation#processedGraphs()} indicates the topmost {@link CallsiteHolder}s
-     * that might be delved-into to explore inlining opportunities.</li>
-     * </ul>
-     * </p>
      *
-     * <p>
-     * The bottom-most element in the stack consists of:
-     * <ul>
-     * <li>
-     * a single {@link CallsiteHolder} (the root one, for the method on which inlining was called)</li>
-     * <li>
-     * a single {@link MethodInvocation} (the
-     * {@link com.oracle.graal.phases.common.inlining.walker.MethodInvocation#isRoot} one, ie the
-     * unknown caller of the root graph)</li>
-     * </ul>
-     *
-     * </p>
+     * This method sets in motion the inlining machinery.
      *
-     * <p>
-     * The stack grows and shrinks as choices are made among the alternatives below:
-     * <ol>
-     * <li>
-     * not worth inlining: pop any remaining graphs not yet delved into, pop the current invocation.
-     * </li>
-     * <li>
-     * process next invoke: delve into one of the callsites hosted in the current candidate graph,
-     * determine whether any inlining should be performed in it</li>
-     * <li>
-     * try to inline: move past the current inlining candidate (remove it from the topmost element).
-     * If that was the last one then try to inline the callsite that is (still) in the topmost
-     * element of {@link com.oracle.graal.phases.common.inlining.walker.InliningData}, and then
-     * remove such callsite.</li>
-     * </ol>
-     * </p>
-     *
-     * <p>
-     * Some facts about the alternatives above:
-     * <ul>
-     * <li>
-     * the first step amounts to backtracking, the 2nd one to delving, and the 3rd one also involves
-     * backtracking (however after may-be inlining).</li>
-     * <li>
-     * the choice of abandon-and-backtrack or delve-into is depends on
-     * {@link InliningPolicy#isWorthInlining} and {@link InliningPolicy#continueInlining}.</li>
-     * <li>
-     * the 3rd choice is picked when both of the previous ones aren't picked</li>
-     * <li>
-     * as part of trying-to-inline, {@link InliningPolicy#isWorthInlining} again sees use, but
-     * that's another story.</li>
-     * </ul>
-     * </p>
+     * @see InliningData
+     * @see InliningData#moveForward()
      *
      */
     @Override
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/elem/InlineableGraph.java	Fri Jun 06 19:46:16 2014 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/elem/InlineableGraph.java	Sat Jun 07 14:23:10 2014 +0200
@@ -37,6 +37,20 @@
 
 import static com.oracle.graal.compiler.common.GraalOptions.OptCanonicalizer;
 
+/**
+ * <p>
+ * Represents a feasible concrete target for inlining, whose graph has been copied already and thus
+ * can be modified without affecting the original (usually cached) version.
+ * </p>
+ *
+ * <p>
+ * Instances of this class don't make sense in isolation but as part of an
+ * {@link com.oracle.graal.phases.common.inlining.info.InlineInfo InlineInfo}.
+ * </p>
+ *
+ * @see com.oracle.graal.phases.common.inlining.walker.InliningData#moveForward()
+ * @see com.oracle.graal.phases.common.inlining.walker.CallsiteHolderExplorable
+ */
 public class InlineableGraph implements Inlineable {
 
     private final StructuredGraph graph;
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/CallsiteHolderExplorable.java	Fri Jun 06 19:46:16 2014 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/CallsiteHolderExplorable.java	Sat Jun 07 14:23:10 2014 +0200
@@ -36,15 +36,19 @@
 
 /**
  * <p>
- * A {@link CallsiteHolder} whose graph has been already copied and thus can be modified without
+ * A {@link CallsiteHolder} whose graph has been copied already and thus can be modified without
  * affecting the original (usually cached) version.
  * </p>
  *
  * <p>
- * An instance of this class is "explorable" in that any {@link Invoke} nodes it contains are
- * candidates for depth-first search for further inlining opportunities (as realized by
- * {@link InliningData})
+ * An instance of this class is derived from an
+ * {@link com.oracle.graal.phases.common.inlining.info.elem.InlineableGraph InlineableGraph} and
+ * contains a subset of the information there: just the {@link Invoke} nodes from it. Such nodes are
+ * candidates for depth-first search of further inlining opportunities (thus the adjective
+ * "explorable" given to this class)
  * </p>
+ *
+ * @see InliningData#moveForward()
  */
 public final class CallsiteHolderExplorable extends CallsiteHolder {
 
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/InliningData.java	Fri Jun 06 19:46:16 2014 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/InliningData.java	Sat Jun 07 14:23:10 2014 +0200
@@ -54,8 +54,31 @@
 import static com.oracle.graal.phases.common.inlining.walker.CallsiteHolderDummy.DUMMY_CALLSITE_HOLDER;
 
 /**
- * Holds the data for building the callee graphs recursively: graphs and invocations (each
- * invocation can have multiple graphs).
+ * <p>
+ * The space of inlining decisions is explored depth-first with the help of a stack realized by
+ * {@link InliningData}. At any point in time, the topmost element of that stack consists of:
+ * <ul>
+ * <li>the callsite under consideration is tracked as a {@link MethodInvocation}.</li>
+ * <li>
+ * one or more {@link CallsiteHolder}s, all of them associated to the callsite above. Why more than
+ * one? Depending on the type-profile for the receiver more than one concrete method may be feasible
+ * target.</li>
+ * </ul>
+ * </p>
+ *
+ * <p>
+ * The bottom element in the stack consists of:
+ * <ul>
+ * <li>
+ * a single {@link MethodInvocation} (the
+ * {@link com.oracle.graal.phases.common.inlining.walker.MethodInvocation#isRoot root} one, ie the
+ * unknown caller of the root graph)</li>
+ * <li>
+ * a single {@link CallsiteHolder} (the root one, for the method on which inlining was called)</li>
+ * </ul>
+ * </p>
+ *
+ * @see #moveForward()
  */
 public class InliningData {
 
@@ -376,6 +399,17 @@
     }
 
     /**
+     *
+     * This method attempts:
+     * <ol>
+     * <li>
+     * to inline at the callsite given by <code>calleeInvocation</code>, where that callsite belongs
+     * to the {@link CallsiteHolderExplorable} at the top of the {@link #graphQueue} maintained in
+     * this class.</li>
+     * <li>
+     * otherwise, to devirtualize the callsite in question.</li>
+     * </ol>
+     *
      * @return true iff inlining was actually performed
      */
     private boolean tryToInline(MethodInvocation calleeInvocation, MethodInvocation parentInvocation, int inliningDepth) {
@@ -398,7 +432,29 @@
     }
 
     /**
-     * Process the next invoke and enqueue all its graphs for processing.
+     * This method picks one of the callsites belonging to the current
+     * {@link CallsiteHolderExplorable}. Provided the callsite qualifies to be analyzed for
+     * inlining, this method prepares a new stack top in {@link InliningData} for such callsite,
+     * which comprises:
+     * <ul>
+     * <li>preparing a summary of feasible targets, ie preparing an {@link InlineInfo}</li>
+     * <li>based on it, preparing the stack top proper which consists of:</li>
+     * <ul>
+     * <li>one {@link MethodInvocation}</li>
+     * <li>a {@link CallsiteHolder} for each feasible target</li>
+     * </ul>
+     * </ul>
+     *
+     * <p>
+     * The thus prepared "stack top" is needed by {@link #moveForward()} to explore the space of
+     * inlining decisions (each decision one of: backtracking, delving, inlining).
+     * </p>
+     *
+     * <p>
+     * The {@link InlineInfo} used to get things rolling is kept around in the
+     * {@link MethodInvocation}, it will be needed in case of inlining, see
+     * {@link InlineInfo#inline(Providers, Assumptions)}
+     * </p>
      */
     private void processNextInvoke() {
         CallsiteHolderExplorable callsiteHolder = (CallsiteHolderExplorable) currentGraph();
@@ -531,6 +587,49 @@
     }
 
     /**
+     * <p>
+     * The stack realized by {@link InliningData} grows and shrinks as choices are made among the
+     * alternatives below:
+     * <ol>
+     * <li>
+     * not worth inlining: pop stack top, which comprises:
+     * <ul>
+     * <li>pop any remaining graphs not yet delved into</li>
+     * <li>pop the current invocation</li>
+     * </ul>
+     * </li>
+     * <li>
+     * {@link #processNextInvoke() delve} into one of the callsites hosted in the current graph,
+     * such callsite is explored next by {@link #moveForward()}</li>
+     * <li>
+     * {@link #tryToInline(MethodInvocation, MethodInvocation, int) try to inline}: move past the
+     * current graph (remove it from the topmost element).
+     * <ul>
+     * <li>
+     * If that was the last one then {@link #tryToInline(MethodInvocation, MethodInvocation, int)
+     * try to inline} the callsite under consideration (ie, the "current invocation").</li>
+     * <li>
+     * Whether inlining occurs or not, that callsite is removed from the top of {@link InliningData}
+     * .</li>
+     * </ul>
+     * </li>
+     * </ol>
+     * </p>
+     *
+     * <p>
+     * Some facts about the alternatives above:
+     * <ul>
+     * <li>
+     * the first step amounts to backtracking, the 2nd one to depth-search, and the 3rd one also
+     * involves backtracking (however possibly after inlining).</li>
+     * <li>
+     * the choice of abandon-and-backtrack or delve-into depends on
+     * {@link InliningPolicy#isWorthInlining} and {@link InliningPolicy#continueInlining}.</li>
+     * <li>
+     * the 3rd choice is picked whenever none of the previous choices are made</li>
+     * </ul>
+     * </p>
+     *
      * @return true iff inlining was actually performed
      */
     public boolean moveForward() {
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/MethodInvocation.java	Fri Jun 06 19:46:16 2014 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/MethodInvocation.java	Sat Jun 07 14:23:10 2014 +0200
@@ -29,6 +29,17 @@
 import com.oracle.graal.nodes.java.MethodCallTargetNode;
 import com.oracle.graal.phases.common.inlining.info.InlineInfo;
 
+/**
+ * <p>
+ * An instance of this class denotes a callsite being analyzed for inlining.
+ * </p>
+ * <p>
+ * Each element of the {@link InliningData} stack contains one such instance, the accompanying
+ * {@link CallsiteHolder}s in that element represent feasible targets for the callsite in question.
+ * </p>
+ *
+ * @see InliningData#moveForward()
+ */
 public class MethodInvocation {
 
     private final InlineInfo callee;