Mercurial > hg > graal-compiler
diff graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/util/InliningUtil.java @ 5335:439ca5ecc7dc
types profiles are now sorted in descending order of each profiled type's probability
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Wed, 02 May 2012 14:39:45 +0200 |
parents | 8ac40aed34bf |
children | 1fbc4a08d029 |
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/util/InliningUtil.java Wed May 02 12:59:59 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/util/InliningUtil.java Wed May 02 14:39:45 2012 +0200 @@ -29,6 +29,7 @@ import com.oracle.max.cri.ci.*; import com.oracle.max.cri.ri.*; import com.oracle.max.cri.ri.RiType.Representation; +import com.oracle.max.cri.ri.RiTypeProfile.ProfiledType; import com.oracle.graal.compiler.*; import com.oracle.graal.compiler.phases.*; import com.oracle.graal.cri.*; @@ -223,21 +224,19 @@ */ private static class MultiTypeGuardInlineInfo extends InlineInfo { public final List<RiResolvedMethod> concretes; - public final RiResolvedType[] types; + public final ProfiledType[] ptypes; public final int[] typesToConcretes; - public final double[] typeProbabilities; public final double notRecordedTypeProbability; - public MultiTypeGuardInlineInfo(Invoke invoke, double weight, int level, List<RiResolvedMethod> concretes, RiResolvedType[] types, - int[] typesToConcretes, double[] typeProbabilities, double notRecordedTypeProbability) { + public MultiTypeGuardInlineInfo(Invoke invoke, double weight, int level, List<RiResolvedMethod> concretes, ProfiledType[] ptypes, + int[] typesToConcretes, double notRecordedTypeProbability) { super(invoke, weight, level); - assert concretes.size() > 0 && concretes.size() <= types.length : "must have at least one method but no more than types methods"; - assert types.length == typesToConcretes.length && types.length == typeProbabilities.length : "array length must match"; + assert concretes.size() > 0 && concretes.size() <= ptypes.length : "must have at least one method but no more than types methods"; + assert ptypes.length == typesToConcretes.length : "array lengths must match"; this.concretes = concretes; - this.types = types; + this.ptypes = ptypes; this.typesToConcretes = typesToConcretes; - this.typeProbabilities = typeProbabilities; this.notRecordedTypeProbability = notRecordedTypeProbability; } @@ -305,7 +304,7 @@ for (int j = 0; j < typesToConcretes.length; j++) { if (typesToConcretes[j] == i) { predecessors++; - probability += typeProbabilities[j]; + probability += ptypes[j].probability; } } @@ -364,9 +363,9 @@ for (int i = 0; i < typesToConcretes.length; i++) { if (typesToConcretes[i] == concreteMethodIndex) { if (commonType == null) { - commonType = types[i]; + commonType = ptypes[i].type; } else { - commonType = commonType.leastCommonAncestor(types[i]); + commonType = commonType.leastCommonAncestor(ptypes[i].type); } } } @@ -375,7 +374,7 @@ } private void inlineSingleMethod(StructuredGraph graph, GraalRuntime runtime, InliningCallback callback) { - assert concretes.size() == 1 && types.length > 1 && !shouldFallbackToInvoke() && notRecordedTypeProbability == 0; + assert concretes.size() == 1 && ptypes.length > 1 && !shouldFallbackToInvoke() && notRecordedTypeProbability == 0; MergeNode calleeEntryNode = graph.add(new MergeNode()); calleeEntryNode.setProbability(invoke.probability()); @@ -397,15 +396,15 @@ } private FixedNode createDispatchOnType(StructuredGraph graph, ReadHubNode objectClassNode, BeginNode[] calleeEntryNodes, FixedNode unknownTypeSux) { - assert types.length > 1; + assert ptypes.length > 1; - int lastIndex = types.length - 1; - double[] branchProbabilities = convertTypeToBranchProbabilities(typeProbabilities, notRecordedTypeProbability); - double nodeProbability = typeProbabilities[lastIndex]; - IfNode nextNode = createTypeCheck(graph, objectClassNode, types[lastIndex], calleeEntryNodes[typesToConcretes[lastIndex]], unknownTypeSux, branchProbabilities[lastIndex], invoke.probability() * nodeProbability); + int lastIndex = ptypes.length - 1; + double[] branchProbabilities = convertTypeToBranchProbabilities(ptypes, notRecordedTypeProbability); + double nodeProbability = ptypes[lastIndex].probability; + IfNode nextNode = createTypeCheck(graph, objectClassNode, ptypes[lastIndex].type, calleeEntryNodes[typesToConcretes[lastIndex]], unknownTypeSux, branchProbabilities[lastIndex], invoke.probability() * nodeProbability); for (int i = lastIndex - 1; i >= 0; i--) { - nodeProbability += typeProbabilities[i]; - nextNode = createTypeCheck(graph, objectClassNode, types[i], calleeEntryNodes[typesToConcretes[i]], nextNode, branchProbabilities[i], invoke.probability() * nodeProbability); + nodeProbability += ptypes[i].probability; + nextNode = createTypeCheck(graph, objectClassNode, ptypes[i].type, calleeEntryNodes[typesToConcretes[i]], nextNode, branchProbabilities[i], invoke.probability() * nodeProbability); } return nextNode; @@ -425,12 +424,12 @@ return result; } - private static double[] convertTypeToBranchProbabilities(double[] typeProbabilities, double notRecordedTypeProbability) { - double[] result = new double[typeProbabilities.length]; + private static double[] convertTypeToBranchProbabilities(ProfiledType[] ptypes, double notRecordedTypeProbability) { + double[] result = new double[ptypes.length]; double total = notRecordedTypeProbability; - for (int i = typeProbabilities.length - 1; i >= 0; i--) { - total += typeProbabilities[i]; - result[i] = typeProbabilities[i] / total; + for (int i = ptypes.length - 1; i >= 0; i--) { + total += ptypes[i].probability; + result[i] = ptypes[i].probability / total; } assert total > 0.99 && total < 1.01; return result; @@ -497,7 +496,7 @@ @Override public String toString() { StringBuilder builder = new StringBuilder(shouldFallbackToInvoke() ? "megamorphic" : "polymorphic"); - builder.append(String.format(", %d methods with %d type checks:", concretes.size(), types.length)); + builder.append(String.format(", %d methods with %d type checks:", concretes.size(), ptypes.length)); for (int i = 0; i < concretes.size(); i++) { builder.append(CiUtil.format(" %H.%n(%p):%r", concretes.get(i))); } @@ -612,15 +611,13 @@ RiProfilingInfo profilingInfo = parent.profilingInfo(); RiTypeProfile typeProfile = profilingInfo.getTypeProfile(invoke.bci()); if (typeProfile != null) { - RiResolvedType[] types = typeProfile.getTypes(); - double[] probabilities = typeProfile.getProbabilities(); + ProfiledType[] ptypes = typeProfile.getTypes(); - if (types != null && probabilities != null && types.length > 0) { - assert types.length == probabilities.length : "length must match"; + if (ptypes != null && ptypes.length > 0) { double notRecordedTypeProbability = typeProfile.getNotRecordedProbability(); - if (types.length == 1 && notRecordedTypeProbability == 0) { + if (ptypes.length == 1 && notRecordedTypeProbability == 0) { if (optimisticOpts.inlineMonomorphicCalls()) { - RiResolvedType type = types[0]; + RiResolvedType type = ptypes[0].type; RiResolvedMethod concrete = type.resolveMethodImpl(targetMethod); if (checkTargetConditions(invoke, concrete, optimisticOpts)) { double weight = callback == null ? 0 : callback.inliningWeight(parent, concrete, invoke); @@ -646,9 +643,9 @@ // determine concrete methods and map type to specific method ArrayList<RiResolvedMethod> concreteMethods = new ArrayList<>(); - int[] typesToConcretes = new int[types.length]; - for (int i = 0; i < types.length; i++) { - RiResolvedMethod concrete = types[i].resolveMethodImpl(targetMethod); + int[] typesToConcretes = new int[ptypes.length]; + for (int i = 0; i < ptypes.length; i++) { + RiResolvedMethod concrete = ptypes[i].type.resolveMethodImpl(targetMethod); int index = concreteMethods.indexOf(concrete); if (index < 0) { @@ -669,7 +666,7 @@ } if (canInline) { - return new MultiTypeGuardInlineInfo(invoke, totalWeight, level, concreteMethods, types, typesToConcretes, probabilities, notRecordedTypeProbability); + return new MultiTypeGuardInlineInfo(invoke, totalWeight, level, concreteMethods, ptypes, typesToConcretes, notRecordedTypeProbability); } else { Debug.log("not inlining %s because it is a polymorphic method call and at least one invoked method cannot be inlined", methodName(targetMethod, invoke)); return null;