Search in sources :

Example 1 with Invoke

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

the class ProfileCompiledMethodsPhase method run.

@Override
protected void run(StructuredGraph graph) {
    SchedulePhase schedule = new SchedulePhase(graph.getOptions());
    schedule.apply(graph, false);
    ControlFlowGraph cfg = ControlFlowGraph.compute(graph, true, true, true, true);
    for (Loop<Block> loop : cfg.getLoops()) {
        double loopProbability = cfg.blockFor(loop.getHeader().getBeginNode()).probability();
        if (loopProbability > (1D / Integer.MAX_VALUE)) {
            addSectionCounters(loop.getHeader().getBeginNode(), loop.getBlocks(), loop.getChildren(), graph.getLastSchedule(), cfg);
        }
    }
    // don't put the counter increase directly after the start (problems with OSR)
    FixedWithNextNode current = graph.start();
    while (current.next() instanceof FixedWithNextNode) {
        current = (FixedWithNextNode) current.next();
    }
    addSectionCounters(current, Arrays.asList(cfg.getBlocks()), cfg.getLoops(), graph.getLastSchedule(), cfg);
    if (WITH_INVOKES) {
        for (Node node : graph.getNodes()) {
            if (node instanceof Invoke) {
                Invoke invoke = (Invoke) node;
                DynamicCounterNode.addCounterBefore(GROUP_NAME_INVOKES, invoke.callTarget().targetName(), 1, true, invoke.asNode());
            }
        }
    }
}
Also used : FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) SchedulePhase(org.graalvm.compiler.phases.schedule.SchedulePhase) ControlFlowGraph(org.graalvm.compiler.nodes.cfg.ControlFlowGraph) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) ReinterpretNode(org.graalvm.compiler.nodes.calc.ReinterpretNode) RemNode(org.graalvm.compiler.nodes.calc.RemNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) IntegerDivRemNode(org.graalvm.compiler.nodes.calc.IntegerDivRemNode) BinaryNode(org.graalvm.compiler.nodes.calc.BinaryNode) SwitchNode(org.graalvm.compiler.nodes.extended.SwitchNode) NotNode(org.graalvm.compiler.nodes.calc.NotNode) MonitorIdNode(org.graalvm.compiler.nodes.java.MonitorIdNode) ParameterNode(org.graalvm.compiler.nodes.ParameterNode) AccessMonitorNode(org.graalvm.compiler.nodes.java.AccessMonitorNode) AbstractNewObjectNode(org.graalvm.compiler.nodes.java.AbstractNewObjectNode) DeoptimizeNode(org.graalvm.compiler.nodes.DeoptimizeNode) ReturnNode(org.graalvm.compiler.nodes.ReturnNode) CallTargetNode(org.graalvm.compiler.nodes.CallTargetNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) IfNode(org.graalvm.compiler.nodes.IfNode) VirtualObjectNode(org.graalvm.compiler.nodes.virtual.VirtualObjectNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) SafepointNode(org.graalvm.compiler.nodes.SafepointNode) UnwindNode(org.graalvm.compiler.nodes.UnwindNode) Node(org.graalvm.compiler.graph.Node) ConvertNode(org.graalvm.compiler.nodes.calc.ConvertNode) MulNode(org.graalvm.compiler.nodes.calc.MulNode) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) DynamicCounterNode(org.graalvm.compiler.nodes.debug.DynamicCounterNode) FloatDivNode(org.graalvm.compiler.nodes.calc.FloatDivNode) Block(org.graalvm.compiler.nodes.cfg.Block) Invoke(org.graalvm.compiler.nodes.Invoke)

Example 2 with Invoke

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

the class MultiTypeGuardInlineInfo method createInvocationBlock.

private static AbstractBeginNode createInvocationBlock(StructuredGraph graph, Invoke invoke, AbstractMergeNode returnMerge, PhiNode returnValuePhi, AbstractMergeNode exceptionMerge, PhiNode exceptionObjectPhi, boolean useForInlining) {
    Invoke duplicatedInvoke = duplicateInvokeForInlining(graph, invoke, exceptionMerge, exceptionObjectPhi, useForInlining);
    AbstractBeginNode calleeEntryNode = graph.add(new BeginNode());
    calleeEntryNode.setNext(duplicatedInvoke.asNode());
    EndNode endNode = graph.add(new EndNode());
    duplicatedInvoke.setNext(endNode);
    returnMerge.addForwardEnd(endNode);
    if (returnValuePhi != null) {
        returnValuePhi.addInput(duplicatedInvoke.asNode());
    }
    return calleeEntryNode;
}
Also used : EndNode(org.graalvm.compiler.nodes.EndNode) BeginNode(org.graalvm.compiler.nodes.BeginNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) Invoke(org.graalvm.compiler.nodes.Invoke) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode)

Example 3 with Invoke

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

the class MultiTypeGuardInlineInfo method inlineMultipleMethods.

private EconomicSet<Node> inlineMultipleMethods(StructuredGraph graph, Providers providers) {
    int numberOfMethods = concretes.size();
    FixedNode continuation = invoke.next();
    // setup merge and phi nodes for results and exceptions
    AbstractMergeNode returnMerge = graph.add(new MergeNode());
    returnMerge.setStateAfter(invoke.stateAfter());
    PhiNode returnValuePhi = null;
    if (invoke.asNode().getStackKind() != JavaKind.Void) {
        returnValuePhi = graph.addWithoutUnique(new ValuePhiNode(invoke.asNode().stamp(NodeView.DEFAULT).unrestricted(), returnMerge));
    }
    AbstractMergeNode exceptionMerge = null;
    PhiNode exceptionObjectPhi = null;
    if (invoke instanceof InvokeWithExceptionNode) {
        InvokeWithExceptionNode invokeWithException = (InvokeWithExceptionNode) invoke;
        ExceptionObjectNode exceptionEdge = (ExceptionObjectNode) invokeWithException.exceptionEdge();
        exceptionMerge = graph.add(new MergeNode());
        FixedNode exceptionSux = exceptionEdge.next();
        graph.addBeforeFixed(exceptionSux, exceptionMerge);
        exceptionObjectPhi = graph.addWithoutUnique(new ValuePhiNode(StampFactory.forKind(JavaKind.Object), exceptionMerge));
        exceptionMerge.setStateAfter(exceptionEdge.stateAfter().duplicateModified(invoke.stateAfter().bci, true, JavaKind.Object, new JavaKind[] { JavaKind.Object }, new ValueNode[] { exceptionObjectPhi }));
    }
    // create one separate block for each invoked method
    AbstractBeginNode[] successors = new AbstractBeginNode[numberOfMethods + 1];
    for (int i = 0; i < numberOfMethods; i++) {
        successors[i] = createInvocationBlock(graph, invoke, returnMerge, returnValuePhi, exceptionMerge, exceptionObjectPhi, true);
    }
    // create the successor for an unknown type
    FixedNode unknownTypeSux;
    if (shouldFallbackToInvoke()) {
        unknownTypeSux = createInvocationBlock(graph, invoke, returnMerge, returnValuePhi, exceptionMerge, exceptionObjectPhi, false);
    } else {
        unknownTypeSux = graph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.TypeCheckedInliningViolated));
    }
    successors[successors.length - 1] = BeginNode.begin(unknownTypeSux);
    // replace the invoke exception edge
    if (invoke instanceof InvokeWithExceptionNode) {
        InvokeWithExceptionNode invokeWithExceptionNode = (InvokeWithExceptionNode) invoke;
        ExceptionObjectNode exceptionEdge = (ExceptionObjectNode) invokeWithExceptionNode.exceptionEdge();
        exceptionEdge.replaceAtUsages(exceptionObjectPhi);
        exceptionEdge.setNext(null);
        GraphUtil.killCFG(invokeWithExceptionNode.exceptionEdge());
    }
    assert invoke.asNode().isAlive();
    // replace the invoke with a switch on the type of the actual receiver
    boolean methodDispatch = createDispatchOnTypeBeforeInvoke(graph, successors, false, providers.getStampProvider(), providers.getConstantReflection());
    assert invoke.next() == continuation;
    invoke.setNext(null);
    returnMerge.setNext(continuation);
    if (returnValuePhi != null) {
        invoke.asNode().replaceAtUsages(returnValuePhi);
    }
    invoke.asNode().safeDelete();
    ArrayList<PiNode> replacementNodes = new ArrayList<>();
    // prepare the anchors for the invokes
    for (int i = 0; i < numberOfMethods; i++) {
        AbstractBeginNode node = successors[i];
        Invoke invokeForInlining = (Invoke) node.next();
        ResolvedJavaType commonType;
        if (methodDispatch) {
            commonType = concretes.get(i).getDeclaringClass();
        } else {
            commonType = getLeastCommonType(i);
        }
        ValueNode receiver = ((MethodCallTargetNode) invokeForInlining.callTarget()).receiver();
        boolean exact = (getTypeCount(i) == 1 && !methodDispatch);
        PiNode anchoredReceiver = InliningUtil.createAnchoredReceiver(graph, node, commonType, receiver, exact);
        invokeForInlining.callTarget().replaceFirstInput(receiver, anchoredReceiver);
        assert !anchoredReceiver.isDeleted() : anchoredReceiver;
        replacementNodes.add(anchoredReceiver);
    }
    if (shouldFallbackToInvoke()) {
        replacementNodes.add(null);
    }
    EconomicSet<Node> canonicalizeNodes = EconomicSet.create(Equivalence.DEFAULT);
    // do the actual inlining for every invoke
    for (int i = 0; i < numberOfMethods; i++) {
        Invoke invokeForInlining = (Invoke) successors[i].next();
        canonicalizeNodes.addAll(doInline(i, invokeForInlining));
    }
    if (returnValuePhi != null) {
        canonicalizeNodes.add(returnValuePhi);
    }
    return canonicalizeNodes;
}
Also used : ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) InvokeWithExceptionNode(org.graalvm.compiler.nodes.InvokeWithExceptionNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) ExceptionObjectNode(org.graalvm.compiler.nodes.java.ExceptionObjectNode) LoadHubNode(org.graalvm.compiler.nodes.extended.LoadHubNode) BeginNode(org.graalvm.compiler.nodes.BeginNode) MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) MergeNode(org.graalvm.compiler.nodes.MergeNode) DeoptimizeNode(org.graalvm.compiler.nodes.DeoptimizeNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) PiNode(org.graalvm.compiler.nodes.PiNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) Node(org.graalvm.compiler.graph.Node) EndNode(org.graalvm.compiler.nodes.EndNode) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) TypeSwitchNode(org.graalvm.compiler.nodes.java.TypeSwitchNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) ExceptionObjectNode(org.graalvm.compiler.nodes.java.ExceptionObjectNode) ArrayList(java.util.ArrayList) FixedNode(org.graalvm.compiler.nodes.FixedNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) PiNode(org.graalvm.compiler.nodes.PiNode) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) Invoke(org.graalvm.compiler.nodes.Invoke) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) MergeNode(org.graalvm.compiler.nodes.MergeNode) MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) InvokeWithExceptionNode(org.graalvm.compiler.nodes.InvokeWithExceptionNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) DeoptimizeNode(org.graalvm.compiler.nodes.DeoptimizeNode) JavaKind(jdk.vm.ci.meta.JavaKind)

Example 4 with Invoke

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

the class MacroStateSplitNode method replaceSnippetInvokes.

protected void replaceSnippetInvokes(StructuredGraph snippetGraph) {
    for (MethodCallTargetNode call : snippetGraph.getNodes(MethodCallTargetNode.TYPE)) {
        Invoke invoke = call.invoke();
        if (!call.targetMethod().equals(getTargetMethod())) {
            throw new GraalError("unexpected invoke %s in snippet", getClass().getSimpleName());
        }
        assert invoke.stateAfter().bci == BytecodeFrame.AFTER_BCI;
        // Here we need to fix the bci of the invoke
        InvokeNode newInvoke = snippetGraph.add(new InvokeNode(invoke.callTarget(), bci()));
        newInvoke.setStateAfter(invoke.stateAfter());
        snippetGraph.replaceFixedWithFixed((InvokeNode) invoke.asNode(), newInvoke);
    }
}
Also used : MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) GraalError(org.graalvm.compiler.debug.GraalError) InvokeNode(org.graalvm.compiler.nodes.InvokeNode) Invoke(org.graalvm.compiler.nodes.Invoke)

Example 5 with Invoke

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

the class RuntimeStrengthenStampsPhase method registerDeoptEntries.

private static void registerDeoptEntries(CallTreeNode node) {
    for (FrameState frameState : node.graph.getNodes(FrameState.TYPE)) {
        if (node.level > 0 && frameState.usages().count() == 1 && frameState.usages().first() == node.graph.start()) {
            /*
                 * During method inlining, the FrameState associated with the StartNode disappears.
                 * Therefore, this frame state cannot be a deoptimization target.
                 */
            continue;
        }
        /*
             * We need to make sure that all inlined caller frames are available for deoptimization
             * too.
             */
        for (FrameState inlineState = frameState; inlineState != null; inlineState = inlineState.outerFrameState()) {
            if (inlineState.bci >= 0) {
                CompilationInfoSupport.singleton().registerDeoptEntry(inlineState.getMethod(), inlineState.bci, inlineState.duringCall(), inlineState.rethrowException());
            }
        }
    }
    for (Node n : node.graph.getNodes()) {
        /*
             * graph.getInvokes() only iterates invokes that have a MethodCallTarget, so by using it
             * we would miss invocations that are already intrinsified to an indirect call.
             */
        if (n instanceof Invoke) {
            Invoke invoke = (Invoke) n;
            /*
                 * The FrameState for the invoke (which is visited by the above loop) is the state
                 * after the call (where deoptimization that happens after the call has returned
                 * will continue execution). We also need to register the state during the call
                 * (where deoptimization while the call is on the stack will continue execution).
                 *
                 * Note that the bci of the Invoke and the bci of the FrameState of the Invoke are
                 * different: the Invoke has the bci of the invocation bytecode, the FrameState has
                 * the bci of the next bytecode after the invoke.
                 */
            CompilationInfoSupport.singleton().registerDeoptEntry(invoke.stateAfter().getMethod(), invoke.bci(), true, false);
        }
    }
}
Also used : StackValueNode(com.oracle.svm.core.graal.stackvalue.StackValueNode) MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) LogicConstantNode(org.graalvm.compiler.nodes.LogicConstantNode) FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) Node(org.graalvm.compiler.graph.Node) FrameState(org.graalvm.compiler.nodes.FrameState) Invoke(org.graalvm.compiler.nodes.Invoke)

Aggregations

Invoke (org.graalvm.compiler.nodes.Invoke)49 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)19 Node (org.graalvm.compiler.graph.Node)17 MethodCallTargetNode (org.graalvm.compiler.nodes.java.MethodCallTargetNode)17 ValueNode (org.graalvm.compiler.nodes.ValueNode)16 FixedNode (org.graalvm.compiler.nodes.FixedNode)13 FixedWithNextNode (org.graalvm.compiler.nodes.FixedWithNextNode)12 ResolvedJavaMethod (jdk.vm.ci.meta.ResolvedJavaMethod)10 FrameState (org.graalvm.compiler.nodes.FrameState)10 DebugContext (org.graalvm.compiler.debug.DebugContext)9 AbstractBeginNode (org.graalvm.compiler.nodes.AbstractBeginNode)9 AbstractMergeNode (org.graalvm.compiler.nodes.AbstractMergeNode)9 CanonicalizerPhase (org.graalvm.compiler.phases.common.CanonicalizerPhase)8 DeoptimizeNode (org.graalvm.compiler.nodes.DeoptimizeNode)7 EndNode (org.graalvm.compiler.nodes.EndNode)7 GraalError (org.graalvm.compiler.debug.GraalError)6 ParameterNode (org.graalvm.compiler.nodes.ParameterNode)6 ArrayList (java.util.ArrayList)5 ResolvedJavaField (jdk.vm.ci.meta.ResolvedJavaField)5 ResolvedJavaType (jdk.vm.ci.meta.ResolvedJavaType)5