changeset 20182:c5ae0424f822

Move special arithemtic nodes from graal.truffle to graal and use them to inrinsify some of the JDK8 Math methods
author Gilles Duboscq <gilles.m.duboscq@oracle.com>
date Tue, 07 Apr 2015 11:30:29 +0200
parents 8dec9eea3186
children 9dc78dc645e5
files graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StandardGraphBuilderPlugins.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/arithmetic/IntegerAddExactNode.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/arithmetic/IntegerAddExactSplitNode.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/arithmetic/IntegerExactArithmeticNode.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/arithmetic/IntegerExactArithmeticSplitNode.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/arithmetic/IntegerMulExactNode.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/arithmetic/IntegerMulExactSplitNode.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/arithmetic/IntegerMulHighNode.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/arithmetic/IntegerSubExactNode.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/arithmetic/IntegerSubExactSplitNode.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/arithmetic/UnsignedMulHighNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactSplitNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerExactArithmeticNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerExactArithmeticSplitNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulExactNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulExactSplitNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulHighNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactSplitNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/UnsignedMulHighNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/TruffleGraphBuilderPlugins.java mx/suite.py
diffstat 23 files changed, 821 insertions(+), 749 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StandardGraphBuilderPlugins.java	Tue Apr 07 11:19:39 2015 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StandardGraphBuilderPlugins.java	Tue Apr 07 11:30:29 2015 +0200
@@ -43,6 +43,7 @@
 import com.oracle.graal.nodes.util.*;
 import com.oracle.graal.options.*;
 import com.oracle.graal.replacements.nodes.*;
+import com.oracle.graal.replacements.nodes.arithmetic.*;
 
 /**
  * Provides non-runtime specific {@link InvocationPlugin}s.
@@ -243,6 +244,27 @@
 
     private static void registerMathPlugins(Architecture arch, InvocationPlugins plugins) {
         Registration r = new Registration(plugins, Math.class);
+        for (Kind kind : new Kind[]{Kind.Int, Kind.Long}) {
+            Class<?> type = kind.toJavaClass();
+            r.register2("addExact", type, type, new InvocationPlugin() {
+                public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x, ValueNode y) {
+                    b.addPush(kind.getStackKind(), new IntegerAddExactNode(x, y));
+                    return true;
+                }
+            });
+            r.register2("subtractExact", type, type, new InvocationPlugin() {
+                public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x, ValueNode y) {
+                    b.addPush(kind.getStackKind(), new IntegerSubExactNode(x, y));
+                    return true;
+                }
+            });
+            r.register2("multiplyExact", type, type, new InvocationPlugin() {
+                public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x, ValueNode y) {
+                    b.addPush(kind.getStackKind(), new IntegerMulExactNode(x, y));
+                    return true;
+                }
+            });
+        }
         r.register1("abs", Float.TYPE, new InvocationPlugin() {
             public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
                 b.push(Kind.Float, b.recursiveAppend(new AbsNode(value).canonical(null, value)));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/arithmetic/IntegerAddExactNode.java	Tue Apr 07 11:30:29 2015 +0200
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2013, 2015, 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.replacements.nodes.arithmetic;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.common.type.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
+import com.oracle.graal.nodeinfo.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.spi.*;
+
+/**
+ * Node representing an exact integer addition that will throw an {@link ArithmeticException} in
+ * case the addition would overflow the 32 bit range.
+ */
+@NodeInfo
+public final class IntegerAddExactNode extends AddNode implements IntegerExactArithmeticNode {
+    public static final NodeClass<IntegerAddExactNode> TYPE = NodeClass.create(IntegerAddExactNode.class);
+
+    public IntegerAddExactNode(ValueNode x, ValueNode y) {
+        super(TYPE, x, y);
+        assert x.stamp().isCompatible(y.stamp()) && x.stamp() instanceof IntegerStamp;
+    }
+
+    @Override
+    public boolean inferStamp() {
+        // TODO Should probably use a specialized version which understands that it can't overflow
+        return super.inferStamp();
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
+        ValueNode result = findSynonym(forX, forY);
+        if (result == null) {
+            return this;
+        } else {
+            return result;
+        }
+    }
+
+    private static ValueNode findSynonym(ValueNode forX, ValueNode forY) {
+        if (forX.isConstant() && !forY.isConstant()) {
+            return new IntegerAddExactNode(forY, forX);
+        }
+        if (forX.isConstant()) {
+            ConstantNode constantNode = canonicalXconstant(forX, forY);
+            if (constantNode != null) {
+                return constantNode;
+            }
+        } else if (forY.isConstant()) {
+            long c = forY.asJavaConstant().asLong();
+            if (c == 0) {
+                return forX;
+            }
+        }
+        return null;
+    }
+
+    private static ConstantNode canonicalXconstant(ValueNode forX, ValueNode forY) {
+        JavaConstant xConst = forX.asJavaConstant();
+        JavaConstant yConst = forY.asJavaConstant();
+        if (xConst != null && yConst != null) {
+            assert xConst.getKind() == yConst.getKind();
+            try {
+                if (xConst.getKind() == Kind.Int) {
+                    return ConstantNode.forInt(Math.addExact(xConst.asInt(), yConst.asInt()));
+                } else {
+                    assert xConst.getKind() == Kind.Long;
+                    return ConstantNode.forLong(Math.addExact(xConst.asLong(), yConst.asLong()));
+                }
+            } catch (ArithmeticException ex) {
+                // The operation will result in an overflow exception, so do not canonicalize.
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public IntegerExactArithmeticSplitNode createSplit(AbstractBeginNode next, AbstractBeginNode deopt) {
+        return graph().add(new IntegerAddExactSplitNode(stamp(), getX(), getY(), next, deopt));
+    }
+
+    @Override
+    public void lower(LoweringTool tool) {
+        IntegerExactArithmeticSplitNode.lower(tool, this);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/arithmetic/IntegerAddExactSplitNode.java	Tue Apr 07 11:30:29 2015 +0200
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2013, 2015, 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.replacements.nodes.arithmetic;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.common.type.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodeinfo.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+
+@NodeInfo
+public final class IntegerAddExactSplitNode extends IntegerExactArithmeticSplitNode {
+    public static final NodeClass<IntegerAddExactSplitNode> TYPE = NodeClass.create(IntegerAddExactSplitNode.class);
+
+    public IntegerAddExactSplitNode(Stamp stamp, ValueNode x, ValueNode y, AbstractBeginNode next, AbstractBeginNode overflowSuccessor) {
+        super(TYPE, stamp, x, y, next, overflowSuccessor);
+    }
+
+    @Override
+    protected Value generateArithmetic(NodeLIRBuilderTool gen) {
+        return gen.getLIRGeneratorTool().emitAdd(gen.operand(getX()), gen.operand(getY()), true);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/arithmetic/IntegerExactArithmeticNode.java	Tue Apr 07 11:30:29 2015 +0200
@@ -0,0 +1,31 @@
+/*
+ * 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.replacements.nodes.arithmetic;
+
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+
+interface IntegerExactArithmeticNode extends Lowerable {
+
+    IntegerExactArithmeticSplitNode createSplit(AbstractBeginNode next, AbstractBeginNode deopt);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/arithmetic/IntegerExactArithmeticSplitNode.java	Tue Apr 07 11:30:29 2015 +0200
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2013, 2015, 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.replacements.nodes.arithmetic;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.common.type.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodeinfo.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.spi.*;
+
+@NodeInfo
+public abstract class IntegerExactArithmeticSplitNode extends ControlSplitNode implements LIRLowerable {
+    public static final NodeClass<IntegerExactArithmeticSplitNode> TYPE = NodeClass.create(IntegerExactArithmeticSplitNode.class);
+
+    @Successor AbstractBeginNode next;
+    @Successor AbstractBeginNode overflowSuccessor;
+    @Input ValueNode x;
+    @Input ValueNode y;
+
+    protected IntegerExactArithmeticSplitNode(NodeClass<? extends IntegerExactArithmeticSplitNode> c, Stamp stamp, ValueNode x, ValueNode y, AbstractBeginNode next, AbstractBeginNode overflowSuccessor) {
+        super(c, stamp);
+        this.x = x;
+        this.y = y;
+        this.overflowSuccessor = overflowSuccessor;
+        this.next = next;
+    }
+
+    @Override
+    public AbstractBeginNode getPrimarySuccessor() {
+        return next;
+    }
+
+    @Override
+    public double probability(AbstractBeginNode successor) {
+        return successor == next ? 1 : 0;
+    }
+
+    public AbstractBeginNode getNext() {
+        return next;
+    }
+
+    public AbstractBeginNode getOverflowSuccessor() {
+        return overflowSuccessor;
+    }
+
+    public ValueNode getX() {
+        return x;
+    }
+
+    public ValueNode getY() {
+        return y;
+    }
+
+    @Override
+    public void generate(NodeLIRBuilderTool generator) {
+        generator.setResult(this, generateArithmetic(generator));
+        generator.emitOverflowCheckBranch(getOverflowSuccessor(), getNext(), stamp, probability(getOverflowSuccessor()));
+    }
+
+    protected abstract Value generateArithmetic(NodeLIRBuilderTool generator);
+
+    static void lower(LoweringTool tool, IntegerExactArithmeticNode node) {
+        if (node.asNode().graph().getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) {
+            FloatingNode floatingNode = (FloatingNode) node;
+            FixedWithNextNode previous = tool.lastFixedNode();
+            FixedNode next = previous.next();
+            previous.setNext(null);
+            DeoptimizeNode deopt = floatingNode.graph().add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.ArithmeticException));
+            AbstractBeginNode normalBegin = floatingNode.graph().add(new BeginNode());
+            normalBegin.setNext(next);
+            IntegerExactArithmeticSplitNode split = node.createSplit(normalBegin, BeginNode.begin(deopt));
+            previous.setNext(split);
+            floatingNode.replaceAndDelete(split);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/arithmetic/IntegerMulExactNode.java	Tue Apr 07 11:30:29 2015 +0200
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2013, 2015, 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.replacements.nodes.arithmetic;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.common.type.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
+import com.oracle.graal.nodeinfo.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.spi.*;
+
+/**
+ * Node representing an exact integer multiplication that will throw an {@link ArithmeticException}
+ * in case the addition would overflow the 32 bit range.
+ */
+@NodeInfo
+public final class IntegerMulExactNode extends MulNode implements IntegerExactArithmeticNode {
+    public static final NodeClass<IntegerMulExactNode> TYPE = NodeClass.create(IntegerMulExactNode.class);
+
+    public IntegerMulExactNode(ValueNode x, ValueNode y) {
+        super(TYPE, x, y);
+        assert x.stamp().isCompatible(y.stamp()) && x.stamp() instanceof IntegerStamp;
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
+        if (forX.isConstant() && !forY.isConstant()) {
+            return new IntegerMulExactNode(forY, forX);
+        }
+        if (forX.isConstant()) {
+            return canonicalXconstant(forX, forY);
+        } else if (forY.isConstant()) {
+            long c = forY.asJavaConstant().asLong();
+            if (c == 1) {
+                return forX;
+            }
+            if (c == 0) {
+                return ConstantNode.forIntegerStamp(stamp(), 0);
+            }
+        }
+        return this;
+    }
+
+    private ValueNode canonicalXconstant(ValueNode forX, ValueNode forY) {
+        JavaConstant xConst = forX.asJavaConstant();
+        JavaConstant yConst = forY.asJavaConstant();
+        assert xConst.getKind() == yConst.getKind();
+        try {
+            if (xConst.getKind() == Kind.Int) {
+                return ConstantNode.forInt(Math.multiplyExact(xConst.asInt(), yConst.asInt()));
+            } else {
+                assert xConst.getKind() == Kind.Long;
+                return ConstantNode.forLong(Math.multiplyExact(xConst.asLong(), yConst.asLong()));
+            }
+        } catch (ArithmeticException ex) {
+            // The operation will result in an overflow exception, so do not canonicalize.
+        }
+        return this;
+    }
+
+    @Override
+    public IntegerExactArithmeticSplitNode createSplit(AbstractBeginNode next, AbstractBeginNode deopt) {
+        return graph().add(new IntegerMulExactSplitNode(stamp(), getX(), getY(), next, deopt));
+    }
+
+    @Override
+    public void lower(LoweringTool tool) {
+        IntegerExactArithmeticSplitNode.lower(tool, this);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/arithmetic/IntegerMulExactSplitNode.java	Tue Apr 07 11:30:29 2015 +0200
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2013, 2015, 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.replacements.nodes.arithmetic;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.common.type.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodeinfo.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+
+@NodeInfo
+public final class IntegerMulExactSplitNode extends IntegerExactArithmeticSplitNode {
+    public static final NodeClass<IntegerMulExactSplitNode> TYPE = NodeClass.create(IntegerMulExactSplitNode.class);
+
+    public IntegerMulExactSplitNode(Stamp stamp, ValueNode x, ValueNode y, AbstractBeginNode next, AbstractBeginNode overflowSuccessor) {
+        super(TYPE, stamp, x, y, next, overflowSuccessor);
+    }
+
+    @Override
+    protected Value generateArithmetic(NodeLIRBuilderTool gen) {
+        return gen.getLIRGeneratorTool().emitMul(gen.operand(getX()), gen.operand(getY()), true);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/arithmetic/IntegerMulHighNode.java	Tue Apr 07 11:30:29 2015 +0200
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2014, 2015, 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.replacements.nodes.arithmetic;
+
+import java.util.function.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.common.type.*;
+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.calc.*;
+import com.oracle.graal.nodes.spi.*;
+
+@NodeInfo(shortName = "*H")
+public final class IntegerMulHighNode extends BinaryNode implements ArithmeticLIRLowerable {
+    public static final NodeClass<IntegerMulHighNode> TYPE = NodeClass.create(IntegerMulHighNode.class);
+
+    public IntegerMulHighNode(ValueNode x, ValueNode y) {
+        this((IntegerStamp) x.stamp().unrestricted(), x, y);
+    }
+
+    public IntegerMulHighNode(IntegerStamp stamp, ValueNode x, ValueNode y) {
+        super(TYPE, stamp, x, y);
+    }
+
+    /**
+     * Determines the minimum and maximum result of this node for the given inputs and returns the
+     * result of the given BiFunction on the minimum and maximum values.
+     */
+    private <T> T processExtremes(ValueNode forX, ValueNode forY, BiFunction<Long, Long, T> op) {
+        IntegerStamp xStamp = (IntegerStamp) forX.stamp();
+        IntegerStamp yStamp = (IntegerStamp) forY.stamp();
+
+        Kind kind = getKind();
+        assert kind == Kind.Int || kind == Kind.Long;
+        long[] xExtremes = {xStamp.lowerBound(), xStamp.upperBound()};
+        long[] yExtremes = {yStamp.lowerBound(), yStamp.upperBound()};
+        long min = Long.MAX_VALUE;
+        long max = Long.MIN_VALUE;
+        for (long a : xExtremes) {
+            for (long b : yExtremes) {
+                long result = kind == Kind.Int ? multiplyHigh((int) a, (int) b) : multiplyHigh(a, b);
+                min = Math.min(min, result);
+                max = Math.max(max, result);
+            }
+        }
+        return op.apply(min, max);
+    }
+
+    @Override
+    public boolean inferStamp() {
+        return updateStamp(processExtremes(getX(), getY(), (min, max) -> StampFactory.forInteger(getKind(), min, max)));
+    }
+
+    @SuppressWarnings("cast")
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
+        return processExtremes(forX, forY, (min, max) -> min == (long) max ? ConstantNode.forIntegerKind(getKind(), min) : this);
+    }
+
+    @Override
+    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
+        Value a = builder.operand(getX());
+        Value b = builder.operand(getY());
+        builder.setResult(this, gen.emitMulHigh(a, b));
+    }
+
+    public static int multiplyHigh(int x, int y) {
+        long r = (long) x * (long) y;
+        return (int) (r >> 32);
+    }
+
+    public static long multiplyHigh(long x, long y) {
+        // Checkstyle: stop
+        long x0, y0, z0;
+        long x1, y1, z1, z2, t;
+        // Checkstyle: resume
+
+        x0 = x & 0xFFFFFFFFL;
+        x1 = x >> 32;
+
+        y0 = y & 0xFFFFFFFFL;
+        y1 = y >> 32;
+
+        z0 = x0 * y0;
+        t = x1 * y0 + (z0 >>> 32);
+        z1 = t & 0xFFFFFFFFL;
+        z2 = t >> 32;
+        z1 += x0 * y1;
+
+        return x1 * y1 + z2 + (z1 >> 32);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/arithmetic/IntegerSubExactNode.java	Tue Apr 07 11:30:29 2015 +0200
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2013, 2015, 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.replacements.nodes.arithmetic;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.common.type.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
+import com.oracle.graal.nodeinfo.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.util.*;
+
+/**
+ * Node representing an exact integer substraction that will throw an {@link ArithmeticException} in
+ * case the addition would overflow the 32 bit range.
+ */
+@NodeInfo
+public final class IntegerSubExactNode extends SubNode implements IntegerExactArithmeticNode {
+    public static final NodeClass<IntegerSubExactNode> TYPE = NodeClass.create(IntegerSubExactNode.class);
+
+    public IntegerSubExactNode(ValueNode x, ValueNode y) {
+        super(TYPE, x, y);
+        assert x.stamp().isCompatible(y.stamp()) && x.stamp() instanceof IntegerStamp;
+    }
+
+    @Override
+    public boolean inferStamp() {
+        // TODO Should probably use a specialized version which understands that it can't overflow
+        return super.inferStamp();
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
+        if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) {
+            return ConstantNode.forIntegerStamp(stamp(), 0);
+        }
+        if (forX.isConstant() && forY.isConstant()) {
+            return canonicalXYconstant(forX, forY);
+        } else if (forY.isConstant()) {
+            long c = forY.asJavaConstant().asLong();
+            if (c == 0) {
+                return forX;
+            }
+        }
+        return this;
+    }
+
+    private ValueNode canonicalXYconstant(ValueNode forX, ValueNode forY) {
+        JavaConstant xConst = forX.asJavaConstant();
+        JavaConstant yConst = forY.asJavaConstant();
+        assert xConst.getKind() == yConst.getKind();
+        try {
+            if (xConst.getKind() == Kind.Int) {
+                return ConstantNode.forInt(Math.subtractExact(xConst.asInt(), yConst.asInt()));
+            } else {
+                assert xConst.getKind() == Kind.Long;
+                return ConstantNode.forLong(Math.subtractExact(xConst.asLong(), yConst.asLong()));
+            }
+        } catch (ArithmeticException ex) {
+            // The operation will result in an overflow exception, so do not canonicalize.
+        }
+        return this;
+    }
+
+    @Override
+    public IntegerExactArithmeticSplitNode createSplit(AbstractBeginNode next, AbstractBeginNode deopt) {
+        return graph().add(new IntegerSubExactSplitNode(stamp(), getX(), getY(), next, deopt));
+    }
+
+    @Override
+    public void lower(LoweringTool tool) {
+        IntegerExactArithmeticSplitNode.lower(tool, this);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/arithmetic/IntegerSubExactSplitNode.java	Tue Apr 07 11:30:29 2015 +0200
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2013, 2015, 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.replacements.nodes.arithmetic;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.common.type.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodeinfo.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+
+@NodeInfo
+public final class IntegerSubExactSplitNode extends IntegerExactArithmeticSplitNode {
+    public static final NodeClass<IntegerSubExactSplitNode> TYPE = NodeClass.create(IntegerSubExactSplitNode.class);
+
+    public IntegerSubExactSplitNode(Stamp stamp, ValueNode x, ValueNode y, AbstractBeginNode next, AbstractBeginNode overflowSuccessor) {
+        super(TYPE, stamp, x, y, next, overflowSuccessor);
+    }
+
+    @Override
+    protected Value generateArithmetic(NodeLIRBuilderTool gen) {
+        return gen.getLIRGeneratorTool().emitSub(gen.operand(getX()), gen.operand(getY()), true);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/arithmetic/UnsignedMulHighNode.java	Tue Apr 07 11:30:29 2015 +0200
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2014, 2015, 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.replacements.nodes.arithmetic;
+
+import java.util.function.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.common.type.*;
+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.calc.*;
+import com.oracle.graal.nodes.spi.*;
+
+@NodeInfo(shortName = "|*H|")
+public final class UnsignedMulHighNode extends BinaryNode implements ArithmeticLIRLowerable {
+
+    public static final NodeClass<UnsignedMulHighNode> TYPE = NodeClass.create(UnsignedMulHighNode.class);
+
+    public UnsignedMulHighNode(ValueNode x, ValueNode y) {
+        this((IntegerStamp) x.stamp().unrestricted(), x, y);
+    }
+
+    public UnsignedMulHighNode(IntegerStamp stamp, ValueNode x, ValueNode y) {
+        super(TYPE, stamp, x, y);
+    }
+
+    /**
+     * Determines the minimum and maximum result of this node for the given inputs and returns the
+     * result of the given BiFunction on the minimum and maximum values. Note that the minima and
+     * maxima are calculated using signed min/max functions, while the values themselves are
+     * unsigned.
+     */
+    private <T> T processExtremes(ValueNode forX, ValueNode forY, BiFunction<Long, Long, T> op) {
+        IntegerStamp xStamp = (IntegerStamp) forX.stamp();
+        IntegerStamp yStamp = (IntegerStamp) forY.stamp();
+
+        Kind kind = getKind();
+        assert kind == Kind.Int || kind == Kind.Long;
+        long[] xExtremes = {xStamp.lowerBound(), xStamp.upperBound()};
+        long[] yExtremes = {yStamp.lowerBound(), yStamp.upperBound()};
+        long min = Long.MAX_VALUE;
+        long max = Long.MIN_VALUE;
+        for (long a : xExtremes) {
+            for (long b : yExtremes) {
+                long result = kind == Kind.Int ? multiplyHighUnsigned((int) a, (int) b) : multiplyHighUnsigned(a, b);
+                min = Math.min(min, result);
+                max = Math.max(max, result);
+            }
+        }
+        return op.apply(min, max);
+    }
+
+    @SuppressWarnings("cast")
+    @Override
+    public boolean inferStamp() {
+        // if min is negative, then the value can reach into the unsigned range
+        return updateStamp(processExtremes(getX(), getY(), (min, max) -> (min == (long) max || min >= 0) ? StampFactory.forInteger(getKind(), min, max) : StampFactory.forKind(getKind())));
+    }
+
+    @SuppressWarnings("cast")
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
+        return processExtremes(forX, forY, (min, max) -> min == (long) max ? ConstantNode.forIntegerKind(getKind(), min) : this);
+    }
+
+    @Override
+    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
+        Value a = builder.operand(getX());
+        Value b = builder.operand(getY());
+        builder.setResult(this, gen.emitUMulHigh(a, b));
+    }
+
+    public static int multiplyHighUnsigned(int x, int y) {
+        long xl = x & 0xFFFFFFFFL;
+        long yl = y & 0xFFFFFFFFL;
+        long r = xl * yl;
+        return (int) (r >> 32);
+    }
+
+    public static long multiplyHighUnsigned(long x, long y) {
+        // Checkstyle: stop
+        long x0, y0, z0;
+        long x1, y1, z1, z2, t;
+        // Checkstyle: resume
+
+        x0 = x & 0xFFFFFFFFL;
+        x1 = x >>> 32;
+
+        y0 = y & 0xFFFFFFFFL;
+        y1 = y >>> 32;
+
+        z0 = x0 * y0;
+        t = x1 * y0 + (z0 >>> 32);
+        z1 = t & 0xFFFFFFFFL;
+        z2 = t >>> 32;
+        z1 += x0 * y1;
+
+        return x1 * y1 + z2 + (z1 >>> 32);
+    }
+}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactNode.java	Tue Apr 07 11:19:39 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,110 +0,0 @@
-/*
- * Copyright (c) 2013, 2015, 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.nodes.arithmetic;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.compiler.common.type.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.graph.spi.*;
-import com.oracle.graal.nodeinfo.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.calc.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.truffle.api.*;
-
-/**
- * Node representing an exact integer addition that will throw an {@link ArithmeticException} in
- * case the addition would overflow the 32 bit range.
- */
-@NodeInfo
-public final class IntegerAddExactNode extends AddNode implements IntegerExactArithmeticNode {
-    public static final NodeClass<IntegerAddExactNode> TYPE = NodeClass.create(IntegerAddExactNode.class);
-
-    public IntegerAddExactNode(ValueNode x, ValueNode y) {
-        super(TYPE, x, y);
-        assert x.stamp().isCompatible(y.stamp()) && x.stamp() instanceof IntegerStamp;
-    }
-
-    @Override
-    public boolean inferStamp() {
-        // TODO Should probably use a specialized version which understands that it can't overflow
-        return super.inferStamp();
-    }
-
-    @Override
-    public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
-        ValueNode result = findSynonym(forX, forY);
-        if (result == null) {
-            return this;
-        } else {
-            return result;
-        }
-    }
-
-    private static ValueNode findSynonym(ValueNode forX, ValueNode forY) {
-        if (forX.isConstant() && !forY.isConstant()) {
-            return new IntegerAddExactNode(forY, forX);
-        }
-        if (forX.isConstant()) {
-            ConstantNode constantNode = canonicalXconstant(forX, forY);
-            if (constantNode != null) {
-                return constantNode;
-            }
-        } else if (forY.isConstant()) {
-            long c = forY.asJavaConstant().asLong();
-            if (c == 0) {
-                return forX;
-            }
-        }
-        return null;
-    }
-
-    private static ConstantNode canonicalXconstant(ValueNode forX, ValueNode forY) {
-        JavaConstant xConst = forX.asJavaConstant();
-        JavaConstant yConst = forY.asJavaConstant();
-        if (xConst != null && yConst != null) {
-            assert xConst.getKind() == yConst.getKind();
-            try {
-                if (xConst.getKind() == Kind.Int) {
-                    return ConstantNode.forInt(ExactMath.addExact(xConst.asInt(), yConst.asInt()));
-                } else {
-                    assert xConst.getKind() == Kind.Long;
-                    return ConstantNode.forLong(ExactMath.addExact(xConst.asLong(), yConst.asLong()));
-                }
-            } catch (ArithmeticException ex) {
-                // The operation will result in an overflow exception, so do not canonicalize.
-            }
-        }
-        return null;
-    }
-
-    @Override
-    public IntegerExactArithmeticSplitNode createSplit(AbstractBeginNode next, AbstractBeginNode deopt) {
-        return graph().add(new IntegerAddExactSplitNode(stamp(), getX(), getY(), next, deopt));
-    }
-
-    @Override
-    public void lower(LoweringTool tool) {
-        IntegerExactArithmeticSplitNode.lower(tool, this);
-    }
-}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactSplitNode.java	Tue Apr 07 11:19:39 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2013, 2015, 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.nodes.arithmetic;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.compiler.common.type.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.nodeinfo.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
-
-@NodeInfo
-public final class IntegerAddExactSplitNode extends IntegerExactArithmeticSplitNode {
-    public static final NodeClass<IntegerAddExactSplitNode> TYPE = NodeClass.create(IntegerAddExactSplitNode.class);
-
-    public IntegerAddExactSplitNode(Stamp stamp, ValueNode x, ValueNode y, AbstractBeginNode next, AbstractBeginNode overflowSuccessor) {
-        super(TYPE, stamp, x, y, next, overflowSuccessor);
-    }
-
-    @Override
-    protected Value generateArithmetic(NodeLIRBuilderTool gen) {
-        return gen.getLIRGeneratorTool().emitAdd(gen.operand(getX()), gen.operand(getY()), true);
-    }
-}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerExactArithmeticNode.java	Tue Apr 07 11:19:39 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-/*
- * 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.truffle.nodes.arithmetic;
-
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
-
-interface IntegerExactArithmeticNode extends Lowerable {
-
-    IntegerExactArithmeticSplitNode createSplit(AbstractBeginNode next, AbstractBeginNode deopt);
-}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerExactArithmeticSplitNode.java	Tue Apr 07 11:19:39 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +0,0 @@
-/*
- * Copyright (c) 2013, 2015, 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.nodes.arithmetic;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.compiler.common.type.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.nodeinfo.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.calc.*;
-import com.oracle.graal.nodes.spi.*;
-
-@NodeInfo
-public abstract class IntegerExactArithmeticSplitNode extends ControlSplitNode implements LIRLowerable {
-    public static final NodeClass<IntegerExactArithmeticSplitNode> TYPE = NodeClass.create(IntegerExactArithmeticSplitNode.class);
-
-    @Successor AbstractBeginNode next;
-    @Successor AbstractBeginNode overflowSuccessor;
-    @Input ValueNode x;
-    @Input ValueNode y;
-
-    protected IntegerExactArithmeticSplitNode(NodeClass<? extends IntegerExactArithmeticSplitNode> c, Stamp stamp, ValueNode x, ValueNode y, AbstractBeginNode next, AbstractBeginNode overflowSuccessor) {
-        super(c, stamp);
-        this.x = x;
-        this.y = y;
-        this.overflowSuccessor = overflowSuccessor;
-        this.next = next;
-    }
-
-    @Override
-    public AbstractBeginNode getPrimarySuccessor() {
-        return next;
-    }
-
-    @Override
-    public double probability(AbstractBeginNode successor) {
-        return successor == next ? 1 : 0;
-    }
-
-    public AbstractBeginNode getNext() {
-        return next;
-    }
-
-    public AbstractBeginNode getOverflowSuccessor() {
-        return overflowSuccessor;
-    }
-
-    public ValueNode getX() {
-        return x;
-    }
-
-    public ValueNode getY() {
-        return y;
-    }
-
-    @Override
-    public void generate(NodeLIRBuilderTool generator) {
-        generator.setResult(this, generateArithmetic(generator));
-        generator.emitOverflowCheckBranch(getOverflowSuccessor(), getNext(), stamp, probability(getOverflowSuccessor()));
-    }
-
-    protected abstract Value generateArithmetic(NodeLIRBuilderTool generator);
-
-    static void lower(LoweringTool tool, IntegerExactArithmeticNode node) {
-        if (node.asNode().graph().getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) {
-            FloatingNode floatingNode = (FloatingNode) node;
-            FixedWithNextNode previous = tool.lastFixedNode();
-            FixedNode next = previous.next();
-            previous.setNext(null);
-            DeoptimizeNode deopt = floatingNode.graph().add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.ArithmeticException));
-            AbstractBeginNode normalBegin = floatingNode.graph().add(new BeginNode());
-            normalBegin.setNext(next);
-            IntegerExactArithmeticSplitNode split = node.createSplit(normalBegin, BeginNode.begin(deopt));
-            previous.setNext(split);
-            floatingNode.replaceAndDelete(split);
-        }
-    }
-}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulExactNode.java	Tue Apr 07 11:19:39 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,93 +0,0 @@
-/*
- * Copyright (c) 2013, 2015, 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.nodes.arithmetic;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.compiler.common.type.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.graph.spi.*;
-import com.oracle.graal.nodeinfo.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.calc.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.truffle.api.*;
-
-/**
- * Node representing an exact integer multiplication that will throw an {@link ArithmeticException}
- * in case the addition would overflow the 32 bit range.
- */
-@NodeInfo
-public final class IntegerMulExactNode extends MulNode implements IntegerExactArithmeticNode {
-    public static final NodeClass<IntegerMulExactNode> TYPE = NodeClass.create(IntegerMulExactNode.class);
-
-    public IntegerMulExactNode(ValueNode x, ValueNode y) {
-        super(TYPE, x, y);
-        assert x.stamp().isCompatible(y.stamp()) && x.stamp() instanceof IntegerStamp;
-    }
-
-    @Override
-    public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
-        if (forX.isConstant() && !forY.isConstant()) {
-            return new IntegerMulExactNode(forY, forX);
-        }
-        if (forX.isConstant()) {
-            return canonicalXconstant(forX, forY);
-        } else if (forY.isConstant()) {
-            long c = forY.asJavaConstant().asLong();
-            if (c == 1) {
-                return forX;
-            }
-            if (c == 0) {
-                return ConstantNode.forIntegerStamp(stamp(), 0);
-            }
-        }
-        return this;
-    }
-
-    private ValueNode canonicalXconstant(ValueNode forX, ValueNode forY) {
-        JavaConstant xConst = forX.asJavaConstant();
-        JavaConstant yConst = forY.asJavaConstant();
-        assert xConst.getKind() == yConst.getKind();
-        try {
-            if (xConst.getKind() == Kind.Int) {
-                return ConstantNode.forInt(ExactMath.multiplyExact(xConst.asInt(), yConst.asInt()));
-            } else {
-                assert xConst.getKind() == Kind.Long;
-                return ConstantNode.forLong(ExactMath.multiplyExact(xConst.asLong(), yConst.asLong()));
-            }
-        } catch (ArithmeticException ex) {
-            // The operation will result in an overflow exception, so do not canonicalize.
-        }
-        return this;
-    }
-
-    @Override
-    public IntegerExactArithmeticSplitNode createSplit(AbstractBeginNode next, AbstractBeginNode deopt) {
-        return graph().add(new IntegerMulExactSplitNode(stamp(), getX(), getY(), next, deopt));
-    }
-
-    @Override
-    public void lower(LoweringTool tool) {
-        IntegerExactArithmeticSplitNode.lower(tool, this);
-    }
-}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulExactSplitNode.java	Tue Apr 07 11:19:39 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2013, 2015, 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.nodes.arithmetic;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.compiler.common.type.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.nodeinfo.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
-
-@NodeInfo
-public final class IntegerMulExactSplitNode extends IntegerExactArithmeticSplitNode {
-    public static final NodeClass<IntegerMulExactSplitNode> TYPE = NodeClass.create(IntegerMulExactSplitNode.class);
-
-    public IntegerMulExactSplitNode(Stamp stamp, ValueNode x, ValueNode y, AbstractBeginNode next, AbstractBeginNode overflowSuccessor) {
-        super(TYPE, stamp, x, y, next, overflowSuccessor);
-    }
-
-    @Override
-    protected Value generateArithmetic(NodeLIRBuilderTool gen) {
-        return gen.getLIRGeneratorTool().emitMul(gen.operand(getX()), gen.operand(getY()), true);
-    }
-}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulHighNode.java	Tue Apr 07 11:19:39 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +0,0 @@
-/*
- * Copyright (c) 2014, 2015, 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.nodes.arithmetic;
-
-import java.util.function.*;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.compiler.common.type.*;
-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.calc.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.truffle.api.*;
-
-@NodeInfo(shortName = "*H")
-public final class IntegerMulHighNode extends BinaryNode implements ArithmeticLIRLowerable {
-    public static final NodeClass<IntegerMulHighNode> TYPE = NodeClass.create(IntegerMulHighNode.class);
-
-    public IntegerMulHighNode(ValueNode x, ValueNode y) {
-        this((IntegerStamp) x.stamp().unrestricted(), x, y);
-    }
-
-    public IntegerMulHighNode(IntegerStamp stamp, ValueNode x, ValueNode y) {
-        super(TYPE, stamp, x, y);
-    }
-
-    /**
-     * Determines the minimum and maximum result of this node for the given inputs and returns the
-     * result of the given BiFunction on the minimum and maximum values.
-     */
-    private <T> T processExtremes(ValueNode forX, ValueNode forY, BiFunction<Long, Long, T> op) {
-        IntegerStamp xStamp = (IntegerStamp) forX.stamp();
-        IntegerStamp yStamp = (IntegerStamp) forY.stamp();
-
-        Kind kind = getKind();
-        assert kind == Kind.Int || kind == Kind.Long;
-        long[] xExtremes = {xStamp.lowerBound(), xStamp.upperBound()};
-        long[] yExtremes = {yStamp.lowerBound(), yStamp.upperBound()};
-        long min = Long.MAX_VALUE;
-        long max = Long.MIN_VALUE;
-        for (long a : xExtremes) {
-            for (long b : yExtremes) {
-                long result = kind == Kind.Int ? ExactMath.multiplyHigh((int) a, (int) b) : ExactMath.multiplyHigh(a, b);
-                min = Math.min(min, result);
-                max = Math.max(max, result);
-            }
-        }
-        return op.apply(min, max);
-    }
-
-    @Override
-    public boolean inferStamp() {
-        return updateStamp(processExtremes(getX(), getY(), (min, max) -> StampFactory.forInteger(getKind(), min, max)));
-    }
-
-    @SuppressWarnings("cast")
-    @Override
-    public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
-        return processExtremes(forX, forY, (min, max) -> min == (long) max ? ConstantNode.forIntegerKind(getKind(), min) : this);
-    }
-
-    @Override
-    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
-        Value a = builder.operand(getX());
-        Value b = builder.operand(getY());
-        builder.setResult(this, gen.emitMulHigh(a, b));
-    }
-}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactNode.java	Tue Apr 07 11:19:39 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
-/*
- * Copyright (c) 2013, 2015, 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.nodes.arithmetic;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.compiler.common.type.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.graph.spi.*;
-import com.oracle.graal.nodeinfo.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.calc.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.util.*;
-import com.oracle.truffle.api.*;
-
-/**
- * Node representing an exact integer substraction that will throw an {@link ArithmeticException} in
- * case the addition would overflow the 32 bit range.
- */
-@NodeInfo
-public final class IntegerSubExactNode extends SubNode implements IntegerExactArithmeticNode {
-    public static final NodeClass<IntegerSubExactNode> TYPE = NodeClass.create(IntegerSubExactNode.class);
-
-    public IntegerSubExactNode(ValueNode x, ValueNode y) {
-        super(TYPE, x, y);
-        assert x.stamp().isCompatible(y.stamp()) && x.stamp() instanceof IntegerStamp;
-    }
-
-    @Override
-    public boolean inferStamp() {
-        // TODO Should probably use a specialized version which understands that it can't overflow
-        return super.inferStamp();
-    }
-
-    @Override
-    public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
-        if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) {
-            return ConstantNode.forIntegerStamp(stamp(), 0);
-        }
-        if (forX.isConstant() && forY.isConstant()) {
-            return canonicalXYconstant(forX, forY);
-        } else if (forY.isConstant()) {
-            long c = forY.asJavaConstant().asLong();
-            if (c == 0) {
-                return forX;
-            }
-        }
-        return this;
-    }
-
-    private ValueNode canonicalXYconstant(ValueNode forX, ValueNode forY) {
-        JavaConstant xConst = forX.asJavaConstant();
-        JavaConstant yConst = forY.asJavaConstant();
-        assert xConst.getKind() == yConst.getKind();
-        try {
-            if (xConst.getKind() == Kind.Int) {
-                return ConstantNode.forInt(ExactMath.subtractExact(xConst.asInt(), yConst.asInt()));
-            } else {
-                assert xConst.getKind() == Kind.Long;
-                return ConstantNode.forLong(ExactMath.subtractExact(xConst.asLong(), yConst.asLong()));
-            }
-        } catch (ArithmeticException ex) {
-            // The operation will result in an overflow exception, so do not canonicalize.
-        }
-        return this;
-    }
-
-    @Override
-    public IntegerExactArithmeticSplitNode createSplit(AbstractBeginNode next, AbstractBeginNode deopt) {
-        return graph().add(new IntegerSubExactSplitNode(stamp(), getX(), getY(), next, deopt));
-    }
-
-    @Override
-    public void lower(LoweringTool tool) {
-        IntegerExactArithmeticSplitNode.lower(tool, this);
-    }
-}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactSplitNode.java	Tue Apr 07 11:19:39 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2013, 2015, 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.nodes.arithmetic;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.compiler.common.type.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.nodeinfo.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
-
-@NodeInfo
-public final class IntegerSubExactSplitNode extends IntegerExactArithmeticSplitNode {
-    public static final NodeClass<IntegerSubExactSplitNode> TYPE = NodeClass.create(IntegerSubExactSplitNode.class);
-
-    public IntegerSubExactSplitNode(Stamp stamp, ValueNode x, ValueNode y, AbstractBeginNode next, AbstractBeginNode overflowSuccessor) {
-        super(TYPE, stamp, x, y, next, overflowSuccessor);
-    }
-
-    @Override
-    protected Value generateArithmetic(NodeLIRBuilderTool gen) {
-        return gen.getLIRGeneratorTool().emitSub(gen.operand(getX()), gen.operand(getY()), true);
-    }
-}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/UnsignedMulHighNode.java	Tue Apr 07 11:19:39 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +0,0 @@
-/*
- * Copyright (c) 2014, 2015, 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.nodes.arithmetic;
-
-import java.util.function.*;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.compiler.common.type.*;
-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.calc.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.truffle.api.*;
-
-@NodeInfo(shortName = "|*H|")
-public final class UnsignedMulHighNode extends BinaryNode implements ArithmeticLIRLowerable {
-
-    public static final NodeClass<UnsignedMulHighNode> TYPE = NodeClass.create(UnsignedMulHighNode.class);
-
-    public UnsignedMulHighNode(ValueNode x, ValueNode y) {
-        this((IntegerStamp) x.stamp().unrestricted(), x, y);
-    }
-
-    public UnsignedMulHighNode(IntegerStamp stamp, ValueNode x, ValueNode y) {
-        super(TYPE, stamp, x, y);
-    }
-
-    /**
-     * Determines the minimum and maximum result of this node for the given inputs and returns the
-     * result of the given BiFunction on the minimum and maximum values. Note that the minima and
-     * maxima are calculated using signed min/max functions, while the values themselves are
-     * unsigned.
-     */
-    private <T> T processExtremes(ValueNode forX, ValueNode forY, BiFunction<Long, Long, T> op) {
-        IntegerStamp xStamp = (IntegerStamp) forX.stamp();
-        IntegerStamp yStamp = (IntegerStamp) forY.stamp();
-
-        Kind kind = getKind();
-        assert kind == Kind.Int || kind == Kind.Long;
-        long[] xExtremes = {xStamp.lowerBound(), xStamp.upperBound()};
-        long[] yExtremes = {yStamp.lowerBound(), yStamp.upperBound()};
-        long min = Long.MAX_VALUE;
-        long max = Long.MIN_VALUE;
-        for (long a : xExtremes) {
-            for (long b : yExtremes) {
-                long result = kind == Kind.Int ? ExactMath.multiplyHighUnsigned((int) a, (int) b) : ExactMath.multiplyHighUnsigned(a, b);
-                min = Math.min(min, result);
-                max = Math.max(max, result);
-            }
-        }
-        return op.apply(min, max);
-    }
-
-    @SuppressWarnings("cast")
-    @Override
-    public boolean inferStamp() {
-        // if min is negative, then the value can reach into the unsigned range
-        return updateStamp(processExtremes(getX(), getY(), (min, max) -> (min == (long) max || min >= 0) ? StampFactory.forInteger(getKind(), min, max) : StampFactory.forKind(getKind())));
-    }
-
-    @SuppressWarnings("cast")
-    @Override
-    public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
-        return processExtremes(forX, forY, (min, max) -> min == (long) max ? ConstantNode.forIntegerKind(getKind(), min) : this);
-    }
-
-    @Override
-    public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) {
-        Value a = builder.operand(getX());
-        Value b = builder.operand(getY());
-        builder.setResult(this, gen.emitUMulHigh(a, b));
-    }
-}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/TruffleGraphBuilderPlugins.java	Tue Apr 07 11:19:39 2015 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/TruffleGraphBuilderPlugins.java	Tue Apr 07 11:30:29 2015 +0200
@@ -37,9 +37,9 @@
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.replacements.nodes.arithmetic.*;
 import com.oracle.graal.truffle.*;
 import com.oracle.graal.truffle.nodes.*;
-import com.oracle.graal.truffle.nodes.arithmetic.*;
 import com.oracle.graal.truffle.nodes.asserts.*;
 import com.oracle.graal.truffle.nodes.frame.*;
 import com.oracle.graal.truffle.unsafe.*;
--- a/mx/suite.py	Tue Apr 07 11:19:39 2015 +0200
+++ b/mx/suite.py	Tue Apr 07 11:30:29 2015 +0200
@@ -1050,6 +1050,7 @@
         "com.oracle.truffle.api",
         "com.oracle.graal.runtime",
         "com.oracle.graal.printer",
+        "com.oracle.graal.replacements",
       ],
       "checkstyle" : "com.oracle.graal.graph",
       "javaCompliance" : "1.8",