Search in sources :

Example 21 with FixedWithNextNode

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

the class ScheduledNodeIterator method replaceCurrent.

protected void replaceCurrent(FixedWithNextNode newNode) {
    Node current = iterator.previous();
    // needed because of the previous() call
    iterator.next();
    current.replaceAndDelete(newNode);
    insert(newNode, newNode);
    iterator.set(newNode);
}
Also used : FixedNode(org.graalvm.compiler.nodes.FixedNode) Node(org.graalvm.compiler.graph.Node) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode)

Example 22 with FixedWithNextNode

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

the class GraphEffectList method replaceAtUsages.

/**
 * Replaces the given node at its usages without deleting it. If the current node is a fixed
 * node it will be disconnected from the control flow, so that it will be deleted by a
 * subsequent {@link DeadCodeEliminationPhase}
 *
 * @param node The node to be replaced.
 * @param replacement The node that should replace the original value. If the replacement is a
 *            non-connected {@link FixedWithNextNode} it will be added to the control flow.
 * @param insertBefore
 */
public void replaceAtUsages(ValueNode node, ValueNode replacement, FixedNode insertBefore) {
    assert node != null && replacement != null : node + " " + replacement;
    assert node.stamp(NodeView.DEFAULT).isCompatible(replacement.stamp(NodeView.DEFAULT)) : "Replacement node stamp not compatible " + node.stamp(NodeView.DEFAULT) + " vs " + replacement.stamp(NodeView.DEFAULT);
    add("replace at usages", (graph, obsoleteNodes) -> {
        assert node.isAlive();
        ValueNode replacementNode = graph.addOrUniqueWithInputs(replacement);
        assert replacementNode.isAlive();
        assert insertBefore != null;
        if (replacementNode instanceof FixedWithNextNode && ((FixedWithNextNode) replacementNode).next() == null) {
            graph.addBeforeFixed(insertBefore, (FixedWithNextNode) replacementNode);
        }
        /*
             * Keep the (better) stamp information when replacing a node with another one if the
             * replacement has a less precise stamp than the original node. This can happen for
             * example in the context of read nodes and unguarded pi nodes where the pi will be used
             * to improve the stamp information of the read. Such a read might later be replaced
             * with a read with a less precise stamp.
             */
        if (!node.stamp(NodeView.DEFAULT).equals(replacementNode.stamp(NodeView.DEFAULT))) {
            replacementNode = graph.unique(new PiNode(replacementNode, node.stamp(NodeView.DEFAULT)));
        }
        node.replaceAtUsages(replacementNode);
        if (node instanceof FixedWithNextNode) {
            GraphUtil.unlinkFixedNode((FixedWithNextNode) node);
        }
        obsoleteNodes.add(node);
    });
}
Also used : FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) PiNode(org.graalvm.compiler.nodes.PiNode)

Example 23 with FixedWithNextNode

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

the class PartialEscapeBlockState method materializeBefore.

/**
 * Materializes the given virtual object and produces the necessary effects in the effects list.
 * This transitively also materializes all other virtual objects that are reachable from the
 * entries.
 */
public void materializeBefore(FixedNode fixed, VirtualObjectNode virtual, GraphEffectList materializeEffects) {
    PartialEscapeClosure.COUNTER_MATERIALIZATIONS.increment(fixed.getDebug());
    List<AllocatedObjectNode> objects = new ArrayList<>(2);
    List<ValueNode> values = new ArrayList<>(8);
    List<List<MonitorIdNode>> locks = new ArrayList<>();
    List<ValueNode> otherAllocations = new ArrayList<>(2);
    List<Boolean> ensureVirtual = new ArrayList<>(2);
    materializeWithCommit(fixed, virtual, objects, locks, values, ensureVirtual, otherAllocations);
    materializeEffects.addVirtualizationDelta(-(objects.size() + otherAllocations.size()));
    materializeEffects.add("materializeBefore", new Effect() {

        @Override
        public void apply(StructuredGraph graph, ArrayList<Node> obsoleteNodes) {
            for (ValueNode alloc : otherAllocations) {
                ValueNode otherAllocation = graph.addOrUniqueWithInputs(alloc);
                if (otherAllocation instanceof FixedWithNextNode) {
                    graph.addBeforeFixed(fixed, (FixedWithNextNode) otherAllocation);
                } else {
                    assert otherAllocation instanceof FloatingNode;
                }
            }
            if (!objects.isEmpty()) {
                CommitAllocationNode commit;
                if (fixed.predecessor() instanceof CommitAllocationNode) {
                    commit = (CommitAllocationNode) fixed.predecessor();
                } else {
                    commit = graph.add(new CommitAllocationNode());
                    graph.addBeforeFixed(fixed, commit);
                }
                for (AllocatedObjectNode obj : objects) {
                    graph.addWithoutUnique(obj);
                    commit.getVirtualObjects().add(obj.getVirtualObject());
                    obj.setCommit(commit);
                }
                for (ValueNode value : values) {
                    commit.getValues().add(graph.addOrUniqueWithInputs(value));
                }
                for (List<MonitorIdNode> monitorIds : locks) {
                    commit.addLocks(monitorIds);
                }
                commit.getEnsureVirtual().addAll(ensureVirtual);
                assert commit.usages().filter(AllocatedObjectNode.class).count() == commit.getUsageCount();
                List<AllocatedObjectNode> materializedValues = commit.usages().filter(AllocatedObjectNode.class).snapshot();
                for (int i = 0; i < commit.getValues().size(); i++) {
                    if (materializedValues.contains(commit.getValues().get(i))) {
                        commit.getValues().set(i, ((AllocatedObjectNode) commit.getValues().get(i)).getVirtualObject());
                    }
                }
            }
        }
    });
}
Also used : FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) AllocatedObjectNode(org.graalvm.compiler.nodes.virtual.AllocatedObjectNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) FloatingNode(org.graalvm.compiler.nodes.calc.FloatingNode) VirtualObjectNode(org.graalvm.compiler.nodes.virtual.VirtualObjectNode) AllocatedObjectNode(org.graalvm.compiler.nodes.virtual.AllocatedObjectNode) CommitAllocationNode(org.graalvm.compiler.nodes.virtual.CommitAllocationNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) MonitorIdNode(org.graalvm.compiler.nodes.java.MonitorIdNode) Node(org.graalvm.compiler.graph.Node) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) ArrayList(java.util.ArrayList) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) ValueNode(org.graalvm.compiler.nodes.ValueNode) FloatingNode(org.graalvm.compiler.nodes.calc.FloatingNode) ArrayList(java.util.ArrayList) List(java.util.List) Effect(org.graalvm.compiler.virtual.phases.ea.EffectList.Effect) CommitAllocationNode(org.graalvm.compiler.nodes.virtual.CommitAllocationNode)

Example 24 with FixedWithNextNode

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

the class StrengthenStampsPhase method strengthenStamp.

private Stamp strengthenStamp(ValueNode node, JavaTypeProfile typeProfile) {
    ObjectStamp oldStamp = (ObjectStamp) node.stamp(NodeView.DEFAULT);
    HostedType oldType = toHosted(oldStamp.type());
    if (oldStamp.alwaysNull()) {
        /* We cannot make that more precise. */
        return oldStamp;
    }
    boolean nonNull = oldStamp.nonNull() || typeProfile.getNullSeen() == TriState.FALSE;
    ProfiledType[] exactTypes = typeProfile.getTypes();
    if (exactTypes.length == 1) {
        ResolvedJavaType exactType = exactTypes[0].getType();
        assert oldType == null || oldType.isAssignableFrom(exactType);
        if (!oldStamp.isExactType() || !exactType.equals(oldType) || nonNull != oldStamp.nonNull()) {
            TypeReference typeRef = TypeReference.createExactTrusted(toTarget(exactType));
            return nonNull ? StampFactory.objectNonNull(typeRef) : StampFactory.object(typeRef);
        } else {
            return oldStamp;
        }
    }
    if (exactTypes.length == 0) {
        if (!nonNull) {
            return StampFactory.alwaysNull();
        } else {
            /*
                 * The code after the node is unreachable. We just insert a always-failing guard
                 * after the node and let dead code elimination remove everything after the node.
                 */
            StructuredGraph graph = node.graph();
            FixedWithNextNode insertionPoint;
            if (node instanceof ParameterNode) {
                /* The whole method is unreachable. */
                insertionPoint = graph.start();
            } else if (node instanceof InvokeWithExceptionNode) {
                /* The invoked method never returns normally (but can throw an exception). */
                insertionPoint = ((InvokeWithExceptionNode) node).next();
            } else {
                insertionPoint = (FixedWithNextNode) node;
            }
            graph.addAfterFixed(insertionPoint, graph.add(new FixedGuardNode(LogicConstantNode.forBoolean(true, graph), DeoptimizationReason.UnreachedCode, DeoptimizationAction.None, true)));
            return oldStamp;
        }
    }
    ResolvedJavaType baseType;
    if (oldStamp.isExactType()) {
        /* Base type cannot be more precise. */
        baseType = oldType;
    } else {
        assert exactTypes.length > 1;
        assert oldType == null || oldType.isAssignableFrom(exactTypes[0].getType());
        baseType = exactTypes[0].getType();
        for (int i = 1; i < exactTypes.length; i++) {
            assert oldType == null || oldType.isAssignableFrom(exactTypes[i].getType());
            baseType = baseType.findLeastCommonAncestor(exactTypes[i].getType());
        }
        if (oldType != null && !oldType.isAssignableFrom(baseType)) {
            /*
                 * When the original stamp is an interface type, we do not want to weaken that type
                 * with the common base class of all implementation types (which could even be
                 * java.lang.Object).
                 */
            baseType = oldType;
        }
    }
    if (!baseType.equals(oldType) || nonNull != oldStamp.nonNull()) {
        TypeReference typeRef = TypeReference.createTrustedWithoutAssumptions(toTarget(baseType));
        return nonNull ? StampFactory.objectNonNull(typeRef) : StampFactory.object(typeRef);
    }
    return oldStamp;
}
Also used : FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) ProfiledType(jdk.vm.ci.meta.JavaTypeProfile.ProfiledType) ObjectStamp(org.graalvm.compiler.core.common.type.ObjectStamp) AbstractObjectStamp(org.graalvm.compiler.core.common.type.AbstractObjectStamp) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) HostedType(com.oracle.svm.hosted.meta.HostedType) FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) ParameterNode(org.graalvm.compiler.nodes.ParameterNode) InvokeWithExceptionNode(org.graalvm.compiler.nodes.InvokeWithExceptionNode) TypeReference(org.graalvm.compiler.core.common.type.TypeReference)

Example 25 with FixedWithNextNode

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

the class AssertValueNode method insert.

protected static void insert(ValueNode input, AssertValueNode assertionNode) {
    StructuredGraph graph = input.graph();
    /* Find the insertion point where we want to add the assertion node. */
    FixedWithNextNode insertionPoint;
    if (input instanceof ParameterNode) {
        insertionPoint = graph.start();
    } else if (input instanceof InvokeWithExceptionNode) {
        insertionPoint = ((InvokeWithExceptionNode) input).next();
    } else if (input instanceof FixedWithNextNode) {
        insertionPoint = (FixedWithNextNode) input;
    } else {
        throw shouldNotReachHere("Node is not fixed: " + input);
    }
    /*
         * When inserting after an invoke that is also a loop exit, a proxy node is inserted between
         * the invoke and every usage. We need to be after this proxy node to avoid unschedulable
         * graphs.
         */
    ProxyNode proxyUsage = null;
    boolean otherUsages = false;
    for (Node usage : input.usages()) {
        if (usage instanceof ProxyNode && ((ProxyNode) usage).proxyPoint() == insertionPoint) {
            assert proxyUsage == null : "can have only one proxy";
            proxyUsage = (ProxyNode) usage;
        } else if (!(usage instanceof FrameState)) {
            otherUsages = true;
        }
    }
    assert proxyUsage == null || otherUsages == false : "cannot have other usages when having a proxy usage";
    ValueNode assertInput = proxyUsage != null ? proxyUsage : input;
    /*
         * Replace the object at usages. We do not process usages at the frame state because it
         * could be the stateAfter() of the insertion point. Since frame states are not doing
         * anything in code, this is not a loss of assertion precision.
         */
    for (Node usage : assertInput.usages().snapshot()) {
        if (!(usage instanceof FrameState)) {
            usage.replaceFirstInput(assertInput, assertionNode);
        }
    }
    /*
         * Set the input object of the assertion node, now that all other usages have been replaced.
         */
    assertionNode.updateUsages(assertionNode.input, assertInput);
    assertionNode.input = assertInput;
    /* Insert assertion node in graph. */
    graph.addAfterFixed(insertionPoint, assertionNode);
}
Also used : ProxyNode(org.graalvm.compiler.nodes.ProxyNode) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) ParameterNode(org.graalvm.compiler.nodes.ParameterNode) InvokeWithExceptionNode(org.graalvm.compiler.nodes.InvokeWithExceptionNode) InvokeWithExceptionNode(org.graalvm.compiler.nodes.InvokeWithExceptionNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) Node(org.graalvm.compiler.graph.Node) ParameterNode(org.graalvm.compiler.nodes.ParameterNode) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) ProxyNode(org.graalvm.compiler.nodes.ProxyNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) FrameState(org.graalvm.compiler.nodes.FrameState)

Aggregations

FixedWithNextNode (org.graalvm.compiler.nodes.FixedWithNextNode)57 FixedNode (org.graalvm.compiler.nodes.FixedNode)33 ValueNode (org.graalvm.compiler.nodes.ValueNode)29 Node (org.graalvm.compiler.graph.Node)26 AbstractMergeNode (org.graalvm.compiler.nodes.AbstractMergeNode)22 LoopBeginNode (org.graalvm.compiler.nodes.LoopBeginNode)21 AbstractBeginNode (org.graalvm.compiler.nodes.AbstractBeginNode)20 ConstantNode (org.graalvm.compiler.nodes.ConstantNode)13 EndNode (org.graalvm.compiler.nodes.EndNode)12 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)12 LoopExitNode (org.graalvm.compiler.nodes.LoopExitNode)10 AbstractEndNode (org.graalvm.compiler.nodes.AbstractEndNode)9 ControlSplitNode (org.graalvm.compiler.nodes.ControlSplitNode)9 Invoke (org.graalvm.compiler.nodes.Invoke)9 LogicNode (org.graalvm.compiler.nodes.LogicNode)9 LoopEndNode (org.graalvm.compiler.nodes.LoopEndNode)9 PhiNode (org.graalvm.compiler.nodes.PhiNode)9 IfNode (org.graalvm.compiler.nodes.IfNode)8 ControlSinkNode (org.graalvm.compiler.nodes.ControlSinkNode)7 DeoptimizeNode (org.graalvm.compiler.nodes.DeoptimizeNode)7