changeset 20006:2d51a92a301a

added helper methods to GraphBuilderContext for common operation combinations
author Doug Simon <doug.simon@oracle.com>
date Mon, 23 Mar 2015 20:57:21 +0100
parents 1671d9111c47
children ae0e4453df73
files graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/GraphBuilderContext.java graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/LoadFieldPlugin.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoadFieldPlugin.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoadIndexedPlugin.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotWordOperationPlugin.java graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultGenericInvocationPlugin.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StandardGraphBuilderPlugins.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/WordOperationPlugin.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/TruffleGraphBuilderPlugins.java
diffstat 12 files changed, 125 insertions(+), 87 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/GraphBuilderContext.java	Mon Mar 23 20:04:55 2015 +0100
+++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/GraphBuilderContext.java	Mon Mar 23 20:57:21 2015 +0100
@@ -59,16 +59,79 @@
         boolean isIntrinsic();
     }
 
+    /**
+     * Raw operation for adding a node to the graph when neither {@link #add},
+     * {@link #addPush(ValueNode)} nor {@link #addPush(Kind, ValueNode)} can be used.
+     */
     <T extends ValueNode> T append(T value);
 
     /**
-     * Adds the given floating node to the graph and also adds recursively all referenced inputs.
+     * Adds the given node to the graph and also adds recursively all referenced inputs.
      *
-     * @param value the floating node to be added to the graph
+     * @param value the node to be added to the graph
      * @return either the node added or an equivalent node
      */
     <T extends ValueNode> T recursiveAppend(T value);
 
+    /**
+     * Pushes a given value to the frame state stack using an explicit kind. This should be used
+     * when {@code value.getKind()} is different from the kind that the bytecode instruction
+     * currently being parsed pushes to the stack.
+     *
+     * @param kind the kind to use when type checking this operation
+     * @param value the value to push to the stack. The value must already have been
+     *            {@linkplain #append(ValueNode) appended}.
+     */
+    void push(Kind kind, ValueNode value);
+
+    /**
+     * Appends a node with a void kind to the graph. If the node is a {@link StateSplit}, then its
+     * {@linkplain StateSplit#stateAfter() frame state} is also set.
+     */
+    default <T extends ValueNode> T add(T value) {
+        assert value.getKind() == Kind.Void;
+        T appended = append(value);
+        if (appended instanceof StateSplit) {
+            StateSplit stateSplit = (StateSplit) appended;
+            assert stateSplit.stateAfter() == null;
+            stateSplit.setStateAfter(createStateAfter());
+        }
+        return appended;
+    }
+
+    /**
+     * Adds a node with a non-void kind to the graph, pushes it to the stack. If the node is a
+     * {@link StateSplit}, then its {@linkplain StateSplit#stateAfter() frame state} is also set.
+     *
+     * @param value the value to push to the stack. The value must already have been
+     *            {@linkplain #append(ValueNode) appended}. The {@code value.getKind()} kind is used
+     *            when type checking this operation.
+     * @return the version of {@code value} in the graph which may be different than {@code value}
+     */
+    default <T extends ValueNode> T addPush(T value) {
+        return addPush(value.getKind().getStackKind(), value);
+    }
+
+    /**
+     * Adds a node with a non-void kind to the graph, pushes it to the stack. If the node is a
+     * {@link StateSplit}, then its {@linkplain StateSplit#stateAfter() frame state} is also set.
+     *
+     * @param kind the kind to use when type checking this operation
+     * @param value the value to push to the stack. The value must already have been
+     *            {@linkplain #append(ValueNode) appended}.
+     * @return the version of {@code value} in the graph which may be different than {@code value}
+     */
+    default <T extends ValueNode> T addPush(Kind kind, T value) {
+        T appended = append(value);
+        push(kind, appended);
+        if (appended instanceof StateSplit) {
+            StateSplit stateSplit = (StateSplit) appended;
+            assert stateSplit.stateAfter() == null;
+            stateSplit.setStateAfter(createStateAfter());
+        }
+        return appended;
+    }
+
     StampProvider getStampProvider();
 
     MetaAccessProvider getMetaAccess();
@@ -79,10 +142,12 @@
 
     SnippetReflectionProvider getSnippetReflection();
 
-    void push(Kind kind, ValueNode value);
-
     StructuredGraph getGraph();
 
+    /**
+     * Creates a snap shot of the current frame state with the BCI of the instruction after the one
+     * currently being parsed.
+     */
     FrameState createStateAfter();
 
     /**
--- a/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/LoadFieldPlugin.java	Mon Mar 23 20:04:55 2015 +0100
+++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/LoadFieldPlugin.java	Mon Mar 23 20:57:21 2015 +0100
@@ -39,8 +39,8 @@
     default boolean tryConstantFold(GraphBuilderContext b, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, ResolvedJavaField field, JavaConstant receiver) {
         JavaConstant result = constantReflection.readConstantFieldValue(field, receiver);
         if (result != null) {
-            ConstantNode constantNode = b.append(ConstantNode.forConstant(result, metaAccess));
-            b.push(constantNode.getKind().getStackKind(), constantNode);
+            ConstantNode constantNode = ConstantNode.forConstant(result, metaAccess);
+            b.addPush(constantNode.getKind().getStackKind(), constantNode);
             return true;
         }
         return false;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java	Mon Mar 23 20:04:55 2015 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java	Mon Mar 23 20:57:21 2015 +0100
@@ -105,17 +105,13 @@
         Registration r = new Registration(plugins, System.class);
         r.register0("currentTimeMillis", new InvocationPlugin() {
             public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
-                ForeignCallNode foreignCall = new ForeignCallNode(foreignCalls, SystemSubstitutions.JAVA_TIME_MILLIS, StampFactory.forKind(Kind.Long));
-                b.push(Kind.Long, b.append(foreignCall));
-                foreignCall.setStateAfter(b.createStateAfter());
+                b.addPush(Kind.Long, new ForeignCallNode(foreignCalls, SystemSubstitutions.JAVA_TIME_MILLIS, StampFactory.forKind(Kind.Long)));
                 return true;
             }
         });
         r.register0("nanoTime", new InvocationPlugin() {
             public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
-                ForeignCallNode foreignCall = new ForeignCallNode(foreignCalls, SystemSubstitutions.JAVA_TIME_NANOS, StampFactory.forKind(Kind.Long));
-                b.push(Kind.Long, b.append(foreignCall));
-                foreignCall.setStateAfter(b.createStateAfter());
+                b.addPush(Kind.Long, new ForeignCallNode(foreignCalls, SystemSubstitutions.JAVA_TIME_NANOS, StampFactory.forKind(Kind.Long)));
                 return true;
             }
         });
@@ -131,7 +127,7 @@
                 ValueNode javaThread = WordOperationPlugin.readOp(b, Kind.Object, thread, location, BarrierType.NONE, compressible);
                 boolean exactType = compressible;
                 boolean nonNull = true;
-                b.push(Kind.Object, b.append(new PiNode(javaThread, metaAccess.lookupJavaType(Thread.class), exactType, nonNull)));
+                b.addPush(Kind.Object, new PiNode(javaThread, metaAccess.lookupJavaType(Thread.class), exactType, nonNull));
                 return true;
             }
         });
@@ -144,8 +140,7 @@
                 if (receiver.isConstant()) {
                     Object object = ((HotSpotObjectConstantImpl) receiver.get().asConstant()).object();
                     StableOptionValue<?> option = (StableOptionValue<?>) object;
-                    ConstantNode value = b.append(ConstantNode.forConstant(HotSpotObjectConstantImpl.forObject(option.getValue()), b.getMetaAccess()));
-                    b.push(Kind.Object, value);
+                    b.addPush(Kind.Object, ConstantNode.forConstant(HotSpotObjectConstantImpl.forObject(option.getValue()), b.getMetaAccess()));
                     return true;
                 }
                 return false;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoadFieldPlugin.java	Mon Mar 23 20:04:55 2015 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoadFieldPlugin.java	Mon Mar 23 20:57:21 2015 +0100
@@ -75,8 +75,7 @@
                 // HotSpotInlineInvokePlugin.notifyOfNoninlinedInvoke). Direct use of
                 // assertions in intrinsics is forbidden.
                 assert b.getMethod().getAnnotation(MethodSubstitution.class) == null : "cannot use assertions in " + b.getMethod().format("%H.%n(%p)");
-                ConstantNode trueNode = b.append(ConstantNode.forBoolean(true));
-                b.push(trueNode.getKind().getStackKind(), trueNode);
+                b.addPush(ConstantNode.forBoolean(true));
                 return true;
             }
             return tryReadField(b, staticField, null);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoadIndexedPlugin.java	Mon Mar 23 20:04:55 2015 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoadIndexedPlugin.java	Mon Mar 23 20:57:21 2015 +0100
@@ -54,9 +54,9 @@
                  */
                 Stamp componentStamp = wordTypes.getWordStamp(arrayType.getComponentType());
                 if (componentStamp instanceof MetaspacePointerStamp) {
-                    b.push(elementKind, b.append(new LoadIndexedPointerNode(componentStamp, array, index)));
+                    b.addPush(elementKind, new LoadIndexedPointerNode(componentStamp, array, index));
                 } else {
-                    b.push(elementKind, b.append(new LoadIndexedNode(array, index, wordTypes.getWordKind())));
+                    b.addPush(elementKind, new LoadIndexedNode(array, index, wordTypes.getWordKind()));
                 }
                 return true;
             }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotWordOperationPlugin.java	Mon Mar 23 20:04:55 2015 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotWordOperationPlugin.java	Mon Mar 23 20:57:21 2015 +0100
@@ -82,7 +82,7 @@
                 PointerEqualsNode comparison = b.append(new PointerEqualsNode(left, right));
                 ValueNode eqValue = b.append(forBoolean(opcode == POINTER_EQ));
                 ValueNode neValue = b.append(forBoolean(opcode == POINTER_NE));
-                b.push(returnStackKind, b.append(new ConditionalNode(comparison, eqValue, neValue)));
+                b.addPush(returnStackKind, new ConditionalNode(comparison, eqValue, neValue));
                 break;
 
             case IS_NULL:
@@ -91,22 +91,22 @@
                 assert pointer.stamp() instanceof MetaspacePointerStamp;
 
                 IsNullNode isNull = b.append(new IsNullNode(pointer));
-                b.push(returnStackKind, b.append(new ConditionalNode(isNull, b.append(forBoolean(true)), b.append(forBoolean(false)))));
+                b.addPush(returnStackKind, new ConditionalNode(isNull, b.append(forBoolean(true)), b.append(forBoolean(false))));
                 break;
 
             case FROM_POINTER:
                 assert args.length == 1;
-                b.push(returnStackKind, b.append(new PointerCastNode(StampFactory.forKind(wordKind), args[0])));
+                b.addPush(returnStackKind, new PointerCastNode(StampFactory.forKind(wordKind), args[0]));
                 break;
 
             case TO_KLASS_POINTER:
                 assert args.length == 1;
-                b.push(returnStackKind, b.append(new PointerCastNode(KlassPointerStamp.klass(), args[0])));
+                b.addPush(returnStackKind, new PointerCastNode(KlassPointerStamp.klass(), args[0]));
                 break;
 
             case TO_METHOD_POINTER:
                 assert args.length == 1;
-                b.push(returnStackKind, b.append(new PointerCastNode(MethodPointerStamp.method(), args[0])));
+                b.addPush(returnStackKind, new PointerCastNode(MethodPointerStamp.method(), args[0]));
                 break;
 
             case READ_KLASS_POINTER:
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Mon Mar 23 20:04:55 2015 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Mon Mar 23 20:57:21 2015 +0100
@@ -823,9 +823,7 @@
 
             @Override
             protected void genStoreIndexed(ValueNode array, ValueNode index, Kind kind, ValueNode value) {
-                StoreIndexedNode storeIndexed = new StoreIndexedNode(array, index, kind, value);
-                append(storeIndexed);
-                storeIndexed.setStateAfter(this.createStateAfter());
+                add(new StoreIndexedNode(array, index, kind, value));
             }
 
             @Override
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultGenericInvocationPlugin.java	Mon Mar 23 20:04:55 2015 +0100
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultGenericInvocationPlugin.java	Mon Mar 23 20:57:21 2015 +0100
@@ -79,7 +79,7 @@
                     if (constant != null) {
                         // Replace the invoke with the result of the call
                         ConstantNode res = b.append(ConstantNode.forConstant(constant, b.getMetaAccess()));
-                        b.push(res.getKind().getStackKind(), b.append(res));
+                        b.addPush(res.getKind().getStackKind(), res);
                     } else {
                         // This must be a void invoke
                         assert method.getSignature().getReturnKind() == Kind.Void;
@@ -99,9 +99,7 @@
         if (res instanceof UnsafeCopyNode) {
             UnsafeCopyNode copy = (UnsafeCopyNode) res;
             UnsafeLoadNode value = b.append(new UnsafeLoadNode(copy.sourceObject(), copy.sourceOffset(), copy.accessKind(), copy.getLocationIdentity()));
-            UnsafeStoreNode unsafeStore = new UnsafeStoreNode(copy.destinationObject(), copy.destinationOffset(), value, copy.accessKind(), copy.getLocationIdentity());
-            b.append(unsafeStore);
-            unsafeStore.setStateAfter(b.createStateAfter());
+            b.add(new UnsafeStoreNode(copy.destinationObject(), copy.destinationOffset(), value, copy.accessKind(), copy.getLocationIdentity()));
             return true;
         } else if (res instanceof ForeignCallNode) {
             ForeignCallNode foreign = (ForeignCallNode) res;
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StandardGraphBuilderPlugins.java	Mon Mar 23 20:04:55 2015 +0100
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StandardGraphBuilderPlugins.java	Mon Mar 23 20:57:21 2015 +0100
@@ -108,9 +108,7 @@
                 public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver unsafe, ValueNode object, ValueNode offset, ValueNode expected, ValueNode x) {
                     // Emits a null-check for the otherwise unused receiver
                     unsafe.get();
-                    CompareAndSwapNode compareAndSwap = new CompareAndSwapNode(object, offset, expected, x, kind, LocationIdentity.any());
-                    b.push(Kind.Boolean.getStackKind(), b.append(compareAndSwap));
-                    compareAndSwap.setStateAfter(b.createStateAfter());
+                    b.addPush(Kind.Int, new CompareAndSwapNode(object, offset, expected, x, kind, LocationIdentity.any()));
                     return true;
                 }
             });
@@ -120,9 +118,7 @@
                     public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver unsafe, ValueNode object, ValueNode offset, ValueNode value) {
                         // Emits a null-check for the otherwise unused receiver
                         unsafe.get();
-                        AtomicReadAndWriteNode atomicReadWrite = new AtomicReadAndWriteNode(object, offset, value, kind, LocationIdentity.any());
-                        b.push(kind.getStackKind(), b.append(atomicReadWrite));
-                        atomicReadWrite.setStateAfter(b.createStateAfter());
+                        b.addPush(kind.getStackKind(), new AtomicReadAndWriteNode(object, offset, value, kind, LocationIdentity.any()));
                         return true;
                     }
                 });
@@ -131,9 +127,7 @@
                         public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver unsafe, ValueNode object, ValueNode offset, ValueNode delta) {
                             // Emits a null-check for the otherwise unused receiver
                             unsafe.get();
-                            AtomicReadAndAddNode atomicReadAdd = new AtomicReadAndAddNode(object, offset, delta, LocationIdentity.any());
-                            b.push(kind.getStackKind(), b.append(atomicReadAdd));
-                            atomicReadAdd.setStateAfter(b.createStateAfter());
+                            b.addPush(kind.getStackKind(), new AtomicReadAndAddNode(object, offset, delta, LocationIdentity.any()));
                             return true;
                         }
                     });
@@ -302,7 +296,7 @@
             }
 
             LogicNode compare = CompareNode.createCompareNode(graph, cond, lhs, rhs, b.getConstantReflection());
-            b.push(Kind.Boolean.getStackKind(), b.append(new ConditionalNode(compare, trueValue, falseValue)));
+            b.addPush(Kind.Boolean.getStackKind(), new ConditionalNode(compare, trueValue, falseValue));
             return true;
         }
     }
@@ -358,9 +352,7 @@
             public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
                 ValueNode object = receiver.get();
                 if (RegisterFinalizerNode.mayHaveFinalizer(object, b.getAssumptions())) {
-                    RegisterFinalizerNode registerFinalizer = new RegisterFinalizerNode(object);
-                    b.append(registerFinalizer);
-                    registerFinalizer.setStateAfter(b.createStateAfter());
+                    b.add(new RegisterFinalizerNode(object));
                 }
                 return true;
             }
@@ -388,7 +380,7 @@
                 if (receiver.isConstant()) {
                     ResolvedJavaType type = b.getConstantReflection().asJavaType(receiver.get().asConstant());
                     if (type != null && !type.isPrimitive()) {
-                        b.push(Kind.Object, b.append(CheckCastNode.create(type, object, null, false, b.getAssumptions())));
+                        b.addPush(Kind.Object, CheckCastNode.create(type, object, null, false, b.getAssumptions()));
                         return true;
                     }
                 }
@@ -412,15 +404,13 @@
                     ValueNode value = b.append(new UnsafeLoadNode(node, offset, Kind.Object, LocationIdentity.any()));
                     boolean exactType = false;
                     boolean nonNull = false;
-                    b.push(Kind.Object, b.append(new PiNode(value, metaAccess.lookupJavaType(c), exactType, nonNull)));
+                    b.addPush(Kind.Object, new PiNode(value, metaAccess.lookupJavaType(c), exactType, nonNull));
                     return true;
                 }
             });
             r.register3("put" + c.getSimpleName() + "Unsafe", Node.class, long.class, c, new InvocationPlugin() {
                 public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode node, ValueNode offset, ValueNode value) {
-                    UnsafeStoreNode unsafeStore = new UnsafeStoreNode(node, offset, value, Kind.Object, LocationIdentity.any());
-                    b.append(unsafeStore);
-                    unsafeStore.setStateAfter(b.createStateAfter());
+                    b.add(new UnsafeStoreNode(node, offset, value, Kind.Object, LocationIdentity.any()));
                     return true;
                 }
             });
@@ -445,7 +435,7 @@
                 }
             }
             ResolvedJavaType resultType = b.getMetaAccess().lookupJavaType(kind.toBoxedJavaClass());
-            b.push(Kind.Object, b.append(new BoxNode(value, resultType, kind)));
+            b.addPush(Kind.Object, new BoxNode(value, resultType, kind));
             return true;
         }
 
@@ -472,7 +462,7 @@
                 }
             }
             ValueNode valueNode = UnboxNode.create(b.getMetaAccess(), b.getConstantReflection(), receiver.get(), kind);
-            b.push(kind.getStackKind(), b.append(valueNode));
+            b.addPush(kind.getStackKind(), valueNode);
             return true;
         }
 
@@ -495,7 +485,7 @@
         public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver unsafe, ValueNode address) {
             // Emits a null-check for the otherwise unused receiver
             unsafe.get();
-            b.push(returnKind.getStackKind(), b.append(new DirectReadNode(address, returnKind)));
+            b.addPush(returnKind.getStackKind(), new DirectReadNode(address, returnKind));
             return true;
         }
 
@@ -505,7 +495,7 @@
             if (isVolatile) {
                 b.append(new MembarNode(JMM_PRE_VOLATILE_READ));
             }
-            b.push(returnKind.getStackKind(), b.append(new UnsafeLoadNode(object, offset, returnKind, LocationIdentity.any())));
+            b.addPush(returnKind.getStackKind(), new UnsafeLoadNode(object, offset, returnKind, LocationIdentity.any()));
             if (isVolatile) {
                 b.append(new MembarNode(JMM_POST_VOLATILE_READ));
             }
@@ -536,9 +526,7 @@
             if (isVolatile) {
                 b.append(new MembarNode(JMM_PRE_VOLATILE_WRITE));
             }
-            UnsafeStoreNode unsafeStore = new UnsafeStoreNode(object, offset, value, kind, LocationIdentity.any());
-            b.append(unsafeStore);
-            unsafeStore.setStateAfter(b.createStateAfter());
+            b.add(new UnsafeStoreNode(object, offset, value, kind, LocationIdentity.any()));
             if (isVolatile) {
                 b.append(new MembarNode(JMM_PRE_VOLATILE_WRITE));
             }
@@ -564,7 +552,7 @@
 
         r.register0("inCompiledCode", new InvocationPlugin() {
             public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
-                b.push(Kind.Int, b.append(ConstantNode.forInt(1)));
+                b.addPush(Kind.Int, ConstantNode.forInt(1));
                 return true;
             }
         });
@@ -578,7 +566,7 @@
 
         r.register2("injectBranchProbability", double.class, boolean.class, new InvocationPlugin() {
             public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode probability, ValueNode condition) {
-                b.push(Kind.Int, b.append(new BranchProbabilityNode(probability, condition)));
+                b.addPush(Kind.Int, new BranchProbabilityNode(probability, condition));
                 return true;
             }
         });
@@ -598,7 +586,7 @@
                 final Kind stackKind = kind.getStackKind();
                 r.register1("opaque", javaClass, new InvocationPlugin() {
                     public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
-                        b.push(stackKind, b.append(new OpaqueNode(value)));
+                        b.addPush(stackKind, new OpaqueNode(value));
                         return true;
                     }
                 });
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/WordOperationPlugin.java	Mon Mar 23 20:04:55 2015 +0100
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/WordOperationPlugin.java	Mon Mar 23 20:57:21 2015 +0100
@@ -81,7 +81,7 @@
                 ValueNode left = args[0];
                 ValueNode right = operation.rightOperandIsInt() ? toUnsigned(b, args[1], Kind.Int) : fromSigned(b, args[1]);
 
-                b.push(returnStackKind, b.append(createBinaryNodeInstance(operation.node(), left, right)));
+                b.addPush(returnStackKind, createBinaryNodeInstance(operation.node(), left, right));
                 break;
 
             case COMPARISON:
@@ -91,7 +91,7 @@
 
             case NOT:
                 assert args.length == 1;
-                b.push(returnStackKind, b.append(new XorNode(args[0], b.append(forIntegerKind(wordKind, -1)))));
+                b.addPush(returnStackKind, new XorNode(args[0], b.append(forIntegerKind(wordKind, -1))));
                 break;
 
             case READ_POINTER:
@@ -133,7 +133,7 @@
             }
             case ZERO:
                 assert args.length == 0;
-                b.push(returnStackKind, b.append(forIntegerKind(wordKind, 0L)));
+                b.addPush(returnStackKind, forIntegerKind(wordKind, 0L));
                 break;
 
             case FROM_UNSIGNED:
@@ -164,7 +164,7 @@
 
             case FROM_ARRAY:
                 assert args.length == 2;
-                b.push(returnStackKind, b.append(new ComputeAddressNode(args[0], args[1], StampFactory.forKind(wordKind))));
+                b.addPush(returnStackKind, new ComputeAddressNode(args[0], args[1], StampFactory.forKind(wordKind)));
                 break;
 
             case TO_OBJECT:
@@ -245,9 +245,7 @@
         final BarrierType barrier = (op == Opcode.WRITE_BARRIERED ? BarrierType.PRECISE : BarrierType.NONE);
         final boolean compressible = (op == Opcode.WRITE_OBJECT || op == Opcode.WRITE_BARRIERED);
         final boolean initialize = (op == Opcode.INITIALIZE);
-        JavaWriteNode writeNode = new JavaWriteNode(writeKind, base, value, location, barrier, compressible, initialize);
-        b.append(writeNode);
-        writeNode.setStateAfter(b.createStateAfter());
+        b.add(new JavaWriteNode(writeKind, base, value, location, barrier, compressible, initialize));
     }
 
     public LocationNode makeLocation(GraphBuilderContext b, ValueNode offset, LocationIdentity locationIdentity) {
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Mon Mar 23 20:04:55 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Mon Mar 23 20:57:21 2015 +0100
@@ -163,7 +163,7 @@
         public boolean apply(GraphBuilderContext builder, ResolvedJavaField staticField) {
             if (TruffleCompilerOptions.TruffleExcludeAssertions.getValue() && staticField.getName().equals("$assertionsDisabled")) {
                 ConstantNode trueNode = builder.append(ConstantNode.forBoolean(true));
-                builder.push(trueNode.getKind().getStackKind(), trueNode);
+                builder.addPush(trueNode);
                 return true;
             }
             return tryConstantFold(builder, providers.getMetaAccess(), providers.getConstantReflection(), staticField, null);
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/TruffleGraphBuilderPlugins.java	Mon Mar 23 20:04:55 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/TruffleGraphBuilderPlugins.java	Mon Mar 23 20:57:21 2015 +0100
@@ -73,7 +73,7 @@
                 if (receiver.isConstant()) {
                     Constant constant = receiver.get().asConstant();
                     OptimizedAssumption assumption = b.getSnippetReflection().asObject(OptimizedAssumption.class, (JavaConstant) constant);
-                    b.push(Kind.Boolean.getStackKind(), b.append(ConstantNode.forBoolean(assumption.isValid())));
+                    b.addPush(Kind.Boolean.getStackKind(), ConstantNode.forBoolean(assumption.isValid()));
                     if (assumption.isValid()) {
                         b.getAssumptions().record(new AssumptionValidAssumption(assumption));
                     }
@@ -91,31 +91,31 @@
             Class<?> type = kind.toJavaClass();
             r.register2("addExact", type, type, new InvocationPlugin() {
                 public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x, ValueNode y) {
-                    b.push(kind.getStackKind(), b.append(new IntegerAddExactNode(x, y)));
+                    b.addPush(kind.getStackKind(), new IntegerAddExactNode(x, y));
                     return true;
                 }
             });
             r.register2("subtractExact", type, type, new InvocationPlugin() {
                 public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x, ValueNode y) {
-                    b.push(kind.getStackKind(), b.append(new IntegerSubExactNode(x, y)));
+                    b.addPush(kind.getStackKind(), new IntegerSubExactNode(x, y));
                     return true;
                 }
             });
             r.register2("multiplyExact", type, type, new InvocationPlugin() {
                 public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x, ValueNode y) {
-                    b.push(kind.getStackKind(), b.append(new IntegerMulExactNode(x, y)));
+                    b.addPush(kind.getStackKind(), new IntegerMulExactNode(x, y));
                     return true;
                 }
             });
             r.register2("multiplyHigh", type, type, new InvocationPlugin() {
                 public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x, ValueNode y) {
-                    b.push(kind.getStackKind(), b.append(new IntegerMulHighNode(x, y)));
+                    b.addPush(kind.getStackKind(), new IntegerMulHighNode(x, y));
                     return true;
                 }
             });
             r.register2("multiplyHighUnsigned", type, type, new InvocationPlugin() {
                 public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x, ValueNode y) {
-                    b.push(kind.getStackKind(), b.append(new UnsignedMulHighNode(x, y)));
+                    b.addPush(kind.getStackKind(), new UnsignedMulHighNode(x, y));
                     return true;
                 }
             });
@@ -126,13 +126,13 @@
         Registration r = new Registration(plugins, CompilerDirectives.class);
         r.register0("inInterpreter", new InvocationPlugin() {
             public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
-                b.push(Kind.Boolean.getStackKind(), b.append(ConstantNode.forBoolean(false)));
+                b.addPush(Kind.Boolean.getStackKind(), ConstantNode.forBoolean(false));
                 return true;
             }
         });
         r.register0("inCompiledCode", new InvocationPlugin() {
             public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
-                b.push(Kind.Boolean.getStackKind(), b.append(ConstantNode.forBoolean(true)));
+                b.addPush(Kind.Boolean.getStackKind(), ConstantNode.forBoolean(true));
                 return true;
             }
         });
@@ -160,7 +160,7 @@
         });
         r.register2("injectBranchProbability", double.class, boolean.class, new InvocationPlugin() {
             public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode probability, ValueNode condition) {
-                b.push(Kind.Boolean.getStackKind(), b.append(new BranchProbabilityNode(probability, condition)));
+                b.addPush(Kind.Boolean.getStackKind(), new BranchProbabilityNode(probability, condition));
                 return true;
             }
         });
@@ -175,9 +175,9 @@
         r.register1("isCompilationConstant", Object.class, new InvocationPlugin() {
             public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
                 if ((value instanceof BoxNode ? ((BoxNode) value).getValue() : value).isConstant()) {
-                    b.push(Kind.Boolean.getStackKind(), b.append(ConstantNode.forBoolean(true)));
+                    b.addPush(Kind.Boolean.getStackKind(), ConstantNode.forBoolean(true));
                 } else {
-                    b.push(Kind.Boolean.getStackKind(), b.append(new IsCompilationConstantNode(value)));
+                    b.addPush(Kind.Boolean.getStackKind(), new IsCompilationConstantNode(value));
                 }
                 return true;
             }
@@ -232,13 +232,13 @@
         r.register2("createFrame", FrameDescriptor.class, Object[].class, new InvocationPlugin() {
             public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode descriptor, ValueNode args) {
                 Class<?> frameClass = TruffleCompilerOptions.TruffleUseFrameWithoutBoxing.getValue() ? FrameWithoutBoxing.class : FrameWithBoxing.class;
-                b.push(Kind.Object, b.append(new NewFrameNode(StampFactory.exactNonNull(metaAccess.lookupJavaType(frameClass)), descriptor, args)));
+                b.addPush(Kind.Object, new NewFrameNode(StampFactory.exactNonNull(metaAccess.lookupJavaType(frameClass)), descriptor, args));
                 return true;
             }
         });
         r.register2("castArrayFixedLength", Object[].class, int.class, new InvocationPlugin() {
             public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode args, ValueNode length) {
-                b.push(Kind.Object, b.append(new PiArrayNode(args, length, args.stamp())));
+                b.addPush(Kind.Object, new PiArrayNode(args, length, args.stamp()));
                 return true;
             }
         });
@@ -266,7 +266,7 @@
     private static void registerMaterialize(Registration r) {
         r.register1("materialize", Receiver.class, new InvocationPlugin() {
             public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver frame) {
-                b.push(Kind.Object, b.append(new MaterializeFrameNode(frame.get())));
+                b.addPush(Kind.Object, new MaterializeFrameNode(frame.get()));
                 return true;
             }
         });
@@ -303,8 +303,7 @@
                         if (!skipAnchor) {
                             valueAnchorNode = b.append(new ConditionAnchorNode(compareNode));
                         }
-                        PiNode piCast = b.append(new PiNode(object, piStamp, valueAnchorNode));
-                        b.push(Kind.Object, piCast);
+                        b.addPush(Kind.Object, new PiNode(object, piStamp, valueAnchorNode));
                     }
                     return true;
                 }
@@ -341,7 +340,7 @@
                     locationIdentity = ObjectLocationIdentity.create(location.asJavaConstant());
                 }
                 LogicNode compare = b.append(CompareNode.createCompareNode(Condition.EQ, condition, ConstantNode.forBoolean(true, object.graph()), b.getConstantReflection()));
-                b.push(returnKind.getStackKind(), b.append(new UnsafeLoadNode(object, offset, returnKind, locationIdentity, compare)));
+                b.addPush(returnKind.getStackKind(), b.append(new UnsafeLoadNode(object, offset, returnKind, locationIdentity, compare)));
                 return true;
             }
             // TODO: should we throw GraalInternalError.shouldNotReachHere() here?
@@ -367,9 +366,7 @@
                     locationIdentity = ObjectLocationIdentity.create(locationArgument.asJavaConstant());
                 }
 
-                UnsafeStoreNode unsafeStore = new UnsafeStoreNode(object, offset, value, kind, locationIdentity, null);
-                b.append(unsafeStore);
-                unsafeStore.setStateAfter(b.createStateAfter());
+                b.add(new UnsafeStoreNode(object, offset, value, kind, locationIdentity, null));
                 return true;
             }
             // TODO: should we throw GraalInternalError.shouldNotReachHere() here?