Search in sources :

Example 6 with PhiNode

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

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

the class GraphUtil method checkRedundantPhi.

public static void checkRedundantPhi(PhiNode phiNode) {
    if (phiNode.isDeleted() || phiNode.valueCount() == 1) {
        return;
    }
    ValueNode singleValue = phiNode.singleValueOrThis();
    if (singleValue != phiNode) {
        Collection<PhiNode> phiUsages = phiNode.usages().filter(PhiNode.class).snapshot();
        Collection<ProxyNode> proxyUsages = phiNode.usages().filter(ProxyNode.class).snapshot();
        phiNode.replaceAtUsagesAndDelete(singleValue);
        for (PhiNode phi : phiUsages) {
            checkRedundantPhi(phi);
        }
        for (ProxyNode proxy : proxyUsages) {
            checkRedundantProxy(proxy);
        }
    }
}
Also used : ProxyNode(org.graalvm.compiler.nodes.ProxyNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) ValueNode(org.graalvm.compiler.nodes.ValueNode)

Example 8 with PhiNode

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

the class UnsafeEATest method testMergedDouble.

@Test
public void testMergedDouble() {
    testEscapeAnalysis("testMergedDoubleSnippet", null, false);
    Assert.assertEquals(1, returnNodes.size());
    Assert.assertTrue(returnNodes.get(0).result() instanceof ValuePhiNode);
    PhiNode phi = (PhiNode) returnNodes.get(0).result();
    Assert.assertTrue(phi.valueAt(0) instanceof LoadFieldNode);
    Assert.assertTrue(phi.valueAt(1) instanceof LoadFieldNode);
}
Also used : ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) LoadFieldNode(org.graalvm.compiler.nodes.java.LoadFieldNode) Test(org.junit.Test)

Example 9 with PhiNode

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

the class EAMergingTest method testSimpleMerge.

@Test
public void testSimpleMerge() {
    testEscapeAnalysis("simpleMergeSnippet", null, false);
    assertDeepEquals(1, returnNodes.size());
    assertTrue(returnNodes.get(0).result() instanceof ValuePhiNode);
    PhiNode phi = (PhiNode) returnNodes.get(0).result();
    assertTrue(phi.valueAt(0) instanceof ParameterNode);
    assertTrue(phi.valueAt(1) instanceof ParameterNode);
}
Also used : ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) ParameterNode(org.graalvm.compiler.nodes.ParameterNode) ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) Test(org.junit.Test)

Example 10 with PhiNode

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

the class NodeLIRBuilder method createPhiOut.

private Value[] createPhiOut(AbstractMergeNode merge, AbstractEndNode pred) {
    List<Value> values = new ArrayList<>();
    for (PhiNode phi : merge.valuePhis()) {
        ValueNode node = phi.valueAt(pred);
        Value value = operand(node);
        assert value != null;
        if (isRegister(value)) {
            /*
                 * Fixed register intervals are not allowed at block boundaries so we introduce a
                 * new Variable.
                 */
            value = gen.emitMove(value);
        } else if (!allowObjectConstantToStackMove() && node instanceof ConstantNode && !LIRKind.isValue(value)) {
            /*
                 * Some constants are not allowed as inputs for PHIs in certain backends. Explicitly
                 * create a copy of this value to force it into a register. The new variable is only
                 * used in the PHI.
                 */
            Variable result = gen.newVariable(value.getValueKind());
            gen.emitMove(result, value);
            value = result;
        }
        values.add(value);
    }
    return values.toArray(new Value[values.size()]);
}
Also used : LogicConstantNode(org.graalvm.compiler.nodes.LogicConstantNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) Variable(org.graalvm.compiler.lir.Variable) ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) ComplexMatchValue(org.graalvm.compiler.core.match.ComplexMatchValue) Value(jdk.vm.ci.meta.Value) AllocatableValue(jdk.vm.ci.meta.AllocatableValue) ArrayList(java.util.ArrayList) ValueNode(org.graalvm.compiler.nodes.ValueNode)

Aggregations

PhiNode (org.graalvm.compiler.nodes.PhiNode)41 ValueNode (org.graalvm.compiler.nodes.ValueNode)31 Node (org.graalvm.compiler.graph.Node)22 AbstractMergeNode (org.graalvm.compiler.nodes.AbstractMergeNode)21 FixedNode (org.graalvm.compiler.nodes.FixedNode)21 LoopBeginNode (org.graalvm.compiler.nodes.LoopBeginNode)19 ValuePhiNode (org.graalvm.compiler.nodes.ValuePhiNode)18 AbstractBeginNode (org.graalvm.compiler.nodes.AbstractBeginNode)17 ConstantNode (org.graalvm.compiler.nodes.ConstantNode)17 AbstractEndNode (org.graalvm.compiler.nodes.AbstractEndNode)15 EndNode (org.graalvm.compiler.nodes.EndNode)15 FixedWithNextNode (org.graalvm.compiler.nodes.FixedWithNextNode)15 ProxyNode (org.graalvm.compiler.nodes.ProxyNode)14 LoopExitNode (org.graalvm.compiler.nodes.LoopExitNode)13 FrameState (org.graalvm.compiler.nodes.FrameState)10 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)10 VirtualObjectNode (org.graalvm.compiler.nodes.virtual.VirtualObjectNode)10 MergeNode (org.graalvm.compiler.nodes.MergeNode)9 PiNode (org.graalvm.compiler.nodes.PiNode)9 BeginNode (org.graalvm.compiler.nodes.BeginNode)7