diff options
author | Roger Sayle <roger@eyesopen.com> | 2006-05-14 15:48:11 +0000 |
---|---|---|
committer | Roger Sayle <sayle@gcc.gnu.org> | 2006-05-14 15:48:11 +0000 |
commit | c505fc0613bc714188de804f9699ff7810418f7a (patch) | |
tree | b1225cf5a03bab747be06a9edf60ab079fbc4eed | |
parent | f9a4b91e4ba0e555780e391f3430d8a0c2c1e963 (diff) | |
download | gcc-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/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/expmed.c | 27 |
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); } |