use of org.graalvm.compiler.core.common.type.IntegerStamp in project graal by oracle.
the class AndNode method canonical.
private static ValueNode canonical(AndNode self, BinaryOp<And> op, Stamp stamp, ValueNode forX, ValueNode forY, NodeView view) {
if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) {
return forX;
}
if (forX.isConstant() && !forY.isConstant()) {
return new AndNode(forY, forX);
}
if (forY.isConstant()) {
Constant c = forY.asConstant();
if (op.isNeutral(c)) {
return forX;
}
if (c instanceof PrimitiveConstant && ((PrimitiveConstant) c).getJavaKind().isNumericInteger()) {
long rawY = ((PrimitiveConstant) c).asLong();
long mask = CodeUtil.mask(PrimitiveStamp.getBits(stamp));
if ((rawY & mask) == 0) {
return ConstantNode.forIntegerStamp(stamp, 0);
}
if (forX instanceof SignExtendNode) {
SignExtendNode ext = (SignExtendNode) forX;
if (rawY == ((1L << ext.getInputBits()) - 1)) {
return new ZeroExtendNode(ext.getValue(), ext.getResultBits());
}
}
IntegerStamp xStamp = (IntegerStamp) forX.stamp(view);
if (((xStamp.upMask() | xStamp.downMask()) & ~rawY) == 0) {
// No bits are set which are outside the mask, so the mask will have no effect.
return forX;
}
}
return reassociate(self != null ? self : (AndNode) new AndNode(forX, forY).maybeCommuteInputs(), ValueNode.isConstantPredicate(), forX, forY, view);
}
if (forX instanceof NotNode && forY instanceof NotNode) {
return new NotNode(OrNode.create(((NotNode) forX).getValue(), ((NotNode) forY).getValue(), view));
}
return self != null ? self : new AndNode(forX, forY).maybeCommuteInputs();
}
use of org.graalvm.compiler.core.common.type.IntegerStamp in project graal by oracle.
the class ConditionalNode method inferStamp.
@Override
public boolean inferStamp() {
Stamp valueStamp = trueValue.stamp(NodeView.DEFAULT).meet(falseValue.stamp(NodeView.DEFAULT));
if (condition instanceof IntegerLessThanNode) {
IntegerLessThanNode lessThan = (IntegerLessThanNode) condition;
if (lessThan.getX() == trueValue && lessThan.getY() == falseValue) {
// this encodes a min operation
JavaConstant constant = lessThan.getX().asJavaConstant();
if (constant == null) {
constant = lessThan.getY().asJavaConstant();
}
if (constant != null) {
IntegerStamp bounds = StampFactory.forInteger(constant.getJavaKind(), constant.getJavaKind().getMinValue(), constant.asLong());
valueStamp = valueStamp.join(bounds);
}
} else if (lessThan.getX() == falseValue && lessThan.getY() == trueValue) {
// this encodes a max operation
JavaConstant constant = lessThan.getX().asJavaConstant();
if (constant == null) {
constant = lessThan.getY().asJavaConstant();
}
if (constant != null) {
IntegerStamp bounds = StampFactory.forInteger(constant.getJavaKind(), constant.asLong(), constant.getJavaKind().getMaxValue());
valueStamp = valueStamp.join(bounds);
}
}
}
return updateStamp(valueStamp);
}
use of org.graalvm.compiler.core.common.type.IntegerStamp in project graal by oracle.
the class ConditionalNode method canonicalizeConditional.
public static ValueNode canonicalizeConditional(LogicNode condition, ValueNode trueValue, ValueNode falseValue, Stamp stamp, NodeView view) {
if (trueValue == falseValue) {
return trueValue;
}
if (condition instanceof CompareNode && ((CompareNode) condition).isIdentityComparison()) {
// optimize the pattern (x == y) ? x : y
CompareNode compare = (CompareNode) condition;
if ((compare.getX() == trueValue && compare.getY() == falseValue) || (compare.getX() == falseValue && compare.getY() == trueValue)) {
return falseValue;
}
}
if (trueValue.stamp(view) instanceof IntegerStamp) {
// check if the conditional is redundant
if (condition instanceof IntegerLessThanNode) {
IntegerLessThanNode lessThan = (IntegerLessThanNode) condition;
IntegerStamp falseValueStamp = (IntegerStamp) falseValue.stamp(view);
IntegerStamp trueValueStamp = (IntegerStamp) trueValue.stamp(view);
if (lessThan.getX() == trueValue && lessThan.getY() == falseValue) {
// return "x" for "x < y ? x : y" in case that we know "x <= y"
if (trueValueStamp.upperBound() <= falseValueStamp.lowerBound()) {
return trueValue;
}
} else if (lessThan.getX() == falseValue && lessThan.getY() == trueValue) {
// return "y" for "x < y ? y : x" in case that we know "x <= y"
if (falseValueStamp.upperBound() <= trueValueStamp.lowerBound()) {
return trueValue;
}
}
}
// range 0 - 1
if (trueValue.isConstant() && falseValue.isConstant()) {
long constTrueValue = trueValue.asJavaConstant().asLong();
long constFalseValue = falseValue.asJavaConstant().asLong();
if (condition instanceof IntegerEqualsNode) {
IntegerEqualsNode equals = (IntegerEqualsNode) condition;
if (equals.getY().isConstant() && equals.getX().stamp(view) instanceof IntegerStamp) {
IntegerStamp equalsXStamp = (IntegerStamp) equals.getX().stamp(view);
if (equalsXStamp.upMask() == 1) {
long equalsY = equals.getY().asJavaConstant().asLong();
if (equalsY == 0) {
if (constTrueValue == 0 && constFalseValue == 1) {
// return x when: x == 0 ? 0 : 1;
return IntegerConvertNode.convertUnsigned(equals.getX(), stamp, view);
} else if (constTrueValue == 1 && constFalseValue == 0) {
// negate a boolean value via xor
return IntegerConvertNode.convertUnsigned(XorNode.create(equals.getX(), ConstantNode.forIntegerStamp(equals.getX().stamp(view), 1), view), stamp, view);
}
} else if (equalsY == 1) {
if (constTrueValue == 1 && constFalseValue == 0) {
// return x when: x == 1 ? 1 : 0;
return IntegerConvertNode.convertUnsigned(equals.getX(), stamp, view);
} else if (constTrueValue == 0 && constFalseValue == 1) {
// negate a boolean value via xor
return IntegerConvertNode.convertUnsigned(XorNode.create(equals.getX(), ConstantNode.forIntegerStamp(equals.getX().stamp(view), 1), view), stamp, view);
}
}
}
}
} else if (condition instanceof IntegerTestNode) {
// replace IntegerTestNode with AndNode for the following patterns:
// (value & 1) == 0 ? 0 : 1
// (value & 1) == 1 ? 1 : 0
IntegerTestNode integerTestNode = (IntegerTestNode) condition;
if (integerTestNode.getY().isConstant()) {
assert integerTestNode.getX().stamp(view) instanceof IntegerStamp;
long testY = integerTestNode.getY().asJavaConstant().asLong();
if (testY == 1 && constTrueValue == 0 && constFalseValue == 1) {
return IntegerConvertNode.convertUnsigned(AndNode.create(integerTestNode.getX(), integerTestNode.getY(), view), stamp, view);
}
}
}
}
if (condition instanceof IntegerLessThanNode) {
/*
* Convert a conditional add ((x < 0) ? (x + y) : x) into (x + (y & (x >> (bits -
* 1)))) to avoid the test.
*/
IntegerLessThanNode lt = (IntegerLessThanNode) condition;
if (lt.getY().isConstant() && lt.getY().asConstant().isDefaultForKind()) {
if (falseValue == lt.getX()) {
if (trueValue instanceof AddNode) {
AddNode add = (AddNode) trueValue;
if (add.getX() == falseValue) {
int bits = ((IntegerStamp) trueValue.stamp(NodeView.DEFAULT)).getBits();
ValueNode shift = new RightShiftNode(lt.getX(), ConstantNode.forIntegerBits(32, bits - 1));
ValueNode and = new AndNode(shift, add.getY());
return new AddNode(add.getX(), and);
}
}
}
}
}
}
return null;
}
use of org.graalvm.compiler.core.common.type.IntegerStamp in project graal by oracle.
the class IntegerConvertNode method convert.
public static ValueNode convert(ValueNode input, Stamp stamp, boolean zeroExtend, NodeView view) {
IntegerStamp fromStamp = (IntegerStamp) input.stamp(view);
IntegerStamp toStamp = (IntegerStamp) stamp;
ValueNode result;
if (toStamp.getBits() == fromStamp.getBits()) {
result = input;
} else if (toStamp.getBits() < fromStamp.getBits()) {
result = new NarrowNode(input, fromStamp.getBits(), toStamp.getBits());
} else if (zeroExtend) {
// toStamp.getBits() > fromStamp.getBits()
result = ZeroExtendNode.create(input, toStamp.getBits(), view);
} else {
// toStamp.getBits() > fromStamp.getBits()
result = SignExtendNode.create(input, toStamp.getBits(), view);
}
IntegerStamp resultStamp = (IntegerStamp) result.stamp(view);
assert toStamp.getBits() == resultStamp.getBits();
return result;
}
use of org.graalvm.compiler.core.common.type.IntegerStamp in project graal by oracle.
the class IntegerEqualsNode method tryFold.
@Override
public TriState tryFold(Stamp xStampGeneric, Stamp yStampGeneric) {
if (xStampGeneric instanceof IntegerStamp && yStampGeneric instanceof IntegerStamp) {
IntegerStamp xStamp = (IntegerStamp) xStampGeneric;
IntegerStamp yStamp = (IntegerStamp) yStampGeneric;
if (xStamp.alwaysDistinct(yStamp)) {
return TriState.FALSE;
} else if (xStamp.neverDistinct(yStamp)) {
return TriState.TRUE;
}
}
return TriState.UNKNOWN;
}
Aggregations