-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
This version incorporates suggestions from Bernd. Basically we have
reload1.c set reload_completed internally rather than deferring it into
ira.c. That allows the call to reload() to return whether or not a DCE
pass is desirable at the end of reload.
That in turn allows us to avoid the DF clumsiness of the previous version.
Bootstrapped and regression tested on x86_64-unknown-linux-gnu.
Bernd is still seeing some differences on mips64-linux; I've been unable
to reproduce those. Bernd, if you can send me the dump files privately,
I'm more than happy to take a look at any remaining codegen differences
this patch is triggering.
Thanks,
Jeff
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/
iQEcBAEBAgAGBQJN938LAAoJEBRtltQi2kC7JxIH/jexv1Wx3RZkba8fgBMbrYYg
QLPv273smckcvITNaOdMKSRRbq/8x+hiGI4VClYX3z1tGrlIaDf+n0S/mOGmMDc3
yjxeXRBf0F8QPmkt+QG+Ck6TH3+ya2OOWmP6/RNCBQdaf7ViVuBI+IlGzhEia1OH
YL+3yDTfLpAgJ9BYTpaIB8o9m/cAAx0Rfnwgx9gcQzFGSPgEep1tg+gnxoyMbvGX
IohygwiMkU27JLokeanowL9d2H7L0kYMX1S0biDOdlm1wLI9n3JfLO9PPF0SLv8A
EESCaRmeJRH93wlNLb5qpacESgQOc6B6++zCjf1W22/GVcZIe9WKaOuxKtsoU/I=
=ZEQd
-----END PGP SIGNATURE-----
PR middle-end/48770
* reload.h (reload): Change to return a bool.
* ira.c (ira): If requested by reload, run a fast DCE pass after
reload has completed. Fix comment typo.
* reload1.c (need_dce): New file scoped static.
(reload): Set reload_completed here. Return whether or not a DCE
pass after reload is needed.
(delete_dead_insn): Set need_dce as needed.
PR middle-end/48770
* gcc.dg/pr48770.c: New test.
Index: reload.h
===================================================================
*** reload.h (revision 174696)
--- reload.h (working copy)
*************** extern void reload_cse_regs (rtx);
*** 420,426 ****
extern void init_reload (void);
/* The reload pass itself. */
! extern int reload (rtx, int);
/* Mark the slots in regs_ever_live for the hard regs
used by pseudo-reg number REGNO. */
--- 420,426 ----
extern void init_reload (void);
/* The reload pass itself. */
! extern bool reload (rtx, int);
/* Mark the slots in regs_ever_live for the hard regs
used by pseudo-reg number REGNO. */
Index: testsuite/gcc.dg/pr48770.c
===================================================================
*** testsuite/gcc.dg/pr48770.c (revision 0)
--- testsuite/gcc.dg/pr48770.c (revision 0)
***************
*** 0 ****
--- 1,21 ----
+ /* { dg-do run } */
+ /* { dg-options "-O -fprofile-arcs -fPIC -fno-dce -fno-forward-propagate" } */
+
+ int test_goto2 (int f)
+ {
+ int i;
+ for (i = 0; ({_Bool a = i < 10;a;}); i++)
+ {
+ if (i == f)
+ goto lab2;
+ }
+ return 4;
+ lab2:
+ return 8;
+ }
+
+ int main ()
+ {
+ test_goto2 (30);
+ return 0;
+ }
Index: ira.c
===================================================================
*** ira.c (revision 174759)
--- ira.c (working copy)
*************** along with GCC; see the file COPYING3.
*** 383,388 ****
--- 383,389 ----
#include "integrate.h"
#include "ggc.h"
#include "ira-int.h"
+ #include "dce.h"
struct target_ira default_target_ira;
*************** ira (FILE *f)
*** 3526,3531 ****
--- 3527,3533 ----
int rebuild_p;
int saved_flag_ira_share_spill_slots;
basic_block bb;
+ bool need_dce;
timevar_push (TV_IRA);
*************** ira (FILE *f)
*** 3717,3723 ****
df_set_flags (DF_NO_INSN_RESCAN);
build_insn_chain ();
! reload_completed = !reload (get_insns (), ira_conflicts_p);
timevar_pop (TV_RELOAD);
--- 3719,3725 ----
df_set_flags (DF_NO_INSN_RESCAN);
build_insn_chain ();
! need_dce = reload (get_insns (), ira_conflicts_p);
timevar_pop (TV_RELOAD);
*************** ira (FILE *f)
*** 3760,3766 ****
#endif
/* The code after the reload has changed so much that at this point
! we might as well just rescan everything. Not that
df_rescan_all_insns is not going to help here because it does not
touch the artificial uses and defs. */
df_finish_pass (true);
--- 3762,3768 ----
#endif
/* The code after the reload has changed so much that at this point
! we might as well just rescan everything. Note that
df_rescan_all_insns is not going to help here because it does not
touch the artificial uses and defs. */
df_finish_pass (true);
*************** ira (FILE *f)
*** 3772,3777 ****
--- 3774,3782 ----
if (optimize)
df_analyze ();
+ if (need_dce && optimize)
+ run_fast_dce ();
+
timevar_pop (TV_IRA);
}
Index: reload1.c
===================================================================
*** reload1.c (revision 174759)
--- reload1.c (working copy)
*************** static char *reload_insn_firstobj;
*** 250,255 ****
--- 250,259 ----
examine. */
struct insn_chain *reload_insn_chain;
+ /* TRUE if we potentially left dead insns in the insn stream and want to
+ run DCE immediately after reload, FALSE otherwise. */
+ static bool need_dce;
+
/* List of all insns needing reloads. */
static struct insn_chain *insns_need_reload;
*************** static int *temp_pseudo_reg_arr;
*** 695,704 ****
If GLOBAL is zero, we do not have enough information to do that,
so any pseudo reg that is spilled must go to the stack.
! Return value is nonzero if reload failed
! and we must not do any more for this function. */
! int
reload (rtx first, int global)
{
int i, n;
--- 699,709 ----
If GLOBAL is zero, we do not have enough information to do that,
so any pseudo reg that is spilled must go to the stack.
! Return value is TRUE if reload likely left dead insns in the
! stream and a DCE pass should be run to elimiante them. Else the
! return value is FALSE. */
! bool
reload (rtx first, int global)
{
int i, n;
*************** reload (rtx first, int global)
*** 1329,1335 ****
gcc_assert (bitmap_empty_p (&spilled_pseudos));
! return failure;
}
/* Yet another special case. Unfortunately, reg-stack forces people to
--- 1334,1342 ----
gcc_assert (bitmap_empty_p (&spilled_pseudos));
! reload_completed = !failure;
!
! return need_dce;
}
/* Yet another special case. Unfortunately, reg-stack forces people to
*************** delete_dead_insn (rtx insn)
*** 2123,2136 ****
rtx prev = prev_active_insn (insn);
rtx prev_dest;
! /* If the previous insn sets a register that dies in our insn, delete it
! too. */
if (prev && GET_CODE (PATTERN (prev)) == SET
&& (prev_dest = SET_DEST (PATTERN (prev)), REG_P (prev_dest))
&& reg_mentioned_p (prev_dest, PATTERN (insn))
&& find_regno_note (insn, REG_DEAD, REGNO (prev_dest))
&& ! side_effects_p (SET_SRC (PATTERN (prev))))
! delete_dead_insn (prev);
SET_INSN_DELETED (insn);
}
--- 2130,2148 ----
rtx prev = prev_active_insn (insn);
rtx prev_dest;
! /* If the previous insn sets a register that dies in our insn make
! a note that we want to run DCE immediately after reload.
!
! We used to delete the previous insn & recurse, but that's wrong for
! block local equivalences. Instead of trying to figure out the exact
! circumstances where we can delete the potentially dead insns, just
! let DCE do the job. */
if (prev && GET_CODE (PATTERN (prev)) == SET
&& (prev_dest = SET_DEST (PATTERN (prev)), REG_P (prev_dest))
&& reg_mentioned_p (prev_dest, PATTERN (insn))
&& find_regno_note (insn, REG_DEAD, REGNO (prev_dest))
&& ! side_effects_p (SET_SRC (PATTERN (prev))))
! need_dce = 1;
SET_INSN_DELETED (insn);
}