Search in sources :

Example 1 with OperandMode

use of org.graalvm.compiler.lir.LIRInstruction.OperandMode in project graal by oracle.

the class HotSpotBackend method gatherDestroyedCallerRegisters.

/**
 * Finds all the registers that are defined by some given LIR.
 *
 * @param lir the LIR to examine
 * @return the registers that are defined by or used as temps for any instruction in {@code lir}
 */
protected final EconomicSet<Register> gatherDestroyedCallerRegisters(LIR lir) {
    final EconomicSet<Register> destroyedRegisters = EconomicSet.create(Equivalence.IDENTITY);
    ValueConsumer defConsumer = new ValueConsumer() {

        @Override
        public void visitValue(Value value, OperandMode mode, EnumSet<OperandFlag> flags) {
            if (ValueUtil.isRegister(value)) {
                final Register reg = ValueUtil.asRegister(value);
                destroyedRegisters.add(reg);
            }
        }
    };
    for (AbstractBlockBase<?> block : lir.codeEmittingOrder()) {
        if (block == null) {
            continue;
        }
        for (LIRInstruction op : lir.getLIRforBlock(block)) {
            if (op instanceof LabelOp) {
            // Don't consider this as a definition
            } else {
                op.visitEachTemp(defConsumer);
                op.visitEachOutput(defConsumer);
            }
        }
    }
    return translateToCallerRegisters(destroyedRegisters);
}
Also used : LabelOp(org.graalvm.compiler.lir.StandardOp.LabelOp) Register(jdk.vm.ci.code.Register) ValueConsumer(org.graalvm.compiler.lir.ValueConsumer) EnumSet(java.util.EnumSet) LIRInstruction(org.graalvm.compiler.lir.LIRInstruction) Value(jdk.vm.ci.meta.Value) OperandMode(org.graalvm.compiler.lir.LIRInstruction.OperandMode)

Example 2 with OperandMode

use of org.graalvm.compiler.lir.LIRInstruction.OperandMode in project graal by oracle.

the class SSALinearScanLifetimeAnalysisPhase method addRegisterHint.

@Override
protected void addRegisterHint(final LIRInstruction op, final Value targetValue, OperandMode mode, EnumSet<OperandFlag> flags, final boolean hintAtDef) {
    super.addRegisterHint(op, targetValue, mode, flags, hintAtDef);
    if (hintAtDef && op instanceof LabelOp) {
        LabelOp label = (LabelOp) op;
        Interval to = allocator.getOrCreateInterval((AllocatableValue) targetValue);
        SSAUtil.forEachPhiRegisterHint(allocator.getLIR(), allocator.blockForId(label.id()), label, targetValue, mode, (ValueConsumer) (registerHint, valueMode, valueFlags) -> {
            if (LinearScan.isVariableOrRegister(registerHint)) {
                Interval from = allocator.getOrCreateInterval((AllocatableValue) registerHint);
                setHint(debug, op, to, from);
                setHint(debug, op, from, to);
            }
        });
    }
}
Also used : OperandMode(org.graalvm.compiler.lir.LIRInstruction.OperandMode) Interval(org.graalvm.compiler.lir.alloc.lsra.Interval) ValueConsumer(org.graalvm.compiler.lir.ValueConsumer) LIRInstruction(org.graalvm.compiler.lir.LIRInstruction) RegisterPriority(org.graalvm.compiler.lir.alloc.lsra.Interval.RegisterPriority) Value(jdk.vm.ci.meta.Value) OperandFlag(org.graalvm.compiler.lir.LIRInstruction.OperandFlag) DebugContext(org.graalvm.compiler.debug.DebugContext) LinearScan(org.graalvm.compiler.lir.alloc.lsra.LinearScan) LinearScanLifetimeAnalysisPhase(org.graalvm.compiler.lir.alloc.lsra.LinearScanLifetimeAnalysisPhase) SSAUtil(org.graalvm.compiler.lir.ssa.SSAUtil) EnumSet(java.util.EnumSet) AllocatableValue(jdk.vm.ci.meta.AllocatableValue) LabelOp(org.graalvm.compiler.lir.StandardOp.LabelOp) LabelOp(org.graalvm.compiler.lir.StandardOp.LabelOp) AllocatableValue(jdk.vm.ci.meta.AllocatableValue) Interval(org.graalvm.compiler.lir.alloc.lsra.Interval)

Example 3 with OperandMode

use of org.graalvm.compiler.lir.LIRInstruction.OperandMode in project graal by oracle.

the class GlobalLivenessInfo method verifyBlock.

private boolean verifyBlock(AbstractBlockBase<?> block, LIR lir) {
    BitSet liveSet = new BitSet(lir.numVariables());
    int[] liveIn = getBlockIn(block);
    for (int varNum : liveIn) {
        liveSet.set(varNum);
    }
    ValueConsumer proc = new ValueConsumer() {

        @Override
        public void visitValue(Value value, OperandMode mode, EnumSet<OperandFlag> flags) {
            if (LIRValueUtil.isVariable(value)) {
                Variable var = LIRValueUtil.asVariable(value);
                if (mode == OperandMode.DEF) {
                    liveSet.set(var.index);
                } else {
                    assert liveSet.get(var.index) : String.format("Variable %s but not defined in block %s (liveIn: %s)", var, block, Arrays.toString(liveIn));
                }
            }
        }
    };
    for (LIRInstruction op : lir.getLIRforBlock(block)) {
        op.visitEachInput(proc);
        op.visitEachAlive(proc);
        op.visitEachState(proc);
        op.visitEachOutput(proc);
    // no need for checking temp
    }
    return true;
}
Also used : Variable(org.graalvm.compiler.lir.Variable) ValueConsumer(org.graalvm.compiler.lir.ValueConsumer) EnumSet(java.util.EnumSet) LIRInstruction(org.graalvm.compiler.lir.LIRInstruction) BitSet(java.util.BitSet) Value(jdk.vm.ci.meta.Value) OperandMode(org.graalvm.compiler.lir.LIRInstruction.OperandMode)

Example 4 with OperandMode

use of org.graalvm.compiler.lir.LIRInstruction.OperandMode in project graal by oracle.

the class TrivialTraceAllocator method handlePhiOut.

private static void handlePhiOut(LIRInstruction jump, int[] varIn, Value[] locIn) {
    // handle outgoing phi values
    ValueProcedure outputConsumer = new ValueProcedure() {

        @Override
        public Value doValue(Value value, OperandMode mode, EnumSet<OperandFlag> flags) {
            if (isVariable(value)) {
                // since incoming variables are sorted, we can do a binary search
                return locIn[Arrays.binarySearch(varIn, asVariable(value).index)];
            }
            return value;
        }
    };
    // Jumps have only alive values (outgoing phi values)
    jump.forEachAlive(outputConsumer);
}
Also used : ValueProcedure(org.graalvm.compiler.lir.ValueProcedure) EnumSet(java.util.EnumSet) Value(jdk.vm.ci.meta.Value) OperandMode(org.graalvm.compiler.lir.LIRInstruction.OperandMode)

Example 5 with OperandMode

use of org.graalvm.compiler.lir.LIRInstruction.OperandMode in project graal by oracle.

the class LinearScanAssignLocationsPhase method debugInfoProcedure.

private Value debugInfoProcedure(LIRInstruction op, Value operand) {
    if (isVirtualStackSlot(operand)) {
        return operand;
    }
    int tempOpId = op.id();
    OperandMode mode = OperandMode.USE;
    AbstractBlockBase<?> block = allocator.blockForId(tempOpId);
    if (block.getSuccessorCount() == 1 && tempOpId == allocator.getLastLirInstructionId(block)) {
        /*
             * Generating debug information for the last instruction of a block. If this instruction
             * is a branch, spill moves are inserted before this branch and so the wrong operand
             * would be returned (spill moves at block boundaries are not considered in the live
             * ranges of intervals).
             *
             * Solution: use the first opId of the branch target block instead.
             */
        final LIRInstruction instr = allocator.getLIR().getLIRforBlock(block).get(allocator.getLIR().getLIRforBlock(block).size() - 1);
        if (instr instanceof StandardOp.JumpOp) {
            if (allocator.getBlockData(block).liveOut.get(allocator.operandNumber(operand))) {
                tempOpId = allocator.getFirstLirInstructionId(block.getSuccessors()[0]);
                mode = OperandMode.DEF;
            }
        }
    }
    /*
         * Get current location of operand. The operand must be live because debug information is
         * considered when building the intervals if the interval is not live, colorLirOperand will
         * cause an assert on failure.
         */
    Value result = colorLirOperand(op, (Variable) operand, mode);
    assert !allocator.hasCall(tempOpId) || isStackSlotValue(result) || isJavaConstant(result) || !allocator.isCallerSave(result) : "cannot have caller-save register operands at calls";
    return result;
}
Also used : LIRInstruction(org.graalvm.compiler.lir.LIRInstruction) LIRValueUtil.isStackSlotValue(org.graalvm.compiler.lir.LIRValueUtil.isStackSlotValue) ConstantValue(org.graalvm.compiler.lir.ConstantValue) Value(jdk.vm.ci.meta.Value) AllocatableValue(jdk.vm.ci.meta.AllocatableValue) OperandMode(org.graalvm.compiler.lir.LIRInstruction.OperandMode)

Aggregations

Value (jdk.vm.ci.meta.Value)10 OperandMode (org.graalvm.compiler.lir.LIRInstruction.OperandMode)10 EnumSet (java.util.EnumSet)8 LIRInstruction (org.graalvm.compiler.lir.LIRInstruction)7 Register (jdk.vm.ci.code.Register)4 OperandFlag (org.graalvm.compiler.lir.LIRInstruction.OperandFlag)4 ValueConsumer (org.graalvm.compiler.lir.ValueConsumer)4 ValueUtil.asRegister (jdk.vm.ci.code.ValueUtil.asRegister)3 ValueUtil.isRegister (jdk.vm.ci.code.ValueUtil.isRegister)3 DebugContext (org.graalvm.compiler.debug.DebugContext)3 InstructionValueConsumer (org.graalvm.compiler.lir.InstructionValueConsumer)3 ArrayList (java.util.ArrayList)2 BitSet (java.util.BitSet)2 AllocatableValue (jdk.vm.ci.meta.AllocatableValue)2 AbstractBlockBase (org.graalvm.compiler.core.common.cfg.AbstractBlockBase)2 BlockMap (org.graalvm.compiler.core.common.cfg.BlockMap)2 GraalError (org.graalvm.compiler.debug.GraalError)2 Indent (org.graalvm.compiler.debug.Indent)2 LIRValueUtil.isStackSlotValue (org.graalvm.compiler.lir.LIRValueUtil.isStackSlotValue)2 LabelOp (org.graalvm.compiler.lir.StandardOp.LabelOp)2