tree-ssa-loop-im.c (schedule_sm, [...]): Use vector of edges instead of array.

* tree-ssa-loop-im.c (schedule_sm, determine_lsm_ref,
	hoist_memory_references, loop_suitable_for_sm, determine_lsm_loop):
	Use vector of edges instead of array.
	* tree-ssa-loop-niter.c (find_loop_niter, find_loop_niter_by_eval,
	estimate_numbers_of_iterations_loop): Ditto.
	* predict.c (predict_loops): Ditto.
	* loop-unroll.c (analyze_insns_in_loop): Ditto.
	* tree-ssa-threadupdate.c: Remove declaration of heap allocation for
	edge vectors.
	* basic-block.h: Declare heap allocation for edge vectors.
	* tree-outof-ssa.c: Ditto.
	* cfgloop.c (get_loop_exit_edges): Return vector of edges.
	* cfgloop.h (get_loop_exit_edges): Declaration changed.

From-SVN: r119039
This commit is contained in:
Zdenek Dvorak 2006-11-21 01:20:02 +01:00 committed by Zdenek Dvorak
parent c61191974b
commit ca83d38556
10 changed files with 88 additions and 78 deletions

View File

@ -1,3 +1,19 @@
2006-11-21 Zdenek Dvorak <dvorakz@suse.cz>
* tree-ssa-loop-im.c (schedule_sm, determine_lsm_ref,
hoist_memory_references, loop_suitable_for_sm, determine_lsm_loop):
Use vector of edges instead of array.
* tree-ssa-loop-niter.c (find_loop_niter, find_loop_niter_by_eval,
estimate_numbers_of_iterations_loop): Ditto.
* predict.c (predict_loops): Ditto.
* loop-unroll.c (analyze_insns_in_loop): Ditto.
* tree-ssa-threadupdate.c: Remove declaration of heap allocation for
edge vectors.
* basic-block.h: Declare heap allocation for edge vectors.
* tree-outof-ssa.c: Ditto.
* cfgloop.c (get_loop_exit_edges): Return vector of edges.
* cfgloop.h (get_loop_exit_edges): Declaration changed.
2006-11-20 Zack Weinberg <zackw@panix.com>
* gengtype.c (process_gc_options): Remove unnecessary forward decl.

View File

@ -146,6 +146,7 @@ struct edge_def GTY(())
typedef struct edge_def *edge;
DEF_VEC_P(edge);
DEF_VEC_ALLOC_P(edge,gc);
DEF_VEC_ALLOC_P(edge,heap);
#define EDGE_FALLTHRU 1 /* 'Straight line' flow */
#define EDGE_ABNORMAL 2 /* Strange flow, like computed

View File

@ -881,30 +881,24 @@ get_loop_body_in_bfs_order (const struct loop *loop)
return blocks;
}
/* Gets exit edges of a LOOP, returning their number in N_EDGES. */
edge *
get_loop_exit_edges (const struct loop *loop, unsigned int *num_edges)
/* Returns the list of the exit edges of a LOOP. */
VEC (edge, heap) *
get_loop_exit_edges (const struct loop *loop)
{
edge *edges, e;
unsigned i, n;
basic_block * body;
VEC (edge, heap) *edges = NULL;
edge e;
unsigned i;
basic_block *body;
edge_iterator ei;
gcc_assert (loop->latch != EXIT_BLOCK_PTR);
body = get_loop_body (loop);
n = 0;
for (i = 0; i < loop->num_nodes; i++)
FOR_EACH_EDGE (e, ei, body[i]->succs)
if (!flow_bb_inside_loop_p (loop, e->dest))
n++;
edges = XNEWVEC (edge, n);
*num_edges = n;
n = 0;
for (i = 0; i < loop->num_nodes; i++)
FOR_EACH_EDGE (e, ei, body[i]->succs)
if (!flow_bb_inside_loop_p (loop, e->dest))
edges[n++] = e;
VEC_safe_push (edge, heap, edges, e);
free (body);
return edges;

View File

@ -222,7 +222,7 @@ extern void mark_loop_exit_edges (struct loops *);
extern basic_block *get_loop_body (const struct loop *);
extern basic_block *get_loop_body_in_dom_order (const struct loop *);
extern basic_block *get_loop_body_in_bfs_order (const struct loop *);
extern edge *get_loop_exit_edges (const struct loop *, unsigned *);
extern VEC (edge, heap) *get_loop_exit_edges (const struct loop *);
extern unsigned num_loop_branches (const struct loop *);
extern edge loop_preheader_edge (const struct loop *);

View File

@ -1709,14 +1709,15 @@ static struct opt_info *
analyze_insns_in_loop (struct loop *loop)
{
basic_block *body, bb;
unsigned i, num_edges = 0;
unsigned i;
struct opt_info *opt_info = XCNEW (struct opt_info);
rtx insn;
struct iv_to_split *ivts = NULL;
struct var_to_expand *ves = NULL;
PTR *slot1;
PTR *slot2;
edge *edges = get_loop_exit_edges (loop, &num_edges);
VEC (edge, heap) *edges = get_loop_exit_edges (loop);
edge exit;
bool can_apply = false;
iv_analysis_loop_init (loop);
@ -1730,11 +1731,14 @@ analyze_insns_in_loop (struct loop *loop)
/* Record the loop exit bb and loop preheader before the unrolling. */
opt_info->loop_preheader = loop_preheader_edge (loop)->src;
if (num_edges == 1
&& !(edges[0]->flags & EDGE_COMPLEX))
if (VEC_length (edge, edges) == 1)
{
opt_info->loop_exit = split_edge (edges[0]);
can_apply = true;
exit = VEC_index (edge, edges, 0);
if (!(exit->flags & EDGE_COMPLEX))
{
opt_info->loop_exit = split_edge (exit);
can_apply = true;
}
}
if (flag_variable_expansion_in_unroller
@ -1774,7 +1778,7 @@ analyze_insns_in_loop (struct loop *loop)
}
}
free (edges);
VEC_free (edge, heap, edges);
free (body);
return opt_info;
}

View File

@ -640,23 +640,23 @@ predict_loops (struct loops *loops_info)
for (i = 1; i < loops_info->num; i++)
{
basic_block bb, *bbs;
unsigned j;
unsigned n_exits;
unsigned j, n_exits;
struct loop *loop = loops_info->parray[i];
edge *exits;
VEC (edge, heap) *exits;
struct tree_niter_desc niter_desc;
edge ex;
exits = get_loop_exit_edges (loop, &n_exits);
exits = get_loop_exit_edges (loop);
n_exits = VEC_length (edge, exits);
for (j = 0; j < n_exits; j++)
for (j = 0; VEC_iterate (edge, exits, j, ex); j++)
{
tree niter = NULL;
if (number_of_iterations_exit (loop, exits[j], &niter_desc, false))
if (number_of_iterations_exit (loop, ex, &niter_desc, false))
niter = niter_desc.niter;
if (!niter || TREE_CODE (niter_desc.niter) != INTEGER_CST)
niter = loop_niter_by_eval (loop, exits[j]);
niter = loop_niter_by_eval (loop, ex);
if (TREE_CODE (niter) == INTEGER_CST)
{
@ -673,10 +673,10 @@ predict_loops (struct loops *loops_info)
else
probability = ((REG_BR_PROB_BASE + max / 2) / max);
predict_edge (exits[j], PRED_LOOP_ITERATIONS, probability);
predict_edge (ex, PRED_LOOP_ITERATIONS, probability);
}
}
free (exits);
VEC_free (edge, heap, exits);
bbs = get_loop_body (loop);

View File

@ -1976,9 +1976,6 @@ rewrite_trees (var_map map, tree *values)
delete_elim_graph (g);
}
DEF_VEC_ALLOC_P(edge,heap);
/* These are the local work structures used to determine the best place to
insert the copies that were placed on edges by the SSA->normal pass.. */
static VEC(edge,heap) *edge_leader;

View File

@ -1016,13 +1016,12 @@ get_lsm_tmp_name (tree ref)
/* Records request for store motion of memory reference REF from LOOP.
MEM_REFS is the list of occurrences of the reference REF inside LOOP;
these references are rewritten by a new temporary variable.
Exits from the LOOP are stored in EXITS, there are N_EXITS of them.
The initialization of the temporary variable is put to the preheader
of the loop, and assignments to the reference from the temporary variable
are emitted to exits. */
Exits from the LOOP are stored in EXITS. The initialization of the
temporary variable is put to the preheader of the loop, and assignments
to the reference from the temporary variable are emitted to exits. */
static void
schedule_sm (struct loop *loop, edge *exits, unsigned n_exits, tree ref,
schedule_sm (struct loop *loop, VEC (edge, heap) *exits, tree ref,
struct mem_ref_loc *mem_refs)
{
struct mem_ref_loc *aref;
@ -1030,6 +1029,7 @@ schedule_sm (struct loop *loop, edge *exits, unsigned n_exits, tree ref,
unsigned i;
tree load, store;
struct fmt_data fmt_data;
edge ex;
if (dump_file && (dump_flags & TDF_DETAILS))
{
@ -1060,11 +1060,11 @@ schedule_sm (struct loop *loop, edge *exits, unsigned n_exits, tree ref,
all dependencies. */
bsi_insert_on_edge (loop_latch_edge (loop), load);
for (i = 0; i < n_exits; i++)
for (i = 0; VEC_iterate (edge, exits, i, ex); i++)
{
store = build2 (MODIFY_EXPR, void_type_node,
unshare_expr (ref), tmp_var);
bsi_insert_on_edge (exits[i], store);
bsi_insert_on_edge (ex, store);
}
}
@ -1072,12 +1072,12 @@ schedule_sm (struct loop *loop, edge *exits, unsigned n_exits, tree ref,
is true, prepare the statements that load the value of the memory reference
to a temporary variable in the loop preheader, store it back on the loop
exits, and replace all the references inside LOOP by this temporary variable.
LOOP has N_EXITS stored in EXITS. CLOBBERED_VOPS is the bitmap of virtual
EXITS is the list of exits of LOOP. CLOBBERED_VOPS is the bitmap of virtual
operands that are clobbered by a call or accessed through multiple references
in loop. */
static void
determine_lsm_ref (struct loop *loop, edge *exits, unsigned n_exits,
determine_lsm_ref (struct loop *loop, VEC (edge, heap) *exits,
bitmap clobbered_vops, struct mem_ref *ref)
{
struct mem_ref_loc *aref;
@ -1123,35 +1123,36 @@ determine_lsm_ref (struct loop *loop, edge *exits, unsigned n_exits,
return;
}
schedule_sm (loop, exits, n_exits, ref->mem, ref->locs);
schedule_sm (loop, exits, ref->mem, ref->locs);
}
/* Hoists memory references MEM_REFS out of LOOP. CLOBBERED_VOPS is the list
of vops clobbered by call in loop or accessed by multiple memory references.
EXITS is the list of N_EXITS exit edges of the LOOP. */
EXITS is the list of exit edges of the LOOP. */
static void
hoist_memory_references (struct loop *loop, struct mem_ref *mem_refs,
bitmap clobbered_vops, edge *exits, unsigned n_exits)
bitmap clobbered_vops, VEC (edge, heap) *exits)
{
struct mem_ref *ref;
for (ref = mem_refs; ref; ref = ref->next)
determine_lsm_ref (loop, exits, n_exits, clobbered_vops, ref);
determine_lsm_ref (loop, exits, clobbered_vops, ref);
}
/* Checks whether LOOP (with N_EXITS exits stored in EXITS array) is suitable
/* Checks whether LOOP (with exits stored in EXITS array) is suitable
for a store motion optimization (i.e. whether we can insert statement
on its exits). */
static bool
loop_suitable_for_sm (struct loop *loop ATTRIBUTE_UNUSED, edge *exits,
unsigned n_exits)
loop_suitable_for_sm (struct loop *loop ATTRIBUTE_UNUSED,
VEC (edge, heap) *exits)
{
unsigned i;
edge ex;
for (i = 0; i < n_exits; i++)
if (exits[i]->flags & EDGE_ABNORMAL)
for (i = 0; VEC_iterate (edge, exits, i, ex); i++)
if (ex->flags & EDGE_ABNORMAL)
return false;
return true;
@ -1345,14 +1346,13 @@ free_mem_refs (struct mem_ref *refs)
static void
determine_lsm_loop (struct loop *loop)
{
unsigned n_exits;
edge *exits = get_loop_exit_edges (loop, &n_exits);
VEC (edge, heap) *exits = get_loop_exit_edges (loop);
bitmap clobbered_vops;
struct mem_ref *mem_refs;
if (!loop_suitable_for_sm (loop, exits, n_exits))
if (!loop_suitable_for_sm (loop, exits))
{
free (exits);
VEC_free (edge, heap, exits);
return;
}
@ -1364,10 +1364,10 @@ determine_lsm_loop (struct loop *loop)
find_more_ref_vops (mem_refs, clobbered_vops);
/* Hoist all suitable memory references. */
hoist_memory_references (loop, mem_refs, clobbered_vops, exits, n_exits);
hoist_memory_references (loop, mem_refs, clobbered_vops, exits);
free_mem_refs (mem_refs);
free (exits);
VEC_free (edge, heap, exits);
BITMAP_FREE (clobbered_vops);
}

View File

@ -1161,16 +1161,15 @@ number_of_iterations_exit (struct loop *loop, edge exit,
tree
find_loop_niter (struct loop *loop, edge *exit)
{
unsigned n_exits, i;
edge *exits = get_loop_exit_edges (loop, &n_exits);
unsigned i;
VEC (edge, heap) *exits = get_loop_exit_edges (loop);
edge ex;
tree niter = NULL_TREE, aniter;
struct tree_niter_desc desc;
*exit = NULL;
for (i = 0; i < n_exits; i++)
for (i = 0; VEC_iterate (edge, exits, i, ex); i++)
{
ex = exits[i];
if (!just_once_each_iteration_p (loop, ex->src))
continue;
@ -1217,7 +1216,7 @@ find_loop_niter (struct loop *loop, edge *exit)
continue;
}
}
free (exits);
VEC_free (edge, heap, exits);
return niter ? niter : chrec_dont_know;
}
@ -1446,15 +1445,14 @@ loop_niter_by_eval (struct loop *loop, edge exit)
tree
find_loop_niter_by_eval (struct loop *loop, edge *exit)
{
unsigned n_exits, i;
edge *exits = get_loop_exit_edges (loop, &n_exits);
unsigned i;
VEC (edge, heap) *exits = get_loop_exit_edges (loop);
edge ex;
tree niter = NULL_TREE, aniter;
*exit = NULL;
for (i = 0; i < n_exits; i++)
for (i = 0; VEC_iterate (edge, exits, i, ex); i++)
{
ex = exits[i];
if (!just_once_each_iteration_p (loop, ex->src))
continue;
@ -1469,7 +1467,7 @@ find_loop_niter_by_eval (struct loop *loop, edge *exit)
niter = aniter;
*exit = ex;
}
free (exits);
VEC_free (edge, heap, exits);
return niter ? niter : chrec_dont_know;
}
@ -1986,20 +1984,21 @@ infer_loop_bounds_from_undefined (struct loop *loop)
static void
estimate_numbers_of_iterations_loop (struct loop *loop)
{
edge *exits;
VEC (edge, heap) *exits;
tree niter, type;
unsigned i, n_exits;
unsigned i;
struct tree_niter_desc niter_desc;
edge ex;
/* Give up if we already have tried to compute an estimation. */
if (loop->estimate_state != EST_NOT_COMPUTED)
return;
loop->estimate_state = EST_NOT_AVAILABLE;
exits = get_loop_exit_edges (loop, &n_exits);
for (i = 0; i < n_exits; i++)
exits = get_loop_exit_edges (loop);
for (i = 0; VEC_iterate (edge, exits, i, ex); i++)
{
if (!number_of_iterations_exit (loop, exits[i], &niter_desc, false))
if (!number_of_iterations_exit (loop, ex, &niter_desc, false))
continue;
niter = niter_desc.niter;
@ -2010,10 +2009,10 @@ estimate_numbers_of_iterations_loop (struct loop *loop)
niter);
record_estimate (loop, niter,
niter_desc.additional_info,
last_stmt (exits[i]->src),
last_stmt (ex->src),
true, true);
}
free (exits);
VEC_free (edge, heap, exits);
infer_loop_bounds_from_undefined (loop);
compute_estimated_nb_iterations (loop);

View File

@ -149,7 +149,6 @@ struct local_info
opportunities as they are discovered. We keep the registered
jump threading opportunities in this vector as edge pairs
(original_edge, target_edge). */
DEF_VEC_ALLOC_P(edge,heap);
static VEC(edge,heap) *threaded_edges;