combine won't substitute reg in (zero_extract (mem (reg)))

Geoff Keating geoffk@geoffk.org
Thu Jul 17 21:24:00 GMT 2003


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>



More information about the Gcc-patches mailing list