Search in sources :

Example 11 with AbstractEndNode

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

the class ReentrantNodeIterator method apply.

private static <StateT> EconomicMap<FixedNode, StateT> apply(NodeIteratorClosure<StateT> closure, FixedNode start, StateT initialState, LoopBeginNode boundary) {
    assert start != null;
    Deque<AbstractBeginNode> nodeQueue = new ArrayDeque<>();
    EconomicMap<FixedNode, StateT> blockEndStates = EconomicMap.create(Equivalence.IDENTITY);
    StateT state = initialState;
    FixedNode current = start;
    do {
        while (current instanceof FixedWithNextNode) {
            if (boundary != null && current instanceof LoopExitNode && ((LoopExitNode) current).loopBegin() == boundary) {
                blockEndStates.put(current, state);
                current = null;
            } else {
                FixedNode next = ((FixedWithNextNode) current).next();
                state = closure.processNode(current, state);
                current = closure.continueIteration(state) ? next : null;
            }
        }
        if (current != null) {
            state = closure.processNode(current, state);
            if (closure.continueIteration(state)) {
                Iterator<Node> successors = current.successors().iterator();
                if (!successors.hasNext()) {
                    if (current instanceof LoopEndNode) {
                        blockEndStates.put(current, state);
                    } else if (current instanceof EndNode) {
                        // add the end node and see if the merge is ready for processing
                        AbstractMergeNode merge = ((EndNode) current).merge();
                        if (merge instanceof LoopBeginNode) {
                            EconomicMap<LoopExitNode, StateT> loopExitState = closure.processLoop((LoopBeginNode) merge, state);
                            MapCursor<LoopExitNode, StateT> entry = loopExitState.getEntries();
                            while (entry.advance()) {
                                blockEndStates.put(entry.getKey(), entry.getValue());
                                nodeQueue.add(entry.getKey());
                            }
                        } else {
                            boolean endsVisited = true;
                            for (AbstractEndNode forwardEnd : merge.forwardEnds()) {
                                if (forwardEnd != current && !blockEndStates.containsKey(forwardEnd)) {
                                    endsVisited = false;
                                    break;
                                }
                            }
                            if (endsVisited) {
                                ArrayList<StateT> states = new ArrayList<>(merge.forwardEndCount());
                                for (int i = 0; i < merge.forwardEndCount(); i++) {
                                    AbstractEndNode forwardEnd = merge.forwardEndAt(i);
                                    assert forwardEnd == current || blockEndStates.containsKey(forwardEnd);
                                    StateT other = forwardEnd == current ? state : blockEndStates.removeKey(forwardEnd);
                                    states.add(other);
                                }
                                state = closure.merge(merge, states);
                                current = closure.continueIteration(state) ? merge : null;
                                continue;
                            } else {
                                assert !blockEndStates.containsKey(current);
                                blockEndStates.put(current, state);
                            }
                        }
                    }
                } else {
                    FixedNode firstSuccessor = (FixedNode) successors.next();
                    if (!successors.hasNext()) {
                        current = firstSuccessor;
                        continue;
                    } else {
                        do {
                            AbstractBeginNode successor = (AbstractBeginNode) successors.next();
                            StateT successorState = closure.afterSplit(successor, state);
                            if (closure.continueIteration(successorState)) {
                                blockEndStates.put(successor, successorState);
                                nodeQueue.add(successor);
                            }
                        } while (successors.hasNext());
                        state = closure.afterSplit((AbstractBeginNode) firstSuccessor, state);
                        current = closure.continueIteration(state) ? firstSuccessor : null;
                        continue;
                    }
                }
            }
        }
        // get next queued block
        if (nodeQueue.isEmpty()) {
            return blockEndStates;
        } else {
            current = nodeQueue.removeFirst();
            assert blockEndStates.containsKey(current);
            state = blockEndStates.removeKey(current);
            assert !(current instanceof AbstractMergeNode) && current instanceof AbstractBeginNode;
        }
    } while (true);
}
Also used : FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) LoopExitNode(org.graalvm.compiler.nodes.LoopExitNode) EconomicMap(org.graalvm.collections.EconomicMap) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) LoopEndNode(org.graalvm.compiler.nodes.LoopEndNode) LoopExitNode(org.graalvm.compiler.nodes.LoopExitNode) Node(org.graalvm.compiler.graph.Node) EndNode(org.graalvm.compiler.nodes.EndNode) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) ArrayList(java.util.ArrayList) FixedNode(org.graalvm.compiler.nodes.FixedNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) ArrayDeque(java.util.ArrayDeque) MapCursor(org.graalvm.collections.MapCursor) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) LoopEndNode(org.graalvm.compiler.nodes.LoopEndNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) LoopEndNode(org.graalvm.compiler.nodes.LoopEndNode) EndNode(org.graalvm.compiler.nodes.EndNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode)

Example 12 with AbstractEndNode

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

the class PartialEscapeClosure method stripKilledLoopLocations.

@Override
protected BlockT stripKilledLoopLocations(Loop<Block> loop, BlockT originalInitialState) {
    BlockT initialState = super.stripKilledLoopLocations(loop, originalInitialState);
    if (loop.getDepth() > GraalOptions.EscapeAnalysisLoopCutoff.getValue(cfg.graph.getOptions())) {
        /*
             * After we've reached the maximum loop nesting, we'll simply materialize everything we
             * can to make sure that the loops only need to be iterated one time. Care is taken here
             * to not materialize virtual objects that have the "ensureVirtualized" flag set.
             */
        LoopBeginNode loopBegin = (LoopBeginNode) loop.getHeader().getBeginNode();
        AbstractEndNode end = loopBegin.forwardEnd();
        Block loopPredecessor = loop.getHeader().getFirstPredecessor();
        assert loopPredecessor.getEndNode() == end;
        int length = initialState.getStateCount();
        boolean change;
        BitSet ensureVirtualized = new BitSet(length);
        for (int i = 0; i < length; i++) {
            ObjectState state = initialState.getObjectStateOptional(i);
            if (state != null && state.isVirtual() && state.getEnsureVirtualized()) {
                ensureVirtualized.set(i);
            }
        }
        do {
            // propagate "ensureVirtualized" flag
            change = false;
            for (int i = 0; i < length; i++) {
                if (!ensureVirtualized.get(i)) {
                    ObjectState state = initialState.getObjectStateOptional(i);
                    if (state != null && state.isVirtual()) {
                        for (ValueNode entry : state.getEntries()) {
                            if (entry instanceof VirtualObjectNode) {
                                if (ensureVirtualized.get(((VirtualObjectNode) entry).getObjectId())) {
                                    change = true;
                                    ensureVirtualized.set(i);
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        } while (change);
        for (int i = 0; i < length; i++) {
            ObjectState state = initialState.getObjectStateOptional(i);
            if (state != null && state.isVirtual() && !ensureVirtualized.get(i)) {
                initialState.materializeBefore(end, virtualObjects.get(i), blockEffects.get(loopPredecessor));
            }
        }
    }
    return initialState;
}
Also used : VirtualObjectNode(org.graalvm.compiler.nodes.virtual.VirtualObjectNode) VirtualObjectState(org.graalvm.compiler.virtual.nodes.VirtualObjectState) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) BitSet(java.util.BitSet) ValueNode(org.graalvm.compiler.nodes.ValueNode) Block(org.graalvm.compiler.nodes.cfg.Block)

Example 13 with AbstractEndNode

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

the class VirtualUtil method assertNonReachable.

public static boolean assertNonReachable(StructuredGraph graph, List<Node> obsoleteNodes) {
    // Helper code that determines the paths that keep obsolete nodes alive.
    // Nodes with support for GVN can be kept alive by GVN and are therefore not part of the
    // assertion.
    DebugContext debug = graph.getDebug();
    NodeFlood flood = graph.createNodeFlood();
    EconomicMap<Node, Node> path = EconomicMap.create(Equivalence.IDENTITY);
    flood.add(graph.start());
    for (Node current : flood) {
        if (current instanceof AbstractEndNode) {
            AbstractEndNode end = (AbstractEndNode) current;
            flood.add(end.merge());
            if (!path.containsKey(end.merge())) {
                path.put(end.merge(), end);
            }
        } else {
            for (Node successor : current.successors()) {
                flood.add(successor);
                if (!path.containsKey(successor)) {
                    path.put(successor, current);
                }
            }
        }
    }
    for (Node node : obsoleteNodes) {
        if (node instanceof FixedNode && !node.isDeleted()) {
            assert !flood.isMarked(node) : node;
        }
    }
    for (Node node : graph.getNodes()) {
        if (flood.isMarked(node)) {
            for (Node input : node.inputs()) {
                flood.add(input);
                if (!path.containsKey(input)) {
                    path.put(input, node);
                }
            }
        }
    }
    for (Node current : flood) {
        for (Node input : current.inputs()) {
            flood.add(input);
            if (!path.containsKey(input)) {
                path.put(input, current);
            }
        }
    }
    boolean success = true;
    for (Node node : obsoleteNodes) {
        if (!node.isDeleted() && flood.isMarked(node) && !node.getNodeClass().valueNumberable()) {
            TTY.println("offending node path:");
            Node current = node;
            TTY.print(current.toString());
            while (true) {
                current = path.get(current);
                if (current != null) {
                    TTY.print(" -> " + current.toString());
                    if (current instanceof FixedNode && !obsoleteNodes.contains(current)) {
                        break;
                    }
                }
            }
            success = false;
        }
    }
    if (!success) {
        TTY.println();
        debug.forceDump(graph, "assertNonReachable");
    }
    return success;
}
Also used : FixedNode(org.graalvm.compiler.nodes.FixedNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) Node(org.graalvm.compiler.graph.Node) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) DebugContext(org.graalvm.compiler.debug.DebugContext) FixedNode(org.graalvm.compiler.nodes.FixedNode) NodeFlood(org.graalvm.compiler.graph.NodeFlood)

Example 14 with AbstractEndNode

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

the class LoopFragmentInside method mergeEnds.

private AbstractBeginNode mergeEnds() {
    assert isDuplicate();
    List<EndNode> endsToMerge = new LinkedList<>();
    // map peel exits to the corresponding loop exits
    EconomicMap<AbstractEndNode, LoopEndNode> reverseEnds = EconomicMap.create(Equivalence.IDENTITY);
    LoopBeginNode loopBegin = original().loop().loopBegin();
    for (LoopEndNode le : loopBegin.loopEnds()) {
        AbstractEndNode duplicate = getDuplicatedNode(le);
        if (duplicate != null) {
            endsToMerge.add((EndNode) duplicate);
            reverseEnds.put(duplicate, le);
        }
    }
    mergedInitializers = EconomicMap.create(Equivalence.IDENTITY);
    AbstractBeginNode newExit;
    StructuredGraph graph = graph();
    if (endsToMerge.size() == 1) {
        AbstractEndNode end = endsToMerge.get(0);
        assert end.hasNoUsages();
        newExit = graph.add(new BeginNode());
        end.replaceAtPredecessor(newExit);
        end.safeDelete();
    } else {
        assert endsToMerge.size() > 1;
        AbstractMergeNode newExitMerge = graph.add(new MergeNode());
        newExit = newExitMerge;
        FrameState state = loopBegin.stateAfter();
        FrameState duplicateState = null;
        if (state != null) {
            duplicateState = state.duplicateWithVirtualState();
            newExitMerge.setStateAfter(duplicateState);
        }
        for (EndNode end : endsToMerge) {
            newExitMerge.addForwardEnd(end);
        }
        for (final PhiNode phi : loopBegin.phis().snapshot()) {
            if (phi.hasNoUsages()) {
                continue;
            }
            final PhiNode firstPhi = patchPhi(graph, phi, newExitMerge);
            for (AbstractEndNode end : newExitMerge.forwardEnds()) {
                LoopEndNode loopEnd = reverseEnds.get(end);
                ValueNode prim = prim(phi.valueAt(loopEnd));
                assert prim != null;
                firstPhi.addInput(prim);
            }
            ValueNode initializer = firstPhi;
            if (duplicateState != null) {
                // fix the merge's state after
                duplicateState.applyToNonVirtual(new NodeClosure<ValueNode>() {

                    @Override
                    public void apply(Node from, ValueNode node) {
                        if (node == phi) {
                            from.replaceFirstInput(phi, firstPhi);
                        }
                    }
                });
            }
            mergedInitializers.put(phi, initializer);
        }
    }
    return newExit;
}
Also used : ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) MemoryPhiNode(org.graalvm.compiler.nodes.memory.MemoryPhiNode) GuardPhiNode(org.graalvm.compiler.nodes.GuardPhiNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) CompareNode(org.graalvm.compiler.nodes.calc.CompareNode) ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) MemoryPhiNode(org.graalvm.compiler.nodes.memory.MemoryPhiNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) AddNode(org.graalvm.compiler.nodes.calc.AddNode) BeginNode(org.graalvm.compiler.nodes.BeginNode) MergeNode(org.graalvm.compiler.nodes.MergeNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) IfNode(org.graalvm.compiler.nodes.IfNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) SubNode(org.graalvm.compiler.nodes.calc.SubNode) LoopEndNode(org.graalvm.compiler.nodes.LoopEndNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) SafepointNode(org.graalvm.compiler.nodes.SafepointNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) GuardPhiNode(org.graalvm.compiler.nodes.GuardPhiNode) LoopExitNode(org.graalvm.compiler.nodes.LoopExitNode) Node(org.graalvm.compiler.graph.Node) EndNode(org.graalvm.compiler.nodes.EndNode) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) ProxyNode(org.graalvm.compiler.nodes.ProxyNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) FrameState(org.graalvm.compiler.nodes.FrameState) LinkedList(java.util.LinkedList) LoopEndNode(org.graalvm.compiler.nodes.LoopEndNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) MergeNode(org.graalvm.compiler.nodes.MergeNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) LoopEndNode(org.graalvm.compiler.nodes.LoopEndNode) EndNode(org.graalvm.compiler.nodes.EndNode) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) BeginNode(org.graalvm.compiler.nodes.BeginNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) ValueNode(org.graalvm.compiler.nodes.ValueNode)

Example 15 with AbstractEndNode

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

the class LoopEx method findInductionVariables.

/**
 * Collect all the basic induction variables for the loop and the find any induction variables
 * which are derived from the basic ones.
 *
 * @param loop
 * @return a map from node to induction variable
 */
private static EconomicMap<Node, InductionVariable> findInductionVariables(LoopEx loop) {
    EconomicMap<Node, InductionVariable> ivs = EconomicMap.create(Equivalence.IDENTITY);
    Queue<InductionVariable> scanQueue = new LinkedList<>();
    LoopBeginNode loopBegin = loop.loopBegin();
    AbstractEndNode forwardEnd = loopBegin.forwardEnd();
    for (PhiNode phi : loopBegin.valuePhis()) {
        ValueNode backValue = phi.singleBackValueOrThis();
        if (backValue == phi) {
            continue;
        }
        ValueNode stride = addSub(loop, backValue, phi);
        if (stride != null) {
            BasicInductionVariable biv = new BasicInductionVariable(loop, (ValuePhiNode) phi, phi.valueAt(forwardEnd), stride, (BinaryArithmeticNode<?>) backValue);
            ivs.put(phi, biv);
            scanQueue.add(biv);
        }
    }
    while (!scanQueue.isEmpty()) {
        InductionVariable baseIv = scanQueue.remove();
        ValueNode baseIvNode = baseIv.valueNode();
        for (ValueNode op : baseIvNode.usages().filter(ValueNode.class)) {
            if (loop.isOutsideLoop(op)) {
                continue;
            }
            if (op.usages().count() == 1 && op.usages().first() == baseIvNode) {
                /*
                     * This is just the base induction variable increment with no other uses so
                     * don't bother reporting it.
                     */
                continue;
            }
            InductionVariable iv = null;
            ValueNode offset = addSub(loop, op, baseIvNode);
            ValueNode scale;
            if (offset != null) {
                iv = new DerivedOffsetInductionVariable(loop, baseIv, offset, (BinaryArithmeticNode<?>) op);
            } else if (op instanceof NegateNode) {
                iv = new DerivedScaledInductionVariable(loop, baseIv, (NegateNode) op);
            } else if ((scale = mul(loop, op, baseIvNode)) != null) {
                iv = new DerivedScaledInductionVariable(loop, baseIv, scale, op);
            } else {
                boolean isValidConvert = op instanceof PiNode || op instanceof SignExtendNode;
                if (!isValidConvert && op instanceof ZeroExtendNode) {
                    ZeroExtendNode zeroExtendNode = (ZeroExtendNode) op;
                    isValidConvert = zeroExtendNode.isInputAlwaysPositive() || ((IntegerStamp) zeroExtendNode.stamp(NodeView.DEFAULT)).isPositive();
                }
                if (isValidConvert) {
                    iv = new DerivedConvertedInductionVariable(loop, baseIv, op.stamp(NodeView.DEFAULT), op);
                }
            }
            if (iv != null) {
                ivs.put(op, iv);
                scanQueue.offer(iv);
            }
        }
    }
    return ivs;
}
Also used : ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) SignExtendNode(org.graalvm.compiler.nodes.calc.SignExtendNode) ValueAnchorNode(org.graalvm.compiler.nodes.extended.ValueAnchorNode) ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) SignExtendNode(org.graalvm.compiler.nodes.calc.SignExtendNode) IntegerLessThanNode(org.graalvm.compiler.nodes.calc.IntegerLessThanNode) NegateNode(org.graalvm.compiler.nodes.calc.NegateNode) ZeroExtendNode(org.graalvm.compiler.nodes.calc.ZeroExtendNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) IfNode(org.graalvm.compiler.nodes.IfNode) 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) BinaryArithmeticNode(org.graalvm.compiler.nodes.calc.BinaryArithmeticNode) FullInfopointNode(org.graalvm.compiler.nodes.FullInfopointNode) MulNode(org.graalvm.compiler.nodes.calc.MulNode) CompareNode(org.graalvm.compiler.nodes.calc.CompareNode) LeftShiftNode(org.graalvm.compiler.nodes.calc.LeftShiftNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) IntegerEqualsNode(org.graalvm.compiler.nodes.calc.IntegerEqualsNode) AddNode(org.graalvm.compiler.nodes.calc.AddNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) IntegerBelowNode(org.graalvm.compiler.nodes.calc.IntegerBelowNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) SubNode(org.graalvm.compiler.nodes.calc.SubNode) Node(org.graalvm.compiler.graph.Node) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) PiNode(org.graalvm.compiler.nodes.PiNode) ZeroExtendNode(org.graalvm.compiler.nodes.calc.ZeroExtendNode) BinaryArithmeticNode(org.graalvm.compiler.nodes.calc.BinaryArithmeticNode) LinkedList(java.util.LinkedList) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) IntegerStamp(org.graalvm.compiler.core.common.type.IntegerStamp) ValueNode(org.graalvm.compiler.nodes.ValueNode) NegateNode(org.graalvm.compiler.nodes.calc.NegateNode)

Aggregations

AbstractEndNode (org.graalvm.compiler.nodes.AbstractEndNode)23 FixedNode (org.graalvm.compiler.nodes.FixedNode)17 AbstractMergeNode (org.graalvm.compiler.nodes.AbstractMergeNode)16 Node (org.graalvm.compiler.graph.Node)14 AbstractBeginNode (org.graalvm.compiler.nodes.AbstractBeginNode)13 LoopBeginNode (org.graalvm.compiler.nodes.LoopBeginNode)11 ValueNode (org.graalvm.compiler.nodes.ValueNode)11 FixedWithNextNode (org.graalvm.compiler.nodes.FixedWithNextNode)10 EndNode (org.graalvm.compiler.nodes.EndNode)9 LoopExitNode (org.graalvm.compiler.nodes.LoopExitNode)9 PhiNode (org.graalvm.compiler.nodes.PhiNode)9 ConstantNode (org.graalvm.compiler.nodes.ConstantNode)7 ControlSplitNode (org.graalvm.compiler.nodes.ControlSplitNode)6 LoopEndNode (org.graalvm.compiler.nodes.LoopEndNode)6 ProxyNode (org.graalvm.compiler.nodes.ProxyNode)6 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)6 ArrayList (java.util.ArrayList)5 IfNode (org.graalvm.compiler.nodes.IfNode)5 LogicNode (org.graalvm.compiler.nodes.LogicNode)5 ValuePhiNode (org.graalvm.compiler.nodes.ValuePhiNode)5