diff options
-rw-r--r-- | gcc/ChangeLog | 16 | ||||
-rw-r--r-- | gcc/basic-block.h | 1 | ||||
-rw-r--r-- | gcc/cfgloop.c | 24 | ||||
-rw-r--r-- | gcc/cfgloop.h | 2 | ||||
-rw-r--r-- | gcc/loop-unroll.c | 18 | ||||
-rw-r--r-- | gcc/predict.c | 20 | ||||
-rw-r--r-- | gcc/tree-outof-ssa.c | 3 | ||||
-rw-r--r-- | gcc/tree-ssa-loop-im.c | 48 | ||||
-rw-r--r-- | gcc/tree-ssa-loop-niter.c | 33 | ||||
-rw-r--r-- | gcc/tree-ssa-threadupdate.c | 1 |
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; |