+2012-08-17 Steven Bosscher <steven@gcc.gnu.org>
+
+ PR middle-end/54146
+ * tree-ssa-loop-im.c (lim_bitmap_obstack): New bitmap_obstack.
+ (memref_free): Don't free the bitmaps individually here.
+ (mem_ref_alloc): Allocate the bitmaps on the new bitmap obstack.
+ (analyze_memory_references): Likewise.
+ (tree_ssa_lim_initialize): Initialize the new bitmap obstack.
+ (tree_ssa_lim_finalize): Release it.
+ * dse.c (dse_bitmap_obstack): New bitmap obstack.
+ (dse_obstack): New obstack.
+ (get_group_info): Allocate the bitmaps on the new bitmap obstack.
+ (dse_step0): Allocate the scratch bitmap on reg_obstack. Initialize
+ the new bitmap obstack and normal obstack. Use XNEWVEC for bb_table.
+ (record_store): Allocate regs_set on reg_obstack.
+ (dse_step1): Allocate regs_live on reg_obstack.
+ (dse_step2_init): Allocate offset_map_n and offset_map_p on the new
+ obstack.
+ (dse_step3_scan): Allocate bitmaps on the new bitmap obstack.
+ (dse_step3): Likewise.
+ (dse_confluence_0): Likewise.
+ (dse_confluence_n): Likewise.
+ (dse_transfer_function): Likewise.
+ (dse_step7): Destroy the new obstacks, and everything allocated on
+ them, in one big sweep.
+ (rest_of_handle_dse): Update.
+ * cfgexpand.c (stack_var_bitmap_obstack): New bitmap obstack.
+ (add_stack_var_conflict): Allocate bitmaps on it.
+ (add_scope_conflicts_1): Likewise.
+ (add_scope_conflicts): Likewise.
+ (update_alias_info_with_stack_vars): Likewise.
+ (init_vars_expansion): Move TREE_USED fiddling expand_used_vars.
+ Initialize the new bitmap obstack.
+ (fini_vars_expansion): Release it.
+ (estimated_stack_frame_size): Use init_vars_expansion to set things up
+ and always clean up at the end.
+ (expand_used_vars): Do the TREE_USED trickery here. Always call
+ fini_vars_expansion.
+ * tree-ssa-live.h (struct tree_live_info_d): Make livein and liveout
+ arrays of bitmap_head to avoid one indirection per bitmap access.
+ (live_on_entry, live_on_exit, live_var_map, live_merge_and_clear,
+ make_live_on_entry): Update.
+ * tree-ssa-live.c (partition_view_bitmap): Don't double-free 'used'.
+ (liveness_bitmap_obstack): New bitmap obstack.
+ (remove_unused_locals): Use it to allocate all bitmaps on. Update
+ for livein/liveout changes in tree-ssa-live.h.
+ (delete_tree_live_info): Release the bitmap obstack.
+ (loe_visit_block, live_worklist, set_var_live_on_entry,
+ calculate_live_on_exit, dump_live_info): Update.
+ (calculate_live_ranges): Initialize the bitmap.
+ * tree-ssa-ter.c (ter_bitmap_obstack): New bitmap obstack.
+ (new_temp_expr_table): Allocate bitmap on it.
+ (make_dependent_on_partition, add_to_partition_kill_list,
+ add_dependence, process_replaceable): Likewise.
+ (find_replaceable_exprs): Initialize and release the new obstack here.
+ * df-problems.c (df_lr_add_problem): Allocate persistent bitmap
+ for out_of_date_transfer_functions on df_bitmap_obstack.
+ (df_live_add_problem): Likewise.
+ (df_chain_add_problem): Likewise.
+ (df_word_lr_add_problem): Likewise.
+
2012-08-17 Nick Clifton <nickc@redhat.com>
* config/mep/t-mep (mep-pragma.o): Use $(COMPILER) to compile
static size_t stack_vars_num;
static struct pointer_map_t *decl_to_stack_part;
+/* Conflict bitmaps go on this obstack. This allows us to destroy
+ all of them in one big sweep. */
+static bitmap_obstack stack_var_bitmap_obstack;
+
/* An array of indices such that stack_vars[stack_vars_sorted[i]].size
is non-decreasing. */
static size_t *stack_vars_sorted;
struct stack_var *a = &stack_vars[x];
struct stack_var *b = &stack_vars[y];
if (!a->conflicts)
- a->conflicts = BITMAP_ALLOC (NULL);
+ a->conflicts = BITMAP_ALLOC (&stack_var_bitmap_obstack);
if (!b->conflicts)
- b->conflicts = BITMAP_ALLOC (NULL);
+ b->conflicts = BITMAP_ALLOC (&stack_var_bitmap_obstack);
bitmap_set_bit (a->conflicts, y);
bitmap_set_bit (b->conflicts, x);
}
{
struct stack_var *a = &stack_vars[i];
if (!a->conflicts)
- a->conflicts = BITMAP_ALLOC (NULL);
+ a->conflicts = BITMAP_ALLOC (&stack_var_bitmap_obstack);
bitmap_ior_into (a->conflicts, work);
}
visit = visit_conflict;
We then do a mostly classical bitmap liveness algorithm. */
FOR_ALL_BB (bb)
- bb->aux = BITMAP_ALLOC (NULL);
+ bb->aux = BITMAP_ALLOC (&stack_var_bitmap_obstack);
rpo = XNEWVEC (int, last_basic_block);
n_bbs = pre_and_rev_post_order_compute (NULL, rpo, false);
{
unsigned i;
struct pointer_set_t *visited = pointer_set_create ();
- bitmap temp = BITMAP_ALLOC (NULL);
+ bitmap temp = BITMAP_ALLOC (&stack_var_bitmap_obstack);
for (i = 1; i < num_ssa_names; i++)
{
static void
init_vars_expansion (void)
{
- tree t;
- unsigned ix;
- /* Set TREE_USED on all variables in the local_decls. */
- FOR_EACH_LOCAL_DECL (cfun, ix, t)
- TREE_USED (t) = 1;
+ /* Conflict bitmaps, and a few related temporary bitmaps, go here. */
+ bitmap_obstack_initialize (&stack_var_bitmap_obstack);
- /* Clear TREE_USED on all variables associated with a block scope. */
- clear_tree_used (DECL_INITIAL (current_function_decl));
+ /* A map from decl to stack partition. */
+ decl_to_stack_part = pointer_map_create ();
/* Initialize local stack smashing state. */
has_protected_decls = false;
static void
fini_vars_expansion (void)
{
- size_t i, n = stack_vars_num;
- for (i = 0; i < n; i++)
- BITMAP_FREE (stack_vars[i].conflicts);
- XDELETEVEC (stack_vars);
- XDELETEVEC (stack_vars_sorted);
+ bitmap_obstack_release (&stack_var_bitmap_obstack);
+ if (stack_vars)
+ XDELETEVEC (stack_vars);
+ if (stack_vars_sorted)
+ XDELETEVEC (stack_vars_sorted);
stack_vars = NULL;
stack_vars_sorted = NULL;
stack_vars_alloc = stack_vars_num = 0;
current_function_decl = node->symbol.decl;
push_cfun (fn);
+ init_vars_expansion ();
+
FOR_EACH_LOCAL_DECL (fn, i, var)
if (auto_var_in_fn_p (var, fn->decl))
size += expand_one_var (var, true, false);
for (i = 0; i < stack_vars_num; ++i)
stack_vars_sorted[i] = i;
size += account_stack_vars ();
- fini_vars_expansion ();
}
+
+ fini_vars_expansion ();
pop_cfun ();
current_function_decl = old_cur_fun_decl;
return size;
frame_phase = off ? align - off : 0;
}
+ /* Set TREE_USED on all variables in the local_decls. */
+ FOR_EACH_LOCAL_DECL (cfun, i, var)
+ TREE_USED (var) = 1;
+ /* Clear TREE_USED on all variables associated with a block scope. */
+ clear_tree_used (DECL_INITIAL (current_function_decl));
+
init_vars_expansion ();
ssa_name_decls = pointer_map_create ();
}
expand_stack_vars (NULL);
-
- fini_vars_expansion ();
}
+ fini_vars_expansion ();
+
/* If there were any artificial non-ignored vars without rtl
found earlier, see if deferred stack allocation hasn't assigned
rtl to them. */
df_add_problem (&problem_LR);
/* These will be initialized when df_scan_blocks processes each
block. */
- df_lr->out_of_date_transfer_functions = BITMAP_ALLOC (NULL);
+ df_lr->out_of_date_transfer_functions = BITMAP_ALLOC (&df_bitmap_obstack);
}
df_add_problem (&problem_LIVE);
/* These will be initialized when df_scan_blocks processes each
block. */
- df_live->out_of_date_transfer_functions = BITMAP_ALLOC (NULL);
+ df_live->out_of_date_transfer_functions = BITMAP_ALLOC (&df_bitmap_obstack);
}
{
df_add_problem (&problem_CHAIN);
df_chain->local_flags = chain_flags;
- df_chain->out_of_date_transfer_functions = BITMAP_ALLOC (NULL);
+ df_chain->out_of_date_transfer_functions = BITMAP_ALLOC (&df_bitmap_obstack);
}
#undef df_chain_problem_p
df_add_problem (&problem_WORD_LR);
/* These will be initialized when df_scan_blocks processes each
block. */
- df_word_lr->out_of_date_transfer_functions = BITMAP_ALLOC (NULL);
+ df_word_lr->out_of_date_transfer_functions = BITMAP_ALLOC (&df_bitmap_obstack);
}
that really have constant offsets this size. */
#define MAX_OFFSET (64 * 1024)
-
+/* Obstack for the DSE dataflow bitmaps. We don't want to put these
+ on the default obstack because these bitmaps can grow quite large
+ (~2GB for the small (!) test case of PR54146) and we'll hold on to
+ all that memory until the end of the compiler run.
+ As a bonus, delete_tree_live_info can destroy all the bitmaps by just
+ releasing the whole obstack. */
+static bitmap_obstack dse_bitmap_obstack;
+
+/* Obstack for other data. As for above: Kinda nice to be able to
+ throw it all away at the end in one big sweep. */
+static struct obstack dse_obstack;
+
+/* Scratch bitmap for cselib's cselib_expand_value_rtx. */
static bitmap scratch = NULL;
+
struct insn_info;
/* This structure holds information about a candidate store. */
(group_info_t) pool_alloc (rtx_group_info_pool);
memset (gi, 0, sizeof (struct group_info));
gi->id = rtx_group_next_id++;
- gi->store1_n = BITMAP_ALLOC (NULL);
- gi->store1_p = BITMAP_ALLOC (NULL);
- gi->store2_n = BITMAP_ALLOC (NULL);
- gi->store2_p = BITMAP_ALLOC (NULL);
- gi->escaped_p = BITMAP_ALLOC (NULL);
- gi->escaped_n = BITMAP_ALLOC (NULL);
- gi->group_kill = BITMAP_ALLOC (NULL);
+ gi->store1_n = BITMAP_ALLOC (&dse_bitmap_obstack);
+ gi->store1_p = BITMAP_ALLOC (&dse_bitmap_obstack);
+ gi->store2_n = BITMAP_ALLOC (&dse_bitmap_obstack);
+ gi->store2_p = BITMAP_ALLOC (&dse_bitmap_obstack);
+ gi->escaped_p = BITMAP_ALLOC (&dse_bitmap_obstack);
+ gi->escaped_n = BITMAP_ALLOC (&dse_bitmap_obstack);
+ gi->group_kill = BITMAP_ALLOC (&dse_bitmap_obstack);
gi->process_globally = false;
gi->offset_map_size_n = 0;
gi->offset_map_size_p = 0;
gi->id = rtx_group_next_id++;
gi->base_mem = gen_rtx_MEM (BLKmode, base);
gi->canon_base_addr = canon_rtx (base);
- gi->store1_n = BITMAP_ALLOC (NULL);
- gi->store1_p = BITMAP_ALLOC (NULL);
- gi->store2_n = BITMAP_ALLOC (NULL);
- gi->store2_p = BITMAP_ALLOC (NULL);
- gi->escaped_p = BITMAP_ALLOC (NULL);
- gi->escaped_n = BITMAP_ALLOC (NULL);
- gi->group_kill = BITMAP_ALLOC (NULL);
+ gi->store1_n = BITMAP_ALLOC (&dse_bitmap_obstack);
+ gi->store1_p = BITMAP_ALLOC (&dse_bitmap_obstack);
+ gi->store2_n = BITMAP_ALLOC (&dse_bitmap_obstack);
+ gi->store2_p = BITMAP_ALLOC (&dse_bitmap_obstack);
+ gi->escaped_p = BITMAP_ALLOC (&dse_bitmap_obstack);
+ gi->escaped_n = BITMAP_ALLOC (&dse_bitmap_obstack);
+ gi->group_kill = BITMAP_ALLOC (&dse_bitmap_obstack);
gi->process_globally = false;
gi->frame_related =
(base == frame_pointer_rtx) || (base == hard_frame_pointer_rtx);
globally_deleted = 0;
spill_deleted = 0;
- scratch = BITMAP_ALLOC (NULL);
- kill_on_calls = BITMAP_ALLOC (NULL);
+ bitmap_obstack_initialize (&dse_bitmap_obstack);
+ gcc_obstack_init (&dse_obstack);
+
+ scratch = BITMAP_ALLOC (®_obstack);
+ kill_on_calls = BITMAP_ALLOC (&dse_bitmap_obstack);
rtx_store_info_pool
= create_alloc_pool ("rtx_store_info_pool",
rtx_group_table = htab_create (11, invariant_group_base_hash,
invariant_group_base_eq, NULL);
- bb_table = XCNEWVEC (bb_info_t, last_basic_block);
+ bb_table = XNEWVEC (bb_info_t, last_basic_block);
rtx_group_next_id = 0;
stores_off_frame_dead_at_return = !cfun->stdarg;
{
store_info->is_large = true;
store_info->positions_needed.large.count = 0;
- store_info->positions_needed.large.bmap = BITMAP_ALLOC (NULL);
+ store_info->positions_needed.large.bmap = BITMAP_ALLOC (&dse_bitmap_obstack);
}
else
{
live at this point. For instance, this can happen if one of
the insns sets the CC and the CC happened to be live at that
point. This does occasionally happen, see PR 37922. */
- bitmap regs_set = BITMAP_ALLOC (NULL);
+ bitmap regs_set = BITMAP_ALLOC (®_obstack);
for (this_insn = insns; this_insn != NULL_RTX; this_insn = NEXT_INSN (this_insn))
note_stores (PATTERN (this_insn), look_for_hardregs, regs_set);
dse_step1 (void)
{
basic_block bb;
- bitmap regs_live = BITMAP_ALLOC (NULL);
+ bitmap regs_live = BITMAP_ALLOC (®_obstack);
cselib_init (0);
all_blocks = BITMAP_ALLOC (NULL);
}
group->offset_map_size_n++;
- group->offset_map_n = XNEWVEC (int, group->offset_map_size_n);
+ group->offset_map_n = XOBNEWVEC (&dse_obstack, int,
+ group->offset_map_size_n);
group->offset_map_size_p++;
- group->offset_map_p = XNEWVEC (int, group->offset_map_size_p);
+ group->offset_map_p = XOBNEWVEC (&dse_obstack, int,
+ group->offset_map_size_p);
group->process_globally = false;
if (dump_file)
{
if (bb_info->kill)
bitmap_clear (bb_info->kill);
else
- bb_info->kill = BITMAP_ALLOC (NULL);
+ bb_info->kill = BITMAP_ALLOC (&dse_bitmap_obstack);
}
else
if (bb_info->kill)
if (bb_info->gen)
bitmap_clear (bb_info->gen);
else
- bb_info->gen = BITMAP_ALLOC (NULL);
+ bb_info->gen = BITMAP_ALLOC (&dse_bitmap_obstack);
if (bb->index == ENTRY_BLOCK)
;
unsigned int j;
group_info_t group;
- all_ones = BITMAP_ALLOC (NULL);
+ all_ones = BITMAP_ALLOC (&dse_bitmap_obstack);
FOR_EACH_VEC_ELT (group_info_t, rtx_group_vec, j, group)
bitmap_ior_into (all_ones, group->group_kill);
}
if (!bb_info->out)
{
- bb_info->out = BITMAP_ALLOC (NULL);
+ bb_info->out = BITMAP_ALLOC (&dse_bitmap_obstack);
bitmap_copy (bb_info->out, all_ones);
}
}
if (!bb_info->out)
{
- bb_info->out = BITMAP_ALLOC (NULL);
+ bb_info->out = BITMAP_ALLOC (&dse_bitmap_obstack);
bitmap_copy (bb_info->out, bb_table[EXIT_BLOCK]->gen);
}
}
bitmap_and_into (src_info->out, dest_info->in);
else
{
- src_info->out = BITMAP_ALLOC (NULL);
+ src_info->out = BITMAP_ALLOC (&dse_bitmap_obstack);
bitmap_copy (src_info->out, dest_info->in);
}
}
bb_info->out, bb_info->kill);
else
{
- bb_info->in = BITMAP_ALLOC (NULL);
+ bb_info->in = BITMAP_ALLOC (&dse_bitmap_obstack);
bitmap_ior_and_compl (bb_info->in, bb_info->gen,
bb_info->out, bb_info->kill);
return true;
return false;
else
{
- bb_info->in = BITMAP_ALLOC (NULL);
+ bb_info->in = BITMAP_ALLOC (&dse_bitmap_obstack);
bitmap_copy (bb_info->in, bb_info->gen);
return true;
}
----------------------------------------------------------------------------*/
static void
-dse_step7 (bool global_done)
+dse_step7 (void)
{
- unsigned int i;
- group_info_t group;
- basic_block bb;
-
- FOR_EACH_VEC_ELT (group_info_t, rtx_group_vec, i, group)
- {
- free (group->offset_map_n);
- free (group->offset_map_p);
- BITMAP_FREE (group->store1_n);
- BITMAP_FREE (group->store1_p);
- BITMAP_FREE (group->store2_n);
- BITMAP_FREE (group->store2_p);
- BITMAP_FREE (group->escaped_n);
- BITMAP_FREE (group->escaped_p);
- BITMAP_FREE (group->group_kill);
- }
-
- if (global_done)
- FOR_ALL_BB (bb)
- {
- bb_info_t bb_info = bb_table[bb->index];
- BITMAP_FREE (bb_info->gen);
- if (bb_info->kill)
- BITMAP_FREE (bb_info->kill);
- if (bb_info->in)
- BITMAP_FREE (bb_info->in);
- if (bb_info->out)
- BITMAP_FREE (bb_info->out);
- }
+ bitmap_obstack_release (&dse_bitmap_obstack);
+ obstack_free (&dse_obstack, NULL);
if (clear_alias_sets)
{
}
dse_step6 ();
- dse_step7 (did_global);
+ dse_step7 ();
if (dump_file)
fprintf (dump_file, "dse: local deletions = %d, global deletions = %d, spill deletions = %d\n",
/* Create a partition view which includes all the used partitions in MAP. If
WANT_BASES is true, create the base variable map as well. */
-extern void
+void
partition_view_normal (var_map map, bool want_bases)
{
bitmap used;
the bitmap ONLY. If WANT_BASES is true, create the base variable map
as well. */
-extern void
+void
partition_view_bitmap (var_map map, bitmap only, bool want_bases)
{
bitmap used;
}
partition_view_fini (map, new_partitions);
- BITMAP_FREE (used);
if (want_bases)
var_map_base_init (map);
else
timevar_pop (TV_REMOVE_UNUSED);
}
+/* Obstack for globale liveness info bitmaps. We don't want to put these
+ on the default obstack because these bitmaps can grow quite large and
+ we'll hold on to all that memory until the end of the compiler run.
+ As a bonus, delete_tree_live_info can destroy all the bitmaps by just
+ releasing the whole obstack. */
+static bitmap_obstack liveness_bitmap_obstack;
/* Allocate and return a new live range information object base on MAP. */
new_tree_live_info (var_map map)
{
tree_live_info_p live;
- unsigned x;
+ basic_block bb;
- live = (tree_live_info_p) xmalloc (sizeof (struct tree_live_info_d));
+ live = XNEW (struct tree_live_info_d);
live->map = map;
live->num_blocks = last_basic_block;
- live->livein = (bitmap *)xmalloc (last_basic_block * sizeof (bitmap));
- for (x = 0; x < (unsigned)last_basic_block; x++)
- live->livein[x] = BITMAP_ALLOC (NULL);
+ live->livein = XNEWVEC (bitmap_head, last_basic_block);
+ FOR_EACH_BB (bb)
+ bitmap_initialize (&live->livein[bb->index], &liveness_bitmap_obstack);
- live->liveout = (bitmap *)xmalloc (last_basic_block * sizeof (bitmap));
- for (x = 0; x < (unsigned)last_basic_block; x++)
- live->liveout[x] = BITMAP_ALLOC (NULL);
+ live->liveout = XNEWVEC (bitmap_head, last_basic_block);
+ FOR_EACH_BB (bb)
+ bitmap_initialize (&live->liveout[bb->index], &liveness_bitmap_obstack);
live->work_stack = XNEWVEC (int, last_basic_block);
live->stack_top = live->work_stack;
- live->global = BITMAP_ALLOC (NULL);
+ live->global = BITMAP_ALLOC (&liveness_bitmap_obstack);
return live;
}
void
delete_tree_live_info (tree_live_info_p live)
{
- int x;
-
- BITMAP_FREE (live->global);
+ bitmap_obstack_release (&liveness_bitmap_obstack);
free (live->work_stack);
-
- for (x = live->num_blocks - 1; x >= 0; x--)
- BITMAP_FREE (live->liveout[x]);
free (live->liveout);
-
- for (x = live->num_blocks - 1; x >= 0; x--)
- BITMAP_FREE (live->livein[x]);
free (live->livein);
-
free (live);
}
predecessor block. This should be the live on entry vars to pred.
Note that liveout is the DEFs in a block while live on entry is
being calculated. */
- bitmap_and_compl (tmp, loe, live->liveout[pred_bb->index]);
+ bitmap_and_compl (tmp, loe, &live->liveout[pred_bb->index]);
/* Add these bits to live-on-entry for the pred. if there are any
changes, and pred_bb has been visited already, add it to the
unsigned b;
basic_block bb;
sbitmap visited = sbitmap_alloc (last_basic_block + 1);
- bitmap tmp = BITMAP_ALLOC (NULL);
+ bitmap tmp = BITMAP_ALLOC (&liveness_bitmap_obstack);
sbitmap_zero (visited);
def_bb = gimple_bb (stmt);
/* Mark defs in liveout bitmap temporarily. */
if (def_bb)
- bitmap_set_bit (live->liveout[def_bb->index], p);
+ bitmap_set_bit (&live->liveout[def_bb->index], p);
}
else
def_bb = ENTRY_BLOCK_PTR;
if (add_block)
{
global = true;
- bitmap_set_bit (live->livein[add_block->index], p);
+ bitmap_set_bit (&live->livein[add_block->index], p);
}
}
/* live on entry calculations used liveout vectors for defs, clear them. */
FOR_EACH_BB (bb)
- bitmap_clear (liveinfo->liveout[bb->index]);
+ bitmap_clear (&liveinfo->liveout[bb->index]);
/* Set all the live-on-exit bits for uses in PHIs. */
FOR_EACH_BB (bb)
continue;
e = gimple_phi_arg_edge (phi, i);
if (e->src != ENTRY_BLOCK_PTR)
- bitmap_set_bit (liveinfo->liveout[e->src->index], p);
+ bitmap_set_bit (&liveinfo->liveout[e->src->index], p);
}
}
/* Add each successors live on entry to this bock live on exit. */
FOR_EACH_EDGE (e, ei, bb->succs)
if (e->dest != EXIT_BLOCK_PTR)
- bitmap_ior_into (liveinfo->liveout[bb->index],
+ bitmap_ior_into (&liveinfo->liveout[bb->index],
live_on_entry (liveinfo, e->dest));
}
}
unsigned i;
tree_live_info_p live;
+ bitmap_obstack_initialize (&liveness_bitmap_obstack);
live = new_tree_live_info (map);
for (i = 0; i < num_var_partitions (map); i++)
{
FOR_EACH_BB (bb)
{
fprintf (f, "\nLive on entry to BB%d : ", bb->index);
- EXECUTE_IF_SET_IN_BITMAP (live->livein[bb->index], 0, i, bi)
+ EXECUTE_IF_SET_IN_BITMAP (&live->livein[bb->index], 0, i, bi)
{
print_generic_expr (f, partition_to_var (map, i), TDF_SLIM);
fprintf (f, " ");
FOR_EACH_BB (bb)
{
fprintf (f, "\nLive on exit from BB%d : ", bb->index);
- EXECUTE_IF_SET_IN_BITMAP (live->liveout[bb->index], 0, i, bi)
+ EXECUTE_IF_SET_IN_BITMAP (&live->liveout[bb->index], 0, i, bi)
{
print_generic_expr (f, partition_to_var (map, i), TDF_SLIM);
fprintf (f, " ");
/* Bitmap indicating which partitions are global. */
bitmap global;
- /* Bitmap of live on entry blocks for partition elements. */
- bitmap *livein;
+ /* Bitmaps of live on entry blocks for partition elements. */
+ bitmap_head *livein;
+
+ /* Bitmaps of what variables are live on exit for a basic blocks. */
+ bitmap_head *liveout;
/* Number of basic blocks when live on exit calculated. */
int num_blocks;
/* Top of workstack. */
int *stack_top;
-
- /* Bitmap of what variables are live on exit for a basic blocks. */
- bitmap *liveout;
} *tree_live_info_p;
&& bb != ENTRY_BLOCK_PTR
&& bb != EXIT_BLOCK_PTR);
- return live->livein[bb->index];
+ return &live->livein[bb->index];
}
&& bb != ENTRY_BLOCK_PTR
&& bb != EXIT_BLOCK_PTR);
- return live->liveout[bb->index];
+ return &live->liveout[bb->index];
}
static inline void
live_merge_and_clear (tree_live_info_p live, int p1, int p2)
{
- gcc_checking_assert (live->livein[p1] && live->livein[p2]);
- bitmap_ior_into (live->livein[p1], live->livein[p2]);
- bitmap_zero (live->livein[p2]);
+ gcc_checking_assert (&live->livein[p1] && &live->livein[p2]);
+ bitmap_ior_into (&live->livein[p1], &live->livein[p2]);
+ bitmap_zero (&live->livein[p2]);
}
static inline void
make_live_on_entry (tree_live_info_p live, basic_block bb , int p)
{
- bitmap_set_bit (live->livein[bb->index], p);
+ bitmap_set_bit (&live->livein[bb->index], p);
bitmap_set_bit (live->global, p);
}
struct pointer_map_t *ttae_cache;
} memory_accesses;
+/* Obstack for the bitmaps in the above data structures. */
+static bitmap_obstack lim_bitmap_obstack;
+
static bool ref_indep_loop_p (struct loop *, mem_ref_p);
/* Minimum cost of an expensive expression. */
unsigned i;
mem_ref_locs_p accs;
- BITMAP_FREE (mem->stored);
- BITMAP_FREE (mem->indep_loop);
- BITMAP_FREE (mem->dep_loop);
- BITMAP_FREE (mem->indep_ref);
- BITMAP_FREE (mem->dep_ref);
-
FOR_EACH_VEC_ELT (mem_ref_locs_p, mem->accesses_in_loop, i, accs)
free_mem_ref_locs (accs);
VEC_free (mem_ref_locs_p, heap, mem->accesses_in_loop);
ref->mem = mem;
ref->id = id;
ref->hash = hash;
- ref->stored = BITMAP_ALLOC (NULL);
- ref->indep_loop = BITMAP_ALLOC (NULL);
- ref->dep_loop = BITMAP_ALLOC (NULL);
- ref->indep_ref = BITMAP_ALLOC (NULL);
- ref->dep_ref = BITMAP_ALLOC (NULL);
+ ref->stored = BITMAP_ALLOC (&lim_bitmap_obstack);
+ ref->indep_loop = BITMAP_ALLOC (&lim_bitmap_obstack);
+ ref->dep_loop = BITMAP_ALLOC (&lim_bitmap_obstack);
+ ref->indep_ref = BITMAP_ALLOC (&lim_bitmap_obstack);
+ ref->dep_ref = BITMAP_ALLOC (&lim_bitmap_obstack);
ref->accesses_in_loop = NULL;
return ref;
for (i = 0; i < number_of_loops (); i++)
{
- empty = BITMAP_ALLOC (NULL);
+ empty = BITMAP_ALLOC (&lim_bitmap_obstack);
VEC_quick_push (bitmap, memory_accesses.refs_in_loop, empty);
- empty = BITMAP_ALLOC (NULL);
+ empty = BITMAP_ALLOC (&lim_bitmap_obstack);
VEC_quick_push (bitmap, memory_accesses.all_refs_in_loop, empty);
- empty = BITMAP_ALLOC (NULL);
+ empty = BITMAP_ALLOC (&lim_bitmap_obstack);
VEC_quick_push (bitmap, memory_accesses.all_refs_stored_in_loop, empty);
}
struct loop *loop;
basic_block bb;
+ bitmap_obstack_initialize (&lim_bitmap_obstack);
+
sbitmap_zero (contains_call);
FOR_EACH_BB (bb)
{
{
basic_block bb;
unsigned i;
- bitmap b;
mem_ref_p ref;
free_aux_for_edges ();
FOR_EACH_BB (bb)
SET_ALWAYS_EXECUTED_IN (bb, NULL);
+ bitmap_obstack_release (&lim_bitmap_obstack);
pointer_map_destroy (lim_aux_data_map);
htab_delete (memory_accesses.refs);
memref_free (ref);
VEC_free (mem_ref_p, heap, memory_accesses.refs_list);
- FOR_EACH_VEC_ELT (bitmap, memory_accesses.refs_in_loop, i, b)
- BITMAP_FREE (b);
VEC_free (bitmap, heap, memory_accesses.refs_in_loop);
-
- FOR_EACH_VEC_ELT (bitmap, memory_accesses.all_refs_in_loop, i, b)
- BITMAP_FREE (b);
VEC_free (bitmap, heap, memory_accesses.all_refs_in_loop);
-
- FOR_EACH_VEC_ELT (bitmap, memory_accesses.all_refs_stored_in_loop, i, b)
- BITMAP_FREE (b);
VEC_free (bitmap, heap, memory_accesses.all_refs_stored_in_loop);
if (memory_accesses.ttae_cache)
add_phi_arg (stmt, va, loop_latch_edge (loop), UNKNOWN_LOCATION);
}
-/* Return the outermost superloop LOOP of USE_LOOP that is a superloop of
+/* Return the innermost superloop LOOP of USE_LOOP that is a superloop of
both DEF_LOOP and USE_LOOP. */
static inline struct loop *
/* Used to indicate a dependency on VDEFs. */
#define VIRTUAL_PARTITION(table) (table->virtual_partition)
+/* A place for the many, many bitmaps we create. */
+static bitmap_obstack ter_bitmap_obstack;
+
#ifdef ENABLE_CHECKING
extern void debug_ter (FILE *, temp_expr_table_p);
#endif
t->expr_decl_uids = XCNEWVEC (bitmap, num_ssa_names + 1);
t->kill_list = XCNEWVEC (bitmap, num_var_partitions (map) + 1);
- t->partition_in_use = BITMAP_ALLOC (NULL);
+ t->partition_in_use = BITMAP_ALLOC (&ter_bitmap_obstack);
t->virtual_partition = num_var_partitions (map);
- t->new_replaceable_dependencies = BITMAP_ALLOC (NULL);
+ t->new_replaceable_dependencies = BITMAP_ALLOC (&ter_bitmap_obstack);
t->replaceable_expressions = NULL;
t->num_in_part = XCNEWVEC (int, num_var_partitions (map));
make_dependent_on_partition (temp_expr_table_p tab, int version, int p)
{
if (!tab->partition_dependencies[version])
- tab->partition_dependencies[version] = BITMAP_ALLOC (NULL);
+ tab->partition_dependencies[version] = BITMAP_ALLOC (&ter_bitmap_obstack);
bitmap_set_bit (tab->partition_dependencies[version], p);
}
{
if (!tab->kill_list[p])
{
- tab->kill_list[p] = BITMAP_ALLOC (NULL);
+ tab->kill_list[p] = BITMAP_ALLOC (&ter_bitmap_obstack);
bitmap_set_bit (tab->partition_in_use, p);
}
bitmap_set_bit (tab->kill_list[p], ver);
/* Rather than set partition_dependencies and in_use lists bit by
bit, simply OR in the new_replaceable_dependencies bits. */
if (!tab->partition_dependencies[version])
- tab->partition_dependencies[version] = BITMAP_ALLOC (NULL);
+ tab->partition_dependencies[version] =
+ BITMAP_ALLOC (&ter_bitmap_obstack);
bitmap_ior_into (tab->partition_dependencies[version],
tab->new_replaceable_dependencies);
bitmap_ior_into (tab->partition_in_use,
def = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_DEF);
version = SSA_NAME_VERSION (def);
- def_vars = BITMAP_ALLOC (NULL);
+ def_vars = BITMAP_ALLOC (&ter_bitmap_obstack);
basevar = SSA_NAME_VAR (def);
if (basevar)
finished_with_expr (tab, version, !more_replacing);
- /* Set the replaceable expression. */
+ /* Set the replaceable expression.
+ The bitmap for this "escapes" from this file so it's allocated
+ on the default obstack. */
if (!tab->replaceable_expressions)
tab->replaceable_expressions = BITMAP_ALLOC (NULL);
bitmap_set_bit (tab->replaceable_expressions, version);
NULL is returned by the function, otherwise an expression vector indexed
by SSA_NAME version numbers. */
-extern bitmap
+bitmap
find_replaceable_exprs (var_map map)
{
basic_block bb;
temp_expr_table_p table;
bitmap ret;
+ bitmap_obstack_initialize (&ter_bitmap_obstack);
table = new_temp_expr_table (map);
FOR_EACH_BB (bb)
{
find_replaceable_in_bb (table, bb);
gcc_checking_assert (bitmap_empty_p (table->partition_in_use));
}
-
ret = free_temp_expr_table (table);
+ bitmap_obstack_release (&ter_bitmap_obstack);
return ret;
}