changeset 17208:d8f4c1e6b538

Merge
author Stefan Anzinger <stefan.anzinger@oracle.com>
date Wed, 24 Sep 2014 16:22:22 -0700
parents 5a7b82c1514e (current diff) 873f082901c8 (diff)
children 1b6172cb270e
files graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeAllRefsIterator.java graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeRefIterable.java graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeRefIterator.java graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeRefWithModCountIterator.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BitLogicNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatAddNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatArithmeticNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatDivNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatMulNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatRemNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatSubNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerAddNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerArithmeticNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerMulNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerSubNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/ValueAndStampProxy.java graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotFrameInstance.java graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/ReadOnlyFrame.java mx/projects.py
diffstat 113 files changed, 3896 insertions(+), 5156 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Wed Sep 24 16:13:34 2014 -0700
+++ b/.hgtags	Wed Sep 24 16:22:22 2014 -0700
@@ -407,3 +407,4 @@
 483d05bf77a7c2a762aca1e06c4191bc06647176 graal-0.2
 9535eccd2a115f6c6f0b15efb508b11ff74cc0d3 graal-0.3
 7d4f630172a16e983212d46c0f1ad6cdb826dfce graal-0.4
+ae5b662550836e851c39e4fbb5c80517fc62488f graal-0.5
--- a/CHANGELOG.md	Wed Sep 24 16:13:34 2014 -0700
+++ b/CHANGELOG.md	Wed Sep 24 16:22:22 2014 -0700
@@ -2,16 +2,29 @@
 
 ## `tip`
 ### Graal
+* Changed name suite specification from `mx/projects.py` to `mx/suite.py`.
 * ...
 
 ### Truffle
-* Added TruffleRuntime#getCallTargets() to get all call targets that were created and are still referenced.
+* ...
+
+## Version 0.5
+23-Sep-2014, [Repository Revision](http://hg.openjdk.java.net/graal/graal/shortlog/graal-0.5)
+### Graal
+* New register allocator optimization: `-G:+ConstantLoadOptimization`.
+* SPARC backend is able to run benchmark and passing most of the JTTs.
+* Fix: Stamp: interface types can not be trusted except after explicit runtime checks.
+* Changed format of suite specification from a properties file (`mx/projects`) to a Python file (`mx/projects.py`).
+
+
+### Truffle
+* Added `TruffleRuntime#getCallTargets()` to get all call targets that were created and are still referenced.
 * Added `NeverValidAssumption` to complement `AlwaysValidAssumption`.
 * Fixed a bug in `AssumedValue` that may not invalidate correctly.
-* New option, TruffleCompilationExceptionsAreThrown, that will throw a OptimizationFailedException for compiler errors.
+* New option, `-G:+/-TruffleCompilationExceptionsAreThrown`, that will throw an `OptimizationFailedException` for compiler errors.
 
 ## Version 0.4
-19-Aug-2014, [Repository Revision](http://hg.openjdk.java.net/graal/graal/rev/graal-0.4)
+19-Aug-2014, [Repository Revision](http://hg.openjdk.java.net/graal/graal/shortlog/graal-0.4)
 ### Graal
 * Made initialization of Graal runtime lazy in hosted mode.
 * Added supported for new `jrelibrary` dependency type in `mx/projects`.
@@ -36,7 +49,7 @@
 * Added new `ConditionProfile`, `BinaryConditionProfile` and `CountingConditionProfile` utility classes to profile if conditions.
 
 ## Version 0.3
-9-May-2014, [Repository Revision](http://hg.openjdk.java.net/graal/graal/rev/graal-0.3)
+9-May-2014, [Repository Revision](http://hg.openjdk.java.net/graal/graal/shortlog/graal-0.3)
 
 ### Graal
 * Explicit support for oop compression/uncompression in high level graph.
@@ -58,7 +71,7 @@
 * Removed deprecated `Node#adoptChild`.
 
 ## Version 0.2
-25-Mar-2014, [Repository Revision](http://hg.openjdk.java.net/graal/graal/rev/graal-0.2)
+25-Mar-2014, [Repository Revision](http://hg.openjdk.java.net/graal/graal/shortlog/graal-0.2)
 
 ### Graal
 * Use HotSpot stubs for certain array copy operations.
@@ -89,7 +102,7 @@
 
 
 ## Version 0.1
-5-Feb-2014, [Repository Revision](http://hg.openjdk.java.net/graal/graal/rev/graal-0.1)
+5-Feb-2014, [Repository Revision](http://hg.openjdk.java.net/graal/graal/shortlog/graal-0.1)
 
 ### Graal
 
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeUtil.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeUtil.java	Wed Sep 24 16:22:22 2014 -0700
@@ -47,7 +47,7 @@
 
     /**
      * Checks whether the specified integer is a power of two.
-     * 
+     *
      * @param val the value to check
      * @return {@code true} if the value is a power of two; {@code false} otherwise
      */
@@ -57,7 +57,7 @@
 
     /**
      * Checks whether the specified long is a power of two.
-     * 
+     *
      * @param val the value to check
      * @return {@code true} if the value is a power of two; {@code false} otherwise
      */
@@ -68,7 +68,7 @@
     /**
      * Computes the log (base 2) of the specified integer, rounding down. (E.g {@code log2(8) = 3},
      * {@code log2(21) = 4} )
-     * 
+     *
      * @param val the value
      * @return the log base 2 of the value
      */
@@ -80,7 +80,7 @@
     /**
      * Computes the log (base 2) of the specified long, rounding down. (E.g {@code log2(8) = 3},
      * {@code log2(21) = 4})
-     * 
+     *
      * @param val the value
      * @return the log base 2 of the value
      */
@@ -90,8 +90,100 @@
     }
 
     /**
+     * Narrow an integer value to a given bit width, and return the result as a signed long.
+     *
+     * @param value the value
+     * @param resultBits the result bit width
+     * @return {@code value} interpreted as {@code resultBits} bit number, encoded as signed long
+     */
+    public static long narrow(long value, int resultBits) {
+        long ret = value & mask(resultBits);
+        return signExtend(ret, resultBits);
+    }
+
+    /**
+     * Sign extend an integer.
+     *
+     * @param value the input value
+     * @param inputBits the bit width of the input value
+     * @return a signed long with the same value as the signed {@code inputBits}-bit number
+     *         {@code value}
+     */
+    public static long signExtend(long value, int inputBits) {
+        if (inputBits < 64) {
+            if ((value >>> (inputBits - 1) & 1) == 1) {
+                return value | (-1L << inputBits);
+            } else {
+                return value & ~(-1L << inputBits);
+            }
+        } else {
+            return value;
+        }
+    }
+
+    /**
+     * Zero extend an integer.
+     *
+     * @param value the input value
+     * @param inputBits the bit width of the input value
+     * @return an unsigned long with the same value as the unsigned {@code inputBits}-bit number
+     *         {@code value}
+     */
+    public static long zeroExtend(long value, int inputBits) {
+        if (inputBits < 64) {
+            return value & ~(-1L << inputBits);
+        } else {
+            return value;
+        }
+    }
+
+    /**
+     * Convert an integer to long.
+     *
+     * @param value the input value
+     * @param inputBits the bit width of the input value
+     * @param unsigned whether the values should be interpreted as signed or unsigned
+     * @return a long with the same value as the {@code inputBits}-bit number {@code value}
+     */
+    public static long convert(long value, int inputBits, boolean unsigned) {
+        if (unsigned) {
+            return zeroExtend(value, inputBits);
+        } else {
+            return signExtend(value, inputBits);
+        }
+    }
+
+    /**
+     * Get a bitmask with the low {@code bits} bit set and the high {@code 64 - bits} bit clear.
+     */
+    public static long mask(int bits) {
+        assert 0 <= bits && bits <= 64;
+        if (bits == 64) {
+            return 0xffffffffffffffffL;
+        } else {
+            return (1L << bits) - 1;
+        }
+    }
+
+    /**
+     * Get the minimum value representable in a {@code bits} bit signed integer.
+     */
+    public static long minValue(int bits) {
+        assert 0 < bits && bits <= 64;
+        return -1L << (bits - 1);
+    }
+
+    /**
+     * Get the maximum value representable in a {@code bits} bit signed integer.
+     */
+    public static long maxValue(int bits) {
+        assert 0 < bits && bits <= 64;
+        return mask(bits - 1);
+    }
+
+    /**
      * Formats the values in a frame as a tabulated string.
-     * 
+     *
      * @param frame
      * @return the values in {@code frame} as a tabulated string
      */
@@ -131,7 +223,7 @@
     /**
      * Formats a given table as a string. The value of each cell is produced by
      * {@link String#valueOf(Object)}.
-     * 
+     *
      * @param cells the cells of the table in row-major order
      * @param cols the number of columns per row
      * @param lpad the number of space padding inserted before each formatted cell value
@@ -179,7 +271,7 @@
 
     /**
      * Appends a formatted code position to a {@link StringBuilder}.
-     * 
+     *
      * @param sb the {@link StringBuilder} to append to
      * @param pos the code position to format and append to {@code sb}
      * @return the value of {@code sb}
@@ -195,7 +287,7 @@
 
     /**
      * Appends a formatted frame to a {@link StringBuilder}.
-     * 
+     *
      * @param sb the {@link StringBuilder} to append to
      * @param frame the frame to format and append to {@code sb}
      * @return the value of {@code sb}
@@ -293,7 +385,7 @@
 
     /**
      * Appends a formatted debug info to a {@link StringBuilder}.
-     * 
+     *
      * @param sb the {@link StringBuilder} to append to
      * @param info the debug info to format and append to {@code sb}
      * @return the value of {@code sb}
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java	Wed Sep 24 16:22:22 2014 -0700
@@ -255,6 +255,12 @@
      */
     public static Constant forIntegerKind(Kind kind, long i) {
         switch (kind) {
+            case Byte:
+                return new PrimitiveConstant(kind, (byte) i);
+            case Short:
+                return new PrimitiveConstant(kind, (short) i);
+            case Char:
+                return new PrimitiveConstant(kind, (char) i);
             case Int:
                 return new PrimitiveConstant(kind, (int) i);
             case Long:
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Wed Sep 24 16:22:22 2014 -0700
@@ -37,7 +37,6 @@
 import com.oracle.graal.asm.amd64.AMD64Assembler.ConditionFlag;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.compiler.common.calc.*;
-import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.StandardOp.JumpOp;
 import com.oracle.graal.lir.amd64.*;
@@ -49,6 +48,7 @@
 import com.oracle.graal.lir.amd64.AMD64Arithmetic.BinaryRegStackConst;
 import com.oracle.graal.lir.amd64.AMD64Arithmetic.DivRemOp;
 import com.oracle.graal.lir.amd64.AMD64Arithmetic.FPDivRemOp;
+import com.oracle.graal.lir.amd64.AMD64Arithmetic.MulHighOp;
 import com.oracle.graal.lir.amd64.AMD64Arithmetic.Unary1Op;
 import com.oracle.graal.lir.amd64.AMD64Arithmetic.Unary2MemoryOp;
 import com.oracle.graal.lir.amd64.AMD64Arithmetic.Unary2Op;
@@ -958,13 +958,13 @@
         } else if (fromBits > 32) {
             assert inputVal.getKind() == Kind.Long;
             Variable result = newVariable(LIRKind.derive(inputVal).changeType(Kind.Long));
-            long mask = IntegerStamp.defaultMask(fromBits);
+            long mask = CodeUtil.mask(fromBits);
             append(new BinaryRegConst(AMD64Arithmetic.LAND, result, asAllocatable(inputVal), Constant.forLong(mask)));
             return result;
         } else {
             assert inputVal.getKind().getStackKind() == Kind.Int;
             Variable result = newVariable(LIRKind.derive(inputVal).changeType(Kind.Int));
-            int mask = (int) IntegerStamp.defaultMask(fromBits);
+            int mask = (int) CodeUtil.mask(fromBits);
             append(new BinaryRegConst(AMD64Arithmetic.IAND, result, asAllocatable(inputVal), Constant.forInt(mask)));
             if (toBits > 32) {
                 Variable longResult = newVariable(LIRKind.derive(inputVal).changeType(Kind.Long));
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeLIRBuilder.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeLIRBuilder.java	Wed Sep 24 16:22:22 2014 -0700
@@ -275,15 +275,12 @@
 
     protected AMD64Arithmetic getOp(ValueNode operation, Access access) {
         Kind memoryKind = getMemoryKind(access);
-        if (operation.getNodeClass().is(IntegerAddNode.class)) {
+        if (operation.getNodeClass().is(AddNode.class)) {
             switch (memoryKind) {
                 case Int:
                     return IADD;
                 case Long:
                     return LADD;
-            }
-        } else if (operation.getNodeClass().is(FloatAddNode.class)) {
-            switch (memoryKind) {
                 case Float:
                     return FADD;
                 case Double:
@@ -310,29 +307,23 @@
                 case Long:
                     return LXOR;
             }
-        } else if (operation.getNodeClass().is(IntegerSubNode.class)) {
+        } else if (operation.getNodeClass().is(SubNode.class)) {
             switch (memoryKind) {
                 case Int:
                     return ISUB;
                 case Long:
                     return LSUB;
-            }
-        } else if (operation.getNodeClass().is(FloatSubNode.class)) {
-            switch (memoryKind) {
                 case Float:
                     return FSUB;
                 case Double:
                     return DSUB;
             }
-        } else if (operation.getNodeClass().is(IntegerMulNode.class)) {
+        } else if (operation.getNodeClass().is(MulNode.class)) {
             switch (memoryKind) {
                 case Int:
                     return IMUL;
                 case Long:
                     return LMUL;
-            }
-        } else if (operation.getNodeClass().is(FloatMulNode.class)) {
-            switch (memoryKind) {
                 case Float:
                     return FMUL;
                 case Double:
@@ -370,7 +361,7 @@
         return null;
     }
 
-    @MatchRule("(Or (LeftShift value (IntegerSub Constant=delta shiftAmount)) (UnsignedRightShift value shiftAmount))")
+    @MatchRule("(Or (LeftShift value (Sub Constant=delta shiftAmount)) (UnsignedRightShift value shiftAmount))")
     public ComplexMatchResult rotateRightVariable(ValueNode value, ConstantNode delta, ValueNode shiftAmount) {
         if (delta.asConstant().asLong() == 0 || delta.asConstant().asLong() == 32) {
             return builder -> getLIRGeneratorTool().emitRor(operand(value), operand(shiftAmount));
@@ -378,7 +369,7 @@
         return null;
     }
 
-    @MatchRule("(Or (LeftShift value shiftAmount) (UnsignedRightShift value (IntegerSub Constant=delta shiftAmount)))")
+    @MatchRule("(Or (LeftShift value shiftAmount) (UnsignedRightShift value (Sub Constant=delta shiftAmount)))")
     public ComplexMatchResult rotateLeftVariable(ValueNode value, ValueNode shiftAmount, ConstantNode delta) {
         if (delta.asConstant().asLong() == 0 || delta.asConstant().asLong() == 32) {
             return builder -> getLIRGeneratorTool().emitRol(operand(value), operand(shiftAmount));
@@ -386,21 +377,15 @@
         return null;
     }
 
-    @MatchRule("(IntegerAdd value Read=access)")
-    @MatchRule("(IntegerSub value Read=access)")
-    @MatchRule("(IntegerMul value Read=access)")
-    @MatchRule("(FloatAdd value Read=access)")
-    @MatchRule("(FloatSub value Read=access)")
-    @MatchRule("(FloatMul value Read=access)")
+    @MatchRule("(Add value Read=access)")
+    @MatchRule("(Sub value Read=access)")
+    @MatchRule("(Mul value Read=access)")
     @MatchRule("(Or value Read=access)")
     @MatchRule("(Xor value Read=access)")
     @MatchRule("(And value Read=access)")
-    @MatchRule("(IntegerAdd value FloatingRead=access)")
-    @MatchRule("(IntegerSub value FloatingRead=access)")
-    @MatchRule("(IntegerMul value FloatingRead=access)")
-    @MatchRule("(FloatAdd value FloatingRead=access)")
-    @MatchRule("(FloatSub value FloatingRead=access)")
-    @MatchRule("(FloatMul value FloatingRead=access)")
+    @MatchRule("(Add value FloatingRead=access)")
+    @MatchRule("(Sub value FloatingRead=access)")
+    @MatchRule("(Mul value FloatingRead=access)")
     @MatchRule("(Or value FloatingRead=access)")
     @MatchRule("(Xor value FloatingRead=access)")
     @MatchRule("(And value FloatingRead=access)")
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/ArithmeticOpTable.java	Wed Sep 24 16:22:22 2014 -0700
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.compiler.common.type;
+
+import com.oracle.graal.api.meta.*;
+
+/**
+ * Information about arithmetic operations.
+ */
+public final class ArithmeticOpTable {
+
+    protected UnaryOp neg;
+    protected BinaryOp add;
+    protected BinaryOp sub;
+
+    protected BinaryOp mul;
+    protected BinaryOp div;
+    protected BinaryOp rem;
+
+    protected UnaryOp not;
+    protected BinaryOp and;
+    protected BinaryOp or;
+    protected BinaryOp xor;
+
+    public static ArithmeticOpTable forStamp(Stamp s) {
+        return ((ArithmeticStamp) s).getOps();
+    }
+
+    /**
+     * Describes the unary negation operation.
+     */
+    public final UnaryOp getNeg() {
+        return neg;
+    }
+
+    /**
+     * Describes the addition operation.
+     */
+    public final BinaryOp getAdd() {
+        return add;
+    }
+
+    /**
+     * Describes the subtraction operation.
+     */
+    public final BinaryOp getSub() {
+        return sub;
+    }
+
+    /**
+     * Describes the multiplication operation.
+     */
+    public final BinaryOp getMul() {
+        return mul;
+    }
+
+    /**
+     * Describes the division operation.
+     */
+    public final BinaryOp getDiv() {
+        return div;
+    }
+
+    /**
+     * Describes the remainder operation.
+     */
+    public final BinaryOp getRem() {
+        return rem;
+    }
+
+    /**
+     * Describes the bitwise not operation.
+     */
+    public final UnaryOp getNot() {
+        return not;
+    }
+
+    /**
+     * Describes the bitwise and operation.
+     */
+    public final BinaryOp getAnd() {
+        return and;
+    }
+
+    /**
+     * Describes the bitwise or operation.
+     */
+    public final BinaryOp getOr() {
+        return or;
+    }
+
+    /**
+     * Describes the bitwise xor operation.
+     */
+    public final BinaryOp getXor() {
+        return xor;
+    }
+
+    /**
+     * Describes a unary arithmetic operation.
+     */
+    public abstract static class UnaryOp {
+
+        /**
+         * Apply the operation to a {@link Constant}.
+         */
+        public abstract Constant foldConstant(Constant value);
+
+        /**
+         * Apply the operation to a {@link Stamp}.
+         */
+        public abstract Stamp foldStamp(Stamp stamp);
+    }
+
+    /**
+     * Describes a binary arithmetic operation.
+     */
+    public abstract static class BinaryOp {
+
+        private final boolean associative;
+        private final boolean commutative;
+
+        protected BinaryOp(boolean associative, boolean commutative) {
+            this.associative = associative;
+            this.commutative = commutative;
+        }
+
+        /**
+         * Apply the operation to two {@linkplain Constant Constants}.
+         */
+        public abstract Constant foldConstant(Constant a, Constant b);
+
+        /**
+         * Apply the operation to two {@linkplain Stamp Stamps}.
+         */
+        public abstract Stamp foldStamp(Stamp a, Stamp b);
+
+        /**
+         * Checks whether this operation is associative. An operation is associative when
+         * {@code (a . b) . c == a . (b . c)} for all a, b, c. Note that you still have to be
+         * careful with inverses. For example the integer subtraction operation will report
+         * {@code true} here, since you can still reassociate as long as the correct negations are
+         * inserted.
+         */
+        public final boolean isAssociative() {
+            return associative;
+        }
+
+        /**
+         * Checks whether this operation is commutative. An operation is commutative when
+         * {@code a . b == b . a} for all a, b.
+         */
+        public final boolean isCommutative() {
+            return commutative;
+        }
+
+        /**
+         * Check whether a {@link Constant} is a neutral element for this operation. A neutral
+         * element is any element {@code n} where {@code a . n == a} for all a.
+         *
+         * @param n the {@link Constant} that should be tested
+         * @return true iff for all {@code a}: {@code a . n == a}
+         */
+        public boolean isNeutral(Constant n) {
+            return false;
+        }
+
+        /**
+         * Check whether this operation has a zero {@code z == a . a} for each a. Examples of
+         * operations having such an element are subtraction and exclusive-or. Note that this may be
+         * different from the numbers tested by {@link #isNeutral}.
+         *
+         * @param stamp a {@link Stamp}
+         * @return a unique {@code z} such that {@code z == a . a} for each {@code a} in
+         *         {@code stamp} if it exists, otherwise {@code null}
+         */
+        public Constant getZero(Stamp stamp) {
+            return null;
+        }
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/ArithmeticStamp.java	Wed Sep 24 16:22:22 2014 -0700
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.compiler.common.type;
+
+/**
+ * Type describing values that support arithmetic operations.
+ */
+public abstract class ArithmeticStamp extends Stamp {
+
+    private final ArithmeticOpTable ops;
+
+    protected ArithmeticStamp(ArithmeticOpTable ops) {
+        this.ops = ops;
+    }
+
+    public ArithmeticOpTable getOps() {
+        return ops;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ops.hashCode();
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!(obj instanceof ArithmeticStamp)) {
+            return false;
+        }
+        ArithmeticStamp other = (ArithmeticStamp) obj;
+        return this.ops == other.ops;
+    }
+}
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/FloatStamp.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/FloatStamp.java	Wed Sep 24 16:22:22 2014 -0700
@@ -27,6 +27,8 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.compiler.common.spi.*;
+import com.oracle.graal.compiler.common.type.ArithmeticOpTable.BinaryOp;
+import com.oracle.graal.compiler.common.type.ArithmeticOpTable.UnaryOp;
 
 public class FloatStamp extends PrimitiveStamp {
 
@@ -39,7 +41,7 @@
     }
 
     public FloatStamp(int bits, double lowerBound, double upperBound, boolean nonNaN) {
-        super(bits);
+        super(bits, OPS);
         this.lowerBound = lowerBound;
         this.upperBound = upperBound;
         this.nonNaN = nonNaN;
@@ -234,7 +236,7 @@
         if (nonNaN != other.nonNaN) {
             return false;
         }
-        return true;
+        return super.equals(other);
     }
 
     @Override
@@ -249,4 +251,189 @@
         }
         return null;
     }
+
+    private static final ArithmeticOpTable OPS = new ArithmeticOpTable();
+
+    static {
+        OPS.neg = new UnaryOp() {
+
+            @Override
+            public Constant foldConstant(Constant value) {
+                switch (value.getKind()) {
+                    case Float:
+                        return Constant.forFloat(-value.asFloat());
+                    case Double:
+                        return Constant.forDouble(-value.asDouble());
+                    default:
+                        throw GraalInternalError.shouldNotReachHere();
+                }
+            }
+
+            @Override
+            public Stamp foldStamp(Stamp s) {
+                FloatStamp stamp = (FloatStamp) s;
+                return new FloatStamp(stamp.getBits(), -stamp.upperBound(), -stamp.lowerBound(), stamp.isNonNaN());
+            }
+        };
+
+        OPS.add = new BinaryOp(false, true) {
+
+            @Override
+            public Constant foldConstant(Constant a, Constant b) {
+                assert a.getKind() == b.getKind();
+                switch (a.getKind()) {
+                    case Float:
+                        return Constant.forFloat(a.asFloat() + b.asFloat());
+                    case Double:
+                        return Constant.forDouble(a.asDouble() + b.asDouble());
+                    default:
+                        throw GraalInternalError.shouldNotReachHere();
+                }
+            }
+
+            @Override
+            public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
+                // TODO
+                return stamp1.unrestricted();
+            }
+
+            @Override
+            public boolean isNeutral(Constant n) {
+                switch (n.getKind()) {
+                    case Float:
+                        return Float.compare(n.asFloat(), -0.0f) == 0;
+                    case Double:
+                        return Double.compare(n.asDouble(), -0.0) == 0;
+                    default:
+                        throw GraalInternalError.shouldNotReachHere();
+                }
+            }
+        };
+
+        OPS.sub = new BinaryOp(false, false) {
+
+            @Override
+            public Constant foldConstant(Constant a, Constant b) {
+                assert a.getKind() == b.getKind();
+                switch (a.getKind()) {
+                    case Float:
+                        return Constant.forFloat(a.asFloat() - b.asFloat());
+                    case Double:
+                        return Constant.forDouble(a.asDouble() - b.asDouble());
+                    default:
+                        throw GraalInternalError.shouldNotReachHere();
+                }
+            }
+
+            @Override
+            public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
+                // TODO
+                return stamp1.unrestricted();
+            }
+
+            @Override
+            public boolean isNeutral(Constant n) {
+                switch (n.getKind()) {
+                    case Float:
+                        return Float.compare(n.asFloat(), 0.0f) == 0;
+                    case Double:
+                        return Double.compare(n.asDouble(), 0.0) == 0;
+                    default:
+                        throw GraalInternalError.shouldNotReachHere();
+                }
+            }
+        };
+
+        OPS.mul = new BinaryOp(false, true) {
+
+            @Override
+            public Constant foldConstant(Constant a, Constant b) {
+                assert a.getKind() == b.getKind();
+                switch (a.getKind()) {
+                    case Float:
+                        return Constant.forFloat(a.asFloat() * b.asFloat());
+                    case Double:
+                        return Constant.forDouble(a.asDouble() * b.asDouble());
+                    default:
+                        throw GraalInternalError.shouldNotReachHere();
+                }
+            }
+
+            @Override
+            public Stamp foldStamp(Stamp a, Stamp b) {
+                // TODO
+                return a.unrestricted();
+            }
+
+            @Override
+            public boolean isNeutral(Constant n) {
+                switch (n.getKind()) {
+                    case Float:
+                        return Float.compare(n.asFloat(), 1.0f) == 0;
+                    case Double:
+                        return Double.compare(n.asDouble(), 1.0) == 0;
+                    default:
+                        throw GraalInternalError.shouldNotReachHere();
+                }
+            }
+
+            // there is no multiplicative zero, since both 0.0 and -0.0 can flip sign
+        };
+
+        OPS.div = new BinaryOp(false, false) {
+
+            @Override
+            public Constant foldConstant(Constant a, Constant b) {
+                assert a.getKind() == b.getKind();
+                switch (a.getKind()) {
+                    case Float:
+                        return Constant.forFloat(a.asFloat() / b.asFloat());
+                    case Double:
+                        return Constant.forDouble(a.asDouble() / b.asDouble());
+                    default:
+                        throw GraalInternalError.shouldNotReachHere();
+                }
+            }
+
+            @Override
+            public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
+                // TODO
+                return stamp1.unrestricted();
+            }
+
+            @Override
+            public boolean isNeutral(Constant n) {
+                switch (n.getKind()) {
+                    case Float:
+                        return Float.compare(n.asFloat(), 1.0f) == 0;
+                    case Double:
+                        return Double.compare(n.asDouble(), 1.0) == 0;
+                    default:
+                        throw GraalInternalError.shouldNotReachHere();
+                }
+            }
+        };
+
+        OPS.rem = new BinaryOp(false, false) {
+
+            @Override
+            public Constant foldConstant(Constant a, Constant b) {
+                assert a.getKind() == b.getKind();
+                switch (a.getKind()) {
+                    case Float:
+                        return Constant.forFloat(a.asFloat() % b.asFloat());
+                    case Double:
+                        return Constant.forDouble(a.asDouble() % b.asDouble());
+                    default:
+                        throw GraalInternalError.shouldNotReachHere();
+                }
+            }
+
+            @Override
+            public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
+                // TODO
+                return stamp1.unrestricted();
+            }
+        };
+    }
 }
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IntegerStamp.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IntegerStamp.java	Wed Sep 24 16:22:22 2014 -0700
@@ -24,9 +24,12 @@
 
 import java.util.*;
 
+import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.compiler.common.spi.*;
+import com.oracle.graal.compiler.common.type.ArithmeticOpTable.BinaryOp;
+import com.oracle.graal.compiler.common.type.ArithmeticOpTable.UnaryOp;
 
 /**
  * Describes the possible values of a node that produces an int or long result.
@@ -42,25 +45,43 @@
     private final long upMask;
 
     public IntegerStamp(int bits, long lowerBound, long upperBound, long downMask, long upMask) {
-        super(bits);
+        super(bits, OPS);
         this.lowerBound = lowerBound;
         this.upperBound = upperBound;
         this.downMask = downMask;
         this.upMask = upMask;
-        assert lowerBound >= defaultMinValue(bits) : this;
-        assert upperBound <= defaultMaxValue(bits) : this;
-        assert (downMask & defaultMask(bits)) == downMask : this;
-        assert (upMask & defaultMask(bits)) == upMask : this;
+        assert lowerBound >= CodeUtil.minValue(bits) : this;
+        assert upperBound <= CodeUtil.maxValue(bits) : this;
+        assert (downMask & CodeUtil.mask(bits)) == downMask : this;
+        assert (upMask & CodeUtil.mask(bits)) == upMask : this;
+    }
+
+    public static IntegerStamp stampForMask(int bits, long downMask, long upMask) {
+        long lowerBound;
+        long upperBound;
+        if (((upMask >>> (bits - 1)) & 1) == 0) {
+            lowerBound = downMask;
+            upperBound = upMask;
+        } else if (((downMask >>> (bits - 1)) & 1) == 1) {
+            lowerBound = downMask;
+            upperBound = upMask;
+        } else {
+            lowerBound = downMask | (-1L << (bits - 1));
+            upperBound = CodeUtil.maxValue(bits) & upMask;
+        }
+        lowerBound = CodeUtil.convert(lowerBound, bits, false);
+        upperBound = CodeUtil.convert(upperBound, bits, false);
+        return new IntegerStamp(bits, lowerBound, upperBound, downMask, upMask);
     }
 
     @Override
-    public Stamp unrestricted() {
-        return new IntegerStamp(getBits(), defaultMinValue(getBits()), defaultMaxValue(getBits()), 0, defaultMask(getBits()));
+    public IntegerStamp unrestricted() {
+        return new IntegerStamp(getBits(), CodeUtil.minValue(getBits()), CodeUtil.maxValue(getBits()), 0, CodeUtil.mask(getBits()));
     }
 
     @Override
     public Stamp illegal() {
-        return new IntegerStamp(getBits(), defaultMaxValue(getBits()), defaultMinValue(getBits()), defaultMask(getBits()), 0);
+        return new IntegerStamp(getBits(), CodeUtil.maxValue(getBits()), CodeUtil.minValue(getBits()), CodeUtil.mask(getBits()), 0);
     }
 
     @Override
@@ -135,11 +156,11 @@
     }
 
     public boolean isUnrestricted() {
-        return lowerBound == defaultMinValue(getBits()) && upperBound == defaultMaxValue(getBits()) && downMask == 0 && upMask == defaultMask(getBits());
+        return lowerBound == CodeUtil.minValue(getBits()) && upperBound == CodeUtil.maxValue(getBits()) && downMask == 0 && upMask == CodeUtil.mask(getBits());
     }
 
     public boolean contains(long value) {
-        return value >= lowerBound && value <= upperBound && (value & downMask) == downMask && (value & upMask) == (value & defaultMask(getBits()));
+        return value >= lowerBound && value <= upperBound && (value & downMask) == downMask && (value & upMask) == (value & CodeUtil.mask(getBits()));
     }
 
     public boolean isPositive() {
@@ -173,14 +194,14 @@
         str.append(getBits());
         if (lowerBound == upperBound) {
             str.append(" [").append(lowerBound).append(']');
-        } else if (lowerBound != defaultMinValue(getBits()) || upperBound != defaultMaxValue(getBits())) {
+        } else if (lowerBound != CodeUtil.minValue(getBits()) || upperBound != CodeUtil.maxValue(getBits())) {
             str.append(" [").append(lowerBound).append(" - ").append(upperBound).append(']');
         }
         if (downMask != 0) {
             str.append(" \u21ca");
             new Formatter(str).format("%016x", downMask);
         }
-        if (upMask != defaultMask(getBits())) {
+        if (upMask != CodeUtil.mask(getBits())) {
             str.append(" \u21c8");
             new Formatter(str).format("%016x", upMask);
         }
@@ -265,24 +286,7 @@
         if (lowerBound != other.lowerBound || upperBound != other.upperBound || downMask != other.downMask || upMask != other.upMask) {
             return false;
         }
-        return true;
-    }
-
-    public static long defaultMask(int bits) {
-        assert 0 <= bits && bits <= 64;
-        if (bits == 64) {
-            return 0xffffffffffffffffL;
-        } else {
-            return (1L << bits) - 1;
-        }
-    }
-
-    public static long defaultMinValue(int bits) {
-        return -1L << (bits - 1);
-    }
-
-    public static long defaultMaxValue(int bits) {
-        return defaultMask(bits - 1);
+        return super.equals(other);
     }
 
     public static long upMaskFor(int bits, long lowerBound, long upperBound) {
@@ -290,7 +294,7 @@
         if (mask == 0) {
             return 0;
         } else {
-            return ((-1L) >>> Long.numberOfLeadingZeros(mask)) & defaultMask(bits);
+            return ((-1L) >>> Long.numberOfLeadingZeros(mask)) & CodeUtil.mask(bits);
         }
     }
 
@@ -323,4 +327,313 @@
         }
         return null;
     }
+
+    private static boolean addOverflowsPositively(long x, long y, int bits) {
+        long result = x + y;
+        if (bits == 64) {
+            return (~x & ~y & result) < 0;
+        } else {
+            return result > CodeUtil.maxValue(bits);
+        }
+    }
+
+    private static boolean addOverflowsNegatively(long x, long y, int bits) {
+        long result = x + y;
+        if (bits == 64) {
+            return (x & y & ~result) < 0;
+        } else {
+            return result < CodeUtil.minValue(bits);
+        }
+    }
+
+    private static long carryBits(long x, long y) {
+        return (x + y) ^ x ^ y;
+    }
+
+    public static final ArithmeticOpTable OPS = new ArithmeticOpTable();
+
+    static {
+        OPS.neg = new UnaryOp() {
+
+            @Override
+            public Constant foldConstant(Constant value) {
+                return Constant.forIntegerKind(value.getKind(), -value.asLong());
+            }
+
+            @Override
+            public Stamp foldStamp(Stamp s) {
+                IntegerStamp stamp = (IntegerStamp) s;
+                int bits = stamp.getBits();
+                if (stamp.lowerBound() != CodeUtil.minValue(bits)) {
+                    // TODO(ls) check if the mask calculation is correct...
+                    return StampFactory.forInteger(bits, -stamp.upperBound(), -stamp.lowerBound());
+                } else {
+                    return stamp.unrestricted();
+                }
+            }
+        };
+
+        OPS.add = new BinaryOp(true, true) {
+
+            @Override
+            public Constant foldConstant(Constant a, Constant b) {
+                assert a.getKind() == b.getKind();
+                return Constant.forIntegerKind(a.getKind(), a.asLong() + b.asLong());
+            }
+
+            @Override
+            public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
+                IntegerStamp a = (IntegerStamp) stamp1;
+                IntegerStamp b = (IntegerStamp) stamp2;
+
+                int bits = a.getBits();
+                assert bits == b.getBits();
+
+                if (a.isUnrestricted()) {
+                    return a;
+                } else if (b.isUnrestricted()) {
+                    return b;
+                }
+                long defaultMask = CodeUtil.mask(bits);
+                long variableBits = (a.downMask() ^ a.upMask()) | (b.downMask() ^ b.upMask());
+                long variableBitsWithCarry = variableBits | (carryBits(a.downMask(), b.downMask()) ^ carryBits(a.upMask(), b.upMask()));
+                long newDownMask = (a.downMask() + b.downMask()) & ~variableBitsWithCarry;
+                long newUpMask = (a.downMask() + b.downMask()) | variableBitsWithCarry;
+
+                newDownMask &= defaultMask;
+                newUpMask &= defaultMask;
+
+                long newLowerBound;
+                long newUpperBound;
+                boolean lowerOverflowsPositively = addOverflowsPositively(a.lowerBound(), b.lowerBound(), bits);
+                boolean upperOverflowsPositively = addOverflowsPositively(a.upperBound(), b.upperBound(), bits);
+                boolean lowerOverflowsNegatively = addOverflowsNegatively(a.lowerBound(), b.lowerBound(), bits);
+                boolean upperOverflowsNegatively = addOverflowsNegatively(a.upperBound(), b.upperBound(), bits);
+                if ((lowerOverflowsNegatively && !upperOverflowsNegatively) || (!lowerOverflowsPositively && upperOverflowsPositively)) {
+                    newLowerBound = CodeUtil.minValue(bits);
+                    newUpperBound = CodeUtil.maxValue(bits);
+                } else {
+                    newLowerBound = CodeUtil.signExtend((a.lowerBound() + b.lowerBound()) & defaultMask, bits);
+                    newUpperBound = CodeUtil.signExtend((a.upperBound() + b.upperBound()) & defaultMask, bits);
+                }
+                IntegerStamp limit = StampFactory.forInteger(bits, newLowerBound, newUpperBound);
+                newUpMask &= limit.upMask();
+                newUpperBound = CodeUtil.signExtend(newUpperBound & newUpMask, bits);
+                newDownMask |= limit.downMask();
+                newLowerBound |= newDownMask;
+                return new IntegerStamp(bits, newLowerBound, newUpperBound, newDownMask, newUpMask);
+            }
+
+            @Override
+            public boolean isNeutral(Constant n) {
+                return n.asLong() == 0;
+            }
+        };
+
+        OPS.sub = new BinaryOp(true, false) {
+
+            @Override
+            public Constant foldConstant(Constant a, Constant b) {
+                assert a.getKind() == b.getKind();
+                return Constant.forIntegerKind(a.getKind(), a.asLong() - b.asLong());
+            }
+
+            @Override
+            public Stamp foldStamp(Stamp a, Stamp b) {
+                return OPS.add.foldStamp(a, OPS.neg.foldStamp(b));
+            }
+
+            @Override
+            public boolean isNeutral(Constant n) {
+                return n.asLong() == 0;
+            }
+
+            @Override
+            public Constant getZero(Stamp s) {
+                IntegerStamp stamp = (IntegerStamp) s;
+                return Constant.forPrimitiveInt(stamp.getBits(), 0);
+            }
+        };
+
+        OPS.mul = new BinaryOp(true, true) {
+
+            @Override
+            public Constant foldConstant(Constant a, Constant b) {
+                assert a.getKind() == b.getKind();
+                return Constant.forIntegerKind(a.getKind(), a.asLong() * b.asLong());
+            }
+
+            @Override
+            public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
+                IntegerStamp a = (IntegerStamp) stamp1;
+                IntegerStamp b = (IntegerStamp) stamp2;
+                if (a.upMask() == 0) {
+                    return a;
+                } else if (b.upMask() == 0) {
+                    return b;
+                } else {
+                    // TODO
+                    return a.unrestricted();
+                }
+            }
+
+            @Override
+            public boolean isNeutral(Constant n) {
+                return n.asLong() == 1;
+            }
+        };
+
+        OPS.div = new BinaryOp(true, false) {
+
+            @Override
+            public Constant foldConstant(Constant a, Constant b) {
+                assert a.getKind() == b.getKind();
+                return Constant.forIntegerKind(a.getKind(), a.asLong() / b.asLong());
+            }
+
+            @Override
+            public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
+                IntegerStamp a = (IntegerStamp) stamp1;
+                IntegerStamp b = (IntegerStamp) stamp2;
+                assert a.getBits() == b.getBits();
+                if (b.isStrictlyPositive()) {
+                    long newLowerBound = a.lowerBound() / b.lowerBound();
+                    long newUpperBound = a.upperBound() / b.lowerBound();
+                    return StampFactory.forInteger(a.getBits(), newLowerBound, newUpperBound);
+                } else {
+                    return a.unrestricted();
+                }
+            }
+
+            @Override
+            public boolean isNeutral(Constant n) {
+                return n.asLong() == 1;
+            }
+        };
+
+        OPS.rem = new BinaryOp(false, false) {
+
+            @Override
+            public Constant foldConstant(Constant a, Constant b) {
+                assert a.getKind() == b.getKind();
+                return Constant.forIntegerKind(a.getKind(), a.asLong() % b.asLong());
+            }
+
+            @Override
+            public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
+                IntegerStamp a = (IntegerStamp) stamp1;
+                IntegerStamp b = (IntegerStamp) stamp2;
+                assert a.getBits() == b.getBits();
+                // zero is always possible
+                long newLowerBound = Math.min(a.lowerBound(), 0);
+                long newUpperBound = Math.max(a.upperBound(), 0);
+
+                long magnitude; // the maximum absolute value of the result, derived from b
+                if (b.lowerBound() == CodeUtil.minValue(b.getBits())) {
+                    // Math.abs(...) - 1 does not work in a case
+                    magnitude = CodeUtil.maxValue(b.getBits());
+                } else {
+                    magnitude = Math.max(Math.abs(b.lowerBound()), Math.abs(b.upperBound())) - 1;
+                }
+                newLowerBound = Math.max(newLowerBound, -magnitude);
+                newUpperBound = Math.min(newUpperBound, magnitude);
+
+                return StampFactory.forInteger(a.getBits(), newLowerBound, newUpperBound);
+            }
+        };
+
+        OPS.not = new UnaryOp() {
+
+            @Override
+            public Constant foldConstant(Constant value) {
+                return Constant.forIntegerKind(value.getKind(), ~value.asLong());
+            }
+
+            @Override
+            public Stamp foldStamp(Stamp stamp) {
+                IntegerStamp integerStamp = (IntegerStamp) stamp;
+                int bits = integerStamp.getBits();
+                long defaultMask = CodeUtil.mask(bits);
+                return new IntegerStamp(bits, ~integerStamp.upperBound(), ~integerStamp.lowerBound(), (~integerStamp.upMask()) & defaultMask, (~integerStamp.downMask()) & defaultMask);
+            }
+        };
+
+        OPS.and = new BinaryOp(true, true) {
+
+            @Override
+            public Constant foldConstant(Constant a, Constant b) {
+                assert a.getKind() == b.getKind();
+                return Constant.forIntegerKind(a.getKind(), a.asLong() & b.asLong());
+            }
+
+            @Override
+            public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
+                IntegerStamp a = (IntegerStamp) stamp1;
+                IntegerStamp b = (IntegerStamp) stamp2;
+                assert a.getBits() == b.getBits();
+                return stampForMask(a.getBits(), a.downMask() & b.downMask(), a.upMask() & b.upMask());
+            }
+
+            @Override
+            public boolean isNeutral(Constant n) {
+                int bits = n.getKind().getBitCount();
+                long mask = CodeUtil.mask(bits);
+                return (n.asLong() & mask) == mask;
+            }
+        };
+
+        OPS.or = new BinaryOp(true, true) {
+
+            @Override
+            public Constant foldConstant(Constant a, Constant b) {
+                assert a.getKind() == b.getKind();
+                return Constant.forIntegerKind(a.getKind(), a.asLong() | b.asLong());
+            }
+
+            @Override
+            public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
+                IntegerStamp a = (IntegerStamp) stamp1;
+                IntegerStamp b = (IntegerStamp) stamp2;
+                assert a.getBits() == b.getBits();
+                return stampForMask(a.getBits(), a.downMask() | b.downMask(), a.upMask() | b.upMask());
+            }
+
+            @Override
+            public boolean isNeutral(Constant n) {
+                return n.asLong() == 0;
+            }
+        };
+
+        OPS.xor = new BinaryOp(true, true) {
+
+            @Override
+            public Constant foldConstant(Constant a, Constant b) {
+                assert a.getKind() == b.getKind();
+                return Constant.forIntegerKind(a.getKind(), a.asLong() ^ b.asLong());
+            }
+
+            @Override
+            public Stamp foldStamp(Stamp stamp1, Stamp stamp2) {
+                IntegerStamp a = (IntegerStamp) stamp1;
+                IntegerStamp b = (IntegerStamp) stamp2;
+                assert a.getBits() == b.getBits();
+
+                long variableBits = (a.downMask() ^ a.upMask()) | (b.downMask() ^ b.upMask());
+                long newDownMask = (a.downMask() ^ b.downMask()) & ~variableBits;
+                long newUpMask = (a.downMask() ^ b.downMask()) | variableBits;
+                return stampForMask(a.getBits(), newDownMask, newUpMask);
+            }
+
+            @Override
+            public boolean isNeutral(Constant n) {
+                return n.asLong() == 0;
+            }
+
+            @Override
+            public Constant getZero(Stamp s) {
+                IntegerStamp stamp = (IntegerStamp) s;
+                return Constant.forPrimitiveInt(stamp.getBits(), 0);
+            }
+        };
+    }
 }
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/PrimitiveStamp.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/PrimitiveStamp.java	Wed Sep 24 16:22:22 2014 -0700
@@ -25,11 +25,12 @@
 /**
  * Type describing primitive values.
  */
-public abstract class PrimitiveStamp extends Stamp {
+public abstract class PrimitiveStamp extends ArithmeticStamp {
 
     private final int bits;
 
-    protected PrimitiveStamp(int bits) {
+    protected PrimitiveStamp(int bits, ArithmeticOpTable ops) {
+        super(ops);
         this.bits = bits;
     }
 
@@ -51,7 +52,7 @@
     @Override
     public int hashCode() {
         final int prime = 31;
-        int result = 1;
+        int result = super.hashCode();
         result = prime * result + bits;
         return result;
     }
@@ -61,10 +62,13 @@
         if (this == obj) {
             return true;
         }
-        if (obj instanceof PrimitiveStamp) {
-            PrimitiveStamp other = (PrimitiveStamp) obj;
-            return bits == other.bits;
+        if (!(obj instanceof PrimitiveStamp)) {
+            return false;
         }
-        return false;
+        PrimitiveStamp other = (PrimitiveStamp) obj;
+        if (bits != other.bits) {
+            return false;
+        }
+        return super.equals(obj);
     }
 }
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/Stamp.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/Stamp.java	Wed Sep 24 16:22:22 2014 -0700
@@ -115,4 +115,8 @@
     public Constant asConstant() {
         return null;
     }
+
+    public final Stamp asStamp() {
+        return this;
+    }
 }
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/StampFactory.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/StampFactory.java	Wed Sep 24 16:22:22 2014 -0700
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.compiler.common.type;
 
+import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.common.*;
 
@@ -45,9 +46,9 @@
         int bits = kind.getStackKind().getBitCount();
         long mask;
         if (kind.isUnsigned()) {
-            mask = IntegerStamp.defaultMask(kind.getBitCount());
+            mask = CodeUtil.mask(kind.getBitCount());
         } else {
-            mask = IntegerStamp.defaultMask(bits);
+            mask = CodeUtil.mask(bits);
         }
         setCache(kind, new IntegerStamp(bits, kind.getMinValue(), kind.getMaxValue(), 0, mask));
     }
@@ -128,11 +129,11 @@
     }
 
     public static IntegerStamp forInteger(int bits) {
-        return new IntegerStamp(bits, IntegerStamp.defaultMinValue(bits), IntegerStamp.defaultMaxValue(bits), 0, IntegerStamp.defaultMask(bits));
+        return new IntegerStamp(bits, CodeUtil.minValue(bits), CodeUtil.maxValue(bits), 0, CodeUtil.mask(bits));
     }
 
     public static IntegerStamp forInteger(int bits, long lowerBound, long upperBound) {
-        long defaultMask = IntegerStamp.defaultMask(bits);
+        long defaultMask = CodeUtil.mask(bits);
         if (lowerBound == upperBound) {
             return new IntegerStamp(bits, lowerBound, lowerBound, lowerBound & defaultMask, lowerBound & defaultMask);
         }
@@ -175,7 +176,7 @@
             case Short:
             case Int:
             case Long:
-                long mask = value.asLong() & IntegerStamp.defaultMask(kind.getBitCount());
+                long mask = value.asLong() & CodeUtil.mask(kind.getBitCount());
                 return forInteger(kind.getStackKind(), value.asLong(), value.asLong(), mask, mask);
             case Float:
                 return forFloat(kind, value.asFloat(), value.asFloat(), !Float.isNaN(value.asFloat()));
--- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java	Wed Sep 24 16:22:22 2014 -0700
@@ -33,7 +33,6 @@
 import com.oracle.graal.asm.*;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.compiler.common.calc.*;
-import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.StandardOp.JumpOp;
 import com.oracle.graal.lir.gen.*;
@@ -709,13 +708,13 @@
         } else if (fromBits > 32) {
             assert inputVal.getKind() == Kind.Long;
             Variable result = newVariable(LIRKind.derive(inputVal).changeType(Kind.Long));
-            long mask = IntegerStamp.defaultMask(fromBits);
+            long mask = CodeUtil.mask(fromBits);
             append(new Op2Stack(LAND, result, inputVal, Constant.forLong(mask)));
             return result;
         } else {
             assert inputVal.getKind() == Kind.Int;
             Variable result = newVariable(LIRKind.derive(inputVal).changeType(Kind.Int));
-            int mask = (int) IntegerStamp.defaultMask(fromBits);
+            int mask = (int) CodeUtil.mask(fromBits);
             append(new Op2Stack(IAND, result, inputVal, Constant.forInt(mask)));
             if (toBits > 32) {
                 Variable longResult = newVariable(LIRKind.derive(inputVal).changeType(Kind.Long));
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Wed Sep 24 16:22:22 2014 -0700
@@ -36,7 +36,6 @@
 import com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.compiler.common.calc.*;
-import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.gen.*;
 import com.oracle.graal.lir.sparc.*;
@@ -997,13 +996,13 @@
         } else if (fromBits > 32) {
             assert inputVal.getKind() == Kind.Long;
             Variable result = newVariable(LIRKind.derive(inputVal).changeType(Kind.Long));
-            long mask = IntegerStamp.defaultMask(fromBits);
+            long mask = CodeUtil.mask(fromBits);
             append(new BinaryRegConst(SPARCArithmetic.LAND, result, asAllocatable(inputVal), Constant.forLong(mask), null));
             return result;
         } else {
             assert inputVal.getKind() == Kind.Int || inputVal.getKind() == Kind.Short || inputVal.getKind() == Kind.Byte || inputVal.getKind() == Kind.Char : inputVal.getKind();
             Variable result = newVariable(LIRKind.derive(inputVal).changeType(Kind.Int));
-            long mask = IntegerStamp.defaultMask(fromBits);
+            long mask = CodeUtil.mask(fromBits);
             Constant constant = Constant.forInt((int) mask);
             if (fromBits == 32) {
                 append(new BinaryRegConst(IUSHR, result, inputVal, Constant.forInt(0)));
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Wed Sep 24 16:22:22 2014 -0700
@@ -54,7 +54,6 @@
 import com.oracle.graal.nodes.virtual.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.*;
-import com.oracle.graal.phases.common.inlining.*;
 import com.oracle.graal.phases.schedule.*;
 import com.oracle.graal.phases.tiers.*;
 import com.oracle.graal.phases.util.*;
@@ -125,7 +124,7 @@
 
     protected Suites createSuites() {
         Suites ret = backend.getSuites().createSuites();
-        ListIterator<BasePhase<? super HighTierContext>> iter = ret.getHighTier().findPhase(InliningPhase.class);
+        ListIterator<BasePhase<? super HighTierContext>> iter = ret.getHighTier().findPhase(CleanTypeProfileProxyPhase.class);
         PhaseSuite.findNextPhase(iter, CanonicalizerPhase.class);
         iter.add(new Phase("ComputeLoopFrequenciesPhase") {
 
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java	Wed Sep 24 16:22:22 2014 -0700
@@ -1916,6 +1916,7 @@
                 } catch (Throwable e) {
                     throw Debug.handle(e);
                 }
+                printLir("After spill move elimination", true);
 
                 try (Scope s1 = Debug.scope("AssignLocations")) {
                     assignLocations();
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java	Wed Sep 24 16:22:22 2014 -0700
@@ -56,10 +56,9 @@
  */
 @MatchableNode(nodeClass = ConstantNode.class, shareable = true)
 @MatchableNode(nodeClass = FloatConvertNode.class, inputs = {"value"})
-@MatchableNode(nodeClass = FloatSubNode.class, inputs = {"x", "y"})
 @MatchableNode(nodeClass = FloatingReadNode.class, inputs = {"object", "location"})
 @MatchableNode(nodeClass = IfNode.class, inputs = {"condition"})
-@MatchableNode(nodeClass = IntegerSubNode.class, inputs = {"x", "y"})
+@MatchableNode(nodeClass = SubNode.class, inputs = {"x", "y"})
 @MatchableNode(nodeClass = LeftShiftNode.class, inputs = {"x", "y"})
 @MatchableNode(nodeClass = NarrowNode.class, inputs = {"value"})
 @MatchableNode(nodeClass = ReadNode.class, inputs = {"object", "location"})
@@ -69,15 +68,13 @@
 @MatchableNode(nodeClass = WriteNode.class, inputs = {"object", "location", "value"})
 @MatchableNode(nodeClass = ZeroExtendNode.class, inputs = {"value"})
 @MatchableNode(nodeClass = AndNode.class, inputs = {"x", "y"}, commutative = true)
-@MatchableNode(nodeClass = FloatAddNode.class, inputs = {"x", "y"}, commutative = true)
 @MatchableNode(nodeClass = FloatEqualsNode.class, inputs = {"x", "y"}, commutative = true)
 @MatchableNode(nodeClass = FloatLessThanNode.class, inputs = {"x", "y"}, commutative = true)
-@MatchableNode(nodeClass = FloatMulNode.class, inputs = {"x", "y"}, commutative = true)
-@MatchableNode(nodeClass = IntegerAddNode.class, inputs = {"x", "y"}, commutative = true)
+@MatchableNode(nodeClass = AddNode.class, inputs = {"x", "y"}, commutative = true)
 @MatchableNode(nodeClass = IntegerBelowNode.class, inputs = {"x", "y"}, commutative = true)
 @MatchableNode(nodeClass = IntegerEqualsNode.class, inputs = {"x", "y"}, commutative = true)
 @MatchableNode(nodeClass = IntegerLessThanNode.class, inputs = {"x", "y"}, commutative = true)
-@MatchableNode(nodeClass = IntegerMulNode.class, inputs = {"x", "y"}, commutative = true)
+@MatchableNode(nodeClass = MulNode.class, inputs = {"x", "y"}, commutative = true)
 @MatchableNode(nodeClass = IntegerTestNode.class, inputs = {"x", "y"}, commutative = true)
 @MatchableNode(nodeClass = ObjectEqualsNode.class, inputs = {"x", "y"}, commutative = true)
 @MatchableNode(nodeClass = OrNode.class, inputs = {"x", "y"}, commutative = true)
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchableNode.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchableNode.java	Wed Sep 24 16:22:22 2014 -0700
@@ -55,7 +55,7 @@
     boolean commutative() default false;
 
     /**
-     * Can a node with multiple users be safely match by a rule.
+     * Can a node with multiple uses be safely matched by a rule.
      */
     boolean shareable() default false;
 }
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java	Wed Sep 24 16:22:22 2014 -0700
@@ -189,8 +189,6 @@
         return graph;
     }
 
-    private static final boolean USE_GENERATED_NODE_ITERATORS = Boolean.getBoolean("graal.useGeneratedNodeIterators");
-
     /**
      * Returns an {@link NodeClassIterable iterable} which can be used to traverse all non-null
      * input edges of this node.
@@ -198,12 +196,6 @@
      * @return an {@link NodeClassIterable iterable} for all non-null input edges.
      */
     public NodeClassIterable inputs() {
-        if (USE_GENERATED_NODES) {
-            if (!USE_GENERATED_NODE_ITERATORS) {
-                return new NodeRefIterable(this, true);
-            }
-            return inputsV2();
-        }
         return getNodeClass().getInputIterable(this);
     }
 
@@ -214,12 +206,6 @@
      * @return an {@link NodeClassIterable iterable} for all non-null successor edges.
      */
     public NodeClassIterable successors() {
-        if (USE_GENERATED_NODES) {
-            if (!USE_GENERATED_NODE_ITERATORS) {
-                return new NodeRefIterable(this, false);
-            }
-            return successorsV2();
-        }
         return getNodeClass().getSuccessorIterable(this);
     }
 
@@ -1007,174 +993,4 @@
             }
         }
     }
-
-    // NEW API IMPLEMENTED BY GENERATED METHODS - NOT YET USED
-
-    public NodeClassIterable inputsV2() {
-        return NodeClassIterable.Empty;
-    }
-
-    /**
-     * Determines if this node's inputs contain a given node.
-     *
-     * @param other
-     */
-    public boolean inputsContains(Node other) {
-        return false;
-    }
-
-    /**
-     * Determines if this node's successors contain a given node.
-     *
-     * @param other
-     */
-    public boolean successorsContains(Node other) {
-        return false;
-    }
-
-    public NodeClassIterable successorsV2() {
-        return NodeClassIterable.Empty;
-    }
-
-    public Collection<Position> getFirstLevelInputs() {
-        return Collections.emptyList();
-    }
-
-    public Collection<Position> getFirstLevelSuccessors() {
-        return Collections.emptyList();
-    }
-
-    /**
-     * Gets an input or successor of this node at a given position.
-     *
-     * @param pos
-     */
-    public Node getNodeAt(Position pos) {
-        throw new NoSuchElementException();
-    }
-
-    /**
-     * Gets the number of {@link Node} and {@link NodeList} fields in this node that are
-     * {@link Input}s or {@link OptionalInput}s.
-     *
-     * @return {@code L << 16 | N} where {@code N} is the number of {@link Node} fields and
-     *         {@code L} is the number of {@link NodeList} fields
-     */
-    public int getInputsCount() {
-        return 0;
-    }
-
-    /**
-     * Gets the number of {@link Node} and {@link NodeList} fields in this node that are
-     * {@link Successor}s.
-     *
-     * @return {@code L << 16 | N} where {@code N} is the number of {@link Node} fields and
-     *         {@code L} is the number of {@link NodeList} fields
-     */
-    public int getSuccessorsCount() {
-        return 0;
-    }
-
-    /**
-     * Gets an input of this node at a given index.
-     *
-     * @param index index of an input {@link Node} field. This value must be in the range of the
-     *            number of {@link Node} fields returned by {@link #getInputsCount()}.
-     */
-    public Node getInputNodeAt(int index) {
-        throw new NoSuchElementException();
-    }
-
-    /**
-     * Gets a successor of this node at a given index.
-     *
-     * @param index index of a successor {@link Node} field. This value must be in the range of the
-     *            number of {@link Node} fields returned by {@link #getSuccessorsCount()}.
-     */
-    public Node getSuccessorNodeAt(int index) {
-        throw new NoSuchElementException();
-    }
-
-    /**
-     * Gets an input list at a given index.
-     *
-     * @param index index of an input {@link NodeList} field. This value must be in the range of the
-     *            number of {@link NodeList} fields returned by {@link #getInputsCount()}.
-     */
-    public NodeList<? extends Node> getInputNodeListAt(int index) {
-        throw new NoSuchElementException();
-    }
-
-    /**
-     * Gets a successor list at a given index.
-     *
-     * @param index index of a successor {@link NodeList} field. This value must be in the range of
-     *            the number of {@link NodeList} fields returned by {@link #getSuccessorsCount()}.
-     */
-    public NodeList<? extends Node> getSuccessorNodeListAt(int index) {
-        throw new NoSuchElementException();
-    }
-
-    /**
-     * Gets an input or successor list at a given position.
-     *
-     * @param position
-     */
-    public NodeList<? extends Node> getNodeListAt(Position position) {
-        throw new NoSuchElementException();
-    }
-
-    /**
-     * Sets an input or successor list at a given position.
-     *
-     * @param position
-     * @param list
-     */
-    public void setNodeListAt(Position position, NodeList<? extends Node> list) {
-        throw new NoSuchElementException();
-    }
-
-    /**
-     * Updates an input or successor of this node at a given position. The existing, non-null input
-     * or successor at {@code position} is notified of the change via
-     * {@link #updateUsages(Node, Node)} or {@link #updatePredecessor(Node, Node)}.
-     *
-     * @param position
-     * @param value
-     */
-    public void updateNodeAt(Position position, Node value) {
-        throw new NoSuchElementException();
-    }
-
-    /**
-     * Sets an input or successor of this node at a given position without notifying the existing
-     * input or successor at {@code position} of the change.
-     *
-     * @param position
-     * @param value
-     */
-    public void initializeNodeAt(Position position, Node value) {
-        throw new NoSuchElementException();
-    }
-
-    /**
-     * @param pos
-     */
-    public InputType getInputTypeAt(Position pos) {
-        throw new NoSuchElementException();
-    }
-
-    /**
-     * @param pos
-     */
-    public String getNameOf(Position pos) {
-        throw new NoSuchElementException();
-    }
-
-    /**
-     * @param pos
-     */
-    public boolean isOptionalInputAt(Position pos) {
-        throw new NoSuchElementException();
-    }
 }
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeAllRefsIterator.java	Wed Sep 24 16:13:34 2014 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.graph;
-
-import com.oracle.graal.graph.Node.Input;
-
-/**
- * An iterator over the references to a given {@link Node}'s {@linkplain Input inputs}.
- *
- * An iterator of this type will return null values.
- */
-public final class NodeAllRefsIterator extends NodeRefIterator {
-
-    public NodeAllRefsIterator(Node node, int nodeFields, int nodeListFields, boolean isInputs) {
-        super(node, nodeFields, nodeListFields, isInputs);
-    }
-
-    @Override
-    protected void forward() {
-        assert needsForward;
-        needsForward = false;
-        if (index < nodeFields) {
-            index++;
-            if (index < nodeFields) {
-                nextElement = getNode(index);
-                return;
-            }
-        } else {
-            subIndex++;
-        }
-
-        while (index < allNodeRefFields) {
-            if (subIndex == 0) {
-                list = getNodeList(index - nodeFields);
-            }
-            if (subIndex < list.size()) {
-                nextElement = list.get(subIndex);
-                return;
-            }
-            subIndex = 0;
-            index++;
-        }
-    }
-}
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java	Wed Sep 24 16:22:22 2014 -0700
@@ -53,8 +53,6 @@
 
     // Timers for creation of a NodeClass instance
     private static final DebugTimer Init = Debug.timer("NodeClass.Init");
-    private static final DebugTimer Init_PositionFieldOrderLoad = Debug.timer("NodeClass.Init.PositionFieldOrderLoad");
-    private static final DebugTimer Init_PositionFieldOrderSort = Debug.timer("NodeClass.Init.PositionFieldOrderSort");
     private static final DebugTimer Init_FieldScanning = Debug.timer("NodeClass.Init.FieldScanning");
     private static final DebugTimer Init_Offsets = Debug.timer("NodeClass.Init.Offsets");
     private static final DebugTimer Init_Naming = Debug.timer("NodeClass.Init.Naming");
@@ -151,42 +149,10 @@
         this(clazz, new DefaultCalcOffset(), null, 0);
     }
 
-    /**
-     * Defines the order of fields in a node class accessed via {@link Position}s.
-     *
-     * This is required so that field positions are consistent in a configuration that mixes
-     * (runtime) field offsets with (annotation processing time) field iterators.
-     */
-    public interface PositionFieldOrder {
-        /**
-         * Gets a field ordering specified by an ordered field name list. The only guarantee
-         * provided by this method is that all {@link NodeList} fields are preceded by all non
-         * {@link NodeList} fields.
-         *
-         * @param input specified whether input or successor field order is being requested
-         */
-        String[] getOrderedFieldNames(boolean input);
-    }
-
-    private static long[] sortedOffsets(boolean input, PositionFieldOrder pfo, Map<Long, String> names, ArrayList<Long> list1, ArrayList<Long> list2) {
+    private static long[] sortedOffsets(ArrayList<Long> list1, ArrayList<Long> list2) {
         if (list1.isEmpty() && list2.isEmpty()) {
             return new long[0];
         }
-        if (pfo != null) {
-            try (TimerCloseable t = Init_PositionFieldOrderSort.start()) {
-
-                List<String> fields = Arrays.asList(pfo.getOrderedFieldNames(input));
-                long[] offsets = new long[fields.size()];
-                assert list1.size() + list2.size() == fields.size();
-                for (Map.Entry<Long, String> e : names.entrySet()) {
-                    int index = fields.indexOf(e.getValue());
-                    if (index != -1) {
-                        offsets[index] = e.getKey();
-                    }
-                }
-                return offsets;
-            }
-        }
         return sortedLongCopy(list1, list2);
     }
 
@@ -211,9 +177,7 @@
 
             isLeafNode = scanner.inputOffsets.isEmpty() && scanner.inputListOffsets.isEmpty() && scanner.successorOffsets.isEmpty() && scanner.successorListOffsets.isEmpty();
 
-            PositionFieldOrder pfo = lookupPositionFieldOrder(clazz);
-
-            inputOffsets = sortedOffsets(true, pfo, scanner.fieldNames, scanner.inputOffsets, scanner.inputListOffsets);
+            inputOffsets = sortedOffsets(scanner.inputOffsets, scanner.inputListOffsets);
 
             inputTypes = new InputType[inputOffsets.length];
             inputOptional = new boolean[inputOffsets.length];
@@ -223,7 +187,7 @@
                 inputOptional[i] = scanner.optionalInputs.contains(inputOffsets[i]);
             }
             directSuccessorCount = scanner.successorOffsets.size();
-            successorOffsets = sortedOffsets(false, pfo, scanner.fieldNames, scanner.successorOffsets, scanner.successorListOffsets);
+            successorOffsets = sortedOffsets(scanner.successorOffsets, scanner.successorListOffsets);
 
             dataOffsets = sortedLongCopy(scanner.dataOffsets);
             dataTypes = new Class[dataOffsets.length];
@@ -298,20 +262,6 @@
         nodeIterableCount = Debug.metric("NodeIterable_%s", shortName);
     }
 
-    private PositionFieldOrder lookupPositionFieldOrder(Class<?> clazz) throws GraalInternalError {
-        if (USE_GENERATED_NODES && !isAbstract(clazz.getModifiers()) && !isLeafNode) {
-            try (TimerCloseable t = Init_PositionFieldOrderLoad.start()) {
-                String name = clazz.getName().replace('$', '_') + "Gen$FieldOrder";
-                try {
-                    return (PositionFieldOrder) Class.forName(name, true, getClazz().getClassLoader()).newInstance();
-                } catch (Exception e) {
-                    throw new GraalInternalError("Could not find generated class " + name + " for " + getClazz());
-                }
-            }
-        }
-        return null;
-    }
-
     /**
      * Gets the {@linkplain GeneratedNode generated} node class (if any) described by the object.
      */
@@ -372,7 +322,7 @@
      *
      * <pre>
      *     if (node.getNodeClass().is(BeginNode.class)) { ... }
-     *
+     * 
      *     // Due to generated Node classes, the test below
      *     // is *not* the same as the test above:
      *     if (node.getClass() == BeginNode.class) { ... }
@@ -999,9 +949,6 @@
     }
 
     public Node get(Node node, Position pos) {
-        if (Node.USE_GENERATED_NODES) {
-            return node.getNodeAt(pos);
-        }
         long offset = pos.isInput() ? inputOffsets[pos.getIndex()] : successorOffsets[pos.getIndex()];
         if (pos.getSubIndex() == NOT_ITERABLE) {
             return getNode(node, offset);
@@ -1021,9 +968,6 @@
     }
 
     public NodeList<?> getNodeList(Node node, Position pos) {
-        if (Node.USE_GENERATED_NODES) {
-            return node.getNodeListAt(pos);
-        }
         long offset = pos.isInput() ? inputOffsets[pos.getIndex()] : successorOffsets[pos.getIndex()];
         assert pos.getSubIndex() == Node.NODE_LIST;
         return getNodeList(node, offset);
@@ -1183,11 +1127,6 @@
     }
 
     public void set(Node node, Position pos, Node x) {
-        if (Node.USE_GENERATED_NODES) {
-            node.updateNodeAt(pos, x);
-            return;
-        }
-
         long offset = pos.isInput() ? inputOffsets[pos.getIndex()] : successorOffsets[pos.getIndex()];
         if (pos.getSubIndex() == NOT_ITERABLE) {
             Node old = getNode(node, offset);
@@ -1212,10 +1151,6 @@
     }
 
     public void initializePosition(Node node, Position pos, Node x) {
-        if (Node.USE_GENERATED_NODES) {
-            node.initializeNodeAt(pos, x);
-            return;
-        }
         long offset = pos.isInput() ? inputOffsets[pos.getIndex()] : successorOffsets[pos.getIndex()];
         if (pos.getSubIndex() == NOT_ITERABLE) {
             assert x == null || fieldTypes.get((pos.isInput() ? inputOffsets : successorOffsets)[pos.getIndex()]).isAssignableFrom(x.getClass()) : this + ".set(node, pos, " + x + ")";
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClassIterable.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClassIterable.java	Wed Sep 24 16:22:22 2014 -0700
@@ -40,15 +40,4 @@
      * Returns an iterator that produces all values, including null values.
      */
     NodePosIterator withNullIterator();
-
-    NodeClassIterable Empty = new NodeClassIterable() {
-
-        public NodeRefIterator withNullIterator() {
-            return NodeRefIterator.Empty;
-        }
-
-        public NodeRefIterator iterator() {
-            return NodeRefIterator.Empty;
-        }
-    };
 }
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeRefIterable.java	Wed Sep 24 16:13:34 2014 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.graph;
-
-import static com.oracle.graal.graph.Graph.*;
-
-import com.oracle.graal.graph.Node.*;
-
-/**
- * An iterator over the references to a given {@link Node}'s {@linkplain Input inputs} or
- * {@linkplain Successor successors}.
- */
-public final class NodeRefIterable implements NodeClassIterable {
-
-    protected final Node node;
-
-    /**
-     * Specifies if {@link #iterator()} and {@link #withNullIterator()} iterate over
-     * {@linkplain Input inputs} or {@linkplain Successor successors}.
-     */
-    protected final boolean isInputs;
-
-    public NodeRefIterable(Node node, boolean isInputs) {
-        this.isInputs = isInputs;
-        this.node = node;
-    }
-
-    @Override
-    public NodePosIterator iterator() {
-        int count = isInputs ? node.getInputsCount() : node.getSuccessorsCount();
-        if (count == 0) {
-            return NodeRefIterator.Empty;
-        }
-        int nodeFields = count & 0xFFFF;
-        int nodeListFields = (count >> 16) & 0xFFFF;
-        if (MODIFICATION_COUNTS_ENABLED) {
-            return new NodeRefWithModCountIterator(node, nodeFields, nodeListFields, isInputs);
-        } else {
-            return new NodeRefIterator(node, nodeFields, nodeListFields, isInputs);
-        }
-    }
-
-    public NodePosIterator withNullIterator() {
-        int count = isInputs ? node.getInputsCount() : node.getSuccessorsCount();
-        if (count == 0) {
-            return NodeRefIterator.Empty;
-        }
-        int nodeFields = count & 0xFFFF;
-        int nodeListFields = (count >> 16) & 0xFFFF;
-        return new NodeAllRefsIterator(node, nodeFields, nodeListFields, isInputs);
-    }
-
-    @Override
-    public boolean contains(Node other) {
-        return isInputs ? node.inputsContains(other) : node.successorsContains(other);
-    }
-}
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeRefIterator.java	Wed Sep 24 16:13:34 2014 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,202 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.graph;
-
-import java.util.*;
-
-import com.oracle.graal.graph.Node.Input;
-import com.oracle.graal.graph.Node.Successor;
-
-/**
- * An iterator over the references to a {@link Node}'s {@linkplain Input inputs} and
- * {@linkplain Successor successors}.
- *
- * An iterator of this type will not return null values, unless the field values are modified
- * concurrently. Concurrent modifications are detected by an assertion on a best-effort basis.
- */
-public class NodeRefIterator implements NodePosIterator {
-
-    public static final NodeRefIterator Empty = new NodeRefIterator();
-
-    protected final Node node;
-
-    /**
-     * The total number of {@link Node} and {@link NodeList} fields.
-     */
-    protected final int allNodeRefFields;
-
-    /**
-     * The number of {@link Node} fields.
-     */
-    protected final int nodeFields;
-
-    /**
-     * Specifies if this iterator iterates over {@linkplain Input inputs} or {@linkplain Successor
-     * successors}.
-     */
-    protected final boolean isInputs;
-
-    /**
-     * Current field iteration index.
-     */
-    protected int index;
-
-    /**
-     * Current iteration index within a {@link NodeList} if {@link #index} denotes a
-     * {@link NodeList} field.
-     */
-    protected int subIndex;
-
-    protected Node nextElement;
-    protected boolean needsForward;
-    protected NodeList<? extends Node> list;
-
-    /**
-     * Creates an iterator over a node's references (i.e., {@linkplain Input inputs} or
-     * {@linkplain Successor successors}) to other nodes. The {@link Node} fields are iterated
-     * before the {@link NodeList} fields. All elements of these NodeLists will be visited by the
-     * iterator as well.
-     *
-     * @param nodeFields the number of {@link Node} fields in the class hierarchy of the node being
-     *            iterated
-     * @param nodeListFields the number of {@link NodeList} fields in the class hierarchy of the
-     *            node being iterated
-     */
-    protected NodeRefIterator(Node node, int nodeFields, int nodeListFields, boolean isInputs) {
-        this.node = node;
-        this.allNodeRefFields = nodeListFields + nodeFields;
-        this.nodeFields = nodeFields;
-        this.isInputs = isInputs;
-        this.needsForward = true;
-        index = -1;
-        subIndex = 0;
-    }
-
-    /**
-     * Constructor for {@link #Empty}.
-     */
-    private NodeRefIterator() {
-        this(null, 0, 0, false);
-        // This constructor must only be used to construct Empty
-        assert Empty == null;
-        // This must be set here to prevent multiple threads racing to
-        // call forward() which never needs to be done for Empty.
-        this.needsForward = false;
-        // Ensure hasNext() will always return false.
-        this.index = 0;
-    }
-
-    /**
-     * Gets the value of a {@link Node} field in the node.
-     *
-     * @param at the index of the Node field whose value is being requested. This is guaranteed to
-     *            be between 0 and the {@code nodeFields} value this iterator was constructed with
-     */
-    protected Node getNode(int at) {
-        return isInputs ? node.getInputNodeAt(at) : node.getSuccessorNodeAt(at);
-    }
-
-    /**
-     * Gets the value of a {@link NodeList} field in the node.
-     *
-     * @param at the index of the {@link NodeList} field whose value is being requested. This is
-     *            guaranteed to be between 0 and the {@code nodeListFields} value this iterator was
-     *            constructed with
-     */
-    protected NodeList<? extends Node> getNodeList(int at) {
-        return isInputs ? node.getInputNodeListAt(at) : node.getSuccessorNodeListAt(at);
-    }
-
-    protected void forward() {
-        needsForward = false;
-        if (index < nodeFields) {
-            index++;
-            while (index < nodeFields) {
-                nextElement = getNode(index);
-                if (nextElement != null) {
-                    return;
-                }
-                index++;
-            }
-        } else {
-            subIndex++;
-        }
-        while (index < allNodeRefFields) {
-            if (subIndex == 0) {
-                list = getNodeList(index - nodeFields);
-            }
-            assert list == getNodeList(index - nodeFields);
-            while (subIndex < list.size()) {
-                nextElement = list.get(subIndex);
-                if (nextElement != null) {
-                    return;
-                }
-                subIndex++;
-            }
-            subIndex = 0;
-            index++;
-        }
-        return;
-    }
-
-    private Node nextElement() {
-        if (needsForward) {
-            forward();
-        }
-        needsForward = true;
-        if (index < allNodeRefFields) {
-            return nextElement;
-        }
-        throw new NoSuchElementException();
-    }
-
-    @Override
-    public boolean hasNext() {
-        if (needsForward) {
-            forward();
-        }
-        return index < allNodeRefFields;
-    }
-
-    @Override
-    public Node next() {
-        return nextElement();
-    }
-
-    public Position nextPosition() {
-        if (needsForward) {
-            forward();
-        }
-        needsForward = true;
-        if (index < nodeFields) {
-            return new Position(isInputs, index, Node.NOT_ITERABLE);
-        } else {
-            return new Position(isInputs, index, subIndex);
-        }
-    }
-
-    @Override
-    public void remove() {
-        throw new UnsupportedOperationException();
-    }
-}
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeRefWithModCountIterator.java	Wed Sep 24 16:13:34 2014 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.graph;
-
-import static com.oracle.graal.graph.Graph.*;
-
-import com.oracle.graal.graph.Node.Input;
-
-/**
- * An iterator over the references to a given {@link Node}'s {@linkplain Input inputs}.
- *
- * An iterator of this type will not return null values, unless the field values are modified
- * concurrently. Concurrent modifications are detected by an assertion on a best-effort basis.
- */
-public final class NodeRefWithModCountIterator extends NodeRefIterator {
-
-    private final int modCount;
-
-    public NodeRefWithModCountIterator(Node node, int nodeFields, int nodeListFields, boolean isInputs) {
-        super(node, nodeFields, nodeListFields, isInputs);
-        assert MODIFICATION_COUNTS_ENABLED;
-        this.modCount = node.modCount();
-    }
-
-    @Override
-    public boolean hasNext() {
-        try {
-            return super.hasNext();
-        } finally {
-            assert modCount == node.modCount() : "must not be modified";
-        }
-    }
-
-    @Override
-    public Node next() {
-        try {
-            return super.next();
-        } finally {
-            assert modCount == node.modCount() : "must not be modified";
-        }
-    }
-
-    @Override
-    public Position nextPosition() {
-        try {
-            return super.nextPosition();
-        } finally {
-            assert modCount == node.modCount();
-        }
-    }
-}
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Position.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Position.java	Wed Sep 24 16:22:22 2014 -0700
@@ -56,47 +56,27 @@
     }
 
     public Node get(Node node) {
-        if (Node.USE_GENERATED_NODES) {
-            return node.getNodeAt(this);
-        }
         return node.getNodeClass().get(node, this);
     }
 
     public InputType getInputType(Node node) {
-        if (Node.USE_GENERATED_NODES) {
-            return node.getInputTypeAt(this);
-        }
         return node.getNodeClass().getInputType(this);
     }
 
     public String getInputName(Node node) {
-        if (Node.USE_GENERATED_NODES) {
-            return node.getNameOf(this);
-        }
         return node.getNodeClass().getName(this);
     }
 
     public boolean isInputOptional(Node node) {
-        if (Node.USE_GENERATED_NODES) {
-            return node.isOptionalInputAt(this);
-        }
         return node.getNodeClass().isInputOptional(this);
     }
 
     public void set(Node node, Node value) {
-        if (Node.USE_GENERATED_NODES) {
-            node.updateNodeAt(this, value);
-        } else {
-            node.getNodeClass().set(node, this, value);
-        }
+        node.getNodeClass().set(node, this, value);
     }
 
     public void initialize(Node node, Node value) {
-        if (Node.USE_GENERATED_NODES) {
-            node.initializeNodeAt(this, value);
-        } else {
-            node.getNodeClass().initializePosition(node, this, value);
-        }
+        node.getNodeClass().initializePosition(node, this, value);
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java	Wed Sep 24 16:22:22 2014 -0700
@@ -265,21 +265,15 @@
         return null;
     }
 
-    @MatchRule("(IntegerAdd value (Read=access (Compression=compress object) ConstantLocation=location))")
-    @MatchRule("(IntegerSub value (Read=access (Compression=compress object) ConstantLocation=location))")
-    @MatchRule("(IntegerMul value (Read=access (Compression=compress object) ConstantLocation=location))")
-    @MatchRule("(FloatAdd value (Read=access (Compression=compress object) ConstantLocation=location))")
-    @MatchRule("(FloatSub value (Read=access (Compression=compress object) ConstantLocation=location))")
-    @MatchRule("(FloatMul value (Read=access (Compression=compress object) ConstantLocation=location))")
+    @MatchRule("(Add value (Read=access (Compression=compress object) ConstantLocation=location))")
+    @MatchRule("(Sub value (Read=access (Compression=compress object) ConstantLocation=location))")
+    @MatchRule("(Mul value (Read=access (Compression=compress object) ConstantLocation=location))")
     @MatchRule("(Or value (Read=access (Compression=compress object) ConstantLocation=location))")
     @MatchRule("(Xor value (Read=access (Compression=compress object) ConstantLocation=location))")
     @MatchRule("(And value (Read=access (Compression=compress object) ConstantLocation=location))")
-    @MatchRule("(IntegerAdd value (FloatingRead=access (Compression=compress object) ConstantLocation=location))")
-    @MatchRule("(IntegerSub value (FloatingRead=access (Compression=compress object) ConstantLocation=location))")
-    @MatchRule("(IntegerMul value (FloatingRead=access (Compression=compress object) ConstantLocation=location))")
-    @MatchRule("(FloatAdd value (FloatingRead=access (Compression=compress object) ConstantLocation=location))")
-    @MatchRule("(FloatSub value (FloatingRead=access (Compression=compress object) ConstantLocation=location))")
-    @MatchRule("(FloatMul value (FloatingRead=access (Compression=compress object) ConstantLocation=location))")
+    @MatchRule("(Add value (FloatingRead=access (Compression=compress object) ConstantLocation=location))")
+    @MatchRule("(Sub value (FloatingRead=access (Compression=compress object) ConstantLocation=location))")
+    @MatchRule("(Mul value (FloatingRead=access (Compression=compress object) ConstantLocation=location))")
     @MatchRule("(Or value (FloatingRead=access (Compression=compress object) ConstantLocation=location))")
     @MatchRule("(Xor value (FloatingRead=access (Compression=compress object) ConstantLocation=location))")
     @MatchRule("(And value (FloatingRead=access (Compression=compress object) ConstantLocation=location))")
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/BenchmarkCounters.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/BenchmarkCounters.java	Wed Sep 24 16:22:22 2014 -0700
@@ -387,7 +387,7 @@
         ReadNode readArray = graph.add(ReadNode.create(thread, arrayLocation, StampFactory.forKind(wordKind), BarrierType.NONE));
         ConstantLocationNode location = ConstantLocationNode.create(LocationIdentity.ANY_LOCATION, Kind.Long, Unsafe.ARRAY_LONG_INDEX_SCALE * index, graph);
         ReadNode read = graph.add(ReadNode.create(readArray, location, StampFactory.forKind(Kind.Long), BarrierType.NONE));
-        IntegerAddNode add = graph.unique(IntegerAddNode.create(read, counter.getIncrement()));
+        AddNode add = graph.unique(AddNode.create(read, counter.getIncrement()));
         WriteNode write = graph.add(WriteNode.create(readArray, add, location, BarrierType.NONE));
 
         graph.addBeforeFixed(counter, thread);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java	Wed Sep 24 16:22:22 2014 -0700
@@ -166,7 +166,7 @@
         } else if (n instanceof IntegerDivNode || n instanceof IntegerRemNode || n instanceof UnsignedDivNode || n instanceof UnsignedRemNode) {
             // Nothing to do for division nodes. The HotSpot signal handler catches divisions by
             // zero and the MIN_VALUE / -1 cases.
-        } else if (n instanceof AbstractDeoptimizeNode || n instanceof UnwindNode || n instanceof FloatRemNode) {
+        } else if (n instanceof AbstractDeoptimizeNode || n instanceof UnwindNode || n instanceof RemNode) {
             /* No lowering, we generate LIR directly for these nodes. */
         } else {
             super.lower(n, tool);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java	Wed Sep 24 16:22:22 2014 -0700
@@ -114,7 +114,7 @@
         }
     }
 
-    private static void emitPrefetchAllocate(Word address, boolean isArray) {
+    public static void emitPrefetchAllocate(Word address, boolean isArray) {
         if (config().allocatePrefetchStyle > 0) {
             // Insert a prefetch for each allocation only on the fast-path
             // Generate several prefetch instructions.
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Wed Sep 24 16:22:22 2014 -0700
@@ -472,42 +472,42 @@
 
             @Override
             protected ValueNode genIntegerAdd(Kind kind, ValueNode x, ValueNode y) {
-                return IntegerAddNode.create(x, y);
+                return AddNode.create(x, y);
             }
 
             @Override
             protected ValueNode genIntegerSub(Kind kind, ValueNode x, ValueNode y) {
-                return IntegerSubNode.create(x, y);
+                return SubNode.create(x, y);
             }
 
             @Override
             protected ValueNode genIntegerMul(Kind kind, ValueNode x, ValueNode y) {
-                return IntegerMulNode.create(x, y);
+                return MulNode.create(x, y);
             }
 
             @Override
             protected ValueNode genFloatAdd(Kind kind, ValueNode x, ValueNode y, boolean isStrictFP) {
-                return FloatAddNode.create(x, y, isStrictFP);
+                return AddNode.create(x, y);
             }
 
             @Override
             protected ValueNode genFloatSub(Kind kind, ValueNode x, ValueNode y, boolean isStrictFP) {
-                return FloatSubNode.create(x, y, isStrictFP);
+                return SubNode.create(x, y);
             }
 
             @Override
             protected ValueNode genFloatMul(Kind kind, ValueNode x, ValueNode y, boolean isStrictFP) {
-                return FloatMulNode.create(x, y, isStrictFP);
+                return MulNode.create(x, y);
             }
 
             @Override
             protected ValueNode genFloatDiv(Kind kind, ValueNode x, ValueNode y, boolean isStrictFP) {
-                return FloatDivNode.create(x, y, isStrictFP);
+                return DivNode.create(x, y);
             }
 
             @Override
             protected ValueNode genFloatRem(Kind kind, ValueNode x, ValueNode y, boolean isStrictFP) {
-                return FloatRemNode.create(x, y, isStrictFP);
+                return RemNode.create(x, y);
             }
 
             @Override
--- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/bytecode/BC_dsub2.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/bytecode/BC_dsub2.java	Wed Sep 24 16:22:22 2014 -0700
@@ -39,4 +39,17 @@
         runTest("test", 0.0d);
     }
 
+    public static double test2(double a) {
+        return a - a;
+    }
+
+    @Test
+    public void run1() {
+        runTest("test2", 17.3);
+    }
+
+    @Test
+    public void run2() {
+        runTest("test2", Double.NaN);
+    }
 }
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/BasicInductionVariable.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/BasicInductionVariable.java	Wed Sep 24 16:22:22 2014 -0700
@@ -32,9 +32,9 @@
     private ValuePhiNode phi;
     private ValueNode init;
     private ValueNode rawStride;
-    private IntegerArithmeticNode op;
+    private BinaryArithmeticNode op;
 
-    public BasicInductionVariable(LoopEx loop, ValuePhiNode phi, ValueNode init, ValueNode rawStride, IntegerArithmeticNode op) {
+    public BasicInductionVariable(LoopEx loop, ValuePhiNode phi, ValueNode init, ValueNode rawStride, BinaryArithmeticNode op) {
         super(loop);
         this.phi = phi;
         this.init = init;
@@ -59,10 +59,10 @@
                 dir = Direction.Down;
             }
             if (dir != null) {
-                if (op instanceof IntegerAddNode) {
+                if (op instanceof AddNode) {
                     return dir;
                 } else {
-                    assert op instanceof IntegerSubNode;
+                    assert op instanceof SubNode;
                     return dir.opposite();
                 }
             }
@@ -82,10 +82,10 @@
 
     @Override
     public ValueNode strideNode() {
-        if (op instanceof IntegerAddNode) {
+        if (op instanceof AddNode) {
             return rawStride;
         }
-        if (op instanceof IntegerSubNode) {
+        if (op instanceof SubNode) {
             return graph().unique(NegateNode.create(rawStride));
         }
         throw GraalInternalError.shouldNotReachHere();
@@ -108,10 +108,10 @@
 
     @Override
     public long constantStride() {
-        if (op instanceof IntegerAddNode) {
+        if (op instanceof AddNode) {
             return rawStride.asConstant().asLong();
         }
-        if (op instanceof IntegerSubNode) {
+        if (op instanceof SubNode) {
             return -rawStride.asConstant().asLong();
         }
         throw GraalInternalError.shouldNotReachHere();
@@ -131,7 +131,7 @@
         if (!maxTripCount.stamp().isCompatible(stamp)) {
             maxTripCount = IntegerConvertNode.convert(maxTripCount, stamp, graph());
         }
-        return IntegerArithmeticNode.add(graph, IntegerArithmeticNode.mul(graph, stride, IntegerArithmeticNode.sub(graph, maxTripCount, ConstantNode.forIntegerStamp(stamp, 1, graph))), initNode);
+        return BinaryArithmeticNode.add(graph, BinaryArithmeticNode.mul(graph, stride, BinaryArithmeticNode.sub(graph, maxTripCount, ConstantNode.forIntegerStamp(stamp, 1, graph))), initNode);
     }
 
     @Override
@@ -141,7 +141,7 @@
         if (!maxTripCount.stamp().isCompatible(stamp)) {
             maxTripCount = IntegerConvertNode.convert(maxTripCount, stamp, graph());
         }
-        return IntegerArithmeticNode.add(graph(), IntegerArithmeticNode.mul(graph(), strideNode(), maxTripCount), initNode());
+        return BinaryArithmeticNode.add(graph(), BinaryArithmeticNode.mul(graph(), strideNode(), maxTripCount), initNode());
     }
 
     @Override
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/CountedLoopInfo.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/CountedLoopInfo.java	Wed Sep 24 16:22:22 2014 -0700
@@ -22,8 +22,9 @@
  */
 package com.oracle.graal.loop;
 
-import static com.oracle.graal.nodes.calc.IntegerArithmeticNode.*;
+import static com.oracle.graal.nodes.calc.BinaryArithmeticNode.*;
 
+import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.loop.InductionVariable.Direction;
@@ -54,12 +55,12 @@
     public ValueNode maxTripCountNode(boolean assumePositive) {
         StructuredGraph graph = iv.valueNode().graph();
         Stamp stamp = iv.valueNode().stamp();
-        IntegerArithmeticNode range = IntegerArithmeticNode.sub(graph, end, iv.initNode());
+        BinaryArithmeticNode range = BinaryArithmeticNode.sub(graph, end, iv.initNode());
         if (oneOff) {
             if (iv.direction() == Direction.Up) {
-                range = IntegerArithmeticNode.add(graph, range, ConstantNode.forIntegerStamp(stamp, 1, graph));
+                range = BinaryArithmeticNode.add(graph, range, ConstantNode.forIntegerStamp(stamp, 1, graph));
             } else {
-                range = IntegerArithmeticNode.sub(graph, range, ConstantNode.forIntegerStamp(stamp, 1, graph));
+                range = BinaryArithmeticNode.sub(graph, range, ConstantNode.forIntegerStamp(stamp, 1, graph));
             }
         }
         IntegerDivNode div = graph.add(IntegerDivNode.create(range, iv.strideNode()));
@@ -143,14 +144,14 @@
         CompareNode cond; // we use a negated guard with a < condition to achieve a >=
         ConstantNode one = ConstantNode.forIntegerStamp(stamp, 1, graph);
         if (iv.direction() == Direction.Up) {
-            IntegerArithmeticNode v1 = sub(graph, ConstantNode.forIntegerStamp(stamp, IntegerStamp.defaultMaxValue(stamp.getBits()), graph), sub(graph, iv.strideNode(), one));
+            BinaryArithmeticNode v1 = sub(graph, ConstantNode.forIntegerStamp(stamp, CodeUtil.maxValue(stamp.getBits()), graph), sub(graph, iv.strideNode(), one));
             if (oneOff) {
                 v1 = sub(graph, v1, one);
             }
             cond = graph.unique(IntegerLessThanNode.create(v1, end));
         } else {
             assert iv.direction() == Direction.Down;
-            IntegerArithmeticNode v1 = add(graph, ConstantNode.forIntegerStamp(stamp, IntegerStamp.defaultMinValue(stamp.getBits()), graph), sub(graph, one, iv.strideNode()));
+            BinaryArithmeticNode v1 = add(graph, ConstantNode.forIntegerStamp(stamp, CodeUtil.minValue(stamp.getBits()), graph), sub(graph, one, iv.strideNode()));
             if (oneOff) {
                 v1 = add(graph, v1, one);
             }
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/DerivedOffsetInductionVariable.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/DerivedOffsetInductionVariable.java	Wed Sep 24 16:22:22 2014 -0700
@@ -31,9 +31,9 @@
 
     private InductionVariable base;
     private ValueNode offset;
-    private IntegerArithmeticNode value;
+    private BinaryArithmeticNode value;
 
-    public DerivedOffsetInductionVariable(LoopEx loop, InductionVariable base, ValueNode offset, IntegerArithmeticNode value) {
+    public DerivedOffsetInductionVariable(LoopEx loop, InductionVariable base, ValueNode offset, BinaryArithmeticNode value) {
         super(loop);
         this.base = base;
         this.offset = offset;
@@ -72,7 +72,7 @@
 
     @Override
     public long constantStride() {
-        if (value instanceof IntegerSubNode && base.valueNode() == value.getY()) {
+        if (value instanceof SubNode && base.valueNode() == value.getY()) {
             return -base.constantStride();
         }
         return base.constantStride();
@@ -85,7 +85,7 @@
 
     @Override
     public ValueNode strideNode() {
-        if (value instanceof IntegerSubNode && base.valueNode() == value.getY()) {
+        if (value instanceof SubNode && base.valueNode() == value.getY()) {
             return graph().unique(NegateNode.create(base.strideNode()));
         }
         return base.strideNode();
@@ -112,10 +112,10 @@
     }
 
     private long op(long b, long o) {
-        if (value instanceof IntegerAddNode) {
+        if (value instanceof AddNode) {
             return b + o;
         }
-        if (value instanceof IntegerSubNode) {
+        if (value instanceof SubNode) {
             if (base.valueNode() == value.getX()) {
                 return b - o;
             } else {
@@ -127,15 +127,15 @@
     }
 
     private ValueNode op(ValueNode b, ValueNode o) {
-        if (value instanceof IntegerAddNode) {
-            return IntegerArithmeticNode.add(graph(), b, o);
+        if (value instanceof AddNode) {
+            return BinaryArithmeticNode.add(graph(), b, o);
         }
-        if (value instanceof IntegerSubNode) {
+        if (value instanceof SubNode) {
             if (base.valueNode() == value.getX()) {
-                return IntegerArithmeticNode.sub(graph(), b, o);
+                return BinaryArithmeticNode.sub(graph(), b, o);
             } else {
                 assert base.valueNode() == value.getY();
-                return IntegerArithmeticNode.sub(graph(), o, b);
+                return BinaryArithmeticNode.sub(graph(), o, b);
             }
         }
         throw GraalInternalError.shouldNotReachHere();
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/DerivedScaledInductionVariable.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/DerivedScaledInductionVariable.java	Wed Sep 24 16:22:22 2014 -0700
@@ -73,12 +73,12 @@
 
     @Override
     public ValueNode initNode() {
-        return IntegerArithmeticNode.mul(graph(), base.initNode(), scale);
+        return BinaryArithmeticNode.mul(graph(), base.initNode(), scale);
     }
 
     @Override
     public ValueNode strideNode() {
-        return IntegerArithmeticNode.mul(graph(), base.strideNode(), scale);
+        return BinaryArithmeticNode.mul(graph(), base.strideNode(), scale);
     }
 
     @Override
@@ -103,12 +103,12 @@
 
     @Override
     public ValueNode extremumNode(boolean assumePositiveTripCount, Stamp stamp) {
-        return IntegerArithmeticNode.mul(graph(), base.extremumNode(assumePositiveTripCount, stamp), IntegerConvertNode.convert(scale, stamp, graph()));
+        return BinaryArithmeticNode.mul(graph(), base.extremumNode(assumePositiveTripCount, stamp), IntegerConvertNode.convert(scale, stamp, graph()));
     }
 
     @Override
     public ValueNode exitValueNode() {
-        return IntegerArithmeticNode.mul(graph(), base.exitValueNode(), scale);
+        return BinaryArithmeticNode.mul(graph(), base.exitValueNode(), scale);
     }
 
     @Override
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/InductionVariables.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/InductionVariables.java	Wed Sep 24 16:22:22 2014 -0700
@@ -26,6 +26,7 @@
 
 import java.util.*;
 
+import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
@@ -56,7 +57,7 @@
             }
             ValueNode stride = addSub(backValue, phi);
             if (stride != null) {
-                BasicInductionVariable biv = new BasicInductionVariable(loop, (ValuePhiNode) phi, phi.valueAt(forwardEnd), stride, (IntegerArithmeticNode) backValue);
+                BasicInductionVariable biv = new BasicInductionVariable(loop, (ValuePhiNode) phi, phi.valueAt(forwardEnd), stride, (BinaryArithmeticNode) backValue);
                 ivs.put(phi, biv);
                 bivs.add(biv);
             }
@@ -77,7 +78,7 @@
                 ValueNode offset = addSub(op, baseIvNode);
                 ValueNode scale;
                 if (offset != null) {
-                    iv = new DerivedOffsetInductionVariable(loop, baseIv, offset, (IntegerArithmeticNode) op);
+                    iv = new DerivedOffsetInductionVariable(loop, baseIv, offset, (BinaryArithmeticNode) op);
                 } else if (op instanceof NegateNode) {
                     iv = new DerivedScaledInductionVariable(loop, baseIv, (NegateNode) op);
                 } else if ((scale = mul(op, baseIvNode)) != null) {
@@ -93,8 +94,8 @@
     }
 
     private ValueNode addSub(ValueNode op, ValueNode base) {
-        if (op instanceof IntegerAddNode || op instanceof IntegerSubNode) {
-            IntegerArithmeticNode aritOp = (IntegerArithmeticNode) op;
+        if (op.stamp() instanceof IntegerStamp && (op instanceof AddNode || op instanceof SubNode)) {
+            BinaryArithmeticNode aritOp = (BinaryArithmeticNode) op;
             if (aritOp.getX() == base && loop.isOutsideLoop(aritOp.getY())) {
                 return aritOp.getY();
             } else if (aritOp.getY() == base && loop.isOutsideLoop(aritOp.getX())) {
@@ -105,8 +106,8 @@
     }
 
     private ValueNode mul(ValueNode op, ValueNode base) {
-        if (op instanceof IntegerMulNode) {
-            IntegerMulNode mul = (IntegerMulNode) op;
+        if (op instanceof MulNode) {
+            MulNode mul = (MulNode) op;
             if (mul.getX() == base && loop.isOutsideLoop(mul.getY())) {
                 return mul.getY();
             } else if (mul.getY() == base && loop.isOutsideLoop(mul.getX())) {
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopEx.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopEx.java	Wed Sep 24 16:22:22 2014 -0700
@@ -137,11 +137,11 @@
     public void reassociateInvariants() {
         InvariantPredicate invariant = new InvariantPredicate();
         StructuredGraph graph = loopBegin().graph();
-        for (BinaryNode binary : whole().nodes().filter(BinaryNode.class)) {
-            if (!BinaryNode.canTryReassociate(binary)) {
+        for (BinaryArithmeticNode binary : whole().nodes().filter(BinaryArithmeticNode.class)) {
+            if (!binary.getOp().isAssociative()) {
                 continue;
             }
-            BinaryNode result = BinaryNode.reassociate(binary, invariant, binary.getX(), binary.getY());
+            BinaryArithmeticNode result = BinaryArithmeticNode.reassociate(binary, invariant, binary.getX(), binary.getY());
             if (result != binary) {
                 if (Debug.isLogEnabled()) {
                     Debug.log("%s : Reassociated %s into %s", graph.method().format("%H::%n"), binary, result);
--- a/graal/com.oracle.graal.nodeinfo.processor/src/com/oracle/graal/nodeinfo/processor/GraphNodeGenerator.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.nodeinfo.processor/src/com/oracle/graal/nodeinfo/processor/GraphNodeGenerator.java	Wed Sep 24 16:22:22 2014 -0700
@@ -22,7 +22,6 @@
  */
 package com.oracle.graal.nodeinfo.processor;
 
-import static com.oracle.graal.nodeinfo.processor.GraphNodeGenerator.NodeRefsType.*;
 import static com.oracle.truffle.dsl.processor.java.ElementUtils.*;
 import static java.util.Arrays.*;
 import static javax.lang.model.element.Modifier.*;
@@ -47,7 +46,7 @@
  */
 public class GraphNodeGenerator {
 
-    private static final boolean GENERATE_ASSERTIONS = false;
+    @SuppressWarnings("unused") private static final boolean GENERATE_ASSERTIONS = false;
 
     private final GraphNodeProcessor env;
     private final Types types;
@@ -58,10 +57,10 @@
     private final TypeElement Successor;
 
     final TypeElement Node;
-    private final TypeElement NodeList;
+    @SuppressWarnings("unused") private final TypeElement NodeList;
     private final TypeElement NodeInputList;
     private final TypeElement NodeSuccessorList;
-    private final TypeElement Position;
+    @SuppressWarnings("unused") private final TypeElement Position;
 
     private final List<VariableElement> inputFields = new ArrayList<>();
     private final List<VariableElement> inputListFields = new ArrayList<>();
@@ -333,53 +332,7 @@
             boolean hasSuccessors = !successorFields.isEmpty() || !successorListFields.isEmpty();
 
             if (hasInputs || hasSuccessors) {
-                createGetNodeAtMethod();
-                createGetInputTypeAtMethod();
-                createGetNameOfMethod();
-                createUpdateOrInitializeNodeAtMethod(false);
-                createUpdateOrInitializeNodeAtMethod(true);
                 createIsLeafNodeMethod();
-                createPositionAccessibleFieldOrderClass(packageElement);
-
-                if (!inputListFields.isEmpty() || !successorListFields.isEmpty()) {
-                    createGetNodeListAtPositionMethod();
-                    createSetNodeListAtMethod();
-                }
-            }
-
-            if (hasInputs) {
-                createIsOptionalInputAtMethod();
-                createGetFirstLevelPositionsMethod(Inputs, inputFields, inputListFields);
-
-                createContainsMethod(Inputs, inputFields, inputListFields);
-                createIterableMethod(Inputs);
-
-                CodeTypeElement inputsIteratorClass = createIteratorClass(Inputs, packageElement, inputFields, inputListFields);
-                createAllIteratorClass(Inputs, inputsIteratorClass.asType(), packageElement, inputFields, inputListFields);
-                createWithModCountIteratorClass(Inputs, inputsIteratorClass.asType(), packageElement);
-                createIterableClass(Inputs, packageElement);
-                createGetNodeAtMethod(NodeRefsType.Inputs, inputFields);
-                createCountMethod(NodeRefsType.Inputs, inputFields.size(), inputListFields.size());
-                if (!inputListFields.isEmpty()) {
-                    createGetNodeListAtIndexMethod(NodeRefsType.Inputs, inputListFields);
-                }
-            }
-
-            if (hasSuccessors) {
-                createGetFirstLevelPositionsMethod(Successors, successorFields, successorListFields);
-
-                createContainsMethod(Successors, successorFields, successorListFields);
-                createIterableMethod(Successors);
-
-                CodeTypeElement successorsIteratorClass = createIteratorClass(Successors, packageElement, successorFields, successorListFields);
-                createAllIteratorClass(Successors, successorsIteratorClass.asType(), packageElement, successorFields, successorListFields);
-                createWithModCountIteratorClass(Successors, successorsIteratorClass.asType(), packageElement);
-                createIterableClass(Successors, packageElement);
-                createGetNodeAtMethod(NodeRefsType.Successors, successorFields);
-                createCountMethod(NodeRefsType.Successors, successorFields.size(), successorListFields.size());
-                if (!successorListFields.isEmpty()) {
-                    createGetNodeListAtIndexMethod(NodeRefsType.Successors, successorListFields);
-                }
             }
         }
         compilationUnit.add(genClass);
@@ -442,6 +395,7 @@
         genClassName = null;
     }
 
+    @SuppressWarnings("unused")
     private CodeVariableElement addParameter(CodeExecutableElement method, TypeMirror type, String name) {
         return addParameter(method, type, name, true);
     }
@@ -478,497 +432,6 @@
         checkOnlyInGenNode(method);
     }
 
-    private ExecutableElement createIsOptionalInputAtMethod() {
-        CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), getType(boolean.class), "isOptionalInputAt");
-        addParameter(method, Position.asType(), "pos");
-        CodeTreeBuilder b = method.createBuilder();
-        if (GENERATE_ASSERTIONS) {
-            b.startAssert().string("pos.isInput()").end();
-        }
-        if (!optionalInputs.isEmpty()) {
-            b.startSwitch().string("pos.getIndex()").end().startBlock();
-            int index = 0;
-            for (VariableElement f : concat(inputFields, inputListFields)) {
-                if (optionalInputs.contains(f)) {
-                    b.startCase().string(String.valueOf(index)).end();
-                }
-                index++;
-            }
-            b.startStatement().string("return true").end();
-            b.end();
-        }
-        b.startReturn().string("false").end();
-        genClass.add(method);
-        checkOnlyInGenNode(method);
-        return method;
-    }
-
-    private ExecutableElement createGetFirstLevelPositionsMethod(NodeRefsType nodeRefsType, List<VariableElement> nodeFields, List<VariableElement> nodeListFields) {
-        DeclaredType collectionOfPosition = types.getDeclaredType((TypeElement) types.asElement(getType(Collection.class)), Position.asType());
-        CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), collectionOfPosition, "getFirstLevel" + nodeRefsType);
-        CodeTreeBuilder b = method.createBuilder();
-        b.startReturn().startNew(getTypeElement("com.oracle.graal.graph.FirstLevelPositionCollection").asType());
-        b.string(String.valueOf(nodeFields.size()));
-        b.string(String.valueOf(nodeListFields.size()));
-        b.string(String.valueOf(nodeRefsType == NodeRefsType.Inputs));
-        b.end().end();
-        genClass.add(method);
-        checkOnlyInGenNode(method);
-        return method;
-    }
-
-    private CodeTypeElement createIteratorClass(NodeRefsType nodeRefsType, PackageElement packageElement, List<VariableElement> nodeFields, List<VariableElement> nodeListFields) {
-        String name = nodeRefsType + "Iterator";
-        CodeTypeElement cls = new CodeTypeElement(modifiers(PRIVATE), ElementKind.CLASS, packageElement, name);
-        cls.setSuperClass(getType("com.oracle.graal.graph.NodeRefIterator"));
-
-        // Constructor
-        CodeExecutableElement ctor = new CodeExecutableElement(Collections.emptySet(), null, name);
-        CodeTreeBuilder b = ctor.createBuilder();
-        b.startStatement().startSuperCall();
-        b.string(genClassName, ".this");
-        b.string(String.valueOf(nodeFields.size()));
-        b.string(String.valueOf(nodeListFields.size()));
-        b.string(String.valueOf(nodeRefsType == NodeRefsType.Inputs));
-        b.end().end();
-        cls.add(ctor);
-
-        // Methods overriding those in NodeRefIterator
-        createGetFieldMethod(cls, nodeFields, Node.asType(), "getNode");
-        createGetFieldMethod(cls, nodeListFields, types.getDeclaredType(NodeList, types.getWildcardType(Node.asType(), null)), "getNodeList");
-        genClass.add(cls);
-        return cls;
-    }
-
-    private void createGetFieldMethod(CodeTypeElement cls, List<VariableElement> fields, TypeMirror returnType, String name) {
-        if (!fields.isEmpty()) {
-            CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED, FINAL), returnType, name);
-            addParameter(method, getType(int.class), "at");
-            CodeTreeBuilder b = method.createBuilder();
-            createGetFieldCases(b, fields, returnType, null);
-            cls.add(method);
-        }
-    }
-
-    private void createGetFieldCases(CodeTreeBuilder b, List<VariableElement> fields, TypeMirror returnType, String returnExpressionSuffix) {
-        for (int i = 0; i < fields.size(); i++) {
-            VariableElement field = fields.get(i);
-            b.startIf().string("at == " + i).end().startBlock();
-            b.startReturn();
-            if (returnExpressionSuffix == null && !isAssignableWithErasure(field, types.asElement(returnType))) {
-                b.cast(((DeclaredType) returnType).asElement().getSimpleName().toString());
-            }
-            b.string(genClassName + ".this." + field.getSimpleName());
-            if (returnExpressionSuffix != null) {
-                b.string(returnExpressionSuffix);
-            }
-            b.end();
-            b.end();
-        }
-        b.startThrow().startNew(getType(NoSuchElementException.class)).end().end();
-    }
-
-    private void createSetNodeListAtCases(CodeTreeBuilder b, List<VariableElement> fields, TypeMirror returnType, String returnExpressionSuffix) {
-        for (int i = 0; i < fields.size(); i++) {
-            VariableElement field = fields.get(i);
-            b.startIf().string("at == " + i).end().startBlock();
-            if (returnExpressionSuffix == null && !isAssignableWithErasure(field, types.asElement(returnType))) {
-                b.cast(((DeclaredType) returnType).asElement().getSimpleName().toString());
-            }
-            b.startStatement();
-            b.string(genClassName + ".this." + field.getSimpleName(), " = ");
-            b.cast(field.asType(), CodeTreeBuilder.singleString("list"));
-            b.end();
-            b.end();
-        }
-    }
-
-    private void createUpdateOrInitializeFieldCases(CodeTreeBuilder b, List<VariableElement> fields, boolean isInitialization, boolean isList) {
-        boolean elseIf = false;
-        for (int i = 0; i < fields.size(); i++) {
-            VariableElement field = fields.get(i);
-            String fieldRef = genClassName + ".this." + field.getSimpleName();
-            if (!isList) {
-                elseIf = b.startIf(elseIf);
-                b.string("at == " + i).end().startBlock();
-                if (!isInitialization) {
-                    b.startStatement().string("Node old = ");
-                    if (!isAssignableWithErasure(field, Node)) {
-                        b.cast(Node.asType(), CodeTreeBuilder.singleString(fieldRef));
-                    } else {
-                        b.string(fieldRef);
-                    }
-                    b.end();
-                }
-                b.startStatement().string(fieldRef, " = ");
-                if (!isAssignableWithErasure(Node, field)) {
-                    b.cast(field.asType(), CodeTreeBuilder.singleString("newValue"));
-                } else {
-                    b.string("newValue");
-                }
-                b.end();
-                if (!isInitialization) {
-                    b.startIf().string("pos.isInput()").end().startBlock();
-                    b.startStatement().string("updateUsages(old, newValue)").end();
-                    b.end();
-                    b.startElseBlock();
-                    b.startStatement().string("updatePredecessor(old, newValue)").end();
-                    b.end();
-                }
-                b.end();
-            } else {
-                elseIf = b.startIf(elseIf);
-                b.string("at == " + i).end().startBlock();
-                DeclaredType nodeListOfNode = types.getDeclaredType(NodeList, types.getWildcardType(Node.asType(), null));
-                b.declaration(nodeListOfNode, "list", fieldRef);
-                if (!isInitialization) {
-                    // if (pos.getSubIndex() < list.size()) {
-                    b.startIf().string("pos.getSubIndex() < list.size()").end().startBlock();
-                    b.startStatement().string("list.set(pos.getSubIndex(), newValue)").end();
-                    b.end();
-                    b.startElseBlock();
-                }
-
-                b.startWhile().string("list.size() <= pos.getSubIndex()").end().startBlock();
-                b.startStatement().string("list.add(null)").end();
-                b.end();
-
-                if (isInitialization) {
-                    b.startStatement().string("list.initialize(pos.getSubIndex(), newValue)").end();
-                } else {
-                    b.startStatement().string("list.add(newValue)").end();
-                    b.end();
-                }
-
-                b.end();
-            }
-        }
-        b.startElseBlock();
-        b.startThrow().startNew(getType(NoSuchElementException.class)).end().end();
-        b.end();
-    }
-
-    private void createPositionAccessibleFieldOrderClass(PackageElement packageElement) {
-        CodeTypeElement cls = new CodeTypeElement(modifiers(PUBLIC, STATIC), ElementKind.CLASS, packageElement, "FieldOrder");
-        cls.getImplements().add(getType("com.oracle.graal.graph.NodeClass.PositionFieldOrder"));
-
-        CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), getType(String[].class), "getOrderedFieldNames");
-
-        addParameter(method, getType(boolean.class), "input", false);
-
-        CodeTreeBuilder b = method.createBuilder();
-        b.startIf().string("input").end().startBlock();
-        String initializer = concat(inputFields, inputListFields).stream().map(v -> v.getSimpleName().toString()).collect(Collectors.joining("\", \"", "\"", "\""));
-        b.startStatement().string("return new String[] {", initializer, "}").end();
-        b.end();
-        b.startElseBlock();
-        initializer = concat(successorFields, successorListFields).stream().map(v -> v.getSimpleName().toString()).collect(Collectors.joining("\", \"", "\"", "\""));
-        b.startStatement().string("return new String[] {", initializer, "}").end();
-        b.end();
-        cls.add(method);
-
-        genClass.add(cls);
-
-    }
-
-    private void createAllIteratorClass(NodeRefsType nodeRefsType, TypeMirror inputsIteratorType, PackageElement packageElement, List<VariableElement> nodeFields, List<VariableElement> nodeListFields) {
-
-        String name = "All" + nodeRefsType + "Iterator";
-        CodeTypeElement cls = new CodeTypeElement(modifiers(PRIVATE, FINAL), ElementKind.CLASS, packageElement, name);
-        cls.setSuperClass(inputsIteratorType);
-
-        // forward() method
-        CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED), getType(void.class), "forward");
-        CodeTreeBuilder b = method.createBuilder();
-        int nodeFieldsSize = nodeFields.size();
-        int nodeListFieldsSize = nodeListFields.size();
-        String cond = "index < " + nodeFieldsSize;
-        if (GENERATE_ASSERTIONS) {
-            b.startAssert().string("needsForward").end();
-        }
-        b.startStatement().string("needsForward = false").end();
-        b.startIf().string(cond).end().startBlock();
-        b.startStatement().string("index++").end();
-        b.startIf().string(cond).end().startBlock();
-        b.startStatement().string("nextElement = getNode(index)").end();
-        b.startStatement().string("return").end();
-        b.end();
-        b.end();
-        b.startElseBlock();
-        b.startStatement().string("subIndex++").end();
-        b.end();
-        int count = nodeFieldsSize + nodeListFieldsSize;
-        b.startWhile().string("index < " + count).end().startBlock();
-        b.startIf().string("subIndex == 0").end().startBlock();
-        b.startStatement().string("list = getNodeList(index - " + nodeFieldsSize + ")").end();
-        b.end();
-        b.startIf().string("subIndex < list.size()").end().startBlock();
-        b.startStatement().string("nextElement = list.get(subIndex)").end();
-        b.startStatement().string("return").end();
-        b.end();
-        b.startStatement().string("subIndex = 0").end();
-        b.startStatement().string("index++").end();
-        b.end();
-
-        cls.add(method);
-
-        genClass.add(cls);
-    }
-
-    private void createWithModCountIteratorClass(NodeRefsType nodeRefsType, TypeMirror superType, PackageElement packageElement) {
-
-        String name = nodeRefsType + "WithModCountIterator";
-        CodeTypeElement cls = new CodeTypeElement(modifiers(PRIVATE, FINAL), ElementKind.CLASS, packageElement, name);
-        cls.setSuperClass(superType);
-
-        // modCount field
-        cls.add(new CodeVariableElement(modifiers(PRIVATE, FINAL), getType(int.class), "modCount"));
-
-        // Constructor
-        CodeExecutableElement ctor = new CodeExecutableElement(Collections.emptySet(), null, name);
-        CodeTreeBuilder b = ctor.createBuilder();
-        b.startAssert().staticReference(getType("com.oracle.graal.graph.Graph"), "MODIFICATION_COUNTS_ENABLED").end();
-        b.startStatement().string("this.modCount = modCount()").end();
-        cls.add(ctor);
-
-        // hasNext, next and nextPosition methods
-        overrideModWithCounterMethod(cls, "hasNext", getType(boolean.class));
-        overrideModWithCounterMethod(cls, "next", Node.asType());
-        overrideModWithCounterMethod(cls, "nextPosition", Position.asType());
-
-        genClass.add(cls);
-    }
-
-    private static void overrideModWithCounterMethod(CodeTypeElement cls, String name, TypeMirror returnType) {
-        CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), returnType, name);
-        CodeTreeBuilder b = method.createBuilder();
-        b.startTryBlock();
-        b.startStatement().string("return super." + name + "()").end();
-        b.end().startFinallyBlock();
-        b.startAssert().string("modCount == modCount() : \"must not be modified\"").end();
-        b.end();
-        cls.add(method);
-    }
-
-    private void createIterableClass(NodeRefsType nodeRefsType, PackageElement packageElement) {
-
-        String name = nodeRefsType + "Iterable";
-        CodeTypeElement cls = new CodeTypeElement(modifiers(PRIVATE), ElementKind.CLASS, packageElement, name);
-        cls.getImplements().add(getType("com.oracle.graal.graph.NodeClassIterable"));
-
-        // iterator() method
-        CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC, FINAL), getType("com.oracle.graal.graph.NodeRefIterator"), "iterator");
-        CodeTreeBuilder b = method.createBuilder();
-        b.startIf().staticReference(getType("com.oracle.graal.graph.Graph"), "MODIFICATION_COUNTS_ENABLED").end().startBlock();
-        b.startStatement().string("return new " + nodeRefsType + "WithModCountIterator()").end();
-        b.end();
-        b.startElseBlock();
-        b.startStatement().string("return new " + nodeRefsType + "Iterator()").end();
-        b.end();
-        cls.add(method);
-
-        // withNullIterator() method
-        method = new CodeExecutableElement(modifiers(PUBLIC, FINAL), getType("com.oracle.graal.graph.NodePosIterator"), "withNullIterator");
-        b = method.createBuilder();
-        b.startStatement().string("return new All" + nodeRefsType + "Iterator()").end();
-        cls.add(method);
-
-        // contains(Node) method
-        method = new CodeExecutableElement(modifiers(PUBLIC, FINAL), getType(boolean.class), "contains");
-        addParameter(method, Node.asType(), "n");
-        b = method.createBuilder();
-        b.startStatement().string("return " + nodeRefsType.name().toLowerCase() + "Contains(n)").end();
-        cls.add(method);
-        genClass.add(cls);
-    }
-
-    private void createContainsMethod(NodeRefsType nodeRefsType, List<VariableElement> nodeFields, List<VariableElement> nodeListFields) {
-        CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC, FINAL), getType(boolean.class), nodeRefsType.name().toLowerCase() + "Contains");
-        addParameter(method, Node.asType(), "n");
-        CodeTreeBuilder b = method.createBuilder();
-        for (VariableElement f : nodeFields) {
-            b.startIf().string("n == " + f).end().startBlock();
-            b.startStatement().string("return true").end();
-            b.end();
-        }
-        for (VariableElement f : nodeListFields) {
-            b.startIf().string(f + ".contains(n)").end().startBlock();
-            b.startStatement().string("return true").end();
-            b.end();
-        }
-        b.startStatement().string("return false").end();
-        genClass.add(method);
-        checkOnlyInGenNode(method);
-    }
-
-    private static final String API_TAG = "V2";
-
-    private void createIterableMethod(NodeRefsType nodeRefsType) {
-        CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC, FINAL), getType("com.oracle.graal.graph.NodeClassIterable"), (nodeRefsType == Inputs ? "inputs" : "successors") +
-                        API_TAG);
-        CodeTreeBuilder b = method.createBuilder();
-        b.startStatement().string("return new " + nodeRefsType + "Iterable()").end();
-        genClass.add(method);
-        checkOnlyInGenNode(method);
-    }
-
-    private void createGetNodeAtMethod() {
-        CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC, FINAL), Node.asType(), "getNodeAt");
-        addParameter(method, Position.asType(), "pos");
-        CodeTreeBuilder b = method.createBuilder();
-        b.startIf().string("pos.isInput()").end().startBlock();
-        createGetNodeAt(b, inputFields, inputListFields);
-        b.end();
-        b.startElseBlock();
-        createGetNodeAt(b, successorFields, successorListFields);
-        b.end();
-        genClass.add(method);
-        checkOnlyInGenNode(method);
-    }
-
-    private void createCountMethod(NodeRefsType nodeRefsType, int nodesCount, int nodeListsCount) {
-        CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC, FINAL), getType(int.class), "get" + nodeRefsType + "Count");
-        CodeTreeBuilder b = method.createBuilder();
-
-        b.startStatement().string("return " + (nodeListsCount << 16 | nodesCount), " /* (" + nodeListsCount + " << 16 | " + nodesCount + ") */").end();
-        genClass.add(method);
-        checkOnlyInGenNode(method);
-    }
-
-    private void createGetNodeAtMethod(NodeRefsType nodeRefsType, List<VariableElement> nodes) {
-        CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC, FINAL), Node.asType(), "get" + nodeRefsType.singular() + "NodeAt");
-        addParameter(method, getType(int.class), "index");
-        CodeTreeBuilder b = method.createBuilder();
-        boolean justOne = nodes.size() == 1;
-        if (!justOne) {
-            b.startSwitch().string("index").end().startBlock();
-        } else if (GENERATE_ASSERTIONS) {
-            b.startAssert().string("index == 0").end();
-        }
-        int index = 0;
-        for (VariableElement f : nodes) {
-            if (!justOne) {
-                b.startCase().string(String.valueOf(index)).end();
-            }
-            b.startReturn();
-            if (!isAssignableWithErasure(f, Node)) {
-                b.cast(((DeclaredType) Node.asType()).asElement().getSimpleName().toString());
-            }
-            b.string(genClassName + ".this." + f.getSimpleName());
-            b.end();
-            index++;
-        }
-        if (!justOne) {
-            b.end();
-            b.startThrow().startNew(getType(NoSuchElementException.class)).end().end();
-        }
-        genClass.add(method);
-        checkOnlyInGenNode(method);
-    }
-
-    private void createGetNodeListAtIndexMethod(NodeRefsType nodeRefsType, List<VariableElement> nodeLists) {
-        CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC, FINAL), types.getDeclaredType(NodeList, types.getWildcardType(Node.asType(), null)), "get" +
-                        nodeRefsType.singular() + "NodeListAt");
-        addParameter(method, getType(int.class), "index");
-        CodeTreeBuilder b = method.createBuilder();
-
-        boolean justOne = nodeLists.size() == 1;
-        if (!justOne) {
-            b.startSwitch().string("index").end().startBlock();
-        } else if (GENERATE_ASSERTIONS) {
-            b.startAssert().string("index == 0").end();
-        }
-        int index = 0;
-        for (VariableElement f : nodeLists) {
-            if (!justOne) {
-                b.startCase().string(String.valueOf(index)).end();
-            }
-            b.startReturn();
-            b.string(genClassName + ".this." + f.getSimpleName());
-            b.end();
-            index++;
-        }
-        if (!justOne) {
-            b.end();
-            b.startThrow().startNew(getType(NoSuchElementException.class)).end().end();
-        }
-        genClass.add(method);
-        checkOnlyInGenNode(method);
-    }
-
-    private void createGetNodeListAtPositionMethod() {
-        CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC, FINAL), types.getDeclaredType(NodeList, types.getWildcardType(Node.asType(), null)), "getNodeListAt");
-        addParameter(method, Position.asType(), "pos");
-        CodeTreeBuilder b = method.createBuilder();
-        b.startIf().string("pos.isInput()").end().startBlock();
-        createGetNodeListAt(b, inputFields, inputListFields);
-        b.end();
-        b.startElseBlock();
-        createGetNodeListAt(b, successorFields, successorListFields);
-        b.end();
-        genClass.add(method);
-        checkOnlyInGenNode(method);
-    }
-
-    private void createSetNodeListAtMethod() {
-        CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC, FINAL), getType(void.class), "setNodeListAt");
-
-        DeclaredType suppress = (DeclaredType) getType(SuppressWarnings.class);
-        CodeAnnotationMirror suppressMirror = new CodeAnnotationMirror(suppress);
-        suppressMirror.setElementValue(suppressMirror.findExecutableElement("value"), new CodeAnnotationValue("unchecked"));
-        method.getAnnotationMirrors().add(suppressMirror);
-
-        addParameter(method, Position.asType(), "pos");
-        addParameter(method, types.getDeclaredType(NodeList, types.getWildcardType(Node.asType(), null)), "list");
-        CodeTreeBuilder b = method.createBuilder();
-        b.startIf().string("pos.isInput()").end().startBlock();
-        createSetNodeListAt(b, inputFields, inputListFields);
-        b.end();
-        b.startElseBlock();
-        createSetNodeListAt(b, successorFields, successorListFields);
-        b.end();
-        genClass.add(method);
-        checkOnlyInGenNode(method);
-    }
-
-    private void createGetNameOfMethod() {
-        CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC, FINAL), getType(String.class), "getNameOf");
-        addParameter(method, Position.asType(), "pos");
-        CodeTreeBuilder b = method.createBuilder();
-
-        b.startIf().string("pos.isInput()").end().startBlock();
-        createGetNameOf(b, inputFields, inputListFields);
-        b.end();
-        b.startElseBlock();
-        createGetNameOf(b, successorFields, successorListFields);
-        b.end();
-        genClass.add(method);
-        checkOnlyInGenNode(method);
-    }
-
-    private void createGetInputTypeAtMethod() {
-        CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC, FINAL), getType(InputType.class), "getInputTypeAt");
-        addParameter(method, Position.asType(), "pos");
-        CodeTreeBuilder b = method.createBuilder();
-        if (GENERATE_ASSERTIONS) {
-            b.startAssert().string("pos.isInput()").end();
-        }
-        boolean hasNodes = !inputFields.isEmpty();
-        boolean hasNodeLists = !inputListFields.isEmpty();
-        if (hasNodeLists || hasNodes) {
-            int index = 0;
-            for (VariableElement f : concat(inputFields, inputListFields)) {
-                b.startIf().string("pos.getIndex() == " + index).end().startBlock();
-                b.startStatement().string("return ").staticReference(getType(InputType.class), inputTypes.get(f).getSimpleName().toString()).end();
-                b.end();
-                index++;
-            }
-        }
-        b.startThrow().startNew(getType(NoSuchElementException.class)).end().end();
-        genClass.add(method);
-        checkOnlyInGenNode(method);
-    }
-
     private boolean hidesField(String name) {
         for (VariableElement field : concat(inputFields, inputListFields, successorFields, successorListFields, dataFields)) {
             if (field.getSimpleName().contentEquals(name)) {
@@ -977,142 +440,4 @@
         }
         return false;
     }
-
-    private void createUpdateOrInitializeNodeAtMethod(boolean isInitialization) {
-        CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC, FINAL), getType(void.class), (isInitialization ? "initialize" : "update") + "NodeAt");
-        addParameter(method, Position.asType(), "pos");
-        addParameter(method, Node.asType(), "newValue");
-        CodeTreeBuilder b = method.createBuilder();
-        b.startIf().string("pos.isInput()").end().startBlock();
-        createUpdateOrInitializeNodeAt(b, inputFields, inputListFields, isInitialization);
-        b.end();
-        b.startElseBlock();
-        createUpdateOrInitializeNodeAt(b, successorFields, successorListFields, isInitialization);
-        b.end();
-        genClass.add(method);
-        checkOnlyInGenNode(method);
-    }
-
-    private void createGetNodeAt(CodeTreeBuilder b, List<VariableElement> nodes, List<VariableElement> nodeLists) {
-        boolean hasNodes = !nodes.isEmpty();
-        boolean hasNodeLists = !nodeLists.isEmpty();
-        if (!hasNodeLists && !hasNodes) {
-            b.startThrow().startNew(getType(NoSuchElementException.class)).end().end();
-        } else {
-            if (hasNodes) {
-                if (!hasNodeLists) {
-                    if (GENERATE_ASSERTIONS) {
-                        b.startAssert().string("pos.getSubIndex() == NOT_ITERABLE").end();
-                    }
-                } else {
-                    b.startIf().string("pos.getSubIndex() == NOT_ITERABLE").end().startBlock();
-                }
-                b.declaration("int", "at", "pos.getIndex()");
-                createGetFieldCases(b, nodes, Node.asType(), null);
-                if (hasNodeLists) {
-                    b.end();
-                }
-            }
-
-            if (hasNodeLists) {
-                if (!hasNodes) {
-                    if (GENERATE_ASSERTIONS) {
-                        b.startAssert().string("pos.getSubIndex() != NOT_ITERABLE").end();
-                    }
-                } else {
-                    b.startElseBlock();
-                }
-                b.declaration("int", "at", "pos.getIndex() - " + nodes.size());
-                createGetFieldCases(b, nodeLists, Node.asType(), ".get(pos.getSubIndex())");
-                if (hasNodes) {
-                    b.end();
-                }
-            }
-        }
-    }
-
-    private void createGetNodeListAt(CodeTreeBuilder b, List<VariableElement> nodes, List<VariableElement> nodeLists) {
-        boolean hasNodeLists = !nodeLists.isEmpty();
-        if (!hasNodeLists) {
-            b.startThrow().startNew(getType(NoSuchElementException.class)).end().end();
-        } else {
-            if (GENERATE_ASSERTIONS) {
-                b.startAssert().string("pos.getSubIndex() == NODE_LIST").end();
-            }
-            b.declaration("int", "at", "pos.getIndex() - " + nodes.size());
-            createGetFieldCases(b, nodeLists, Node.asType(), "");
-        }
-    }
-
-    private void createSetNodeListAt(CodeTreeBuilder b, List<VariableElement> nodes, List<VariableElement> nodeLists) {
-        boolean hasNodeLists = !nodeLists.isEmpty();
-        if (!hasNodeLists) {
-            b.startThrow().startNew(getType(NoSuchElementException.class)).end().end();
-        } else {
-            if (GENERATE_ASSERTIONS) {
-                b.startAssert().string("pos.getSubIndex() == NODE_LIST").end();
-            }
-            b.declaration("int", "at", "pos.getIndex() - " + nodes.size());
-            createSetNodeListAtCases(b, nodeLists, Node.asType(), "");
-        }
-    }
-
-    private void createGetNameOf(CodeTreeBuilder b, List<VariableElement> nodes, List<VariableElement> nodeLists) {
-        boolean hasNodes = !nodes.isEmpty();
-        boolean hasNodeLists = !nodeLists.isEmpty();
-        if (hasNodeLists || hasNodes) {
-            int index = 0;
-            for (VariableElement f : nodes) {
-                b.startIf().string("pos.getIndex() == " + index).end().startBlock();
-                b.startStatement().string("return \"" + f.getSimpleName() + "\"").end();
-                b.end();
-                index++;
-            }
-            for (VariableElement f : nodeLists) {
-                b.startIf().string("pos.getIndex() == " + index).end().startBlock();
-                b.startStatement().string("return \"" + f.getSimpleName() + "\"").end();
-                b.end();
-                index++;
-            }
-        }
-        b.startThrow().startNew(getType(NoSuchElementException.class)).end().end();
-    }
-
-    private void createUpdateOrInitializeNodeAt(CodeTreeBuilder b, List<VariableElement> nodes, List<VariableElement> nodeLists, boolean isInitialization) {
-        boolean hasNodes = !nodes.isEmpty();
-        boolean hasNodeLists = !nodeLists.isEmpty();
-        if (nodes.isEmpty() && nodeLists.isEmpty()) {
-            b.startThrow().startNew(getType(NoSuchElementException.class)).end().end();
-        } else {
-            if (hasNodes) {
-                if (!hasNodeLists) {
-                    if (GENERATE_ASSERTIONS) {
-                        b.startAssert().string("pos.getSubIndex() == NOT_ITERABLE").end();
-                    }
-                } else {
-                    b.startIf().string("pos.getSubIndex() == NOT_ITERABLE").end().startBlock();
-                }
-                b.declaration("int", "at", "pos.getIndex()");
-                createUpdateOrInitializeFieldCases(b, nodes, isInitialization, false);
-                if (hasNodeLists) {
-                    b.end();
-                }
-            }
-
-            if (hasNodeLists) {
-                if (!hasNodes) {
-                    if (GENERATE_ASSERTIONS) {
-                        b.startAssert().string("pos.getSubIndex() != NOT_ITERABLE").end();
-                    }
-                } else {
-                    b.startElseBlock();
-                }
-                b.declaration("int", "at", "pos.getIndex() - " + nodes.size());
-                createUpdateOrInitializeFieldCases(b, nodeLists, isInitialization, true);
-                if (hasNodes) {
-                    b.end();
-                }
-            }
-        }
-    }
 }
--- a/graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/IntegerStampTest.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/IntegerStampTest.java	Wed Sep 24 16:22:22 2014 -0700
@@ -38,6 +38,10 @@
 
     private StructuredGraph graph;
 
+    private static Stamp addIntStamp(Stamp a, Stamp b) {
+        return IntegerStamp.OPS.getAdd().foldStamp(a, b);
+    }
+
     @Before
     public void before() {
         graph = new StructuredGraph();
@@ -160,106 +164,107 @@
 
     @Test
     public void testXor() {
-        assertEquals(new IntegerStamp(32, 0, 0xff, 0, 0xff), StampTool.xor(new IntegerStamp(32, 0, 0, 0, 0), new IntegerStamp(32, 0, 0xff, 0, 0xff)));
-        assertEquals(new IntegerStamp(32, 0x10, 0x1f, 0x10, 0x1f), StampTool.xor(new IntegerStamp(32, 0, 0, 0, 0), new IntegerStamp(32, 0x10, 0x1f, 0x10, 0x1f)));
-        assertEquals(new IntegerStamp(32, 0x0, 0xf, 0x0, 0xf), StampTool.xor(new IntegerStamp(32, 0x10, 0x10, 0x10, 0x10), new IntegerStamp(32, 0x10, 0x1f, 0x10, 0x1f)));
-        assertEquals(new IntegerStamp(32, 0x10, 0x1f, 0x10, 0x1f), StampTool.xor(new IntegerStamp(32, 0x10, 0x10, 0x10, 0x10), new IntegerStamp(32, 0x0, 0xf, 0x0, 0xf)));
+        assertEquals(new IntegerStamp(32, 0, 0xff, 0, 0xff), IntegerStamp.OPS.getXor().foldStamp(new IntegerStamp(32, 0, 0, 0, 0), new IntegerStamp(32, 0, 0xff, 0, 0xff)));
+        assertEquals(new IntegerStamp(32, 0x10, 0x1f, 0x10, 0x1f), IntegerStamp.OPS.getXor().foldStamp(new IntegerStamp(32, 0, 0, 0, 0), new IntegerStamp(32, 0x10, 0x1f, 0x10, 0x1f)));
+        assertEquals(new IntegerStamp(32, 0x0, 0xf, 0x0, 0xf), IntegerStamp.OPS.getXor().foldStamp(new IntegerStamp(32, 0x10, 0x10, 0x10, 0x10), new IntegerStamp(32, 0x10, 0x1f, 0x10, 0x1f)));
+        assertEquals(new IntegerStamp(32, 0x10, 0x1f, 0x10, 0x1f), IntegerStamp.OPS.getXor().foldStamp(new IntegerStamp(32, 0x10, 0x10, 0x10, 0x10), new IntegerStamp(32, 0x0, 0xf, 0x0, 0xf)));
     }
 
     @Test
     public void testNot() {
-        assertEquals(new IntegerStamp(32, -11, -1, 0xffff_fff0L, 0xffff_ffffL), StampTool.not(new IntegerStamp(32, 0, 10, 0, 0xf)));
+        assertEquals(new IntegerStamp(32, -11, -1, 0xffff_fff0L, 0xffff_ffffL), IntegerStamp.OPS.getNot().foldStamp(new IntegerStamp(32, 0, 10, 0, 0xf)));
     }
 
     @Test
     public void testAddIntSimple() {
-        assertEquals(StampFactory.forInteger(Kind.Int, 0, 30, 0, 31), StampTool.add(StampFactory.forInteger(Kind.Int, 0, 10), StampFactory.forInteger(Kind.Int, 0, 20)));
+        assertEquals(StampFactory.forInteger(Kind.Int, 0, 30, 0, 31), addIntStamp(StampFactory.forInteger(Kind.Int, 0, 10), StampFactory.forInteger(Kind.Int, 0, 20)));
     }
 
     @Test
     public void testAddNegativeOverFlowInt1() {
         assertEquals(StampFactory.forInteger(Kind.Int, Integer.MIN_VALUE, Integer.MAX_VALUE, 0, 0xffff_ffffL),
-                        StampTool.add(StampFactory.forInteger(Kind.Int, Integer.MIN_VALUE, 0), StampFactory.forInteger(Kind.Int, -1, 0)));
+                        addIntStamp(StampFactory.forInteger(Kind.Int, Integer.MIN_VALUE, 0), StampFactory.forInteger(Kind.Int, -1, 0)));
     }
 
     @Test
     public void testAddNegativeOverFlowInt2() {
         assertEquals(StampFactory.forInteger(Kind.Int, Integer.MAX_VALUE - 2, Integer.MAX_VALUE, 0x7fff_fffcL, 0x7fff_ffffL),
-                        StampTool.add(StampFactory.forInteger(Kind.Int, Integer.MIN_VALUE, Integer.MIN_VALUE + 1), StampFactory.forInteger(Kind.Int, -3, -2)));
+                        addIntStamp(StampFactory.forInteger(Kind.Int, Integer.MIN_VALUE, Integer.MIN_VALUE + 1), StampFactory.forInteger(Kind.Int, -3, -2)));
     }
 
     @Test
     public void testAddPositiveOverFlowInt1() {
-        assertEquals(StampFactory.forKind(Kind.Int), StampTool.add(StampFactory.forInteger(Kind.Int, 0, 1), StampFactory.forInteger(Kind.Int, 0, Integer.MAX_VALUE)));
+        assertEquals(StampFactory.forKind(Kind.Int), addIntStamp(StampFactory.forInteger(Kind.Int, 0, 1), StampFactory.forInteger(Kind.Int, 0, Integer.MAX_VALUE)));
     }
 
     @Test
     public void testAddPositiveOverFlowInt2() {
         assertEquals(StampFactory.forInteger(Kind.Int, Integer.MIN_VALUE, Integer.MIN_VALUE + 2),
-                        StampTool.add(StampFactory.forInteger(Kind.Int, Integer.MAX_VALUE - 1, Integer.MAX_VALUE), StampFactory.forInteger(Kind.Int, 2, 3)));
+                        addIntStamp(StampFactory.forInteger(Kind.Int, Integer.MAX_VALUE - 1, Integer.MAX_VALUE), StampFactory.forInteger(Kind.Int, 2, 3)));
     }
 
     @Test
     public void testAddOverFlowsInt() {
-        assertEquals(StampFactory.forKind(Kind.Int), StampTool.add(StampFactory.forInteger(Kind.Int, -1, 1), StampFactory.forInteger(Kind.Int, Integer.MIN_VALUE, Integer.MAX_VALUE)));
+        assertEquals(StampFactory.forKind(Kind.Int), addIntStamp(StampFactory.forInteger(Kind.Int, -1, 1), StampFactory.forInteger(Kind.Int, Integer.MIN_VALUE, Integer.MAX_VALUE)));
     }
 
     @Test
     public void testAddLongSimple() {
-        assertEquals(StampFactory.forInteger(Kind.Long, 0, 30, 0, 31), StampTool.add(StampFactory.forInteger(Kind.Long, 0, 10), StampFactory.forInteger(Kind.Long, 0, 20)));
+        assertEquals(StampFactory.forInteger(Kind.Long, 0, 30, 0, 31), addIntStamp(StampFactory.forInteger(Kind.Long, 0, 10), StampFactory.forInteger(Kind.Long, 0, 20)));
     }
 
     @Test
     public void testAddNegativOverFlowLong1() {
         assertEquals(StampFactory.forInteger(Kind.Long, Long.MIN_VALUE, Long.MAX_VALUE, 0, 0xffff_ffff_ffff_ffffL),
-                        StampTool.add(StampFactory.forInteger(Kind.Long, Long.MIN_VALUE, Long.MIN_VALUE + 1), StampFactory.forInteger(Kind.Long, Integer.MIN_VALUE, Integer.MAX_VALUE)));
+                        addIntStamp(StampFactory.forInteger(Kind.Long, Long.MIN_VALUE, Long.MIN_VALUE + 1), StampFactory.forInteger(Kind.Long, Integer.MIN_VALUE, Integer.MAX_VALUE)));
     }
 
     @Test
     public void testAddNegativeOverFlowLong2() {
         assertEquals(StampFactory.forInteger(Kind.Long, Long.MAX_VALUE - 2, Long.MAX_VALUE),
-                        StampTool.add(StampFactory.forInteger(Kind.Long, Long.MIN_VALUE, Long.MIN_VALUE + 1), StampFactory.forInteger(Kind.Long, -3, -2)));
+                        addIntStamp(StampFactory.forInteger(Kind.Long, Long.MIN_VALUE, Long.MIN_VALUE + 1), StampFactory.forInteger(Kind.Long, -3, -2)));
     }
 
     @Test
     public void testAddPositiveOverFlowLong1() {
-        assertEquals(StampFactory.forKind(Kind.Long), StampTool.add(StampFactory.forInteger(Kind.Long, 0, 1), StampFactory.forInteger(Kind.Long, 0, Long.MAX_VALUE)));
+        assertEquals(StampFactory.forKind(Kind.Long), addIntStamp(StampFactory.forInteger(Kind.Long, 0, 1), StampFactory.forInteger(Kind.Long, 0, Long.MAX_VALUE)));
     }
 
     @Test
     public void testAddPositiveOverFlowLong2() {
         assertEquals(StampFactory.forInteger(Kind.Long, Long.MIN_VALUE, Long.MIN_VALUE + 2),
-                        StampTool.add(StampFactory.forInteger(Kind.Long, Long.MAX_VALUE - 1, Long.MAX_VALUE), StampFactory.forInteger(Kind.Long, 2, 3)));
+                        addIntStamp(StampFactory.forInteger(Kind.Long, Long.MAX_VALUE - 1, Long.MAX_VALUE), StampFactory.forInteger(Kind.Long, 2, 3)));
     }
 
     @Test
     public void testAddOverFlowsLong() {
-        assertEquals(StampFactory.forKind(Kind.Long), StampTool.add(StampFactory.forInteger(Kind.Long, -1, 1), StampFactory.forInteger(Kind.Long, Long.MIN_VALUE, Long.MAX_VALUE)));
+        assertEquals(StampFactory.forKind(Kind.Long), addIntStamp(StampFactory.forInteger(Kind.Long, -1, 1), StampFactory.forInteger(Kind.Long, Long.MIN_VALUE, Long.MAX_VALUE)));
     }
 
     @Test
     public void testAdd1() {
         assertEquals(StampFactory.forInteger(Kind.Int, Integer.MIN_VALUE + 1, 31 + (Integer.MIN_VALUE + 1)),
-                        StampTool.add(StampFactory.forInteger(Kind.Int, 0, 31), StampFactory.forInteger(Kind.Int, Integer.MIN_VALUE + 1, Integer.MIN_VALUE + 1)));
+                        addIntStamp(StampFactory.forInteger(Kind.Int, 0, 31), StampFactory.forInteger(Kind.Int, Integer.MIN_VALUE + 1, Integer.MIN_VALUE + 1)));
     }
 
     @Test
     public void testAdd2() {
         assertEquals(StampFactory.forInteger(Kind.Int, 0x8000_007e, 0x8000_007f, 0x8000_007eL, 0x8000_007fL),
-                        StampTool.add(StampFactory.forInteger(Kind.Int, 0x7fff_fffe, 0x7fff_ffff, 0x7fff_fffeL, 0x7ffff_fffL), StampFactory.forInteger(Kind.Int, 128, 128)));
+                        addIntStamp(StampFactory.forInteger(Kind.Int, 0x7fff_fffe, 0x7fff_ffff, 0x7fff_fffeL, 0x7ffff_fffL), StampFactory.forInteger(Kind.Int, 128, 128)));
     }
 
     @Test
     public void testAdd3() {
         assertEquals(StampFactory.forInteger(Kind.Long, Long.MIN_VALUE, Long.MAX_VALUE - 1, 0, 0xffff_ffff_ffff_fffeL),
-                        StampTool.add(StampFactory.forInteger(Kind.Long, Long.MIN_VALUE, Long.MAX_VALUE - 1, 0, 0xffff_ffff_ffff_fffeL),
+                        addIntStamp(StampFactory.forInteger(Kind.Long, Long.MIN_VALUE, Long.MAX_VALUE - 1, 0, 0xffff_ffff_ffff_fffeL),
                                         StampFactory.forInteger(Kind.Long, Long.MIN_VALUE, Long.MAX_VALUE - 1, 0, 0xffff_ffff_ffff_fffeL)));
 
     }
 
     @Test
     public void testAnd() {
-        assertEquals(new IntegerStamp(32, Integer.MIN_VALUE, 0x40000000L, 0, 0xc0000000L), StampTool.and(StampFactory.forKind(Kind.Int), StampFactory.forConstant(Constant.forInt(0xc0000000))));
+        assertEquals(new IntegerStamp(32, Integer.MIN_VALUE, 0x40000000L, 0, 0xc0000000L),
+                        IntegerStamp.OPS.getAnd().foldStamp(StampFactory.forKind(Kind.Int), StampFactory.forConstant(Constant.forInt(0xc0000000))));
     }
 
     private static void testSignExtendShort(long lower, long upper) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java	Wed Sep 24 16:22:22 2014 -0700
@@ -24,6 +24,7 @@
 
 import java.util.*;
 
+import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.compiler.common.type.*;
@@ -318,7 +319,7 @@
 
     private static ConstantNode forIntegerBits(int bits, Constant constant, StructuredGraph graph) {
         long value = constant.asLong();
-        long bounds = SignExtendNode.signExtend(value, bits);
+        long bounds = CodeUtil.signExtend(value, bits);
         return unique(graph, ConstantNode.create(constant, StampFactory.forInteger(bits, bounds, bounds)));
     }
 
@@ -332,7 +333,7 @@
 
     private static ConstantNode forIntegerBits(int bits, Constant constant) {
         long value = constant.asLong();
-        long bounds = SignExtendNode.signExtend(value, bits);
+        long bounds = CodeUtil.signExtend(value, bits);
         return ConstantNode.create(constant, StampFactory.forInteger(bits, bounds, bounds));
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java	Wed Sep 24 16:22:22 2014 -0700
@@ -26,6 +26,7 @@
 
 import java.util.*;
 
+import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.iterators.*;
 import com.oracle.graal.graph.spi.*;
@@ -247,8 +248,8 @@
         for (int i = 0; i < phi.valueCount(); i++) {
             ValueNode input = phi.valueAt(i);
             long increment = NO_INCREMENT;
-            if (input != null && input instanceof IntegerAddNode) {
-                IntegerAddNode add = (IntegerAddNode) input;
+            if (input != null && input instanceof AddNode && input.stamp() instanceof IntegerStamp) {
+                AddNode add = (AddNode) input;
                 if (add.getX() == phi && add.getY().isConstant()) {
                     increment = add.getY().asConstant().asLong();
                 } else if (add.getY() == phi && add.getX().isConstant()) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java	Wed Sep 24 16:22:22 2014 -0700
@@ -168,6 +168,8 @@
     public StructuredGraph copy(String newName, ResolvedJavaMethod newMethod) {
         StructuredGraph copy = new StructuredGraph(newName, newMethod, graphId, entryBCI);
         copy.setGuardsStage(getGuardsStage());
+        copy.isAfterFloatingReadPhase = isAfterFloatingReadPhase;
+        copy.hasValueProxies = hasValueProxies;
         HashMap<Node, Node> replacements = new HashMap<>();
         replacements.put(start, copy.start);
         copy.addDuplicates(getNodes(), this, this.getNodeCount(), replacements);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueProxyNode.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueProxyNode.java	Wed Sep 24 16:22:22 2014 -0700
@@ -28,7 +28,7 @@
 import com.oracle.graal.nodes.spi.*;
 
 @NodeInfo
-public class ValueProxyNode extends ProxyNode implements Canonicalizable, Virtualizable, ValueAndStampProxy {
+public class ValueProxyNode extends ProxyNode implements Canonicalizable, Virtualizable, ValueProxy {
 
     @Input ValueNode value;
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AddNode.java	Wed Sep 24 16:22:22 2014 -0700
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.nodes.calc;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.common.type.*;
+import com.oracle.graal.graph.spi.*;
+import com.oracle.graal.lir.gen.*;
+import com.oracle.graal.nodeinfo.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+
+@NodeInfo(shortName = "+")
+public class AddNode extends BinaryArithmeticNode implements NarrowableArithmeticNode {
+
+    public static AddNode create(ValueNode x, ValueNode y) {
+        return USE_GENERATED_NODES ? new AddNodeGen(x, y) : new AddNode(x, y);
+    }
+
+    protected AddNode(ValueNode x, ValueNode y) {
+        super(ArithmeticOpTable.forStamp(x.stamp()).getAdd(), x, y);
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
+        ValueNode ret = super.canonical(tool, forX, forY);
+        if (ret != this) {
+            return ret;
+        }
+
+        if (forX.isConstant() && !forY.isConstant()) {
+            return AddNode.create(forY, forX);
+        }
+        boolean associative = getOp().isAssociative();
+        if (associative) {
+            if (forX instanceof SubNode) {
+                SubNode sub = (SubNode) forX;
+                if (sub.getY() == forY) {
+                    // (a - b) + b
+                    return sub.getX();
+                }
+            }
+            if (forY instanceof SubNode) {
+                SubNode sub = (SubNode) forY;
+                if (sub.getY() == forX) {
+                    // b + (a - b)
+                    return sub.getX();
+                }
+            }
+        }
+        if (forY.isConstant()) {
+            Constant c = forY.asConstant();
+            if (getOp().isNeutral(c)) {
+                return forX;
+            }
+            if (associative) {
+                // canonicalize expressions like "(a + 1) + 2"
+                BinaryNode reassociated = reassociate(this, ValueNode.isConstantPredicate(), forX, forY);
+                if (reassociated != this) {
+                    return reassociated;
+                }
+            }
+        }
+        if (forX instanceof NegateNode) {
+            return BinaryArithmeticNode.sub(forY, ((NegateNode) forX).getValue());
+        } else if (forY instanceof NegateNode) {
+            return BinaryArithmeticNode.sub(forX, ((NegateNode) forY).getValue());
+        }
+        return this;
+    }
+
+    @Override
+    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
+        Value op1 = builder.operand(getX());
+        assert op1 != null : getX() + ", this=" + this;
+        Value op2 = builder.operand(getY());
+        if (!getY().isConstant() && !BinaryArithmeticNode.livesLonger(this, getY(), builder)) {
+            Value op = op1;
+            op1 = op2;
+            op2 = op;
+        }
+        builder.setResult(this, gen.emitAdd(op1, op2));
+    }
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AndNode.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AndNode.java	Wed Sep 24 16:22:22 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.nodes.calc;
 
+import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graph.spi.*;
@@ -29,58 +30,50 @@
 import com.oracle.graal.nodeinfo.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.nodes.util.*;
 
 @NodeInfo(shortName = "&")
-public class AndNode extends BitLogicNode implements NarrowableArithmeticNode {
+public class AndNode extends BinaryArithmeticNode implements NarrowableArithmeticNode {
 
     public static AndNode create(ValueNode x, ValueNode y) {
         return USE_GENERATED_NODES ? new AndNodeGen(x, y) : new AndNode(x, y);
     }
 
     AndNode(ValueNode x, ValueNode y) {
-        super(StampTool.and(x.stamp(), y.stamp()), x, y);
-        assert x.stamp().isCompatible(y.stamp());
-    }
-
-    @Override
-    public boolean inferStamp() {
-        return updateStamp(StampTool.and(getX().stamp(), getY().stamp()));
-    }
-
-    @Override
-    public Constant evalConst(Constant... inputs) {
-        assert inputs.length == 2;
-        return Constant.forPrimitiveInt(PrimitiveStamp.getBits(stamp()), inputs[0].asLong() & inputs[1].asLong());
+        super(ArithmeticOpTable.forStamp(x.stamp()).getAnd(), x, y);
     }
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
+        ValueNode ret = super.canonical(tool, forX, forY);
+        if (ret != this) {
+            return ret;
+        }
+
         if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) {
             return forX;
         }
         if (forX.isConstant() && !forY.isConstant()) {
             return AndNode.create(forY, forX);
         }
-        if (forX.isConstant()) {
-            return ConstantNode.forPrimitive(stamp(), evalConst(forX.asConstant(), forY.asConstant()));
-        } else if (forY.isConstant()) {
-            long rawY = forY.asConstant().asLong();
-            long mask = IntegerStamp.defaultMask(PrimitiveStamp.getBits(stamp()));
-            if ((rawY & mask) == mask) {
+        if (forY.isConstant()) {
+            Constant c = forY.asConstant();
+            if (getOp().isNeutral(c)) {
                 return forX;
             }
-            if ((rawY & mask) == 0) {
-                return ConstantNode.forIntegerStamp(stamp(), 0);
-            }
-            if (forX instanceof SignExtendNode) {
-                SignExtendNode ext = (SignExtendNode) forX;
-                if (rawY == ((1L << ext.getInputBits()) - 1)) {
-                    return ZeroExtendNode.create(ext.getValue(), ext.getResultBits());
+
+            if (c.getKind().isNumericInteger()) {
+                long rawY = c.asLong();
+                long mask = CodeUtil.mask(PrimitiveStamp.getBits(stamp()));
+                if ((rawY & mask) == 0) {
+                    return ConstantNode.forIntegerStamp(stamp(), 0);
                 }
-            }
-            if (forX.stamp() instanceof IntegerStamp) {
+                if (forX instanceof SignExtendNode) {
+                    SignExtendNode ext = (SignExtendNode) forX;
+                    if (rawY == ((1L << ext.getInputBits()) - 1)) {
+                        return ZeroExtendNode.create(ext.getValue(), ext.getResultBits());
+                    }
+                }
                 IntegerStamp xStamp = (IntegerStamp) forX.stamp();
                 if (((xStamp.upMask() | xStamp.downMask()) & ~rawY) == 0) {
                     // No bits are set which are outside the mask, so the mask will have no effect.
@@ -88,7 +81,7 @@
                 }
             }
 
-            return BinaryNode.reassociate(this, ValueNode.isConstantPredicate(), forX, forY);
+            return reassociate(this, ValueNode.isConstantPredicate(), forX, forY);
         }
         return this;
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BinaryArithmeticNode.java	Wed Sep 24 16:22:22 2014 -0700
@@ -0,0 +1,238 @@
+/*
+ * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.nodes.calc;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.common.*;
+import com.oracle.graal.compiler.common.type.ArithmeticOpTable.BinaryOp;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.iterators.*;
+import com.oracle.graal.graph.spi.*;
+import com.oracle.graal.nodeinfo.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+
+@NodeInfo
+public abstract class BinaryArithmeticNode extends BinaryNode implements ArithmeticLIRLowerable {
+
+    private final BinaryOp op;
+
+    public BinaryArithmeticNode(BinaryOp op, ValueNode x, ValueNode y) {
+        super(op.foldStamp(x.stamp(), y.stamp()), x, y);
+        this.op = op;
+    }
+
+    public BinaryOp getOp() {
+        return op;
+    }
+
+    @Override
+    public Constant evalConst(Constant... inputs) {
+        assert inputs.length == 2;
+        return op.foldConstant(inputs[0], inputs[1]);
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
+        if (forX.isConstant() && forY.isConstant()) {
+            Constant ret = op.foldConstant(forX.asConstant(), forY.asConstant());
+            return ConstantNode.forPrimitive(stamp(), ret);
+        }
+        return this;
+    }
+
+    @Override
+    public boolean inferStamp() {
+        return updateStamp(op.foldStamp(getX().stamp(), getY().stamp()));
+    }
+
+    public static AddNode add(StructuredGraph graph, ValueNode v1, ValueNode v2) {
+        return graph.unique(AddNode.create(v1, v2));
+    }
+
+    public static AddNode add(ValueNode v1, ValueNode v2) {
+        return AddNode.create(v1, v2);
+    }
+
+    public static MulNode mul(StructuredGraph graph, ValueNode v1, ValueNode v2) {
+        return graph.unique(MulNode.create(v1, v2));
+    }
+
+    public static MulNode mul(ValueNode v1, ValueNode v2) {
+        return MulNode.create(v1, v2);
+    }
+
+    public static SubNode sub(StructuredGraph graph, ValueNode v1, ValueNode v2) {
+        return graph.unique(SubNode.create(v1, v2));
+    }
+
+    public static SubNode sub(ValueNode v1, ValueNode v2) {
+        return SubNode.create(v1, v2);
+    }
+
+    private enum ReassociateMatch {
+        x,
+        y;
+
+        public ValueNode getValue(BinaryNode binary) {
+            switch (this) {
+                case x:
+                    return binary.getX();
+                case y:
+                    return binary.getY();
+                default:
+                    throw GraalInternalError.shouldNotReachHere();
+            }
+        }
+
+        public ValueNode getOtherValue(BinaryNode binary) {
+            switch (this) {
+                case x:
+                    return binary.getY();
+                case y:
+                    return binary.getX();
+                default:
+                    throw GraalInternalError.shouldNotReachHere();
+            }
+        }
+    }
+
+    private static ReassociateMatch findReassociate(BinaryNode binary, NodePredicate criterion) {
+        boolean resultX = criterion.apply(binary.getX());
+        boolean resultY = criterion.apply(binary.getY());
+        if (resultX && !resultY) {
+            return ReassociateMatch.x;
+        }
+        if (!resultX && resultY) {
+            return ReassociateMatch.y;
+        }
+        return null;
+    }
+
+    //@formatter:off
+    /*
+     * In reassociate, complexity comes from the handling of IntegerSub (non commutative) which can
+     * be mixed with IntegerAdd. It first tries to find m1, m2 which match the criterion :
+     * (a o m2) o m1
+     * (m2 o a) o m1
+     * m1 o (a o m2)
+     * m1 o (m2 o a)
+     * It then produces 4 boolean for the -/+ cases:
+     * invertA : should the final expression be like *-a (rather than a+*)
+     * aSub : should the final expression be like a-* (rather than a+*)
+     * invertM1 : should the final expression contain -m1
+     * invertM2 : should the final expression contain -m2
+     *
+     */
+    //@formatter:on
+    /**
+     * Tries to re-associate values which satisfy the criterion. For example with a constantness
+     * criterion: {@code (a + 2) + 1 => a + (1 + 2)}
+     * <p>
+     * This method accepts only {@linkplain BinaryOp#isAssociative() associative} operations such as
+     * +, -, *, &amp;, | and ^
+     *
+     * @param forY
+     * @param forX
+     */
+    public static BinaryArithmeticNode reassociate(BinaryArithmeticNode node, NodePredicate criterion, ValueNode forX, ValueNode forY) {
+        assert node.getOp().isAssociative();
+        ReassociateMatch match1 = findReassociate(node, criterion);
+        if (match1 == null) {
+            return node;
+        }
+        ValueNode otherValue = match1.getOtherValue(node);
+        boolean addSub = false;
+        boolean subAdd = false;
+        if (otherValue.getClass() != node.getClass()) {
+            if (node instanceof AddNode && otherValue instanceof SubNode) {
+                addSub = true;
+            } else if (node instanceof SubNode && otherValue instanceof AddNode) {
+                subAdd = true;
+            } else {
+                return node;
+            }
+        }
+        BinaryNode other = (BinaryNode) otherValue;
+        ReassociateMatch match2 = findReassociate(other, criterion);
+        if (match2 == null) {
+            return node;
+        }
+        boolean invertA = false;
+        boolean aSub = false;
+        boolean invertM1 = false;
+        boolean invertM2 = false;
+        if (addSub) {
+            invertM2 = match2 == ReassociateMatch.y;
+            invertA = !invertM2;
+        } else if (subAdd) {
+            invertA = invertM2 = match1 == ReassociateMatch.x;
+            invertM1 = !invertM2;
+        } else if (node instanceof SubNode && other instanceof SubNode) {
+            invertA = match1 == ReassociateMatch.x ^ match2 == ReassociateMatch.x;
+            aSub = match1 == ReassociateMatch.y && match2 == ReassociateMatch.y;
+            invertM1 = match1 == ReassociateMatch.y && match2 == ReassociateMatch.x;
+            invertM2 = match1 == ReassociateMatch.x && match2 == ReassociateMatch.x;
+        }
+        assert !(invertM1 && invertM2) && !(invertA && aSub);
+        ValueNode m1 = match1.getValue(node);
+        ValueNode m2 = match2.getValue(other);
+        ValueNode a = match2.getOtherValue(other);
+        if (node instanceof AddNode || node instanceof SubNode) {
+            BinaryNode associated;
+            if (invertM1) {
+                associated = BinaryArithmeticNode.sub(m2, m1);
+            } else if (invertM2) {
+                associated = BinaryArithmeticNode.sub(m1, m2);
+            } else {
+                associated = BinaryArithmeticNode.add(m1, m2);
+            }
+            if (invertA) {
+                return BinaryArithmeticNode.sub(associated, a);
+            }
+            if (aSub) {
+                return BinaryArithmeticNode.sub(a, associated);
+            }
+            return BinaryArithmeticNode.add(a, associated);
+        } else if (node instanceof MulNode) {
+            return BinaryArithmeticNode.mul(a, AddNode.mul(m1, m2));
+        } else if (node instanceof AndNode) {
+            return AndNode.create(a, AndNode.create(m1, m2));
+        } else if (node instanceof OrNode) {
+            return OrNode.create(a, OrNode.create(m1, m2));
+        } else if (node instanceof XorNode) {
+            return XorNode.create(a, XorNode.create(m1, m2));
+        } else {
+            throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    protected static boolean livesLonger(ValueNode after, ValueNode value, NodeMappableLIRBuilder builder) {
+        for (Node usage : value.usages()) {
+            if (usage != after && usage instanceof ValueNode && builder.hasOperand(((ValueNode) usage))) {
+                return true;
+            }
+        }
+        return false;
+    }
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BinaryNode.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BinaryNode.java	Wed Sep 24 16:22:22 2014 -0700
@@ -22,9 +22,7 @@
  */
 package com.oracle.graal.nodes.calc;
 
-import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.compiler.common.type.*;
-import com.oracle.graal.graph.iterators.*;
 import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodeinfo.*;
 import com.oracle.graal.nodes.*;
@@ -58,181 +56,4 @@
         this.x = x;
         this.y = y;
     }
-
-    public enum ReassociateMatch {
-        x,
-        y;
-
-        public ValueNode getValue(BinaryNode binary) {
-            switch (this) {
-                case x:
-                    return binary.getX();
-                case y:
-                    return binary.getY();
-                default:
-                    throw GraalInternalError.shouldNotReachHere();
-            }
-        }
-
-        public ValueNode getOtherValue(BinaryNode binary) {
-            switch (this) {
-                case x:
-                    return binary.getY();
-                case y:
-                    return binary.getX();
-                default:
-                    throw GraalInternalError.shouldNotReachHere();
-            }
-        }
-    }
-
-    public static BinaryNode add(StructuredGraph graph, ValueNode x, ValueNode y) {
-        assert x.stamp().isCompatible(y.stamp());
-        Stamp stamp = x.stamp();
-        if (stamp instanceof IntegerStamp) {
-            return IntegerArithmeticNode.add(graph, x, y);
-        } else if (stamp instanceof FloatStamp) {
-            return graph.unique(FloatAddNode.create(x, y, false));
-        } else {
-            throw GraalInternalError.shouldNotReachHere();
-        }
-    }
-
-    public static BinaryNode sub(StructuredGraph graph, ValueNode x, ValueNode y) {
-        assert x.stamp().isCompatible(y.stamp());
-        Stamp stamp = x.stamp();
-        if (stamp instanceof IntegerStamp) {
-            return IntegerArithmeticNode.sub(graph, x, y);
-        } else if (stamp instanceof FloatStamp) {
-            return graph.unique(FloatSubNode.create(x, y, false));
-        } else {
-            throw GraalInternalError.shouldNotReachHere();
-        }
-    }
-
-    public static BinaryNode mul(StructuredGraph graph, ValueNode x, ValueNode y) {
-        assert x.stamp().isCompatible(y.stamp());
-        Stamp stamp = x.stamp();
-        if (stamp instanceof IntegerStamp) {
-            return IntegerArithmeticNode.mul(graph, x, y);
-        } else if (stamp instanceof FloatStamp) {
-            return graph.unique(FloatMulNode.create(x, y, false));
-        } else {
-            throw GraalInternalError.shouldNotReachHere();
-        }
-    }
-
-    public static boolean canTryReassociate(BinaryNode node) {
-        return node instanceof IntegerAddNode || node instanceof IntegerSubNode || node instanceof IntegerMulNode || node instanceof AndNode || node instanceof OrNode || node instanceof XorNode;
-    }
-
-    public static ReassociateMatch findReassociate(BinaryNode binary, NodePredicate criterion) {
-        boolean resultX = criterion.apply(binary.getX());
-        boolean resultY = criterion.apply(binary.getY());
-        if (resultX && !resultY) {
-            return ReassociateMatch.x;
-        }
-        if (!resultX && resultY) {
-            return ReassociateMatch.y;
-        }
-        return null;
-    }
-
-    //@formatter:off
-    /*
-     * In reassociate, complexity comes from the handling of IntegerSub (non commutative) which can
-     * be mixed with IntegerAdd. It first tries to find m1, m2 which match the criterion :
-     * (a o m2) o m1
-     * (m2 o a) o m1
-     * m1 o (a o m2)
-     * m1 o (m2 o a)
-     * It then produces 4 boolean for the -/+ cases:
-     * invertA : should the final expression be like *-a (rather than a+*)
-     * aSub : should the final expression be like a-* (rather than a+*)
-     * invertM1 : should the final expression contain -m1
-     * invertM2 : should the final expression contain -m2
-     *
-     */
-    //@formatter:on
-    /**
-     * Tries to re-associate values which satisfy the criterion. For example with a constantness
-     * criterion: {@code (a + 2) + 1 => a + (1 + 2)}
-     * <p>
-     * This method accepts only {@linkplain #canTryReassociate(BinaryNode) reassociable} operations
-     * such as +, -, *, &amp;, | and ^
-     *
-     * @param forY
-     * @param forX
-     */
-    public static BinaryNode reassociate(BinaryNode node, NodePredicate criterion, ValueNode forX, ValueNode forY) {
-        assert canTryReassociate(node);
-        ReassociateMatch match1 = findReassociate(node, criterion);
-        if (match1 == null) {
-            return node;
-        }
-        ValueNode otherValue = match1.getOtherValue(node);
-        boolean addSub = false;
-        boolean subAdd = false;
-        if (otherValue.getClass() != node.getClass()) {
-            if (node instanceof IntegerAddNode && otherValue instanceof IntegerSubNode) {
-                addSub = true;
-            } else if (node instanceof IntegerSubNode && otherValue instanceof IntegerAddNode) {
-                subAdd = true;
-            } else {
-                return node;
-            }
-        }
-        BinaryNode other = (BinaryNode) otherValue;
-        ReassociateMatch match2 = findReassociate(other, criterion);
-        if (match2 == null) {
-            return node;
-        }
-        boolean invertA = false;
-        boolean aSub = false;
-        boolean invertM1 = false;
-        boolean invertM2 = false;
-        if (addSub) {
-            invertM2 = match2 == ReassociateMatch.y;
-            invertA = !invertM2;
-        } else if (subAdd) {
-            invertA = invertM2 = match1 == ReassociateMatch.x;
-            invertM1 = !invertM2;
-        } else if (node instanceof IntegerSubNode && other instanceof IntegerSubNode) {
-            invertA = match1 == ReassociateMatch.x ^ match2 == ReassociateMatch.x;
-            aSub = match1 == ReassociateMatch.y && match2 == ReassociateMatch.y;
-            invertM1 = match1 == ReassociateMatch.y && match2 == ReassociateMatch.x;
-            invertM2 = match1 == ReassociateMatch.x && match2 == ReassociateMatch.x;
-        }
-        assert !(invertM1 && invertM2) && !(invertA && aSub);
-        ValueNode m1 = match1.getValue(node);
-        ValueNode m2 = match2.getValue(other);
-        ValueNode a = match2.getOtherValue(other);
-        if (node instanceof IntegerAddNode || node instanceof IntegerSubNode) {
-            BinaryNode associated;
-            if (invertM1) {
-                associated = IntegerArithmeticNode.sub(m2, m1);
-            } else if (invertM2) {
-                associated = IntegerArithmeticNode.sub(m1, m2);
-            } else {
-                associated = IntegerArithmeticNode.add(m1, m2);
-            }
-            if (invertA) {
-                return IntegerArithmeticNode.sub(associated, a);
-            }
-            if (aSub) {
-                return IntegerArithmeticNode.sub(a, associated);
-            }
-            return IntegerArithmeticNode.add(a, associated);
-        } else if (node instanceof IntegerMulNode) {
-            return IntegerArithmeticNode.mul(a, IntegerAddNode.mul(m1, m2));
-        } else if (node instanceof AndNode) {
-            return BitLogicNode.and(a, BitLogicNode.and(m1, m2));
-        } else if (node instanceof OrNode) {
-            return BitLogicNode.or(a, BitLogicNode.or(m1, m2));
-        } else if (node instanceof XorNode) {
-            return BitLogicNode.xor(a, BitLogicNode.xor(m1, m2));
-        } else {
-            throw GraalInternalError.shouldNotReachHere();
-        }
-    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BitLogicNode.java	Wed Sep 24 16:13:34 2014 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.nodes.calc;
-
-import com.oracle.graal.compiler.common.type.*;
-import com.oracle.graal.nodeinfo.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
-
-/**
- * The {@code LogicNode} class definition.
- */
-@NodeInfo
-public abstract class BitLogicNode extends BinaryNode implements ArithmeticLIRLowerable, NarrowableArithmeticNode {
-
-    /**
-     * Constructs a new logic operation node.
-     *
-     * @param x the first input into this node
-     * @param y the second input into this node
-     */
-    public BitLogicNode(Stamp stamp, ValueNode x, ValueNode y) {
-        super(stamp, x, y);
-        assert stamp instanceof IntegerStamp;
-    }
-
-    public static BitLogicNode and(StructuredGraph graph, ValueNode v1, ValueNode v2) {
-        return graph.unique(AndNode.create(v1, v2));
-    }
-
-    public static BitLogicNode and(ValueNode v1, ValueNode v2) {
-        return AndNode.create(v1, v2);
-    }
-
-    public static BitLogicNode or(StructuredGraph graph, ValueNode v1, ValueNode v2) {
-        return graph.unique(OrNode.create(v1, v2));
-    }
-
-    public static BitLogicNode or(ValueNode v1, ValueNode v2) {
-        return OrNode.create(v1, v2);
-    }
-
-    public static BitLogicNode xor(StructuredGraph graph, ValueNode v1, ValueNode v2) {
-        return graph.unique(XorNode.create(v1, v2));
-    }
-
-    public static BitLogicNode xor(ValueNode v1, ValueNode v2) {
-        return XorNode.create(v1, v2);
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/DivNode.java	Wed Sep 24 16:22:22 2014 -0700
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.nodes.calc;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.common.type.*;
+import com.oracle.graal.graph.spi.*;
+import com.oracle.graal.lir.gen.*;
+import com.oracle.graal.nodeinfo.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+
+@NodeInfo(shortName = "/")
+public class DivNode extends BinaryArithmeticNode {
+
+    public static DivNode create(ValueNode x, ValueNode y) {
+        return USE_GENERATED_NODES ? new DivNodeGen(x, y) : new DivNode(x, y);
+    }
+
+    protected DivNode(ValueNode x, ValueNode y) {
+        super(ArithmeticOpTable.forStamp(x.stamp()).getDiv(), x, y);
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
+        ValueNode ret = super.canonical(tool, forX, forY);
+        if (ret != this) {
+            return ret;
+        }
+
+        if (forY.isConstant()) {
+            Constant c = forY.asConstant();
+            if (getOp().isNeutral(c)) {
+                return forX;
+            }
+        }
+        return this;
+    }
+
+    @Override
+    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
+        builder.setResult(this, gen.emitDiv(builder.operand(getX()), builder.operand(getY()), null));
+    }
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatAddNode.java	Wed Sep 24 16:13:34 2014 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,118 +0,0 @@
-/*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.nodes.calc;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.graph.spi.*;
-import com.oracle.graal.lir.gen.*;
-import com.oracle.graal.nodeinfo.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
-
-@NodeInfo(shortName = "+")
-public class FloatAddNode extends FloatArithmeticNode {
-
-    public static FloatAddNode create(ValueNode x, ValueNode y, boolean isStrictFP) {
-        return USE_GENERATED_NODES ? new FloatAddNodeGen(x, y, isStrictFP) : new FloatAddNode(x, y, isStrictFP);
-    }
-
-    protected FloatAddNode(ValueNode x, ValueNode y, boolean isStrictFP) {
-        super(x.stamp().unrestricted(), x, y, isStrictFP);
-    }
-
-    public Constant evalConst(Constant... inputs) {
-        assert inputs.length == 2;
-        assert inputs[0].getKind() == inputs[1].getKind();
-        if (inputs[0].getKind() == Kind.Float) {
-            return Constant.forFloat(inputs[0].asFloat() + inputs[1].asFloat());
-        } else {
-            assert inputs[0].getKind() == Kind.Double;
-            return Constant.forDouble(inputs[0].asDouble() + inputs[1].asDouble());
-        }
-    }
-
-    @Override
-    public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
-        if (forX.isConstant() && !forY.isConstant()) {
-            return FloatAddNode.create(forY, forX, isStrictFP());
-        }
-        if (forX.isConstant()) {
-            return ConstantNode.forConstant(evalConst(forX.asConstant(), forY.asConstant()), null);
-        }
-        // Constant 0.0 can't be eliminated since it can affect the sign of the result.
-        // Constant -0.0 is an additive identity.
-        if (forY.isConstant()) {
-            @SuppressWarnings("hiding")
-            Constant y = forY.asConstant();
-            switch (y.getKind()) {
-                case Float:
-                    // use Float.compare because -0.0f == 0.0f
-                    if (Float.compare(y.asFloat(), -0.0f) == 0) {
-                        return forX;
-                    }
-                    break;
-                case Double:
-                    // use Double.compare because -0.0 == 0.0
-                    if (Double.compare(y.asDouble(), -0.0) == 0) {
-                        return forX;
-                    }
-                    break;
-                default:
-                    throw GraalGraphInternalError.shouldNotReachHere();
-            }
-        }
-        /*
-         * JVM spec, Chapter 6, dsub/fsub bytecode: For double subtraction, it is always the case
-         * that a-b produces the same result as a+(-b).
-         */
-        if (forX instanceof NegateNode) {
-            return FloatSubNode.create(forY, ((NegateNode) forX).getValue(), isStrictFP());
-        }
-        if (forY instanceof NegateNode) {
-            return FloatSubNode.create(forX, ((NegateNode) forY).getValue(), isStrictFP());
-        }
-        return this;
-    }
-
-    @Override
-    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
-        Value op1 = builder.operand(getX());
-        Value op2 = builder.operand(getY());
-        if (!getY().isConstant() && !livesLonger(this, getY(), builder)) {
-            Value op = op1;
-            op1 = op2;
-            op2 = op;
-        }
-        builder.setResult(this, gen.emitAdd(op1, op2));
-    }
-
-    public static boolean livesLonger(ValueNode after, ValueNode value, NodeMappableLIRBuilder builder) {
-        for (Node usage : value.usages()) {
-            if (usage != after && usage instanceof ValueNode && builder.hasOperand(((ValueNode) usage))) {
-                return true;
-            }
-        }
-        return false;
-    }
-}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatArithmeticNode.java	Wed Sep 24 16:13:34 2014 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.nodes.calc;
-
-import com.oracle.graal.compiler.common.type.*;
-import com.oracle.graal.nodeinfo.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
-
-@NodeInfo
-public abstract class FloatArithmeticNode extends BinaryNode implements ArithmeticLIRLowerable {
-
-    private final boolean isStrictFP;
-
-    public FloatArithmeticNode(Stamp stamp, ValueNode x, ValueNode y, boolean isStrictFP) {
-        super(stamp, x, y);
-        assert stamp instanceof FloatStamp;
-        this.isStrictFP = isStrictFP;
-    }
-
-    /**
-     * Checks whether this instruction has strict fp semantics.
-     * 
-     * @return {@code true} if this instruction has strict fp semantics
-     */
-    public boolean isStrictFP() {
-        return isStrictFP;
-    }
-}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatDivNode.java	Wed Sep 24 16:13:34 2014 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
-/*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.nodes.calc;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.graph.spi.*;
-import com.oracle.graal.lir.gen.*;
-import com.oracle.graal.nodeinfo.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
-
-@NodeInfo(shortName = "/")
-public class FloatDivNode extends FloatArithmeticNode {
-
-    public static FloatDivNode create(ValueNode x, ValueNode y, boolean isStrictFP) {
-        return USE_GENERATED_NODES ? new FloatDivNodeGen(x, y, isStrictFP) : new FloatDivNode(x, y, isStrictFP);
-    }
-
-    protected FloatDivNode(ValueNode x, ValueNode y, boolean isStrictFP) {
-        super(x.stamp().unrestricted(), x, y, isStrictFP);
-    }
-
-    public Constant evalConst(Constant... inputs) {
-        assert inputs.length == 2;
-        assert inputs[0].getKind() == inputs[1].getKind();
-        if (inputs[0].getKind() == Kind.Float) {
-            return Constant.forFloat(inputs[0].asFloat() / inputs[1].asFloat());
-        } else {
-            assert inputs[0].getKind() == Kind.Double;
-            return Constant.forDouble(inputs[0].asDouble() / inputs[1].asDouble());
-        }
-    }
-
-    @Override
-    public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
-        if (forX.isConstant() && forY.isConstant()) {
-            return ConstantNode.forPrimitive(evalConst(forX.asConstant(), forY.asConstant()));
-        }
-        if (forY.isConstant()) {
-            @SuppressWarnings("hiding")
-            Constant y = forY.asConstant();
-            switch (y.getKind()) {
-                case Float:
-                    if (y.asFloat() == 1.0f) {
-                        return forX;
-                    }
-                    break;
-                case Double:
-                    if (y.asDouble() == 1.0) {
-                        return forX;
-                    }
-                    break;
-                default:
-                    throw GraalGraphInternalError.shouldNotReachHere();
-            }
-        }
-        return this;
-    }
-
-    @Override
-    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
-        builder.setResult(this, gen.emitDiv(builder.operand(getX()), builder.operand(getY()), null));
-    }
-}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatMulNode.java	Wed Sep 24 16:13:34 2014 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +0,0 @@
-/*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.nodes.calc;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.graph.spi.*;
-import com.oracle.graal.lir.gen.*;
-import com.oracle.graal.nodeinfo.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
-
-@NodeInfo(shortName = "*")
-public class FloatMulNode extends FloatArithmeticNode {
-
-    public static FloatMulNode create(ValueNode x, ValueNode y, boolean isStrictFP) {
-        return USE_GENERATED_NODES ? new FloatMulNodeGen(x, y, isStrictFP) : new FloatMulNode(x, y, isStrictFP);
-    }
-
-    protected FloatMulNode(ValueNode x, ValueNode y, boolean isStrictFP) {
-        super(x.stamp().unrestricted(), x, y, isStrictFP);
-    }
-
-    public Constant evalConst(Constant... inputs) {
-        assert inputs.length == 2;
-        assert inputs[0].getKind() == inputs[1].getKind();
-        if (inputs[0].getKind() == Kind.Float) {
-            return Constant.forFloat(inputs[0].asFloat() * inputs[1].asFloat());
-        } else {
-            assert inputs[0].getKind() == Kind.Double;
-            return Constant.forDouble(inputs[0].asDouble() * inputs[1].asDouble());
-        }
-    }
-
-    @Override
-    public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
-        if (forX.isConstant() && !forY.isConstant()) {
-            return FloatMulNode.create(forY, forX, isStrictFP());
-        }
-        if (forX.isConstant()) {
-            return ConstantNode.forPrimitive(evalConst(forX.asConstant(), forY.asConstant()));
-        }
-        if (forY.isConstant()) {
-            @SuppressWarnings("hiding")
-            Constant y = forY.asConstant();
-            switch (y.getKind()) {
-                case Float:
-                    if (y.asFloat() == 1.0f) {
-                        return forX;
-                    }
-                    break;
-                case Double:
-                    if (y.asDouble() == 1.0) {
-                        return forX;
-                    }
-                    break;
-                default:
-                    throw GraalGraphInternalError.shouldNotReachHere();
-            }
-        }
-        return this;
-    }
-
-    @Override
-    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
-        Value op1 = builder.operand(getX());
-        Value op2 = builder.operand(getY());
-        if (!getY().isConstant() && !FloatAddNode.livesLonger(this, getY(), builder)) {
-            Value op = op1;
-            op1 = op2;
-            op2 = op;
-        }
-        builder.setResult(this, gen.emitMul(op1, op2));
-    }
-}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatRemNode.java	Wed Sep 24 16:13:34 2014 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-/*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.nodes.calc;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.spi.*;
-import com.oracle.graal.lir.gen.*;
-import com.oracle.graal.nodeinfo.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
-
-@NodeInfo(shortName = "%")
-public class FloatRemNode extends FloatArithmeticNode implements Lowerable {
-
-    public static FloatRemNode create(ValueNode x, ValueNode y, boolean isStrictFP) {
-        return USE_GENERATED_NODES ? new FloatRemNodeGen(x, y, isStrictFP) : new FloatRemNode(x, y, isStrictFP);
-    }
-
-    protected FloatRemNode(ValueNode x, ValueNode y, boolean isStrictFP) {
-        super(x.stamp().unrestricted(), x, y, isStrictFP);
-    }
-
-    public Constant evalConst(Constant... inputs) {
-        assert inputs.length == 2;
-        assert inputs[0].getKind() == inputs[1].getKind();
-        if (inputs[0].getKind() == Kind.Float) {
-            return Constant.forFloat(inputs[0].asFloat() % inputs[1].asFloat());
-        } else {
-            assert inputs[0].getKind() == Kind.Double;
-            return Constant.forDouble(inputs[0].asDouble() % inputs[1].asDouble());
-        }
-    }
-
-    @Override
-    public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
-        if (forX.isConstant() && forY.isConstant()) {
-            return ConstantNode.forPrimitive(evalConst(forX.asConstant(), forY.asConstant()));
-        }
-        return this;
-    }
-
-    @Override
-    public void lower(LoweringTool tool) {
-        tool.getLowerer().lower(this, tool);
-    }
-
-    @Override
-    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
-        builder.setResult(this, gen.emitRem(builder.operand(getX()), builder.operand(getY()), null));
-    }
-}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatSubNode.java	Wed Sep 24 16:13:34 2014 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,119 +0,0 @@
-/*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.nodes.calc;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.graph.spi.*;
-import com.oracle.graal.lir.gen.*;
-import com.oracle.graal.nodeinfo.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.util.*;
-
-@NodeInfo(shortName = "-")
-public class FloatSubNode extends FloatArithmeticNode {
-
-    public static FloatSubNode create(ValueNode x, ValueNode y, boolean isStrictFP) {
-        return USE_GENERATED_NODES ? new FloatSubNodeGen(x, y, isStrictFP) : new FloatSubNode(x, y, isStrictFP);
-    }
-
-    protected FloatSubNode(ValueNode x, ValueNode y, boolean isStrictFP) {
-        super(x.stamp().unrestricted(), x, y, isStrictFP);
-    }
-
-    public Constant evalConst(Constant... inputs) {
-        assert inputs.length == 2;
-        assert inputs[0].getKind() == inputs[1].getKind();
-        if (inputs[0].getKind() == Kind.Float) {
-            return Constant.forFloat(inputs[0].asFloat() - inputs[1].asFloat());
-        } else {
-            assert inputs[0].getKind() == Kind.Double;
-            return Constant.forDouble(inputs[0].asDouble() - inputs[1].asDouble());
-        }
-    }
-
-    @Override
-    public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
-        if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) {
-            return ConstantNode.forFloatingStamp(stamp(), 0.0f);
-        }
-        if (forX.isConstant() && forY.isConstant()) {
-            return ConstantNode.forPrimitive(evalConst(forX.asConstant(), forY.asConstant()));
-        }
-        // Constant -0.0 is an additive identity, so (-0.0) - x == (-0.0) + (-x) == -x.
-        if (forX.isConstant()) {
-            @SuppressWarnings("hiding")
-            Constant x = forX.asConstant();
-            switch (x.getKind()) {
-                case Float:
-                    if (Float.compare(x.asFloat(), -0.0f) == 0) {
-                        return NegateNode.create(forY);
-                    }
-                    break;
-                case Double:
-                    if (Double.compare(x.asDouble(), -0.0) == 0) {
-                        return NegateNode.create(forY);
-                    }
-                    break;
-                default:
-                    throw GraalGraphInternalError.shouldNotReachHere();
-            }
-        }
-        // Constant -0.0 can't be eliminated since it can affect the sign of the result.
-        // Constant 0.0 is a subtractive identity.
-        if (forY.isConstant()) {
-            @SuppressWarnings("hiding")
-            Constant y = forY.asConstant();
-            switch (y.getKind()) {
-                case Float:
-                    // use Float.compare because -0.0f == 0.0f
-                    if (Float.compare(y.asFloat(), 0.0f) == 0) {
-                        return forX;
-                    }
-                    break;
-                case Double:
-                    // use Double.compare because -0.0 == 0.0
-                    if (Double.compare(y.asDouble(), 0.0) == 0) {
-                        return forX;
-                    }
-                    break;
-                default:
-                    throw GraalGraphInternalError.shouldNotReachHere();
-            }
-        }
-        /*
-         * JVM spec, Chapter 6, dsub/fsub bytecode: For double subtraction, it is always the case
-         * that a-b produces the same result as a+(-b).
-         */
-        if (forY instanceof NegateNode) {
-            return FloatAddNode.create(forX, ((NegateNode) forY).getValue(), isStrictFP());
-        }
-        return this;
-    }
-
-    @Override
-    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
-        builder.setResult(this, gen.emitSub(builder.operand(getX()), builder.operand(getY())));
-    }
-}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerAddNode.java	Wed Sep 24 16:13:34 2014 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,108 +0,0 @@
-/*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.nodes.calc;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.compiler.common.type.*;
-import com.oracle.graal.graph.spi.*;
-import com.oracle.graal.lir.gen.*;
-import com.oracle.graal.nodeinfo.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.type.*;
-
-@NodeInfo(shortName = "+")
-public class IntegerAddNode extends IntegerArithmeticNode implements NarrowableArithmeticNode {
-
-    public static IntegerAddNode create(ValueNode x, ValueNode y) {
-        return USE_GENERATED_NODES ? new IntegerAddNodeGen(x, y) : new IntegerAddNode(x, y);
-    }
-
-    protected IntegerAddNode(ValueNode x, ValueNode y) {
-        super(StampTool.add(x.stamp(), y.stamp()), x, y);
-    }
-
-    @Override
-    public boolean inferStamp() {
-        return updateStamp(StampTool.add(getX().stamp(), getY().stamp()));
-    }
-
-    @Override
-    public Constant evalConst(Constant... inputs) {
-        assert inputs.length == 2;
-        return Constant.forPrimitiveInt(PrimitiveStamp.getBits(stamp()), inputs[0].asLong() + inputs[1].asLong());
-    }
-
-    @Override
-    public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
-        if (forX.isConstant() && !forY.isConstant()) {
-            return IntegerAddNode.create(forY, forX);
-        }
-        if (forX instanceof IntegerSubNode) {
-            IntegerSubNode sub = (IntegerSubNode) forX;
-            if (sub.getY() == forY) {
-                // (a - b) + b
-                return sub.getX();
-            }
-        }
-        if (forY instanceof IntegerSubNode) {
-            IntegerSubNode sub = (IntegerSubNode) forY;
-            if (sub.getY() == forX) {
-                // b + (a - b)
-                return sub.getX();
-            }
-        }
-        if (forX.isConstant()) {
-            return ConstantNode.forPrimitive(evalConst(forX.asConstant(), forY.asConstant()));
-        } else if (forY.isConstant()) {
-            long c = forY.asConstant().asLong();
-            if (c == 0) {
-                return forX;
-            }
-            // canonicalize expressions like "(a + 1) + 2"
-            BinaryNode reassociated = BinaryNode.reassociate(this, ValueNode.isConstantPredicate(), forX, forY);
-            if (reassociated != this) {
-                return reassociated;
-            }
-        }
-        if (forX instanceof NegateNode) {
-            return IntegerArithmeticNode.sub(forY, ((NegateNode) forX).getValue());
-        } else if (forY instanceof NegateNode) {
-            return IntegerArithmeticNode.sub(forX, ((NegateNode) forY).getValue());
-        }
-        return this;
-    }
-
-    @Override
-    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
-        Value op1 = builder.operand(getX());
-        assert op1 != null : getX() + ", this=" + this;
-        Value op2 = builder.operand(getY());
-        if (!getY().isConstant() && !FloatAddNode.livesLonger(this, getY(), builder)) {
-            Value op = op1;
-            op1 = op2;
-            op2 = op;
-        }
-        builder.setResult(this, gen.emitAdd(op1, op2));
-    }
-}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerArithmeticNode.java	Wed Sep 24 16:13:34 2014 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.nodes.calc;
-
-import com.oracle.graal.compiler.common.type.*;
-import com.oracle.graal.nodeinfo.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
-
-@NodeInfo
-public abstract class IntegerArithmeticNode extends BinaryNode implements ArithmeticLIRLowerable {
-
-    public IntegerArithmeticNode(Stamp stamp, ValueNode x, ValueNode y) {
-        super(stamp, x, y);
-        assert stamp instanceof IntegerStamp;
-    }
-
-    public static IntegerAddNode add(StructuredGraph graph, ValueNode v1, ValueNode v2) {
-        return graph.unique(IntegerAddNode.create(v1, v2));
-    }
-
-    public static IntegerAddNode add(ValueNode v1, ValueNode v2) {
-        return IntegerAddNode.create(v1, v2);
-    }
-
-    public static IntegerMulNode mul(StructuredGraph graph, ValueNode v1, ValueNode v2) {
-        return graph.unique(IntegerMulNode.create(v1, v2));
-    }
-
-    public static IntegerMulNode mul(ValueNode v1, ValueNode v2) {
-        return IntegerMulNode.create(v1, v2);
-    }
-
-    public static IntegerSubNode sub(StructuredGraph graph, ValueNode v1, ValueNode v2) {
-        return graph.unique(IntegerSubNode.create(v1, v2));
-    }
-
-    public static IntegerSubNode sub(ValueNode v1, ValueNode v2) {
-        return IntegerSubNode.create(v1, v2);
-    }
-}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerConvertNode.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerConvertNode.java	Wed Sep 24 16:22:22 2014 -0700
@@ -52,14 +52,6 @@
         }
     }
 
-    public static long convert(long value, int bits, boolean unsigned) {
-        if (unsigned) {
-            return ZeroExtendNode.zeroExtend(value, bits);
-        } else {
-            return SignExtendNode.signExtend(value, bits);
-        }
-    }
-
     protected ValueNode canonicalConvert(@SuppressWarnings("hiding") ValueNode value) {
         if (value.stamp() instanceof IntegerStamp) {
             int inputBits = ((IntegerStamp) value.stamp()).getBits();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerDivNode.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerDivNode.java	Wed Sep 24 16:22:22 2014 -0700
@@ -29,7 +29,6 @@
 import com.oracle.graal.nodeinfo.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.type.*;
 
 @NodeInfo(shortName = "/")
 public class IntegerDivNode extends FixedBinaryNode implements Lowerable, LIRLowerable {
@@ -39,12 +38,12 @@
     }
 
     protected IntegerDivNode(ValueNode x, ValueNode y) {
-        super(StampTool.div(x.stamp(), y.stamp()), x, y);
+        super(IntegerStamp.OPS.getDiv().foldStamp(x.stamp(), y.stamp()), x, y);
     }
 
     @Override
     public boolean inferStamp() {
-        return updateStamp(StampTool.div(getX().stamp(), getY().stamp()));
+        return updateStamp(IntegerStamp.OPS.getDiv().foldStamp(getX().stamp(), getY().stamp()));
     }
 
     @Override
@@ -74,7 +73,7 @@
                     int bits = PrimitiveStamp.getBits(stamp());
                     RightShiftNode sign = RightShiftNode.create(forX, ConstantNode.forInt(bits - 1));
                     UnsignedRightShiftNode round = UnsignedRightShiftNode.create(sign, ConstantNode.forInt(bits - log2));
-                    dividend = IntegerArithmeticNode.add(dividend, round);
+                    dividend = BinaryArithmeticNode.add(dividend, round);
                 }
                 RightShiftNode shift = RightShiftNode.create(dividend, ConstantNode.forInt(log2));
                 if (c < 0) {
@@ -85,8 +84,8 @@
         }
 
         // Convert the expression ((a - a % b) / b) into (a / b).
-        if (forX instanceof IntegerSubNode) {
-            IntegerSubNode integerSubNode = (IntegerSubNode) forX;
+        if (forX instanceof SubNode) {
+            SubNode integerSubNode = (SubNode) forX;
             if (integerSubNode.getY() instanceof IntegerRemNode) {
                 IntegerRemNode integerRemNode = (IntegerRemNode) integerSubNode.getY();
                 if (integerSubNode.stamp().isCompatible(this.stamp()) && integerRemNode.stamp().isCompatible(this.stamp()) && integerSubNode.getX() == integerRemNode.getX() &&
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerMulNode.java	Wed Sep 24 16:13:34 2014 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,93 +0,0 @@
-/*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.nodes.calc;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.compiler.common.type.*;
-import com.oracle.graal.graph.spi.*;
-import com.oracle.graal.lir.gen.*;
-import com.oracle.graal.nodeinfo.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
-
-@NodeInfo(shortName = "*")
-public class IntegerMulNode extends IntegerArithmeticNode implements NarrowableArithmeticNode {
-
-    public static IntegerMulNode create(ValueNode x, ValueNode y) {
-        return USE_GENERATED_NODES ? new IntegerMulNodeGen(x, y) : new IntegerMulNode(x, y);
-    }
-
-    protected IntegerMulNode(ValueNode x, ValueNode y) {
-        super(x.stamp().unrestricted(), x, y);
-        assert x.stamp().isCompatible(y.stamp());
-    }
-
-    @Override
-    public Constant evalConst(Constant... inputs) {
-        assert inputs.length == 2;
-        return Constant.forPrimitiveInt(PrimitiveStamp.getBits(stamp()), inputs[0].asLong() * inputs[1].asLong());
-    }
-
-    @Override
-    public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
-        if (forX.isConstant() && !forY.isConstant()) {
-            return IntegerMulNode.create(forY, forX);
-        }
-        if (forX.isConstant()) {
-            return ConstantNode.forPrimitive(evalConst(forX.asConstant(), forY.asConstant()));
-        } else if (forY.isConstant()) {
-            long c = forY.asConstant().asLong();
-            if (c == 1) {
-                return forX;
-            }
-            if (c == 0) {
-                return ConstantNode.forIntegerStamp(stamp(), 0);
-            }
-            long abs = Math.abs(c);
-            if (abs > 0 && CodeUtil.isPowerOf2(abs)) {
-                LeftShiftNode shift = LeftShiftNode.create(forX, ConstantNode.forInt(CodeUtil.log2(abs)));
-                if (c < 0) {
-                    return NegateNode.create(shift);
-                } else {
-                    return shift;
-                }
-            }
-            // canonicalize expressions like "(a * 1) * 2"
-            return BinaryNode.reassociate(this, ValueNode.isConstantPredicate(), forX, forY);
-        }
-        return this;
-    }
-
-    @Override
-    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
-        Value op1 = builder.operand(getX());
-        Value op2 = builder.operand(getY());
-        if (!getY().isConstant() && !FloatAddNode.livesLonger(this, getY(), builder)) {
-            Value op = op1;
-            op1 = op2;
-            op2 = op;
-        }
-        builder.setResult(this, gen.emitMul(op1, op2));
-    }
-}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerRemNode.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerRemNode.java	Wed Sep 24 16:22:22 2014 -0700
@@ -28,7 +28,6 @@
 import com.oracle.graal.nodeinfo.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.type.*;
 
 @NodeInfo(shortName = "%")
 public class IntegerRemNode extends FixedBinaryNode implements Lowerable, LIRLowerable {
@@ -38,12 +37,12 @@
     }
 
     protected IntegerRemNode(ValueNode x, ValueNode y) {
-        super(StampTool.rem(x.stamp(), y.stamp()), x, y);
+        super(IntegerStamp.OPS.getRem().foldStamp(x.stamp(), y.stamp()), x, y);
     }
 
     @Override
     public boolean inferStamp() {
-        return updateStamp(StampTool.rem(getX().stamp(), getY().stamp()));
+        return updateStamp(IntegerStamp.OPS.getRem().foldStamp(getX().stamp(), getY().stamp()));
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerSubNode.java	Wed Sep 24 16:13:34 2014 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,130 +0,0 @@
-/*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.nodes.calc;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.compiler.common.type.*;
-import com.oracle.graal.graph.spi.*;
-import com.oracle.graal.lir.gen.*;
-import com.oracle.graal.nodeinfo.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.type.*;
-import com.oracle.graal.nodes.util.*;
-
-@NodeInfo(shortName = "-")
-public class IntegerSubNode extends IntegerArithmeticNode implements NarrowableArithmeticNode {
-
-    public static IntegerSubNode create(ValueNode x, ValueNode y) {
-        return USE_GENERATED_NODES ? new IntegerSubNodeGen(x, y) : new IntegerSubNode(x, y);
-    }
-
-    protected IntegerSubNode(ValueNode x, ValueNode y) {
-        super(StampTool.sub(x.stamp(), y.stamp()), x, y);
-    }
-
-    @Override
-    public boolean inferStamp() {
-        return updateStamp(StampTool.sub(getX().stamp(), getY().stamp()));
-    }
-
-    @Override
-    public Constant evalConst(Constant... inputs) {
-        assert inputs.length == 2;
-        return Constant.forPrimitiveInt(PrimitiveStamp.getBits(stamp()), inputs[0].asLong() - inputs[1].asLong());
-    }
-
-    @SuppressWarnings("hiding")
-    @Override
-    public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
-        if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) {
-            return ConstantNode.forIntegerStamp(stamp(), 0);
-        }
-        if (forX instanceof IntegerAddNode) {
-            IntegerAddNode x = (IntegerAddNode) forX;
-            if (x.getY() == forY) {
-                // (a + b) - b
-                return x.getX();
-            }
-            if (x.getX() == forY) {
-                // (a + b) - a
-                return x.getY();
-            }
-        } else if (forX instanceof IntegerSubNode) {
-            IntegerSubNode x = (IntegerSubNode) forX;
-            if (x.getX() == forY) {
-                // (a - b) - a
-                return NegateNode.create(x.getY());
-            }
-        }
-        if (forY instanceof IntegerAddNode) {
-            IntegerAddNode y = (IntegerAddNode) forY;
-            if (y.getX() == forX) {
-                // a - (a + b)
-                return NegateNode.create(y.getY());
-            }
-            if (y.getY() == forX) {
-                // b - (a + b)
-                return NegateNode.create(y.getX());
-            }
-        } else if (forY instanceof IntegerSubNode) {
-            IntegerSubNode y = (IntegerSubNode) forY;
-            if (y.getX() == forX) {
-                // a - (a - b)
-                return y.getY();
-            }
-        }
-        if (forX.isConstant() && forY.isConstant()) {
-            return ConstantNode.forPrimitive(evalConst(forX.asConstant(), forY.asConstant()));
-        } else if (forY.isConstant()) {
-            long c = forY.asConstant().asLong();
-            if (c == 0) {
-                return forX;
-            }
-            BinaryNode reassociated = BinaryNode.reassociate(this, ValueNode.isConstantPredicate(), forX, forY);
-            if (reassociated != this) {
-                return reassociated;
-            }
-            if (c < 0 || ((IntegerStamp) StampFactory.forKind(forY.getKind())).contains(-c)) {
-                // Adding a negative is more friendly to the backend since adds are
-                // commutative, so prefer add when it fits.
-                return IntegerArithmeticNode.add(forX, ConstantNode.forIntegerStamp(stamp(), -c));
-            }
-        } else if (forX.isConstant()) {
-            long c = forX.asConstant().asLong();
-            if (c == 0) {
-                return NegateNode.create(forY);
-            }
-            return BinaryNode.reassociate(this, ValueNode.isConstantPredicate(), forX, forY);
-        }
-        if (forY instanceof NegateNode) {
-            return IntegerArithmeticNode.add(forX, ((NegateNode) forY).getValue());
-        }
-        return this;
-    }
-
-    @Override
-    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
-        builder.setResult(this, gen.emitSub(builder.operand(getX()), builder.operand(getY())));
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/MulNode.java	Wed Sep 24 16:22:22 2014 -0700
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.nodes.calc;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.common.type.*;
+import com.oracle.graal.graph.spi.*;
+import com.oracle.graal.lir.gen.*;
+import com.oracle.graal.nodeinfo.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+
+@NodeInfo(shortName = "*")
+public class MulNode extends BinaryArithmeticNode implements NarrowableArithmeticNode {
+
+    public static MulNode create(ValueNode x, ValueNode y) {
+        return USE_GENERATED_NODES ? new MulNodeGen(x, y) : new MulNode(x, y);
+    }
+
+    protected MulNode(ValueNode x, ValueNode y) {
+        super(ArithmeticOpTable.forStamp(x.stamp()).getMul(), x, y);
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
+        ValueNode ret = super.canonical(tool, forX, forY);
+        if (ret != this) {
+            return ret;
+        }
+
+        if (forX.isConstant() && !forY.isConstant()) {
+            return MulNode.create(forY, forX);
+        }
+        if (forY.isConstant()) {
+            Constant c = forY.asConstant();
+            if (getOp().isNeutral(c)) {
+                return forX;
+            }
+
+            if (c.getKind().isNumericInteger()) {
+                long i = c.asLong();
+                long abs = Math.abs(i);
+                if (abs > 0 && CodeUtil.isPowerOf2(abs)) {
+                    LeftShiftNode shift = LeftShiftNode.create(forX, ConstantNode.forInt(CodeUtil.log2(abs)));
+                    if (i < 0) {
+                        return NegateNode.create(shift);
+                    } else {
+                        return shift;
+                    }
+                }
+            }
+
+            if (getOp().isAssociative()) {
+                // canonicalize expressions like "(a * 1) * 2"
+                return reassociate(this, ValueNode.isConstantPredicate(), forX, forY);
+            }
+        }
+        return this;
+    }
+
+    @Override
+    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
+        Value op1 = builder.operand(getX());
+        Value op2 = builder.operand(getY());
+        if (!getY().isConstant() && !BinaryArithmeticNode.livesLonger(this, getY(), builder)) {
+            Value op = op1;
+            op1 = op2;
+            op2 = op;
+        }
+        builder.setResult(this, gen.emitMul(op1, op2));
+    }
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NarrowNode.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NarrowNode.java	Wed Sep 24 16:22:22 2014 -0700
@@ -22,8 +22,8 @@
  */
 package com.oracle.graal.nodes.calc;
 
+import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.lir.gen.*;
 import com.oracle.graal.nodeinfo.*;
@@ -45,19 +45,14 @@
         super(StampTool.narrowingConversion(input.stamp(), resultBits), input, resultBits);
     }
 
-    public static long narrow(long value, int resultBits) {
-        long ret = value & IntegerStamp.defaultMask(resultBits);
-        return SignExtendNode.signExtend(ret, resultBits);
-    }
-
     @Override
     public Constant convert(Constant c) {
-        return Constant.forPrimitiveInt(getResultBits(), narrow(c.asLong(), getResultBits()));
+        return Constant.forPrimitiveInt(getResultBits(), CodeUtil.narrow(c.asLong(), getResultBits()));
     }
 
     @Override
     public Constant reverse(Constant input) {
-        long result = SignExtendNode.signExtend(input.asLong(), getResultBits());
+        long result = CodeUtil.signExtend(input.asLong(), getResultBits());
         return Constant.forPrimitiveInt(getInputBits(), result);
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NegateNode.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NegateNode.java	Wed Sep 24 16:22:22 2014 -0700
@@ -22,25 +22,18 @@
  */
 package com.oracle.graal.nodes.calc;
 
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.compiler.common.*;
+import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.lir.gen.*;
 import com.oracle.graal.nodeinfo.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.type.*;
 
 /**
  * The {@code NegateNode} node negates its operand.
  */
 @NodeInfo
-public class NegateNode extends UnaryNode implements ArithmeticLIRLowerable, NarrowableArithmeticNode {
-
-    @Override
-    public boolean inferStamp() {
-        return updateStamp(StampTool.negate(getValue().stamp()));
-    }
+public class NegateNode extends UnaryArithmeticNode implements NarrowableArithmeticNode {
 
     /**
      * Creates new NegateNode instance.
@@ -51,38 +44,22 @@
         return USE_GENERATED_NODES ? new NegateNodeGen(value) : new NegateNode(value);
     }
 
-    protected NegateNode(ValueNode value) {
-        super(StampTool.negate(value.stamp()), value);
-    }
-
-    public Constant evalConst(Constant... inputs) {
-        assert inputs.length == 1;
-        Constant constant = inputs[0];
-        switch (constant.getKind()) {
-            case Int:
-                return Constant.forInt(-(constant.asInt()));
-            case Long:
-                return Constant.forLong(-(constant.asLong()));
-            case Float:
-                return Constant.forFloat(-(constant.asFloat()));
-            case Double:
-                return Constant.forDouble(-(constant.asDouble()));
-            default:
-                throw GraalInternalError.shouldNotReachHere("unknown kind " + constant.getKind());
-        }
+    NegateNode(ValueNode value) {
+        super(ArithmeticOpTable.forStamp(value.stamp()).getNeg(), value);
     }
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) {
-        if (forValue.isConstant()) {
-            return ConstantNode.forConstant(evalConst(forValue.asConstant()), null);
+        ValueNode ret = super.canonical(tool, forValue);
+        if (ret != this) {
+            return ret;
         }
         if (forValue instanceof NegateNode) {
             return ((NegateNode) forValue).getValue();
         }
-        if (forValue instanceof IntegerSubNode) {
-            IntegerSubNode sub = (IntegerSubNode) forValue;
-            return IntegerSubNode.create(sub.getY(), sub.getX());
+        if (forValue instanceof SubNode) {
+            SubNode sub = (SubNode) forValue;
+            return SubNode.create(sub.getY(), sub.getX());
         }
         return this;
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NotNode.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NotNode.java	Wed Sep 24 16:22:22 2014 -0700
@@ -22,34 +22,21 @@
  */
 package com.oracle.graal.nodes.calc;
 
-import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.lir.gen.*;
 import com.oracle.graal.nodeinfo.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.type.*;
 
 /**
  * Binary negation of long or integer values.
  */
 @NodeInfo
-public class NotNode extends UnaryNode implements ArithmeticLIRLowerable, NarrowableArithmeticNode {
-
-    @Override
-    public boolean inferStamp() {
-        return updateStamp(StampTool.not(getValue().stamp()));
-    }
-
-    @Override
-    public Constant evalConst(Constant... inputs) {
-        assert inputs.length == 1;
-        return Constant.forPrimitiveInt(PrimitiveStamp.getBits(stamp()), ~inputs[0].asLong());
-    }
+public class NotNode extends UnaryArithmeticNode implements ArithmeticLIRLowerable, NarrowableArithmeticNode {
 
     /**
-     * Creates new NegateNode instance.
+     * Creates new NotNode instance.
      *
      * @param x the instruction producing the value that is input to this instruction
      */
@@ -58,13 +45,14 @@
     }
 
     protected NotNode(ValueNode x) {
-        super(StampTool.not(x.stamp()), x);
+        super(ArithmeticOpTable.forStamp(x.stamp()).getNot(), x);
     }
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) {
-        if (forValue.isConstant()) {
-            return ConstantNode.forConstant(evalConst(forValue.asConstant()), null);
+        ValueNode ret = super.canonical(tool, forValue);
+        if (ret != this) {
+            return ret;
         }
         if (forValue instanceof NotNode) {
             return ((NotNode) forValue).getValue();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/OrNode.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/OrNode.java	Wed Sep 24 16:22:22 2014 -0700
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.nodes.calc;
 
+import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graph.spi.*;
@@ -29,52 +30,46 @@
 import com.oracle.graal.nodeinfo.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.nodes.util.*;
 
 @NodeInfo(shortName = "|")
-public class OrNode extends BitLogicNode {
+public class OrNode extends BinaryArithmeticNode {
 
     public static OrNode create(ValueNode x, ValueNode y) {
         return USE_GENERATED_NODES ? new OrNodeGen(x, y) : new OrNode(x, y);
     }
 
     OrNode(ValueNode x, ValueNode y) {
-        super(StampTool.or(x.stamp(), y.stamp()), x, y);
-        assert x.stamp().isCompatible(y.stamp());
-    }
-
-    @Override
-    public boolean inferStamp() {
-        return updateStamp(StampTool.or(getX().stamp(), getY().stamp()));
-    }
-
-    @Override
-    public Constant evalConst(Constant... inputs) {
-        assert inputs.length == 2;
-        return Constant.forPrimitiveInt(PrimitiveStamp.getBits(stamp()), inputs[0].asLong() | inputs[1].asLong());
+        super(ArithmeticOpTable.forStamp(x.stamp()).getOr(), x, y);
     }
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
+        ValueNode ret = super.canonical(tool, forX, forY);
+        if (ret != this) {
+            return ret;
+        }
+
         if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) {
             return forX;
         }
         if (forX.isConstant() && !forY.isConstant()) {
             return create(forY, forX);
         }
-        if (forX.isConstant()) {
-            return ConstantNode.forPrimitive(stamp(), evalConst(forX.asConstant(), forY.asConstant()));
-        } else if (forY.isConstant()) {
-            long rawY = forY.asConstant().asLong();
-            long mask = IntegerStamp.defaultMask(PrimitiveStamp.getBits(stamp()));
-            if ((rawY & mask) == mask) {
-                return ConstantNode.forIntegerStamp(stamp(), mask);
-            }
-            if ((rawY & mask) == 0) {
+        if (forY.isConstant()) {
+            Constant c = forY.asConstant();
+            if (getOp().isNeutral(c)) {
                 return forX;
             }
-            return BinaryNode.reassociate(this, ValueNode.isConstantPredicate(), forX, forY);
+
+            if (c.getKind().isNumericInteger()) {
+                long rawY = c.asLong();
+                long mask = CodeUtil.mask(PrimitiveStamp.getBits(stamp()));
+                if ((rawY & mask) == mask) {
+                    return ConstantNode.forIntegerStamp(stamp(), mask);
+                }
+            }
+            return reassociate(this, ValueNode.isConstantPredicate(), forX, forY);
         }
         return this;
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/RemNode.java	Wed Sep 24 16:22:22 2014 -0700
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.nodes.calc;
+
+import com.oracle.graal.compiler.common.type.*;
+import com.oracle.graal.lir.gen.*;
+import com.oracle.graal.nodeinfo.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+
+@NodeInfo(shortName = "%")
+public class RemNode extends BinaryArithmeticNode implements Lowerable {
+
+    public static RemNode create(ValueNode x, ValueNode y) {
+        return USE_GENERATED_NODES ? new RemNodeGen(x, y) : new RemNode(x, y);
+    }
+
+    protected RemNode(ValueNode x, ValueNode y) {
+        super(ArithmeticOpTable.forStamp(x.stamp()).getRem(), x, y);
+    }
+
+    @Override
+    public void lower(LoweringTool tool) {
+        tool.getLowerer().lower(this, tool);
+    }
+
+    @Override
+    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
+        builder.setResult(this, gen.emitRem(builder.operand(getX()), builder.operand(getY()), null));
+    }
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/SignExtendNode.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/SignExtendNode.java	Wed Sep 24 16:22:22 2014 -0700
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.nodes.calc;
 
+import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graph.spi.*;
@@ -45,26 +46,14 @@
         super(StampTool.signExtend(input.stamp(), resultBits), input, resultBits);
     }
 
-    public static long signExtend(long value, int inputBits) {
-        if (inputBits < 64) {
-            if ((value >>> (inputBits - 1) & 1) == 1) {
-                return value | (-1L << inputBits);
-            } else {
-                return value & ~(-1L << inputBits);
-            }
-        } else {
-            return value;
-        }
-    }
-
     @Override
     public Constant convert(Constant c) {
-        return Constant.forPrimitiveInt(getResultBits(), signExtend(c.asLong(), getInputBits()));
+        return Constant.forPrimitiveInt(getResultBits(), CodeUtil.signExtend(c.asLong(), getInputBits()));
     }
 
     @Override
     public Constant reverse(Constant c) {
-        return Constant.forPrimitiveInt(getInputBits(), NarrowNode.narrow(c.asLong(), getInputBits()));
+        return Constant.forPrimitiveInt(getInputBits(), CodeUtil.narrow(c.asLong(), getInputBits()));
     }
 
     @Override
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/SubNode.java	Wed Sep 24 16:22:22 2014 -0700
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.nodes.calc;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.common.type.*;
+import com.oracle.graal.graph.spi.*;
+import com.oracle.graal.lir.gen.*;
+import com.oracle.graal.nodeinfo.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.util.*;
+
+@NodeInfo(shortName = "-")
+public class SubNode extends BinaryArithmeticNode implements NarrowableArithmeticNode {
+
+    public static SubNode create(ValueNode x, ValueNode y) {
+        return USE_GENERATED_NODES ? new SubNodeGen(x, y) : new SubNode(x, y);
+    }
+
+    protected SubNode(ValueNode x, ValueNode y) {
+        super(ArithmeticOpTable.forStamp(x.stamp()).getSub(), x, y);
+    }
+
+    @SuppressWarnings("hiding")
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
+        ValueNode ret = super.canonical(tool, forX, forY);
+        if (ret != this) {
+            return ret;
+        }
+
+        if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) {
+            Constant zero = getOp().getZero(forX.stamp());
+            if (zero != null) {
+                return ConstantNode.forPrimitive(stamp(), zero);
+            }
+        }
+        boolean associative = getOp().isAssociative();
+        if (associative) {
+            if (forX instanceof AddNode) {
+                AddNode x = (AddNode) forX;
+                if (x.getY() == forY) {
+                    // (a + b) - b
+                    return x.getX();
+                }
+                if (x.getX() == forY) {
+                    // (a + b) - a
+                    return x.getY();
+                }
+            } else if (forX instanceof SubNode) {
+                SubNode x = (SubNode) forX;
+                if (x.getX() == forY) {
+                    // (a - b) - a
+                    return NegateNode.create(x.getY());
+                }
+            }
+            if (forY instanceof AddNode) {
+                AddNode y = (AddNode) forY;
+                if (y.getX() == forX) {
+                    // a - (a + b)
+                    return NegateNode.create(y.getY());
+                }
+                if (y.getY() == forX) {
+                    // b - (a + b)
+                    return NegateNode.create(y.getX());
+                }
+            } else if (forY instanceof SubNode) {
+                SubNode y = (SubNode) forY;
+                if (y.getX() == forX) {
+                    // a - (a - b)
+                    return y.getY();
+                }
+            }
+        }
+        if (forY.isConstant()) {
+            Constant c = forY.asConstant();
+            if (getOp().isNeutral(c)) {
+                return forX;
+            }
+            if (associative) {
+                BinaryNode reassociated = reassociate(this, ValueNode.isConstantPredicate(), forX, forY);
+                if (reassociated != this) {
+                    return reassociated;
+                }
+            }
+            if (c.getKind().isNumericInteger()) {
+                long i = c.asLong();
+                if (i < 0 || ((IntegerStamp) StampFactory.forKind(forY.getKind())).contains(-i)) {
+                    // Adding a negative is more friendly to the backend since adds are
+                    // commutative, so prefer add when it fits.
+                    return BinaryArithmeticNode.add(forX, ConstantNode.forIntegerStamp(stamp(), -i));
+                }
+            }
+        } else if (forX.isConstant()) {
+            Constant c = forX.asConstant();
+            if (ArithmeticOpTable.forStamp(stamp()).getAdd().isNeutral(c)) {
+                /*
+                 * Note that for floating point numbers, + and - have different neutral elements. We
+                 * have to test for the neutral element of +, because we are doing this
+                 * transformation: 0 - x == (-x) + 0 == -x.
+                 */
+                return NegateNode.create(forY);
+            }
+            if (associative) {
+                return reassociate(this, ValueNode.isConstantPredicate(), forX, forY);
+            }
+        }
+        if (forY instanceof NegateNode) {
+            return BinaryArithmeticNode.add(forX, ((NegateNode) forY).getValue());
+        }
+        return this;
+    }
+
+    @Override
+    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
+        builder.setResult(this, gen.emitSub(builder.operand(getX()), builder.operand(getY())));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnaryArithmeticNode.java	Wed Sep 24 16:22:22 2014 -0700
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.nodes.calc;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.common.type.ArithmeticOpTable.UnaryOp;
+import com.oracle.graal.graph.spi.*;
+import com.oracle.graal.nodeinfo.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+
+@NodeInfo
+public abstract class UnaryArithmeticNode extends UnaryNode implements ArithmeticLIRLowerable {
+
+    private final UnaryOp op;
+
+    protected UnaryArithmeticNode(UnaryOp op, ValueNode value) {
+        super(op.foldStamp(value.stamp()), value);
+        this.op = op;
+    }
+
+    public UnaryOp getOp() {
+        return op;
+    }
+
+    public Constant evalConst(Constant... inputs) {
+        assert inputs.length == 1;
+        return op.foldConstant(inputs[0]);
+    }
+
+    @Override
+    public boolean inferStamp() {
+        return updateStamp(op.foldStamp(getValue().stamp()));
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) {
+        if (forValue.isConstant()) {
+            return ConstantNode.forPrimitive(stamp(), op.foldConstant(forValue.asConstant()));
+        }
+        return this;
+    }
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/XorNode.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/XorNode.java	Wed Sep 24 16:22:22 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.nodes.calc;
 
+import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graph.spi.*;
@@ -29,51 +30,47 @@
 import com.oracle.graal.nodeinfo.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.nodes.util.*;
 
 @NodeInfo(shortName = "^")
-public class XorNode extends BitLogicNode {
+public class XorNode extends BinaryArithmeticNode {
 
     public static XorNode create(ValueNode x, ValueNode y) {
         return USE_GENERATED_NODES ? new XorNodeGen(x, y) : new XorNode(x, y);
     }
 
     protected XorNode(ValueNode x, ValueNode y) {
-        super(StampTool.xor(x.stamp(), y.stamp()), x, y);
+        super(ArithmeticOpTable.forStamp(x.stamp()).getXor(), x, y);
         assert x.stamp().isCompatible(y.stamp());
     }
 
     @Override
-    public boolean inferStamp() {
-        return updateStamp(StampTool.xor(getX().stamp(), getY().stamp()));
-    }
-
-    @Override
-    public Constant evalConst(Constant... inputs) {
-        assert inputs.length == 2;
-        return Constant.forPrimitiveInt(PrimitiveStamp.getBits(stamp()), inputs[0].asLong() ^ inputs[1].asLong());
-    }
-
-    @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
+        ValueNode ret = super.canonical(tool, forX, forY);
+        if (ret != this) {
+            return ret;
+        }
+
         if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) {
-            return ConstantNode.forIntegerStamp(stamp(), 0);
+            return ConstantNode.forPrimitive(stamp(), getOp().getZero(forX.stamp()));
         }
         if (forX.isConstant() && !forY.isConstant()) {
             return XorNode.create(forY, forX);
         }
-        if (forX.isConstant()) {
-            return ConstantNode.forPrimitive(stamp(), evalConst(forX.asConstant(), forY.asConstant()));
-        } else if (forY.isConstant()) {
-            long rawY = forY.asConstant().asLong();
-            long mask = IntegerStamp.defaultMask(PrimitiveStamp.getBits(stamp()));
-            if ((rawY & mask) == 0) {
+        if (forY.isConstant()) {
+            Constant c = forY.asConstant();
+            if (getOp().isNeutral(c)) {
                 return forX;
-            } else if ((rawY & mask) == mask) {
-                return NotNode.create(forX);
             }
-            return BinaryNode.reassociate(this, ValueNode.isConstantPredicate(), forX, forY);
+
+            if (c.getKind().isNumericInteger()) {
+                long rawY = c.asLong();
+                long mask = CodeUtil.mask(PrimitiveStamp.getBits(stamp()));
+                if ((rawY & mask) == mask) {
+                    return NotNode.create(forX);
+                }
+            }
+            return reassociate(this, ValueNode.isConstantPredicate(), forX, forY);
         }
         return this;
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ZeroExtendNode.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ZeroExtendNode.java	Wed Sep 24 16:22:22 2014 -0700
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.nodes.calc;
 
+import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.common.calc.*;
 import com.oracle.graal.compiler.common.type.*;
@@ -46,22 +47,14 @@
         super(StampTool.zeroExtend(input.stamp(), resultBits), input, resultBits);
     }
 
-    public static long zeroExtend(long value, int inputBits) {
-        if (inputBits < 64) {
-            return value & ~(-1L << inputBits);
-        } else {
-            return value;
-        }
-    }
-
     @Override
     public Constant convert(Constant c) {
-        return Constant.forPrimitiveInt(getResultBits(), zeroExtend(c.asLong(), getInputBits()));
+        return Constant.forPrimitiveInt(getResultBits(), CodeUtil.zeroExtend(c.asLong(), getInputBits()));
     }
 
     @Override
     public Constant reverse(Constant c) {
-        return Constant.forPrimitiveInt(getInputBits(), NarrowNode.narrow(c.asLong(), getInputBits()));
+        return Constant.forPrimitiveInt(getInputBits(), CodeUtil.narrow(c.asLong(), getInputBits()));
     }
 
     @Override
@@ -100,7 +93,7 @@
             Stamp inputStamp = narrow.getValue().stamp();
             if (inputStamp instanceof IntegerStamp && inputStamp.isCompatible(stamp())) {
                 IntegerStamp istamp = (IntegerStamp) inputStamp;
-                long mask = IntegerStamp.defaultMask(PrimitiveStamp.getBits(narrow.stamp()));
+                long mask = CodeUtil.mask(PrimitiveStamp.getBits(narrow.stamp()));
                 if (((istamp.upMask() | istamp.downMask()) & ~mask) == 0) {
                     // The original value is in the range of the masked zero extended result so
                     // simply return the original input.
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AddLocationNode.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AddLocationNode.java	Wed Sep 24 16:22:22 2014 -0700
@@ -31,7 +31,6 @@
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.type.*;
 
 /**
  * Location node that is the sum of two other location nodes. Can represent locations in the form of
@@ -88,7 +87,7 @@
             IndexedLocationNode yIdx = (IndexedLocationNode) forY;
             if (xIdx.getIndexScaling() == yIdx.getIndexScaling()) {
                 long displacement = xIdx.getDisplacement() + yIdx.getDisplacement();
-                ValueNode index = IntegerArithmeticNode.add(xIdx.getIndex(), yIdx.getIndex());
+                ValueNode index = BinaryArithmeticNode.add(xIdx.getIndex(), yIdx.getIndex());
                 return IndexedLocationNode.create(getLocationIdentity(), getValueKind(), displacement, index, xIdx.getIndexScaling());
             }
         }
@@ -120,7 +119,7 @@
 
     @Override
     public IntegerStamp getDisplacementStamp() {
-        return StampTool.add(getX().getDisplacementStamp(), getY().getDisplacementStamp());
+        return (IntegerStamp) IntegerStamp.OPS.getAdd().foldStamp(getX().getDisplacementStamp(), getY().getDisplacementStamp());
     }
 
     @NodeIntrinsic
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IndexedLocationNode.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IndexedLocationNode.java	Wed Sep 24 16:22:22 2014 -0700
@@ -107,7 +107,7 @@
     public IntegerStamp getDisplacementStamp() {
         assert indexScaling > 0 && CodeUtil.isPowerOf2(indexScaling);
         int scale = CodeUtil.log2(indexScaling);
-        return (IntegerStamp) StampTool.add(StampFactory.forInteger(64, displacement, displacement),
+        return (IntegerStamp) IntegerStamp.OPS.getAdd().foldStamp(StampFactory.forInteger(64, displacement, displacement),
                         StampTool.signExtend(StampTool.leftShift(index.stamp(), StampFactory.forInteger(64, scale, scale)), 64));
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java	Wed Sep 24 16:22:22 2014 -0700
@@ -63,16 +63,8 @@
     @Override
     public void generate(NodeLIRBuilderTool gen) {
         Value address = location().generateAddress(gen, gen.getLIRGeneratorTool(), gen.operand(object()));
-        // It's possible a constant was forced for other usages so inspect the value directly and
-        // use a constant if it can be directly stored.
-        Value v;
-        if (value().isConstant() && gen.getLIRGeneratorTool().canStoreConstant(value().asConstant())) {
-            v = value().asConstant();
-        } else {
-            v = gen.operand(value());
-        }
         LIRKind writeKind = gen.getLIRGeneratorTool().getLIRKind(value().stamp());
-        gen.getLIRGeneratorTool().emitStore(writeKind, address, v, gen.state(this));
+        gen.getLIRGeneratorTool().emitStore(writeKind, address, gen.operand(value()), gen.state(this));
     }
 
     @Override
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LimitedValueProxy.java	Wed Sep 24 16:22:22 2014 -0700
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.nodes.spi;
+
+import com.oracle.graal.nodes.*;
+
+/**
+ * This interface is like the derived {@link ValueProxy}. The difference is that only the graph
+ * builder should see through the proxy for doing some checks. Optimizations should not see through
+ * this proxy and therefore should only test for {@link ValueProxy}.
+ */
+public interface LimitedValueProxy extends Proxy {
+
+    ValueNode getOriginalNode();
+
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/ValueAndStampProxy.java	Wed Sep 24 16:13:34 2014 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.nodes.spi;
-
-/**
- * This interface marks nodes whose result is the same as one of their inputs, and whose stamp is
- * the same as one of their inputs.
- * 
- * For some algorithms it is necessary or advantageous to see through these proxies.
- */
-public interface ValueAndStampProxy extends ValueProxy {
-}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/ValueProxy.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/ValueProxy.java	Wed Sep 24 16:22:22 2014 -0700
@@ -22,16 +22,12 @@
  */
 package com.oracle.graal.nodes.spi;
 
-import com.oracle.graal.nodes.*;
-
 /**
  * This interface marks nodes whose result is the same as one of their inputs. Such nodes are used
  * to add type information, to introduce scheduling restrictions, etc.
  *
  * For some algorithms it is necessary or advantageous to see through these proxies.
  */
-public interface ValueProxy extends Proxy {
-
-    ValueNode getOriginalNode();
+public interface ValueProxy extends LimitedValueProxy {
 
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java	Wed Sep 24 16:22:22 2014 -0700
@@ -24,42 +24,16 @@
 
 import java.util.*;
 
+import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.calc.*;
 
 /**
  * Helper class that is used to keep all stamp-related operations in one place.
  */
 public class StampTool {
 
-    public static Stamp negate(Stamp stamp) {
-        if (stamp instanceof IntegerStamp) {
-            IntegerStamp integerStamp = (IntegerStamp) stamp;
-            int bits = integerStamp.getBits();
-            if (integerStamp.lowerBound() != IntegerStamp.defaultMinValue(bits)) {
-                // TODO(ls) check if the mask calculation is correct...
-                return StampFactory.forInteger(bits, -integerStamp.upperBound(), -integerStamp.lowerBound());
-            }
-        } else if (stamp instanceof FloatStamp) {
-            FloatStamp floatStamp = (FloatStamp) stamp;
-            return new FloatStamp(floatStamp.getBits(), -floatStamp.upperBound(), -floatStamp.lowerBound(), floatStamp.isNonNaN());
-        }
-
-        return stamp.unrestricted();
-    }
-
-    public static Stamp not(Stamp stamp) {
-        if (stamp instanceof IntegerStamp) {
-            IntegerStamp integerStamp = (IntegerStamp) stamp;
-            int bits = integerStamp.getBits();
-            long defaultMask = IntegerStamp.defaultMask(bits);
-            return new IntegerStamp(bits, ~integerStamp.upperBound(), ~integerStamp.lowerBound(), (~integerStamp.upMask()) & defaultMask, (~integerStamp.downMask()) & defaultMask);
-        }
-        return stamp.unrestricted();
-    }
-
     public static Stamp meet(Collection<? extends StampProvider> values) {
         Iterator<? extends StampProvider> iterator = values.iterator();
         if (iterator.hasNext()) {
@@ -73,185 +47,6 @@
         }
     }
 
-    public static Stamp add(Stamp stamp1, Stamp stamp2) {
-        if (stamp1 instanceof IntegerStamp && stamp2 instanceof IntegerStamp) {
-            return add((IntegerStamp) stamp1, (IntegerStamp) stamp2);
-        }
-        return StampFactory.illegal();
-    }
-
-    private static long carryBits(long x, long y) {
-        return (x + y) ^ x ^ y;
-    }
-
-    public static Stamp sub(Stamp stamp1, Stamp stamp2) {
-        return add(stamp1, StampTool.negate(stamp2));
-    }
-
-    public static Stamp div(Stamp stamp1, Stamp stamp2) {
-        if (stamp1 instanceof IntegerStamp && stamp2 instanceof IntegerStamp) {
-            return div((IntegerStamp) stamp1, (IntegerStamp) stamp2);
-        }
-        return StampFactory.illegal();
-    }
-
-    public static Stamp div(IntegerStamp stamp1, IntegerStamp stamp2) {
-        assert stamp1.getBits() == stamp2.getBits();
-        if (stamp2.isStrictlyPositive()) {
-            long lowerBound = stamp1.lowerBound() / stamp2.lowerBound();
-            long upperBound = stamp1.upperBound() / stamp2.lowerBound();
-            return StampFactory.forInteger(stamp1.getBits(), lowerBound, upperBound);
-        }
-        return stamp1.unrestricted();
-    }
-
-    public static Stamp rem(Stamp stamp1, Stamp stamp2) {
-        if (stamp1 instanceof IntegerStamp && stamp2 instanceof IntegerStamp) {
-            return rem((IntegerStamp) stamp1, (IntegerStamp) stamp2);
-        }
-        return StampFactory.illegal();
-    }
-
-    public static Stamp rem(IntegerStamp stamp1, IntegerStamp stamp2) {
-        assert stamp1.getBits() == stamp2.getBits();
-        // zero is always possible
-        long lowerBound = Math.min(stamp1.lowerBound(), 0);
-        long upperBound = Math.max(stamp1.upperBound(), 0);
-
-        long magnitude; // the maximum absolute value of the result, derived from stamp2
-        if (stamp2.lowerBound() == IntegerStamp.defaultMinValue(stamp2.getBits())) {
-            // Math.abs(...) - 1 does not work in this case
-            magnitude = IntegerStamp.defaultMaxValue(stamp2.getBits());
-        } else {
-            magnitude = Math.max(Math.abs(stamp2.lowerBound()), Math.abs(stamp2.upperBound())) - 1;
-        }
-        lowerBound = Math.max(lowerBound, -magnitude);
-        upperBound = Math.min(upperBound, magnitude);
-
-        return StampFactory.forInteger(stamp1.getBits(), lowerBound, upperBound);
-    }
-
-    private static boolean addOverflowsPositively(long x, long y, int bits) {
-        long result = x + y;
-        if (bits == 64) {
-            return (~x & ~y & result) < 0;
-        } else {
-            return result > IntegerStamp.defaultMaxValue(bits);
-        }
-    }
-
-    private static boolean addOverflowsNegatively(long x, long y, int bits) {
-        long result = x + y;
-        if (bits == 64) {
-            return (x & y & ~result) < 0;
-        } else {
-            return result < IntegerStamp.defaultMinValue(bits);
-        }
-    }
-
-    public static IntegerStamp add(IntegerStamp stamp1, IntegerStamp stamp2) {
-        int bits = stamp1.getBits();
-        assert bits == stamp2.getBits();
-
-        if (stamp1.isUnrestricted()) {
-            return stamp1;
-        } else if (stamp2.isUnrestricted()) {
-            return stamp2;
-        }
-        long defaultMask = IntegerStamp.defaultMask(bits);
-        long variableBits = (stamp1.downMask() ^ stamp1.upMask()) | (stamp2.downMask() ^ stamp2.upMask());
-        long variableBitsWithCarry = variableBits | (carryBits(stamp1.downMask(), stamp2.downMask()) ^ carryBits(stamp1.upMask(), stamp2.upMask()));
-        long newDownMask = (stamp1.downMask() + stamp2.downMask()) & ~variableBitsWithCarry;
-        long newUpMask = (stamp1.downMask() + stamp2.downMask()) | variableBitsWithCarry;
-
-        newDownMask &= defaultMask;
-        newUpMask &= defaultMask;
-
-        long lowerBound;
-        long upperBound;
-        boolean lowerOverflowsPositively = addOverflowsPositively(stamp1.lowerBound(), stamp2.lowerBound(), bits);
-        boolean upperOverflowsPositively = addOverflowsPositively(stamp1.upperBound(), stamp2.upperBound(), bits);
-        boolean lowerOverflowsNegatively = addOverflowsNegatively(stamp1.lowerBound(), stamp2.lowerBound(), bits);
-        boolean upperOverflowsNegatively = addOverflowsNegatively(stamp1.upperBound(), stamp2.upperBound(), bits);
-        if ((lowerOverflowsNegatively && !upperOverflowsNegatively) || (!lowerOverflowsPositively && upperOverflowsPositively)) {
-            lowerBound = IntegerStamp.defaultMinValue(bits);
-            upperBound = IntegerStamp.defaultMaxValue(bits);
-        } else {
-            lowerBound = SignExtendNode.signExtend((stamp1.lowerBound() + stamp2.lowerBound()) & defaultMask, bits);
-            upperBound = SignExtendNode.signExtend((stamp1.upperBound() + stamp2.upperBound()) & defaultMask, bits);
-        }
-        IntegerStamp limit = StampFactory.forInteger(bits, lowerBound, upperBound);
-        newUpMask &= limit.upMask();
-        upperBound = SignExtendNode.signExtend(upperBound & newUpMask, bits);
-        newDownMask |= limit.downMask();
-        lowerBound |= newDownMask;
-        return new IntegerStamp(bits, lowerBound, upperBound, newDownMask, newUpMask);
-    }
-
-    public static Stamp sub(IntegerStamp stamp1, IntegerStamp stamp2) {
-        if (stamp1.isUnrestricted() || stamp2.isUnrestricted()) {
-            return stamp1.unrestricted();
-        }
-        return add(stamp1, (IntegerStamp) StampTool.negate(stamp2));
-    }
-
-    public static Stamp stampForMask(int bits, long downMask, long upMask) {
-        long lowerBound;
-        long upperBound;
-        if (((upMask >>> (bits - 1)) & 1) == 0) {
-            lowerBound = downMask;
-            upperBound = upMask;
-        } else if (((downMask >>> (bits - 1)) & 1) == 1) {
-            lowerBound = downMask;
-            upperBound = upMask;
-        } else {
-            lowerBound = downMask | (-1L << (bits - 1));
-            upperBound = IntegerStamp.defaultMaxValue(bits) & upMask;
-        }
-        lowerBound = IntegerConvertNode.convert(lowerBound, bits, false);
-        upperBound = IntegerConvertNode.convert(upperBound, bits, false);
-        return new IntegerStamp(bits, lowerBound, upperBound, downMask, upMask);
-    }
-
-    public static Stamp and(Stamp stamp1, Stamp stamp2) {
-        if (stamp1 instanceof IntegerStamp && stamp2 instanceof IntegerStamp) {
-            return and((IntegerStamp) stamp1, (IntegerStamp) stamp2);
-        }
-        return StampFactory.illegal();
-    }
-
-    public static Stamp and(IntegerStamp stamp1, IntegerStamp stamp2) {
-        assert stamp1.getBits() == stamp2.getBits();
-        return stampForMask(stamp1.getBits(), stamp1.downMask() & stamp2.downMask(), stamp1.upMask() & stamp2.upMask());
-    }
-
-    public static Stamp or(Stamp stamp1, Stamp stamp2) {
-        if (stamp1 instanceof IntegerStamp && stamp2 instanceof IntegerStamp) {
-            return or((IntegerStamp) stamp1, (IntegerStamp) stamp2);
-        }
-        return StampFactory.illegal();
-    }
-
-    public static Stamp or(IntegerStamp stamp1, IntegerStamp stamp2) {
-        assert stamp1.getBits() == stamp2.getBits();
-        return stampForMask(stamp1.getBits(), stamp1.downMask() | stamp2.downMask(), stamp1.upMask() | stamp2.upMask());
-    }
-
-    public static Stamp xor(Stamp stamp1, Stamp stamp2) {
-        if (stamp1 instanceof IntegerStamp && stamp2 instanceof IntegerStamp) {
-            return xor((IntegerStamp) stamp1, (IntegerStamp) stamp2);
-        }
-        return StampFactory.illegal();
-    }
-
-    public static Stamp xor(IntegerStamp stamp1, IntegerStamp stamp2) {
-        assert stamp1.getBits() == stamp2.getBits();
-        long variableBits = (stamp1.downMask() ^ stamp1.upMask()) | (stamp2.downMask() ^ stamp2.upMask());
-        long newDownMask = (stamp1.downMask() ^ stamp2.downMask()) & ~variableBits;
-        long newUpMask = (stamp1.downMask() ^ stamp2.downMask()) | variableBits;
-        return stampForMask(stamp1.getBits(), newDownMask, newUpMask);
-    }
-
     public static Stamp rightShift(Stamp value, Stamp shift) {
         if (value instanceof IntegerStamp && shift instanceof IntegerStamp) {
             return rightShift((IntegerStamp) value, (IntegerStamp) shift);
@@ -265,14 +60,14 @@
             int extraBits = 64 - bits;
             long shiftMask = bits > 32 ? 0x3FL : 0x1FL;
             long shiftCount = shift.lowerBound() & shiftMask;
-            long defaultMask = IntegerStamp.defaultMask(bits);
+            long defaultMask = CodeUtil.mask(bits);
             // shifting back and forth performs sign extension
             long downMask = (value.downMask() << extraBits) >> (shiftCount + extraBits) & defaultMask;
             long upMask = (value.upMask() << extraBits) >> (shiftCount + extraBits) & defaultMask;
             return new IntegerStamp(bits, value.lowerBound() >> shiftCount, value.upperBound() >> shiftCount, downMask, upMask);
         }
         long mask = IntegerStamp.upMaskFor(bits, value.lowerBound(), value.upperBound());
-        return stampForMask(bits, 0, mask);
+        return IntegerStamp.stampForMask(bits, 0, mask);
     }
 
     public static Stamp unsignedRightShift(Stamp value, Stamp shift) {
@@ -296,7 +91,7 @@
             }
         }
         long mask = IntegerStamp.upMaskFor(bits, value.lowerBound(), value.upperBound());
-        return stampForMask(bits, 0, mask);
+        return IntegerStamp.stampForMask(bits, 0, mask);
     }
 
     public static Stamp leftShift(Stamp value, Stamp shift) {
@@ -308,7 +103,7 @@
 
     public static Stamp leftShift(IntegerStamp value, IntegerStamp shift) {
         int bits = value.getBits();
-        long defaultMask = IntegerStamp.defaultMask(bits);
+        long defaultMask = CodeUtil.mask(bits);
         if (value.upMask() == 0) {
             return value;
         }
@@ -335,7 +130,7 @@
                     upMask |= value.upMask() << (i & shiftMask);
                 }
             }
-            Stamp result = stampForMask(bits, downMask, upMask & defaultMask);
+            Stamp result = IntegerStamp.stampForMask(bits, downMask, upMask & defaultMask);
             return result;
         }
         return value.unrestricted();
@@ -347,9 +142,9 @@
             int inputBits = inputStamp.getBits();
             assert inputBits <= resultBits;
 
-            long defaultMask = IntegerStamp.defaultMask(resultBits);
-            long downMask = SignExtendNode.signExtend(inputStamp.downMask(), inputBits) & defaultMask;
-            long upMask = SignExtendNode.signExtend(inputStamp.upMask(), inputBits) & defaultMask;
+            long defaultMask = CodeUtil.mask(resultBits);
+            long downMask = CodeUtil.signExtend(inputStamp.downMask(), inputBits) & defaultMask;
+            long upMask = CodeUtil.signExtend(inputStamp.upMask(), inputBits) & defaultMask;
 
             return new IntegerStamp(resultBits, inputStamp.lowerBound(), inputStamp.upperBound(), downMask, upMask);
         } else {
@@ -363,17 +158,17 @@
             int inputBits = inputStamp.getBits();
             assert inputBits <= resultBits;
 
-            long downMask = ZeroExtendNode.zeroExtend(inputStamp.downMask(), inputBits);
-            long upMask = ZeroExtendNode.zeroExtend(inputStamp.upMask(), inputBits);
+            long downMask = CodeUtil.zeroExtend(inputStamp.downMask(), inputBits);
+            long upMask = CodeUtil.zeroExtend(inputStamp.upMask(), inputBits);
 
             if (inputStamp.lowerBound() < 0 && inputStamp.upperBound() >= 0) {
                 // signed range including 0 and -1
                 // after sign extension, the whole range from 0 to MAX_INT is possible
-                return stampForMask(resultBits, downMask, upMask);
+                return IntegerStamp.stampForMask(resultBits, downMask, upMask);
             }
 
-            long lowerBound = ZeroExtendNode.zeroExtend(inputStamp.lowerBound(), inputBits);
-            long upperBound = ZeroExtendNode.zeroExtend(inputStamp.upperBound(), inputBits);
+            long lowerBound = CodeUtil.zeroExtend(inputStamp.lowerBound(), inputBits);
+            long upperBound = CodeUtil.zeroExtend(inputStamp.upperBound(), inputBits);
 
             return new IntegerStamp(resultBits, lowerBound, upperBound, downMask, upMask);
         } else {
@@ -391,23 +186,23 @@
             }
 
             final long upperBound;
-            if (inputStamp.lowerBound() < IntegerStamp.defaultMinValue(resultBits)) {
-                upperBound = IntegerStamp.defaultMaxValue(resultBits);
+            if (inputStamp.lowerBound() < CodeUtil.minValue(resultBits)) {
+                upperBound = CodeUtil.maxValue(resultBits);
             } else {
                 upperBound = saturate(inputStamp.upperBound(), resultBits);
             }
             final long lowerBound;
-            if (inputStamp.upperBound() > IntegerStamp.defaultMaxValue(resultBits)) {
-                lowerBound = IntegerStamp.defaultMinValue(resultBits);
+            if (inputStamp.upperBound() > CodeUtil.maxValue(resultBits)) {
+                lowerBound = CodeUtil.minValue(resultBits);
             } else {
                 lowerBound = saturate(inputStamp.lowerBound(), resultBits);
             }
 
-            long defaultMask = IntegerStamp.defaultMask(resultBits);
+            long defaultMask = CodeUtil.mask(resultBits);
             long newDownMask = inputStamp.downMask() & defaultMask;
             long newUpMask = inputStamp.upMask() & defaultMask;
-            long newLowerBound = SignExtendNode.signExtend((lowerBound | newDownMask) & newUpMask, resultBits);
-            long newUpperBound = SignExtendNode.signExtend((upperBound | newDownMask) & newUpMask, resultBits);
+            long newLowerBound = CodeUtil.signExtend((lowerBound | newDownMask) & newUpMask, resultBits);
+            long newUpperBound = CodeUtil.signExtend((upperBound | newDownMask) & newUpMask, resultBits);
             return new IntegerStamp(resultBits, newLowerBound, newUpperBound, newDownMask, newUpMask);
         } else {
             return input.illegal();
@@ -429,8 +224,8 @@
             lowerBound = saturate(fromStamp.lowerBound(), toKind);
         }
 
-        long defaultMask = IntegerStamp.defaultMask(toKind.getBitCount());
-        long intMask = IntegerStamp.defaultMask(32);
+        long defaultMask = CodeUtil.mask(toKind.getBitCount());
+        long intMask = CodeUtil.mask(32);
         long newUpMask = signExtend(fromStamp.upMask() & defaultMask, toKind) & intMask;
         long newDownMask = signExtend(fromStamp.downMask() & defaultMask, toKind) & intMask;
         return new IntegerStamp(toKind.getStackKind().getBitCount(), (int) ((lowerBound | newDownMask) & newUpMask), (int) ((upperBound | newDownMask) & newUpMask), newDownMask, newUpMask);
@@ -446,11 +241,11 @@
 
     private static long saturate(long v, int bits) {
         if (bits < 64) {
-            long max = IntegerStamp.defaultMaxValue(bits);
+            long max = CodeUtil.maxValue(bits);
             if (v > max) {
                 return max;
             }
-            long min = IntegerStamp.defaultMinValue(bits);
+            long min = CodeUtil.minValue(bits);
             if (v < min) {
                 return min;
             }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java	Wed Sep 24 16:22:22 2014 -0700
@@ -335,8 +335,8 @@
     public static ValueNode originalValue(ValueNode proxy) {
         ValueNode v = proxy;
         do {
-            if (v instanceof ValueProxy) {
-                v = ((ValueProxy) v).getOriginalNode();
+            if (v instanceof LimitedValueProxy) {
+                v = ((LimitedValueProxy) v).getOriginalNode();
             } else if (v instanceof PhiNode) {
                 v = ((PhiNode) v).singleValue();
                 if (v == PhiNode.MULTIPLE_VALUES) {
@@ -372,8 +372,8 @@
             NodeWorkList worklist = proxy.graph().createNodeWorkList();
             worklist.add(proxy);
             for (Node node : worklist) {
-                if (node instanceof ValueProxy) {
-                    ValueNode originalValue = ((ValueProxy) node).getOriginalNode();
+                if (node instanceof LimitedValueProxy) {
+                    ValueNode originalValue = ((LimitedValueProxy) node).getOriginalNode();
                     if (!process(originalValue, worklist)) {
                         return;
                     }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ProfileCompiledMethodsPhase.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ProfileCompiledMethodsPhase.java	Wed Sep 24 16:22:22 2014 -0700
@@ -136,9 +136,9 @@
             return 2;
         } else if (node instanceof LogicNode || node instanceof ConvertNode || node instanceof BinaryNode || node instanceof NotNode) {
             return 1;
-        } else if (node instanceof IntegerDivNode || node instanceof FloatDivNode || node instanceof IntegerRemNode || node instanceof FloatRemNode) {
+        } else if (node instanceof IntegerDivNode || node instanceof DivNode || node instanceof IntegerRemNode || node instanceof RemNode) {
             return 10;
-        } else if (node instanceof IntegerMulNode || node instanceof FloatMulNode) {
+        } else if (node instanceof MulNode) {
             return 3;
         } else if (node instanceof Invoke) {
             return 5;
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/InferStamps.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/InferStamps.java	Wed Sep 24 16:22:22 2014 -0700
@@ -25,7 +25,6 @@
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
 
 public class InferStamps {
 
@@ -47,7 +46,7 @@
          * when the phi function performs the "meet" operator on its input stamps.
          */
         for (Node n : graph.getNodes()) {
-            if (n instanceof ValuePhiNode || n instanceof ValueAndStampProxy) {
+            if (n instanceof ValuePhiNode) {
                 ValueNode node = (ValueNode) n;
                 if (node.stamp() instanceof ObjectStamp) {
                     assert node.stamp().isLegal() : "We assume all Phi and Proxy stamps are legal before the analysis";
@@ -84,7 +83,7 @@
 
     private static boolean checkNoIllegalStamp(StructuredGraph graph) {
         for (Node n : graph.getNodes()) {
-            if (n instanceof ValuePhiNode || n instanceof ValueAndStampProxy) {
+            if (n instanceof ValuePhiNode) {
                 ValueNode node = (ValueNode) n;
                 assert !(node.stamp() instanceof IllegalStamp) : "Stamp is illegal after analysis. This is not necessarily an error, but a condition that we want to investigate (and then maybe relax or remove the assertion).";
             }
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinter.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinter.java	Wed Sep 24 16:22:22 2014 -0700
@@ -450,30 +450,35 @@
 
         for (int i = 0; i < lirInstructions.size(); i++) {
             LIRInstruction inst = lirInstructions.get(i);
-            out.printf("nr %4d ", inst.id()).print(COLUMN_END);
+            if (inst == null) {
+                out.print("nr   -1 ").print(COLUMN_END).print(" instruction ").print("<deleted>").print(COLUMN_END);
+                out.println(COLUMN_END);
+            } else {
+                out.printf("nr %4d ", inst.id()).print(COLUMN_END);
 
-            final StringBuilder stateString = new StringBuilder();
-            inst.forEachState(new StateProcedure() {
+                final StringBuilder stateString = new StringBuilder();
+                inst.forEachState(new StateProcedure() {
 
-                @Override
-                protected void doState(LIRFrameState state) {
-                    if (state.hasDebugInfo()) {
-                        DebugInfo di = state.debugInfo();
-                        stateString.append(debugInfoToString(di.getBytecodePosition(), di.getReferenceMap(), di.getCalleeSaveInfo(), target.arch));
-                    } else {
-                        stateString.append(debugInfoToString(state.topFrame, null, null, target.arch));
+                    @Override
+                    protected void doState(LIRFrameState state) {
+                        if (state.hasDebugInfo()) {
+                            DebugInfo di = state.debugInfo();
+                            stateString.append(debugInfoToString(di.getBytecodePosition(), di.getReferenceMap(), di.getCalleeSaveInfo(), target.arch));
+                        } else {
+                            stateString.append(debugInfoToString(state.topFrame, null, null, target.arch));
+                        }
                     }
+                });
+                if (stateString.length() > 0) {
+                    int level = out.indentationLevel();
+                    out.adjustIndentation(-level);
+                    out.print(" st ").print(HOVER_START).print("st").print(HOVER_SEP).print(stateString.toString()).print(HOVER_END).print(COLUMN_END);
+                    out.adjustIndentation(level);
                 }
-            });
-            if (stateString.length() > 0) {
-                int level = out.indentationLevel();
-                out.adjustIndentation(-level);
-                out.print(" st ").print(HOVER_START).print("st").print(HOVER_SEP).print(stateString.toString()).print(HOVER_END).print(COLUMN_END);
-                out.adjustIndentation(level);
+
+                out.print(" instruction ").print(inst.toString()).print(COLUMN_END);
+                out.println(COLUMN_END);
             }
-
-            out.print(" instruction ").print(inst.toString()).print(COLUMN_END);
-            out.println(COLUMN_END);
         }
         end("IR");
     }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java	Wed Sep 24 16:22:22 2014 -0700
@@ -625,19 +625,19 @@
                 offset = extend.getValue();
             }
         }
-        if (offset instanceof IntegerAddNode) {
-            IntegerAddNode integerAddNode = (IntegerAddNode) offset;
+        if (offset instanceof AddNode) {
+            AddNode integerAddNode = (AddNode) offset;
             if (integerAddNode.getY() instanceof ConstantNode) {
                 displacement = integerAddNode.getY().asConstant().asLong();
                 offset = integerAddNode.getX();
             }
         }
-        if (base != null && signExtend == false && offset instanceof IntegerAddNode) {
+        if (base != null && signExtend == false && offset instanceof AddNode) {
             /*
              * Try to decompose the operation into base plus offset so the base can go into a new
              * node. Prefer the unshifted side of an add as the base.
              */
-            IntegerAddNode integerAddNode = (IntegerAddNode) offset;
+            AddNode integerAddNode = (AddNode) offset;
             if (integerAddNode.getY() instanceof LeftShiftNode) {
                 base[0] = integerAddNode.getX();
                 offset = integerAddNode.getY();
@@ -645,8 +645,8 @@
                 base[0] = integerAddNode.getY();
                 offset = integerAddNode.getX();
             }
-            if (offset instanceof IntegerAddNode) {
-                integerAddNode = (IntegerAddNode) offset;
+            if (offset instanceof AddNode) {
+                integerAddNode = (AddNode) offset;
                 if (integerAddNode.getY() instanceof ConstantNode) {
                     displacement = integerAddNode.getY().asConstant().asLong();
                     offset = integerAddNode.getX();
@@ -748,7 +748,7 @@
             if (base == 0) {
                 return index;
             } else {
-                return IntegerArithmeticNode.add(graph, ConstantNode.forInt((int) base, graph), index);
+                return BinaryArithmeticNode.add(graph, ConstantNode.forInt((int) base, graph), index);
             }
         }
     }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitCountNode.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitCountNode.java	Wed Sep 24 16:22:22 2014 -0700
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.replacements.nodes;
 
+import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graph.spi.*;
@@ -45,8 +46,8 @@
     @Override
     public boolean inferStamp() {
         IntegerStamp valueStamp = (IntegerStamp) getValue().stamp();
-        assert (valueStamp.downMask() & IntegerStamp.defaultMask(valueStamp.getBits())) == valueStamp.downMask();
-        assert (valueStamp.upMask() & IntegerStamp.defaultMask(valueStamp.getBits())) == valueStamp.upMask();
+        assert (valueStamp.downMask() & CodeUtil.mask(valueStamp.getBits())) == valueStamp.downMask();
+        assert (valueStamp.upMask() & CodeUtil.mask(valueStamp.getBits())) == valueStamp.upMask();
         return updateStamp(StampFactory.forInteger(Kind.Int, bitCount(valueStamp.downMask()), bitCount(valueStamp.upMask())));
     }
 
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanForwardNode.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanForwardNode.java	Wed Sep 24 16:22:22 2014 -0700
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.replacements.nodes;
 
+import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graph.spi.*;
@@ -51,7 +52,7 @@
         IntegerStamp valueStamp = (IntegerStamp) getValue().stamp();
         int min;
         int max;
-        long mask = IntegerStamp.defaultMask(valueStamp.getBits());
+        long mask = CodeUtil.mask(valueStamp.getBits());
         int firstAlwaysSetBit = scan(valueStamp.downMask() & mask);
         if (firstAlwaysSetBit == -1) {
             int lastMaybeSetBit = BitScanReverseNode.scan(valueStamp.upMask() & mask);
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanReverseNode.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanReverseNode.java	Wed Sep 24 16:22:22 2014 -0700
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.replacements.nodes;
 
+import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graph.spi.*;
@@ -51,7 +52,7 @@
         IntegerStamp valueStamp = (IntegerStamp) getValue().stamp();
         int min;
         int max;
-        long mask = IntegerStamp.defaultMask(valueStamp.getBits());
+        long mask = CodeUtil.mask(valueStamp.getBits());
         int lastAlwaysSetBit = scan(valueStamp.downMask() & mask);
         if (lastAlwaysSetBit == -1) {
             min = -1;
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ReverseBytesNode.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ReverseBytesNode.java	Wed Sep 24 16:22:22 2014 -0700
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.replacements.nodes;
 
+import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graph.spi.*;
@@ -29,7 +30,6 @@
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.type.*;
 
 @NodeInfo
 public class ReverseBytesNode extends UnaryNode implements LIRLowerable {
@@ -48,10 +48,10 @@
         IntegerStamp valueStamp = (IntegerStamp) getValue().stamp();
         Stamp newStamp;
         if (getKind() == Kind.Int) {
-            long mask = IntegerStamp.defaultMask(Kind.Int.getBitCount());
-            newStamp = StampTool.stampForMask(valueStamp.getBits(), reverse((int) valueStamp.downMask()) & mask, reverse((int) valueStamp.upMask()) & mask);
+            long mask = CodeUtil.mask(Kind.Int.getBitCount());
+            newStamp = IntegerStamp.stampForMask(valueStamp.getBits(), reverse((int) valueStamp.downMask()) & mask, reverse((int) valueStamp.upMask()) & mask);
         } else if (getKind() == Kind.Long) {
-            newStamp = StampTool.stampForMask(valueStamp.getBits(), reverse(valueStamp.downMask()), reverse(valueStamp.upMask()));
+            newStamp = IntegerStamp.stampForMask(valueStamp.getBits(), reverse(valueStamp.downMask()), reverse(valueStamp.upMask()));
         } else {
             return false;
         }
--- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotFrameInstance.java	Wed Sep 24 16:13:34 2014 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,186 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.truffle.hotspot;
-
-import java.lang.reflect.*;
-
-import com.oracle.graal.api.code.stack.*;
-import com.oracle.graal.compiler.common.*;
-import com.oracle.graal.truffle.*;
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.CompilerDirectives.SlowPath;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-
-public abstract class HotSpotFrameInstance implements FrameInstance {
-
-    protected final InspectedFrame stackFrame;
-
-    public HotSpotFrameInstance(InspectedFrame stackFrame) {
-        this.stackFrame = stackFrame;
-    }
-
-    protected abstract int getNotifyIndex();
-
-    protected abstract int getFrameIndex();
-
-    @SlowPath
-    public Frame getFrame(FrameAccess access, boolean slowPath) {
-        if (access == FrameAccess.NONE) {
-            return null;
-        }
-        if (!slowPath && getNotifyIndex() != -1) {
-            MaterializedFrameNotify notify = (MaterializedFrameNotify) stackFrame.getLocal(getNotifyIndex());
-            if (notify != null) {
-                if (access.ordinal() > notify.getOutsideFrameAccess().ordinal()) {
-                    notify.setOutsideFrameAccess(access);
-                }
-                if (stackFrame.isVirtual(getFrameIndex())) {
-                    stackFrame.materializeVirtualObjects(true);
-                }
-            }
-        }
-        switch (access) {
-            case READ_ONLY: {
-                Frame frame = (Frame) stackFrame.getLocal(getFrameIndex());
-                // assert that it is really used read only
-                assert (frame = new ReadOnlyFrame(frame)) != null;
-                return frame;
-            }
-            case READ_WRITE:
-            case MATERIALIZE:
-                if (stackFrame.isVirtual(getFrameIndex())) {
-                    stackFrame.materializeVirtualObjects(false);
-                }
-                return (Frame) stackFrame.getLocal(getFrameIndex());
-            default:
-                throw GraalInternalError.unimplemented();
-        }
-    }
-
-    public boolean isVirtualFrame() {
-        return stackFrame.isVirtual(getFrameIndex());
-    }
-
-    public abstract CallTarget getCallTarget();
-
-    public abstract Node getCallNode();
-
-    /**
-     * This class represents a frame that is taken from the
-     * {@link OptimizedDirectCallNode#callProxy(MaterializedFrameNotify, CallTarget, VirtualFrame, Object[], boolean, boolean)}
-     * method.
-     */
-    public static final class CallNodeFrame extends HotSpotFrameInstance {
-        public static final Method METHOD;
-        static {
-            try {
-                METHOD = OptimizedDirectCallNode.class.getDeclaredMethod("callProxy", MaterializedFrameNotify.class, CallTarget.class, VirtualFrame.class, Object[].class, boolean.class, boolean.class);
-            } catch (NoSuchMethodException | SecurityException e) {
-                throw new GraalInternalError(e);
-            }
-        }
-        private static final int NOTIFY_INDEX = 0;
-        private static final int FRAME_INDEX = 2;
-
-        public CallNodeFrame(InspectedFrame stackFrame) {
-            super(stackFrame);
-        }
-
-        @Override
-        protected int getNotifyIndex() {
-            return NOTIFY_INDEX;
-        }
-
-        @Override
-        protected int getFrameIndex() {
-            return FRAME_INDEX;
-        }
-
-        @Override
-        public CallTarget getCallTarget() {
-            return getCallNode().getRootNode().getCallTarget();
-        }
-
-        @Override
-        public Node getCallNode() {
-            Object receiver = stackFrame.getLocal(getNotifyIndex());
-            if (receiver instanceof DirectCallNode || receiver instanceof IndirectCallNode) {
-                return (Node) receiver;
-            }
-            return null;
-        }
-    }
-
-    /**
-     * This class represents a frame that is taken from the {@link OptimizedCallTarget#callProxy}
-     * method.
-     */
-    public static final class CallTargetFrame extends HotSpotFrameInstance {
-        public static final Method METHOD;
-        static {
-            try {
-                METHOD = OptimizedCallTarget.class.getDeclaredMethod("callProxy", VirtualFrame.class);
-            } catch (NoSuchMethodException | SecurityException e) {
-                throw new GraalInternalError(e);
-            }
-        }
-        private static final int NOTIFY_INDEX = -1;
-        private static final int CALL_TARGET_INDEX = 0;
-        private static final int FRAME_INDEX = 1;
-        private final boolean currentFrame;
-
-        public CallTargetFrame(InspectedFrame stackFrame, boolean currentFrame) {
-            super(stackFrame);
-            this.currentFrame = currentFrame;
-        }
-
-        @Override
-        public Frame getFrame(FrameAccess access, boolean slowPath) {
-            if (!slowPath && currentFrame) {
-                throw new UnsupportedOperationException("cannot access current frame as fast path");
-            }
-            return super.getFrame(access, slowPath);
-        }
-
-        @Override
-        protected int getNotifyIndex() {
-            return NOTIFY_INDEX;
-        }
-
-        @Override
-        protected int getFrameIndex() {
-            return FRAME_INDEX;
-        }
-
-        @Override
-        public CallTarget getCallTarget() {
-            return (CallTarget) stackFrame.getLocal(CALL_TARGET_INDEX);
-        }
-
-        @Override
-        public Node getCallNode() {
-            return null;
-        }
-    }
-}
--- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java	Wed Sep 24 16:22:22 2014 -0700
@@ -34,7 +34,6 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.code.CallingConvention.Type;
-import com.oracle.graal.api.code.stack.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.compiler.*;
@@ -57,15 +56,12 @@
 import com.oracle.graal.truffle.*;
 import com.oracle.graal.word.*;
 import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.CompilerDirectives.SlowPath;
-import com.oracle.truffle.api.frame.*;
 import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.api.nodes.Node;
 
 /**
  * Implementation of the Truffle runtime when running on top of Graal.
  */
-public final class HotSpotTruffleRuntime implements GraalTruffleRuntime {
+public final class HotSpotTruffleRuntime extends GraalTruffleRuntime {
 
     public static HotSpotTruffleRuntime makeInstance() {
         return new HotSpotTruffleRuntime();
@@ -73,23 +69,14 @@
 
     private TruffleCompilerImpl truffleCompiler;
     private Replacements truffleReplacements;
-    private StackIntrospection stackIntrospection;
-    private ArrayList<String> includes;
-    private ArrayList<String> excludes;
     private Map<OptimizedCallTarget, Future<?>> compilations = newIdentityMap();
     private final ThreadPoolExecutor compileQueue;
 
-    private final ResolvedJavaMethod[] callNodeMethod;
-    private final ResolvedJavaMethod[] callTargetMethod;
-    private final ResolvedJavaMethod[] anyFrameMethod;
     private final Map<RootCallTarget, Void> callTargets = Collections.synchronizedMap(new WeakHashMap<RootCallTarget, Void>());
 
     private HotSpotTruffleRuntime() {
         installOptimizedCallTargetCallMethod();
-
-        callNodeMethod = new ResolvedJavaMethod[]{getGraalProviders().getMetaAccess().lookupJavaMethod(HotSpotFrameInstance.CallNodeFrame.METHOD)};
-        callTargetMethod = new ResolvedJavaMethod[]{getGraalProviders().getMetaAccess().lookupJavaMethod(HotSpotFrameInstance.CallTargetFrame.METHOD)};
-        anyFrameMethod = new ResolvedJavaMethod[]{callNodeMethod[0], callTargetMethod[0]};
+        lookupCallMethods(getGraalProviders().getMetaAccess());
 
         // Create compilation queue.
         CompilerThreadFactory factory = new CompilerThreadFactory("TruffleCompilerThread", new CompilerThreadFactory.DebugConfigAccess() {
@@ -106,10 +93,12 @@
         compileQueue = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), factory);
     }
 
+    @Override
     public String getName() {
         return "Graal Truffle Runtime";
     }
 
+    @Override
     public RootCallTarget createCallTarget(RootNode rootNode) {
         CompilationPolicy compilationPolicy;
         if (acceptForCompilation(rootNode)) {
@@ -123,50 +112,7 @@
         return target;
     }
 
-    public LoopNode createLoopNode(RepeatingNode repeating) {
-        if (!(repeating instanceof Node)) {
-            throw new IllegalArgumentException("Repeating node must be of type Node.");
-        }
-        return new OptimizedLoopNode(repeating);
-    }
-
-    public DirectCallNode createDirectCallNode(CallTarget target) {
-        if (target instanceof OptimizedCallTarget) {
-            return new OptimizedDirectCallNode((OptimizedCallTarget) target);
-        } else {
-            throw new IllegalStateException(String.format("Unexpected call target class %s!", target.getClass()));
-        }
-    }
-
-    public IndirectCallNode createIndirectCallNode() {
-        return new OptimizedIndirectCallNode();
-    }
-
     @Override
-    public VirtualFrame createVirtualFrame(Object[] arguments, FrameDescriptor frameDescriptor) {
-        return OptimizedCallTarget.createFrame(frameDescriptor, arguments);
-    }
-
-    @Override
-    public MaterializedFrame createMaterializedFrame(Object[] arguments) {
-        return createMaterializedFrame(arguments, new FrameDescriptor());
-    }
-
-    @Override
-    public MaterializedFrame createMaterializedFrame(Object[] arguments, FrameDescriptor frameDescriptor) {
-        return new FrameWithoutBoxing(frameDescriptor, arguments);
-    }
-
-    @Override
-    public Assumption createAssumption() {
-        return createAssumption(null);
-    }
-
-    @Override
-    public Assumption createAssumption(String name) {
-        return new OptimizedAssumption(name);
-    }
-
     public Replacements getReplacements() {
         if (truffleReplacements == null) {
             truffleReplacements = HotSpotTruffleReplacements.makeInstance();
@@ -174,45 +120,6 @@
         return truffleReplacements;
     }
 
-    private boolean acceptForCompilation(RootNode rootNode) {
-        if (TruffleCompileOnly.getValue() != null) {
-            if (includes == null) {
-                parseCompileOnly();
-            }
-
-            String name = rootNode.toString();
-            boolean included = includes.isEmpty();
-            for (int i = 0; !included && i < includes.size(); i++) {
-                if (name.contains(includes.get(i))) {
-                    included = true;
-                }
-            }
-            if (!included) {
-                return false;
-            }
-            for (String exclude : excludes) {
-                if (name.contains(exclude)) {
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
-
-    private void parseCompileOnly() {
-        includes = new ArrayList<>();
-        excludes = new ArrayList<>();
-
-        String[] items = TruffleCompileOnly.getValue().split(",");
-        for (String item : items) {
-            if (item.startsWith("~")) {
-                excludes.add(item.substring(1));
-            } else {
-                includes.add(item);
-            }
-        }
-    }
-
     public static void installOptimizedCallTargetCallMethod() {
         Providers providers = getGraalProviders();
         MetaAccessProvider metaAccess = providers.getMetaAccess();
@@ -272,53 +179,7 @@
         }
     }
 
-    @SlowPath
     @Override
-    public <T> T iterateFrames(FrameInstanceVisitor<T> visitor) {
-        initStackIntrospection();
-
-        InspectedFrameVisitor<T> inspectedFrameVisitor = new InspectedFrameVisitor<T>() {
-            private boolean skipNext = false;
-
-            public T visitFrame(InspectedFrame frame) {
-                if (skipNext) {
-                    assert frame.isMethod(callTargetMethod[0]);
-                    skipNext = false;
-                    return null;
-                }
-
-                if (frame.isMethod(callNodeMethod[0])) {
-                    skipNext = true;
-                    return visitor.visitFrame(new HotSpotFrameInstance.CallNodeFrame(frame));
-                } else {
-                    assert frame.isMethod(callTargetMethod[0]);
-                    return visitor.visitFrame(new HotSpotFrameInstance.CallTargetFrame(frame, false));
-                }
-
-            }
-        };
-        return stackIntrospection.iterateFrames(anyFrameMethod, anyFrameMethod, 1, inspectedFrameVisitor);
-    }
-
-    private void initStackIntrospection() {
-        if (stackIntrospection == null) {
-            stackIntrospection = Graal.getRequiredCapability(StackIntrospection.class);
-        }
-    }
-
-    @Override
-    public FrameInstance getCallerFrame() {
-        return iterateFrames(frame -> frame);
-    }
-
-    @SlowPath
-    @Override
-    public FrameInstance getCurrentFrame() {
-        initStackIntrospection();
-
-        return stackIntrospection.iterateFrames(callTargetMethod, callTargetMethod, 0, frame -> new HotSpotFrameInstance.CallTargetFrame(frame, true));
-    }
-
     public void compile(OptimizedCallTarget optimizedCallTarget, boolean mayBeAsynchronous) {
         if (truffleCompiler == null) {
             truffleCompiler = new TruffleCompilerImpl();
@@ -346,6 +207,7 @@
         }
     }
 
+    @Override
     public boolean cancelInstalledTask(OptimizedCallTarget optimizedCallTarget) {
         Future<?> codeTask = this.compilations.get(optimizedCallTarget);
         if (codeTask != null && isCompiling(optimizedCallTarget)) {
@@ -355,6 +217,7 @@
         return false;
     }
 
+    @Override
     public void waitForCompilation(OptimizedCallTarget optimizedCallTarget, long timeout) throws ExecutionException, TimeoutException {
         Future<?> codeTask = this.compilations.get(optimizedCallTarget);
         if (codeTask != null && isCompiling(optimizedCallTarget)) {
@@ -366,6 +229,7 @@
         }
     }
 
+    @Override
     public boolean isCompiling(OptimizedCallTarget optimizedCallTarget) {
         Future<?> codeTask = this.compilations.get(optimizedCallTarget);
         if (codeTask != null) {
@@ -378,10 +242,12 @@
         return false;
     }
 
+    @Override
     public void invalidateInstalledCode(OptimizedCallTarget optimizedCallTarget) {
         HotSpotGraalRuntime.runtime().getCompilerToVM().invalidateInstalledCode(optimizedCallTarget);
     }
 
+    @Override
     public void reinstallStubs() {
         installOptimizedCallTargetCallMethod();
     }
@@ -391,6 +257,7 @@
         return Collections.unmodifiableSet(callTargets.keySet());
     }
 
+    @Override
     public void notifyTransferToInterpreter() {
         CompilerAsserts.neverPartOfCompilation();
         if (TraceTruffleTransferToInterpreter.getValue()) {
--- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/ReadOnlyFrame.java	Wed Sep 24 16:13:34 2014 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,134 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.truffle.hotspot;
-
-import com.oracle.graal.compiler.common.*;
-import com.oracle.truffle.api.frame.*;
-
-class ReadOnlyFrame implements Frame {
-    private final Frame delegate;
-
-    public ReadOnlyFrame(Frame delegate) {
-        this.delegate = delegate;
-    }
-
-    public FrameDescriptor getFrameDescriptor() {
-        return delegate.getFrameDescriptor();
-    }
-
-    public Object[] getArguments() {
-        return delegate.getArguments().clone();
-    }
-
-    public Object getObject(FrameSlot slot) throws FrameSlotTypeException {
-        return delegate.getObject(slot);
-    }
-
-    public void setObject(FrameSlot slot, Object value) {
-        throw GraalInternalError.shouldNotReachHere();
-    }
-
-    public byte getByte(FrameSlot slot) throws FrameSlotTypeException {
-        return delegate.getByte(slot);
-    }
-
-    public void setByte(FrameSlot slot, byte value) {
-        throw GraalInternalError.shouldNotReachHere();
-    }
-
-    public boolean getBoolean(FrameSlot slot) throws FrameSlotTypeException {
-        return delegate.getBoolean(slot);
-    }
-
-    public void setBoolean(FrameSlot slot, boolean value) {
-        throw GraalInternalError.shouldNotReachHere();
-    }
-
-    public int getInt(FrameSlot slot) throws FrameSlotTypeException {
-        return delegate.getInt(slot);
-    }
-
-    public void setInt(FrameSlot slot, int value) {
-        throw GraalInternalError.shouldNotReachHere();
-    }
-
-    public long getLong(FrameSlot slot) throws FrameSlotTypeException {
-        return delegate.getLong(slot);
-    }
-
-    public void setLong(FrameSlot slot, long value) {
-        throw GraalInternalError.shouldNotReachHere();
-    }
-
-    public float getFloat(FrameSlot slot) throws FrameSlotTypeException {
-        return delegate.getFloat(slot);
-    }
-
-    public void setFloat(FrameSlot slot, float value) {
-        throw GraalInternalError.shouldNotReachHere();
-    }
-
-    public double getDouble(FrameSlot slot) throws FrameSlotTypeException {
-        return delegate.getDouble(slot);
-    }
-
-    public void setDouble(FrameSlot slot, double value) {
-        throw GraalInternalError.shouldNotReachHere();
-    }
-
-    public Object getValue(FrameSlot slot) {
-        return delegate.getValue(slot);
-    }
-
-    public MaterializedFrame materialize() {
-        throw GraalInternalError.shouldNotReachHere();
-    }
-
-    public boolean isObject(FrameSlot slot) {
-        return delegate.isObject(slot);
-    }
-
-    public boolean isByte(FrameSlot slot) {
-        return delegate.isByte(slot);
-    }
-
-    public boolean isBoolean(FrameSlot slot) {
-        return delegate.isBoolean(slot);
-    }
-
-    public boolean isInt(FrameSlot slot) {
-        return delegate.isInt(slot);
-    }
-
-    public boolean isLong(FrameSlot slot) {
-        return delegate.isLong(slot);
-    }
-
-    public boolean isFloat(FrameSlot slot) {
-        return delegate.isFloat(slot);
-    }
-
-    public boolean isDouble(FrameSlot slot) {
-        return delegate.isDouble(slot);
-    }
-}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalFrameInstance.java	Wed Sep 24 16:22:22 2014 -0700
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.truffle;
+
+import java.lang.reflect.*;
+
+import com.oracle.graal.api.code.stack.*;
+import com.oracle.graal.compiler.common.*;
+import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.CompilerDirectives.SlowPath;
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.nodes.*;
+
+public abstract class GraalFrameInstance implements FrameInstance {
+
+    protected final InspectedFrame stackFrame;
+
+    public GraalFrameInstance(InspectedFrame stackFrame) {
+        this.stackFrame = stackFrame;
+    }
+
+    protected abstract int getNotifyIndex();
+
+    protected abstract int getFrameIndex();
+
+    @SlowPath
+    public Frame getFrame(FrameAccess access, boolean slowPath) {
+        if (access == FrameAccess.NONE) {
+            return null;
+        }
+        if (!slowPath && getNotifyIndex() != -1) {
+            MaterializedFrameNotify notify = (MaterializedFrameNotify) stackFrame.getLocal(getNotifyIndex());
+            if (notify != null) {
+                if (access.ordinal() > notify.getOutsideFrameAccess().ordinal()) {
+                    notify.setOutsideFrameAccess(access);
+                }
+                if (stackFrame.isVirtual(getFrameIndex())) {
+                    stackFrame.materializeVirtualObjects(true);
+                }
+            }
+        }
+        switch (access) {
+            case READ_ONLY: {
+                Frame frame = (Frame) stackFrame.getLocal(getFrameIndex());
+                // assert that it is really used read only
+                assert (frame = new ReadOnlyFrame(frame)) != null;
+                return frame;
+            }
+            case READ_WRITE:
+            case MATERIALIZE:
+                if (stackFrame.isVirtual(getFrameIndex())) {
+                    stackFrame.materializeVirtualObjects(false);
+                }
+                return (Frame) stackFrame.getLocal(getFrameIndex());
+            default:
+                throw GraalInternalError.unimplemented();
+        }
+    }
+
+    public boolean isVirtualFrame() {
+        return stackFrame.isVirtual(getFrameIndex());
+    }
+
+    public abstract CallTarget getCallTarget();
+
+    public abstract Node getCallNode();
+
+    /**
+     * This class represents a frame that is taken from the
+     * {@link OptimizedDirectCallNode#callProxy(MaterializedFrameNotify, CallTarget, VirtualFrame, Object[], boolean, boolean)}
+     * method.
+     */
+    public static final class CallNodeFrame extends GraalFrameInstance {
+        public static final Method METHOD;
+        static {
+            try {
+                METHOD = OptimizedDirectCallNode.class.getDeclaredMethod("callProxy", MaterializedFrameNotify.class, CallTarget.class, VirtualFrame.class, Object[].class, boolean.class, boolean.class);
+            } catch (NoSuchMethodException | SecurityException e) {
+                throw new GraalInternalError(e);
+            }
+        }
+        private static final int NOTIFY_INDEX = 0;
+        private static final int FRAME_INDEX = 2;
+
+        public CallNodeFrame(InspectedFrame stackFrame) {
+            super(stackFrame);
+        }
+
+        @Override
+        protected int getNotifyIndex() {
+            return NOTIFY_INDEX;
+        }
+
+        @Override
+        protected int getFrameIndex() {
+            return FRAME_INDEX;
+        }
+
+        @Override
+        public CallTarget getCallTarget() {
+            return getCallNode().getRootNode().getCallTarget();
+        }
+
+        @Override
+        public Node getCallNode() {
+            Object receiver = stackFrame.getLocal(getNotifyIndex());
+            if (receiver instanceof DirectCallNode || receiver instanceof IndirectCallNode) {
+                return (Node) receiver;
+            }
+            return null;
+        }
+    }
+
+    /**
+     * This class represents a frame that is taken from the {@link OptimizedCallTarget#callProxy}
+     * method.
+     */
+    public static final class CallTargetFrame extends GraalFrameInstance {
+        public static final Method METHOD;
+        static {
+            try {
+                METHOD = OptimizedCallTarget.class.getDeclaredMethod("callProxy", VirtualFrame.class);
+            } catch (NoSuchMethodException | SecurityException e) {
+                throw new GraalInternalError(e);
+            }
+        }
+        private static final int NOTIFY_INDEX = -1;
+        private static final int CALL_TARGET_INDEX = 0;
+        private static final int FRAME_INDEX = 1;
+        private final boolean currentFrame;
+
+        public CallTargetFrame(InspectedFrame stackFrame, boolean currentFrame) {
+            super(stackFrame);
+            this.currentFrame = currentFrame;
+        }
+
+        @Override
+        public Frame getFrame(FrameAccess access, boolean slowPath) {
+            if (!slowPath && currentFrame) {
+                throw new UnsupportedOperationException("cannot access current frame as fast path");
+            }
+            return super.getFrame(access, slowPath);
+        }
+
+        @Override
+        protected int getNotifyIndex() {
+            return NOTIFY_INDEX;
+        }
+
+        @Override
+        protected int getFrameIndex() {
+            return FRAME_INDEX;
+        }
+
+        @Override
+        public CallTarget getCallTarget() {
+            return (CallTarget) stackFrame.getLocal(CALL_TARGET_INDEX);
+        }
+
+        @Override
+        public Node getCallNode() {
+            return null;
+        }
+    }
+}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java	Wed Sep 24 16:22:22 2014 -0700
@@ -22,24 +22,180 @@
  */
 package com.oracle.graal.truffle;
 
+import static com.oracle.graal.truffle.TruffleCompilerOptions.*;
+
+import java.util.*;
 import java.util.concurrent.*;
 
+import com.oracle.graal.api.code.stack.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.CompilerDirectives.SlowPath;
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.nodes.*;
 
-public interface GraalTruffleRuntime extends TruffleRuntime {
+public abstract class GraalTruffleRuntime implements TruffleRuntime {
+
+    private ArrayList<String> includes;
+    private ArrayList<String> excludes;
+
+    private StackIntrospection stackIntrospection;
+    protected ResolvedJavaMethod[] callNodeMethod;
+    protected ResolvedJavaMethod[] callTargetMethod;
+    protected ResolvedJavaMethod[] anyFrameMethod;
+
+    protected void lookupCallMethods(MetaAccessProvider metaAccess) {
+        callNodeMethod = new ResolvedJavaMethod[]{metaAccess.lookupJavaMethod(GraalFrameInstance.CallNodeFrame.METHOD)};
+        callTargetMethod = new ResolvedJavaMethod[]{metaAccess.lookupJavaMethod(GraalFrameInstance.CallTargetFrame.METHOD)};
+        anyFrameMethod = new ResolvedJavaMethod[]{callNodeMethod[0], callTargetMethod[0]};
+    }
+
+    @Override
+    public LoopNode createLoopNode(RepeatingNode repeating) {
+        if (!(repeating instanceof Node)) {
+            throw new IllegalArgumentException("Repeating node must be of type Node.");
+        }
+        return new OptimizedLoopNode(repeating);
+    }
+
+    @Override
+    public DirectCallNode createDirectCallNode(CallTarget target) {
+        if (target instanceof OptimizedCallTarget) {
+            return new OptimizedDirectCallNode((OptimizedCallTarget) target);
+        } else {
+            throw new IllegalStateException(String.format("Unexpected call target class %s!", target.getClass()));
+        }
+    }
 
-    Replacements getReplacements();
+    @Override
+    public IndirectCallNode createIndirectCallNode() {
+        return new OptimizedIndirectCallNode();
+    }
+
+    @Override
+    public VirtualFrame createVirtualFrame(Object[] arguments, FrameDescriptor frameDescriptor) {
+        return OptimizedCallTarget.createFrame(frameDescriptor, arguments);
+    }
+
+    @Override
+    public MaterializedFrame createMaterializedFrame(Object[] arguments) {
+        return createMaterializedFrame(arguments, new FrameDescriptor());
+    }
+
+    @Override
+    public MaterializedFrame createMaterializedFrame(Object[] arguments, FrameDescriptor frameDescriptor) {
+        return new FrameWithoutBoxing(frameDescriptor, arguments);
+    }
 
-    void compile(OptimizedCallTarget optimizedCallTarget, boolean mayBeAsynchronous);
+    @Override
+    public Assumption createAssumption() {
+        return createAssumption(null);
+    }
+
+    @Override
+    public Assumption createAssumption(String name) {
+        return new OptimizedAssumption(name);
+    }
 
-    boolean cancelInstalledTask(OptimizedCallTarget optimizedCallTarget);
+    @SlowPath
+    @Override
+    public <T> T iterateFrames(FrameInstanceVisitor<T> visitor) {
+        initStackIntrospection();
+
+        InspectedFrameVisitor<T> inspectedFrameVisitor = new InspectedFrameVisitor<T>() {
+            private boolean skipNext = false;
+
+            public T visitFrame(InspectedFrame frame) {
+                if (skipNext) {
+                    assert frame.isMethod(callTargetMethod[0]);
+                    skipNext = false;
+                    return null;
+                }
 
-    void waitForCompilation(OptimizedCallTarget optimizedCallTarget, long timeout) throws ExecutionException, TimeoutException;
+                if (frame.isMethod(callNodeMethod[0])) {
+                    skipNext = true;
+                    return visitor.visitFrame(new GraalFrameInstance.CallNodeFrame(frame));
+                } else {
+                    assert frame.isMethod(callTargetMethod[0]);
+                    return visitor.visitFrame(new GraalFrameInstance.CallTargetFrame(frame, false));
+                }
+
+            }
+        };
+        return stackIntrospection.iterateFrames(anyFrameMethod, anyFrameMethod, 1, inspectedFrameVisitor);
+    }
+
+    private void initStackIntrospection() {
+        if (stackIntrospection == null) {
+            stackIntrospection = Graal.getRequiredCapability(StackIntrospection.class);
+        }
+    }
 
-    boolean isCompiling(OptimizedCallTarget optimizedCallTarget);
+    @Override
+    public FrameInstance getCallerFrame() {
+        return iterateFrames(frame -> frame);
+    }
+
+    @SlowPath
+    @Override
+    public FrameInstance getCurrentFrame() {
+        initStackIntrospection();
+
+        return stackIntrospection.iterateFrames(callTargetMethod, callTargetMethod, 0, frame -> new GraalFrameInstance.CallTargetFrame(frame, true));
+    }
+
+    protected boolean acceptForCompilation(RootNode rootNode) {
+        if (TruffleCompileOnly.getValue() != null) {
+            if (includes == null) {
+                parseCompileOnly();
+            }
 
-    void invalidateInstalledCode(OptimizedCallTarget optimizedCallTarget);
+            String name = rootNode.toString();
+            boolean included = includes.isEmpty();
+            for (int i = 0; !included && i < includes.size(); i++) {
+                if (name.contains(includes.get(i))) {
+                    included = true;
+                }
+            }
+            if (!included) {
+                return false;
+            }
+            for (String exclude : excludes) {
+                if (name.contains(exclude)) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    protected void parseCompileOnly() {
+        includes = new ArrayList<>();
+        excludes = new ArrayList<>();
 
-    void reinstallStubs();
+        String[] items = TruffleCompileOnly.getValue().split(",");
+        for (String item : items) {
+            if (item.startsWith("~")) {
+                excludes.add(item.substring(1));
+            } else {
+                includes.add(item);
+            }
+        }
+    }
+
+    public abstract Replacements getReplacements();
+
+    public abstract void compile(OptimizedCallTarget optimizedCallTarget, boolean mayBeAsynchronous);
+
+    public abstract boolean cancelInstalledTask(OptimizedCallTarget optimizedCallTarget);
+
+    public abstract void waitForCompilation(OptimizedCallTarget optimizedCallTarget, long timeout) throws ExecutionException, TimeoutException;
+
+    public abstract boolean isCompiling(OptimizedCallTarget optimizedCallTarget);
+
+    public abstract void invalidateInstalledCode(OptimizedCallTarget optimizedCallTarget);
+
+    public abstract void reinstallStubs();
 }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java	Wed Sep 24 16:22:22 2014 -0700
@@ -118,12 +118,12 @@
             profiledArgumentTypesAssumption.invalidate();
             profiledArgumentTypes = null;
         }
-        return callBoundary(args);
+        return doInvoke(args);
     }
 
     public Object callDirect(Object... args) {
         profileArguments(args);
-        Object result = callBoundary(args);
+        Object result = doInvoke(args);
         Class<?> klass = profiledReturnType;
         if (klass != null && CompilerDirectives.inCompiledCode() && profiledReturnTypeAssumption.isValid()) {
             result = CompilerDirectives.unsafeCast(result, klass, true, true);
@@ -191,8 +191,12 @@
         }
     }
 
+    protected Object doInvoke(Object[] args) {
+        return callBoundary(args);
+    }
+
     @TruffleCallBoundary
-    private Object callBoundary(Object[] args) {
+    protected final Object callBoundary(Object[] args) {
         if (CompilerDirectives.inInterpreter()) {
             // We are called and we are still in Truffle interpreter mode.
             interpreterCall();
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTargetLog.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTargetLog.java	Wed Sep 24 16:22:22 2014 -0700
@@ -182,7 +182,7 @@
         log(0, "opt fail", callSite.toString(), properties);
     }
 
-    static void logOptimizingDone(OptimizedCallTarget target, Map<String, Object> properties) {
+    public static void logOptimizingDone(OptimizedCallTarget target, Map<String, Object> properties) {
         if (TraceTruffleCompilationDetails.getValue() || TraceTruffleCompilation.getValue()) {
             log(0, "opt done", target.toString(), properties);
         }
@@ -223,7 +223,7 @@
         }
     }
 
-    static void addASTSizeProperty(OptimizedCallTarget target, Map<String, Object> properties) {
+    public static void addASTSizeProperty(OptimizedCallTarget target, Map<String, Object> properties) {
         int polymorphicCount = NodeUtil.countNodes(target.getRootNode(), new NodeCountFilter() {
             public boolean isCounted(Node node) {
                 return node.getCost() == NodeCost.POLYMORPHIC;
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallUtils.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallUtils.java	Wed Sep 24 16:22:22 2014 -0700
@@ -29,7 +29,7 @@
 import com.oracle.truffle.api.nodes.NodeUtil.NodeCountFilter;
 import com.oracle.truffle.api.nodes.NodeUtil.NodeField;
 
-class OptimizedCallUtils {
+public class OptimizedCallUtils {
 
     public static int countCalls(OptimizedCallTarget target) {
         return NodeUtil.countNodes(target.getRootNode(), new NodeCountFilter() {
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Wed Sep 24 16:22:22 2014 -0700
@@ -222,7 +222,7 @@
 
                         StructuredGraph inlineGraph = replacements.getMethodSubstitution(methodCallTargetNode.targetMethod());
                         if (inlineGraph == null && !methodCallTargetNode.targetMethod().isNative() && methodCallTargetNode.targetMethod().canBeInlined()) {
-                            inlineGraph = parseGraph(methodCallTargetNode.targetMethod(), methodCallTargetNode.arguments(), assumptions, phaseContext, false);
+                            inlineGraph = parseGraph(methodCallTargetNode.targetMethod(), methodCallTargetNode.arguments(), assumptions, phaseContext);
                         }
 
                         if (inlineGraph != null) {
@@ -264,10 +264,9 @@
         }
     }
 
-    private StructuredGraph parseGraph(final ResolvedJavaMethod targetMethod, final NodeInputList<ValueNode> arguments, final Assumptions assumptions, final PhaseContext phaseContext,
-                    boolean ignoreSlowPath) {
+    private StructuredGraph parseGraph(final ResolvedJavaMethod targetMethod, final NodeInputList<ValueNode> arguments, final Assumptions assumptions, final PhaseContext phaseContext) {
 
-        StructuredGraph graph = truffleCache.lookup(targetMethod, arguments, assumptions, canonicalizer, ignoreSlowPath);
+        StructuredGraph graph = truffleCache.lookup(targetMethod, arguments, assumptions, canonicalizer);
 
         if (graph != null && targetMethod.getAnnotation(ExplodeLoop.class) != null) {
             assert graph.hasLoops() : graph + " does not contain a loop";
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/ReadOnlyFrame.java	Wed Sep 24 16:22:22 2014 -0700
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.truffle;
+
+import com.oracle.graal.compiler.common.*;
+import com.oracle.truffle.api.frame.*;
+
+class ReadOnlyFrame implements Frame {
+    private final Frame delegate;
+
+    public ReadOnlyFrame(Frame delegate) {
+        this.delegate = delegate;
+    }
+
+    public FrameDescriptor getFrameDescriptor() {
+        return delegate.getFrameDescriptor();
+    }
+
+    public Object[] getArguments() {
+        return delegate.getArguments().clone();
+    }
+
+    public Object getObject(FrameSlot slot) throws FrameSlotTypeException {
+        return delegate.getObject(slot);
+    }
+
+    public void setObject(FrameSlot slot, Object value) {
+        throw GraalInternalError.shouldNotReachHere();
+    }
+
+    public byte getByte(FrameSlot slot) throws FrameSlotTypeException {
+        return delegate.getByte(slot);
+    }
+
+    public void setByte(FrameSlot slot, byte value) {
+        throw GraalInternalError.shouldNotReachHere();
+    }
+
+    public boolean getBoolean(FrameSlot slot) throws FrameSlotTypeException {
+        return delegate.getBoolean(slot);
+    }
+
+    public void setBoolean(FrameSlot slot, boolean value) {
+        throw GraalInternalError.shouldNotReachHere();
+    }
+
+    public int getInt(FrameSlot slot) throws FrameSlotTypeException {
+        return delegate.getInt(slot);
+    }
+
+    public void setInt(FrameSlot slot, int value) {
+        throw GraalInternalError.shouldNotReachHere();
+    }
+
+    public long getLong(FrameSlot slot) throws FrameSlotTypeException {
+        return delegate.getLong(slot);
+    }
+
+    public void setLong(FrameSlot slot, long value) {
+        throw GraalInternalError.shouldNotReachHere();
+    }
+
+    public float getFloat(FrameSlot slot) throws FrameSlotTypeException {
+        return delegate.getFloat(slot);
+    }
+
+    public void setFloat(FrameSlot slot, float value) {
+        throw GraalInternalError.shouldNotReachHere();
+    }
+
+    public double getDouble(FrameSlot slot) throws FrameSlotTypeException {
+        return delegate.getDouble(slot);
+    }
+
+    public void setDouble(FrameSlot slot, double value) {
+        throw GraalInternalError.shouldNotReachHere();
+    }
+
+    public Object getValue(FrameSlot slot) {
+        return delegate.getValue(slot);
+    }
+
+    public MaterializedFrame materialize() {
+        throw GraalInternalError.shouldNotReachHere();
+    }
+
+    public boolean isObject(FrameSlot slot) {
+        return delegate.isObject(slot);
+    }
+
+    public boolean isByte(FrameSlot slot) {
+        return delegate.isByte(slot);
+    }
+
+    public boolean isBoolean(FrameSlot slot) {
+        return delegate.isBoolean(slot);
+    }
+
+    public boolean isInt(FrameSlot slot) {
+        return delegate.isInt(slot);
+    }
+
+    public boolean isLong(FrameSlot slot) {
+        return delegate.isLong(slot);
+    }
+
+    public boolean isFloat(FrameSlot slot) {
+        return delegate.isFloat(slot);
+    }
+
+    public boolean isDouble(FrameSlot slot) {
+        return delegate.isDouble(slot);
+    }
+}
\ No newline at end of file
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java	Wed Sep 24 16:22:22 2014 -0700
@@ -37,8 +37,6 @@
 
     /**
      * Returns a cached graph for a method with given arguments.
-     *
-     * @param ignoreSlowPath TODO
      */
-    StructuredGraph lookup(final ResolvedJavaMethod method, final NodeInputList<ValueNode> arguments, final Assumptions assumptions, final CanonicalizerPhase finalCanonicalizer, boolean ignoreSlowPath);
+    StructuredGraph lookup(final ResolvedJavaMethod method, final NodeInputList<ValueNode> arguments, final Assumptions assumptions, final CanonicalizerPhase finalCanonicalizer);
 }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCacheImpl.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCacheImpl.java	Wed Sep 24 16:22:22 2014 -0700
@@ -52,7 +52,7 @@
 /**
  * Implementation of a cache for Truffle graphs for improving partial evaluation time.
  */
-public final class TruffleCacheImpl implements TruffleCache {
+public class TruffleCacheImpl implements TruffleCache {
 
     private final Providers providers;
     private final GraphBuilderConfiguration config;
@@ -95,9 +95,9 @@
         return graph;
     }
 
-    public StructuredGraph lookup(ResolvedJavaMethod method, NodeInputList<ValueNode> arguments, Assumptions assumptions, CanonicalizerPhase canonicalizer, boolean ignoreSlowPath) {
+    public StructuredGraph lookup(ResolvedJavaMethod method, NodeInputList<ValueNode> arguments, Assumptions assumptions, CanonicalizerPhase canonicalizer) {
 
-        if (!ignoreSlowPath && method.getAnnotation(CompilerDirectives.SlowPath.class) != null) {
+        if (method.getAnnotation(CompilerDirectives.SlowPath.class) != null) {
             return null;
         }
 
@@ -123,14 +123,18 @@
             lookupExceedsMaxSize();
         }
 
-        lastUsed.put(key, counter++);
-        cache.put(key, markerGraph);
         try (Scope s = Debug.scope("TruffleCache", providers.getMetaAccess(), method)) {
 
-            final StructuredGraph graph = new StructuredGraph(method);
             final PhaseContext phaseContext = new PhaseContext(providers, new Assumptions(false));
-            Mark mark = graph.getMark();
-            new GraphBuilderPhase.Instance(phaseContext.getMetaAccess(), config, optimisticOptimizations).apply(graph);
+            Mark mark = null;
+
+            final StructuredGraph graph = parseGraph(method, phaseContext);
+            if (graph == null) {
+                return null;
+            }
+
+            lastUsed.put(key, counter++);
+            cache.put(key, markerGraph);
 
             for (ParameterNode param : graph.getNodes(ParameterNode.class)) {
                 if (param.getKind() == Kind.Object) {
@@ -249,10 +253,19 @@
         canonicalizer.applyIncremental(graph, phaseContext, canonicalizerUsages);
     }
 
+    protected StructuredGraph parseGraph(final ResolvedJavaMethod method, final PhaseContext phaseContext) {
+        final StructuredGraph graph = new StructuredGraph(method);
+        new GraphBuilderPhase.Instance(phaseContext.getMetaAccess(), config, optimisticOptimizations).apply(graph);
+        return graph;
+    }
+
     private void expandInvoke(MethodCallTargetNode methodCallTargetNode, CanonicalizerPhase canonicalizer) {
         StructuredGraph inlineGraph = providers.getReplacements().getMethodSubstitution(methodCallTargetNode.targetMethod());
         if (inlineGraph == null) {
-            inlineGraph = TruffleCacheImpl.this.lookup(methodCallTargetNode.targetMethod(), methodCallTargetNode.arguments(), null, canonicalizer, false);
+            inlineGraph = TruffleCacheImpl.this.lookup(methodCallTargetNode.targetMethod(), methodCallTargetNode.arguments(), null, canonicalizer);
+        }
+        if (inlineGraph == null) {
+            return;
         }
         if (inlineGraph == this.markerGraph) {
             // Can happen for recursive calls.
@@ -281,7 +294,7 @@
         return false;
     }
 
-    private boolean shouldInline(MethodCallTargetNode methodCallTargetNode) {
+    protected boolean shouldInline(MethodCallTargetNode methodCallTargetNode) {
         boolean result = (methodCallTargetNode.invokeKind() == InvokeKind.Special || methodCallTargetNode.invokeKind() == InvokeKind.Static) && methodCallTargetNode.targetMethod().canBeInlined() &&
                         !methodCallTargetNode.targetMethod().isNative() && methodCallTargetNode.targetMethod().getAnnotation(ExplodeLoop.class) == null &&
                         methodCallTargetNode.targetMethod().getAnnotation(CompilerDirectives.SlowPath.class) == null &&
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactNode.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactNode.java	Wed Sep 24 16:22:22 2014 -0700
@@ -29,7 +29,6 @@
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.type.*;
 import com.oracle.truffle.api.*;
 
 /**
@@ -37,7 +36,7 @@
  * case the addition would overflow the 32 bit range.
  */
 @NodeInfo
-public class IntegerAddExactNode extends IntegerAddNode implements IntegerExactArithmeticNode {
+public class IntegerAddExactNode extends AddNode implements IntegerExactArithmeticNode {
 
     public static IntegerAddExactNode create(ValueNode x, ValueNode y) {
         return USE_GENERATED_NODES ? new IntegerAddExactNodeGen(x, y) : new IntegerAddExactNode(x, y);
@@ -51,7 +50,7 @@
     @Override
     public boolean inferStamp() {
         // TODO Should probably use a specialized version which understands that it can't overflow
-        return updateStamp(StampTool.add(getX().stamp(), getY().stamp()));
+        return super.inferStamp();
     }
 
     @Override
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulExactNode.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulExactNode.java	Wed Sep 24 16:22:22 2014 -0700
@@ -36,7 +36,7 @@
  * in case the addition would overflow the 32 bit range.
  */
 @NodeInfo
-public class IntegerMulExactNode extends IntegerMulNode implements IntegerExactArithmeticNode {
+public class IntegerMulExactNode extends MulNode implements IntegerExactArithmeticNode {
 
     public static IntegerMulExactNode create(ValueNode x, ValueNode y) {
         return USE_GENERATED_NODES ? new IntegerMulExactNodeGen(x, y) : new IntegerMulExactNode(x, y);
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulHighNode.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulHighNode.java	Wed Sep 24 16:22:22 2014 -0700
@@ -36,21 +36,21 @@
 import com.oracle.truffle.api.*;
 
 @NodeInfo(shortName = "*H")
-public class IntegerMulHighNode extends IntegerArithmeticNode {
+public class IntegerMulHighNode extends BinaryNode implements ArithmeticLIRLowerable {
 
     public static IntegerMulHighNode create(ValueNode x, ValueNode y) {
         return USE_GENERATED_NODES ? new IntegerMulHighNodeGen(x, y) : new IntegerMulHighNode(x, y);
     }
 
     protected IntegerMulHighNode(ValueNode x, ValueNode y) {
-        this(x.stamp().unrestricted(), x, y);
+        this((IntegerStamp) x.stamp().unrestricted(), x, y);
     }
 
-    public static IntegerMulHighNode create(Stamp stamp, ValueNode x, ValueNode y) {
+    public static IntegerMulHighNode create(IntegerStamp stamp, ValueNode x, ValueNode y) {
         return USE_GENERATED_NODES ? new IntegerMulHighNodeGen(stamp, x, y) : new IntegerMulHighNode(stamp, x, y);
     }
 
-    protected IntegerMulHighNode(Stamp stamp, ValueNode x, ValueNode y) {
+    protected IntegerMulHighNode(IntegerStamp stamp, ValueNode x, ValueNode y) {
         super(stamp, x, y);
     }
 
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactNode.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactNode.java	Wed Sep 24 16:22:22 2014 -0700
@@ -29,7 +29,6 @@
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.nodes.util.*;
 import com.oracle.truffle.api.*;
 
@@ -38,7 +37,7 @@
  * case the addition would overflow the 32 bit range.
  */
 @NodeInfo
-public class IntegerSubExactNode extends IntegerSubNode implements IntegerExactArithmeticNode {
+public class IntegerSubExactNode extends SubNode implements IntegerExactArithmeticNode {
 
     public static IntegerSubExactNode create(ValueNode x, ValueNode y) {
         return USE_GENERATED_NODES ? new IntegerSubExactNodeGen(x, y) : new IntegerSubExactNode(x, y);
@@ -52,7 +51,7 @@
     @Override
     public boolean inferStamp() {
         // TODO Should probably use a specialized version which understands that it can't overflow
-        return updateStamp(StampTool.sub(getX().stamp(), getY().stamp()));
+        return super.inferStamp();
     }
 
     @Override
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/UnsignedMulHighNode.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/UnsignedMulHighNode.java	Wed Sep 24 16:22:22 2014 -0700
@@ -36,21 +36,21 @@
 import com.oracle.truffle.api.*;
 
 @NodeInfo(shortName = "|*H|")
-public class UnsignedMulHighNode extends IntegerArithmeticNode {
+public class UnsignedMulHighNode extends BinaryNode implements ArithmeticLIRLowerable {
 
     public static UnsignedMulHighNode create(ValueNode x, ValueNode y) {
         return USE_GENERATED_NODES ? new UnsignedMulHighNodeGen(x, y) : new UnsignedMulHighNode(x, y);
     }
 
     protected UnsignedMulHighNode(ValueNode x, ValueNode y) {
-        this(x.stamp().unrestricted(), x, y);
+        this((IntegerStamp) x.stamp().unrestricted(), x, y);
     }
 
-    public static UnsignedMulHighNode create(Stamp stamp, ValueNode x, ValueNode y) {
+    public static UnsignedMulHighNode create(IntegerStamp stamp, ValueNode x, ValueNode y) {
         return USE_GENERATED_NODES ? new UnsignedMulHighNodeGen(stamp, x, y) : new UnsignedMulHighNode(stamp, x, y);
     }
 
-    protected UnsignedMulHighNode(Stamp stamp, ValueNode x, ValueNode y) {
+    protected UnsignedMulHighNode(IntegerStamp stamp, ValueNode x, ValueNode y) {
         super(stamp, x, y);
     }
 
--- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/Word.java	Wed Sep 24 16:13:34 2014 -0700
+++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/Word.java	Wed Sep 24 16:22:22 2014 -0700
@@ -181,70 +181,70 @@
     public native Object toObject();
 
     @Override
-    @Operation(node = IntegerAddNode.class)
+    @Operation(node = AddNode.class)
     public Word add(Signed val) {
         return add((Word) val);
     }
 
     @Override
-    @Operation(node = IntegerAddNode.class)
+    @Operation(node = AddNode.class)
     public Word add(Unsigned val) {
         return add((Word) val);
     }
 
     @Override
-    @Operation(node = IntegerAddNode.class)
+    @Operation(node = AddNode.class)
     public Word add(int val) {
         return add(intParam(val));
     }
 
-    @Operation(node = IntegerAddNode.class)
+    @Operation(node = AddNode.class)
     public Word add(Word val) {
         return box(unbox() + val.unbox());
     }
 
     @Override
-    @Operation(node = IntegerSubNode.class)
+    @Operation(node = SubNode.class)
     public Word subtract(Signed val) {
         return subtract((Word) val);
     }
 
     @Override
-    @Operation(node = IntegerSubNode.class)
+    @Operation(node = SubNode.class)
     public Word subtract(Unsigned val) {
         return subtract((Word) val);
     }
 
     @Override
-    @Operation(node = IntegerSubNode.class)
+    @Operation(node = SubNode.class)
     public Word subtract(int val) {
         return subtract(intParam(val));
     }
 
-    @Operation(node = IntegerSubNode.class)
+    @Operation(node = SubNode.class)
     public Word subtract(Word val) {
         return box(unbox() - val.unbox());
     }
 
     @Override
-    @Operation(node = IntegerMulNode.class)
+    @Operation(node = MulNode.class)
     public Word multiply(Signed val) {
         return multiply((Word) val);
     }
 
     @Override
-    @Operation(node = IntegerMulNode.class)
+    @Operation(node = MulNode.class)
     public Word multiply(Unsigned val) {
         return multiply((Word) val);
     }
 
     @Override
-    @Operation(node = IntegerMulNode.class)
+    @Operation(node = MulNode.class)
     public Word multiply(int val) {
         return multiply(intParam(val));
     }
 
-    @Operation(node = IntegerMulNode.class)
+    @Operation(node = MulNode.class)
     public Word multiply(Word val) {
         return box(unbox() * val.unbox());
     }
--- a/make/bsd/makefiles/gcc.make	Wed Sep 24 16:13:34 2014 -0700
+++ b/make/bsd/makefiles/gcc.make	Wed Sep 24 16:22:22 2014 -0700
@@ -381,6 +381,11 @@
 # statically link libstdc++.so, work with gcc but ignored by g++
 STATIC_STDCXX = -Wl,-Bstatic -lstdc++ -Wl,-Bdynamic
 
+# Ensure use libstdc++ on clang, not libc++
+ifeq ($(USE_CLANG), true)
+  LFLAGS += -stdlib=libstdc++
+endif
+
 ifeq ($(USE_CLANG),)
   # statically link libgcc and/or libgcc_s, libgcc does not exist before gcc-3.x.
   ifneq ("${CC_VER_MAJOR}", "2")
--- a/mx/projects.py	Wed Sep 24 16:13:34 2014 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1255 +0,0 @@
-suite = {
-  "mxversion" : "1.0",
-  "name" : "graal",
-  "libraries" : {
-    "JUNIT" : {
-      "path" : "lib/junit-4.11.jar",
-      "urls" : [
-        "http://lafo.ssw.uni-linz.ac.at/graal-external-deps/junit-4.11.jar",
-        "http://repo1.maven.org/maven2/junit/junit/4.11/junit-4.11.jar",
-      ],
-      "sha1" : "4e031bb61df09069aeb2bffb4019e7a5034a4ee0",
-      "eclipse.container" : "org.eclipse.jdt.junit.JUNIT_CONTAINER/4",
-      "sourcePath" : "lib/junit-4.11-sources.jar",
-      "sourceUrls" : [
-        "http://lafo.ssw.uni-linz.ac.at/graal-external-deps/junit-4.11-sources.jar",
-        "http://repo1.maven.org/maven2/junit/junit/4.11/junit-4.11-sources.jar",
-      ],
-      "sourceSha1" : "28e0ad201304e4a4abf999ca0570b7cffc352c3c",
-      "dependencies" : ["HAMCREST"],
-    },
-
-    "HAMCREST" : {
-      "path" : "lib/hamcrest-core-1.3.jar",
-      "urls" : [
-        "http://lafo.ssw.uni-linz.ac.at/graal-external-deps/hamcrest-core-1.3.jar",
-        "http://repo1.maven.org/maven2/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar",
-      ],
-      "sha1" : "42a25dc3219429f0e5d060061f71acb49bf010a0",
-      "sourcePath" : "lib/hamcrest-core-1.3-sources.jar",
-      "sourceUrls" : [
-        "http://lafo.ssw.uni-linz.ac.at/graal-external-deps/hamcrest-core-1.3-sources.jar",
-        "http://repo1.maven.org/maven2/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3-sources.jar",
-      ],
-      "sourceSha1" : "1dc37250fbc78e23a65a67fbbaf71d2e9cbc3c0b",
-    },
-
-    "HCFDIS" : {
-      "path" : "lib/hcfdis-2.jar",
-      "urls" : ["http://lafo.ssw.uni-linz.ac.at/hcfdis-2.jar"],
-      "sha1" : "bc8b2253436485e9dbaf81771c259ccfa1a24c80",
-    },
-
-    "FINDBUGS_DIST" : {
-      "path" : "lib/findbugs-dist-3.0.0.zip",
-      "urls" : [
-        "http://lafo.ssw.uni-linz.ac.at/graal-external-deps/findbugs-3.0.0.zip",
-        "http://sourceforge.net/projects/findbugs/files/findbugs/3.0.0/findbugs-3.0.0.zip/download",
-      ],
-      "sha1" : "6e56d67f238dbcd60acb88a81655749aa6419c5b",
-    },
-
-    "C1VISUALIZER_DIST" : {
-      "path" : "lib/c1visualizer_2014-04-22.zip",
-      "urls" : ["https://java.net/downloads/c1visualizer/c1visualizer_2014-04-22.zip"],
-      "sha1" : "220488d87affb569b893c7201f8ce5d2b0e03141",
-    },
-
-    "JOL_INTERNALS" : {
-      "path" : "lib/jol-internals.jar",
-      "urls" : ["http://lafo.ssw.uni-linz.ac.at/truffle/jol/jol-internals.jar"],
-      "sha1" : "508bcd26a4d7c4c44048990c6ea789a3b11a62dc",
-    },
-
-    "FINDBUGS" : {
-      "path" : "lib/findbugs-3.0.0.jar",
-      "urls" : [
-        "jar:http://lafo.ssw.uni-linz.ac.at/graal-external-deps/findbugs-3.0.0.zip!/findbugs-3.0.0/lib/findbugs.jar",
-        "jar:http://sourceforge.net/projects/findbugs/files/findbugs/3.0.0/findbugs-3.0.0.zip/download!/findbugs-3.0.0/lib/findbugs.jar",
-      ],
-      "sha1" : "e9a938f0cb34e2ab5853f9ecb1989f6f590ee385",
-    },
-
-    "DACAPO" : {
-      "path" : "lib/dacapo-9.12-bach.jar",
-      "urls" : [
-        "http://lafo.ssw.uni-linz.ac.at/graal-external-deps/dacapo-9.12-bach.jar",
-        "http://softlayer.dl.sourceforge.net/project/dacapobench/9.12-bach/dacapo-9.12-bach.jar",
-      ],
-      "sha1" : "2626a9546df09009f6da0df854e6dc1113ef7dd4",
-    },
-
-    "JACOCOAGENT" : {
-      "path" : "lib/jacocoagent.jar",
-      "urls" : ["http://lafo.ssw.uni-linz.ac.at/jacoco/jacocoagent-0.7.1-1.jar"],
-      "sha1" : "2f73a645b02e39290e577ce555f00b02004650b0",
-    },
-
-    "JACOCOREPORT" : {
-      "path" : "lib/jacocoreport.jar",
-      "urls" : ["http://lafo.ssw.uni-linz.ac.at/jacoco/jacocoreport-0.7.1-2.jar"],
-      "sha1" : "a630436391832d697a12c8f7daef8655d7a1efd2",
-    },
-
-    "DACAPO_SCALA" : {
-      "path" : "lib/dacapo-scala-0.1.0-20120216.jar",
-      "urls" : [
-        "http://lafo.ssw.uni-linz.ac.at/graal-external-deps/dacapo-scala-0.1.0-20120216.jar",
-        "http://repo.scalabench.org/snapshots/org/scalabench/benchmarks/scala-benchmark-suite/0.1.0-SNAPSHOT/scala-benchmark-suite-0.1.0-20120216.103539-3.jar",
-      ],
-      "sha1" : "59b64c974662b5cf9dbd3cf9045d293853dd7a51",
-    },
-
-    "OKRA" : {
-      "path" : "lib/okra-1.10.jar",
-      "urls" : [
-        "http://lafo.ssw.uni-linz.ac.at/graal-external-deps/okra-1.10.jar",
-        "http://cr.openjdk.java.net/~tdeneau/okra-1.10.jar",
-      ],
-      "sha1" : "96eb3c0ec808ed944ba88d1eb9311058fe0f3d1e",
-      "sourcePath" : "lib/okra-1.10-src.jar",
-      "sourceUrls" : [
-        "http://lafo.ssw.uni-linz.ac.at/graal-external-deps/okra-1.10-src.jar",
-        "http://cr.openjdk.java.net/~tdeneau/okra-1.10-src.jar",
-      ],
-      "sourceSha1" : "75751bb148fcebaba78ff590f883a114b2b09176",
-    },
-
-    "OKRA_WITH_SIM" : {
-      "path" : "lib/okra-1.10-with-sim.jar",
-      "urls" : [
-        "http://lafo.ssw.uni-linz.ac.at/graal-external-deps/okra-1.10-with-sim.jar",
-        "http://cr.openjdk.java.net/~tdeneau/okra-1.10-with-sim.jar",
-      ],
-      "sha1" : "7b8db879f1dbcf571290add78d9af24e15a2a50d",
-      "sourcePath" : "lib/okra-1.10-with-sim-src.jar",
-      "sourceSha1" : "7eefd94f16a3e3fd3b8f470cf91e265c6f5e7767",
-      "sourceUrls" : [
-        "http://lafo.ssw.uni-linz.ac.at/graal-external-deps/okra-1.10-with-sim-src.jar",
-        "http://cr.openjdk.java.net/~tdeneau/okra-1.10-with-sim-src.jar",
-      ],
-    },
-
-    "ASM" : {
-      "path" : "lib/asm-5.0.3.jar",
-      "urls" : [
-        "http://lafo.ssw.uni-linz.ac.at/graal-external-deps/asm-5.0.3.jar",
-        "http://central.maven.org/maven2/org/ow2/asm/asm/5.0.3/asm-5.0.3.jar",
-      ],
-      "sha1" : "dcc2193db20e19e1feca8b1240dbbc4e190824fa",
-      "sourcePath" : "lib/asm-5.0.3-sources.jar",
-      "sourceSha1" : "f0f24f6666c1a15c7e202e91610476bd4ce59368",
-      "sourceUrls" : [
-        "http://lafo.ssw.uni-linz.ac.at/graal-external-deps/asm-5.0.3-sources.jar",
-        "http://central.maven.org/maven2/org/ow2/asm/asm/5.0.3/asm-5.0.3-sources.jar",
-      ],
-    },
-
-    "JAVA_ALLOCATION_INSTRUMENTER" : {
-      "path" : "lib/java-allocation-instrumenter.jar",
-      "sourcePath" : "lib/java-allocation-instrumenter.jar",
-      "urls" : ["http://lafo.ssw.uni-linz.ac.at/java-allocation-instrumenter/java-allocation-instrumenter-8f0db117e64e.jar"],
-      "sha1" : "476d9a44cd19d6b55f81571077dfa972a4f8a083",
-      "bootClassPathAgent" : "true",
-    },
-
-    "VECMATH" : {
-      "path" : "lib/vecmath-1.3.1.jar",
-      "urls" : [
-        "http://lafo.ssw.uni-linz.ac.at/graal-external-deps/vecmath-1.3.1.jar",
-        "http://mirrors.ibiblio.org/pub/mirrors/maven/java3d/jars/vecmath-1.3.1.jar",
-      ],
-      "sha1" : "a0ae4f51da409fa0c20fa0ca59e6bbc9413ae71d",
-    }
-  },
-
-  "jrelibraries" : {
-    "JFR" : {
-      "jar" : "jfr.jar",
-    }
-  },
-
-  "projects" : {
-    "com.oracle.nfi" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : [],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.7",
-    },
-
-    "com.oracle.nfi.test" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["test"],
-      "dependencies" : [
-        "com.oracle.nfi",
-        "com.oracle.graal.compiler.common",
-        "JUNIT",
-      ],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.7",
-    },
-
-    "com.oracle.graal.api.collections" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "API,Graal",
-    },
-
-    "com.oracle.graal.api.runtime" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "API,Graal",
-    },
-
-    "com.oracle.graal.api.test" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : [
-        "JUNIT",
-        "com.oracle.graal.api.runtime",
-      ],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "API,Graal,Test",
-    },
-
-    "com.oracle.graal.api.meta" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "API,Graal",
-    },
-
-    "com.oracle.graal.api.meta.test" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : [
-        "JUNIT",
-        "com.oracle.graal.runtime",
-        "com.oracle.graal.java",
-      ],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "API,Graal,Test",
-    },
-
-    "com.oracle.graal.api.code" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : ["com.oracle.graal.api.meta"],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "API,Graal",
-    },
-
-    "com.oracle.graal.api.replacements" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : ["com.oracle.graal.api.meta"],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "API,Graal,Replacements",
-    },
-
-    "com.oracle.graal.service.processor" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : ["com.oracle.graal.api.runtime"],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Codegen,HotSpot",
-    },
-
-    "com.oracle.graal.amd64" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : ["com.oracle.graal.api.code"],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,AMD64",
-    },
-
-    "com.oracle.graal.ptx" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : ["com.oracle.graal.api.code"],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,PTX",
-    },
-
-    "com.oracle.graal.sparc" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : ["com.oracle.graal.api.code"],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,SPARC",
-    },
-
-    "com.oracle.graal.hotspotvmconfig" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : ["com.oracle.graal.compiler.common"],
-      "checkstyle" : "com.oracle.graal.graph",
-      "annotationProcessors" : ["com.oracle.graal.service.processor"],
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,HotSpot",
-    },
-
-    "com.oracle.graal.hotspot" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : [
-        "com.oracle.graal.replacements",
-        "com.oracle.graal.runtime",
-        "com.oracle.graal.printer",
-        "com.oracle.graal.baseline",
-        "com.oracle.graal.hotspotvmconfig",
-        "com.oracle.nfi",
-      ],
-      "checkstyle" : "com.oracle.graal.graph",
-      "annotationProcessors" : [
-        "com.oracle.graal.replacements.verifier",
-        "com.oracle.graal.service.processor",
-      ],
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,HotSpot",
-    },
-
-    "com.oracle.graal.hotspot.loader" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : [],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,HotSpot",
-    },
-
-    "com.oracle.graal.hotspot.sourcegen" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : ["com.oracle.graal.hotspot"],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,HotSpot",
-    },
-
-    "com.oracle.graal.hotspot.jfr" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : [
-        "com.oracle.graal.hotspot",
-        "JFR",
-      ],
-      "checkstyle" : "com.oracle.graal.graph",
-      "annotationProcessors" : ["com.oracle.graal.service.processor"],
-      "javaCompliance" : "1.8",
-      "profile" : "",
-      "workingSets" : "Graal,HotSpot",
-    },
-
-    "com.oracle.graal.hotspot.amd64" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : [
-        "com.oracle.graal.compiler.amd64",
-        "com.oracle.graal.hotspot",
-        "com.oracle.graal.replacements.amd64",
-      ],
-      "checkstyle" : "com.oracle.graal.graph",
-      "annotationProcessors" : ["com.oracle.graal.service.processor"],
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,HotSpot,AMD64",
-    },
-
-    "com.oracle.graal.hotspot.sparc" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : ["com.oracle.graal.compiler.sparc"],
-      "checkstyle" : "com.oracle.graal.graph",
-      "annotationProcessors" : ["com.oracle.graal.service.processor"],
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,HotSpot,SPARC",
-    },
-
-    "com.oracle.graal.hotspot.ptx" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : [
-        "com.oracle.graal.ptx",
-        "com.oracle.graal.compiler.ptx",
-        "com.oracle.graal.hotspot",
-        "com.oracle.graal.gpu",
-      ],
-      "checkstyle" : "com.oracle.graal.graph",
-      "annotationProcessors" : ["com.oracle.graal.service.processor"],
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,HotSpot,PTX",
-    },
-
-    "com.oracle.graal.hotspot.hsail" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : [
-        "com.oracle.graal.replacements.hsail",
-        "com.oracle.graal.hotspot",
-        "com.oracle.graal.gpu",
-      ],
-      "checkstyle" : "com.oracle.graal.graph",
-      "annotationProcessors" : ["com.oracle.graal.service.processor"],
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,HotSpot,PTX",
-    },
-
-    "com.oracle.graal.hotspot.server" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : ["com.oracle.graal.hotspot"],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,HotSpot",
-    },
-
-    "com.oracle.graal.hotspot.test" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : [
-        "com.oracle.graal.replacements.test",
-        "com.oracle.graal.hotspot",
-      ],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,HotSpot,Test",
-    },
-
-    "com.oracle.graal.hotspot.amd64.test" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : [
-        "com.oracle.graal.asm.amd64",
-        "com.oracle.graal.compiler.test",
-        "com.oracle.graal.hotspot",
-      ],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,HotSpot,AMD64,Test",
-    },
-
-    "com.oracle.graal.options" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,Codegen",
-    },
-
-    "com.oracle.graal.options.test" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : [
-        "com.oracle.graal.options",
-        "JUNIT",
-      ],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal",
-    },
-
-    "com.oracle.graal.nodeinfo" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,Graph",
-    },
-
-    "com.oracle.graal.nodeinfo.processor" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "checkstyle" : "com.oracle.graal.graph",
-      "dependencies" : [
-        "com.oracle.graal.nodeinfo",
-        "com.oracle.truffle.dsl.processor",
-      ],
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,Graph",
-    },
-
-    "com.oracle.graal.graph" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : [
-        "com.oracle.graal.nodeinfo",
-        "com.oracle.graal.debug",
-        "com.oracle.graal.compiler.common",
-        "com.oracle.graal.api.collections",
-        "com.oracle.graal.api.runtime",
-        "FINDBUGS",
-      ],
-      "javaCompliance" : "1.8",
-      "annotationProcessors" : ["com.oracle.graal.nodeinfo.processor"],
-      "workingSets" : "Graal,Graph",
-    },
-
-    "com.oracle.graal.graph.test" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "checkstyle" : "com.oracle.graal.graph",
-      "dependencies" : [
-        "JUNIT",
-        "com.oracle.graal.graph",
-      ],
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,Graph,Test",
-    },
-
-    "com.oracle.graal.debug" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,Debug",
-    },
-
-    "com.oracle.graal.debug.test" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : [
-        "JUNIT",
-        "com.oracle.graal.debug",
-      ],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,Debug,Test",
-    },
-
-    "com.oracle.graal.lir" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : [
-        "com.oracle.graal.compiler.common",
-        "com.oracle.graal.asm",
-        "com.oracle.graal.debug",
-      ],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,LIR",
-    },
-
-    "com.oracle.graal.lir.test" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : [
-        "JUNIT",
-        "com.oracle.graal.lir",
-      ],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,LIR",
-    },
-
-    "com.oracle.graal.lir.amd64" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : [
-        "com.oracle.graal.lir",
-        "com.oracle.graal.asm.amd64",
-      ],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,LIR,AMD64",
-    },
-
-    "com.oracle.graal.lir.ptx" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : ["com.oracle.graal.asm.ptx"],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,LIR,PTX",
-    },
-
-    "com.oracle.graal.lir.sparc" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : ["com.oracle.graal.asm.sparc"],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,LIR,SPARC",
-    },
-
-    "com.oracle.graal.alloc" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : ["com.oracle.graal.compiler.common"],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal",
-    },
-
-    "com.oracle.graal.word" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : ["com.oracle.graal.phases"],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "API,Graal",
-    },
-
-    "com.oracle.graal.replacements" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : [
-        "com.oracle.graal.compiler",
-        "com.oracle.graal.java",
-        "com.oracle.graal.word",
-      ],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "annotationProcessors" : [
-        "com.oracle.graal.replacements.verifier",
-        "com.oracle.graal.service.processor",
-      ],
-      "workingSets" : "Graal,Replacements",
-    },
-
-    "com.oracle.graal.replacements.amd64" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : ["com.oracle.graal.replacements"],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "annotationProcessors" : ["com.oracle.graal.service.processor"],
-      "workingSets" : "Graal,Replacements,AMD64",
-    },
-
-    "com.oracle.graal.replacements.hsail" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : ["com.oracle.graal.compiler.hsail"],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,Replacements,HSAIL",
-    },
-
-    "com.oracle.graal.replacements.test" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : [
-        "com.oracle.graal.compiler.test",
-        "com.oracle.graal.replacements",
-      ],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,Replacements,Test",
-    },
-
-    "com.oracle.graal.replacements.verifier" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : [
-        "com.oracle.graal.api.replacements",
-        "com.oracle.graal.graph",
-      ],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,Replacements",
-    },
-
-    "com.oracle.graal.nodes" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : [
-        "com.oracle.graal.graph",
-        "com.oracle.graal.api.replacements",
-        "com.oracle.graal.lir",
-      ],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "annotationProcessors" : ["com.oracle.graal.replacements.verifier"],
-      "workingSets" : "Graal,Graph",
-    },
-
-    "com.oracle.graal.nodes.test" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : ["com.oracle.graal.compiler.test"],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,Graph",
-    },
-
-    "com.oracle.graal.phases" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : ["com.oracle.graal.nodes"],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,Phases",
-    },
-
-    "com.oracle.graal.phases.common" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : ["com.oracle.graal.phases"],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,Phases",
-    },
-
-    "com.oracle.graal.virtual" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : ["com.oracle.graal.phases.common"],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,Phases",
-    },
-
-    "com.oracle.graal.loop" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : ["com.oracle.graal.phases.common"],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,Phases",
-    },
-
-    "com.oracle.graal.compiler" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : [
-        "com.oracle.graal.virtual",
-        "com.oracle.graal.loop",
-        "com.oracle.graal.alloc",
-      ],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "annotationProcessors" : ["com.oracle.graal.service.processor"],
-      "workingSets" : "Graal",
-    },
-
-    "com.oracle.graal.compiler.amd64" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : [
-        "com.oracle.graal.compiler",
-        "com.oracle.graal.lir.amd64",
-      ],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,AMD64",
-    },
-
-    "com.oracle.graal.compiler.amd64.test" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : ["com.oracle.graal.compiler.test"],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,AMD64,Test",
-    },
-
-    "com.oracle.graal.compiler.ptx" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : [
-        "com.oracle.graal.lir.ptx",
-        "com.oracle.graal.compiler",
-      ],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,PTX",
-    },
-
-    "com.oracle.graal.compiler.ptx.test" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : [
-        "com.oracle.graal.hotspot.ptx",
-        "com.oracle.graal.compiler.test",
-      ],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,PTX,Test",
-    },
-
-    "com.oracle.graal.compiler.sparc" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : ["com.oracle.graal.lir.sparc"],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,SPARC",
-    },
-
-    "com.oracle.graal.compiler.sparc.test" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : ["com.oracle.graal.compiler.test"],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,SPARC,Test",
-    },
-
-    "com.oracle.graal.runtime" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : ["com.oracle.graal.compiler"],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal",
-    },
-
-    "com.oracle.graal.bytecode" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,Java",
-    },
-
-    "com.oracle.graal.java" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : [
-        "com.oracle.graal.phases",
-        "com.oracle.graal.bytecode",
-      ],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,Java",
-    },
-
-    "com.oracle.graal.compiler.common" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : [
-        "com.oracle.graal.api.code",
-        "com.oracle.graal.options",
-      ],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,Java",
-    },
-
-    "com.oracle.graal.baseline" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : [
-        "com.oracle.graal.compiler",
-        "com.oracle.graal.java",
-      ],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,Java",
-    },
-
-    "com.oracle.graal.java.decompiler" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : ["com.oracle.graal.java"],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal",
-    },
-
-    "com.oracle.graal.java.decompiler.test" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : [
-        "JUNIT",
-        "com.oracle.graal.printer",
-        "com.oracle.graal.runtime",
-      ],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,Test",
-    },
-
-    "com.oracle.graal.printer" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : [
-        "com.oracle.graal.java.decompiler",
-        "com.oracle.graal.compiler",
-      ],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,Graph",
-    },
-
-    "com.oracle.graal.test" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : [
-        "JUNIT",
-        "com.oracle.graal.debug",
-      ],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,Test",
-    },
-
-    "com.oracle.graal.compiler.test" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : [
-        "com.oracle.graal.test",
-        "com.oracle.graal.printer",
-        "com.oracle.graal.runtime",
-        "com.oracle.graal.baseline",
-        "JAVA_ALLOCATION_INSTRUMENTER",
-      ],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,Test",
-    },
-
-    "com.oracle.graal.jtt" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : [
-        "com.oracle.graal.compiler.test",
-        "ASM",
-      ],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,Test",
-    },
-
-    "com.oracle.graal.asm" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : ["com.oracle.graal.api.code"],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,Assembler",
-    },
-
-    "com.oracle.graal.asm.test" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : [
-        "com.oracle.graal.test",
-        "com.oracle.graal.runtime",
-      ],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,Assembler,Test",
-    },
-
-    "com.oracle.graal.asm.amd64" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : [
-        "com.oracle.graal.asm",
-        "com.oracle.graal.amd64",
-      ],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,Assembler,AMD64",
-    },
-
-    "com.oracle.graal.asm.amd64.test" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : [
-        "com.oracle.graal.asm.test",
-        "com.oracle.graal.asm.amd64",
-      ],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,Assembler,AMD64,Test",
-    },
-
-    "com.oracle.graal.gpu" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : ["com.oracle.graal.nodes"],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-    },
-
-    "com.oracle.graal.hsail" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : ["com.oracle.graal.api.code"],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-    },
-
-    "com.oracle.graal.lir.hsail" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : [
-        "com.oracle.graal.lir",
-        "com.oracle.graal.asm.hsail",
-      ],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-    },
-
-    "com.oracle.graal.compiler.hsail" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : [
-        "com.oracle.graal.compiler",
-        "com.oracle.graal.lir.hsail",
-      ],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-    },
-
-    "com.oracle.graal.compiler.hsail.test.infra" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : [
-        "com.oracle.graal.test",
-        "com.oracle.graal.hotspot.hsail",
-        "OKRA_WITH_SIM",
-      ],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-    },
-
-    "com.oracle.graal.compiler.hsail.test" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : [
-        "com.oracle.graal.compiler.hsail.test.infra",
-        "com.oracle.graal.compiler.test",
-        "VECMATH",
-      ],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-    },
-
-    "com.oracle.graal.asm.hsail" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : [
-        "com.oracle.graal.hsail",
-        "OKRA",
-        "com.oracle.graal.asm",
-        "com.oracle.graal.compiler.common",
-      ],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-    },
-
-    "com.oracle.graal.asm.ptx" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : ["com.oracle.graal.lir"],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,Assembler,PTX",
-    },
-
-    "com.oracle.graal.asm.sparc" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : [
-        "com.oracle.graal.hotspot",
-        "com.oracle.graal.sparc",
-      ],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,Assembler,SPARC",
-    },
-
-    "com.oracle.truffle.api" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : [],
-      "javaCompliance" : "1.7",
-      "workingSets" : "API,Truffle",
-    },
-
-    "com.oracle.truffle.api.test" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : [
-        "com.oracle.truffle.api",
-        "JUNIT",
-      ],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.7",
-      "workingSets" : "API,Truffle,Test",
-    },
-
-    "com.oracle.truffle.api.dsl" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : ["com.oracle.truffle.api"],
-      "checkstyle" : "com.oracle.truffle.api",
-      "javaCompliance" : "1.7",
-      "workingSets" : "API,Truffle,Codegen",
-    },
-
-    "com.oracle.truffle.api.dsl.test" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : [
-        "com.oracle.truffle.api.dsl",
-        "JUNIT",
-      ],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.7",
-      "annotationProcessors" : ["com.oracle.truffle.dsl.processor"],
-      "workingSets" : "API,Truffle,Codegen,Test",
-    },
-
-    "com.oracle.truffle.dsl.processor" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : ["com.oracle.truffle.api.dsl"],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.7",
-      "workingSets" : "Truffle,Codegen",
-    },
-
-    "com.oracle.truffle.sl" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : ["com.oracle.truffle.api.dsl"],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "annotationProcessors" : ["com.oracle.truffle.dsl.processor"],
-      "workingSets" : "Truffle,SimpleLanguage",
-    },
-
-    "com.oracle.truffle.sl.test" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : [
-        "com.oracle.truffle.sl",
-        "JUNIT",
-      ],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Truffle,SimpleLanguage,Test",
-    },
-
-    "com.oracle.graal.truffle" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : [
-        "com.oracle.truffle.api",
-        "com.oracle.graal.replacements",
-        "com.oracle.graal.runtime",
-        "com.oracle.graal.printer",
-      ],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,Truffle",
-    },
-
-    "com.oracle.graal.truffle.test" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : [
-        "com.oracle.graal.truffle",
-        "com.oracle.graal.compiler.test",
-        "com.oracle.truffle.sl.test",
-      ],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "workingSets" : "Graal,Truffle,Test",
-    },
-
-    "com.oracle.graal.truffle.hotspot" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : [
-        "com.oracle.graal.truffle",
-        "com.oracle.graal.hotspot",
-      ],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "annotationProcessors" : ["com.oracle.graal.service.processor"],
-      "workingSets" : "Graal,Truffle",
-    },
-
-    "com.oracle.graal.truffle.hotspot.amd64" : {
-      "subDir" : "graal",
-      "sourceDirs" : ["src"],
-      "dependencies" : [
-        "com.oracle.graal.truffle.hotspot",
-        "com.oracle.graal.asm.amd64",
-      ],
-      "checkstyle" : "com.oracle.graal.graph",
-      "javaCompliance" : "1.8",
-      "annotationProcessors" : ["com.oracle.graal.service.processor"],
-      "workingSets" : "Graal,Truffle",
-    }
-  },
-
-  "distributions" : {
-    "GRAAL" : {
-      "path" : "build/graal.jar",
-      "subDir" : "graal",
-      "sourcesPath" : "build/graal.src.zip",
-      "dependencies" : [
-        "com.oracle.graal.hotspot.amd64",
-        "com.oracle.graal.hotspot.ptx",
-        "com.oracle.graal.hotspot.sparc",
-        "com.oracle.graal.hotspot",
-        "com.oracle.graal.hotspot.jfr",
-        "com.oracle.graal.hotspot.hsail",
-      ],
-      "exclude" : ["FINDBUGS"],
-    },
-
-    "GRAAL_LOADER" : {
-      "path" : "build/graal-loader.jar",
-      "subDir" : "graal",
-      "sourcesPath" : "build/graal-loader.src.zip",
-      "dependencies" : ["com.oracle.graal.hotspot.loader"],
-    },
-
-    "TRUFFLE" : {
-      "path" : "build/truffle.jar",
-      "subDir" : "graal",
-      "sourcesPath" : "build/truffle.src.zip",
-      "javaCompliance" : "1.7",
-      "dependencies" : [
-        "com.oracle.truffle.api.dsl",
-        "com.oracle.nfi",
-      ],
-    },
-
-    "GRAAL_TRUFFLE" : {
-      "path" : "build/graal-truffle.jar",
-      "subDir" : "graal",
-      "sourcesPath" : "build/graal-truffle.src.zip",
-      "dependencies" : [
-        "com.oracle.graal.truffle",
-        "com.oracle.graal.truffle.hotspot.amd64",
-      ],
-      "exclude" : ["FINDBUGS"],
-      "distDependencies" : [
-        "GRAAL",
-        "TRUFFLE",
-      ],
-    },
-
-    "TRUFFLE-DSL-PROCESSOR" : {
-      "path" : "build/truffle-dsl-processor.jar",
-      "subDir" : "graal",
-      "sourcesPath" : "build/truffle-dsl-processor.src.zip",
-      "javaCompliance" : "1.7",
-      "dependencies" : ["com.oracle.truffle.dsl.processor"],
-      "distDependencies" : ["TRUFFLE"],
-    }
-  },
-
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mx/suite.py	Wed Sep 24 16:22:22 2014 -0700
@@ -0,0 +1,1255 @@
+suite = {
+  "mxversion" : "1.0",
+  "name" : "graal",
+  "libraries" : {
+    "JUNIT" : {
+      "path" : "lib/junit-4.11.jar",
+      "urls" : [
+        "http://lafo.ssw.uni-linz.ac.at/graal-external-deps/junit-4.11.jar",
+        "http://repo1.maven.org/maven2/junit/junit/4.11/junit-4.11.jar",
+      ],
+      "sha1" : "4e031bb61df09069aeb2bffb4019e7a5034a4ee0",
+      "eclipse.container" : "org.eclipse.jdt.junit.JUNIT_CONTAINER/4",
+      "sourcePath" : "lib/junit-4.11-sources.jar",
+      "sourceUrls" : [
+        "http://lafo.ssw.uni-linz.ac.at/graal-external-deps/junit-4.11-sources.jar",
+        "http://repo1.maven.org/maven2/junit/junit/4.11/junit-4.11-sources.jar",
+      ],
+      "sourceSha1" : "28e0ad201304e4a4abf999ca0570b7cffc352c3c",
+      "dependencies" : ["HAMCREST"],
+    },
+
+    "HAMCREST" : {
+      "path" : "lib/hamcrest-core-1.3.jar",
+      "urls" : [
+        "http://lafo.ssw.uni-linz.ac.at/graal-external-deps/hamcrest-core-1.3.jar",
+        "http://repo1.maven.org/maven2/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar",
+      ],
+      "sha1" : "42a25dc3219429f0e5d060061f71acb49bf010a0",
+      "sourcePath" : "lib/hamcrest-core-1.3-sources.jar",
+      "sourceUrls" : [
+        "http://lafo.ssw.uni-linz.ac.at/graal-external-deps/hamcrest-core-1.3-sources.jar",
+        "http://repo1.maven.org/maven2/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3-sources.jar",
+      ],
+      "sourceSha1" : "1dc37250fbc78e23a65a67fbbaf71d2e9cbc3c0b",
+    },
+
+    "HCFDIS" : {
+      "path" : "lib/hcfdis-2.jar",
+      "urls" : ["http://lafo.ssw.uni-linz.ac.at/hcfdis-2.jar"],
+      "sha1" : "bc8b2253436485e9dbaf81771c259ccfa1a24c80",
+    },
+
+    "FINDBUGS_DIST" : {
+      "path" : "lib/findbugs-dist-3.0.0.zip",
+      "urls" : [
+        "http://lafo.ssw.uni-linz.ac.at/graal-external-deps/findbugs-3.0.0.zip",
+        "http://sourceforge.net/projects/findbugs/files/findbugs/3.0.0/findbugs-3.0.0.zip/download",
+      ],
+      "sha1" : "6e56d67f238dbcd60acb88a81655749aa6419c5b",
+    },
+
+    "C1VISUALIZER_DIST" : {
+      "path" : "lib/c1visualizer_2014-04-22.zip",
+      "urls" : ["https://java.net/downloads/c1visualizer/c1visualizer_2014-04-22.zip"],
+      "sha1" : "220488d87affb569b893c7201f8ce5d2b0e03141",
+    },
+
+    "JOL_INTERNALS" : {
+      "path" : "lib/jol-internals.jar",
+      "urls" : ["http://lafo.ssw.uni-linz.ac.at/truffle/jol/jol-internals.jar"],
+      "sha1" : "508bcd26a4d7c4c44048990c6ea789a3b11a62dc",
+    },
+
+    "FINDBUGS" : {
+      "path" : "lib/findbugs-3.0.0.jar",
+      "urls" : [
+        "jar:http://lafo.ssw.uni-linz.ac.at/graal-external-deps/findbugs-3.0.0.zip!/findbugs-3.0.0/lib/findbugs.jar",
+        "jar:http://sourceforge.net/projects/findbugs/files/findbugs/3.0.0/findbugs-3.0.0.zip/download!/findbugs-3.0.0/lib/findbugs.jar",
+      ],
+      "sha1" : "e9a938f0cb34e2ab5853f9ecb1989f6f590ee385",
+    },
+
+    "DACAPO" : {
+      "path" : "lib/dacapo-9.12-bach.jar",
+      "urls" : [
+        "http://lafo.ssw.uni-linz.ac.at/graal-external-deps/dacapo-9.12-bach.jar",
+        "http://softlayer.dl.sourceforge.net/project/dacapobench/9.12-bach/dacapo-9.12-bach.jar",
+      ],
+      "sha1" : "2626a9546df09009f6da0df854e6dc1113ef7dd4",
+    },
+
+    "JACOCOAGENT" : {
+      "path" : "lib/jacocoagent.jar",
+      "urls" : ["http://lafo.ssw.uni-linz.ac.at/jacoco/jacocoagent-0.7.1-1.jar"],
+      "sha1" : "2f73a645b02e39290e577ce555f00b02004650b0",
+    },
+
+    "JACOCOREPORT" : {
+      "path" : "lib/jacocoreport.jar",
+      "urls" : ["http://lafo.ssw.uni-linz.ac.at/jacoco/jacocoreport-0.7.1-2.jar"],
+      "sha1" : "a630436391832d697a12c8f7daef8655d7a1efd2",
+    },
+
+    "DACAPO_SCALA" : {
+      "path" : "lib/dacapo-scala-0.1.0-20120216.jar",
+      "urls" : [
+        "http://lafo.ssw.uni-linz.ac.at/graal-external-deps/dacapo-scala-0.1.0-20120216.jar",
+        "http://repo.scalabench.org/snapshots/org/scalabench/benchmarks/scala-benchmark-suite/0.1.0-SNAPSHOT/scala-benchmark-suite-0.1.0-20120216.103539-3.jar",
+      ],
+      "sha1" : "59b64c974662b5cf9dbd3cf9045d293853dd7a51",
+    },
+
+    "OKRA" : {
+      "path" : "lib/okra-1.10.jar",
+      "urls" : [
+        "http://lafo.ssw.uni-linz.ac.at/graal-external-deps/okra-1.10.jar",
+        "http://cr.openjdk.java.net/~tdeneau/okra-1.10.jar",
+      ],
+      "sha1" : "96eb3c0ec808ed944ba88d1eb9311058fe0f3d1e",
+      "sourcePath" : "lib/okra-1.10-src.jar",
+      "sourceUrls" : [
+        "http://lafo.ssw.uni-linz.ac.at/graal-external-deps/okra-1.10-src.jar",
+        "http://cr.openjdk.java.net/~tdeneau/okra-1.10-src.jar",
+      ],
+      "sourceSha1" : "75751bb148fcebaba78ff590f883a114b2b09176",
+    },
+
+    "OKRA_WITH_SIM" : {
+      "path" : "lib/okra-1.10-with-sim.jar",
+      "urls" : [
+        "http://lafo.ssw.uni-linz.ac.at/graal-external-deps/okra-1.10-with-sim.jar",
+        "http://cr.openjdk.java.net/~tdeneau/okra-1.10-with-sim.jar",
+      ],
+      "sha1" : "7b8db879f1dbcf571290add78d9af24e15a2a50d",
+      "sourcePath" : "lib/okra-1.10-with-sim-src.jar",
+      "sourceSha1" : "7eefd94f16a3e3fd3b8f470cf91e265c6f5e7767",
+      "sourceUrls" : [
+        "http://lafo.ssw.uni-linz.ac.at/graal-external-deps/okra-1.10-with-sim-src.jar",
+        "http://cr.openjdk.java.net/~tdeneau/okra-1.10-with-sim-src.jar",
+      ],
+    },
+
+    "ASM" : {
+      "path" : "lib/asm-5.0.3.jar",
+      "urls" : [
+        "http://lafo.ssw.uni-linz.ac.at/graal-external-deps/asm-5.0.3.jar",
+        "http://central.maven.org/maven2/org/ow2/asm/asm/5.0.3/asm-5.0.3.jar",
+      ],
+      "sha1" : "dcc2193db20e19e1feca8b1240dbbc4e190824fa",
+      "sourcePath" : "lib/asm-5.0.3-sources.jar",
+      "sourceSha1" : "f0f24f6666c1a15c7e202e91610476bd4ce59368",
+      "sourceUrls" : [
+        "http://lafo.ssw.uni-linz.ac.at/graal-external-deps/asm-5.0.3-sources.jar",
+        "http://central.maven.org/maven2/org/ow2/asm/asm/5.0.3/asm-5.0.3-sources.jar",
+      ],
+    },
+
+    "JAVA_ALLOCATION_INSTRUMENTER" : {
+      "path" : "lib/java-allocation-instrumenter.jar",
+      "sourcePath" : "lib/java-allocation-instrumenter.jar",
+      "urls" : ["http://lafo.ssw.uni-linz.ac.at/java-allocation-instrumenter/java-allocation-instrumenter-8f0db117e64e.jar"],
+      "sha1" : "476d9a44cd19d6b55f81571077dfa972a4f8a083",
+      "bootClassPathAgent" : "true",
+    },
+
+    "VECMATH" : {
+      "path" : "lib/vecmath-1.3.1.jar",
+      "urls" : [
+        "http://lafo.ssw.uni-linz.ac.at/graal-external-deps/vecmath-1.3.1.jar",
+        "http://mirrors.ibiblio.org/pub/mirrors/maven/java3d/jars/vecmath-1.3.1.jar",
+      ],
+      "sha1" : "a0ae4f51da409fa0c20fa0ca59e6bbc9413ae71d",
+    }
+  },
+
+  "jrelibraries" : {
+    "JFR" : {
+      "jar" : "jfr.jar",
+    }
+  },
+
+  "projects" : {
+    "com.oracle.nfi" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : [],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.7",
+    },
+
+    "com.oracle.nfi.test" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["test"],
+      "dependencies" : [
+        "com.oracle.nfi",
+        "com.oracle.graal.compiler.common",
+        "JUNIT",
+      ],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.7",
+    },
+
+    "com.oracle.graal.api.collections" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "API,Graal",
+    },
+
+    "com.oracle.graal.api.runtime" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "API,Graal",
+    },
+
+    "com.oracle.graal.api.test" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : [
+        "JUNIT",
+        "com.oracle.graal.api.runtime",
+      ],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "API,Graal,Test",
+    },
+
+    "com.oracle.graal.api.meta" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "API,Graal",
+    },
+
+    "com.oracle.graal.api.meta.test" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : [
+        "JUNIT",
+        "com.oracle.graal.runtime",
+        "com.oracle.graal.java",
+      ],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "API,Graal,Test",
+    },
+
+    "com.oracle.graal.api.code" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : ["com.oracle.graal.api.meta"],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "API,Graal",
+    },
+
+    "com.oracle.graal.api.replacements" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : ["com.oracle.graal.api.meta"],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "API,Graal,Replacements",
+    },
+
+    "com.oracle.graal.service.processor" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : ["com.oracle.graal.api.runtime"],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Codegen,HotSpot",
+    },
+
+    "com.oracle.graal.amd64" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : ["com.oracle.graal.api.code"],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,AMD64",
+    },
+
+    "com.oracle.graal.ptx" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : ["com.oracle.graal.api.code"],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,PTX",
+    },
+
+    "com.oracle.graal.sparc" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : ["com.oracle.graal.api.code"],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,SPARC",
+    },
+
+    "com.oracle.graal.hotspotvmconfig" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : ["com.oracle.graal.compiler.common"],
+      "checkstyle" : "com.oracle.graal.graph",
+      "annotationProcessors" : ["com.oracle.graal.service.processor"],
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,HotSpot",
+    },
+
+    "com.oracle.graal.hotspot" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : [
+        "com.oracle.graal.replacements",
+        "com.oracle.graal.runtime",
+        "com.oracle.graal.printer",
+        "com.oracle.graal.baseline",
+        "com.oracle.graal.hotspotvmconfig",
+        "com.oracle.nfi",
+      ],
+      "checkstyle" : "com.oracle.graal.graph",
+      "annotationProcessors" : [
+        "com.oracle.graal.replacements.verifier",
+        "com.oracle.graal.service.processor",
+      ],
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,HotSpot",
+    },
+
+    "com.oracle.graal.hotspot.loader" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : [],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,HotSpot",
+    },
+
+    "com.oracle.graal.hotspot.sourcegen" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : ["com.oracle.graal.hotspot"],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,HotSpot",
+    },
+
+    "com.oracle.graal.hotspot.jfr" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : [
+        "com.oracle.graal.hotspot",
+        "JFR",
+      ],
+      "checkstyle" : "com.oracle.graal.graph",
+      "annotationProcessors" : ["com.oracle.graal.service.processor"],
+      "javaCompliance" : "1.8",
+      "profile" : "",
+      "workingSets" : "Graal,HotSpot",
+    },
+
+    "com.oracle.graal.hotspot.amd64" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : [
+        "com.oracle.graal.compiler.amd64",
+        "com.oracle.graal.hotspot",
+        "com.oracle.graal.replacements.amd64",
+      ],
+      "checkstyle" : "com.oracle.graal.graph",
+      "annotationProcessors" : ["com.oracle.graal.service.processor"],
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,HotSpot,AMD64",
+    },
+
+    "com.oracle.graal.hotspot.sparc" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : ["com.oracle.graal.compiler.sparc"],
+      "checkstyle" : "com.oracle.graal.graph",
+      "annotationProcessors" : ["com.oracle.graal.service.processor"],
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,HotSpot,SPARC",
+    },
+
+    "com.oracle.graal.hotspot.ptx" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : [
+        "com.oracle.graal.ptx",
+        "com.oracle.graal.compiler.ptx",
+        "com.oracle.graal.hotspot",
+        "com.oracle.graal.gpu",
+      ],
+      "checkstyle" : "com.oracle.graal.graph",
+      "annotationProcessors" : ["com.oracle.graal.service.processor"],
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,HotSpot,PTX",
+    },
+
+    "com.oracle.graal.hotspot.hsail" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : [
+        "com.oracle.graal.replacements.hsail",
+        "com.oracle.graal.hotspot",
+        "com.oracle.graal.gpu",
+      ],
+      "checkstyle" : "com.oracle.graal.graph",
+      "annotationProcessors" : ["com.oracle.graal.service.processor"],
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,HotSpot,PTX",
+    },
+
+    "com.oracle.graal.hotspot.server" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : ["com.oracle.graal.hotspot"],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,HotSpot",
+    },
+
+    "com.oracle.graal.hotspot.test" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : [
+        "com.oracle.graal.replacements.test",
+        "com.oracle.graal.hotspot",
+      ],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,HotSpot,Test",
+    },
+
+    "com.oracle.graal.hotspot.amd64.test" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : [
+        "com.oracle.graal.asm.amd64",
+        "com.oracle.graal.compiler.test",
+        "com.oracle.graal.hotspot",
+      ],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,HotSpot,AMD64,Test",
+    },
+
+    "com.oracle.graal.options" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,Codegen",
+    },
+
+    "com.oracle.graal.options.test" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : [
+        "com.oracle.graal.options",
+        "JUNIT",
+      ],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal",
+    },
+
+    "com.oracle.graal.nodeinfo" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,Graph",
+    },
+
+    "com.oracle.graal.nodeinfo.processor" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "checkstyle" : "com.oracle.graal.graph",
+      "dependencies" : [
+        "com.oracle.graal.nodeinfo",
+        "com.oracle.truffle.dsl.processor",
+      ],
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,Graph",
+    },
+
+    "com.oracle.graal.graph" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : [
+        "com.oracle.graal.nodeinfo",
+        "com.oracle.graal.debug",
+        "com.oracle.graal.compiler.common",
+        "com.oracle.graal.api.collections",
+        "com.oracle.graal.api.runtime",
+        "FINDBUGS",
+      ],
+      "javaCompliance" : "1.8",
+      "annotationProcessors" : ["com.oracle.graal.nodeinfo.processor"],
+      "workingSets" : "Graal,Graph",
+    },
+
+    "com.oracle.graal.graph.test" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "checkstyle" : "com.oracle.graal.graph",
+      "dependencies" : [
+        "JUNIT",
+        "com.oracle.graal.graph",
+      ],
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,Graph,Test",
+    },
+
+    "com.oracle.graal.debug" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,Debug",
+    },
+
+    "com.oracle.graal.debug.test" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : [
+        "JUNIT",
+        "com.oracle.graal.debug",
+      ],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,Debug,Test",
+    },
+
+    "com.oracle.graal.lir" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : [
+        "com.oracle.graal.compiler.common",
+        "com.oracle.graal.asm",
+        "com.oracle.graal.debug",
+      ],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,LIR",
+    },
+
+    "com.oracle.graal.lir.test" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : [
+        "JUNIT",
+        "com.oracle.graal.lir",
+      ],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,LIR",
+    },
+
+    "com.oracle.graal.lir.amd64" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : [
+        "com.oracle.graal.lir",
+        "com.oracle.graal.asm.amd64",
+      ],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,LIR,AMD64",
+    },
+
+    "com.oracle.graal.lir.ptx" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : ["com.oracle.graal.asm.ptx"],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,LIR,PTX",
+    },
+
+    "com.oracle.graal.lir.sparc" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : ["com.oracle.graal.asm.sparc"],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,LIR,SPARC",
+    },
+
+    "com.oracle.graal.alloc" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : ["com.oracle.graal.compiler.common"],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal",
+    },
+
+    "com.oracle.graal.word" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : ["com.oracle.graal.phases"],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "API,Graal",
+    },
+
+    "com.oracle.graal.replacements" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : [
+        "com.oracle.graal.compiler",
+        "com.oracle.graal.java",
+        "com.oracle.graal.word",
+      ],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "annotationProcessors" : [
+        "com.oracle.graal.replacements.verifier",
+        "com.oracle.graal.service.processor",
+      ],
+      "workingSets" : "Graal,Replacements",
+    },
+
+    "com.oracle.graal.replacements.amd64" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : ["com.oracle.graal.replacements"],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "annotationProcessors" : ["com.oracle.graal.service.processor"],
+      "workingSets" : "Graal,Replacements,AMD64",
+    },
+
+    "com.oracle.graal.replacements.hsail" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : ["com.oracle.graal.compiler.hsail"],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,Replacements,HSAIL",
+    },
+
+    "com.oracle.graal.replacements.test" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : [
+        "com.oracle.graal.compiler.test",
+        "com.oracle.graal.replacements",
+      ],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,Replacements,Test",
+    },
+
+    "com.oracle.graal.replacements.verifier" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : [
+        "com.oracle.graal.api.replacements",
+        "com.oracle.graal.graph",
+      ],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,Replacements",
+    },
+
+    "com.oracle.graal.nodes" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : [
+        "com.oracle.graal.graph",
+        "com.oracle.graal.api.replacements",
+        "com.oracle.graal.lir",
+      ],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "annotationProcessors" : ["com.oracle.graal.replacements.verifier"],
+      "workingSets" : "Graal,Graph",
+    },
+
+    "com.oracle.graal.nodes.test" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : ["com.oracle.graal.compiler.test"],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,Graph",
+    },
+
+    "com.oracle.graal.phases" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : ["com.oracle.graal.nodes"],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,Phases",
+    },
+
+    "com.oracle.graal.phases.common" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : ["com.oracle.graal.phases"],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,Phases",
+    },
+
+    "com.oracle.graal.virtual" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : ["com.oracle.graal.phases.common"],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,Phases",
+    },
+
+    "com.oracle.graal.loop" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : ["com.oracle.graal.phases.common"],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,Phases",
+    },
+
+    "com.oracle.graal.compiler" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : [
+        "com.oracle.graal.virtual",
+        "com.oracle.graal.loop",
+        "com.oracle.graal.alloc",
+      ],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "annotationProcessors" : ["com.oracle.graal.service.processor"],
+      "workingSets" : "Graal",
+    },
+
+    "com.oracle.graal.compiler.amd64" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : [
+        "com.oracle.graal.compiler",
+        "com.oracle.graal.lir.amd64",
+      ],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,AMD64",
+    },
+
+    "com.oracle.graal.compiler.amd64.test" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : ["com.oracle.graal.compiler.test"],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,AMD64,Test",
+    },
+
+    "com.oracle.graal.compiler.ptx" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : [
+        "com.oracle.graal.lir.ptx",
+        "com.oracle.graal.compiler",
+      ],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,PTX",
+    },
+
+    "com.oracle.graal.compiler.ptx.test" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : [
+        "com.oracle.graal.hotspot.ptx",
+        "com.oracle.graal.compiler.test",
+      ],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,PTX,Test",
+    },
+
+    "com.oracle.graal.compiler.sparc" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : ["com.oracle.graal.lir.sparc"],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,SPARC",
+    },
+
+    "com.oracle.graal.compiler.sparc.test" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : ["com.oracle.graal.compiler.test"],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,SPARC,Test",
+    },
+
+    "com.oracle.graal.runtime" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : ["com.oracle.graal.compiler"],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal",
+    },
+
+    "com.oracle.graal.bytecode" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,Java",
+    },
+
+    "com.oracle.graal.java" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : [
+        "com.oracle.graal.phases",
+        "com.oracle.graal.bytecode",
+      ],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,Java",
+    },
+
+    "com.oracle.graal.compiler.common" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : [
+        "com.oracle.graal.api.code",
+        "com.oracle.graal.options",
+      ],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,Java",
+    },
+
+    "com.oracle.graal.baseline" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : [
+        "com.oracle.graal.compiler",
+        "com.oracle.graal.java",
+      ],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,Java",
+    },
+
+    "com.oracle.graal.java.decompiler" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : ["com.oracle.graal.java"],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal",
+    },
+
+    "com.oracle.graal.java.decompiler.test" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : [
+        "JUNIT",
+        "com.oracle.graal.printer",
+        "com.oracle.graal.runtime",
+      ],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,Test",
+    },
+
+    "com.oracle.graal.printer" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : [
+        "com.oracle.graal.java.decompiler",
+        "com.oracle.graal.compiler",
+      ],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,Graph",
+    },
+
+    "com.oracle.graal.test" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : [
+        "JUNIT",
+        "com.oracle.graal.debug",
+      ],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,Test",
+    },
+
+    "com.oracle.graal.compiler.test" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : [
+        "com.oracle.graal.test",
+        "com.oracle.graal.printer",
+        "com.oracle.graal.runtime",
+        "com.oracle.graal.baseline",
+        "JAVA_ALLOCATION_INSTRUMENTER",
+      ],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,Test",
+    },
+
+    "com.oracle.graal.jtt" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : [
+        "com.oracle.graal.compiler.test",
+        "ASM",
+      ],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,Test",
+    },
+
+    "com.oracle.graal.asm" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : ["com.oracle.graal.api.code"],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,Assembler",
+    },
+
+    "com.oracle.graal.asm.test" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : [
+        "com.oracle.graal.test",
+        "com.oracle.graal.runtime",
+      ],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,Assembler,Test",
+    },
+
+    "com.oracle.graal.asm.amd64" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : [
+        "com.oracle.graal.asm",
+        "com.oracle.graal.amd64",
+      ],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,Assembler,AMD64",
+    },
+
+    "com.oracle.graal.asm.amd64.test" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : [
+        "com.oracle.graal.asm.test",
+        "com.oracle.graal.asm.amd64",
+      ],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,Assembler,AMD64,Test",
+    },
+
+    "com.oracle.graal.gpu" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : ["com.oracle.graal.nodes"],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+    },
+
+    "com.oracle.graal.hsail" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : ["com.oracle.graal.api.code"],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+    },
+
+    "com.oracle.graal.lir.hsail" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : [
+        "com.oracle.graal.lir",
+        "com.oracle.graal.asm.hsail",
+      ],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+    },
+
+    "com.oracle.graal.compiler.hsail" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : [
+        "com.oracle.graal.compiler",
+        "com.oracle.graal.lir.hsail",
+      ],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+    },
+
+    "com.oracle.graal.compiler.hsail.test.infra" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : [
+        "com.oracle.graal.test",
+        "com.oracle.graal.hotspot.hsail",
+        "OKRA_WITH_SIM",
+      ],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+    },
+
+    "com.oracle.graal.compiler.hsail.test" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : [
+        "com.oracle.graal.compiler.hsail.test.infra",
+        "com.oracle.graal.compiler.test",
+        "VECMATH",
+      ],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+    },
+
+    "com.oracle.graal.asm.hsail" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : [
+        "com.oracle.graal.hsail",
+        "OKRA",
+        "com.oracle.graal.asm",
+        "com.oracle.graal.compiler.common",
+      ],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+    },
+
+    "com.oracle.graal.asm.ptx" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : ["com.oracle.graal.lir"],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,Assembler,PTX",
+    },
+
+    "com.oracle.graal.asm.sparc" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : [
+        "com.oracle.graal.hotspot",
+        "com.oracle.graal.sparc",
+      ],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,Assembler,SPARC",
+    },
+
+    "com.oracle.truffle.api" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : [],
+      "javaCompliance" : "1.7",
+      "workingSets" : "API,Truffle",
+    },
+
+    "com.oracle.truffle.api.test" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : [
+        "com.oracle.truffle.api",
+        "JUNIT",
+      ],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.7",
+      "workingSets" : "API,Truffle,Test",
+    },
+
+    "com.oracle.truffle.api.dsl" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : ["com.oracle.truffle.api"],
+      "checkstyle" : "com.oracle.truffle.api",
+      "javaCompliance" : "1.7",
+      "workingSets" : "API,Truffle,Codegen",
+    },
+
+    "com.oracle.truffle.api.dsl.test" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : [
+        "com.oracle.truffle.api.dsl",
+        "JUNIT",
+      ],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.7",
+      "annotationProcessors" : ["com.oracle.truffle.dsl.processor"],
+      "workingSets" : "API,Truffle,Codegen,Test",
+    },
+
+    "com.oracle.truffle.dsl.processor" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : ["com.oracle.truffle.api.dsl"],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.7",
+      "workingSets" : "Truffle,Codegen",
+    },
+
+    "com.oracle.truffle.sl" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : ["com.oracle.truffle.api.dsl"],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "annotationProcessors" : ["com.oracle.truffle.dsl.processor"],
+      "workingSets" : "Truffle,SimpleLanguage",
+    },
+
+    "com.oracle.truffle.sl.test" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : [
+        "com.oracle.truffle.sl",
+        "JUNIT",
+      ],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Truffle,SimpleLanguage,Test",
+    },
+
+    "com.oracle.graal.truffle" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : [
+        "com.oracle.truffle.api",
+        "com.oracle.graal.replacements",
+        "com.oracle.graal.runtime",
+        "com.oracle.graal.printer",
+      ],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,Truffle",
+    },
+
+    "com.oracle.graal.truffle.test" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : [
+        "com.oracle.graal.truffle",
+        "com.oracle.graal.compiler.test",
+        "com.oracle.truffle.sl.test",
+      ],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,Truffle,Test",
+    },
+
+    "com.oracle.graal.truffle.hotspot" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : [
+        "com.oracle.graal.truffle",
+        "com.oracle.graal.hotspot",
+      ],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "annotationProcessors" : ["com.oracle.graal.service.processor"],
+      "workingSets" : "Graal,Truffle",
+    },
+
+    "com.oracle.graal.truffle.hotspot.amd64" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : [
+        "com.oracle.graal.truffle.hotspot",
+        "com.oracle.graal.asm.amd64",
+      ],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "annotationProcessors" : ["com.oracle.graal.service.processor"],
+      "workingSets" : "Graal,Truffle",
+    }
+  },
+
+  "distributions" : {
+    "GRAAL" : {
+      "path" : "build/graal.jar",
+      "subDir" : "graal",
+      "sourcesPath" : "build/graal.src.zip",
+      "dependencies" : [
+        "com.oracle.graal.hotspot.amd64",
+        "com.oracle.graal.hotspot.ptx",
+        "com.oracle.graal.hotspot.sparc",
+        "com.oracle.graal.hotspot",
+        "com.oracle.graal.hotspot.jfr",
+        "com.oracle.graal.hotspot.hsail",
+      ],
+      "exclude" : ["FINDBUGS"],
+    },
+
+    "GRAAL_LOADER" : {
+      "path" : "build/graal-loader.jar",
+      "subDir" : "graal",
+      "sourcesPath" : "build/graal-loader.src.zip",
+      "dependencies" : ["com.oracle.graal.hotspot.loader"],
+    },
+
+    "TRUFFLE" : {
+      "path" : "build/truffle.jar",
+      "subDir" : "graal",
+      "sourcesPath" : "build/truffle.src.zip",
+      "javaCompliance" : "1.7",
+      "dependencies" : [
+        "com.oracle.truffle.api.dsl",
+        "com.oracle.nfi",
+      ],
+    },
+
+    "GRAAL_TRUFFLE" : {
+      "path" : "build/graal-truffle.jar",
+      "subDir" : "graal",
+      "sourcesPath" : "build/graal-truffle.src.zip",
+      "dependencies" : [
+        "com.oracle.graal.truffle",
+        "com.oracle.graal.truffle.hotspot.amd64",
+      ],
+      "exclude" : ["FINDBUGS"],
+      "distDependencies" : [
+        "GRAAL",
+        "TRUFFLE",
+      ],
+    },
+
+    "TRUFFLE-DSL-PROCESSOR" : {
+      "path" : "build/truffle-dsl-processor.jar",
+      "subDir" : "graal",
+      "sourcesPath" : "build/truffle-dsl-processor.src.zip",
+      "javaCompliance" : "1.7",
+      "dependencies" : ["com.oracle.truffle.dsl.processor"],
+      "distDependencies" : ["TRUFFLE"],
+    }
+  },
+
+}
--- a/mxtool/mx.py	Wed Sep 24 16:13:34 2014 -0700
+++ b/mxtool/mx.py	Wed Sep 24 16:22:22 2014 -0700
@@ -850,114 +850,6 @@
                 attrs[attr] = value
     return suite
 
-# TODO: remove this command once all repos have transitioned
-# to the new project format
-def convertprojects(args, verbose=True):
-    """convert old style projects file to projects*.py file(s)"""
-
-    class Printer:
-        def __init__(self, fp, indent):
-            self.fp = fp
-            self.indent = indent
-            self.prefix = ''
-        def println(self, s):
-            if len(s) == 0:
-                print >> self.fp, s
-            else:
-                print >> self.fp, self.prefix + s
-        def inc(self):
-            self.prefix = ''.rjust(len(self.prefix) + self.indent)
-        def dec(self):
-            self.prefix = ''.rjust(len(self.prefix) - self.indent)
-
-    list_attrs = ['urls', 'dependencies', 'sourceUrls', 'sourceDirs', 'annotationProcessors', 'exclude', 'distDependencies']
-
-    for projectsFile in args:
-        suite = _read_projects_file(projectsFile)
-        def print_attrs(p, name, attrs, is_last=False):
-            p.println('"' + name + '" : {')
-            p.inc()
-            for n, v in attrs.iteritems():
-                if n in list_attrs:
-                    if len(v) == 0:
-                        p.println('"{}" : [],'.format(n))
-                    else:
-                        v = [e.strip() for e in v.split(',')]
-                        if len(v) == 1:
-                            p.println('"{}" : ["{}"],'.format(n, v[0]))
-                        else:
-                            p.println('"{}" : ['.format(n))
-                            p.inc()
-                            for e in v:
-                                p.println('"' + e + '",')
-                            p.dec()
-                            p.println('],')
-                else:
-                    p.println('"{}" : "{}",'.format(n, v))
-            p.dec()
-            if is_last:
-                p.println('}')
-            else:
-                p.println('},')
-                p.println('')
-
-        def print_section(p, sname, suite, is_last=False):
-            section = suite.get(sname)
-            if section:
-                p.println('"' + sname + '" : {')
-                p.inc()
-                i = 0
-                for name, attrs in section.iteritems():
-                    i = i + 1
-                    print_attrs(p, name, attrs, i == len(section))
-
-                p.dec()
-                if is_last:
-                    p.println('}')
-                else:
-                    p.println('},')
-                    p.println('')
-
-        existing, projectsPyFile = _load_suite_dict(dirname(projectsFile))
-        if existing:
-            assert existing['name'] == suite.pop('name')
-            assert existing['mxversion'] == suite.pop('mxversion')
-            for s in ['projects', 'libraries', 'jrelibraries', 'distributions']:
-                section = suite[s]
-                for k in existing[s].iterkeys():
-                    duplicate = section.pop(k)
-                    if duplicate and s == 'distributions':
-                        original = existing[s][k]
-                        extensions = [d for d in duplicate['dependencies'].split(',') if d not in original['dependencies']]
-                        if len(extensions):
-                            extensions = ','.join(extensions)
-                            suite.setdefault('distribution_extensions', {})[k] = {'dependencies' : extensions}
-                if len(section) == 0:
-                    suite.pop(s)
-
-        if len(suite):
-            out = StringIO.StringIO()
-            p = Printer(out, 2)
-            p.println(('extra' if existing else 'suite') + ' = {')
-            p.inc()
-            if not existing:
-                p.println('"mxversion" : "' + suite['mxversion'] + '",')
-                p.println('"name" : "' + suite['name'] + '",')
-            print_section(p, 'libraries', suite)
-            print_section(p, 'jrelibraries', suite)
-            print_section(p, 'projects', suite)
-            print_section(p, 'distributions', suite)
-            if existing and suite.has_key('distribution_extensions'):
-                print_section(p, 'distribution_extensions', suite, is_last=True)
-
-            p.dec()
-            p.println('}')
-
-            with open(projectsPyFile, 'w') as fp:
-                fp.write(out.getvalue())
-                if verbose:
-                    print 'created: ' + projectsPyFile
-
 def _load_suite_dict(mxDir):
 
     suffix = 1
@@ -980,7 +872,7 @@
 
         return value
 
-    moduleName = 'projects'
+    moduleName = 'suite'
     modulePath = join(mxDir, moduleName + '.py')
     while exists(modulePath):
 
@@ -1046,8 +938,13 @@
                         original['dependencies'] += v
 
         dictName = 'extra'
-        moduleName = 'projects' + str(suffix)
+        moduleName = 'suite' + str(suffix)
         modulePath = join(mxDir, moduleName + '.py')
+
+        deprecatedModulePath = join(mxDir, 'projects' + str(suffix) + '.py')
+        if exists(deprecatedModulePath):
+            abort('Please rename ' + deprecatedModulePath + ' to ' + modulePath)
+
         suffix = suffix + 1
 
     return suite, modulePath
@@ -1075,13 +972,8 @@
         return self.name
 
     def _load_projects(self):
-        # TODO: remove once mx/projects has been deprecated
-        projectsFile = join(self.mxDir, 'projects')
-        if exists(projectsFile):
-            convertprojects([projectsFile], verbose=False)
-
-        projectsPyFile = join(self.mxDir, 'projects.py')
-        if not exists(projectsPyFile):
+        suitePyFile = join(self.mxDir, 'suite.py')
+        if not exists(suitePyFile):
             return
 
         suiteDict, _ = _load_suite_dict(self.mxDir)
@@ -1219,7 +1111,7 @@
                 self.dists.append(d)
 
         if self.name is None:
-            abort('Missing "suite=<name>" in ' + projectsPyFile)
+            abort('Missing "suite=<name>" in ' + suitePyFile)
 
     def _commands_name(self):
         return 'mx_' + self.name.replace('-', '_')
@@ -3586,8 +3478,8 @@
 
 def _check_ide_timestamp(suite, configZip, ide):
     """return True if and only if the projects file, eclipse-settings files, and mx itself are all older than configZip"""
-    projectsPyFiles = [join(suite.mxDir, e) for e in os.listdir(suite.mxDir) if e.startswith('projects') and e.endswith('.py')]
-    if configZip.isOlderThan(projectsPyFiles):
+    suitePyFiles = [join(suite.mxDir, e) for e in os.listdir(suite.mxDir) if e.startswith('suite') and e.endswith('.py')]
+    if configZip.isOlderThan(suitePyFiles):
         return False
     # Assume that any mx change might imply changes to the generated IDE files
     if configZip.isOlderThan(__file__):
@@ -5128,13 +5020,28 @@
         run([javapExe, '-private', '-verbose', '-classpath', classpath()] + selection)
 
 def show_projects(args):
-    """show all loaded projects"""
+    """show all projects"""
     for s in suites():
         if len(s.projects) != 0:
-            log(join(s.mxDir, 'projects*.py'))
+            log(join(s.mxDir, 'suite*.py'))
             for p in s.projects:
                 log('\t' + p.name)
 
+def show_suites(args):
+    """show all suites"""
+    def _show_section(name, section):
+        if len(section) != 0:
+            log('  ' + name + ':')
+            for e in section:
+                log('    ' + e.name)
+
+    for s in suites():
+        log(join(s.mxDir, 'suite*.py'))
+        _show_section('libraries', s.libs)
+        _show_section('jrelibraries', s.jreLibs)
+        _show_section('projects', s.projects)
+        _show_section('distributions', s.dists)
+
 def ask_yes_no(question, default=None):
     """"""
     assert not default or default == 'y' or default == 'n'
@@ -5177,7 +5084,6 @@
     'about': [about, ''],
     'build': [build, '[options]'],
     'checkstyle': [checkstyle, ''],
-    'convertprojects' : [convertprojects, ''],
     'canonicalizeprojects': [canonicalizeprojects, ''],
     'clean': [clean, ''],
     'eclipseinit': [eclipseinit, ''],
@@ -5196,6 +5102,7 @@
     'javadoc': [javadoc, '[options]'],
     'site': [site, '[options]'],
     'netbeansinit': [netbeansinit, ''],
+    'suites': [show_suites, ''],
     'projects': [show_projects, ''],
 }
 
@@ -5219,7 +5126,7 @@
         for f in os.listdir(d):
             if (mxDirName == None and (f == 'mx' or fnmatch.fnmatch(f, 'mx.*'))) or f == mxDirName:
                 mxDir = join(d, f)
-                if exists(mxDir) and isdir(mxDir) and (exists(join(mxDir, 'projects.py')) or exists(join(mxDir, 'projects'))):
+                if exists(mxDir) and isdir(mxDir) and (exists(join(mxDir, 'suite.py'))):
                     return mxDir
 
 def _check_primary_suite():