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
This commit is contained in:
Zdenek Dvorak 2002-06-01 11:24:41 +02:00 committed by Jan Hubicka
parent d6ee5ebf93
commit 2ecfd709c2
6 changed files with 883 additions and 418 deletions

View file

@ -1,3 +1,37 @@
Sat Jun 1 11:23:22 CEST 2002 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
* 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.
2002-06-01 Alan Lehotsky <apl@alum.mit.edu>
* except.c (nothrow_function_p): Walk epilogue delay list

View file

@ -212,6 +212,9 @@ typedef struct basic_block_def {
/* The loop depth of this block. */
int loop_depth;
/* Outermost loop containing the block. */
struct loop *loop_father;
/* Expected number of executions: calculated in profile.c. */
gcov_type count;
@ -228,6 +231,7 @@ typedef struct basic_block_def {
#define BB_DIRTY 1
#define BB_NEW 2
#define BB_REACHABLE 4
#define BB_VISITED 8
/* Number of basic blocks in the current function. */
@ -403,6 +407,9 @@ struct loop
/* The loop nesting depth. */
int depth;
/* Superloops of the loop. */
struct loop **pred;
/* The height of the loop (enclosed loop levels) within the loop
hierarchy tree. */
int level;
@ -416,9 +423,6 @@ struct loop
/* Link to the next (sibling) loop. */
struct loop *next;
/* Non-zero if the loop shares a header with another loop. */
int shared;
/* Non-zero if the loop is invalid (e.g., contains setjmp.). */
int invalid;
@ -484,6 +488,11 @@ struct loops
will find the inner loops before their enclosing outer loops). */
struct loop *array;
/* The above array is unused in new loop infrastructure and is kept only for
purposes of the old loop optimizer. Instead we store just pointers to
loops here. */
struct loop **parray;
/* Pointer to root of loop heirachy tree. */
struct loop *tree_root;
@ -515,6 +524,8 @@ extern void flow_loop_dump PARAMS ((const struct loop *, FILE *,
void (*)(const struct loop *,
FILE *, int), int));
extern int flow_loop_scan PARAMS ((struct loops *, struct loop *, int));
extern void flow_loop_tree_node_add PARAMS ((struct loop *, struct loop *));
extern void flow_loop_tree_node_remove PARAMS ((struct loop *));
/* This structure maintains an edge list vector. */
struct edge_list
@ -613,8 +624,7 @@ enum update_life_extent
#define LOOP_ENTRY_EDGES 4 /* Find entry edges. */
#define LOOP_EXIT_EDGES 8 /* Find exit edges. */
#define LOOP_EDGES (LOOP_ENTRY_EDGES | LOOP_EXIT_EDGES)
#define LOOP_EXITS_DOMS 16 /* Find nodes that dom. all exits. */
#define LOOP_ALL 31 /* All of the above */
#define LOOP_ALL 15 /* All of the above */
extern void life_analysis PARAMS ((rtx, FILE *, int));
extern int update_life_info PARAMS ((sbitmap, enum update_life_extent,
@ -701,7 +711,24 @@ extern void free_aux_for_edges PARAMS ((void));
debugger, and it is declared extern so we don't get warnings about
it being unused. */
extern void verify_flow_info PARAMS ((void));
extern int flow_loop_outside_edge_p PARAMS ((const struct loop *, edge));
extern bool flow_loop_outside_edge_p PARAMS ((const struct loop *, edge));
extern bool flow_loop_nested_p PARAMS ((const struct loop *, const struct loop *));
extern bool flow_bb_inside_loop_p PARAMS ((const struct loop *, basic_block));
extern basic_block *get_loop_body PARAMS ((const struct loop *));
extern int dfs_enumerate_from PARAMS ((basic_block, int,
bool (*)(basic_block, void *),
basic_block *, int, void *));
extern edge loop_preheader_edge PARAMS ((struct loop *));
extern edge loop_latch_edge PARAMS ((struct loop *));
extern void add_bb_to_loop PARAMS ((basic_block, struct loop *));
extern void remove_bb_from_loops PARAMS ((basic_block));
extern struct loop * find_common_loop PARAMS ((struct loop *, struct loop *));
extern void verify_loop_structure PARAMS ((struct loops *, int));
#define VLS_EXPECT_PREHEADERS 1
#define VLS_EXPECT_SIMPLE_LATCHES 2
typedef struct conflict_graph_def *conflict_graph;

View file

@ -100,6 +100,7 @@ struct basic_block_def entry_exit_blocks[2]
NULL, /* prev_bb */
EXIT_BLOCK_PTR, /* next_bb */
0, /* loop_depth */
NULL, /* loop_father */
0, /* count */
0, /* frequency */
0 /* flags */
@ -120,6 +121,7 @@ struct basic_block_def entry_exit_blocks[2]
ENTRY_BLOCK_PTR, /* prev_bb */
NULL, /* next_bb */
0, /* loop_depth */
NULL, /* loop_father */
0, /* count */
0, /* frequency */
0 /* flags */

View file

@ -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;
}

File diff suppressed because it is too large Load diff

View file

@ -70,7 +70,7 @@ static void combine_predictions_for_insn PARAMS ((rtx, basic_block));
static void dump_prediction PARAMS ((enum br_predictor, int,
basic_block, int));
static void estimate_loops_at_level PARAMS ((struct loop *loop));
static void propagate_freq PARAMS ((basic_block));
static void propagate_freq PARAMS ((struct loop *));
static void estimate_bb_frequencies PARAMS ((struct loops *));
static void counts_to_freqs PARAMS ((void));
static void process_note_predictions PARAMS ((basic_block, int *, int *,
@ -419,19 +419,23 @@ estimate_probability (loops_info)
/* Try to predict out blocks in a loop that are not part of a
natural loop. */
for (i = 0; i < loops_info->num; i++)
for (i = 1; i < loops_info->num; i++)
{
basic_block bb, *bbs;
int j;
int exits;
struct loop *loop = &loops_info->array[i];
struct loop *loop = loops_info->parray[i];
flow_loop_scan (loops_info, loop, LOOP_EXIT_EDGES);
exits = loop->num_exits;
FOR_BB_BETWEEN (bb, loop->first, loop->last->next_bb, next_bb)
if (TEST_BIT (loop->nodes, bb->index))
{
int header_found = 0;
edge e;
bbs = get_loop_body (loop);
for (j = 0; j < loop->num_nodes; j++)
{
int header_found = 0;
edge e;
bb = bbs[j];
/* Bypass loop heuristics on continue statement. These
statements construct loops via "non-loop" constructs
@ -440,28 +444,28 @@ estimate_probability (loops_info)
if (predicted_by_p (bb, PRED_CONTINUE))
continue;
/* Loop branch heuristics - predict an edge back to a
loop's head as taken. */
for (e = bb->succ; e; e = e->succ_next)
if (e->dest == loop->header
&& e->src == loop->latch)
{
header_found = 1;
predict_edge_def (e, PRED_LOOP_BRANCH, TAKEN);
}
/* Loop branch heuristics - predict an edge back to a
loop's head as taken. */
for (e = bb->succ; e; e = e->succ_next)
if (e->dest == loop->header
&& e->src == loop->latch)
{
header_found = 1;
predict_edge_def (e, PRED_LOOP_BRANCH, TAKEN);
}
/* Loop exit heuristics - predict an edge exiting the loop if the
conditinal has no loop header successors as not taken. */
if (!header_found)
for (e = bb->succ; e; e = e->succ_next)
if (e->dest->index < 0
|| !TEST_BIT (loop->nodes, e->dest->index))
predict_edge
(e, PRED_LOOP_EXIT,
(REG_BR_PROB_BASE
- predictor_info [(int) PRED_LOOP_EXIT].hitrate)
/ exits);
}
/* Loop exit heuristics - predict an edge exiting the loop if the
conditinal has no loop header successors as not taken. */
if (!header_found)
for (e = bb->succ; e; e = e->succ_next)
if (e->dest->index < 0
|| !flow_bb_inside_loop_p (loop, e->dest))
predict_edge
(e, PRED_LOOP_EXIT,
(REG_BR_PROB_BASE
- predictor_info [(int) PRED_LOOP_EXIT].hitrate)
/ exits);
}
}
/* Attempt to predict conditional jumps using a number of heuristics. */
@ -896,12 +900,13 @@ typedef struct edge_info_def
#define EDGE_INFO(E) ((edge_info) (E)->aux)
/* Helper function for estimate_bb_frequencies.
Propagate the frequencies for loops headed by HEAD. */
Propagate the frequencies for LOOP. */
static void
propagate_freq (head)
basic_block head;
propagate_freq (loop)
struct loop *loop;
{
basic_block head = loop->header;
basic_block bb;
basic_block last;
edge e;
@ -1028,41 +1033,28 @@ static void
estimate_loops_at_level (first_loop)
struct loop *first_loop;
{
struct loop *l, *loop = first_loop;
struct loop *loop;
for (loop = first_loop; loop; loop = loop->next)
{
int n;
edge e;
basic_block *bbs;
int i;
estimate_loops_at_level (loop->inner);
/* Find current loop back edge and mark it. */
for (e = loop->latch->succ; e->dest != loop->header; e = e->succ_next)
;
EDGE_INFO (e)->back_edge = 1;
/* In case the loop header is shared, ensure that it is the last
one sharing the same header, so we avoid redundant work. */
if (loop->shared)
if (loop->latch->succ) /* Do not do this for dummy function loop. */
{
for (l = loop->next; l; l = l->next)
if (l->header == loop->header)
break;
/* Find current loop back edge and mark it. */
e = loop_latch_edge (loop);
EDGE_INFO (e)->back_edge = 1;
}
if (l)
continue;
}
/* Now merge all nodes of all loops with given header as not visited. */
for (l = loop->shared ? first_loop : loop; l != loop->next; l = l->next)
if (loop->header == l->header)
EXECUTE_IF_SET_IN_SBITMAP (l->nodes, 0, n,
BLOCK_INFO (BASIC_BLOCK (n))->tovisit = 1
);
propagate_freq (loop->header);
bbs = get_loop_body (loop);
for (i = 0; i < loop->num_nodes; i++)
BLOCK_INFO (bbs[i])->tovisit = 1;
free (bbs);
propagate_freq (loop);
}
}
@ -1202,12 +1194,6 @@ estimate_bb_frequencies (loops)
to outermost to examine probabilities for back edges. */
estimate_loops_at_level (loops->tree_root);
/* Now fake loop around whole function to finalize probabilities. */
FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
BLOCK_INFO (bb)->tovisit = 1;
propagate_freq (ENTRY_BLOCK_PTR);
memcpy (&freq_max, &real_zero, sizeof (real_zero));
FOR_EACH_BB (bb)
if (REAL_VALUES_LESS