public abstract class Node extends Object implements Cloneable, Formattable
Graph.
Once a node has been added to a graph, it has a graph-unique Node.id(). Edges in the
subclasses are represented with annotated fields. There are two kind of edges: Node.Input and
Node.Successor. If a field of type Node is annotated with Node.Input or
Node.Successor, it must not be null. There is an edge from this node to the node
denoted by the field's value. A field annotated with Node.OptionalInput is also such an edge
but it may be null.
Exactly one of Node.Input, Node.OptionalInput, or Node.Successor must be applied to all
fields of a node that are of type Node. A field of type NodeInputList must be
annotated with Node.Input or Node.OptionalInput. A field of type NodeSuccessorList
must be annotated with Node.Successor.
Nodes which are value numberable should implement the Node.ValueNumberable interface.
Node.assertTrue(boolean, String, Object...) and
Node.assertFalse(boolean, String, Object...) methods, which will check the supplied boolean
and throw a VerificationError if it has the wrong value. Both methods will always either throw an
exception or return true. They can thus be used within an assert statement, so that the check is
only performed if assertions are enabled.| Modifier and Type | Class and Description |
|---|---|
static interface |
Node.ConstantNodeParameter
Denotes that a parameter of an intrinsic method must be a compile
time constant at all call sites to the intrinsic method.
|
static class |
Node.EdgeVisitor |
static interface |
Node.IndirectCanonicalization
Marker interface for nodes that contain other nodes.
|
static interface |
Node.InjectedNodeParameter
Denotes an injected parameter in a node intrinsic constructor.
|
static interface |
Node.Input
Denotes a non-optional (non-null) node input.
|
static class |
Node.NodeInsertionStackTrace |
static interface |
Node.NodeIntrinsic
Annotates a method that can be replaced by a compiler intrinsic.
|
static interface |
Node.NodeIntrinsicFactory
Marker annotation indicating that the class uses factory methods instead of constructors for
intrinsification.
|
static interface |
Node.OptionalInput
Denotes an optional (nullable) node input.
|
static interface |
Node.Successor
Denotes a non-optional (non-null) node successor.
|
static interface |
Node.ValueNumberable
Marker for a node that can be replaced by another node via global value numbering.
|
| Modifier and Type | Field and Description |
|---|---|
static int |
NODE_LIST |
static int |
NOT_ITERABLE |
static boolean |
TRACK_CREATION_POSITION |
static NodeClass<?> |
TYPE |
static EnumSet<Edges.Type> |
WithAllEdges |
static EnumSet<Edges.Type> |
WithNoEdges |
static EnumSet<Edges.Type> |
WithOnlyInputEdges |
static EnumSet<Edges.Type> |
WithOnlySucessorEdges |
| Modifier and Type | Method and Description |
|---|---|
protected void |
afterClone(Node other) |
void |
applyInputs(Node.EdgeVisitor visitor)
Applies the given visitor to all inputs of
this. |
void |
applySuccessors(Node.EdgeVisitor visitor)
Applies the given visitor to all successors of
this. |
boolean |
assertFalse(boolean condition,
String message,
Object... args) |
boolean |
assertTrue(boolean condition,
String message,
Object... args) |
Iterable<? extends Node> |
cfgPredecessors() |
Iterable<? extends Node> |
cfgSuccessors()
Returns an iterator that will provide all control-flow successors of
this. |
protected boolean |
checkReplaceAtUsagesInvariants(Node replacement)
Subclasses can override this to check invariants related to replacing uses of
this. |
void |
clearInputs() |
void |
clearNodeSourcePosition() |
void |
clearSuccessors() |
Node |
copyWithInputs() |
Node |
copyWithInputs(boolean insertIntoGraph) |
boolean |
dataFlowEquals(Node other)
Determines if
this is equal to the other node while ignoring differences in
control-flow edges. |
protected NodeSize |
dynamicNodeSizeEstimate()
Node subclasses should override this method if they need to specify a dynamically calculated
NodeSize value. |
NodeCycles |
estimatedNodeCycles() |
NodeSize |
estimatedNodeSize() |
protected GraalGraphError |
fail(String message,
Object... args) |
void |
formatTo(Formatter formatter,
int flags,
int width,
int precision) |
org.graalvm.compiler.graph.Node.NodeCreationStackTrace |
getCreationPosition() |
DebugContext |
getDebug()
Gets the debug context associated with
this.graph(). |
Map<Object,Object> |
getDebugProperties()
Provides a
Map of properties of this for use in debugging (e.g., to view in
the ideal graph visualizer). |
Map<Object,Object> |
getDebugProperties(Map<Object,Object> map)
Fills a
Map with properties of this for use in debugging (e.g., to view in
the ideal graph visualizer). |
Node.NodeInsertionStackTrace |
getInsertionPosition() |
NodeClass<? extends Node> |
getNodeClass() |
NodeSourcePosition |
getNodeSourcePosition()
Gets the source position information for
this or null if it doesn't exist. |
OptionValues |
getOptions()
Gets the option values associated with
this.graph(). |
int |
getUsageCount()
Gets the maximum number of usages
this has had at any point in time. |
Graph |
graph()
Gets the graph context of
this. |
boolean |
hasExactlyOneUsage()
Checks whether
this has exactly one usage. |
int |
hashCode()
Nodes using their
Node.id as the hash code. |
boolean |
hasMoreThanOneUsage()
Checks whether
this has more than one usage. |
boolean |
hasNoUsages()
Checks whether
this has no usages. |
boolean |
hasOnlyUsagesOfType(InputType inputType)
Checks whether
this has only usages of type inputType. |
boolean |
hasUsages()
Checks whether
this has usages. |
boolean |
hasUsagesOfType(InputType type)
Checks whether this node has usages of a given
InputType. |
Iterable<Position> |
inputPositions()
Returns an
iterable which can be used to traverse all non-null input edges
of this. |
NodeIterable<Node> |
inputs()
Returns an
iterable which can be used to traverse all non-null input
edges of this. |
boolean |
isAlive() |
boolean |
isAllowedUsageType(InputType type) |
boolean |
isDeleted() |
boolean |
isUnregistered() |
void |
markDeleted() |
void |
maybeNotifyZeroUsages(Node node)
Iterates over each
Graph.NodeEventListener attached to this.graph() if
node.isAlive() and notifies the listener that node has had its last usage
removed. |
int |
modCount() |
Node |
predecessor() |
void |
pushInputs(NodeStack stack) |
boolean |
removeUsage(Node node)
Removes one occurrence of a given node from this node's usages.
|
void |
replaceAllInputs(Node oldInput,
Node newInput)
Finds all
Node.Inputs and Node.OptionalInputs in this whose value is
oldInput and replaces them with newInput. |
void |
replaceAndDelete(Node replacement)
Replaces
this at its predecessor (if any) and its usages with replacement and
removes it from its graph. |
void |
replaceAtAllUsages(Node replacement,
boolean forDeletion)
For each use of
this in another node, replace it with replacement. |
void |
replaceAtMatchingUsages(Node replacement,
NodePredicate usagePredicate)
For each use of
this in another node, n, replace it with replacement
if filter.test(n) == true. |
void |
replaceAtPredecessor(Node replacement)
Updates the control flow edge, if it exists, from
Node.predecessor() to this to
have a target of replacement. |
void |
replaceAtUsages(Node replacement)
For each use of
this in another node, replace it with replacement. |
void |
replaceAtUsages(Node replacement,
InputType... inputTypes)
For each use of
this in another node, n, replace it with replacement
if the type of the use is in inputTypes. |
void |
replaceAtUsages(Node replacement,
InputType inputType)
For each use of
this in another node, n, replace it with replacement
if the type of the use is inputType. |
void |
replaceAtUsages(Node replacement,
Predicate<Node> filter)
For each use of
this in another node, n, replace it with replacement
if filter == null or filter.test(n) == true. |
void |
replaceAtUsages(Node replacement,
Predicate<Node> filter,
boolean checkInvariants)
For each use of
this in another node, n, replace it with replacement
if filter == null or filter.test(n) == true. |
void |
replaceAtUsagesAndDelete(Node replacement)
For each use of
this in another node, replace it with replacement and then
remove this from the graph. |
void |
replaceAtUsagesAndDelete(Node replacement,
Predicate<Node> filter)
For each use of
this in another node, n, replace it with replacement
if filter == null or filter.test(n) == true and then
remove this from the graph. |
void |
replaceFirstInput(Node oldInput,
Node newInput)
Finds the first
Node.Input or Node.OptionalInput in this whose value is
oldInput and replaces it with newInput. |
void |
replaceFirstSuccessor(Node oldSuccessor,
Node newSuccessor)
Finds the first
Node.Successor in this whose value is oldSuccessor and
replaces it with newSuccessor. |
void |
safeDelete()
Removes
this from this.graph(). |
void |
setCreationPosition(org.graalvm.compiler.graph.Node.NodeCreationStackTrace trace) |
void |
setInsertionPosition(Node.NodeInsertionStackTrace trace) |
void |
setNodeSourcePosition(NodeSourcePosition sourcePosition)
Set the source position to
sourcePosition. |
Node |
singleUsage() |
Iterable<Position> |
successorPositions()
Returns an
iterable which can be used to traverse all successor edge
positions of this. |
NodeIterable<Node> |
successors()
Returns an
iterable which can be used to traverse all non-null successor
edges of this. |
String |
toString()
This method is a shortcut for
Node.toString(Verbosity) with Verbosity.Short. |
String |
toString(Verbosity verbosity)
Creates a String representation for
this with a given Verbosity. |
void |
updateNodeSourcePosition(Supplier<NodeSourcePosition> sourcePositionSupp)
Update the source position only if it is null.
|
protected void |
updatePredecessor(Node oldSuccessor,
Node newSuccessor)
Updates the predecessor of the given nodes after a successor slot is changed from
oldSuccessor to newSuccessor: removes
this from oldSuccessor's predecessors and adds
this to newSuccessor's predecessors. |
protected void |
updateUsages(Node oldInput,
Node newInput)
Removes one occurrence of
this from oldInput's usages and adds it to
newInput's usages. |
NodeIterable<Node> |
usages()
Gets the list of nodes that use
this (i.e., as an input). |
boolean |
valueEquals(Node other)
Determines if this node's
data fields are equal to the data
fields of another node of the same type. |
boolean |
verify() |
boolean |
verifyEdges()
Perform expensive verification of inputs, usages, predecessors and successors.
|
protected boolean |
verifyInputs() |
boolean |
verifySourcePosition() |
DebugCloseable |
withNodeSourcePosition() |
public static final NodeClass<?> TYPE
public static final boolean TRACK_CREATION_POSITION
public static final int NODE_LIST
public static final int NOT_ITERABLE
public static final EnumSet<Edges.Type> WithNoEdges
public static final EnumSet<Edges.Type> WithAllEdges
public static final EnumSet<Edges.Type> WithOnlyInputEdges
public static final EnumSet<Edges.Type> WithOnlySucessorEdges
public Graph graph()
this.public final OptionValues getOptions()
this.graph().public final DebugContext getDebug()
this.graph().public NodeIterable<Node> inputs()
iterable which can be used to traverse all non-null input
edges of this.iterable for all non-null input edges.public Iterable<Position> inputPositions()
iterable which can be used to traverse all non-null input edges
of this.iterable for all non-null input edges.public void applyInputs(Node.EdgeVisitor visitor)
this.visitor - the visitor to be applied to the inputspublic void applySuccessors(Node.EdgeVisitor visitor)
this.visitor - the visitor to be applied to the successorspublic NodeIterable<Node> successors()
iterable which can be used to traverse all non-null successor
edges of this.iterable for all non-null successor edges.public Iterable<Position> successorPositions()
iterable which can be used to traverse all successor edge
positions of this.iterable for all successor edge positoins.public int getUsageCount()
this has had at any point in time.public final NodeIterable<Node> usages()
this (i.e., as an input).public final boolean hasNoUsages()
this has no usages.public final boolean hasUsages()
this has usages.public final boolean hasMoreThanOneUsage()
this has more than one usage.public final boolean hasExactlyOneUsage()
this has exactly one usage.public final boolean hasOnlyUsagesOfType(InputType inputType)
this has only usages of type inputType.inputType - the type of usages to look forpublic final boolean hasUsagesOfType(InputType type)
InputType.type - the type of usages to look forpublic boolean removeUsage(Node node)
node - the node to removeusage was in the usage listpublic final Node predecessor()
public final int modCount()
public final boolean isDeleted()
public final boolean isAlive()
public final boolean isUnregistered()
protected void updateUsages(Node oldInput, Node newInput)
this from oldInput's usages and adds it to
newInput's usages.protected void updatePredecessor(Node oldSuccessor, Node newSuccessor)
this from oldSuccessor's predecessors and adds
this to newSuccessor's predecessors.public NodeSourcePosition getNodeSourcePosition()
this or null if it doesn't exist.public void setNodeSourcePosition(NodeSourcePosition sourcePosition)
sourcePosition. Setting it to null is ignored so that it's
not accidentally cleared. Use Node.clearNodeSourcePosition() instead.public void clearNodeSourcePosition()
public org.graalvm.compiler.graph.Node.NodeCreationStackTrace getCreationPosition()
public void setCreationPosition(org.graalvm.compiler.graph.Node.NodeCreationStackTrace trace)
public Node.NodeInsertionStackTrace getInsertionPosition()
public void setInsertionPosition(Node.NodeInsertionStackTrace trace)
public void updateNodeSourcePosition(Supplier<NodeSourcePosition> sourcePositionSupp)
public DebugCloseable withNodeSourcePosition()
public boolean isAllowedUsageType(InputType type)
public final void replaceAtUsages(Node replacement)
this in another node, replace it with replacement.
This is shown by the graph transformation below where edges are from usages to inputs (e.g.
this is an input of n0).
Before:
this
^
|
/|\
/ | \
/ | \
n0 n1 ..nN
After:
replacement
^
|
/|\
/ | \
/ | \
n0 n1 ..nN
If replacement == null, then the edges are simply removed.public final void replaceAtUsages(Node replacement, Predicate<Node> filter)
this in another node, n, replace it with replacement
if filter == null or filter.test(n) == true.Node.replaceAtUsages(Node)public final void replaceAtUsages(Node replacement, Predicate<Node> filter, boolean checkInvariants)
this in another node, n, replace it with replacement
if filter == null or filter.test(n) == true.Node.replaceAtUsages(Node)public final void replaceAtUsagesAndDelete(Node replacement)
this in another node, replace it with replacement and then
remove this from the graph.Node.replaceAtUsages(Node)public final void replaceAtUsagesAndDelete(Node replacement, Predicate<Node> filter)
this in another node, n, replace it with replacement
if filter == null or filter.test(n) == true and then
remove this from the graph.Node.replaceAtUsages(Node)protected boolean checkReplaceAtUsagesInvariants(Node replacement)
this.replacement - true if all invariants holdpublic final void replaceAtAllUsages(Node replacement, boolean forDeletion)
this in another node, replace it with replacement.forDeletion - specifies if the caller will remove
this from the graph after this method returnspublic Node singleUsage()
public void replaceAtMatchingUsages(Node replacement, NodePredicate usagePredicate)
this in another node, n, replace it with replacement
if filter.test(n) == true.Node.replaceAtUsages(Node)public void replaceAtUsages(Node replacement, InputType inputType)
this in another node, n, replace it with replacement
if the type of the use is inputType.Node.replaceAtUsages(Node)public void replaceAtUsages(Node replacement, InputType... inputTypes)
this in another node, n, replace it with replacement
if the type of the use is in inputTypes.Node.replaceAtUsages(Node)public void maybeNotifyZeroUsages(Node node)
Graph.NodeEventListener attached to this.graph() if
node.isAlive() and notifies the listener that node has had its last usage
removed.public void replaceAtPredecessor(Node replacement)
Node.predecessor() to this to
have a target of replacement.public void replaceAndDelete(Node replacement)
this at its predecessor (if any) and its usages with replacement and
removes it from its graph.public void replaceFirstSuccessor(Node oldSuccessor, Node newSuccessor)
Node.Successor in this whose value is oldSuccessor and
replaces it with newSuccessor. The predecessor fields in oldSuccessor and
newSuccessor are updated to reflect any change made.public void replaceFirstInput(Node oldInput, Node newInput)
Node.Input or Node.OptionalInput in this whose value is
oldInput and replaces it with newInput. If the input is changed, the usage
info for oldInput and newInput is updated as well.
Before this.replaceFirstInput(n0, n2):
n0 n1 n0
\ | /
\ | /
\|/
|
V
this
After this.replaceFirstInput(n0, n2):
n2 n1 n0
\ | /
\ | /
\|/
|
V
this
public void replaceAllInputs(Node oldInput, Node newInput)
Node.Inputs and Node.OptionalInputs in this whose value is
oldInput and replaces them with newInput. If any input is changed, the usage
info for oldInput and newInput is updated as well.
Before this.replaceAllInputs(n0, n2):
n0 n1 n0
\ | /
\ | /
\|/
|
V
this
After this.replaceAllInputs(n0, n2):
n2 n1 n2
\ | /
\ | /
\|/
|
V
this
public void clearInputs()
public void clearSuccessors()
public void safeDelete()
public void markDeleted()
public final Node copyWithInputs()
public final Node copyWithInputs(boolean insertIntoGraph)
protected void afterClone(Node other)
protected boolean verifyInputs()
public boolean verify()
public boolean verifySourcePosition()
public boolean verifyEdges()
protected GraalGraphError fail(String message, Object... args) throws GraalGraphError
GraalGraphErrorpublic Iterable<? extends Node> cfgSuccessors()
this. Normally
this will be the contents of all fields annotated with Node.Successor, but some node
classes (like EndNode) may return different nodes.public final int hashCode()
Node.id as the hash code. This works very well when nodes of the same
graph are stored in sets. It can give bad behavior when storing nodes of different graphs in
the same set.public final Map<Object,Object> getDebugProperties()
Map of properties of this for use in debugging (e.g., to view in
the ideal graph visualizer).public Map<Object,Object> getDebugProperties(Map<Object,Object> map)
Map with properties of this for use in debugging (e.g., to view in
the ideal graph visualizer). Subclasses overriding this method should also fill the map using
their superclass.map - public final String toString()
Node.toString(Verbosity) with Verbosity.Short.public String toString(Verbosity verbosity)
this with a given Verbosity.public void formatTo(Formatter formatter, int flags, int width, int precision)
formatTo in interface Formattablepublic final boolean valueEquals(Node other)
data fields are equal to the data
fields of another node of the same type. Primitive fields are compared by value and
non-primitive fields are compared by Objects.equals(Object, Object).
The result of this method undefined if other.getClass() != this.getClass().other - a node of exactly the same type as thisother are equalpublic final boolean dataFlowEquals(Node other)
this is equal to the other node while ignoring differences in
control-flow edges.public final void pushInputs(NodeStack stack)
public final NodeSize estimatedNodeSize()
protected NodeSize dynamicNodeSizeEstimate()
NodeSize value. If the node size is static please use NodeInfo.size().
NOTE: When overriding this method, make sure that *all* field reads are null checked (even if
Java semantics seemingly make the value of the field non-null). This is necessary because
node size estimates are needed even during graph decoding which, for some nodes, first
reflectively creates a stub and then later, reflectively, populates its fields. This method
could be invoked between these two points. For this reason, when overriding this method
assume that all fields can and will be null.public NodeCycles estimatedNodeCycles()