# HG changeset patch # User Miguel Garcia # Date 1401808301 -7200 # Node ID 2aa285cf40db9780a60a6304a4280872c3451f4c # Parent 4408391d34a134588e253fe8f383e66f6cf33ca7 [inliner] the two personalities embodied by CallsiteHolder finally taken apart diff -r 4408391d34a1 -r 2aa285cf40db graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/CallsiteHolder.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/CallsiteHolder.java Tue Jun 03 16:00:11 2014 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/CallsiteHolder.java Tue Jun 03 17:11:41 2014 +0200 @@ -22,102 +22,31 @@ */ package com.oracle.graal.phases.common.inlining.walker; -import com.oracle.graal.api.meta.MetaUtil; import com.oracle.graal.api.meta.ResolvedJavaMethod; -import com.oracle.graal.nodes.FixedNode; -import com.oracle.graal.nodes.Invoke; import com.oracle.graal.nodes.StructuredGraph; -import com.oracle.graal.phases.graph.FixedNodeProbabilityCache; - -import java.util.LinkedList; -import java.util.function.ToDoubleFunction; - -import static com.oracle.graal.compiler.common.GraalOptions.CapInheritedRelevance; /** * Information about a graph that will potentially be inlined. This includes tracking the * invocations in graph that will subject to inlining themselves. */ -public class CallsiteHolder { - - private final StructuredGraph graph; - private final LinkedList remainingInvokes; - private final double probability; - private final double relevance; - - private final ToDoubleFunction probabilities; - private final ComputeInliningRelevance computeInliningRelevance; - - public CallsiteHolder(StructuredGraph graph, double probability, double relevance) { - this.graph = graph; - this.probability = probability; - this.relevance = relevance; - if (graph == null) { - remainingInvokes = new LinkedList<>(); - probabilities = null; - computeInliningRelevance = null; - } else { - remainingInvokes = new InliningIterator(graph).apply(); - if (remainingInvokes.isEmpty()) { - probabilities = null; - computeInliningRelevance = null; - } else { - probabilities = new FixedNodeProbabilityCache(); - computeInliningRelevance = new ComputeInliningRelevance(graph, probabilities); - computeProbabilities(); - } - } - } +public abstract class CallsiteHolder { /** * Gets the method associated with the {@linkplain #graph() graph} represented by this object. */ - public ResolvedJavaMethod method() { - return graph == null ? null : graph.method(); - } + public abstract ResolvedJavaMethod method(); - public boolean hasRemainingInvokes() { - return !remainingInvokes.isEmpty(); - } + /** + * The stack realized by {@link InliningData} grows upon {@link InliningData#moveForward()} + * deciding to explore (depth-first) a callsite of the graph associated to this + * {@link CallsiteHolder}. The list of not-yet-considered callsites is managed by + * {@link CallsiteHolderExplorable}, and this method reports whether any such candidates remain. + */ + public abstract boolean hasRemainingInvokes(); /** * The graph about which this object contains inlining information. */ - public StructuredGraph graph() { - return graph; - } - - public Invoke popInvoke() { - return remainingInvokes.removeFirst(); - } - - public void pushInvoke(Invoke invoke) { - remainingInvokes.push(invoke); - } + public abstract StructuredGraph graph(); - public boolean containsInvoke(Invoke invoke) { - for (Invoke i : graph().getInvokes()) { - if (i == invoke) { - return true; - } - } - return false; - } - - public void computeProbabilities() { - computeInliningRelevance.compute(); - } - - public double invokeProbability(Invoke invoke) { - return probability * probabilities.applyAsDouble(invoke.asNode()); - } - - public double invokeRelevance(Invoke invoke) { - return Math.min(CapInheritedRelevance.getValue(), relevance) * computeInliningRelevance.getRelevance(invoke); - } - - @Override - public String toString() { - return (graph != null ? MetaUtil.format("%H.%n(%p)", method()) : "") + remainingInvokes; - } } diff -r 4408391d34a1 -r 2aa285cf40db graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/CallsiteHolderDummy.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/CallsiteHolderDummy.java Tue Jun 03 17:11:41 2014 +0200 @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.phases.common.inlining.walker; + +import com.oracle.graal.api.meta.ResolvedJavaMethod; +import com.oracle.graal.nodes.StructuredGraph; + +import com.oracle.graal.phases.common.inlining.info.elem.InlineableMacroNode; + +/** + * A {@link CallsiteHolder} that stands for an {@link InlineableMacroNode} in the stack realized by + * {@link InliningData}. + */ +public final class CallsiteHolderDummy extends CallsiteHolder { + + public CallsiteHolderDummy() { + } + + @Override + public ResolvedJavaMethod method() { + return null; + } + + @Override + public boolean hasRemainingInvokes() { + return false; + } + + @Override + public StructuredGraph graph() { + return null; + } + + @Override + public String toString() { + return ""; + } +} diff -r 4408391d34a1 -r 2aa285cf40db graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/CallsiteHolderExplorable.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/CallsiteHolderExplorable.java Tue Jun 03 17:11:41 2014 +0200 @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.phases.common.inlining.walker; + +import com.oracle.graal.api.meta.MetaUtil; +import com.oracle.graal.api.meta.ResolvedJavaMethod; +import com.oracle.graal.nodes.FixedNode; +import com.oracle.graal.nodes.Invoke; +import com.oracle.graal.nodes.StructuredGraph; +import com.oracle.graal.phases.graph.FixedNodeProbabilityCache; + +import java.util.LinkedList; +import java.util.function.ToDoubleFunction; + +import static com.oracle.graal.compiler.common.GraalOptions.CapInheritedRelevance; + +/** + *

+ * A {@link CallsiteHolder} whose graph has been already copied and thus can be modified without + * affecting the original (usually cached) version. + *

+ * + *

+ * 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}) + *

+ */ +public final class CallsiteHolderExplorable extends CallsiteHolder { + + private final StructuredGraph graph; + private final LinkedList remainingInvokes; + private final double probability; + private final double relevance; + + private final ToDoubleFunction probabilities; + private final ComputeInliningRelevance computeInliningRelevance; + + public CallsiteHolderExplorable(StructuredGraph graph, double probability, double relevance) { + assert graph != null; + this.graph = graph; + this.probability = probability; + this.relevance = relevance; + remainingInvokes = new InliningIterator(graph).apply(); + if (remainingInvokes.isEmpty()) { + probabilities = null; + computeInliningRelevance = null; + } else { + probabilities = new FixedNodeProbabilityCache(); + computeInliningRelevance = new ComputeInliningRelevance(graph, probabilities); + computeProbabilities(); + } + } + + @Override + public ResolvedJavaMethod method() { + return graph == null ? null : graph.method(); + } + + @Override + public boolean hasRemainingInvokes() { + return !remainingInvokes.isEmpty(); + } + + @Override + public StructuredGraph graph() { + return graph; + } + + public Invoke popInvoke() { + return remainingInvokes.removeFirst(); + } + + public void pushInvoke(Invoke invoke) { + remainingInvokes.push(invoke); + } + + public boolean containsInvoke(Invoke invoke) { + for (Invoke i : graph().getInvokes()) { + if (i == invoke) { + return true; + } + } + return false; + } + + public void computeProbabilities() { + computeInliningRelevance.compute(); + } + + public double invokeProbability(Invoke invoke) { + return probability * probabilities.applyAsDouble(invoke.asNode()); + } + + public double invokeRelevance(Invoke invoke) { + return Math.min(CapInheritedRelevance.getValue(), relevance) * computeInliningRelevance.getRelevance(invoke); + } + + @Override + public String toString() { + return (graph != null ? MetaUtil.format("%H.%n(%p)", method()) : "") + remainingInvokes; + } +} diff -r 4408391d34a1 -r 2aa285cf40db graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/InliningData.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/InliningData.java Tue Jun 03 16:00:11 2014 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/InliningData.java Tue Jun 03 17:11:41 2014 +0200 @@ -58,7 +58,7 @@ */ public class InliningData { - private static final CallsiteHolder DUMMY_CALLSITE_HOLDER = new CallsiteHolder(null, 1.0, 1.0); + private static final CallsiteHolder DUMMY_CALLSITE_HOLDER = new CallsiteHolderDummy(); // Metrics private static final DebugMetric metricInliningPerformed = Debug.metric("InliningPerformed"); private static final DebugMetric metricInliningRuns = Debug.metric("InliningRuns"); @@ -88,7 +88,7 @@ Assumptions rootAssumptions = context.getAssumptions(); invocationQueue.push(new MethodInvocation(null, rootAssumptions, 1.0, 1.0)); - pushGraph(rootGraph, 1.0, 1.0); + pushExplorableGraph(rootGraph, 1.0, 1.0); } private String checkTargetConditionsHelper(ResolvedJavaMethod method) { @@ -336,7 +336,7 @@ return new ExactInlineInfo(invoke, targetMethod); } - private void doInline(CallsiteHolder callerCallsiteHolder, MethodInvocation calleeInvocation, Assumptions callerAssumptions) { + private void doInline(CallsiteHolderExplorable callerCallsiteHolder, MethodInvocation calleeInvocation, Assumptions callerAssumptions) { StructuredGraph callerGraph = callerCallsiteHolder.graph(); InlineInfo calleeInfo = calleeInvocation.callee(); try { @@ -378,7 +378,7 @@ /** * @return true iff inlining was actually performed */ - private boolean tryToInline(CallsiteHolder callerCallsiteHolder, MethodInvocation calleeInvocation, MethodInvocation parentInvocation, int inliningDepth) { + private boolean tryToInline(CallsiteHolderExplorable callerCallsiteHolder, MethodInvocation calleeInvocation, MethodInvocation parentInvocation, int inliningDepth) { InlineInfo calleeInfo = calleeInvocation.callee(); assert callerCallsiteHolder.containsInvoke(calleeInfo.invoke()); Assumptions callerAssumptions = parentInvocation.assumptions(); @@ -400,7 +400,7 @@ * Process the next invoke and enqueue all its graphs for processing. */ private void processNextInvoke() { - CallsiteHolder callsiteHolder = currentGraph(); + CallsiteHolderExplorable callsiteHolder = (CallsiteHolderExplorable) currentGraph(); Invoke invoke = callsiteHolder.popInvoke(); MethodInvocation callerInvocation = currentInvocation(); Assumptions parentAssumptions = callerInvocation.assumptions(); @@ -431,10 +431,10 @@ return graphQueue.size(); } - private void pushGraph(StructuredGraph graph, double probability, double relevance) { + private void pushExplorableGraph(StructuredGraph graph, double probability, double relevance) { assert graph != null; assert !contains(graph); - graphQueue.push(new CallsiteHolder(graph, probability, relevance)); + graphQueue.push(new CallsiteHolderExplorable(graph, probability, relevance)); assert graphQueue.size() <= maxGraphs; } @@ -494,7 +494,7 @@ for (int i = 0; i < info.numberOfMethods(); i++) { Inlineable elem = info.inlineableElementAt(i); if (elem instanceof InlineableGraph) { - pushGraph(((InlineableGraph) elem).getGraph(), invokeProbability * info.probabilityAt(i), invokeRelevance * info.relevanceAt(i)); + pushExplorableGraph(((InlineableGraph) elem).getGraph(), invokeProbability * info.probabilityAt(i), invokeRelevance * info.relevanceAt(i)); } else { assert elem instanceof InlineableMacroNode; pushDummyGraph(); @@ -593,7 +593,7 @@ popInvocation(); final MethodInvocation parentInvoke = currentInvocation(); try (Debug.Scope s = Debug.scope("Inlining", inliningContext())) { - return tryToInline(currentGraph(), currentInvocation, parentInvoke, inliningDepth() + 1); + return tryToInline((CallsiteHolderExplorable) currentGraph(), currentInvocation, parentInvoke, inliningDepth() + 1); } catch (Throwable e) { throw Debug.handle(e); }