Search in sources :

Example 86 with Value

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;
}
Also used : Condition(org.graalvm.compiler.core.common.calc.Condition) Variable(org.graalvm.compiler.lir.Variable) FloatCondSetOp(org.graalvm.compiler.lir.amd64.AMD64ControlFlow.FloatCondSetOp) LIRValueUtil.asConstantValue(org.graalvm.compiler.lir.LIRValueUtil.asConstantValue) ConstantValue(org.graalvm.compiler.lir.ConstantValue) LIRValueUtil.isConstantValue(org.graalvm.compiler.lir.LIRValueUtil.isConstantValue) Value(jdk.vm.ci.meta.Value) ValueUtil.isAllocatableValue(jdk.vm.ci.code.ValueUtil.isAllocatableValue) AllocatableValue(jdk.vm.ci.meta.AllocatableValue) RegisterValue(jdk.vm.ci.code.RegisterValue) AMD64AddressValue(org.graalvm.compiler.lir.amd64.AMD64AddressValue) CondMoveOp(org.graalvm.compiler.lir.amd64.AMD64ControlFlow.CondMoveOp) FloatCondMoveOp(org.graalvm.compiler.lir.amd64.AMD64ControlFlow.FloatCondMoveOp) FloatCondMoveOp(org.graalvm.compiler.lir.amd64.AMD64ControlFlow.FloatCondMoveOp) CondSetOp(org.graalvm.compiler.lir.amd64.AMD64ControlFlow.CondSetOp) FloatCondSetOp(org.graalvm.compiler.lir.amd64.AMD64ControlFlow.FloatCondSetOp)

Example 87 with Value

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;
}
Also used : FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) IntegerDivRemNode(org.graalvm.compiler.nodes.calc.IntegerDivRemNode) Value(jdk.vm.ci.meta.Value) AllocatableValue(jdk.vm.ci.meta.AllocatableValue) FixedNode(org.graalvm.compiler.nodes.FixedNode) IfNode(org.graalvm.compiler.nodes.IfNode)

Example 88 with Value

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;
}
Also used : OperandSize(org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize) AMD64RMOp(org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp) AVXOp(org.graalvm.compiler.asm.amd64.AMD64Assembler.AVXOp) AMD64BinaryConsumer(org.graalvm.compiler.lir.amd64.AMD64BinaryConsumer) NarrowNode(org.graalvm.compiler.nodes.calc.NarrowNode) LabelRef(org.graalvm.compiler.lir.LabelRef) UnsignedRightShiftNode(org.graalvm.compiler.nodes.calc.UnsignedRightShiftNode) SUB(org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.SUB) SignExtendNode(org.graalvm.compiler.nodes.calc.SignExtendNode) FloatConvertNode(org.graalvm.compiler.nodes.calc.FloatConvertNode) ZeroExtendNode(org.graalvm.compiler.nodes.calc.ZeroExtendNode) AMD64Kind(jdk.vm.ci.amd64.AMD64Kind) NumUtil(org.graalvm.compiler.core.common.NumUtil) IfNode(org.graalvm.compiler.nodes.IfNode) GraphUtil(org.graalvm.compiler.nodes.util.GraphUtil) NodeView(org.graalvm.compiler.nodes.NodeView) LIRLowerableAccess(org.graalvm.compiler.nodes.memory.LIRLowerableAccess) BranchOp(org.graalvm.compiler.lir.amd64.AMD64ControlFlow.BranchOp) MOVSX(org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSX) NodeLIRBuilder(org.graalvm.compiler.core.gen.NodeLIRBuilder) DeoptimizingNode(org.graalvm.compiler.nodes.DeoptimizingNode) TargetDescription(jdk.vm.ci.code.TargetDescription) JavaConstant(jdk.vm.ci.meta.JavaConstant) PlatformKind(jdk.vm.ci.meta.PlatformKind) ValueNode(org.graalvm.compiler.nodes.ValueNode) Value(jdk.vm.ci.meta.Value) ComplexMatchResult(org.graalvm.compiler.core.match.ComplexMatchResult) Access(org.graalvm.compiler.nodes.memory.Access) ADD(org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.ADD) SS(org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.SS) DWORD(org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.DWORD) GraalError(org.graalvm.compiler.debug.GraalError) ValueKind(jdk.vm.ci.meta.ValueKind) MatchRule(org.graalvm.compiler.core.match.MatchRule) LogicCompareAndSwapNode(org.graalvm.compiler.nodes.java.LogicCompareAndSwapNode) AllocatableValue(jdk.vm.ci.meta.AllocatableValue) CompareNode(org.graalvm.compiler.nodes.calc.CompareNode) LeftShiftNode(org.graalvm.compiler.nodes.calc.LeftShiftNode) MOVSXB(org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSXB) WriteNode(org.graalvm.compiler.nodes.memory.WriteNode) LIRFrameState(org.graalvm.compiler.lir.LIRFrameState) SD(org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.SD) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) ReinterpretNode(org.graalvm.compiler.nodes.calc.ReinterpretNode) AMD64RRMOp(org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RRMOp) AMD64(jdk.vm.ci.amd64.AMD64) AMD64MIOp(org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MIOp) ValueCompareAndSwapNode(org.graalvm.compiler.nodes.java.ValueCompareAndSwapNode) MOVSXD(org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSXD) Condition(org.graalvm.compiler.core.common.calc.Condition) CPUFeature(jdk.vm.ci.amd64.AMD64.CPUFeature) LIRKind(org.graalvm.compiler.core.common.LIRKind) CanonicalCondition(org.graalvm.compiler.core.common.calc.CanonicalCondition) SSEOp(org.graalvm.compiler.asm.amd64.AMD64Assembler.SSEOp) OR(org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.OR) LIRValueUtil(org.graalvm.compiler.lir.LIRValueUtil) NodeMatchRules(org.graalvm.compiler.core.gen.NodeMatchRules) XOR(org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.XOR) LIRGeneratorTool(org.graalvm.compiler.lir.gen.LIRGeneratorTool) AND(org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.AND) AMD64AddressValue(org.graalvm.compiler.lir.amd64.AMD64AddressValue) QWORD(org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.QWORD) AMD64AddressValue(org.graalvm.compiler.lir.amd64.AMD64AddressValue) Condition(org.graalvm.compiler.core.common.calc.Condition) CanonicalCondition(org.graalvm.compiler.core.common.calc.CanonicalCondition) Value(jdk.vm.ci.meta.Value) AllocatableValue(jdk.vm.ci.meta.AllocatableValue) AMD64AddressValue(org.graalvm.compiler.lir.amd64.AMD64AddressValue) JavaConstant(jdk.vm.ci.meta.JavaConstant) LIRKind(org.graalvm.compiler.core.common.LIRKind) LabelRef(org.graalvm.compiler.lir.LabelRef) MatchRule(org.graalvm.compiler.core.match.MatchRule)

Example 89 with Value

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);
}
Also used : ConstantValue(org.graalvm.compiler.lir.ConstantValue) AArch64AddressValue(org.graalvm.compiler.lir.aarch64.AArch64AddressValue) RegisterValue(jdk.vm.ci.code.RegisterValue) Value(jdk.vm.ci.meta.Value) AllocatableValue(jdk.vm.ci.meta.AllocatableValue) LIRKind(org.graalvm.compiler.core.common.LIRKind) ConstantValue(org.graalvm.compiler.lir.ConstantValue)

Example 90 with Value

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;
}
Also used : AArch64Compare(org.graalvm.compiler.lir.aarch64.AArch64Compare) AArch64AddressValue(org.graalvm.compiler.lir.aarch64.AArch64AddressValue) RegisterValue(jdk.vm.ci.code.RegisterValue) Value(jdk.vm.ci.meta.Value) AllocatableValue(jdk.vm.ci.meta.AllocatableValue) AArch64Kind(jdk.vm.ci.aarch64.AArch64Kind)

Aggregations

Value (jdk.vm.ci.meta.Value)151 AllocatableValue (jdk.vm.ci.meta.AllocatableValue)76 RegisterValue (jdk.vm.ci.code.RegisterValue)33 LIRKind (org.graalvm.compiler.core.common.LIRKind)18 LIRInstruction (org.graalvm.compiler.lir.LIRInstruction)14 LIRValueUtil.isConstantValue (org.graalvm.compiler.lir.LIRValueUtil.isConstantValue)14 LIRValueUtil.isStackSlotValue (org.graalvm.compiler.lir.LIRValueUtil.isStackSlotValue)14 OperandMode (org.graalvm.compiler.lir.LIRInstruction.OperandMode)12 Variable (org.graalvm.compiler.lir.Variable)12 ComplexMatchValue (org.graalvm.compiler.core.match.ComplexMatchValue)11 Indent (org.graalvm.compiler.debug.Indent)11 EnumSet (java.util.EnumSet)10 DebugContext (org.graalvm.compiler.debug.DebugContext)10 GraalError (org.graalvm.compiler.debug.GraalError)10 LIRFrameState (org.graalvm.compiler.lir.LIRFrameState)10 BitSet (java.util.BitSet)9 Register (jdk.vm.ci.code.Register)9 ConstantValue (org.graalvm.compiler.lir.ConstantValue)9 SPARCAddressValue (org.graalvm.compiler.lir.sparc.SPARCAddressValue)9 ValueNode (org.graalvm.compiler.nodes.ValueNode)9