summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog16
-rw-r--r--gcc/basic-block.h1
-rw-r--r--gcc/cfgloop.c24
-rw-r--r--gcc/cfgloop.h2
-rw-r--r--gcc/loop-unroll.c18
-rw-r--r--gcc/predict.c20
-rw-r--r--gcc/tree-outof-ssa.c3
-rw-r--r--gcc/tree-ssa-loop-im.c48
-rw-r--r--gcc/tree-ssa-loop-niter.c33
-rw-r--r--gcc/tree-ssa-threadupdate.c1
10 files changed, 88 insertions, 78 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 896ac0e0243..c960ed934f7 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/basic-block.h b/gcc/basic-block.h
index 6b6820c1d0f..e330f3e40f3 100644
--- a/gcc/basic-block.h
+++ b/gcc/basic-block.h
@@ -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
diff --git a/gcc/cfgloop.c b/gcc/cfgloop.c
index 25549db5b94..4a5631df081 100644
--- a/gcc/cfgloop.c
+++ b/gcc/cfgloop.c
@@ -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;
diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h
index 17a1cf7d931..b02b4c7879a 100644
--- a/gcc/cfgloop.h
+++ b/gcc/cfgloop.h
@@ -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 *);
diff --git a/gcc/loop-unroll.c b/gcc/loop-unroll.c
index 49af45d4073..7d230fb6f3a 100644
--- a/gcc/loop-unroll.c
+++ b/gcc/loop-unroll.c
@@ -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;
}
diff --git a/gcc/predict.c b/gcc/predict.c
index caf867ee042..5e905430273 100644
--- a/gcc/predict.c
+++ b/gcc/predict.c
@@ -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);
diff --git a/gcc/tree-outof-ssa.c b/gcc/tree-outof-ssa.c
index ecfd1eef1db..b502fccec66 100644
--- a/gcc/tree-outof-ssa.c
+++ b/gcc/tree-outof-ssa.c
@@ -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;
diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c
index de0429e7683..e10017daf30 100644
--- a/gcc/tree-ssa-loop-im.c
+++ b/gcc/tree-ssa-loop-im.c
@@ -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);
}
diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c
index 487a08d8dd6..f410d8c63a8 100644
--- a/gcc/tree-ssa-loop-niter.c
+++ b/gcc/tree-ssa-loop-niter.c
@@ -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);
diff --git a/gcc/tree-ssa-threadupdate.c b/gcc/tree-ssa-threadupdate.c
index 0697ae4648e..c6b52095716 100644
--- a/gcc/tree-ssa-threadupdate.c
+++ b/gcc/tree-ssa-threadupdate.c
@@ -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;