use of jdk.vm.ci.meta.Value in project graal by oracle.
the class AMD64LIRGenerator method emitConditionalMove.
@Override
public Variable emitConditionalMove(PlatformKind cmpKind, Value left, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue) {
boolean isFloatComparison = cmpKind == AMD64Kind.SINGLE || cmpKind == AMD64Kind.DOUBLE;
Condition finalCondition = cond;
Value finalTrueValue = trueValue;
Value finalFalseValue = falseValue;
if (isFloatComparison) {
// eliminate the parity check in case of a float comparison
Value finalLeft = left;
Value finalRight = right;
if (unorderedIsTrue != AMD64ControlFlow.trueOnUnordered(finalCondition)) {
if (unorderedIsTrue == AMD64ControlFlow.trueOnUnordered(finalCondition.mirror())) {
finalCondition = finalCondition.mirror();
finalLeft = right;
finalRight = left;
} else if (finalCondition != Condition.EQ && finalCondition != Condition.NE) {
// NaN semantics)
assert unorderedIsTrue == AMD64ControlFlow.trueOnUnordered(finalCondition.negate());
finalCondition = finalCondition.negate();
finalTrueValue = falseValue;
finalFalseValue = trueValue;
}
}
emitRawCompare(cmpKind, finalLeft, finalRight);
} else {
finalCondition = emitCompare(cmpKind, left, right, cond);
}
boolean isParityCheckNecessary = isFloatComparison && unorderedIsTrue != AMD64ControlFlow.trueOnUnordered(finalCondition);
Variable result = newVariable(finalTrueValue.getValueKind());
if (!isParityCheckNecessary && isIntConstant(finalTrueValue, 1) && isIntConstant(finalFalseValue, 0)) {
if (isFloatComparison) {
append(new FloatCondSetOp(result, finalCondition));
} else {
append(new CondSetOp(result, finalCondition));
}
} else if (!isParityCheckNecessary && isIntConstant(finalTrueValue, 0) && isIntConstant(finalFalseValue, 1)) {
if (isFloatComparison) {
if (unorderedIsTrue == AMD64ControlFlow.trueOnUnordered(finalCondition.negate())) {
append(new FloatCondSetOp(result, finalCondition.negate()));
} else {
append(new FloatCondSetOp(result, finalCondition));
Variable negatedResult = newVariable(result.getValueKind());
append(new AMD64Binary.ConstOp(AMD64BinaryArithmetic.XOR, OperandSize.get(result.getPlatformKind()), negatedResult, result, 1));
result = negatedResult;
}
} else {
append(new CondSetOp(result, finalCondition.negate()));
}
} else if (isFloatComparison) {
append(new FloatCondMoveOp(result, finalCondition, unorderedIsTrue, load(finalTrueValue), load(finalFalseValue)));
} else {
append(new CondMoveOp(result, finalCondition, load(finalTrueValue), loadNonConst(finalFalseValue)));
}
return result;
}
use of jdk.vm.ci.meta.Value in project graal by oracle.
the class AMD64NodeLIRBuilder method peephole.
@Override
protected boolean peephole(ValueNode valueNode) {
if (valueNode instanceof IntegerDivRemNode) {
AMD64ArithmeticLIRGenerator arithmeticGen = (AMD64ArithmeticLIRGenerator) gen.getArithmetic();
IntegerDivRemNode divRem = (IntegerDivRemNode) valueNode;
FixedNode node = divRem.next();
while (true) {
if (node instanceof IfNode) {
IfNode ifNode = (IfNode) node;
double probability = ifNode.getTrueSuccessorProbability();
if (probability == 1.0) {
node = ifNode.trueSuccessor();
} else if (probability == 0.0) {
node = ifNode.falseSuccessor();
} else {
break;
}
} else if (!(node instanceof FixedWithNextNode)) {
break;
}
FixedWithNextNode fixedWithNextNode = (FixedWithNextNode) node;
if (fixedWithNextNode instanceof IntegerDivRemNode) {
IntegerDivRemNode otherDivRem = (IntegerDivRemNode) fixedWithNextNode;
if (divRem.getOp() != otherDivRem.getOp() && divRem.getType() == otherDivRem.getType()) {
if (otherDivRem.getX() == divRem.getX() && otherDivRem.getY() == divRem.getY() && !hasOperand(otherDivRem)) {
Value[] results;
switch(divRem.getType()) {
case SIGNED:
results = arithmeticGen.emitSignedDivRem(operand(divRem.getX()), operand(divRem.getY()), state((DeoptimizingNode) valueNode));
break;
case UNSIGNED:
results = arithmeticGen.emitUnsignedDivRem(operand(divRem.getX()), operand(divRem.getY()), state((DeoptimizingNode) valueNode));
break;
default:
throw GraalError.shouldNotReachHere();
}
switch(divRem.getOp()) {
case DIV:
assert otherDivRem.getOp() == Op.REM;
setResult(divRem, results[0]);
setResult(otherDivRem, results[1]);
break;
case REM:
assert otherDivRem.getOp() == Op.DIV;
setResult(divRem, results[1]);
setResult(otherDivRem, results[0]);
break;
default:
throw GraalError.shouldNotReachHere();
}
return true;
}
}
}
node = fixedWithNextNode.next();
}
}
return false;
}
use of jdk.vm.ci.meta.Value in project graal by oracle.
the class AMD64NodeMatchRules method ifCompareLogicCas.
@MatchRule("(If (ObjectEquals=compare value LogicCompareAndSwap=cas))")
@MatchRule("(If (PointerEquals=compare value LogicCompareAndSwap=cas))")
@MatchRule("(If (FloatEquals=compare value LogicCompareAndSwap=cas))")
@MatchRule("(If (IntegerEquals=compare value LogicCompareAndSwap=cas))")
public ComplexMatchResult ifCompareLogicCas(IfNode root, CompareNode compare, ValueNode value, LogicCompareAndSwapNode cas) {
JavaConstant constant = value.asJavaConstant();
assert compare.condition() == CanonicalCondition.EQ;
if (constant != null && cas.usages().count() == 1) {
long constantValue = constant.asLong();
boolean successIsTrue;
if (constantValue == 0) {
successIsTrue = false;
} else if (constantValue == 1) {
successIsTrue = true;
} else {
return null;
}
return builder -> {
LIRKind kind = getLirKind(cas);
LabelRef trueLabel = getLIRBlock(root.trueSuccessor());
LabelRef falseLabel = getLIRBlock(root.falseSuccessor());
double trueLabelProbability = root.probability(root.trueSuccessor());
Value expectedValue = operand(cas.getExpectedValue());
Value newValue = operand(cas.getNewValue());
AMD64AddressValue address = (AMD64AddressValue) operand(cas.getAddress());
Condition condition = successIsTrue ? Condition.EQ : Condition.NE;
getLIRGeneratorTool().emitCompareAndSwapBranch(kind, address, expectedValue, newValue, condition, trueLabel, falseLabel, trueLabelProbability);
return null;
};
}
return null;
}
use of jdk.vm.ci.meta.Value in project graal by oracle.
the class AArch64ArithmeticLIRGenerator method emitZeroExtend.
@Override
public Value emitZeroExtend(Value inputVal, int fromBits, int toBits) {
assert fromBits <= toBits && toBits <= 64;
if (fromBits == toBits) {
return inputVal;
}
LIRKind resultKind = getResultLirKind(toBits, inputVal);
long mask = NumUtil.getNbitNumberLong(fromBits);
Value maskValue = new ConstantValue(resultKind, JavaConstant.forLong(mask));
return emitBinary(resultKind, AArch64ArithmeticOp.AND, true, inputVal, maskValue);
}
use of jdk.vm.ci.meta.Value in project graal by oracle.
the class AArch64LIRGenerator method emitCompare.
/**
* This method emits the compare instruction, and may reorder the operands. It returns true if
* it did so.
*
* @param a the left operand of the comparison. Has to have same type as b. Non null.
* @param b the right operand of the comparison. Has to have same type as a. Non null.
* @return true if mirrored (i.e. "b cmp a" instead of "a cmp b" was done).
*/
protected boolean emitCompare(PlatformKind cmpKind, Value a, Value b, Condition condition, boolean unorderedIsTrue) {
Value left;
Value right;
boolean mirrored;
AArch64Kind kind = (AArch64Kind) cmpKind;
if (kind.isInteger()) {
Value aExt = a;
Value bExt = b;
int compareBytes = cmpKind.getSizeInBytes();
// AArch64 compares 32 or 64 bits: sign extend a and b as required.
if (compareBytes < a.getPlatformKind().getSizeInBytes()) {
aExt = arithmeticLIRGen.emitSignExtend(a, compareBytes * 8, 64);
}
if (compareBytes < b.getPlatformKind().getSizeInBytes()) {
bExt = arithmeticLIRGen.emitSignExtend(b, compareBytes * 8, 64);
}
if (LIRValueUtil.isVariable(bExt)) {
left = load(bExt);
right = loadNonConst(aExt);
mirrored = true;
} else {
left = load(aExt);
right = loadNonConst(bExt);
mirrored = false;
}
append(new AArch64Compare.CompareOp(left, loadNonCompareConst(right)));
} else if (kind.isSIMD()) {
if (AArch64Compare.FloatCompareOp.isFloatCmpConstant(a, condition, unorderedIsTrue)) {
left = load(b);
right = a;
mirrored = true;
} else if (AArch64Compare.FloatCompareOp.isFloatCmpConstant(b, condition, unorderedIsTrue)) {
left = load(a);
right = b;
mirrored = false;
} else {
left = load(a);
right = loadReg(b);
mirrored = false;
}
append(new AArch64Compare.FloatCompareOp(left, asAllocatable(right), condition, unorderedIsTrue));
} else {
throw GraalError.shouldNotReachHere();
}
return mirrored;
}
Aggregations