< 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,34 ****
--- 25,35 ----
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,55 ****
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;
@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);
--- 43,55 ----
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 jdk.vm.ci.meta.JavaKind;
! 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,94 ****
--- 85,131 ----
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,169 ****
}
return null;
}
protected UnaryMathIntrinsicNode(ValueNode value, UnaryOperation op) {
! super(TYPE, computeStamp(value.stamp(NodeView.DEFAULT), op), 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);
}
@Override
public void lower(LoweringTool tool) {
tool.getLowerer().lower(this, tool);
}
@Override
public void generate(NodeLIRBuilderTool nodeValueMap, ArithmeticLIRGeneratorTool gen) {
Value input = nodeValueMap.operand(getValue());
Value result;
switch (getOperation()) {
case LOG:
result = gen.emitMathLog(input, false);
--- 144,171 ----
}
return null;
}
protected UnaryMathIntrinsicNode(ValueNode value, UnaryOperation op) {
! 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 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 >