changeset 10614:f84ea5453961

Fixes for Truffle cache.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Sun, 07 Jul 2013 17:20:13 +0200
parents 7220a8568e8c
children cb2d97f002d4 8060a20be76b
files graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java
diffstat 1 files changed, 24 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java	Sat Jul 06 12:20:23 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java	Sun Jul 07 17:20:13 2013 +0200
@@ -33,6 +33,7 @@
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.internal.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.Node;
 import com.oracle.graal.java.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.java.*;
@@ -44,6 +45,7 @@
 import com.oracle.graal.phases.tiers.*;
 import com.oracle.graal.truffle.phases.*;
 import com.oracle.graal.virtual.phases.ea.*;
+import com.oracle.truffle.api.nodes.*;
 
 /**
  * Implementation of a cache for Truffle graphs for improving partial evaluation time.
@@ -122,25 +124,20 @@
 
         Integer maxNodes = TruffleCompilerOptions.TruffleOperationCacheMaxNodes.getValue();
 
+        contractGraph(newGraph, eliminate, convertDeoptimizeToGuardPhase, canonicalizerPhase);
+
         while (newGraph.getNodeCount() <= maxNodes) {
 
             int mark = newGraph.getMark();
 
             expandGraph(newGraph, maxNodes);
 
-            // Canonicalize / constant propagate.
-            canonicalizerPhase.apply(newGraph);
-
-            // Convert deopt to guards.
-            convertDeoptimizeToGuardPhase.apply(newGraph);
-
-            // Conditional elimination.
-            eliminate.apply(newGraph);
-
             if (newGraph.getNewNodes(mark).count() == 0) {
                 // No progress => exit iterative optimization.
                 break;
             }
+
+            contractGraph(newGraph, eliminate, convertDeoptimizeToGuardPhase, canonicalizerPhase);
         }
 
         HighTierContext context = new HighTierContext(metaAccessProvider, assumptions, replacements);
@@ -152,6 +149,18 @@
         }
     }
 
+    private static void contractGraph(StructuredGraph newGraph, ConditionalEliminationPhase eliminate, ConvertDeoptimizeToGuardPhase convertDeoptimizeToGuardPhase,
+                    CanonicalizerPhase.Instance canonicalizerPhase) {
+        // Canonicalize / constant propagate.
+        canonicalizerPhase.apply(newGraph);
+
+        // Convert deopt to guards.
+        convertDeoptimizeToGuardPhase.apply(newGraph);
+
+        // Conditional elimination.
+        eliminate.apply(newGraph);
+    }
+
     private void expandGraph(StructuredGraph newGraph, int maxNodes) {
         NodeBitMap visitedNodes = newGraph.createNodeBitMap(true);
         Queue<AbstractBeginNode> workQueue = new LinkedList<>();
@@ -208,6 +217,11 @@
             final MethodCallTargetNode methodCallTargetNode = (MethodCallTargetNode) invoke.callTarget();
             if ((methodCallTargetNode.invokeKind() == InvokeKind.Special || methodCallTargetNode.invokeKind() == InvokeKind.Static) &&
                             !Modifier.isNative(methodCallTargetNode.targetMethod().getModifiers())) {
+                if (methodCallTargetNode.targetMethod().getAnnotation(ExplodeLoop.class) != null) {
+                    // Do not inline explode loop methods, they need canonicalization and forced
+                    // unrolling.
+                    return invoke.asNode();
+                }
                 StructuredGraph inlinedGraph = Debug.scope("ExpandInvoke", methodCallTargetNode.targetMethod(), new Callable<StructuredGraph>() {
 
                     public StructuredGraph call() {
@@ -223,7 +237,7 @@
                 return fixedNode;
             }
         }
-        return invoke.next();
+        return invoke.asNode();
     }
 
     private StructuredGraph parseGraph(ResolvedJavaMethod method) {