changeset 17200:56458afc02a3

Use common nodes for integer and floating point arithmetic.
author Roland Schatz <roland.schatz@oracle.com>
date Wed, 24 Sep 2014 14:57:03 +0200
parents 88012c1750a0
children 3f176485d807
files graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeLIRBuilder.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java graal/com.oracle.graal.loop/src/com/oracle/graal/loop/InductionVariables.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AddNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BinaryArithmeticNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BinaryNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/DivNode.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/MulNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/RemNode.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ProfileCompiledMethodsPhase.java
diffstat 20 files changed, 139 insertions(+), 610 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeLIRBuilder.java	Wed Sep 24 14:29:43 2014 +0200
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeLIRBuilder.java	Wed Sep 24 14:57:03 2014 +0200
@@ -281,9 +281,6 @@
                     return IADD;
                 case Long:
                     return LADD;
-            }
-        } else if (operation.getNodeClass().is(FloatAddNode.class)) {
-            switch (memoryKind) {
                 case Float:
                     return FADD;
                 case Double:
@@ -316,9 +313,6 @@
                     return ISUB;
                 case Long:
                     return LSUB;
-            }
-        } else if (operation.getNodeClass().is(FloatSubNode.class)) {
-            switch (memoryKind) {
                 case Float:
                     return FSUB;
                 case Double:
@@ -330,9 +324,6 @@
                     return IMUL;
                 case Long:
                     return LMUL;
-            }
-        } else if (operation.getNodeClass().is(FloatMulNode.class)) {
-            switch (memoryKind) {
                 case Float:
                     return FMUL;
                 case Double:
@@ -389,18 +380,12 @@
     @MatchRule("(Add value Read=access)")
     @MatchRule("(Sub value Read=access)")
     @MatchRule("(Mul value Read=access)")
-    @MatchRule("(FloatAdd value Read=access)")
-    @MatchRule("(FloatSub value Read=access)")
-    @MatchRule("(FloatMul value Read=access)")
     @MatchRule("(Or value Read=access)")
     @MatchRule("(Xor value Read=access)")
     @MatchRule("(And value Read=access)")
     @MatchRule("(Add value FloatingRead=access)")
     @MatchRule("(Sub value FloatingRead=access)")
     @MatchRule("(Mul value FloatingRead=access)")
-    @MatchRule("(FloatAdd value FloatingRead=access)")
-    @MatchRule("(FloatSub value FloatingRead=access)")
-    @MatchRule("(FloatMul value FloatingRead=access)")
     @MatchRule("(Or value FloatingRead=access)")
     @MatchRule("(Xor value FloatingRead=access)")
     @MatchRule("(And value FloatingRead=access)")
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java	Wed Sep 24 14:29:43 2014 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java	Wed Sep 24 14:57:03 2014 +0200
@@ -56,7 +56,6 @@
  */
 @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 = SubNode.class, inputs = {"x", "y"})
@@ -69,10 +68,8 @@
 @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 = 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)
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java	Wed Sep 24 14:29:43 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java	Wed Sep 24 14:57:03 2014 +0200
@@ -268,18 +268,12 @@
     @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("(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("(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("(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("(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("(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/meta/DefaultHotSpotLoweringProvider.java	Wed Sep 24 14:29:43 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java	Wed Sep 24 14:57:03 2014 +0200
@@ -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.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Wed Sep 24 14:29:43 2014 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Wed Sep 24 14:57:03 2014 +0200
@@ -487,27 +487,27 @@
 
             @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.loop/src/com/oracle/graal/loop/InductionVariables.java	Wed Sep 24 14:29:43 2014 +0200
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/InductionVariables.java	Wed Sep 24 14:57:03 2014 +0200
@@ -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.*;
@@ -93,7 +94,7 @@
     }
 
     private ValueNode addSub(ValueNode op, ValueNode base) {
-        if (op instanceof AddNode || op instanceof SubNode) {
+        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();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java	Wed Sep 24 14:29:43 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java	Wed Sep 24 14:57:03 2014 +0200
@@ -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,7 +248,7 @@
         for (int i = 0; i < phi.valueCount(); i++) {
             ValueNode input = phi.valueAt(i);
             long increment = NO_INCREMENT;
-            if (input != null && input instanceof AddNode) {
+            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();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AddNode.java	Wed Sep 24 14:29:43 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AddNode.java	Wed Sep 24 14:57:03 2014 +0200
@@ -94,7 +94,7 @@
         Value op1 = builder.operand(getX());
         assert op1 != null : getX() + ", this=" + this;
         Value op2 = builder.operand(getY());
-        if (!getY().isConstant() && !FloatAddNode.livesLonger(this, getY(), builder)) {
+        if (!getY().isConstant() && !BinaryArithmeticNode.livesLonger(this, getY(), builder)) {
             Value op = op1;
             op1 = op2;
             op2 = op;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BinaryArithmeticNode.java	Wed Sep 24 14:29:43 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BinaryArithmeticNode.java	Wed Sep 24 14:57:03 2014 +0200
@@ -25,6 +25,7 @@
 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.*;
@@ -225,4 +226,13 @@
             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 14:29:43 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BinaryNode.java	Wed Sep 24 14:57:03 2014 +0200
@@ -22,7 +22,6 @@
  */
 package com.oracle.graal.nodes.calc;
 
-import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodeinfo.*;
@@ -57,40 +56,4 @@
         this.x = x;
         this.y = y;
     }
-
-    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 BinaryArithmeticNode.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 BinaryArithmeticNode.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 BinaryArithmeticNode.mul(graph, x, y);
-        } else if (stamp instanceof FloatStamp) {
-            return graph.unique(FloatMulNode.create(x, y, false));
-        } else {
-            throw GraalInternalError.shouldNotReachHere();
-        }
-    }
 }
--- /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 14:57:03 2014 +0200
@@ -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 14:29:43 2014 +0200
+++ /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 14:29:43 2014 +0200
+++ /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 14:29:43 2014 +0200
+++ /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 14:29:43 2014 +0200
+++ /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 14:29:43 2014 +0200
+++ /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 14:29:43 2014 +0200
+++ /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/MulNode.java	Wed Sep 24 14:29:43 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/MulNode.java	Wed Sep 24 14:57:03 2014 +0200
@@ -83,7 +83,7 @@
     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)) {
+        if (!getY().isConstant() && !BinaryArithmeticNode.livesLonger(this, getY(), builder)) {
             Value op = op1;
             op1 = op2;
             op2 = op;
--- /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 14:57:03 2014 +0200
@@ -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.phases.common/src/com/oracle/graal/phases/common/ProfileCompiledMethodsPhase.java	Wed Sep 24 14:29:43 2014 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ProfileCompiledMethodsPhase.java	Wed Sep 24 14:57:03 2014 +0200
@@ -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 MulNode || node instanceof FloatMulNode) {
+        } else if (node instanceof MulNode) {
             return 3;
         } else if (node instanceof Invoke) {
             return 5;