@@ -15,6 +15,45 @@ private import SsaInternals as Ssa
1515
1616cached
1717private module Cached {
18+ /**
19+ * The IR dataflow graph consists of the following nodes:
20+ * - `InstructionNode`, which represents an `Instruction` in the graph.
21+ * - `OperandNode`, which represents an `Operand` in the graph.
22+ * - `VariableNode`, which is used to model global variables.
23+ * - Two kinds of `StoreNode`s:
24+ * 1. `StoreNodeInstr`, which represents the value of an address computed by an `Instruction` that
25+ * has been updated by a write operation.
26+ * 2. `StoreNodeOperand`, which represents the value of an address in an `ArgumentOperand` after a
27+ * function call that may have changed the value.
28+ * - `ReadNode`, which represents the result of reading a field of an object.
29+ * - `SsaPhiNode`, which represents phi nodes as computed by the shared SSA library.
30+ *
31+ * The following section describes how flow is generally transferred between these nodes:
32+ * - Flow between `InstructionNode`s and `OperandNode`s follow the def-use information as computed by
33+ * the IR. Because the IR compute must-alias information for memory operands, we only follow def-use
34+ * flow for register operands.
35+ * - Flow can enter a `StoreNode` in two ways (both done in `StoreNode.flowInto`):
36+ * 1. Flow is transferred from a `StoreValueOperand` to a `StoreNodeInstr`. Flow will then proceed
37+ * along the chain of addresses computed by `StoreNodeInstr.getInner` to identify field writes
38+ * and call `storeStep` accordingly (i.e., for an expression like `a.b.c = x`, we visit `c`, then
39+ * `b`, then `a`).
40+ * 2. Flow is transfered from a `WriteSideEffectInstruction` to a `StoreNodeOperand` after flow
41+ * returns to a caller. Flow will then proceed to the defining instruction of the operand (because
42+ * the `StoreNodeInstr` computed by `StoreNodeOperand.getInner()` is the `StoreNode` containing
43+ * the defining instruction), and then along the chain computed by `StoreNodeInstr.getInner` like
44+ * above.
45+ * In both cases, flow leaves a `StoreNode` once the entire chain has been traversed, and the shared
46+ * SSA library is used to find the next use of the variable at the end of the chain.
47+ * - Flow can enter a `ReadNode` through an `OperandNode` that represents an address of some variable.
48+ * Flow will then proceed along the chain of addresses computed by `ReadNode.getOuter` (i.e., for an
49+ * expression like `use(a.b.c)` we visit `a`, then `b`, then `c`) and call `readStep` accordingly.
50+ * Once the entire chain has been traversed, flow is transferred to the load instruction that reads
51+ * the final address of the chain.
52+ * - Flow can enter a `SsaPhiNode` from an `InstructionNode`, a `StoreNode` or another `SsaPhiNode`
53+ * (in `toPhiNode`), depending on which node provided the previous definition of the underlying
54+ * variable. Flow leaves a `SsaPhiNode` (in `fromPhiNode`) by using the shared SSA library to
55+ * determine the next use of the variable.
56+ */
1857 cached
1958 newtype TIRDataFlowNode =
2059 TInstructionNode ( Instruction i ) or
0 commit comments