From c302207e352d7372845458212fa30251ff1ae730 Mon Sep 17 00:00:00 2001 From: Steven Bosscher Date: Mon, 13 Aug 2012 21:02:19 +0000 Subject: [PATCH] tree-ssa-pre.c (do_regular_insertion): Add FIXME markers at points of potentially huge memset overhead. * tree-ssa-pre.c (do_regular_insertion): Add FIXME markers at points of potentially huge memset overhead. (do_partial_partial_insertion): Likewise. * cfgexpand.c (gimple_expand_cfg): Use XCNEWVEC instead of xcalloc. * tree-vrp.c (find_assert_locations): Use XNEWVEC instead of XCNEWVEC for arrays to be filled by pre_and_rev_post_order_compute. Allocate the right number of slots, not that number plus NUM_FIXED_BLOCKS. * tree-ssa-reassoc.c (init_reassoc): Likewise. * cfganal.c (dfs_enumerate_from): Use XNEWVEC instead of XCNEWVEC for array used as stack. * tree-ssa-sccvn.c (init_scc_vn): Use XNEWVEC instead of XCNEWVEC for arrays to be filled by pre_and_rev_post_order_compute. * cfgloopmanip.c (find_path): Use XNEWVEC instead of XCNEWVEC for array to be filled by dfs_enumerate_from. (remove_path): Likewise. (duplicate_loop_to_header_edge): Use XNEWVEC instead of XCNEWVEC for array of loops that is filled on the next lines. * cfgloop.c (get_loop_body): Use XNEWVEC instead of XCNEWVEC for array of basic blocks to be returned. (get_loop_body_in_dom_order): Likewise. (get_loop_body_in_bfs_order): Likewise. * tree-ssa-loop-manip.c (loop_renamer_obstack): New static obstack for all bitmaps used for rewriting into loop-closed SSA form. (add_exit_phis_var): Allocate the def bitmap on it. Clear the livein bitmap at the end to release a lot of memory. (add_exit_phis): Allocate the exits bitmap on the new obstack. (get_loops_exits): Allocate the exits bitmap on the new obstack. (find_uses_to_rename_use): Allocate a use_blocks bitmap if ver is seen for the first time. (find_uses_to_rename): Add "???" for why the whole function must be re-scanned if changed_bbs is empty. (rewrite_into_loop_closed_ssa): Allocate bitmaps on the new obstack. Use XNEWVEC to allocate the use_blocks array. Initialize the new obstack, and free it at the end. Remove loop over all SSA names. (check_loop_closed_ssa_stmt): Look only at SSA_OP_USE operands. * tree-cfg.c (move_sese_region_to_fn): Use XNEWVEC instead of xcalloc to allocate edge_pred and edge_flag arrays. From-SVN: r190359 --- gcc/ChangeLog | 40 +++++++++++++++++++++++++++++++++++++++ gcc/cfganal.c | 2 +- gcc/cfgexpand.c | 3 +-- gcc/cfgloop.c | 6 +++--- gcc/cfgloopmanip.c | 6 +++--- gcc/tree-cfg.c | 9 ++++----- gcc/tree-ssa-loop-manip.c | 39 +++++++++++++++++++++++--------------- gcc/tree-ssa-pre.c | 6 ++++++ gcc/tree-ssa-reassoc.c | 4 ++-- gcc/tree-ssa-sccvn.c | 7 ++++--- gcc/tree-vrp.c | 12 ++++++------ 11 files changed, 94 insertions(+), 40 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bb28bd87271..dde7c78fd36 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,43 @@ +2012-08-13 Steven Bosscher + + * tree-ssa-pre.c (do_regular_insertion): Add FIXME markers at points + of potentially huge memset overhead. + (do_partial_partial_insertion): Likewise. + * cfgexpand.c (gimple_expand_cfg): Use XCNEWVEC instead of xcalloc. + * tree-vrp.c (find_assert_locations): Use XNEWVEC instead of XCNEWVEC + for arrays to be filled by pre_and_rev_post_order_compute. Allocate + the right number of slots, not that number plus NUM_FIXED_BLOCKS. + * tree-ssa-reassoc.c (init_reassoc): Likewise. + * cfganal.c (dfs_enumerate_from): Use XNEWVEC instead of XCNEWVEC for + array used as stack. + * tree-ssa-sccvn.c (init_scc_vn): Use XNEWVEC instead of XCNEWVEC for + arrays to be filled by pre_and_rev_post_order_compute. + * cfgloopmanip.c (find_path): Use XNEWVEC instead of XCNEWVEC for + array to be filled by dfs_enumerate_from. + (remove_path): Likewise. + (duplicate_loop_to_header_edge): Use XNEWVEC instead of XCNEWVEC for + array of loops that is filled on the next lines. + * cfgloop.c (get_loop_body): Use XNEWVEC instead of XCNEWVEC for + array of basic blocks to be returned. + (get_loop_body_in_dom_order): Likewise. + (get_loop_body_in_bfs_order): Likewise. + * tree-ssa-loop-manip.c (loop_renamer_obstack): New static obstack + for all bitmaps used for rewriting into loop-closed SSA form. + (add_exit_phis_var): Allocate the def bitmap on it. Clear the livein + bitmap at the end to release a lot of memory. + (add_exit_phis): Allocate the exits bitmap on the new obstack. + (get_loops_exits): Allocate the exits bitmap on the new obstack. + (find_uses_to_rename_use): Allocate a use_blocks bitmap if ver is + seen for the first time. + (find_uses_to_rename): Add "???" for why the whole function must + be re-scanned if changed_bbs is empty. + (rewrite_into_loop_closed_ssa): Allocate bitmaps on the new obstack. + Use XNEWVEC to allocate the use_blocks array. Initialize the new + obstack, and free it at the end. Remove loop over all SSA names. + (check_loop_closed_ssa_stmt): Look only at SSA_OP_USE operands. + * tree-cfg.c (move_sese_region_to_fn): Use XNEWVEC instead of + xcalloc to allocate edge_pred and edge_flag arrays. + 2012-08-13 Uros Bizjak * config/i386/i386.h (FIXED_REGISTERS): Do not mark REX registers here. diff --git a/gcc/cfganal.c b/gcc/cfganal.c index 692be3808b8..7cf9ca85606 100644 --- a/gcc/cfganal.c +++ b/gcc/cfganal.c @@ -1019,7 +1019,7 @@ dfs_enumerate_from (basic_block bb, int reverse, v_size = size; } - st = XCNEWVEC (basic_block, rslt_max); + st = XNEWVEC (basic_block, rslt_max); rslt[tv++] = st[sp++] = bb; MARK_VISITED (bb); while (sp) diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index c6cd4e29089..6793ba68daf 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -4334,8 +4334,7 @@ gimple_expand_cfg (void) timevar_push (TV_OUT_OF_SSA); rewrite_out_of_ssa (&SA); timevar_pop (TV_OUT_OF_SSA); - SA.partition_to_pseudo = (rtx *)xcalloc (SA.map->num_partitions, - sizeof (rtx)); + SA.partition_to_pseudo = XCNEWVEC (rtx, SA.map->num_partitions); /* Make sure all values used by the optimization passes have sane defaults. */ diff --git a/gcc/cfgloop.c b/gcc/cfgloop.c index 0c51682897e..dd75be668e3 100644 --- a/gcc/cfgloop.c +++ b/gcc/cfgloop.c @@ -805,7 +805,7 @@ get_loop_body (const struct loop *loop) gcc_assert (loop->num_nodes); - body = XCNEWVEC (basic_block, loop->num_nodes); + body = XNEWVEC (basic_block, loop->num_nodes); if (loop->latch == EXIT_BLOCK_PTR) { @@ -865,7 +865,7 @@ get_loop_body_in_dom_order (const struct loop *loop) gcc_assert (loop->num_nodes); - tovisit = XCNEWVEC (basic_block, loop->num_nodes); + tovisit = XNEWVEC (basic_block, loop->num_nodes); gcc_assert (loop->latch != EXIT_BLOCK_PTR); @@ -904,7 +904,7 @@ get_loop_body_in_bfs_order (const struct loop *loop) gcc_assert (loop->num_nodes); gcc_assert (loop->latch != EXIT_BLOCK_PTR); - blocks = XCNEWVEC (basic_block, loop->num_nodes); + blocks = XNEWVEC (basic_block, loop->num_nodes); visited = BITMAP_ALLOC (NULL); bb = loop->header; diff --git a/gcc/cfgloopmanip.c b/gcc/cfgloopmanip.c index b9ca4b024de..98a306fd68c 100644 --- a/gcc/cfgloopmanip.c +++ b/gcc/cfgloopmanip.c @@ -71,7 +71,7 @@ find_path (edge e, basic_block **bbs) gcc_assert (EDGE_COUNT (e->dest->preds) <= 1); /* Find bbs in the path. */ - *bbs = XCNEWVEC (basic_block, n_basic_blocks); + *bbs = XNEWVEC (basic_block, n_basic_blocks); return dfs_enumerate_from (e->dest, 0, rpe_enum_p, *bbs, n_basic_blocks, e->dest); } @@ -322,7 +322,7 @@ remove_path (edge e) nrem = find_path (e, &rem_bbs); n_bord_bbs = 0; - bord_bbs = XCNEWVEC (basic_block, n_basic_blocks); + bord_bbs = XNEWVEC (basic_block, n_basic_blocks); seen = sbitmap_alloc (last_basic_block); sbitmap_zero (seen); @@ -1135,7 +1135,7 @@ duplicate_loop_to_header_edge (struct loop *loop, edge e, n_orig_loops = 0; for (aloop = loop->inner; aloop; aloop = aloop->next) n_orig_loops++; - orig_loops = XCNEWVEC (struct loop *, n_orig_loops); + orig_loops = XNEWVEC (struct loop *, n_orig_loops); for (aloop = loop->inner, i = 0; aloop; aloop = aloop->next, i++) orig_loops[i] = aloop; diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index f8d841a86d2..f1e9ddf52b2 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -6467,8 +6467,8 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb, EXIT_BB so that we can re-attach them to the new basic block that will replace the region. */ num_entry_edges = EDGE_COUNT (entry_bb->preds); - entry_pred = (basic_block *) xcalloc (num_entry_edges, sizeof (basic_block)); - entry_flag = (int *) xcalloc (num_entry_edges, sizeof (int)); + entry_pred = XNEWVEC (basic_block, num_entry_edges); + entry_flag = XNEWVEC (int, num_entry_edges); entry_prob = XNEWVEC (unsigned, num_entry_edges); i = 0; for (ei = ei_start (entry_bb->preds); (e = ei_safe_edge (ei)) != NULL;) @@ -6482,9 +6482,8 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb, if (exit_bb) { num_exit_edges = EDGE_COUNT (exit_bb->succs); - exit_succ = (basic_block *) xcalloc (num_exit_edges, - sizeof (basic_block)); - exit_flag = (int *) xcalloc (num_exit_edges, sizeof (int)); + exit_succ = XNEWVEC (basic_block, num_exit_edges); + exit_flag = XNEWVEC (int, num_exit_edges); exit_prob = XNEWVEC (unsigned, num_exit_edges); i = 0; for (ei = ei_start (exit_bb->succs); (e = ei_safe_edge (ei)) != NULL;) diff --git a/gcc/tree-ssa-loop-manip.c b/gcc/tree-ssa-loop-manip.c index 5aa8c7d3c3f..98846138e7c 100644 --- a/gcc/tree-ssa-loop-manip.c +++ b/gcc/tree-ssa-loop-manip.c @@ -34,6 +34,10 @@ along with GCC; see the file COPYING3. If not see #include "tree-inline.h" #include "langhooks.h" +/* All bitmaps for rewriting into loop-closed SSA go on this obstack, + so that we can free them all at once. */ +static bitmap_obstack loop_renamer_obstack; + /* Creates an induction variable with value BASE + STEP * iteration in LOOP. It is expected that neither BASE nor STEP are shared with other expressions (unless the sharing rules allow this). Use VAR as a base var_decl for it @@ -168,7 +172,7 @@ add_exit_phis_var (tree var, bitmap livein, bitmap exits) gcc_checking_assert (is_gimple_reg (var)); bitmap_clear_bit (livein, def_bb->index); - def = BITMAP_ALLOC (NULL); + def = BITMAP_ALLOC (&loop_renamer_obstack); bitmap_set_bit (def, def_bb->index); compute_global_livein (livein, def); BITMAP_FREE (def); @@ -177,6 +181,10 @@ add_exit_phis_var (tree var, bitmap livein, bitmap exits) { add_exit_phis_edge (BASIC_BLOCK (index), var); } + + /* Free the livein bitmap. We'll not be needing it anymore, and + it may have grown quite large. No reason to hold on to it. */ + bitmap_clear (livein); } /* Add exit phis for the names marked in NAMES_TO_RENAME. @@ -200,7 +208,7 @@ add_exit_phis (bitmap names_to_rename, bitmap *use_blocks, bitmap loop_exits) static bitmap get_loops_exits (void) { - bitmap exits = BITMAP_ALLOC (NULL); + bitmap exits = BITMAP_ALLOC (&loop_renamer_obstack); basic_block bb; edge e; edge_iterator ei; @@ -253,11 +261,11 @@ find_uses_to_rename_use (basic_block bb, tree use, bitmap *use_blocks, if (flow_bb_inside_loop_p (def_loop, bb)) return; - if (!use_blocks[ver]) - use_blocks[ver] = BITMAP_ALLOC (NULL); + /* If we're seeing VER for the first time, we still have to allocate + a bitmap for its uses. */ + if (bitmap_set_bit (need_phis, ver)) + use_blocks[ver] = BITMAP_ALLOC (&loop_renamer_obstack); bitmap_set_bit (use_blocks[ver], bb->index); - - bitmap_set_bit (need_phis, ver); } /* For uses in STMT, mark names that are used outside of the loop they are @@ -312,6 +320,7 @@ find_uses_to_rename (bitmap changed_bbs, bitmap *use_blocks, bitmap need_phis) unsigned index; bitmap_iterator bi; + /* ??? If CHANGED_BBS is empty we rewrite the whole function -- why? */ if (changed_bbs && !bitmap_empty_p (changed_bbs)) { EXECUTE_IF_SET_IN_BITMAP (changed_bbs, 0, index, bi) @@ -365,22 +374,25 @@ rewrite_into_loop_closed_ssa (bitmap changed_bbs, unsigned update_flag) { bitmap loop_exits; bitmap *use_blocks; - unsigned i, old_num_ssa_names; bitmap names_to_rename; loops_state_set (LOOP_CLOSED_SSA); if (number_of_loops () <= 1) return; + bitmap_obstack_initialize (&loop_renamer_obstack); + loop_exits = get_loops_exits (); - names_to_rename = BITMAP_ALLOC (NULL); + names_to_rename = BITMAP_ALLOC (&loop_renamer_obstack); /* If the pass has caused the SSA form to be out-of-date, update it now. */ update_ssa (update_flag); - old_num_ssa_names = num_ssa_names; - use_blocks = XCNEWVEC (bitmap, old_num_ssa_names); + /* Uses of names to rename. We don't have to initialize this array, + because we know that we will only have entries for the SSA names + in NAMES_TO_RENAME. */ + use_blocks = XCNEWVEC (bitmap, num_ssa_names); /* Find the uses outside loops. */ find_uses_to_rename (changed_bbs, use_blocks, names_to_rename); @@ -389,11 +401,8 @@ rewrite_into_loop_closed_ssa (bitmap changed_bbs, unsigned update_flag) rewrite. */ add_exit_phis (names_to_rename, use_blocks, loop_exits); - for (i = 0; i < old_num_ssa_names; i++) - BITMAP_FREE (use_blocks[i]); + bitmap_obstack_release (&loop_renamer_obstack); free (use_blocks); - BITMAP_FREE (loop_exits); - BITMAP_FREE (names_to_rename); /* Fix up all the names found to be used outside their original loops. */ @@ -428,7 +437,7 @@ check_loop_closed_ssa_stmt (basic_block bb, gimple stmt) if (is_gimple_debug (stmt)) return; - FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_ALL_USES) + FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_USE) check_loop_closed_ssa_use (bb, var); } diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c index 47df596ee6c..b4775404fdb 100644 --- a/gcc/tree-ssa-pre.c +++ b/gcc/tree-ssa-pre.c @@ -3442,6 +3442,9 @@ do_regular_insertion (basic_block block, basic_block dom) continue; } + /* FIXME: This costs N_EXPR*N_BASIC_BLOCKS. Should use + a less costly data structure for avail (e.g. a VEC + indexed by edge index). */ avail = XCNEWVEC (pre_expr, last_basic_block); FOR_EACH_EDGE (pred, ei, block->preds) { @@ -3602,6 +3605,9 @@ do_partial_partial_insertion (basic_block block, basic_block dom) if (bitmap_set_contains_value (AVAIL_OUT (dom), val)) continue; + /* FIXME: This costs N_EXPR*N_BASIC_BLOCKS. Should use + a less costly data structure for avail (e.g. a VEC + indexed by edge index). */ avail = XCNEWVEC (pre_expr, last_basic_block); FOR_EACH_EDGE (pred, ei, block->preds) { diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c index 233ecce59bd..ebe2dc3fc92 100644 --- a/gcc/tree-ssa-reassoc.c +++ b/gcc/tree-ssa-reassoc.c @@ -3613,7 +3613,7 @@ init_reassoc (void) { int i; long rank = 2; - int *bbs = XNEWVEC (int, last_basic_block + 1); + int *bbs = XNEWVEC (int, n_basic_blocks - NUM_FIXED_BLOCKS); /* Find the loops, so that we can prevent moving calculations in them. */ @@ -3628,7 +3628,7 @@ init_reassoc (void) /* Reverse RPO (Reverse Post Order) will give us something where deeper loops come later. */ pre_and_rev_post_order_compute (NULL, bbs, false); - bb_rank = XCNEWVEC (long, last_basic_block + 1); + bb_rank = XCNEWVEC (long, last_basic_block); operand_rank = pointer_map_create (); /* Give each default definition a distinct rank. This includes diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index 842c392914d..b7e343be7c3 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -3835,13 +3835,14 @@ init_scc_vn (void) vn_ssa_aux_table = VEC_alloc (vn_ssa_aux_t, heap, num_ssa_names + 1); /* VEC_alloc doesn't actually grow it to the right size, it just preallocates the space to do so. */ - VEC_safe_grow_cleared (vn_ssa_aux_t, heap, vn_ssa_aux_table, num_ssa_names + 1); + VEC_safe_grow_cleared (vn_ssa_aux_t, heap, vn_ssa_aux_table, + num_ssa_names + 1); gcc_obstack_init (&vn_ssa_aux_obstack); shared_lookup_phiargs = NULL; shared_lookup_references = NULL; - rpo_numbers = XCNEWVEC (int, last_basic_block + NUM_FIXED_BLOCKS); - rpo_numbers_temp = XCNEWVEC (int, last_basic_block + NUM_FIXED_BLOCKS); + rpo_numbers = XNEWVEC (int, last_basic_block); + rpo_numbers_temp = XNEWVEC (int, n_basic_blocks - NUM_FIXED_BLOCKS); pre_and_rev_post_order_compute (NULL, rpo_numbers_temp, false); /* RPO numbers is an array of rpo ordering, rpo[i] = bb means that diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index eb6402bd281..65aa6c1169b 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -5574,19 +5574,19 @@ find_assert_locations_1 (basic_block bb, sbitmap live) static bool find_assert_locations (void) { - int *rpo = XCNEWVEC (int, last_basic_block + NUM_FIXED_BLOCKS); - int *bb_rpo = XCNEWVEC (int, last_basic_block + NUM_FIXED_BLOCKS); - int *last_rpo = XCNEWVEC (int, last_basic_block + NUM_FIXED_BLOCKS); + int *rpo = XNEWVEC (int, last_basic_block); + int *bb_rpo = XNEWVEC (int, last_basic_block); + int *last_rpo = XCNEWVEC (int, last_basic_block); int rpo_cnt, i; bool need_asserts; - live = XCNEWVEC (sbitmap, last_basic_block + NUM_FIXED_BLOCKS); + live = XCNEWVEC (sbitmap, last_basic_block); rpo_cnt = pre_and_rev_post_order_compute (NULL, rpo, false); for (i = 0; i < rpo_cnt; ++i) bb_rpo[rpo[i]] = i; need_asserts = false; - for (i = rpo_cnt-1; i >= 0; --i) + for (i = rpo_cnt - 1; i >= 0; --i) { basic_block bb = BASIC_BLOCK (rpo[i]); edge e; @@ -5647,7 +5647,7 @@ find_assert_locations (void) XDELETEVEC (rpo); XDELETEVEC (bb_rpo); XDELETEVEC (last_rpo); - for (i = 0; i < last_basic_block + NUM_FIXED_BLOCKS; ++i) + for (i = 0; i < last_basic_block; ++i) if (live[i]) sbitmap_free (live[i]); XDELETEVEC (live);