Constructing a DAG for a Basic Block with Variable Redefinitions
To construct the DAG for a basic block, you typically represent each statement as a node and draw edges to express data dependencies between the definitions of values and the uses of those values. Key dependency notions include true (flow) dependence and anti-dependence; together they guide correct ordering constraints. 2
For the basic block:
the challenge is the redefinition of in the third statement. That means the uses of in statement 2 must depend on the original (from before the block), while the computation in statement 3 defines a new that is not used later within the block. Correct DAG construction therefore distinguishes “versions” of (via conceptual SSA-style renaming) so that edges reflect the proper source of each used value. 2
Footnotes
-
Dynamic Data Flow Dependence / true dependence concepts (overview) - Defines true (flow) dependence and related dependence types. ↩
-
Reordering constraints from dependence (data dependence graph relationships) - Discusses dependence relations used in program analysis. ↩
-
Static Single Assignment (SSA) form - Explains SSA renaming and why it clarifies definitions/uses. ↩
-
Compiler intermediate representation basics (basic blocks) - Defines basic blocks and how straight-line code segments are modeled. ↩
Data Dependence Graphs and SSA (conceptual overview)
Key definitions for DAG construction
- basic block: we assume control flow is fixed, so dependencies are about values, not branch decisions.
- node: each assignment becomes a node.
- use and definition: edges connect definitions to uses.
- SSA renaming: often done conceptually to handle reassignments like .
A compact way to think about the DAG is:
- Create a node for each assignment.
- For each operand on the RHS, connect from the node (or input) that produces that exact value version.
Footnotes
-
Static Single Assignment (SSA) form - Explains SSA renaming and why it clarifies definitions/uses. ↩
Step-by-step: build the DAG nodes and edges
- 1Step 1
Create nodes N1..N4 corresponding to the four assignments in program order.
- 2Step 2
Because is assigned in statement 3, treat the used in statements 1 and 2 as (the block’s incoming value), and treat the defined in statement 3 as .
- 3Step 3
For each statement, add incoming edges from the node/input that defines each RHS operand. For example, uses and .
- 4Step 4
Treat , , and as coming from the block inputs (source nodes), then connect them to the computations that use them.
- 5Step 5
The defined in statement 3 is not used later in the block, so there are no edges from N3 to statements after it.
- 6Step 6
Because edges only go from the defining occurrence to the later use within the basic block, the graph remains acyclic.
DAG construction with value renaming
Let:
- Node :
- Node :
- Node : (redefines )
- Node :
Conceptually rename:
- used in and is (incoming to the block)
- defined by is
Also treat and as block inputs feeding the first uses:
- input is
- input is
Now the true dependencies are:
- uses and , defines
- uses and , defines
- uses and , defines
- uses and , defines (new value )
Thus, edges are from the definition of each operand to each use:
- From input to , ,
- From input to ,
- From input to
- From (defines ) to (uses )
- From (defines ) to (uses )
A correct DAG reflects only these value-producing dependencies (and not “schedule” dependencies that would be implied by anti/output dependence unless you’re building a dependence graph for reordering). The usual DAG for expression evaluation in a basic block is centered on true data dependencies. 2
Footnotes
-
Dynamic Data Flow Dependence / true dependence concepts (overview) - Defines true (flow) dependence and related dependence types. ↩
-
Reordering constraints from dependence (data dependence graph relationships) - Discusses dependence relations used in program analysis. ↩
Visual DAG (true data dependence)
Pro Tip: Rename only what matters
You don’t need full SSA construction for every variable; here it’s sufficient to distinguish vs so that uses in correctly depend on the pre-redefinition .
Don’t add edges based on “name” alone
A common mistake is to connect to because both mention / by name. DAG edges should connect the specific value definitions to their uses.
Dependency-driven evaluation order (one valid schedule)
Compute d and e in parallel
Step 1N1 and N2 depend only on inputs a0, b0, c0."
Compute b1
Step 2N3 can run after inputs are available; it does not affect later nodes in this block."
Compute a1
Step 3N4 requires both d (from N1) and e (from N2)."
Summary of true dependencies per node
Counts of distinct value sources feeding each computation (inputs and prior nodes).
FAQ on DAG vs other dependence graphs
Knowledge Check
In the DAG for the block, which statement defines the value of used by the final statement ?