changeset 8542:30a141944bcb

tail recursion for SchedulePhase.addToEarliestSorting (fixes StackOverflowErrors)
author Lukas Stadler <lukas.stadler@jku.at>
date Wed, 27 Mar 2013 14:27:38 +0100
parents cc433555c5a3
children 354d729ae588
files graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java
diffstat 1 files changed, 33 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java	Tue Mar 26 18:32:58 2013 +0100
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java	Wed Mar 27 14:27:38 2013 +0100
@@ -100,7 +100,7 @@
         }
 
         @Override
-        protected HashSet<FloatingReadNode> afterSplit(FixedNode node, HashSet<FloatingReadNode> oldState) {
+        protected HashSet<FloatingReadNode> cloneState(HashSet<FloatingReadNode> oldState) {
             return new HashSet<>(oldState);
         }
 
@@ -580,41 +580,45 @@
     }
 
     private void addToEarliestSorting(Block b, ScheduledNode i, List<ScheduledNode> sortedInstructions, NodeBitMap visited) {
-        if (i == null || visited.isMarked(i) || cfg.getNodeToBlock().get(i) != b || i instanceof PhiNode || i instanceof LocalNode) {
-            return;
-        }
+        ScheduledNode instruction = i;
+        while (true) {
+            if (instruction == null || visited.isMarked(instruction) || cfg.getNodeToBlock().get(instruction) != b || instruction instanceof PhiNode || instruction instanceof LocalNode) {
+                return;
+            }
 
-        visited.mark(i);
-        for (Node usage : i.usages()) {
-            if (usage instanceof VirtualState) {
-                // only fixed nodes can have VirtualState -> no need to schedule them
-            } else {
-                if (i instanceof LoopExitNode && usage instanceof ProxyNode) {
-                    // value proxies should be scheduled before the loopexit, not after
+            visited.mark(instruction);
+            for (Node usage : instruction.usages()) {
+                if (usage instanceof VirtualState) {
+                    // only fixed nodes can have VirtualState -> no need to schedule them
                 } else {
-                    addToEarliestSorting(b, (ScheduledNode) usage, sortedInstructions, visited);
-                }
-            }
-        }
-
-        if (i instanceof BeginNode) {
-            ArrayList<ProxyNode> proxies = (i instanceof LoopExitNode) ? new ArrayList<ProxyNode>() : null;
-            for (ScheduledNode inBlock : blockToNodesMap.get(b)) {
-                if (!visited.isMarked(inBlock)) {
-                    if (inBlock instanceof ProxyNode) {
-                        proxies.add((ProxyNode) inBlock);
+                    if (instruction instanceof LoopExitNode && usage instanceof ProxyNode) {
+                        // value proxies should be scheduled before the loopexit, not after
                     } else {
-                        addToEarliestSorting(b, inBlock, sortedInstructions, visited);
+                        addToEarliestSorting(b, (ScheduledNode) usage, sortedInstructions, visited);
                     }
                 }
             }
-            sortedInstructions.add(i);
-            if (proxies != null) {
-                sortedInstructions.addAll(proxies);
+
+            if (instruction instanceof BeginNode) {
+                ArrayList<ProxyNode> proxies = (instruction instanceof LoopExitNode) ? new ArrayList<ProxyNode>() : null;
+                for (ScheduledNode inBlock : blockToNodesMap.get(b)) {
+                    if (!visited.isMarked(inBlock)) {
+                        if (inBlock instanceof ProxyNode) {
+                            proxies.add((ProxyNode) inBlock);
+                        } else {
+                            addToEarliestSorting(b, inBlock, sortedInstructions, visited);
+                        }
+                    }
+                }
+                sortedInstructions.add(instruction);
+                if (proxies != null) {
+                    sortedInstructions.addAll(proxies);
+                }
+                break;
+            } else {
+                sortedInstructions.add(instruction);
+                instruction = (ScheduledNode) instruction.predecessor();
             }
-        } else {
-            sortedInstructions.add(i);
-            addToEarliestSorting(b, (ScheduledNode) i.predecessor(), sortedInstructions, visited);
         }
     }
 }