Mercurial > hg > graal-jvmci-8
changeset 9392:5a74cbafe5b9
Adjustment to the megamorphic inlining strategy such that it focuses on concrete methods.
author | Thomas Wuerthinger <thomas.wuerthinger@oracle.com> |
---|---|
date | Sun, 28 Apr 2013 19:17:56 +0200 |
parents | afc859750f41 |
children | 6a2a9eac243a 16a10b48e526 |
files | graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java |
diffstat | 2 files changed, 53 insertions(+), 78 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Sun Apr 28 18:46:00 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Sun Apr 28 19:17:56 2013 +0200 @@ -419,15 +419,15 @@ public final List<ResolvedJavaMethod> concretes; public final ArrayList<ProfiledType> ptypes; - public final int[] typesToConcretes; + public final ArrayList<Integer> typesToConcretes; public final double notRecordedTypeProbability; private final ArrayList<Double> concretesProbabilities; - public MultiTypeGuardInlineInfo(Invoke invoke, ArrayList<ResolvedJavaMethod> concretes, ArrayList<Double> concretesProbabilities, ArrayList<ProfiledType> ptypes, int[] typesToConcretes, - double notRecordedTypeProbability) { + public MultiTypeGuardInlineInfo(Invoke invoke, ArrayList<ResolvedJavaMethod> concretes, ArrayList<Double> concretesProbabilities, ArrayList<ProfiledType> ptypes, + ArrayList<Integer> typesToConcretes, double notRecordedTypeProbability) { super(invoke); - assert concretes.size() > 0 && concretes.size() <= ptypes.size() : "must have at least one method but no more than types methods"; - assert ptypes.size() == typesToConcretes.length : "array lengths must match"; + assert concretes.size() > 0 : "must have at least one method"; + assert ptypes.size() == typesToConcretes.size() : "array lengths must match"; this.concretesProbabilities = concretesProbabilities; this.concretes = concretes; @@ -582,8 +582,8 @@ private int getTypeCount(int concreteMethodIndex) { int count = 0; - for (int i = 0; i < typesToConcretes.length; i++) { - if (typesToConcretes[i] == concreteMethodIndex) { + for (int i = 0; i < typesToConcretes.size(); i++) { + if (typesToConcretes.get(i) == concreteMethodIndex) { count++; } } @@ -592,8 +592,8 @@ private ResolvedJavaType getLeastCommonType(int concreteMethodIndex) { ResolvedJavaType commonType = null; - for (int i = 0; i < typesToConcretes.length; i++) { - if (typesToConcretes[i] == concreteMethodIndex) { + for (int i = 0; i < typesToConcretes.size(); i++) { + if (typesToConcretes.get(i) == concreteMethodIndex) { if (commonType == null) { commonType = ptypes.get(i).getType(); } else { @@ -678,7 +678,7 @@ for (int i = 0; i < ptypes.size(); i++) { keys[i] = ptypes.get(i).getType(); keyProbabilities[i] = ptypes.get(i).getProbability(); - keySuccessors[i] = invokeIsOnlySuccessor ? 0 : typesToConcretes[i]; + keySuccessors[i] = invokeIsOnlySuccessor ? 0 : typesToConcretes.get(i); assert keySuccessors[i] < successors.length - 1 : "last successor is the unknownTypeSux"; } keyProbabilities[keyProbabilities.length - 1] = notRecordedTypeProbability; @@ -992,13 +992,53 @@ notRecordedTypeProbability * 100); } - // Clean out uncommon types. + // 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); + 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); + } + } + + // 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) >= GraalOptions.MegamorphicInliningMinMethodProbability) { + newConcreteMethods.add(concreteMethods.get(i)); + newConcreteMethodsProbabilities.add(concreteMethodsProbabilities.get(i)); + } + } + + if (newConcreteMethods.size() == 0) { + // No method left that is worth inlining. + return logNotInlinedMethodAndReturnNull(invoke, targetMethod, "no methods remaining after filtering less frequent methods (%d methods previously)", concreteMethods.size()); + } + + 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) { - if (notRecordedTypeProbability > 0 && type.getProbability() < GraalOptions.MegamorphicInliningMinTypeProbability) { + ResolvedJavaMethod concrete = type.getType().resolveMethod(targetMethod); + int index = concreteMethods.indexOf(concrete); + if (index == -1) { notRecordedTypeProbability += type.getProbability(); } else { usedTypes.add(type); + typesToConcretes.add(index); } } @@ -1007,70 +1047,6 @@ return logNotInlinedMethodAndReturnNull(invoke, targetMethod, "no types remaining after filtering less frequent types (%d types previously)", ptypes.length); } - // determine concrete methods and map type to specific method - ArrayList<ResolvedJavaMethod> concreteMethods = new ArrayList<>(); - ArrayList<Double> concreteMethodsProbabilities = new ArrayList<>(); - int[] typesToConcretes = new int[usedTypes.size()]; - for (int i = 0; i < usedTypes.size(); i++) { - ResolvedJavaMethod concrete = usedTypes.get(i).getType().resolveMethod(targetMethod); - - int index = concreteMethods.indexOf(concrete); - if (index < 0) { - index = concreteMethods.size(); - concreteMethods.add(concrete); - concreteMethodsProbabilities.add(usedTypes.get(i).getProbability()); - } else { - concreteMethodsProbabilities.set(index, concreteMethodsProbabilities.get(index) + usedTypes.get(i).getProbability()); - } - typesToConcretes[i] = index; - } - - if (notRecordedTypeProbability > 0) { - // Clean out uncommon methods. - ArrayList<ResolvedJavaMethod> newConcreteMethods = new ArrayList<>(); - ArrayList<Double> newConcreteMethodsProbabilities = new ArrayList<>(); - for (int i = 0; i < concreteMethods.size(); ++i) { - if (concreteMethodsProbabilities.get(i) >= GraalOptions.MegamorphicInliningMinMethodProbability) { - newConcreteMethods.add(concreteMethods.get(i)); - newConcreteMethodsProbabilities.add(concreteMethodsProbabilities.get(i)); - } else { - concreteMethods.set(i, null); - } - } - - if (concreteMethods.size() != newConcreteMethods.size()) { - - if (newConcreteMethods.size() == 0) { - // No method left that is worth inlining. - return logNotInlinedMethodAndReturnNull(invoke, targetMethod, "no methods remaining after filtering less frequent methods (%d methods previously)", concreteMethods.size()); - } - - // Clean all types that referred to cleaned methods. - ArrayList<ProfiledType> newTypes = new ArrayList<>(); - ArrayList<Integer> newTypesToConcretes = new ArrayList<>(); - for (int i = 0; i < typesToConcretes.length; ++i) { - ResolvedJavaMethod resolvedJavaMethod = concreteMethods.get(typesToConcretes[i]); - if (resolvedJavaMethod != null) { - newTypes.add(usedTypes.get(i)); - newTypesToConcretes.add(newConcreteMethods.indexOf(resolvedJavaMethod)); - } else { - notRecordedTypeProbability += usedTypes.get(i).getProbability(); - } - } - - int[] newTypesToConcretesArray = new int[newTypesToConcretes.size()]; - for (int i = 0; i < newTypesToConcretesArray.length; ++i) { - newTypesToConcretesArray[i] = newTypesToConcretes.get(i); - concreteMethods.get(typesToConcretes[i]); - } - - usedTypes = newTypes; - typesToConcretes = newTypesToConcretesArray; - concreteMethods = newConcreteMethods; - concreteMethodsProbabilities = newConcreteMethodsProbabilities; - } - } - for (ResolvedJavaMethod concrete : concreteMethods) { if (!checkTargetConditions(replacements, invoke, concrete, optimisticOpts)) { return logNotInlinedMethodAndReturnNull(invoke, targetMethod, "it is a polymorphic method call and at least one invoked method cannot be inlined");
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Sun Apr 28 18:46:00 2013 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Sun Apr 28 19:17:56 2013 +0200 @@ -45,8 +45,7 @@ static boolean InlineMonomorphicCalls = true; static boolean InlinePolymorphicCalls = true; static boolean InlineMegamorphicCalls = true; - public static double MegamorphicInliningMinTypeProbability = 0.05; - public static double MegamorphicInliningMinMethodProbability = 0.20; + public static double MegamorphicInliningMinMethodProbability = 0.33; public static int MaximumDesiredSize = 5000; public static int MaximumRecursiveInlining = 1; public static float BoostInliningForEscapeAnalysis = 2f;