changeset 17332:6e590e01ecf9

Truffle: make preliminary inlining decisions with the best possible characteristics to avoid the exploration of unneccessary pathes in the inlining tree for context sensitive inlining.
author Christian Humer <christian.humer@gmail.com>
date Fri, 03 Oct 2014 16:22:48 +0200
parents 7b6e829e995a
children 329eee851ee1
files graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/ContextSensitiveInlining.java
diffstat 1 files changed, 34 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/ContextSensitiveInlining.java	Fri Oct 03 16:22:48 2014 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/ContextSensitiveInlining.java	Fri Oct 03 16:22:48 2014 +0200
@@ -36,41 +36,54 @@
     }
 
     public ContextSensitiveInlining(OptimizedCallTarget sourceTarget, TruffleInliningPolicy policy) {
-        this(decideInlining(OptimizedCallUtils.countNonTrivialNodes(sourceTarget, false), exploreCallSites(new ArrayList<>(Arrays.asList(sourceTarget)), policy), policy));
+        this(createDecisions(sourceTarget, policy));
     }
 
-    private static List<InliningDecision> exploreCallSites(List<OptimizedCallTarget> stack, TruffleInliningPolicy policy) {
+    private static List<InliningDecision> createDecisions(OptimizedCallTarget sourceTarget, TruffleInliningPolicy policy) {
+        int nodeCount = OptimizedCallUtils.countNonTrivialNodes(sourceTarget, false);
+        List<InliningDecision> exploredCallSites = exploreCallSites(new ArrayList<>(Arrays.asList(sourceTarget)), nodeCount, policy);
+        return decideInlining(exploredCallSites, policy, nodeCount);
+    }
+
+    private static List<InliningDecision> exploreCallSites(List<OptimizedCallTarget> stack, int callStackNodeCount, TruffleInliningPolicy policy) {
         List<InliningDecision> exploredCallSites = new ArrayList<>();
         OptimizedCallTarget parentTarget = stack.get(stack.size() - 1);
         for (OptimizedDirectCallNode callNode : parentTarget.getCallNodes()) {
             OptimizedCallTarget currentTarget = callNode.getCurrentCallTarget();
             stack.add(currentTarget); // push
-            exploredCallSites.add(exploreCallSite(stack, policy, callNode));
+            exploredCallSites.add(exploreCallSite(stack, callStackNodeCount, policy, callNode));
             stack.remove(stack.size() - 1); // pop
         }
         return exploredCallSites;
     }
 
-    private static InliningDecision exploreCallSite(List<OptimizedCallTarget> callStack, TruffleInliningPolicy policy, OptimizedDirectCallNode callNode) {
+    private static InliningDecision exploreCallSite(List<OptimizedCallTarget> callStack, int callStackNodeCount, TruffleInliningPolicy policy, OptimizedDirectCallNode callNode) {
         OptimizedCallTarget parentTarget = callStack.get(callStack.size() - 2);
         OptimizedCallTarget currentTarget = callStack.get(callStack.size() - 1);
 
         boolean recursive = isRecursiveStack(callStack);
         boolean maxDepth = callStack.size() >= 15;
 
-        List<InliningDecision> childCallSites;
+        List<InliningDecision> childCallSites = Collections.emptyList();
         double frequency = TruffleInliningHandler.calculateFrequency(parentTarget, callNode);
         int nodeCount = OptimizedCallUtils.countNonTrivialNodes(callNode.getCurrentCallTarget(), false);
-        int deepNodeCount;
-        if (recursive || maxDepth) {
-            deepNodeCount = nodeCount;
-            childCallSites = Collections.emptyList();
-        } else {
-            childCallSites = decideInlining(nodeCount, exploreCallSites(callStack, policy), policy);
-            deepNodeCount = nodeCount;
-            for (InliningDecision childCallSite : childCallSites) {
-                if (childCallSite.isInline()) {
-                    deepNodeCount += childCallSite.getProfile().getDeepNodeCount();
+
+        int deepNodeCount = nodeCount;
+        if (!recursive && !maxDepth) {
+            /*
+             * We make a preliminary optimistic inlining decision with best possible characteristics
+             * to avoid the exploration of unnecessary pathes in the inlining tree.
+             */
+            if (policy.isAllowed(new TruffleInliningProfile(callNode, nodeCount, nodeCount, frequency, recursive, null), callStackNodeCount)) {
+                List<InliningDecision> exploredCallSites = exploreCallSites(callStack, callStackNodeCount + nodeCount, policy);
+                childCallSites = decideInlining(exploredCallSites, policy, nodeCount);
+                for (InliningDecision childCallSite : childCallSites) {
+                    if (childCallSite.isInline()) {
+                        deepNodeCount += childCallSite.getProfile().getDeepNodeCount();
+                    } else {
+                        /* we don't need those anymore. */
+                        childCallSite.getCallSites().clear();
+                    }
                 }
             }
         }
@@ -90,7 +103,7 @@
         return false;
     }
 
-    private static List<InliningDecision> decideInlining(int nodeCount, List<InliningDecision> callSites, TruffleInliningPolicy policy) {
+    private static List<InliningDecision> decideInlining(List<InliningDecision> callSites, TruffleInliningPolicy policy, int nodeCount) {
         int deepNodeCount = nodeCount;
         int index = 0;
         for (InliningDecision callSite : callSites.stream().sorted().collect(Collectors.toList())) {
@@ -195,6 +208,11 @@
             }
         }
 
+        @Override
+        public String toString() {
+            return String.format("InliningDecision(callNode=%s, inline=%b)", profile.getCallNode(), inline);
+        }
+
     }
 
 }