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]

Repost: RFA: fix PR rtl-optimization/18992


This patch previously posted,
http://gcc.gnu.org/ml/gcc-patches/2004-05/msg01037.html ,
no longer applies automatically because the context has changed
due to the introduction of all the foo_P macros.

I have appended the updated patch. Sucessfully bootstrapped/build
and regression tested on i686-pc-linux-gnu native and i686-pc-linux-gnu X sh-elf
in the sh-elf-4_1-branch.


2004-05-17  J"orn Rennecke <joern.rennecke@superh.com>

	PR rtl-optimization/18992
	Back out this patch:
	  2003-10-08  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>
	  PR optimization/12142
	  * cse.c (count_reg_usage): In a SET with a REG SET_DEST, count the
	  uses of the register in the SET_SRC.  Remove unnecessary argument.

	Replace it with this:
	* cse.c (count_reg_usage): In INSN, JUMP_INSN and CALL_INSN cases,
	if flag_non_call_exceptions is set and the insn may trap, pass
	pc_rtx as dest for recursion.
	In SET_SRC part of SET case, if dest is already set, pass it down
	unchanged.

Index: cse.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cse.c,v
retrieving revision 1.351.2.1
diff -p -r1.351.2.1 cse.c
*** cse.c	6 Jul 2005 21:34:18 -0000	1.351.2.1
--- cse.c	18 Jul 2005 13:26:25 -0000
*************** static rtx cse_process_notes (rtx, rtx);
*** 618,624 ****
  static void invalidate_skipped_set (rtx, rtx, void *);
  static void invalidate_skipped_block (rtx);
  static rtx cse_basic_block (rtx, rtx, struct branch_path *);
! static void count_reg_usage (rtx, int *, int);
  static int check_for_label_ref (rtx *, void *);
  extern void dump_class (struct table_elt*);
  static void get_cse_reg_info_1 (unsigned int regno);
--- 618,624 ----
  static void invalidate_skipped_set (rtx, rtx, void *);
  static void invalidate_skipped_block (rtx);
  static rtx cse_basic_block (rtx, rtx, struct branch_path *);
! static void count_reg_usage (rtx, int *, rtx, int);
  static int check_for_label_ref (rtx *, void *);
  extern void dump_class (struct table_elt*);
  static void get_cse_reg_info_1 (unsigned int regno);
*************** check_for_label_ref (rtx *rtl, void *dat
*** 7079,7088 ****
  
  /* Count the number of times registers are used (not set) in X.
     COUNTS is an array in which we accumulate the count, INCR is how much
!    we count each register usage.  */
  
  static void
! count_reg_usage (rtx x, int *counts, int incr)
  {
    enum rtx_code code;
    rtx note;
--- 7079,7094 ----
  
  /* Count the number of times registers are used (not set) in X.
     COUNTS is an array in which we accumulate the count, INCR is how much
!    we count each register usage.
! 
!    Don't count a usage of DEST, which is the SET_DEST of a SET which
!    contains X in its SET_SRC.  This is because such a SET does not
!    modify the liveness of DEST.
!    DEST is set to pc_rtx for a trapping insn, which means that we must count
!    uses of a SET_DEST regardless because the insn can't be deleted here.  */
  
  static void
! count_reg_usage (rtx x, int *counts, rtx dest, int incr)
  {
    enum rtx_code code;
    rtx note;
*************** count_reg_usage (rtx x, int *counts, int
*** 7095,7101 ****
    switch (code = GET_CODE (x))
      {
      case REG:
!       counts[REGNO (x)] += incr;
        return;
  
      case PC:
--- 7101,7108 ----
    switch (code = GET_CODE (x))
      {
      case REG:
!       if (x != dest)
! 	counts[REGNO (x)] += incr;
        return;
  
      case PC:
*************** count_reg_usage (rtx x, int *counts, int
*** 7112,7134 ****
        /* If we are clobbering a MEM, mark any registers inside the address
           as being used.  */
        if (MEM_P (XEXP (x, 0)))
! 	count_reg_usage (XEXP (XEXP (x, 0), 0), counts, incr);
        return;
  
      case SET:
        /* Unless we are setting a REG, count everything in SET_DEST.  */
        if (!REG_P (SET_DEST (x)))
! 	count_reg_usage (SET_DEST (x), counts, incr);
!       count_reg_usage (SET_SRC (x), counts, incr);
        return;
  
      case CALL_INSN:
-       count_reg_usage (CALL_INSN_FUNCTION_USAGE (x), counts, incr);
-       /* Fall through.  */
- 
      case INSN:
      case JUMP_INSN:
!       count_reg_usage (PATTERN (x), counts, incr);
  
        /* Things used in a REG_EQUAL note aren't dead since loop may try to
  	 use them.  */
--- 7119,7146 ----
        /* If we are clobbering a MEM, mark any registers inside the address
           as being used.  */
        if (MEM_P (XEXP (x, 0)))
! 	count_reg_usage (XEXP (XEXP (x, 0), 0), counts, NULL_RTX, incr);
        return;
  
      case SET:
        /* Unless we are setting a REG, count everything in SET_DEST.  */
        if (!REG_P (SET_DEST (x)))
! 	count_reg_usage (SET_DEST (x), counts, NULL_RTX, incr);
!       count_reg_usage (SET_SRC (x), counts,
! 		       dest ? dest : SET_DEST (x),
! 		       incr);
        return;
  
      case CALL_INSN:
      case INSN:
      case JUMP_INSN:
!     /* We expect dest to be NULL_RTX here.  If the insn may trap, mark
!        this fact by setting DEST to pc_rtx.  */
!       if (flag_non_call_exceptions && may_trap_p (PATTERN (x)))
! 	dest = pc_rtx;
!       if (code == CALL_INSN)
! 	count_reg_usage (CALL_INSN_FUNCTION_USAGE (x), counts, dest, incr);
!       count_reg_usage (PATTERN (x), counts, dest, incr);
  
        /* Things used in a REG_EQUAL note aren't dead since loop may try to
  	 use them.  */
*************** count_reg_usage (rtx x, int *counts, int
*** 7143,7154 ****
  	     Process all the arguments.  */
  	    do
  	      {
! 		count_reg_usage (XEXP (eqv, 0), counts, incr);
  		eqv = XEXP (eqv, 1);
  	      }
  	    while (eqv && GET_CODE (eqv) == EXPR_LIST);
  	  else
! 	    count_reg_usage (eqv, counts, incr);
  	}
        return;
  
--- 7155,7166 ----
  	     Process all the arguments.  */
  	    do
  	      {
! 		count_reg_usage (XEXP (eqv, 0), counts, dest, incr);
  		eqv = XEXP (eqv, 1);
  	      }
  	    while (eqv && GET_CODE (eqv) == EXPR_LIST);
  	  else
! 	    count_reg_usage (eqv, counts, dest, incr);
  	}
        return;
  
*************** count_reg_usage (rtx x, int *counts, int
*** 7158,7172 ****
  	  /* FUNCTION_USAGE expression lists may include (CLOBBER (mem /u)),
  	     involving registers in the address.  */
  	  || GET_CODE (XEXP (x, 0)) == CLOBBER)
! 	count_reg_usage (XEXP (x, 0), counts, incr);
  
!       count_reg_usage (XEXP (x, 1), counts, incr);
        return;
  
      case ASM_OPERANDS:
        /* Iterate over just the inputs, not the constraints as well.  */
        for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
! 	count_reg_usage (ASM_OPERANDS_INPUT (x, i), counts, incr);
        return;
  
      case INSN_LIST:
--- 7170,7188 ----
  	  /* FUNCTION_USAGE expression lists may include (CLOBBER (mem /u)),
  	     involving registers in the address.  */
  	  || GET_CODE (XEXP (x, 0)) == CLOBBER)
! 	count_reg_usage (XEXP (x, 0), counts, NULL_RTX, incr);
  
!       count_reg_usage (XEXP (x, 1), counts, NULL_RTX, incr);
        return;
  
      case ASM_OPERANDS:
+       /* If the asm is volatile, then this insn cannot be deleted,
+ 	 and so the inputs *must* be live.  */
+       if (MEM_VOLATILE_P (x))
+ 	dest = NULL_RTX;
        /* Iterate over just the inputs, not the constraints as well.  */
        for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
! 	count_reg_usage (ASM_OPERANDS_INPUT (x, i), counts, dest, incr);
        return;
  
      case INSN_LIST:
*************** count_reg_usage (rtx x, int *counts, int
*** 7180,7189 ****
    for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
      {
        if (fmt[i] == 'e')
! 	count_reg_usage (XEXP (x, i), counts, incr);
        else if (fmt[i] == 'E')
  	for (j = XVECLEN (x, i) - 1; j >= 0; j--)
! 	  count_reg_usage (XVECEXP (x, i, j), counts, incr);
      }
  }
  
--- 7196,7205 ----
    for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
      {
        if (fmt[i] == 'e')
! 	count_reg_usage (XEXP (x, i), counts, dest, incr);
        else if (fmt[i] == 'E')
  	for (j = XVECLEN (x, i) - 1; j >= 0; j--)
! 	  count_reg_usage (XVECEXP (x, i, j), counts, dest, incr);
      }
  }
  
*************** dead_libcall_p (rtx insn, int *counts)
*** 7270,7280 ****
      new = XEXP (note, 0);
  
    /* While changing insn, we must update the counts accordingly.  */
!   count_reg_usage (insn, counts, -1);
  
    if (validate_change (insn, &SET_SRC (set), new, 0))
      {
!       count_reg_usage (insn, counts, 1);
        remove_note (insn, find_reg_note (insn, REG_RETVAL, NULL_RTX));
        remove_note (insn, note);
        return true;
--- 7286,7296 ----
      new = XEXP (note, 0);
  
    /* While changing insn, we must update the counts accordingly.  */
!   count_reg_usage (insn, counts, NULL_RTX, -1);
  
    if (validate_change (insn, &SET_SRC (set), new, 0))
      {
!       count_reg_usage (insn, counts, NULL_RTX, 1);
        remove_note (insn, find_reg_note (insn, REG_RETVAL, NULL_RTX));
        remove_note (insn, note);
        return true;
*************** dead_libcall_p (rtx insn, int *counts)
*** 7285,7298 ****
        new = force_const_mem (GET_MODE (SET_DEST (set)), new);
        if (new && validate_change (insn, &SET_SRC (set), new, 0))
  	{
! 	  count_reg_usage (insn, counts, 1);
  	  remove_note (insn, find_reg_note (insn, REG_RETVAL, NULL_RTX));
  	  remove_note (insn, note);
  	  return true;
  	}
      }
  
!   count_reg_usage (insn, counts, 1);
    return false;
  }
  
--- 7301,7314 ----
        new = force_const_mem (GET_MODE (SET_DEST (set)), new);
        if (new && validate_change (insn, &SET_SRC (set), new, 0))
  	{
! 	  count_reg_usage (insn, counts, NULL_RTX, 1);
  	  remove_note (insn, find_reg_note (insn, REG_RETVAL, NULL_RTX));
  	  remove_note (insn, note);
  	  return true;
  	}
      }
  
!   count_reg_usage (insn, counts, NULL_RTX, 1);
    return false;
  }
  
*************** delete_trivially_dead_insns (rtx insns, 
*** 7317,7323 ****
    counts = xcalloc (nreg, sizeof (int));
    for (insn = insns; insn; insn = NEXT_INSN (insn))
      if (INSN_P (insn))
!       count_reg_usage (insn, counts, 1);
  
    /* Go from the last insn to the first and delete insns that only set unused
       registers or copy a register to itself.  As we delete an insn, remove
--- 7333,7339 ----
    counts = xcalloc (nreg, sizeof (int));
    for (insn = insns; insn; insn = NEXT_INSN (insn))
      if (INSN_P (insn))
!       count_reg_usage (insn, counts, NULL_RTX, 1);
  
    /* Go from the last insn to the first and delete insns that only set unused
       registers or copy a register to itself.  As we delete an insn, remove
*************** delete_trivially_dead_insns (rtx insns, 
*** 7355,7361 ****
  
        if (! live_insn)
  	{
! 	  count_reg_usage (insn, counts, -1);
  	  delete_insn_and_edges (insn);
  	  ndead++;
  	}
--- 7371,7377 ----
  
        if (! live_insn)
  	{
! 	  count_reg_usage (insn, counts, NULL_RTX, -1);
  	  delete_insn_and_edges (insn);
  	  ndead++;
  	}

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