This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
validate subregs, part 3
- From: Richard Henderson <rth at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 23 Nov 2004 15:27:47 -0800
- Subject: 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