changeset 3481:d95db56f8deb

more work on new node structure, executes scimark, fop, avrora, luindex, lusearch, pmd, h2 and xalan
author Lukas Stadler <lukas.stadler@jku.at>
date Wed, 03 Aug 2011 11:51:47 +0200
parents 2423a432fa6b
children a6c1f49a7319
files graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AbstractMemoryCheckpointNode.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AbstractVectorNode.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AccessArray.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AccessField.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AccessIndexed.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AccessMonitor.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AccessNode.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AccessVectorNode.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Arithmetic.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Binary.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/BooleanNode.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/CastNode.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/CheckCast.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Compare.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Conditional.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Constant.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Convert.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/CreateVectorNode.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/EndNode.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/GuardNode.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/InstanceOf.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerAddVectorNode.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Invoke.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IsNonNull.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IsType.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LoadField.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LoadIndexed.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Local.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LocationNode.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Logic.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LoopBegin.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LoopCounter.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MaterializeNode.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Merge.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MonitorEnter.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MonitorExit.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Negate.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NegateBooleanNode.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NormalizeCompare.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Phi.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ReadNode.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ReadVectorNode.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Shift.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/StoreField.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/StoreIndexed.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/TypeCheck.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/VirtualObject.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/VirtualObjectField.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/WriteMemoryCheckpointNode.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/WriteNode.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/WriteVectorNode.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/DuplicationPhase.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoopPhase.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/MemoryPhase.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/Phase.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/Block.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/LoopUtil.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/Util.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/value/FrameState.java graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/opt/OptimizerImpl.java graal/com.oracle.max.graal.graphviz/src/com/oracle/max/graal/graphviz/GraphvizPrinter.java graal/com.oracle.max.graal.graphviz/test/com/oracle/graal/graph/vis/GraphvizTest.java graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotRuntime.java graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/nodes/CurrentThread.java graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/nodes/FPConversionNode.java
diffstat 68 files changed, 555 insertions(+), 927 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java	Wed Aug 03 11:51:47 2011 +0200
@@ -296,7 +296,7 @@
             }
         }
         if (block.blockSuccessors().size() >= 1 && !block.endsWithJump()) {
-            NodeSuccessorsIterable<Node> successors = block.lastInstruction().successors();
+            NodeSuccessorsIterable successors = block.lastInstruction().successors();
             assert successors.explicitCount() >= 1 : "should have at least one successor : " + block.lastInstruction();
             block.lir().jump(getLIRBlock((FixedNode) successors.first()));
         }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AbstractMemoryCheckpointNode.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AbstractMemoryCheckpointNode.java	Wed Aug 03 11:51:47 2011 +0200
@@ -30,15 +30,18 @@
 
 public abstract class AbstractMemoryCheckpointNode extends StateSplit {
 
+    @NodeInput
+    private final NodeInputList<Node> mergedNodes = new NodeInputList<Node>(this);
+
     private static final int SUCCESSOR_COUNT = 0;
     private static final int INPUT_COUNT = 0;
 
     public AbstractMemoryCheckpointNode(Graph graph) {
-        this(CiKind.Illegal, 0, 0, graph);
+        this(CiKind.Illegal, graph);
     }
 
-    public AbstractMemoryCheckpointNode(CiKind result, int inputCount, int successorCount, Graph graph) {
-        super(result, inputCount + INPUT_COUNT, successorCount + SUCCESSOR_COUNT, graph);
+    public AbstractMemoryCheckpointNode(CiKind result, Graph graph) {
+        super(result, graph);
     }
 
     @Override
@@ -48,7 +51,7 @@
         return debugProperties;
     }
 
-    public List<Node> mergedNodes() {
-        return variableInputs();
+    public NodeInputList<Node> mergedNodes() {
+        return mergedNodes;
     }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AbstractVectorNode.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AbstractVectorNode.java	Wed Aug 03 11:51:47 2011 +0200
@@ -30,30 +30,20 @@
 
 public abstract class AbstractVectorNode extends StateSplit {
 
-    private static final int INPUT_COUNT = 1;
-    private static final int INPUT_VECTOR = 0;
-    private static final int SUCCESSOR_COUNT = 0;
+    @NodeInput
+    private AbstractVectorNode vector;
 
-    @Override
-    protected int inputCount() {
-        return super.inputCount() + INPUT_COUNT;
+    public AbstractVectorNode vector() {
+        return vector;
     }
 
-    @Override
-    protected int successorCount() {
-        return super.successorCount() + SUCCESSOR_COUNT;
+    public void setVector(AbstractVectorNode x) {
+        updateUsages(vector, x);
+        vector = x;
     }
 
-    public void setVector(AbstractVectorNode length) {
-        inputs().set(super.inputCount() + INPUT_VECTOR, length);
-    }
-
-    public AbstractVectorNode vector() {
-        return (AbstractVectorNode) inputs().get(super.inputCount() + INPUT_VECTOR);
-    }
-
-    public AbstractVectorNode(CiKind kind, int inputCount, int successorCount, AbstractVectorNode vector, Graph graph) {
-        super(kind, inputCount + INPUT_COUNT, successorCount + SUCCESSOR_COUNT, graph);
+    public AbstractVectorNode(CiKind kind, AbstractVectorNode vector, Graph graph) {
+        super(kind, graph);
         setVector(vector);
     }
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AccessArray.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AccessArray.java	Wed Aug 03 11:51:47 2011 +0200
@@ -30,42 +30,26 @@
  */
 public abstract class AccessArray extends StateSplit {
 
-    private static final int INPUT_COUNT = 1;
-    private static final int INPUT_ARRAY = 0;
+    @NodeInput
+    private Value array;
 
-    private static final int SUCCESSOR_COUNT = 0;
-
-    @Override
-    protected int inputCount() {
-        return super.inputCount() + INPUT_COUNT;
+    public Value array() {
+        return array;
     }
 
-    @Override
-    protected int successorCount() {
-        return super.successorCount() + SUCCESSOR_COUNT;
-    }
-
-    /**
-     * The instruction that produces the array object.
-     */
-     public Value array() {
-        return (Value) inputs().get(super.inputCount() + INPUT_ARRAY);
-    }
-
-    public Value setArray(Value n) {
-        return (Value) inputs().set(super.inputCount() + INPUT_ARRAY, n);
+    public void setArray(Value x) {
+        updateUsages(array, x);
+        array = x;
     }
 
     /**
      * Creates a new AccessArray instruction.
      * @param kind the type of the result of this instruction
      * @param array the instruction that produces the array object value
-     * @param inputCount
-     * @param successorCount
      * @param graph
      */
-    public AccessArray(CiKind kind, Value array, int inputCount, int successorCount, Graph graph) {
-        super(kind, inputCount + INPUT_COUNT, successorCount + SUCCESSOR_COUNT, graph);
+    public AccessArray(CiKind kind, Value array, Graph graph) {
+        super(kind, graph);
         setArray(array);
     }
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AccessField.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AccessField.java	Wed Aug 03 11:51:47 2011 +0200
@@ -34,30 +34,16 @@
  */
 public abstract class AccessField extends StateSplit {
 
-    private static final int INPUT_COUNT = 1;
-    private static final int INPUT_OBJECT = 0;
+    @NodeInput
+    private Value object;
 
-    private static final int SUCCESSOR_COUNT = 0;
-
-    @Override
-    protected int inputCount() {
-        return super.inputCount() + INPUT_COUNT;
+    public Value object() {
+        return object;
     }
 
-    @Override
-    protected int successorCount() {
-        return super.successorCount() + SUCCESSOR_COUNT;
-    }
-
-    /**
-     * The instruction that produces the receiver object of this field access (for instance field accesses).
-     */
-     public Value object() {
-        return (Value) inputs().get(super.inputCount() + INPUT_OBJECT);
-    }
-
-    public Value setObject(Value n) {
-        return (Value) inputs().set(super.inputCount() + INPUT_OBJECT, n);
+    public void setObject(Value x) {
+        updateUsages(object, x);
+        object = x;
     }
 
     protected final RiField field;
@@ -67,12 +53,10 @@
      * @param kind the result kind of the access
      * @param object the instruction producing the receiver object
      * @param field the compiler interface representation of the field
-     * @param inputCount
-     * @param successorCount
      * @param graph
      */
-    public AccessField(CiKind kind, Value object, RiField field, int inputCount, int successorCount, Graph graph) {
-        super(kind, inputCount + INPUT_COUNT, successorCount + SUCCESSOR_COUNT, graph);
+    public AccessField(CiKind kind, Value object, RiField field, Graph graph) {
+        super(kind, graph);
         this.field = field;
         setObject(object);
         assert field.isResolved();
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AccessIndexed.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AccessIndexed.java	Wed Aug 03 11:51:47 2011 +0200
@@ -31,42 +31,28 @@
  */
 public abstract class AccessIndexed extends AccessArray {
 
-    private static final int INPUT_COUNT = 2;
-    private static final int INPUT_INDEX = 0;
-    private static final int INPUT_LENGTH = 1;
-
-    private static final int SUCCESSOR_COUNT = 0;
+    @NodeInput
+    private Value index;
 
-    @Override
-    protected int inputCount() {
-        return super.inputCount() + INPUT_COUNT;
-    }
+    @NodeInput
+    private Value length;
 
-    @Override
-    protected int successorCount() {
-        return super.successorCount() + SUCCESSOR_COUNT;
+    public Value index() {
+        return index;
     }
 
-    /**
-     * The instruction producing the index into the array.
-     */
-     public Value index() {
-        return (Value) inputs().get(super.inputCount() + INPUT_INDEX);
+    public void setIndex(Value x) {
+        updateUsages(index, x);
+        index = x;
     }
 
-    public Value setIndex(Value n) {
-        return (Value) inputs().set(super.inputCount() + INPUT_INDEX, n);
+    public Value length() {
+        return length;
     }
 
-    /**
-     * The instruction that produces the length of the array.
-     */
-    public Value length() {
-        return (Value) inputs().get(super.inputCount() + INPUT_LENGTH);
-    }
-
-    public Value setLength(Value n) {
-        return (Value) inputs().set(super.inputCount() + INPUT_LENGTH, n);
+    public void setLength(Value x) {
+        updateUsages(length, x);
+        length = x;
     }
 
     private final CiKind elementType;
@@ -78,12 +64,10 @@
      * @param index the instruction producing the index
      * @param length the instruction producing the length (used in bounds check elimination?)
      * @param elementKind the type of the elements of the array
-     * @param inputCount
-     * @param successorCount
      * @param graph
      */
-    AccessIndexed(CiKind kind, Value array, Value index, Value length, CiKind elementKind, int inputCount, int successorCount, Graph graph) {
-        super(kind, array, inputCount + INPUT_COUNT, successorCount + SUCCESSOR_COUNT, graph);
+    AccessIndexed(CiKind kind, Value array, Value index, Value length, CiKind elementKind, Graph graph) {
+        super(kind, array, graph);
         setIndex(index);
         setLength(length);
         this.elementType = elementKind;
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AccessMonitor.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AccessMonitor.java	Wed Aug 03 11:51:47 2011 +0200
@@ -30,42 +30,28 @@
  */
 public abstract class AccessMonitor extends AbstractMemoryCheckpointNode {
 
-    private static final int INPUT_COUNT = 2;
-    private static final int INPUT_OBJECT = 0;
-    private static final int INPUT_LOCK_ADDRESS = 1;
-
-    private static final int SUCCESSOR_COUNT = 0;
+    @NodeInput
+    private Value object;
 
-    @Override
-    protected int inputCount() {
-        return super.inputCount() + INPUT_COUNT;
-    }
+    @NodeInput
+    private Value lockAddress;
 
-    @Override
-    protected int successorCount() {
-        return super.successorCount() + SUCCESSOR_COUNT;
+    public Value object() {
+        return object;
     }
 
-    /**
-     * The instruction producing the object locked or unlocked by this instruction.
-     */
-     public Value object() {
-        return (Value) inputs().get(super.inputCount() + INPUT_OBJECT);
+    public void setObject(Value x) {
+        updateUsages(object, x);
+        object = x;
     }
 
-    public Value setObject(Value n) {
-        return (Value) inputs().set(super.inputCount() + INPUT_OBJECT, n);
+    public Value lockAddress() {
+        return lockAddress;
     }
 
-    /**
-     * The instruction producing the address of the lock object.
-     */
-    public Value lockAddress() {
-        return (Value) inputs().get(super.inputCount() + INPUT_LOCK_ADDRESS);
-    }
-
-    public Value setLockAddress(Value n) {
-        return (Value) inputs().set(super.inputCount() + INPUT_LOCK_ADDRESS, n);
+    public void setLockAddress(Value x) {
+        updateUsages(lockAddress, x);
+        lockAddress = x;
     }
 
     /**
@@ -79,12 +65,10 @@
      * @param object the instruction producing the object
      * @param lockAddress the address of the on-stack lock object or {@code null} if the runtime does not place locks on the stack
      * @param lockNumber the number of the lock being acquired
-     * @param inputCount
-     * @param successorCount
      * @param graph
      */
-    public AccessMonitor(Value object, Value lockAddress, int lockNumber, int inputCount, int successorCount, Graph graph) {
-        super(CiKind.Illegal, inputCount + INPUT_COUNT, successorCount + SUCCESSOR_COUNT, graph);
+    public AccessMonitor(Value object, Value lockAddress, int lockNumber, Graph graph) {
+        super(CiKind.Illegal, graph);
         this.lockNumber = lockNumber;
         setObject(object);
         setLockAddress(lockAddress);
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AccessNode.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AccessNode.java	Wed Aug 03 11:51:47 2011 +0200
@@ -22,64 +22,64 @@
  */
 package com.oracle.max.graal.compiler.ir;
 
-import java.util.*;
-
 import com.oracle.max.graal.compiler.debug.*;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.ci.*;
 
 
 public abstract class AccessNode extends AbstractMemoryCheckpointNode {
-    private static final int INPUT_COUNT = 3;
-    private static final int INPUT_NODE = 0;
-    private static final int INPUT_LOCATION = 1;
-    private static final int INPUT_GUARD = 2;
+
+    @NodeInput
+    private Value object;
 
-    private static final int SUCCESSOR_COUNT = 0;
+    @NodeInput
+    private GuardNode guard;
 
+    @NodeInput
     private LocationNode location;
 
-    @Override
-    protected int inputCount() {
-        return super.inputCount() + INPUT_COUNT;
-    }
+    @NodeInput
+    private final NodeInputList<Node> dependencies = new NodeInputList<Node>(this);
 
     public Value object() {
-        return (Value) inputs().get(super.inputCount() + INPUT_NODE);
+        return object;
     }
 
-    public Value setObject(Value n) {
-        return (Value) inputs().set(super.inputCount() + INPUT_NODE, n);
+    public void setObject(Value x) {
+        updateUsages(object, x);
+        object = x;
     }
 
     public GuardNode guard() {
-        return (GuardNode) inputs().get(super.inputCount() + INPUT_GUARD);
+        return guard;
     }
 
-    public void setGuard(GuardNode n) {
-        inputs().set(super.inputCount() + INPUT_GUARD, n);
+    public void setGuard(GuardNode x) {
+        updateUsages(guard, x);
+        guard = x;
     }
 
     public LocationNode location() {
-        return (LocationNode) inputs().get(super.inputCount() + INPUT_LOCATION);
+        return location;
     }
 
-    public void setLocation(LocationNode n) {
-        inputs().set(super.inputCount() + INPUT_LOCATION, n);
+    public void setLocation(LocationNode x) {
+        updateUsages(location, x);
+        location = x;
     }
 
-    public AccessNode(CiKind kind, Value object, LocationNode location, int inputCount, int successorCount, Graph graph) {
-        super(kind, INPUT_COUNT + inputCount, SUCCESSOR_COUNT + successorCount, graph);
+    public AccessNode(CiKind kind, Value object, LocationNode location, Graph graph) {
+        super(kind, graph);
         setLocation(location);
         setObject(object);
     }
 
     public void addDependency(Node x) {
-        variableInputs().add(x);
+        dependencies.add(x);
     }
 
-    public List<Node> dependencies() {
-        return variableInputs();
+    public NodeInputList<Node> dependencies() {
+        return dependencies;
     }
 
     @Override
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AccessVectorNode.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/AccessVectorNode.java	Wed Aug 03 11:51:47 2011 +0200
@@ -27,39 +27,36 @@
 
 
 public abstract class AccessVectorNode extends AbstractVectorNode {
-    private static final int INPUT_COUNT = 2;
-    private static final int INPUT_OBJECT = 0;
-    private static final int INPUT_LOCATION = 1;
-    private static final int SUCCESSOR_COUNT = 0;
+
+    @NodeInput
+    private Value object;
 
-    @Override
-    protected int inputCount() {
-        return super.inputCount() + INPUT_COUNT;
+    @NodeInput
+    private LocationNode location;
+
+    @NodeInput
+    private final NodeInputList<Node> dependencies = new NodeInputList<Node>(this);
+
+    public Value object() {
+        return object;
     }
 
-    @Override
-    protected int successorCount() {
-        return super.successorCount() + SUCCESSOR_COUNT;
-    }
-
-    public void setObject(Value object) {
-        inputs().set(super.inputCount() + INPUT_OBJECT, object);
-    }
-
-    public Value object() {
-        return (Value) inputs().get(super.inputCount() + INPUT_OBJECT);
-    }
-
-    public void setLocation(LocationNode object) {
-        inputs().set(super.inputCount() + INPUT_LOCATION, object);
+    public void setObject(Value x) {
+        updateUsages(object, x);
+        object = x;
     }
 
     public LocationNode location() {
-        return (LocationNode) inputs().get(super.inputCount() + INPUT_LOCATION);
+        return location;
     }
 
-    public AccessVectorNode(CiKind kind, int inputCount, int successorCount, AbstractVectorNode vector, Value object, LocationNode location, Graph graph) {
-        super(kind, inputCount + INPUT_COUNT, successorCount + SUCCESSOR_COUNT, vector, graph);
+    public void setLocation(LocationNode x) {
+        updateUsages(location, x);
+        location = x;
+    }
+
+    public AccessVectorNode(CiKind kind, AbstractVectorNode vector, Value object, LocationNode location, Graph graph) {
+        super(kind, vector, graph);
         setObject(object);
         setLocation(location);
     }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Arithmetic.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Arithmetic.java	Wed Aug 03 11:51:47 2011 +0200
@@ -32,9 +32,6 @@
  */
 public abstract class Arithmetic extends Binary {
 
-    private static final int INPUT_COUNT = 0;
-    private static final int SUCCESSOR_COUNT = 0;
-
     private final boolean isStrictFP;
 
     /**
@@ -46,7 +43,7 @@
      * @param isStrictFP indicates this operation has strict rounding semantics
      */
     public Arithmetic(CiKind kind, int opcode, Value x, Value y, boolean isStrictFP, Graph graph) {
-        super(kind, opcode, x, y, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+        super(kind, opcode, x, y, graph);
         this.isStrictFP = isStrictFP;
     }
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Binary.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Binary.java	Wed Aug 03 11:51:47 2011 +0200
@@ -32,42 +32,28 @@
  */
 public abstract class Binary extends FloatingNode {
 
-    private static final int INPUT_COUNT = 2;
-    private static final int INPUT_X = 0;
-    private static final int INPUT_Y = 1;
-
-    private static final int SUCCESSOR_COUNT = 0;
+    @NodeInput
+    private Value x;
 
-    @Override
-    protected int inputCount() {
-        return super.inputCount() + INPUT_COUNT;
-    }
+    @NodeInput
+    private Value y;
 
-    @Override
-    protected int successorCount() {
-        return super.successorCount() + SUCCESSOR_COUNT;
+    public Value x() {
+        return x;
     }
 
-    /**
-     * The first input to this instruction.
-     */
-     public Value x() {
-        return (Value) inputs().get(super.inputCount() + INPUT_X);
+    public void setX(Value x) {
+        updateUsages(this.x, x);
+        this.x = x;
     }
 
-    public Value setX(Value n) {
-        return (Value) inputs().set(super.inputCount() + INPUT_X, n);
+    public Value y() {
+        return y;
     }
 
-    /**
-     * The second input to this instruction.
-     */
-    public Value y() {
-        return (Value) inputs().get(super.inputCount() + INPUT_Y);
-    }
-
-    public Value setY(Value n) {
-        return (Value) inputs().set(super.inputCount() + INPUT_Y, n);
+    public void setY(Value x) {
+        updateUsages(y, x);
+        this.y = x;
     }
 
     /**
@@ -82,8 +68,8 @@
      * @param x the first input instruction
      * @param y the second input instruction
      */
-    public Binary(CiKind kind, int opcode, Value x, Value y, int inputCount, int successorCount, Graph graph) {
-        super(kind, inputCount + INPUT_COUNT, successorCount + SUCCESSOR_COUNT, graph);
+    public Binary(CiKind kind, int opcode, Value x, Value y, Graph graph) {
+        super(kind, graph);
         this.opcode = opcode;
         setX(x);
         setY(y);
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/BooleanNode.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/BooleanNode.java	Wed Aug 03 11:51:47 2011 +0200
@@ -28,7 +28,7 @@
 
 public abstract class BooleanNode extends FloatingNode {
 
-    public BooleanNode(CiKind kind, int inputCount, int successorCount, Graph graph) {
-        super(kind, inputCount, successorCount, graph);
+    public BooleanNode(CiKind kind, Graph graph) {
+        super(kind, graph);
     }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/CastNode.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/CastNode.java	Wed Aug 03 11:51:47 2011 +0200
@@ -29,24 +29,21 @@
 
 
 public final class CastNode extends FloatingNode {
-    private static final int INPUT_COUNT = 1;
-    private static final int INPUT_NODE = 0;
-
-    private static final int SUCCESSOR_COUNT = 0;
 
-    /**
-     * The instruction that produces the object tested against null.
-     */
+    @NodeInput
+    private Value value;
+
     public Value value() {
-        return (Value) inputs().get(super.inputCount() + INPUT_NODE);
+        return value;
     }
 
-    public void setValue(Value n) {
-        inputs().set(super.inputCount() + INPUT_NODE, n);
+    public void setValue(Value x) {
+        updateUsages(value, x);
+        value = x;
     }
 
     public CastNode(CiKind kind, Value n, Graph graph) {
-        super(kind, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+        super(kind, graph);
         setValue(n);
     }
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/CheckCast.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/CheckCast.java	Wed Aug 03 11:51:47 2011 +0200
@@ -34,9 +34,6 @@
  */
 public final class CheckCast extends TypeCheck {
 
-    private static final int INPUT_COUNT = 0;
-    private static final int SUCCESSOR_COUNT = 0;
-
     /**
      * Creates a new CheckCast instruction.
      * @param targetClass the class being cast to
@@ -44,7 +41,7 @@
      * @param graph
      */
     public CheckCast(Value targetClassInstruction, Value object, Graph graph) {
-        super(targetClassInstruction, object, CiKind.Object, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+        super(targetClassInstruction, object, CiKind.Object, graph);
     }
 
     /**
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Compare.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Compare.java	Wed Aug 03 11:51:47 2011 +0200
@@ -39,42 +39,28 @@
  */
 public final class Compare extends BooleanNode {
 
-    private static final int INPUT_COUNT = 2;
-    private static final int INPUT_X = 0;
-    private static final int INPUT_Y = 1;
-
-    private static final int SUCCESSOR_COUNT = 0;
+    @NodeInput
+    private Value x;
 
-    @Override
-    protected int inputCount() {
-        return super.inputCount() + INPUT_COUNT;
-    }
+    @NodeInput
+    private Value y;
 
-    @Override
-    protected int successorCount() {
-        return super.successorCount() + SUCCESSOR_COUNT;
+    public Value x() {
+        return x;
     }
 
-    /**
-     * The instruction that produces the first input to this comparison.
-     */
-     public Value x() {
-        return (Value) inputs().get(super.inputCount() + INPUT_X);
+    public void setX(Value x) {
+        updateUsages(this.x, x);
+        this.x = x;
     }
 
-    public Value setX(Value n) {
-        return (Value) inputs().set(super.inputCount() + INPUT_X, n);
+    public Value y() {
+        return y;
     }
 
-    /**
-     * The instruction that produces the second input to this comparison.
-     */
-    public Value y() {
-        return (Value) inputs().get(super.inputCount() + INPUT_Y);
-    }
-
-    public Value setY(Value n) {
-        return (Value) inputs().set(super.inputCount() + INPUT_Y, n);
+    public void setY(Value x) {
+        updateUsages(y, x);
+        this.y = x;
     }
 
     Condition condition;
@@ -88,7 +74,7 @@
      * @param graph
      */
     public Compare(Value x, Condition condition, Value y, Graph graph) {
-        super(CiKind.Illegal, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+        super(CiKind.Illegal, graph);
         assert (x == null && y == null) || Util.archKindsEqual(x, y);
         this.condition = condition;
         setX(x);
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Conditional.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Conditional.java	Wed Aug 03 11:51:47 2011 +0200
@@ -35,46 +35,30 @@
  */
 public final class Conditional extends Binary {
 
-    private static final int INPUT_COUNT = 2;
-    private static final int INPUT_TRUE_VALUE = 0;
-    private static final int INPUT_FALSE_VALUE = 1;
-
-    private static final int SUCCESSOR_COUNT = 0;
+    @NodeInput
+    private Value trueValue;
 
-    @Override
-    protected int inputCount() {
-        return super.inputCount() + INPUT_COUNT;
-    }
+    @NodeInput
+    private Value falseValue;
 
-    @Override
-    protected int successorCount() {
-        return super.successorCount() + SUCCESSOR_COUNT;
+    public Value trueValue() {
+        return trueValue;
     }
 
-
-    /**
-     * The instruction that produces the value if the comparison is true.
-     */
-    public Value trueValue() {
-        return (Value) inputs().get(super.inputCount() + INPUT_TRUE_VALUE);
-    }
-
-    public Value setTrueValue(Value n) {
-        return (Value) inputs().set(super.inputCount() + INPUT_TRUE_VALUE, n);
+    public void setTrueValue(Value x) {
+        updateUsages(trueValue, x);
+        trueValue = x;
     }
 
-    /**
-     * The instruction that produces the value if the comparison is false.
-     */
     public Value falseValue() {
-        return (Value) inputs().get(super.inputCount() + INPUT_FALSE_VALUE);
+        return falseValue;
     }
 
-    public Value setFalseValue(Value n) {
-        return (Value) inputs().set(super.inputCount() + INPUT_FALSE_VALUE, n);
+    public void setFalseValue(Value x) {
+        updateUsages(falseValue, x);
+        falseValue = x;
     }
 
-
     Condition condition;
 
     /**
@@ -87,7 +71,7 @@
      */
     public Conditional(Value x, Condition condition, Value y, Value trueValue, Value falseValue, Graph graph) {
         // TODO: return the appropriate bytecode IF_ICMPEQ, etc
-        super(trueValue.kind.meet(falseValue.kind), Bytecodes.ILLEGAL, x, y, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+        super(trueValue.kind.meet(falseValue.kind), Bytecodes.ILLEGAL, x, y, graph);
         this.condition = condition;
         setTrueValue(trueValue);
         setFalseValue(falseValue);
@@ -95,7 +79,7 @@
 
     // for copying
     private Conditional(CiKind kind, Condition cond, Graph graph) {
-        super(kind, Bytecodes.ILLEGAL, null, null, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+        super(kind, Bytecodes.ILLEGAL, null, null, graph);
         this.condition = cond;
     }
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Constant.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Constant.java	Wed Aug 03 11:51:47 2011 +0200
@@ -35,9 +35,6 @@
  */
 public final class Constant extends BooleanNode {
 
-    private static final int INPUT_COUNT = 0;
-    private static final int SUCCESSOR_COUNT = 0;
-
     public final CiConstant value;
 
     /**
@@ -46,7 +43,7 @@
      * @param graph
      */
     public Constant(CiConstant value, Graph graph) {
-        super(value.kind.stackKind(), INPUT_COUNT, SUCCESSOR_COUNT, graph);
+        super(value.kind.stackKind(), graph);
         this.value = value;
     }
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Convert.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Convert.java	Wed Aug 03 11:51:47 2011 +0200
@@ -33,30 +33,16 @@
  */
 public final class Convert extends FloatingNode {
 
-    private static final int INPUT_COUNT = 1;
-    private static final int INPUT_VALUE = 0;
+    @NodeInput
+    private Value value;
 
-    private static final int SUCCESSOR_COUNT = 0;
-
-    @Override
-    protected int inputCount() {
-        return super.inputCount() + INPUT_COUNT;
+    public Value value() {
+        return value;
     }
 
-    @Override
-    protected int successorCount() {
-        return super.successorCount() + SUCCESSOR_COUNT;
-    }
-
-    /**
-     * The instruction which produces the input value to this instruction.
-     */
-     public Value value() {
-        return (Value) inputs().get(super.inputCount() + INPUT_VALUE);
-    }
-
-    public Value setValue(Value n) {
-        return (Value) inputs().set(super.inputCount() + INPUT_VALUE, n);
+    public void setValue(Value x) {
+        updateUsages(value, x);
+        value = x;
     }
 
     /**
@@ -72,7 +58,7 @@
      * @param graph
      */
     public Convert(int opcode, Value value, CiKind kind, Graph graph) {
-        super(kind, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+        super(kind, graph);
         this.opcode = opcode;
         setValue(value);
     }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/CreateVectorNode.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/CreateVectorNode.java	Wed Aug 03 11:51:47 2011 +0200
@@ -33,17 +33,21 @@
 
 
 public final class CreateVectorNode extends AbstractVectorNode {
-    private static final int INPUT_COUNT = 1;
-    private static final int INPUT_LENGTH = 0;
-    private static final int SUCCESSOR_COUNT = 0;
+
+    @NodeInput
+    private Value length;
+
+    public Value length() {
+        return length;
+    }
+
+    public void setLength(Value x) {
+        updateUsages(length, x);
+        length = x;
+    }
 
     private boolean reversed;
 
-    public void setLength(Value length) {
-        assert length == null || length.kind == CiKind.Int;
-        inputs().set(super.inputCount() + INPUT_LENGTH, length);
-    }
-
     public boolean reversed() {
         return reversed;
     }
@@ -52,12 +56,8 @@
         reversed = r;
     }
 
-    public Value length() {
-        return (Value) inputs().get(super.inputCount() + INPUT_LENGTH);
-    }
-
     public CreateVectorNode(boolean reversed, Value length, Graph graph) {
-        super(CiKind.Illegal, INPUT_COUNT, SUCCESSOR_COUNT, null, graph);
+        super(CiKind.Illegal, null, graph);
         setLength(length);
         setReversed(reversed);
     }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/EndNode.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/EndNode.java	Wed Aug 03 11:51:47 2011 +0200
@@ -57,7 +57,7 @@
             return null;
         } else {
             assert usages().size() == 1;
-            return (Merge) usages().get(0);
+            return (Merge) usages().iterator().next();
         }
     }
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/GuardNode.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/GuardNode.java	Wed Aug 03 11:51:47 2011 +0200
@@ -30,33 +30,33 @@
 
 
 public final class GuardNode extends FloatingNode {
-    private static final int INPUT_COUNT = 2;
-    private static final int INPUT_ANCHOR = 0;
-    private static final int INPUT_NODE = 1;
 
-    private static final int SUCCESSOR_COUNT = 0;
+    @NodeInput
+    private FixedNode anchor;
+
+    @NodeInput
+    private BooleanNode node;
 
     public FixedNode anchor() {
-        return (FixedNode) inputs().get(super.inputCount() + INPUT_ANCHOR);
+        return anchor;
     }
 
-    public void setAnchor(FixedNode anchor) {
-        inputs().set(super.inputCount() + INPUT_ANCHOR, anchor);
+    public void setAnchor(FixedNode x) {
+        updateUsages(anchor, x);
+        anchor = x;
     }
 
-    /**
-     * The instruction that produces the object tested against null.
-     */
     public BooleanNode node() {
-        return (BooleanNode) inputs().get(super.inputCount() + INPUT_NODE);
+        return node;
     }
 
-    public void setNode(BooleanNode n) {
-        inputs().set(super.inputCount() + INPUT_NODE, n);
+    public void setNode(BooleanNode x) {
+        updateUsages(node, x);
+        node = x;
     }
 
     public GuardNode(BooleanNode node, Graph graph) {
-        super(CiKind.Illegal, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+        super(CiKind.Illegal, graph);
         setNode(node);
     }
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/InstanceOf.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/InstanceOf.java	Wed Aug 03 11:51:47 2011 +0200
@@ -35,9 +35,6 @@
  */
 public final class InstanceOf extends TypeCheck {
 
-    private static final int INPUT_COUNT = 0;
-    private static final int SUCCESSOR_COUNT = 0;
-
     private boolean nullIsTrue;
 
     /**
@@ -47,7 +44,7 @@
      * @param graph
      */
     public InstanceOf(Constant targetClassInstruction, Value object, boolean nullIsTrue, Graph graph) {
-        super(targetClassInstruction, object, CiKind.Illegal, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+        super(targetClassInstruction, object, CiKind.Illegal, graph);
     }
 
     @Override
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerAddVectorNode.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerAddVectorNode.java	Wed Aug 03 11:51:47 2011 +0200
@@ -30,20 +30,21 @@
 
 
 public final class IntegerAddVectorNode extends AbstractVectorNode {
-    private static final int INPUT_COUNT = 1;
-    private static final int INPUT_VALUE = 0;
-    private static final int SUCCESSOR_COUNT = 0;
+
+    @NodeInput
+    private Value value;
 
     public Value value() {
-        return (Value) inputs().get(super.inputCount() + INPUT_VALUE);
+        return value;
     }
 
-    public void setValue(Value v) {
-        inputs().set(super.inputCount() + INPUT_VALUE, v);
+    public void setValue(Value x) {
+        updateUsages(value, x);
+        value = x;
     }
 
     public IntegerAddVectorNode(AbstractVectorNode vector, Value value, Graph graph) {
-        super(CiKind.Illegal, INPUT_COUNT, SUCCESSOR_COUNT, vector, graph);
+        super(CiKind.Illegal, vector, graph);
         setValue(value);
     }
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Invoke.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Invoke.java	Wed Aug 03 11:51:47 2011 +0200
@@ -36,18 +36,26 @@
  */
 public final class Invoke extends AbstractMemoryCheckpointNode implements ExceptionEdgeInstruction {
 
-    private final int argumentCount;
+    @NodeSuccessor
+    private FixedNode exceptionEdge;
+
+    @NodeInput
+    private final NodeInputList<Value> arguments;
 
-    private static final int SUCCESSOR_COUNT = 1;
-    private static final int SUCCESSOR_EXCEPTION_EDGE = 0;
+    @Override
+    public FixedNode exceptionEdge() {
+        return exceptionEdge;
+    }
+
+    public void setExceptionEdge(FixedNode x) {
+        updatePredecessors(exceptionEdge, x);
+        exceptionEdge = x;
+    }
+
+    private final int argumentCount;
 
     private boolean canInline = true;
 
-    @Override
-    protected int inputCount() {
-        return super.inputCount() + argumentCount;
-    }
-
     public boolean canInline() {
         return canInline;
     }
@@ -56,41 +64,8 @@
         canInline = b;
     }
 
-    @Override
-    protected int successorCount() {
-        return super.successorCount() + SUCCESSOR_COUNT;
-    }
-
-    public List<Value> arguments() {
-        return new AbstractList<Value>() {
-            @Override
-            public int size() {
-                return argumentCount;
-            }
-
-            @Override
-            public Value get(int index) {
-                return (Value) inputs().get(Invoke.super.inputCount() + index);
-            }
-
-            @Override
-            public Value set(int index, Value node) {
-                return (Value) inputs().set(Invoke.super.inputCount() + index, node);
-            }
-        };
-
-    }
-
-    /**
-     * The entry to the exception dispatch chain for this invoke.
-     */
-    @Override
-    public FixedNode exceptionEdge() {
-        return (FixedNode) successors().get(super.successorCount() + SUCCESSOR_EXCEPTION_EDGE);
-    }
-
-    public FixedNode setExceptionEdge(FixedNode n) {
-        return (FixedNode) successors().set(super.successorCount() + SUCCESSOR_EXCEPTION_EDGE, n);
+    public NodeInputList<Value> arguments() {
+        return arguments;
     }
 
     public final int opcode;
@@ -108,7 +83,8 @@
      * @param target the target method being called
      */
     public Invoke(int bci, int opcode, CiKind result, Value[] args, RiMethod target, RiType returnType, Graph graph) {
-        super(result, args.length, SUCCESSOR_COUNT, graph);
+        super(result, graph);
+        arguments = new NodeInputList<Value>(this, args.length);
         this.opcode = opcode;
         this.target = target;
         this.returnType = returnType;
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IsNonNull.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IsNonNull.java	Wed Aug 03 11:51:47 2011 +0200
@@ -35,30 +35,16 @@
  */
 public final class IsNonNull extends BooleanNode {
 
-    private static final int INPUT_COUNT = 1;
-    private static final int INPUT_OBJECT = 0;
+    @NodeInput
+    private Value object;
 
-    private static final int SUCCESSOR_COUNT = 0;
-
-    @Override
-    protected int inputCount() {
-        return super.inputCount() + INPUT_COUNT;
+    public Value object() {
+        return object;
     }
 
-    @Override
-    protected int successorCount() {
-        return super.successorCount() + SUCCESSOR_COUNT;
-    }
-
-    /**
-     * The instruction that produces the object tested against null.
-     */
-     public Value object() {
-        return (Value) inputs().get(super.inputCount() + INPUT_OBJECT);
-    }
-
-    public Value setObject(Value n) {
-        return (Value) inputs().set(super.inputCount() + INPUT_OBJECT, n);
+    public void setObject(Value x) {
+        updateUsages(object, x);
+        object = x;
     }
 
     /**
@@ -67,7 +53,7 @@
      * @param graph
      */
     public IsNonNull(Value object, Graph graph) {
-        super(CiKind.Object, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+        super(CiKind.Object, graph);
         assert object == null || object.kind == CiKind.Object : object;
         setObject(object);
     }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IsType.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IsType.java	Wed Aug 03 11:51:47 2011 +0200
@@ -37,30 +37,16 @@
  */
 public final class IsType extends BooleanNode {
 
-    private static final int INPUT_COUNT = 1;
-    private static final int INPUT_OBJECT = 0;
+    @NodeInput
+    private Value object;
 
-    private static final int SUCCESSOR_COUNT = 0;
-
-    @Override
-    protected int inputCount() {
-        return super.inputCount() + INPUT_COUNT;
+    public Value object() {
+        return object;
     }
 
-    @Override
-    protected int successorCount() {
-        return super.successorCount() + SUCCESSOR_COUNT;
-    }
-
-    /**
-     * The instruction that produces the object tested against null.
-     */
-     public Value object() {
-        return (Value) inputs().get(super.inputCount() + INPUT_OBJECT);
-    }
-
-    public Value setObject(Value n) {
-        return (Value) inputs().set(super.inputCount() + INPUT_OBJECT, n);
+    public void setObject(Value x) {
+        updateUsages(object, x);
+        object = x;
     }
 
     private final RiType type;
@@ -71,7 +57,7 @@
      * @param graph
      */
     public IsType(Value object, RiType type, Graph graph) {
-        super(CiKind.Object, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+        super(CiKind.Object, graph);
         assert type.isResolved();
         assert object == null || object.kind == CiKind.Object;
         this.type = type;
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LoadField.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LoadField.java	Wed Aug 03 11:51:47 2011 +0200
@@ -36,9 +36,6 @@
 public final class LoadField extends AccessField {
     private static final LoadFieldCanonicalizerOp CANONICALIZER = new LoadFieldCanonicalizerOp();
 
-    private static final int INPUT_COUNT = 0;
-    private static final int SUCCESSOR_COUNT = 0;
-
     /**
      * Creates a new LoadField instance.
      * @param object the receiver object
@@ -49,7 +46,7 @@
      * @param isLoaded indicates if the class is loaded
      */
     public LoadField(Value object, RiField field, Graph graph) {
-        super(field.kind().stackKind(), object, field, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+        super(field.kind().stackKind(), object, field, graph);
     }
 
     /**
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LoadIndexed.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LoadIndexed.java	Wed Aug 03 11:51:47 2011 +0200
@@ -34,9 +34,6 @@
  */
 public final class LoadIndexed extends AccessIndexed {
 
-    private static final int INPUT_COUNT = 0;
-    private static final int SUCCESSOR_COUNT = 0;
-
     /**
      * Creates a new LoadIndexed instruction.
      * @param array the instruction producing the array
@@ -46,7 +43,7 @@
      * @param graph
      */
     public LoadIndexed(Value array, Value index, Value length, CiKind elementKind, Graph graph) {
-        super(elementKind.stackKind(), array, index, length, elementKind, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+        super(elementKind.stackKind(), array, index, length, elementKind, graph);
     }
 
     /**
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Local.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Local.java	Wed Aug 03 11:51:47 2011 +0200
@@ -35,37 +35,23 @@
  */
 public final class Local extends FloatingNode {
 
-    private static final int INPUT_COUNT = 1;
-    private static final int INPUT_START = 0;
+    @NodeInput
+    private StartNode start;
 
-    private static final int SUCCESSOR_COUNT = 0;
-
-    @Override
-    protected int inputCount() {
-        return super.inputCount() + INPUT_COUNT;
+    public StartNode start() {
+        return start;
     }
 
-    @Override
-    protected int successorCount() {
-        return super.successorCount() + SUCCESSOR_COUNT;
+    public void setStart(StartNode x) {
+        updateUsages(start, x);
+        start = x;
     }
 
-    /**
-     * The start node of the graph that this local belongs to. This is used for correctly scheduling the locals.
-     */
-     private StartNode start() {
-        return (StartNode) inputs().get(super.inputCount() + INPUT_START);
-    }
-
-     private void setStart(StartNode n) {
-         inputs().set(super.inputCount() + INPUT_START, n);
-     }
-
     private final int index;
     private RiType declaredType;
 
     public Local(CiKind kind, int javaIndex, Graph graph) {
-        super(kind, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+        super(kind, graph);
         this.index = javaIndex;
         setStart(graph.start());
     }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LocationNode.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LocationNode.java	Wed Aug 03 11:51:47 2011 +0200
@@ -30,9 +30,18 @@
 
 
 public final class LocationNode extends FloatingNode {
-    private static final int INPUT_COUNT = 1;
-    private static final int INPUT_INDEX = 0;
-    private static final int SUCCESSOR_COUNT = 0;
+
+    @NodeInput
+    private Value index;
+
+    public Value index() {
+        return index;
+    }
+
+    public void setIndex(Value x) {
+        updateUsages(index, x);
+        index = x;
+    }
 
     public static final Object FINAL_LOCATION = new Object();
 
@@ -48,21 +57,13 @@
         return displacement;
     }
 
-    public Value index() {
-        return (Value) inputs().get(super.inputCount() + INPUT_INDEX);
-    }
-
-    public void setIndex(Value index) {
-        inputs().set(super.inputCount() + INPUT_INDEX, index);
-    }
-
     public static LocationNode create(Object identity, CiKind kind, int displacement, Graph graph) {
         LocationNode result = new LocationNode(identity, kind, displacement, graph);
         return graph.ideal(result);
     }
 
     private LocationNode(Object identity, CiKind kind, int displacement, Graph graph) {
-        super(CiKind.Illegal, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+        super(CiKind.Illegal, graph);
         this.displacement = displacement;
         this.valueKind = kind;
         this.locationIdentity = identity;
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Logic.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Logic.java	Wed Aug 03 11:51:47 2011 +0200
@@ -31,9 +31,6 @@
  */
 public abstract class Logic extends Binary {
 
-    private static final int INPUT_COUNT = 0;
-    private static final int SUCCESSOR_COUNT = 0;
-
     /**
      * Constructs a new logic operation instruction.
      * @param opcode the opcode of the logic operation
@@ -41,7 +38,7 @@
      * @param y the second input into this instruction
      */
     public Logic(CiKind kind, int opcode, Value x, Value y, Graph graph) {
-        super(kind, opcode, x, y, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+        super(kind, opcode, x, y, graph);
     }
 
     @Override
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LoopBegin.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LoopBegin.java	Wed Aug 03 11:51:47 2011 +0200
@@ -110,7 +110,7 @@
     }
 
     @Override
-    public List<Node> phiPredecessors() {
+    public Iterable<Node> phiPredecessors() {
         return Arrays.asList(new Node[]{this.forwardEdge(), this.loopEnd()});
     }
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LoopCounter.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LoopCounter.java	Wed Aug 03 11:51:47 2011 +0200
@@ -29,55 +29,50 @@
 
 public final class LoopCounter extends FloatingNode {
 
-    private static final int INPUT_COUNT = 3;
-    private static final int INPUT_MERGE = 0;
-    private static final int INPUT_INIT = 1;
-    private static final int INPUT_STRIDE = 2;
+    @NodeInput
+    private Value init;
+
+    @NodeInput
+    private Value stride;
+
+    @NodeInput
+    private LoopBegin loopBegin;
+
+    public Value init() {
+        return init;
+    }
+
+    public void setInit(Value x) {
+        updateUsages(init, x);
+        init = x;
+    }
 
-    private static final int SUCCESSOR_COUNT = 0;
+    public Value stride() {
+        return stride;
+    }
+
+    public void setStride(Value x) {
+        updateUsages(stride, x);
+        stride = x;
+    }
+
+    public LoopBegin loopBegin() {
+        return loopBegin;
+    }
+
+    public void setLoopBegin(LoopBegin x) {
+        updateUsages(loopBegin, x);
+        loopBegin = x;
+    }
 
     public LoopCounter(CiKind kind, Value init, Value stride, LoopBegin loop, Graph graph) {
-        super(kind, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+        super(kind, graph);
         setInit(init);
         setStride(stride);
         setLoopBegin(loop);
     }
 
     @Override
-    protected int inputCount() {
-        return super.inputCount() + INPUT_COUNT;
-    }
-
-    @Override
-    protected int successorCount() {
-        return super.successorCount() + SUCCESSOR_COUNT;
-    }
-
-    public Value init() {
-        return (Value) inputs().get(super.inputCount() + INPUT_INIT);
-    }
-
-    public Value setInit(Value n) {
-        return (Value) inputs().set(super.inputCount() + INPUT_INIT, n);
-    }
-
-    public Value stride() {
-        return (Value) inputs().get(super.inputCount() + INPUT_STRIDE);
-    }
-
-    public Value setStride(Value n) {
-        return (Value) inputs().set(super.inputCount() + INPUT_STRIDE, n);
-    }
-
-    public LoopBegin loopBegin() {
-        return (LoopBegin) inputs().get(super.inputCount() + INPUT_MERGE);
-    }
-
-    public Value setLoopBegin(LoopBegin n) {
-        return (Value) inputs().set(super.inputCount() + INPUT_MERGE, n);
-    }
-
-    @Override
     public void accept(ValueVisitor v) {
         // TODO Auto-generated method stub
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MaterializeNode.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MaterializeNode.java	Wed Aug 03 11:51:47 2011 +0200
@@ -31,34 +31,20 @@
 
 public final class MaterializeNode extends FloatingNode {
 
-    private static final int INPUT_COUNT = 1;
-    private static final int INPUT_VALUE = 0;
+    @NodeInput
+    private Value value;
 
-    private static final int SUCCESSOR_COUNT = 0;
-
-    @Override
-    protected int inputCount() {
-        return super.inputCount() + INPUT_COUNT;
+    public Value value() {
+        return value;
     }
 
-    @Override
-    protected int successorCount() {
-        return super.successorCount() + SUCCESSOR_COUNT;
-    }
-
-    /**
-     * The instruction which produces the input value to this instruction.
-     */
-     public Value value() {
-        return (Value) inputs().get(super.inputCount() + INPUT_VALUE);
-    }
-
-    public void setValue(Value n) {
-        inputs().set(super.inputCount() + INPUT_VALUE, n);
+    public void setValue(Value x) {
+        updateUsages(value, x);
+        value = x;
     }
 
     public MaterializeNode(Value value, Graph graph) {
-        super(CiKind.Int, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+        super(CiKind.Int, graph);
         setValue(value);
     }
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Merge.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Merge.java	Wed Aug 03 11:51:47 2011 +0200
@@ -38,7 +38,7 @@
 public class Merge extends StateSplit{
 
     @NodeInput
-    private final NodeInputList<EndNode> ends = new NodeInputList<EndNode>(this);
+    private final NodeInputList<Node> ends = new NodeInputList<Node>(this);
 
     public Merge(Graph graph) {
         super(CiKind.Illegal, graph);
@@ -55,7 +55,6 @@
     }
 
     public int endIndex(EndNode end) {
-        assert variableInputs().contains(end);
         return ends.indexOf(end);
     }
 
@@ -68,7 +67,7 @@
     }
 
     public EndNode endAt(int index) {
-        return ends.get(index);
+        return (EndNode) ends.get(index);
     }
 
     @Override
@@ -319,7 +318,7 @@
         return Util.filter(this.usages(), Phi.class);
     }
 
-    public List<Node> phiPredecessors() {
-        return Collections.unmodifiableList(variableInputs());
+    public Iterable<Node> phiPredecessors() {
+        return ends;
     }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MonitorEnter.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MonitorEnter.java	Wed Aug 03 11:51:47 2011 +0200
@@ -30,15 +30,6 @@
  */
 public final class MonitorEnter extends AccessMonitor {
 
-    private static final int INPUT_COUNT = 0;
-
-    private static final int SUCCESSOR_COUNT = 1;
-
-    @Override
-    protected int successorCount() {
-        return super.successorCount() + SUCCESSOR_COUNT;
-    }
-
     /**
      * Creates a new MonitorEnter instruction.
      *
@@ -48,7 +39,7 @@
      * @param graph
      */
     public MonitorEnter(Value object, Value lockAddress, int lockNumber, Graph graph) {
-        super(object, lockAddress, lockNumber, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+        super(object, lockAddress, lockNumber, graph);
     }
 
     @Override
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MonitorExit.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/MonitorExit.java	Wed Aug 03 11:51:47 2011 +0200
@@ -30,9 +30,6 @@
  */
 public final class MonitorExit extends AccessMonitor {
 
-    private static final int INPUT_COUNT = 0;
-    private static final int SUCCESSOR_COUNT = 0;
-
     /**
      * Creates a new MonitorExit instruction.
      *
@@ -42,7 +39,7 @@
      * @param graph
      */
     public MonitorExit(Value object, Value lockAddress, int lockNumber, Graph graph) {
-        super(object, lockAddress, lockNumber, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+        super(object, lockAddress, lockNumber, graph);
     }
 
     @Override
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Negate.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Negate.java	Wed Aug 03 11:51:47 2011 +0200
@@ -35,31 +35,16 @@
 public final class Negate extends FloatingNode {
     private static final NegateCanonicalizerOp CANONICALIZER = new NegateCanonicalizerOp();
 
-    private static final int INPUT_COUNT = 2;
-    private static final int INPUT_X = 0;
-    private static final int INPUT_Y = 1;
+    @NodeInput
+    private Value x;
 
-    private static final int SUCCESSOR_COUNT = 0;
-
-    @Override
-    protected int inputCount() {
-        return super.inputCount() + INPUT_COUNT;
+    public Value x() {
+        return x;
     }
 
-    @Override
-    protected int successorCount() {
-        return super.successorCount() + SUCCESSOR_COUNT;
-    }
-
-    /**
-     * The instruction producing input to this instruction.
-     */
-     public Value x() {
-        return (Value) inputs().get(super.inputCount() + INPUT_X);
-    }
-
-    public Value setX(Value n) {
-        return (Value) inputs().set(super.inputCount() + INPUT_X, n);
+    public void setX(Value x) {
+        updateUsages(this.x, x);
+        this.x = x;
     }
 
     /**
@@ -67,13 +52,13 @@
      * @param x the instruction producing the value that is input to this instruction
      */
     public Negate(Value x, Graph graph) {
-        super(x.kind, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+        super(x.kind, graph);
         setX(x);
     }
 
     // for copying
     private Negate(CiKind kind, Graph graph) {
-        super(kind, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+        super(kind, graph);
     }
 
     @Override
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NegateBooleanNode.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NegateBooleanNode.java	Wed Aug 03 11:51:47 2011 +0200
@@ -28,34 +28,21 @@
 import com.sun.cri.ci.*;
 
 public final class NegateBooleanNode extends BooleanNode {
-    private static final int INPUT_COUNT = 1;
-    private static final int INPUT_NODE = 0;
 
-    private static final int SUCCESSOR_COUNT = 0;
+    @NodeInput
+    private Value value;
 
-    @Override
-    protected int inputCount() {
-        return super.inputCount() + INPUT_COUNT;
+    public Value value() {
+        return value;
     }
 
-    @Override
-    protected int successorCount() {
-        return super.successorCount() + SUCCESSOR_COUNT;
-    }
-
-    /**
-     * The instruction that produces the array object.
-     */
-     public Value value() {
-        return (Value) inputs().get(super.inputCount() + INPUT_NODE);
-    }
-
-    public Value setValue(Value n) {
-        return (Value) inputs().set(super.inputCount() + INPUT_NODE, n);
+    public void setValue(Value x) {
+        updateUsages(value, x);
+        value = x;
     }
 
     public NegateBooleanNode(Value value, Graph graph) {
-        super(CiKind.Int, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+        super(CiKind.Int, graph);
         setValue(value);
     }
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NormalizeCompare.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/NormalizeCompare.java	Wed Aug 03 11:51:47 2011 +0200
@@ -32,9 +32,6 @@
  */
 public final class NormalizeCompare extends Binary {
 
-    private static final int INPUT_COUNT = 0;
-    private static final int SUCCESSOR_COUNT = 0;
-
     /**
      * Creates a new compare operation.
      * @param opcode the bytecode opcode
@@ -43,7 +40,7 @@
      * @param y the second input
      */
     public NormalizeCompare(int opcode, CiKind kind, Value x, Value y, Graph graph) {
-        super(kind, opcode, x, y, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+        super(kind, opcode, x, y, graph);
     }
 
     @Override
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Phi.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Phi.java	Wed Aug 03 11:51:47 2011 +0200
@@ -36,35 +36,19 @@
  */
 public final class Phi extends FloatingNode {
 
-    private static final int DEFAULT_MAX_VALUES = 2;
-
-    private static final int INPUT_COUNT = 1;
-    private static final int INPUT_MERGE = 0;
+    @NodeInput
+    private Merge merge;
 
-    private static final int SUCCESSOR_COUNT = 0;
-
-    private final PhiType type;
+    @NodeInput
+    private final NodeInputList<Value> values = new NodeInputList<Value>(this);
 
-    @Override
-    protected int inputCount() {
-        return super.inputCount() + INPUT_COUNT;
+    public Merge merge() {
+        return merge;
     }
 
-    @Override
-    protected int successorCount() {
-        return super.successorCount() + SUCCESSOR_COUNT;
-    }
-
-    /**
-     * The merge node for this phi.
-     */
-    public Merge merge() {
-        return (Merge) inputs().get(super.inputCount() + INPUT_MERGE);
-    }
-
-    public void setMerge(Merge n) {
-        assert n != null;
-        inputs().set(super.inputCount() + INPUT_MERGE, n);
+    public void setMerge(Merge x) {
+        updateUsages(merge, x);
+        merge = x;
     }
 
     public static enum PhiType {
@@ -73,14 +57,16 @@
         Virtual         // phis used for VirtualObjectField merges
     }
 
+    private final PhiType type;
+
     public Phi(CiKind kind, Merge merge, PhiType type, Graph graph) {
-        super(kind, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+        super(kind, graph);
         this.type = type;
         setMerge(merge);
     }
 
     private Phi(CiKind kind, PhiType type, Graph graph) {
-        super(kind, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+        super(kind, graph);
         this.type = type;
     }
 
@@ -102,11 +88,11 @@
      * @return the instruction that produced the value in the i'th predecessor
      */
     public Value valueAt(int i) {
-        return (Value) variableInputs().get(i);
+        return values.get(i);
     }
 
     public void setValueAt(int i, Value x) {
-        inputs().set(INPUT_COUNT + i, x);
+        values.set(i, x);
     }
 
     /**
@@ -114,7 +100,7 @@
      * @return the number of inputs in this phi
      */
     public int valueCount() {
-        return variableInputs().size();
+        return values.size();
     }
 
     @Override
@@ -150,12 +136,12 @@
         }
     }
 
-    public void addInput(Node y) {
-        variableInputs().add(y);
+    public void addInput(Value x) {
+        values.add(x);
     }
 
     public void removeInput(int index) {
-        variableInputs().remove(index);
+        values.remove(index);
     }
 
     @Override
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ReadNode.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ReadNode.java	Wed Aug 03 11:51:47 2011 +0200
@@ -28,12 +28,9 @@
 
 
 public final class ReadNode extends AccessNode {
-    private static final int INPUT_COUNT = 0;
-    private static final int SUCCESSOR_COUNT = 0;
-
 
     public ReadNode(CiKind kind, Value object, LocationNode location, Graph graph) {
-        super(kind, object, location, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+        super(kind, object, location, graph);
     }
 
     @Override
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ReadVectorNode.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/ReadVectorNode.java	Wed Aug 03 11:51:47 2011 +0200
@@ -30,11 +30,9 @@
 
 
 public final class ReadVectorNode extends AccessVectorNode {
-    private static final int INPUT_COUNT = 0;
-    private static final int SUCCESSOR_COUNT = 0;
 
     public ReadVectorNode(AbstractVectorNode vector, Value object, LocationNode location, Graph graph) {
-        super(CiKind.Illegal, INPUT_COUNT, SUCCESSOR_COUNT, vector, object, location, graph);
+        super(CiKind.Illegal, vector, object, location, graph);
     }
 
     @Override
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Shift.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Shift.java	Wed Aug 03 11:51:47 2011 +0200
@@ -31,9 +31,6 @@
  */
 public abstract class Shift extends Binary {
 
-    private static final int INPUT_COUNT = 0;
-    private static final int SUCCESSOR_COUNT = 0;
-
     /**
      * Creates a new shift operation.
      * @param opcode the opcode of the shift
@@ -41,7 +38,7 @@
      * @param s the second input value
      */
     public Shift(CiKind kind, int opcode, Value x, Value s, Graph graph) {
-        super(kind, opcode, x, s, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+        super(kind, opcode, x, s, graph);
         assert x == null || x.kind == kind;
     }
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/StoreField.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/StoreField.java	Wed Aug 03 11:51:47 2011 +0200
@@ -34,30 +34,16 @@
  */
 public final class StoreField extends AccessField {
 
-    private static final int INPUT_COUNT = 1;
-    private static final int INPUT_VALUE = 0;
+    @NodeInput
+    private Value value;
 
-    private static final int SUCCESSOR_COUNT = 0;
-
-    @Override
-    protected int inputCount() {
-        return super.inputCount() + INPUT_COUNT;
+    public Value value() {
+        return value;
     }
 
-    @Override
-    protected int successorCount() {
-        return super.successorCount() + SUCCESSOR_COUNT;
-    }
-
-    /**
-     * The value that is written to the field.
-     */
-     public Value value() {
-        return (Value) inputs().get(super.inputCount() + INPUT_VALUE);
-    }
-
-    public Value setValue(Value n) {
-        return (Value) inputs().set(super.inputCount() + INPUT_VALUE, n);
+    public void setValue(Value x) {
+        updateUsages(value, x);
+        value = x;
     }
 
     /**
@@ -69,7 +55,7 @@
      * @param graph
      */
     public StoreField(Value object, RiField field, Value value, Graph graph) {
-        super(CiKind.Void, object, field, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+        super(CiKind.Void, object, field, graph);
         setValue(value);
     }
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/StoreIndexed.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/StoreIndexed.java	Wed Aug 03 11:51:47 2011 +0200
@@ -33,30 +33,16 @@
  */
 public final class StoreIndexed extends AccessIndexed {
 
-    private static final int INPUT_COUNT = 1;
-    private static final int INPUT_VALUE = 0;
+    @NodeInput
+    private Value value;
 
-    private static final int SUCCESSOR_COUNT = 0;
-
-    @Override
-    protected int inputCount() {
-        return super.inputCount() + INPUT_COUNT;
+    public Value value() {
+        return value;
     }
 
-    @Override
-    protected int successorCount() {
-        return super.successorCount() + SUCCESSOR_COUNT;
-    }
-
-    /**
-     * The instruction that produces the value that is to be stored into the array.
-     */
-     public Value value() {
-        return (Value) inputs().get(super.inputCount() + INPUT_VALUE);
-    }
-
-    public Value setValue(Value n) {
-        return (Value) inputs().set(super.inputCount() + INPUT_VALUE, n);
+    public void setValue(Value x) {
+        updateUsages(value, x);
+        value = x;
     }
 
     /**
@@ -70,7 +56,7 @@
      * @param graph
      */
     public StoreIndexed(Value array, Value index, Value length, CiKind elementKind, Value value, Graph graph) {
-        super(CiKind.Void, array, index, length, elementKind, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+        super(CiKind.Void, array, index, length, elementKind, graph);
         setValue(value);
     }
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/TypeCheck.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/TypeCheck.java	Wed Aug 03 11:51:47 2011 +0200
@@ -31,45 +31,30 @@
  */
 public abstract class TypeCheck extends BooleanNode {
 
-    private static final int INPUT_COUNT = 2;
-    private static final int INPUT_OBJECT = 0;
-    private static final int INPUT_TARGET_CLASS_INSTRUCTION = 1;
-
-    private static final int SUCCESSOR_COUNT = 0;
+    @NodeInput
+    private Value object;
 
-    @Override
-    protected int inputCount() {
-        return super.inputCount() + INPUT_COUNT;
-    }
+    @NodeInput
+    private Value targetClassInstruction;
 
-    @Override
-    protected int successorCount() {
-        return super.successorCount() + SUCCESSOR_COUNT;
+    public Value object() {
+        return object;
     }
 
-    /**
-     * The instruction which produces the object input.
-     */
-     public Value object() {
-        return (Value) inputs().get(super.inputCount() + INPUT_OBJECT);
-    }
-
-    public Value setObject(Value n) {
-        return (Value) inputs().set(super.inputCount() + INPUT_OBJECT, n);
+    public void setObject(Value x) {
+        updateUsages(object, x);
+        object = x;
     }
 
-    /**
-     * The instruction that loads the target class object that is used by this checkcast.
-     */
-     public Value targetClassInstruction() {
-        return (Value) inputs().get(super.inputCount() + INPUT_TARGET_CLASS_INSTRUCTION);
+    public Value targetClassInstruction() {
+        return targetClassInstruction;
     }
 
-    private void setTargetClassInstruction(Value n) {
-        inputs().set(super.inputCount() + INPUT_TARGET_CLASS_INSTRUCTION, n);
+    public void setTargetClassInstruction(Value x) {
+        updateUsages(targetClassInstruction, x);
+        targetClassInstruction = x;
     }
 
-
     /**
      * Gets the target class, i.e. the class being cast to, or the class being tested against.
      * @return the target class
@@ -83,12 +68,10 @@
      * @param targetClass the class which is being casted to or checked against
      * @param object the instruction which produces the object
      * @param kind the result type of this instruction
-     * @param inputCount
-     * @param successorCount
      * @param graph
      */
-    public TypeCheck(Value targetClassInstruction, Value object, CiKind kind, int inputCount, int successorCount, Graph graph) {
-        super(kind, inputCount + INPUT_COUNT, successorCount + SUCCESSOR_COUNT, graph);
+    public TypeCheck(Value targetClassInstruction, Value object, CiKind kind, Graph graph) {
+        super(kind, graph);
         setObject(object);
         setTargetClassInstruction(targetClassInstruction);
     }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/VirtualObject.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/VirtualObject.java	Wed Aug 03 11:51:47 2011 +0200
@@ -33,25 +33,11 @@
 
 public class VirtualObject extends FloatingNode {
 
-    private static final int INPUT_COUNT = 0;
-
-    private static final int SUCCESSOR_COUNT = 0;
-
-    @Override
-    protected int inputCount() {
-        return super.inputCount() + INPUT_COUNT;
-    }
-
-    @Override
-    protected int successorCount() {
-        return super.successorCount() + SUCCESSOR_COUNT;
-    }
-
     private EscapeField[] fields;
     private RiType type;
 
     public VirtualObject(RiType type, EscapeField[] fields, Graph graph) {
-        super(CiKind.Int, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+        super(CiKind.Int, graph);
         this.type = type;
         this.fields = fields;
     }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/VirtualObjectField.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/VirtualObjectField.java	Wed Aug 03 11:51:47 2011 +0200
@@ -31,54 +31,40 @@
 
 public class VirtualObjectField extends FloatingNode {
 
-    private static final int INPUT_COUNT = 3;
-    private static final int INPUT_OBJECT = 0;
-    private static final int INPUT_LAST_STATE = 1;
-    private static final int INPUT_INPUT = 2;
+    @NodeInput
+    private VirtualObject object;
 
-    private static final int SUCCESSOR_COUNT = 0;
+    @NodeInput
+    private FloatingNode lastState;
 
-    @Override
-    protected int inputCount() {
-        return super.inputCount() + INPUT_COUNT;
-    }
+    @NodeInput
+    private Value input;
 
-    @Override
-    protected int successorCount() {
-        return super.successorCount() + SUCCESSOR_COUNT;
-    }
-
-    /**
-     * The instruction that specifies the virtual object instance.
-     */
-     public VirtualObject object() {
-        return (VirtualObject) inputs().get(super.inputCount() + INPUT_OBJECT);
+    public VirtualObject object() {
+        return object;
     }
 
-    private VirtualObject setObject(VirtualObject n) {
-        return (VirtualObject) inputs().set(super.inputCount() + INPUT_OBJECT, n);
+    public void setObject(VirtualObject x) {
+        updateUsages(object, x);
+        object = x;
     }
 
-    /**
-     * The instruction that specifies the old state of the virtual object.
-     */
-     public FloatingNode lastState() {
-        return (FloatingNode) inputs().get(super.inputCount() + INPUT_LAST_STATE);
+    public FloatingNode lastState() {
+        return lastState;
     }
 
-    private FloatingNode setLastState(FloatingNode n) {
-        return (FloatingNode) inputs().set(super.inputCount() + INPUT_LAST_STATE, n);
+    public void setLastState(FloatingNode x) {
+        updateUsages(lastState, x);
+        lastState = x;
     }
 
-    /**
-     * The instruction that contains the new state of the specified field.
-     */
-     public Value input() {
-        return (Value) inputs().get(super.inputCount() + INPUT_INPUT);
+    public Value input() {
+        return input;
     }
 
-    public Value setInput(Value n) {
-        return (Value) inputs().set(super.inputCount() + INPUT_INPUT, n);
+    public void setInput(Value x) {
+        updateUsages(input, x);
+        input = x;
     }
 
     private int index;
@@ -89,7 +75,7 @@
      * @param newFrameState the state after executing this instruction
      */
     public VirtualObjectField(VirtualObject object, FloatingNode lastState, Value input, int index, Graph graph) {
-        super(CiKind.Int, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+        super(CiKind.Int, graph);
         this.index = index;
         setObject(object);
         setLastState(lastState);
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/WriteMemoryCheckpointNode.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/WriteMemoryCheckpointNode.java	Wed Aug 03 11:51:47 2011 +0200
@@ -29,15 +29,12 @@
 
 public final class WriteMemoryCheckpointNode extends AbstractMemoryCheckpointNode {
 
-    private static final int SUCCESSOR_COUNT = 0;
-    private static final int INPUT_COUNT = 0;
-
     public WriteMemoryCheckpointNode(Graph graph) {
-        this(CiKind.Illegal, 0, 0, graph);
+        this(CiKind.Illegal, graph);
     }
 
-    public WriteMemoryCheckpointNode(CiKind result, int inputCount, int successorCount, Graph graph) {
-        super(result, inputCount + INPUT_COUNT, successorCount + SUCCESSOR_COUNT, graph);
+    public WriteMemoryCheckpointNode(CiKind result, Graph graph) {
+        super(result, graph);
     }
 
     @Override
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/WriteNode.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/WriteNode.java	Wed Aug 03 11:51:47 2011 +0200
@@ -28,25 +28,21 @@
 
 
 public final class WriteNode extends AccessNode {
-    private static final int INPUT_COUNT = 1;
-    private static final int INPUT_VALUE = 0;
-    private static final int SUCCESSOR_COUNT = 0;
 
-    @Override
-    protected int inputCount() {
-        return super.inputCount() + INPUT_COUNT;
+    @NodeInput
+    private Value value;
+
+    public Value value() {
+        return value;
     }
 
-    public Value value() {
-        return (Value) inputs().get(super.inputCount() + INPUT_VALUE);
-    }
-
-    public void setValue(Value v) {
-        inputs().set(super.inputCount() + INPUT_VALUE, v);
+    public void setValue(Value x) {
+        updateUsages(value, x);
+        value = x;
     }
 
     public WriteNode(CiKind kind, Value object, Value value, LocationNode location, Graph graph) {
-        super(kind, object, location, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+        super(kind, object, location, graph);
         setValue(value);
     }
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/WriteVectorNode.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/WriteVectorNode.java	Wed Aug 03 11:51:47 2011 +0200
@@ -31,20 +31,21 @@
 
 
 public final class WriteVectorNode extends AccessVectorNode {
-    private static final int INPUT_COUNT = 1;
-    private static final int INPUT_VALUES = 0;
-    private static final int SUCCESSOR_COUNT = 0;
 
-    public void setValues(AbstractVectorNode length) {
-        inputs().set(super.inputCount() + INPUT_VALUES, length);
+    @NodeInput
+    private AbstractVectorNode values;
+
+    public AbstractVectorNode values() {
+        return values;
     }
 
-    public AbstractVectorNode values() {
-        return (AbstractVectorNode) inputs().get(super.inputCount() + INPUT_VALUES);
+    public void setValues(AbstractVectorNode x) {
+        updateUsages(values, x);
+        values = x;
     }
 
     public WriteVectorNode(AbstractVectorNode vector, Value object, LocationNode location, AbstractVectorNode values, Graph graph) {
-        super(CiKind.Illegal, INPUT_COUNT, SUCCESSOR_COUNT, vector, object, location, graph);
+        super(CiKind.Illegal, vector, object, location, graph);
         setValues(values);
     }
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/DuplicationPhase.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/DuplicationPhase.java	Wed Aug 03 11:51:47 2011 +0200
@@ -44,7 +44,12 @@
         // Delete nodes in original graph.
         for (Node n : graph.getNodes()) {
             if (n != graph.start()) {
-                n.forceDelete();
+                n.clearEdges();
+            }
+        }
+        for (Node n : graph.getNodes()) {
+            if (n != graph.start()) {
+                n.delete();
             }
         }
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java	Wed Aug 03 11:51:47 2011 +0200
@@ -1134,6 +1134,7 @@
                 If ifNode = (If) cur;
                 if (ifNode.falseSuccessor() == prev) {
                     FixedNode successor = ifNode.trueSuccessor();
+                    ifNode.setTrueSuccessor(null);
                     BooleanNode condition = ifNode.compare();
                     FixedGuard fixedGuard = new FixedGuard(condition, graph);
                     fixedGuard.setNext(successor);
@@ -1301,7 +1302,9 @@
                     loopEnd.delete();
                     Merge merge = new Merge(graph);
                     merge.addEnd(begin.forwardEdge());
-                    merge.setNext(begin.next());
+                    FixedNode next = begin.next();
+                    begin.setNext(null);
+                    merge.setNext(next);
                     merge.setStateAfter(begin.stateAfter());
                     begin.replaceAndDelete(merge);
                 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java	Wed Aug 03 11:51:47 2011 +0200
@@ -550,7 +550,7 @@
 
         if (exceptionEdge != null) {
             if (unwindNode != null) {
-                assert unwindNode.predecessor()!= null;
+                assert unwindNode.predecessor() != null;
                 assert exceptionEdge.successors().explicitCount() == 1;
                 ExceptionObject obj = (ExceptionObject) exceptionEdge;
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoopPhase.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoopPhase.java	Wed Aug 03 11:51:47 2011 +0200
@@ -135,13 +135,12 @@
     private List<LoopCounter> findLoopCounters(LoopBegin loopBegin, NodeBitMap loopNodes) {
         LoopEnd loopEnd = loopBegin.loopEnd();
         FrameState loopEndState = null;
-        Node loopEndPred = loopEnd.singlePredecessor();
+        Node loopEndPred = loopEnd.predecessor();
         if (loopEndPred instanceof Merge) {
             loopEndState = ((Merge) loopEndPred).stateAfter();
         }
-        List<Node> usages = new ArrayList<Node>(loopBegin.usages());
         List<LoopCounter> counters = new LinkedList<LoopCounter>();
-        for (Node usage : usages) {
+        for (Node usage : loopBegin.usages().snapshot()) {
             if (usage instanceof Phi) {
                 Phi phi = (Phi) usage;
                 if (phi.valueCount() == 2) {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/MemoryPhase.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/MemoryPhase.java	Wed Aug 03 11:51:47 2011 +0200
@@ -73,8 +73,9 @@
             StartNode startNode = b.firstNode().graph().start();
             if (b.firstNode() == startNode) {
                 WriteMemoryCheckpointNode checkpoint = new WriteMemoryCheckpointNode(startNode.graph());
-                checkpoint.setNext((FixedNode) startNode.next());
+                FixedNode next = (FixedNode) startNode.next();
                 startNode.setNext(checkpoint);
+                checkpoint.setNext(next);
                 mergeForWrite = checkpoint;
                 mergeForRead = checkpoint;
             }
@@ -150,7 +151,7 @@
             Merge m = (Merge) block.firstNode();
             if (original instanceof Phi && ((Phi) original).merge() == m) {
                 Phi phi = (Phi) original;
-                phi.addInput(newValue);
+                phi.addInput((Value) newValue);
                 if (GraalOptions.TraceMemoryMaps) {
                     TTY.println("Add new input to phi " + original.id());
                 }
@@ -159,9 +160,9 @@
             } else {
                 Phi phi = new Phi(CiKind.Illegal, m, PhiType.Memory, m.graph());
                 for (int i = 0; i < mergeOperationCount + 1; ++i) {
-                    phi.addInput(original);
+                    phi.addInput((Value) original);
                 }
-                phi.addInput(newValue);
+                phi.addInput((Value) newValue);
                 if (GraalOptions.TraceMemoryMaps) {
                     TTY.println("Creating new phi " + phi.id());
                 }
@@ -291,16 +292,18 @@
         for (final Node n : b.getInstructions()) {
             if (n instanceof ReadNode) {
                 ReadNode readNode = (ReadNode) n;
-                readNode.replaceAtPredecessors(readNode.next());
+                FixedNode next = readNode.next();
                 readNode.setNext(null);
+                readNode.replaceAtPredecessors(next);
                 map.registerRead(readNode);
             } else if (n instanceof WriteNode) {
                 WriteNode writeNode = (WriteNode) n;
                 WriteMemoryCheckpointNode checkpoint = new WriteMemoryCheckpointNode(writeNode.graph());
                 checkpoint.setStateAfter(writeNode.stateAfter());
                 writeNode.setStateAfter(null);
-                checkpoint.setNext(writeNode.next());
+                FixedNode next = writeNode.next();
                 writeNode.setNext(null);
+                checkpoint.setNext(next);
                 writeNode.replaceAtPredecessors(checkpoint);
                 map.registerWrite(writeNode);
                 map.createWriteMemoryMerge(checkpoint);
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/Phase.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/Phase.java	Wed Aug 03 11:51:47 2011 +0200
@@ -25,7 +25,7 @@
 import com.oracle.max.graal.compiler.*;
 import com.oracle.max.graal.compiler.observer.*;
 import com.oracle.max.graal.compiler.schedule.*;
-import com.oracle.max.graal.graph.Graph;
+import com.oracle.max.graal.graph.*;
 
 public abstract class Phase {
 
@@ -88,7 +88,6 @@
             }
             throw t;
         }
-        //System.out.println("Finished Phase " + getName());
         if (GraalOptions.Time) {
             GraalTimers.get(getName()).stop();
             if (oldCurrentPhase != null) {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/Block.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/Block.java	Wed Aug 03 11:51:47 2011 +0200
@@ -92,8 +92,9 @@
                     this.anchor = (Anchor) start.next();
                 } else {
                     Anchor a = new Anchor(firstNode.graph());
-                    a.setNext((FixedNode) firstNode.graph().start().next());
+                    FixedNode oldStart = (FixedNode) firstNode.graph().start().next();
                     firstNode.graph().start().setNext(a);
+                    a.setNext(oldStart);
                     this.anchor = a;
                 }
             } else if (firstNode instanceof Merge || firstNode instanceof ExceptionObject) {
@@ -102,8 +103,9 @@
                     this.anchor = (Anchor) fixedNode.next();
                 } else {
                     Anchor a = new Anchor(firstNode.graph());
-                    a.setNext(fixedNode.next());
+                    FixedNode next = fixedNode.next();
                     fixedNode.setNext(a);
+                    a.setNext(next);
                     this.anchor = a;
                 }
             } else {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/LoopUtil.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/LoopUtil.java	Wed Aug 03 11:51:47 2011 +0200
@@ -34,6 +34,7 @@
 import com.oracle.max.graal.compiler.util.GraphUtil.ColoringLambda;
 import com.oracle.max.graal.compiler.value.*;
 import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.graph.NodeClass.*;
 import com.oracle.max.graal.graph.collections.*;
 import com.sun.cri.ci.*;
 
@@ -238,7 +239,7 @@
         // move peeled part to the end
         LoopBegin loopBegin = loop.loopBegin();
         LoopEnd loopEnd = loopBegin.loopEnd();
-        FixedNode lastNode = (FixedNode) loopEnd.singlePredecessor();
+        FixedNode lastNode = (FixedNode) loopEnd.predecessor();
         if (loopBegin.next() != lastNode) {
             lastNode.successors().replace(loopEnd, loopBegin.next());
             loopBegin.setNext(noExit);
@@ -250,8 +251,7 @@
         for (Phi phi : loopBegin.phis()) {
             Value backValue = phi.valueAt(backIndex);
             if (loop.nodes().isMarked(backValue) && peeling.peeledNodes.isNotNewNotMarked(backValue)) {
-                List<Node> usages = new ArrayList<Node>(phi.usages());
-                for (Node usage : usages) {
+                for (Node usage : phi.usages().snapshot()) {
                     if (peeling.peeledNodes.isNotNewMarked(usage)) {
                         usage.inputs().replace(phi, backValue);
                     }
@@ -326,23 +326,25 @@
     private static void rewirePeeling(PeelingResult peeling, Loop loop, FixedNode from, boolean inversion) {
         LoopBegin loopBegin = loop.loopBegin();
         Graph graph = loopBegin.graph();
-        Node loopPred = loopBegin.singlePredecessor();
+        Node loopPred = loopBegin.predecessor();
         loopPred.successors().replace(loopBegin.forwardEdge(), peeling.begin);
         NodeBitMap loopNodes = loop.cfgNodes();
         Node originalLast = from;
         if (originalLast == loopBegin.loopEnd()) {
-            originalLast = loopBegin.loopEnd().singlePredecessor();
+            originalLast = loopBegin.loopEnd().predecessor();
+        }
+        for (Node sux : originalLast.successors()) {
         }
-        int size = originalLast.successors().size();
         boolean found = false;
-        for (int i = 0; i < size; i++) {
-            Node sux = originalLast.successors().get(i);
+        for (NodeClassIterator iter = originalLast.successors().iterator(); iter.hasNext();) {
+            Position pos = iter.nextPosition();
+            Node sux = originalLast.getNodeClass().get(originalLast, pos);
             if (sux == null) {
                 continue;
             }
             if (loopNodes.isMarked(sux)) {
                 assert !found;
-                peeling.end.successors().set(i, loopBegin.forwardEdge());
+                peeling.end.getNodeClass().set(peeling.end, pos, loopBegin.forwardEdge());
                 found = true;
             }
         }
@@ -400,7 +402,7 @@
             EndNode oEnd = (EndNode) original.next();
             Merge merge = oEnd.merge();
             EndNode nEnd = merge.endAt(1 - merge.phiPredecessorIndex(oEnd));
-            Node newExit = nEnd.singlePredecessor();
+            Node newExit = nEnd.predecessor();
             for (Entry<Node, Node> dataEntry : peeling.dataOut.entries()) {
                 Node originalValue = dataEntry.getKey();
                 Node newValue = dataEntry.getValue();
@@ -440,8 +442,7 @@
                 }
                 Value newValue = (Value) entry.getValue();
                 Phi phi = null;
-                List<Node> usages = new ArrayList<Node>(originalValue.usages());
-                for (Node usage : usages) {
+                for (Node usage : originalValue.usages().snapshot()) {
                     if (exitMergesPhis.isMarked(usage) || (
                                     loop.nodes().isNotNewMarked(usage)
                                     && peeling.peeledNodes.isNotNewNotMarked(usage)
@@ -588,7 +589,7 @@
                 System.out.println(" - inputs > 0 : " + (n.inputs().size() > 0));
                 System.out.println(" - !danglingMergeFrameState : " + (!danglingMergeFrameState(n)));*/
                 return exitFrameStates.isNotNewMarked(n)
-                || (inOrBefore.isNotNewNotMarked(n) && n.inputs().size() > 0 && !afterColoringFramestate(n)); //TODO (gd) hum
+                || (inOrBefore.isNotNewNotMarked(n) && n.inputs().explicitCount() > 0 && !afterColoringFramestate(n)); //TODO (gd) hum
             }
             public boolean afterColoringFramestate(Node n) {
                 if (!(n instanceof FrameState)) {
@@ -620,15 +621,16 @@
                     }
                     inOrBefore.mark(node);
                 } else {
-                    for (int i = 0; i < node.inputs().size(); i++) {
-                        Node input = node.inputs().get(i);
+                    for (NodeClassIterator iter = node.inputs().iterator(); iter.hasNext();) {
+                        Position pos = iter.nextPosition();
+                        Node input = node.getNodeClass().get(node, pos);
                         if (input == null || newExitValues.isNew(input)) {
                             continue;
                         }
                         NodeMap<Value> valueMap = newExitValues.get(input);
                         if (valueMap != null) {
                             Value replacement = getValueAt(color, valueMap, ((Value) input).kind);
-                            node.inputs().set(i, replacement);
+                            node.getNodeClass().set(node, pos, replacement);
                         }
                     }
                 }
@@ -688,7 +690,7 @@
         NodeBitMap clonedExits = graph.createNodeBitMap();
         NodeBitMap exitFrameStates = graph.createNodeBitMap();
         for (Node exit : loop.exits()) {
-            if (marked.isMarked(exit.singlePredecessor())) {
+            if (marked.isMarked(exit.predecessor())) {
                 StateSplit pExit = findNearestMergableExitPoint((FixedNode) exit, marked);
                 markWithState(pExit, marked);
                 clonedExits.mark(pExit);
@@ -775,7 +777,7 @@
         }
 
         FixedNode newBegin = (FixedNode) duplicates.get(loopBegin.next());
-        FixedNode newFrom = (FixedNode) duplicates.get(from == loopBegin.loopEnd() ? from.singlePredecessor() : from);
+        FixedNode newFrom = (FixedNode) duplicates.get(from == loopBegin.loopEnd() ? from.predecessor() : from);
         return new PeelingResult(newBegin, newFrom, exits, phis, phiInits, dataOutMapping, unaffectedExits, exitFrameStates, marked);
     }
 
@@ -857,8 +859,8 @@
         for (Node n : work) {
             inOrBefore.mark(n);
             if (full) {
-                for (Node pred : n.predecessors()) {
-                    work.add(pred);
+                if (n.predecessor() != null) {
+                    work.add(n.predecessor());
                 }
             }
             if (n instanceof Phi) { // filter out data graph cycles
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/Util.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/Util.java	Wed Aug 03 11:51:47 2011 +0200
@@ -427,7 +427,7 @@
     }
 
     @SuppressWarnings("unchecked")
-    public static <T extends Node> Collection<T> filter(Collection<Node> nodes, Class<T> clazz) {
+    public static <T extends Node> Collection<T> filter(Iterable<Node> nodes, Class<T> clazz) {
         ArrayList<T> phis = new ArrayList<T>();
         for (Node node : nodes) {
             if (clazz.isInstance(node)) {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/value/FrameState.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/value/FrameState.java	Wed Aug 03 11:51:47 2011 +0200
@@ -378,7 +378,7 @@
      */
     public Value valueAt(int i) {
         assert i < (localsSize + stackSize + locksSize);
-        return values.get(i);
+        return values.isEmpty() ? null : values.get(i);
     }
 
     /**
--- a/graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/opt/OptimizerImpl.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/opt/OptimizerImpl.java	Wed Aug 03 11:51:47 2011 +0200
@@ -70,7 +70,7 @@
         // look at all loop exits:
         for (Node exit : exits) {
             TTY.println("exit: " + exit);
-            Node pred = exit.predecessors().get(0);
+            Node pred = exit.predecessor();
             // if this exit is an If node ...
             if (pred instanceof If) {
                 If ifNode = (If) pred;
--- a/graal/com.oracle.max.graal.graphviz/src/com/oracle/max/graal/graphviz/GraphvizPrinter.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.graphviz/src/com/oracle/max/graal/graphviz/GraphvizPrinter.java	Wed Aug 03 11:51:47 2011 +0200
@@ -30,7 +30,8 @@
 
 import com.oracle.max.graal.graph.Graph;
 import com.oracle.max.graal.graph.Node;
-import com.oracle.max.graal.graph.NodeArray;
+import com.oracle.max.graal.graph.NodeInputsIterable;
+import com.oracle.max.graal.graph.NodeSuccessorsIterable;
 
 /**
  * Generates a representation of {@link Node Nodes} or entire {@link Graph Graphs} in the DOT language that can be
@@ -105,32 +106,34 @@
         }
         int id = node.id();
         String name = "n" + id;
-        NodeArray inputs = node.inputs();
-        NodeArray successors = node.successors();
+        NodeInputsIterable inputs = node.inputs();
+        NodeSuccessorsIterable successors = node.successors();
 
         String color = classColors.get(node.getClass());
 
         if (shortNames) {
-            printNode(name, node.id(), excapeLabel(node.shortName()), color, inputs.size(), successors.size());
+            printNode(name, node.id(), excapeLabel(node.shortName()), color, inputs.explicitCount(), successors.explicitCount());
         } else {
-            printNode(name, node.id(), excapeLabel(node.toString()), color, inputs.size(), successors.size());
+            printNode(name, node.id(), excapeLabel(node.toString()), color, inputs.explicitCount(), successors.explicitCount());
         }
 
-        for (int i = 0; i < successors.size(); ++i) {
-            Node successor = successors.get(i);
+        int i = 0;
+        for (Node successor : successors) {
             if (successor != Node.Null && !omittedClasses.contains(successor.getClass())) {
                 printControlEdge(id, i, successor.id());
             }
+            i++;
         }
 
-        for (int i = 0; i < inputs.size(); ++i) {
-            Node input = inputs.get(i);
+        i = 0;
+        for (Node input : inputs) {
             if (input != Node.Null && !omittedClasses.contains(input.getClass())) {
                 if (node.getClass().getSimpleName().equals("FrameState") && input.getClass().getSimpleName().equals("Local")) {
                     continue;
                 }
                 printDataEdge(id, i, input.id());
             }
+            i++;
         }
     }
 
--- a/graal/com.oracle.max.graal.graphviz/test/com/oracle/graal/graph/vis/GraphvizTest.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.graphviz/test/com/oracle/graal/graph/vis/GraphvizTest.java	Wed Aug 03 11:51:47 2011 +0200
@@ -33,6 +33,10 @@
 
 import com.oracle.max.graal.graph.Graph;
 import com.oracle.max.graal.graph.Node;
+import com.oracle.max.graal.graph.NodeInput;
+import com.oracle.max.graal.graph.NodeInputList;
+import com.oracle.max.graal.graph.NodeSuccessor;
+import com.oracle.max.graal.graph.NodeSuccessorList;
 import com.oracle.max.graal.graphviz.GraphvizPrinter;
 import com.oracle.max.graal.graphviz.GraphvizRunner;
 
@@ -78,39 +82,33 @@
 
     private static class DummyNode extends Node {
 
-        private final int inputCount;
-        private final int successorCount;
-        private final String name;
+        @NodeInput
+        private final NodeInputList<Node> inputs;
+
+        @NodeSuccessor
+        private final NodeSuccessorList<Node> successors;
 
         public DummyNode(String name, int inputCount, int successorCount, Graph graph) {
-            super(inputCount, successorCount, graph);
+            super(graph);
             this.name = name;
-            this.inputCount = inputCount;
-            this.successorCount = successorCount;
+            inputs = new NodeInputList<Node>(this, inputCount);
+            successors = new NodeSuccessorList<Node>(this, successorCount);
+        }
+
+        public void setInput(int idx, Node n) {
+            inputs.set(idx, n);
+        }
+
+        public void setSuccessor(int idx, Node n) {
+            successors.set(idx, n);
         }
 
         @Override
         public Node copy(Graph into) {
-            return new DummyNode(name, inputCount, successorCount, into);
-        }
-
-        public void setInput(int idx, Node n) {
-            inputs().set(idx, n);
+            return new DummyNode(name, inputs.size(), successors.size(), into);
         }
 
-        public void setSuccessor(int idx, Node n) {
-            successors().set(idx, n);
-        }
-
-        @Override
-        protected int inputCount() {
-            return super.inputCount() + inputCount;
-        }
-
-        @Override
-        protected int successorCount() {
-            return super.inputCount() + successorCount;
-        }
+        private final String name;
 
         @Override
         public String toString() {
--- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotRuntime.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotRuntime.java	Wed Aug 03 11:51:47 2011 +0200
@@ -263,7 +263,9 @@
             assert field.kind != CiKind.Illegal;
             ReadNode memoryRead = new ReadNode(field.field().kind().stackKind(), field.object(), LocationNode.create(field.field(), field.field().kind(), displacement, graph), graph);
             memoryRead.setGuard((GuardNode) tool.createGuard(new IsNonNull(field.object(), graph)));
-            memoryRead.setNext(field.next());
+            FixedNode next = field.next();
+            field.setNext(null);
+            memoryRead.setNext(next);
             field.replaceAndDelete(memoryRead);
         } else if (n instanceof StoreField) {
             StoreField field = (StoreField) n;
@@ -275,13 +277,14 @@
             WriteNode memoryWrite = new WriteNode(CiKind.Illegal, field.object(), field.value(), LocationNode.create(field.field(), field.field().kind(), displacement, graph), graph);
             memoryWrite.setGuard((GuardNode) tool.createGuard(new IsNonNull(field.object(), graph)));
             memoryWrite.setStateAfter(field.stateAfter());
-            memoryWrite.setNext(field.next());
+            FixedNode next = field.next();
+            field.setNext(null);
             if (field.field().kind() == CiKind.Object && !field.value().isNullConstant()) {
                 FieldWriteBarrier writeBarrier = new FieldWriteBarrier(field.object(), graph);
                 memoryWrite.setNext(writeBarrier);
-                writeBarrier.setNext(field.next());
+                writeBarrier.setNext(next);
             } else {
-                memoryWrite.setNext(field.next());
+                memoryWrite.setNext(next);
             }
             field.replaceAndDelete(memoryWrite);
         } else if (n instanceof LoadIndexed) {
@@ -294,7 +297,9 @@
             arrayLocation.setIndex(loadIndexed.index());
             ReadNode memoryRead = new ReadNode(elementKind.stackKind(), loadIndexed.array(), arrayLocation, graph);
             memoryRead.setGuard(boundsCheck);
-            memoryRead.setNext(loadIndexed.next());
+            FixedNode next = loadIndexed.next();
+            loadIndexed.setNext(null);
+            memoryRead.setNext(next);
             loadIndexed.replaceAndDelete(memoryRead);
         } else if (n instanceof StoreIndexed) {
             StoreIndexed storeIndexed = (StoreIndexed) n;
@@ -327,13 +332,15 @@
             WriteNode memoryWrite = new WriteNode(elementKind.stackKind(), array, value, arrayLocation, graph);
             memoryWrite.setGuard(boundsCheck);
             memoryWrite.setStateAfter(storeIndexed.stateAfter());
+            FixedNode next = storeIndexed.next();
+            storeIndexed.setNext(null);
             anchor.setNext(memoryWrite);
             if (elementKind == CiKind.Object && !value.isNullConstant()) {
                 ArrayWriteBarrier writeBarrier = new ArrayWriteBarrier(array, arrayLocation, graph);
                 memoryWrite.setNext(writeBarrier);
-                writeBarrier.setNext(storeIndexed.next());
+                writeBarrier.setNext(next);
             } else {
-                memoryWrite.setNext(storeIndexed.next());
+                memoryWrite.setNext(next);
             }
             storeIndexed.replaceAtPredecessors(anchor);
             storeIndexed.delete();
--- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/nodes/CurrentThread.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/nodes/CurrentThread.java	Wed Aug 03 11:51:47 2011 +0200
@@ -31,12 +31,11 @@
 
 
 public final class CurrentThread extends FloatingNode {
-    private static final int INPUT_COUNT = 0;
-    private static final int SUCCESSOR_COUNT = 0;
+
     private int threadObjectOffset;
 
     public CurrentThread(int threadObjectOffset, Graph graph) {
-        super(CiKind.Object, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+        super(CiKind.Object, graph);
         this.threadObjectOffset = threadObjectOffset;
     }
 
--- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/nodes/FPConversionNode.java	Thu Jul 28 08:18:43 2011 +0200
+++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/nodes/FPConversionNode.java	Wed Aug 03 11:51:47 2011 +0200
@@ -30,29 +30,21 @@
 
 
 public final class FPConversionNode extends FloatingNode {
-    private static final int INPUT_COUNT = 1;
-    private static final int INPUT_OBJECT = 0;
 
-    private static final int SUCCESSOR_COUNT = 0;
+    @NodeInput
+    private Value value;
 
-    @Override
-    protected int inputCount() {
-        return super.inputCount() + INPUT_COUNT;
+    public Value value() {
+        return value;
     }
 
-    /**
-     * The instruction that produces the object tested against null.
-     */
-     public Value value() {
-        return (Value) inputs().get(super.inputCount() + INPUT_OBJECT);
-    }
-
-    public void setValue(Value n) {
-        inputs().set(super.inputCount() + INPUT_OBJECT, n);
+    public void setValue(Value x) {
+        updateUsages(value, x);
+        value = x;
     }
 
     public FPConversionNode(CiKind kind, Value value, Graph graph) {
-        super(kind, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+        super(kind, graph);
         this.setValue(value);
     }