Search in sources :

Example 36 with ReturnNode

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

the class PointerTest method assertWrite.

private void assertWrite(StructuredGraph graph, boolean indexConvert, LocationIdentity locationIdentity) {
    WordCastNode cast = (WordCastNode) graph.start().next();
    JavaWriteNode write = (JavaWriteNode) cast.next();
    Assert.assertEquals(graph.getParameter(2), write.value());
    Assert.assertEquals(BytecodeFrame.AFTER_BCI, write.stateAfter().bci);
    OffsetAddressNode address = (OffsetAddressNode) write.getAddress();
    Assert.assertEquals(cast, address.getBase());
    Assert.assertEquals(graph.getParameter(0), cast.getInput());
    Assert.assertEquals(target.wordJavaKind, cast.stamp(NodeView.DEFAULT).getStackKind());
    Assert.assertEquals(locationIdentity, write.getLocationIdentity());
    if (indexConvert) {
        SignExtendNode convert = (SignExtendNode) address.getOffset();
        Assert.assertEquals(convert.getInputBits(), 32);
        Assert.assertEquals(convert.getResultBits(), 64);
        Assert.assertEquals(graph.getParameter(1), convert.getValue());
    } else {
        Assert.assertEquals(graph.getParameter(1), address.getOffset());
    }
    ReturnNode ret = (ReturnNode) write.next();
    Assert.assertEquals(null, ret.result());
}
Also used : ReturnNode(org.graalvm.compiler.nodes.ReturnNode) WordCastNode(org.graalvm.compiler.word.WordCastNode) OffsetAddressNode(org.graalvm.compiler.nodes.memory.address.OffsetAddressNode) SignExtendNode(org.graalvm.compiler.nodes.calc.SignExtendNode) JavaWriteNode(org.graalvm.compiler.nodes.extended.JavaWriteNode)

Example 37 with ReturnNode

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

the class SubstitutionsTest method checkHighTierGraph.

@Override
protected boolean checkHighTierGraph(StructuredGraph graph) {
    // Check that the graph contains the expected test nodes.
    NodeIterable<ReturnNode> retNodes = graph.getNodes().filter(ReturnNode.class);
    Assert.assertTrue("expected exactly one ReturnNode", retNodes.count() == 1);
    ReturnNode ret = retNodes.first();
    Assert.assertThat(ret.result(), instanceOf(TestValue.class));
    TestValue value = (TestValue) ret.result();
    Assert.assertThat(value.guard, instanceOf(TestGuard.class));
    TestGuard guard = (TestGuard) value.guard;
    Assert.assertThat(guard.memory, instanceOf(TestMemory.class));
    TestMemory memory = (TestMemory) guard.memory;
    // Remove the test nodes, replacing them by the constant 42.
    // This implicitly makes sure that the rest of the graph is valid.
    ret.replaceFirstInput(value, graph.unique(ConstantNode.forInt(42)));
    value.safeDelete();
    guard.safeDelete();
    graph.removeFixed(memory);
    return true;
}
Also used : ReturnNode(org.graalvm.compiler.nodes.ReturnNode)

Example 38 with ReturnNode

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

the class EarlyReadEliminationTest method testPhi.

@Test
public void testPhi() {
    StructuredGraph graph = processMethod("testPhiSnippet", false);
    assertTrue(graph.getNodes().filter(LoadFieldNode.class).isEmpty());
    List<ReturnNode> returnNodes = graph.getNodes(ReturnNode.TYPE).snapshot();
    assertDeepEquals(2, returnNodes.size());
    assertTrue(returnNodes.get(0).predecessor() instanceof StoreFieldNode);
    assertTrue(returnNodes.get(1).predecessor() instanceof StoreFieldNode);
    assertTrue(returnNodes.get(0).result().isConstant());
    assertTrue(returnNodes.get(1).result().isConstant());
}
Also used : ReturnNode(org.graalvm.compiler.nodes.ReturnNode) StoreFieldNode(org.graalvm.compiler.nodes.java.StoreFieldNode) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) Test(org.junit.Test) GraalCompilerTest(org.graalvm.compiler.core.test.GraalCompilerTest)

Example 39 with ReturnNode

use of org.graalvm.compiler.nodes.ReturnNode 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 ReturnNode

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

the class ValueMergeUtil method mergeValueProducers.

public static <T> ValueNode mergeValueProducers(AbstractMergeNode merge, List<? extends T> valueProducers, Function<T, FixedWithNextNode> lastInstrFunction, Function<T, ValueNode> valueFunction) {
    ValueNode singleResult = null;
    PhiNode phiResult = null;
    for (T valueProducer : valueProducers) {
        ValueNode result = valueFunction.apply(valueProducer);
        if (result != null) {
            if (phiResult == null && (singleResult == null || singleResult == result)) {
                /* Only one result value, so no need yet for a phi node. */
                singleResult = result;
            } else if (phiResult == null) {
                /* Found a second result value, so create phi node. */
                phiResult = merge.graph().addWithoutUnique(new ValuePhiNode(result.stamp(NodeView.DEFAULT).unrestricted(), merge));
                for (int i = 0; i < merge.forwardEndCount(); i++) {
                    phiResult.addInput(singleResult);
                }
                phiResult.addInput(result);
            } else {
                /* Multiple return values, just add to existing phi node. */
                phiResult.addInput(result);
            }
        }
        // create and wire up a new EndNode
        EndNode endNode = merge.graph().add(new EndNode());
        merge.addForwardEnd(endNode);
        if (lastInstrFunction == null) {
            assert valueProducer instanceof ReturnNode || valueProducer instanceof UnwindNode;
            ((ControlSinkNode) valueProducer).replaceAndDelete(endNode);
        } else {
            FixedWithNextNode lastInstr = lastInstrFunction.apply(valueProducer);
            lastInstr.setNext(endNode);
        }
    }
    if (phiResult != null) {
        assert phiResult.verify();
        phiResult.inferStamp();
        return phiResult;
    } else {
        return singleResult;
    }
}
Also used : ReturnNode(org.graalvm.compiler.nodes.ReturnNode) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) EndNode(org.graalvm.compiler.nodes.EndNode) ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) UnwindNode(org.graalvm.compiler.nodes.UnwindNode) ControlSinkNode(org.graalvm.compiler.nodes.ControlSinkNode)

Aggregations

ReturnNode (org.graalvm.compiler.nodes.ReturnNode)40 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)22 ValueNode (org.graalvm.compiler.nodes.ValueNode)12 ParameterNode (org.graalvm.compiler.nodes.ParameterNode)11 DebugContext (org.graalvm.compiler.debug.DebugContext)10 Node (org.graalvm.compiler.graph.Node)10 FixedNode (org.graalvm.compiler.nodes.FixedNode)10 ResolvedJavaMethod (jdk.vm.ci.meta.ResolvedJavaMethod)8 Test (org.junit.Test)8 AbstractBeginNode (org.graalvm.compiler.nodes.AbstractBeginNode)7 AbstractMergeNode (org.graalvm.compiler.nodes.AbstractMergeNode)7 FixedWithNextNode (org.graalvm.compiler.nodes.FixedWithNextNode)7 FrameState (org.graalvm.compiler.nodes.FrameState)7 MergeNode (org.graalvm.compiler.nodes.MergeNode)7 StartNode (org.graalvm.compiler.nodes.StartNode)7 JavaConstant (jdk.vm.ci.meta.JavaConstant)6 PhiNode (org.graalvm.compiler.nodes.PhiNode)6 ControlSinkNode (org.graalvm.compiler.nodes.ControlSinkNode)5 DebugCloseable (org.graalvm.compiler.debug.DebugCloseable)4 BeginNode (org.graalvm.compiler.nodes.BeginNode)4