|
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 149 of file Dominators.H.
|
private |
Definition at line 154 of file Dominators.H.
|
private |
Definition at line 153 of file Dominators.H.
|
inlinenoexcept |
Construct a dominator computation instance.
| __sa | Arc filter functor. Defaults to Dft_Show_Arc<GT>. |
Definition at line 392 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 443 of file Dominators.H.
References Aleph::blossom_maximum_cardinality_matching(), Aleph::clear_graph(), 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 178 of file Dominators.H.
References Aleph::Lengauer_Tarjan_Dominators< GT, SA >::anc, Aleph::and, Aleph::Array< T >::append(), Aleph::blossom_maximum_cardinality_matching(), 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 418 of file Dominators.H.
References Aleph::DynList< T >::append(), Aleph::blossom_maximum_cardinality_matching(), 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 207 of file Dominators.H.
References Aleph::Lengauer_Tarjan_Dominators< GT, SA >::anc, Aleph::blossom_maximum_cardinality_matching(), 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().
|
inlineprivate |
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 278 of file Dominators.H.
References Aleph::Lengauer_Tarjan_Dominators< GT, SA >::anc, Aleph::and, Aleph::Array< T >::append(), Aleph::blossom_maximum_cardinality_matching(), Aleph::Lengauer_Tarjan_Dominators< GT, SA >::dfs(), 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 543 of file Dominators.H.
References Aleph::and, Aleph::blossom_maximum_cardinality_matching(), Aleph::df(), 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 500 of file Dominators.H.
References Aleph::blossom_maximum_cardinality_matching(), 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 376 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().
|
inlineprivate |
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 261 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 597 of file Dominators.H.
References Aleph::Lengauer_Tarjan_Dominators< GT, SA >::sa.
|
inlinenoexcept |
Get the arc filter.
Definition at line 594 of file Dominators.H.
References Aleph::Lengauer_Tarjan_Dominators< GT, SA >::sa.
|
inlinenoexcept |
Get the graph of the last computation.
Definition at line 603 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 476 of file Dominators.H.
References ah_domain_error_if, Aleph::blossom_maximum_cardinality_matching(), 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 609 of file Dominators.H.
References Aleph::Lengauer_Tarjan_Dominators< GT, SA >::num_reachable.
|
inlinenoexcept |
Get the root of the last computation.
Definition at line 606 of file Dominators.H.
References Aleph::Lengauer_Tarjan_Dominators< GT, SA >::root_ptr.
|
inlinenoexcept |
Check if a computation has been performed.
Definition at line 600 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 585 of file Dominators.H.
References build_tree(), and root().
|
delete |
|
default |
|
private |
|
private |
|
private |
Definition at line 165 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 158 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 159 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 163 of file Dominators.H.
Referenced by Aleph::Lengauer_Tarjan_Dominators< GT, SA >::dfs(), and Aleph::Lengauer_Tarjan_Dominators< GT, SA >::do_compute().
|
private |
Definition at line 168 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 164 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 162 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().