A postblit is present on this object, but not explicitly documented in the source.
Compares two nodes for equivalence.
Fetches a specific in-edge slot in this node.
Returns this node's (assumedly up to date) cached hash value.
Updates a node's cached hash value.
SSA form is one of Gyre's key aspects. It can be summarized as an attempt to make program values and variable names correspond one-to-one. In a graph, we swap 'names' for 'edges' (or pointers, in our case). We'll try to make all uses of a specific value point to the same edge slot.
This is essentially GVN. Doing this perfectly in all cases has a prohibitive canonicalization cost, so we approximate it on a per-node basis: whenever we're about to add a new node to the graph, we'll check if it is redundant, in which case it can be hash-consed, with its uses rewired into the existing graph. This check requires a way to compare two nodes for equivalence, i.e., whether swapping one for the other preserves program semantics.
In data-only operations, this usually reduces to structural equality: a node produces the same value (in a corresponding InEdge) as another when they perform the same operation and their inputs are equal (notice the recursion here). Structural comparisons are relatively expensive operations (especially since the graph could be cyclic), so we want to leverage hashing to do as few comparisons as possible. Therefore, a node's hash value better reflect its semantic structure: having equal hashes is a necessary (but insufficient) condition for two nodes to be equal. Now, computing a node's hash value becomes an expensive operation as well, but fortunately it can be cached once a node's structure has stabilized.
Hidden member | Type | Description |
---|---|---|
hash | hash_t | A node's cached hash value. This is what gets returned when toHash is called on a generic Node, so it should be updated (see updateHash) whenever a node's semantic structure stabilizes. |
asNode | ref T -> Node* | Method which upcasts (and this never fails) a concrete node ref to a generic Node*. |
ofNode | Node* -> T* | Static method which tries to downcast a generic Node* to a pointer to a concrete type, returning null when the cast would have resulted in an invalid reference (so this is technically type-safe). |
Common prefix shared by all nodes, safely used ONLY through pointers.
References to this substructure can be used as type-punned handles to any of our nodes.