Search in sources :

Example 1 with EndNode

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

the class ConvertDeoptimizeToGuardPhase method processFixedGuardAndMerge.

@SuppressWarnings("try")
private void processFixedGuardAndMerge(FixedGuardNode fixedGuard, PhaseContext context, CompareNode compare, ValueNode x, ValuePhiNode xPhi, ValueNode y, ValuePhiNode yPhi, AbstractMergeNode merge) {
    List<EndNode> mergePredecessors = merge.cfgPredecessors().snapshot();
    for (int i = 0; i < mergePredecessors.size(); ++i) {
        AbstractEndNode mergePredecessor = mergePredecessors.get(i);
        if (!mergePredecessor.isAlive()) {
            break;
        }
        Constant xs;
        if (xPhi == null) {
            xs = x.asConstant();
        } else {
            xs = xPhi.valueAt(mergePredecessor).asConstant();
        }
        Constant ys;
        if (yPhi == null) {
            ys = y.asConstant();
        } else {
            ys = yPhi.valueAt(mergePredecessor).asConstant();
        }
        if (xs != null && ys != null && compare.condition().foldCondition(xs, ys, context.getConstantReflection(), compare.unorderedIsTrue()) == fixedGuard.isNegated()) {
            try (DebugCloseable position = fixedGuard.withNodeSourcePosition()) {
                propagateFixed(mergePredecessor, fixedGuard, context.getLowerer());
            }
        }
    }
}
Also used : AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) EndNode(org.graalvm.compiler.nodes.EndNode) Constant(jdk.vm.ci.meta.Constant) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) DebugCloseable(org.graalvm.compiler.debug.DebugCloseable)

Example 2 with EndNode

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

the class DeoptimizationGroupingPhase method run.

@Override
protected void run(StructuredGraph graph, MidTierContext context) {
    ControlFlowGraph cfg = null;
    for (FrameState fs : graph.getNodes(FrameState.TYPE)) {
        FixedNode target = null;
        PhiNode reasonActionPhi = null;
        PhiNode speculationPhi = null;
        List<AbstractDeoptimizeNode> obsoletes = null;
        for (AbstractDeoptimizeNode deopt : fs.usages().filter(AbstractDeoptimizeNode.class)) {
            if (target == null) {
                target = deopt;
            } else {
                if (cfg == null) {
                    cfg = ControlFlowGraph.compute(graph, true, true, false, false);
                }
                AbstractMergeNode merge;
                if (target instanceof AbstractDeoptimizeNode) {
                    merge = graph.add(new MergeNode());
                    EndNode firstEnd = graph.add(new EndNode());
                    ValueNode actionAndReason = ((AbstractDeoptimizeNode) target).getActionAndReason(context.getMetaAccess());
                    ValueNode speculation = ((AbstractDeoptimizeNode) target).getSpeculation(context.getMetaAccess());
                    reasonActionPhi = graph.addWithoutUnique(new ValuePhiNode(StampFactory.forKind(actionAndReason.getStackKind()), merge));
                    speculationPhi = graph.addWithoutUnique(new ValuePhiNode(StampFactory.forKind(speculation.getStackKind()), merge));
                    merge.addForwardEnd(firstEnd);
                    reasonActionPhi.addInput(actionAndReason);
                    speculationPhi.addInput(speculation);
                    target.replaceAtPredecessor(firstEnd);
                    exitLoops((AbstractDeoptimizeNode) target, firstEnd, cfg);
                    merge.setNext(graph.add(new DynamicDeoptimizeNode(reasonActionPhi, speculationPhi)));
                    obsoletes = new LinkedList<>();
                    obsoletes.add((AbstractDeoptimizeNode) target);
                    target = merge;
                } else {
                    merge = (AbstractMergeNode) target;
                }
                EndNode newEnd = graph.add(new EndNode());
                merge.addForwardEnd(newEnd);
                reasonActionPhi.addInput(deopt.getActionAndReason(context.getMetaAccess()));
                speculationPhi.addInput(deopt.getSpeculation(context.getMetaAccess()));
                deopt.replaceAtPredecessor(newEnd);
                exitLoops(deopt, newEnd, cfg);
                obsoletes.add(deopt);
            }
        }
        if (obsoletes != null) {
            ((DynamicDeoptimizeNode) ((AbstractMergeNode) target).next()).setStateBefore(fs);
            for (AbstractDeoptimizeNode obsolete : obsoletes) {
                obsolete.safeDelete();
            }
        }
    }
}
Also used : ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) DynamicDeoptimizeNode(org.graalvm.compiler.nodes.DynamicDeoptimizeNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) FrameState(org.graalvm.compiler.nodes.FrameState) AbstractDeoptimizeNode(org.graalvm.compiler.nodes.AbstractDeoptimizeNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) MergeNode(org.graalvm.compiler.nodes.MergeNode) EndNode(org.graalvm.compiler.nodes.EndNode) ControlFlowGraph(org.graalvm.compiler.nodes.cfg.ControlFlowGraph) ValueNode(org.graalvm.compiler.nodes.ValueNode)

Example 3 with EndNode

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

the class InliningUtil method fixFrameStates.

private static void fixFrameStates(StructuredGraph graph, MergeNode originalMerge, PhiNode returnPhi) {
    // It is possible that some of the frame states that came from AFTER_BCI reference a Phi
    // node that was created to merge multiple returns. This can create cycles
    // (see GR-3949 and GR-3957).
    // To detect this, we follow the control paths starting from the merge node,
    // split the Phi node inputs at merges and assign the proper input to each frame state.
    NodeMap<Node> seen = new NodeMap<>(graph);
    ArrayDeque<Node> workList = new ArrayDeque<>();
    ArrayDeque<ValueNode> valueList = new ArrayDeque<>();
    workList.push(originalMerge);
    valueList.push(returnPhi);
    while (!workList.isEmpty()) {
        Node current = workList.pop();
        ValueNode currentValue = valueList.pop();
        if (seen.containsKey(current)) {
            continue;
        }
        seen.put(current, current);
        if (current instanceof StateSplit && current != originalMerge) {
            StateSplit stateSplit = (StateSplit) current;
            FrameState state = stateSplit.stateAfter();
            if (state != null && state.values().contains(returnPhi)) {
                int index = 0;
                FrameState duplicate = state.duplicate();
                for (ValueNode value : state.values()) {
                    if (value == returnPhi) {
                        duplicate.values().set(index, currentValue);
                    }
                    index++;
                }
                stateSplit.setStateAfter(duplicate);
                GraphUtil.tryKillUnused(state);
            }
        }
        if (current instanceof AbstractMergeNode) {
            AbstractMergeNode currentMerge = (AbstractMergeNode) current;
            for (EndNode pred : currentMerge.cfgPredecessors()) {
                ValueNode newValue = currentValue;
                if (currentMerge.isPhiAtMerge(currentValue)) {
                    PhiNode currentPhi = (PhiNode) currentValue;
                    newValue = currentPhi.valueAt(pred);
                }
                workList.push(pred);
                valueList.push(newValue);
            }
        } else if (current.predecessor() != null) {
            workList.push(current.predecessor());
            valueList.push(currentValue);
        }
    }
}
Also used : PhiNode(org.graalvm.compiler.nodes.PhiNode) 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) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) FrameState(org.graalvm.compiler.nodes.FrameState) ArrayDeque(java.util.ArrayDeque) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) EndNode(org.graalvm.compiler.nodes.EndNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) NodeMap(org.graalvm.compiler.graph.NodeMap) StateSplit(org.graalvm.compiler.nodes.StateSplit)

Example 4 with EndNode

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

the class MultiTypeGuardInlineInfo method createInvocationBlock.

private static AbstractBeginNode createInvocationBlock(StructuredGraph graph, Invoke invoke, AbstractMergeNode returnMerge, PhiNode returnValuePhi, AbstractMergeNode exceptionMerge, PhiNode exceptionObjectPhi, boolean useForInlining) {
    Invoke duplicatedInvoke = duplicateInvokeForInlining(graph, invoke, exceptionMerge, exceptionObjectPhi, useForInlining);
    AbstractBeginNode calleeEntryNode = graph.add(new BeginNode());
    calleeEntryNode.setNext(duplicatedInvoke.asNode());
    EndNode endNode = graph.add(new EndNode());
    duplicatedInvoke.setNext(endNode);
    returnMerge.addForwardEnd(endNode);
    if (returnValuePhi != null) {
        returnValuePhi.addInput(duplicatedInvoke.asNode());
    }
    return calleeEntryNode;
}
Also used : EndNode(org.graalvm.compiler.nodes.EndNode) BeginNode(org.graalvm.compiler.nodes.BeginNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) Invoke(org.graalvm.compiler.nodes.Invoke) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode)

Example 5 with EndNode

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

the class SimpleCFGTest method testImplies.

@Test
public void testImplies() {
    OptionValues options = getInitialOptions();
    DebugContext debug = DebugContext.create(options, new GraalDebugHandlersFactory(getSnippetReflection()));
    StructuredGraph graph = new StructuredGraph.Builder(options, debug, AllowAssumptions.YES).build();
    EndNode trueEnd = graph.add(new EndNode());
    EndNode falseEnd = graph.add(new EndNode());
    AbstractBeginNode trueBegin = graph.add(new BeginNode());
    trueBegin.setNext(trueEnd);
    AbstractBeginNode falseBegin = graph.add(new BeginNode());
    falseBegin.setNext(falseEnd);
    IfNode ifNode = graph.add(new IfNode(null, trueBegin, falseBegin, 0.5));
    graph.start().setNext(ifNode);
    AbstractMergeNode merge = graph.add(new MergeNode());
    merge.addForwardEnd(trueEnd);
    merge.addForwardEnd(falseEnd);
    ReturnNode returnNode = graph.add(new ReturnNode(null));
    merge.setNext(returnNode);
    dumpGraph(graph);
    ControlFlowGraph cfg = ControlFlowGraph.compute(graph, true, true, true, true);
    Block[] blocks = cfg.getBlocks();
    // check number of blocks
    assertDeepEquals(4, blocks.length);
    // check block - node assignment
    assertDeepEquals(blocks[0], cfg.blockFor(graph.start()));
    assertDeepEquals(blocks[0], cfg.blockFor(ifNode));
    assertDeepEquals(blocks[1], cfg.blockFor(trueBegin));
    assertDeepEquals(blocks[1], cfg.blockFor(trueEnd));
    assertDeepEquals(blocks[2], cfg.blockFor(falseBegin));
    assertDeepEquals(blocks[2], cfg.blockFor(falseEnd));
    assertDeepEquals(blocks[3], cfg.blockFor(merge));
    assertDeepEquals(blocks[3], cfg.blockFor(returnNode));
    // check dominators
    assertDominator(blocks[0], null);
    assertDominator(blocks[1], blocks[0]);
    assertDominator(blocks[2], blocks[0]);
    assertDominator(blocks[3], blocks[0]);
    // check dominated
    assertDominatedSize(blocks[0], 3);
    assertDominatedSize(blocks[1], 0);
    assertDominatedSize(blocks[2], 0);
    assertDominatedSize(blocks[3], 0);
    // check postdominators
    assertPostdominator(blocks[0], blocks[3]);
    assertPostdominator(blocks[1], blocks[3]);
    assertPostdominator(blocks[2], blocks[3]);
    assertPostdominator(blocks[3], null);
}
Also used : OptionValues(org.graalvm.compiler.options.OptionValues) DebugContext(org.graalvm.compiler.debug.DebugContext) IfNode(org.graalvm.compiler.nodes.IfNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) GraalDebugHandlersFactory(org.graalvm.compiler.printer.GraalDebugHandlersFactory) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) MergeNode(org.graalvm.compiler.nodes.MergeNode) ReturnNode(org.graalvm.compiler.nodes.ReturnNode) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) EndNode(org.graalvm.compiler.nodes.EndNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) BeginNode(org.graalvm.compiler.nodes.BeginNode) ControlFlowGraph(org.graalvm.compiler.nodes.cfg.ControlFlowGraph) Block(org.graalvm.compiler.nodes.cfg.Block) Test(org.junit.Test)

Aggregations

EndNode (org.graalvm.compiler.nodes.EndNode)30 AbstractMergeNode (org.graalvm.compiler.nodes.AbstractMergeNode)22 FixedNode (org.graalvm.compiler.nodes.FixedNode)18 LoopBeginNode (org.graalvm.compiler.nodes.LoopBeginNode)16 FixedWithNextNode (org.graalvm.compiler.nodes.FixedWithNextNode)15 AbstractBeginNode (org.graalvm.compiler.nodes.AbstractBeginNode)14 LoopEndNode (org.graalvm.compiler.nodes.LoopEndNode)13 MergeNode (org.graalvm.compiler.nodes.MergeNode)13 Node (org.graalvm.compiler.graph.Node)12 AbstractEndNode (org.graalvm.compiler.nodes.AbstractEndNode)12 ValueNode (org.graalvm.compiler.nodes.ValueNode)10 LoopExitNode (org.graalvm.compiler.nodes.LoopExitNode)9 PhiNode (org.graalvm.compiler.nodes.PhiNode)9 BeginNode (org.graalvm.compiler.nodes.BeginNode)7 ControlSinkNode (org.graalvm.compiler.nodes.ControlSinkNode)7 ControlSplitNode (org.graalvm.compiler.nodes.ControlSplitNode)7 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)7 FrameState (org.graalvm.compiler.nodes.FrameState)6 IfNode (org.graalvm.compiler.nodes.IfNode)6 ValuePhiNode (org.graalvm.compiler.nodes.ValuePhiNode)6