=== modified file 'gcc/df-scan.c'
@@ -184,6 +184,17 @@ struct df_scan_problem_data
bitmap_obstack insn_bitmaps;
};
+/* Obstack for storing all of all of
+ insn_info->{defs,uses,eq_uses,mw_hardregs} and
+ bb_info->artificial_{defs,uses}. */
+static struct obstack df_refs_obstack;
+
+/* Keep the obstack initialised (only 4k overhead) and use this pointer to
+ actually empty it fast. */
+static void *df_first_refs_obj;
+static int df_refs_obstack_is_init;
+
+
typedef struct df_scan_bb_info *df_scan_bb_info_t;
@@ -193,36 +204,13 @@ df_scan_free_internal (void)
{
struct df_scan_problem_data *problem_data
= (struct df_scan_problem_data *) df_scan->problem_data;
- unsigned int i;
- basic_block bb;
- /* The vectors that hold the refs are not pool allocated because
- they come in many sizes. This makes them impossible to delete
- all at once. */
- for (i = 0; i < DF_INSN_SIZE(); i++)
- {
- struct df_insn_info *insn_info = DF_INSN_UID_GET(i);
- /* Skip the insns that have no insn_info or have been
- deleted. */
- if (insn_info)
- {
- df_scan_free_ref_vec (insn_info->defs);
- df_scan_free_ref_vec (insn_info->uses);
- df_scan_free_ref_vec (insn_info->eq_uses);
- df_scan_free_mws_vec (insn_info->mw_hardregs);
- }
- }
-
- FOR_ALL_BB (bb)
- {
- unsigned int bb_index = bb->index;
- struct df_scan_bb_info *bb_info = df_scan_get_bb_info (bb_index);
- if (bb_info)
- {
- df_scan_free_ref_vec (bb_info->artificial_defs);
- df_scan_free_ref_vec (bb_info->artificial_uses);
- }
- }
+ /* Delete at once all vectors that hold the refs (all of
+ insn_info->{defs,uses,eq_uses,mw_hardregs} and
+ bb_info->artificial_{defs,uses}) but keep the obstack initialised, so
+ that it's ready for more BBs. */
+ obstack_free (&df_refs_obstack, df_first_refs_obj);
+ df_first_refs_obj = NULL;
free (df->def_info.refs);
free (df->def_info.begin);
@@ -364,6 +352,14 @@ df_scan_alloc (bitmap all_blocks ATTRIBU
bb_info->artificial_uses = NULL;
}
+ if (! df_refs_obstack_is_init)
+ {
+ obstack_init (&df_refs_obstack);
+ df_refs_obstack_is_init = 1;
+ }
+ gcc_assert (df_first_refs_obj == NULL);
+ df_first_refs_obj = XOBNEW (&df_refs_obstack, void *);
+
bitmap_initialize (&df->hardware_regs_used, &problem_data->reg_bitmaps);
bitmap_initialize (&df->regular_block_artificial_uses, &problem_data->reg_bitmaps);
bitmap_initialize (&df->eh_block_artificial_uses, &problem_data->reg_bitmaps);
@@ -791,9 +787,15 @@ df_install_ref_incremental (df_ref ref)
}
ref_rec = *ref_rec_ptr;
+ /* fprintf (stderr, "count:%d ref_rec:%p\n", count, ref_rec); */
if (count)
{
- ref_rec = XRESIZEVEC (df_ref, ref_rec, count+2);
+ /* Impossible to actually know if ref_rec was malloc'ed or obstack'ed
+ thus we might have a leak here! */
+ df_ref *ref_rec2 = XOBNEWVEC (&df_refs_obstack, df_ref, count+2);
+ memcpy (ref_rec2, ref_rec, count*sizeof(df_ref));
+ /* free (ref_rec); */
+ ref_rec = ref_rec2;
*ref_rec_ptr = ref_rec;
ref_rec[count] = ref;
ref_rec[count+1] = NULL;
@@ -801,7 +803,7 @@ df_install_ref_incremental (df_ref ref)
}
else
{
- df_ref *ref_rec = XNEWVEC (df_ref, 2);
+ ref_rec = XOBNEWVEC (&df_refs_obstack, df_ref, 2);
ref_rec[0] = ref;
ref_rec[1] = NULL;
*ref_rec_ptr = ref_rec;
@@ -1070,8 +1072,9 @@ df_ref_chain_delete (df_ref *ref_rec)
/* If the list is empty, it has a special shared element that is not
to be deleted. */
- if (*start)
- free (start);
+ /* if (*start) */
+ /* free (start); */
+ /* obstack_free'd alltogether in the end of df pass. */
}
@@ -2611,7 +2615,7 @@ df_install_refs (basic_block bb,
count = VEC_length (df_ref, old_vec);
if (count)
{
- df_ref *new_vec = XNEWVEC (df_ref, count + 1);
+ df_ref *new_vec = XOBNEWVEC (&df_refs_obstack, df_ref, count + 1);
bool add_to_table;
df_ref this_ref;
unsigned int ix;