-----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); }