This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[Bug middle-end/34400] [4.3 regression] bad interaction between DF and SJLJ exceptions
- From: Kenneth Zadeck <zadeck at naturalbridge dot com>
- To: gcc-patches <gcc-patches at gcc dot gnu dot org>, zadeck at naturalbridge dot com <gcc-bugzilla at gcc dot gnu dot org>, "Park, Seongbae" <seongbae dot park at gmail dot com>, "Bonzini, Paolo" <bonzini at gnu dot org>, Steven Bosscher <stevenb dot gcc at gmail dot com>
- Date: Thu, 17 Jan 2008 16:05:40 -0500
- Subject: [Bug middle-end/34400] [4.3 regression] bad interaction between DF and SJLJ exceptions
This is the second of three patches to fix 34400. This patch also makes
some progress on 26854 but more work is required that is not going to be
done in 4.3 to fix the problems here.
This patch uses the output of the df_lr problem to make the df_live
problem converge faster.
This not only saves time but also space since the size of the df_live
bitmaps never grows and the space of our bitmaps is proportional to the
number of 1 bits.
This has been tested on several platforms and along with the patch just
committed cuts the time on the 34400 problems significantly. I believe
that this patch also has some modest improvement on bootstrap time, i.e
regular programs.
The change to df_live_reset is a slightly related latent bug fix.
Ok to commit?
Kenny
2008-01-17 Kenneth Zadeck <zadeck@naturalbridge.com>
Steven Bosscher <stevenb.gcc@gmail.com>
PR rtl-optimization/26854
PR rtl-optimization/34400
* df-problems.c (df_live_scratch): New scratch bitmap.
(df_live_alloc): Allocate df_live_scratch when doing df_live.
(df_live_reset): Clear the proper bitmaps.
(df_live_bb_local_compute): Only process the artificial defs once
since the order is not important.
(df_live_init): Init the df_live sets only with the variables
found live by df_lr.
(df_live_transfer_function): Use the df_lr sets to prune the
df_live sets as they are being computed.
(df_live_free): Free df_live_scratch.
Index: df-problems.c
===================================================================
--- df-problems.c (revision 130752)
+++ df-problems.c (working copy)
@@ -1323,6 +1323,8 @@ struct df_live_problem_data
bitmap *out;
};
+/* Scratch var used by transfer functions. */
+static bitmap df_live_scratch;
/* Set basic block info. */
@@ -1366,6 +1368,8 @@ df_live_alloc (bitmap all_blocks ATTRIBU
if (!df_live->block_pool)
df_live->block_pool = create_alloc_pool ("df_live_block pool",
sizeof (struct df_live_bb_info), 100);
+ if (!df_live_scratch)
+ df_live_scratch = BITMAP_ALLOC (NULL);
df_grow_bb_info (df_live);
@@ -1401,7 +1405,7 @@ df_live_reset (bitmap all_blocks)
EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
{
- struct df_lr_bb_info *bb_info = df_lr_get_bb_info (bb_index);
+ struct df_live_bb_info *bb_info = df_live_get_bb_info (bb_index);
gcc_assert (bb_info);
bitmap_clear (bb_info->in);
bitmap_clear (bb_info->out);
@@ -1420,13 +1424,6 @@ df_live_bb_local_compute (unsigned int b
struct df_ref **def_rec;
int luid = 0;
- for (def_rec = df_get_artificial_defs (bb_index); *def_rec; def_rec++)
- {
- struct df_ref *def = *def_rec;
- if (DF_REF_FLAGS (def) & DF_REF_AT_TOP)
- bitmap_set_bit (bb_info->gen, DF_REF_REGNO (def));
- }
-
FOR_BB_INSNS (bb, insn)
{
unsigned int uid = INSN_UID (insn);
@@ -1467,8 +1464,7 @@ df_live_bb_local_compute (unsigned int b
for (def_rec = df_get_artificial_defs (bb_index); *def_rec; def_rec++)
{
struct df_ref *def = *def_rec;
- if ((DF_REF_FLAGS (def) & DF_REF_AT_TOP) == 0)
- bitmap_set_bit (bb_info->gen, DF_REF_REGNO (def));
+ bitmap_set_bit (bb_info->gen, DF_REF_REGNO (def));
}
}
@@ -1504,8 +1500,11 @@ df_live_init (bitmap all_blocks)
EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
{
struct df_live_bb_info *bb_info = df_live_get_bb_info (bb_index);
+ struct df_lr_bb_info *bb_lr_info = df_lr_get_bb_info (bb_index);
- bitmap_copy (bb_info->out, bb_info->gen);
+ /* No register may reach a location where it is not used. Thus
+ we trim the rr result to the places where it is used. */
+ bitmap_and (bb_info->out, bb_info->gen, bb_lr_info->out);
bitmap_clear (bb_info->in);
}
}
@@ -1531,12 +1530,18 @@ static bool
df_live_transfer_function (int bb_index)
{
struct df_live_bb_info *bb_info = df_live_get_bb_info (bb_index);
+ struct df_lr_bb_info *bb_lr_info = df_lr_get_bb_info (bb_index);
bitmap in = bb_info->in;
bitmap out = bb_info->out;
bitmap gen = bb_info->gen;
bitmap kill = bb_info->kill;
- return bitmap_ior_and_compl (out, gen, in, kill);
+ bitmap_and (df_live_scratch, gen, bb_lr_info->out);
+ /* No register may reach a location where it is not used. Thus
+ we trim the rr result to the places where it is used. */
+ bitmap_and_into (in, bb_lr_info->in);
+
+ return bitmap_ior_and_compl (out, df_live_scratch, in, kill);
}
@@ -1591,6 +1596,9 @@ df_live_free (void)
free_alloc_pool (df_live->block_pool);
df_live->block_info_size = 0;
free (df_live->block_info);
+
+ if (df_live_scratch)
+ BITMAP_FREE (df_live_scratch);
}
BITMAP_FREE (df_live->out_of_date_transfer_functions);
free (df_live);