changeset 16034:2aa285cf40db

[inliner] the two personalities embodied by CallsiteHolder finally taken apart
author Miguel Garcia <miguel.m.garcia@oracle.com>
date Tue, 03 Jun 2014 17:11:41 +0200
parents 4408391d34a1
children 15f1580a37e7
files graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/CallsiteHolder.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/CallsiteHolderDummy.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
diffstat 4 files changed, 200 insertions(+), 90 deletions(-) [+]
line wrap: on
line diff
--- 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<Invoke> remainingInvokes;
-    private final double probability;
-    private final double relevance;
-
-    private final ToDoubleFunction<FixedNode> 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()) : "<null method>") + remainingInvokes;
-    }
 }
--- /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 "<macro-node>";
+    }
+}
--- /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;
+
+/**
+ * <p>
+ * A {@link CallsiteHolder} whose graph has been already copied 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})
+ * </p>
+ */
+public final class CallsiteHolderExplorable extends CallsiteHolder {
+
+    private final StructuredGraph graph;
+    private final LinkedList<Invoke> remainingInvokes;
+    private final double probability;
+    private final double relevance;
+
+    private final ToDoubleFunction<FixedNode> 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()) : "<null method>") + remainingInvokes;
+    }
+}
--- 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);
             }