aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoger Sayle <roger@eyesopen.com>2006-05-14 15:48:11 +0000
committerRoger Sayle <sayle@gcc.gnu.org>2006-05-14 15:48:11 +0000
commitc505fc0613bc714188de804f9699ff7810418f7a (patch)
treeb1225cf5a03bab747be06a9edf60ab079fbc4eed
parentf9a4b91e4ba0e555780e391f3430d8a0c2c1e963 (diff)
downloadgcc-c505fc0613bc714188de804f9699ff7810418f7a.zip
gcc-c505fc0613bc714188de804f9699ff7810418f7a.tar.gz
gcc-c505fc0613bc714188de804f9699ff7810418f7a.tar.bz2
re PR rtl-optimization/22563 (performance regression for gcc newer than 2.95)
PR rtl-optimization/22563 * expmed.c (store_fixed_bit_field): When using AND and IOR to store a fixed width bitfield, always force the intermediates into psuedos. From-SVN: r113762
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/expmed.c27
2 files changed, 19 insertions, 14 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index eff9113..1c6df66 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2006-05-14 Roger Sayle <roger@eyesopen.com>
+
+ PR rtl-optimization/22563
+ * expmed.c (store_fixed_bit_field): When using AND and IOR to store
+ a fixed width bitfield, always force the intermediates into psuedos.
+
2006-05-14 Bernhard Fischer <aldot@gcc.gnu.org>
PR 27501
diff --git a/gcc/expmed.c b/gcc/expmed.c
index 89ae78d..56c0d24 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -793,7 +793,7 @@ store_fixed_bit_field (rtx op0, unsigned HOST_WIDE_INT offset,
{
enum machine_mode mode;
unsigned int total_bits = BITS_PER_WORD;
- rtx subtarget, temp;
+ rtx temp;
int all_zero = 0;
int all_one = 0;
@@ -919,29 +919,28 @@ store_fixed_bit_field (rtx op0, unsigned HOST_WIDE_INT offset,
/* Now clear the chosen bits in OP0,
except that if VALUE is -1 we need not bother. */
+ /* We keep the intermediates in registers to allow CSE to combine
+ consecutive bitfield assignments. */
- subtarget = op0;
+ temp = force_reg (mode, op0);
if (! all_one)
{
- /* Don't try and keep the intermediate in memory, if we need to
- perform both a bit-wise AND and a bit-wise IOR (except when
- we're optimizing for size). */
- if (MEM_P (subtarget) && !all_zero && !optimize_size)
- subtarget = force_reg (mode, subtarget);
- temp = expand_binop (mode, and_optab, subtarget,
+ temp = expand_binop (mode, and_optab, temp,
mask_rtx (mode, bitpos, bitsize, 1),
- subtarget, 1, OPTAB_LIB_WIDEN);
- subtarget = temp;
+ NULL_RTX, 1, OPTAB_LIB_WIDEN);
+ temp = force_reg (mode, temp);
}
- else
- temp = op0;
/* Now logical-or VALUE into OP0, unless it is zero. */
if (! all_zero)
- temp = expand_binop (mode, ior_optab, temp, value,
- subtarget, 1, OPTAB_LIB_WIDEN);
+ {
+ temp = expand_binop (mode, ior_optab, temp, value,
+ NULL_RTX, 1, OPTAB_LIB_WIDEN);
+ temp = force_reg (mode, temp);
+ }
+
if (op0 != temp)
emit_move_insn (op0, temp);
}