# HG changeset patch # User Christian Haeubl # Date 1359981816 -3600 # Node ID afa802ff433cabab8b8f6c052eced8560b7cc5a5 # Parent ed51e7237e94217a459b4b2a7abdebc2ae916222 better computation of inlining relevance fix for removing interpreter api diff -r ed51e7237e94 -r afa802ff433c graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ComputeProbabilityPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ComputeProbabilityPhase.java Mon Feb 04 10:53:24 2013 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ComputeProbabilityPhase.java Mon Feb 04 13:43:36 2013 +0100 @@ -275,6 +275,7 @@ } private class PropagateLoopFrequency extends PostOrderNodeIterator { + public PropagateLoopFrequency(FixedNode start) { super(start, new LoopCount(1d)); } @@ -287,6 +288,7 @@ } private static class ComputeInliningRelevanceIterator extends ScopedPostOrderNodeIterator { + private final HashMap scopes; private double currentProbability; private double parentRelevance; @@ -307,13 +309,13 @@ if (scope.start instanceof LoopBeginNode) { assert scope.parent != null; double parentProbability = 0; - for (EndNode end: ((LoopBeginNode) scope.start).forwardEnds()) { + for (EndNode end : ((LoopBeginNode) scope.start).forwardEnds()) { parentProbability += end.probability(); } return parentProbability / scope.parent.minPathProbability; } else { - assert scope.parent == null; - return 1.0; + assert scope.parent == null; + return 1.0; } } @@ -354,7 +356,7 @@ private static HashMap computeLowestPathProbabilities(Scope[] scopes) { HashMap result = new HashMap<>(); - for (Scope scope: scopes) { + for (Scope scope : scopes) { double lowestPathProbability = computeLowestPathProbability(scope); scope.minPathProbability = Math.max(EPSILON, lowestPathProbability); result.put(scope.start, scope); @@ -365,66 +367,86 @@ private static double computeLowestPathProbability(Scope scope) { FixedNode scopeStart = scope.start; - Node current = scopeStart; + ArrayList pathBeginNodes = new ArrayList<>(); + pathBeginNodes.add(scopeStart); double minPathProbability = scopeStart.probability(); boolean isLoopScope = scopeStart instanceof LoopBeginNode; - while (current != null) { - if (isLoopScope && current instanceof LoopExitNode && ((LoopBeginNode) scopeStart).loopExits().contains((LoopExitNode) current)) { - return minPathProbability; - } else if (current instanceof LoopBeginNode && current != scopeStart) { - current = getMaxProbabilityLoopExit((LoopBeginNode) current); - if (((FixedNode) current).probability() < minPathProbability) { - minPathProbability = ((FixedNode) current).probability(); + do { + Node current = pathBeginNodes.remove(pathBeginNodes.size() - 1); + do { + if (isLoopScope && current instanceof LoopExitNode && ((LoopBeginNode) scopeStart).loopExits().contains((LoopExitNode) current)) { + return minPathProbability; + } else if (current instanceof LoopBeginNode && current != scopeStart) { + current = getMaxProbabilityLoopExit((LoopBeginNode) current, pathBeginNodes); + minPathProbability = getMinPathProbability((FixedNode) current, minPathProbability); + } else if (current instanceof ControlSplitNode) { + current = getMaxProbabilitySux((ControlSplitNode) current, pathBeginNodes); + minPathProbability = getMinPathProbability((FixedNode) current, minPathProbability); + } else { + assert current.successors().count() <= 1; + current = current.successors().first(); } - } else if (current instanceof ControlSplitNode) { - current = getMaxProbabilitySux((ControlSplitNode) current); - if (((FixedNode) current).probability() < minPathProbability) { - minPathProbability = ((FixedNode) current).probability(); - } - } else { - assert current.successors().count() <= 1; - current = current.successors().first(); - } - } + } while (current != null); + } while (!pathBeginNodes.isEmpty()); return minPathProbability; } - private static Node getMaxProbabilitySux(ControlSplitNode controlSplit) { + private static double getMinPathProbability(FixedNode current, double minPathProbability) { + if (current.probability() < minPathProbability) { + return current.probability(); + } + return minPathProbability; + } + + private static Node getMaxProbabilitySux(ControlSplitNode controlSplit, ArrayList pathBeginNodes) { Node maxSux = null; double maxProbability = 0.0; + int pathBeginCount = pathBeginNodes.size(); - // TODO (chaeubl): process recursively if we have multiple successors with same probability for (Node sux : controlSplit.successors()) { double probability = controlSplit.probability((BeginNode) sux); if (probability > maxProbability) { maxProbability = probability; maxSux = sux; + truncate(pathBeginNodes, pathBeginCount); + } else if (probability == maxProbability) { + pathBeginNodes.add((FixedNode) sux); } } return maxSux; } - private static Node getMaxProbabilityLoopExit(LoopBeginNode loopBegin) { + private static Node getMaxProbabilityLoopExit(LoopBeginNode loopBegin, ArrayList pathBeginNodes) { Node maxSux = null; double maxProbability = 0.0; + int pathBeginCount = pathBeginNodes.size(); - // TODO (chaeubl): process recursively if we have multiple successors with same probability - for (LoopExitNode sux: loopBegin.loopExits()) { + for (LoopExitNode sux : loopBegin.loopExits()) { double probability = sux.probability(); if (probability > maxProbability) { maxProbability = probability; maxSux = sux; + truncate(pathBeginNodes, pathBeginCount); + } else if (probability == maxProbability) { + pathBeginNodes.add(sux); } } return maxSux; } + + public static void truncate(ArrayList pathBeginNodes, int pathBeginCount) { + for (int i = pathBeginNodes.size() - pathBeginCount; i > 0; i--) { + pathBeginNodes.remove(pathBeginNodes.size() - 1); + } + } } private static class Scope { + public final FixedNode start; public final Scope parent; public double minPathProbability; diff -r ed51e7237e94 -r afa802ff433c 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 Mon Feb 04 10:53:24 2013 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java Mon Feb 04 13:43:36 2013 +0100 @@ -191,10 +191,12 @@ // 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"); @@ -205,8 +207,10 @@ 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); @@ -217,8 +221,10 @@ } } - // 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); @@ -281,8 +287,10 @@ } 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; diff -r ed51e7237e94 -r afa802ff433c src/share/vm/runtime/arguments.cpp --- a/src/share/vm/runtime/arguments.cpp Mon Feb 04 10:53:24 2013 +0100 +++ b/src/share/vm/runtime/arguments.cpp Mon Feb 04 13:43:36 2013 +0100 @@ -2270,7 +2270,6 @@ "com.oracle.graal.api.runtime", "com.oracle.graal.api.meta", "com.oracle.graal.api.code", - "com.oracle.graal.api.interpreter", "com.oracle.graal.hotspot", "com.oracle.graal.asm", "com.oracle.graal.alloc",