diff options
author | Jakub Jelinek <jakub@redhat.com> | 2008-11-24 13:57:37 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2008-11-24 13:57:37 +0100 |
commit | 72a2609f5d7421ab10d04b06f10e78814b0370cc (patch) | |
tree | f665d5278a21eaab0e6a13d9c9e2d0869b83709d /gcc | |
parent | 5b19c351a4f1dc42504e2867883f71f7bd122cbb (diff) | |
download | gcc-72a2609f5d7421ab10d04b06f10e78814b0370cc.zip gcc-72a2609f5d7421ab10d04b06f10e78814b0370cc.tar.gz gcc-72a2609f5d7421ab10d04b06f10e78814b0370cc.tar.bz2 |
re PR middle-end/37135 (code size increase for struct assignment)
PR middle-end/37135
* dse.c (find_shift_sequence): Optimize extraction from a constant.
From-SVN: r142157
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/dse.c | 23 |
2 files changed, 28 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2f131af..ecb4f62 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2008-11-24 Jakub Jelinek <jakub@redhat.com> + + PR middle-end/37135 + * dse.c (find_shift_sequence): Optimize extraction from a constant. + 2008-11-23 John David Anglin <dave.anglin@nrc-cnrc.gc.ca> * pa.c (function_arg): Revert 2008-10-26 change. @@ -1447,6 +1447,29 @@ find_shift_sequence (int access_size, rtx target, new_reg, shift_seq, insn, new_lhs; int cost; + /* If a constant was stored into memory, try to simplify it here, + otherwise the cost of the shift might preclude this optimization + e.g. at -Os, even when no actual shift will be needed. */ + if (CONSTANT_P (store_info->rhs)) + { + unsigned int byte = subreg_lowpart_offset (new_mode, store_mode); + rtx ret = simplify_subreg (new_mode, store_info->rhs, store_mode, + byte); + if (ret && CONSTANT_P (ret)) + { + ret = simplify_const_binary_operation (LSHIFTRT, new_mode, + ret, GEN_INT (shift)); + if (ret && CONSTANT_P (ret)) + { + byte = subreg_lowpart_offset (read_mode, new_mode); + ret = simplify_subreg (read_mode, ret, new_mode, byte); + if (ret && CONSTANT_P (ret) + && rtx_cost (ret, SET, speed) <= COSTS_N_INSNS (1)) + return ret; + } + } + } + /* Try a wider mode if truncating the store mode to NEW_MODE requires a real instruction. */ if (GET_MODE_BITSIZE (new_mode) < GET_MODE_BITSIZE (store_mode) |