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]

validate subregs, part 3


This bit is cleanup only, no functional changes.  I believe that I once
had functional changes in here, but backed them out.  But I think the
change to "isize" from "GET_MODE_SIZE (GET_MODE (x))" is still valuable
for readability purposes.


r~


        * combine.c (gen_lowpart_for_combine): Factor out mode of x as well
        as mode sizes into local temporaries.  Unify failure path.

Index: combine.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/combine.c,v
retrieving revision 1.460
diff -c -p -d -r1.460 combine.c
*** combine.c	22 Oct 2004 17:05:03 -0000	1.460
--- combine.c	23 Nov 2004 23:22:36 -0000
*************** recog_for_combine (rtx *pnewpat, rtx ins
*** 9308,9323 ****
     An insn containing that will not be recognized.  */
  
  static rtx
! gen_lowpart_for_combine (enum machine_mode mode, rtx x)
  {
    rtx result;
  
!   if (GET_MODE (x) == mode)
      return x;
  
!   /* Return identity if this is a CONST or symbolic
!      reference.  */
!   if (mode == Pmode
        && (GET_CODE (x) == CONST
  	  || GET_CODE (x) == SYMBOL_REF
  	  || GET_CODE (x) == LABEL_REF))
--- 9308,9325 ----
     An insn containing that will not be recognized.  */
  
  static rtx
! gen_lowpart_for_combine (enum machine_mode omode, rtx x)
  {
+   enum machine_mode imode = GET_MODE (x);
+   unsigned int osize = GET_MODE_SIZE (omode);
+   unsigned int isize = GET_MODE_SIZE (imode);
    rtx result;
  
!   if (omode == imode)
      return x;
  
!   /* Return identity if this is a CONST or symbolic reference.  */
!   if (omode == Pmode
        && (GET_CODE (x) == CONST
  	  || GET_CODE (x) == SYMBOL_REF
  	  || GET_CODE (x) == LABEL_REF))
*************** gen_lowpart_for_combine (enum machine_mo
*** 9325,9337 ****
  
    /* We can only support MODE being wider than a word if X is a
       constant integer or has a mode the same size.  */
! 
!   if (GET_MODE_SIZE (mode) > UNITS_PER_WORD
!       && ! ((GET_MODE (x) == VOIDmode
  	     && (GET_CODE (x) == CONST_INT
  		 || GET_CODE (x) == CONST_DOUBLE))
! 	    || GET_MODE_SIZE (GET_MODE (x)) == GET_MODE_SIZE (mode)))
!     return gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
  
    /* X might be a paradoxical (subreg (mem)).  In that case, gen_lowpart
       won't know what to do.  So we will strip off the SUBREG here and
--- 9327,9338 ----
  
    /* We can only support MODE being wider than a word if X is a
       constant integer or has a mode the same size.  */
!   if (GET_MODE_SIZE (omode) > UNITS_PER_WORD
!       && ! ((imode == VOIDmode
  	     && (GET_CODE (x) == CONST_INT
  		 || GET_CODE (x) == CONST_DOUBLE))
! 	    || isize == osize))
!     goto fail;
  
    /* X might be a paradoxical (subreg (mem)).  In that case, gen_lowpart
       won't know what to do.  So we will strip off the SUBREG here and
*************** gen_lowpart_for_combine (enum machine_mo
*** 9339,9349 ****
    if (GET_CODE (x) == SUBREG && MEM_P (SUBREG_REG (x)))
      {
        x = SUBREG_REG (x);
!       if (GET_MODE (x) == mode)
  	return x;
      }
  
!   result = gen_lowpart_common (mode, x);
  #ifdef CANNOT_CHANGE_MODE_CLASS
    if (result != 0 && GET_CODE (result) == SUBREG)
      record_subregs_of_mode (result);
--- 9340,9351 ----
    if (GET_CODE (x) == SUBREG && MEM_P (SUBREG_REG (x)))
      {
        x = SUBREG_REG (x);
!       if (GET_MODE (x) == omode)
  	return x;
      }
  
!   result = gen_lowpart_common (omode, x);
! 
  #ifdef CANNOT_CHANGE_MODE_CLASS
    if (result != 0 && GET_CODE (result) == SUBREG)
      record_subregs_of_mode (result);
*************** gen_lowpart_for_combine (enum machine_mo
*** 9359,9391 ****
        /* Refuse to work on a volatile memory ref or one with a mode-dependent
  	 address.  */
        if (MEM_VOLATILE_P (x) || mode_dependent_address_p (XEXP (x, 0)))
! 	return gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
  
        /* If we want to refer to something bigger than the original memref,
  	 generate a paradoxical subreg instead.  That will force a reload
  	 of the original memref X.  */
!       if (GET_MODE_SIZE (GET_MODE (x)) < GET_MODE_SIZE (mode))
! 	return gen_rtx_SUBREG (mode, x, 0);
  
        if (WORDS_BIG_ENDIAN)
! 	offset = (MAX (GET_MODE_SIZE (GET_MODE (x)), UNITS_PER_WORD)
! 		  - MAX (GET_MODE_SIZE (mode), UNITS_PER_WORD));
  
        if (BYTES_BIG_ENDIAN)
! 	{
! 	  /* Adjust the address so that the address-after-the-data is
! 	     unchanged.  */
! 	  offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (mode))
! 		     - MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (x))));
! 	}
  
!       return adjust_address_nv (x, mode, offset);
      }
  
    /* If X is a comparison operator, rewrite it in a new mode.  This
       probably won't match, but may allow further simplifications.  */
    else if (COMPARISON_P (x))
!     return gen_rtx_fmt_ee (GET_CODE (x), mode, XEXP (x, 0), XEXP (x, 1));
  
    /* If we couldn't simplify X any other way, just enclose it in a
       SUBREG.  Normally, this SUBREG won't match, but some patterns may
--- 9361,9388 ----
        /* Refuse to work on a volatile memory ref or one with a mode-dependent
  	 address.  */
        if (MEM_VOLATILE_P (x) || mode_dependent_address_p (XEXP (x, 0)))
! 	goto fail;
  
        /* If we want to refer to something bigger than the original memref,
  	 generate a paradoxical subreg instead.  That will force a reload
  	 of the original memref X.  */
!       if (isize < osize)
! 	return gen_rtx_SUBREG (omode, x, 0);
  
        if (WORDS_BIG_ENDIAN)
! 	offset = MAX (isize, UNITS_PER_WORD) - MAX (osize, UNITS_PER_WORD);
  
+       /* Adjust the address so that the address-after-the-data is unchanged. */
        if (BYTES_BIG_ENDIAN)
! 	offset -= MIN (UNITS_PER_WORD, osize) - MIN (UNITS_PER_WORD, isize);
  
!       return adjust_address_nv (x, omode, offset);
      }
  
    /* If X is a comparison operator, rewrite it in a new mode.  This
       probably won't match, but may allow further simplifications.  */
    else if (COMPARISON_P (x))
!     return gen_rtx_fmt_ee (GET_CODE (x), omode, XEXP (x, 0), XEXP (x, 1));
  
    /* If we couldn't simplify X any other way, just enclose it in a
       SUBREG.  Normally, this SUBREG won't match, but some patterns may
*************** gen_lowpart_for_combine (enum machine_mo
*** 9394,9414 ****
      {
        int offset = 0;
        rtx res;
-       enum machine_mode sub_mode = GET_MODE (x);
  
!       offset = subreg_lowpart_offset (mode, sub_mode);
!       if (sub_mode == VOIDmode)
  	{
! 	  sub_mode = int_mode_for_mode (mode);
! 	  x = gen_lowpart_common (sub_mode, x);
! 	  if (x == 0)
! 	    return gen_rtx_CLOBBER (VOIDmode, const0_rtx);
  	}
!       res = simplify_gen_subreg (mode, x, sub_mode, offset);
        if (res)
  	return res;
-       return gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
      }
  }
  
  /* These routines make binary and unary operations by first seeing if they
--- 9391,9412 ----
      {
        int offset = 0;
        rtx res;
  
!       offset = subreg_lowpart_offset (omode, imode);
!       if (imode == VOIDmode)
  	{
! 	  imode = int_mode_for_mode (omode);
! 	  x = gen_lowpart_common (imode, x);
! 	  if (x == NULL)
! 	    goto fail;
  	}
!       res = simplify_gen_subreg (omode, x, imode, offset);
        if (res)
  	return res;
      }
+ 
+  fail:
+   return gen_rtx_CLOBBER (imode, const0_rtx);
  }
  
  /* These routines make binary and unary operations by first seeing if they


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