Mercurial > hg > graal-compiler
changeset 18304:bf586af6fa0c
Merge.
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Fri, 07 Nov 2014 12:36:32 +0100 |
parents | ab47ef2f2207 (current diff) 9734f97bddfe (diff) |
children | da76d42c397e |
files | |
diffstat | 9 files changed, 403 insertions(+), 24 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Fri Nov 07 12:35:58 2014 +0100 +++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Fri Nov 07 12:36:32 2014 +0100 @@ -1006,7 +1006,16 @@ @Override public Value emitMathAbs(Value input) { Variable result = newVariable(LIRKind.derive(input)); - append(new BinaryRegConst(DAND, result, asAllocatable(input), JavaConstant.forDouble(Double.longBitsToDouble(0x7FFFFFFFFFFFFFFFL)))); + switch (input.getKind()) { + case Float: + append(new BinaryRegConst(FAND, result, asAllocatable(input), JavaConstant.forFloat(Float.intBitsToFloat(0x7FFFFFFF)))); + break; + case Double: + append(new BinaryRegConst(DAND, result, asAllocatable(input), JavaConstant.forDouble(Double.longBitsToDouble(0x7FFFFFFFFFFFFFFFL)))); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } return result; }
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/ArithmeticOpTable.java Fri Nov 07 12:35:58 2014 +0100 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/ArithmeticOpTable.java Fri Nov 07 12:36:32 2014 +0100 @@ -41,8 +41,10 @@ import com.oracle.graal.compiler.common.type.ArithmeticOpTable.IntegerConvertOp.Narrow; import com.oracle.graal.compiler.common.type.ArithmeticOpTable.IntegerConvertOp.SignExtend; import com.oracle.graal.compiler.common.type.ArithmeticOpTable.IntegerConvertOp.ZeroExtend; +import com.oracle.graal.compiler.common.type.ArithmeticOpTable.UnaryOp.Abs; import com.oracle.graal.compiler.common.type.ArithmeticOpTable.UnaryOp.Neg; import com.oracle.graal.compiler.common.type.ArithmeticOpTable.UnaryOp.Not; +import com.oracle.graal.compiler.common.type.ArithmeticOpTable.UnaryOp.Sqrt; /** * Information about arithmetic operations. @@ -62,6 +64,9 @@ private final BinaryOp<Or> or; private final BinaryOp<Xor> xor; + private final UnaryOp<Abs> abs; + private final UnaryOp<Sqrt> sqrt; + private final IntegerConvertOp<ZeroExtend> zeroExtend; private final IntegerConvertOp<SignExtend> signExtend; private final IntegerConvertOp<Narrow> narrow; @@ -76,11 +81,12 @@ } } - public static final ArithmeticOpTable EMPTY = new ArithmeticOpTable(null, null, null, null, null, null, null, null, null, null, null, null, null); + public static final ArithmeticOpTable EMPTY = new ArithmeticOpTable(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null); public ArithmeticOpTable(UnaryOp<Neg> neg, BinaryOp<Add> add, BinaryOp<Sub> sub, BinaryOp<Mul> mul, BinaryOp<Div> div, BinaryOp<Rem> rem, UnaryOp<Not> not, BinaryOp<And> and, BinaryOp<Or> or, - BinaryOp<Xor> xor, IntegerConvertOp<ZeroExtend> zeroExtend, IntegerConvertOp<SignExtend> signExtend, IntegerConvertOp<Narrow> narrow, FloatConvertOp... floatConvert) { - this(neg, add, sub, mul, div, rem, not, and, or, xor, zeroExtend, signExtend, narrow, Stream.of(floatConvert)); + BinaryOp<Xor> xor, UnaryOp<Abs> abs, UnaryOp<Sqrt> sqrt, IntegerConvertOp<ZeroExtend> zeroExtend, IntegerConvertOp<SignExtend> signExtend, IntegerConvertOp<Narrow> narrow, + FloatConvertOp... floatConvert) { + this(neg, add, sub, mul, div, rem, not, and, or, xor, abs, sqrt, zeroExtend, signExtend, narrow, Stream.of(floatConvert)); } public interface ArithmeticOpWrapper { @@ -116,17 +122,21 @@ BinaryOp<Or> or = wrapIfNonNull(wrapper::wrapBinaryOp, inner.getOr()); BinaryOp<Xor> xor = wrapIfNonNull(wrapper::wrapBinaryOp, inner.getXor()); + UnaryOp<Abs> abs = wrapIfNonNull(wrapper::wrapUnaryOp, inner.getAbs()); + UnaryOp<Sqrt> sqrt = wrapIfNonNull(wrapper::wrapUnaryOp, inner.getSqrt()); + IntegerConvertOp<ZeroExtend> zeroExtend = wrapIfNonNull(wrapper::wrapIntegerConvertOp, inner.getZeroExtend()); IntegerConvertOp<SignExtend> signExtend = wrapIfNonNull(wrapper::wrapIntegerConvertOp, inner.getSignExtend()); IntegerConvertOp<Narrow> narrow = wrapIfNonNull(wrapper::wrapIntegerConvertOp, inner.getNarrow()); Stream<FloatConvertOp> floatConvert = Stream.of(inner.floatConvert).filter(Objects::nonNull).map(wrapper::wrapFloatConvertOp); - return new ArithmeticOpTable(neg, add, sub, mul, div, rem, not, and, or, xor, zeroExtend, signExtend, narrow, floatConvert); + return new ArithmeticOpTable(neg, add, sub, mul, div, rem, not, and, or, xor, abs, sqrt, zeroExtend, signExtend, narrow, floatConvert); } private ArithmeticOpTable(UnaryOp<Neg> neg, BinaryOp<Add> add, BinaryOp<Sub> sub, BinaryOp<Mul> mul, BinaryOp<Div> div, BinaryOp<Rem> rem, UnaryOp<Not> not, BinaryOp<And> and, BinaryOp<Or> or, - BinaryOp<Xor> xor, IntegerConvertOp<ZeroExtend> zeroExtend, IntegerConvertOp<SignExtend> signExtend, IntegerConvertOp<Narrow> narrow, Stream<FloatConvertOp> floatConvert) { + BinaryOp<Xor> xor, UnaryOp<Abs> abs, UnaryOp<Sqrt> sqrt, IntegerConvertOp<ZeroExtend> zeroExtend, IntegerConvertOp<SignExtend> signExtend, IntegerConvertOp<Narrow> narrow, + Stream<FloatConvertOp> floatConvert) { this.neg = neg; this.add = add; this.sub = sub; @@ -137,6 +147,8 @@ this.and = and; this.or = or; this.xor = xor; + this.abs = abs; + this.sqrt = sqrt; this.zeroExtend = zeroExtend; this.signExtend = signExtend; this.narrow = narrow; @@ -215,6 +227,20 @@ } /** + * Describes the absolute value operation. + */ + public UnaryOp<Abs> getAbs() { + return abs; + } + + /** + * Describes the square root operation. + */ + public UnaryOp<Sqrt> getSqrt() { + return sqrt; + } + + /** * Describes the zero extend conversion. */ public IntegerConvertOp<ZeroExtend> getZeroExtend() { @@ -248,7 +274,8 @@ @Override public String toString() { - return getClass().getSimpleName() + "[" + toString(neg, add, sub, mul, div, rem, not, and, or, xor, zeroExtend, signExtend, narrow) + ",floatConvert[" + toString(floatConvert) + "]]"; + return getClass().getSimpleName() + "[" + toString(neg, add, sub, mul, div, rem, not, and, or, xor, abs, sqrt, zeroExtend, signExtend, narrow) + ",floatConvert[" + toString(floatConvert) + + "]]"; } public abstract static class Op { @@ -300,6 +327,20 @@ } } + public abstract static class Abs extends UnaryOp<Abs> { + + protected Abs() { + super("ABS"); + } + } + + public abstract static class Sqrt extends UnaryOp<Sqrt> { + + protected Sqrt() { + super("SQRT"); + } + } + protected UnaryOp(String operation) { super(operation); }
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/FloatStamp.java Fri Nov 07 12:35:58 2014 +0100 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/FloatStamp.java Fri Nov 07 12:36:32 2014 +0100 @@ -452,7 +452,191 @@ } }, - null, null, null, null, + new UnaryOp.Not() { + + @Override + public Constant foldConstant(Constant c) { + PrimitiveConstant value = (PrimitiveConstant) c; + switch (value.getKind()) { + case Float: + int f = Float.floatToRawIntBits(value.asFloat()); + return JavaConstant.forFloat(Float.intBitsToFloat(~f)); + case Double: + long d = Double.doubleToRawLongBits(value.asDouble()); + return JavaConstant.forDouble(Double.longBitsToDouble(~d)); + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + + @Override + public Stamp foldStamp(Stamp s) { + return s.unrestricted(); + } + }, + + new BinaryOp.And(true, true) { + + @Override + public Constant foldConstant(Constant const1, Constant const2) { + PrimitiveConstant a = (PrimitiveConstant) const1; + PrimitiveConstant b = (PrimitiveConstant) const2; + assert a.getKind() == b.getKind(); + switch (a.getKind()) { + case Float: + int fa = Float.floatToRawIntBits(a.asFloat()); + int fb = Float.floatToRawIntBits(b.asFloat()); + return JavaConstant.forFloat(Float.intBitsToFloat(fa & fb)); + case Double: + long da = Double.doubleToRawLongBits(a.asDouble()); + long db = Double.doubleToRawLongBits(b.asDouble()); + return JavaConstant.forDouble(Double.longBitsToDouble(da & db)); + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + + @Override + public Stamp foldStamp(Stamp stamp1, Stamp stamp2) { + return stamp1.unrestricted(); + } + + @Override + public boolean isNeutral(Constant n) { + PrimitiveConstant value = (PrimitiveConstant) n; + switch (value.getKind()) { + case Float: + return Float.floatToRawIntBits(value.asFloat()) == 0xFFFFFFFF; + case Double: + return Double.doubleToRawLongBits(value.asDouble()) == 0xFFFFFFFFFFFFFFFFL; + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + }, + + new BinaryOp.Or(true, true) { + + @Override + public Constant foldConstant(Constant const1, Constant const2) { + PrimitiveConstant a = (PrimitiveConstant) const1; + PrimitiveConstant b = (PrimitiveConstant) const2; + assert a.getKind() == b.getKind(); + switch (a.getKind()) { + case Float: + int fa = Float.floatToRawIntBits(a.asFloat()); + int fb = Float.floatToRawIntBits(b.asFloat()); + return JavaConstant.forFloat(Float.intBitsToFloat(fa | fb)); + case Double: + long da = Double.doubleToRawLongBits(a.asDouble()); + long db = Double.doubleToRawLongBits(b.asDouble()); + return JavaConstant.forDouble(Double.longBitsToDouble(da | db)); + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + + @Override + public Stamp foldStamp(Stamp stamp1, Stamp stamp2) { + return stamp1.unrestricted(); + } + + @Override + public boolean isNeutral(Constant n) { + PrimitiveConstant value = (PrimitiveConstant) n; + switch (value.getKind()) { + case Float: + return Float.floatToRawIntBits(value.asFloat()) == 0; + case Double: + return Double.doubleToRawLongBits(value.asDouble()) == 0L; + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + }, + + new BinaryOp.Xor(true, true) { + + @Override + public Constant foldConstant(Constant const1, Constant const2) { + PrimitiveConstant a = (PrimitiveConstant) const1; + PrimitiveConstant b = (PrimitiveConstant) const2; + assert a.getKind() == b.getKind(); + switch (a.getKind()) { + case Float: + int fa = Float.floatToRawIntBits(a.asFloat()); + int fb = Float.floatToRawIntBits(b.asFloat()); + return JavaConstant.forFloat(Float.intBitsToFloat(fa ^ fb)); + case Double: + long da = Double.doubleToRawLongBits(a.asDouble()); + long db = Double.doubleToRawLongBits(b.asDouble()); + return JavaConstant.forDouble(Double.longBitsToDouble(da ^ db)); + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + + @Override + public Stamp foldStamp(Stamp stamp1, Stamp stamp2) { + return stamp1.unrestricted(); + } + + @Override + public boolean isNeutral(Constant n) { + PrimitiveConstant value = (PrimitiveConstant) n; + switch (value.getKind()) { + case Float: + return Float.floatToRawIntBits(value.asFloat()) == 0; + case Double: + return Double.doubleToRawLongBits(value.asDouble()) == 0L; + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + }, + + new UnaryOp.Abs() { + + @Override + public Constant foldConstant(Constant c) { + PrimitiveConstant value = (PrimitiveConstant) c; + switch (value.getKind()) { + case Float: + return JavaConstant.forFloat(Math.abs(value.asFloat())); + case Double: + return JavaConstant.forDouble(Math.abs(value.asDouble())); + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + + @Override + public Stamp foldStamp(Stamp s) { + FloatStamp stamp = (FloatStamp) s; + return new FloatStamp(stamp.getBits(), 0, Math.max(-stamp.lowerBound(), stamp.upperBound()), stamp.isNonNaN()); + } + }, + + new UnaryOp.Sqrt() { + + @Override + public Constant foldConstant(Constant c) { + PrimitiveConstant value = (PrimitiveConstant) c; + switch (value.getKind()) { + case Float: + return JavaConstant.forFloat((float) Math.sqrt(value.asFloat())); + case Double: + return JavaConstant.forDouble(Math.sqrt(value.asDouble())); + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + + @Override + public Stamp foldStamp(Stamp s) { + return s.unrestricted(); + } + }, null, null, null,
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IntegerStamp.java Fri Nov 07 12:35:58 2014 +0100 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IntegerStamp.java Fri Nov 07 12:36:32 2014 +0100 @@ -678,6 +678,29 @@ } }, + new UnaryOp.Abs() { + + @Override + public Constant foldConstant(Constant value) { + PrimitiveConstant c = (PrimitiveConstant) value; + return PrimitiveConstant.forIntegerKind(c.getKind(), Math.abs(c.asLong())); + } + + @Override + public Stamp foldStamp(Stamp input) { + IntegerStamp stamp = (IntegerStamp) input; + int bits = stamp.getBits(); + if (stamp.lowerBound() == CodeUtil.minValue(bits)) { + return input.unrestricted(); + } else { + long limit = Math.max(-stamp.lowerBound(), stamp.upperBound()); + return StampFactory.forInteger(bits, 0, limit); + } + } + }, + + null, + new IntegerConvertOp.ZeroExtend() { @Override
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AbsNode.java Fri Nov 07 12:36:32 2014 +0100 @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.nodes.calc; + +import com.oracle.graal.compiler.common.type.*; +import com.oracle.graal.compiler.common.type.ArithmeticOpTable.UnaryOp.Abs; +import com.oracle.graal.graph.spi.*; +import com.oracle.graal.lir.gen.*; +import com.oracle.graal.nodeinfo.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; + +/** + * Absolute value. + */ +@NodeInfo +public class AbsNode extends UnaryArithmeticNode<Abs> implements ArithmeticLIRLowerable, NarrowableArithmeticNode { + + public static AbsNode create(ValueNode x) { + return new AbsNode(x); + } + + protected AbsNode(ValueNode x) { + super(ArithmeticOpTable::getAbs, x); + } + + @Override + public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) { + ValueNode ret = super.canonical(tool, forValue); + if (ret != this) { + return ret; + } + if (forValue instanceof AbsNode) { + return forValue; + } + return this; + } + + @Override + public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) { + builder.setResult(this, gen.emitMathAbs(builder.operand(getValue()))); + } + + @NodeIntrinsic + public static float abs(float n) { + return Math.abs(n); + } + + @NodeIntrinsic + public static double abs(double n) { + return Math.abs(n); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/SqrtNode.java Fri Nov 07 12:36:32 2014 +0100 @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.nodes.calc; + +import com.oracle.graal.compiler.common.type.*; +import com.oracle.graal.compiler.common.type.ArithmeticOpTable.UnaryOp.Sqrt; +import com.oracle.graal.lir.gen.*; +import com.oracle.graal.nodeinfo.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; + +/** + * Square root. + */ +@NodeInfo +public class SqrtNode extends UnaryArithmeticNode<Sqrt> implements ArithmeticLIRLowerable, NarrowableArithmeticNode { + + public static SqrtNode create(ValueNode x) { + return new SqrtNode(x); + } + + protected SqrtNode(ValueNode x) { + super(ArithmeticOpTable::getSqrt, x); + } + + @Override + public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) { + builder.setResult(this, gen.emitMathSqrt(builder.operand(getValue()))); + } + + @NodeIntrinsic + public static double sqrt(double n) { + return Math.sqrt(n); + } +}
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/StandardMethodSubstitutionsTest.java Fri Nov 07 12:35:58 2014 +0100 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/StandardMethodSubstitutionsTest.java Fri Nov 07 12:36:32 2014 +0100 @@ -39,7 +39,7 @@ @Test public void testMathSubstitutions() { - assertInGraph(assertNotInGraph(test("mathAbs"), IfNode.class), MathIntrinsicNode.class); // Java + assertInGraph(assertNotInGraph(test("mathAbs"), IfNode.class), AbsNode.class); // Java test("math"); double value = 34567.891D;
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/MathSubstitutionsX86.java Fri Nov 07 12:35:58 2014 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/MathSubstitutionsX86.java Fri Nov 07 12:36:32 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,7 @@ import com.oracle.graal.api.replacements.*; import com.oracle.graal.graph.Node.ConstantNodeParameter; import com.oracle.graal.graph.Node.NodeIntrinsic; +import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.replacements.nodes.*; import com.oracle.graal.replacements.nodes.MathIntrinsicNode.Operation; @@ -39,13 +40,18 @@ private static final double PI_4 = Math.PI / 4; @MethodSubstitution + public static float abs(float x) { + return AbsNode.abs(x); + } + + @MethodSubstitution public static double abs(double x) { - return MathIntrinsicNode.compute(x, Operation.ABS); + return AbsNode.abs(x); } @MethodSubstitution public static double sqrt(double x) { - return MathIntrinsicNode.compute(x, Operation.SQRT); + return SqrtNode.sqrt(x); } @MethodSubstitution(guard = UnsafeSubstitutions.GetAndSetGuard.class)
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MathIntrinsicNode.java Fri Nov 07 12:35:58 2014 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MathIntrinsicNode.java Fri Nov 07 12:36:32 2014 +0100 @@ -38,8 +38,6 @@ protected final Operation operation; public enum Operation { - ABS, - SQRT, LOG, LOG10, SIN, @@ -66,12 +64,6 @@ Value input = builder.operand(getValue()); Value result; switch (operation()) { - case ABS: - result = gen.emitMathAbs(input); - break; - case SQRT: - result = gen.emitMathSqrt(input); - break; case LOG: result = gen.emitMathLog(input, false); break; @@ -109,10 +101,6 @@ private static double doCompute(double value, Operation op) { switch (op) { - case ABS: - return Math.abs(value); - case SQRT: - return Math.sqrt(value); case LOG: return Math.log(value); case LOG10: