diff options
author | Richard Sandiford <richard.sandiford@linaro.org> | 2011-05-03 07:46:10 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2011-05-03 07:46:10 +0000 |
commit | 0f6d54f720796f2ebcb15764ac0d0b174529367d (patch) | |
tree | 0a9929f4d33aeb581d3ef899196493bcc28993e8 /gcc/stor-layout.c | |
parent | b15eacc7da352ad393b29bd35b71019f1da2af7d (diff) | |
download | gcc-0f6d54f720796f2ebcb15764ac0d0b174529367d.zip gcc-0f6d54f720796f2ebcb15764ac0d0b174529367d.tar.gz gcc-0f6d54f720796f2ebcb15764ac0d0b174529367d.tar.bz2 |
hooks.h (hook_bool_mode_uhwi_false): Declare.
gcc/
* hooks.h (hook_bool_mode_uhwi_false): Declare.
* hooks.c (hook_bool_mode_uhwi_false): New function.
* target.def (array_mode_supported_p): New hook.
* doc/tm.texi.in (TARGET_ARRAY_MODE_SUPPORTED_P): Add @hook.
* doc/tm.texi: Regenerate.
* stor-layout.c (mode_for_array): New function.
(layout_type): Use it.
* config/arm/arm.c (arm_array_mode_supported_p): New function.
(TARGET_ARRAY_MODE_SUPPORTED_P): Define.
From-SVN: r173290
Diffstat (limited to 'gcc/stor-layout.c')
-rw-r--r-- | gcc/stor-layout.c | 38 |
1 files changed, 30 insertions, 8 deletions
diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c index ea0d44d..62de10d 100644 --- a/gcc/stor-layout.c +++ b/gcc/stor-layout.c @@ -546,6 +546,34 @@ get_mode_alignment (enum machine_mode mode) return MIN (BIGGEST_ALIGNMENT, MAX (1, mode_base_align[mode]*BITS_PER_UNIT)); } +/* Return the natural mode of an array, given that it is SIZE bytes in + total and has elements of type ELEM_TYPE. */ + +static enum machine_mode +mode_for_array (tree elem_type, tree size) +{ + tree elem_size; + unsigned HOST_WIDE_INT int_size, int_elem_size; + bool limit_p; + + /* One-element arrays get the component type's mode. */ + elem_size = TYPE_SIZE (elem_type); + if (simple_cst_equal (size, elem_size)) + return TYPE_MODE (elem_type); + + limit_p = true; + if (host_integerp (size, 1) && host_integerp (elem_size, 1)) + { + int_size = tree_low_cst (size, 1); + int_elem_size = tree_low_cst (elem_size, 1); + if (int_elem_size > 0 + && int_size % int_elem_size == 0 + && targetm.array_mode_supported_p (TYPE_MODE (elem_type), + int_size / int_elem_size)) + limit_p = false; + } + return mode_for_size_tree (size, MODE_INT, limit_p); +} /* Subroutine of layout_decl: Force alignment required for the data type. But if the decl itself wants greater alignment, don't override that. */ @@ -2040,14 +2068,8 @@ layout_type (tree type) && (TYPE_MODE (TREE_TYPE (type)) != BLKmode || TYPE_NO_FORCE_BLK (TREE_TYPE (type)))) { - /* One-element arrays get the component type's mode. */ - if (simple_cst_equal (TYPE_SIZE (type), - TYPE_SIZE (TREE_TYPE (type)))) - SET_TYPE_MODE (type, TYPE_MODE (TREE_TYPE (type))); - else - SET_TYPE_MODE (type, mode_for_size_tree (TYPE_SIZE (type), - MODE_INT, 1)); - + SET_TYPE_MODE (type, mode_for_array (TREE_TYPE (type), + TYPE_SIZE (type))); if (TYPE_MODE (type) != BLKmode && STRICT_ALIGNMENT && TYPE_ALIGN (type) < BIGGEST_ALIGNMENT && TYPE_ALIGN (type) < GET_MODE_ALIGNMENT (TYPE_MODE (type))) |