146 template <
class GT,
class SA = Dft_Show_Arc<GT>>
228 if (
Frame & top = stack.
top(); top.it.has_curr())
247 static_cast<void>(stack.
pop());
317 for (
typename GT::Arc_Iterator
ait(g);
ait.has_curr();
ait.next_ne())
319 auto arc =
ait.get_curr();
347 while (
not bucket[
par[
w]].is_empty())
377 <<
"Lengauer_Tarjan_Dominators: root cannot be null";
477 <<
"Lengauer_Tarjan_Dominators::get_idom: node cannot be null";
563 for (
auto it =
pred[b].get_it(); it.has_curr(); it.next_ne())
565 long runner = it.get_curr();
634 template <
class GT,
class SA = Dft_Show_Arc<GT>>
656 template <
class GT,
class SA = Dft_Show_Arc<GT>>
677 template <
class GT,
class SA = Dft_Show_Arc<GT>>
727 template <
class GT,
class SA = Dft_Show_Arc<GT>>
750 return p ? p->second :
nullptr;
757 return p ? p->second :
nullptr;
777 <<
"Lengauer_Tarjan_Post_Dominators: exit node cannot be null";
779 gptr = &
const_cast<GT &
>(g);
789 for (
auto it = g.
get_node_it(); it.has_curr(); it.next_ne())
791 auto orig = it.get_curr();
846 for (
auto it =
rev_idoms.get_it(); it.has_curr(); it.next_ne())
885 for (
auto it =
rev_idoms.get_it(); it.has_curr(); it.next_ne())
896 for (
auto it =
rev_idoms.get_it(); it.has_curr(); it.next_ne())
920 <<
"Lengauer_Tarjan_Post_Dominators::get_ipdom: node cannot be null";
924 if (
rev_n ==
nullptr)
981 for (
auto it =
rev_df.get_it(); it.has_curr(); it.next_ne())
1044 template <
class GT,
class SA = Dft_Show_Arc<GT>>
1068 template <
class GT,
class SA = Dft_Show_Arc<GT>>
1090 template <
class GT,
class SA = Dft_Show_Arc<GT>>
1097 .post_dominance_frontiers(g,
exit_node);
Exception handling system with formatted messages for Aleph-w.
#define ah_domain_error_if(C)
Throws std::domain_error if condition holds.
EepicNode< long > * build_tree()
Simple dynamic array with automatic resizing and functional operations.
constexpr bool is_empty() const noexcept
Checks if the container is empty.
T & insert(const T &data)
insert a copy of data at the beginning of the array.
T & append(const T &data)
Append a copy of data
Dynamic stack of elements of generic type T based on a singly linked list.
T & top()
Return a modifiable reference to the top item of the stack.
bool is_empty() const noexcept
Check if the stack is empty.
T pop()
Remove and return the top item of the stack.
T & push(const T &data)
Push an item by copy onto the top of the stack.
Dynamic singly linked list with functional programming support.
T & append(const T &item)
Generic key-value map implemented on top of a binary search tree.
Pair * search(const Key &key) const noexcept
Collect all keys.
Pair * insert(const Key &key, const Data &data)
Insert a key-value pair.
Dynamic set backed by balanced binary search trees with automatic memory management.
Key * insert(const Key &key)
Inserts a key into the dynamic set.
Computes dominator tree and dominance frontiers of a digraph using the Lengauer-Tarjan algorithm.
Lengauer_Tarjan_Dominators(const Lengauer_Tarjan_Dominators &)=delete
Dominator instances should not be copied (they hold internal state)
Lengauer_Tarjan_Dominators(Lengauer_Tarjan_Dominators &&)=default
Move is allowed.
DynMapTree< Node *, DynSetTree< Node * > > dominance_frontiers(GT &g, Node *root)
Compute dominance frontiers for all reachable nodes.
void build_tree(GT &g, Node *root, GT &tree)
Build the dominator tree as a separate graph.
bool has_computation() const noexcept
Check if a computation has been performed.
void ensure_computed(GT &g, Node *root)
Ensure computation is up to date.
SA & get_filter() noexcept
Get the arc filter.
Lengauer_Tarjan_Dominators & operator=(Lengauer_Tarjan_Dominators &&)=default
Lengauer_Tarjan_Dominators & operator=(const Lengauer_Tarjan_Dominators &)=delete
void dfs(Node *root_ptr)
Iterative DFS to number nodes and build DFS tree.
void operator()(GT &g, Node *root, GT &tree)
Build dominator tree (operator() alias).
long get_num_reachable() const noexcept
Get the number of reachable nodes in the last computation.
long eval(const long v)
EVAL operation for the Union-Find forest.
bool dominates(GT &g, Node *root, Node *d, Node *v)
Test whether node d dominates node v.
Lengauer_Tarjan_Dominators(SA __sa=SA()) noexcept
Construct a dominator computation instance.
Array< DynList< long > > pred
Node * get_idom(GT &g, Node *root, Node *node)
Get the immediate dominator of a specific node.
void do_compute(GT &g, Node *root)
Core computation of dominators.
DynList< std::pair< Node *, Node * > > compute_idom(GT &g, Node *root)
Compute immediate dominators.
Node * get_root() const noexcept
Get the root of the last computation.
const SA & get_filter() const noexcept
Get the arc filter (const).
GT * get_graph() const noexcept
Get the graph of the last computation.
void compress(long v)
Path compression for Union-Find (iterative).
Computes post-dominator tree and post-dominance frontiers of a digraph using the Lengauer-Tarjan algo...
bool has_computation() const noexcept
Check if a computation has been performed.
Lengauer_Tarjan_Post_Dominators(const Lengauer_Tarjan_Post_Dominators &)=delete
Post-dominator instances should not be copied (they hold internal state)
SA & get_filter() noexcept
Get the arc filter.
DynMapTree< Node *, DynSetTree< Node * > > post_dominance_frontiers(const GT &g, Node *exit_node)
Compute post-dominance frontiers for all reachable nodes.
void build_tree(const GT &g, Node *exit_node, GT &tree)
Build the post-dominator tree as a separate graph.
void ensure_computed(const GT &g, Node *exit_node)
Ensure computation is up to date.
Lengauer_Tarjan_Post_Dominators & operator=(const Lengauer_Tarjan_Post_Dominators &)=delete
Lengauer_Tarjan_Post_Dominators & operator=(Lengauer_Tarjan_Post_Dominators &&)=default
const SA & get_filter() const noexcept
Get the arc filter (const).
void operator()(const GT &g, Node *exit_node, GT &tree)
Build post-dominator tree (operator() alias).
Lengauer_Tarjan_Dominators< GT, SA > dom
GT * get_graph() const noexcept
Get the graph of the last computation.
DynList< std::pair< Node *, Node * > > compute_ipdom(const GT &g, Node *exit_node)
Compute immediate post-dominators.
Lengauer_Tarjan_Post_Dominators(SA __sa=SA()) noexcept
Construct a post-dominator computation instance.
Lengauer_Tarjan_Post_Dominators(Lengauer_Tarjan_Post_Dominators &&)=default
Move is allowed.
DynMapTree< Node *, Node * > rev_to_orig
Node * to_rev(Node *orig) const
Map original node to reversed graph node.
bool post_dominates(const GT &g, Node *exit_node, Node *d, Node *v)
Test whether node d post-dominates node v.
Node * get_exit() const noexcept
Get the exit node of the last computation.
Node * get_ipdom(const GT &g, Node *exit_node, Node *node)
Get the immediate post-dominator of a specific node.
Node * to_orig(Node *rev_n) const
Map reversed graph node to original node.
DynMapTree< Node *, Node * > orig_to_rev
virtual Node * insert_node(Node *node) noexcept
Insertion of a node already allocated.
Graph_Node< Node_Info > Node
The graph type.
Graph_Arc< Arc_Info > Arc
The node class type.
Arc * insert_arc(Node *src_node, Node *tgt_node, void *a)
Filtered iterator for outcoming arcs of a node.
Node * get_src_node(Arc *arc) const noexcept
Return the source node of arc (only for directed graphs)
constexpr size_t get_num_nodes() const noexcept
Return the total of nodes of graph.
auto get_node_it() const noexcept
Obtains an iterator to the nodes of graph.
Node * get_tgt_node(Arc *arc) const noexcept
Return the target node of arc (only for directed graphs)
static void map_nodes(N1 *p, N2 *q) noexcept
Map the nodes through their cookies.
void for_each_node(Operation &operation) const
Unconditionally traverse all the nodes of graph and on each one perform an operation.
__gmp_expr< T, __gmp_binary_expr< __gmp_expr< T, U >, unsigned long int, __gmp_root_function > > root(const __gmp_expr< T, U > &expr, unsigned long int l)
void build_post_dominator_tree(const GT &g, typename GT::Node *exit_node, GT &tree, SA sa=SA())
Build the post-dominator tree of a digraph.
#define NODE_COUNTER(p)
Get the counter of a node.
GT invert_digraph(const GT &g)
Compute the transpose (arc-reversed) digraph.
void build_dominator_tree(GT &g, typename GT::Node *root, GT &tree, SA sa=SA())
Build the dominator tree of a digraph.
#define NODE_COOKIE(p)
Return the node cookie
void clear_graph(GT &g) noexcept
Clean a graph: all its nodes and arcs are removed and freed.
DynList< std::pair< typename GT::Node *, typename GT::Node * > > compute_dominators(GT &g, typename GT::Node *root, SA sa=SA())
Compute immediate dominators of a digraph from a root node.
DynList< std::pair< typename GT::Node *, typename GT::Node * > > compute_post_dominators(const GT &g, typename GT::Node *exit_node, SA sa=SA())
Compute immediate post-dominators of a digraph from an exit node.
DynMapTree< typename GT::Node *, DynSetTree< typename GT::Node * > > compute_post_dominance_frontiers(const GT &g, typename GT::Node *exit_node, SA sa=SA())
Compute post-dominance frontiers of a digraph.
DynMapTree< typename GT::Node *, DynSetTree< typename GT::Node * > > compute_dominance_frontiers(GT &g, typename GT::Node *root, SA sa=SA())
Compute dominance frontiers of a digraph.
Singly linked list implementations with head-tail access.
Main namespace for Aleph-w library functions.
and
Check uniqueness with explicit hash + equality functors.
size_t size(Node *root) noexcept
Divide_Conquer_DP_Result< Cost > divide_and_conquer_partition_dp(const size_t groups, const size_t n, Transition_Cost_Fn transition_cost, const Cost inf=dp_optimization_detail::default_inf< Cost >())
Optimize partition DP using divide-and-conquer optimization.
static long & df(typename GT::Node *p)
Internal helper: DFS discovery time stored in NODE_COUNTER(p).
Dynamic array container with automatic resizing.
Dynamic stack implementation based on linked lists.
Dynamic set implementations based on balanced binary search trees.
Generic graph and digraph implementations.
Utility algorithms and operations for graphs.