dominators (module G) g entry
builds a dominators tree for a given graph.
Definition: a walk is a sequence of alternating nodes and edges, where each edge's endpoints are the preceding and following nodes in the sequence.
Definition: a node v
is reachable if there exists a walk starting from entry
and ending with v
.
Definition: node u
dominates v
if u = v
or if all walks from entry
to v
contains u
.
Definition: node u
strictly dominates v
if it dominates v
and u <> v
.
Definition: node u
immediately dominates v
if it strictly dominates v
and there is no other node that strictly dominates v
and is dominated by u
.
Algorithm computes a dominator tree t
that has the following properties:
- Sets of graph nodes and tree nodes are equal;
- if node
u
is a parent of node v
, then node u
immediately dominates node v
; - if node
u
is an ancestors of node v
, then node u
strictly dominates node v
; - if node
v
is a child of node u
, then node u
immediately dominates node v
; - if node
v
is a descendant of node u
, then node u
strictly dominates node v
.
If every node of graph g
is reachable from a provided entry
node, then properties (2) - (5) are reversible, i.e., an if
statement can be read as iff
, and the tree is unique.
Lemma: Everything dominates unreachable block.
Proof: (by contradiction) suppose there exists a node u
that doesn't dominate unreachable block v
. That means, that there exists a path from entry
to v
that doesn't contain u
. But that means, at least, that v
is reachable. This is a contradiction with the original statement that v
is unreachable. Qed.
If some nodes of graph g
are unreachable from the provided entry
node, then they are dominated by all other nodes of a graph. It means that the provided system is under constrained and has more then one solution (i.e., there exists more than one tree, that satisfies properties (1) - (5). In a current implementation each unreachable node is immediately dominated by the entry
, if the entry
is in graph.
To get a post-dominator tree, reverse the graph by passing true
to rev
and pass exit node as a starting node.
Note: although it is not imposed by the algotihm, but it is a good idea to have an entry node, that doesn't have any predecessors. Usually, this is what is silently assumed in many program analysis textbooks, but is not true in general for control-flow graphs that are reconstructed from binaries