Search in sources :

Example 31 with AllocatableValue

use of jdk.vm.ci.meta.AllocatableValue 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 32 with AllocatableValue

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

the class TraceRegisterAllocationPhase method run.

@Override
@SuppressWarnings("try")
protected void run(TargetDescription target, LIRGenerationResult lirGenRes, AllocationContext context) {
    MoveFactory spillMoveFactory = context.spillMoveFactory;
    RegisterAllocationConfig registerAllocationConfig = context.registerAllocationConfig;
    LIR lir = lirGenRes.getLIR();
    DebugContext debug = lir.getDebug();
    TraceBuilderResult resultTraces = context.contextLookup(TraceBuilderResult.class);
    GlobalLivenessInfo livenessInfo = context.contextLookup(GlobalLivenessInfo.class);
    assert livenessInfo != null;
    TraceAllocationContext traceContext = new TraceAllocationContext(spillMoveFactory, registerAllocationConfig, resultTraces, livenessInfo);
    AllocatableValue[] cachedStackSlots = Options.TraceRACacheStackSlots.getValue(lir.getOptions()) ? new AllocatableValue[lir.numVariables()] : null;
    // currently this is not supported
    boolean neverSpillConstant = false;
    final TraceRegisterAllocationPolicy plan = DefaultTraceRegisterAllocationPolicy.allocationPolicy(target, lirGenRes, spillMoveFactory, registerAllocationConfig, cachedStackSlots, resultTraces, neverSpillConstant, livenessInfo, lir.getOptions());
    try (DebugContext.Scope s0 = debug.scope("AllocateTraces", resultTraces, livenessInfo)) {
        for (Trace trace : resultTraces.getTraces()) {
            tracesCounter.increment(debug);
            TraceAllocationPhase<TraceAllocationContext> allocator = plan.selectStrategy(trace);
            try (Indent i = debug.logAndIndent("Allocating Trace%d: %s (%s)", trace.getId(), trace, allocator);
                DebugContext.Scope s = debug.scope("AllocateTrace", trace)) {
                allocator.apply(target, lirGenRes, trace, traceContext);
            }
        }
    } catch (Throwable e) {
        throw debug.handle(e);
    }
    TraceGlobalMoveResolutionPhase.resolve(target, lirGenRes, traceContext);
    deconstructSSAForm(lir);
}
Also used : Indent(org.graalvm.compiler.debug.Indent) DebugContext(org.graalvm.compiler.debug.DebugContext) TraceAllocationContext(org.graalvm.compiler.lir.alloc.trace.TraceAllocationPhase.TraceAllocationContext) AllocatableValue(jdk.vm.ci.meta.AllocatableValue) Trace(org.graalvm.compiler.core.common.alloc.Trace) LIR(org.graalvm.compiler.lir.LIR) RegisterAllocationConfig(org.graalvm.compiler.core.common.alloc.RegisterAllocationConfig) TraceBuilderResult(org.graalvm.compiler.core.common.alloc.TraceBuilderResult) MoveFactory(org.graalvm.compiler.lir.gen.LIRGeneratorTool.MoveFactory)

Example 33 with AllocatableValue

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

the class BottomUpAllocator method allocateSpillSlot.

/**
 * Returns a new spill slot or a cached entry if there is already one for the variable.
 */
private AllocatableValue allocateSpillSlot(Variable var) {
    int variableIndex = var.index;
    AllocatableValue cachedStackSlot = stackSlots[variableIndex];
    if (cachedStackSlot != null) {
        TraceRegisterAllocationPhase.globalStackSlots.increment(debug);
        assert cachedStackSlot.getValueKind().equals(var.getValueKind()) : "CachedStackSlot: kind mismatch? " + var.getValueKind() + " vs. " + cachedStackSlot.getValueKind();
        return cachedStackSlot;
    }
    VirtualStackSlot slot = lirGenRes.getFrameMapBuilder().allocateSpillSlot(var.getValueKind());
    stackSlots[variableIndex] = slot;
    TraceRegisterAllocationPhase.allocatedStackSlots.increment(debug);
    return slot;
}
Also used : ValueUtil.asAllocatableValue(jdk.vm.ci.code.ValueUtil.asAllocatableValue) AllocatableValue(jdk.vm.ci.meta.AllocatableValue) VirtualStackSlot(org.graalvm.compiler.lir.VirtualStackSlot)

Example 34 with AllocatableValue

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

the class SubstrateAMD64RegisterConfig method getCallingConvention.

@Override
public CallingConvention getCallingConvention(Type t, JavaType returnType, JavaType[] parameterTypes, ValueKindFactory<?> valueKindFactory) {
    SubstrateCallingConventionType type = (SubstrateCallingConventionType) t;
    boolean isEntryPoint = type.nativeABI && !type.outgoing;
    AllocatableValue[] locations = new AllocatableValue[parameterTypes.length];
    int currentGeneral = 0;
    int currentXMM = 0;
    /*
         * We have to reserve a slot between return address and outgoing parameters for the deopt
         * frame handle. Exception: calls to native methods.
         */
    int currentStackOffset = (type.nativeABI ? 0 : target.wordSize);
    JavaKind[] kinds = new JavaKind[locations.length];
    for (int i = 0; i < parameterTypes.length; i++) {
        JavaKind kind = ObjectLayout.getCallSignatureKind(isEntryPoint, (ResolvedJavaType) parameterTypes[i], metaAccess, target);
        kinds[i] = kind;
        switch(kind) {
            case Byte:
            case Boolean:
            case Short:
            case Char:
            case Int:
            case Long:
            case Object:
                if (currentGeneral < generalParameterRegs.size()) {
                    Register register = generalParameterRegs.get(currentGeneral++);
                    locations[i] = register.asValue(valueKindFactory.getValueKind(kind.getStackKind()));
                }
                break;
            case Float:
            case Double:
                if (currentXMM < xmmParameterRegs.size()) {
                    Register register = xmmParameterRegs.get(currentXMM++);
                    locations[i] = register.asValue(valueKindFactory.getValueKind(kind));
                }
                break;
            default:
                throw shouldNotReachHere();
        }
        if (locations[i] == null) {
            ValueKind<?> valueKind = valueKindFactory.getValueKind(kind.getStackKind());
            locations[i] = StackSlot.get(valueKind, currentStackOffset, !type.outgoing);
            currentStackOffset += Math.max(valueKind.getPlatformKind().getSizeInBytes(), target.wordSize);
        }
    }
    JavaKind returnKind = returnType == null ? JavaKind.Void : ObjectLayout.getCallSignatureKind(isEntryPoint, (ResolvedJavaType) returnType, metaAccess, target);
    AllocatableValue returnLocation = returnKind == JavaKind.Void ? Value.ILLEGAL : getReturnRegister(returnKind).asValue(valueKindFactory.getValueKind(returnKind.getStackKind()));
    return new SubstrateCallingConvention(type, kinds, currentStackOffset, returnLocation, locations);
}
Also used : Register(jdk.vm.ci.code.Register) AllocatableValue(jdk.vm.ci.meta.AllocatableValue) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) JavaKind(jdk.vm.ci.meta.JavaKind)

Example 35 with AllocatableValue

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

the class LIRGenerator method emitForeignCall.

@Override
public Variable emitForeignCall(ForeignCallLinkage linkage, LIRFrameState frameState, Value... args) {
    LIRFrameState state = null;
    if (linkage.needsDebugInfo()) {
        if (frameState != null) {
            state = frameState;
        } else {
            assert needOnlyOopMaps();
            state = new LIRFrameState(null, null, null);
        }
    }
    // move the arguments into the correct location
    CallingConvention linkageCc = linkage.getOutgoingCallingConvention();
    res.getFrameMapBuilder().callsMethod(linkageCc);
    assert linkageCc.getArgumentCount() == args.length : "argument count mismatch";
    Value[] argLocations = new Value[args.length];
    for (int i = 0; i < args.length; i++) {
        Value arg = args[i];
        AllocatableValue loc = linkageCc.getArgument(i);
        emitMove(loc, arg);
        argLocations[i] = loc;
    }
    res.setForeignCall(true);
    emitForeignCallOp(linkage, linkageCc.getReturn(), argLocations, linkage.getTemporaries(), state);
    if (isLegal(linkageCc.getReturn())) {
        return emitMove(linkageCc.getReturn());
    } else {
        return null;
    }
}
Also used : CallingConvention(jdk.vm.ci.code.CallingConvention) LIRFrameState(org.graalvm.compiler.lir.LIRFrameState) ConstantValue(org.graalvm.compiler.lir.ConstantValue) LIRValueUtil.isConstantValue(org.graalvm.compiler.lir.LIRValueUtil.isConstantValue) ValueUtil.asAllocatableValue(jdk.vm.ci.code.ValueUtil.asAllocatableValue) Value(jdk.vm.ci.meta.Value) ValueUtil.isAllocatableValue(jdk.vm.ci.code.ValueUtil.isAllocatableValue) AllocatableValue(jdk.vm.ci.meta.AllocatableValue) ValueUtil.asAllocatableValue(jdk.vm.ci.code.ValueUtil.asAllocatableValue) ValueUtil.isAllocatableValue(jdk.vm.ci.code.ValueUtil.isAllocatableValue) 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