1/*
2 * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23package org.graalvm.compiler.graph;
24
25import static org.graalvm.compiler.graph.Edges.Type.Inputs;
26import static org.graalvm.compiler.graph.Edges.Type.Successors;
27import static org.graalvm.compiler.graph.Graph.isModificationCountsEnabled;
28import static org.graalvm.compiler.graph.UnsafeAccess.UNSAFE;
29
30import java.lang.annotation.ElementType;
31import java.lang.annotation.RetentionPolicy;
32import java.util.Collection;
33import java.util.Collections;
34import java.util.EnumSet;
35import java.util.Formattable;
36import java.util.FormattableFlags;
37import java.util.Formatter;
38import java.util.HashMap;
39import java.util.List;
40import java.util.Map;
41import java.util.Objects;
42import java.util.Set;
43import java.util.function.Predicate;
44
45import org.graalvm.compiler.core.common.CollectionsFactory;
46import org.graalvm.compiler.core.common.Fields;
47import org.graalvm.compiler.debug.DebugCloseable;
48import org.graalvm.compiler.debug.Fingerprint;
49import org.graalvm.compiler.graph.Graph.NodeEvent;
50import org.graalvm.compiler.graph.Graph.NodeEventListener;
51import org.graalvm.compiler.graph.Graph.Options;
52import org.graalvm.compiler.graph.iterators.NodeIterable;
53import org.graalvm.compiler.graph.iterators.NodePredicate;
54import org.graalvm.compiler.graph.spi.Simplifiable;
55import org.graalvm.compiler.graph.spi.SimplifierTool;
56import org.graalvm.compiler.nodeinfo.InputType;
57import org.graalvm.compiler.nodeinfo.NodeInfo;
58import org.graalvm.compiler.nodeinfo.Verbosity;
59
60import sun.misc.Unsafe;
61
62/**
63 * This class is the base class for all nodes. It represents a node that can be inserted in a
64 * {@link Graph}.
65 * <p>
66 * Once a node has been added to a graph, it has a graph-unique {@link #id()}. Edges in the
67 * subclasses are represented with annotated fields. There are two kind of edges : {@link Input} and
68 * {@link Successor}. If a field, of a type compatible with {@link Node}, annotated with either
69 * {@link Input} and {@link Successor} is not null, then there is an edge from this node to the node
70 * this field points to.
71 * <p>
72 * Nodes which are be value numberable should implement the {@link ValueNumberable} interface.
73 *
74 * <h1>Replay Compilation</h1>
75 *
76 * To enable deterministic replay compilation, node sets and node maps should be instantiated with
77 * the following methods:
78 * <ul>
79 * <li>{@link #newSet()}</li>
80 * <li>{@link #newSet(Collection)}</li>
81 * <li>{@link #newMap()}</li>
82 * <li>{@link #newMap(int)}</li>
83 * <li>{@link #newMap(Map)}</li>
84 * <li>{@link #newIdentityMap()}</li>
85 * <li>{@link #newIdentityMap(int)}</li>
86 * <li>{@link #newIdentityMap(Map)}</li>
87 * </ul>
88 *
89 * <h1>Assertions and Verification</h1>
90 *
91 * The Node class supplies the {@link #assertTrue(boolean, String, Object...)} and
92 * {@link #assertFalse(boolean, String, Object...)} methods, which will check the supplied boolean
93 * and throw a VerificationError if it has the wrong value. Both methods will always either throw an
94 * exception or return true. They can thus be used within an assert statement, so that the check is
95 * only performed if assertions are enabled.
96 */
97@NodeInfo
98public abstract class Node implements Cloneable, Formattable, NodeInterface {
99
100    public static final NodeClass<?> TYPE = null;
101    public static final boolean USE_UNSAFE_TO_CLONE = Graph.Options.CloneNodesWithUnsafe.getValue();
102
103    static final int DELETED_ID_START = -1000000000;
104    static final int INITIAL_ID = -1;
105    static final int ALIVE_ID_START = 0;
106
107    // The use of fully qualified class names here and in the rest
108    // of this file works around a problem javac has resolving symbols
109
110    /**
111     * Denotes a non-optional (non-null) node input. This should be applied to exactly the fields of
112     * a node that are of type {@link Node} or {@link NodeInputList}. Nodes that update fields of
113     * type {@link Node} outside of their constructor should call
114     * {@link Node#updateUsages(Node, Node)} just prior to doing the update of the input.
115     */
116    @java.lang.annotation.Retention(RetentionPolicy.RUNTIME)
117    @java.lang.annotation.Target(ElementType.FIELD)
118    public static @interface Input {
119        InputType value() default InputType.Value;
120    }
121
122    /**
123     * Denotes an optional (nullable) node input. This should be applied to exactly the fields of a
124     * node that are of type {@link Node} or {@link NodeInputList}. Nodes that update fields of type
125     * {@link Node} outside of their constructor should call {@link Node#updateUsages(Node, Node)}
126     * just prior to doing the update of the input.
127     */
128    @java.lang.annotation.Retention(RetentionPolicy.RUNTIME)
129    @java.lang.annotation.Target(ElementType.FIELD)
130    public static @interface OptionalInput {
131        InputType value() default InputType.Value;
132    }
133
134    @java.lang.annotation.Retention(RetentionPolicy.RUNTIME)
135    @java.lang.annotation.Target(ElementType.FIELD)
136    public static @interface Successor {
137    }
138
139    /**
140     * Denotes that a parameter of an {@linkplain NodeIntrinsic intrinsic} method must be a compile
141     * time constant at all call sites to the intrinsic method.
142     */
143    @java.lang.annotation.Retention(RetentionPolicy.RUNTIME)
144    @java.lang.annotation.Target(ElementType.PARAMETER)
145    public static @interface ConstantNodeParameter {
146    }
147
148    /**
149     * Denotes an injected parameter in a {@linkplain NodeIntrinsic node intrinsic} constructor. If
150     * the constructor is called as part of node intrinsification, the node intrinsifier will inject
151     * an argument for the annotated parameter. Injected parameters must precede all non-injected
152     * parameters in a constructor.
153     */
154    @java.lang.annotation.Retention(RetentionPolicy.RUNTIME)
155    @java.lang.annotation.Target(ElementType.PARAMETER)
156    public static @interface InjectedNodeParameter {
157    }
158
159    /**
160     * Annotates a method that can be replaced by a compiler intrinsic. A (resolved) call to the
161     * annotated method can be replaced with an instance of the node class denoted by
162     * {@link #value()}. For this reason, the signature of the annotated method must match the
163     * signature (excluding a prefix of {@linkplain InjectedNodeParameter injected} parameters) of a
164     * constructor in the node class.
165     * <p>
166     * If the node class has a static method {@code intrinsify} with a matching signature plus a
167     * {@code GraphBuilderContext} as first argument, this method is called instead of creating the
168     * node.
169     */
170    @java.lang.annotation.Retention(RetentionPolicy.RUNTIME)
171    @java.lang.annotation.Target(ElementType.METHOD)
172    public static @interface NodeIntrinsic {
173
174        /**
175         * Gets the {@link Node} subclass instantiated when intrinsifying a call to the annotated
176         * method. If not specified, then the class in which the annotated method is declared is
177         * used (and is assumed to be a {@link Node} subclass).
178         */
179        Class<?> value() default NodeIntrinsic.class;
180
181        /**
182         * Determines if the stamp of the instantiated intrinsic node has its stamp set from the
183         * return type of the annotated method.
184         * <p>
185         * When it is set to true, the stamp that is passed in to the constructor of ValueNode is
186         * ignored and can therefore safely be {@code null}.
187         */
188        boolean setStampFromReturnType() default false;
189
190        /**
191         * Determines if the stamp of the instantiated intrinsic node is guaranteed to be non-null.
192         * Generally used in conjunction with {@link #setStampFromReturnType()}.
193         */
194        boolean returnStampIsNonNull() default false;
195    }
196
197    /**
198     * Marker for a node that can be replaced by another node via global value numbering. A
199     * {@linkplain NodeClass#isLeafNode() leaf} node can be replaced by another node of the same
200     * type that has exactly the same {@linkplain NodeClass#getData() data} values. A non-leaf node
201     * can be replaced by another node of the same type that has exactly the same data values as
202     * well as the same {@linkplain Node#inputs() inputs} and {@linkplain Node#successors()
203     * successors}.
204     */
205    public interface ValueNumberable {
206    }
207
208    /**
209     * Marker interface for nodes that contains other nodes. When the inputs to this node changes,
210     * users of this node should also be placed on the work list for canonicalization.
211     */
212    public interface IndirectCanonicalization {
213    }
214
215    private Graph graph;
216    int id;
217
218    // this next pointer is used in Graph to implement fast iteration over NodeClass types, it
219    // therefore points to the next Node of the same type.
220    Node typeCacheNext;
221
222    static final int INLINE_USAGE_COUNT = 2;
223    private static final Node[] NO_NODES = {};
224
225    /**
226     * Head of usage list. The elements of the usage list in order are {@link #usage0},
227     * {@link #usage1} and {@link #extraUsages}. The first null entry terminates the list.
228     */
229    Node usage0;
230    Node usage1;
231    Node[] extraUsages;
232    int extraUsagesCount;
233
234    private Node predecessor;
235    private NodeClass<? extends Node> nodeClass;
236
237    public static final int NODE_LIST = -2;
238    public static final int NOT_ITERABLE = -1;
239
240    public Node(NodeClass<? extends Node> c) {
241        init(c);
242    }
243
244    final void init(NodeClass<? extends Node> c) {
245        assert c.getJavaClass() == this.getClass();
246        this.nodeClass = c;
247        id = INITIAL_ID;
248        extraUsages = NO_NODES;
249    }
250
251    final int id() {
252        return id;
253    }
254
255    @Override
256    public Node asNode() {
257        return this;
258    }
259
260    /**
261     * @see CollectionsFactory#newSet()
262     */
263    public static <E extends Node> Set<E> newSet() {
264        return CollectionsFactory.newSet();
265    }
266
267    /**
268     * @see #newSet()
269     */
270    public static <E extends Node> Set<E> newSet(Collection<? extends E> c) {
271        return CollectionsFactory.newSet(c);
272    }
273
274    public static <K extends Node, V> Map<K, V> newMap() {
275        // Node.equals() and Node.hashCode() are final and are implemented
276        // purely in terms of identity so HashMap and IdentityHashMap with
277        // Node's as keys will behave the same. We choose to use the latter
278        // due to its lighter memory footprint.
279        return newIdentityMap();
280    }
281
282    public static <K extends Node, V> Map<K, V> newMap(Map<K, V> m) {
283        // Node.equals() and Node.hashCode() are final and are implemented
284        // purely in terms of identity so HashMap and IdentityHashMap with
285        // Node's as keys will behave the same. We choose to use the latter
286        // due to its lighter memory footprint.
287        return newIdentityMap(m);
288    }
289
290    public static <K extends Node, V> Map<K, V> newMap(int expectedMaxSize) {
291        // Node.equals() and Node.hashCode() are final and are implemented
292        // purely in terms of identity so HashMap and IdentityHashMap with
293        // Node's as keys will behave the same. We choose to use the latter
294        // due to its lighter memory footprint.
295        return newIdentityMap(expectedMaxSize);
296    }
297
298    public static <K extends Node, V> Map<K, V> newIdentityMap() {
299        return CollectionsFactory.newIdentityMap();
300    }
301
302    public static <K extends Node, V> Map<K, V> newIdentityMap(Map<K, V> m) {
303        return CollectionsFactory.newIdentityMap(m);
304    }
305
306    public static <K extends Node, V> Map<K, V> newIdentityMap(int expectedMaxSize) {
307        return CollectionsFactory.newIdentityMap(expectedMaxSize);
308    }
309
310    /**
311     * Gets the graph context of this node.
312     */
313    public Graph graph() {
314        return graph;
315    }
316
317    /**
318     * Returns an {@link NodeIterable iterable} which can be used to traverse all non-null input
319     * edges of this node.
320     *
321     * @return an {@link NodeIterable iterable} for all non-null input edges.
322     */
323    public NodeIterable<Node> inputs() {
324        return nodeClass.getInputIterable(this);
325    }
326
327    /**
328     * Returns an {@link Iterable iterable} which can be used to traverse all non-null input edges
329     * of this node.
330     *
331     * @return an {@link Iterable iterable} for all non-null input edges.
332     */
333    public Iterable<Position> inputPositions() {
334        return nodeClass.getInputEdges().getPositionsIterable(this);
335    }
336
337    public abstract static class EdgeVisitor {
338
339        public abstract Node apply(Node source, Node target);
340
341    }
342
343    /**
344     * Applies the given visitor to all inputs of this node.
345     *
346     * @param visitor the visitor to be applied to the inputs
347     */
348    public void applyInputs(EdgeVisitor visitor) {
349        nodeClass.applyInputs(this, visitor);
350    }
351
352    /**
353     * Applies the given visitor to all successors of this node.
354     *
355     * @param visitor the visitor to be applied to the successors
356     */
357    public void applySuccessors(EdgeVisitor visitor) {
358        nodeClass.applySuccessors(this, visitor);
359    }
360
361    /**
362     * Returns an {@link NodeIterable iterable} which can be used to traverse all non-null successor
363     * edges of this node.
364     *
365     * @return an {@link NodeIterable iterable} for all non-null successor edges.
366     */
367    public NodeIterable<Node> successors() {
368        assert !this.isDeleted();
369        return nodeClass.getSuccessorIterable(this);
370    }
371
372    /**
373     * Returns an {@link Iterable iterable} which can be used to traverse all successor edge
374     * positions of this node.
375     *
376     * @return an {@link Iterable iterable} for all successor edge positoins.
377     */
378    public Iterable<Position> successorPositions() {
379        return nodeClass.getSuccessorEdges().getPositionsIterable(this);
380    }
381
382    /**
383     * Gets the maximum number of usages this node has had at any point in time.
384     */
385    public int getUsageCount() {
386        if (usage0 == null) {
387            return 0;
388        }
389        if (usage1 == null) {
390            return 1;
391        }
392        return 2 + extraUsagesCount;
393    }
394
395    /**
396     * Gets the list of nodes that use this node (i.e., as an input).
397     */
398    public final NodeIterable<Node> usages() {
399        return new NodeUsageIterable(this);
400    }
401
402    /**
403     * Checks whether this node has no usages.
404     */
405    public final boolean hasNoUsages() {
406        return this.usage0 == null;
407    }
408
409    /**
410     * Checks whether this node has usages.
411     */
412    public final boolean hasUsages() {
413        return this.usage0 != null;
414    }
415
416    void reverseUsageOrder() {
417        List<Node> snapshot = this.usages().snapshot();
418        for (Node n : snapshot) {
419            this.removeUsage(n);
420        }
421        Collections.reverse(snapshot);
422        for (Node n : snapshot) {
423            this.addUsage(n);
424        }
425    }
426
427    /**
428     * Adds a given node to this node's {@linkplain #usages() usages}.
429     *
430     * @param node the node to add
431     */
432    void addUsage(Node node) {
433        incUsageModCount();
434        if (usage0 == null) {
435            usage0 = node;
436        } else if (usage1 == null) {
437            usage1 = node;
438        } else {
439            int length = extraUsages.length;
440            if (length == 0) {
441                extraUsages = new Node[4];
442            } else if (extraUsagesCount == length) {
443                Node[] newExtraUsages = new Node[length * 2 + 1];
444                System.arraycopy(extraUsages, 0, newExtraUsages, 0, length);
445                extraUsages = newExtraUsages;
446            }
447            extraUsages[extraUsagesCount++] = node;
448        }
449    }
450
451    private void movUsageFromEndTo(int destIndex) {
452        int lastIndex = this.getUsageCount() - 1;
453        if (destIndex == 0) {
454            if (lastIndex == 0) {
455                usage0 = null;
456                return;
457            } else if (lastIndex == 1) {
458                usage0 = usage1;
459                usage1 = null;
460                return;
461            } else {
462                usage0 = extraUsages[lastIndex - INLINE_USAGE_COUNT];
463            }
464        } else if (destIndex == 1) {
465            if (lastIndex == 1) {
466                usage1 = null;
467                return;
468            }
469            usage1 = extraUsages[lastIndex - INLINE_USAGE_COUNT];
470        } else {
471            Node n = extraUsages[lastIndex - INLINE_USAGE_COUNT];
472            extraUsages[destIndex - INLINE_USAGE_COUNT] = n;
473        }
474        extraUsages[lastIndex - INLINE_USAGE_COUNT] = null;
475        this.extraUsagesCount--;
476    }
477
478    /**
479     * Removes a given node from this node's {@linkplain #usages() usages}.
480     *
481     * @param node the node to remove
482     * @return whether or not {@code usage} was in the usage list
483     */
484    public boolean removeUsage(Node node) {
485        assert node != null;
486        // It is critical that this method maintains the invariant that
487        // the usage list has no null element preceding a non-null element
488        incUsageModCount();
489        if (usage0 == node) {
490            this.movUsageFromEndTo(0);
491            return true;
492        }
493        if (usage1 == node) {
494            this.movUsageFromEndTo(1);
495            return true;
496        }
497        for (int i = this.extraUsagesCount - 1; i >= 0; i--) {
498            if (extraUsages[i] == node) {
499                this.movUsageFromEndTo(i + INLINE_USAGE_COUNT);
500                return true;
501            }
502        }
503        return false;
504    }
505
506    public final Node predecessor() {
507        return predecessor;
508    }
509
510    public final int modCount() {
511        if (isModificationCountsEnabled() && graph != null) {
512            return graph.modCount(this);
513        }
514        return 0;
515    }
516
517    final void incModCount() {
518        if (isModificationCountsEnabled() && graph != null) {
519            graph.incModCount(this);
520        }
521    }
522
523    final int usageModCount() {
524        if (isModificationCountsEnabled() && graph != null) {
525            return graph.usageModCount(this);
526        }
527        return 0;
528    }
529
530    final void incUsageModCount() {
531        if (isModificationCountsEnabled() && graph != null) {
532            graph.incUsageModCount(this);
533        }
534    }
535
536    public boolean isDeleted() {
537        return id <= DELETED_ID_START;
538    }
539
540    public boolean isAlive() {
541        return id >= ALIVE_ID_START;
542    }
543
544    /**
545     * Updates the usages sets of the given nodes after an input slot is changed from
546     * {@code oldInput} to {@code newInput} by removing this node from {@code oldInput}'s usages and
547     * adds this node to {@code newInput}'s usages.
548     */
549    protected void updateUsages(Node oldInput, Node newInput) {
550        assert isAlive() && (newInput == null || newInput.isAlive()) : "adding " + newInput + " to " + this + " instead of " + oldInput;
551        if (oldInput != newInput) {
552            if (oldInput != null) {
553                boolean result = removeThisFromUsages(oldInput);
554                assert assertTrue(result, "not found in usages, old input: %s", oldInput);
555            }
556            maybeNotifyInputChanged(this);
557            if (newInput != null) {
558                newInput.addUsage(this);
559            }
560            if (oldInput != null && oldInput.hasNoUsages()) {
561                maybeNotifyZeroUsages(oldInput);
562            }
563        }
564    }
565
566    protected void updateUsagesInterface(NodeInterface oldInput, NodeInterface newInput) {
567        updateUsages(oldInput == null ? null : oldInput.asNode(), newInput == null ? null : newInput.asNode());
568    }
569
570    /**
571     * Updates the predecessor of the given nodes after a successor slot is changed from
572     * oldSuccessor to newSuccessor: removes this node from oldSuccessor's predecessors and adds
573     * this node to newSuccessor's predecessors.
574     */
575    protected void updatePredecessor(Node oldSuccessor, Node newSuccessor) {
576        assert isAlive() && (newSuccessor == null || newSuccessor.isAlive()) || newSuccessor == null && !isAlive() : "adding " + newSuccessor + " to " + this + " instead of " + oldSuccessor;
577        assert graph == null || !graph.isFrozen();
578        if (oldSuccessor != newSuccessor) {
579            if (oldSuccessor != null) {
580                assert assertTrue(newSuccessor == null || oldSuccessor.predecessor == this, "wrong predecessor in old successor (%s): %s, should be %s", oldSuccessor, oldSuccessor.predecessor, this);
581                oldSuccessor.predecessor = null;
582            }
583            if (newSuccessor != null) {
584                assert assertTrue(newSuccessor.predecessor == null, "unexpected non-null predecessor in new successor (%s): %s, this=%s", newSuccessor, newSuccessor.predecessor, this);
585                newSuccessor.predecessor = this;
586            }
587        }
588    }
589
590    void initialize(Graph newGraph) {
591        assert assertTrue(id == INITIAL_ID, "unexpected id: %d", id);
592        this.graph = newGraph;
593        newGraph.register(this);
594        this.getNodeClass().registerAtInputsAsUsage(this);
595        this.getNodeClass().registerAtSuccessorsAsPredecessor(this);
596    }
597
598    /**
599     * The position of the bytecode that generated this node.
600     */
601    NodeSourcePosition sourcePosition;
602
603    /**
604     * Gets the source position information for this node or null if it doesn't exist.
605     */
606
607    public NodeSourcePosition getNodeSourcePosition() {
608        return sourcePosition;
609    }
610
611    /**
612     * Set the source position to {@code sourcePosition}.
613     */
614    public void setNodeSourcePosition(NodeSourcePosition sourcePosition) {
615        this.sourcePosition = sourcePosition;
616        if (sourcePosition != null && graph != null && !graph.seenNodeSourcePosition) {
617            graph.seenNodeSourcePosition = true;
618        }
619    }
620
621    public DebugCloseable withNodeSourcePosition() {
622        return graph.withNodeSourcePosition(this);
623    }
624
625    public final NodeClass<? extends Node> getNodeClass() {
626        return nodeClass;
627    }
628
629    public boolean isAllowedUsageType(InputType type) {
630        if (type == InputType.Value) {
631            return false;
632        }
633        return getNodeClass().getAllowedUsageTypes().contains(type);
634    }
635
636    private boolean checkReplaceWith(Node other) {
637        assert assertTrue(graph == null || !graph.isFrozen(), "cannot modify frozen graph");
638        assert assertFalse(other == this, "cannot replace a node with itself");
639        assert assertFalse(isDeleted(), "cannot replace deleted node");
640        assert assertTrue(other == null || !other.isDeleted(), "cannot replace with deleted node %s", other);
641        return true;
642    }
643
644    public final void replaceAtUsages(Node other) {
645        replaceAtUsages(other, null, null);
646    }
647
648    public final void replaceAtUsages(Node other, Predicate<Node> filter) {
649        replaceAtUsages(other, filter, null);
650    }
651
652    public final void replaceAtUsagesAndDelete(Node other) {
653        replaceAtUsages(other, null, this);
654        safeDelete();
655    }
656
657    public final void replaceAtUsagesAndDelete(Node other, Predicate<Node> filter) {
658        replaceAtUsages(other, filter, this);
659        safeDelete();
660    }
661
662    protected void replaceAtUsages(Node other, Predicate<Node> filter, Node toBeDeleted) {
663        assert checkReplaceWith(other);
664        int i = 0;
665        while (i < this.getUsageCount()) {
666            Node usage = this.getUsageAt(i);
667            if (filter == null || filter.test(usage)) {
668                boolean result = usage.getNodeClass().replaceFirstInput(usage, this, other);
669                assert assertTrue(result, "not found in inputs, usage: %s", usage);
670                /*
671                 * Don't notify for nodes which are about to be deleted.
672                 */
673                if (toBeDeleted == null || usage != toBeDeleted) {
674                    maybeNotifyInputChanged(usage);
675                }
676                if (other != null) {
677                    other.addUsage(usage);
678                }
679                this.movUsageFromEndTo(i);
680            } else {
681                ++i;
682            }
683        }
684    }
685
686    public Node getUsageAt(int index) {
687        if (index == 0) {
688            return this.usage0;
689        } else if (index == 1) {
690            return this.usage1;
691        } else {
692            return this.extraUsages[index - INLINE_USAGE_COUNT];
693        }
694    }
695
696    public void replaceAtMatchingUsages(Node other, NodePredicate usagePredicate) {
697        assert checkReplaceWith(other);
698        int index = 0;
699        while (index < this.getUsageCount()) {
700            Node usage = getUsageAt(index);
701            if (usagePredicate.apply(usage)) {
702                boolean result = usage.getNodeClass().replaceFirstInput(usage, this, other);
703                assert assertTrue(result, "not found in inputs, usage: %s", usage);
704                if (other != null) {
705                    maybeNotifyInputChanged(usage);
706                    other.addUsage(usage);
707                }
708                this.movUsageFromEndTo(index);
709            } else {
710                index++;
711            }
712        }
713    }
714
715    public void replaceAtUsages(InputType type, Node other) {
716        assert checkReplaceWith(other);
717        for (Node usage : usages().snapshot()) {
718            for (Position pos : usage.inputPositions()) {
719                if (pos.getInputType() == type && pos.get(usage) == this) {
720                    pos.set(usage, other);
721                }
722            }
723        }
724    }
725
726    private void maybeNotifyInputChanged(Node node) {
727        if (graph != null) {
728            assert !graph.isFrozen();
729            NodeEventListener listener = graph.nodeEventListener;
730            if (listener != null) {
731                listener.inputChanged(node);
732            }
733            if (Fingerprint.ENABLED) {
734                Fingerprint.submit("%s: %s", NodeEvent.INPUT_CHANGED, node);
735            }
736        }
737    }
738
739    public void maybeNotifyZeroUsages(Node node) {
740        if (graph != null) {
741            assert !graph.isFrozen();
742            NodeEventListener listener = graph.nodeEventListener;
743            if (listener != null && node.isAlive()) {
744                listener.usagesDroppedToZero(node);
745            }
746            if (Fingerprint.ENABLED) {
747                Fingerprint.submit("%s: %s", NodeEvent.ZERO_USAGES, node);
748            }
749        }
750    }
751
752    public void replaceAtPredecessor(Node other) {
753        assert checkReplaceWith(other);
754        if (predecessor != null) {
755            boolean result = predecessor.getNodeClass().replaceFirstSuccessor(predecessor, this, other);
756            assert assertTrue(result, "not found in successors, predecessor: %s", predecessor);
757            predecessor.updatePredecessor(this, other);
758        }
759    }
760
761    public void replaceAndDelete(Node other) {
762        assert checkReplaceWith(other);
763        assert other != null;
764        replaceAtUsages(other);
765        replaceAtPredecessor(other);
766        this.safeDelete();
767    }
768
769    public void replaceFirstSuccessor(Node oldSuccessor, Node newSuccessor) {
770        if (nodeClass.replaceFirstSuccessor(this, oldSuccessor, newSuccessor)) {
771            updatePredecessor(oldSuccessor, newSuccessor);
772        }
773    }
774
775    public void replaceFirstInput(Node oldInput, Node newInput) {
776        if (nodeClass.replaceFirstInput(this, oldInput, newInput)) {
777            updateUsages(oldInput, newInput);
778        }
779    }
780
781    public void clearInputs() {
782        assert assertFalse(isDeleted(), "cannot clear inputs of deleted node");
783        getNodeClass().unregisterAtInputsAsUsage(this);
784    }
785
786    boolean removeThisFromUsages(Node n) {
787        return n.removeUsage(this);
788    }
789
790    public void clearSuccessors() {
791        assert assertFalse(isDeleted(), "cannot clear successors of deleted node");
792        getNodeClass().unregisterAtSuccessorsAsPredecessor(this);
793    }
794
795    private boolean checkDeletion() {
796        assertTrue(isAlive(), "must be alive");
797        assertTrue(hasNoUsages(), "cannot delete node %s because of usages: %s", this, usages());
798        assertTrue(predecessor == null, "cannot delete node %s because of predecessor: %s", this, predecessor);
799        return true;
800    }
801
802    /**
803     * Removes this node from its graph. This node must have no {@linkplain Node#usages() usages}
804     * and no {@linkplain #predecessor() predecessor}.
805     */
806    public void safeDelete() {
807        assert checkDeletion();
808        this.clearInputs();
809        this.clearSuccessors();
810        markDeleted();
811    }
812
813    public void markDeleted() {
814        graph.unregister(this);
815        id = DELETED_ID_START - id;
816        assert isDeleted();
817    }
818
819    public final Node copyWithInputs() {
820        return copyWithInputs(true);
821    }
822
823    public final Node copyWithInputs(boolean insertIntoGraph) {
824        Node newNode = clone(insertIntoGraph ? graph : null, WithOnlyInputEdges);
825        if (insertIntoGraph) {
826            for (Node input : inputs()) {
827                input.addUsage(newNode);
828            }
829        }
830        return newNode;
831    }
832
833    /**
834     * Must be overridden by subclasses that implement {@link Simplifiable}. The implementation in
835     * {@link Node} exists to obviate the need to cast a node before invoking
836     * {@link Simplifiable#simplify(SimplifierTool)}.
837     *
838     * @param tool
839     */
840    public void simplify(SimplifierTool tool) {
841        throw new UnsupportedOperationException();
842    }
843
844    /**
845     * @param newNode the result of cloning this node or {@link Unsafe#allocateInstance(Class) raw
846     *            allocating} a copy of this node
847     * @param type the type of edges to process
848     * @param edgesToCopy if {@code type} is in this set, the edges are copied otherwise they are
849     *            cleared
850     */
851    private void copyOrClearEdgesForClone(Node newNode, Edges.Type type, EnumSet<Edges.Type> edgesToCopy) {
852        if (edgesToCopy.contains(type)) {
853            getNodeClass().getEdges(type).copy(this, newNode);
854        } else {
855            if (USE_UNSAFE_TO_CLONE) {
856                // The direct edges are already null
857                getNodeClass().getEdges(type).initializeLists(newNode, this);
858            } else {
859                getNodeClass().getEdges(type).clear(newNode);
860            }
861        }
862    }
863
864    public static final EnumSet<Edges.Type> WithNoEdges = EnumSet.noneOf(Edges.Type.class);
865    public static final EnumSet<Edges.Type> WithAllEdges = EnumSet.allOf(Edges.Type.class);
866    public static final EnumSet<Edges.Type> WithOnlyInputEdges = EnumSet.of(Inputs);
867    public static final EnumSet<Edges.Type> WithOnlySucessorEdges = EnumSet.of(Successors);
868
869    /**
870     * Makes a copy of this node in(to) a given graph.
871     *
872     * @param into the graph in which the copy will be registered (which may be this node's graph)
873     *            or null if the copy should not be registered in a graph
874     * @param edgesToCopy specifies the edges to be copied. The edges not specified in this set are
875     *            initialized to their default value (i.e., {@code null} for a direct edge, an empty
876     *            list for an edge list)
877     * @return the copy of this node
878     */
879    final Node clone(Graph into, EnumSet<Edges.Type> edgesToCopy) {
880        final NodeClass<? extends Node> nodeClassTmp = getNodeClass();
881        boolean useIntoLeafNodeCache = false;
882        if (into != null) {
883            if (nodeClassTmp.valueNumberable() && nodeClassTmp.isLeafNode()) {
884                useIntoLeafNodeCache = true;
885                Node otherNode = into.findNodeInCache(this);
886                if (otherNode != null) {
887                    return otherNode;
888                }
889            }
890        }
891
892        Node newNode = null;
893        try {
894            if (USE_UNSAFE_TO_CLONE) {
895                newNode = (Node) UNSAFE.allocateInstance(getClass());
896                newNode.nodeClass = nodeClassTmp;
897                nodeClassTmp.getData().copy(this, newNode);
898                copyOrClearEdgesForClone(newNode, Inputs, edgesToCopy);
899                copyOrClearEdgesForClone(newNode, Successors, edgesToCopy);
900            } else {
901                newNode = (Node) this.clone();
902                newNode.typeCacheNext = null;
903                newNode.usage0 = null;
904                newNode.usage1 = null;
905                newNode.predecessor = null;
906                newNode.extraUsagesCount = 0;
907                copyOrClearEdgesForClone(newNode, Inputs, edgesToCopy);
908                copyOrClearEdgesForClone(newNode, Successors, edgesToCopy);
909            }
910        } catch (Exception e) {
911            throw new GraalGraphError(e).addContext(this);
912        }
913        newNode.graph = into;
914        newNode.id = INITIAL_ID;
915        if (into != null) {
916            into.register(newNode);
917        }
918        newNode.extraUsages = NO_NODES;
919
920        if (into != null && useIntoLeafNodeCache) {
921            into.putNodeIntoCache(newNode);
922        }
923        if (graph != null && into != null && sourcePosition != null) {
924            newNode.setNodeSourcePosition(sourcePosition);
925        }
926        newNode.afterClone(this);
927        return newNode;
928    }
929
930    protected void afterClone(@SuppressWarnings("unused") Node other) {
931    }
932
933    protected boolean verifyInputs() {
934        for (Position pos : inputPositions()) {
935            Node input = pos.get(this);
936            if (input == null) {
937                assertTrue(pos.isInputOptional(), "non-optional input %s cannot be null in %s (fix nullness or use @OptionalInput)", pos, this);
938            } else {
939                assertFalse(input.isDeleted(), "input was deleted");
940                assertTrue(input.isAlive(), "input is not alive yet, i.e., it was not yet added to the graph");
941                assertTrue(pos.getInputType() == InputType.Unchecked || input.isAllowedUsageType(pos.getInputType()), "invalid usage type %s %s", input, pos.getInputType());
942            }
943        }
944        return true;
945    }
946
947    public boolean verify() {
948        assertTrue(isAlive(), "cannot verify inactive nodes (id=%d)", id);
949        assertTrue(graph() != null, "null graph");
950        verifyInputs();
951        if (Options.VerifyGraalGraphEdges.getValue()) {
952            verifyEdges();
953        }
954        return true;
955    }
956
957    /**
958     * Perform expensive verification of inputs, usages, predecessors and successors.
959     *
960     * @return true
961     */
962    public boolean verifyEdges() {
963        for (Node input : inputs()) {
964            assertTrue(input == null || input.usages().contains(this), "missing usage of %s in input %s", this, input);
965        }
966
967        for (Node successor : successors()) {
968            assertTrue(successor.predecessor() == this, "missing predecessor in %s (actual: %s)", successor, successor.predecessor());
969            assertTrue(successor.graph() == graph(), "mismatching graph in successor %s", successor);
970        }
971        for (Node usage : usages()) {
972            assertFalse(usage.isDeleted(), "usage %s must never be deleted", usage);
973            assertTrue(usage.inputs().contains(this), "missing input in usage %s", usage);
974            boolean foundThis = false;
975            for (Position pos : usage.inputPositions()) {
976                if (pos.get(usage) == this) {
977                    foundThis = true;
978                    if (pos.getInputType() != InputType.Unchecked) {
979                        assertTrue(isAllowedUsageType(pos.getInputType()), "invalid input of type %s from %s to %s (%s)", pos.getInputType(), usage, this, pos.getName());
980                    }
981                }
982            }
983            assertTrue(foundThis, "missing input in usage %s", usage);
984        }
985
986        if (predecessor != null) {
987            assertFalse(predecessor.isDeleted(), "predecessor %s must never be deleted", predecessor);
988            assertTrue(predecessor.successors().contains(this), "missing successor in predecessor %s", predecessor);
989        }
990        return true;
991    }
992
993    public boolean assertTrue(boolean condition, String message, Object... args) {
994        if (condition) {
995            return true;
996        } else {
997            throw fail(message, args);
998        }
999    }
1000
1001    public boolean assertFalse(boolean condition, String message, Object... args) {
1002        if (condition) {
1003            throw fail(message, args);
1004        } else {
1005            return true;
1006        }
1007    }
1008
1009    protected VerificationError fail(String message, Object... args) throws GraalGraphError {
1010        throw new VerificationError(message, args).addContext(this);
1011    }
1012
1013    public Iterable<? extends Node> cfgPredecessors() {
1014        if (predecessor == null) {
1015            return Collections.emptySet();
1016        } else {
1017            return Collections.singleton(predecessor);
1018        }
1019    }
1020
1021    /**
1022     * Returns an iterator that will provide all control-flow successors of this node. Normally this
1023     * will be the contents of all fields annotated with {@link Successor}, but some node classes
1024     * (like EndNode) may return different nodes.
1025     */
1026    public Iterable<? extends Node> cfgSuccessors() {
1027        return successors();
1028    }
1029
1030    /**
1031     * Nodes always use an {@linkplain System#identityHashCode(Object) identity} hash code.
1032     */
1033    @Override
1034    public final int hashCode() {
1035        return System.identityHashCode(this);
1036    }
1037
1038    /**
1039     * Equality tests must rely solely on identity.
1040     */
1041    @Override
1042    public final boolean equals(Object obj) {
1043        return super.equals(obj);
1044    }
1045
1046    /**
1047     * Provides a {@link Map} of properties of this node for use in debugging (e.g., to view in the
1048     * ideal graph visualizer).
1049     */
1050    public final Map<Object, Object> getDebugProperties() {
1051        return getDebugProperties(new HashMap<>());
1052    }
1053
1054    /**
1055     * Fills a {@link Map} with properties of this node for use in debugging (e.g., to view in the
1056     * ideal graph visualizer). Subclasses overriding this method should also fill the map using
1057     * their superclass.
1058     *
1059     * @param map
1060     */
1061    public Map<Object, Object> getDebugProperties(Map<Object, Object> map) {
1062        Fields properties = getNodeClass().getData();
1063        for (int i = 0; i < properties.getCount(); i++) {
1064            map.put(properties.getName(i), properties.get(this, i));
1065        }
1066        NodeSourcePosition pos = getNodeSourcePosition();
1067        if (pos != null) {
1068            map.put("nodeSourcePosition", pos);
1069        }
1070        return map;
1071    }
1072
1073    /**
1074     * This method is a shortcut for {@link #toString(Verbosity)} with {@link Verbosity#Short}.
1075     */
1076    @Override
1077    public final String toString() {
1078        return toString(Verbosity.Short);
1079    }
1080
1081    /**
1082     * Creates a String representation for this node with a given {@link Verbosity}.
1083     */
1084    public String toString(Verbosity verbosity) {
1085        switch (verbosity) {
1086            case Id:
1087                return Integer.toString(id);
1088            case Name:
1089                return getNodeClass().shortName();
1090            case Short:
1091                return toString(Verbosity.Id) + "|" + toString(Verbosity.Name);
1092            case Long:
1093                return toString(Verbosity.Short);
1094            case Debugger:
1095            case All: {
1096                StringBuilder str = new StringBuilder();
1097                str.append(toString(Verbosity.Short)).append(" { ");
1098                for (Map.Entry<Object, Object> entry : getDebugProperties().entrySet()) {
1099                    str.append(entry.getKey()).append("=").append(entry.getValue()).append(", ");
1100                }
1101                str.append(" }");
1102                return str.toString();
1103            }
1104            default:
1105                throw new RuntimeException("unknown verbosity: " + verbosity);
1106        }
1107    }
1108
1109    @Deprecated
1110    public int getId() {
1111        return id;
1112    }
1113
1114    @Override
1115    public void formatTo(Formatter formatter, int flags, int width, int precision) {
1116        if ((flags & FormattableFlags.ALTERNATE) == FormattableFlags.ALTERNATE) {
1117            formatter.format("%s", toString(Verbosity.Id));
1118        } else if ((flags & FormattableFlags.UPPERCASE) == FormattableFlags.UPPERCASE) {
1119            // Use All here since Long is only slightly longer than Short.
1120            formatter.format("%s", toString(Verbosity.All));
1121        } else {
1122            formatter.format("%s", toString(Verbosity.Short));
1123        }
1124
1125        boolean neighborsAlternate = ((flags & FormattableFlags.LEFT_JUSTIFY) == FormattableFlags.LEFT_JUSTIFY);
1126        int neighborsFlags = (neighborsAlternate ? FormattableFlags.ALTERNATE | FormattableFlags.LEFT_JUSTIFY : 0);
1127        if (width > 0) {
1128            if (this.predecessor != null) {
1129                formatter.format(" pred={");
1130                this.predecessor.formatTo(formatter, neighborsFlags, width - 1, 0);
1131                formatter.format("}");
1132            }
1133
1134            for (Position position : this.inputPositions()) {
1135                Node input = position.get(this);
1136                if (input != null) {
1137                    formatter.format(" ");
1138                    formatter.format(position.getName());
1139                    formatter.format("={");
1140                    input.formatTo(formatter, neighborsFlags, width - 1, 0);
1141                    formatter.format("}");
1142                }
1143            }
1144        }
1145
1146        if (precision > 0) {
1147            if (!hasNoUsages()) {
1148                formatter.format(" usages={");
1149                int z = 0;
1150                for (Node usage : usages()) {
1151                    if (z != 0) {
1152                        formatter.format(", ");
1153                    }
1154                    usage.formatTo(formatter, neighborsFlags, 0, precision - 1);
1155                    ++z;
1156                }
1157                formatter.format("}");
1158            }
1159
1160            for (Position position : this.successorPositions()) {
1161                Node successor = position.get(this);
1162                if (successor != null) {
1163                    formatter.format(" ");
1164                    formatter.format(position.getName());
1165                    formatter.format("={");
1166                    successor.formatTo(formatter, neighborsFlags, 0, precision - 1);
1167                    formatter.format("}");
1168                }
1169            }
1170        }
1171    }
1172
1173    /**
1174     * Determines if this node's {@link NodeClass#getData() data} fields are equal to the data
1175     * fields of another node of the same type. Primitive fields are compared by value and
1176     * non-primitive fields are compared by {@link Objects#equals(Object, Object)}.
1177     *
1178     * The result of this method undefined if {@code other.getClass() != this.getClass()}.
1179     *
1180     * @param other a node of exactly the same type as this node
1181     * @return true if the data fields of this object and {@code other} are equal
1182     */
1183    public boolean valueEquals(Node other) {
1184        return getNodeClass().dataEquals(this, other);
1185    }
1186
1187    public final void pushInputs(NodeStack stack) {
1188        getNodeClass().pushInputs(this, stack);
1189    }
1190}
1191