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
This commit is contained in:
Roger Sayle 2006-05-14 15:48:11 +00:00 committed by Roger Sayle
parent f9a4b91e4b
commit c505fc0613
2 changed files with 19 additions and 14 deletions

View File

@ -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

View File

@ -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);
}