changeset 15721:1e3f19292a32

[inlining] reverting refactoring trail until spoiling commit(s) are discovered
author Miguel Garcia <miguel.m.garcia@oracle.com>
date Fri, 16 May 2014 19:59:52 +0200
parents 0b363d4ceb84
children c583759bbcfd
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/InliningUtil.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/policy/GreedyInliningPolicy.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/InliningData.java
diffstat 4 files changed, 89 insertions(+), 112 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningPhase.java	Fri May 16 16:36:07 2014 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningPhase.java	Fri May 16 19:59:52 2014 +0200
@@ -23,6 +23,7 @@
 package com.oracle.graal.phases.common.inlining;
 
 import java.util.*;
+import java.util.function.*;
 
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.options.*;
@@ -32,6 +33,7 @@
 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.graph.*;
 import com.oracle.graal.phases.tiers.*;
 
 public class InliningPhase extends AbstractInliningPhase {
@@ -123,12 +125,12 @@
      * <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>
+     * bakctraking (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>
+     * the 3rd choice is picked when both of the previous one aren't picked</li>
      * <li>
      * as part of trying-to-inline, {@link InliningPolicy#isWorthInlining} again sees use, but
      * that's another story.</li>
@@ -138,10 +140,11 @@
      */
     @Override
     protected void run(final StructuredGraph graph, final HighTierContext context) {
-        final InliningData data = new InliningData(graph, context, maxMethodPerInlining, canonicalizer, inliningPolicy);
+        final InliningData data = new InliningData(graph, context.getAssumptions(), maxMethodPerInlining, canonicalizer, inliningPolicy);
+        ToDoubleFunction<FixedNode> probabilities = new FixedNodeProbabilityCache();
 
         while (data.hasUnprocessedGraphs()) {
-            boolean wasInlined = data.moveForward();
+            boolean wasInlined = data.moveForward(context, probabilities);
             if (wasInlined) {
                 inliningCount++;
             }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java	Fri May 16 16:36:07 2014 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java	Fri May 16 19:59:52 2014 +0200
@@ -142,19 +142,22 @@
         }
     }
 
-    public static void logInlinedMethod(InlineInfo info, int inliningDepth, String msg, Object... args) {
-        logInliningDecision(info, inliningDepth, true, msg, args);
+    public static boolean logInlinedMethod(InlineInfo info, int inliningDepth, boolean allowLogging, String msg, Object... args) {
+        return logInliningDecision(info, inliningDepth, allowLogging, true, msg, args);
+    }
+
+    public static boolean logNotInlinedMethod(InlineInfo info, int inliningDepth, String msg, Object... args) {
+        return logInliningDecision(info, inliningDepth, true, false, msg, args);
     }
 
-    public static void logNotInlinedMethod(InlineInfo info, int inliningDepth, String msg, Object... args) {
-        logInliningDecision(info, inliningDepth, false, msg, args);
-    }
-
-    public static void logInliningDecision(InlineInfo info, int inliningDepth, boolean success, String msg, final Object... args) {
-        printInlining(info, inliningDepth, success, msg, args);
-        if (shouldLogInliningDecision()) {
-            logInliningDecision(methodName(info), success, msg, args);
+    public static boolean logInliningDecision(InlineInfo info, int inliningDepth, boolean allowLogging, boolean success, String msg, final Object... args) {
+        if (allowLogging) {
+            printInlining(info, inliningDepth, success, msg, args);
+            if (shouldLogInliningDecision()) {
+                logInliningDecision(methodName(info), success, msg, args);
+            }
         }
+        return success;
     }
 
     public static void logInliningDecision(final String msg, final Object... args) {
@@ -166,23 +169,34 @@
         }
     }
 
-    private static void logNotInlined(Invoke invoke, String msg) {
+    private static boolean logNotInlinedMethod(Invoke invoke, String msg) {
         if (shouldLogInliningDecision()) {
             String methodString = invoke.toString() + (invoke.callTarget() == null ? " callTarget=null" : invoke.callTarget().targetName());
             logInliningDecision(methodString, false, msg, new Object[0]);
         }
+        return false;
     }
 
-    private static void logNotInlinedMethod(Invoke invoke, int inliningDepth, ResolvedJavaMethod method, String msg) {
-        logNotInlined(invoke, inliningDepth, method, msg, new Object[0]);
+    private static InlineInfo logNotInlinedMethodAndReturnNull(Invoke invoke, int inliningDepth, ResolvedJavaMethod method, String msg) {
+        return logNotInlinedMethodAndReturnNull(invoke, inliningDepth, method, msg, new Object[0]);
     }
 
-    private static void logNotInlined(Invoke invoke, int inliningDepth, ResolvedJavaMethod method, String msg, Object... args) {
+    private static InlineInfo logNotInlinedMethodAndReturnNull(Invoke invoke, int inliningDepth, ResolvedJavaMethod method, String msg, Object... args) {
         printInlining(method, invoke, inliningDepth, false, msg, args);
         if (shouldLogInliningDecision()) {
             String methodString = methodName(method, invoke);
             logInliningDecision(methodString, false, msg, args);
         }
+        return null;
+    }
+
+    private static boolean logNotInlinedMethodAndReturnFalse(Invoke invoke, int inliningDepth, ResolvedJavaMethod method, String msg) {
+        printInlining(method, invoke, inliningDepth, false, msg, new Object[0]);
+        if (shouldLogInliningDecision()) {
+            String methodString = methodName(method, invoke);
+            logInliningDecision(methodString, false, msg, new Object[0]);
+        }
+        return false;
     }
 
     private static void logInliningDecision(final String methodString, final boolean success, final String msg, final Object... args) {
@@ -241,9 +255,7 @@
      * @return an instance of InlineInfo, or null if no inlining is possible at the given invoke
      */
     public static InlineInfo getInlineInfo(InliningData data, Invoke invoke, int maxNumberOfMethods, Replacements replacements, Assumptions assumptions, OptimisticOptimizations optimisticOpts) {
-        final String failureMessage = checkInvokeConditions(invoke);
-        if (failureMessage != null) {
-            logNotInlined(invoke, failureMessage);
+        if (!checkInvokeConditions(invoke)) {
             return null;
         }
         MethodCallTargetNode callTarget = (MethodCallTargetNode) invoke.callTarget();
@@ -332,21 +344,18 @@
             TypeProfileProxyNode typeProfileProxyNode = (TypeProfileProxyNode) receiver;
             typeProfile = typeProfileProxyNode.getProfile();
         } else {
-            logNotInlinedMethod(invoke, data.inliningDepth(), targetMethod, "no type profile exists");
-            return null;
+            return logNotInlinedMethodAndReturnNull(invoke, data.inliningDepth(), targetMethod, "no type profile exists");
         }
 
         ProfiledType[] ptypes = typeProfile.getTypes();
         if (ptypes == null || ptypes.length <= 0) {
-            logNotInlinedMethod(invoke, data.inliningDepth(), targetMethod, "no types in profile");
-            return null;
+            return logNotInlinedMethodAndReturnNull(invoke, data.inliningDepth(), targetMethod, "no types in profile");
         }
 
         double notRecordedTypeProbability = typeProfile.getNotRecordedProbability();
         if (ptypes.length == 1 && notRecordedTypeProbability == 0) {
             if (!optimisticOpts.inlineMonomorphicCalls()) {
-                logNotInlinedMethod(invoke, data.inliningDepth(), targetMethod, "inlining monomorphic calls is disabled");
-                return null;
+                return logNotInlinedMethodAndReturnNull(invoke, data.inliningDepth(), targetMethod, "inlining monomorphic calls is disabled");
             }
 
             ResolvedJavaType type = ptypes[0].getType();
@@ -360,15 +369,13 @@
             invoke.setPolymorphic(true);
 
             if (!optimisticOpts.inlinePolymorphicCalls() && notRecordedTypeProbability == 0) {
-                logNotInlined(invoke, data.inliningDepth(), targetMethod, "inlining polymorphic calls is disabled (%d types)", ptypes.length);
-                return null;
+                return logNotInlinedMethodAndReturnNull(invoke, data.inliningDepth(), targetMethod, "inlining polymorphic calls is disabled (%d types)", ptypes.length);
             }
             if (!optimisticOpts.inlineMegamorphicCalls() && notRecordedTypeProbability > 0) {
                 // due to filtering impossible types, notRecordedTypeProbability can be > 0 although
                 // the number of types is lower than what can be recorded in a type profile
-                logNotInlined(invoke, data.inliningDepth(), targetMethod, "inlining megamorphic calls is disabled (%d types, %f %% not recorded types)", ptypes.length,
+                return logNotInlinedMethodAndReturnNull(invoke, data.inliningDepth(), targetMethod, "inlining megamorphic calls is disabled (%d types, %f %% not recorded types)", ptypes.length,
                                 notRecordedTypeProbability * 100);
-                return null;
             }
 
             // Find unique methods and their probabilities.
@@ -377,8 +384,7 @@
             for (int i = 0; i < ptypes.length; i++) {
                 ResolvedJavaMethod concrete = ptypes[i].getType().resolveMethod(targetMethod);
                 if (concrete == null) {
-                    logNotInlinedMethod(invoke, data.inliningDepth(), targetMethod, "could not resolve method");
-                    return null;
+                    return logNotInlinedMethodAndReturnNull(invoke, data.inliningDepth(), targetMethod, "could not resolve method");
                 }
                 int index = concreteMethods.indexOf(concrete);
                 double curProbability = ptypes[i].getProbability();
@@ -392,8 +398,7 @@
             }
 
             if (concreteMethods.size() > maxNumberOfMethods) {
-                logNotInlined(invoke, data.inliningDepth(), targetMethod, "polymorphic call with more than %d target methods", maxNumberOfMethods);
-                return null;
+                return logNotInlinedMethodAndReturnNull(invoke, data.inliningDepth(), targetMethod, "polymorphic call with more than %d target methods", maxNumberOfMethods);
             }
 
             // Clear methods that fall below the threshold.
@@ -409,8 +414,8 @@
 
                 if (newConcreteMethods.size() == 0) {
                     // No method left that is worth inlining.
-                    logNotInlined(invoke, data.inliningDepth(), targetMethod, "no methods remaining after filtering less frequent methods (%d methods previously)", concreteMethods.size());
-                    return null;
+                    return logNotInlinedMethodAndReturnNull(invoke, data.inliningDepth(), targetMethod, "no methods remaining after filtering less frequent methods (%d methods previously)",
+                                    concreteMethods.size());
                 }
 
                 concreteMethods = newConcreteMethods;
@@ -434,14 +439,12 @@
 
             if (usedTypes.size() == 0) {
                 // No type left that is worth checking for.
-                logNotInlined(invoke, data.inliningDepth(), targetMethod, "no types remaining after filtering less frequent types (%d types previously)", ptypes.length);
-                return null;
+                return logNotInlinedMethodAndReturnNull(invoke, data.inliningDepth(), targetMethod, "no types remaining after filtering less frequent types (%d types previously)", ptypes.length);
             }
 
             for (ResolvedJavaMethod concrete : concreteMethods) {
                 if (!checkTargetConditions(data, replacements, invoke, concrete, optimisticOpts)) {
-                    logNotInlinedMethod(invoke, data.inliningDepth(), targetMethod, "it is a polymorphic method call and at least one invoked method cannot be inlined");
-                    return null;
+                    return logNotInlinedMethodAndReturnNull(invoke, data.inliningDepth(), targetMethod, "it is a polymorphic method call and at least one invoked method cannot be inlined");
                 }
             }
             return new MultiTypeGuardInlineInfo(invoke, concreteMethods, concreteMethodsProbabilities, usedTypes, typesToConcretes, notRecordedTypeProbability);
@@ -457,51 +460,44 @@
         return graph.unique(new GuardedValueNode(receiver, anchor, stamp));
     }
 
-    /**
-     * @return null iff the check succeeds, otherwise a (non-null) descriptive message.
-     */
-    private static String checkInvokeConditions(Invoke invoke) {
+    // TODO (chaeubl): cleanup this method
+    private static boolean checkInvokeConditions(Invoke invoke) {
         if (invoke.predecessor() == null || !invoke.asNode().isAlive()) {
-            return "the invoke is dead code";
+            return logNotInlinedMethod(invoke, "the invoke is dead code");
         } else if (!(invoke.callTarget() instanceof MethodCallTargetNode)) {
-            return "the invoke has already been lowered, or has been created as a low-level node";
+            return logNotInlinedMethod(invoke, "the invoke has already been lowered, or has been created as a low-level node");
         } else if (((MethodCallTargetNode) invoke.callTarget()).targetMethod() == null) {
-            return "target method is null";
+            return logNotInlinedMethod(invoke, "target method is null");
         } else if (invoke.stateAfter() == null) {
             // TODO (chaeubl): why should an invoke not have a state after?
-            return "the invoke has no after state";
+            return logNotInlinedMethod(invoke, "the invoke has no after state");
         } else if (!invoke.useForInlining()) {
-            return "the invoke is marked to be not used for inlining";
+            return logNotInlinedMethod(invoke, "the invoke is marked to be not used for inlining");
         } else if (((MethodCallTargetNode) invoke.callTarget()).receiver() != null && ((MethodCallTargetNode) invoke.callTarget()).receiver().isConstant() &&
                         ((MethodCallTargetNode) invoke.callTarget()).receiver().asConstant().isNull()) {
-            return "receiver is null";
+            return logNotInlinedMethod(invoke, "receiver is null");
         } else {
-            return null;
+            return true;
         }
     }
 
     private static boolean checkTargetConditions(InliningData data, Replacements replacements, Invoke invoke, ResolvedJavaMethod method, OptimisticOptimizations optimisticOpts) {
-        String failureMessage = null;
         if (method == null) {
-            failureMessage = "the method is not resolved";
+            return logNotInlinedMethodAndReturnFalse(invoke, data.inliningDepth(), method, "the method is not resolved");
         } else if (method.isNative() && (!Intrinsify.getValue() || !InliningUtil.canIntrinsify(replacements, method))) {
-            failureMessage = "it is a non-intrinsic native method";
+            return logNotInlinedMethodAndReturnFalse(invoke, data.inliningDepth(), method, "it is a non-intrinsic native method");
         } else if (method.isAbstract()) {
-            failureMessage = "it is an abstract method";
+            return logNotInlinedMethodAndReturnFalse(invoke, data.inliningDepth(), method, "it is an abstract method");
         } else if (!method.getDeclaringClass().isInitialized()) {
-            failureMessage = "the method's class is not initialized";
+            return logNotInlinedMethodAndReturnFalse(invoke, data.inliningDepth(), method, "the method's class is not initialized");
         } else if (!method.canBeInlined()) {
-            failureMessage = "it is marked non-inlinable";
+            return logNotInlinedMethodAndReturnFalse(invoke, data.inliningDepth(), method, "it is marked non-inlinable");
         } else if (data.countRecursiveInlining(method) > MaximumRecursiveInlining.getValue()) {
-            failureMessage = "it exceeds the maximum recursive inlining depth";
+            return logNotInlinedMethodAndReturnFalse(invoke, data.inliningDepth(), method, "it exceeds the maximum recursive inlining depth");
         } else if (new OptimisticOptimizations(method.getProfilingInfo()).lessOptimisticThan(optimisticOpts)) {
-            failureMessage = "the callee uses less optimistic optimizations than caller";
-        }
-        if (failureMessage == null) {
+            return logNotInlinedMethodAndReturnFalse(invoke, data.inliningDepth(), method, "the callee uses less optimistic optimizations than caller");
+        } else {
             return true;
-        } else {
-            logNotInlinedMethod(invoke, data.inliningDepth(), method, failureMessage);
-            return false;
         }
     }
 
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/policy/GreedyInliningPolicy.java	Fri May 16 16:36:07 2014 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/policy/GreedyInliningPolicy.java	Fri May 16 19:59:52 2014 +0200
@@ -34,9 +34,6 @@
 import java.util.Map;
 import java.util.function.ToDoubleFunction;
 
-import static com.oracle.graal.phases.common.inlining.InliningUtil.logInlinedMethod;
-import static com.oracle.graal.phases.common.inlining.InliningUtil.logNotInlinedMethod;
-
 import static com.oracle.graal.compiler.common.GraalOptions.*;
 
 public class GreedyInliningPolicy extends AbstractInliningPolicy {
@@ -60,24 +57,15 @@
     public boolean isWorthInlining(ToDoubleFunction<FixedNode> probabilities, Replacements replacements, InlineInfo info, int inliningDepth, double probability, double relevance,
                     boolean fullyProcessed) {
         if (InlineEverything.getValue()) {
-            if (fullyProcessed) {
-                logInlinedMethod(info, inliningDepth, "inline everything");
-            }
-            return true;
+            return InliningUtil.logInlinedMethod(info, inliningDepth, fullyProcessed, "inline everything");
         }
 
         if (isIntrinsic(replacements, info)) {
-            if (fullyProcessed) {
-                logInlinedMethod(info, inliningDepth, "intrinsic");
-            }
-            return true;
+            return InliningUtil.logInlinedMethod(info, inliningDepth, fullyProcessed, "intrinsic");
         }
 
         if (info.shouldInline()) {
-            if (fullyProcessed) {
-                logInlinedMethod(info, inliningDepth, "forced inlining");
-            }
-            return true;
+            return InliningUtil.logInlinedMethod(info, inliningDepth, fullyProcessed, "forced inlining");
         }
 
         double inliningBonus = getInliningBonus(info);
@@ -85,16 +73,12 @@
         int lowLevelGraphSize = previousLowLevelGraphSize(info);
 
         if (SmallCompiledLowLevelGraphSize.getValue() > 0 && lowLevelGraphSize > SmallCompiledLowLevelGraphSize.getValue() * inliningBonus) {
-            logNotInlinedMethod(info, inliningDepth, "too large previous low-level graph (low-level-nodes: %d, relevance=%f, probability=%f, bonus=%f, nodes=%d)", lowLevelGraphSize, relevance,
-                            probability, inliningBonus, nodes);
-            return false;
+            return InliningUtil.logNotInlinedMethod(info, inliningDepth, "too large previous low-level graph (low-level-nodes: %d, relevance=%f, probability=%f, bonus=%f, nodes=%d)",
+                            lowLevelGraphSize, relevance, probability, inliningBonus, nodes);
         }
 
         if (nodes < TrivialInliningSize.getValue() * inliningBonus) {
-            if (fullyProcessed) {
-                logInlinedMethod(info, inliningDepth, "trivial (relevance=%f, probability=%f, bonus=%f, nodes=%d)", relevance, probability, inliningBonus, nodes);
-            }
-            return true;
+            return InliningUtil.logInlinedMethod(info, inliningDepth, fullyProcessed, "trivial (relevance=%f, probability=%f, bonus=%f, nodes=%d)", relevance, probability, inliningBonus, nodes);
         }
 
         /*
@@ -105,20 +89,17 @@
          */
         double invokes = determineInvokeProbability(probabilities, info);
         if (LimitInlinedInvokes.getValue() > 0 && fullyProcessed && invokes > LimitInlinedInvokes.getValue() * inliningBonus) {
-            logNotInlinedMethod(info, inliningDepth, "callee invoke probability is too high (invokeP=%f, relevance=%f, probability=%f, bonus=%f, nodes=%d)", invokes, relevance, probability,
-                            inliningBonus, nodes);
-            return false;
+            return InliningUtil.logNotInlinedMethod(info, inliningDepth, "callee invoke probability is too high (invokeP=%f, relevance=%f, probability=%f, bonus=%f, nodes=%d)", invokes, relevance,
+                            probability, inliningBonus, nodes);
         }
 
         double maximumNodes = computeMaximumSize(relevance, (int) (MaximumInliningSize.getValue() * inliningBonus));
         if (nodes <= maximumNodes) {
-            if (fullyProcessed) {
-                logInlinedMethod(info, inliningDepth, "relevance-based (relevance=%f, probability=%f, bonus=%f, nodes=%d <= %f)", relevance, probability, inliningBonus, nodes, maximumNodes);
-            }
-            return true;
+            return InliningUtil.logInlinedMethod(info, inliningDepth, fullyProcessed, "relevance-based (relevance=%f, probability=%f, bonus=%f, nodes=%d <= %f)", relevance, probability,
+                            inliningBonus, nodes, maximumNodes);
         }
 
-        logNotInlinedMethod(info, inliningDepth, "relevance-based (relevance=%f, probability=%f, bonus=%f, nodes=%d > %f)", relevance, probability, inliningBonus, nodes, maximumNodes);
-        return false;
+        return InliningUtil.logNotInlinedMethod(info, inliningDepth, "relevance-based (relevance=%f, probability=%f, bonus=%f, nodes=%d > %f)", relevance, probability, inliningBonus, nodes,
+                        maximumNodes);
     }
 }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/InliningData.java	Fri May 16 16:36:07 2014 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/InliningData.java	Fri May 16 19:59:52 2014 +0200
@@ -37,7 +37,6 @@
 import com.oracle.graal.phases.common.inlining.InliningUtil;
 import com.oracle.graal.phases.common.inlining.info.InlineInfo;
 import com.oracle.graal.phases.common.inlining.policy.InliningPolicy;
-import com.oracle.graal.phases.graph.FixedNodeProbabilityCache;
 import com.oracle.graal.phases.tiers.HighTierContext;
 import com.oracle.graal.phases.util.Providers;
 
@@ -62,31 +61,28 @@
     /**
      * Call hierarchy from outer most call (i.e., compilation unit) to inner most callee.
      */
-    private final ArrayDeque<CallsiteHolder> graphQueue = new ArrayDeque<>();
-    private final ArrayDeque<MethodInvocation> invocationQueue = new ArrayDeque<>();
-    private final ToDoubleFunction<FixedNode> probabilities = new FixedNodeProbabilityCache();
-
-    private final HighTierContext context;
+    private final ArrayDeque<CallsiteHolder> graphQueue;
+    private final ArrayDeque<MethodInvocation> invocationQueue;
     private final int maxMethodPerInlining;
     private final CanonicalizerPhase canonicalizer;
     private final InliningPolicy inliningPolicy;
 
     private int maxGraphs;
 
-    public InliningData(StructuredGraph rootGraph, HighTierContext context, int maxMethodPerInlining, CanonicalizerPhase canonicalizer, InliningPolicy inliningPolicy) {
+    public InliningData(StructuredGraph rootGraph, Assumptions rootAssumptions, int maxMethodPerInlining, CanonicalizerPhase canonicalizer, InliningPolicy inliningPolicy) {
         assert rootGraph != null;
-        this.context = context;
+        this.graphQueue = new ArrayDeque<>();
+        this.invocationQueue = new ArrayDeque<>();
         this.maxMethodPerInlining = maxMethodPerInlining;
         this.canonicalizer = canonicalizer;
         this.inliningPolicy = inliningPolicy;
         this.maxGraphs = 1;
 
-        Assumptions rootAssumptions = context.getAssumptions();
         invocationQueue.push(new MethodInvocation(null, rootAssumptions, 1.0, 1.0));
         pushGraph(rootGraph, 1.0, 1.0);
     }
 
-    private void doInline(CallsiteHolder callerCallsiteHolder, MethodInvocation calleeInfo, Assumptions callerAssumptions) {
+    private void doInline(CallsiteHolder callerCallsiteHolder, MethodInvocation calleeInfo, Assumptions callerAssumptions, HighTierContext context) {
         StructuredGraph callerGraph = callerCallsiteHolder.graph();
         Graph.Mark markBeforeInlining = callerGraph.getMark();
         InlineInfo callee = calleeInfo.callee();
@@ -126,13 +122,14 @@
     /**
      * @return true iff inlining was actually performed
      */
-    private boolean tryToInline(CallsiteHolder callerCallsiteHolder, MethodInvocation calleeInfo, MethodInvocation parentInvocation, int inliningDepth) {
+    private boolean tryToInline(ToDoubleFunction<FixedNode> probabilities, CallsiteHolder callerCallsiteHolder, MethodInvocation calleeInfo, MethodInvocation parentInvocation, int inliningDepth,
+                    HighTierContext context) {
         InlineInfo callee = calleeInfo.callee();
         Assumptions callerAssumptions = parentInvocation.assumptions();
         metricInliningConsidered.increment();
 
         if (inliningPolicy.isWorthInlining(probabilities, context.getReplacements(), callee, inliningDepth, calleeInfo.probability(), calleeInfo.relevance(), true)) {
-            doInline(callerCallsiteHolder, calleeInfo, callerAssumptions);
+            doInline(callerCallsiteHolder, calleeInfo, callerAssumptions, context);
             return true;
         }
 
@@ -146,7 +143,7 @@
     /**
      * Process the next invoke and enqueue all its graphs for processing.
      */
-    void processNextInvoke() {
+    void processNextInvoke(HighTierContext context) {
         CallsiteHolder callsiteHolder = currentGraph();
         Invoke invoke = callsiteHolder.popInvoke();
         MethodInvocation callerInvocation = currentInvocation();
@@ -290,7 +287,7 @@
     /**
      * @return true iff inlining was actually performed
      */
-    public boolean moveForward() {
+    public boolean moveForward(HighTierContext context, ToDoubleFunction<FixedNode> probabilities) {
 
         final MethodInvocation currentInvocation = currentInvocation();
 
@@ -306,7 +303,7 @@
 
         final boolean delve = currentGraph().hasRemainingInvokes() && inliningPolicy.continueInlining(currentGraph().graph());
         if (delve) {
-            processNextInvoke();
+            processNextInvoke(context);
             return false;
         }
 
@@ -322,7 +319,7 @@
             popInvocation();
             final MethodInvocation parentInvoke = currentInvocation();
             try (Debug.Scope s = Debug.scope("Inlining", inliningContext())) {
-                return tryToInline(currentGraph(), currentInvocation, parentInvoke, inliningDepth() + 1);
+                return tryToInline(probabilities, currentGraph(), currentInvocation, parentInvoke, inliningDepth() + 1, context);
             } catch (Throwable e) {
                 throw Debug.handle(e);
             }