This amends ADJUST_FIELD_ALIGN to always get the type of the field
as argument but make the field itself optional.  All actual target
macro implementations only look at the type of the field but FRV
(which seems to misuse ADJUST_FIELD_ALIGN to do bitfield layout
rather than using one of the three standard ways - Alex/Nick?).

This speeds up min_align_of_type (no longer needs to build a FIELD_DECL)
and thus (IMHO) makes it usable from get_object_alignment.  This
causes us no longer to return bogus answers for indirect accesses to
doubles on i?86 and expand to RTL with proper MEM_ALIGN.  (it also
makes the previous fix for PR79256 no longer necessary)

Bootstrap and regtest running on x86_64-unknown-linux-gnu - is this ok
for trunk at this stage?

grep found a ADJUST_FIELD_ALIGN use in libobjc/encoding.c but that
is fed a C string(!?) as FIELD_DECL so I discounted it as unrelated
(and grep didn't find a way this macro could be defined there)?

Ian, go_field_alignment seems to be basically a copy of min_align_of_type.

CCing maintainers (though the changes are really obvious).  If we were
to solve the FRV "issue" we could get rid of the field-decl arg instead.

Thanks,
Richard.

2017-01-31  Richard Biener  <rguent...@suse.de>

        PR tree-optimization/79256
        PR middle-end/79278
        * builtins.c (get_object_alignment_2): Use min_align_of_type
        to extract alignment for MEM_REFs to honor BIGGEST_FIELD_ALIGNMENT
        and ADJUST_FIELD_ALIGN.

        * doc/tm.texi.in (ADJUST_FIELD_ALIGN): Adjust to take additional
        type parameter.
        * doc/tm.texi: Regenerate.
        * stor-layout.c (layout_decl): Adjust.
        (update_alignment_for_field): Likewise.
        (place_field): Likewise.
        (min_align_of_type): Likewise.
        * config/arc/arc.h (ADJUST_FIELD_ALIGN): Adjust.
        * config/epiphany/epiphany.h (ADJUST_FIELD_ALIGN): Likewise.
        * config/epiphany/epiphany.c (epiphany_adjust_field_align): Likewise.
        * config/frv/frv.h (ADJUST_FIELD_ALIGN): Likewise.
        * config/frv/frv.c (frv_adjust_field_align): Likewise.
        * config/i386/i386.h (ADJUST_FIELD_ALIGN): Likewise.
        * config/i386/i386.c (x86_field_alignment): Likewise.
        * config/rs6000/aix.h (ADJUST_FIELD_ALIGN): Likewise.
        * config/rs6000/darwin.h (ADJUST_FIELD_ALIGN): Likewise.
        * config/rs6000/freebsd64.h (ADJUST_FIELD_ALIGN): Likewise.
        * config/rs6000/linux64.h (ADJUST_FIELD_ALIGN): Likewise.
        * config/rs6000/sysv4.h (ADJUST_FIELD_ALIGN): Likewise.
        * config/rs6000/rs6000.c (rs6000_special_adjust_field_align_p):
         Likewise.

        go/
        * go-backend.c (go_field_alignment): Adjust.

Index: gcc/builtins.c
===================================================================
--- gcc/builtins.c      (revision 245052)
+++ gcc/builtins.c      (working copy)
@@ -334,9 +334,11 @@ get_object_alignment_2 (tree exp, unsign
         Do so only if get_pointer_alignment_1 did not reveal absolute
         alignment knowledge and if using that alignment would
         improve the situation.  */
+      unsigned int talign;
       if (!addr_p && !known_alignment
-         && TYPE_ALIGN (TREE_TYPE (exp)) > align)
-       align = TYPE_ALIGN (TREE_TYPE (exp));
+         && (talign = min_align_of_type (TREE_TYPE (exp)) * BITS_PER_UNIT)
+         && talign > align)
+       align = talign;
       else
        {
          /* Else adjust bitpos accordingly.  */
Index: gcc/config/arc/arc.h
===================================================================
--- gcc/config/arc/arc.h        (revision 245052)
+++ gcc/config/arc/arc.h        (working copy)
@@ -317,8 +317,8 @@ if (GET_MODE_CLASS (MODE) == MODE_INT               \
    construct.
 */
 
-#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
-(TYPE_MODE (strip_array_types (TREE_TYPE (FIELD))) == DFmode \
+#define ADJUST_FIELD_ALIGN(FIELD, TYPE, COMPUTED) \
+(TYPE_MODE (strip_array_types (TYPE)) == DFmode \
  ? MIN ((COMPUTED), 32) : (COMPUTED))
 
 
Index: gcc/config/epiphany/epiphany.c
===================================================================
--- gcc/config/epiphany/epiphany.c      (revision 245052)
+++ gcc/config/epiphany/epiphany.c      (working copy)
@@ -2855,12 +2855,12 @@ epiphany_special_round_type_align (tree
    arrays-at-the-end-of-structs work, like for struct gcov_fn_info in
    libgcov.c .  */
 unsigned
-epiphany_adjust_field_align (tree field, unsigned computed)
+epiphany_adjust_field_align (tree type, unsigned computed)
 {
   if (computed == 32
-      && TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE)
+      && TREE_CODE (type) == ARRAY_TYPE)
     {
-      tree elmsz = TYPE_SIZE (TREE_TYPE (TREE_TYPE (field)));
+      tree elmsz = TYPE_SIZE (TREE_TYPE (type));
 
       if (!tree_fits_uhwi_p (elmsz) || tree_to_uhwi (elmsz) >= 32)
        return 64;
Index: gcc/config/epiphany/epiphany.h
===================================================================
--- gcc/config/epiphany/epiphany.h      (revision 245052)
+++ gcc/config/epiphany/epiphany.h      (working copy)
@@ -187,8 +187,8 @@ along with GCC; see the file COPYING3.
                                       (SPECIFIED_ALIGN)) \
   : MAX ((MANGLED_ALIGN), (SPECIFIED_ALIGN)))
 
-#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
-  epiphany_adjust_field_align((FIELD), (COMPUTED))
+#define ADJUST_FIELD_ALIGN(FIELD, TYPE, COMPUTED) \
+  epiphany_adjust_field_align((TYPE), (COMPUTED))
 
 /* Layout of source language data types.  */
 
Index: gcc/config/frv/frv.c
===================================================================
--- gcc/config/frv/frv.c        (revision 245052)
+++ gcc/config/frv/frv.c        (working copy)
@@ -6482,7 +6482,8 @@ int
 frv_adjust_field_align (tree field, int computed)
 {
   /* Make sure that the bitfield is not wider than the type.  */
-  if (DECL_BIT_FIELD (field)
+  if (field
+      && DECL_BIT_FIELD (field)
       && !DECL_ARTIFICIAL (field))
     {
       tree parent = DECL_CONTEXT (field);
Index: gcc/config/frv/frv.h
===================================================================
--- gcc/config/frv/frv.h        (revision 245052)
+++ gcc/config/frv/frv.h        (working copy)
@@ -331,7 +331,7 @@
    alignment computed in the usual way is COMPUTED.  GCC uses this
    value instead of the value in `BIGGEST_ALIGNMENT' or
    `BIGGEST_FIELD_ALIGNMENT', if defined, for structure fields only.  */
-#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED)                            \
+#define ADJUST_FIELD_ALIGN(FIELD, TYPE, COMPUTED)                      \
   frv_adjust_field_align (FIELD, COMPUTED)
 #endif
 
Index: gcc/config/i386/i386.c
===================================================================
--- gcc/config/i386/i386.c      (revision 245052)
+++ gcc/config/i386/i386.c      (working copy)
@@ -41670,10 +41670,9 @@ x86_file_start (void)
 }
 
 int
-x86_field_alignment (tree field, int computed)
+x86_field_alignment (tree type, int computed)
 {
   machine_mode mode;
-  tree type = TREE_TYPE (field);
 
   if (TARGET_64BIT || TARGET_ALIGN_DOUBLE)
     return computed;
Index: gcc/config/i386/i386.h
===================================================================
--- gcc/config/i386/i386.h      (revision 245052)
+++ gcc/config/i386/i386.h      (working copy)
@@ -847,8 +847,8 @@ extern const char *host_detect_local_cpu
 #define BIGGEST_FIELD_ALIGNMENT 32
 #endif
 #else
-#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
-  x86_field_alignment ((FIELD), (COMPUTED))
+#define ADJUST_FIELD_ALIGN(FIELD, TYPE, COMPUTED) \
+  x86_field_alignment ((TYPE), (COMPUTED))
 #endif
 
 /* If defined, a C expression to compute the alignment given to a
Index: gcc/config/rs6000/aix.h
===================================================================
--- gcc/config/rs6000/aix.h     (revision 245052)
+++ gcc/config/rs6000/aix.h     (working copy)
@@ -218,9 +218,9 @@
 
 /* This now supports a natural alignment mode.  */
 /* AIX word-aligns FP doubles but doubleword-aligns 64-bit ints.  */
-#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
+#define ADJUST_FIELD_ALIGN(FIELD, TYPE, COMPUTED) \
   ((TARGET_ALIGN_NATURAL == 0                                          \
-    && TYPE_MODE (strip_array_types (TREE_TYPE (FIELD))) == DFmode)    \
+    && TYPE_MODE (strip_array_types (TYPE)) == DFmode)                 \
    ? MIN ((COMPUTED), 32)                                              \
    : (COMPUTED))
 
Index: gcc/config/rs6000/darwin.h
===================================================================
--- gcc/config/rs6000/darwin.h  (revision 245052)
+++ gcc/config/rs6000/darwin.h  (working copy)
@@ -319,7 +319,7 @@ extern int darwin_emit_branch_islands;
    suppressed for vector and long double items (both 128 in size).
    There is a dummy use of the FIELD argument to avoid an unused variable
    warning (see PR59496).  */
-#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED)                    \
+#define ADJUST_FIELD_ALIGN(FIELD, TYPE, COMPUTED)              \
   ((void) (FIELD),                                             \
     (TARGET_ALIGN_NATURAL                                      \
      ? (COMPUTED)                                              \
Index: gcc/config/rs6000/freebsd64.h
===================================================================
--- gcc/config/rs6000/freebsd64.h       (revision 245052)
+++ gcc/config/rs6000/freebsd64.h       (working copy)
@@ -365,12 +365,12 @@ extern int dot_symbols;
 
 /* PowerPC64 Linux word-aligns FP doubles when -malign-power is given.  */
 #undef  ADJUST_FIELD_ALIGN
-#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
-  (rs6000_special_adjust_field_align_p ((FIELD), (COMPUTED))           \
+#define ADJUST_FIELD_ALIGN(FIELD, TYPE, COMPUTED) \
+  (rs6000_special_adjust_field_align_p ((TYPE), (COMPUTED))            \
    ? 128                                                                \
    : (TARGET_64BIT                                                      \
       && TARGET_ALIGN_NATURAL == 0                                      \
-      && TYPE_MODE (strip_array_types (TREE_TYPE (FIELD))) == DFmode)   \
+      && TYPE_MODE (strip_array_types (TYPE)) == DFmode)               \
    ? MIN ((COMPUTED), 32)                                               \
    : (COMPUTED))
 
Index: gcc/config/rs6000/linux64.h
===================================================================
--- gcc/config/rs6000/linux64.h (revision 245052)
+++ gcc/config/rs6000/linux64.h (working copy)
@@ -292,12 +292,12 @@ extern int dot_symbols;
 
 /* PowerPC64 Linux word-aligns FP doubles when -malign-power is given.  */
 #undef  ADJUST_FIELD_ALIGN
-#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
-  (rs6000_special_adjust_field_align_p ((FIELD), (COMPUTED))           \
+#define ADJUST_FIELD_ALIGN(FIELD, TYPE, COMPUTED) \
+  (rs6000_special_adjust_field_align_p ((TYPE), (COMPUTED))            \
    ? 128                                                               \
    : (TARGET_64BIT                                                     \
       && TARGET_ALIGN_NATURAL == 0                                     \
-      && TYPE_MODE (strip_array_types (TREE_TYPE (FIELD))) == DFmode)  \
+      && TYPE_MODE (strip_array_types (TYPE)) == DFmode)               \
    ? MIN ((COMPUTED), 32)                                              \
    : (COMPUTED))
 
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c  (revision 245052)
+++ gcc/config/rs6000/rs6000.c  (working copy)
@@ -7972,9 +7972,9 @@ rs6000_data_alignment (tree type, unsign
 /* Previous GCC releases forced all vector types to have 16-byte alignment.  */
 
 bool
-rs6000_special_adjust_field_align_p (tree field, unsigned int computed)
+rs6000_special_adjust_field_align_p (tree type, unsigned int computed)
 {
-  if (TARGET_ALTIVEC && TREE_CODE (TREE_TYPE (field)) == VECTOR_TYPE)
+  if (TARGET_ALTIVEC && TREE_CODE (type) == VECTOR_TYPE)
     {
       if (computed != 128)
        {
Index: gcc/config/rs6000/sysv4.h
===================================================================
--- gcc/config/rs6000/sysv4.h   (revision 245052)
+++ gcc/config/rs6000/sysv4.h   (working copy)
@@ -298,8 +298,8 @@ do {                                                        
                \
 
 /* An expression for the alignment of a structure field FIELD if the
    alignment computed in the usual way is COMPUTED.  */
-#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED)                                  \
-       (rs6000_special_adjust_field_align_p ((FIELD), (COMPUTED))            \
+#define ADJUST_FIELD_ALIGN(FIELD, TYPE, COMPUTED)                            \
+       (rs6000_special_adjust_field_align_p ((TYPE), (COMPUTED))             \
         ? 128 : COMPUTED)
 
 #undef  BIGGEST_FIELD_ALIGNMENT
Index: gcc/doc/tm.texi
===================================================================
--- gcc/doc/tm.texi     (revision 245052)
+++ gcc/doc/tm.texi     (working copy)
@@ -1042,13 +1042,15 @@ structure and union fields only, unless
 by the @code{__attribute__ ((aligned (@var{n})))} construct.
 @end defmac
 
-@defmac ADJUST_FIELD_ALIGN (@var{field}, @var{computed})
-An expression for the alignment of a structure field @var{field} if the
-alignment computed in the usual way (including applying of
-@code{BIGGEST_ALIGNMENT} and @code{BIGGEST_FIELD_ALIGNMENT} to the
+@defmac ADJUST_FIELD_ALIGN (@var{field}, @var{type}, @var{computed})
+An expression for the alignment of a structure field @var{field} of
+type @var{type} if the alignment computed in the usual way (including
+applying of @code{BIGGEST_ALIGNMENT} and @code{BIGGEST_FIELD_ALIGNMENT} to the
 alignment) is @var{computed}.  It overrides alignment only if the
 field alignment has not been set by the
-@code{__attribute__ ((aligned (@var{n})))} construct.
+@code{__attribute__ ((aligned (@var{n})))} construct.  Note that @var{field}
+may be @code{NULL_TREE} in case we just query for the minimum alignment
+of a field of type @var{type} in structure context.
 @end defmac
 
 @defmac MAX_STACK_ALIGNMENT
Index: gcc/go/go-backend.c
===================================================================
--- gcc/go/go-backend.c (revision 245052)
+++ gcc/go/go-backend.c (working copy)
@@ -71,11 +71,7 @@ go_field_alignment (tree t)
 #endif
 
 #ifdef ADJUST_FIELD_ALIGN
-  {
-    tree field ATTRIBUTE_UNUSED;
-    field = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL, t);
-    v = ADJUST_FIELD_ALIGN (field, v);
-  }
+  v = ADJUST_FIELD_ALIGN (NULL_TREE, t, v);
 #endif
 
   return v / BITS_PER_UNIT;
Index: gcc/stor-layout.c
===================================================================
--- gcc/stor-layout.c   (revision 245052)
+++ gcc/stor-layout.c   (working copy)
@@ -718,7 +718,8 @@ layout_decl (tree decl, unsigned int kno
                                     (unsigned) BIGGEST_FIELD_ALIGNMENT));
 #endif
 #ifdef ADJUST_FIELD_ALIGN
-         SET_DECL_ALIGN (decl, ADJUST_FIELD_ALIGN (decl, DECL_ALIGN (decl)));
+         SET_DECL_ALIGN (decl, ADJUST_FIELD_ALIGN (decl, TREE_TYPE (decl),
+                                                   DECL_ALIGN (decl)));
 #endif
        }
 
@@ -1032,7 +1033,7 @@ update_alignment_for_field (record_layou
 
 #ifdef ADJUST_FIELD_ALIGN
          if (! TYPE_USER_ALIGN (type))
-           type_align = ADJUST_FIELD_ALIGN (field, type_align);
+           type_align = ADJUST_FIELD_ALIGN (field, type, type_align);
 #endif
 
          /* Targets might chose to handle unnamed and hence possibly
@@ -1260,7 +1261,7 @@ place_field (record_layout_info rli, tre
 
 #ifdef ADJUST_FIELD_ALIGN
       if (! TYPE_USER_ALIGN (type))
-       type_align = ADJUST_FIELD_ALIGN (field, type_align);
+       type_align = ADJUST_FIELD_ALIGN (field, type, type_align);
 #endif
 
       /* A bit field may not span more units of alignment of its type
@@ -1303,7 +1304,7 @@ place_field (record_layout_info rli, tre
 
 #ifdef ADJUST_FIELD_ALIGN
       if (! TYPE_USER_ALIGN (type))
-       type_align = ADJUST_FIELD_ALIGN (field, type_align);
+       type_align = ADJUST_FIELD_ALIGN (field, type, type_align);
 #endif
 
       if (maximum_field_alignment != 0)
@@ -2411,9 +2412,7 @@ min_align_of_type (tree type)
 #endif
       unsigned int field_align = align;
 #ifdef ADJUST_FIELD_ALIGN
-      tree field = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE, type);
-      field_align = ADJUST_FIELD_ALIGN (field, field_align);
-      ggc_free (field);
+      field_align = ADJUST_FIELD_ALIGN (NULL_TREE, type, field_align);
 #endif
       align = MIN (align, field_align);
     }

Reply via email to