This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Optimize subregs of zero and sign extensions
- From: Roger Sayle <roger at eyesopen dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Paolo Bonzini <bonzini at gnu dot org>, Richard Henderson <rth at redhat dot com>
- Date: Wed, 21 Jan 2004 10:30:08 -0700 (MST)
- Subject: [PATCH] Optimize subregs of zero and sign extensions
The following patch is an enhancement to simplify_subreg to optimize
subreg truncations of zero and sign extensions. It was originally
developed to implement Paolo Bonzini's (subreg (zero_extend ...)) =>
const0_rtx optimization, but whilst I was there I also noticed we were
missing several related optimizations.
(subreg:SI (zero_extend:DI (foo:SI)) 0) => (foo:SI)
(subreg:SI (sign_extend:DI (foo:SI)) 0) => (foo:SI)
(subreg:HI (zero_extend:DI (foo:SI)) 0) => (subreg:HI (foo:SI) 0)
(subreg:HI (sign_extend:DI (foo:SI)) 0) => (subreg:HI (foo:SI) 0)
(subreg:SI (zero_extend:DI (foo:HI)) 0) => (zero_extend:SI (foo:HI))
(subreg:SI (sign_extend:DI (foo:HI)) 0) => (sign_extend:SI (foo:HI))
I'd expect these transformations to really help 64-bit targets, and
targets that hold 32-bit (or shorter) quantities in 64-bit registers.
The following patch has been tested on i686-pc-linux-gnu with a full
"make bootstrap", all languages except treelang, and regression tested
with a top-level "make -k check" with no new failures.
Ok for mainline?
2004-01-21 Roger Sayle <roger@eyesopen.com>
Paolo Bonzini <bonzini@gnu.org>
* simplify-rtx.c (simplify_subreg): Optimize subregs of zero and
sign extensions.
Index: simplify-rtx.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/simplify-rtx.c,v
retrieving revision 1.173
diff -c -3 -p -r1.173 simplify-rtx.c
*** simplify-rtx.c 19 Jan 2004 21:51:06 -0000 1.173
--- simplify-rtx.c 21 Jan 2004 15:23:54 -0000
*************** simplify_subreg (enum machine_mode outer
*** 3379,3386 ****
res = simplify_subreg (outermode, part, GET_MODE (part), final_offset);
if (res)
return res;
! /* We can at least simplify it by referring directly to the relevant part. */
return gen_rtx_SUBREG (outermode, part, final_offset);
}
return NULL_RTX;
--- 3379,3435 ----
res = simplify_subreg (outermode, part, GET_MODE (part), final_offset);
if (res)
return res;
! /* We can at least simplify it by referring directly to the
! relevant part. */
return gen_rtx_SUBREG (outermode, part, final_offset);
+ }
+
+ /* Optimize SUBREG truncations of zero and sign extended values. */
+ if ((GET_CODE (op) == ZERO_EXTEND
+ || GET_CODE (op) == SIGN_EXTEND)
+ && GET_MODE_BITSIZE (outermode) < GET_MODE_BITSIZE (innermode))
+ {
+ unsigned int lsbword, lsbbyte, lsbbitpos;
+
+ if (WORDS_BIG_ENDIAN)
+ lsbword = (GET_MODE_SIZE (innermode)
+ - (byte + GET_MODE_SIZE (outermode))) / UNITS_PER_WORD;
+ else
+ lsbword = byte / UNITS_PER_WORD;
+ lsbbitpos = lsbword * BITS_PER_WORD;
+
+ if (BYTES_BIG_ENDIAN)
+ lsbbyte = (GET_MODE_SIZE (innermode)
+ - (byte + GET_MODE_SIZE (outermode))) % UNITS_PER_WORD;
+ else
+ lsbbyte = byte % UNITS_PER_WORD;
+ lsbbitpos += lsbbyte * BITS_PER_UNIT;
+
+ /* If we're requesting the lowpart of a zero or sign extension,
+ there are three possibilities. If the outermode is the same
+ as the origmode, we can omit both the extension and the subreg.
+ If the outermode is not larger than the origmode, we can apply
+ the truncation without the extension. Finally, if the outermode
+ is larger than the origmode, but both are integer modes, we
+ can just extend to the appropriate mode. */
+ if (lsbbitpos == 0)
+ {
+ enum machine_mode origmode = GET_MODE (XEXP (op, 0));
+ if (outermode == origmode)
+ return XEXP (op, 0);
+ if (GET_MODE_BITSIZE (outermode) <= GET_MODE_BITSIZE (origmode))
+ return simplify_gen_subreg (outermode, XEXP (op, 0),
+ origmode, byte);
+ if (SCALAR_INT_MODE_P (outermode))
+ return simplify_gen_unary (GET_CODE (op), outermode,
+ XEXP (op, 0), origmode);
+ }
+
+ /* A SUBREG resulting from a zero extension may fold to zero if
+ it extracts higher bits that the ZERO_EXTEND's source bits. */
+ if (GET_CODE (op) == ZERO_EXTEND
+ && lsbbitpos >= GET_MODE_BITSIZE (GET_MODE (XEXP (op, 0))))
+ return const0_rtx;
}
return NULL_RTX;
Roger
--
Roger Sayle, E-mail: roger@eyesopen.com
OpenEye Scientific Software, WWW: http://www.eyesopen.com/
Suite 1107, 3600 Cerrillos Road, Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507. Fax: (+1) 505-473-0833