re PR rtl-optimization/22563 (performance regression for gcc newer than 2.95)
authorRoger Sayle <roger@eyesopen.com>
Sun, 14 May 2006 15:48:11 +0000 (15:48 +0000)
committerRoger Sayle <sayle@gcc.gnu.org>
Sun, 14 May 2006 15:48:11 +0000 (15:48 +0000)
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

gcc/ChangeLog
gcc/expmed.c

index eff9113d34e15d3c7bf0923bca21c736ee4f0905..1c6df66f205ea2d0734d9e080d04d33f2629a629 100644 (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
index 89ae78df7cd0dbb688739a672a254d09a16c8d81..56c0d24bd66fee2bef217c9ee512b447659ef9ad 100644 (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);
 }