Commit ca83d385 by Zdenek Dvorak Committed by Zdenek Dvorak

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
parent c6119197
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.
......
......@@ -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
......
......@@ -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;
......
......@@ -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 *);
......
......@@ -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;
}
......
......@@ -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);
......
......@@ -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;
......
......@@ -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);
}
......
......@@ -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);
......
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment