diff graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java @ 19619:711f46f691cf

New bytecode interpreter partial evaluation test including an IFZERO bytecode. Make graph builder loop explosion support multiple loop back edges from one peeling iteration.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Fri, 27 Feb 2015 13:54:30 +0100
parents d28482893f28
children 0e90dbf0b9fd
line wrap: on
line diff
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Fri Feb 27 13:54:05 2015 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Fri Feb 27 13:54:30 2015 +0100
@@ -179,7 +179,7 @@
 
         private static class ExplodedLoopContext {
             private BciBlock header;
-            private int targetPeelIteration;
+            private int[] targetPeelIteration;
             private int peelIteration;
         }
 
@@ -342,12 +342,17 @@
                 ExplodedLoopContext context = new ExplodedLoopContext();
                 context.header = header;
                 context.peelIteration = this.getCurrentDimension();
-                context.targetPeelIteration = -1;
                 explodeLoopsContext.push(context);
                 if (Debug.isDumpEnabled() && DumpDuringGraphBuilding.getValue()) {
                     Debug.dump(currentGraph, "before loop explosion dimension " + context.peelIteration);
                 }
 
+                peelIteration(blocks, header, context);
+                explodeLoopsContext.pop();
+                return header.loopEnd + 1;
+            }
+
+            private void peelIteration(BciBlock[] blocks, BciBlock header, ExplodedLoopContext context) {
                 while (true) {
 
                     processBlock(this, header);
@@ -356,20 +361,24 @@
                         iterateBlock(blocks, block);
                     }
 
-                    if (context.targetPeelIteration != -1) {
+                    int[] targets = context.targetPeelIteration;
+                    if (targets != null) {
                         // We were reaching the backedge during explosion. Explode further.
-                        context.peelIteration = context.targetPeelIteration;
-                        context.targetPeelIteration = -1;
-                        if (Debug.isDumpEnabled() && DumpDuringGraphBuilding.getValue()) {
-                            Debug.dump(currentGraph, "next loop explosion iteration " + context.peelIteration);
+                        for (int i = 0; i < targets.length; ++i) {
+                            context.peelIteration = targets[i];
+                            context.targetPeelIteration = null;
+                            if (Debug.isDumpEnabled() && DumpDuringGraphBuilding.getValue()) {
+                                Debug.dump(currentGraph, "next loop explosion iteration " + context.peelIteration);
+                            }
+                            if (i < targets.length - 1) {
+                                peelIteration(blocks, header, context);
+                            }
                         }
                     } else {
                         // We did not reach the backedge. Exit.
                         break;
                     }
                 }
-                explodeLoopsContext.pop();
-                return header.loopEnd + 1;
             }
 
             /**
@@ -1457,23 +1466,27 @@
                     if (context.header == block) {
 
                         // We have a hit on our current explosion context loop begin.
-                        if (context.targetPeelIteration == -1) {
-                            // This is the first hit => allocate a new dimension and at the same
-                            // time mark the context loop begin as hit during the current
-                            // iteration.
-                            context.targetPeelIteration = nextPeelIteration++;
-                            if (nextPeelIteration > MaximumLoopExplosionCount.getValue()) {
-                                String message = "too many loop explosion interations - does the explosion not terminate for method " + method + "?";
-                                if (FailedLoopExplosionIsFatal.getValue()) {
-                                    throw new RuntimeException(message);
-                                } else {
-                                    throw bailout(message);
-                                }
+                        if (context.targetPeelIteration == null) {
+                            context.targetPeelIteration = new int[1];
+                        } else {
+                            context.targetPeelIteration = Arrays.copyOf(context.targetPeelIteration, context.targetPeelIteration.length + 1);
+                        }
+
+                        // This is the first hit => allocate a new dimension and at the same
+                        // time mark the context loop begin as hit during the current
+                        // iteration.
+                        context.targetPeelIteration[context.targetPeelIteration.length - 1] = nextPeelIteration++;
+                        if (nextPeelIteration > MaximumLoopExplosionCount.getValue()) {
+                            String message = "too many loop explosion interations - does the explosion not terminate for method " + method + "?";
+                            if (FailedLoopExplosionIsFatal.getValue()) {
+                                throw new RuntimeException(message);
+                            } else {
+                                throw bailout(message);
                             }
                         }
 
                         // Operate on the target dimension.
-                        return context.targetPeelIteration;
+                        return context.targetPeelIteration[context.targetPeelIteration.length - 1];
                     } else if (block.getId() > context.header.getId() && block.getId() <= context.header.loopEnd) {
                         // We hit the range of this context.
                         return context.peelIteration;