changeset 9662:eade47d311a3

Merge.
author Doug Simon <doug.simon@oracle.com>
date Mon, 13 May 2013 14:17:35 +0200
parents c6f3c1e48f54 (current diff) 309181f26fc7 (diff)
children 822adbb2ee7b 86fa3d9f9fdd
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java
diffstat 49 files changed, 463 insertions(+), 412 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Register.java	Mon May 13 13:59:34 2013 +0200
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Register.java	Mon May 13 14:17:35 2013 +0200
@@ -96,29 +96,16 @@
 
         @Override
         public int hashCode() {
-            return 31 + ((name == null) ? 0 : name.hashCode());
+            return 23 + name.hashCode();
         }
 
         @Override
         public boolean equals(Object obj) {
-            if (this == obj) {
-                return true;
-            }
-            if (obj == null) {
-                return false;
-            }
-            if (getClass() != obj.getClass()) {
-                return false;
+            if (obj instanceof RegisterCategory) {
+                RegisterCategory other = (RegisterCategory) obj;
+                return name.equals(other.name);
             }
-            RegisterCategory other = (RegisterCategory) obj;
-            if (name == null) {
-                if (other.name != null) {
-                    return false;
-                }
-            } else if (!name.equals(other.name)) {
-                return false;
-            }
-            return true;
+            return false;
         }
     }
 
@@ -219,48 +206,21 @@
 
     @Override
     public int hashCode() {
-        final int prime = 31;
+        final int prime = 17;
         int result = 1;
         result = prime * result + encoding;
-        result = prime * result + ((name == null) ? 0 : name.hashCode());
+        result = prime * result + name.hashCode();
         result = prime * result + number;
-        result = prime * result + ((registerCategory == null) ? 0 : registerCategory.hashCode());
+        result = prime * result + registerCategory.hashCode();
         return result;
     }
 
     @Override
     public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj == null) {
-            return false;
-        }
-        if (getClass() != obj.getClass()) {
-            return false;
-        }
-        Register other = (Register) obj;
-        if (encoding != other.encoding) {
-            return false;
+        if (obj instanceof Register) {
+            Register other = (Register) obj;
+            return encoding == other.encoding && name.equals(other.name) && number == other.number && registerCategory.equals(registerCategory);
         }
-        if (name == null) {
-            if (other.name != null) {
-                return false;
-            }
-        } else if (!name.equals(other.name)) {
-            return false;
-        }
-        if (number != other.number) {
-            return false;
-        }
-        if (registerCategory == null) {
-            if (other.registerCategory != null) {
-                return false;
-            }
-        } else if (!registerCategory.equals(other.registerCategory)) {
-            return false;
-        }
-        return true;
+        return false;
     }
-
 }
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/RegisterValue.java	Mon May 13 13:59:34 2013 +0200
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/RegisterValue.java	Mon May 13 14:17:35 2013 +0200
@@ -58,28 +58,15 @@
 
     @Override
     public int hashCode() {
-        return 31 * super.hashCode() + ((reg == null) ? 0 : reg.hashCode());
+        return 29 * super.hashCode() + reg.hashCode();
     }
 
     @Override
     public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (!super.equals(obj)) {
-            return false;
-        }
-        if (getClass() != obj.getClass()) {
-            return false;
+        if (obj instanceof RegisterValue) {
+            RegisterValue other = (RegisterValue) obj;
+            return super.equals(obj) && reg.equals(other.reg);
         }
-        RegisterValue other = (RegisterValue) obj;
-        if (reg == null) {
-            if (other.reg != null) {
-                return false;
-            }
-        } else if (!reg.equals(other.reg)) {
-            return false;
-        }
-        return true;
+        return false;
     }
 }
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/StackSlot.java	Mon May 13 13:59:34 2013 +0200
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/StackSlot.java	Mon May 13 14:17:35 2013 +0200
@@ -118,7 +118,7 @@
 
     @Override
     public int hashCode() {
-        final int prime = 31;
+        final int prime = 37;
         int result = super.hashCode();
         result = prime * result + (addFrameSize ? 1231 : 1237);
         result = prime * result + offset;
@@ -127,22 +127,10 @@
 
     @Override
     public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (!super.equals(obj)) {
-            return false;
-        }
-        if (getClass() != obj.getClass()) {
-            return false;
+        if (obj instanceof StackSlot) {
+            StackSlot other = (StackSlot) obj;
+            return super.equals(obj) && addFrameSize == other.addFrameSize && offset == other.offset;
         }
-        StackSlot other = (StackSlot) obj;
-        if (addFrameSize != other.addFrameSize) {
-            return false;
-        }
-        if (offset != other.offset) {
-            return false;
-        }
-        return true;
+        return false;
     }
 }
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Value.java	Mon May 13 13:59:34 2013 +0200
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Value.java	Mon May 13 14:17:35 2013 +0200
@@ -81,35 +81,19 @@
 
     @Override
     public int hashCode() {
-        final int prime = 31;
+        final int prime = 41;
         int result = 1;
-        result = prime * result + ((kind == null) ? 0 : kind.hashCode());
-        result = prime * result + ((platformKind == null) ? 0 : platformKind.hashCode());
+        result = prime * result + kind.hashCode();
+        result = prime * result + platformKind.hashCode();
         return result;
     }
 
     @Override
     public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj == null) {
-            return false;
-        }
-        if (getClass() != obj.getClass()) {
-            return false;
+        if (obj instanceof Value) {
+            Value other = (Value) obj;
+            return kind.equals(other.kind) && platformKind.equals(platformKind);
         }
-        Value other = (Value) obj;
-        if (kind != other.kind) {
-            return false;
-        }
-        if (platformKind == null) {
-            if (other.platformKind != null) {
-                return false;
-            }
-        } else if (!platformKind.equals(other.platformKind)) {
-            return false;
-        }
-        return true;
+        return false;
     }
 }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Mon May 13 13:59:34 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Mon May 13 14:17:35 2013 +0200
@@ -44,6 +44,7 @@
 import com.oracle.graal.phases.graph.*;
 import com.oracle.graal.phases.schedule.*;
 import com.oracle.graal.phases.tiers.*;
+import com.oracle.graal.phases.verify.*;
 import com.oracle.graal.virtual.phases.ea.*;
 
 /**
@@ -124,6 +125,7 @@
         } else {
             Debug.dump(graph, "initial state");
         }
+        new VerifyValueUsage(runtime).apply(graph);
 
         if (GraalOptions.OptCanonicalizer) {
             new CanonicalizerPhase.Instance(runtime, assumptions).apply(graph);
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScanWalker.java	Mon May 13 13:59:34 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScanWalker.java	Mon May 13 14:17:35 2013 +0200
@@ -936,7 +936,7 @@
         if (interval.insertMoveWhenActivated()) {
             assert interval.isSplitChild();
             assert interval.currentSplitChild() != null;
-            assert interval.currentSplitChild().operand != operand : "cannot insert move between same interval";
+            assert !interval.currentSplitChild().operand.equals(operand) : "cannot insert move between same interval";
             if (GraalOptions.TraceLinearScanLevel >= 4) {
                 TTY.println("Inserting move from interval %d to %d because insertMoveWhenActivated is set", interval.currentSplitChild().operandNumber, interval.operandNumber);
             }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/MoveResolver.java	Mon May 13 13:59:34 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/MoveResolver.java	Mon May 13 14:17:35 2013 +0200
@@ -192,7 +192,7 @@
     }
 
     private void insertMove(Interval fromInterval, Interval toInterval) {
-        assert fromInterval.operand != toInterval.operand : "from and to interval equal: " + fromInterval;
+        assert !fromInterval.operand.equals(toInterval.operand) : "from and to interval equal: " + fromInterval;
         assert fromInterval.kind() == toInterval.kind() : "move between different types";
         assert insertIdx != -1 : "must setup insert position first";
 
@@ -331,7 +331,7 @@
             TTY.println("MoveResolver: adding mapping from interval %d (%s) to interval %d (%s)", fromInterval.operandNumber, fromInterval.location(), toInterval.operandNumber, toInterval.location());
         }
 
-        assert fromInterval.operand != toInterval.operand : "from and to interval equal: " + fromInterval;
+        assert !fromInterval.operand.equals(toInterval.operand) : "from and to interval equal: " + fromInterval;
         assert fromInterval.kind() == toInterval.kind();
         mappingFrom.add(fromInterval);
         mappingFromOpr.add(Value.ILLEGAL);
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java	Mon May 13 13:59:34 2013 +0200
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java	Mon May 13 14:17:35 2013 +0200
@@ -192,7 +192,7 @@
                 if (INPUT_LIST_CLASS.isAssignableFrom(type)) {
                     inputListOffsets.add(offset);
                 } else {
-                    assert NODE_CLASS.isAssignableFrom(type) : "invalid input type: " + type;
+                    assert NODE_CLASS.isAssignableFrom(type) || type.isInterface() : "invalid input type: " + type;
                     inputOffsets.add(offset);
                 }
                 if (field.getAnnotation(Node.Input.class).notDataflow()) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMonitorValue.java	Mon May 13 13:59:34 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMonitorValue.java	Mon May 13 14:17:35 2013 +0200
@@ -66,43 +66,20 @@
 
     @Override
     public int hashCode() {
-        final int prime = 31;
+        final int prime = 43;
         int result = super.hashCode();
         result = prime * result + (eliminated ? 1231 : 1237);
-        result = prime * result + ((owner == null) ? 0 : owner.hashCode());
-        result = prime * result + ((slot == null) ? 0 : slot.hashCode());
+        result = prime * result + owner.hashCode();
+        result = prime * result + slot.hashCode();
         return result;
     }
 
     @Override
     public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (!super.equals(obj)) {
-            return false;
-        }
-        if (getClass() != obj.getClass()) {
-            return false;
-        }
-        HotSpotMonitorValue other = (HotSpotMonitorValue) obj;
-        if (eliminated != other.eliminated) {
-            return false;
+        if (obj instanceof HotSpotMonitorValue) {
+            HotSpotMonitorValue other = (HotSpotMonitorValue) obj;
+            return super.equals(obj) && eliminated == other.eliminated && owner.equals(other.owner) && slot.equals(other.slot);
         }
-        if (owner == null) {
-            if (other.owner != null) {
-                return false;
-            }
-        } else if (!owner.equals(other.owner)) {
-            return false;
-        }
-        if (slot == null) {
-            if (other.slot != null) {
-                return false;
-            }
-        } else if (!slot.equals(other.slot)) {
-            return false;
-        }
-        return true;
+        return false;
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Mon May 13 13:59:34 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Mon May 13 14:17:35 2013 +0200
@@ -754,7 +754,7 @@
             ArrayLengthNode arrayLengthNode = (ArrayLengthNode) n;
             ValueNode array = arrayLengthNode.array();
             ReadNode arrayLengthRead = graph.add(new ReadNode(array, ConstantLocationNode.create(LocationNode.FINAL_LOCATION, Kind.Int, config.arrayLengthOffset, graph), StampFactory.positiveInt()));
-            tool.createNullCheckGuard(arrayLengthRead.dependencies(), array);
+            tool.createNullCheckGuard(arrayLengthRead, array);
             graph.replaceFixedWithFixed(arrayLengthNode, arrayLengthRead);
         } else if (n instanceof Invoke) {
             Invoke invoke = (Invoke) n;
@@ -763,7 +763,7 @@
                 NodeInputList<ValueNode> parameters = callTarget.arguments();
                 ValueNode receiver = parameters.size() <= 0 ? null : parameters.get(0);
                 if (!callTarget.isStatic() && receiver.kind() == Kind.Object && !receiver.objectStamp().nonNull()) {
-                    tool.createNullCheckGuard(invoke.asNode().dependencies(), receiver);
+                    tool.createNullCheckGuard(invoke, receiver);
                 }
                 JavaType[] signature = MetaUtil.signatureToTypes(callTarget.targetMethod().getSignature(), callTarget.isStatic() ? null : callTarget.targetMethod().getDeclaringClass());
 
@@ -805,7 +805,7 @@
             ValueNode object = loadField.isStatic() ? ConstantNode.forObject(field.getDeclaringClass().mirror(), this, graph) : loadField.object();
             assert loadField.kind() != Kind.Illegal;
             ReadNode memoryRead = graph.add(new ReadNode(object, createFieldLocation(graph, field), loadField.stamp()));
-            tool.createNullCheckGuard(memoryRead.dependencies(), object);
+            tool.createNullCheckGuard(memoryRead, object);
 
             graph.replaceFixedWithFixed(loadField, memoryRead);
 
@@ -821,7 +821,7 @@
             ValueNode object = storeField.isStatic() ? ConstantNode.forObject(field.getDeclaringClass().mirror(), this, graph) : storeField.object();
             WriteBarrierType barrierType = getFieldStoreBarrierType(storeField);
             WriteNode memoryWrite = graph.add(new WriteNode(object, storeField.value(), createFieldLocation(graph, field), barrierType));
-            tool.createNullCheckGuard(memoryWrite.dependencies(), object);
+            tool.createNullCheckGuard(memoryWrite, object);
             memoryWrite.setStateAfter(storeField.stateAfter());
             graph.replaceFixedWithFixed(storeField, memoryWrite);
             FixedWithNextNode last = memoryWrite;
@@ -841,15 +841,15 @@
             cas.setWriteBarrierType(getCompareAndSwapBarrier(cas));
         } else if (n instanceof LoadIndexedNode) {
             LoadIndexedNode loadIndexed = (LoadIndexedNode) n;
-            ValueNode boundsCheck = createBoundsCheck(loadIndexed, tool);
+            GuardingNode boundsCheck = createBoundsCheck(loadIndexed, tool);
             Kind elementKind = loadIndexed.elementKind();
             LocationNode arrayLocation = createArrayLocation(graph, elementKind, loadIndexed.index());
             ReadNode memoryRead = graph.add(new ReadNode(loadIndexed.array(), arrayLocation, loadIndexed.stamp()));
-            memoryRead.dependencies().add(boundsCheck);
+            memoryRead.setGuard(boundsCheck);
             graph.replaceFixedWithFixed(loadIndexed, memoryRead);
         } else if (n instanceof StoreIndexedNode) {
             StoreIndexedNode storeIndexed = (StoreIndexedNode) n;
-            ValueNode boundsCheck = createBoundsCheck(storeIndexed, tool);
+            GuardingNode boundsCheck = createBoundsCheck(storeIndexed, tool);
             Kind elementKind = storeIndexed.elementKind();
             LocationNode arrayLocation = createArrayLocation(graph, elementKind, storeIndexed.index());
             ValueNode value = storeIndexed.value();
@@ -876,7 +876,7 @@
             }
             WriteBarrierType barrierType = getArrayStoreBarrierType(storeIndexed);
             WriteNode memoryWrite = graph.add(new WriteNode(array, value, arrayLocation, barrierType));
-            memoryWrite.dependencies().add(boundsCheck);
+            memoryWrite.setGuard(boundsCheck);
             memoryWrite.setStateAfter(storeIndexed.stateAfter());
             graph.replaceFixedWithFixed(storeIndexed, memoryWrite);
 
@@ -887,7 +887,7 @@
             ReadNode memoryRead = graph.add(new ReadNode(load.object(), location, load.stamp()));
             // An unsafe read must not floating outside its block as may float above an explicit
             // null check on its object.
-            memoryRead.dependencies().add(AbstractBeginNode.prevBegin(load));
+            memoryRead.setGuard(AbstractBeginNode.prevBegin(load));
             graph.replaceFixedWithFixed(load, memoryRead);
         } else if (n instanceof UnsafeStoreNode) {
             UnsafeStoreNode store = (UnsafeStoreNode) n;
@@ -910,7 +910,7 @@
             graph.replaceFixed(loadMethodNode, metaspaceMethod);
         } else if (n instanceof FixedGuardNode) {
             FixedGuardNode node = (FixedGuardNode) n;
-            ValueAnchorNode newAnchor = graph.add(new ValueAnchorNode(tool.createGuard(node.condition(), node.getReason(), node.getAction(), node.isNegated())));
+            ValueAnchorNode newAnchor = graph.add(new ValueAnchorNode(tool.createGuard(node.condition(), node.getReason(), node.getAction(), node.isNegated()).asNode()));
             graph.replaceFixedWithFixed(node, newAnchor);
         } else if (n instanceof CommitAllocationNode) {
             CommitAllocationNode commit = (CommitAllocationNode) n;
@@ -1062,7 +1062,7 @@
         LocationNode location = ConstantLocationNode.create(LocationNode.FINAL_LOCATION, wordKind, config.hubOffset, graph);
         assert !object.isConstant() || object.asConstant().isNull();
         ReadNode hub = graph.add(new ReadNode(object, location, StampFactory.forKind(wordKind())));
-        tool.createNullCheckGuard(hub.dependencies(), object);
+        tool.createNullCheckGuard(hub, object);
         return hub;
     }
 
@@ -1117,10 +1117,10 @@
         return IndexedLocationNode.create(LocationNode.getArrayLocation(elementKind), elementKind, getArrayBaseOffset(elementKind), index, graph, scale);
     }
 
-    private static ValueNode createBoundsCheck(AccessIndexedNode n, LoweringTool tool) {
+    private static GuardingNode createBoundsCheck(AccessIndexedNode n, LoweringTool tool) {
         StructuredGraph graph = n.graph();
         ArrayLengthNode arrayLength = graph.add(new ArrayLengthNode(n.array()));
-        ValueNode guard = tool.createGuard(graph.unique(new IntegerBelowThanNode(n.index(), arrayLength)), BoundsCheckException, InvalidateReprofile);
+        GuardingNode guard = tool.createGuard(graph.unique(new IntegerBelowThanNode(n.index(), arrayLength)), BoundsCheckException, InvalidateReprofile);
 
         graph.addBeforeFixed(n, arrayLength);
         return guard;
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValue.java	Mon May 13 13:59:34 2013 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValue.java	Mon May 13 14:17:35 2013 +0200
@@ -61,31 +61,15 @@
 
     @Override
     public int hashCode() {
-        final int prime = 31;
-        int result = super.hashCode();
-        result = prime * result + ((valueClass == null) ? 0 : valueClass.hashCode());
-        return result;
+        return 53 * super.hashCode() + valueClass.hashCode();
     }
 
     @Override
     public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (!super.equals(obj)) {
-            return false;
-        }
-        if (getClass() != obj.getClass()) {
-            return false;
+        if (obj instanceof CompositeValue) {
+            CompositeValue other = (CompositeValue) obj;
+            return super.equals(other) && valueClass.equals(other.valueClass);
         }
-        CompositeValue other = (CompositeValue) obj;
-        if (valueClass == null) {
-            if (other.valueClass != null) {
-                return false;
-            }
-        } else if (!valueClass.equals(other.valueClass)) {
-            return false;
-        }
-        return true;
+        return false;
     }
 }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/Variable.java	Mon May 13 13:59:34 2013 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/Variable.java	Mon May 13 14:17:35 2013 +0200
@@ -57,24 +57,15 @@
 
     @Override
     public int hashCode() {
-        return 31 * super.hashCode() + index;
+        return 71 * super.hashCode() + index;
     }
 
     @Override
     public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (!super.equals(obj)) {
-            return false;
+        if (obj instanceof Variable) {
+            Variable other = (Variable) obj;
+            return super.equals(other) && index == other.index;
         }
-        if (getClass() != obj.getClass()) {
-            return false;
-        }
-        Variable other = (Variable) obj;
-        if (index != other.index) {
-            return false;
-        }
-        return true;
+        return false;
     }
 }
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/CountedLoopInfo.java	Mon May 13 13:59:34 2013 +0200
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/CountedLoopInfo.java	Mon May 13 14:17:35 2013 +0200
@@ -30,6 +30,7 @@
 import com.oracle.graal.loop.InductionVariable.Direction;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.extended.*;
 
 public class CountedLoopInfo {
 
@@ -37,7 +38,6 @@
     private InductionVariable iv;
     private ValueNode end;
     private boolean oneOff;
-    private ValueNode overflowGuard;
     private AbstractBeginNode body;
 
     CountedLoopInfo(LoopEx loop, InductionVariable iv, ValueNode end, boolean oneOff, AbstractBeginNode body) {
@@ -126,28 +126,35 @@
         return iv.direction();
     }
 
-    public ValueNode getOverFlowGuard() {
-        if (overflowGuard == null) {
-            Kind kind = iv.valueNode().kind();
-            Graph graph = iv.valueNode().graph();
-            CompareNode cond; // we use a negated guard with a < condition to achieve a >=
-            ConstantNode one = ConstantNode.forIntegerKind(kind, 1, graph);
-            if (iv.direction() == Direction.Up) {
-                IntegerArithmeticNode v1 = sub(ConstantNode.forIntegerKind(kind, kind.getMaxValue(), graph), sub(iv.strideNode(), one));
-                if (oneOff) {
-                    v1 = sub(v1, one);
-                }
-                cond = graph.unique(new IntegerLessThanNode(v1, end));
-            } else {
-                assert iv.direction() == Direction.Down;
-                IntegerArithmeticNode v1 = add(ConstantNode.forIntegerKind(kind, kind.getMinValue(), graph), sub(one, iv.strideNode()));
-                if (oneOff) {
-                    v1 = add(v1, one);
-                }
-                cond = graph.unique(new IntegerLessThanNode(end, v1));
+    public GuardingNode getOverFlowGuard() {
+        return loop.loopBegin().getOverflowGuard();
+    }
+
+    public GuardingNode createOverFlowGuard() {
+        GuardingNode overflowGuard = getOverFlowGuard();
+        if (overflowGuard != null) {
+            return overflowGuard;
+        }
+        Kind kind = iv.valueNode().kind();
+        Graph graph = iv.valueNode().graph();
+        CompareNode cond; // we use a negated guard with a < condition to achieve a >=
+        ConstantNode one = ConstantNode.forIntegerKind(kind, 1, graph);
+        if (iv.direction() == Direction.Up) {
+            IntegerArithmeticNode v1 = sub(ConstantNode.forIntegerKind(kind, kind.getMaxValue(), graph), sub(iv.strideNode(), one));
+            if (oneOff) {
+                v1 = sub(v1, one);
             }
-            overflowGuard = graph.unique(new GuardNode(cond, BeginNode.prevBegin(loop.entryPoint()), DeoptimizationReason.LoopLimitCheck, DeoptimizationAction.InvalidateRecompile, true));
+            cond = graph.unique(new IntegerLessThanNode(v1, end));
+        } else {
+            assert iv.direction() == Direction.Down;
+            IntegerArithmeticNode v1 = add(ConstantNode.forIntegerKind(kind, kind.getMinValue(), graph), sub(one, iv.strideNode()));
+            if (oneOff) {
+                v1 = add(v1, one);
+            }
+            cond = graph.unique(new IntegerLessThanNode(end, v1));
         }
+        overflowGuard = graph.unique(new GuardNode(cond, BeginNode.prevBegin(loop.entryPoint()), DeoptimizationReason.LoopLimitCheck, DeoptimizationAction.InvalidateRecompile, true));
+        loop.loopBegin().setOverflowGuard(overflowGuard);
         return overflowGuard;
     }
 
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopSafepointEliminationPhase.java	Mon May 13 13:59:34 2013 +0200
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopSafepointEliminationPhase.java	Mon May 13 14:17:35 2013 +0200
@@ -39,7 +39,7 @@
             loops.detectedCountedLoops();
             for (LoopEx loop : loops.countedLoops()) {
                 if (loop.lirLoop().children.isEmpty() && loop.counted().getKind() == Kind.Int) {
-                    loop.loopBegin().dependencies().add(loop.counted().getOverFlowGuard());
+                    loop.counted().createOverFlowGuard();
                     for (LoopEndNode loopEnd : loop.loopBegin().loopEnds()) {
                         loopEnd.disableSafepoint();
                     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractBeginNode.java	Mon May 13 13:59:34 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractBeginNode.java	Mon May 13 14:17:35 2013 +0200
@@ -28,10 +28,11 @@
 
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.iterators.*;
+import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 
-public abstract class AbstractBeginNode extends FixedWithNextNode implements StateSplit, LIRLowerable, Simplifiable, Node.IterableNodeType {
+public abstract class AbstractBeginNode extends FixedWithNextNode implements StateSplit, LIRLowerable, Simplifiable, Node.IterableNodeType, GuardingNode {
 
     @Input(notDataflow = true) private FrameState stateAfter;
 
@@ -184,4 +185,9 @@
             throw new UnsupportedOperationException();
         }
     }
+
+    @Override
+    public AbstractBeginNode asNode() {
+        return this;
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizingFixedWithNextNode.java	Mon May 13 13:59:34 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizingFixedWithNextNode.java	Mon May 13 14:17:35 2013 +0200
@@ -22,8 +22,6 @@
  */
 package com.oracle.graal.nodes;
 
-import java.util.*;
-
 import com.oracle.graal.nodes.type.*;
 
 public abstract class DeoptimizingFixedWithNextNode extends FixedWithNextNode implements DeoptimizingNode {
@@ -34,14 +32,6 @@
         super(stamp);
     }
 
-    public DeoptimizingFixedWithNextNode(Stamp stamp, List<ValueNode> dependencies) {
-        super(stamp, dependencies);
-    }
-
-    public DeoptimizingFixedWithNextNode(Stamp stamp, ValueNode... dependencies) {
-        super(stamp, dependencies);
-    }
-
     @Override
     public FrameState getDeoptimizationState() {
         return deoptState;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedNode.java	Mon May 13 13:59:34 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedNode.java	Mon May 13 14:17:35 2013 +0200
@@ -22,8 +22,6 @@
  */
 package com.oracle.graal.nodes;
 
-import java.util.*;
-
 import com.oracle.graal.nodes.type.*;
 
 public abstract class FixedNode extends ValueNode {
@@ -32,14 +30,6 @@
         super(stamp);
     }
 
-    public FixedNode(Stamp stamp, List<ValueNode> dependencies) {
-        super(stamp, dependencies);
-    }
-
-    public FixedNode(Stamp stamp, ValueNode... dependencies) {
-        super(stamp, dependencies);
-    }
-
     @Override
     public boolean verify() {
         assertTrue(this.successors().isNotEmpty() || this.predecessor() != null, "FixedNode should not float");
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedWithNextNode.java	Mon May 13 13:59:34 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedWithNextNode.java	Mon May 13 14:17:35 2013 +0200
@@ -22,8 +22,6 @@
  */
 package com.oracle.graal.nodes;
 
-import java.util.*;
-
 import com.oracle.graal.nodes.type.*;
 
 /**
@@ -44,12 +42,4 @@
     public FixedWithNextNode(Stamp stamp) {
         super(stamp);
     }
-
-    public FixedWithNextNode(Stamp stamp, List<ValueNode> dependencies) {
-        super(stamp, dependencies);
-    }
-
-    public FixedWithNextNode(Stamp stamp, ValueNode... dependencies) {
-        super(stamp, dependencies);
-    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FloatingGuardedNode.java	Mon May 13 14:17:35 2013 +0200
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.nodes;
+
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.type.*;
+
+public abstract class FloatingGuardedNode extends FloatingNode implements GuardedNode {
+
+    @Input private GuardingNode guard;
+
+    public FloatingGuardedNode(Stamp stamp) {
+        super(stamp);
+    }
+
+    public FloatingGuardedNode(Stamp stamp, GuardingNode guard) {
+        super(stamp);
+        this.guard = guard;
+    }
+
+    @Override
+    public GuardingNode getGuard() {
+        return guard;
+    }
+
+    @Override
+    public void setGuard(GuardingNode guard) {
+        updateUsages(this.guard == null ? null : this.guard.asNode(), guard == null ? null : guard.asNode());
+        this.guard = guard;
+    }
+
+    @Override
+    public FloatingNode asNode() {
+        return this;
+    }
+
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java	Mon May 13 13:59:34 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java	Mon May 13 14:17:35 2013 +0200
@@ -25,7 +25,7 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
-import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 
@@ -42,14 +42,14 @@
  * control flow would have reached the guarded node (without taking exceptions into account).
  */
 @NodeInfo(nameTemplate = "Guard(!={p#negated}) {p#reason/s}")
-public final class GuardNode extends FloatingNode implements Canonicalizable, Node.IterableNodeType, Negatable {
+public final class GuardNode extends FloatingGuardedNode implements Canonicalizable, Node.IterableNodeType, Negatable, GuardingNode, GuardedNode {
 
     @Input private LogicNode condition;
     private final DeoptimizationReason reason;
     private final DeoptimizationAction action;
     private boolean negated;
 
-    public GuardNode(LogicNode condition, FixedNode anchor, DeoptimizationReason reason, DeoptimizationAction action, boolean negated) {
+    public GuardNode(LogicNode condition, GuardingNode anchor, DeoptimizationReason reason, DeoptimizationAction action, boolean negated) {
         super(StampFactory.dependency(), anchor);
         this.condition = condition;
         this.reason = reason;
@@ -95,9 +95,7 @@
         if (condition() instanceof LogicConstantNode) {
             LogicConstantNode c = (LogicConstantNode) condition();
             if (c.getValue() != negated) {
-                if (dependencies().size() == 1) {
-                    return dependencies().get(0);
-                }
+                return getGuard().asNode();
             }
         }
         return this;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/Invoke.java	Mon May 13 13:59:34 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/Invoke.java	Mon May 13 14:17:35 2013 +0200
@@ -23,9 +23,10 @@
 package com.oracle.graal.nodes;
 
 import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
 
-public interface Invoke extends StateSplit, Lowerable, DeoptimizingNode {
+public interface Invoke extends StateSplit, Lowerable, DeoptimizingNode, GuardedNode {
 
     FixedNode next();
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java	Mon May 13 13:59:34 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java	Mon May 13 14:17:35 2013 +0200
@@ -39,6 +39,7 @@
 
     @Input private final CallTargetNode callTarget;
     @Input private FrameState deoptState;
+    @Input private GuardingNode guard;
     private final int bci;
     private boolean polymorphic;
     private boolean useForInlining;
@@ -188,4 +189,15 @@
     public boolean isCallSiteDeoptimization() {
         return true;
     }
+
+    @Override
+    public GuardingNode getGuard() {
+        return guard;
+    }
+
+    @Override
+    public void setGuard(GuardingNode guard) {
+        updateUsages(this.guard == null ? null : this.guard.asNode(), guard == null ? null : guard.asNode());
+        this.guard = guard;
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java	Mon May 13 13:59:34 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java	Mon May 13 14:17:35 2013 +0200
@@ -40,6 +40,7 @@
     @Input private final CallTargetNode callTarget;
     @Input private FrameState deoptState;
     @Input private FrameState stateAfter;
+    @Input private GuardingNode guard;
     private final int bci;
     private boolean polymorphic;
     private boolean useForInlining;
@@ -239,4 +240,15 @@
     public boolean isCallSiteDeoptimization() {
         return true;
     }
+
+    @Override
+    public GuardingNode getGuard() {
+        return guard;
+    }
+
+    @Override
+    public void setGuard(GuardingNode guard) {
+        updateUsages(this.guard == null ? null : this.guard.asNode(), guard == null ? null : guard.asNode());
+        this.guard = guard;
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicNode.java	Mon May 13 13:59:34 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicNode.java	Mon May 13 14:17:35 2013 +0200
@@ -29,8 +29,8 @@
 
 public abstract class LogicNode extends FloatingNode {
 
-    public LogicNode(ValueNode... dependencies) {
-        super(StampFactory.condition(), dependencies);
+    public LogicNode() {
+        super(StampFactory.condition());
     }
 
     /**
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java	Mon May 13 13:59:34 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java	Mon May 13 14:17:35 2013 +0200
@@ -28,6 +28,7 @@
 
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.iterators.*;
+import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
 
 public class LoopBeginNode extends MergeNode implements Node.IterableNodeType, LIRLowerable {
@@ -35,6 +36,7 @@
     private double loopFrequency;
     private int nextEndIndex;
     private int unswitches;
+    @Input private GuardingNode overflowGuard;
 
     public LoopBeginNode() {
         loopFrequency = 1;
@@ -183,4 +185,13 @@
             graph().replaceFixedWithFixed(loopexit, graph().add(new BeginNode()));
         }
     }
+
+    public GuardingNode getOverflowGuard() {
+        return overflowGuard;
+    }
+
+    public void setOverflowGuard(GuardingNode overflowGuard) {
+        updateUsages(this.overflowGuard == null ? null : this.overflowGuard.asNode(), overflowGuard == null ? null : overflowGuard.asNode());
+        this.overflowGuard = overflowGuard;
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PhiNode.java	Mon May 13 13:59:34 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PhiNode.java	Mon May 13 14:17:35 2013 +0200
@@ -25,6 +25,7 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 
@@ -33,7 +34,7 @@
  * variable.
  */
 @NodeInfo(nameTemplate = "{p#type/s}Phi({i#values})")
-public final class PhiNode extends FloatingNode implements Canonicalizable, Node.IterableNodeType {
+public final class PhiNode extends FloatingNode implements Canonicalizable, Node.IterableNodeType, GuardingNode {
 
     public static enum PhiType {
         Value(null), // normal value phis
@@ -251,4 +252,9 @@
     public boolean isLoopPhi() {
         return merge() instanceof LoopBeginNode;
     }
+
+    @Override
+    public PhiNode asNode() {
+        return this;
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java	Mon May 13 13:59:34 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java	Mon May 13 14:17:35 2013 +0200
@@ -22,8 +22,9 @@
  */
 package com.oracle.graal.nodes;
 
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
-import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 
@@ -31,9 +32,10 @@
  * A node that changes the type of its input, usually narrowing it. For example, a PI node refines
  * the type of a receiver during type-guarded inlining to be the type tested by the guard.
  */
-public class PiNode extends FloatingNode implements LIRLowerable, Virtualizable, Node.IterableNodeType {
+public class PiNode extends FloatingGuardedNode implements LIRLowerable, Virtualizable, Node.IterableNodeType, GuardingNode {
 
     @Input private ValueNode object;
+    @Input private FixedNode anchor;
 
     public ValueNode object() {
         return object;
@@ -44,20 +46,22 @@
         this.object = object;
     }
 
-    public PiNode(ValueNode object, Stamp stamp, ValueNode anchor) {
-        super(stamp, anchor);
-        assert anchor instanceof FixedNode;
+    public PiNode(ValueNode object, Stamp stamp, FixedNode anchor) {
+        super(stamp);
         this.object = object;
+        this.anchor = anchor;
     }
 
     @Override
     public void generate(LIRGeneratorTool generator) {
-        generator.setResult(this, generator.operand(object));
+        if (object.kind() != Kind.Void && object.kind() != Kind.Illegal) {
+            generator.setResult(this, generator.operand(object));
+        }
     }
 
     @Override
     public boolean inferStamp() {
-        if (object().objectStamp().alwaysNull() && objectStamp().nonNull()) {
+        if (stamp() instanceof ObjectStamp && object().objectStamp().alwaysNull() && objectStamp().nonNull()) {
             // a null value flowing into a nonNull PiNode should be guarded by a type/isNull guard,
             // but the
             // compiler might see this situation before the branch is deleted
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java	Mon May 13 13:59:34 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java	Mon May 13 14:17:35 2013 +0200
@@ -22,8 +22,6 @@
  */
 package com.oracle.graal.nodes;
 
-import java.util.*;
-
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.iterators.*;
@@ -42,28 +40,8 @@
      */
     private Stamp stamp;
 
-    @Input(notDataflow = true) private final NodeInputList<ValueNode> dependencies;
-
-    /**
-     * This collection keeps dependencies that should be observed while scheduling (guards, etc.).
-     */
-    public NodeInputList<ValueNode> dependencies() {
-        return dependencies;
-    }
-
     public ValueNode(Stamp stamp) {
         this.stamp = stamp;
-        this.dependencies = new NodeInputList<>(this);
-    }
-
-    public ValueNode(Stamp stamp, ValueNode... dependencies) {
-        this.stamp = stamp;
-        this.dependencies = new NodeInputList<>(this, dependencies);
-    }
-
-    public ValueNode(Stamp stamp, List<ValueNode> dependencies) {
-        this.stamp = stamp;
-        this.dependencies = new NodeInputList<>(this, dependencies);
     }
 
     public Stamp stamp() {
@@ -177,17 +155,4 @@
         assertTrue(kind() == kind().getStackKind(), "Should have a stack kind : %s", kind());
         return super.verify();
     }
-
-    @Override
-    public Map<Object, Object> getDebugProperties(Map<Object, Object> map) {
-        Map<Object, Object> properties = super.getDebugProperties(map);
-        if (!dependencies.isEmpty()) {
-            StringBuilder str = new StringBuilder();
-            for (int i = 0; i < dependencies.size(); i++) {
-                str.append(i == 0 ? "" : ", ").append(dependencies.get(i) == null ? "null" : dependencies.get(i).toString(Verbosity.Id));
-            }
-            properties.put("dependencies", str.toString());
-        }
-        return properties;
-    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatingNode.java	Mon May 13 13:59:34 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatingNode.java	Mon May 13 14:17:35 2013 +0200
@@ -22,8 +22,6 @@
  */
 package com.oracle.graal.nodes.calc;
 
-import java.util.*;
-
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.type.*;
@@ -33,12 +31,4 @@
     public FloatingNode(Stamp stamp) {
         super(stamp);
     }
-
-    public FloatingNode(Stamp stamp, ValueNode... dependencies) {
-        super(stamp, dependencies);
-    }
-
-    public FloatingNode(Stamp stamp, List<ValueNode> dependencies) {
-        super(stamp, dependencies);
-    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/Access.java	Mon May 13 13:59:34 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/Access.java	Mon May 13 14:17:35 2013 +0200
@@ -22,10 +22,9 @@
  */
 package com.oracle.graal.nodes.extended;
 
-import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 
-public interface Access extends DeoptimizingNode {
+public interface Access extends DeoptimizingNode, GuardedNode {
 
     ValueNode object();
 
@@ -33,5 +32,4 @@
 
     void setNullCheck(boolean check);
 
-    Node asNode();
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AccessNode.java	Mon May 13 13:59:34 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AccessNode.java	Mon May 13 14:17:35 2013 +0200
@@ -22,10 +22,7 @@
  */
 package com.oracle.graal.nodes.extended;
 
-import java.util.*;
-
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.type.*;
 
@@ -34,8 +31,9 @@
  * {@linkplain #nullCheckLocation() location}. The access does not include a null check on the
  * object.
  */
-public abstract class AccessNode extends DeoptimizingFixedWithNextNode implements Access {
+public abstract class AccessNode extends DeoptimizingFixedWithNextNode implements Access, GuardingNode {
 
+    @Input private GuardingNode guard;
     @Input private ValueNode object;
     @Input private ValueNode location;
     private boolean nullCheck;
@@ -61,25 +59,18 @@
     }
 
     public AccessNode(ValueNode object, ValueNode location, Stamp stamp) {
+        this(object, location, stamp, null);
+    }
+
+    public AccessNode(ValueNode object, ValueNode location, Stamp stamp, GuardingNode guard) {
         super(stamp);
         this.object = object;
         this.location = location;
-    }
-
-    public AccessNode(ValueNode object, ValueNode location, Stamp stamp, List<ValueNode> dependencies) {
-        super(stamp, dependencies);
-        this.object = object;
-        this.location = location;
-    }
-
-    public AccessNode(ValueNode object, ValueNode location, Stamp stamp, ValueNode... dependencies) {
-        super(stamp, dependencies);
-        this.object = object;
-        this.location = location;
+        this.guard = guard;
     }
 
     @Override
-    public Node asNode() {
+    public AccessNode asNode() {
         return this;
     }
 
@@ -92,4 +83,15 @@
     public DeoptimizationReason getDeoptimizationReason() {
         return DeoptimizationReason.NullCheckException;
     }
+
+    @Override
+    public GuardingNode getGuard() {
+        return guard;
+    }
+
+    @Override
+    public void setGuard(GuardingNode guard) {
+        updateUsages(this.guard == null ? null : this.guard.asNode(), guard == null ? null : guard.asNode());
+        this.guard = guard;
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatableAccessNode.java	Mon May 13 13:59:34 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatableAccessNode.java	Mon May 13 14:17:35 2013 +0200
@@ -22,8 +22,6 @@
  */
 package com.oracle.graal.nodes.extended;
 
-import java.util.*;
-
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.type.*;
 
@@ -36,12 +34,8 @@
         super(object, location, stamp);
     }
 
-    public FloatableAccessNode(ValueNode object, ValueNode location, Stamp stamp, List<ValueNode> dependencies) {
-        super(object, location, stamp, dependencies);
-    }
-
-    public FloatableAccessNode(ValueNode object, ValueNode location, Stamp stamp, ValueNode... dependencies) {
-        super(object, location, stamp, dependencies);
+    public FloatableAccessNode(ValueNode object, ValueNode location, Stamp stamp, GuardingNode guard) {
+        super(object, location, stamp, guard);
     }
 
     public abstract FloatingAccessNode asFloatingNode(ValueNode lastLocationAccess);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingAccessNode.java	Mon May 13 13:59:34 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingAccessNode.java	Mon May 13 14:17:35 2013 +0200
@@ -22,15 +22,11 @@
  */
 package com.oracle.graal.nodes.extended;
 
-import java.util.*;
-
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.type.*;
 
-public abstract class FloatingAccessNode extends FloatingNode implements Access {
+public abstract class FloatingAccessNode extends FloatingGuardedNode implements Access {
 
     @Input private ValueNode object;
     @Input private LocationNode location;
@@ -63,20 +59,14 @@
         this.location = location;
     }
 
-    public FloatingAccessNode(ValueNode object, LocationNode location, Stamp stamp, ValueNode... dependencies) {
-        super(stamp, dependencies);
-        this.object = object;
-        this.location = location;
-    }
-
-    public FloatingAccessNode(ValueNode object, LocationNode location, Stamp stamp, List<ValueNode> dependencies) {
-        super(stamp, dependencies);
+    public FloatingAccessNode(ValueNode object, LocationNode location, Stamp stamp, GuardingNode guard) {
+        super(stamp, guard);
         this.object = object;
         this.location = location;
     }
 
     @Override
-    public Node asNode() {
+    public FloatingAccessNode asNode() {
         return this;
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java	Mon May 13 13:59:34 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java	Mon May 13 14:17:35 2013 +0200
@@ -22,8 +22,6 @@
  */
 package com.oracle.graal.nodes.extended;
 
-import java.util.*;
-
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
@@ -38,13 +36,12 @@
 
     @Input private Node lastLocationAccess;
 
-    public FloatingReadNode(ValueNode object, LocationNode location, Node lastLocationAccess, Stamp stamp, ValueNode... dependencies) {
-        super(object, location, stamp, dependencies);
-        this.lastLocationAccess = lastLocationAccess;
+    public FloatingReadNode(ValueNode object, LocationNode location, Node lastLocationAccess, Stamp stamp) {
+        this(object, location, lastLocationAccess, stamp, null);
     }
 
-    public FloatingReadNode(ValueNode object, LocationNode location, Node lastLocationAccess, Stamp stamp, List<ValueNode> dependencies) {
-        super(object, location, stamp, dependencies);
+    public FloatingReadNode(ValueNode object, LocationNode location, Node lastLocationAccess, Stamp stamp, GuardingNode guard) {
+        super(object, location, stamp, guard);
         this.lastLocationAccess = lastLocationAccess;
     }
 
@@ -65,6 +62,6 @@
 
     @Override
     public Access asFixedNode() {
-        return graph().add(new ReadNode(object(), nullCheckLocation(), stamp(), dependencies()));
+        return graph().add(new ReadNode(object(), nullCheckLocation(), stamp(), getGuard()));
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/GuardedNode.java	Mon May 13 14:17:35 2013 +0200
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.nodes.extended;
+
+import com.oracle.graal.nodes.*;
+
+public interface GuardedNode {
+
+    GuardingNode getGuard();
+
+    void setGuard(GuardingNode guard);
+
+    ValueNode asNode();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/GuardingNode.java	Mon May 13 14:17:35 2013 +0200
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.nodes.extended;
+
+import com.oracle.graal.nodes.*;
+
+public interface GuardingNode {
+
+    ValueNode asNode();
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/NullCheckNode.java	Mon May 13 13:59:34 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/NullCheckNode.java	Mon May 13 14:17:35 2013 +0200
@@ -27,7 +27,7 @@
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 
-public class NullCheckNode extends DeoptimizingFixedWithNextNode implements LIRLowerable {
+public class NullCheckNode extends DeoptimizingFixedWithNextNode implements LIRLowerable, GuardingNode {
 
     @Input public ValueNode object;
 
@@ -54,4 +54,9 @@
     public DeoptimizationReason getDeoptimizationReason() {
         return DeoptimizationReason.NullCheckException;
     }
+
+    @Override
+    public ValueNode asNode() {
+        return this;
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Mon May 13 13:59:34 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Mon May 13 14:17:35 2013 +0200
@@ -22,8 +22,6 @@
  */
 package com.oracle.graal.nodes.extended;
 
-import java.util.*;
-
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
@@ -40,20 +38,20 @@
         super(object, location, stamp);
     }
 
-    public ReadNode(ValueNode object, ValueNode location, Stamp stamp, List<ValueNode> dependencies) {
-        super(object, location, stamp, dependencies);
+    public ReadNode(ValueNode object, ValueNode location, Stamp stamp, GuardingNode guard) {
+        super(object, location, stamp, guard);
     }
 
     private ReadNode(ValueNode object, int displacement, LocationIdentity locationIdentity, Kind kind) {
         super(object, ConstantLocationNode.create(locationIdentity, kind, displacement, object.graph()), StampFactory.forKind(kind));
     }
 
-    private ReadNode(ValueNode object, ValueNode location, ValueNode dependency) {
+    private ReadNode(ValueNode object, ValueNode location, GuardingNode guard) {
         /*
          * Used by node intrinsics. Since the initial value for location is a parameter, i.e., a
          * LocalNode, the constructor cannot use the declared type LocationNode.
          */
-        super(object, location, StampFactory.forNodeIntrinsic(), dependency);
+        super(object, location, StampFactory.forNodeIntrinsic(), guard);
     }
 
     @Override
@@ -69,7 +67,7 @@
 
     @Override
     public FloatingAccessNode asFloatingNode(ValueNode lastLocationAccess) {
-        return graph().unique(new FloatingReadNode(object(), location(), lastLocationAccess, stamp(), dependencies()));
+        return graph().unique(new FloatingReadNode(object(), location(), lastLocationAccess, stamp(), getGuard()));
     }
 
     public static ValueNode canonicalizeRead(ValueNode read, LocationNode location, ValueNode object, CanonicalizerTool tool) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java	Mon May 13 13:59:34 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java	Mon May 13 14:17:35 2013 +0200
@@ -37,7 +37,7 @@
     }
 
     public UnsafeCastNode(ValueNode object, Stamp stamp, ValueNode anchor) {
-        super(object, stamp, anchor);
+        super(object, stamp, (FixedNode) anchor);
     }
 
     public UnsafeCastNode(ValueNode object, ResolvedJavaType toType, boolean exactType, boolean nonNull) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java	Mon May 13 13:59:34 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java	Mon May 13 14:17:35 2013 +0200
@@ -34,15 +34,18 @@
 /**
  * The ValueAnchor instruction keeps non-CFG (floating) nodes above a certain point in the graph.
  */
-public final class ValueAnchorNode extends FixedWithNextNode implements Canonicalizable, LIRLowerable, Node.IterableNodeType, Virtualizable {
+public final class ValueAnchorNode extends FixedWithNextNode implements Canonicalizable, LIRLowerable, Node.IterableNodeType, Virtualizable, GuardingNode {
+
+    @Input private NodeInputList<ValueNode> anchored;
 
     public ValueAnchorNode(ValueNode... values) {
         this(false, values);
     }
 
     public ValueAnchorNode(boolean permanent, ValueNode... values) {
-        super(StampFactory.dependency(), values);
+        super(StampFactory.dependency());
         this.permanent = permanent;
+        this.anchored = new NodeInputList<>(this, values);
     }
 
     private final boolean permanent;
@@ -53,8 +56,8 @@
     }
 
     public void addAnchoredNode(ValueNode value) {
-        if (!this.dependencies().contains(value)) {
-            this.dependencies().add(value);
+        if (!anchored.contains(value)) {
+            this.anchored.add(value);
         }
     }
 
@@ -67,13 +70,13 @@
             ValueAnchorNode previousAnchor = (ValueAnchorNode) this.predecessor();
             if (previousAnchor.usages().isEmpty()) { // avoid creating cycles
                 // transfer values and remove
-                for (ValueNode node : dependencies().nonNull().distinct()) {
+                for (ValueNode node : anchored.nonNull().distinct()) {
                     previousAnchor.addAnchoredNode(node);
                 }
                 return previousAnchor;
             }
         }
-        for (Node node : dependencies().nonNull().and(isNotA(FixedNode.class))) {
+        for (Node node : anchored.nonNull().and(isNotA(FixedNode.class))) {
             if (node instanceof ConstantNode) {
                 continue;
             }
@@ -100,7 +103,7 @@
         if (permanent) {
             return;
         }
-        for (ValueNode node : dependencies().nonNull().and(isNotA(AbstractBeginNode.class))) {
+        for (ValueNode node : anchored.nonNull().and(isNotA(AbstractBeginNode.class))) {
             State state = tool.getObjectState(node);
             if (state == null || state.getState() != EscapeState.Virtual) {
                 return;
@@ -108,4 +111,9 @@
         }
         tool.delete();
     }
+
+    @Override
+    public ValueNode asNode() {
+        return this;
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LoweringTool.java	Mon May 13 13:59:34 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LoweringTool.java	Mon May 13 14:17:35 2013 +0200
@@ -27,6 +27,7 @@
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.cfg.*;
+import com.oracle.graal.nodes.extended.*;
 
 public interface LoweringTool {
 
@@ -34,11 +35,11 @@
 
     Replacements getReplacements();
 
-    ValueNode createNullCheckGuard(NodeInputList<ValueNode> dependencies, ValueNode object);
+    GuardingNode createNullCheckGuard(GuardedNode guardedNode, ValueNode object);
 
-    ValueNode createGuard(LogicNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action);
+    GuardingNode createGuard(LogicNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action);
 
-    ValueNode createGuard(LogicNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action, boolean negated);
+    GuardingNode createGuard(LogicNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action, boolean negated);
 
     Assumptions assumptions();
 
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/EliminatePartiallyRedundantGuardsPhase.java	Mon May 13 13:59:34 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/EliminatePartiallyRedundantGuardsPhase.java	Mon May 13 14:17:35 2013 +0200
@@ -116,16 +116,10 @@
         }
         Collection<GuardNode> hits = new LinkedList<>();
         for (GuardNode guard : merge.guards()) {
-            if (guard.dependencies().size() != 1) {
-                continue;
-            }
             for (AbstractEndNode end : merge.forwardEnds()) {
                 AbstractBeginNode begin = AbstractBeginNode.prevBegin(end);
                 boolean found = false;
                 for (GuardNode predecessorGuard : begin.guards()) {
-                    if (predecessorGuard.dependencies().size() != 1) {
-                        continue;
-                    }
                     if (guard.condition() == predecessorGuard.condition() && guard.negated() == predecessorGuard.negated()) {
                         hits.add(guard);
                         found = true;
@@ -154,9 +148,6 @@
         for (Node successor : controlSplit.successors()) {
             AbstractBeginNode begin = (AbstractBeginNode) successor;
             for (GuardNode guard : begin.guards()) {
-                if (guard.dependencies().size() != 1) {
-                    continue;
-                }
                 Condition condition = new Condition(guard.condition(), guard.negated());
                 Collection<GuardNode> guards = conditionToGuard.get(condition);
                 if (guards == null) {
@@ -177,7 +168,7 @@
             DeoptimizationAction action = DeoptimizationAction.None;
             Set<AbstractBeginNode> begins = new HashSet<>(3);
             for (GuardNode guard : guards) {
-                AbstractBeginNode begin = (AbstractBeginNode) guard.dependencies().first();
+                AbstractBeginNode begin = (AbstractBeginNode) guard.getGuard();
                 begins.add(begin);
                 if (guard.action().ordinal() > action.ordinal()) {
                     action = guard.action();
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java	Mon May 13 13:59:34 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java	Mon May 13 14:17:35 2013 +0200
@@ -165,12 +165,10 @@
                 FloatingAccessNode floatingNode = accessNode.asFloatingNode(lastLocationAccess);
                 floatingNode.setNullCheck(accessNode.getNullCheck());
                 ValueAnchorNode anchor = null;
-                for (GuardNode guard : accessNode.dependencies().filter(GuardNode.class)) {
-                    if (anchor == null) {
-                        anchor = graph.add(new ValueAnchorNode());
-                        graph.addAfterFixed(accessNode, anchor);
-                    }
-                    anchor.addAnchoredNode(guard);
+                GuardingNode guard = accessNode.getGuard();
+                if (guard != null) {
+                    anchor = graph.add(new ValueAnchorNode(guard.asNode()));
+                    graph.addAfterFixed(accessNode, anchor);
                 }
                 graph.replaceFixedWithFloating(accessNode, floatingNode);
             }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java	Mon May 13 13:59:34 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java	Mon May 13 14:17:35 2013 +0200
@@ -114,8 +114,7 @@
         private void processAccess(Access access) {
             GuardNode guard = nullGuarded.get(access.object());
             if (guard != null && isImplicitNullCheck(access.nullCheckLocation())) {
-                NodeInputList<ValueNode> dependencies = ((ValueNode) access).dependencies();
-                dependencies.remove(guard);
+                access.setGuard(guard.getGuard());
                 Access fixedAccess = access;
                 if (access instanceof FloatingAccessNode) {
                     fixedAccess = ((FloatingAccessNode) access).asFixedNode();
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java	Mon May 13 13:59:34 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java	Mon May 13 14:17:35 2013 +0200
@@ -31,6 +31,7 @@
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.cfg.*;
+import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.spi.Lowerable.LoweringType;
 import com.oracle.graal.phases.*;
@@ -45,12 +46,12 @@
     final class LoweringToolImpl implements LoweringTool {
 
         private final PhaseContext context;
-        private final FixedNode guardAnchor;
+        private final GuardingNode guardAnchor;
         private final NodeBitMap activeGuards;
         private FixedWithNextNode lastFixedNode;
         private ControlFlowGraph cfg;
 
-        public LoweringToolImpl(PhaseContext context, FixedNode guardAnchor, NodeBitMap activeGuards, ControlFlowGraph cfg) {
+        public LoweringToolImpl(PhaseContext context, GuardingNode guardAnchor, NodeBitMap activeGuards, ControlFlowGraph cfg) {
             this.context = context;
             this.guardAnchor = guardAnchor;
             this.activeGuards = activeGuards;
@@ -68,18 +69,19 @@
         }
 
         @Override
-        public ValueNode createNullCheckGuard(NodeInputList<ValueNode> list, ValueNode object) {
+        public GuardingNode createNullCheckGuard(GuardedNode guardedNode, ValueNode object) {
             if (object.objectStamp().nonNull()) {
                 // Short cut creation of null check guard if the object is known to be non-null.
                 return null;
             }
-            ValueNode guard = createGuard(object.graph().unique(new IsNullNode(object)), DeoptimizationReason.NullCheckException, DeoptimizationAction.InvalidateReprofile, true);
-            list.add(guard);
+            GuardingNode guard = createGuard(object.graph().unique(new IsNullNode(object)), DeoptimizationReason.NullCheckException, DeoptimizationAction.InvalidateReprofile, true);
+            assert guardedNode.getGuard() == null;
+            guardedNode.setGuard(guard);
             return guard;
         }
 
         @Override
-        public ValueNode createGuard(LogicNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action) {
+        public GuardingNode createGuard(LogicNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action) {
             return createGuard(condition, deoptReason, action, false);
         }
 
@@ -89,7 +91,7 @@
         }
 
         @Override
-        public ValueNode createGuard(LogicNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action, boolean negated) {
+        public GuardingNode createGuard(LogicNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action, boolean negated) {
             if (loweringType == LoweringType.AFTER_GUARDS) {
                 throw new GraalInternalError("Cannot create guards in after-guard lowering");
             }
@@ -100,7 +102,7 @@
                     }
                 }
             }
-            GuardNode newGuard = guardAnchor.graph().unique(new GuardNode(condition, guardAnchor, deoptReason, action, negated));
+            GuardNode newGuard = guardAnchor.asNode().graph().unique(new GuardNode(condition, guardAnchor, deoptReason, action, negated));
             if (GraalOptions.OptEliminateGuards) {
                 activeGuards.grow();
                 activeGuards.mark(newGuard);
@@ -179,9 +181,9 @@
             processBlock(schedule.getCFG().getStartBlock(), graph.createNodeBitMap(), null);
         }
 
-        private void processBlock(Block block, NodeBitMap activeGuards, FixedNode parentAnchor) {
+        private void processBlock(Block block, NodeBitMap activeGuards, GuardingNode parentAnchor) {
 
-            FixedNode anchor = parentAnchor;
+            GuardingNode anchor = parentAnchor;
             if (anchor == null) {
                 anchor = block.getBeginNode();
             }
@@ -202,13 +204,13 @@
             }
 
             if (parentAnchor == null && GraalOptions.OptEliminateGuards) {
-                for (GuardNode guard : anchor.usages().filter(GuardNode.class)) {
+                for (GuardNode guard : anchor.asNode().usages().filter(GuardNode.class)) {
                     activeGuards.clear(guard);
                 }
             }
         }
 
-        private void process(final Block b, final NodeBitMap activeGuards, final FixedNode anchor) {
+        private void process(final Block b, final NodeBitMap activeGuards, final GuardingNode anchor) {
 
             final LoweringToolImpl loweringTool = new LoweringToolImpl(context, anchor, activeGuards, schedule.getCFG());
 
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java	Mon May 13 13:59:34 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java	Mon May 13 14:17:35 2013 +0200
@@ -282,11 +282,6 @@
                 // re-wire the phi duplicates to the correct input
                 for (PhiNode phi : phiSnapshot) {
                     PhiNode phiDuplicate = (PhiNode) duplicates.get(phi);
-                    for (Node usage : phiDuplicate.usages()) {
-                        if (usage instanceof ValueNode) {
-                            ((ValueNode) usage).dependencies().add(prevBegin);
-                        }
-                    }
                     phiDuplicate.replaceAtUsages(phi.valueAt(forwardEnd));
                     phiDuplicate.safeDelete();
                 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/VerifyPhase.java	Mon May 13 14:17:35 2013 +0200
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.phases;
+
+import com.oracle.graal.nodes.*;
+
+public abstract class VerifyPhase extends Phase {
+
+    @Override
+    protected final void run(StructuredGraph graph) {
+        assert verify(graph);
+    }
+
+    protected abstract boolean verify(StructuredGraph graph);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/verify/VerifyValueUsage.java	Mon May 13 14:17:35 2013 +0200
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.phases.verify;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.phases.*;
+
+public class VerifyValueUsage extends VerifyPhase {
+
+    private MetaAccessProvider runtime;
+
+    public VerifyValueUsage(MetaAccessProvider runtime) {
+        this.runtime = runtime;
+    }
+
+    private boolean checkType(ValueNode node) {
+        if (node.stamp() instanceof ObjectStamp) {
+            ResolvedJavaType valueType = runtime.lookupJavaType(Value.class);
+            ResolvedJavaType nodeType = node.objectStamp().type();
+
+            if (valueType.isAssignableFrom(nodeType)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    protected boolean verify(StructuredGraph graph) {
+        for (ObjectEqualsNode cn : graph.getNodes().filter(ObjectEqualsNode.class)) {
+            String desc = "VerifyValueUsage: " + cn.x() + " or " + cn.y() + " in " + graph.method() + " uses object identity. Should use equals() instead.";
+            if (!graph.method().toString().endsWith("equals(Object)>")) {
+                assert !((checkType(cn.x()) && !(cn.y() instanceof ConstantNode)) || (checkType(cn.y()) && !(cn.x() instanceof ConstantNode))) : desc;
+            }
+        }
+        return true;
+    }
+}
--- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java	Mon May 13 13:59:34 2013 +0200
+++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java	Mon May 13 14:17:35 2013 +0200
@@ -313,7 +313,7 @@
         graph.addBeforeFixed(invoke.asNode(), read);
         // The read must not float outside its block otherwise it may float above an explicit zero
         // check on its base address
-        read.dependencies().add(AbstractBeginNode.prevBegin(invoke.asNode()));
+        read.setGuard(AbstractBeginNode.prevBegin(invoke.asNode()));
         return read;
     }