changeset 14715:4ea4db3f23ba

Truffle: fixed call count profile; added leaf check for inlining; inline tracing now shows dispatched calls.
author Christian Humer <christian.humer@gmail.com>
date Fri, 21 Mar 2014 13:54:08 +0100
parents ab8a5b82fe73
children 03704aa6e71b
files graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CompilationProfile.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallNodeProfile.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java
diffstat 4 files changed, 61 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- 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;
--- 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
--- 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<OptimizedCallTarget> 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;
     }
--- 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<String, Object> 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 @@
             });
         }
     }
+
 }