This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] Use tablejump_p in cfgcleanup.c/merge_blocks_move_successor_nojumps()


> > http://gcc.gnu.org/ml/gcc-patches/2003-07/msg00800.html
> > (Fix latent bug in cfgcleanup.c)
> 
> Please rewrite this section of code to use tablejump_p.

This patch uses tablejump_p in merge_blocks_move_successor_nojumps.
I have also updated tablejump_p () (mainline version written by me)
to be similar to the 3.3 branch version (written by Richard Henderson).

Bootstrapped/regtested i686.

OK for mainline?

Josef

2003-07-20  Josef Zlomek  <zlomekj@suse.cz>

	* cfgcleanup.c (merge_blocks_move_successor_nojumps): Use tablejump_p.
	* rtlanal.c (tablejump_p): Use next_active_insn for finding the jump
	table.

Index: cfgcleanup.c
===================================================================
RCS file: /cvs/gcc-cvs/gcc/gcc/cfgcleanup.c,v
retrieving revision 1.88
diff -c -3 -p -r1.88 cfgcleanup.c
*** cfgcleanup.c	5 Jul 2003 15:17:26 -0000	1.88
--- cfgcleanup.c	19 Jul 2003 16:45:07 -0000
*************** static void
*** 714,738 ****
  merge_blocks_move_successor_nojumps (basic_block a, basic_block b)
  {
    rtx barrier, real_b_end;
  
    real_b_end = b->end;
-   barrier = NEXT_INSN (b->end);
  
!   /* Recognize a jump table following block B.  */
!   if (barrier
!       && GET_CODE (barrier) == CODE_LABEL
!       && NEXT_INSN (barrier)
!       && GET_CODE (NEXT_INSN (barrier)) == JUMP_INSN
!       && (GET_CODE (PATTERN (NEXT_INSN (barrier))) == ADDR_VEC
! 	  || GET_CODE (PATTERN (NEXT_INSN (barrier))) == ADDR_DIFF_VEC))
      {
!       /* Temporarily add the table jump insn to b, so that it will also
! 	 be moved to the correct location.  */
!       b->end = NEXT_INSN (barrier);
!       barrier = NEXT_INSN (b->end);
      }
  
    /* There had better have been a barrier there.  Delete it.  */
    if (barrier && GET_CODE (barrier) == BARRIER)
      delete_insn (barrier);
 
--- 714,733 ----
  merge_blocks_move_successor_nojumps (basic_block a, basic_block b)
  {
    rtx barrier, real_b_end;
+   rtx label, table;
  
    real_b_end = b->end;
  
!   /* If there is a jump table following block B temporarily add the jump table
!      to block B so that it will also be moved to the correct location.  */
!   if (tablejump_p (b->end, &label, &table)
!       && prev_active_insn (label) == b->end)
      {
!       b->end = table;
      }
  
    /* There had better have been a barrier there.  Delete it.  */
+   barrier = NEXT_INSN (b->end);
    if (barrier && GET_CODE (barrier) == BARRIER)
      delete_insn (barrier);
  
Index: rtlanal.c
===================================================================
RCS file: /cvs/gcc-cvs/gcc/gcc/rtlanal.c,v
retrieving revision 1.165
diff -c -3 -p -r1.165 rtlanal.c
*** rtlanal.c	6 Jul 2003 09:56:08 -0000	1.165
--- rtlanal.c	19 Jul 2003 16:29:49 -0000
*************** rtx_referenced_p (rtx x, rtx body)
*** 2795,2820 ****
    return for_each_rtx (&body, rtx_referenced_p_1, x);
  }
  
! /* If INSN is a jump to jumptable insn rturn true and store the label (which
!    INSN jumps to) to *LABEL and the tablejump insn to *TABLE.
!    LABEL and TABLE may be NULL.  */
  
  bool
! tablejump_p (rtx insn, rtx *label, rtx *table)
  {
!   rtx l, t;
  
!   if (onlyjump_p (insn)
!       && (l = JUMP_LABEL (insn)) != NULL_RTX
!       && (t = NEXT_INSN (l)) != NULL_RTX
!       && GET_CODE (t) == JUMP_INSN
!       && (GET_CODE (PATTERN (t)) == ADDR_VEC
! 	  || GET_CODE (PATTERN (t)) == ADDR_DIFF_VEC))
      {
!       if (label)
! 	*label = l;
!       if (table)
! 	*table = t;
        return true;
      }
    return false;
--- 2795,2819 ----
    return for_each_rtx (&body, rtx_referenced_p_1, x);
  }
  
! /* If INSN is a tablejump return true and store the label (before jump table) to
!    *LABELP and the jump table to *TABLEP.  LABELP and TABLEP may be NULL.  */
  
  bool
! tablejump_p (rtx insn, rtx *labelp, rtx *tablep)
  {
!   rtx label, table;
  
!   if (GET_CODE (insn) == JUMP_INSN
!       && (label = JUMP_LABEL (insn)) != NULL_RTX
!       && (table = next_active_insn (label)) != NULL_RTX
!       && GET_CODE (table) == JUMP_INSN
!       && (GET_CODE (PATTERN (table)) == ADDR_VEC
! 	  || GET_CODE (PATTERN (table)) == ADDR_DIFF_VEC))
      {
!       if (labelp)
! 	*labelp = label;
!       if (tablep)
! 	*tablep = table;
        return true;
      }
    return false;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]