use of org.graalvm.compiler.nodes.ValueNode in project graal by oracle.
the class BinaryArithmeticNode method canonical.
@Override
public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
NodeView view = NodeView.from(tool);
ValueNode result = tryConstantFold(getOp(forX, forY), forX, forY, stamp(view), view);
if (result != null) {
return result;
}
return this;
}
use of org.graalvm.compiler.nodes.ValueNode in project graal by oracle.
the class ConditionalNode method canonical.
@Override
public ValueNode canonical(CanonicalizerTool tool) {
NodeView view = NodeView.from(tool);
ValueNode synonym = findSynonym(condition, trueValue(), falseValue(), view);
if (synonym != null) {
return synonym;
}
ValueNode result = canonicalizeConditional(condition, trueValue(), falseValue(), stamp, view);
if (result != null) {
return result;
}
return this;
}
use of org.graalvm.compiler.nodes.ValueNode 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.nodes.ValueNode in project graal by oracle.
the class ConditionalNode method create.
public static ValueNode create(LogicNode condition, ValueNode trueValue, ValueNode falseValue, NodeView view) {
ValueNode synonym = findSynonym(condition, trueValue, falseValue, view);
if (synonym != null) {
return synonym;
}
ValueNode result = canonicalizeConditional(condition, trueValue, falseValue, trueValue.stamp(view).meet(falseValue.stamp(view)), view);
if (result != null) {
return result;
}
return new ConditionalNode(condition, trueValue, falseValue);
}
use of org.graalvm.compiler.nodes.ValueNode in project graal by oracle.
the class FloatLessThanNode method canonical.
@Override
public Node canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
NodeView view = NodeView.from(tool);
ValueNode value = OP.canonical(tool.getConstantReflection(), tool.getMetaAccess(), tool.getOptions(), tool.smallestCompareWidth(), CanonicalCondition.LT, unorderedIsTrue, forX, forY, view);
if (value != null) {
return value;
}
return this;
}
Aggregations