expr.c (move_by_pieces): Set alignment for move to minimum of MOVE_MAX_PIECES mode...
authorDavid Edelsohn <edelsohn@gnu.org>
Thu, 12 Aug 2004 15:05:38 +0000 (15:05 +0000)
committerDavid Edelsohn <dje@gcc.gnu.org>
Thu, 12 Aug 2004 15:05:38 +0000 (11:05 -0400)
        * expr.c (move_by_pieces): Set alignment for move to minimum of
        MOVE_MAX_PIECES mode alignment and the largest non-slow mode
        alignment, but not less than the original alignment.
        (move_by_pieces_ninsns): Same.
        (can_store_by_pieces): Similar for store with STORE_MAX_PIECES.
        (store_by_pieces_1): Same.

From-SVN: r85875

gcc/ChangeLog
gcc/expr.c

index b9c2ff04ac1641e9a8b2479b965bab64fb669691..50d746415f978ab56bbd2a6b3565f11b09af997d 100644 (file)
@@ -1,3 +1,12 @@
+2004-08-12  David Edelsohn  <edelsohn@gnu.org>
+
+       * expr.c (move_by_pieces): Set alignment for move to minimum of
+       MOVE_MAX_PIECES mode alignment and the largest non-slow mode
+       alignment, but not less than the original alignment.
+       (move_by_pieces_ninsns): Same.
+       (can_store_by_pieces): Similar for store with STORE_MAX_PIECES.
+       (store_by_pieces_1): Same.
+
 2004-08-12  Diego Novillo  <dnovillo@redhat.com>
 
        PR tree-optimization/16867
index 282bb9af57d9233e11839e92525cc18b47088d81..7d216aeb318ac28409034161ff5c1e831369d7b3 100644 (file)
@@ -925,9 +925,22 @@ move_by_pieces (rtx to, rtx from, unsigned HOST_WIDE_INT len,
        data.to_addr = copy_addr_to_reg (to_addr);
     }
 
-  if (! SLOW_UNALIGNED_ACCESS (word_mode, align)
-      || align > MOVE_MAX * BITS_PER_UNIT || align >= BIGGEST_ALIGNMENT)
-    align = MOVE_MAX * BITS_PER_UNIT;
+  tmode = mode_for_size (MOVE_MAX_PIECES * BITS_PER_UNIT, MODE_INT, 1);
+  if (align >= GET_MODE_ALIGNMENT (tmode))
+    align = GET_MODE_ALIGNMENT (tmode);
+  else
+    {
+      enum machine_mode xmode;
+
+      for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT), xmode = tmode;
+          tmode != VOIDmode;
+          xmode = tmode, tmode = GET_MODE_WIDER_MODE (tmode))
+       if (GET_MODE_SIZE (tmode) > MOVE_MAX_PIECES
+           || SLOW_UNALIGNED_ACCESS (tmode, align))
+         break;
+
+      align = MAX (align, GET_MODE_ALIGNMENT (xmode));
+    }
 
   /* First move what we can in the largest integer mode, then go to
      successively smaller modes.  */
@@ -992,14 +1005,28 @@ move_by_pieces_ninsns (unsigned HOST_WIDE_INT l, unsigned int align,
                       unsigned int max_size)
 {
   unsigned HOST_WIDE_INT n_insns = 0;
+  enum machine_mode tmode;
 
-  if (! SLOW_UNALIGNED_ACCESS (word_mode, align)
-      || align > MOVE_MAX * BITS_PER_UNIT || align >= BIGGEST_ALIGNMENT)
-    align = MOVE_MAX * BITS_PER_UNIT;
+  tmode = mode_for_size (MOVE_MAX_PIECES * BITS_PER_UNIT, MODE_INT, 1);
+  if (align >= GET_MODE_ALIGNMENT (tmode))
+    align = GET_MODE_ALIGNMENT (tmode);
+  else
+    {
+      enum machine_mode tmode, xmode;
+
+      for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT), xmode = tmode;
+          tmode != VOIDmode;
+          xmode = tmode, tmode = GET_MODE_WIDER_MODE (tmode))
+       if (GET_MODE_SIZE (tmode) > MOVE_MAX_PIECES
+           || SLOW_UNALIGNED_ACCESS (tmode, align))
+         break;
+
+      align = MAX (align, GET_MODE_ALIGNMENT (xmode));
+    }
 
   while (max_size > 1)
     {
-      enum machine_mode mode = VOIDmode, tmode;
+      enum machine_mode mode = VOIDmode;
       enum insn_code icode;
 
       for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT);
@@ -1999,9 +2026,22 @@ can_store_by_pieces (unsigned HOST_WIDE_INT len,
   if (! STORE_BY_PIECES_P (len, align))
     return 0;
 
-  if (! SLOW_UNALIGNED_ACCESS (word_mode, align)
-      || align > MOVE_MAX * BITS_PER_UNIT || align >= BIGGEST_ALIGNMENT)
-    align = MOVE_MAX * BITS_PER_UNIT;
+  tmode = mode_for_size (STORE_MAX_PIECES * BITS_PER_UNIT, MODE_INT, 1);
+  if (align >= GET_MODE_ALIGNMENT (tmode))
+    align = GET_MODE_ALIGNMENT (tmode);
+  else
+    {
+      enum machine_mode xmode;
+
+      for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT), xmode = tmode;
+          tmode != VOIDmode;
+          xmode = tmode, tmode = GET_MODE_WIDER_MODE (tmode))
+       if (GET_MODE_SIZE (tmode) > STORE_MAX_PIECES
+           || SLOW_UNALIGNED_ACCESS (tmode, align))
+         break;
+
+      align = MAX (align, GET_MODE_ALIGNMENT (xmode));
+    }
 
   /* We would first store what we can in the largest integer mode, then go to
      successively smaller modes.  */
@@ -2201,9 +2241,22 @@ store_by_pieces_1 (struct store_by_pieces *data ATTRIBUTE_UNUSED,
        data->to_addr = copy_addr_to_reg (to_addr);
     }
 
-  if (! SLOW_UNALIGNED_ACCESS (word_mode, align)
-      || align > MOVE_MAX * BITS_PER_UNIT || align >= BIGGEST_ALIGNMENT)
-    align = MOVE_MAX * BITS_PER_UNIT;
+  tmode = mode_for_size (STORE_MAX_PIECES * BITS_PER_UNIT, MODE_INT, 1);
+  if (align >= GET_MODE_ALIGNMENT (tmode))
+    align = GET_MODE_ALIGNMENT (tmode);
+  else
+    {
+      enum machine_mode xmode;
+
+      for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT), xmode = tmode;
+          tmode != VOIDmode;
+          xmode = tmode, tmode = GET_MODE_WIDER_MODE (tmode))
+       if (GET_MODE_SIZE (tmode) > STORE_MAX_PIECES
+           || SLOW_UNALIGNED_ACCESS (tmode, align))
+         break;
+
+      align = MAX (align, GET_MODE_ALIGNMENT (xmode));
+    }
 
   /* First store what we can in the largest integer mode, then go to
      successively smaller modes.  */