# HG changeset patch # User Christian Haeubl # Date 1359735939 -3600 # Node ID 149092d59dd0e93c93bbcadafdb6e19af39bb0b6 # Parent 7d66682cc9012f5de14b7ed36c6c83809dff8ee5 fixes after merge diff -r 7d66682cc901 -r 149092d59dd0 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java Fri Feb 01 17:06:26 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java Fri Feb 01 17:25:39 2013 +0100 @@ -131,10 +131,6 @@ return this; } - public JavaType returnType() { - return returnType; - } - @Override public Stamp returnStamp() { Kind returnKind = targetMethod.getSignature().getReturnKind(); diff -r 7d66682cc901 -r 149092d59dd0 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java Fri Feb 01 17:06:26 2013 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java Fri Feb 01 17:25:39 2013 +0100 @@ -72,7 +72,8 @@ this.customCanonicalizer = customCanonicalizer; } - public InliningPhase(TargetDescription target, GraalCodeCacheProvider runtime, Assumptions assumptions, GraphCache cache, PhasePlan plan, InliningPolicy inliningPolicy, OptimisticOptimizations optimisticOpts) { + public InliningPhase(TargetDescription target, GraalCodeCacheProvider runtime, Assumptions assumptions, GraphCache cache, PhasePlan plan, InliningPolicy inliningPolicy, + OptimisticOptimizations optimisticOpts) { this.target = target; this.runtime = runtime; this.assumptions = assumptions; @@ -159,6 +160,7 @@ } private static class GreedySizeBasedInliningDecision implements InliningDecision { + private final GraalCodeCacheProvider runtime; private final Collection hints; @@ -169,27 +171,31 @@ @Override public boolean isWorthInlining(InlineInfo info) { -// assert GraalOptions.ProbabilityAnalysis; -// if (compiledCodeSize(info) > GraalOptions.SmallCompiledCodeSize) { -// return false; -// } +// assert GraalOptions.ProbabilityAnalysis; +// if (compiledCodeSize(info) > GraalOptions.SmallCompiledCodeSize) { +// return false; +// } // -// double maxSize = GraalOptions.NormalComplexity; -// Signature signature = info.invoke().methodCallTarget().targetMethod().getSignature(); -// int transferredValues = signature.getParameterCount(!Modifier.isStatic(info.invoke().methodCallTarget().targetMethod().getModifiers())); -// if (signature.getReturnKind() != Kind.Void) { -// transferredValues++; -// } -// maxSize += transferredValues * 10; +// double maxSize = GraalOptions.NormalComplexity; +// Signature signature = info.invoke().methodCallTarget().targetMethod().getSignature(); +// int transferredValues = +// signature.getParameterCount(!Modifier.isStatic(info.invoke().methodCallTarget().targetMethod().getModifiers())); +// if (signature.getReturnKind() != Kind.Void) { +// transferredValues++; +// } +// maxSize += transferredValues * 10; // -// maxSize = Math.min(GraalOptions.RelevanceCapForInlining, info.invoke().inliningRelevance()) * maxSize; -// maxSize = Math.max(maxSize, GraalOptions.TrivialComplexity); +// maxSize = Math.min(GraalOptions.RelevanceCapForInlining, info.invoke().inliningRelevance()) * +// maxSize; +// maxSize = Math.max(maxSize, GraalOptions.TrivialComplexity); // -// return compilationComplexity(info) < maxSize; +// return compilationComplexity(info) < maxSize; assert GraalOptions.ProbabilityAnalysis; - // TODO (chaeubl): invoked methods that are on important paths but not yet compiled -> will be compiled anyways and it is likely that we are the only caller... - // might be useful to inline those methods but increases bootstrap time (maybe those methods are also getting queued in the compilation queue concurrently) + // TODO (chaeubl): invoked methods that are on important paths but not yet compiled -> +// will be compiled anyways and it is likely that we are the only caller... + // might be useful to inline those methods but increases bootstrap time (maybe those +// methods are also getting queued in the compilation queue concurrently) if (GraalOptions.AlwaysInlineIntrinsics && onlyIntrinsics(info)) { return InliningUtil.logInlinedMethod(info, "intrinsic"); @@ -200,7 +206,8 @@ int compiledCodeSize = compiledCodeSize(info); double relevance = info.invoke().inliningRelevance(); - // as long as the compiled code size is small enough (or the method was not yet compiled), we can do a pretty general inlining that suits most situations + // as long as the compiled code size is small enough (or the method was not yet +// compiled), we can do a pretty general inlining that suits most situations if (compiledCodeSize < GraalOptions.SmallCompiledCodeSize) { if (isTrivialInlining(bytecodeSize, complexity, compiledCodeSize)) { return InliningUtil.logInlinedMethod(info, "trivial (bytecodes=%d, complexity=%d, codeSize=%d)", bytecodeSize, complexity, compiledCodeSize); @@ -211,7 +218,8 @@ } } - // the normal inlining did not fit this invoke, so check if we have any reason why we should still do the inlining + // the normal inlining did not fit this invoke, so check if we have any reason why we +// should still do the inlining double probability = info.invoke().probability(); int transferredValues = numberOfTransferredValues(info); int invokeUsages = countInvokeUsages(info); @@ -219,31 +227,33 @@ int level = info.level(); boolean preferredInvoke = hints != null && hints.contains(info.invoke()); - // TODO (chaeubl): compute metric that is used to check if this method should be inlined anyways. also use the relevance somehow... -// double metric = (moreSpecificArguments * 5 + transferredValues + invokeUsages) * (preferredInvoke ? 1 : GraalOptions.BoostInliningForEscapeAnalysis); -// if (metric > 50) { -// // TEMP: -// TTY.println("Inlined special method (relevance=%f, bytecodes=%d, complexity=%d, codeSize=%d, probability=%f, transferredValues=%d, invokeUsages=%d, moreSpecificArguments=%d, level=%d, preferred=%b)", -// relevance, bytecodeSize, complexity, compiledCodeSize, probability, transferredValues, invokeUsages, moreSpecificArguments, level, preferredInvoke); -// return InliningUtil.logInlinedMethod(info, "(relevance=%f, bytecodes=%d, complexity=%d, codeSize=%d, probability=%f, transferredValues=%d, invokeUsages=%d, moreSpecificArguments=%d, level=%d, preferred=%b)", -// relevance, bytecodeSize, complexity, compiledCodeSize, probability, transferredValues, invokeUsages, moreSpecificArguments, level, preferredInvoke); -// } + // TODO (chaeubl): compute metric that is used to check if this method should be inlined +// anyways. also use the relevance somehow... +// double metric = (moreSpecificArguments * 5 + transferredValues + invokeUsages) * (preferredInvoke +// ? 1 : GraalOptions.BoostInliningForEscapeAnalysis); +// if (metric > 50) { +// // TEMP: +// TTY.println("Inlined special method (relevance=%f, bytecodes=%d, complexity=%d, codeSize=%d, probability=%f, transferredValues=%d, invokeUsages=%d, moreSpecificArguments=%d, level=%d, preferred=%b)", +// relevance, bytecodeSize, complexity, compiledCodeSize, probability, transferredValues, +// invokeUsages, moreSpecificArguments, level, preferredInvoke); +// return InliningUtil.logInlinedMethod(info, +// "(relevance=%f, bytecodes=%d, complexity=%d, codeSize=%d, probability=%f, transferredValues=%d, invokeUsages=%d, moreSpecificArguments=%d, level=%d, preferred=%b)", +// relevance, bytecodeSize, complexity, compiledCodeSize, probability, transferredValues, +// invokeUsages, moreSpecificArguments, level, preferredInvoke); +// } - - return InliningUtil.logNotInlinedMethod(info, "(relevance=%f, bytecodes=%d, complexity=%d, codeSize=%d, probability=%f, transferredValues=%d, invokeUsages=%d, moreSpecificArguments=%d, level=%d, preferred=%b)", + return InliningUtil.logNotInlinedMethod(info, + "(relevance=%f, bytecodes=%d, complexity=%d, codeSize=%d, probability=%f, transferredValues=%d, invokeUsages=%d, moreSpecificArguments=%d, level=%d, preferred=%b)", relevance, bytecodeSize, complexity, compiledCodeSize, probability, transferredValues, invokeUsages, moreSpecificArguments, level, preferredInvoke); } private static boolean isTrivialInlining(int bytecodeSize, int complexity, int compiledCodeSize) { - return bytecodeSize < GraalOptions.TrivialBytecodeSize || - complexity < GraalOptions.TrivialComplexity || - compiledCodeSize > 0 && compiledCodeSize < GraalOptions.TrivialCompiledCodeSize; + return bytecodeSize < GraalOptions.TrivialBytecodeSize || complexity < GraalOptions.TrivialComplexity || compiledCodeSize > 0 && compiledCodeSize < GraalOptions.TrivialCompiledCodeSize; } private static boolean canInlineRelevanceBased(double relevance, int bytecodeSize, int complexity, int compiledCodeSize) { - return bytecodeSize < computeMaximumSize(relevance, GraalOptions.NormalBytecodeSize) || - complexity < computeMaximumSize(relevance, GraalOptions.NormalComplexity) || - compiledCodeSize > 0 && compiledCodeSize < computeMaximumSize(relevance, GraalOptions.NormalCompiledCodeSize); + return bytecodeSize < computeMaximumSize(relevance, GraalOptions.NormalBytecodeSize) || complexity < computeMaximumSize(relevance, GraalOptions.NormalComplexity) || compiledCodeSize > 0 && + compiledCodeSize < computeMaximumSize(relevance, GraalOptions.NormalCompiledCodeSize); } private static double computeMaximumSize(double relevance, int configuredMaximum) { @@ -263,7 +273,7 @@ private static int countInvokeUsages(InlineInfo info) { // inlining calls with lots of usages simplifies the caller int usages = 0; - for (Node n: info.invoke().node().usages()) { + for (Node n : info.invoke().node().usages()) { if (!(n instanceof FrameState)) { usages++; } @@ -272,7 +282,8 @@ } private int countMoreSpecificArgumentInfo(InlineInfo info) { - // inlining invokes where the caller has very specific information about the passed argument simplifies the callee + // inlining invokes where the caller has very specific information about the passed +// argument simplifies the callee int moreSpecificArgumentInfo = 0; boolean isStatic = info.invoke().methodCallTarget().isStatic(); int signatureOffset = isStatic ? 0 : 1; @@ -348,8 +359,7 @@ private NodeBitMap visitedFixedNodes; private FixedNode invokePredecessor; - public CFInliningPolicy(InliningDecision inliningPolicy, Collection hints, - OptimisticOptimizations optimisticOpts) { + public CFInliningPolicy(InliningDecision inliningPolicy, Collection hints, Assumptions assumptions, OptimisticOptimizations optimisticOpts) { this.inliningDecision = inliningPolicy; this.hints = hints; this.assumptions = assumptions; @@ -411,7 +421,7 @@ private static int countInvokes(Iterable nodes) { int count = 0; - for (Node n: nodes) { + for (Node n : nodes) { if (n instanceof Invoke) { count++; } @@ -518,7 +528,7 @@ } private static InliningPolicy createInliningPolicy(GraalCodeCacheProvider runtime, Assumptions assumptions, OptimisticOptimizations optimisticOpts, Collection hints) { - InliningDecision inliningDecision = new GreedySizeBasedInliningDecision(runtime, hints); + InliningDecision inliningDecision = new GreedySizeBasedInliningDecision(runtime, hints); return new CFInliningPolicy(inliningDecision, hints, assumptions, optimisticOpts); } } diff -r 7d66682cc901 -r 149092d59dd0 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Fri Feb 01 17:06:26 2013 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Fri Feb 01 17:25:39 2013 +0100 @@ -49,9 +49,9 @@ private static final String inliningDecisionsScopeString = "InliningDecisions"; /** - * Meters the size (in bytecodes) of all methods processed during compilation (i.e., top level and all - * inlined methods), irrespective of how many bytecodes in each method are actually parsed - * (which may be none for methods whose IR is retrieved from a cache). + * Meters the size (in bytecodes) of all methods processed during compilation (i.e., top level + * and all inlined methods), irrespective of how many bytecodes in each method are actually + * parsed (which may be none for methods whose IR is retrieved from a cache). */ public static final DebugMetric InlinedBytecodes = Debug.metric("InlinedBytecodes"); @@ -70,7 +70,6 @@ void scanInvokes(Iterable newNodes); - boolean isWorthInlining(InlineInfo info); } @@ -183,13 +182,12 @@ Invoke invoke(); - int level(); int numberOfMethods(); + ResolvedJavaMethod methodAt(int index); - /** * Performs the inlining described by this object and returns the node that represents the * return value of the inlined method (or null for void methods and methods that have no @@ -197,7 +195,6 @@ **/ void inline(StructuredGraph graph, GraalCodeCacheProvider runtime, InliningCallback callback, Assumptions assumptions); - /** * Try to make the call static bindable to avoid interface and virtual method calls. */ @@ -253,7 +250,7 @@ } } - private static StructuredGraph getGraph(final ResolvedJavaMethod concrete, final InliningCallback callback) { + protected static StructuredGraph getGraph(final ResolvedJavaMethod concrete, final InliningCallback callback) { return Debug.scope("GetInliningGraph", concrete, new Callable() { @Override @@ -344,7 +341,7 @@ StructuredGraph calleeGraph = getGraph(concrete, callback); assumptions.recordMethodContents(concrete); - inline(invoke, calleeGraph, false); + InliningUtil.inline(invoke, calleeGraph, false); } @Override @@ -389,7 +386,7 @@ public final int[] typesToConcretes; public final double notRecordedTypeProbability; - public MultiTypeGuardInlineInfo(Invoke invoke, double weight, ArrayList concretes, ArrayList ptypes, int[] typesToConcretes, double notRecordedTypeProbability) { + public MultiTypeGuardInlineInfo(Invoke invoke, ArrayList concretes, ArrayList ptypes, int[] 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"; @@ -698,7 +695,8 @@ if (methodCallTarget.invokeKind() == InvokeKind.Interface) { ResolvedJavaMethod targetMethod = methodCallTarget.targetMethod(); ResolvedJavaType leastCommonType = getLeastCommonType(); - // check if we have a common base type that implements the interface -> in that case we have a vtable entry for the interface method and can use a less expensive virtual call + // check if we have a common base type that implements the interface -> in that case +// we have a vtable entry for the interface method and can use a less expensive virtual call if (!leastCommonType.isInterface() && targetMethod.getDeclaringClass().isAssignableFrom(leastCommonType)) { ResolvedJavaMethod baseClassTargetMethod = leastCommonType.resolveMethod(targetMethod); if (baseClassTargetMethod != null) { @@ -715,7 +713,7 @@ invocationEntry.setProbability(invoke.probability()); BeginNode unknownTypeSux = createUnknownTypeSuccessor(graph); - BeginNode[] successors = new BeginNode[] {invocationEntry, unknownTypeSux}; + BeginNode[] successors = new BeginNode[]{invocationEntry, unknownTypeSux}; createDispatchOnTypeBeforeInvoke(graph, successors, true); invocationEntry.setNext(invoke.node()); @@ -860,8 +858,7 @@ return new ExactInlineInfo(invoke, targetMethod); } - private static InlineInfo getTypeCheckedInlineInfo(Invoke invoke, ResolvedJavaMethod caller, - OptimisticOptimizations optimisticOpts) { + private static InlineInfo getTypeCheckedInlineInfo(Invoke invoke, ResolvedJavaMethod caller, ResolvedJavaType holder, ResolvedJavaMethod targetMethod, OptimisticOptimizations optimisticOpts) { ProfilingInfo profilingInfo = caller.getProfilingInfo(); JavaTypeProfile typeProfile = profilingInfo.getTypeProfile(invoke.bci()); if (typeProfile == null) { @@ -1190,9 +1187,9 @@ public static StructuredGraph getIntrinsicGraph(ResolvedJavaMethod target) { return (StructuredGraph) target.getCompilerStorage().get(Graph.class); } - } public static Class getMacroNodeClass(ResolvedJavaMethod target) { Object result = target.getCompilerStorage().get(Node.class); return result == null ? null : ((Class) result).asSubclass(FixedWithNextNode.class); + } }