changeset 15761:00dd189ff7be

[inlining-4] getTypeCheckedInlineInfo() becomes instance method of InliningData
author Miguel Garcia <miguel.m.garcia@oracle.com>
date Mon, 19 May 2014 15:39:43 +0200
parents 559532aa3490
children a63d94e780ca
files 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/walker/InliningData.java
diffstat 2 files changed, 133 insertions(+), 134 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java	Mon May 19 15:30:58 2014 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java	Mon May 19 15:39:43 2014 +0200
@@ -31,7 +31,6 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.api.meta.JavaTypeProfile.ProfiledType;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.debug.*;
@@ -174,11 +173,11 @@
         }
     }
 
-    private static void logNotInlined(Invoke invoke, int inliningDepth, ResolvedJavaMethod method, String msg) {
+    public static void logNotInlined(Invoke invoke, int inliningDepth, ResolvedJavaMethod method, String msg) {
         logNotInlinedInvoke(invoke, inliningDepth, method, msg, new Object[0]);
     }
 
-    private static void logNotInlinedInvoke(Invoke invoke, int inliningDepth, ResolvedJavaMethod method, String msg, Object... args) {
+    public static void logNotInlinedInvoke(Invoke invoke, int inliningDepth, ResolvedJavaMethod method, String msg, Object... args) {
         printInlining(method, invoke, inliningDepth, false, msg, args);
         if (shouldLogInliningDecision()) {
             String methodString = methodName(method, invoke);
@@ -306,131 +305,7 @@
         }
 
         // type check based inlining
-        return getTypeCheckedInlineInfo(data, invoke, maxNumberOfMethods, replacements, targetMethod, optimisticOpts);
-    }
-
-    private static InlineInfo getTypeCheckedInlineInfo(InliningData data, Invoke invoke, int maxNumberOfMethods, Replacements replacements, ResolvedJavaMethod targetMethod,
-                    OptimisticOptimizations optimisticOpts) {
-        JavaTypeProfile typeProfile;
-        ValueNode receiver = invoke.callTarget().arguments().get(0);
-        if (receiver instanceof TypeProfileProxyNode) {
-            TypeProfileProxyNode typeProfileProxyNode = (TypeProfileProxyNode) receiver;
-            typeProfile = typeProfileProxyNode.getProfile();
-        } else {
-            logNotInlined(invoke, data.inliningDepth(), targetMethod, "no type profile exists");
-            return null;
-        }
-
-        ProfiledType[] ptypes = typeProfile.getTypes();
-        if (ptypes == null || ptypes.length <= 0) {
-            logNotInlined(invoke, data.inliningDepth(), targetMethod, "no types in profile");
-            return null;
-        }
-        ResolvedJavaType contextType = invoke.getContextType();
-        double notRecordedTypeProbability = typeProfile.getNotRecordedProbability();
-        if (ptypes.length == 1 && notRecordedTypeProbability == 0) {
-            if (!optimisticOpts.inlineMonomorphicCalls()) {
-                logNotInlined(invoke, data.inliningDepth(), targetMethod, "inlining monomorphic calls is disabled");
-                return null;
-            }
-
-            ResolvedJavaType type = ptypes[0].getType();
-            assert type.isArray() || !type.isAbstract();
-            ResolvedJavaMethod concrete = type.resolveMethod(targetMethod, contextType);
-            if (!checkTargetConditions(data, replacements, invoke, concrete, optimisticOpts)) {
-                return null;
-            }
-            return new TypeGuardInlineInfo(invoke, concrete, type);
-        } else {
-            invoke.setPolymorphic(true);
-
-            if (!optimisticOpts.inlinePolymorphicCalls() && notRecordedTypeProbability == 0) {
-                logNotInlinedInvoke(invoke, data.inliningDepth(), targetMethod, "inlining polymorphic calls is disabled (%d types)", ptypes.length);
-                return null;
-            }
-            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
-                logNotInlinedInvoke(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.
-            ArrayList<ResolvedJavaMethod> concreteMethods = new ArrayList<>();
-            ArrayList<Double> concreteMethodsProbabilities = new ArrayList<>();
-            for (int i = 0; i < ptypes.length; i++) {
-                ResolvedJavaMethod concrete = ptypes[i].getType().resolveMethod(targetMethod, contextType);
-                if (concrete == null) {
-                    logNotInlined(invoke, data.inliningDepth(), targetMethod, "could not resolve method");
-                    return null;
-                }
-                int index = concreteMethods.indexOf(concrete);
-                double curProbability = ptypes[i].getProbability();
-                if (index < 0) {
-                    index = concreteMethods.size();
-                    concreteMethods.add(concrete);
-                    concreteMethodsProbabilities.add(curProbability);
-                } else {
-                    concreteMethodsProbabilities.set(index, concreteMethodsProbabilities.get(index) + curProbability);
-                }
-            }
-
-            if (concreteMethods.size() > maxNumberOfMethods) {
-                logNotInlinedInvoke(invoke, data.inliningDepth(), targetMethod, "polymorphic call with more than %d target methods", maxNumberOfMethods);
-                return null;
-            }
-
-            // Clear methods that fall below the threshold.
-            if (notRecordedTypeProbability > 0) {
-                ArrayList<ResolvedJavaMethod> newConcreteMethods = new ArrayList<>();
-                ArrayList<Double> newConcreteMethodsProbabilities = new ArrayList<>();
-                for (int i = 0; i < concreteMethods.size(); ++i) {
-                    if (concreteMethodsProbabilities.get(i) >= MegamorphicInliningMinMethodProbability.getValue()) {
-                        newConcreteMethods.add(concreteMethods.get(i));
-                        newConcreteMethodsProbabilities.add(concreteMethodsProbabilities.get(i));
-                    }
-                }
-
-                if (newConcreteMethods.size() == 0) {
-                    // No method left that is worth inlining.
-                    logNotInlinedInvoke(invoke, data.inliningDepth(), targetMethod, "no methods remaining after filtering less frequent methods (%d methods previously)", concreteMethods.size());
-                    return null;
-                }
-
-                concreteMethods = newConcreteMethods;
-                concreteMethodsProbabilities = newConcreteMethodsProbabilities;
-            }
-
-            // Clean out types whose methods are no longer available.
-            ArrayList<ProfiledType> usedTypes = new ArrayList<>();
-            ArrayList<Integer> typesToConcretes = new ArrayList<>();
-            for (ProfiledType type : ptypes) {
-                ResolvedJavaMethod concrete = type.getType().resolveMethod(targetMethod, contextType);
-                int index = concreteMethods.indexOf(concrete);
-                if (index == -1) {
-                    notRecordedTypeProbability += type.getProbability();
-                } else {
-                    assert type.getType().isArray() || !type.getType().isAbstract() : type + " " + concrete;
-                    usedTypes.add(type);
-                    typesToConcretes.add(index);
-                }
-            }
-
-            if (usedTypes.size() == 0) {
-                // No type left that is worth checking for.
-                logNotInlinedInvoke(invoke, data.inliningDepth(), targetMethod, "no types remaining after filtering less frequent types (%d types previously)", ptypes.length);
-                return null;
-            }
-
-            for (ResolvedJavaMethod concrete : concreteMethods) {
-                if (!checkTargetConditions(data, replacements, invoke, concrete, optimisticOpts)) {
-                    logNotInlined(invoke, data.inliningDepth(), targetMethod, "it is a polymorphic method call and at least one invoked method cannot be inlined");
-                    return null;
-                }
-            }
-            return new MultiTypeGuardInlineInfo(invoke, concreteMethods, concreteMethodsProbabilities, usedTypes, typesToConcretes, notRecordedTypeProbability);
-        }
+        return data.getTypeCheckedInlineInfo(invoke, maxNumberOfMethods, replacements, targetMethod, optimisticOpts);
     }
 
     public static GuardedValueNode createAnchoredReceiver(StructuredGraph graph, GuardingNode anchor, ResolvedJavaType commonType, ValueNode receiver, boolean exact) {
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/InliningData.java	Mon May 19 15:30:58 2014 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/InliningData.java	Mon May 19 15:39:43 2014 +0200
@@ -24,31 +24,31 @@
 
 import com.oracle.graal.api.code.Assumptions;
 import com.oracle.graal.api.code.BailoutException;
+import com.oracle.graal.api.meta.JavaTypeProfile;
 import com.oracle.graal.api.meta.ResolvedJavaMethod;
+import com.oracle.graal.api.meta.ResolvedJavaType;
 import com.oracle.graal.compiler.common.GraalInternalError;
 import com.oracle.graal.debug.Debug;
 import com.oracle.graal.debug.DebugMetric;
 import com.oracle.graal.graph.Graph;
 import com.oracle.graal.graph.Node;
-import com.oracle.graal.nodes.FixedNode;
-import com.oracle.graal.nodes.Invoke;
-import com.oracle.graal.nodes.StructuredGraph;
+import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.Replacements;
 import com.oracle.graal.phases.OptimisticOptimizations;
 import com.oracle.graal.phases.common.CanonicalizerPhase;
 import com.oracle.graal.phases.common.inlining.InliningUtil;
-import com.oracle.graal.phases.common.inlining.info.AssumptionInlineInfo;
-import com.oracle.graal.phases.common.inlining.info.ExactInlineInfo;
-import com.oracle.graal.phases.common.inlining.info.InlineInfo;
+import com.oracle.graal.phases.common.inlining.info.*;
 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;
 
 import java.util.ArrayDeque;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.function.ToDoubleFunction;
 
+import static com.oracle.graal.compiler.common.GraalOptions.MegamorphicInliningMinMethodProbability;
 import static com.oracle.graal.compiler.common.GraalOptions.OptCanonicalizer;
 
 /**
@@ -90,6 +90,130 @@
         pushGraph(rootGraph, 1.0, 1.0);
     }
 
+    public InlineInfo getTypeCheckedInlineInfo(Invoke invoke, int maxNumberOfMethods, Replacements replacements, ResolvedJavaMethod targetMethod, OptimisticOptimizations optimisticOpts) {
+        JavaTypeProfile typeProfile;
+        ValueNode receiver = invoke.callTarget().arguments().get(0);
+        if (receiver instanceof TypeProfileProxyNode) {
+            TypeProfileProxyNode typeProfileProxyNode = (TypeProfileProxyNode) receiver;
+            typeProfile = typeProfileProxyNode.getProfile();
+        } else {
+            InliningUtil.logNotInlined(invoke, inliningDepth(), targetMethod, "no type profile exists");
+            return null;
+        }
+
+        JavaTypeProfile.ProfiledType[] ptypes = typeProfile.getTypes();
+        if (ptypes == null || ptypes.length <= 0) {
+            InliningUtil.logNotInlined(invoke, inliningDepth(), targetMethod, "no types in profile");
+            return null;
+        }
+        ResolvedJavaType contextType = invoke.getContextType();
+        double notRecordedTypeProbability = typeProfile.getNotRecordedProbability();
+        if (ptypes.length == 1 && notRecordedTypeProbability == 0) {
+            if (!optimisticOpts.inlineMonomorphicCalls()) {
+                InliningUtil.logNotInlined(invoke, inliningDepth(), targetMethod, "inlining monomorphic calls is disabled");
+                return null;
+            }
+
+            ResolvedJavaType type = ptypes[0].getType();
+            assert type.isArray() || !type.isAbstract();
+            ResolvedJavaMethod concrete = type.resolveMethod(targetMethod, contextType);
+            if (!InliningUtil.checkTargetConditions(this, replacements, invoke, concrete, optimisticOpts)) {
+                return null;
+            }
+            return new TypeGuardInlineInfo(invoke, concrete, type);
+        } else {
+            invoke.setPolymorphic(true);
+
+            if (!optimisticOpts.inlinePolymorphicCalls() && notRecordedTypeProbability == 0) {
+                InliningUtil.logNotInlinedInvoke(invoke, inliningDepth(), targetMethod, "inlining polymorphic calls is disabled (%d types)", ptypes.length);
+                return null;
+            }
+            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
+                InliningUtil.logNotInlinedInvoke(invoke, 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.
+            ArrayList<ResolvedJavaMethod> concreteMethods = new ArrayList<>();
+            ArrayList<Double> concreteMethodsProbabilities = new ArrayList<>();
+            for (int i = 0; i < ptypes.length; i++) {
+                ResolvedJavaMethod concrete = ptypes[i].getType().resolveMethod(targetMethod, contextType);
+                if (concrete == null) {
+                    InliningUtil.logNotInlined(invoke, inliningDepth(), targetMethod, "could not resolve method");
+                    return null;
+                }
+                int index = concreteMethods.indexOf(concrete);
+                double curProbability = ptypes[i].getProbability();
+                if (index < 0) {
+                    index = concreteMethods.size();
+                    concreteMethods.add(concrete);
+                    concreteMethodsProbabilities.add(curProbability);
+                } else {
+                    concreteMethodsProbabilities.set(index, concreteMethodsProbabilities.get(index) + curProbability);
+                }
+            }
+
+            if (concreteMethods.size() > maxNumberOfMethods) {
+                InliningUtil.logNotInlinedInvoke(invoke, inliningDepth(), targetMethod, "polymorphic call with more than %d target methods", maxNumberOfMethods);
+                return null;
+            }
+
+            // Clear methods that fall below the threshold.
+            if (notRecordedTypeProbability > 0) {
+                ArrayList<ResolvedJavaMethod> newConcreteMethods = new ArrayList<>();
+                ArrayList<Double> newConcreteMethodsProbabilities = new ArrayList<>();
+                for (int i = 0; i < concreteMethods.size(); ++i) {
+                    if (concreteMethodsProbabilities.get(i) >= MegamorphicInliningMinMethodProbability.getValue()) {
+                        newConcreteMethods.add(concreteMethods.get(i));
+                        newConcreteMethodsProbabilities.add(concreteMethodsProbabilities.get(i));
+                    }
+                }
+
+                if (newConcreteMethods.size() == 0) {
+                    // No method left that is worth inlining.
+                    InliningUtil.logNotInlinedInvoke(invoke, inliningDepth(), targetMethod, "no methods remaining after filtering less frequent methods (%d methods previously)",
+                                    concreteMethods.size());
+                    return null;
+                }
+
+                concreteMethods = newConcreteMethods;
+                concreteMethodsProbabilities = newConcreteMethodsProbabilities;
+            }
+
+            // Clean out types whose methods are no longer available.
+            ArrayList<JavaTypeProfile.ProfiledType> usedTypes = new ArrayList<>();
+            ArrayList<Integer> typesToConcretes = new ArrayList<>();
+            for (JavaTypeProfile.ProfiledType type : ptypes) {
+                ResolvedJavaMethod concrete = type.getType().resolveMethod(targetMethod, contextType);
+                int index = concreteMethods.indexOf(concrete);
+                if (index == -1) {
+                    notRecordedTypeProbability += type.getProbability();
+                } else {
+                    assert type.getType().isArray() || !type.getType().isAbstract() : type + " " + concrete;
+                    usedTypes.add(type);
+                    typesToConcretes.add(index);
+                }
+            }
+
+            if (usedTypes.size() == 0) {
+                // No type left that is worth checking for.
+                InliningUtil.logNotInlinedInvoke(invoke, inliningDepth(), targetMethod, "no types remaining after filtering less frequent types (%d types previously)", ptypes.length);
+                return null;
+            }
+
+            for (ResolvedJavaMethod concrete : concreteMethods) {
+                if (!InliningUtil.checkTargetConditions(this, replacements, invoke, concrete, optimisticOpts)) {
+                    InliningUtil.logNotInlined(invoke, inliningDepth(), targetMethod, "it is a polymorphic method call and at least one invoked method cannot be inlined");
+                    return null;
+                }
+            }
+            return new MultiTypeGuardInlineInfo(invoke, concreteMethods, concreteMethodsProbabilities, usedTypes, typesToConcretes, notRecordedTypeProbability);
+        }
+    }
+
     public InlineInfo getAssumptionInlineInfo(Invoke invoke, Replacements replacements, OptimisticOptimizations optimisticOpts, ResolvedJavaMethod concrete, Assumptions.Assumption takenAssumption) {
         assert !concrete.isAbstract();
         if (!InliningUtil.checkTargetConditions(this, replacements, invoke, concrete, optimisticOpts)) {