aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2017-09-09 12:29:08 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2017-09-09 12:29:08 +0000
commit89ec98ed7ecf0a52175726cca867d471fcad9811 (patch)
tree69c068c8f67a967e86f534a73ae17a418845d075 /gcc/ada
parent7f46ecf6dcc9047bf659932990e55759a00978c0 (diff)
downloadgcc-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/ChangeLog8
-rw-r--r--gcc/ada/gcc-interface/decl.c98
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. */