Search in sources :

Example 36 with MethodCallTargetNode

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

the class MethodSubstitutionTest method testGraph.

@SuppressWarnings("try")
protected StructuredGraph testGraph(final String snippet, String name) {
    DebugContext debug = getDebugContext();
    try (DebugContext.Scope s = debug.scope("MethodSubstitutionTest", getResolvedJavaMethod(snippet))) {
        StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES, debug);
        HighTierContext context = getDefaultHighTierContext();
        debug.dump(DebugContext.BASIC_LEVEL, graph, "Graph");
        new InliningPhase(new CanonicalizerPhase()).apply(graph, context);
        debug.dump(DebugContext.BASIC_LEVEL, graph, "Graph");
        new CanonicalizerPhase().apply(graph, context);
        new DeadCodeEliminationPhase().apply(graph);
        // Try to ensure any macro nodes are lowered to expose any resulting invokes
        if (graph.getNodes().filter(MacroNode.class).isNotEmpty()) {
            new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
        }
        if (graph.getNodes().filter(MacroNode.class).isNotEmpty()) {
            new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.MID_TIER).apply(graph, context);
        }
        assertNotInGraph(graph, MacroNode.class);
        if (name != null) {
            for (Node node : graph.getNodes()) {
                if (node instanceof Invoke) {
                    Invoke invoke = (Invoke) node;
                    if (invoke.callTarget() instanceof MethodCallTargetNode) {
                        MethodCallTargetNode call = (MethodCallTargetNode) invoke.callTarget();
                        assertTrue(!call.targetMethod().getName().equals(name), "Unexpected invoke of intrinsic %s", call.targetMethod());
                    }
                }
            }
        } else {
            assertNotInGraph(graph, Invoke.class);
        }
        return graph;
    } catch (Throwable e) {
        throw debug.handle(e);
    }
}
Also used : MacroNode(org.graalvm.compiler.replacements.nodes.MacroNode) Node(org.graalvm.compiler.graph.Node) MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) LoweringPhase(org.graalvm.compiler.phases.common.LoweringPhase) DebugContext(org.graalvm.compiler.debug.DebugContext) Invoke(org.graalvm.compiler.nodes.Invoke) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) MacroNode(org.graalvm.compiler.replacements.nodes.MacroNode) MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) CanonicalizerPhase(org.graalvm.compiler.phases.common.CanonicalizerPhase) HighTierContext(org.graalvm.compiler.phases.tiers.HighTierContext) InliningPhase(org.graalvm.compiler.phases.common.inlining.InliningPhase) DeadCodeEliminationPhase(org.graalvm.compiler.phases.common.DeadCodeEliminationPhase)

Example 37 with MethodCallTargetNode

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

the class VerifyVirtualizableUsage method verify.

@Override
protected boolean verify(StructuredGraph graph, PhaseContext context) {
    final ResolvedJavaType graphType = context.getMetaAccess().lookupJavaType(Graph.class);
    final ResolvedJavaType virtualizableType = context.getMetaAccess().lookupJavaType(Virtualizable.class);
    final ResolvedJavaType constantNodeType = context.getMetaAccess().lookupJavaType(ConstantNode.class);
    if (virtualizableType.isAssignableFrom(graph.method().getDeclaringClass()) && graph.method().getName().equals("virtualize")) {
        for (MethodCallTargetNode t : graph.getNodes(MethodCallTargetNode.TYPE)) {
            int bci = t.invoke().bci();
            ResolvedJavaMethod callee = t.targetMethod();
            String calleeName = callee.getName();
            if (callee.getDeclaringClass().equals(graphType)) {
                if (calleeName.equals("add") || calleeName.equals("addWithoutUnique") || calleeName.equals("addOrUnique") || calleeName.equals("addWithoutUniqueWithInputs") || calleeName.equals("addOrUniqueWithInputs")) {
                    verifyVirtualizableEffectArguments(constantNodeType, graph.method(), callee, bci, t.arguments(), 1);
                }
            }
        }
    }
    return true;
}
Also used : MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod)

Example 38 with MethodCallTargetNode

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

the class InliningUtil method checkInvokeConditions.

/**
 * @return null iff the check succeeds, otherwise a (non-null) descriptive message.
 */
public static String checkInvokeConditions(Invoke invoke) {
    if (invoke.predecessor() == null || !invoke.asNode().isAlive()) {
        return "the invoke is dead code";
    }
    if (!(invoke.callTarget() instanceof MethodCallTargetNode)) {
        return "the invoke has already been lowered, or has been created as a low-level node";
    }
    MethodCallTargetNode callTarget = (MethodCallTargetNode) invoke.callTarget();
    if (callTarget.targetMethod() == null) {
        return "target method is null";
    }
    assert invoke.stateAfter() != null : invoke;
    if (!invoke.useForInlining()) {
        return "the invoke is marked to be not used for inlining";
    }
    ValueNode receiver = callTarget.receiver();
    if (receiver != null && receiver.isConstant() && receiver.isNullConstant()) {
        return "receiver is null";
    }
    return null;
}
Also used : MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) ValueNode(org.graalvm.compiler.nodes.ValueNode)

Example 39 with MethodCallTargetNode

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

the class InliningUtil method inline.

/**
 * Performs an actual inlining, thereby replacing the given invoke with the given
 * {@code inlineGraph}.
 *
 * @param invoke the invoke that will be replaced
 * @param inlineGraph the graph that the invoke will be replaced with
 * @param receiverNullCheck true if a null check needs to be generated for non-static inlinings,
 *            false if no such check is required
 * @param inlineeMethod the actual method being inlined. Maybe be null for snippets.
 * @param reason the reason for inlining, used in tracing
 * @param phase the phase that invoked inlining
 */
@SuppressWarnings("try")
public static UnmodifiableEconomicMap<Node, Node> inline(Invoke invoke, StructuredGraph inlineGraph, boolean receiverNullCheck, ResolvedJavaMethod inlineeMethod, String reason, String phase) {
    FixedNode invokeNode = invoke.asNode();
    StructuredGraph graph = invokeNode.graph();
    final NodeInputList<ValueNode> parameters = invoke.callTarget().arguments();
    assert inlineGraph.getGuardsStage().ordinal() >= graph.getGuardsStage().ordinal();
    assert !invokeNode.graph().isAfterFloatingReadPhase() : "inline isn't handled correctly after floating reads phase";
    if (receiverNullCheck && !((MethodCallTargetNode) invoke.callTarget()).isStatic()) {
        nonNullReceiver(invoke);
    }
    ArrayList<Node> nodes = new ArrayList<>(inlineGraph.getNodes().count());
    ArrayList<ReturnNode> returnNodes = new ArrayList<>(4);
    ArrayList<Invoke> partialIntrinsicExits = new ArrayList<>();
    UnwindNode unwindNode = null;
    final StartNode entryPointNode = inlineGraph.start();
    FixedNode firstCFGNode = entryPointNode.next();
    if (firstCFGNode == null) {
        throw new IllegalStateException("Inlined graph is in invalid state: " + inlineGraph);
    }
    for (Node node : inlineGraph.getNodes()) {
        if (node == entryPointNode || (node == entryPointNode.stateAfter() && node.usages().count() == 1) || node instanceof ParameterNode) {
        // Do nothing.
        } else {
            nodes.add(node);
            if (node instanceof ReturnNode) {
                returnNodes.add((ReturnNode) node);
            } else if (node instanceof Invoke) {
                Invoke invokeInInlineGraph = (Invoke) node;
                if (invokeInInlineGraph.bci() == BytecodeFrame.UNKNOWN_BCI) {
                    ResolvedJavaMethod target1 = inlineeMethod;
                    ResolvedJavaMethod target2 = invokeInInlineGraph.callTarget().targetMethod();
                    assert target1.equals(target2) : String.format("invoke in inlined method expected to be partial intrinsic exit (i.e., call to %s), not a call to %s", target1.format("%H.%n(%p)"), target2.format("%H.%n(%p)"));
                    partialIntrinsicExits.add(invokeInInlineGraph);
                }
            } else if (node instanceof UnwindNode) {
                assert unwindNode == null;
                unwindNode = (UnwindNode) node;
            }
        }
    }
    final AbstractBeginNode prevBegin = AbstractBeginNode.prevBegin(invokeNode);
    DuplicationReplacement localReplacement = new DuplicationReplacement() {

        @Override
        public Node replacement(Node node) {
            if (node instanceof ParameterNode) {
                return parameters.get(((ParameterNode) node).index());
            } else if (node == entryPointNode) {
                return prevBegin;
            }
            return node;
        }
    };
    assert invokeNode.successors().first() != null : invoke;
    assert invokeNode.predecessor() != null;
    Mark mark = graph.getMark();
    // Instead, attach the inlining log of the child graph to the current inlining log.
    EconomicMap<Node, Node> duplicates;
    try (InliningLog.UpdateScope scope = graph.getInliningLog().openDefaultUpdateScope()) {
        duplicates = graph.addDuplicates(nodes, inlineGraph, inlineGraph.getNodeCount(), localReplacement);
        if (scope != null) {
            graph.getInliningLog().addDecision(invoke, true, reason, phase, duplicates, inlineGraph.getInliningLog());
        }
    }
    FrameState stateAfter = invoke.stateAfter();
    assert stateAfter == null || stateAfter.isAlive();
    FrameState stateAtExceptionEdge = null;
    if (invoke instanceof InvokeWithExceptionNode) {
        InvokeWithExceptionNode invokeWithException = ((InvokeWithExceptionNode) invoke);
        if (unwindNode != null) {
            ExceptionObjectNode obj = (ExceptionObjectNode) invokeWithException.exceptionEdge();
            stateAtExceptionEdge = obj.stateAfter();
        }
    }
    updateSourcePositions(invoke, inlineGraph, duplicates, !Objects.equals(inlineGraph.method(), inlineeMethod), mark);
    if (stateAfter != null) {
        processFrameStates(invoke, inlineGraph, duplicates, stateAtExceptionEdge, returnNodes.size() > 1);
        int callerLockDepth = stateAfter.nestedLockDepth();
        if (callerLockDepth != 0) {
            for (MonitorIdNode original : inlineGraph.getNodes(MonitorIdNode.TYPE)) {
                MonitorIdNode monitor = (MonitorIdNode) duplicates.get(original);
                processMonitorId(invoke.stateAfter(), monitor);
            }
        }
    } else {
        assert checkContainsOnlyInvalidOrAfterFrameState(duplicates);
    }
    firstCFGNode = (FixedNode) duplicates.get(firstCFGNode);
    for (int i = 0; i < returnNodes.size(); i++) {
        returnNodes.set(i, (ReturnNode) duplicates.get(returnNodes.get(i)));
    }
    for (Invoke exit : partialIntrinsicExits) {
        // A partial intrinsic exit must be replaced with a call to
        // the intrinsified method.
        Invoke dup = (Invoke) duplicates.get(exit.asNode());
        if (dup instanceof InvokeNode) {
            InvokeNode repl = graph.add(new InvokeNode(invoke.callTarget(), invoke.bci()));
            dup.intrinsify(repl.asNode());
        } else {
            ((InvokeWithExceptionNode) dup).replaceWithNewBci(invoke.bci());
        }
    }
    if (unwindNode != null) {
        unwindNode = (UnwindNode) duplicates.get(unwindNode);
    }
    finishInlining(invoke, graph, firstCFGNode, returnNodes, unwindNode, inlineGraph.getAssumptions(), inlineGraph);
    GraphUtil.killCFG(invokeNode);
    return duplicates;
}
Also used : AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) BeginNode(org.graalvm.compiler.nodes.BeginNode) MonitorIdNode(org.graalvm.compiler.nodes.java.MonitorIdNode) MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) ReturnNode(org.graalvm.compiler.nodes.ReturnNode) CallTargetNode(org.graalvm.compiler.nodes.CallTargetNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) PiNode(org.graalvm.compiler.nodes.PiNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) MonitorExitNode(org.graalvm.compiler.nodes.java.MonitorExitNode) IsNullNode(org.graalvm.compiler.nodes.calc.IsNullNode) GuardingNode(org.graalvm.compiler.nodes.extended.GuardingNode) KillingBeginNode(org.graalvm.compiler.nodes.KillingBeginNode) StartNode(org.graalvm.compiler.nodes.StartNode) InvokeWithExceptionNode(org.graalvm.compiler.nodes.InvokeWithExceptionNode) ExceptionObjectNode(org.graalvm.compiler.nodes.java.ExceptionObjectNode) InvokeNode(org.graalvm.compiler.nodes.InvokeNode) ParameterNode(org.graalvm.compiler.nodes.ParameterNode) MergeNode(org.graalvm.compiler.nodes.MergeNode) DeoptimizeNode(org.graalvm.compiler.nodes.DeoptimizeNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) UnwindNode(org.graalvm.compiler.nodes.UnwindNode) Node(org.graalvm.compiler.graph.Node) EndNode(org.graalvm.compiler.nodes.EndNode) ForeignCallNode(org.graalvm.compiler.nodes.extended.ForeignCallNode) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) ArrayList(java.util.ArrayList) ExceptionObjectNode(org.graalvm.compiler.nodes.java.ExceptionObjectNode) Mark(org.graalvm.compiler.graph.Graph.Mark) FixedNode(org.graalvm.compiler.nodes.FixedNode) FrameState(org.graalvm.compiler.nodes.FrameState) Invoke(org.graalvm.compiler.nodes.Invoke) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) ParameterNode(org.graalvm.compiler.nodes.ParameterNode) UnwindNode(org.graalvm.compiler.nodes.UnwindNode) MonitorIdNode(org.graalvm.compiler.nodes.java.MonitorIdNode) StartNode(org.graalvm.compiler.nodes.StartNode) DuplicationReplacement(org.graalvm.compiler.graph.Graph.DuplicationReplacement) ReturnNode(org.graalvm.compiler.nodes.ReturnNode) MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) InvokeWithExceptionNode(org.graalvm.compiler.nodes.InvokeWithExceptionNode) InliningLog(org.graalvm.compiler.nodes.InliningLog) ValueNode(org.graalvm.compiler.nodes.ValueNode) InvokeNode(org.graalvm.compiler.nodes.InvokeNode) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod)

Example 40 with MethodCallTargetNode

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

the class InliningUtil method inlineMacroNode.

public static FixedWithNextNode inlineMacroNode(Invoke invoke, ResolvedJavaMethod concrete, Class<? extends FixedWithNextNode> macroNodeClass) throws GraalError {
    StructuredGraph graph = invoke.asNode().graph();
    if (!concrete.equals(((MethodCallTargetNode) invoke.callTarget()).targetMethod())) {
        assert ((MethodCallTargetNode) invoke.callTarget()).invokeKind().hasReceiver();
        InliningUtil.replaceInvokeCallTarget(invoke, graph, InvokeKind.Special, concrete);
    }
    FixedWithNextNode macroNode = createMacroNodeInstance(macroNodeClass, invoke);
    CallTargetNode callTarget = invoke.callTarget();
    if (invoke instanceof InvokeNode) {
        graph.replaceFixedWithFixed((InvokeNode) invoke, graph.add(macroNode));
    } else {
        InvokeWithExceptionNode invokeWithException = (InvokeWithExceptionNode) invoke;
        invokeWithException.killExceptionEdge();
        graph.replaceSplitWithFixed(invokeWithException, graph.add(macroNode), invokeWithException.next());
    }
    GraphUtil.killWithUnusedFloatingInputs(callTarget);
    return macroNode;
}
Also used : FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) InvokeWithExceptionNode(org.graalvm.compiler.nodes.InvokeWithExceptionNode) InvokeNode(org.graalvm.compiler.nodes.InvokeNode) MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) CallTargetNode(org.graalvm.compiler.nodes.CallTargetNode)

Aggregations

MethodCallTargetNode (org.graalvm.compiler.nodes.java.MethodCallTargetNode)46 ResolvedJavaType (jdk.vm.ci.meta.ResolvedJavaType)17 ResolvedJavaMethod (jdk.vm.ci.meta.ResolvedJavaMethod)15 ValueNode (org.graalvm.compiler.nodes.ValueNode)15 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)11 Invoke (org.graalvm.compiler.nodes.Invoke)10 Node (org.graalvm.compiler.graph.Node)9 InvokeNode (org.graalvm.compiler.nodes.InvokeNode)9 ArrayList (java.util.ArrayList)7 StampPair (org.graalvm.compiler.core.common.type.StampPair)7 PiNode (org.graalvm.compiler.nodes.PiNode)7 DebugContext (org.graalvm.compiler.debug.DebugContext)6 CallTargetNode (org.graalvm.compiler.nodes.CallTargetNode)6 AbstractBeginNode (org.graalvm.compiler.nodes.AbstractBeginNode)5 FixedWithNextNode (org.graalvm.compiler.nodes.FixedWithNextNode)5 FrameState (org.graalvm.compiler.nodes.FrameState)5 JavaType (jdk.vm.ci.meta.JavaType)4 ObjectStamp (org.graalvm.compiler.core.common.type.ObjectStamp)4 AbstractMergeNode (org.graalvm.compiler.nodes.AbstractMergeNode)4 FixedGuardNode (org.graalvm.compiler.nodes.FixedGuardNode)4