Search in sources :

Example 11 with BciBlock

use of org.graalvm.compiler.java.BciBlockMapping.BciBlock in project graal by oracle.

the class BytecodeParser method genRet.

protected void genRet(int localIndex) {
    BciBlock successor = currentBlock.getRetSuccessor();
    ValueNode local = frameState.loadLocal(localIndex, JavaKind.Object);
    JsrScope scope = currentBlock.getJsrScope();
    int retAddress = scope.nextReturnAddress();
    ConstantNode returnBciNode = getJsrConstant(retAddress);
    LogicNode guard = IntegerEqualsNode.create(constantReflection, metaAccess, options, null, local, returnBciNode, NodeView.DEFAULT);
    guard = graph.addOrUniqueWithInputs(guard);
    append(new FixedGuardNode(guard, JavaSubroutineMismatch, InvalidateReprofile));
    if (!successor.getJsrScope().equals(scope.pop())) {
        throw new JsrNotSupportedBailout("unstructured control flow (ret leaves more than one scope)");
    }
    appendGoto(successor);
}
Also used : FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) LogicConstantNode(org.graalvm.compiler.nodes.LogicConstantNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) BciBlock(org.graalvm.compiler.java.BciBlockMapping.BciBlock) RuntimeConstraint(jdk.vm.ci.meta.DeoptimizationReason.RuntimeConstraint)

Example 12 with BciBlock

use of org.graalvm.compiler.java.BciBlockMapping.BciBlock in project graal by oracle.

the class BytecodeParser method genSwitch.

private void genSwitch(BytecodeSwitch bs) {
    int bci = bci();
    ValueNode value = frameState.pop(JavaKind.Int);
    int nofCases = bs.numberOfCases();
    int nofCasesPlusDefault = nofCases + 1;
    double[] keyProbabilities = switchProbability(nofCasesPlusDefault, bci);
    EconomicMap<Integer, SuccessorInfo> bciToBlockSuccessorIndex = EconomicMap.create(Equivalence.DEFAULT);
    for (int i = 0; i < currentBlock.getSuccessorCount(); i++) {
        assert !bciToBlockSuccessorIndex.containsKey(currentBlock.getSuccessor(i).startBci);
        bciToBlockSuccessorIndex.put(currentBlock.getSuccessor(i).startBci, new SuccessorInfo(i));
    }
    ArrayList<BciBlock> actualSuccessors = new ArrayList<>();
    int[] keys = new int[nofCases];
    int[] keySuccessors = new int[nofCasesPlusDefault];
    int deoptSuccessorIndex = -1;
    int nextSuccessorIndex = 0;
    boolean constantValue = value.isConstant();
    for (int i = 0; i < nofCasesPlusDefault; i++) {
        if (i < nofCases) {
            keys[i] = bs.keyAt(i);
        }
        if (!constantValue && isNeverExecutedCode(keyProbabilities[i])) {
            if (deoptSuccessorIndex < 0) {
                deoptSuccessorIndex = nextSuccessorIndex++;
                actualSuccessors.add(null);
            }
            keySuccessors[i] = deoptSuccessorIndex;
        } else {
            int targetBci = i < nofCases ? bs.targetAt(i) : bs.defaultTarget();
            SuccessorInfo info = bciToBlockSuccessorIndex.get(targetBci);
            if (info.actualIndex < 0) {
                info.actualIndex = nextSuccessorIndex++;
                actualSuccessors.add(currentBlock.getSuccessor(info.blockIndex));
            }
            keySuccessors[i] = info.actualIndex;
        }
    }
    /*
         * When the profile indicates a case is never taken, the above code will cause the case to
         * deopt should it be subsequently encountered. However, the case may share code with
         * another case that is taken according to the profile.
         *
         * For example:
         * // @formatter:off
         * switch (opcode) {
         *     case GOTO:
         *     case GOTO_W: {
         *         // emit goto code
         *         break;
         *     }
         * }
         * // @formatter:on
         *
         * The profile may indicate the GOTO_W case is never taken, and thus a deoptimization stub
         * will be emitted. There might be optimization opportunity if additional branching based
         * on opcode is within the case block. Specially, if there is only single case that
         * reaches a target, we have better chance cutting out unused branches. Otherwise,
         * it might be beneficial routing to the same code instead of deopting.
         *
         * The following code rewires deoptimization stub to existing resolved branch target if
         * the target is connected by more than 1 cases.
         */
    if (deoptSuccessorIndex >= 0) {
        int[] connectedCases = new int[nextSuccessorIndex];
        for (int i = 0; i < nofCasesPlusDefault; i++) {
            connectedCases[keySuccessors[i]]++;
        }
        for (int i = 0; i < nofCasesPlusDefault; i++) {
            if (keySuccessors[i] == deoptSuccessorIndex) {
                int targetBci = i < nofCases ? bs.targetAt(i) : bs.defaultTarget();
                SuccessorInfo info = bciToBlockSuccessorIndex.get(targetBci);
                int rewiredIndex = info.actualIndex;
                if (rewiredIndex >= 0 && connectedCases[rewiredIndex] > 1) {
                    keySuccessors[i] = info.actualIndex;
                }
            }
        }
    }
    genIntegerSwitch(value, actualSuccessors, keys, keyProbabilities, keySuccessors);
}
Also used : ValueNode(org.graalvm.compiler.nodes.ValueNode) ArrayList(java.util.ArrayList) BciBlock(org.graalvm.compiler.java.BciBlockMapping.BciBlock) RuntimeConstraint(jdk.vm.ci.meta.DeoptimizationReason.RuntimeConstraint)

Example 13 with BciBlock

use of org.graalvm.compiler.java.BciBlockMapping.BciBlock in project graal by oracle.

the class BytecodeParser method createHandleExceptionTarget.

protected void createHandleExceptionTarget(FixedWithNextNode finishedDispatch, int bci, FrameStateBuilder dispatchState) {
    BciBlock dispatchBlock = currentBlock.exceptionDispatchBlock();
    /*
         * The exception dispatch block is always for the last bytecode of a block, so if we are not
         * at the endBci yet, there is no exception handler for this bci and we can unwind
         * immediately.
         */
    if (bci != currentBlock.endBci || dispatchBlock == null) {
        dispatchBlock = blockMap.getUnwindBlock();
    }
    FixedNode target = createTarget(dispatchBlock, dispatchState);
    finishedDispatch.setNext(target);
}
Also used : FixedNode(org.graalvm.compiler.nodes.FixedNode) BciBlock(org.graalvm.compiler.java.BciBlockMapping.BciBlock)

Example 14 with BciBlock

use of org.graalvm.compiler.java.BciBlockMapping.BciBlock in project graal by oracle.

the class BytecodeParser method createExceptionDispatch.

private void createExceptionDispatch(ExceptionDispatchBlock block) {
    lastInstr = finishInstruction(lastInstr, frameState);
    assert frameState.stackSize() == 1 : frameState;
    if (block.handler.isCatchAll()) {
        assert block.getSuccessorCount() == 1;
        appendGoto(block.getSuccessor(0));
        return;
    }
    JavaType catchType = block.handler.getCatchType();
    if (graphBuilderConfig.eagerResolving()) {
        catchType = lookupType(block.handler.catchTypeCPI(), INSTANCEOF);
    }
    if (catchType instanceof ResolvedJavaType) {
        TypeReference checkedCatchType = TypeReference.createTrusted(graph.getAssumptions(), (ResolvedJavaType) catchType);
        if (graphBuilderConfig.getSkippedExceptionTypes() != null) {
            for (ResolvedJavaType skippedType : graphBuilderConfig.getSkippedExceptionTypes()) {
                if (skippedType.isAssignableFrom(checkedCatchType.getType())) {
                    BciBlock nextBlock = block.getSuccessorCount() == 1 ? blockMap.getUnwindBlock() : block.getSuccessor(1);
                    ValueNode exception = frameState.stack[0];
                    FixedNode trueSuccessor = graph.add(new DeoptimizeNode(InvalidateReprofile, UnreachedCode));
                    FixedNode nextDispatch = createTarget(nextBlock, frameState);
                    append(new IfNode(graph.addOrUniqueWithInputs(createInstanceOf(checkedCatchType, exception)), trueSuccessor, nextDispatch, 0));
                    return;
                }
            }
        }
        BciBlock nextBlock = block.getSuccessorCount() == 1 ? blockMap.getUnwindBlock() : block.getSuccessor(1);
        ValueNode exception = frameState.stack[0];
        /* Anchor for the piNode, which must be before any LoopExit inserted by createTarget. */
        BeginNode piNodeAnchor = graph.add(new BeginNode());
        ObjectStamp checkedStamp = StampFactory.objectNonNull(checkedCatchType);
        PiNode piNode = graph.addWithoutUnique(new PiNode(exception, checkedStamp));
        frameState.pop(JavaKind.Object);
        frameState.push(JavaKind.Object, piNode);
        FixedNode catchSuccessor = createTarget(block.getSuccessor(0), frameState);
        frameState.pop(JavaKind.Object);
        frameState.push(JavaKind.Object, exception);
        FixedNode nextDispatch = createTarget(nextBlock, frameState);
        piNodeAnchor.setNext(catchSuccessor);
        IfNode ifNode = append(new IfNode(graph.unique(createInstanceOf(checkedCatchType, exception)), piNodeAnchor, nextDispatch, 0.5));
        assert ifNode.trueSuccessor() == piNodeAnchor;
        piNode.setGuard(ifNode.trueSuccessor());
    } else {
        handleUnresolvedExceptionType(catchType);
    }
}
Also used : ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) JavaType(jdk.vm.ci.meta.JavaType) ObjectStamp(org.graalvm.compiler.core.common.type.ObjectStamp) BeginNode(org.graalvm.compiler.nodes.BeginNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) KillingBeginNode(org.graalvm.compiler.nodes.KillingBeginNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) DeoptimizeNode(org.graalvm.compiler.nodes.DeoptimizeNode) TypeReference(org.graalvm.compiler.core.common.type.TypeReference) FixedNode(org.graalvm.compiler.nodes.FixedNode) IfNode(org.graalvm.compiler.nodes.IfNode) PiNode(org.graalvm.compiler.nodes.PiNode) BciBlock(org.graalvm.compiler.java.BciBlockMapping.BciBlock) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType)

Example 15 with BciBlock

use of org.graalvm.compiler.java.BciBlockMapping.BciBlock in project graal by oracle.

the class LargeLocalLiveness method storeOne.

@Override
protected void storeOne(int blockID, int local) {
    if (!localsLiveGen[blockID].get(local)) {
        localsLiveKill[blockID].set(local);
    }
    BciBlock block = blocks[blockID];
    long tmp = block.loops;
    int pos = 0;
    while (tmp != 0) {
        if ((tmp & 1L) == 1L) {
            this.localsChangedInLoop[pos].set(local);
        }
        tmp >>>= 1;
        ++pos;
    }
}
Also used : BciBlock(org.graalvm.compiler.java.BciBlockMapping.BciBlock)

Aggregations

BciBlock (org.graalvm.compiler.java.BciBlockMapping.BciBlock)15 RuntimeConstraint (jdk.vm.ci.meta.DeoptimizationReason.RuntimeConstraint)8 ValueNode (org.graalvm.compiler.nodes.ValueNode)6 LogicConstantNode (org.graalvm.compiler.nodes.LogicConstantNode)4 LogicNode (org.graalvm.compiler.nodes.LogicNode)4 FixedGuardNode (org.graalvm.compiler.nodes.FixedGuardNode)3 FixedNode (org.graalvm.compiler.nodes.FixedNode)3 FrameState (org.graalvm.compiler.nodes.FrameState)3 ProfilingPlugin (org.graalvm.compiler.nodes.graphbuilderconf.ProfilingPlugin)3 ArrayList (java.util.ArrayList)2 JavaType (jdk.vm.ci.meta.JavaType)2 ResolvedJavaType (jdk.vm.ci.meta.ResolvedJavaType)2 TypeReference (org.graalvm.compiler.core.common.type.TypeReference)2 ConstantNode (org.graalvm.compiler.nodes.ConstantNode)2 LoopBeginNode (org.graalvm.compiler.nodes.LoopBeginNode)2 JavaTypeProfile (jdk.vm.ci.meta.JavaTypeProfile)1 Bytecode (org.graalvm.compiler.bytecode.Bytecode)1 BytecodeDisassembler (org.graalvm.compiler.bytecode.BytecodeDisassembler)1 BytecodeStream (org.graalvm.compiler.bytecode.BytecodeStream)1 ResolvedJavaMethodBytecode (org.graalvm.compiler.bytecode.ResolvedJavaMethodBytecode)1