-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Updated based on some comments from Bernd; specifically the other use of
delete_dead_insn has been removed.

WRT the assembly differences on MIPS Bernd referred to; what ultimately
caused this problem were two dead insns that had been previously
eliminated by reload were still in the insn stream and inhibited an
if-conversion which resulted in slightly different assembly code, but
shouldn't have had any significant impact on the performance or size of
the resulting code.  The dead insns were deleted by the post-reload DCE
pass (which obviously runs after post-reload if conversion).

If we really wanted to get those insns out of the stream, we could flag
when reload deleted insns which might result in dead code remaining in
the stream, then conditionally run DCE immediately after reload.  I
didn't think this was worth doing right now, but if someone objects I
can certainly look into it.

Bootstrapped and regression tested on x86_64-unknown-linux-gnu.

Jeff
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/

iQEcBAEBAgAGBQJN3+RCAAoJEBRtltQi2kC7qUMH/3Z8NB8bogEnVvS7qF6eubu0
UNWp2HzJ/QnvxgKQiJUBar/kOF3y20kl2oZpqIoPVea2TqmeZ/lfuS1+lzWWxC/t
HGvjBWfkA60DkcDxFmHn0TadoqL11eAWEzsRRf/HfEn6I3rnrO3vP0RR3X8Dtiqe
qeFf8HVY8ysQoaFTyaiMLLo7yePmvlVy+HTsg+s3F0Yvg18P2WoJjpM/EY2y/tUR
QmIcFi8q4Q92YsfBpjweY6NyqepKrATAZT+CcFdc7GFvfa5TZQj9gGhWqPHiHQ5w
3c8RmKbaGEWhPSjIgmcqtY/FpY2CoRDn2BMosr8N4F0FMN2PkQlU8E7hTE2V6eM=
=UeKy
-----END PGP SIGNATURE-----
        PR middle-end/48770
        * ira.c (update_equiv_regs): Update comment.
        * reload1.c (reload): Don't call delete_dead_insn to delete
        insns which create equivalences.
        (eliminate_regs_in_insn): Likewise.
        (delete_dead_insn): Remove.

        PR middle-end/48770
        * gcc.dg/pr48770.c: New test.

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 174066)
--- ira.c       (working copy)
*************** update_equiv_regs (void)
*** 2842,2848 ****
             If we don't have a REG_EQUIV note, see if this insn is loading
             a register used only in one basic block from a MEM.  If so, and the
             MEM remains unchanged for the life of the register, add a REG_EQUIV
!            note.  */
  
          note = find_reg_note (insn, REG_EQUIV, NULL_RTX);
  
--- 2842,2848 ----
             If we don't have a REG_EQUIV note, see if this insn is loading
             a register used only in one basic block from a MEM.  If so, and the
             MEM remains unchanged for the life of the register, add a REG_EQUIV
!            note, this creates a block local equivalence.  */
  
          note = find_reg_note (insn, REG_EQUIV, NULL_RTX);
  
Index: reload1.c
===================================================================
*** reload1.c   (revision 174066)
--- reload1.c   (working copy)
*************** static void delete_caller_save_insns (vo
*** 356,362 ****
  
  static void spill_failure (rtx, enum reg_class);
  static void count_spilled_pseudo (int, int, int);
- static void delete_dead_insn (rtx);
  static void alter_reg (int, int, bool);
  static void set_label_offsets (rtx, rtx, int);
  static void check_eliminable_occurrences (rtx);
--- 356,361 ----
*************** reload (rtx first, int global)
*** 1011,1021 ****
        mark_elimination (ep->from, ep->to);
  
    /* If a pseudo has no hard reg, delete the insns that made the equivalence.
!      If that insn didn't set the register (i.e., it copied the register to
!      memory), just delete that insn instead of the equivalencing insn plus
!      anything now dead.  If we call delete_dead_insn on that insn, we may
!      delete the insn that actually sets the register if the register dies
!      there and that is incorrect.  */
  
    for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
      {
--- 1010,1024 ----
        mark_elimination (ep->from, ep->to);
  
    /* If a pseudo has no hard reg, delete the insns that made the equivalence.
!      We used to recursively delete anything else now dead.  That is incorrect
!      if that insn didn't set the register (i.e., it copied the register to
!      memory); it is also incorrect for a block local equivalence as the memory
!      address may refer to another pseudo which still needs proper
!      initialization. 
! 
!      That code predated running dead code elimination after reload, so rather
!      that trying to identify all the dead code here (and get it wrong), just
!      delete the equivalencing insn and let DCE do its job.  */
  
    for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
      {
*************** reload (rtx first, int global)
*** 1034,1041 ****
              if (NOTE_P (equiv_insn)
                  || can_throw_internal (equiv_insn))
                ;
-             else if (reg_set_p (regno_reg_rtx[i], PATTERN (equiv_insn)))
-               delete_dead_insn (equiv_insn);
              else
                SET_INSN_DELETED (equiv_insn);
            }
--- 1037,1042 ----
*************** spill_failure (rtx insn, enum reg_class 
*** 2114,2140 ****
      }
  }
  
- /* Delete an unneeded INSN and any previous insns who sole purpose is loading
-    data that is dead in INSN.  */
- 
- static void
- 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 (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);
- }
- 
  /* Modify the home of pseudo-reg I.
     The new home is present in reg_renumber[I].
  
--- 2115,2120 ----
*************** eliminate_regs_in_insn (rtx insn, int re
*** 3319,3325 ****
               process it since it won't be used unless something changes.  */
            if (replace)
              {
!               delete_dead_insn (insn);
                return 1;
              }
            val = 1;
--- 3299,3305 ----
               process it since it won't be used unless something changes.  */
            if (replace)
              {
!               SET_INSN_DELETED (insn);
                return 1;
              }
            val = 1;

Reply via email to