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] REG_EQUAL notes on cond_jumps.


The following patch fixes the failure of 20010119-1.c on both
H8300 and PA.  Its a correction and enchancement of Kazu Hirata's
patch http://gcc.gnu.org/ml/gcc-patches/2003-02/msg00144.html

The theory is to make more effective use of REG_EQUAL notes in GCSE.
As in the original patch, we make use of any REG_EQUAL note attached
to the condition code setting instruction.  However, we now ignore
notes that contain EXPR_LISTs, i.e. those attached to the RETVAL
instruction of a libcall, that caused the failures with the original
patch.  Additionally, we now also attach and re-use REG_EQUAL notes
to the cond_jump instruction itself.  This provides a form of
mid-level RTL where the optimizers may operate on conditional
branches free from the restrictions of the machine modes and
patterns provided by the back-end.

For example, pa.md doesn't support comparison with large immediate
constants in a single instruction.  As a result code such as the
following (reduced from 20010119-1.c) was failing to be optimized:

void foo()
{
  int a = 10;
  int b = 20000;
  if (a > b)
    link_error();
}


The following patch has been tested by complete bootstraps, all
languages except Ada and treelang, on both i686-pc-linux-gnu and
hppa2.0w-hp-hpux11.00, and a full testsuite run with no new
regressions, and 12 less failures on HP-UX.  It should be pointed
out that PA/HP-UX was one of the targets showing libcall related
failures from Kazu's original patch.  Additionally, I'd like to
thank Kazu for running this patch of H8, where he reports it fixes
20010119-1.c with no new regressions.

Ok for mainline?


2003-03-09  Roger Sayle  <roger at eyesopen dot com>
	    Kazu Hirata <kazu at cs dot umass dot edu>

	* gcse.c (cprop_jump):  Make use of REG_EQUAL notes on both
	setcc and jump, if they exist.  If substituted instruction
	fails to validate, store current effort in a REG_EQUAL note.
	(cprop_insn): Don't attempt further substitutions if the
	current instruction has been deleted.
	(local_cprop_pass): Likewise.

	* jump.c (redirect_jump):  Also update REG_EQUAL note, if
	one is attached to the jump instruction.
	(invert_jump): Delete REG_EQUAL note on jump, if one exists.


Index: gcse.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gcse.c,v
retrieving revision 1.239
diff -c -3 -p -r1.239 gcse.c
*** gcse.c	8 Mar 2003 09:47:28 -0000	1.239
--- gcse.c	8 Mar 2003 20:57:56 -0000
*************** cprop_jump (bb, setcc, jump, from, src)
*** 4048,4075 ****
       rtx from;
       rtx src;
  {
!   rtx new, new_set;
    rtx set = pc_set (jump);

!   /* First substitute in the INSN condition as the SET_SRC of the JUMP,
!      then substitute that given values in this expanded JUMP.  */
!   if (setcc != NULL
        && !modified_between_p (from, setcc, jump)
        && !modified_between_p (src, setcc, jump))
      {
        rtx setcc_set = single_set (setcc);
!       new_set = simplify_replace_rtx (SET_SRC (set),
! 				      SET_DEST (setcc_set),
! 				      SET_SRC (setcc_set));
      }
    else
!     new_set = set;

!   new = simplify_replace_rtx (new_set, from, src);

!   /* If no simplification can be made, then try the next
!      register.  */
!   if (rtx_equal_p (new, new_set) || rtx_equal_p (new, SET_SRC (set)))
      return 0;

    /* If this is now a no-op delete it, otherwise this must be a valid insn.  */
--- 4048,4089 ----
       rtx from;
       rtx src;
  {
!   rtx new, set_src, note_src;
    rtx set = pc_set (jump);
+   rtx note = find_reg_equal_equiv_note (jump);

!   if (note)
!     {
!       note_src = XEXP (note, 0);
!       if (GET_CODE (note_src) == EXPR_LIST)
! 	note_src = NULL_RTX;
!     }
!   else note_src = NULL_RTX;
!
!   /* Prefer REG_EQUAL notes except those containing EXPR_LISTs.  */
!   set_src = note_src ? note_src : SET_SRC (set);
!
!   /* First substitute the SETCC condition into the JUMP instruction,
!      then substitute that given values into this expanded JUMP.  */
!   if (setcc != NULL_RTX
        && !modified_between_p (from, setcc, jump)
        && !modified_between_p (src, setcc, jump))
      {
+       rtx setcc_src;
        rtx setcc_set = single_set (setcc);
!       rtx setcc_note = find_reg_equal_equiv_note (setcc);
!       setcc_src = (setcc_note && GET_CODE (XEXP (setcc_note, 0)) != EXPR_LIST)
! 		? XEXP (setcc_note, 0) : SET_SRC (setcc_set);
!       set_src = simplify_replace_rtx (set_src, SET_DEST (setcc_set),
! 				      setcc_src);
      }
    else
!     setcc = NULL_RTX;

!   new = simplify_replace_rtx (set_src, from, src);

!   /* If no simplification can be made, then try the next register.  */
!   if (rtx_equal_p (new, SET_SRC (set)))
      return 0;

    /* If this is now a no-op delete it, otherwise this must be a valid insn.  */
*************** cprop_jump (bb, setcc, jump, from, src)
*** 4079,4089 ****
      {
        /* Ensure the value computed inside the jump insn to be equivalent
           to one computed by setcc.  */
!       if (setcc
! 	  && modified_in_p (new, setcc))
  	return 0;
        if (! validate_change (jump, &SET_SRC (set), new, 0))
! 	return 0;

        /* If this has turned into an unconditional jump,
  	 then put a barrier after it so that the unreachable
--- 4093,4111 ----
      {
        /* Ensure the value computed inside the jump insn to be equivalent
           to one computed by setcc.  */
!       if (setcc && modified_in_p (new, setcc))
  	return 0;
        if (! validate_change (jump, &SET_SRC (set), new, 0))
! 	{
! 	  /* If novel, record our substitution in a REG_EQUAL note.  */
! 	  if (!rtx_equal_p (new, note_src))
! 	    set_unique_reg_note (jump, REG_EQUAL, copy_rtx (new));
! 	  return 0;
! 	}
!
!       /* Remove REG_EQUAL note after simplification.  */
!       if (note_src)
! 	remove_note (jump, note);

        /* If this has turned into an unconditional jump,
  	 then put a barrier after it so that the unreachable
*************** cprop_insn (insn, alter_jumps)
*** 4220,4225 ****
--- 4242,4249 ----
  		  print_rtl (gcse_file, src);
  		  fprintf (gcse_file, "\n");
  		}
+ 	      if (INSN_DELETED_P (insn))
+ 		return 1;
  	    }
  	}
        else if (GET_CODE (src) == REG
*************** local_cprop_pass (alter_jumps)
*** 4463,4468 ****
--- 4487,4494 ----
  		    changed = true;
  		    break;
  		  }
+ 	      if (INSN_DELETED_P (insn))
+ 		break;
  	    }
  	  while (reg_use_count);
  	}
Index: jump.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/jump.c,v
retrieving revision 1.219
diff -c -3 -p -r1.219 jump.c
*** jump.c	26 Feb 2003 11:09:32 -0000	1.219
--- jump.c	8 Mar 2003 20:57:56 -0000
*************** redirect_jump (jump, nlabel, delete_unus
*** 2062,2067 ****
--- 2062,2068 ----
       int delete_unused;
  {
    rtx olabel = JUMP_LABEL (jump);
+   rtx note;

    if (nlabel == olabel)
      return 1;
*************** redirect_jump (jump, nlabel, delete_unus
*** 2073,2078 ****
--- 2074,2102 ----
    if (nlabel)
      ++LABEL_NUSES (nlabel);

+   /* Update labels in any REG_EQUAL note.  */
+   if ((note = find_reg_note (jump, REG_EQUAL, NULL_RTX)) != NULL_RTX)
+     {
+       if (nlabel && olabel)
+ 	{
+ 	  rtx dest = XEXP (note, 0);
+
+ 	  if (GET_CODE (dest) == IF_THEN_ELSE)
+ 	    {
+ 	      if (GET_CODE (XEXP (dest, 1)) == LABEL_REF
+ 		  && XEXP (XEXP (dest, 1), 0) == olabel)
+ 		XEXP (XEXP (dest, 1), 0) = nlabel;
+ 	      if (GET_CODE (XEXP (dest, 2)) == LABEL_REF
+ 		  && XEXP (XEXP (dest, 2), 0) == olabel)
+ 		XEXP (XEXP (dest, 2), 0) = nlabel;
+ 	    }
+ 	  else
+ 	    remove_note (jump, note);
+ 	}
+       else
+         remove_note (jump, note);
+     }
+
    /* If we're eliding the jump over exception cleanups at the end of a
       function, move the function end note so that -Wreturn-type works.  */
    if (olabel && nlabel
*************** invert_jump (jump, nlabel, delete_unused
*** 2189,2194 ****
--- 2213,2223 ----

    if (redirect_jump (jump, nlabel, delete_unused))
      {
+       /* Remove REG_EQUAL note if we have one.  */
+       rtx note = find_reg_note (jump, REG_EQUAL, NULL_RTX);
+       if (note)
+ 	remove_note (jump, note);
+
        invert_br_probabilities (jump);

        return 1;

Roger
--
Roger Sayle,                         E-mail: roger at eyesopen dot com
OpenEye Scientific Software,         WWW: http://www.eyesopen.com/
Suite 1107, 3600 Cerrillos Road,     Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507.         Fax: (+1) 505-473-0833


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