diff graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java @ 2799:e1dad0edd57a

first part of loop reworking
author Lukas Stadler <lukas.stadler@jku.at>
date Fri, 27 May 2011 17:48:28 +0200
parents d6bf240963fb
children c3f64b66fc78
line wrap: on
line diff
--- a/graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java	Fri May 27 14:20:30 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java	Fri May 27 17:48:28 2011 +0200
@@ -287,6 +287,9 @@
 
     public void mergeOrClone(Block target, FrameStateAccess newState) {
         Instruction first = target.firstInstruction;
+        if (target.isLoopHeader && isVisited(target)) {
+            first = ((LoopBegin) first).loopEnd();
+        }
         assert first instanceof StateSplit;
 
         int bci = target.startBci;
@@ -294,13 +297,13 @@
         FrameState existingState = ((StateSplit) first).stateBefore();
 
         if (existingState == null) {
-            assert first instanceof Merge ^ !target.isLoopHeader : "isLoopHeader: " + target.isLoopHeader;
+//            assert first instanceof Merge ^ !target.isLoopHeader : "isLoopHeader: " + target.isLoopHeader;
 
             // copy state because it is modified
             FrameState duplicate = newState.duplicate(bci);
 
             // if the block is a loop header, insert all necessary phis
-            if (target.isLoopHeader) {
+            if (first instanceof LoopBegin && target.isLoopHeader) {
                 assert first instanceof Merge;
                 insertLoopPhis((Merge) first, duplicate);
                 ((Merge) first).setStateBefore(duplicate);
@@ -318,16 +321,18 @@
             assert existingState.stackSize() == newState.stackSize();
 
             if (first instanceof Placeholder) {
-                Merge merge = new Merge(existingState.bci, target.isLoopHeader, graph);
+                assert !target.isLoopHeader;
+                Merge merge = new Merge(graph);
 
                 Placeholder p = (Placeholder) first;
                 assert p.next() == null;
                 p.replace(merge);
                 target.firstInstruction = merge;
                 merge.setStateBefore(existingState);
+                first = merge;
             }
 
-            existingState.merge((Merge) target.firstInstruction, newState);
+            existingState.merge((Merge) first, newState);
         }
 
         for (int j = 0; j < frameState.localsSize() + frameState.stackSize(); ++j) {
@@ -1056,7 +1061,6 @@
     }
 
     private Instruction createTarget(Block block, FrameStateAccess stateAfter) {
-
         assert block != null && stateAfter != null;
         assert block.isLoopHeader || block.firstInstruction == null || block.firstInstruction.next() == null : "non-loop block must be iterated after all its predecessors";
 
@@ -1066,14 +1070,24 @@
 
         if (block.firstInstruction == null) {
             if (block.isLoopHeader) {
-                block.firstInstruction = new Merge(block.startBci, block.isLoopHeader, graph);
+//                block.firstInstruction = new Merge(block.startBci, graph);
+
+                LoopBegin loopBegin = new LoopBegin(graph);
+                LoopEnd loopEnd = new LoopEnd(graph);
+                loopEnd.setLoopBegin(loopBegin);
+                block.firstInstruction = loopBegin;
             } else {
                 block.firstInstruction = new Placeholder(graph);
             }
         }
         mergeOrClone(block, stateAfter);
         addToWorkList(block);
-        return block.firstInstruction;
+
+        if (block.firstInstruction instanceof LoopBegin && isVisited(block)) {
+            return ((LoopBegin) block.firstInstruction).loopEnd();
+        } else {
+            return block.firstInstruction;
+        }
     }
 
     private Value synchronizedObject(FrameStateAccess state, RiMethod target) {
@@ -1135,6 +1149,28 @@
                 }
             }
         }
+        for (Block b : blocksVisited) {
+            if (b.isLoopHeader) {
+                LoopBegin begin = (LoopBegin) b.firstInstruction;
+                LoopEnd end = begin.loopEnd();
+
+//              This can happen with degenerated loops like this one:
+//                for (;;) {
+//                    try {
+//                        break;
+//                    } catch (UnresolvedException iioe) {
+//                    }
+//                }
+                if (end.stateBefore() != null) {
+                    begin.stateBefore().merge(begin, end.stateBefore());
+                } else {
+                    end.delete();
+                    Merge merge = new Merge(graph);
+                    merge.successors().setAndClear(merge.nextIndex(), begin, begin.nextIndex());
+                    begin.replace(merge);
+                }
+            }
+        }
     }
 
     private void createExceptionDispatch(ExceptionBlock block) {