2 * This file is part of libFirm.
3 * Copyright (C) 2012 University of Karlsruhe.
8 * @brief Algorithms for computing dominance frontiers.
9 * @author Sebastian Hack, Daniel Grund
20 #include "iredges_t.h"
21 #include "irnodeset.h"
24 * A wrapper for get_Block_idom.
25 * This function returns the block itself, if the block is the start
26 * block. Returning NULL would make any != comparison true which
27 * suggests, that the start block is dominated by some other node.
28 * @param bl The block.
29 * @return The immediate dominator of the block.
31 static inline ir_node *get_idom(ir_node *bl)
33 ir_node *idom = get_Block_idom(bl);
34 return idom == NULL ? bl : idom;
38 * Compute the dominance frontier for a given block.
40 * @param blk the block where the calculation starts
42 * @return the list of all blocks in the dominance frontier of blk
44 static ir_node **compute_df(ir_node *blk, ir_dom_front_info_t *info)
47 ir_node **df_list = NEW_ARR_F(ir_node *, 0);
49 /* Add local dominance frontiers */
50 foreach_block_succ(blk, edge) {
51 ir_node *y = get_edge_src_irn(edge);
53 if (get_idom(y) != blk) {
54 ARR_APP1(ir_node *, df_list, y);
59 * Go recursively down the dominance tree and add all blocks
60 * into the dominance frontiers of the children, which are not
61 * dominated by the given block.
63 for (c = get_Block_dominated_first(blk); c; c = get_Block_dominated_next(c)) {
65 ir_node **df_c_list = compute_df(c, info);
67 for (i = ARR_LEN(df_c_list); i > 0;) {
68 ir_node *w = df_c_list[--i];
69 if (get_idom(w) != blk)
70 ARR_APP1(ir_node *, df_list, w);
74 /* now copy the flexible array to the obstack */
75 ir_node **const df = DUP_ARR_D(ir_node*, &info->obst, df_list);
78 pmap_insert(info->df_map, blk, df);
82 void ir_compute_dominance_frontiers(ir_graph *irg)
84 ir_dom_front_info_t *info = &irg->domfront;
87 obstack_init(&info->obst);
88 info->df_map = pmap_create();
90 compute_df(get_irg_start_block(irg), info);
92 add_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE_FRONTIERS);
95 void ir_free_dominance_frontiers(ir_graph *irg)
97 clear_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE_FRONTIERS);
99 ir_dom_front_info_t *info = &irg->domfront;
100 if (info->df_map == NULL)
103 obstack_free(&info->obst, NULL);
104 pmap_destroy(info->df_map);
108 /* Get the dominance frontier of a block. */
109 ir_node **ir_get_dominance_frontier(const ir_node *block)
111 ir_graph *irg = get_irn_irg(block);
112 ir_dom_front_info_t *info = &irg->domfront;
113 return pmap_get(ir_node*, info->df_map, block);