61 template <
typename Container>
113 auto entry =
cfg.insert_node(
"entry");
114 auto cond =
cfg.insert_node(
"cond");
117 auto join =
cfg.insert_node(
"join");
122 cfg.insert_arc(entry, cond);
132 cout <<
"=== Control-Flow Graph ===" <<
endl;
133 cout <<
"Nodes: " <<
cfg.get_num_nodes() <<
endl;
134 cout <<
"Arcs: " <<
cfg.get_num_arcs() <<
endl;
136 cout <<
"Edges:" <<
endl;
137 for (
auto it =
cfg.get_arc_it(); it.has_curr(); it.next_ne())
139 auto arc = it.get_curr();
140 cout <<
" " <<
cfg.get_src_node(arc)->get_info()
141 <<
" -> " <<
cfg.get_tgt_node(arc)->get_info() <<
endl;
152 cout <<
"=== Immediate Dominators ===" <<
endl;
153 for (
auto it =
idoms.get_it(); it.has_curr(); it.next_ne())
155 auto [node,
idom] = it.get_curr();
156 cout <<
" idom(" << node->get_info() <<
") = "
168 cout <<
"=== Dominator Tree ===" <<
endl;
172 cout <<
"Tree edges (parent -> child):" <<
endl;
173 for (
auto it =
dom_tree.get_arc_it(); it.has_curr(); it.next_ne())
175 auto arc = it.get_curr();
176 cout <<
" " <<
dom_tree.get_src_node(arc)->get_info()
177 <<
" -> " <<
dom_tree.get_tgt_node(arc)->get_info() <<
endl;
187 cout <<
"=== Dominance Frontiers ===" <<
endl;
188 for (
auto it =
df.get_it(); it.has_curr(); it.next_ne())
190 auto & [node,
frontier] = it.get_curr();
191 cout <<
" DF(" << node->get_info() <<
") = ";
201 cout <<
"=== SSA Phi-Function Placement ===" <<
endl;
202 cout <<
"Blocks where phi-functions would be needed:" <<
endl;
206 for (
auto it =
df.get_it(); it.has_curr(); it.next_ne())
208 auto & [node,
frontier] = it.get_curr();
211 cout <<
" Definitions in '" << node->get_info()
212 <<
"' need phi at: ";
223 cout <<
"=== Dominance Queries ===" <<
endl;
224 cout <<
" entry dominates exit? "
226 cout <<
" cond dominates join? "
228 cout <<
" then dominates join? "
230 cout <<
" loop_hdr dominates loop_body? "
241 cout <<
"=== Immediate Post-Dominators (exit = " <<
exit_block->get_info()
245 auto [node,
ipdom] =
pit.get_curr();
246 cout <<
" ipdom(" << node->get_info() <<
") = "
258 cout <<
"=== Post-Dominator Tree ===" <<
endl;
262 cout <<
"Tree edges (parent -> child):" <<
endl;
265 auto arc =
pit.get_curr();
266 cout <<
" " <<
pdom_tree.get_src_node(arc)->get_info()
267 <<
" -> " <<
pdom_tree.get_tgt_node(arc)->get_info() <<
endl;
277 cout <<
"=== Post-Dominance Frontiers ===" <<
endl;
278 for (
auto pit =
pdf.get_it();
pit.has_curr();
pit.next_ne())
281 cout <<
" PDF(" << node->get_info() <<
") = ";
291 cout <<
"=== Post-Dominance Queries ===" <<
endl;
292 cout <<
" exit post-dominates entry? "
295 cout <<
" loop_hdr post-dominates cond? "
298 cout <<
" then post-dominates entry? "
Dominator and post-dominator tree computation via the Lengauer-Tarjan algorithm.
Generic directed graph (digraph) wrapper template.
Computes dominator tree and dominance frontiers of a digraph using the Lengauer-Tarjan algorithm.
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 dominates(GT &g, Node *root, Node *d, Node *v)
Test whether node d dominates node v.
DynList< std::pair< Node *, Node * > > compute_idom(GT &g, Node *root)
Compute immediate dominators.
Computes post-dominator tree and post-dominance frontiers of a digraph using the Lengauer-Tarjan algo...
DynList< std::pair< Node *, Node * > > compute_ipdom(const GT &g, Node *exit_node)
Compute immediate post-dominators.
ArcInfo & get_info() noexcept
Return a modifiable reference to the arc data.
int main()
Demonstrates construction of a control-flow graph and performs dominance analyses.
Main namespace for Aleph-w library functions.
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).
std::ostream & join(const C &c, const std::string &sep, std::ostream &out)
Join elements of an Aleph-style container into a stream.
Arc of graph implemented with double-linked adjacency lists.
Generic graph and digraph implementations.