changeset 5697:62f1b4b8de5c

Merge
author Gilles Duboscq <duboscq@ssw.jku.at>
date Tue, 26 Jun 2012 16:54:58 +0200
parents f592c22421e7 (diff) 7ee5a3634003 (current diff)
children 764db9ada24f e9f7d16194a8 05c5f68e23d5
files
diffstat 18 files changed, 207 insertions(+), 33 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Tue Jun 26 10:56:03 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Tue Jun 26 16:54:58 2012 +0200
@@ -149,6 +149,7 @@
             }
         }
 
+        new ConvertUnreachedToGuardPhase(optimisticOpts).apply(graph);
 
         plan.runPhases(PhasePosition.HIGH_LEVEL, graph);
 
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalOptions.java	Tue Jun 26 10:56:03 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalOptions.java	Tue Jun 26 16:54:58 2012 +0200
@@ -100,7 +100,11 @@
     public static float   MinimumUsageProbability            = 0.95f;
 
     //loop transform settings
-    public static float   MinimumPeelProbability             = 0.25f;
+    public static float   MinimumPeelProbability             = 0.35f;
+    public static boolean ReassociateInvariants              = true;
+    public static boolean FullUnroll                         = true;
+    public static int     FullUnrollMaxNodes                 = 150; // TODO (gd) tune
+    public static boolean LoopUnswitch                       = ____;
 
     // debugging settings
     public static int     MethodEndBreakpointGuards          = 0;
@@ -208,11 +212,6 @@
     public static boolean OptLoopTransform                   = true;
     public static boolean OptSafepointElimination            = true;
 
-    // Loops
-    public static boolean ReassociateInvariants              = true;
-    public static boolean FullUnroll                         = true;
-    public static int FullUnrollMaxNodes                     = 250; // TODO (gd) tune
-
     /**
      * Insert a counter in the method prologue to track the most frequently called methods that were compiled by Graal.
      */
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopPolicies.java	Tue Jun 26 10:56:03 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopPolicies.java	Tue Jun 26 16:54:58 2012 +0200
@@ -47,4 +47,9 @@
         int size = Math.max(1, loop.size() - 1 - loop.loopBegin().phis().count());
         return size * exactTrips <= maxNodes;
     }
+
+    public static boolean shouldTryUnswitch(@SuppressWarnings("unused") LoopEx loop) {
+        // TODO (gd) maybe there should be a may number of unswitching per loop
+        return true;
+    }
 }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopTransformations.java	Tue Jun 26 10:56:03 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopTransformations.java	Tue Jun 26 16:54:58 2012 +0200
@@ -69,7 +69,7 @@
         BeginNode tempBegin = graph.add(new BeginNode());
         loop.entryPoint().replaceAtPredecessor(tempBegin);
         double takenProbability = ifNode.probability(ifNode.blockSuccessorIndex(ifNode.trueSuccessor()));
-        IfNode newIf = graph.add(new IfNode(ifNode.compare(), duplicateLoop.loop().entryPoint(), loop.entryPoint(), takenProbability));
+        IfNode newIf = graph.add(new IfNode(ifNode.compare(), duplicateLoop.loop().entryPoint(), loop.entryPoint(), takenProbability, ifNode.leafGraphId()));
         tempBegin.setNext(newIf);
         ifNode.setCompare(graph.unique(ConstantNode.forBoolean(false, graph)));
         IfNode duplicateIf = duplicateLoop.getDuplicatedNode(ifNode);
@@ -97,4 +97,13 @@
             inside.duplicate().appendInside(loop);
         }
     }
+
+    public static IfNode findUnswitchableIf(LoopEx loop) {
+        for (IfNode ifNode : loop.whole().nodes().filter(IfNode.class)) {
+            if (loop.isOutsideLoop(ifNode.compare())) {
+                return ifNode;
+            }
+        }
+        return null;
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/ConvertUnreachedToGuardPhase.java	Tue Jun 26 16:54:58 2012 +0200
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.compiler.phases;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.util.*;
+
+
+public class ConvertUnreachedToGuardPhase extends Phase {
+    private OptimisticOptimizations opt;
+
+    public ConvertUnreachedToGuardPhase(OptimisticOptimizations opt) {
+        this.opt = opt;
+    }
+
+    @Override
+    protected void run(StructuredGraph graph) {
+        if (!opt.removeNeverExecutedCode()) {
+            return;
+        }
+        for (Node node : graph.getNodes()) {
+            if (node instanceof IfNode) {
+                IfNode ifNode = (IfNode) node;
+                BeginNode insertGuard = null;
+                BeginNode delete = null;
+                boolean inverted = false;
+                if (ifNode.probability(IfNode.TRUE_EDGE) == 0) {
+                    insertGuard = ifNode.falseSuccessor();
+                    delete = ifNode.trueSuccessor();
+                    inverted = true;
+                } else if (ifNode.probability(IfNode.FALSE_EDGE) == 0) {
+                    insertGuard = ifNode.trueSuccessor();
+                    delete = ifNode.falseSuccessor();
+                }
+                if (insertGuard != null) {
+                    GuardNode guard = graph.unique(new GuardNode(ifNode.compare(), BeginNode.prevBegin(ifNode), DeoptimizationReason.UnreachedCode, DeoptimizationAction.InvalidateReprofile, inverted, ifNode.leafGraphId()));
+                    graph.addBeforeFixed(ifNode, graph.add(new ValueAnchorNode(guard)));
+                    GraphUtil.killCFG(delete);
+                    graph.removeSplit(ifNode, inverted ? IfNode.FALSE_EDGE : IfNode.TRUE_EDGE);
+                }
+            }
+        }
+
+    }
+
+}
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LoopFullUnrollPhase.java	Tue Jun 26 10:56:03 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LoopFullUnrollPhase.java	Tue Jun 26 16:54:58 2012 +0200
@@ -44,7 +44,7 @@
                 peeled = false;
                 final LoopsData dataCounted = new LoopsData(graph);
                 dataCounted.detectedCountedLoops();
-                for (final LoopEx loop : dataCounted.countedLoops()) {
+                for (LoopEx loop : dataCounted.countedLoops()) {
                     if (LoopPolicies.shouldFullUnroll(loop)) {
                         Debug.log("FullUnroll %s", loop);
                         LoopTransformations.fullUnroll(loop, runtime);
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LoopTransformLowPhase.java	Tue Jun 26 10:56:03 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LoopTransformLowPhase.java	Tue Jun 26 16:54:58 2012 +0200
@@ -25,9 +25,11 @@
 import com.oracle.graal.compiler.*;
 import com.oracle.graal.compiler.loop.*;
 import com.oracle.graal.debug.*;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 
 public class LoopTransformLowPhase extends Phase {
+    private static final DebugMetric UNSWITCHED = Debug.metric("Unswitched");
 
     @Override
     protected void run(StructuredGraph graph) {
@@ -43,6 +45,28 @@
                     }
                 });
             }
+            if (GraalOptions.LoopUnswitch) {
+                NodeBitMap unswitchedDebug = graph.createNodeBitMap();
+                boolean unswitched;
+                do {
+                    unswitched = false;
+                    final LoopsData dataUnswitch = new LoopsData(graph);
+                    for (LoopEx loop : dataUnswitch.loops()) {
+                        if (LoopPolicies.shouldTryUnswitch(loop)) {
+                            IfNode ifNode = LoopTransformations.findUnswitchableIf(loop);
+                            if (ifNode != null && !unswitchedDebug.isMarked(ifNode)) {
+                                unswitchedDebug.mark(ifNode);
+                                Debug.log("Unswitching %s at %s [%f - %f]", loop, ifNode, ifNode.probability(0), ifNode.probability(1));
+                                //LoopTransformations.unswitch(loop, ifNode);
+                                UNSWITCHED.increment();
+                                //Debug.dump(graph, "After unswitch %s", loop);
+                                unswitched = true;
+                                break;
+                            }
+                        }
+                    }
+                } while(unswitched);
+            }
         }
     }
 }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/util/InliningUtil.java	Tue Jun 26 10:56:03 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/util/InliningUtil.java	Tue Jun 26 16:54:58 2012 +0200
@@ -780,12 +780,15 @@
             } else {
                 nodes.add(node);
                 if (node instanceof ReturnNode) {
+                    assert returnNode == null;
                     returnNode = (ReturnNode) node;
                 } else if (node instanceof UnwindNode) {
+                    assert unwindNode == null;
                     unwindNode = (UnwindNode) node;
                 }
             }
         }
+        replacements.put(entryPointNode, BeginNode.prevBegin(invoke.node())); // ensure proper anchoring of things that where anchored to the StartNode
 
         assert invoke.node().successors().first() != null : invoke;
         assert invoke.node().predecessor() != null;
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java	Tue Jun 26 10:56:03 2012 +0200
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java	Tue Jun 26 16:54:58 2012 +0200
@@ -952,7 +952,7 @@
                             replacementsMap.put(input, replacement);
                             assert replacement == null || node.getNodeClass().inputTypes[pos.index] == null || node.getNodeClass().inputTypes[pos.index].isAssignableFrom(replacement.getClass());
                             target = replacement;
-                        } else { // patch to the outer world
+                        } else if (input.graph() == graph) { // patch to the outer world
                             target = input;
                         }
                     }
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Tue Jun 26 10:56:03 2012 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Tue Jun 26 16:54:58 2012 +0200
@@ -541,7 +541,7 @@
         BeginNode trueSuccessor = createBlockTarget(probability, trueBlock, frameState);
         BeginNode falseSuccessor = createBlockTarget(1 - probability, falseBlock, frameState);
 
-        IfNode ifNode = negate ? new IfNode(condition, falseSuccessor, trueSuccessor, 1 - probability) : new IfNode(condition, trueSuccessor, falseSuccessor, probability);
+        IfNode ifNode = negate ? new IfNode(condition, falseSuccessor, trueSuccessor, 1 - probability, graphId) : new IfNode(condition, trueSuccessor, falseSuccessor, probability, graphId);
         append(currentGraph.add(ifNode));
     }
 
@@ -653,7 +653,7 @@
         } else {
             BlockPlaceholderNode successor = currentGraph.add(new BlockPlaceholderNode());
             DeoptimizeNode deopt = currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved, graphId));
-            IfNode ifNode = currentGraph.add(new IfNode(currentGraph.unique(new IsNullNode(object)), successor, deopt, 0));
+            IfNode ifNode = currentGraph.add(new IfNode(currentGraph.unique(new IsNullNode(object)), successor, deopt, 0, graphId));
             append(ifNode);
             lastInstr = successor;
             frameState.ipush(appendConstant(Constant.INT_0));
@@ -757,7 +757,7 @@
     private void emitNullCheck(ValueNode receiver) {
         BlockPlaceholderNode trueSucc = currentGraph.add(new BlockPlaceholderNode());
         BlockPlaceholderNode falseSucc = currentGraph.add(new BlockPlaceholderNode());
-        IfNode ifNode = currentGraph.add(new IfNode(currentGraph.unique(new IsNullNode(receiver)), trueSucc, falseSucc, 1));
+        IfNode ifNode = currentGraph.add(new IfNode(currentGraph.unique(new IsNullNode(receiver)), trueSucc, falseSucc, 1, graphId));
 
         append(ifNode);
         lastInstr = falseSucc;
@@ -776,7 +776,7 @@
     private void emitBoundsCheck(ValueNode index, ValueNode length) {
         BlockPlaceholderNode trueSucc = currentGraph.add(new BlockPlaceholderNode());
         BlockPlaceholderNode falseSucc = currentGraph.add(new BlockPlaceholderNode());
-        IfNode ifNode = currentGraph.add(new IfNode(currentGraph.unique(new IntegerBelowThanNode(index, length)), trueSucc, falseSucc, 1));
+        IfNode ifNode = currentGraph.add(new IfNode(currentGraph.unique(new IntegerBelowThanNode(index, length)), trueSucc, falseSucc, 1, graphId));
 
         append(ifNode);
         lastInstr = trueSucc;
@@ -1405,7 +1405,7 @@
             frameState.push(Kind.Object, exception);
             FixedNode nextDispatch = createTarget(nextBlock, frameState);
             checkCast.setNext(catchSuccessor);
-            IfNode ifNode = currentGraph.add(new IfNode(currentGraph.unique(new InstanceOfNode(typeInstruction, (ResolvedJavaType) catchType, exception)), checkCast, nextDispatch, 0.5));
+            IfNode ifNode = currentGraph.add(new IfNode(currentGraph.unique(new InstanceOfNode(typeInstruction, (ResolvedJavaType) catchType, exception)), checkCast, nextDispatch, 0.5, graphId));
             append(ifNode);
         }
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/bytecode/BC_ldiv3.java	Tue Jun 26 16:54:58 2012 +0200
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_ldiv3 {
+    public static long PLUS7 = 7;
+    public static long PLUS3 = 3;
+    public static long MIN7 = -7;
+    public static long MIN3 = -3;
+
+    public static long test(long a, long b) {
+        return a / b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(3, test(PLUS7, 2));
+        Assert.assertEquals(1, test(PLUS3, 2));
+        Assert.assertEquals(-3, test(MIN7, 2));
+        Assert.assertEquals(-1, test(MIN3, 2));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-1, test(PLUS7, -4));
+        Assert.assertEquals(0, test(PLUS3, -4));
+        Assert.assertEquals(1, test(MIN7, -4));
+        Assert.assertEquals(0, test(MIN3, -4));
+    }
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ControlSplitNode.java	Tue Jun 26 10:56:03 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ControlSplitNode.java	Tue Jun 26 16:54:58 2012 +0200
@@ -31,8 +31,8 @@
  * The {@code ControlSplitNode} is a base class for all instructions that split the control flow (ie. have more than one successor).
  */
 public abstract class ControlSplitNode extends FixedNode {
-
     @Successor private final NodeSuccessorList<BeginNode> blockSuccessors;
+    protected double[] branchProbability;
 
     public BeginNode blockSuccessor(int index) {
         return blockSuccessors.get(index);
@@ -46,8 +46,6 @@
         return blockSuccessors.size();
     }
 
-    protected final double[] branchProbability;
-
     public ControlSplitNode(Stamp stamp, BeginNode[] blockSuccessors, double[] branchProbability) {
         super(stamp);
         assert branchProbability.length == blockSuccessors.length;
@@ -113,4 +111,11 @@
         }
         return idx;
     }
+
+    @Override
+    public ControlSplitNode clone(Graph into) {
+        ControlSplitNode csn = (ControlSplitNode) super.clone(into);
+        csn.branchProbability = Arrays.copyOf(branchProbability, branchProbability.length);
+        return csn;
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java	Tue Jun 26 10:56:03 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java	Tue Jun 26 16:54:58 2012 +0200
@@ -36,6 +36,7 @@
 public final class IfNode extends ControlSplitNode implements Simplifiable, LIRLowerable, SplitTypeFeedbackProvider, Negatable {
     public static final int TRUE_EDGE = 0;
     public static final int FALSE_EDGE = 1;
+    private final long leafGraphId;
 
     @Input private BooleanNode compare;
 
@@ -48,9 +49,14 @@
         compare = x;
     }
 
-    public IfNode(BooleanNode condition, FixedNode trueSuccessor, FixedNode falseSuccessor, double takenProbability) {
+    public IfNode(BooleanNode condition, FixedNode trueSuccessor, FixedNode falseSuccessor, double takenProbability, long leafGraphId) {
         super(StampFactory.forVoid(), new BeginNode[] {BeginNode.begin(trueSuccessor), BeginNode.begin(falseSuccessor)}, new double[] {takenProbability, 1 - takenProbability});
         this.compare = condition;
+        this.leafGraphId = leafGraphId;
+    }
+
+    public long leafGraphId() {
+        return leafGraphId;
     }
 
     /**
@@ -125,6 +131,7 @@
                     if (!phis.hasNext()) {
                         // empty if construct with no phis: remove it
                         removeEmptyIf(tool);
+                        return;
                     } else {
                         PhiNode singlePhi = phis.next();
                         if (!phis.hasNext()) {
@@ -142,6 +149,7 @@
                                 MaterializeNode materialize = MaterializeNode.create(compare(), graph(), trueValue, falseValue);
                                 ((StructuredGraph) graph()).replaceFloating(singlePhi, materialize);
                                 removeEmptyIf(tool);
+                                return;
                             }
                         }
                     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java	Tue Jun 26 10:56:03 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java	Tue Jun 26 16:54:58 2012 +0200
@@ -350,8 +350,8 @@
         // evacuateGuards
         merge.prepareDelete((FixedNode) singleEnd.predecessor());
         merge.safeDelete();
-        if (stateAfter != null && stateAfter.usages().isEmpty()) {
-            stateAfter.safeDelete();
+        if (stateAfter != null && stateAfter.isAlive() && stateAfter.usages().isEmpty()) {
+            GraphUtil.killWithUnusedFloatingInputs(stateAfter);
         }
         if (sux == null) {
             singleEnd.replaceAtPredecessor(null);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LookupSwitchNode.java	Tue Jun 26 10:56:03 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LookupSwitchNode.java	Tue Jun 26 16:54:58 2012 +0200
@@ -73,24 +73,21 @@
             ConstantNode constant = (ConstantNode) value();
             int value = constant.value.asInt();
 
-            BeginNode remainingSux = (BeginNode) defaultSuccessor();
             int remainingSuxIndex = blockSuccessorCount() - 1;
             for (int i = 0; i < keys.length; i++) {
                 if (value == keys[i]) {
-                    remainingSux = blockSuccessor(i);
                     remainingSuxIndex = i;
                     break;
                 }
             }
 
             for (int i = 0; i < blockSuccessorCount(); i++) {
-                BeginNode sux = blockSuccessor(i);
-                if (sux != remainingSux) {
-                    tool.deleteBranch(sux);
+                if (i != remainingSuxIndex) {
+                    tool.deleteBranch(blockSuccessor(i));
                 }
             }
 
-            tool.addToWorkList(remainingSux);
+            tool.addToWorkList(blockSuccessor(remainingSuxIndex));
             ((StructuredGraph) graph()).removeSplit(this, remainingSuxIndex);
         }
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/TableSwitchNode.java	Tue Jun 26 10:56:03 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/TableSwitchNode.java	Tue Jun 26 16:54:58 2012 +0200
@@ -81,15 +81,13 @@
                 remainingSuxIndex = blockSuccessorCount() - 1;
             }
 
-            BeginNode remainingSux = blockSuccessor(remainingSuxIndex);
             for (int i = 0; i < blockSuccessorCount(); i++) {
-                BeginNode sux = blockSuccessor(i);
-                if (sux != remainingSux) {
-                    tool.deleteBranch(sux);
+                if (i != remainingSuxIndex) {
+                    tool.deleteBranch(blockSuccessor(i));
                 }
             }
 
-            tool.addToWorkList(remainingSux);
+            tool.addToWorkList(blockSuccessor(remainingSuxIndex));
             ((StructuredGraph) graph()).removeSplit(this, remainingSuxIndex);
         }
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java	Tue Jun 26 10:56:03 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java	Tue Jun 26 16:54:58 2012 +0200
@@ -47,7 +47,7 @@
         } else {
             // Normal control flow node.
             /* We do not take a successor snapshot because this iterator supports concurrent modifications
-             * as long as they do not change the size of the successor list. Not tasking a snapshot allows
+             * as long as they do not change the size of the successor list. Not taking a snapshot allows
              * us to see modifications to other branches that may happen while processing one branch.
              */
             for (Node successor : node.successors()) {
--- a/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/cfg/SimpleCFGTest.java	Tue Jun 26 10:56:03 2012 +0200
+++ b/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/cfg/SimpleCFGTest.java	Tue Jun 26 16:54:58 2012 +0200
@@ -43,7 +43,7 @@
         BeginNode falseBegin = graph.add(new BeginNode());
         falseBegin.setNext(falseEnd);
 
-        IfNode ifNode = graph.add(new IfNode(null, trueBegin, falseBegin, 0.5));
+        IfNode ifNode = graph.add(new IfNode(null, trueBegin, falseBegin, 0.5, graph.graphId()));
         graph.start().setNext(ifNode);
 
         MergeNode merge = graph.add(new MergeNode());