This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[dataflow]: PATCH COMMITTED to fix dce/dse handling of libcalls.
- From: Kenneth Zadeck <zadeck at naturalbridge dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>, "Berlin, Daniel" <dberlin at dberlin dot org>, Seongbae Park <seongbae dot park at gmail dot com>, "Zadeck, Kenneth" <zadeck at naturalbridge dot com>, Steven Bosscher <stevenb dot gcc at gmail dot com>
- Date: Fri, 22 Dec 2006 20:09:55 -0500
- Subject: [dataflow]: PATCH COMMITTED to fix dce/dse handling of libcalls.
This patch gets the merge with mainline that dannyb committed two days
ago bootstrapping with no regressions on x86-64, x86-32 and ppc. The
branch will not bootstrap on the ia-64 because the point where Danny
merged from the mainline was having a bad ia-64 day. (However, the
dataflow branch does fail in exactly the same place as mainline).
There was one bug uncovered in this merge. An assertion added to cse by
stevenb triggered. The assertion was caused by dce deleting part of a
libcall. This is fixed here. Stevenb also noticed that dataflow info
being printed in the dumps needed to be prepended with an ";; " so it
looks more like the old dumps (and more importantly can be removed with
the same scripts). This has been also fixed here.
Kenny
2006-12-22 Kenneth Zadeck <zadeck@naturalbridge.com>
* df-problems.c (df_ru_start_dump, df_ru_top_dump,
df_ru_bottom_dump, df_rd_start_dump, df_rd_top_dump,
df_rd_bottom_dump, df_lr_top_dump, df_lr_bottom_dump,
df_ur_top_dump, df_ur_bottom_dump, df_live_top_dump,
df_urec_top_dump, df_urec_bottom_dump, df_chain_start_dump,
df_ri_start_dump): Added ";; " to the beginning of dataflow
information put in dump files.
* dce.c (marked_libcalls, delete_unmarked_insns): Removed.
(prescan_insns_for_dce, mark_libcall, dce_process_block,
prescan_insns_for_dse): Replaced libcall marking mechanism.
(init_dce, end_dce, end_fast_dce, run_fast_df_dce): Removed
marked_libcalls.
Index: df-problems.c
===================================================================
--- df-problems.c (revision 120099)
+++ df-problems.c (working copy)
@@ -687,11 +687,11 @@ df_ru_start_dump (FILE *file)
if (!df_ru->block_info)
return;
- fprintf (file, "Reaching uses:\n");
+ fprintf (file, ";; Reaching uses:\n");
- fprintf (file, " sparse invalidated \t");
+ fprintf (file, ";; sparse invalidated \t");
dump_bitmap (file, problem_data->sparse_invalidated_by_call);
- fprintf (file, " dense invalidated \t");
+ fprintf (file, " dense invalidated \t");
dump_bitmap (file, problem_data->dense_invalidated_by_call);
for (regno = 0; regno < m; regno++)
@@ -712,11 +712,11 @@ df_ru_top_dump (basic_block bb, FILE *fi
if (!bb_info || !bb_info->in)
return;
- fprintf (file, "ru in \t(%d)\n", (int) bitmap_count_bits (bb_info->in));
+ fprintf (file, ";; ru in \t(%d)\n", (int) bitmap_count_bits (bb_info->in));
dump_bitmap (file, bb_info->in);
- fprintf (file, "ru gen \t(%d)\n", (int) bitmap_count_bits (bb_info->gen));
+ fprintf (file, ";; ru gen \t(%d)\n", (int) bitmap_count_bits (bb_info->gen));
dump_bitmap (file, bb_info->gen);
- fprintf (file, "ru kill\t(%d)\n", (int) bitmap_count_bits (bb_info->kill));
+ fprintf (file, ";; ru kill\t(%d)\n", (int) bitmap_count_bits (bb_info->kill));
dump_bitmap (file, bb_info->kill);
}
@@ -730,7 +730,7 @@ df_ru_bottom_dump (basic_block bb, FILE
if (!bb_info || !bb_info->out)
return;
- fprintf (file, "ru out \t(%d)\n", (int) bitmap_count_bits (bb_info->out));
+ fprintf (file, ";; ru out \t(%d)\n", (int) bitmap_count_bits (bb_info->out));
dump_bitmap (file, bb_info->out);
}
@@ -1228,7 +1228,7 @@ df_rd_start_dump (FILE *file)
if (!df_rd->block_info)
return;
- fprintf (file, "Reaching defs:\n\n");
+ fprintf (file, ";; Reaching defs:\n\n");
fprintf (file, " sparse invalidated \t");
dump_bitmap (file, problem_data->sparse_invalidated_by_call);
@@ -1254,11 +1254,11 @@ df_rd_top_dump (basic_block bb, FILE *fi
if (!bb_info || !bb_info->in)
return;
- fprintf (file, "rd in \t(%d)\n", (int) bitmap_count_bits (bb_info->in));
+ fprintf (file, ";; rd in \t(%d)\n", (int) bitmap_count_bits (bb_info->in));
dump_bitmap (file, bb_info->in);
- fprintf (file, "rd gen \t(%d)\n", (int) bitmap_count_bits (bb_info->gen));
+ fprintf (file, ";; rd gen \t(%d)\n", (int) bitmap_count_bits (bb_info->gen));
dump_bitmap (file, bb_info->gen);
- fprintf (file, "rd kill\t(%d)\n", (int) bitmap_count_bits (bb_info->kill));
+ fprintf (file, ";; rd kill\t(%d)\n", (int) bitmap_count_bits (bb_info->kill));
dump_bitmap (file, bb_info->kill);
}
@@ -1272,7 +1272,7 @@ df_rd_bottom_dump (basic_block bb, FILE
if (!bb_info || !bb_info->out)
return;
- fprintf (file, "rd out \t(%d)\n", (int) bitmap_count_bits (bb_info->out));
+ fprintf (file, ";; rd out \t(%d)\n", (int) bitmap_count_bits (bb_info->out));
dump_bitmap (file, bb_info->out);
}
@@ -1812,11 +1812,11 @@ df_lr_top_dump (basic_block bb, FILE *fi
if (!bb_info || !bb_info->in)
return;
- fprintf (file, "lr in \t");
+ fprintf (file, ";; lr in \t");
df_print_regset (file, bb_info->in);
- fprintf (file, "lr use \t");
+ fprintf (file, ";; lr use \t");
df_print_regset (file, bb_info->use);
- fprintf (file, "lr def \t");
+ fprintf (file, ";; lr def \t");
df_print_regset (file, bb_info->def);
}
@@ -1830,7 +1830,7 @@ df_lr_bottom_dump (basic_block bb, FILE
if (!bb_info || !bb_info->out)
return;
- fprintf (file, "lr out \t");
+ fprintf (file, ";; lr out \t");
df_print_regset (file, bb_info->out);
}
@@ -2141,11 +2141,11 @@ df_ur_top_dump (basic_block bb, FILE *fi
if (!bb_info || !bb_info->in)
return;
- fprintf (file, "ur in \t");
+ fprintf (file, ";; ur in \t");
df_print_regset (file, bb_info->in);
- fprintf (file, "ur gen \t");
+ fprintf (file, ";; ur gen \t");
df_print_regset (file, bb_info->gen);
- fprintf (file, "ur kill\t");
+ fprintf (file, ";; ur kill\t");
df_print_regset (file, bb_info->kill);
}
@@ -2159,7 +2159,7 @@ df_ur_bottom_dump (basic_block bb, FILE
if (!bb_info || !bb_info->out)
return;
- fprintf (file, "ur out \t");
+ fprintf (file, ";; ur out \t");
df_print_regset (file, bb_info->out);
}
@@ -2338,7 +2338,7 @@ df_live_top_dump (basic_block bb, FILE *
if (!bb_info || !bb_info->in)
return;
- fprintf (file, "live in \t");
+ fprintf (file, ";; live in \t");
df_print_regset (file, bb_info->in);
}
@@ -2352,7 +2352,7 @@ df_live_bottom_dump (basic_block bb, FIL
if (!bb_info || !bb_info->out)
return;
- fprintf (file, "live out \t");
+ fprintf (file, ";; live out \t");
df_print_regset (file, bb_info->out);
}
@@ -2949,13 +2949,13 @@ df_urec_top_dump (basic_block bb, FILE *
if (!bb_info || !bb_info->in)
return;
- fprintf (file, "urec in \t");
+ fprintf (file, ";; urec in \t");
df_print_regset (file, bb_info->in);
- fprintf (file, "urec gen \t");
+ fprintf (file, ";; urec gen \t");
df_print_regset (file, bb_info->gen);
- fprintf (file, "urec kill\t");
+ fprintf (file, ";; urec kill\t");
df_print_regset (file, bb_info->kill);
- fprintf (file, "urec ec\t");
+ fprintf (file, ";; urec ec\t");
df_print_regset (file, bb_info->earlyclobber);
}
@@ -2968,7 +2968,7 @@ df_urec_bottom_dump (basic_block bb, FIL
struct df_urec_bb_info *bb_info = df_urec_get_bb_info (bb->index);
if (!bb_info || !bb_info->out)
return;
- fprintf (file, "urec out \t");
+ fprintf (file, ";; urec out \t");
df_print_regset (file, bb_info->out);
}
@@ -3334,13 +3334,13 @@ df_chain_start_dump (FILE *file)
if (df_chain_problem_p (DF_DU_CHAIN))
{
- fprintf (file, "Def-use chains:\n");
+ fprintf (file, ";; Def-use chains:\n");
for (j = 0; j < DF_DEFS_TABLE_SIZE (); j++)
{
struct df_ref *def = DF_DEFS_GET (j);
if (def)
{
- fprintf (file, "d%d bb %d luid %d insn %d reg %d ",
+ fprintf (file, ";; d%d bb %d luid %d insn %d reg %d ",
j, DF_REF_BBNO (def),
DF_REF_INSN (def) ?
DF_INSN_LUID (DF_REF_INSN (def)):
@@ -3357,13 +3357,13 @@ df_chain_start_dump (FILE *file)
if (df_chain_problem_p (DF_UD_CHAIN))
{
- fprintf (file, "Use-def chains:\n");
+ fprintf (file, ";; Use-def chains:\n");
for (j = 0; j < DF_USES_TABLE_SIZE (); j++)
{
struct df_ref *use = DF_USES_GET (j);
if (use)
{
- fprintf (file, "u%d bb %d luid %d insn %d reg %d ",
+ fprintf (file, ";; u%d bb %d luid %d insn %d reg %d ",
j, DF_REF_BBNO (use),
DF_REF_INSN (use) ?
DF_INSN_LUID (DF_REF_INSN (use))
@@ -4127,7 +4127,7 @@ df_ri_start_dump (FILE *file)
{
if (df_ri_problem_p (DF_RI_LIFE))
{
- fprintf (file, "Register info:\n");
+ fprintf (file, ";; Register info:\n");
dump_reg_info (file);
}
}
Index: dce.c
===================================================================
--- dce.c (revision 120099)
+++ dce.c (working copy)
@@ -54,7 +54,6 @@ static bool something_changed;
static VEC(rtx,heap) *worklist;
static bitmap marked = NULL;
-static bitmap marked_libcalls = NULL;
/* Return true if INSN a normal instruction that can be deleted by the
DCE pass. */
@@ -165,31 +164,6 @@ mark_nonreg_stores (rtx body, rtx insn,
}
-/* Go through the instructions and mark those whose necessity is not
- dependent on inter-instruction information. Make sure all other
- instructions are not marked. */
-
-static void
-prescan_insns_for_dce (void)
-{
- basic_block bb;
- rtx insn;
-
- if (dump_file)
- fprintf (dump_file, "Finding needed instructions:\n");
-
- FOR_EACH_BB (bb)
- FOR_BB_INSNS (bb, insn)
- if (INSN_P (insn))
- {
- if (deletable_insn_p (insn))
- mark_nonreg_stores (PATTERN (insn), insn, true);
- else
- mark_insn (insn, true);
- }
-}
-
-
/* Initialize global variables for a new DCE pass. */
static void
@@ -206,7 +180,6 @@ init_dce (bool fast)
df_dump (dump_file);
marked = BITMAP_ALLOC (NULL);
- marked_libcalls = BITMAP_ALLOC (NULL);
}
@@ -269,18 +242,6 @@ delete_unmarked_insns (void)
}
-/* Return true if INSN has libcall id ID. */
-static bool
-libcall_matches_p (rtx insn, int id)
-{
- rtx note;
- if ((note = find_reg_note (insn, REG_LIBCALL_ID, NULL_RTX)))
- return id == INTVAL (XEXP (note, 0));
- else
- return false;
-}
-
-
/* Mark all insns using DELETE_PARM in the libcall that contains
START_INSN. */
static void
@@ -293,12 +254,24 @@ mark_libcall (rtx start_insn, bool delet
mark_insn (start_insn, delete_parm);
insn = NEXT_INSN (start_insn);
+ /* There are tales, long ago and far away, of the mystical nested
+ libcall. No one alive has actually seen one, but other parts of
+ the compiler support them so we will here. */
for (insn = NEXT_INSN (start_insn); insn; insn = NEXT_INSN (insn))
{
if (INSN_P (insn))
{
- if (libcall_matches_p (insn, id))
- mark_insn (insn, delete_parm);
+ /* Stay in the loop as long as we are in any libcall. */
+ if ((note = find_reg_note (insn, REG_LIBCALL_ID, NULL_RTX)))
+ {
+ if (id == INTVAL (XEXP (note, 0)))
+ {
+ mark_insn (insn, delete_parm);
+ if (dump_file)
+ fprintf (dump_file, "matching forward libcall %d[%d]\n",
+ INSN_UID (insn), id);
+ }
+ }
else
break;
}
@@ -308,8 +281,17 @@ mark_libcall (rtx start_insn, bool delet
{
if (INSN_P (insn))
{
- if (libcall_matches_p (insn, id))
- mark_insn (insn, delete_parm);
+ /* Stay in the loop as long as we are in any libcall. */
+ if ((note = find_reg_note (insn, REG_LIBCALL_ID, NULL_RTX)))
+ {
+ if (id == INTVAL (XEXP (note, 0)))
+ {
+ mark_insn (insn, delete_parm);
+ if (dump_file)
+ fprintf (dump_file, "matching backward libcall %d[%d]\n",
+ INSN_UID (insn), id);
+ }
+ }
else
break;
}
@@ -317,13 +299,46 @@ mark_libcall (rtx start_insn, bool delet
}
+/* Go through the instructions and mark those whose necessity is not
+ dependent on inter-instruction information. Make sure all other
+ instructions are not marked. */
+
+static void
+prescan_insns_for_dce (void)
+{
+ basic_block bb;
+ rtx insn;
+
+ if (dump_file)
+ fprintf (dump_file, "Finding needed instructions:\n");
+
+ FOR_EACH_BB (bb)
+ FOR_BB_INSNS (bb, insn)
+ if (INSN_P (insn))
+ {
+ if (deletable_insn_p (insn))
+ mark_nonreg_stores (PATTERN (insn), insn, true);
+ else
+ {
+ rtx note = find_reg_note (insn, REG_LIBCALL_ID, NULL_RTX);
+ if (note)
+ mark_libcall (insn, true);
+ else
+ mark_insn (insn, true);
+ }
+ }
+
+ if (dump_file)
+ fprintf (dump_file, "Finished finding needed instructions:\n");
+}
+
+
/* Free the data allocated by init_dce. */
static void
end_dce (void)
{
BITMAP_FREE (marked);
- BITMAP_FREE (marked_libcalls);
df_in_progress = false;
}
@@ -388,7 +403,6 @@ static void
end_fast_dce (void)
{
BITMAP_FREE (marked);
- BITMAP_FREE (marked_libcalls);
df_in_progress = false;
}
@@ -404,8 +418,6 @@ dce_process_block (basic_block bb, bool
bool block_changed;
struct df_ref *def, *use;
unsigned int bb_index = bb->index;
- rtx libcall_start = NULL;
- int libcall_id = -1;
if (redo_out)
{
@@ -441,29 +453,7 @@ dce_process_block (basic_block bb, bool
if (!marked_insn_p (insn))
{
bool needed = false;
- rtx note;
- if ((note = find_reg_note (insn, REG_LIBCALL_ID, NULL_RTX)))
- {
- int new_id = INTVAL (XEXP (note, 0));
- if (libcall_start)
- {
- if (libcall_id != new_id)
- {
- libcall_start = insn;
- libcall_id = new_id;
- }
- }
- else
- {
- libcall_start = insn;
- libcall_id = new_id;
- }
- }
- else
- {
- libcall_start = NULL;
- libcall_id = -1;
- }
+
for (def = DF_INSN_DEFS (insn);
def; def = def->next_ref)
if (bitmap_bit_p (local_live, DF_REF_REGNO (def)))
@@ -474,14 +464,18 @@ dce_process_block (basic_block bb, bool
if (needed)
{
+ rtx note = find_reg_note (insn, REG_LIBCALL_ID, NULL_RTX);
+
/* If we need to mark an insn in the middle of a
libcall, we need to back up to mark the entire
libcall. Given that libcalls are rare, rescanning
the block should be a reasonable solution to trying
to figure out how to back up. */
- if (libcall_start)
+ if (note)
{
- mark_libcall (libcall_start, true);
+ if (dump_file)
+ fprintf (dump_file, "needed libcall %d\n", INSN_UID (insn));
+ mark_libcall (insn, true);
BITMAP_FREE (local_live);
return dce_process_block (bb, false);
}
@@ -654,7 +648,6 @@ run_fast_df_dce (void)
init_dce (true);
fast_dce ();
BITMAP_FREE (marked);
- BITMAP_FREE (marked_libcalls);
df_in_progress = false;
}
@@ -1619,7 +1612,13 @@ prescan_insns_for_dse (void)
if (INSN_P (insn))
{
if (!deletable_insn_p (insn))
- mark_insn (insn, false);
+ {
+ rtx note = find_reg_note (insn, REG_LIBCALL_ID, NULL_RTX);
+ if (note)
+ mark_libcall (insn, false);
+ else
+ mark_insn (insn, false);
+ }
else
record_stores (insn);
}