Search in sources :

Example 26 with AllocatableValue

use of jdk.vm.ci.meta.AllocatableValue in project graal by oracle.

the class LinearScanIntervalDumper method printInterval.

private static void printInterval(Interval interval, IntervalVisitor visitor) {
    Value hint = interval.locationHint(false) != null ? interval.locationHint(false).operand : null;
    AllocatableValue operand = interval.operand;
    String type = isRegister(operand) ? "fixed" : operand.getValueKind().getPlatformKind().toString();
    visitor.visitIntervalStart(interval.splitParent().operand, operand, interval.location(), hint, type);
    // print ranges
    Range cur = interval.first();
    while (!cur.isEndMarker()) {
        visitor.visitRange(cur.from, cur.to);
        cur = cur.next;
        assert cur != null : "range list not closed with range sentinel";
    }
    // print use positions
    int prev = -1;
    UsePosList usePosList = interval.usePosList();
    for (int i = usePosList.size() - 1; i >= 0; --i) {
        assert prev < usePosList.usePos(i) : "use positions not sorted";
        visitor.visitUsePos(usePosList.usePos(i), usePosList.registerPriority(i));
        prev = usePosList.usePos(i);
    }
    visitor.visitIntervalEnd(interval.spillState());
}
Also used : UsePosList(org.graalvm.compiler.lir.alloc.lsra.Interval.UsePosList) Value(jdk.vm.ci.meta.Value) AllocatableValue(jdk.vm.ci.meta.AllocatableValue) AllocatableValue(jdk.vm.ci.meta.AllocatableValue)

Example 27 with AllocatableValue

use of jdk.vm.ci.meta.AllocatableValue in project graal by oracle.

the class LinearScanOptimizeSpillPositionPhase method optimizeInterval.

@SuppressWarnings("try")
private void optimizeInterval(LIRInsertionBuffer[] insertionBuffers, Interval interval, LIRGenerationResult res) {
    if (interval == null || !interval.isSplitParent() || interval.spillState() != SpillState.SpillInDominator) {
        return;
    }
    AbstractBlockBase<?> defBlock = allocator.blockForId(interval.spillDefinitionPos());
    AbstractBlockBase<?> spillBlock = null;
    Interval firstSpillChild = null;
    try (Indent indent = debug.logAndIndent("interval %s (%s)", interval, defBlock)) {
        for (Interval splitChild : interval.getSplitChildren()) {
            if (isStackSlotValue(splitChild.location())) {
                if (firstSpillChild == null || splitChild.from() < firstSpillChild.from()) {
                    firstSpillChild = splitChild;
                } else {
                    assert firstSpillChild.from() < splitChild.from();
                }
                // iterate all blocks where the interval has use positions
                for (AbstractBlockBase<?> splitBlock : blocksForInterval(splitChild)) {
                    if (dominates(defBlock, splitBlock)) {
                        debug.log("Split interval %s, block %s", splitChild, splitBlock);
                        if (spillBlock == null) {
                            spillBlock = splitBlock;
                        } else {
                            spillBlock = commonDominator(spillBlock, splitBlock);
                            assert spillBlock != null;
                        }
                    }
                }
            }
        }
        if (spillBlock == null) {
            debug.log("not spill interval found");
            // no spill interval
            interval.setSpillState(SpillState.StoreAtDefinition);
            return;
        }
        debug.log(DebugContext.VERBOSE_LEVEL, "Spill block candidate (initial): %s", spillBlock);
        // move out of loops
        if (defBlock.getLoopDepth() < spillBlock.getLoopDepth()) {
            spillBlock = moveSpillOutOfLoop(defBlock, spillBlock);
        }
        debug.log(DebugContext.VERBOSE_LEVEL, "Spill block candidate (after loop optimizaton): %s", spillBlock);
        /*
             * The spill block is the begin of the first split child (aka the value is on the
             * stack).
             *
             * The problem is that if spill block has more than one predecessor, the values at the
             * end of the predecessors might differ. Therefore, we would need a spill move in all
             * predecessors. To avoid this we spill in the dominator.
             */
        assert firstSpillChild != null;
        if (!defBlock.equals(spillBlock) && spillBlock.equals(allocator.blockForId(firstSpillChild.from()))) {
            AbstractBlockBase<?> dom = spillBlock.getDominator();
            if (debug.isLogEnabled()) {
                debug.log("Spill block (%s) is the beginning of a spill child -> use dominator (%s)", spillBlock, dom);
            }
            spillBlock = dom;
        }
        if (defBlock.equals(spillBlock)) {
            debug.log(DebugContext.VERBOSE_LEVEL, "Definition is the best choice: %s", defBlock);
            // definition is the best choice
            interval.setSpillState(SpillState.StoreAtDefinition);
            return;
        }
        assert dominates(defBlock, spillBlock);
        betterSpillPos.increment(debug);
        if (debug.isLogEnabled()) {
            debug.log("Better spill position found (Block %s)", spillBlock);
        }
        if (defBlock.probability() <= spillBlock.probability()) {
            debug.log(DebugContext.VERBOSE_LEVEL, "Definition has lower probability %s (%f) is lower than spill block %s (%f)", defBlock, defBlock.probability(), spillBlock, spillBlock.probability());
            // better spill block has the same probability -> do nothing
            interval.setSpillState(SpillState.StoreAtDefinition);
            return;
        }
        LIRInsertionBuffer insertionBuffer = insertionBuffers[spillBlock.getId()];
        if (insertionBuffer == null) {
            insertionBuffer = new LIRInsertionBuffer();
            insertionBuffers[spillBlock.getId()] = insertionBuffer;
            insertionBuffer.init(allocator.getLIR().getLIRforBlock(spillBlock));
        }
        int spillOpId = allocator.getFirstLirInstructionId(spillBlock);
        // insert spill move
        AllocatableValue fromLocation = interval.getSplitChildAtOpId(spillOpId, OperandMode.DEF, allocator).location();
        AllocatableValue toLocation = LinearScan.canonicalSpillOpr(interval);
        LIRInstruction move = allocator.getSpillMoveFactory().createMove(toLocation, fromLocation);
        move.setComment(res, "LSRAOptimizeSpillPos: optimize spill pos");
        debug.log(DebugContext.VERBOSE_LEVEL, "Insert spill move %s", move);
        move.setId(LinearScan.DOMINATOR_SPILL_MOVE_ID);
        /*
             * We can use the insertion buffer directly because we always insert at position 1.
             */
        insertionBuffer.append(1, move);
        betterSpillPosWithLowerProbability.increment(debug);
        interval.setSpillDefinitionPos(spillOpId);
    }
}
Also used : Indent(org.graalvm.compiler.debug.Indent) LIRInsertionBuffer(org.graalvm.compiler.lir.LIRInsertionBuffer) LIRInstruction(org.graalvm.compiler.lir.LIRInstruction) AllocatableValue(jdk.vm.ci.meta.AllocatableValue)

Example 28 with AllocatableValue

use of jdk.vm.ci.meta.AllocatableValue in project graal by oracle.

the class ShadowedRegisterValue method forEachComponent.

@Override
public CompositeValue forEachComponent(LIRInstruction inst, OperandMode mode, InstructionValueProcedure proc) {
    RegisterValue newRegister = (RegisterValue) proc.doValue(inst, register, mode, registerFlags);
    AllocatableValue newStackSlot = (AllocatableValue) proc.doValue(inst, stackslot, mode, stackslotFlags);
    if (register.equals(newRegister) || stackslot.equals(newStackSlot)) {
        return this;
    }
    return new ShadowedRegisterValue(newRegister, newStackSlot);
}
Also used : RegisterValue(jdk.vm.ci.code.RegisterValue) AllocatableValue(jdk.vm.ci.meta.AllocatableValue)

Example 29 with AllocatableValue

use of jdk.vm.ci.meta.AllocatableValue in project graal by oracle.

the class TraceGlobalMoveResolutionPhase method addMappingToRegister.

private static void addMappingToRegister(MoveResolver moveResolver, Value from, RegisterValue register) {
    if (isShadowedRegisterValue(from)) {
        RegisterValue fromReg = asShadowedRegisterValue(from).getRegister();
        AllocatableValue fromStack = asShadowedRegisterValue(from).getStackSlot();
        checkAndAddMapping(moveResolver, fromReg, register, fromStack);
    } else {
        checkAndAddMapping(moveResolver, from, register, null);
    }
}
Also used : TraceUtil.isShadowedRegisterValue(org.graalvm.compiler.lir.alloc.trace.TraceUtil.isShadowedRegisterValue) TraceUtil.asShadowedRegisterValue(org.graalvm.compiler.lir.alloc.trace.TraceUtil.asShadowedRegisterValue) RegisterValue(jdk.vm.ci.code.RegisterValue) ValueUtil.asRegisterValue(jdk.vm.ci.code.ValueUtil.asRegisterValue) AllocatableValue(jdk.vm.ci.meta.AllocatableValue)

Example 30 with AllocatableValue

use of jdk.vm.ci.meta.AllocatableValue in project graal by oracle.

the class TraceGlobalMoveResolutionPhase method addMappingToStackSlot.

private static void addMappingToStackSlot(MoveResolver moveResolver, Value from, AllocatableValue stack) {
    if (isShadowedRegisterValue(from)) {
        ShadowedRegisterValue shadowedFrom = asShadowedRegisterValue(from);
        RegisterValue fromReg = shadowedFrom.getRegister();
        AllocatableValue fromStack = shadowedFrom.getStackSlot();
        if (!fromStack.equals(stack)) {
            checkAndAddMapping(moveResolver, fromReg, stack, fromStack);
        }
    } else {
        checkAndAddMapping(moveResolver, from, stack, null);
    }
}
Also used : TraceUtil.isShadowedRegisterValue(org.graalvm.compiler.lir.alloc.trace.TraceUtil.isShadowedRegisterValue) TraceUtil.asShadowedRegisterValue(org.graalvm.compiler.lir.alloc.trace.TraceUtil.asShadowedRegisterValue) RegisterValue(jdk.vm.ci.code.RegisterValue) ValueUtil.asRegisterValue(jdk.vm.ci.code.ValueUtil.asRegisterValue) TraceUtil.isShadowedRegisterValue(org.graalvm.compiler.lir.alloc.trace.TraceUtil.isShadowedRegisterValue) TraceUtil.asShadowedRegisterValue(org.graalvm.compiler.lir.alloc.trace.TraceUtil.asShadowedRegisterValue) AllocatableValue(jdk.vm.ci.meta.AllocatableValue)

Aggregations

AllocatableValue (jdk.vm.ci.meta.AllocatableValue)87 Value (jdk.vm.ci.meta.Value)22 Variable (org.graalvm.compiler.lir.Variable)20 LIRKind (org.graalvm.compiler.core.common.LIRKind)13 LIRInstruction (org.graalvm.compiler.lir.LIRInstruction)11 Indent (org.graalvm.compiler.debug.Indent)10 RegisterValue (jdk.vm.ci.code.RegisterValue)9 ValueUtil.asAllocatableValue (jdk.vm.ci.code.ValueUtil.asAllocatableValue)8 DebugContext (org.graalvm.compiler.debug.DebugContext)8 Register (jdk.vm.ci.code.Register)6 JavaConstant (jdk.vm.ci.meta.JavaConstant)6 AMD64MathIntrinsicUnaryOp (org.graalvm.compiler.lir.amd64.AMD64MathIntrinsicUnaryOp)5 LIRValueUtil.asJavaConstant (org.graalvm.compiler.lir.LIRValueUtil.asJavaConstant)4 LIRValueUtil.isJavaConstant (org.graalvm.compiler.lir.LIRValueUtil.isJavaConstant)4 ValueMoveOp (org.graalvm.compiler.lir.StandardOp.ValueMoveOp)4 ArithmeticLIRGenerator (org.graalvm.compiler.lir.gen.ArithmeticLIRGenerator)4 LIRGenerator (org.graalvm.compiler.lir.gen.LIRGenerator)4 SPARCAddressValue (org.graalvm.compiler.lir.sparc.SPARCAddressValue)4 AMD64Kind (jdk.vm.ci.amd64.AMD64Kind)3 ValueUtil.isAllocatableValue (jdk.vm.ci.code.ValueUtil.isAllocatableValue)3