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

Reply via email to