# HG changeset patch # User Christian Humer # Date 1412346168 -7200 # Node ID 6e590e01ecf957dd9dae707edf8fe3e3ef7148d3 # Parent 7b6e829e995ad2576badb3454ee58d8ba8e45ec3 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. diff -r 7b6e829e995a -r 6e590e01ecf9 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/ContextSensitiveInlining.java --- 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 exploreCallSites(List stack, TruffleInliningPolicy policy) { + private static List createDecisions(OptimizedCallTarget sourceTarget, TruffleInliningPolicy policy) { + int nodeCount = OptimizedCallUtils.countNonTrivialNodes(sourceTarget, false); + List exploredCallSites = exploreCallSites(new ArrayList<>(Arrays.asList(sourceTarget)), nodeCount, policy); + return decideInlining(exploredCallSites, policy, nodeCount); + } + + private static List exploreCallSites(List stack, int callStackNodeCount, TruffleInliningPolicy policy) { List 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 callStack, TruffleInliningPolicy policy, OptimizedDirectCallNode callNode) { + private static InliningDecision exploreCallSite(List 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 childCallSites; + List 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 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 decideInlining(int nodeCount, List callSites, TruffleInliningPolicy policy) { + private static List decideInlining(List 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); + } + } }