# HG changeset patch # User Roland Schatz # Date 1380708591 -7200 # Node ID 04b039d82e8691ee5844fbdcf890f3349bedf8bf # Parent e6892286973229df21dd780ae22276c700daf3cd Simplify constant folding. diff -r e68922869732 -r 04b039d82e86 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ArithmeticOperation.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ArithmeticOperation.java Tue Oct 01 17:26:56 2013 -0700 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ArithmeticOperation.java Wed Oct 02 12:09:51 2013 +0200 @@ -22,9 +22,13 @@ */ package com.oracle.graal.api.code; +import com.oracle.graal.api.meta.*; + /** * An {@code ArithmeticOperation} is an operation that does primitive value arithmetic without side * effect. */ public interface ArithmeticOperation { + + Constant evalConst(Constant... inputs); } diff -r e68922869732 -r 04b039d82e86 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AndNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AndNode.java Tue Oct 01 17:26:56 2013 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AndNode.java Wed Oct 02 12:09:51 2013 +0200 @@ -41,6 +41,12 @@ } @Override + public Constant evalConst(Constant... inputs) { + assert inputs.length == 2; + return Constant.forIntegerKind(kind(), inputs[0].asLong() & inputs[1].asLong(), null); + } + + @Override public ValueNode canonical(CanonicalizerTool tool) { if (x() == y()) { return x(); @@ -49,12 +55,7 @@ return graph().unique(new AndNode(kind(), y(), x())); } if (x().isConstant()) { - if (kind() == Kind.Int) { - return ConstantNode.forInt(x().asConstant().asInt() & y().asConstant().asInt(), graph()); - } else { - assert kind() == Kind.Long; - return ConstantNode.forLong(x().asConstant().asLong() & y().asConstant().asLong(), graph()); - } + return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph()); } else if (y().isConstant()) { if (kind() == Kind.Int) { int c = y().asConstant().asInt(); diff -r e68922869732 -r 04b039d82e86 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConvertNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConvertNode.java Tue Oct 01 17:26:56 2013 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConvertNode.java Wed Oct 02 12:09:51 2013 +0200 @@ -150,52 +150,59 @@ this.value = value; } + public Constant evalConst(Constant... inputs) { + assert inputs.length == 1; + Constant c = inputs[0]; + switch (opcode) { + case I2L: + return Constant.forLong(c.asInt()); + case L2I: + return Constant.forInt((int) c.asLong()); + case I2B: + return Constant.forByte((byte) c.asInt()); + case I2C: + return Constant.forChar((char) c.asInt()); + case I2S: + return Constant.forShort((short) c.asInt()); + case F2D: + return Constant.forDouble(c.asFloat()); + case D2F: + return Constant.forFloat((float) c.asDouble()); + case I2F: + return Constant.forFloat(c.asInt()); + case I2D: + return Constant.forDouble(c.asInt()); + case F2I: + return Constant.forInt((int) c.asFloat()); + case D2I: + return Constant.forInt((int) c.asDouble()); + case L2F: + return Constant.forFloat(c.asLong()); + case L2D: + return Constant.forDouble(c.asLong()); + case F2L: + return Constant.forLong((long) c.asFloat()); + case D2L: + return Constant.forLong((long) c.asDouble()); + case UNSIGNED_I2L: + return Constant.forLong(c.asInt() & 0xffffffffL); + case MOV_I2F: + return Constant.forFloat(java.lang.Float.intBitsToFloat(c.asInt())); + case MOV_L2D: + return Constant.forDouble(java.lang.Double.longBitsToDouble(c.asLong())); + case MOV_F2I: + return Constant.forInt(java.lang.Float.floatToRawIntBits(c.asFloat())); + case MOV_D2L: + return Constant.forLong(java.lang.Double.doubleToRawLongBits(c.asDouble())); + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + @Override public ValueNode canonical(CanonicalizerTool tool) { - if (value instanceof ConstantNode) { - Constant c = ((ConstantNode) value).asConstant(); - switch (opcode) { - case I2L: - return ConstantNode.forLong(c.asInt(), graph()); - case L2I: - return ConstantNode.forInt((int) c.asLong(), graph()); - case I2B: - return ConstantNode.forByte((byte) c.asInt(), graph()); - case I2C: - return ConstantNode.forChar((char) c.asInt(), graph()); - case I2S: - return ConstantNode.forShort((short) c.asInt(), graph()); - case F2D: - return ConstantNode.forDouble(c.asFloat(), graph()); - case D2F: - return ConstantNode.forFloat((float) c.asDouble(), graph()); - case I2F: - return ConstantNode.forFloat(c.asInt(), graph()); - case I2D: - return ConstantNode.forDouble(c.asInt(), graph()); - case F2I: - return ConstantNode.forInt((int) c.asFloat(), graph()); - case D2I: - return ConstantNode.forInt((int) c.asDouble(), graph()); - case L2F: - return ConstantNode.forFloat(c.asLong(), graph()); - case L2D: - return ConstantNode.forDouble(c.asLong(), graph()); - case F2L: - return ConstantNode.forLong((long) c.asFloat(), graph()); - case D2L: - return ConstantNode.forLong((long) c.asDouble(), graph()); - case UNSIGNED_I2L: - return ConstantNode.forLong(c.asInt() & 0xffffffffL, graph()); - case MOV_I2F: - return ConstantNode.forFloat(java.lang.Float.intBitsToFloat(c.asInt()), graph()); - case MOV_L2D: - return ConstantNode.forDouble(java.lang.Double.longBitsToDouble(c.asLong()), graph()); - case MOV_F2I: - return ConstantNode.forInt(java.lang.Float.floatToRawIntBits(c.asFloat()), graph()); - case MOV_D2L: - return ConstantNode.forLong(java.lang.Double.doubleToRawLongBits(c.asDouble()), graph()); - } + if (value.isConstant()) { + return ConstantNode.forPrimitive(evalConst(value.asConstant()), graph()); } return this; } diff -r e68922869732 -r 04b039d82e86 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatAddNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatAddNode.java Tue Oct 01 17:26:56 2013 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatAddNode.java Wed Oct 02 12:09:51 2013 +0200 @@ -34,18 +34,23 @@ super(kind, x, y, isStrictFP); } + public Constant evalConst(Constant... inputs) { + assert inputs.length == 2; + if (kind() == Kind.Float) { + return Constant.forFloat(x().asConstant().asFloat() + y().asConstant().asFloat()); + } else { + assert kind() == Kind.Double; + return Constant.forDouble(x().asConstant().asDouble() + y().asConstant().asDouble()); + } + } + @Override public ValueNode canonical(CanonicalizerTool tool) { if (x().isConstant() && !y().isConstant()) { return graph().unique(new FloatAddNode(kind(), y(), x(), isStrictFP())); } if (x().isConstant()) { - if (kind() == Kind.Float) { - return ConstantNode.forFloat(x().asConstant().asFloat() + y().asConstant().asFloat(), graph()); - } else { - assert kind() == Kind.Double; - return ConstantNode.forDouble(x().asConstant().asDouble() + y().asConstant().asDouble(), graph()); - } + return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph()); } else if (y().isConstant()) { if (kind() == Kind.Float) { float c = y().asConstant().asFloat(); diff -r e68922869732 -r 04b039d82e86 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatDivNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatDivNode.java Tue Oct 01 17:26:56 2013 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatDivNode.java Wed Oct 02 12:09:51 2013 +0200 @@ -34,19 +34,20 @@ super(kind, x, y, isStrictFP); } + public Constant evalConst(Constant... inputs) { + assert inputs.length == 2; + if (kind() == Kind.Float) { + return Constant.forFloat(x().asConstant().asFloat() / y().asConstant().asFloat()); + } else { + assert kind() == Kind.Double; + return Constant.forDouble(x().asConstant().asDouble() / y().asConstant().asDouble()); + } + } + @Override public ValueNode canonical(CanonicalizerTool tool) { if (x().isConstant() && y().isConstant()) { - if (kind() == Kind.Float) { - if (y().asConstant().asFloat() != 0) { - return ConstantNode.forFloat(x().asConstant().asFloat() / y().asConstant().asFloat(), graph()); - } - } else { - assert kind() == Kind.Double; - if (y().asConstant().asDouble() != 0) { - return ConstantNode.forDouble(x().asConstant().asDouble() / y().asConstant().asDouble(), graph()); - } - } + return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph()); } return this; } diff -r e68922869732 -r 04b039d82e86 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatMulNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatMulNode.java Tue Oct 01 17:26:56 2013 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatMulNode.java Wed Oct 02 12:09:51 2013 +0200 @@ -34,18 +34,23 @@ super(kind, x, y, isStrictFP); } + public Constant evalConst(Constant... inputs) { + assert inputs.length == 2; + if (kind() == Kind.Float) { + return Constant.forFloat(x().asConstant().asFloat() * y().asConstant().asFloat()); + } else { + assert kind() == Kind.Double; + return Constant.forDouble(x().asConstant().asDouble() * y().asConstant().asDouble()); + } + } + @Override public ValueNode canonical(CanonicalizerTool tool) { if (x().isConstant() && !y().isConstant()) { return graph().unique(new FloatMulNode(kind(), y(), x(), isStrictFP())); } if (x().isConstant()) { - if (kind() == Kind.Float) { - return ConstantNode.forFloat(x().asConstant().asFloat() * y().asConstant().asFloat(), graph()); - } else { - assert kind() == Kind.Double; - return ConstantNode.forDouble(x().asConstant().asDouble() * y().asConstant().asDouble(), graph()); - } + return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph()); } return this; } diff -r e68922869732 -r 04b039d82e86 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatRemNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatRemNode.java Tue Oct 01 17:26:56 2013 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatRemNode.java Wed Oct 02 12:09:51 2013 +0200 @@ -34,15 +34,20 @@ super(kind, x, y, isStrictFP); } + public Constant evalConst(Constant... inputs) { + assert inputs.length == 2; + if (kind() == Kind.Float) { + return Constant.forFloat(x().asConstant().asFloat() % y().asConstant().asFloat()); + } else { + assert kind() == Kind.Double; + return Constant.forDouble(x().asConstant().asDouble() % y().asConstant().asDouble()); + } + } + @Override public ValueNode canonical(CanonicalizerTool tool) { if (x().isConstant() && y().isConstant()) { - if (kind() == Kind.Float) { - return ConstantNode.forFloat(x().asConstant().asFloat() % y().asConstant().asFloat(), graph()); - } else { - assert kind() == Kind.Double; - return ConstantNode.forDouble(x().asConstant().asDouble() % y().asConstant().asDouble(), graph()); - } + return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph()); } return this; } diff -r e68922869732 -r 04b039d82e86 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatSubNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatSubNode.java Tue Oct 01 17:26:56 2013 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatSubNode.java Wed Oct 02 12:09:51 2013 +0200 @@ -34,18 +34,23 @@ super(kind, x, y, isStrictFP); } + public Constant evalConst(Constant... inputs) { + assert inputs.length == 2; + if (kind() == Kind.Float) { + return Constant.forFloat(x().asConstant().asFloat() - y().asConstant().asFloat()); + } else { + assert kind() == Kind.Double; + return Constant.forDouble(x().asConstant().asDouble() - y().asConstant().asDouble()); + } + } + @Override public ValueNode canonical(CanonicalizerTool tool) { if (x() == y()) { return ConstantNode.forFloatingKind(kind(), 0.0f, graph()); } if (x().isConstant() && y().isConstant()) { - if (kind() == Kind.Float) { - return ConstantNode.forFloat(x().asConstant().asFloat() - y().asConstant().asFloat(), graph()); - } else { - assert kind() == Kind.Double; - return ConstantNode.forDouble(x().asConstant().asDouble() - y().asConstant().asDouble(), graph()); - } + return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph()); } else if (y().isConstant()) { if (kind() == Kind.Float) { float c = y().asConstant().asFloat(); diff -r e68922869732 -r 04b039d82e86 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerAddNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerAddNode.java Tue Oct 01 17:26:56 2013 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerAddNode.java Wed Oct 02 12:09:51 2013 +0200 @@ -41,6 +41,12 @@ } @Override + public Constant evalConst(Constant... inputs) { + assert inputs.length == 2; + return Constant.forIntegerKind(kind(), inputs[0].asLong() + inputs[1].asLong(), null); + } + + @Override public ValueNode canonical(CanonicalizerTool tool) { if (x().isConstant() && !y().isConstant()) { return graph().unique(new IntegerAddNode(kind(), y(), x())); @@ -60,12 +66,7 @@ } } if (x().isConstant()) { - if (kind() == Kind.Int) { - return ConstantNode.forInt(x().asConstant().asInt() + y().asConstant().asInt(), graph()); - } else { - assert kind() == Kind.Long; - return ConstantNode.forLong(x().asConstant().asLong() + y().asConstant().asLong(), graph()); - } + return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph()); } else if (y().isConstant()) { long c = y().asConstant().asLong(); if (c == 0) { diff -r e68922869732 -r 04b039d82e86 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerMulNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerMulNode.java Tue Oct 01 17:26:56 2013 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerMulNode.java Wed Oct 02 12:09:51 2013 +0200 @@ -36,17 +36,18 @@ } @Override + public Constant evalConst(Constant... inputs) { + assert inputs.length == 2; + return Constant.forIntegerKind(kind(), inputs[0].asLong() * inputs[1].asLong(), null); + } + + @Override public ValueNode canonical(CanonicalizerTool tool) { if (x().isConstant() && !y().isConstant()) { return graph().unique(new IntegerMulNode(kind(), y(), x())); } if (x().isConstant()) { - if (kind() == Kind.Int) { - return ConstantNode.forInt(x().asConstant().asInt() * y().asConstant().asInt(), graph()); - } else { - assert kind() == Kind.Long; - return ConstantNode.forLong(x().asConstant().asLong() * y().asConstant().asLong(), graph()); - } + return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph()); } else if (y().isConstant()) { long c = y().asConstant().asLong(); if (c == 1) { diff -r e68922869732 -r 04b039d82e86 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerSubNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerSubNode.java Tue Oct 01 17:26:56 2013 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerSubNode.java Wed Oct 02 12:09:51 2013 +0200 @@ -41,6 +41,12 @@ } @Override + public Constant evalConst(Constant... inputs) { + assert inputs.length == 2; + return Constant.forIntegerKind(kind(), inputs[0].asLong() - inputs[1].asLong(), null); + } + + @Override public ValueNode canonical(CanonicalizerTool tool) { if (x() == y()) { return ConstantNode.forIntegerKind(kind(), 0, graph()); @@ -80,12 +86,7 @@ } } if (x().isConstant() && y().isConstant()) { - if (kind() == Kind.Int) { - return ConstantNode.forInt(x().asConstant().asInt() - y().asConstant().asInt(), graph()); - } else { - assert kind() == Kind.Long; - return ConstantNode.forLong(x().asConstant().asLong() - y().asConstant().asLong(), graph()); - } + return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph()); } else if (y().isConstant()) { long c = y().asConstant().asLong(); if (c == 0) { diff -r e68922869732 -r 04b039d82e86 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/LeftShiftNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/LeftShiftNode.java Tue Oct 01 17:26:56 2013 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/LeftShiftNode.java Wed Oct 02 12:09:51 2013 +0200 @@ -41,8 +41,21 @@ } @Override + public Constant evalConst(Constant... inputs) { + assert inputs.length == 2; + if (kind() == Kind.Int) { + return Constant.forInt(inputs[0].asInt() << inputs[1].asInt()); + } else { + assert kind() == Kind.Long; + return Constant.forLong(inputs[0].asLong() << inputs[1].asLong()); + } + } + + @Override public ValueNode canonical(CanonicalizerTool tool) { - if (y().isConstant()) { + if (x().isConstant() && y().isConstant()) { + return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph()); + } else if (y().isConstant()) { int amount = y().asConstant().asInt(); int originalAmout = amount; int mask; @@ -53,14 +66,6 @@ mask = 0x3f; } amount &= mask; - if (x().isConstant()) { - if (kind() == Kind.Int) { - return ConstantNode.forInt(x().asConstant().asInt() << amount, graph()); - } else { - assert kind() == Kind.Long; - return ConstantNode.forLong(x().asConstant().asLong() << amount, graph()); - } - } if (amount == 0) { return x(); } diff -r e68922869732 -r 04b039d82e86 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NegateNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NegateNode.java Tue Oct 01 17:26:56 2013 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NegateNode.java Wed Oct 02 12:09:51 2013 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.nodes.calc; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -52,19 +54,26 @@ this.x = x; } + public Constant evalConst(Constant... inputs) { + assert inputs.length == 1; + switch (inputs[0].getKind()) { + case Int: + return Constant.forInt(-inputs[0].asInt()); + case Long: + return Constant.forLong(-inputs[0].asLong()); + case Float: + return Constant.forFloat(-inputs[0].asFloat()); + case Double: + return Constant.forDouble(-inputs[0].asDouble()); + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + @Override public ValueNode canonical(CanonicalizerTool tool) { if (x().isConstant()) { - switch (x().kind()) { - case Int: - return ConstantNode.forInt(-x().asConstant().asInt(), graph()); - case Long: - return ConstantNode.forLong(-x().asConstant().asLong(), graph()); - case Float: - return ConstantNode.forFloat(-x().asConstant().asFloat(), graph()); - case Double: - return ConstantNode.forDouble(-x().asConstant().asDouble(), graph()); - } + return ConstantNode.forPrimitive(evalConst(x.asConstant()), graph()); } if (x() instanceof NegateNode) { return ((NegateNode) x()).x(); diff -r e68922869732 -r 04b039d82e86 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NotNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NotNode.java Tue Oct 01 17:26:56 2013 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NotNode.java Wed Oct 02 12:09:51 2013 +0200 @@ -43,6 +43,12 @@ return updateStamp(StampTool.not(x().stamp())); } + @Override + public Constant evalConst(Constant... inputs) { + assert inputs.length == 1; + return Constant.forIntegerKind(kind(), ~inputs[0].asLong(), null); + } + /** * Creates new NegateNode instance. * @@ -57,12 +63,7 @@ @Override public ValueNode canonical(CanonicalizerTool tool) { if (x().isConstant()) { - switch (x().kind()) { - case Int: - return ConstantNode.forInt(~x().asConstant().asInt(), graph()); - case Long: - return ConstantNode.forLong(~x().asConstant().asLong(), graph()); - } + return ConstantNode.forPrimitive(evalConst(x().asConstant()), graph()); } if (x() instanceof NotNode) { return ((NotNode) x()).x(); diff -r e68922869732 -r 04b039d82e86 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/OrNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/OrNode.java Tue Oct 01 17:26:56 2013 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/OrNode.java Wed Oct 02 12:09:51 2013 +0200 @@ -41,6 +41,12 @@ } @Override + public Constant evalConst(Constant... inputs) { + assert inputs.length == 2; + return Constant.forIntegerKind(kind(), inputs[0].asLong() | inputs[1].asLong(), null); + } + + @Override public ValueNode canonical(CanonicalizerTool tool) { if (x() == y()) { return x(); @@ -49,12 +55,7 @@ return graph().unique(new OrNode(kind(), y(), x())); } if (x().isConstant()) { - if (kind() == Kind.Int) { - return ConstantNode.forInt(x().asConstant().asInt() | y().asConstant().asInt(), graph()); - } else { - assert kind() == Kind.Long; - return ConstantNode.forLong(x().asConstant().asLong() | y().asConstant().asLong(), graph()); - } + return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph()); } else if (y().isConstant()) { if (kind() == Kind.Int) { int c = y().asConstant().asInt(); diff -r e68922869732 -r 04b039d82e86 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/RightShiftNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/RightShiftNode.java Tue Oct 01 17:26:56 2013 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/RightShiftNode.java Wed Oct 02 12:09:51 2013 +0200 @@ -36,11 +36,24 @@ } @Override + public Constant evalConst(Constant... inputs) { + assert inputs.length == 2; + if (kind() == Kind.Int) { + return Constant.forInt(inputs[0].asInt() >> inputs[1].asInt()); + } else { + assert kind() == Kind.Long; + return Constant.forLong(inputs[0].asLong() >> inputs[1].asLong()); + } + } + + @Override public ValueNode canonical(CanonicalizerTool tool) { if (x().stamp() instanceof IntegerStamp && ((IntegerStamp) x().stamp()).isPositive()) { return graph().unique(new UnsignedRightShiftNode(kind(), x(), y())); } - if (y().isConstant()) { + if (x().isConstant() && y().isConstant()) { + return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph()); + } else if (y().isConstant()) { int amount = y().asConstant().asInt(); int originalAmout = amount; int mask; @@ -51,14 +64,6 @@ mask = 0x3f; } amount &= mask; - if (x().isConstant()) { - if (kind() == Kind.Int) { - return ConstantNode.forInt(x().asConstant().asInt() >> amount, graph()); - } else { - assert kind() == Kind.Long; - return ConstantNode.forLong(x().asConstant().asLong() >> amount, graph()); - } - } if (amount == 0) { return x(); } diff -r e68922869732 -r 04b039d82e86 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRightShiftNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRightShiftNode.java Tue Oct 01 17:26:56 2013 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRightShiftNode.java Wed Oct 02 12:09:51 2013 +0200 @@ -41,8 +41,21 @@ } @Override + public Constant evalConst(Constant... inputs) { + assert inputs.length == 2; + if (kind() == Kind.Int) { + return Constant.forInt(inputs[0].asInt() >>> inputs[1].asInt()); + } else { + assert kind() == Kind.Long; + return Constant.forLong(inputs[0].asLong() >>> inputs[1].asLong()); + } + } + + @Override public ValueNode canonical(CanonicalizerTool tool) { - if (y().isConstant()) { + if (x().isConstant() && y().isConstant()) { + return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph()); + } else if (y().isConstant()) { int amount = y().asConstant().asInt(); int originalAmout = amount; int mask; @@ -53,14 +66,6 @@ mask = 0x3f; } amount &= mask; - if (x().isConstant()) { - if (kind() == Kind.Int) { - return ConstantNode.forInt(x().asConstant().asInt() >>> amount, graph()); - } else { - assert kind() == Kind.Long; - return ConstantNode.forLong(x().asConstant().asLong() >>> amount, graph()); - } - } if (amount == 0) { return x(); } diff -r e68922869732 -r 04b039d82e86 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/XorNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/XorNode.java Tue Oct 01 17:26:56 2013 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/XorNode.java Wed Oct 02 12:09:51 2013 +0200 @@ -41,6 +41,12 @@ } @Override + public Constant evalConst(Constant... inputs) { + assert inputs.length == 2; + return Constant.forIntegerKind(kind(), inputs[0].asLong() ^ inputs[1].asLong(), null); + } + + @Override public ValueNode canonical(CanonicalizerTool tool) { if (x() == y()) { return ConstantNode.forIntegerKind(kind(), 0, graph()); @@ -49,12 +55,7 @@ return graph().unique(new XorNode(kind(), y(), x())); } if (x().isConstant()) { - if (kind() == Kind.Int) { - return ConstantNode.forInt(x().asConstant().asInt() ^ y().asConstant().asInt(), graph()); - } else { - assert kind() == Kind.Long; - return ConstantNode.forLong(x().asConstant().asLong() ^ y().asConstant().asLong(), graph()); - } + return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph()); } else if (y().isConstant()) { if (kind() == Kind.Int) { int c = y().asConstant().asInt(); diff -r e68922869732 -r 04b039d82e86 graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64ConvertNode.java --- a/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64ConvertNode.java Tue Oct 01 17:26:56 2013 -0700 +++ b/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64ConvertNode.java Wed Oct 02 12:09:51 2013 +0200 @@ -22,9 +22,10 @@ */ package com.oracle.graal.replacements.amd64; +import com.oracle.graal.api.meta.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.calc.ConvertNode.Op; -import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -44,6 +45,12 @@ this.value = value; } + public Constant evalConst(Constant... inputs) { + // this node should never have been created if its input is constant + assert false; + return null; + } + public void generate(ArithmeticLIRGenerator gen) { gen.setResult(this, gen.emitConvert(opcode, gen.operand(value))); } diff -r e68922869732 -r 04b039d82e86 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MathIntrinsicNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MathIntrinsicNode.java Tue Oct 01 17:26:56 2013 -0700 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MathIntrinsicNode.java Wed Oct 02 12:09:51 2013 +0200 @@ -85,28 +85,15 @@ gen.setResult(this, result); } + public Constant evalConst(Constant... inputs) { + assert inputs.length == 1; + return Constant.forDouble(compute(inputs[0].asDouble(), operation())); + } + @Override public ValueNode canonical(CanonicalizerTool tool) { if (x().isConstant()) { - double value = x().asConstant().asDouble(); - switch (operation()) { - case ABS: - return ConstantNode.forDouble(Math.abs(value), graph()); - case SQRT: - return ConstantNode.forDouble(Math.sqrt(value), graph()); - case LOG: - return ConstantNode.forDouble(Math.log(value), graph()); - case LOG10: - return ConstantNode.forDouble(Math.log10(value), graph()); - case SIN: - return ConstantNode.forDouble(Math.sin(value), graph()); - case COS: - return ConstantNode.forDouble(Math.cos(value), graph()); - case TAN: - return ConstantNode.forDouble(Math.tan(value), graph()); - default: - throw GraalInternalError.shouldNotReachHere(); - } + return ConstantNode.forPrimitive(evalConst(x().asConstant()), graph()); } return this; }