summaryrefslogtreecommitdiff
path: root/gcc/cfganal.c
diff options
context:
space:
mode:
authorZdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>2002-06-01 11:24:41 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2002-06-01 09:24:41 +0000
commit2ecfd709c24bcc376504af4317552e7e492c6702 (patch)
tree32dca2e27bb3e45f9ac6684f98ae4a2fb5d94a27 /gcc/cfganal.c
parentd6ee5ebf93778e5d9b7f7ed82e5def46ba793619 (diff)
downloadgcc-2ecfd709c24bcc376504af4317552e7e492c6702.tar.gz
basic-block.h (struct basic_block_def): New field loop_father.
* basic-block.h (struct basic_block_def): New field loop_father. (BB_VISITED): New flag. (struct loop): New field pred, removed field shared. (struct loops): New field parray. (LOOP_EXITS_DOMS): Removed. (flow_loop_tree_node_add, flow_loop_tree_node_remove, flow_loop_nested_p, flow_bb_inside_loop_p, get_loop_body, dfs_enumerate_from, loop_preheader_edge, loop_latch_edge, add_bb_to_loop, remove_bb_from_loops, find_common_loop, verify_loop_structure): Declare. * cfg.c (entry_exit_blocks): Initialize loop_father field. * cfganal.c (dfs_enumerate_from): New function. * cfgloop.c (HEAVY_EDGE_RATIO): New constant. (flow_loop_entry_edges_find, flow_loop_exit_edges_find, flow_loop_nodes_find, flow_loop_level_compute, flow_loop_nested_p, flow_loop_dump, flow_loops_dump, flow_loops_free, flow_loop_tree_node_add, flow_loop_level_compute, flow_loops_level_compute, flow_loop_scan, flow_loops_update, flow_loop_outside_edge_p): Modified for new infrastructure. (make_forwarder_block, canonicalize_loop_headers, glb_enum_p, redirect_edge_with_latch_update, flow_loop_free): New static functions. (flow_loop_tree_node_remove, flow_bb_inside_loop_p, get_loop_body, add_bb_to_loop, remove_bb_from_loops, find_common_loop, verify_loop_structure, loop_latch_edge, loop_preheader_edge): New functions. (flow_loops_cfg_dump): Do not show dominators, as this information does not remain up to date long. (flow_loops_find): Store results in new format. * predict.c (propagate_freq, estimate_probability, estimate_loops_at_level, estimate_bb_frequencies): Use new loop infrastructure. From-SVN: r54142
Diffstat (limited to 'gcc/cfganal.c')
-rw-r--r--gcc/cfganal.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/gcc/cfganal.c b/gcc/cfganal.c
index 5f69d1ab2d4..24759e1141e 100644
--- a/gcc/cfganal.c
+++ b/gcc/cfganal.c
@@ -1103,3 +1103,54 @@ flow_dfs_compute_reverse_finish (data)
free (data->stack);
sbitmap_free (data->visited_blocks);
}
+
+/* Performs dfs search from BB over vertices satisfying PREDICATE;
+ if REVERSE, go against direction of edges. Returns number of blocks
+ found and their list in RSLT. RSLT can contain at most RSLT_MAX items. */
+int
+dfs_enumerate_from (bb, reverse, predicate, rslt, rslt_max, data)
+ basic_block bb;
+ int reverse;
+ bool (*predicate) (basic_block, void *);
+ basic_block *rslt;
+ int rslt_max;
+ void *data;
+{
+ basic_block *st, lbb;
+ int sp = 0, tv = 0;
+
+ st = xcalloc (rslt_max, sizeof (basic_block));
+ rslt[tv++] = st[sp++] = bb;
+ bb->flags |= BB_VISITED;
+ while (sp)
+ {
+ edge e;
+ lbb = st[--sp];
+ if (reverse)
+ {
+ for (e = lbb->pred; e; e = e->pred_next)
+ if (!(e->src->flags & BB_VISITED) && predicate (e->src, data))
+ {
+ if (tv == rslt_max)
+ abort ();
+ rslt[tv++] = st[sp++] = e->src;
+ e->src->flags |= BB_VISITED;
+ }
+ }
+ else
+ {
+ for (e = lbb->succ; e; e = e->succ_next)
+ if (!(e->dest->flags & BB_VISITED) && predicate (e->dest, data))
+ {
+ if (tv == rslt_max)
+ abort ();
+ rslt[tv++] = st[sp++] = e->dest;
+ e->dest->flags |= BB_VISITED;
+ }
+ }
+ }
+ free (st);
+ for (sp = 0; sp < tv; sp++)
+ rslt[sp]->flags &= ~BB_VISITED;
+ return tv;
+}