This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: combine won't substitute reg in (zero_extract (mem (reg)))
- From: Geoff Keating <geoffk at geoffk dot org>
- To: Alexandre Oliva <aoliva at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: 17 Jul 2003 14:20:23 -0700
- Subject: Re: combine won't substitute reg in (zero_extract (mem (reg)))
- References: <oradbcoq37.fsf@free.redhat.lsd.ic.unicamp.br>
Alexandre Oliva <aoliva@redhat.com> writes:
> This patch fixes a problem in combine that prevents it from moving
> addresses back into MEMs of SET_DESTs. For example, given:
>
> (set (reg A) (plus (symbol_ref) (const_int)))
> (set (zero_extract (mem (reg A)) (const_int) (const_int)) (reg B))
>
> combinable_i3pat() would decide it was not combinable because it
> thought (reg A) was partially written into, since it appeared inside
> an expression containing zero_extract. However, it is the enclosing
> mem that is partially written to, the address is not written to at
> all. After this patch, we combine the patterns into:
>
> (set (zero_extract (mem (plus (symbol_ref) (const_int))) (const_int)
> (const_int)) (reg B))
>
> I'm not entirely sure the test for equality of inner_dest and i2dest
> or i1dest is necessary. The patch bootstrapped both with and without
> the calls to rtx_equal_p, but I thought I'd leave them in, just in
> case.
>
> Bootstrapped on athlon-pc-linux-gnu, and tested on the port I'm
> working on. Ok to install?
This is OK.
> Index: gcc/ChangeLog
> from Alexandre Oliva <aoliva@redhat.com>
>
> * combine.c (combinable_i3pat): Don't forbid occurrences of
> i2dest or i1dest in inner_dest if inner_dest is a mem.
>
> Index: gcc/combine.c
> ===================================================================
> RCS file: /cvs/gcc/gcc/gcc/combine.c,v
> retrieving revision 1.370
> diff -u -p -r1.370 combine.c
> --- gcc/combine.c 16 Jul 2003 19:36:38 -0000 1.370
> +++ gcc/combine.c 17 Jul 2003 19:36:40 -0000
> @@ -1301,9 +1301,14 @@ combinable_i3pat (rtx i3, rtx *loc, rtx
> || GET_CODE (inner_dest) == ZERO_EXTRACT)
> inner_dest = XEXP (inner_dest, 0);
>
> - /* Check for the case where I3 modifies its output, as
> - discussed above. */
> - if ((inner_dest != dest
> + /* Check for the case where I3 modifies its output, as discussed
> + above. We don't want to prevent pseudos from being combined
> + into the address of a MEM, so only prevent the combination if
> + i1 or i2 set the same MEM. */
> + if ((inner_dest != dest &&
> + (GET_CODE (inner_dest) != MEM
> + || rtx_equal_p (i2dest, inner_dest)
> + || (i1dest && rtx_equal_p (i1dest, inner_dest)))
> && (reg_overlap_mentioned_p (i2dest, inner_dest)
> || (i1dest && reg_overlap_mentioned_p (i1dest, inner_dest))))
>
>
>
> --
> Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/
> Red Hat GCC Developer aoliva@{redhat.com, gcc.gnu.org}
> CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org}
> Free Software Evangelist Professional serial bug killer
--
- Geoffrey Keating <geoffk@geoffk.org>