Search in sources :

Example 16 with LIRInstruction

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

the class TraceGlobalMoveResolver method resolveMappings.

@SuppressWarnings("try")
private void resolveMappings() {
    try (Indent indent = debug.logAndIndent("resolveMapping")) {
        assert verifyBeforeResolve();
        if (debug.isLogEnabled()) {
            printMapping();
        }
        // This is necessary for detecting cycles in moves.
        for (int i = mappingFrom.size() - 1; i >= 0; i--) {
            Value from = mappingFrom.get(i);
            block(from);
        }
        ArrayList<AllocatableValue> busySpillSlots = null;
        while (mappingFrom.size() > 0) {
            boolean processedInterval = false;
            int spillCandidate = -1;
            for (int i = mappingFrom.size() - 1; i >= 0; i--) {
                Value fromLocation = mappingFrom.get(i);
                AllocatableValue toLocation = mappingTo.get(i);
                if (safeToProcessMove(fromLocation, toLocation)) {
                    // this interval can be processed because target is free
                    LIRInstruction move = insertMove(fromLocation, toLocation);
                    move.setComment(res, "TraceGlobalMoveResolver: resolveMapping");
                    unblock(fromLocation);
                    if (isStackSlotValue(toLocation)) {
                        if (busySpillSlots == null) {
                            busySpillSlots = new ArrayList<>(2);
                        }
                        busySpillSlots.add(toLocation);
                    }
                    mappingFrom.remove(i);
                    mappingFromStack.remove(i);
                    mappingTo.remove(i);
                    processedInterval = true;
                } else if (fromLocation != null) {
                    if (isRegister(fromLocation) && (busySpillSlots == null || !busySpillSlots.contains(mappingFromStack.get(i)))) {
                        // this interval cannot be processed now because target is not free
                        // it starts in a register, so it is a possible candidate for spilling
                        spillCandidate = i;
                    } else if (isStackSlotValue(fromLocation) && spillCandidate == -1) {
                        // fall back to spill a stack slot in case no other candidate is found
                        spillCandidate = i;
                    }
                }
            }
            if (!processedInterval) {
                breakCycle(spillCandidate);
            }
        }
    }
    // check that all intervals have been processed
    assert checkEmpty();
}
Also used : Indent(org.graalvm.compiler.debug.Indent) LIRInstruction(org.graalvm.compiler.lir.LIRInstruction) LIRValueUtil.isStackSlotValue(org.graalvm.compiler.lir.LIRValueUtil.isStackSlotValue) TraceUtil.isShadowedRegisterValue(org.graalvm.compiler.lir.alloc.trace.TraceUtil.isShadowedRegisterValue) TraceUtil.asShadowedRegisterValue(org.graalvm.compiler.lir.alloc.trace.TraceUtil.asShadowedRegisterValue) ValueUtil.asAllocatableValue(jdk.vm.ci.code.ValueUtil.asAllocatableValue) Value(jdk.vm.ci.meta.Value) AllocatableValue(jdk.vm.ci.meta.AllocatableValue) ValueUtil.asAllocatableValue(jdk.vm.ci.code.ValueUtil.asAllocatableValue) AllocatableValue(jdk.vm.ci.meta.AllocatableValue)

Example 17 with LIRInstruction

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

the class BottomUpAllocator method resolveFindInsertPos.

private void resolveFindInsertPos(AbstractBlockBase<?> fromBlock, AbstractBlockBase<?> toBlock) {
    LIR lir = lirGenRes.getLIR();
    if (fromBlock.getSuccessorCount() <= 1) {
        if (debug.isLogEnabled()) {
            debug.log("inserting moves at end of fromBlock B%d", fromBlock.getId());
        }
        ArrayList<LIRInstruction> instructions = lir.getLIRforBlock(fromBlock);
        LIRInstruction instr = instructions.get(instructions.size() - 1);
        if (instr instanceof StandardOp.JumpOp) {
            // insert moves before branch
            moveResolver.setInsertPosition(instructions, instructions.size() - 1);
        } else {
            moveResolver.setInsertPosition(instructions, instructions.size());
        }
    } else {
        if (debug.isLogEnabled()) {
            debug.log("inserting moves at beginning of toBlock B%d", toBlock.getId());
        }
        if (Assertions.detailedAssertionsEnabled(getLIR().getOptions())) {
            assert lir.getLIRforBlock(fromBlock).get(0) instanceof StandardOp.LabelOp : "block does not start with a label";
            /*
                 * Because the number of predecessor edges matches the number of successor edges,
                 * blocks which are reached by switch statements may have be more than one
                 * predecessor but it will be guaranteed that all predecessors will be the same.
                 */
            for (AbstractBlockBase<?> predecessor : toBlock.getPredecessors()) {
                assert fromBlock == predecessor : "all critical edges must be broken";
            }
        }
        moveResolver.setInsertPosition(lir.getLIRforBlock(toBlock), 1);
    }
}
Also used : LabelOp(org.graalvm.compiler.lir.StandardOp.LabelOp) LIR(org.graalvm.compiler.lir.LIR) JumpOp(org.graalvm.compiler.lir.StandardOp.JumpOp) LIRInstruction(org.graalvm.compiler.lir.LIRInstruction)

Example 18 with LIRInstruction

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

the class UseEntry method replaceValue.

private static void replaceValue(LIRInstruction op, Value oldValue, Value newValue) {
    ValueProcedure proc = (value, mode, flags) -> value.identityEquals(oldValue) ? newValue : value;
    op.forEachAlive(proc);
    op.forEachInput(proc);
    op.forEachOutput(proc);
    op.forEachTemp(proc);
    op.forEachState(proc);
}
Also used : ValueProcedure(org.graalvm.compiler.lir.ValueProcedure) AbstractBlockBase(org.graalvm.compiler.core.common.cfg.AbstractBlockBase) Value(jdk.vm.ci.meta.Value) ValueProcedure(org.graalvm.compiler.lir.ValueProcedure) LIRInstruction(org.graalvm.compiler.lir.LIRInstruction)

Example 19 with LIRInstruction

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

the class SaveCalleeSaveRegisters method restoreAtExit.

private static void restoreAtExit(LIR lir, LIRGeneratorTool.MoveFactory moveFactory, LIRGenerationResult lirGenRes, RegisterMap<Variable> calleeSaveRegisters, AbstractBlockBase<?> block) {
    ArrayList<LIRInstruction> instructions = lir.getLIRforBlock(block);
    int insertionIndex = instructions.size() - 1;
    LIRInsertionBuffer buffer = new LIRInsertionBuffer();
    buffer.init(instructions);
    assert instructions.get(insertionIndex) instanceof StandardOp.BlockEndOp;
    calleeSaveRegisters.forEach((Register register, Variable saved) -> {
        LIRInstruction restore = moveFactory.createMove(register.asValue(saved.getValueKind()), saved);
        buffer.append(insertionIndex, restore);
        restore.setComment(lirGenRes, "SaveCalleeSavedRegisters: restoreAtExit");
    });
    buffer.finish();
}
Also used : LIRInsertionBuffer(org.graalvm.compiler.lir.LIRInsertionBuffer) Variable(org.graalvm.compiler.lir.Variable) Register(jdk.vm.ci.code.Register) LIRInstruction(org.graalvm.compiler.lir.LIRInstruction)

Example 20 with LIRInstruction

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

the class SaveCalleeSaveRegisters method saveAtEntry.

private static RegisterMap<Variable> saveAtEntry(LIR lir, LIRGeneratorTool lirGen, LIRGenerationResult lirGenRes, RegisterArray calleeSaveRegisters, Architecture arch) {
    AbstractBlockBase<?> startBlock = lir.getControlFlowGraph().getStartBlock();
    ArrayList<LIRInstruction> instructions = lir.getLIRforBlock(startBlock);
    int insertionIndex = 1;
    LIRInsertionBuffer buffer = new LIRInsertionBuffer();
    buffer.init(instructions);
    StandardOp.LabelOp entry = (StandardOp.LabelOp) instructions.get(insertionIndex - 1);
    RegisterValue[] savedRegisterValues = new RegisterValue[calleeSaveRegisters.size()];
    int savedRegisterValueIndex = 0;
    RegisterMap<Variable> saveMap = new RegisterMap<>(arch);
    for (Register register : calleeSaveRegisters) {
        PlatformKind registerPlatformKind = arch.getLargestStorableKind(register.getRegisterCategory());
        LIRKind lirKind = LIRKind.value(registerPlatformKind);
        RegisterValue registerValue = register.asValue(lirKind);
        Variable saveVariable = lirGen.newVariable(lirKind);
        LIRInstruction save = lirGen.getSpillMoveFactory().createMove(saveVariable, registerValue);
        buffer.append(insertionIndex, save);
        save.setComment(lirGenRes, "SaveCalleeSavedRegisters: saveAtEntry");
        saveMap.put(register, saveVariable);
        savedRegisterValues[savedRegisterValueIndex++] = registerValue;
    }
    entry.addIncomingValues(savedRegisterValues);
    buffer.finish();
    return saveMap;
}
Also used : Variable(org.graalvm.compiler.lir.Variable) LIRInstruction(org.graalvm.compiler.lir.LIRInstruction) PlatformKind(jdk.vm.ci.meta.PlatformKind) RegisterValue(jdk.vm.ci.code.RegisterValue) LIRInsertionBuffer(org.graalvm.compiler.lir.LIRInsertionBuffer) Register(jdk.vm.ci.code.Register) RegisterMap(org.graalvm.compiler.lir.util.RegisterMap) LIRKind(org.graalvm.compiler.core.common.LIRKind) StandardOp(org.graalvm.compiler.lir.StandardOp)

Aggregations

LIRInstruction (org.graalvm.compiler.lir.LIRInstruction)55 DebugContext (org.graalvm.compiler.debug.DebugContext)25 Indent (org.graalvm.compiler.debug.Indent)19 AllocatableValue (jdk.vm.ci.meta.AllocatableValue)15 Value (jdk.vm.ci.meta.Value)15 OperandMode (org.graalvm.compiler.lir.LIRInstruction.OperandMode)10 EnumSet (java.util.EnumSet)8 Register (jdk.vm.ci.code.Register)8 AbstractBlockBase (org.graalvm.compiler.core.common.cfg.AbstractBlockBase)8 OperandFlag (org.graalvm.compiler.lir.LIRInstruction.OperandFlag)7 BitSet (java.util.BitSet)6 GraalError (org.graalvm.compiler.debug.GraalError)6 InstructionValueConsumer (org.graalvm.compiler.lir.InstructionValueConsumer)6 LIR (org.graalvm.compiler.lir.LIR)6 LIRInsertionBuffer (org.graalvm.compiler.lir.LIRInsertionBuffer)6 ValueConsumer (org.graalvm.compiler.lir.ValueConsumer)6 ArrayList (java.util.ArrayList)5 ValueUtil.asRegister (jdk.vm.ci.code.ValueUtil.asRegister)5 ValueUtil.isRegister (jdk.vm.ci.code.ValueUtil.isRegister)5 LoadConstantOp (org.graalvm.compiler.lir.StandardOp.LoadConstantOp)5