diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2017-09-09 12:29:08 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2017-09-09 12:29:08 +0000 |
commit | 89ec98ed7ecf0a52175726cca867d471fcad9811 (patch) | |
tree | 69c068c8f67a967e86f534a73ae17a418845d075 /gcc/ada | |
parent | 7f46ecf6dcc9047bf659932990e55759a00978c0 (diff) | |
download | gcc-89ec98ed7ecf0a52175726cca867d471fcad9811.zip gcc-89ec98ed7ecf0a52175726cca867d471fcad9811.tar.gz gcc-89ec98ed7ecf0a52175726cca867d471fcad9811.tar.bz2 |
decl.c (promote_object_alignment): New function taken from...
* gcc-interface/decl.c (promote_object_alignment): New function taken
from...
(gnat_to_gnu_entity) <E_Variable>: ...here. Invoke it.
(gnat_to_gnu_field): If the field is Atomic or VFA, invoke it and
create a padding type on success before doing the atomic check.
From-SVN: r251931
Diffstat (limited to 'gcc/ada')
-rw-r--r-- | gcc/ada/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/ada/gcc-interface/decl.c | 98 |
2 files changed, 66 insertions, 40 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 2c906b9..d0d230c 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,5 +1,13 @@ 2017-09-09 Eric Botcazou <ebotcazou@adacore.com> + * gcc-interface/decl.c (promote_object_alignment): New function taken + from... + (gnat_to_gnu_entity) <E_Variable>: ...here. Invoke it. + (gnat_to_gnu_field): If the field is Atomic or VFA, invoke it and + create a padding type on success before doing the atomic check. + +2017-09-09 Eric Botcazou <ebotcazou@adacore.com> + * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Variable>: Apply the promotion to static memory earlier in the processing. diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c index 0798a8f..2a31e8f 100644 --- a/gcc/ada/gcc-interface/decl.c +++ b/gcc/ada/gcc-interface/decl.c @@ -230,6 +230,7 @@ static vec<variant_desc> build_variant_list (tree, vec<subst_pair>, static tree validate_size (Uint, tree, Entity_Id, enum tree_code, bool, bool); static void set_rm_size (Uint, tree, Entity_Id); static unsigned int validate_alignment (Uint, Entity_Id, unsigned int); +static unsigned int promote_object_alignment (tree, Entity_Id); static void check_ok_for_atomic_type (tree, Entity_Id, bool); static tree create_field_decl_from (tree, tree, tree, tree, tree, vec<subst_pair>); @@ -856,45 +857,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) && No (Renamed_Object (gnat_entity)) && No (Address_Clause (gnat_entity)))) && TREE_CODE (TYPE_SIZE (gnu_type)) == INTEGER_CST) - { - unsigned int size_cap, align_cap; - - /* No point in promoting the alignment if this doesn't prevent - BLKmode access to the object, in particular block copy, as - this will for example disable the NRV optimization for it. - No point in jumping through all the hoops needed in order - to support BIGGEST_ALIGNMENT if we don't really have to. - So we cap to the smallest alignment that corresponds to - a known efficient memory access pattern of the target. */ - if (Is_Atomic_Or_VFA (gnat_entity)) - { - size_cap = UINT_MAX; - align_cap = BIGGEST_ALIGNMENT; - } - else - { - size_cap = MAX_FIXED_MODE_SIZE; - align_cap = get_mode_alignment (ptr_mode); - } - - if (!tree_fits_uhwi_p (TYPE_SIZE (gnu_type)) - || compare_tree_int (TYPE_SIZE (gnu_type), size_cap) > 0) - align = 0; - else if (compare_tree_int (TYPE_SIZE (gnu_type), align_cap) > 0) - align = align_cap; - else - align = ceil_pow2 (tree_to_uhwi (TYPE_SIZE (gnu_type))); - - /* But make sure not to under-align the object. */ - if (align <= TYPE_ALIGN (gnu_type)) - align = 0; - - /* And honor the minimum valid atomic alignment, if any. */ -#ifdef MINIMUM_ATOMIC_ALIGNMENT - else if (align < MINIMUM_ATOMIC_ALIGNMENT) - align = MINIMUM_ATOMIC_ALIGNMENT; -#endif - } + align = promote_object_alignment (gnu_type, gnat_entity); /* If the object is set to have atomic components, find the component type and validate it. @@ -6891,7 +6854,15 @@ gnat_to_gnu_field (Entity_Id gnat_field, tree gnu_record_type, int packed, } if (Is_Atomic_Or_VFA (gnat_field)) - check_ok_for_atomic_type (gnu_field_type, gnat_field, false); + { + const unsigned int align + = promote_object_alignment (gnu_field_type, gnat_field); + if (align > 0) + gnu_field_type + = maybe_pad_type (gnu_field_type, NULL_TREE, align, gnat_field, + false, false, definition, true); + check_ok_for_atomic_type (gnu_field_type, gnat_field, false); + } if (Present (Component_Clause (gnat_field))) { @@ -8808,6 +8779,53 @@ validate_alignment (Uint alignment, Entity_Id gnat_entity, unsigned int align) return align; } +/* Promote the alignment of GNU_TYPE corresponding to GNAT_ENTITY. Return + a positive value on success or zero on failure. */ + +static unsigned int +promote_object_alignment (tree gnu_type, Entity_Id gnat_entity) +{ + unsigned int align, size_cap, align_cap; + + /* No point in promoting the alignment if this doesn't prevent BLKmode access + to the object, in particular block copy, as this will for example disable + the NRV optimization for it. No point in jumping through all the hoops + needed in order to support BIGGEST_ALIGNMENT if we don't really have to. + So we cap to the smallest alignment that corresponds to a known efficient + memory access pattern, except for Atomic and Volatile_Full_Access. */ + if (Is_Atomic_Or_VFA (gnat_entity)) + { + size_cap = UINT_MAX; + align_cap = BIGGEST_ALIGNMENT; + } + else + { + size_cap = MAX_FIXED_MODE_SIZE; + align_cap = get_mode_alignment (ptr_mode); + } + + /* Do the promotion within the above limits. */ + if (!tree_fits_uhwi_p (TYPE_SIZE (gnu_type)) + || compare_tree_int (TYPE_SIZE (gnu_type), size_cap) > 0) + align = 0; + else if (compare_tree_int (TYPE_SIZE (gnu_type), align_cap) > 0) + align = align_cap; + else + align = ceil_pow2 (tree_to_uhwi (TYPE_SIZE (gnu_type))); + + /* But make sure not to under-align the object. */ + if (align <= TYPE_ALIGN (gnu_type)) + align = 0; + + /* And honor the minimum valid atomic alignment, if any. */ +#ifdef MINIMUM_ATOMIC_ALIGNMENT + else if (align < MINIMUM_ATOMIC_ALIGNMENT) + align = MINIMUM_ATOMIC_ALIGNMENT; +#endif + + return align; +} + /* Verify that TYPE is something we can implement atomically. If not, issue an error for GNAT_ENTITY. COMPONENT_P is true if we are being called to process a component type. */ |