Search in sources :

Example 46 with AbstractMergeNode

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

the class UseTrappingNullChecksPhase method tryUseTrappingNullCheck.

private static void tryUseTrappingNullCheck(MetaAccessProvider metaAccessProvider, DynamicDeoptimizeNode deopt, long implicitNullCheckLimit) {
    Node predecessor = deopt.predecessor();
    if (predecessor instanceof AbstractMergeNode) {
        AbstractMergeNode merge = (AbstractMergeNode) predecessor;
        // Process each predecessor at the merge, unpacking the reasons and speculations as
        // needed.
        ValueNode reason = deopt.getActionAndReason();
        ValuePhiNode reasonPhi = null;
        List<ValueNode> reasons = null;
        int expectedPhis = 0;
        if (reason instanceof ValuePhiNode) {
            reasonPhi = (ValuePhiNode) reason;
            if (reasonPhi.merge() != merge) {
                return;
            }
            reasons = reasonPhi.values().snapshot();
            expectedPhis++;
        } else if (!reason.isConstant()) {
            return;
        }
        ValueNode speculation = deopt.getSpeculation();
        ValuePhiNode speculationPhi = null;
        List<ValueNode> speculations = null;
        if (speculation instanceof ValuePhiNode) {
            speculationPhi = (ValuePhiNode) speculation;
            if (speculationPhi.merge() != merge) {
                return;
            }
            speculations = speculationPhi.values().snapshot();
            expectedPhis++;
        }
        if (merge.phis().count() != expectedPhis) {
            return;
        }
        int index = 0;
        for (AbstractEndNode end : merge.cfgPredecessors().snapshot()) {
            ValueNode thisReason = reasons != null ? reasons.get(index) : reason;
            ValueNode thisSpeculation = speculations != null ? speculations.get(index++) : speculation;
            if (!thisReason.isConstant() || !thisSpeculation.isConstant() || !thisSpeculation.asConstant().equals(JavaConstant.NULL_POINTER)) {
                continue;
            }
            DeoptimizationReason deoptimizationReason = metaAccessProvider.decodeDeoptReason(thisReason.asJavaConstant());
            tryUseTrappingNullCheck(deopt, end.predecessor(), deoptimizationReason, null, implicitNullCheckLimit);
        }
    }
}
Also used : ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) DynamicDeoptimizeNode(org.graalvm.compiler.nodes.DynamicDeoptimizeNode) FixedAccessNode(org.graalvm.compiler.nodes.memory.FixedAccessNode) DeoptimizingFixedWithNextNode(org.graalvm.compiler.nodes.DeoptimizingFixedWithNextNode) BeginNode(org.graalvm.compiler.nodes.BeginNode) DeoptimizeNode(org.graalvm.compiler.nodes.DeoptimizeNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) IfNode(org.graalvm.compiler.nodes.IfNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) CompressionNode(org.graalvm.compiler.nodes.CompressionNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) AbstractDeoptimizeNode(org.graalvm.compiler.nodes.AbstractDeoptimizeNode) AddressNode(org.graalvm.compiler.nodes.memory.address.AddressNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) IsNullNode(org.graalvm.compiler.nodes.calc.IsNullNode) NullCheckNode(org.graalvm.compiler.nodes.extended.NullCheckNode) Node(org.graalvm.compiler.graph.Node) ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) DeoptimizationReason(jdk.vm.ci.meta.DeoptimizationReason)

Example 47 with AbstractMergeNode

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

the class InliningUtil method handleMissingAfterExceptionFrameState.

public static FrameState handleMissingAfterExceptionFrameState(FrameState nonReplaceableFrameState, Invoke invoke, EconomicMap<Node, Node> replacements, boolean alwaysDuplicateStateAfter) {
    StructuredGraph graph = nonReplaceableFrameState.graph();
    NodeWorkList workList = graph.createNodeWorkList();
    workList.add(nonReplaceableFrameState);
    for (Node node : workList) {
        FrameState fs = (FrameState) node;
        for (Node usage : fs.usages().snapshot()) {
            if (!usage.isAlive()) {
                continue;
            }
            if (usage instanceof FrameState) {
                workList.add(usage);
            } else {
                StateSplit stateSplit = (StateSplit) usage;
                FixedNode fixedStateSplit = stateSplit.asNode();
                if (fixedStateSplit instanceof AbstractMergeNode) {
                    AbstractMergeNode merge = (AbstractMergeNode) fixedStateSplit;
                    while (merge.isAlive()) {
                        AbstractEndNode end = merge.forwardEnds().first();
                        DeoptimizeNode deoptimizeNode = addDeoptimizeNode(graph, DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.NotCompiledExceptionHandler);
                        end.replaceAtPredecessor(deoptimizeNode);
                        GraphUtil.killCFG(end);
                    }
                } else if (fixedStateSplit instanceof ExceptionObjectNode) {
                    // The target invoke does not have an exception edge. This means that the
                    // bytecode parser made the wrong assumption of making an
                    // InvokeWithExceptionNode for the partial intrinsic exit. We therefore
                    // replace the InvokeWithExceptionNode with a normal
                    // InvokeNode -- the deoptimization occurs when the invoke throws.
                    InvokeWithExceptionNode oldInvoke = (InvokeWithExceptionNode) fixedStateSplit.predecessor();
                    FrameState oldFrameState = oldInvoke.stateAfter();
                    InvokeNode newInvoke = oldInvoke.replaceWithInvoke();
                    newInvoke.setStateAfter(oldFrameState.duplicate());
                    if (replacements != null) {
                        replacements.put(oldInvoke, newInvoke);
                    }
                    handleAfterBciFrameState(newInvoke.stateAfter(), invoke, alwaysDuplicateStateAfter);
                } else {
                    FixedNode deoptimizeNode = addDeoptimizeNode(graph, DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.NotCompiledExceptionHandler);
                    if (fixedStateSplit instanceof AbstractBeginNode) {
                        deoptimizeNode = BeginNode.begin(deoptimizeNode);
                    }
                    fixedStateSplit.replaceAtPredecessor(deoptimizeNode);
                    GraphUtil.killCFG(fixedStateSplit);
                }
            }
        }
    }
    return nonReplaceableFrameState;
}
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) ExceptionObjectNode(org.graalvm.compiler.nodes.java.ExceptionObjectNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) FrameState(org.graalvm.compiler.nodes.FrameState) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) NodeWorkList(org.graalvm.compiler.graph.NodeWorkList) InvokeWithExceptionNode(org.graalvm.compiler.nodes.InvokeWithExceptionNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) InvokeNode(org.graalvm.compiler.nodes.InvokeNode) DeoptimizeNode(org.graalvm.compiler.nodes.DeoptimizeNode) StateSplit(org.graalvm.compiler.nodes.StateSplit)

Example 48 with AbstractMergeNode

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

the class ComputeInliningRelevance method createLoopScope.

/**
 * Determines the parent of the given loop and creates a {@link Scope} object for each one. This
 * method will call itself recursively if no {@link Scope} for the parent loop exists.
 */
private Scope createLoopScope(LoopBeginNode loopBegin, EconomicMap<LoopBeginNode, Scope> loops, Scope topScope) {
    Scope scope = loops.get(loopBegin);
    if (scope == null) {
        final Scope parent;
        // look for the parent scope
        FixedNode current = loopBegin.forwardEnd();
        while (true) {
            if (current.predecessor() == null) {
                if (current instanceof LoopBeginNode) {
                    // if we reach a LoopBeginNode then we're within this loop
                    parent = createLoopScope((LoopBeginNode) current, loops, topScope);
                    break;
                } else if (current instanceof StartNode) {
                    // we're within the outermost scope
                    parent = topScope;
                    break;
                } else {
                    assert current instanceof MergeNode : current;
                    // follow any path upwards - it doesn't matter which one
                    current = ((AbstractMergeNode) current).forwardEndAt(0);
                }
            } else if (current instanceof LoopExitNode) {
                // if we reach a loop exit then we follow this loop and have the same parent
                parent = createLoopScope(((LoopExitNode) current).loopBegin(), loops, topScope).parent;
                break;
            } else {
                current = (FixedNode) current.predecessor();
            }
        }
        scope = new Scope(loopBegin, parent);
        loops.put(loopBegin, scope);
    }
    return scope;
}
Also used : AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) MergeNode(org.graalvm.compiler.nodes.MergeNode) StartNode(org.graalvm.compiler.nodes.StartNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) LoopExitNode(org.graalvm.compiler.nodes.LoopExitNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode)

Example 49 with AbstractMergeNode

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

the class InliningIterator method queueMerge.

private void queueMerge(AbstractEndNode end) {
    AbstractMergeNode merge = end.merge();
    if (!queuedNodes.isMarked(merge) && visitedAllEnds(merge)) {
        queuedNodes.mark(merge);
        nodeQueue.add(merge);
    }
}
Also used : AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode)

Example 50 with AbstractMergeNode

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

the class InliningIterator method apply.

public LinkedList<Invoke> apply() {
    LinkedList<Invoke> invokes = new LinkedList<>();
    FixedNode current;
    forcedQueue(start);
    while ((current = nextQueuedNode()) != null) {
        assert current.isAlive();
        if (current instanceof Invoke && ((Invoke) current).callTarget() instanceof MethodCallTargetNode) {
            if (current != start) {
                invokes.addLast((Invoke) current);
            }
            queueSuccessors(current);
        } else if (current instanceof LoopBeginNode) {
            queueSuccessors(current);
        } else if (current instanceof LoopEndNode) {
        // nothing to do
        } else if (current instanceof AbstractMergeNode) {
            queueSuccessors(current);
        } else if (current instanceof FixedWithNextNode) {
            queueSuccessors(current);
        } else if (current instanceof EndNode) {
            queueMerge((EndNode) current);
        } else if (current instanceof ControlSinkNode) {
        // nothing to do
        } else if (current instanceof ControlSplitNode) {
            queueSuccessors(current);
        } else {
            assert false : current;
        }
    }
    assert invokes.size() == count(start.graph().getInvokes());
    return invokes;
}
Also used : FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) LoopEndNode(org.graalvm.compiler.nodes.LoopEndNode) EndNode(org.graalvm.compiler.nodes.EndNode) ControlSplitNode(org.graalvm.compiler.nodes.ControlSplitNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) ControlSinkNode(org.graalvm.compiler.nodes.ControlSinkNode) LinkedList(java.util.LinkedList) Invoke(org.graalvm.compiler.nodes.Invoke) LoopEndNode(org.graalvm.compiler.nodes.LoopEndNode)

Aggregations

AbstractMergeNode (org.graalvm.compiler.nodes.AbstractMergeNode)59 FixedNode (org.graalvm.compiler.nodes.FixedNode)31 AbstractBeginNode (org.graalvm.compiler.nodes.AbstractBeginNode)28 EndNode (org.graalvm.compiler.nodes.EndNode)24 Node (org.graalvm.compiler.graph.Node)22 AbstractEndNode (org.graalvm.compiler.nodes.AbstractEndNode)22 ValueNode (org.graalvm.compiler.nodes.ValueNode)22 FixedWithNextNode (org.graalvm.compiler.nodes.FixedWithNextNode)20 LoopBeginNode (org.graalvm.compiler.nodes.LoopBeginNode)19 PhiNode (org.graalvm.compiler.nodes.PhiNode)18 MergeNode (org.graalvm.compiler.nodes.MergeNode)16 ValuePhiNode (org.graalvm.compiler.nodes.ValuePhiNode)14 ControlSplitNode (org.graalvm.compiler.nodes.ControlSplitNode)13 LoopEndNode (org.graalvm.compiler.nodes.LoopEndNode)13 LoopExitNode (org.graalvm.compiler.nodes.LoopExitNode)13 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)12 ConstantNode (org.graalvm.compiler.nodes.ConstantNode)11 ArrayList (java.util.ArrayList)10 FrameState (org.graalvm.compiler.nodes.FrameState)10 IfNode (org.graalvm.compiler.nodes.IfNode)9