re PR middle-end/48770 (wrong code with -O -fprofile-arcs -fPIC -fno-dce -fno-forward...
authorJeff Law <law@redhat.com>
Thu, 23 Jun 2011 21:30:20 +0000 (15:30 -0600)
committerJeff Law <law@gcc.gnu.org>
Thu, 23 Jun 2011 21:30:20 +0000 (15:30 -0600)
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.

From-SVN: r175353

gcc/ChangeLog
gcc/ira.c
gcc/reload.h
gcc/reload1.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr48770.c [new file with mode: 0644]

index a0758e1dc957bcc53ee16ecd105792595564f6a6..6c6617b3c8f1ed8d621e483a290774adec5dc95d 100644 (file)
@@ -1,5 +1,14 @@
 2011-06-23  Jeff Law  <law@redhat.com>
 
+       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/49465
        * tree-ssa-threadupate.c (fix_duplicate_block_edges): Fix condition
        to detect threading through joiner block.  If there was already
index 5cfe5c0fa6b5878de7d0a52b1a934e8c84c678f3..6cca90807dfbe32a6cba3c9d480118f2a36e76ea 100644 (file)
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -383,6 +383,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "integrate.h"
 #include "ggc.h"
 #include "ira-int.h"
+#include "dce.h"
 
 
 struct target_ira default_target_ira;
@@ -3526,6 +3527,7 @@ ira (FILE *f)
   int rebuild_p;
   int saved_flag_ira_share_spill_slots;
   basic_block bb;
+  bool need_dce;
 
   timevar_push (TV_IRA);
 
@@ -3717,7 +3719,7 @@ ira (FILE *f)
   df_set_flags (DF_NO_INSN_RESCAN);
   build_insn_chain ();
 
-  reload_completed = !reload (get_insns (), ira_conflicts_p);
+  need_dce = reload (get_insns (), ira_conflicts_p);
 
   timevar_pop (TV_RELOAD);
 
@@ -3760,7 +3762,7 @@ ira (FILE *f)
 #endif
 
   /* The code after the reload has changed so much that at this point
-     we might as well just rescan everything.  Not that
+     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);
@@ -3772,6 +3774,9 @@ ira (FILE *f)
   if (optimize)
     df_analyze ();
 
+  if (need_dce && optimize)
+    run_fast_dce ();
+
   timevar_pop (TV_IRA);
 }
 
index c9df112b2d02490b5bd8eb7091a4e6e91d07ea35..ad0cfcd82d8de59393a5014238cc03b2ce07ee23 100644 (file)
@@ -420,7 +420,7 @@ extern void reload_cse_regs (rtx);
 extern void init_reload (void);
 
 /* The reload pass itself.  */
-extern int reload (rtx, int);
+extern bool reload (rtx, int);
 
 /* Mark the slots in regs_ever_live for the hard regs
    used by pseudo-reg number REGNO.  */
index a87e6ad08d6f9ba6eb9c3e6d043ceca2d0b688e4..a9aa01723eee60447efb5fca6de678c290b88dd5 100644 (file)
@@ -250,6 +250,10 @@ static char *reload_insn_firstobj;
    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;
 \f
@@ -695,10 +699,11 @@ static int *temp_pseudo_reg_arr;
    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.  */
+   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.  */
 
-int
+bool
 reload (rtx first, int global)
 {
   int i, n;
@@ -1329,7 +1334,9 @@ reload (rtx first, int global)
 
   gcc_assert (bitmap_empty_p (&spilled_pseudos));
 
-  return failure;
+  reload_completed = !failure;
+
+  return need_dce;
 }
 
 /* Yet another special case.  Unfortunately, reg-stack forces people to
@@ -2123,14 +2130,19 @@ delete_dead_insn (rtx insn)
   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 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))))
-    delete_dead_insn (prev);
+    need_dce = 1;
 
   SET_INSN_DELETED (insn);
 }
index b622eb3e421b309d58d21e935b08d3503fc035a0..c3e0f0e3ba858d6f154915699f9b0c64b389e313 100644 (file)
@@ -1,3 +1,8 @@
+2011-06-23  Jeff Law <law@redhat.com>
+
+       PR middle-end/48770
+       * gcc.dg/pr48770.c: New test.
+
 2011-06-23  Jan Hubicka  <jh@suse.cz>
 
        PR middle-end/49373
diff --git a/gcc/testsuite/gcc.dg/pr48770.c b/gcc/testsuite/gcc.dg/pr48770.c
new file mode 100644 (file)
index 0000000..d0b8554
--- /dev/null
@@ -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;
+}