Mercurial > hg > graal-compiler
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;