Search in sources :

Example 51 with FixedNode

use of org.graalvm.compiler.nodes.FixedNode in project graal by oracle.

the class BytecodeParser method genIf.

protected void genIf(LogicNode conditionInput, BciBlock trueBlockInput, BciBlock falseBlockInput, double probabilityInput) {
    BciBlock trueBlock = trueBlockInput;
    BciBlock falseBlock = falseBlockInput;
    LogicNode condition = conditionInput;
    double probability = probabilityInput;
    FrameState stateBefore = null;
    ProfilingPlugin profilingPlugin = this.graphBuilderConfig.getPlugins().getProfilingPlugin();
    if (profilingPlugin != null && profilingPlugin.shouldProfile(this, method)) {
        stateBefore = frameState.create(bci(), getNonIntrinsicAncestor(), false, null, null);
    }
    // Remove a logic negation node.
    if (condition instanceof LogicNegationNode) {
        LogicNegationNode logicNegationNode = (LogicNegationNode) condition;
        BciBlock tmpBlock = trueBlock;
        trueBlock = falseBlock;
        falseBlock = tmpBlock;
        probability = 1 - probability;
        condition = logicNegationNode.getValue();
    }
    if (condition instanceof LogicConstantNode) {
        genConstantTargetIf(trueBlock, falseBlock, condition);
    } else {
        if (condition.graph() == null) {
            condition = genUnique(condition);
        }
        if (isNeverExecutedCode(probability)) {
            append(new FixedGuardNode(condition, UnreachedCode, InvalidateReprofile, true));
            if (profilingPlugin != null && profilingPlugin.shouldProfile(this, method)) {
                profilingPlugin.profileGoto(this, method, bci(), falseBlock.startBci, stateBefore);
            }
            appendGoto(falseBlock);
            return;
        } else if (isNeverExecutedCode(1 - probability)) {
            append(new FixedGuardNode(condition, UnreachedCode, InvalidateReprofile, false));
            if (profilingPlugin != null && profilingPlugin.shouldProfile(this, method)) {
                profilingPlugin.profileGoto(this, method, bci(), trueBlock.startBci, stateBefore);
            }
            appendGoto(trueBlock);
            return;
        }
        if (profilingPlugin != null && profilingPlugin.shouldProfile(this, method)) {
            profilingPlugin.profileIf(this, method, bci(), condition, trueBlock.startBci, falseBlock.startBci, stateBefore);
        }
        int oldBci = stream.currentBCI();
        int trueBlockInt = checkPositiveIntConstantPushed(trueBlock);
        if (trueBlockInt != -1) {
            int falseBlockInt = checkPositiveIntConstantPushed(falseBlock);
            if (falseBlockInt != -1) {
                if (tryGenConditionalForIf(trueBlock, falseBlock, condition, oldBci, trueBlockInt, falseBlockInt)) {
                    return;
                }
            }
        }
        this.controlFlowSplit = true;
        FixedNode trueSuccessor = createTarget(trueBlock, frameState, false, false);
        FixedNode falseSuccessor = createTarget(falseBlock, frameState, false, true);
        ValueNode ifNode = genIfNode(condition, trueSuccessor, falseSuccessor, probability);
        postProcessIfNode(ifNode);
        append(ifNode);
    }
}
Also used : FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) LogicNegationNode(org.graalvm.compiler.nodes.LogicNegationNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) LogicConstantNode(org.graalvm.compiler.nodes.LogicConstantNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) FrameState(org.graalvm.compiler.nodes.FrameState) BciBlock(org.graalvm.compiler.java.BciBlockMapping.BciBlock) RuntimeConstraint(jdk.vm.ci.meta.DeoptimizationReason.RuntimeConstraint) ProfilingPlugin(org.graalvm.compiler.nodes.graphbuilderconf.ProfilingPlugin)

Example 52 with FixedNode

use of org.graalvm.compiler.nodes.FixedNode 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 53 with FixedNode

use of org.graalvm.compiler.nodes.FixedNode in project graal by oracle.

the class BytecodeParser method createBlockTarget.

/**
 * Returns a block begin node with the specified state. If the specified probability is 0, the
 * block deoptimizes immediately.
 */
private AbstractBeginNode createBlockTarget(double probability, BciBlock block, FrameStateBuilder stateAfter) {
    FixedNode target = createTarget(probability, block, stateAfter);
    AbstractBeginNode begin = BeginNode.begin(target);
    assert !(target instanceof DeoptimizeNode && begin instanceof BeginStateSplitNode && ((BeginStateSplitNode) begin).stateAfter() != null) : "We are not allowed to set the stateAfter of the begin node," + " because we have to deoptimize to a bci _before_ the actual if, so that the interpreter can update the profiling information.";
    return begin;
}
Also used : DeoptimizeNode(org.graalvm.compiler.nodes.DeoptimizeNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) BeginStateSplitNode(org.graalvm.compiler.nodes.BeginStateSplitNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode)

Example 54 with FixedNode

use of org.graalvm.compiler.nodes.FixedNode 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 55 with FixedNode

use of org.graalvm.compiler.nodes.FixedNode in project graal by oracle.

the class BytecodeParser method createTarget.

@SuppressWarnings("try")
private FixedNode createTarget(BciBlock block, FrameStateBuilder state, boolean canReuseInstruction, boolean canReuseState) {
    assert block != null && state != null;
    assert !block.isExceptionEntry || state.stackSize() == 1;
    try (DebugCloseable context = openNodeContext(state, block.startBci)) {
        if (getFirstInstruction(block) == null) {
            /*
                 * This is the first time we see this block as a branch target. Create and return a
                 * placeholder that later can be replaced with a MergeNode when we see this block
                 * again.
                 */
            FixedNode targetNode;
            if (canReuseInstruction && (block.getPredecessorCount() == 1 || !controlFlowSplit) && !block.isLoopHeader && (currentBlock.loops & ~block.loops) == 0) {
                setFirstInstruction(block, lastInstr);
                lastInstr = null;
            } else {
                setFirstInstruction(block, graph.add(new BeginNode()));
            }
            targetNode = getFirstInstruction(block);
            Target target = checkLoopExit(targetNode, block, state);
            FixedNode result = target.fixed;
            FrameStateBuilder currentEntryState = target.state == state ? (canReuseState ? state : state.copy()) : target.state;
            setEntryState(block, currentEntryState);
            currentEntryState.clearNonLiveLocals(block, liveness, true);
            debug.log("createTarget %s: first visit, result: %s", block, targetNode);
            return result;
        }
        // We already saw this block before, so we have to merge states.
        if (!getEntryState(block).isCompatibleWith(state)) {
            throw bailout("stacks do not match; bytecodes would not verify");
        }
        if (getFirstInstruction(block) instanceof LoopBeginNode) {
            assert (block.isLoopHeader && currentBlock.getId() >= block.getId()) : "must be backward branch";
            /*
                 * Backward loop edge. We need to create a special LoopEndNode and merge with the
                 * loop begin node created before.
                 */
            LoopBeginNode loopBegin = (LoopBeginNode) getFirstInstruction(block);
            LoopEndNode loopEnd = graph.add(new LoopEndNode(loopBegin));
            Target target = checkLoopExit(loopEnd, block, state);
            FixedNode result = target.fixed;
            getEntryState(block).merge(loopBegin, target.state);
            debug.log("createTarget %s: merging backward branch to loop header %s, result: %s", block, loopBegin, result);
            return result;
        }
        assert currentBlock == null || currentBlock.getId() < block.getId() : "must not be backward branch";
        assert getFirstInstruction(block).next() == null : "bytecodes already parsed for block";
        if (getFirstInstruction(block) instanceof AbstractBeginNode && !(getFirstInstruction(block) instanceof AbstractMergeNode)) {
            /*
                 * This is the second time we see this block. Create the actual MergeNode and the
                 * End Node for the already existing edge.
                 */
            AbstractBeginNode beginNode = (AbstractBeginNode) getFirstInstruction(block);
            // The EndNode for the already existing edge.
            EndNode end = graph.add(new EndNode());
            // The MergeNode that replaces the placeholder.
            AbstractMergeNode mergeNode = graph.add(new MergeNode());
            FixedNode next = beginNode.next();
            if (beginNode.predecessor() instanceof ControlSplitNode) {
                beginNode.setNext(end);
            } else {
                beginNode.replaceAtPredecessor(end);
                beginNode.safeDelete();
            }
            mergeNode.addForwardEnd(end);
            mergeNode.setNext(next);
            setFirstInstruction(block, mergeNode);
        }
        AbstractMergeNode mergeNode = (AbstractMergeNode) getFirstInstruction(block);
        // The EndNode for the newly merged edge.
        EndNode newEnd = graph.add(new EndNode());
        Target target = checkLoopExit(newEnd, block, state);
        FixedNode result = target.fixed;
        getEntryState(block).merge(mergeNode, target.state);
        mergeNode.addForwardEnd(newEnd);
        debug.log("createTarget %s: merging state, result: %s", block, result);
        return result;
    }
}
Also used : AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) MergeNode(org.graalvm.compiler.nodes.MergeNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) LoopEndNode(org.graalvm.compiler.nodes.LoopEndNode) EndNode(org.graalvm.compiler.nodes.EndNode) BeginNode(org.graalvm.compiler.nodes.BeginNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) KillingBeginNode(org.graalvm.compiler.nodes.KillingBeginNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) ControlSplitNode(org.graalvm.compiler.nodes.ControlSplitNode) DebugCloseable(org.graalvm.compiler.debug.DebugCloseable) FixedNode(org.graalvm.compiler.nodes.FixedNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) LoopEndNode(org.graalvm.compiler.nodes.LoopEndNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode)

Aggregations

FixedNode (org.graalvm.compiler.nodes.FixedNode)87 Node (org.graalvm.compiler.graph.Node)41 FixedWithNextNode (org.graalvm.compiler.nodes.FixedWithNextNode)41 AbstractBeginNode (org.graalvm.compiler.nodes.AbstractBeginNode)39 AbstractMergeNode (org.graalvm.compiler.nodes.AbstractMergeNode)39 ValueNode (org.graalvm.compiler.nodes.ValueNode)34 LoopBeginNode (org.graalvm.compiler.nodes.LoopBeginNode)33 EndNode (org.graalvm.compiler.nodes.EndNode)27 AbstractEndNode (org.graalvm.compiler.nodes.AbstractEndNode)25 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)23 PhiNode (org.graalvm.compiler.nodes.PhiNode)22 ControlSplitNode (org.graalvm.compiler.nodes.ControlSplitNode)21 LoopExitNode (org.graalvm.compiler.nodes.LoopExitNode)21 LoopEndNode (org.graalvm.compiler.nodes.LoopEndNode)20 ControlSinkNode (org.graalvm.compiler.nodes.ControlSinkNode)17 MergeNode (org.graalvm.compiler.nodes.MergeNode)17 StartNode (org.graalvm.compiler.nodes.StartNode)17 ConstantNode (org.graalvm.compiler.nodes.ConstantNode)16 DeoptimizeNode (org.graalvm.compiler.nodes.DeoptimizeNode)13 ProxyNode (org.graalvm.compiler.nodes.ProxyNode)13