Search in sources :

Example 41 with ParameterNode

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

the class IfCanonicalizerTest method test.

private void test(String snippet) {
    StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES);
    DebugContext debug = graph.getDebug();
    ParameterNode param = graph.getNodes(ParameterNode.TYPE).iterator().next();
    ConstantNode constant = ConstantNode.forInt(0, graph);
    for (Node n : param.usages().snapshot()) {
        if (!(n instanceof FrameState)) {
            n.replaceFirstInput(param, constant);
        }
    }
    debug.dump(DebugContext.BASIC_LEVEL, graph, "Graph");
    new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders()));
    for (FrameState fs : param.usages().filter(FrameState.class).snapshot()) {
        fs.replaceFirstInput(param, null);
        param.safeDelete();
    }
    StructuredGraph referenceGraph = parseEager(REFERENCE_SNIPPET, AllowAssumptions.YES);
    assertEquals(referenceGraph, graph);
}
Also used : PhaseContext(org.graalvm.compiler.phases.tiers.PhaseContext) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) ParameterNode(org.graalvm.compiler.nodes.ParameterNode) IfNode(org.graalvm.compiler.nodes.IfNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) Node(org.graalvm.compiler.graph.Node) ParameterNode(org.graalvm.compiler.nodes.ParameterNode) CanonicalizerPhase(org.graalvm.compiler.phases.common.CanonicalizerPhase) DebugContext(org.graalvm.compiler.debug.DebugContext) FrameState(org.graalvm.compiler.nodes.FrameState)

Example 42 with ParameterNode

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

the class NodeLIRBuilder method emitPrologue.

protected void emitPrologue(StructuredGraph graph) {
    CallingConvention incomingArguments = gen.getResult().getCallingConvention();
    Value[] params = new Value[incomingArguments.getArgumentCount()];
    for (int i = 0; i < params.length; i++) {
        params[i] = incomingArguments.getArgument(i);
        if (ValueUtil.isStackSlot(params[i])) {
            StackSlot slot = ValueUtil.asStackSlot(params[i]);
            if (slot.isInCallerFrame() && !gen.getResult().getLIR().hasArgInCallerFrame()) {
                gen.getResult().getLIR().setHasArgInCallerFrame();
            }
        }
    }
    gen.emitIncomingValues(params);
    for (ParameterNode param : graph.getNodes(ParameterNode.TYPE)) {
        Value paramValue = params[param.index()];
        assert paramValue.getValueKind().equals(getLIRGeneratorTool().getLIRKind(param.stamp(NodeView.DEFAULT))) : paramValue + " " + getLIRGeneratorTool().getLIRKind(param.stamp(NodeView.DEFAULT));
        setResult(param, gen.emitMove(paramValue));
    }
}
Also used : CallingConvention(jdk.vm.ci.code.CallingConvention) ParameterNode(org.graalvm.compiler.nodes.ParameterNode) ComplexMatchValue(org.graalvm.compiler.core.match.ComplexMatchValue) Value(jdk.vm.ci.meta.Value) AllocatableValue(jdk.vm.ci.meta.AllocatableValue) StackSlot(jdk.vm.ci.code.StackSlot)

Example 43 with ParameterNode

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

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

the class InliningData method freshlyInstantiatedArguments.

/**
 * Gets the freshly instantiated arguments.
 * <p>
 * A freshly instantiated argument is either:
 * <uL>
 * <li>an {@link InliningData#isFreshInstantiation(org.graalvm.compiler.nodes.ValueNode)}</li>
 * <li>a fixed-param, ie a {@link ParameterNode} receiving a freshly instantiated argument</li>
 * </uL>
 * </p>
 *
 * @return the positions of freshly instantiated arguments in the argument list of the
 *         <code>invoke</code>, or null if no such positions exist.
 */
public static BitSet freshlyInstantiatedArguments(Invoke invoke, EconomicSet<ParameterNode> fixedParams) {
    assert fixedParams != null;
    assert paramsAndInvokeAreInSameGraph(invoke, fixedParams);
    BitSet result = null;
    int argIdx = 0;
    for (ValueNode arg : invoke.callTarget().arguments()) {
        assert arg != null;
        if (isFreshInstantiation(arg) || (arg instanceof ParameterNode && fixedParams.contains((ParameterNode) arg))) {
            if (result == null) {
                result = new BitSet();
            }
            result.set(argIdx);
        }
        argIdx++;
    }
    return result;
}
Also used : ParameterNode(org.graalvm.compiler.nodes.ParameterNode) BitSet(java.util.BitSet) ValueNode(org.graalvm.compiler.nodes.ValueNode)

Example 45 with ParameterNode

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

the class InlineableGraph method replaceParamsWithMoreInformativeArguments.

/**
 * This method detects:
 * <ul>
 * <li>constants among the arguments to the <code>invoke</code></li>
 * <li>arguments with more precise type than that declared by the corresponding parameter</li>
 * </ul>
 *
 * <p>
 * The corresponding parameters are updated to reflect the above information. Before doing so,
 * their usages are added to <code>parameterUsages</code> for later incremental
 * canonicalization.
 * </p>
 *
 * @return null if no incremental canonicalization is need, a list of nodes for such
 *         canonicalization otherwise.
 */
private ArrayList<Node> replaceParamsWithMoreInformativeArguments(final Invoke invoke, final HighTierContext context) {
    NodeInputList<ValueNode> args = invoke.callTarget().arguments();
    ArrayList<Node> parameterUsages = null;
    List<ParameterNode> params = graph.getNodes(ParameterNode.TYPE).snapshot();
    assert params.size() <= args.size();
    /*
         * param-nodes that aren't used (eg, as a result of canonicalization) don't occur in
         * `params`. Thus, in general, the sizes of `params` and `args` don't always match. Still,
         * it's always possible to pair a param-node with its corresponding arg-node using
         * param.index() as index into `args`.
         */
    for (ParameterNode param : params) {
        if (param.usages().isNotEmpty()) {
            ValueNode arg = args.get(param.index());
            if (arg.isConstant()) {
                ConstantNode constant = (ConstantNode) arg;
                parameterUsages = trackParameterUsages(param, parameterUsages);
                // collect param usages before replacing the param
                param.replaceAtUsagesAndDelete(graph.unique(ConstantNode.forConstant(arg.stamp(NodeView.DEFAULT), constant.getValue(), constant.getStableDimension(), constant.isDefaultStable(), context.getMetaAccess())));
            // param-node gone, leaving a gap in the sequence given by param.index()
            } else {
                Stamp impro = improvedStamp(arg, param);
                if (impro != null) {
                    param.setStamp(impro);
                    parameterUsages = trackParameterUsages(param, parameterUsages);
                } else {
                    assert !isArgMoreInformativeThanParam(arg, param);
                }
            }
        }
    }
    assert (parameterUsages == null) || (!parameterUsages.isEmpty());
    return parameterUsages;
}
Also used : ConstantNode(org.graalvm.compiler.nodes.ConstantNode) ParameterNode(org.graalvm.compiler.nodes.ParameterNode) Stamp(org.graalvm.compiler.core.common.type.Stamp) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) Node(org.graalvm.compiler.graph.Node) ParameterNode(org.graalvm.compiler.nodes.ParameterNode) ValueNode(org.graalvm.compiler.nodes.ValueNode)

Aggregations

ParameterNode (org.graalvm.compiler.nodes.ParameterNode)46 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)19 ValueNode (org.graalvm.compiler.nodes.ValueNode)19 Node (org.graalvm.compiler.graph.Node)13 ConstantNode (org.graalvm.compiler.nodes.ConstantNode)13 ReturnNode (org.graalvm.compiler.nodes.ReturnNode)13 Test (org.junit.Test)10 ResolvedJavaMethod (jdk.vm.ci.meta.ResolvedJavaMethod)9 ResolvedJavaType (jdk.vm.ci.meta.ResolvedJavaType)8 DebugContext (org.graalvm.compiler.debug.DebugContext)7 FixedWithNextNode (org.graalvm.compiler.nodes.FixedWithNextNode)7 FrameState (org.graalvm.compiler.nodes.FrameState)7 InvokeWithExceptionNode (org.graalvm.compiler.nodes.InvokeWithExceptionNode)7 FixedNode (org.graalvm.compiler.nodes.FixedNode)6 CanonicalizerPhase (org.graalvm.compiler.phases.common.CanonicalizerPhase)6 AbstractMergeNode (org.graalvm.compiler.nodes.AbstractMergeNode)5 InvokeNode (org.graalvm.compiler.nodes.InvokeNode)5 PhiNode (org.graalvm.compiler.nodes.PhiNode)5 ArrayList (java.util.ArrayList)4 JavaConstant (jdk.vm.ci.meta.JavaConstant)4