changeset 13988:83b20e343f73

Truffle: added visited set to avoid duplicate inlinings when operating on truffle trees violating the tree property.
author Christian Humer <christian.humer@gmail.com>
date Thu, 20 Feb 2014 13:44:06 +0100
parents fc47ce139d49
children aaba5b41c953
files graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java
diffstat 1 files changed, 9 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java	Thu Feb 20 13:43:15 2014 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java	Thu Feb 20 13:44:06 2014 +0100
@@ -168,8 +168,12 @@
             return;
         }
         PriorityQueue<TruffleInliningProfile> queue = new PriorityQueue<>();
-        queueCallSitesForInlining(getRootNode(), queue);
 
+        // Used to avoid running in cycles or inline nodes in Truffle trees
+        // which do not suffice the tree property twice.
+        Set<CallNode> visitedCallNodes = new HashSet<>();
+
+        queueCallSitesForInlining(getRootNode(), visitedCallNodes, queue);
         TruffleInliningProfile callSite = queue.poll();
         while (callSite != null) {
             if (callSite.isInliningAllowed()) {
@@ -177,7 +181,7 @@
                 logInlined(callSite);
                 RootNode inlinedRoot = callNode.inlineImpl().getInlinedRoot();
                 assert inlinedRoot != null;
-                queueCallSitesForInlining(inlinedRoot, queue);
+                queueCallSitesForInlining(inlinedRoot, visitedCallNodes, queue);
             } else {
                 logInliningFailed(callSite);
             }
@@ -185,13 +189,14 @@
         }
     }
 
-    private static void queueCallSitesForInlining(RootNode rootNode, final PriorityQueue<TruffleInliningProfile> queue) {
+    private static void queueCallSitesForInlining(RootNode rootNode, final Set<CallNode> visitedCallSites, final PriorityQueue<TruffleInliningProfile> queue) {
         rootNode.accept(new NodeVisitor() {
             public boolean visit(Node node) {
                 if (node instanceof OptimizedCallNode) {
                     OptimizedCallNode call = ((OptimizedCallNode) node);
-                    if (call.isInlinable() && !call.isInlined()) {
+                    if (call.isInlinable() && !call.isInlined() && !visitedCallSites.contains(call)) {
                         queue.add(call.createInliningProfile());
+                        visitedCallSites.add(call);
                     } else if (call.getInlinedRoot() != null) {
                         call.getInlinedRoot().accept(this);
                     }