Search in sources :

Example 31 with PhiNode

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

the class GraphUtil method checkRedundantProxy.

public static void checkRedundantProxy(ProxyNode vpn) {
    if (vpn.isDeleted()) {
        return;
    }
    AbstractBeginNode proxyPoint = vpn.proxyPoint();
    if (proxyPoint instanceof LoopExitNode) {
        LoopExitNode exit = (LoopExitNode) proxyPoint;
        LoopBeginNode loopBegin = exit.loopBegin();
        Node vpnValue = vpn.value();
        for (ValueNode v : loopBegin.stateAfter().values()) {
            ValueNode v2 = v;
            if (loopBegin.isPhiAtMerge(v2)) {
                v2 = ((PhiNode) v2).valueAt(loopBegin.forwardEnd());
            }
            if (vpnValue == v2) {
                Collection<PhiNode> phiUsages = vpn.usages().filter(PhiNode.class).snapshot();
                Collection<ProxyNode> proxyUsages = vpn.usages().filter(ProxyNode.class).snapshot();
                vpn.replaceAtUsagesAndDelete(vpnValue);
                for (PhiNode phi : phiUsages) {
                    checkRedundantPhi(phi);
                }
                for (ProxyNode proxy : proxyUsages) {
                    checkRedundantProxy(proxy);
                }
                return;
            }
        }
    }
}
Also used : ProxyNode(org.graalvm.compiler.nodes.ProxyNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) LoopExitNode(org.graalvm.compiler.nodes.LoopExitNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) MonitorIdNode(org.graalvm.compiler.nodes.java.MonitorIdNode) MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) LoadIndexedNode(org.graalvm.compiler.nodes.java.LoadIndexedNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) VirtualObjectNode(org.graalvm.compiler.nodes.virtual.VirtualObjectNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) PiNode(org.graalvm.compiler.nodes.PiNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) VirtualArrayNode(org.graalvm.compiler.nodes.virtual.VirtualArrayNode) GuardNode(org.graalvm.compiler.nodes.GuardNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) ControlSplitNode(org.graalvm.compiler.nodes.ControlSplitNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) LoopEndNode(org.graalvm.compiler.nodes.LoopEndNode) LoopExitNode(org.graalvm.compiler.nodes.LoopExitNode) Node(org.graalvm.compiler.graph.Node) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) ProxyNode(org.graalvm.compiler.nodes.ProxyNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode)

Example 32 with PhiNode

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

the class GraphUtil method killWithUnusedFloatingInputs.

public static void killWithUnusedFloatingInputs(Node node, boolean mayKillGuard) {
    assert checkKill(node, mayKillGuard);
    node.markDeleted();
    outer: for (Node in : node.inputs()) {
        if (in.isAlive()) {
            in.removeUsage(node);
            if (in.hasNoUsages()) {
                node.maybeNotifyZeroUsages(in);
            }
            if (isFloatingNode(in)) {
                if (in.hasNoUsages()) {
                    if (in instanceof GuardNode) {
                    // Guard nodes are only killed if their anchor dies.
                    } else {
                        killWithUnusedFloatingInputs(in);
                    }
                } else if (in instanceof PhiNode) {
                    for (Node use : in.usages()) {
                        if (use != in) {
                            continue outer;
                        }
                    }
                    in.replaceAtUsages(null);
                    killWithUnusedFloatingInputs(in);
                }
            }
        }
    }
}
Also used : PhiNode(org.graalvm.compiler.nodes.PhiNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) MonitorIdNode(org.graalvm.compiler.nodes.java.MonitorIdNode) MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) LoadIndexedNode(org.graalvm.compiler.nodes.java.LoadIndexedNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) VirtualObjectNode(org.graalvm.compiler.nodes.virtual.VirtualObjectNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) PiNode(org.graalvm.compiler.nodes.PiNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) VirtualArrayNode(org.graalvm.compiler.nodes.virtual.VirtualArrayNode) GuardNode(org.graalvm.compiler.nodes.GuardNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) ControlSplitNode(org.graalvm.compiler.nodes.ControlSplitNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) LoopEndNode(org.graalvm.compiler.nodes.LoopEndNode) LoopExitNode(org.graalvm.compiler.nodes.LoopExitNode) Node(org.graalvm.compiler.graph.Node) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) ProxyNode(org.graalvm.compiler.nodes.ProxyNode) GuardNode(org.graalvm.compiler.nodes.GuardNode)

Example 33 with PhiNode

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

the class GraphUtil method originalValueSimple.

private static ValueNode originalValueSimple(ValueNode value) {
    /* The very simple case: look through proxies. */
    ValueNode cur = originalValueForProxy(value);
    while (cur instanceof PhiNode) {
        /*
             * We found a phi function. Check if we can analyze it without allocating temporary data
             * structures.
             */
        PhiNode phi = (PhiNode) cur;
        ValueNode phiSingleValue = null;
        int count = phi.valueCount();
        for (int i = 0; i < count; ++i) {
            ValueNode phiCurValue = originalValueForProxy(phi.valueAt(i));
            if (phiCurValue == phi) {
            /* Simple cycle, we can ignore the input value. */
            } else if (phiSingleValue == null) {
                /* The first input. */
                phiSingleValue = phiCurValue;
            } else if (phiSingleValue != phiCurValue) {
                if (phiSingleValue instanceof PhiNode || phiCurValue instanceof PhiNode) {
                    /*
                         * We have two different input values for the phi function, and at least one
                         * of the inputs is another phi function. We need to do a complicated
                         * exhaustive check.
                         */
                    return originalValueForComplicatedPhi(phi, new NodeBitMap(value.graph()));
                } else {
                    /*
                         * We have two different input values for the phi function, but none of them
                         * is another phi function. This phi function cannot be reduce any further,
                         * so the phi function is the original value.
                         */
                    return phi;
                }
            }
        }
        /*
             * Successfully reduced the phi function to a single input value. The single input value
             * can itself be a phi function again, so we might take another loop iteration.
             */
        assert phiSingleValue != null;
        cur = phiSingleValue;
    }
    /* We reached a "normal" node, which is the original value. */
    assert !(cur instanceof LimitedValueProxy) && !(cur instanceof PhiNode);
    return cur;
}
Also used : PhiNode(org.graalvm.compiler.nodes.PhiNode) NodeBitMap(org.graalvm.compiler.graph.NodeBitMap) ValueNode(org.graalvm.compiler.nodes.ValueNode) LimitedValueProxy(org.graalvm.compiler.nodes.spi.LimitedValueProxy)

Example 34 with PhiNode

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

the class GraphUtil method originalValueForComplicatedPhi.

/**
 * Handling for complicated nestings of phi functions. We need to reduce phi functions
 * recursively, and need a temporary map of visited nodes to avoid endless recursion of cycles.
 */
private static ValueNode originalValueForComplicatedPhi(PhiNode phi, NodeBitMap visited) {
    if (visited.isMarked(phi)) {
        /*
             * Found a phi function that was already seen. Either a cycle, or just a second phi
             * input to a path we have already processed.
             */
        return null;
    }
    visited.mark(phi);
    ValueNode phiSingleValue = null;
    int count = phi.valueCount();
    for (int i = 0; i < count; ++i) {
        ValueNode phiCurValue = originalValueForProxy(phi.valueAt(i));
        if (phiCurValue instanceof PhiNode) {
            /* Recursively process a phi function input. */
            phiCurValue = originalValueForComplicatedPhi((PhiNode) phiCurValue, visited);
        }
        if (phiCurValue == null) {
        /* Cycle to a phi function that was already seen. We can ignore this input. */
        } else if (phiSingleValue == null) {
            /* The first input. */
            phiSingleValue = phiCurValue;
        } else if (phiCurValue != phiSingleValue) {
            /*
                 * Another input that is different from the first input. Since we already
                 * recursively looked through other phi functions, we now know that this phi
                 * function cannot be reduce any further, so the phi function is the original value.
                 */
            return phi;
        }
    }
    return phiSingleValue;
}
Also used : PhiNode(org.graalvm.compiler.nodes.PhiNode) ValueNode(org.graalvm.compiler.nodes.ValueNode)

Example 35 with PhiNode

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

the class LoadFieldNode method asPhi.

private static PhiNode asPhi(ConstantFieldProvider constantFields, ConstantReflectionProvider constantReflection, MetaAccessProvider metaAcccess, OptionValues options, ValueNode forObject, ResolvedJavaField field, Stamp stamp) {
    if (!field.isStatic() && field.isFinal() && forObject instanceof ValuePhiNode && ((ValuePhiNode) forObject).values().filter(isNotA(ConstantNode.class)).isEmpty()) {
        PhiNode phi = (PhiNode) forObject;
        ConstantNode[] constantNodes = new ConstantNode[phi.valueCount()];
        for (int i = 0; i < phi.valueCount(); i++) {
            ConstantNode constant = ConstantFoldUtil.tryConstantFold(constantFields, constantReflection, metaAcccess, field, phi.valueAt(i).asJavaConstant(), options);
            if (constant == null) {
                return null;
            }
            constantNodes[i] = constant;
        }
        return new ValuePhiNode(stamp, phi.merge(), constantNodes);
    }
    return null;
}
Also used : ConstantNode(org.graalvm.compiler.nodes.ConstantNode) ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode)

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