expr.c (move_by_pieces): Set alignment for move to minimum of MOVE_MAX_PIECES mode alignment and the...

* 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
This commit is contained in:
David Edelsohn 2004-08-12 15:05:38 +00:00 committed by David Edelsohn
parent c597ef4eab
commit f64d6991d4
2 changed files with 75 additions and 13 deletions

View 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

View 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. */