diff options
author | David Edelsohn <edelsohn@gnu.org> | 2004-08-12 15:05:38 +0000 |
---|---|---|
committer | David Edelsohn <dje@gcc.gnu.org> | 2004-08-12 11:05:38 -0400 |
commit | f64d6991d42d47569e602a11dcbd21814d0a5026 (patch) | |
tree | efaabf2ae2baf7a2843abb3d69518a7f30d1bee1 /gcc | |
parent | c597ef4eab9a2de9ad0b2187547ac9bac0b53132 (diff) | |
download | gcc-f64d6991d42d47569e602a11dcbd21814d0a5026.zip gcc-f64d6991d42d47569e602a11dcbd21814d0a5026.tar.gz gcc-f64d6991d42d47569e602a11dcbd21814d0a5026.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/expr.c | 79 |
2 files changed, 75 insertions, 13 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b9c2ff0..50d7464 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 @@ -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. */ |