changeset 15002:06e50d290784

isAllowedUsageType on Nodes
author Lukas Stadler <lukas.stadler@oracle.com>
date Mon, 07 Apr 2014 11:32:08 +0200
parents 27c04ee36dcb
children 4b1f128a3d45
files graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeInfo.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/BeginLockScopeNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CStringNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DirectCompareAndSwapNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/EndLockScopeNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/StubForeignCallNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyCallNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopyNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractBeginNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractLocalNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/CallTargetNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/EndNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/EntryMarkerNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedWithNextNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FloatingGuardedNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/KillingBeginNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopExitNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryPhiNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryProxyNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MergeNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PhiNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StartNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/VirtualState.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BinaryNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatingNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NegateNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NotNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AbstractWriteNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LocationNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MembarNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AbstractNewObjectNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessMonitorNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ArrayLengthNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredCompareAndSwapNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorIdNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewMultiArrayNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/CommitAllocationNode.java graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/GraphOrder.java graal/com.oracle.graal.printer/src/com/oracle/graal/printer/IdealGraphPrinter.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/GraphEffectList.java
diffstat 59 files changed, 195 insertions(+), 85 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java	Mon Apr 07 11:32:08 2014 +0200
@@ -136,6 +136,8 @@
     private static final int INLINE_USAGE_COUNT = 2;
     private static final Node[] NO_NODES = {};
 
+    private static final boolean VERIFY_TYPES = true;
+
     /**
      * Head of usage list. The elements of the usage list in order are {@link #usage0},
      * {@link #usage1} and {@link #extraUsages}. The first null entry terminates the list.
@@ -512,6 +514,10 @@
         return NodeClass.get(getClass());
     }
 
+    public boolean isAllowedUsageType(InputType type) {
+        return getNodeClass().getAllowedUsageTypes().contains(type);
+    }
+
     private boolean checkReplaceWith(Node other) {
         assert assertTrue(graph == null || !graph.isFrozen(), "cannot modify frozen graph");
         assert assertFalse(other == this, "cannot replace a node with itself");
@@ -738,6 +744,16 @@
             for (Node usage : usages()) {
                 assertFalse(usage.isDeleted(), "usage %s must never be deleted", usage);
                 assertTrue(usage.inputs().contains(this), "missing input in usage %s", usage);
+                if (VERIFY_TYPES) {
+                    NodeClassIterator iterator = usage.inputs().iterator();
+                    while (iterator.hasNext()) {
+                        Position pos = iterator.nextPosition();
+                        if (pos.get(usage) == this && pos.getInputType(usage) != InputType.Unchecked) {
+                            assert isAllowedUsageType(pos.getInputType(usage)) : "invalid input of type " + pos.getInputType(usage) + " from " + usage + " to " + this + " (" +
+                                            pos.getInputName(usage) + ")";
+                        }
+                    }
+                }
             }
         }
         if (predecessor != null) {
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java	Mon Apr 07 11:32:08 2014 +0200
@@ -148,6 +148,7 @@
     private final String shortName;
     private final String nameTemplate;
     private final int iterableId;
+    private final EnumSet<InputType> allowedUsageTypes;
     private int[] iterableIds;
 
     private static final DebugMetric ITERABLE_NODE_TYPES = Debug.metric("IterableNodeTypes");
@@ -220,7 +221,19 @@
                 newNameTemplate = info.nameTemplate();
             }
         }
+        EnumSet<InputType> newAllowedUsageTypes = EnumSet.noneOf(InputType.class);
+        Class<?> current = clazz;
+        do {
+            NodeInfo currentInfo = current.getAnnotation(NodeInfo.class);
+            if (currentInfo != null) {
+                if (currentInfo.allowedUsageTypes().length > 0) {
+                    newAllowedUsageTypes.addAll(Arrays.asList(currentInfo.allowedUsageTypes()));
+                }
+            }
+            current = current.getSuperclass();
+        } while (current != Node.class);
         this.nameTemplate = newNameTemplate == null ? newShortName : newNameTemplate;
+        this.allowedUsageTypes = newAllowedUsageTypes;
         this.shortName = newShortName;
         if (presetIterableIds != null) {
             this.iterableIds = presetIterableIds;
@@ -314,6 +327,10 @@
         return nextIterableId;
     }
 
+    public EnumSet<InputType> getAllowedUsageTypes() {
+        return allowedUsageTypes;
+    }
+
     protected static class FieldScanner extends BaseFieldScanner {
 
         public final ArrayList<Long> inputOffsets = new ArrayList<>();
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeInfo.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeInfo.java	Mon Apr 07 11:32:08 2014 +0200
@@ -37,4 +37,6 @@
      * using &#123;i#inputName&#125; or &#123;p#propertyName&#125;.
      */
     String nameTemplate() default "";
+
+    InputType[] allowedUsageTypes() default {};
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/BeginLockScopeNode.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/BeginLockScopeNode.java	Mon Apr 07 11:32:08 2014 +0200
@@ -26,6 +26,7 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.compiler.target.*;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
@@ -37,6 +38,7 @@
  * is locked (ensuring the GC sees and updates the object) so it must come after any null pointer
  * check on the object.
  */
+@NodeInfo(allowedUsageTypes = {InputType.Memory})
 public final class BeginLockScopeNode extends AbstractMemoryCheckpoint implements LIRGenLowerable, MonitorEnter, MemoryCheckpoint.Single {
 
     private int lockDepth;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CStringNode.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CStringNode.java	Mon Apr 07 11:32:08 2014 +0200
@@ -53,7 +53,7 @@
 
     /**
      * Converts a string to a null terminated byte array of ASCII characters.
-     * 
+     *
      * @param s a String that must only contain ASCII characters
      */
     public static byte[] toCString(String s) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DirectCompareAndSwapNode.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DirectCompareAndSwapNode.java	Mon Apr 07 11:32:08 2014 +0200
@@ -25,6 +25,7 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.compiler.target.*;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
@@ -37,6 +38,7 @@
  * {@linkplain #compareAndSwap(Object, long, Word, Word, LocationIdentity)} returns either the
  * expected value or the compared against value instead of a boolean.
  */
+@NodeInfo(allowedUsageTypes = {InputType.Memory})
 public class DirectCompareAndSwapNode extends FixedWithNextNode implements LIRGenLowerable, MemoryCheckpoint.Single {
 
     @Input private ValueNode object;
@@ -86,7 +88,7 @@
      * given offset. Iff they are same, {@code newValue} is placed into the location and the
      * {@code expectedValue} is returned. Otherwise, the actual value is returned. All of the above
      * is performed in one atomic hardware transaction.
-     * 
+     *
      * @param object the object containing a field to be atomically tested and updated
      * @param offset offset from {@code object} of the field
      * @param expectedValue if this value is currently in the field, perform the swap
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/EndLockScopeNode.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/EndLockScopeNode.java	Mon Apr 07 11:32:08 2014 +0200
@@ -23,6 +23,7 @@
 package com.oracle.graal.hotspot.nodes;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
@@ -32,6 +33,7 @@
  * Intrinsic for closing a {@linkplain BeginLockScopeNode scope} binding a stack-based lock with an
  * object.
  */
+@NodeInfo(allowedUsageTypes = {InputType.Memory})
 public final class EndLockScopeNode extends AbstractMemoryCheckpoint implements LIRLowerable, MonitorExit, MemoryCheckpoint.Single {
 
     public EndLockScopeNode() {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/StubForeignCallNode.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/StubForeignCallNode.java	Mon Apr 07 11:32:08 2014 +0200
@@ -33,7 +33,7 @@
 /**
  * Node for a {@linkplain ForeignCallDescriptor foreign} call from within a stub.
  */
-@NodeInfo(nameTemplate = "StubForeignCall#{p#descriptor/s}")
+@NodeInfo(nameTemplate = "StubForeignCall#{p#descriptor/s}", allowedUsageTypes = {InputType.Memory})
 public class StubForeignCallNode extends FixedWithNextNode implements LIRLowerable, MemoryCheckpoint.Multi {
 
     @Input private final NodeInputList<ValueNode> arguments;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyCallNode.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyCallNode.java	Mon Apr 07 11:32:08 2014 +0200
@@ -27,6 +27,7 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.runtime.*;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.nodes.*;
@@ -38,6 +39,7 @@
 import com.oracle.graal.replacements.SnippetTemplate.Arguments;
 import com.oracle.graal.runtime.*;
 
+@NodeInfo(allowedUsageTypes = {InputType.Memory})
 public final class ArrayCopyCallNode extends ArrayRangeWriteNode implements Lowerable, MemoryCheckpoint.Single {
 
     @Input private ValueNode src;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopyNode.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopyNode.java	Mon Apr 07 11:32:08 2014 +0200
@@ -25,12 +25,14 @@
 import static com.oracle.graal.api.meta.LocationIdentity.*;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.replacements.SnippetTemplate.Arguments;
 
+@NodeInfo(allowedUsageTypes = {InputType.Memory})
 public final class UnsafeArrayCopyNode extends ArrayRangeWriteNode implements Lowerable, MemoryCheckpoint.Single {
 
     @Input private ValueNode src;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractBeginNode.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractBeginNode.java	Mon Apr 07 11:32:08 2014 +0200
@@ -33,6 +33,7 @@
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 
+@NodeInfo(allowedUsageTypes = {InputType.Guard, InputType.Anchor})
 public abstract class AbstractBeginNode extends FixedWithNextNode implements StateSplit, LIRLowerable, Simplifiable, GuardingNode, IterableNodeType {
 
     @Input(InputType.State) private FrameState stateAfter;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractLocalNode.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractLocalNode.java	Mon Apr 07 11:32:08 2014 +0200
@@ -36,7 +36,7 @@
 
     /**
      * Gets the index of this local in the array of parameters. This is NOT the JVM local index.
-     * 
+     *
      * @return the index
      */
     public int index() {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/CallTargetNode.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/CallTargetNode.java	Mon Apr 07 11:32:08 2014 +0200
@@ -28,6 +28,7 @@
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 
+@NodeInfo(allowedUsageTypes = {InputType.Association})
 public abstract class CallTargetNode extends ValueNode implements LIRLowerable {
 
     @Input private final NodeInputList<ValueNode> arguments;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java	Mon Apr 07 11:32:08 2014 +0200
@@ -49,7 +49,7 @@
 
     /**
      * Constructs a new node representing the specified constant.
-     * 
+     *
      * @param value the constant
      */
     protected ConstantNode(Constant value, Stamp stamp) {
@@ -184,7 +184,7 @@
 
     /**
      * Returns a node for a double constant.
-     * 
+     *
      * @param d the double value for which to create the instruction
      * @return a node for a double constant
      */
@@ -194,7 +194,7 @@
 
     /**
      * Returns a node for a float constant.
-     * 
+     *
      * @param f the float value for which to create the instruction
      * @return a node for a float constant
      */
@@ -204,7 +204,7 @@
 
     /**
      * Returns a node for an long constant.
-     * 
+     *
      * @param i the long value for which to create the instruction
      * @return a node for an long constant
      */
@@ -214,7 +214,7 @@
 
     /**
      * Returns a node for an integer constant.
-     * 
+     *
      * @param i the integer value for which to create the instruction
      * @return a node for an integer constant
      */
@@ -224,7 +224,7 @@
 
     /**
      * Returns a node for a boolean constant.
-     * 
+     *
      * @param i the boolean value for which to create the instruction
      * @return a node representing the boolean
      */
@@ -234,7 +234,7 @@
 
     /**
      * Returns a node for a byte constant.
-     * 
+     *
      * @param i the byte value for which to create the instruction
      * @return a node representing the byte
      */
@@ -244,7 +244,7 @@
 
     /**
      * Returns a node for a char constant.
-     * 
+     *
      * @param i the char value for which to create the instruction
      * @return a node representing the char
      */
@@ -254,7 +254,7 @@
 
     /**
      * Returns a node for a short constant.
-     * 
+     *
      * @param i the short value for which to create the instruction
      * @return a node representing the short
      */
@@ -264,7 +264,7 @@
 
     /**
      * Returns a node for an object constant.
-     * 
+     *
      * @param o the object value for which to create the instruction
      * @return a node representing the object
      */
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/EndNode.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/EndNode.java	Mon Apr 07 11:32:08 2014 +0200
@@ -22,5 +22,8 @@
  */
 package com.oracle.graal.nodes;
 
+import com.oracle.graal.graph.*;
+
+@NodeInfo(allowedUsageTypes = {InputType.Association})
 public final class EndNode extends AbstractEndNode {
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/EntryMarkerNode.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/EntryMarkerNode.java	Mon Apr 07 11:32:08 2014 +0200
@@ -30,6 +30,7 @@
  * This node will be inserted at point specified by {@link StructuredGraph#getEntryBCI()}, usually
  * by the graph builder.
  */
+@NodeInfo(allowedUsageTypes = {InputType.Association})
 public class EntryMarkerNode extends AbstractBeginNode implements IterableNodeType, Simplifiable, LIRLowerable {
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java	Mon Apr 07 11:32:08 2014 +0200
@@ -28,7 +28,7 @@
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
 
-@NodeInfo(nameTemplate = "FixedGuard(!={p#negated}) {p#reason/s}")
+@NodeInfo(nameTemplate = "FixedGuard(!={p#negated}) {p#reason/s}", allowedUsageTypes = {InputType.Guard})
 public final class FixedGuardNode extends AbstractFixedGuardNode implements Lowerable, IterableNodeType {
 
     public FixedGuardNode(LogicNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedWithNextNode.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedWithNextNode.java	Mon Apr 07 11:32:08 2014 +0200
@@ -44,9 +44,4 @@
     public FixedWithNextNode(Stamp stamp) {
         super(stamp);
     }
-
-    @Override
-    public FixedWithNextNode asNode() {
-        return this;
-    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FloatingGuardedNode.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FloatingGuardedNode.java	Mon Apr 07 11:32:08 2014 +0200
@@ -29,7 +29,7 @@
 
 public abstract class FloatingGuardedNode extends FloatingNode implements GuardedNode {
 
-    @Input(InputType.Anchor) private GuardingNode guard;
+    @Input(InputType.Guard) private GuardingNode guard;
 
     public FloatingGuardedNode(Stamp stamp) {
         super(stamp);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java	Mon Apr 07 11:32:08 2014 +0200
@@ -40,7 +40,7 @@
  * maximum flexibility for the guard node and guarantees that deoptimization occurs only if the
  * control flow would have reached the guarded node (without taking exceptions into account).
  */
-@NodeInfo(nameTemplate = "Guard(!={p#negated}) {p#reason/s}")
+@NodeInfo(nameTemplate = "Guard(!={p#negated}) {p#reason/s}", allowedUsageTypes = {InputType.Guard})
 public class GuardNode extends FloatingGuardedNode implements Canonicalizable, IterableNodeType, GuardingNode, GuardedNode {
 
     @Input(InputType.Condition) private LogicNode condition;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java	Mon Apr 07 11:32:08 2014 +0200
@@ -27,6 +27,7 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.nodes.util.*;
@@ -34,7 +35,7 @@
 /**
  * The {@code InvokeNode} represents all kinds of method calls.
  */
-@NodeInfo(nameTemplate = "Invoke#{p#targetMethod/s}")
+@NodeInfo(nameTemplate = "Invoke#{p#targetMethod/s}", allowedUsageTypes = {InputType.Memory})
 public final class InvokeNode extends AbstractMemoryCheckpoint implements Invoke, LIRLowerable, MemoryCheckpoint.Single {
 
     @Input(InputType.Association) private CallTargetNode callTarget;
@@ -94,6 +95,16 @@
     }
 
     @Override
+    public boolean isAllowedUsageType(InputType type) {
+        if (getKind() != Kind.Void) {
+            if (callTarget instanceof MethodCallTargetNode && ((MethodCallTargetNode) callTarget).targetMethod().getAnnotation(NodeIntrinsic.class) != null) {
+                return true;
+            }
+        }
+        return super.isAllowedUsageType(type);
+    }
+
+    @Override
     public Map<Object, Object> getDebugProperties(Map<Object, Object> map) {
         Map<Object, Object> debugProperties = super.getDebugProperties(map);
         if (callTarget != null) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java	Mon Apr 07 11:32:08 2014 +0200
@@ -31,7 +31,7 @@
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.util.*;
 
-@NodeInfo(nameTemplate = "Invoke!#{p#targetMethod/s}")
+@NodeInfo(nameTemplate = "Invoke!#{p#targetMethod/s}", allowedUsageTypes = {InputType.Memory})
 public class InvokeWithExceptionNode extends ControlSplitNode implements Invoke, MemoryCheckpoint.Single, LIRLowerable {
 
     private static final double EXCEPTION_PROBA = 1e-5;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/KillingBeginNode.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/KillingBeginNode.java	Mon Apr 07 11:32:08 2014 +0200
@@ -23,8 +23,10 @@
 package com.oracle.graal.nodes;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.extended.*;
 
+@NodeInfo(allowedUsageTypes = {InputType.Memory})
 public class KillingBeginNode extends AbstractBeginNode implements MemoryCheckpoint.Single {
 
     private LocationIdentity locationIdentity;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicNode.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicNode.java	Mon Apr 07 11:32:08 2014 +0200
@@ -22,9 +22,13 @@
  */
 package com.oracle.graal.nodes;
 
+import static com.oracle.graal.graph.InputType.*;
+
+import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.type.*;
 
+@NodeInfo(allowedUsageTypes = {Condition})
 public abstract class LogicNode extends FloatingNode {
 
     public LogicNode() {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopExitNode.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopExitNode.java	Mon Apr 07 11:32:08 2014 +0200
@@ -25,6 +25,7 @@
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.spi.*;
 
+@NodeInfo(allowedUsageTypes = {InputType.Association})
 public class LoopExitNode extends BeginStateSplitNode implements IterableNodeType {
 
     @Input(InputType.Association) private LoopBeginNode loopBegin;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryPhiNode.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryPhiNode.java	Mon Apr 07 11:32:08 2014 +0200
@@ -30,6 +30,7 @@
 /**
  * The {@code PhiNode} represents the merging of dataflow in the memory graph.
  */
+@NodeInfo(nameTemplate = "MemoryPhi({i#values}) {p#locationIdentity/s}", allowedUsageTypes = {InputType.Memory})
 public class MemoryPhiNode extends PhiNode implements MemoryNode {
 
     @Input(InputType.Memory) final NodeInputList<ValueNode> values = new NodeInputList<>(this);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryProxyNode.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryProxyNode.java	Mon Apr 07 11:32:08 2014 +0200
@@ -28,6 +28,7 @@
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 
+@NodeInfo(allowedUsageTypes = {InputType.Memory})
 public class MemoryProxyNode extends ProxyNode implements MemoryProxy, LIRLowerable {
 
     @Input(InputType.Memory) private ValueNode value;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MergeNode.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MergeNode.java	Mon Apr 07 11:32:08 2014 +0200
@@ -36,6 +36,7 @@
 /**
  * Denotes the merging of multiple control-flow paths.
  */
+@NodeInfo(allowedUsageTypes = {InputType.Association})
 public class MergeNode extends BeginStateSplitNode implements IterableNodeType, LIRLowerable {
 
     @Input(InputType.Association) private final NodeInputList<AbstractEndNode> ends = new NodeInputList<>(this);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PhiNode.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PhiNode.java	Mon Apr 07 11:32:08 2014 +0200
@@ -25,6 +25,7 @@
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.type.*;
 
 public abstract class PhiNode extends FloatingNode {
@@ -57,7 +58,7 @@
     /**
      * Get the instruction that produces the value associated with the i'th predecessor of the
      * merge.
-     *
+     * 
      * @param i the index of the predecessor
      * @return the instruction that produced the value in the i'th predecessor
      */
@@ -67,7 +68,7 @@
 
     /**
      * Sets the value at the given index and makes sure that the values list is large enough.
-     *
+     * 
      * @param i the index at which to set the value
      * @param x the new phi input value for the given location
      */
@@ -88,7 +89,7 @@
 
     /**
      * Get the number of inputs to this phi (i.e. the number of predecessors to the merge).
-     *
+     * 
      * @return the number of inputs in this phi
      */
     public int valueCount() {
@@ -171,4 +172,5 @@
     public boolean isLoopPhi() {
         return merge() instanceof LoopBeginNode;
     }
-}
+
+}
\ No newline at end of file
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StartNode.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StartNode.java	Mon Apr 07 11:32:08 2014 +0200
@@ -23,11 +23,13 @@
 package com.oracle.graal.nodes;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.extended.*;
 
 /**
  * The start node of a graph.
  */
+@NodeInfo(allowedUsageTypes = {InputType.Memory})
 public class StartNode extends BeginStateSplitNode implements MemoryCheckpoint.Single {
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java	Mon Apr 07 11:32:08 2014 +0200
@@ -41,7 +41,7 @@
      * The different stages of the compilation of a {@link Graph} regarding the status of
      * {@link GuardNode guards}, {@link DeoptimizingNode deoptimizations} and {@link FrameState
      * framestates}. The stage of a graph progresses monotonously.
-     * 
+     *
      */
     public static enum GuardsStage {
         /**
@@ -137,7 +137,7 @@
 
     /**
      * Gets the method from which this graph was built.
-     * 
+     *
      * @return null if this method was not built from a method or the method is not available
      */
     public ResolvedJavaMethod method() {
@@ -250,7 +250,7 @@
     /**
      * Unlinks a node from all its control flow neighbors and then removes it from its graph. The
      * node must have no {@linkplain Node#usages() usages}.
-     * 
+     *
      * @param node the node to be unlinked and removed
      */
     public void removeFixed(FixedWithNextNode node) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java	Mon Apr 07 11:32:08 2014 +0200
@@ -25,6 +25,7 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.iterators.*;
+import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.type.*;
 
 /**
@@ -55,7 +56,7 @@
      * Checks if the given stamp is different than the current one (
      * {@code newStamp.equals(oldStamp) == false}). If it is different then the new stamp will
      * become the current stamp for this node.
-     * 
+     *
      * @return true if the stamp has changed, false otherwise.
      */
     protected final boolean updateStamp(Stamp newStamp) {
@@ -72,7 +73,7 @@
      * their stamp if their inputs change. A typical implementation will compute the stamp and pass
      * it to {@link #updateStamp(Stamp)}, whose return value can be used as the result of this
      * method.
-     * 
+     *
      * @return true if the stamp has changed, false otherwise.
      */
     public boolean inferStamp() {
@@ -85,7 +86,7 @@
 
     /**
      * Checks whether this value is a constant (i.e. it is of type {@link ConstantNode}.
-     * 
+     *
      * @return {@code true} if this value is a constant
      */
     public final boolean isConstant() {
@@ -106,7 +107,7 @@
 
     /**
      * Checks whether this value represents the null constant.
-     * 
+     *
      * @return {@code true} if this value represents the null constant
      */
     public final boolean isNullConstant() {
@@ -115,7 +116,7 @@
 
     /**
      * Convert this value to a constant if it is a constant, otherwise return null.
-     * 
+     *
      * @return the {@link Constant} represented by this value if it is a constant; {@code null}
      *         otherwise
      */
@@ -129,4 +130,26 @@
     public ValueNode asNode() {
         return this;
     }
+
+    @Override
+    public boolean isAllowedUsageType(InputType type) {
+        if (getKind() != Kind.Void && getKind() != Kind.Illegal && type == InputType.Value) {
+            return true;
+        } else {
+            return super.isAllowedUsageType(type);
+        }
+    }
+
+    @Override
+    public boolean verify() {
+        if ((getKind() != Kind.Illegal && getKind() != Kind.Void) != isAllowedUsageType(InputType.Value)) {
+            System.out.println("mismatch: " + this + " kind: " + getKind() + " isAllowedUsageType: " + isAllowedUsageType(InputType.Value));
+        }
+        if (!(this instanceof WriteNode || this instanceof ReadNode || this instanceof JavaWriteNode || this instanceof JavaReadNode || this instanceof InvokeNode)) {
+            if ((this instanceof GuardingNode) != isAllowedUsageType(InputType.Guard)) {
+                System.out.println("mismatch: " + this + " guard: " + (this instanceof GuardingNode) + " isAllowedUsageType: " + isAllowedUsageType(InputType.Guard));
+            }
+        }
+        return super.verify();
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/VirtualState.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/VirtualState.java	Mon Apr 07 11:32:08 2014 +0200
@@ -28,6 +28,7 @@
  * Base class for nodes that contain "virtual" state, like FrameState and VirtualObjectState.
  * Subclasses of this class will be treated in a special way by the scheduler.
  */
+@NodeInfo(allowedUsageTypes = {InputType.State})
 public abstract class VirtualState extends Node {
 
     public interface NodeClosure<T extends Node> {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BinaryNode.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BinaryNode.java	Mon Apr 07 11:32:08 2014 +0200
@@ -45,7 +45,7 @@
 
     /**
      * Creates a new BinaryNode instance.
-     * 
+     *
      * @param stamp the result type of this instruction
      * @param x the first input instruction
      * @param y the second input instruction
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatingNode.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatingNode.java	Mon Apr 07 11:32:08 2014 +0200
@@ -31,9 +31,4 @@
     public FloatingNode(Stamp stamp) {
         super(stamp);
     }
-
-    @Override
-    public FloatingNode asNode() {
-        return this;
-    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NegateNode.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NegateNode.java	Mon Apr 07 11:32:08 2014 +0200
@@ -47,7 +47,7 @@
 
     /**
      * Creates new NegateNode instance.
-     * 
+     *
      * @param x the instruction producing the value that is input to this instruction
      */
     public NegateNode(ValueNode x) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NotNode.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NotNode.java	Mon Apr 07 11:32:08 2014 +0200
@@ -53,7 +53,7 @@
 
     /**
      * Creates new NegateNode instance.
-     * 
+     *
      * @param x the instruction producing the value that is input to this instruction
      */
     public NotNode(ValueNode x) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AbstractWriteNode.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AbstractWriteNode.java	Mon Apr 07 11:32:08 2014 +0200
@@ -27,6 +27,7 @@
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.type.*;
 
+@NodeInfo(allowedUsageTypes = {InputType.Memory})
 public abstract class AbstractWriteNode extends FixedAccessNode implements StateSplit, MemoryCheckpoint.Single, MemoryAccess, GuardingNode {
 
     @Input private ValueNode value;
@@ -73,6 +74,11 @@
     }
 
     @Override
+    public boolean isAllowedUsageType(InputType type) {
+        return (type == InputType.Guard && getNullCheck()) ? true : super.isAllowedUsageType(type);
+    }
+
+    @Override
     public LocationIdentity getLocationIdentity() {
         return location().getLocationIdentity();
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallNode.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallNode.java	Mon Apr 07 11:32:08 2014 +0200
@@ -34,7 +34,7 @@
 /**
  * Node for a {@linkplain ForeignCallDescriptor foreign} call.
  */
-@NodeInfo(nameTemplate = "ForeignCall#{p#descriptor/s}")
+@NodeInfo(nameTemplate = "ForeignCall#{p#descriptor/s}", allowedUsageTypes = {InputType.Memory})
 public class ForeignCallNode extends AbstractMemoryCheckpoint implements LIRLowerable, DeoptimizingNode.DeoptDuring, MemoryCheckpoint.Multi {
 
     @Input private final NodeInputList<ValueNode> arguments;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LocationNode.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LocationNode.java	Mon Apr 07 11:32:08 2014 +0200
@@ -23,6 +23,7 @@
 package com.oracle.graal.nodes.extended;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.Node.ValueNumberable;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.spi.*;
@@ -33,6 +34,7 @@
  * locations have the form [base + location], where base is a node and location is defined by
  * subclasses of the {@link LocationNode}.
  */
+@NodeInfo(allowedUsageTypes = {InputType.Association})
 public abstract class LocationNode extends FloatingNode implements LIRLowerable, ValueNumberable {
 
     /**
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MembarNode.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MembarNode.java	Mon Apr 07 11:32:08 2014 +0200
@@ -38,6 +38,7 @@
 /**
  * Creates a memory barrier.
  */
+@NodeInfo(allowedUsageTypes = {InputType.Memory})
 public class MembarNode extends FixedWithNextNode implements LIRLowerable, MemoryCheckpoint.Single {
 
     private final int barriers;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Mon Apr 07 11:32:08 2014 +0200
@@ -72,6 +72,11 @@
         return graph().unique(new FloatingReadNode(object(), location(), lastLocationAccess, stamp(), getGuard(), getBarrierType(), isCompressible()));
     }
 
+    @Override
+    public boolean isAllowedUsageType(InputType type) {
+        return (getNullCheck() && type == InputType.Guard) ? true : super.isAllowedUsageType(type);
+    }
+
     public static ValueNode canonicalizeRead(ValueNode read, LocationNode location, ValueNode object, CanonicalizerTool tool, boolean compressible) {
         MetaAccessProvider metaAccess = tool.getMetaAccess();
         if (read.usages().isEmpty()) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java	Mon Apr 07 11:32:08 2014 +0200
@@ -33,6 +33,7 @@
 /**
  * The ValueAnchor instruction keeps non-CFG (floating) nodes above a certain point in the graph.
  */
+@NodeInfo(allowedUsageTypes = {InputType.Anchor})
 public final class ValueAnchorNode extends FixedWithNextNode implements LIRLowerable, Simplifiable, Virtualizable {
 
     @Input(InputType.Guard) private ValueNode anchored;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AbstractNewObjectNode.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AbstractNewObjectNode.java	Mon Apr 07 11:32:08 2014 +0200
@@ -40,7 +40,7 @@
 
     /**
      * Constructs a new AbstractNewObjectNode.
-     * 
+     *
      * @param stamp the stamp of the newly created object
      * @param fillContents determines if the object's contents should be initialized to zero/null.
      */
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessMonitorNode.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessMonitorNode.java	Mon Apr 07 11:32:08 2014 +0200
@@ -34,6 +34,7 @@
  * The Java bytecode specification allows non-balanced locking. Graal does not handle such cases and
  * throws a {@link BailoutException} instead during graph building.
  */
+@NodeInfo(allowedUsageTypes = {InputType.Memory})
 public abstract class AccessMonitorNode extends AbstractMemoryCheckpoint implements MemoryCheckpoint, DeoptimizingNode.DeoptBefore, DeoptimizingNode.DeoptAfter {
 
     @Input(InputType.State) private FrameState stateBefore;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ArrayLengthNode.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ArrayLengthNode.java	Mon Apr 07 11:32:08 2014 +0200
@@ -56,10 +56,10 @@
 
     /**
      * Gets the length of an array if possible.
-     * 
+     *
      * @param graph TODO
      * @param array an array
-     * 
+     *
      * @return a node representing the length of {@code array} or null if it is not available
      */
     public static ValueNode readArrayLength(StructuredGraph graph, ValueNode array, ConstantReflectionProvider constantReflection) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java	Mon Apr 07 11:32:08 2014 +0200
@@ -52,7 +52,7 @@
 
     /**
      * Creates a new CheckCast instruction.
-     * 
+     *
      * @param type the type being cast to
      * @param object the instruction producing the object
      */
@@ -71,26 +71,26 @@
 
     /**
      * Lowers a {@link CheckCastNode} to a {@link GuardingPiNode}. That is:
-     * 
+     *
      * <pre>
      * 1: A a = ...
      * 2: B b = (B) a;
      * </pre>
-     * 
+     *
      * is lowered to:
-     * 
+     *
      * <pre>
      * 1: A a = ...
      * 2: B b = guardingPi(a == null || a instanceof B, a, stamp(B))
      * </pre>
-     * 
+     *
      * or if a is known to be non-null:
-     * 
+     *
      * <pre>
      * 1: A a = ...
      * 2: B b = guardingPi(a instanceof B, a, stamp(B, non-null))
      * </pre>
-     * 
+     *
      * Note: we use {@link Graph#addWithoutUnique} as opposed to {@link Graph#unique} for the new
      * {@link InstanceOfNode} to maintain the invariant checked by
      * {@code LoweringPhase.checkUsagesAreScheduled()}.
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java	Mon Apr 07 11:32:08 2014 +0200
@@ -25,6 +25,7 @@
 import static com.oracle.graal.graph.UnsafeAccess.*;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
@@ -34,6 +35,7 @@
  * Represents an atomic compare-and-swap operation The result is a boolean that contains whether the
  * value matched the expected value.
  */
+@NodeInfo(allowedUsageTypes = {InputType.Memory})
 public class CompareAndSwapNode extends AbstractMemoryCheckpoint implements Lowerable, MemoryCheckpoint.Single {
 
     @Input private ValueNode object;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java	Mon Apr 07 11:32:08 2014 +0200
@@ -34,7 +34,7 @@
 
     /**
      * Creates a new LoadIndexedNode.
-     * 
+     *
      * @param array the instruction producing the array
      * @param index the instruction producing the index
      * @param elementKind the element type
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredCompareAndSwapNode.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredCompareAndSwapNode.java	Mon Apr 07 11:32:08 2014 +0200
@@ -32,6 +32,7 @@
 /**
  * Represents the lowered version of an atomic compare-and-swap operation{@code CompareAndSwapNode}.
  */
+@NodeInfo(allowedUsageTypes = {InputType.Value, InputType.Memory})
 public class LoweredCompareAndSwapNode extends FixedAccessNode implements StateSplit, LIRLowerable, MemoryCheckpoint.Single {
 
     @Input private ValueNode expectedValue;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorIdNode.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorIdNode.java	Mon Apr 07 11:32:08 2014 +0200
@@ -32,6 +32,7 @@
  * states together. It is thus referenced from the {@link MonitorEnterNode}, from the
  * {@link MonitorExitNode} and from the {@link FrameState}.
  */
+@NodeInfo(allowedUsageTypes = {InputType.Association})
 public class MonitorIdNode extends ValueNode implements IterableNodeType, LIRLowerable {
 
     private int lockDepth;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewMultiArrayNode.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewMultiArrayNode.java	Mon Apr 07 11:32:08 2014 +0200
@@ -50,7 +50,7 @@
 
     /**
      * Constructs a new NewMultiArrayNode.
-     * 
+     *
      * @param type the element type of the array
      * @param dimensions the node which produce the dimensions for this array
      */
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java	Mon Apr 07 11:32:08 2014 +0200
@@ -205,7 +205,7 @@
 
     /**
      * Gets an approximate source code location for a node if possible.
-     * 
+     *
      * @return the StackTraceElements if an approximate source location is found, null otherwise
      */
     public static StackTraceElement[] approxSourceStackTraceElement(Node node) {
@@ -235,7 +235,7 @@
 
     /**
      * Gets an approximate source code location for a node, encoded as an exception, if possible.
-     * 
+     *
      * @return the exception with the location
      */
     public static RuntimeException approxSourceException(Node node, Throwable cause) {
@@ -254,7 +254,7 @@
 
     /**
      * Gets an approximate source code location for a node if possible.
-     * 
+     *
      * @return a file name and source line number in stack trace format (e.g. "String.java:32") if
      *         an approximate source location is found, null otherwise
      */
@@ -271,7 +271,7 @@
 
     /**
      * Returns a string representation of the given collection of objects.
-     * 
+     *
      * @param objects The {@link Iterable} that will be used to iterate over the objects.
      * @return A string of the format "[a, b, ...]".
      */
@@ -290,7 +290,7 @@
 
     /**
      * Gets the original value by iterating through all {@link ValueProxy ValueProxies}.
-     * 
+     *
      * @param value The start value.
      * @return The first non-proxy value encountered.
      */
@@ -306,7 +306,7 @@
      * Tries to find an original value of the given node by traversing through proxies and
      * unambiguous phis. Note that this method will perform an exhaustive search through phis. It is
      * intended to be used during graph building, when phi nodes aren't yet canonicalized.
-     * 
+     *
      * @param proxy The node whose original value should be determined.
      */
     public static ValueNode originalValue(ValueNode proxy) {
@@ -359,7 +359,7 @@
 
         /**
          * Process a node as part of this search.
-         * 
+         *
          * @param node the next node encountered in the search
          * @param worklist if non-null, {@code node} will be added to this list. Otherwise,
          *            {@code node} is treated as a candidate result.
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/CommitAllocationNode.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/CommitAllocationNode.java	Mon Apr 07 11:32:08 2014 +0200
@@ -32,7 +32,7 @@
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 
-@NodeInfo(nameTemplate = "Alloc {i#virtualObjects}")
+@NodeInfo(nameTemplate = "Alloc {i#virtualObjects}", allowedUsageTypes = {InputType.Association})
 public final class CommitAllocationNode extends FixedWithNextNode implements VirtualizableAllocation, Lowerable, Simplifiable {
 
     @Input private final NodeInputList<VirtualObjectNode> virtualObjects = new NodeInputList<>(this);
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/GraphOrder.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/GraphOrder.java	Mon Apr 07 11:32:08 2014 +0200
@@ -43,7 +43,7 @@
      * Quick (and imprecise) assertion that there are no (invalid) cycles in the given graph. First,
      * an ordered list of all nodes in the graph (a total ordering) is created. A second run over
      * this list checks whether inputs are scheduled before their usages.
-     * 
+     *
      * @param graph the graph to be checked.
      * @throws AssertionError if a cycle was detected.
      */
@@ -133,7 +133,7 @@
     /**
      * This method schedules the graph and makes sure that, for every node, all inputs are available
      * at the position where it is scheduled. This is a very expensive assertion.
-     * 
+     *
      * Also, this phase assumes ProxyNodes to exist at LoopExitNodes, so that it cannot be run after
      * phases that remove loop proxies or move proxies to BeginNodes.
      */
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/IdealGraphPrinter.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/IdealGraphPrinter.java	Mon Apr 07 11:32:08 2014 +0200
@@ -46,7 +46,7 @@
 
     /**
      * Creates a new {@link IdealGraphPrinter} that writes to the specified output stream.
-     * 
+     *
      * @param tryToSchedule If false, no scheduling is done, which avoids exceptions for
      *            non-schedulable graphs.
      */
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Mon Apr 07 11:32:08 2014 +0200
@@ -220,7 +220,7 @@
 
     /**
      * Registers a method substitution.
-     * 
+     *
      * @param originalMember a method or constructor being substituted
      * @param substituteMethod the substitute method
      * @return the original method
@@ -244,7 +244,7 @@
 
     /**
      * Registers a macro substitution.
-     * 
+     *
      * @param originalMethod a method or constructor being substituted
      * @param macro the substitute macro node class
      * @return the original method
@@ -283,7 +283,7 @@
 
     /**
      * Creates a preprocessed graph for a snippet or method substitution.
-     * 
+     *
      * @param method the snippet or method substitution for which a graph will be created
      * @param original the original method if {@code method} is a {@linkplain MethodSubstitution
      *            substitution} otherwise null
@@ -434,7 +434,7 @@
 
         /**
          * Called after a graph is inlined.
-         * 
+         *
          * @param caller the graph into which {@code callee} was inlined
          * @param callee the graph that was inlined into {@code caller}
          * @param beforeInlineData value returned by {@link #beforeInline}.
@@ -528,7 +528,7 @@
 
     /**
      * Resolves a name to a class.
-     * 
+     *
      * @param className the name of the class to resolve
      * @param optional if true, resolution failure returns null
      * @return the resolved class or null if resolution fails and {@code optional} is true
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java	Mon Apr 07 11:32:08 2014 +0200
@@ -102,7 +102,7 @@
 
     /**
      * Applies {@linkplain LoweringPhase lowering} to a replacement graph.
-     * 
+     *
      * @param replacementGraph a replacement (i.e., snippet or method substitution) graph
      */
     protected StructuredGraph lowerReplacement(final StructuredGraph replacementGraph, LoweringTool tool) {
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/GraphEffectList.java	Mon Apr 07 11:32:04 2014 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/GraphEffectList.java	Mon Apr 07 11:32:08 2014 +0200
@@ -69,7 +69,7 @@
     /**
      * Adds the given fixed node to the graph's control flow, before position (so that the original
      * predecessor of position will then be node's predecessor).
-     * 
+     *
      * @param node The fixed node to be added to the graph.
      * @param position The fixed node before which the node should be added.
      */
@@ -91,7 +91,7 @@
 
     /**
      * Add the given floating node to the graph.
-     * 
+     *
      * @param node The floating node to be added.
      */
     public void addFloatingNode(final ValueNode node, final String cause) {
@@ -112,7 +112,7 @@
 
     /**
      * Adds an value to the given phi node.
-     * 
+     *
      * @param node The phi node to which the value should be added.
      * @param value The value that will be added to the phi node.
      */
@@ -135,7 +135,7 @@
     /**
      * Sets the phi node's input at the given index to the given value, adding new phi inputs as
      * needed.
-     * 
+     *
      * @param node The phi node whose input should be changed.
      * @param index The index of the phi input to be changed.
      * @param value The new value for the phi input.
@@ -159,7 +159,7 @@
     /**
      * Adds a virtual object's state to the given frame state. If the given reusedVirtualObjects set
      * contains the virtual object then old states for this object will be removed.
-     * 
+     *
      * @param node The frame state to which the state should be added.
      * @param state The virtual object state to add.
      */
@@ -192,7 +192,7 @@
 
     /**
      * Removes the given fixed node from the control flow and deletes it.
-     * 
+     *
      * @param node The fixed node that should be deleted.
      */
     public void deleteFixedNode(final FixedWithNextNode node) {
@@ -218,11 +218,11 @@
      * Replaces the given node at its usages without deleting it. If the current node is a fixed
      * node it will be disconnected from the control flow, so that it will be deleted by a
      * subsequent {@link DeadCodeEliminationPhase}
-     * 
+     *
      * @param node The node to be replaced.
      * @param replacement The node that should replace the original value. If the replacement is a
      *            non-connected {@link FixedWithNextNode} it will be added to the control flow.
-     * 
+     *
      */
     public void replaceAtUsages(final ValueNode node, final ValueNode replacement) {
         add(new Effect() {
@@ -252,7 +252,7 @@
 
     /**
      * Replaces the first occurrence of oldInput in node with newInput.
-     * 
+     *
      * @param node The node whose input should be changed.
      * @param oldInput The value to look for.
      * @param newInput The value to replace with.
@@ -280,7 +280,7 @@
 
     /**
      * Performs a custom action.
-     * 
+     *
      * @param action The action that should be performed when the effects are applied.
      */
     public void customAction(final Runnable action) {
@@ -301,7 +301,7 @@
     /**
      * Add the materialization node to the graph's control flow at the given position, and then sets
      * its values.
-     * 
+     *
      * @param position The fixed node before which the materialization node should be added.
      * @param objects The allocated objects.
      * @param locks The lock depths for each object.