|
Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
|
Computes dominator tree and dominance frontiers of a digraph using the Lengauer-Tarjan algorithm. More...
#include <Dominators.H>
Public Member Functions | |
| Lengauer_Tarjan_Dominators (SA __sa=SA()) noexcept | |
| Construct a dominator computation instance. | |
| Lengauer_Tarjan_Dominators (const Lengauer_Tarjan_Dominators &)=delete | |
| Dominator instances should not be copied (they hold internal state) | |
| Lengauer_Tarjan_Dominators & | operator= (const Lengauer_Tarjan_Dominators &)=delete |
| Lengauer_Tarjan_Dominators (Lengauer_Tarjan_Dominators &&)=default | |
| Move is allowed. | |
| Lengauer_Tarjan_Dominators & | operator= (Lengauer_Tarjan_Dominators &&)=default |
| DynList< std::pair< Node *, Node * > > | compute_idom (GT &g, Node *root) |
| Compute immediate dominators. | |
| void | build_tree (GT &g, Node *root, GT &tree) |
| Build the dominator tree as a separate graph. | |
| Node * | get_idom (GT &g, Node *root, Node *node) |
| Get the immediate dominator of a specific node. | |
| bool | dominates (GT &g, Node *root, Node *d, Node *v) |
| Test whether node d dominates node v. | |
| DynMapTree< Node *, DynSetTree< Node * > > | dominance_frontiers (GT &g, Node *root) |
| Compute dominance frontiers for all reachable nodes. | |
| void | operator() (GT &g, Node *root, GT &tree) |
| Build dominator tree (operator() alias). | |
Accessors | |
| SA & | get_filter () noexcept |
| Get the arc filter. | |
| const SA & | get_filter () const noexcept |
| Get the arc filter (const). | |
| bool | has_computation () const noexcept |
| Check if a computation has been performed. | |
| GT * | get_graph () const noexcept |
| Get the graph of the last computation. | |
| Node * | get_root () const noexcept |
| Get the root of the last computation. | |
| long | get_num_reachable () const noexcept |
| Get the number of reachable nodes in the last computation. | |
Private Types | |
| using | Node = typename GT::Node |
| using | Arc = typename GT::Arc |
Private Member Functions | |
| void | compress (long v) |
| Path compression for Union-Find (iterative). | |
| void | dfs (Node *root_ptr) |
| Iterative DFS to number nodes and build DFS tree. | |
| long | eval (const long v) |
| EVAL operation for the Union-Find forest. | |
| void | do_compute (GT &g, Node *root) |
| Core computation of dominators. | |
| void | ensure_computed (GT &g, Node *root) |
| Ensure computation is up to date. | |
Private Attributes | |
| SA | sa |
| GT * | gptr = nullptr |
| Node * | root_ptr = nullptr |
| bool | is_computed = false |
| long | num_reachable = 0 |
| Array< Node * > | vertex |
| Array< long > | par |
| Array< long > | semi |
| Array< long > | idom_arr |
| Array< long > | anc |
| Array< long > | label_arr |
| Array< DynList< long > > | pred |
Computes dominator tree and dominance frontiers of a digraph using the Lengauer-Tarjan algorithm.
This class implements the Lengauer-Tarjan algorithm for computing immediate dominators in a directed graph from a given root node. The algorithm runs in O(E * alpha(V)) time using a Union-Find structure with path compression.
The class caches its computation: calling multiple methods with the same graph and root reuses the previous result without recomputing.
| GT | The directed graph type. |
| SA | Arc filter class for the internal iterator. Defaults to Dft_Show_Arc<GT> which shows all arcs. |
NODE_COUNTER on graph nodes internally. After computation, node counters contain DFS numbers. Definition at line 147 of file Dominators.H.
Definition at line 152 of file Dominators.H.
Definition at line 151 of file Dominators.H.
|
inlinenoexcept |
Construct a dominator computation instance.
| __sa | Arc filter functor. Defaults to Dft_Show_Arc<GT>. |
Definition at line 390 of file Dominators.H.
|
delete |
Dominator instances should not be copied (they hold internal state)
|
default |
Move is allowed.
|
inline |
Build the dominator tree as a separate graph.
Creates a new directed graph tree where each reachable node from the original graph is represented, and arcs go from idom to child. Nodes are mapped via NODE_COOKIE between the original graph and the tree (bidirectional mapping via GT::map_nodes).
| g | The directed graph. | |
| root | Root node. | |
| [out] | tree | Output dominator tree (cleared first). |
| std::domain_error | If root is null. |
Definition at line 441 of file Dominators.H.
References Aleph::clear_graph(), Aleph::divide_and_conquer_partition_dp(), Aleph::Lengauer_Tarjan_Dominators< GT, SA >::ensure_computed(), Aleph::Lengauer_Tarjan_Dominators< GT, SA >::idom_arr, Aleph::List_Graph< _Graph_Node, _Graph_Arc >::insert_arc(), Aleph::List_Graph< _Graph_Node, _Graph_Arc >::insert_node(), GraphCommon< GT, Node, Arc >::map_nodes(), Aleph::Lengauer_Tarjan_Dominators< GT, SA >::num_reachable, root(), and Aleph::Lengauer_Tarjan_Dominators< GT, SA >::vertex.
|
inlineprivate |
Path compression for Union-Find (iterative).
Updates label[v] to hold the node with the minimum semi-dominator on the path from v to the tree root in the current forest.
| v | The node (DFS number) to compress. |
Definition at line 176 of file Dominators.H.
References Aleph::Lengauer_Tarjan_Dominators< GT, SA >::anc, Aleph::and, Aleph::Array< T >::append(), Aleph::divide_and_conquer_partition_dp(), Aleph::Array< T >::is_empty(), Aleph::Lengauer_Tarjan_Dominators< GT, SA >::label_arr, Aleph::Array< T >::remove_last(), root(), and Aleph::Lengauer_Tarjan_Dominators< GT, SA >::semi.
Referenced by Aleph::Lengauer_Tarjan_Dominators< GT, SA >::eval().
|
inline |
Compute immediate dominators.
Returns a list of (node, idom) pairs for every node reachable from the root. The root's idom is nullptr.
| g | The directed graph. |
| root | Root node for dominator computation. |
| std::domain_error | If root is null. |
Definition at line 416 of file Dominators.H.
References Aleph::DynList< T >::append(), Aleph::divide_and_conquer_partition_dp(), Aleph::Lengauer_Tarjan_Dominators< GT, SA >::ensure_computed(), Aleph::Lengauer_Tarjan_Dominators< GT, SA >::idom_arr, Aleph::Lengauer_Tarjan_Dominators< GT, SA >::num_reachable, root(), and Aleph::Lengauer_Tarjan_Dominators< GT, SA >::vertex.
Referenced by main().
|
inlineprivate |
Iterative DFS to number nodes and build DFS tree.
| root_ptr | Root node pointer. |
Definition at line 205 of file Dominators.H.
References Aleph::Lengauer_Tarjan_Dominators< GT, SA >::anc, Aleph::divide_and_conquer_partition_dp(), GraphCommon< GT, Node, Arc >::get_tgt_node(), Aleph::Lengauer_Tarjan_Dominators< GT, SA >::gptr, Aleph::DynListStack< T >::is_empty(), Aleph::Lengauer_Tarjan_Dominators< GT, SA >::label_arr, NODE_COUNTER, Aleph::Lengauer_Tarjan_Dominators< GT, SA >::num_reachable, Aleph::Lengauer_Tarjan_Dominators< GT, SA >::par, Aleph::DynListStack< T >::pop(), Aleph::DynListStack< T >::push(), Aleph::Lengauer_Tarjan_Dominators< GT, SA >::root_ptr, Aleph::Lengauer_Tarjan_Dominators< GT, SA >::sa, Aleph::Lengauer_Tarjan_Dominators< GT, SA >::semi, Aleph::DynListStack< T >::top(), and Aleph::Lengauer_Tarjan_Dominators< GT, SA >::vertex.
Referenced by Aleph::Lengauer_Tarjan_Dominators< GT, SA >::do_compute().
Core computation of dominators.
Performs DFS from root, computes semi-dominators in reverse DFS order using the Union-Find forest, then resolves immediate dominators in a forward pass.
| g | The directed graph. |
| root | The root node for dominator computation. |
Definition at line 276 of file Dominators.H.
References Aleph::Lengauer_Tarjan_Dominators< GT, SA >::anc, Aleph::and, Aleph::Array< T >::append(), Aleph::Lengauer_Tarjan_Dominators< GT, SA >::dfs(), Aleph::divide_and_conquer_partition_dp(), Aleph::Lengauer_Tarjan_Dominators< GT, SA >::eval(), GraphCommon< GT, Node, Arc >::for_each_node(), GraphCommon< GT, Node, Arc >::get_num_nodes(), GraphCommon< GT, Node, Arc >::get_src_node(), GraphCommon< GT, Node, Arc >::get_tgt_node(), Aleph::Lengauer_Tarjan_Dominators< GT, SA >::gptr, Aleph::Lengauer_Tarjan_Dominators< GT, SA >::idom_arr, Aleph::Lengauer_Tarjan_Dominators< GT, SA >::is_computed, Aleph::Lengauer_Tarjan_Dominators< GT, SA >::label_arr, N, NODE_COUNTER, Aleph::Lengauer_Tarjan_Dominators< GT, SA >::num_reachable, Aleph::Lengauer_Tarjan_Dominators< GT, SA >::par, Aleph::Lengauer_Tarjan_Dominators< GT, SA >::pred, Aleph::Array< T >::remove_first(), root(), Aleph::Lengauer_Tarjan_Dominators< GT, SA >::root_ptr, Aleph::Lengauer_Tarjan_Dominators< GT, SA >::sa, Aleph::Lengauer_Tarjan_Dominators< GT, SA >::semi, Aleph::Lengauer_Tarjan_Dominators< GT, SA >::vertex, and w.
Referenced by Aleph::Lengauer_Tarjan_Dominators< GT, SA >::ensure_computed().
|
inline |
Compute dominance frontiers for all reachable nodes.
The dominance frontier DF(x) of a node x is the set of nodes y where x dominates a predecessor of y but does not strictly dominate y. This is the key data structure for placing phi-functions in SSA form.
Uses the standard algorithm: for each join point (node with 2+ predecessors), walk up from each predecessor to its idom, adding the join point to each visited node's frontier.
| g | The directed graph. |
| root | Root node. |
| std::domain_error | If root is null. |
Definition at line 541 of file Dominators.H.
References Aleph::and, Aleph::df(), Aleph::divide_and_conquer_partition_dp(), Aleph::Lengauer_Tarjan_Dominators< GT, SA >::ensure_computed(), Aleph::Lengauer_Tarjan_Dominators< GT, SA >::idom_arr, Aleph::DynMapTree< Key, Data, Tree, Compare >::insert(), Aleph::Array< T >::insert(), Aleph::Lengauer_Tarjan_Dominators< GT, SA >::num_reachable, Aleph::Lengauer_Tarjan_Dominators< GT, SA >::pred, root(), Aleph::size(), and Aleph::Lengauer_Tarjan_Dominators< GT, SA >::vertex.
Referenced by main().
|
inline |
Test whether node d dominates node v.
Dominance is reflexive: every node dominates itself.
| g | The directed graph. |
| root | Root node. |
| d | Potential dominator. |
| v | Potential dominated node. |
| std::domain_error | If root is null. |
Definition at line 498 of file Dominators.H.
References Aleph::divide_and_conquer_partition_dp(), Aleph::Lengauer_Tarjan_Dominators< GT, SA >::ensure_computed(), Aleph::Lengauer_Tarjan_Dominators< GT, SA >::idom_arr, NODE_COUNTER, Aleph::Lengauer_Tarjan_Dominators< GT, SA >::num_reachable, root(), and Aleph::Lengauer_Tarjan_Dominators< GT, SA >::vertex.
Referenced by main().
|
inlineprivate |
Ensure computation is up to date.
If the computation was already done for the same graph and root, this is a no-op. Otherwise, recomputes.
| g | The directed graph. |
| root | Root node (must not be null). |
Definition at line 374 of file Dominators.H.
References ah_domain_error_if, Aleph::and, Aleph::Lengauer_Tarjan_Dominators< GT, SA >::do_compute(), Aleph::Lengauer_Tarjan_Dominators< GT, SA >::gptr, Aleph::Lengauer_Tarjan_Dominators< GT, SA >::is_computed, root(), and Aleph::Lengauer_Tarjan_Dominators< GT, SA >::root_ptr.
Referenced by Aleph::Lengauer_Tarjan_Dominators< GT, SA >::build_tree(), Aleph::Lengauer_Tarjan_Dominators< GT, SA >::compute_idom(), Aleph::Lengauer_Tarjan_Dominators< GT, SA >::dominance_frontiers(), Aleph::Lengauer_Tarjan_Dominators< GT, SA >::dominates(), and Aleph::Lengauer_Tarjan_Dominators< GT, SA >::get_idom().
EVAL operation for the Union-Find forest.
Returns the node with minimum semi-dominator on the path from v to the root of v's tree in the forest.
| v | The node (DFS number) to evaluate. |
Definition at line 259 of file Dominators.H.
References Aleph::Lengauer_Tarjan_Dominators< GT, SA >::anc, Aleph::Lengauer_Tarjan_Dominators< GT, SA >::compress(), and Aleph::Lengauer_Tarjan_Dominators< GT, SA >::label_arr.
Referenced by Aleph::Lengauer_Tarjan_Dominators< GT, SA >::do_compute().
|
inlinenoexcept |
Get the arc filter (const).
Definition at line 595 of file Dominators.H.
References Aleph::Lengauer_Tarjan_Dominators< GT, SA >::sa.
|
inlinenoexcept |
Get the arc filter.
Definition at line 592 of file Dominators.H.
References Aleph::Lengauer_Tarjan_Dominators< GT, SA >::sa.
|
inlinenoexcept |
Get the graph of the last computation.
Definition at line 601 of file Dominators.H.
References Aleph::Lengauer_Tarjan_Dominators< GT, SA >::gptr.
|
inline |
Get the immediate dominator of a specific node.
| g | The directed graph. |
| root | Root node. |
| node | The node whose idom is queried. |
| std::domain_error | If root or node is null. |
Definition at line 474 of file Dominators.H.
References ah_domain_error_if, Aleph::divide_and_conquer_partition_dp(), Aleph::Lengauer_Tarjan_Dominators< GT, SA >::ensure_computed(), Aleph::Lengauer_Tarjan_Dominators< GT, SA >::idom_arr, NODE_COUNTER, Aleph::Lengauer_Tarjan_Dominators< GT, SA >::num_reachable, root(), and Aleph::Lengauer_Tarjan_Dominators< GT, SA >::vertex.
|
inlinenoexcept |
Get the number of reachable nodes in the last computation.
Definition at line 607 of file Dominators.H.
References Aleph::Lengauer_Tarjan_Dominators< GT, SA >::num_reachable.
|
inlinenoexcept |
Get the root of the last computation.
Definition at line 604 of file Dominators.H.
References Aleph::Lengauer_Tarjan_Dominators< GT, SA >::root_ptr.
|
inlinenoexcept |
Check if a computation has been performed.
Definition at line 598 of file Dominators.H.
References Aleph::Lengauer_Tarjan_Dominators< GT, SA >::is_computed.
|
inline |
Build dominator tree (operator() alias).
| g | The directed graph. | |
| root | Root node. | |
| [out] | tree | Output dominator tree. |
Definition at line 583 of file Dominators.H.
References build_tree(), and root().
|
delete |
|
default |
|
private |
|
private |
|
private |
Definition at line 163 of file Dominators.H.
Referenced by Aleph::Lengauer_Tarjan_Dominators< GT, SA >::build_tree(), Aleph::Lengauer_Tarjan_Dominators< GT, SA >::compute_idom(), Aleph::Lengauer_Tarjan_Dominators< GT, SA >::do_compute(), Aleph::Lengauer_Tarjan_Dominators< GT, SA >::dominance_frontiers(), Aleph::Lengauer_Tarjan_Dominators< GT, SA >::dominates(), and Aleph::Lengauer_Tarjan_Dominators< GT, SA >::get_idom().
|
private |
Definition at line 156 of file Dominators.H.
Referenced by Aleph::Lengauer_Tarjan_Dominators< GT, SA >::do_compute(), Aleph::Lengauer_Tarjan_Dominators< GT, SA >::ensure_computed(), and Aleph::Lengauer_Tarjan_Dominators< GT, SA >::has_computation().
|
private |
|
private |
Definition at line 157 of file Dominators.H.
Referenced by Aleph::Lengauer_Tarjan_Dominators< GT, SA >::build_tree(), Aleph::Lengauer_Tarjan_Dominators< GT, SA >::compute_idom(), Aleph::Lengauer_Tarjan_Dominators< GT, SA >::dfs(), Aleph::Lengauer_Tarjan_Dominators< GT, SA >::do_compute(), Aleph::Lengauer_Tarjan_Dominators< GT, SA >::dominance_frontiers(), Aleph::Lengauer_Tarjan_Dominators< GT, SA >::dominates(), Aleph::Lengauer_Tarjan_Dominators< GT, SA >::get_idom(), and Aleph::Lengauer_Tarjan_Dominators< GT, SA >::get_num_reachable().
|
private |
Definition at line 161 of file Dominators.H.
Referenced by Aleph::Lengauer_Tarjan_Dominators< GT, SA >::dfs(), and Aleph::Lengauer_Tarjan_Dominators< GT, SA >::do_compute().
Definition at line 166 of file Dominators.H.
Referenced by Aleph::Lengauer_Tarjan_Dominators< GT, SA >::do_compute(), and Aleph::Lengauer_Tarjan_Dominators< GT, SA >::dominance_frontiers().
|
private |
|
private |
|
private |
Definition at line 162 of file Dominators.H.
Referenced by Aleph::Lengauer_Tarjan_Dominators< GT, SA >::compress(), Aleph::Lengauer_Tarjan_Dominators< GT, SA >::dfs(), and Aleph::Lengauer_Tarjan_Dominators< GT, SA >::do_compute().
|
private |
Definition at line 160 of file Dominators.H.
Referenced by Aleph::Lengauer_Tarjan_Dominators< GT, SA >::build_tree(), Aleph::Lengauer_Tarjan_Dominators< GT, SA >::compute_idom(), Aleph::Lengauer_Tarjan_Dominators< GT, SA >::dfs(), Aleph::Lengauer_Tarjan_Dominators< GT, SA >::do_compute(), Aleph::Lengauer_Tarjan_Dominators< GT, SA >::dominance_frontiers(), Aleph::Lengauer_Tarjan_Dominators< GT, SA >::dominates(), and Aleph::Lengauer_Tarjan_Dominators< GT, SA >::get_idom().