20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23 package org.graalvm.compiler.replacements.nodes;
24
25 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_UNKNOWN;
26 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1;
27 import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
28 import org.graalvm.compiler.core.common.type.FloatStamp;
29 import org.graalvm.compiler.core.common.type.PrimitiveStamp;
30 import org.graalvm.compiler.core.common.type.Stamp;
31 import org.graalvm.compiler.core.common.type.StampFactory;
32 import org.graalvm.compiler.debug.GraalError;
33 import org.graalvm.compiler.graph.NodeClass;
34 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
35 import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
36 import org.graalvm.compiler.nodeinfo.NodeInfo;
37 import org.graalvm.compiler.nodes.ConstantNode;
38 import org.graalvm.compiler.nodes.ValueNode;
39 import org.graalvm.compiler.nodes.calc.BinaryNode;
40 import org.graalvm.compiler.nodes.calc.DivNode;
41 import org.graalvm.compiler.nodes.calc.MulNode;
42 import org.graalvm.compiler.nodes.calc.SqrtNode;
43 import org.graalvm.compiler.nodes.spi.ArithmeticLIRLowerable;
44 import org.graalvm.compiler.nodes.spi.Lowerable;
45 import org.graalvm.compiler.nodes.spi.LoweringTool;
46 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
47
48 import jdk.vm.ci.meta.JavaKind;
49 import jdk.vm.ci.meta.Value;
50
51 @NodeInfo(nameTemplate = "MathIntrinsic#{p#operation/s}", cycles = CYCLES_UNKNOWN, size = SIZE_1)
52 public final class BinaryMathIntrinsicNode extends BinaryNode implements ArithmeticLIRLowerable, Lowerable {
53
54 public static final NodeClass<BinaryMathIntrinsicNode> TYPE = NodeClass.create(BinaryMathIntrinsicNode.class);
55 protected final BinaryOperation operation;
56
57 public enum BinaryOperation {
58 POW(new ForeignCallDescriptor("arithmeticPow", double.class, double.class, double.class));
59
60 public final ForeignCallDescriptor foreignCallDescriptor;
124 }
125 if (forY.isConstant()) {
126 double yValue = forY.asJavaConstant().asDouble();
127 // If the second argument is positive or negative zero, then the result is 1.0.
128 if (yValue == 0.0D) {
129 return ConstantNode.forDouble(1);
130 }
131
132 // If the second argument is 1.0, then the result is the same as the first argument.
133 if (yValue == 1.0D) {
134 return x;
135 }
136
137 // If the second argument is NaN, then the result is NaN.
138 if (Double.isNaN(yValue)) {
139 return ConstantNode.forDouble(Double.NaN);
140 }
141
142 // x**-1 = 1/x
143 if (yValue == -1.0D) {
144 return new DivNode(ConstantNode.forDouble(1), x);
145 }
146
147 // x**2 = x*x
148 if (yValue == 2.0D) {
149 return new MulNode(x, x);
150 }
151
152 // x**0.5 = sqrt(x)
153 if (yValue == 0.5D && x.stamp() instanceof FloatStamp && ((FloatStamp) x.stamp()).lowerBound() >= 0.0D) {
154 return new SqrtNode(x);
155 }
156 }
157 return this;
158 }
159
160 @NodeIntrinsic
161 public static native double compute(double x, double y, @ConstantNodeParameter BinaryOperation op);
162
163 private static double doCompute(double x, double y, BinaryOperation op) {
164 switch (op) {
|
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23 package org.graalvm.compiler.replacements.nodes;
24
25 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_UNKNOWN;
26 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1;
27 import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
28 import org.graalvm.compiler.core.common.type.FloatStamp;
29 import org.graalvm.compiler.core.common.type.PrimitiveStamp;
30 import org.graalvm.compiler.core.common.type.Stamp;
31 import org.graalvm.compiler.core.common.type.StampFactory;
32 import org.graalvm.compiler.debug.GraalError;
33 import org.graalvm.compiler.graph.NodeClass;
34 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
35 import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
36 import org.graalvm.compiler.nodeinfo.NodeInfo;
37 import org.graalvm.compiler.nodes.ConstantNode;
38 import org.graalvm.compiler.nodes.ValueNode;
39 import org.graalvm.compiler.nodes.calc.BinaryNode;
40 import org.graalvm.compiler.nodes.calc.FloatDivNode;
41 import org.graalvm.compiler.nodes.calc.MulNode;
42 import org.graalvm.compiler.nodes.calc.SqrtNode;
43 import org.graalvm.compiler.nodes.spi.ArithmeticLIRLowerable;
44 import org.graalvm.compiler.nodes.spi.Lowerable;
45 import org.graalvm.compiler.nodes.spi.LoweringTool;
46 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
47
48 import jdk.vm.ci.meta.JavaKind;
49 import jdk.vm.ci.meta.Value;
50
51 @NodeInfo(nameTemplate = "MathIntrinsic#{p#operation/s}", cycles = CYCLES_UNKNOWN, size = SIZE_1)
52 public final class BinaryMathIntrinsicNode extends BinaryNode implements ArithmeticLIRLowerable, Lowerable {
53
54 public static final NodeClass<BinaryMathIntrinsicNode> TYPE = NodeClass.create(BinaryMathIntrinsicNode.class);
55 protected final BinaryOperation operation;
56
57 public enum BinaryOperation {
58 POW(new ForeignCallDescriptor("arithmeticPow", double.class, double.class, double.class));
59
60 public final ForeignCallDescriptor foreignCallDescriptor;
124 }
125 if (forY.isConstant()) {
126 double yValue = forY.asJavaConstant().asDouble();
127 // If the second argument is positive or negative zero, then the result is 1.0.
128 if (yValue == 0.0D) {
129 return ConstantNode.forDouble(1);
130 }
131
132 // If the second argument is 1.0, then the result is the same as the first argument.
133 if (yValue == 1.0D) {
134 return x;
135 }
136
137 // If the second argument is NaN, then the result is NaN.
138 if (Double.isNaN(yValue)) {
139 return ConstantNode.forDouble(Double.NaN);
140 }
141
142 // x**-1 = 1/x
143 if (yValue == -1.0D) {
144 return new FloatDivNode(ConstantNode.forDouble(1), x);
145 }
146
147 // x**2 = x*x
148 if (yValue == 2.0D) {
149 return new MulNode(x, x);
150 }
151
152 // x**0.5 = sqrt(x)
153 if (yValue == 0.5D && x.stamp() instanceof FloatStamp && ((FloatStamp) x.stamp()).lowerBound() >= 0.0D) {
154 return new SqrtNode(x);
155 }
156 }
157 return this;
158 }
159
160 @NodeIntrinsic
161 public static native double compute(double x, double y, @ConstantNodeParameter BinaryOperation op);
162
163 private static double doCompute(double x, double y, BinaryOperation op) {
164 switch (op) {
|