# HG changeset patch # User Christian Humer # Date 1395406448 -3600 # Node ID 4ea4db3f23bac353ace38c38ec70dcc4c4c16427 # Parent ab8a5b82fe7335e95905a0ed5922b020db143af7 Truffle: fixed call count profile; added leaf check for inlining; inline tracing now shows dispatched calls. diff -r ab8a5b82fe73 -r 4ea4db3f23ba graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CompilationProfile.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CompilationProfile.java Thu Mar 20 20:40:11 2014 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CompilationProfile.java Fri Mar 21 13:54:08 2014 +0100 @@ -137,6 +137,13 @@ callAndLoopCount++; } + void reportInlinedCall() { + callCount++; + callAndLoopCount++; + compilationCallThreshold++; + compilationCallAndLoopThreshold++; + } + void reportInterpreterCalls(int calls) { this.callCount += calls; this.callAndLoopCount += calls; diff -r ab8a5b82fe73 -r 4ea4db3f23ba graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallNode.java Thu Mar 20 20:40:11 2014 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallNode.java Fri Mar 21 13:54:08 2014 +0100 @@ -78,7 +78,7 @@ throw new IllegalStateException("CallNode must be adopted before it is split."); } - return replace(new InlinedOptimizedCallNode(getCallTarget(), getSplitCallTarget(), getCurrentCallTarget().getRootNode(), callCount)); + return replace(new InlinedOptimizedCallNode(getCallTarget(), getSplitCallTarget(), callCount)); } public static OptimizedCallNode create(OptimizedCallTarget target) { @@ -211,12 +211,10 @@ private static final class InlinedOptimizedCallNode extends OptimizedCallNode { - private final RootNode inlinedRoot; private final OptimizedCallTarget splittedTarget; - public InlinedOptimizedCallNode(OptimizedCallTarget target, OptimizedCallTarget splittedTarget, RootNode inlinedRoot, int callCount) { + public InlinedOptimizedCallNode(OptimizedCallTarget target, OptimizedCallTarget splittedTarget, int callCount) { super(target); - this.inlinedRoot = inlinedRoot; this.splittedTarget = splittedTarget; this.callCount = callCount; } @@ -226,7 +224,7 @@ if (CompilerDirectives.inInterpreter()) { callCount++; } - return inlinedRoot.execute(Truffle.getRuntime().createVirtualFrame(caller, arguments, inlinedRoot.getFrameDescriptor())); + return getCurrentCallTarget().callInlined(caller, arguments); } @Override diff -r ab8a5b82fe73 -r 4ea4db3f23ba graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallNodeProfile.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallNodeProfile.java Thu Mar 20 20:40:11 2014 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallNodeProfile.java Fri Mar 21 13:54:08 2014 +0100 @@ -45,6 +45,7 @@ private final int targetShallowNodeCount; private final double averageFrequency; private final double score; + private final boolean leaf; private String reason; public OptimizedCallNodeProfile(OptimizedCallTarget target, OptimizedCallNode callNode) { @@ -56,6 +57,22 @@ this.compilationRoots = findCompilationRoots(callNode); this.averageFrequency = calculateFrequency(); this.score = calculateScore(); + this.leaf = calculateLeaf(); + + } + + private boolean calculateLeaf() { + return NodeUtil.countNodes(callNode.getCurrentRootNode(), new NodeCountFilter() { + public boolean isCounted(Node node) { + if (node instanceof CallNode) { + CallNode childCall = (CallNode) node; + if (!childCall.isInlined()) { + return true; + } + } + return false; + } + }, true) <= 0; } private double calculateFrequency() { @@ -71,7 +88,7 @@ } public double calculateScore() { - return averageFrequency / targetDeepNodeCount; + return averageFrequency / Math.max(1, targetDeepNodeCount); } public boolean isInliningAllowed() { @@ -188,17 +205,13 @@ for (OptimizedCallNode c : callStack) { int childCallCount = c.getCallCount(); frequency *= childCallCount / (double) parentCallCount; - if (c.isInlined() || c.isSplit()) { - parentCallCount = childCallCount; - } else { - parentCallCount = c.getCurrentCallTarget().getCompilationProfile().getCallCount(); - } + parentCallCount = c.getCurrentCallTarget().getCompilationProfile().getCallCount(); } return frequency; } double calculateSimpleFrequency() { - return callNode.getCallCount() / (double) callTarget.getCompilationProfile().getCallCount(); + return callNode.getCallCount() / (double) ((OptimizedCallTarget) callNode.getRootNode().getCallTarget()).getCompilationProfile().getCallCount(); } static List findCompilationRoots(Node call) { @@ -218,7 +231,11 @@ public int compareTo(TruffleInliningProfile o) { if (o instanceof OptimizedCallNodeProfile) { - return Double.compare(((OptimizedCallNodeProfile) o).getScore(), getScore()); + int cmp = Boolean.compare(((OptimizedCallNodeProfile) o).leaf, leaf); + if (cmp == 0) { + return Double.compare(((OptimizedCallNodeProfile) o).getScore(), getScore()); + } + return cmp; } return 0; } @@ -231,7 +248,7 @@ properties.put("inlinedTotalCount", calculateInlinedTotalNodeCount(getCallNode())); properties.put("score", score); properties.put("frequency", averageFrequency); - properties.put("callCount", callNode.getCallCount()); + properties.put("leaf", leaf); properties.put("reason", reason); return properties; } diff -r ab8a5b82fe73 -r 4ea4db3f23ba graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java Thu Mar 20 20:40:11 2014 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java Fri Mar 21 13:54:08 2014 +0100 @@ -102,6 +102,13 @@ return callHelper(caller, args); } + public Object callInlined(PackedFrame caller, Arguments arguments) { + if (CompilerDirectives.inInterpreter()) { + compilationProfile.reportInlinedCall(); + } + return executeHelper(caller, arguments); + } + private Object callHelper(PackedFrame caller, Arguments args) { if (installedCode != null && installedCode.isValid()) { reinstallCallMethodShortcut(); @@ -196,8 +203,8 @@ while (callSite != null) { if (callSite.isInliningAllowed()) { OptimizedCallNode callNode = callSite.getCallNode(); + RootNode inlinedRoot = callNode.inlineImpl().getCurrentRootNode(); logInlined(this, callSite); - RootNode inlinedRoot = callNode.inlineImpl().getCurrentRootNode(); assert inlinedRoot != null; queueCallSitesForInlining(this, inlinedRoot, visitedCallNodes, queue); } else { @@ -334,7 +341,7 @@ } } - private static void logInlined(@SuppressWarnings("unused") final OptimizedCallTarget target, TruffleInliningProfile callSite) { + private static void logInlined(final OptimizedCallTarget target, TruffleInliningProfile callSite) { if (TraceTruffleInliningDetails.getValue() || TraceTruffleInlining.getValue()) { log(2, "inline success", callSite.getCallNode().getCurrentCallTarget().toString(), callSite.getDebugProperties()); @@ -348,13 +355,23 @@ OptimizedCallNode callNode = ((OptimizedCallNode) node); RootNode inlinedRoot = callNode.getCurrentRootNode(); - if (inlinedRoot != null && callNode.isInlined()) { + if (inlinedRoot != null) { Map properties = new LinkedHashMap<>(); addASTSizeProperty(callNode.getCurrentRootNode(), properties); - log(2 + (depth * 2), "inline success", callNode.getCurrentCallTarget().toString(), properties); - depth++; - inlinedRoot.accept(this); - depth--; + properties.putAll(callNode.createInliningProfile(target).getDebugProperties()); + String message; + if (callNode.isInlined()) { + message = "inline success"; + } else { + message = "inline dispatch"; + } + log(2 + (depth * 2), message, callNode.getCurrentCallTarget().toString(), properties); + + if (callNode.isInlined()) { + depth++; + inlinedRoot.accept(this); + depth--; + } } } return true; @@ -566,4 +583,5 @@ }); } } + }