< prev index next >
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/UnaryMathIntrinsicNode.java
Print this page
@@ -25,10 +25,11 @@
package org.graalvm.compiler.replacements.nodes;
import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_64;
import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1;
+import jdk.vm.ci.meta.Value;
import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
import org.graalvm.compiler.core.common.type.FloatStamp;
import org.graalvm.compiler.core.common.type.PrimitiveStamp;
import org.graalvm.compiler.core.common.type.Stamp;
import org.graalvm.compiler.core.common.type.StampFactory;
@@ -42,14 +43,13 @@
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.calc.UnaryNode;
import org.graalvm.compiler.nodes.spi.ArithmeticLIRLowerable;
import org.graalvm.compiler.nodes.spi.Lowerable;
import org.graalvm.compiler.nodes.spi.LoweringTool;
-import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
import jdk.vm.ci.meta.JavaKind;
-import jdk.vm.ci.meta.Value;
+import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
@NodeInfo(nameTemplate = "MathIntrinsic#{p#operation/s}", cycles = CYCLES_64, size = SIZE_1)
public final class UnaryMathIntrinsicNode extends UnaryNode implements ArithmeticLIRLowerable, Lowerable {
public static final NodeClass<UnaryMathIntrinsicNode> TYPE = NodeClass.create(UnaryMathIntrinsicNode.class);
@@ -85,10 +85,47 @@
return Math.tan(value);
default:
throw new GraalError("unknown op %s", this);
}
}
+
+ public Stamp computeStamp(Stamp valueStamp) {
+ if (valueStamp instanceof FloatStamp) {
+ FloatStamp floatStamp = (FloatStamp) valueStamp;
+ switch (this) {
+ case COS:
+ case SIN: {
+ boolean nonNaN = floatStamp.lowerBound() != Double.NEGATIVE_INFINITY && floatStamp.upperBound() != Double.POSITIVE_INFINITY && floatStamp.isNonNaN();
+ return StampFactory.forFloat(JavaKind.Double, -1.0, 1.0, nonNaN);
+ }
+ case TAN: {
+ boolean nonNaN = floatStamp.lowerBound() != Double.NEGATIVE_INFINITY && floatStamp.upperBound() != Double.POSITIVE_INFINITY && floatStamp.isNonNaN();
+ return StampFactory.forFloat(JavaKind.Double, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, nonNaN);
+ }
+ case LOG:
+ case LOG10: {
+ double lowerBound = compute(floatStamp.lowerBound());
+ double upperBound = compute(floatStamp.upperBound());
+ if (floatStamp.contains(0.0)) {
+ // 0.0 and -0.0 infinity produces -Inf
+ lowerBound = Double.NEGATIVE_INFINITY;
+ }
+ boolean nonNaN = floatStamp.lowerBound() >= 0.0 && floatStamp.isNonNaN();
+ return StampFactory.forFloat(JavaKind.Double, lowerBound, upperBound, nonNaN);
+ }
+ case EXP: {
+ double lowerBound = Math.exp(floatStamp.lowerBound());
+ double upperBound = Math.exp(floatStamp.upperBound());
+ boolean nonNaN = floatStamp.isNonNaN();
+ return StampFactory.forFloat(JavaKind.Double, lowerBound, upperBound, nonNaN);
+ }
+
+ }
+ }
+ return StampFactory.forKind(JavaKind.Double);
+ }
+
}
public UnaryOperation getOperation() {
return operation;
}
@@ -107,63 +144,28 @@
}
return null;
}
protected UnaryMathIntrinsicNode(ValueNode value, UnaryOperation op) {
- super(TYPE, computeStamp(value.stamp(NodeView.DEFAULT), op), value);
+ super(TYPE, op.computeStamp(value.stamp(NodeView.DEFAULT)), value);
assert value.stamp(NodeView.DEFAULT) instanceof FloatStamp && PrimitiveStamp.getBits(value.stamp(NodeView.DEFAULT)) == 64;
this.operation = op;
}
@Override
public Stamp foldStamp(Stamp valueStamp) {
- return computeStamp(valueStamp, getOperation());
- }
-
- static Stamp computeStamp(Stamp valueStamp, UnaryOperation op) {
- if (valueStamp instanceof FloatStamp) {
- FloatStamp floatStamp = (FloatStamp) valueStamp;
- switch (op) {
- case COS:
- case SIN: {
- boolean nonNaN = floatStamp.lowerBound() != Double.NEGATIVE_INFINITY && floatStamp.upperBound() != Double.POSITIVE_INFINITY && floatStamp.isNonNaN();
- return StampFactory.forFloat(JavaKind.Double, -1.0, 1.0, nonNaN);
- }
- case TAN: {
- boolean nonNaN = floatStamp.lowerBound() != Double.NEGATIVE_INFINITY && floatStamp.upperBound() != Double.POSITIVE_INFINITY && floatStamp.isNonNaN();
- return StampFactory.forFloat(JavaKind.Double, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, nonNaN);
- }
- case LOG:
- case LOG10: {
- double lowerBound = op.compute(floatStamp.lowerBound());
- double upperBound = op.compute(floatStamp.upperBound());
- if (floatStamp.contains(0.0)) {
- // 0.0 and -0.0 infinity produces -Inf
- lowerBound = Double.NEGATIVE_INFINITY;
- }
- boolean nonNaN = floatStamp.lowerBound() >= 0.0 && floatStamp.isNonNaN();
- return StampFactory.forFloat(JavaKind.Double, lowerBound, upperBound, nonNaN);
- }
- case EXP: {
- double lowerBound = Math.exp(floatStamp.lowerBound());
- double upperBound = Math.exp(floatStamp.upperBound());
- boolean nonNaN = floatStamp.isNonNaN();
- return StampFactory.forFloat(JavaKind.Double, lowerBound, upperBound, nonNaN);
- }
-
- }
- }
- return StampFactory.forKind(JavaKind.Double);
+ return getOperation().computeStamp(valueStamp);
}
@Override
public void lower(LoweringTool tool) {
tool.getLowerer().lower(this, tool);
}
@Override
public void generate(NodeLIRBuilderTool nodeValueMap, ArithmeticLIRGeneratorTool gen) {
+ // We can only reach here in the math stubs
Value input = nodeValueMap.operand(getValue());
Value result;
switch (getOperation()) {
case LOG:
result = gen.emitMathLog(input, false);
< prev index next >