changeset 2792:2f3258e3800e

Merge.
author Thomas Wuerthinger <thomas@wuerthinger.net>
date Thu, 26 May 2011 11:55:16 +0200
parents 6d14aa4fbf90 (diff) 9253df721472 (current diff)
children d3fc4fe063bf
files graal/GraalGraph/src/com/oracle/graal/graph/Node.java
diffstat 15 files changed, 153 insertions(+), 104 deletions(-) [+]
line wrap: on
line diff
--- a/graal/GraalCompiler/src/com/oracle/max/graal/schedule/Schedule.java	Wed May 25 17:48:56 2011 +0200
+++ b/graal/GraalCompiler/src/com/oracle/max/graal/schedule/Schedule.java	Thu May 26 11:55:16 2011 +0200
@@ -27,6 +27,7 @@
 import com.oracle.graal.graph.*;
 import com.sun.c1x.debug.*;
 import com.sun.c1x.ir.*;
+import com.sun.c1x.lir.*;
 
 
 public class Schedule {
@@ -67,18 +68,20 @@
     private Block assignBlock(Node n, Block b) {
         assert nodeToBlock.get(n) == null;
         nodeToBlock.set(n, b);
-        b.getInstructions().add((Instruction) n);
+        if (n != n.graph().start()) {
+            b.getInstructions().add((Instruction) n);
+        }
         return b;
     }
 
     private boolean isCFG(Node n) {
-        return n != null && (n instanceof Instruction);
+        return n != null && ((n instanceof Instruction) || n == n.graph().start());
     }
 
     private void identifyBlocks() {
         // Identify blocks.
         final ArrayList<Node> blockBeginNodes = new ArrayList<Node>();
-        NodeIterator.iterate(EdgeType.SUCCESSORS, graph.start().successors().get(0), null, new NodeVisitor() {
+        NodeIterator.iterate(EdgeType.SUCCESSORS, graph.start(), null, new NodeVisitor() {
             @Override
             public boolean visit(Node n) {
                 if (!isCFG(n)) {
@@ -185,8 +188,11 @@
                TTY.print(pred + ";");
            }
            TTY.println();
-           TTY.print("first instr: " + b.getInstructions().get(0));
-           TTY.print("last instr: " + b.getInstructions().get(b.getInstructions().size() - 1));
+
+           if (b.getInstructions().size() > 0) {
+               TTY.print("first instr: " + b.getInstructions().get(0));
+               TTY.print("last instr: " + b.getInstructions().get(b.getInstructions().size() - 1));
+           }
         }
 
 /*
--- a/graal/GraalCompiler/src/com/sun/c1x/alloc/LinearScan.java	Wed May 25 17:48:56 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/alloc/LinearScan.java	Thu May 26 11:55:16 2011 +0200
@@ -27,6 +27,7 @@
 
 import java.util.*;
 
+import com.oracle.graal.graph.*;
 import com.sun.c1x.*;
 import com.sun.c1x.alloc.Interval.*;
 import com.sun.c1x.debug.*;
@@ -725,7 +726,7 @@
         // this is checked by these assertions to be sure about it.
         // the entry block may have incoming
         // values in registers, which is ok.
-        if (!operand.isVariable() /*&& block != ir.startBlock*/) {
+        if (!operand.isVariable() && block != ir.startBlock) {
             if (isProcessed(operand)) {
                 assert liveKill.get(operandNumber(operand)) : "using fixed register that is not defined in this block";
             }
@@ -812,12 +813,16 @@
                 reportFailure(numBlocks);
             }
 
+            TTY.println("preds=" + startBlock.blockPredecessors().size() + ", succs=" + startBlock.blockSuccessors().size());
+            TTY.println("startBlock-ID: " + startBlock.blockID());
+
             // bailout of if this occurs in product mode.
             throw new CiBailout("liveIn set of first block must be empty");
         }
     }
 
     private void reportFailure(int numBlocks) {
+        TTY.println(compilation.method.toString());
         TTY.println("Error: liveIn set of first block must be empty (when this fails, variables are used before they are defined)");
         TTY.print("affected registers:");
         TTY.println(ir.startBlock.liveIn.toString());
@@ -829,6 +834,17 @@
                 Value instr = operand.isVariable() ? gen.operands.instructionForResult(((CiVariable) operand)) : null;
                 TTY.println(" var %d (HIR instruction %s)", operandNum, instr == null ? " " : instr.toString());
 
+                if (instr instanceof Phi) {
+                    Phi phi = (Phi) instr;
+                    TTY.println("phi block begin: " + phi.block());
+                    TTY.println("pred count on blockbegin: " + phi.block().predecessors().size());
+                    TTY.println("phi values: " + phi.valueCount());
+                    TTY.println("phi block preds:");
+                    for (Node n : phi.block().predecessors()) {
+                        TTY.println(n.toString());
+                    }
+                }
+
                 for (int j = 0; j < numBlocks; j++) {
                     LIRBlock block = blockAt(j);
                     if (block.liveGen.get(operandNum)) {
--- a/graal/GraalCompiler/src/com/sun/c1x/gen/LIRGenerator.java	Wed May 25 17:48:56 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/gen/LIRGenerator.java	Thu May 26 11:55:16 2011 +0200
@@ -253,6 +253,10 @@
                 }
             }
         }
+        if (block.blockSuccessors().size() == 1 && (block.getInstructions().size() == 0  || !(block.getInstructions().get(block.getInstructions().size() - 1) instanceof BlockEnd))) {
+            moveToPhi();
+            block.lir().jump(block.blockSuccessors().get(0));
+        }
 
         if (C1XOptions.TraceLIRGeneratorLevel >= 1) {
             TTY.println("END Generating LIR for block B" + block.blockID());
@@ -587,7 +591,11 @@
     }
 
     protected LIRBlock getLIRBlock(Instruction b) {
-        return ir.valueToBlock.get(b);
+        LIRBlock result = ir.valueToBlock.get(b);
+        if (result == null) {
+            TTY.println("instruction without lir block: " + b);
+        }
+        return result;
     }
 
     @Override
@@ -1320,7 +1328,7 @@
 
                     PhiResolver resolver = new PhiResolver(this);
                     for (Phi phi : phis) {
-                        if (!phi.isDeadPhi() && phi.valueCount() > predIndex) {
+                        if (!phi.isDeadPhi()) {
                             Value curVal = phi.valueAt(predIndex);
                             if (curVal != null && curVal != phi) {
                                 if (curVal instanceof Phi) {
--- a/graal/GraalCompiler/src/com/sun/c1x/gen/PhiSimplifier.java	Wed May 25 17:48:56 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/gen/PhiSimplifier.java	Thu May 26 11:55:16 2011 +0200
@@ -44,6 +44,11 @@
             return x;
         }
         Phi phi = (Phi) x;
+
+        if (phi.valueCount() == 1) {
+            return (Value) phi.replace(phi.valueAt(0));
+        }
+
         if (phi.checkFlag(Value.Flag.PhiCannotSimplify)) {
             // already tried, cannot simplify this phi
             return phi;
--- a/graal/GraalCompiler/src/com/sun/c1x/graph/CriticalEdgeFinder.java	Wed May 25 17:48:56 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/graph/CriticalEdgeFinder.java	Thu May 26 11:55:16 2011 +0200
@@ -45,9 +45,9 @@
      * The graph edges represented as a map from source to target nodes.
      * Using a linked hash map makes compilation tracing more deterministic and thus eases debugging.
      */
-    private Map<LIRBlock, Set<LIRBlock>> edges = C1XOptions.DetailedAsserts ?
-                    new LinkedHashMap<LIRBlock, Set<LIRBlock>>() :
-                    new HashMap<LIRBlock, Set<LIRBlock>>();
+    private Map<LIRBlock, List<LIRBlock>> edges = C1XOptions.DetailedAsserts ?
+                    new LinkedHashMap<LIRBlock, List<LIRBlock>>() :
+                    new HashMap<LIRBlock, List<LIRBlock>>();
 
     public CriticalEdgeFinder(List<LIRBlock> lirBlocks, Graph graph) {
         this.lirBlocks = lirBlocks;
@@ -71,14 +71,14 @@
 
     private void recordCriticalEdge(LIRBlock block, LIRBlock succ) {
         if (!edges.containsKey(block)) {
-            edges.put(block, new HashSet<LIRBlock>());
+            edges.put(block, new ArrayList<LIRBlock>());
         }
 
         edges.get(block).add(succ);
     }
 
     public void splitCriticalEdges() {
-        for (Map.Entry<LIRBlock, Set<LIRBlock>> entry : edges.entrySet()) {
+        for (Map.Entry<LIRBlock, List<LIRBlock>> entry : edges.entrySet()) {
             LIRBlock from = entry.getKey();
             for (LIRBlock to : entry.getValue()) {
                 LIRBlock split = splitEdge(from, to);
@@ -104,17 +104,20 @@
         lirBlocks.add(newSucc);
 
         // This goto is not a safepoint.
-        Goto e = new Goto(target.getInstructions().get(0), graph);
+        Goto e = new Goto(null, graph);
+        Instruction sourceInstruction = source.getInstructions().get(source.getInstructions().size() - 1);
+        Instruction targetInstruction = target.getInstructions().get(0);
+        int sourceInstructionPredIndex = targetInstruction.predecessors().indexOf(sourceInstruction);
+        int replacedIndex = targetInstruction.predecessorsIndex().get(sourceInstructionPredIndex);
+        assert replacedIndex != -1 && sourceInstruction.successors().get(replacedIndex) != null;
+        e.successors().setAndClear(1, sourceInstruction, replacedIndex);
+        sourceInstruction.successors().set(replacedIndex, e);
         newSucc.getInstructions().add(e);
-
-        // link predecessor to new block
-        ((BlockEnd) source.getInstructions().get(source.getInstructions().size() - 1)).successors().replace(target.getInstructions().get(0), newSucc.getInstructions().get(0));
-
+        assert e.defaultSuccessor() != null;
         source.substituteSuccessor(target, newSucc);
         target.substitutePredecessor(source, newSucc);
         newSucc.blockPredecessors().add(source);
         newSucc.blockSuccessors().add(target);
-
         return newSucc;
     }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java	Wed May 25 17:48:56 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java	Thu May 26 11:55:16 2011 +0200
@@ -178,6 +178,7 @@
                 }
             }
             flags |= Flag.HasHandler.mask;
+
         }
 
         // 1. create the start block
@@ -220,20 +221,11 @@
         for (Node n : graph.getNodes()) {
             if (n instanceof Placeholder) {
                 Placeholder p = (Placeholder) n;
-
-                /*if (p == graph.start().successors().get(0)) {
-                    // nothing to do...
-                } else*/ if (p.blockPredecessors().size() == 0) {
-                    assert p.next() == null;
-                    p.delete();
-                } else {
-                    assert p.blockPredecessors().size() == 1;
-                    for (Node pred : new ArrayList<Node>(p.predecessors())) {
-                        pred.successors().replace(p, p.next());
-                    }
-                    p.successors().clearAll();
-                    p.delete();
-                }
+                assert p.blockPredecessors().size() == 1;
+                Node pred = p.blockPredecessors().get(0);
+                int predIndex = p.predecessorsIndex().get(0);
+                pred.successors().setAndClear(predIndex, p, 0);
+                p.delete();
             }
         }
 
@@ -290,8 +282,7 @@
     private void finishStartBlock(Block startBlock) {
         assert bci() == 0;
         Instruction target = createTargetAt(0, frameState);
-        Goto base = new Goto(target, graph);
-        appendWithBCI(base);
+        appendGoto(target);
     }
 
     public void mergeOrClone(Block target, FrameStateAccess newState) {
@@ -319,6 +310,8 @@
         } else {
             if (!C1XOptions.AssumeVerifiedBytecode && !existingState.isCompatibleWith(newState)) {
                 // stacks or locks do not match--bytecodes would not verify
+                TTY.println(existingState.toString());
+                TTY.println(newState.duplicate(0).toString());
                 throw new CiBailout("stack or locks do not match");
             }
             assert existingState.localsSize() == newState.localsSize();
@@ -326,9 +319,10 @@
 
             if (first instanceof Placeholder) {
                 BlockBegin merge = new BlockBegin(existingState.bci, target.blockID, target.isLoopHeader, graph);
-                for (Node n : new ArrayList<Node>(first.predecessors())) {
-                    n.successors().replace(first, merge);
-                }
+
+                Placeholder p = (Placeholder) first;
+                assert p.next() == null;
+                p.replace(merge);
                 target.firstInstruction = merge;
                 merge.setStateBefore(existingState);
             }
@@ -610,7 +604,7 @@
     }
 
     private void genGoto(int fromBCI, int toBCI) {
-        append(new Goto(createTargetAt(toBCI, frameState), graph));
+        appendGoto(createTargetAt(toBCI, frameState));
     }
 
     private void ifNode(Value x, Condition cond, Value y) {
@@ -1062,9 +1056,14 @@
     }
 
     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";
 
+        if (block.isExceptionEntry) {
+            assert stateAfter.stackSize() == 1;
+        }
+
         if (block.firstInstruction == null) {
             if (block.isLoopHeader) {
                 block.firstInstruction = new BlockBegin(block.startBci, block.blockID, block.isLoopHeader, graph);
@@ -1165,17 +1164,26 @@
                 deopt.setMessage("unresolved " + block.handler.catchType().name());
                 append(deopt);
                 Instruction nextDispatch = createTarget(block.next, frameState);
-                append(new Goto(nextDispatch, graph));
+                appendGoto(nextDispatch);
             }
         }
     }
 
+    private void appendGoto(Instruction target) {
+        //if (target instanceof BlockBegin && !((BlockBegin)target).isLoopHeader) {
+        //    System.out.println("NOTOMITTED");
+            //append(new Goto(target, graph));
+        //} else {
+        //    System.out.println("omitted");
+            lastInstr.appendNext(target);
+        //}
+    }
+
     private void iterateBytecodesForBlock(Block block) {
         assert frameState != null;
 
         stream.setBCI(block.startBci);
 
-        BlockEnd end = null;
         int endBCI = stream.endBCI();
         boolean blockStart = true;
 
@@ -1183,10 +1191,10 @@
         while (bci < endBCI) {
             Block nextBlock = blockFromBci[bci];
             if (nextBlock != null && nextBlock != block) {
+                assert !nextBlock.isExceptionEntry;
                 // we fell through to the next block, add a goto and break
                 Instruction next = createTarget(nextBlock, frameState);
-                end = new Goto(next, graph);
-                lastInstr = lastInstr.appendNext(end);
+                appendGoto(next);
                 break;
             }
             // read the opcode
@@ -1196,10 +1204,10 @@
             traceInstruction(bci, opcode, blockStart);
             processBytecode(bci, opcode);
 
-            if (lastInstr instanceof BlockEnd) {
-                end = (BlockEnd) lastInstr;
+            if (lastInstr instanceof BlockEnd || lastInstr.next() != null) {
                 break;
             }
+
             stream.next();
             bci = stream.currentBCI();
             if (lastInstr instanceof StateSplit) {
--- a/graal/GraalCompiler/src/com/sun/c1x/graph/IR.java	Wed May 25 17:48:56 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/graph/IR.java	Thu May 26 11:55:16 2011 +0200
@@ -122,9 +122,17 @@
                 valueToBlock.put(i, b);
             }
         }
-        startBlock = valueToBlock.get(getHIRStartBlock());
+        startBlock = lirBlocks.get(0);
         assert startBlock != null;
-        verifyAndPrint("After linear scan order");
+        assert startBlock.blockPredecessors().size() == 0;
+
+/*        if (startBlock.blockPredecessors().size() > 0) {
+            LIRBlock oldStartBlock = startBlock;
+            startBlock = new LIRBlock(orderedBlocks.size());
+            startBlock.blockSuccessors().add(oldStartBlock);
+
+            orderedBlocks.add(startBlock);
+        }*/
 
         ComputeLinearScanOrder clso = new ComputeLinearScanOrder(lirBlocks.size(), startBlock);
         orderedBlocks = clso.linearScanOrder();
@@ -135,7 +143,7 @@
             b.setLinearScanNumber(z++);
         }
 
-
+        verifyAndPrint("After linear scan order");
 
         if (C1XOptions.PrintTimers) {
             C1XTimers.HIR_OPTIMIZE.stop();
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/BlockBegin.java	Wed May 25 17:48:56 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/BlockBegin.java	Thu May 26 11:55:16 2011 +0200
@@ -174,12 +174,12 @@
         if (end() != null) {
             builder.append(" -> ");
             boolean hasSucc = false;
-            for (BlockBegin s : end().blockSuccessors()) {
+            for (Instruction s : end().blockSuccessors()) {
                 if (hasSucc) {
                     builder.append(", ");
                 }
                 builder.append("#");
-                builder.append(s.blockID);
+                builder.append(s.id());
                 hasSucc = true;
             }
         }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/BlockEnd.java	Wed May 25 17:48:56 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/BlockEnd.java	Thu May 26 11:55:16 2011 +0200
@@ -35,8 +35,7 @@
 
     private static final int INPUT_COUNT = 0;
 
-    private static final int SUCCESSOR_COUNT = 1;
-    private static final int SUCCESSOR_STATE_AFTER = 0;
+    private static final int SUCCESSOR_COUNT = 0;
     private final int blockSuccessorCount;
 
     @Override
@@ -143,18 +142,6 @@
     }
 
     /**
-     * This method reorders the predecessors of the i-th successor in such a way that this BlockEnd is at position backEdgeIndex.
-     */
-    public void reorderSuccessor(int i, int backEdgeIndex) {
-        assert i >= 0 && i < blockSuccessorCount;
-        Instruction successor = blockSuccessor(i);
-        if (successor != null) {
-            successors().set(super.successorCount() + SUCCESSOR_COUNT + i, Node.Null);
-            successors().set(super.successorCount() + SUCCESSOR_COUNT + i, successor, backEdgeIndex);
-        }
-    }
-
-    /**
      * Gets this block end's list of successors.
      * @return the successor list
      */
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/ComputeLinearScanOrder.java	Wed May 25 17:48:56 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/ComputeLinearScanOrder.java	Thu May 26 11:55:16 2011 +0200
@@ -461,9 +461,9 @@
 
         // the start block is always the first block in the linear scan order
         linearScanOrder = new ArrayList<LIRBlock>(numBlocks);
-        appendBlock(startBlock);
+//        appendBlock(startBlock);
 
-        LIRBlock stdEntry = startBlock.suxAt(0);
+        LIRBlock stdEntry = startBlock; //.suxAt(0);
 
         // start processing with standard entry block
         assert workList.isEmpty() : "list must be empty before processing";
--- a/graal/GraalCompiler/src/com/sun/c1x/lir/LIRBlock.java	Wed May 25 17:48:56 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/lir/LIRBlock.java	Thu May 26 11:55:16 2011 +0200
@@ -256,6 +256,7 @@
         for (int i = 0; i < successors.size(); ++i) {
             if (successors.get(i) == target) {
                 successors.set(i, newSucc);
+                break;
             }
         }
     }
@@ -264,6 +265,7 @@
         for (int i = 0; i < predecessors.size(); ++i) {
             if (predecessors.get(i) == source) {
                 predecessors.set(i, newSucc);
+                break;
             }
         }
     }
--- a/graal/GraalCompiler/src/com/sun/c1x/lir/LIRInstruction.java	Wed May 25 17:48:56 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/lir/LIRInstruction.java	Thu May 26 11:55:16 2011 +0200
@@ -482,7 +482,7 @@
     }
 
     public final LIRBlock exceptionEdge() {
-        return info.exceptionEdge;
+        return (info == null) ? null : info.exceptionEdge;
     }
 
     @Override
--- a/graal/GraalGraph/src/com/oracle/graal/graph/Node.java	Wed May 25 17:48:56 2011 +0200
+++ b/graal/GraalGraph/src/com/oracle/graal/graph/Node.java	Thu May 26 11:55:16 2011 +0200
@@ -39,6 +39,7 @@
     final NodeArray successors;
     final ArrayList<Node> usages;
     final ArrayList<Node> predecessors;
+    final ArrayList<Integer> predecessorsIndex;
 
     public Node(int inputCount, int successorCount, Graph graph) {
         assert graph != null;
@@ -48,12 +49,17 @@
         this.successors = new NodeArray(this, successorCount);
         this.predecessors = new ArrayList<Node>();
         this.usages = new ArrayList<Node>();
+        this.predecessorsIndex = new ArrayList<Integer>();
     }
 
     public List<Node> predecessors() {
         return Collections.unmodifiableList(predecessors);
     }
 
+    public List<Integer> predecessorsIndex() {
+        return Collections.unmodifiableList(predecessorsIndex);
+    }
+
     public List<Node> usages() {
         return Collections.unmodifiableList(usages);
     }
@@ -78,22 +84,28 @@
         return getClass().getSimpleName();
     }
 
-    public void replace(Node other) {
-        assert !isDeleted() && !other.isDeleted();
+    public Node replace(Node other) {
+        assert !isDeleted() && (other == null || !other.isDeleted());
         assert other == null || other.graph == graph;
         for (Node usage : usages) {
             usage.inputs.replaceFirstOccurrence(this, other);
         }
+        int z = 0;
         for (Node predecessor : predecessors) {
-            predecessor.successors.replaceFirstOccurrence(this, other);
+            int predIndex = predecessorsIndex.get(z);
+            predecessor.successors.nodes[predIndex] = other;
+            ++z;
         }
         if (other != null) {
             other.usages.addAll(usages);
             other.predecessors.addAll(predecessors);
+            other.predecessorsIndex.addAll(predecessorsIndex);
         }
         usages.clear();
         predecessors.clear();
+        predecessorsIndex.clear();
         delete();
+        return other;
     }
 
     public boolean isDeleted() {
@@ -103,6 +115,7 @@
     public void delete() {
         assert !isDeleted();
         assert usages.size() == 0 && predecessors.size() == 0;
+        assert predecessorsIndex.size() == 0;
         for (int i = 0; i < inputs.size(); ++i) {
             inputs.set(i, Null);
         }
--- a/graal/GraalGraph/src/com/oracle/graal/graph/NodeArray.java	Wed May 25 17:48:56 2011 +0200
+++ b/graal/GraalGraph/src/com/oracle/graal/graph/NodeArray.java	Thu May 26 11:55:16 2011 +0200
@@ -24,12 +24,13 @@
 
 import java.util.AbstractList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.Iterator;
 
 public class NodeArray extends AbstractList<Node> {
 
     private final Node node;
-    private final Node[] nodes;
+    final Node[] nodes;
 
     public NodeArray(Node node, int length) {
         this.node = node;
@@ -61,40 +62,17 @@
             } else {
                 assert self().successors == this;
                 if (old != null) {
-                    old.predecessors.remove(self());
+                    for (int i = 0; i < old.predecessors.size(); ++i) {
+                        Node cur = old.predecessors.get(i);
+                        if (cur == self() && old.predecessorsIndex.get(i) == index) {
+                            old.predecessors.remove(i);
+                            old.predecessorsIndex.remove(i);
+                        }
+                    }
                 }
                 if (node != null) {
                     node.predecessors.add(self());
-                }
-            }
-        }
-
-        return old;
-    }
-
-    /**
-     * Sets the specified input/successor to the given node, and inserts the back edge (usage/predecessor) at the given index.
-     */
-    public Node set(int index, Node node, int backIndex) {
-        assert node == Node.Null || node.graph == self().graph;
-        Node old = nodes[index];
-
-        if (old != node) {
-            nodes[index] = node;
-            if (self().inputs == this) {
-                if (old != null) {
-                    old.usages.remove(self());
-                }
-                if (node != null) {
-                    node.usages.add(backIndex, self());
-                }
-            } else {
-                assert self().successors == this;
-                if (old != null) {
-                    old.predecessors.remove(self());
-                }
-                if (node != null) {
-                    node.predecessors.add(backIndex, self());
+                    node.predecessorsIndex.add(index);
                 }
             }
         }
@@ -138,6 +116,22 @@
         return result;
     }
 
+    public void setAndClear(int index, Node clearedNode, int clearedIndex) {
+        assert self().successors == this;
+        Node value = clearedNode.successors.get(clearedIndex);
+        assert value != Node.Null;
+        clearedNode.successors.nodes[clearedIndex] = Node.Null;
+        set(index, Node.Null);
+        nodes[index] = value;
+
+        for (int i = 0; i < value.predecessors.size(); ++i) {
+            if (value.predecessors.get(i) == clearedNode && value.predecessorsIndex.get(i) == clearedIndex) {
+                value.predecessors.set(i, self());
+                value.predecessorsIndex.set(i, index);
+            }
+        }
+    }
+
     public int size() {
         return nodes.length;
     }
--- a/graal/GraalRuntime/src/com/oracle/graal/runtime/HotSpotOptions.java	Wed May 25 17:48:56 2011 +0200
+++ b/graal/GraalRuntime/src/com/oracle/graal/runtime/HotSpotOptions.java	Thu May 26 11:55:16 2011 +0200
@@ -31,7 +31,6 @@
 public class HotSpotOptions {
 
     public static void setDefaultOptions() {
-        C1XOptions.DetailedAsserts = false;
         C1XOptions.CommentedAssembly = false;
         C1XOptions.MethodEndBreakpointGuards = 2;
         C1XOptions.ResolveClassBeforeStaticInvoke = false;
@@ -78,7 +77,7 @@
             }
             if (value != null) {
                 f.set(null, value);
-                Logger.info("Set option " + fieldName + " to " + value);
+                //Logger.info("Set option " + fieldName + " to " + value);
             } else {
                 Logger.info("Wrong value \"" + valueString + "\" for option " + fieldName);
                 return false;