aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/dse.c23
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.
diff --git a/gcc/dse.c b/gcc/dse.c
index 0a3ebb4..d7fb2d8 100644
--- a/gcc/dse.c
+++ b/gcc/dse.c
@@ -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)