[Committed] Delete multiple barriers after BB in rtl_delete_block

Roger Sayle roger@eyesopen.com
Thu Jan 6 18:06:00 GMT 2005


The following patch fixes the latent bug in rtl_delete_block that caused
a bootstrap failure on ia64-unknown-linux-gnu with by recent patch to
avoid empty blocks in ifcvt.c.

To quote the comment above the function cleanup_barriers in jump.c:

>  /* Some old code expects exactly one BARRIER as the NEXT_INSN of a
>     non-fallthru insn.  This is not generally true, as multiple barriers
>     may have crept in, or the BARRIER may be separated from the last
>     real insn by one or more NOTEs.
>
>     This simple pass moves barriers and removes duplicates so that the
>     old code is happy.  */

It turns out that the function rtl_delete_block in cfgrtl.c suffers from
the same flaw as the "old code" mentioned above, and assumes that basic
blocks are followed by exactly one BARRIER.  The fix below is to simply
loop over all of the barriers following a basic block when deleting it.

I also quickly investigated whether I could avoid the double barriers
on ia64-unknown-linux-gnu in the first place, but by a strange recursive
twist of fate, it looks as though the double barrier generated in flow2
is caused by rtl_delete_block not removing all the barriers following a
basic block!  Slightly amused by this, I didn't bother investigating
further where the even earlier double barrier came from.

The following patch has been tested on both i686-pc-linux-gnu and
ia64-unknown-linux-gnu with a full "make bootstrap", all default
languages, and regression tested with a top-level "make -k check"
with no new failures.

Committed to mainline CVS.



2005-01-06  Roger Sayle  <roger@eyesopen.com>

	* cfgrtl.c (rtl_delete_block): A basic block may be followed by
	more than one barrier, in which case we should delete them all.


Index: cfgrtl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cfgrtl.c,v
retrieving revision 1.156
diff -c -3 -p -r1.156 cfgrtl.c
*** cfgrtl.c	3 Dec 2004 07:43:39 -0000	1.156
--- cfgrtl.c	6 Jan 2005 04:08:11 -0000
*************** rtl_delete_block (basic_block b)
*** 379,388 ****
    if (tablejump_p (end, NULL, &tmp))
      end = tmp;

!   /* Include any barrier that may follow the basic block.  */
    tmp = next_nonnote_insn (end);
!   if (tmp && BARRIER_P (tmp))
!     end = tmp;

    /* Selectively delete the entire chain.  */
    BB_HEAD (b) = NULL;
--- 379,391 ----
    if (tablejump_p (end, NULL, &tmp))
      end = tmp;

!   /* Include any barriers that may follow the basic block.  */
    tmp = next_nonnote_insn (end);
!   while (tmp && BARRIER_P (tmp))
!     {
!       end = tmp;
!       tmp = next_nonnote_insn (end);
!     }

    /* Selectively delete the entire chain.  */
    BB_HEAD (b) = NULL;


Roger
--



More information about the Gcc-patches mailing list