Search in sources :

Example 11 with AbstractMergeNode

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

the class BytecodeParser method afterInvocationPluginExecution.

/**
 * Performs any action required after execution of an invocation plugin. This includes
 * {@linkplain InvocationPluginAssertions#check checking} invocation plugin invariants as well
 * as weaving the {@code else} branch of the code woven by {@link #guardIntrinsic} if
 * {@code guard != null}.
 */
protected void afterInvocationPluginExecution(boolean pluginHandledInvoke, InvocationPluginAssertions assertions, IntrinsicGuard intrinsicGuard, InvokeKind invokeKind, ValueNode[] args, ResolvedJavaMethod targetMethod, JavaKind resultType, JavaType returnType) {
    assert assertions.check(pluginHandledInvoke);
    if (intrinsicGuard != null) {
        if (pluginHandledInvoke) {
            if (intrinsicGuard.nonIntrinsicBranch != null) {
                // Intrinsic emitted: emit a virtual call to the target method and
                // merge it with the intrinsic branch
                EndNode intrinsicEnd = append(new EndNode());
                FrameStateBuilder intrinsicState = null;
                FrameStateBuilder nonIntrinisicState = null;
                if (resultType != JavaKind.Void) {
                    intrinsicState = frameState.copy();
                    frameState.pop(resultType);
                    nonIntrinisicState = frameState;
                }
                lastInstr = intrinsicGuard.nonIntrinsicBranch;
                createNonInlinedInvoke(getActionForInvokeExceptionEdge(null), bci(), args, targetMethod, invokeKind, resultType, returnType, intrinsicGuard.profile);
                EndNode nonIntrinsicEnd = append(new EndNode());
                AbstractMergeNode mergeNode = graph.add(new MergeNode());
                mergeNode.addForwardEnd(intrinsicEnd);
                if (intrinsicState != null) {
                    intrinsicState.merge(mergeNode, nonIntrinisicState);
                    frameState = intrinsicState;
                }
                mergeNode.addForwardEnd(nonIntrinsicEnd);
                mergeNode.setStateAfter(frameState.create(stream.nextBCI(), mergeNode));
                lastInstr = mergeNode;
            }
        } else {
            // Intrinsic was not applied: remove intrinsic guard
            // and restore the original receiver node in the arguments array
            intrinsicGuard.lastInstr.setNext(null);
            GraphUtil.removeNewNodes(graph, intrinsicGuard.mark);
            lastInstr = intrinsicGuard.lastInstr;
            args[0] = intrinsicGuard.receiver;
        }
    }
}
Also used : AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) MergeNode(org.graalvm.compiler.nodes.MergeNode) LoopEndNode(org.graalvm.compiler.nodes.LoopEndNode) EndNode(org.graalvm.compiler.nodes.EndNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode)

Example 12 with AbstractMergeNode

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

the class BytecodeParser method iterateBytecodesForBlock.

@SuppressWarnings("try")
protected void iterateBytecodesForBlock(BciBlock block) {
    if (block.isLoopHeader) {
        // Create the loop header block, which later will merge the backward branches of
        // the loop.
        controlFlowSplit = true;
        LoopBeginNode loopBegin = appendLoopBegin(this.lastInstr, block.startBci);
        lastInstr = loopBegin;
        // Create phi functions for all local variables and operand stack slots.
        frameState.insertLoopPhis(liveness, block.loopId, loopBegin, forceLoopPhis(), stampFromValueForForcedPhis());
        loopBegin.setStateAfter(createFrameState(block.startBci, loopBegin));
        /*
             * We have seen all forward branches. All subsequent backward branches will merge to the
             * loop header. This ensures that the loop header has exactly one non-loop predecessor.
             */
        setFirstInstruction(block, loopBegin);
        /*
             * We need to preserve the frame state builder of the loop header so that we can merge
             * values for phi functions, so make a copy of it.
             */
        setEntryState(block, frameState.copy());
        debug.log("  created loop header %s", loopBegin);
    } else if (lastInstr instanceof MergeNode) {
        /*
             * All inputs of non-loop phi nodes are known by now. We can infer the stamp for the
             * phi, so that parsing continues with more precise type information.
             */
        frameState.inferPhiStamps((AbstractMergeNode) lastInstr);
    }
    assert lastInstr.next() == null : "instructions already appended at block " + block;
    debug.log("  frameState: %s", frameState);
    lastInstr = finishInstruction(lastInstr, frameState);
    int endBCI = stream.endBCI();
    stream.setBCI(block.startBci);
    int bci = block.startBci;
    BytecodesParsed.add(debug, block.endBci - bci);
    /* Reset line number for new block */
    if (graphBuilderConfig.insertFullInfopoints()) {
        previousLineNumber = -1;
    }
    while (bci < endBCI) {
        try (DebugCloseable context = openNodeContext()) {
            if (graphBuilderConfig.insertFullInfopoints() && !parsingIntrinsic()) {
                currentLineNumber = lnt != null ? lnt.getLineNumber(bci) : -1;
                if (currentLineNumber != previousLineNumber) {
                    genInfoPointNode(InfopointReason.BYTECODE_POSITION, null);
                    previousLineNumber = currentLineNumber;
                }
            }
            // read the opcode
            int opcode = stream.currentBC();
            assert traceState();
            assert traceInstruction(bci, opcode, bci == block.startBci);
            if (parent == null && bci == entryBCI) {
                if (block.getJsrScope() != JsrScope.EMPTY_SCOPE) {
                    throw new JsrNotSupportedBailout("OSR into a JSR scope is not supported");
                }
                EntryMarkerNode x = append(new EntryMarkerNode());
                frameState.insertProxies(value -> graph.unique(new EntryProxyNode(value, x)));
                x.setStateAfter(createFrameState(bci, x));
            }
            processBytecode(bci, opcode);
        } catch (BailoutException e) {
            // Don't wrap bailouts as parser errors
            throw e;
        } catch (Throwable e) {
            throw throwParserError(e);
        }
        if (lastInstr == null || lastInstr.next() != null) {
            break;
        }
        stream.next();
        bci = stream.currentBCI();
        assert block == currentBlock;
        assert checkLastInstruction();
        lastInstr = finishInstruction(lastInstr, frameState);
        if (bci < endBCI) {
            if (bci > block.endBci) {
                assert !block.getSuccessor(0).isExceptionEntry;
                assert block.numNormalSuccessors() == 1;
                // we fell through to the next block, add a goto and break
                appendGoto(block.getSuccessor(0));
                break;
            }
        }
    }
}
Also used : AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) MergeNode(org.graalvm.compiler.nodes.MergeNode) EntryMarkerNode(org.graalvm.compiler.nodes.EntryMarkerNode) PermanentBailoutException(org.graalvm.compiler.core.common.PermanentBailoutException) BailoutException(jdk.vm.ci.code.BailoutException) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) DebugCloseable(org.graalvm.compiler.debug.DebugCloseable) RuntimeConstraint(jdk.vm.ci.meta.DeoptimizationReason.RuntimeConstraint) EntryProxyNode(org.graalvm.compiler.nodes.EntryProxyNode)

Example 13 with AbstractMergeNode

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

the class BytecodeParser method setMergeStateAfter.

private void setMergeStateAfter(BciBlock block, FixedWithNextNode firstInstruction) {
    AbstractMergeNode abstractMergeNode = (AbstractMergeNode) firstInstruction;
    if (abstractMergeNode.stateAfter() == null) {
        int bci = block.startBci;
        if (block instanceof ExceptionDispatchBlock) {
            bci = ((ExceptionDispatchBlock) block).deoptBci;
        }
        abstractMergeNode.setStateAfter(createFrameState(bci, abstractMergeNode));
    }
}
Also used : ExceptionDispatchBlock(org.graalvm.compiler.java.BciBlockMapping.ExceptionDispatchBlock) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) RuntimeConstraint(jdk.vm.ci.meta.DeoptimizationReason.RuntimeConstraint)

Example 14 with AbstractMergeNode

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

the class BytecodeParser method processBlock.

@SuppressWarnings("try")
protected void processBlock(BciBlock block) {
    // Ignore blocks that have no predecessors by the time their bytecodes are parsed
    FixedWithNextNode firstInstruction = getFirstInstruction(block);
    if (firstInstruction == null) {
        debug.log("Ignoring block %s", block);
        return;
    }
    try (Indent indent = debug.logAndIndent("Parsing block %s  firstInstruction: %s  loopHeader: %b", block, firstInstruction, block.isLoopHeader)) {
        lastInstr = firstInstruction;
        frameState = getEntryState(block);
        setCurrentFrameState(frameState);
        currentBlock = block;
        if (block != blockMap.getUnwindBlock() && !(block instanceof ExceptionDispatchBlock)) {
            frameState.setRethrowException(false);
        }
        if (firstInstruction instanceof AbstractMergeNode) {
            setMergeStateAfter(block, firstInstruction);
        }
        if (block == blockMap.getUnwindBlock()) {
            handleUnwindBlock((ExceptionDispatchBlock) block);
        } else if (block instanceof ExceptionDispatchBlock) {
            createExceptionDispatch((ExceptionDispatchBlock) block);
        } else {
            iterateBytecodesForBlock(block);
        }
    }
}
Also used : FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) Indent(org.graalvm.compiler.debug.Indent) ExceptionDispatchBlock(org.graalvm.compiler.java.BciBlockMapping.ExceptionDispatchBlock) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode)

Example 15 with AbstractMergeNode

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

the class NodeLIRBuilder method isPhiInputFromBackedge.

private static boolean isPhiInputFromBackedge(PhiNode phi, int index) {
    AbstractMergeNode merge = phi.merge();
    AbstractEndNode end = merge.phiPredecessorAt(index);
    return end instanceof LoopEndNode && ((LoopEndNode) end).loopBegin().equals(merge);
}
Also used : AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) LoopEndNode(org.graalvm.compiler.nodes.LoopEndNode)

Aggregations

AbstractMergeNode (org.graalvm.compiler.nodes.AbstractMergeNode)59 FixedNode (org.graalvm.compiler.nodes.FixedNode)31 AbstractBeginNode (org.graalvm.compiler.nodes.AbstractBeginNode)28 EndNode (org.graalvm.compiler.nodes.EndNode)24 Node (org.graalvm.compiler.graph.Node)22 AbstractEndNode (org.graalvm.compiler.nodes.AbstractEndNode)22 ValueNode (org.graalvm.compiler.nodes.ValueNode)22 FixedWithNextNode (org.graalvm.compiler.nodes.FixedWithNextNode)20 LoopBeginNode (org.graalvm.compiler.nodes.LoopBeginNode)19 PhiNode (org.graalvm.compiler.nodes.PhiNode)18 MergeNode (org.graalvm.compiler.nodes.MergeNode)16 ValuePhiNode (org.graalvm.compiler.nodes.ValuePhiNode)14 ControlSplitNode (org.graalvm.compiler.nodes.ControlSplitNode)13 LoopEndNode (org.graalvm.compiler.nodes.LoopEndNode)13 LoopExitNode (org.graalvm.compiler.nodes.LoopExitNode)13 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)12 ConstantNode (org.graalvm.compiler.nodes.ConstantNode)11 ArrayList (java.util.ArrayList)10 FrameState (org.graalvm.compiler.nodes.FrameState)10 IfNode (org.graalvm.compiler.nodes.IfNode)9