This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[PATCH] (was Re: i386 alignment tweaks...) take 2


On Tue, Jun 06, 2000 at 07:13:56AM +0200, Jakub Jelinek wrote:
> On Mon, Jun 05, 2000 at 05:58:54PM -0700, Richard Henderson wrote:
> > The patch is largely ok.
> > 
> > > @@ -2310,6 +2312,7 @@ layout_vtable_decl (binfo, n)
> > >  	 fails on Sparc unless you have 8-byte alignment.  */
> > >        DECL_ALIGN (vtable) = MAX (TYPE_ALIGN (double_type_node),
> > >  				 DECL_ALIGN (vtable));
> > > +      DECL_USER_ALIGN (vtable) |= TYPE_USER_ALIGN (double_type_node);
> > 
> > This shouldn't be.  The user cannot set double_type_node.
> > There are a handfull of other examples of this.
> 
> Ok, will change that.
> 

Here is the updated patch (which includes documentation on
BIGGEST_DEFAULT_FIELD_ALIGNMENT so that the difference between the two
macros is clear).

2000-06-06  Jakub Jelinek  <jakub@redhat.com>

	* tree.h (TYPE_USER_ALIGN, DECL_USER_ALIGN): Define.
	(struct tree_type, struct tree_decl): Add user_align member.
	* stor-layout.c (layout_decl): Set DECL_USER_ALIGN.
	(place_union_field): If BIGGEST_DEFAULT_FIELD_ALIGNMENT is defined
	and DECL_USER_ALIGN 0, cap alignment to this value.
	(place_field): Likewise.
	(finalize_type_size): Set TYPE_USER_ALIGN.
	(layout_type): Likewise.
	(initialize_sizetypes): Likewise.
	* c-common.c (decl_attributes): Set TYPE_USER_ALIGN resp.
	DECL_USER_ALIGN to 1.
	* c-decl.c (duplicate_decls): Set DECL_USER_ALIGN.
	(xfer_tag): Set TYPE_USER_ALIGN.
	(finish_struct): Set DECL_USER_ALIGN resp. TYPE_USER_ALIGN.
	(finish_enum): Likewise.
	* stmt.c (expand_decl): Set DECL_USER_ALIGN.
	(expand_anon_union_decl): Likewise.
	* tree.c (make_node): Set DECL_USER_ALIGN resp. TYPE_USER_ALIGN.
	(build_index_type): Set TYPE_USER_ALIGN.
	(build_range_type): Likewise.
	(build_common_tree_nodes_2): Likewise.
	* config/i386/i386.h (BIGGEST_FIELD_ALIGNMENT): Remove.
	(BIGGEST_DEFAULT_FIELD_ALIGNMENT): Define.
	* tm.texi (BIGGEST_DEFAULT_FIELD_ALIGNMENT): Document it.

ch/:
	* decl.c (init_decl_processing): Set TYPE_USER_ALIGN.
	(layout_enum): Set DECL_USER_ALIGN resp. TYPE_USER_ALIGN.
	* typeck.c (layout_chill_range_type): Set TYPE_USER_ALIGN.
	(apply_chill_field_layout): Set DECL_USER_ALIGN.
	(layout_chill_struct_type): Set TYPE_USER_ALIGN.

cp/:
	* class.c (build_secondary_vtable): Set DECL_USER_ALIGN.
	(check_bitfield_decl, check_field_decl): Likewise.
	(build_vtbl_or_vbase_field, build_base_field): Likewise.
	(layout_class_type): Set DECL_USER_ALIGN resp. CLASSTYPE_USER_ALIGN.
	* decl.c (record_unknown_type): Set TYPE_USER_ALIGN.
	(xfer_tag, finish_enum): Likewise.
	* decl2.c (finish_builtin_type): Likewise.
	* init.c (init_init_processing): Likewise.
	* pt.c (instantiate_class_template): Likewise.
	* rtti.c (get_tinfo_decl, synthesize_tinfo_fn): Set DECL_USER_ALIGN.
	* cp-tree.h (struct lang_type): Add user_align member.
	(CLASSTYPE_USER_ALIGN): Define.

f/:
	* com.c (ffecom_transform_common_): Set DECL_USER_ALIGN.
	(ffecom_transform_equiv_, ffecom_decl_field): Likewise.
	(ffecom_init_0): Set DECL_USER_ALIGN resp. TYPE_USER_ALIGN.
	(duplicate_decls): Set DECL_USER_ALIGN.

java/:
	* typeck.c (build_java_array_type): Set TYPE_USER_ALIGN.
	* parse.c (java_complete_class): Set DECL_USER_ALIGN.

--- gcc/ch/decl.c.jj	Sun May 21 21:13:23 2000
+++ gcc/ch/decl.c	Mon Jun  5 11:17:51 2000
@@ -3447,6 +3447,7 @@ init_decl_processing ()
   /* We are not going to have real types in C with less than byte alignment,
      so we might as well not have any types that claim to have it.  */
   TYPE_ALIGN (void_type_node) = BITS_PER_UNIT;
+  TYPE_USER_ALIGN (void_type_node) = 0;
 
   /* This is for wide string constants.  */
   wchar_type_node = short_unsigned_type_node;
@@ -4596,6 +4597,7 @@ layout_enum (enumtype)
       DECL_SIZE (decl) = TYPE_SIZE (enumtype);
       DECL_SIZE_UNIT (decl) = TYPE_SIZE_UNIT (enumtype);
       DECL_ALIGN (decl) = TYPE_ALIGN (enumtype);
+      DECL_USER_ALIGN (decl) = TYPE_USER_ALIGN (enumtype);
 
       /* Set the TREE_VALUE to the name, rather than the decl,
 	 since that is what the rest of the compiler expects. */
@@ -4612,6 +4614,7 @@ layout_enum (enumtype)
       TYPE_MODE (tem) = TYPE_MODE (enumtype);
       TYPE_PRECISION (tem) = TYPE_PRECISION (enumtype);
       TYPE_ALIGN (tem) = TYPE_ALIGN (enumtype);
+      TYPE_USER_ALIGN (tem) = TYPE_USER_ALIGN (enumtype);
       TREE_UNSIGNED (tem) = TREE_UNSIGNED (enumtype);
     }
 
--- gcc/ch/typeck.c.jj	Mon Mar 27 12:20:01 2000
+++ gcc/ch/typeck.c	Mon Jun  5 11:18:23 2000
@@ -2725,6 +2725,7 @@ layout_chill_range_type (rangetype, must
   TYPE_SIZE (rangetype) = TYPE_SIZE (type);
   TYPE_SIZE_UNIT (rangetype) = TYPE_SIZE_UNIT (type);
   TYPE_ALIGN (rangetype) = TYPE_ALIGN (type);
+  TYPE_USER_ALIGN (rangetype) = TYPE_USER_ALIGN (type);
   TREE_UNSIGNED (rangetype) = TREE_UNSIGNED (type);
   CH_NOVELTY (rangetype) = CH_NOVELTY (type);
   return rangetype;
@@ -3113,7 +3114,10 @@ apply_chill_field_layout (decl, next_str
 	  DECL_SIZE (decl) = bitsize_int (natural_length);
 	}
       else
-	DECL_ALIGN (decl) = BITS_PER_UNIT;
+	{
+	  DECL_ALIGN (decl) = BITS_PER_UNIT;
+	  DECL_USER_ALIGN (decl) = 0;
+	}
 
       DECL_PACKED (decl) = 1;
       *next_struct_offset += natural_length;
@@ -3351,6 +3355,7 @@ layout_chill_struct_type (t)
       TYPE_FIELDS (x) = TYPE_FIELDS (t);
       TYPE_LANG_SPECIFIC (x) = TYPE_LANG_SPECIFIC (t);
       TYPE_ALIGN (x) = TYPE_ALIGN (t);
+      TYPE_USER_ALIGN (x) = TYPE_USER_ALIGN (t);
     }
 
   resume_momentary (old_momentary);
--- gcc/cp/class.c.jj	Thu Jun  1 11:56:54 2000
+++ gcc/cp/class.c	Tue Jun  6 21:02:09 2000
@@ -968,6 +968,7 @@ build_secondary_vtable (binfo, for_type)
 
   new_decl = build_vtable (for_type, name, TREE_TYPE (orig_decl));
   DECL_ALIGN (new_decl) = DECL_ALIGN (orig_decl);
+  DECL_USER_ALIGN (new_decl) = DECL_USER_ALIGN (orig_decl);
   BINFO_VTABLE (binfo) = pushdecl_top_level (new_decl);
 
 #ifdef GATHER_STATISTICS
@@ -3152,8 +3153,11 @@ check_bitfield_decl (field)
 #endif
 #ifdef PCC_BITFIELD_TYPE_MATTERS
 	  if (PCC_BITFIELD_TYPE_MATTERS)
-	    DECL_ALIGN (field) = MAX (DECL_ALIGN (field), 
-				      TYPE_ALIGN (type));
+	    {
+	      DECL_ALIGN (field) = MAX (DECL_ALIGN (field), 
+					TYPE_ALIGN (type));
+	      DECL_USER_ALIGN (field) |= TYPE_USER_ALIGN (type);
+	    }
 #endif
 	}
     }
@@ -3163,6 +3167,7 @@ check_bitfield_decl (field)
       DECL_BIT_FIELD (field) = 0;
       CLEAR_DECL_C_BIT_FIELD (field);
       DECL_ALIGN (field) = MAX (DECL_ALIGN (field), TYPE_ALIGN (type));
+      DECL_USER_ALIGN (field) |= TYPE_USER_ALIGN (type);
     }
 }
 
@@ -3253,6 +3258,8 @@ check_field_decl (field, t, cant_have_co
 			    (DECL_PACKED (field) 
 			     ? BITS_PER_UNIT
 			     : TYPE_ALIGN (TREE_TYPE (field))));
+  if (! DECL_PACKED (field))
+    DECL_USER_ALIGN (field) |= TYPE_USER_ALIGN (TREE_TYPE (field));
 }
 
 /* Check the data members (both static and non-static), class-scoped
@@ -3552,6 +3559,7 @@ build_vtbl_or_vbase_field (name, assembl
   DECL_FIELD_CONTEXT (field) = class_type;
   DECL_FCONTEXT (field) = fcontext;
   DECL_ALIGN (field) = TYPE_ALIGN (type);
+  DECL_USER_ALIGN (field) = TYPE_USER_ALIGN (type);
 
   /* Return it.  */
   return field;
@@ -3771,6 +3779,7 @@ build_base_field (rli, binfo, empty_p, b
   DECL_SIZE (decl) = CLASSTYPE_SIZE (basetype);
   DECL_SIZE_UNIT (decl) = CLASSTYPE_SIZE_UNIT (basetype);
   DECL_ALIGN (decl) = CLASSTYPE_ALIGN (basetype);
+  DECL_USER_ALIGN (decl) = CLASSTYPE_USER_ALIGN (basetype);
   
   if (! flag_new_abi)
     {
@@ -4727,6 +4736,7 @@ layout_class_type (t, empty_p, vfuns_p, 
 				TYPE_SIZE (integer_type));
 	  DECL_SIZE (field) = TYPE_SIZE (integer_type);
 	  DECL_ALIGN (field) = TYPE_ALIGN (integer_type);
+	  DECL_USER_ALIGN (field) = TYPE_USER_ALIGN (integer_type);
 	}
       else
 	padding = NULL_TREE;
@@ -4748,6 +4758,7 @@ layout_class_type (t, empty_p, vfuns_p, 
 	  DECL_BIT_FIELD (padding_field) = 1;
 	  DECL_SIZE (padding_field) = padding;
 	  DECL_ALIGN (padding_field) = 1;
+	  DECL_USER_ALIGN (padding_field) = 0;
 	  layout_nonempty_base_or_field (rli, padding_field, NULL_TREE, v);
 	}
     }
@@ -4824,6 +4835,7 @@ layout_class_type (t, empty_p, vfuns_p, 
     }
 
   CLASSTYPE_ALIGN (t) = TYPE_ALIGN (t);
+  CLASSTYPE_USER_ALIGN (t) = TYPE_USER_ALIGN (t);
 
   /* Set the TYPE_DECL for this type to contain the right
      value for DECL_OFFSET, so that we can use it as part
--- gcc/cp/decl.c.jj	Thu Jun  1 11:56:54 2000
+++ gcc/cp/decl.c	Tue Jun  6 21:04:37 2000
@@ -6182,6 +6182,7 @@ record_unknown_type (type, name)
   TYPE_DECL_SUPPRESS_DEBUG (decl) = 1;
   TYPE_SIZE (type) = TYPE_SIZE (void_type_node);
   TYPE_ALIGN (type) = 1;
+  TYPE_USER_ALIGN (type) = 0;
   TYPE_MODE (type) = TYPE_MODE (void_type_node);
 }
 
@@ -12850,6 +12851,7 @@ xref_tag (code_type_node, name, globaliz
 	     to avoid crashing if it does not get defined.  */
 	  TYPE_MODE (ref) = TYPE_MODE (unsigned_type_node);
 	  TYPE_ALIGN (ref) = TYPE_ALIGN (unsigned_type_node);
+	  TYPE_USER_ALIGN (ref) = 0;
 	  TREE_UNSIGNED (ref) = 1;
 	  TYPE_PRECISION (ref) = TYPE_PRECISION (unsigned_type_node);
 	  TYPE_MIN_VALUE (ref) = TYPE_MIN_VALUE (unsigned_type_node);
@@ -13263,6 +13265,7 @@ finish_enum (enumtype)
 	  TYPE_MODE (tem) = TYPE_MODE (enumtype);
 	  TYPE_PRECISION (tem) = TYPE_PRECISION (enumtype);
 	  TYPE_ALIGN (tem) = TYPE_ALIGN (enumtype);
+	  TYPE_USER_ALIGN (tem) = TYPE_USER_ALIGN (enumtype);
 	  TREE_UNSIGNED (tem) = TREE_UNSIGNED (enumtype);
 	}
 
--- gcc/cp/decl2.c.jj	Thu Jun  1 11:56:54 2000
+++ gcc/cp/decl2.c	Mon Jun  5 10:39:10 2000
@@ -2292,6 +2292,7 @@ finish_builtin_type (type, name, fields,
     }
   DECL_FIELD_CONTEXT (fields[i]) = type;
   TYPE_ALIGN (type) = TYPE_ALIGN (align_type);
+  TYPE_USER_ALIGN (type) = TYPE_USER_ALIGN (align_type);
   layout_type (type);
 #if 0 /* not yet, should get fixed properly later */
   TYPE_NAME (type) = make_type_decl (get_identifier (name), type);
--- gcc/cp/init.c.jj	Thu Jun  1 11:56:55 2000
+++ gcc/cp/init.c	Mon Jun  5 10:40:26 2000
@@ -74,6 +74,7 @@ void init_init_processing ()
   /* Use the biggest alignment supported by the target to prevent operator
      new from returning misaligned pointers. */
   TYPE_ALIGN (BI_header_type) = BIGGEST_ALIGNMENT;
+  TYPE_USER_ALIGN (BI_header_type) = 0;
   finish_builtin_type (BI_header_type, "__new_cookie", fields,
 		       0, BI_header_type);
   BI_header_size = size_in_bytes (BI_header_type);
--- gcc/cp/pt.c.jj	Thu Jun  1 11:56:57 2000
+++ gcc/cp/pt.c	Mon Jun  5 10:40:52 2000
@@ -4846,6 +4846,7 @@ instantiate_class_template (type)
     = TYPE_USES_VIRTUAL_BASECLASSES (pattern);
   TYPE_PACKED (type) = TYPE_PACKED (pattern);
   TYPE_ALIGN (type) = TYPE_ALIGN (pattern);
+  TYPE_USER_ALIGN (type) = TYPE_USER_ALIGN (pattern);
   TYPE_FOR_JAVA (type) = TYPE_FOR_JAVA (pattern); /* For libjava's JArray<T> */
   if (ANON_AGGR_TYPE_P (pattern))
     SET_ANON_AGGR_TYPE_P (type);
--- gcc/cp/rtti.c.jj	Thu Jun  1 11:56:57 2000
+++ gcc/cp/rtti.c	Tue Jun  6 21:06:01 2000
@@ -429,6 +429,7 @@ get_tinfo_decl (type)
       
       DECL_ARTIFICIAL (d) = 1;
       DECL_ALIGN (d) = TYPE_ALIGN (ptr_type_node);
+      DECL_USER_ALIGN (d) = 0;
       TREE_READONLY (d) = 1;
       TREE_STATIC (d) = 1;
       DECL_EXTERNAL (d) = 1;
@@ -1171,6 +1172,7 @@ synthesize_tinfo_fn (fndecl)
   DECL_COMMON (tdecl) = 1;
   TREE_USED (tdecl) = 1;
   DECL_ALIGN (tdecl) = TYPE_ALIGN (ptr_type_node);
+  DECL_USER_ALIGN (tdecl) = 0;
   cp_finish_decl (tdecl, NULL_TREE, NULL_TREE, 0);
 
   /* Begin processing the function.  */
--- gcc/cp/cp-tree.h.jj	Fri Jun  2 16:00:46 2000
+++ gcc/cp/cp-tree.h	Mon Jun  5 11:38:35 2000
@@ -1392,6 +1392,7 @@ struct lang_type
   unsigned has_abstract_assign_ref : 1;
   unsigned non_aggregate : 1;
   unsigned is_partial_instantiation : 1;
+  unsigned user_align : 1;
 
   /* When adding a flag here, consider whether or not it ought to
      apply to a template instance if it applies to the template.  If
@@ -1400,7 +1401,7 @@ struct lang_type
   /* There are some bits left to fill out a 32-bit word.  Keep track
      of this by updating the size of this bitfield whenever you add or
      remove a flag.  */
-  unsigned dummy : 9;
+  unsigned dummy : 8;
       
   int vsize;
   int vfield_parent;
@@ -1634,6 +1635,7 @@ struct lang_type
 #define CLASSTYPE_SIZE(NODE) (TYPE_LANG_SPECIFIC(NODE)->size)
 #define CLASSTYPE_SIZE_UNIT(NODE) (TYPE_LANG_SPECIFIC(NODE)->size_unit)
 #define CLASSTYPE_ALIGN(NODE) (TYPE_LANG_SPECIFIC(NODE)->align)
+#define CLASSTYPE_USER_ALIGN(NODE) (TYPE_LANG_SPECIFIC(NODE)->user_align)
 
 /* The alignment of NODE, without its virtual bases, in bytes.  */
 #define CLASSTYPE_ALIGN_UNIT(NODE) \
--- gcc/f/com.c.jj	Fri May 12 09:52:58 2000
+++ gcc/f/com.c	Mon Jun  5 11:40:21 2000
@@ -8801,6 +8801,7 @@ ffecom_transform_common_ (ffesymbol s)
      this seems easy enough.  */
 
   DECL_ALIGN (cbt) = BIGGEST_ALIGNMENT;
+  DECL_USER_ALIGN (cbt) = 0;
 
   if (is_init && (ffestorag_init (st) == NULL))
     init = ffecom_init_zero_ (cbt);
@@ -8936,6 +8937,7 @@ ffecom_transform_equiv_ (ffestorag eqst)
      this seems easy enough.  */
 
   DECL_ALIGN (eqt) = BIGGEST_ALIGNMENT;
+  DECL_USER_ALIGN (eqt) = 0;
 
   if ((!is_init && ffe_is_init_local_zero ())
       || (is_init && (ffestorag_init (eqst) == NULL)))
@@ -10999,6 +11001,7 @@ ffecom_decl_field (tree context, tree pr
   field = build_decl (FIELD_DECL, get_identifier (name), type);
   DECL_CONTEXT (field) = context;
   DECL_ALIGN (field) = 0;
+  DECL_USER_ALIGN (field) = 0;
   if (prevfield != NULL_TREE)
     TREE_CHAIN (prevfield) = field;
 
@@ -11634,6 +11637,7 @@ ffecom_init_0 ()
   /* We are not going to have real types in C with less than byte alignment,
      so we might as well not have any types that claim to have it.  */
   TYPE_ALIGN (void_type_node) = BITS_PER_UNIT;
+  TYPE_USER_ALIGN (void_type_node) = 0;
 
   string_type_node = build_pointer_type (char_type_node);
 
@@ -12055,6 +12059,7 @@ ffecom_init_0 ()
 	DECL_CONTEXT (ffecom_multi_fields_[i][j])
 	  = ffecom_multi_type_node_;
 	DECL_ALIGN (ffecom_multi_fields_[i][j]) = 0;
+	DECL_USER_ALIGN (ffecom_multi_fields_[i][j]) = 0;
 	TREE_CHAIN (ffecom_multi_fields_[i][j]) = field;
 	field = ffecom_multi_fields_[i][j];
       }
@@ -13783,7 +13788,10 @@ duplicate_decls (tree newdecl, tree oldd
 	  DECL_SIZE_UNIT (newdecl) = DECL_SIZE_UNIT (olddecl);
 	  if (TREE_CODE (olddecl) != FUNCTION_DECL)
 	    if (DECL_ALIGN (olddecl) > DECL_ALIGN (newdecl))
-	      DECL_ALIGN (newdecl) = DECL_ALIGN (olddecl);
+	      {
+		DECL_ALIGN (newdecl) = DECL_ALIGN (olddecl);
+		DECL_USER_ALIGN (newdecl) |= DECL_USER_ALIGN (olddecl);
+	      }
 	}
 
       /* Keep the old rtl since we can safely use it.  */
--- gcc/config/i386/i386.h.jj	Tue May  9 16:08:22 2000
+++ gcc/config/i386/i386.h	Mon Jun  5 11:06:39 2000
@@ -499,14 +499,8 @@ extern int ix86_arch;
 
 /* The published ABIs say that doubles should be aligned on word
    boundaries, so lower the aligment for structure fields unless
-   -malign-double is set.  */
-/* BIGGEST_FIELD_ALIGNMENT is also used in libobjc, where it must be
-   constant.  Use the smaller value in that context.  */
-#ifndef IN_TARGET_LIBS
-#define BIGGEST_FIELD_ALIGNMENT (TARGET_ALIGN_DOUBLE ? 64 : 32)
-#else
-#define BIGGEST_FIELD_ALIGNMENT 32
-#endif
+   -malign-double is set or unless it was overriden by attribute aligned.  */
+#define BIGGEST_DEFAULT_FIELD_ALIGNMENT (TARGET_ALIGN_DOUBLE ? 64 : 32)
 
 /* If defined, a C expression to compute the alignment given to a
    constant that is being placed in memory.  CONSTANT is the constant
--- gcc/java/typeck.c.jj	Sun Mar 19 20:31:23 2000
+++ gcc/java/typeck.c	Mon Jun  5 10:43:04 2000
@@ -421,7 +421,10 @@ build_java_array_type (element_type, len
       TREE_CHAIN (fld) = arfld;
     }
   else
-    TYPE_ALIGN (t) = TYPE_ALIGN (element_type);
+    {
+      TYPE_ALIGN (t) = TYPE_ALIGN (element_type);
+      TYPE_USER_ALIGN (t) = TYPE_USER_ALIGN (element_type);
+    }
   pop_obstacks ();
 
   /* We could layout_class, but that loads java.lang.Object prematurely.
--- gcc/java/parse.c.jj	Fri Jun  2 11:14:43 2000
+++ gcc/java/parse.c	Mon Jun  5 11:41:53 2000
@@ -7949,6 +7949,7 @@ java_complete_class ()
 		pop_obstacks ();
 		TREE_TYPE (field_decl) = field_type;
 		DECL_ALIGN (field_decl) = 0;
+		DECL_USER_ALIGN (field_decl) = 0;
 		layout_decl (field_decl, 0);
 		SOURCE_FRONTEND_DEBUG 
 		  (("Completed field/var decl `%s' with `%s'",
--- gcc/stor-layout.c.jj	Sat Jun  3 08:46:49 2000
+++ gcc/stor-layout.c	Mon Jun  5 11:11:54 2000
@@ -330,7 +330,10 @@ layout_decl (decl, known_align)
       && (DECL_ALIGN (decl) == 0
 	  || (! (code == FIELD_DECL && DECL_PACKED (decl))
 	      && TYPE_ALIGN (type) > DECL_ALIGN (decl))))
-    DECL_ALIGN (decl) = TYPE_ALIGN (type);
+    {	      
+      DECL_ALIGN (decl) = TYPE_ALIGN (type);
+      DECL_USER_ALIGN (decl) = TYPE_USER_ALIGN (type);
+    }
 
   /* For fields, set the bit field type and update the alignment.  */
   if (code == FIELD_DECL)
@@ -339,7 +342,10 @@ layout_decl (decl, known_align)
       if (maximum_field_alignment != 0)
 	DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), maximum_field_alignment);
       else if (DECL_PACKED (decl))
-	DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), BITS_PER_UNIT);
+	{
+	  DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), BITS_PER_UNIT);
+	  DECL_USER_ALIGN (decl) = 0;
+	}
     }
 
   /* See if we can use an ordinary integer mode for a bit-field. 
@@ -572,14 +578,27 @@ place_union_field (rli, field)
      record_layout_info rli;
      tree field;
 {
+  unsigned int desired_align;
+
   layout_decl (field, 0);
   
   DECL_FIELD_OFFSET (field) = size_zero_node;
   DECL_FIELD_BIT_OFFSET (field) = bitsize_zero_node;
   DECL_OFFSET_ALIGN (field) = BIGGEST_ALIGNMENT;
 
+  desired_align = DECL_ALIGN (field);
+
+#ifdef BIGGEST_DEFAULT_FIELD_ALIGNMENT
+  /* Some targets (i.e. i386) limit union field alignment
+     to a lower boundary than alignment of variables unless
+     it was overridden by attribute aligned.  */
+  if (! DECL_USER_ALIGN (field))
+    desired_align =
+      MIN (desired_align, (unsigned) BIGGEST_DEFAULT_FIELD_ALIGNMENT);
+#endif
+
   /* Union must be at least as aligned as any field requires.  */
-  rli->record_align = MAX (rli->record_align, DECL_ALIGN (field));
+  rli->record_align = MAX (rli->record_align, desired_align);
 
 #ifdef PCC_BITFIELD_TYPE_MATTERS
   /* On the m88000, a bit field of declare type `int' forces the
@@ -615,6 +634,7 @@ place_field (rli, field)
      record as it presently stands.  */
   unsigned int known_align;
   unsigned int actual_align;
+  unsigned int user_align;
   /* The type of this field.  */
   tree type = TREE_TYPE (field);
  
@@ -660,10 +680,22 @@ place_field (rli, field)
      packed field, use the alignment as specified, disregarding what
      the type would want.  */
   desired_align = DECL_ALIGN (field);
+  user_align = DECL_USER_ALIGN (field);
   layout_decl (field, known_align);
   if (! DECL_PACKED (field))
-    desired_align = DECL_ALIGN (field);
+    {
+      desired_align = DECL_ALIGN (field);
+      user_align = DECL_USER_ALIGN (field);
+    }
 
+#ifdef BIGGEST_DEFAULT_FIELD_ALIGNMENT
+  /* Some targets (i.e. i386) limit struct field alignment
+     to a lower boundary than alignment of variables unless
+     it was overridden by attribute aligned.  */
+  if (! user_align)
+    desired_align =
+      MIN (desired_align, (unsigned) BIGGEST_DEFAULT_FIELD_ALIGNMENT);
+#endif
   /* Some targets (i.e. VMS) limit struct field alignment
      to a lower boundary than alignment of variables.  */
 #ifdef BIGGEST_FIELD_ALIGNMENT
@@ -902,6 +934,7 @@ finalize_record_size (rli)
 #else
   TYPE_ALIGN (rli->t) = MAX (TYPE_ALIGN (rli->t), rli->record_align);
 #endif
+  TYPE_USER_ALIGN (rli->t) = 1;
 
   /* Compute the size so far.  Be sure to allow for extra bits in the
      size in bytes.  We have guaranteed above that it will be no more
@@ -1083,7 +1116,10 @@ finalize_type_size (type)
 	  || (TREE_CODE (type) != RECORD_TYPE && TREE_CODE (type) != UNION_TYPE
 	      && TREE_CODE (type) != QUAL_UNION_TYPE
 	      && TREE_CODE (type) != ARRAY_TYPE)))
-    TYPE_ALIGN (type) = GET_MODE_ALIGNMENT (TYPE_MODE (type));
+    {
+      TYPE_ALIGN (type) = GET_MODE_ALIGNMENT (TYPE_MODE (type));
+      TYPE_USER_ALIGN (type) = 0;
+    }
 
   /* Do machine-dependent extra alignment.  */
 #ifdef ROUND_TYPE_ALIGN
@@ -1133,6 +1169,7 @@ finalize_type_size (type)
       tree size = TYPE_SIZE (type);
       tree size_unit = TYPE_SIZE_UNIT (type);
       unsigned int align = TYPE_ALIGN (type);
+      unsigned int user_align = TYPE_USER_ALIGN (type);
       enum machine_mode mode = TYPE_MODE (type);
 
       /* Copy it into all variants.  */
@@ -1143,6 +1180,7 @@ finalize_type_size (type)
 	  TYPE_SIZE (variant) = size;
 	  TYPE_SIZE_UNIT (variant) = size_unit;
 	  TYPE_ALIGN (variant) = align;
+	  TYPE_USER_ALIGN (variant) = user_align;
 	  TYPE_MODE (variant) = mode;
 	}
     }
@@ -1259,6 +1297,7 @@ layout_type (type)
     case VOID_TYPE:
       /* This is an incomplete type and so doesn't have a size.  */
       TYPE_ALIGN (type) = 1;
+      TYPE_USER_ALIGN (type) = 0;
       TYPE_MODE (type) = VOIDmode;
       break;
 
@@ -1463,6 +1502,7 @@ layout_type (type)
 	  TYPE_SIZE (type) = bitsize_int (rounded_size);
 	  TYPE_SIZE_UNIT (type) = size_int (rounded_size / BITS_PER_UNIT);
 	  TYPE_ALIGN (type) = alignment;
+	  TYPE_USER_ALIGN (type) = 0;
 	  TYPE_PRECISION (type) = size_in_bits;
 	}
       break;
@@ -1471,6 +1511,7 @@ layout_type (type)
       /* The size may vary in different languages, so the language front end
 	 should fill in the size.  */
       TYPE_ALIGN (type) = BIGGEST_ALIGNMENT;
+      TYPE_USER_ALIGN (type) = 0;
       TYPE_MODE  (type) = BLKmode;
       break;
 
@@ -1537,6 +1578,7 @@ initialize_sizetypes ()
 
   TYPE_MODE (t) = SImode;
   TYPE_ALIGN (t) = GET_MODE_ALIGNMENT (SImode);
+  TYPE_USER_ALIGN (t) = 0;
   TYPE_SIZE (t) = build_int_2 (GET_MODE_BITSIZE (SImode), 0);
   TYPE_SIZE_UNIT (t) = build_int_2 (GET_MODE_SIZE (SImode), 0);
   TREE_UNSIGNED (t) = 1;
--- gcc/c-common.c.jj	Fri Jun  2 14:34:47 2000
+++ gcc/c-common.c	Mon Jun  5 10:11:26 2000
@@ -779,13 +779,19 @@ decl_attributes (node, attributes, prefi
 	    else if (i > HOST_BITS_PER_INT - 2)
 	      error ("requested alignment is too large");
 	    else if (is_type)
-	      TYPE_ALIGN (type) = (1 << i) * BITS_PER_UNIT;
+	      {
+		TYPE_ALIGN (type) = (1 << i) * BITS_PER_UNIT;
+		TYPE_USER_ALIGN (type) = 1;
+	      }
 	    else if (TREE_CODE (decl) != VAR_DECL
 		     && TREE_CODE (decl) != FIELD_DECL)
 	      error_with_decl (decl,
 			       "alignment may not be specified for `%s'");
 	    else
-	      DECL_ALIGN (decl) = (1 << i) * BITS_PER_UNIT;
+	      {
+		DECL_ALIGN (decl) = (1 << i) * BITS_PER_UNIT;
+		DECL_USER_ALIGN (decl) = 1;
+	      }
 	  }
 	  break;
 
--- gcc/tree.h.jj	Thu Jun  1 11:56:43 2000
+++ gcc/tree.h	Mon Jun  5 10:09:01 2000
@@ -928,6 +928,10 @@ struct tree_block
    The value is an int, measured in bits.  */
 #define TYPE_ALIGN(NODE) (TYPE_CHECK (NODE)->type.align)
 
+/* 1 if the alignment for this type was requested by "aligned" attribute,
+   0 if it is the default for this type.  */
+#define TYPE_USER_ALIGN(NODE) (TYPE_CHECK (NODE)->type.user_align)
+
 /* The alignment for NODE, in bytes.  */
 #define TYPE_ALIGN_UNIT(NODE) \
   (TYPE_ALIGN (NODE) / BITS_PER_UNIT)
@@ -1103,6 +1107,7 @@ struct tree_type
   unsigned lang_flag_4 : 1;
   unsigned lang_flag_5 : 1;
   unsigned lang_flag_6 : 1;
+  unsigned user_align : 1;
 
   unsigned int align;
   union tree_node *pointer_to;
@@ -1287,6 +1292,9 @@ struct tree_type
 #define DECL_ALIGN(NODE) (DECL_CHECK (NODE)->decl.u1.a.align)
 /* For FIELD_DECLs, holds the alignment that DECL_FIELD_OFFSET has.  */
 #define DECL_OFFSET_ALIGN(NODE) (FIELD_DECL_CHECK (NODE)->decl.u1.a.off_align)
+/* 1 if the alignment for this type was requested by "aligned" attribute,
+   0 if it is the default for this type.  */
+#define DECL_USER_ALIGN(NODE) (DECL_CHECK (NODE)->decl.user_align)
 /* Holds the machine mode corresponding to the declaration of a variable or
    field.  Always equal to TYPE_MODE (TREE_TYPE (decl)) except for a
    FIELD_DECL.  */
@@ -1576,6 +1584,8 @@ struct tree_decl
   unsigned malloc_flag : 1;
   unsigned no_limit_stack : 1;
   unsigned pure_flag : 1;
+  unsigned user_align : 1;
+
   ENUM_BITFIELD(built_in_class) built_in_class : 2;
   unsigned pointer_depth : 2;
 
--- gcc/c-decl.c.jj	Thu Jun  1 11:56:18 2000
+++ gcc/c-decl.c	Mon Jun  5 10:54:47 2000
@@ -1801,7 +1801,10 @@ duplicate_decls (newdecl, olddecl, diffe
 	  DECL_MODE (newdecl) = DECL_MODE (olddecl);
 	  if (TREE_CODE (olddecl) != FUNCTION_DECL)
 	    if (DECL_ALIGN (olddecl) > DECL_ALIGN (newdecl))
-	      DECL_ALIGN (newdecl) = DECL_ALIGN (olddecl);
+	      {
+		DECL_ALIGN (newdecl) = DECL_ALIGN (olddecl);
+		DECL_USER_ALIGN (newdecl) |= DECL_ALIGN (olddecl);
+	      }
 	}
 
       /* Keep the old rtl since we can safely use it.  */
@@ -5103,6 +5106,7 @@ xref_tag (code, name)
 	 to avoid crashing if it does not get defined.  */
       TYPE_MODE (ref) = TYPE_MODE (unsigned_type_node);
       TYPE_ALIGN (ref) = TYPE_ALIGN (unsigned_type_node);
+      TYPE_USER_ALIGN (ref) = 0;
       TREE_UNSIGNED (ref) = 1;
       TYPE_PRECISION (ref) = TYPE_PRECISION (unsigned_type_node);
       TYPE_MIN_VALUE (ref) = TYPE_MIN_VALUE (unsigned_type_node);
@@ -5329,8 +5333,11 @@ finish_struct (t, fieldlist, attributes)
 #endif
 #ifdef PCC_BITFIELD_TYPE_MATTERS
 		  if (PCC_BITFIELD_TYPE_MATTERS)
-		    DECL_ALIGN (x) = MAX (DECL_ALIGN (x),
-					  TYPE_ALIGN (TREE_TYPE (x)));
+		    {
+		      DECL_ALIGN (x) = MAX (DECL_ALIGN (x),
+					    TYPE_ALIGN (TREE_TYPE (x)));
+		      DECL_USER_ALIGN (x) |= TYPE_USER_ALIGN (TREE_TYPE (x));
+		    }
 #endif
 		}
 	    }
@@ -5344,6 +5351,8 @@ finish_struct (t, fieldlist, attributes)
 	  /* Non-bit-fields are aligned for their type, except packed
 	     fields which require only BITS_PER_UNIT alignment.  */
 	  DECL_ALIGN (x) = MAX (DECL_ALIGN (x), min_align);
+	  if (! DECL_PACKED (x))
+	    DECL_USER_ALIGN (x) |= TYPE_USER_ALIGN (TREE_TYPE (x));
 	}
 
       DECL_INITIAL (x) = 0;
@@ -5401,6 +5410,7 @@ finish_struct (t, fieldlist, attributes)
       TYPE_FIELDS (x) = TYPE_FIELDS (t);
       TYPE_LANG_SPECIFIC (x) = TYPE_LANG_SPECIFIC (t);
       TYPE_ALIGN (x) = TYPE_ALIGN (t);
+      TYPE_USER_ALIGN (x) = TYPE_USER_ALIGN (t);
     }
 
   /* If this was supposed to be a transparent union, but we can't
@@ -5585,6 +5595,7 @@ finish_enum (enumtype, values, attribute
 	  DECL_SIZE (enu) = TYPE_SIZE (enumtype);
 	  DECL_SIZE_UNIT (enu) = TYPE_SIZE_UNIT (enumtype);
 	  DECL_ALIGN (enu) = TYPE_ALIGN (enumtype);
+	  DECL_USER_ALIGN (enu) = TYPE_USER_ALIGN (enumtype);
 	  DECL_MODE (enu) = TYPE_MODE (enumtype);
 	  DECL_INITIAL (enu) = convert (enumtype, DECL_INITIAL (enu));
 
@@ -5608,6 +5619,7 @@ finish_enum (enumtype, values, attribute
       TYPE_MODE (tem) = TYPE_MODE (enumtype);
       TYPE_PRECISION (tem) = TYPE_PRECISION (enumtype);
       TYPE_ALIGN (tem) = TYPE_ALIGN (enumtype);
+      TYPE_USER_ALIGN (tem) = TYPE_USER_ALIGN (enumtype);
       TREE_UNSIGNED (tem) = TREE_UNSIGNED (enumtype);
     }
 
--- gcc/stmt.c.jj	Sat Jun  3 08:46:44 2000
+++ gcc/stmt.c	Mon Jun  5 10:57:32 2000
@@ -3848,6 +3848,7 @@ expand_decl (decl)
       /* Set alignment we actually gave this decl.  */
       DECL_ALIGN (decl) = (DECL_MODE (decl) == BLKmode ? BIGGEST_ALIGNMENT
 			   : GET_MODE_BITSIZE (DECL_MODE (decl)));
+      DECL_USER_ALIGN (decl) = 0;
 
       if (oldaddr)
 	{
@@ -3900,6 +3901,7 @@ expand_decl (decl)
 #else
       DECL_ALIGN (decl) = BIGGEST_ALIGNMENT;
 #endif
+      DECL_USER_ALIGN (decl) = 0;
     }
 }
 
@@ -4203,6 +4205,7 @@ expand_anon_union_decl (decl, cleanup, d
 
       /* Propagate the union's alignment to the elements.  */
       DECL_ALIGN (decl_elt) = DECL_ALIGN (decl);
+      DECL_USER_ALIGN (decl_elt) = DECL_USER_ALIGN (decl);
 
       /* If the element has BLKmode and the union doesn't, the union is
          aligned such that the element doesn't need to have BLKmode, so
--- gcc/tree.c.jj	Thu Jun  1 11:56:43 2000
+++ gcc/tree.c	Mon Jun  5 11:02:55 2000
@@ -1064,6 +1064,7 @@ make_node (code)
     case 'd':
       if (code != FUNCTION_DECL)
 	DECL_ALIGN (t) = 1;
+      DECL_USER_ALIGN (t) = 0;
       DECL_IN_SYSTEM_HEADER (t) = in_system_header;
       DECL_SOURCE_LINE (t) = lineno;
       DECL_SOURCE_FILE (t) = 
@@ -1077,6 +1078,7 @@ make_node (code)
     case 't':
       TYPE_UID (t) = next_type_uid++;
       TYPE_ALIGN (t) = 1;
+      TYPE_USER_ALIGN (t) = 0;
       TYPE_MAIN_VARIANT (t) = t;
       TYPE_OBSTACK (t) = obstack;
       TYPE_ATTRIBUTES (t) = NULL_TREE;
@@ -4651,6 +4653,7 @@ build_index_type (maxval)
   TYPE_SIZE (itype) = TYPE_SIZE (sizetype);
   TYPE_SIZE_UNIT (itype) = TYPE_SIZE_UNIT (sizetype);
   TYPE_ALIGN (itype) = TYPE_ALIGN (sizetype);
+  TYPE_USER_ALIGN (itype) = TYPE_USER_ALIGN (sizetype);
 
   if (host_integerp (maxval, 1))
     return type_hash_canon (tree_low_cst (maxval, 1), itype);
@@ -4683,6 +4686,7 @@ build_range_type (type, lowval, highval)
   TYPE_SIZE (itype) = TYPE_SIZE (type);
   TYPE_SIZE_UNIT (itype) = TYPE_SIZE_UNIT (type);
   TYPE_ALIGN (itype) = TYPE_ALIGN (type);
+  TYPE_USER_ALIGN (itype) = TYPE_USER_ALIGN (type);
 
   if (host_integerp (lowval, 0) && highval != 0 && host_integerp (highval, 0))
     return type_hash_canon (tree_low_cst (highval, 0)
@@ -5716,6 +5720,7 @@ build_common_tree_nodes_2 (short_double)
   /* We are not going to have real types in C with less than byte alignment,
      so we might as well not have any types that claim to have it.  */
   TYPE_ALIGN (void_type_node) = BITS_PER_UNIT;
+  TYPE_USER_ALIGN (void_type_node) = 0;
 
   null_pointer_node = build_int_2 (0, 0);
   TREE_TYPE (null_pointer_node) = build_pointer_type (void_type_node);
--- gcc/tm.texi.jj	Tue Jun  6 21:12:51 2000
+++ gcc/tm.texi	Tue Jun  6 21:19:01 2000
@@ -853,6 +853,13 @@ Biggest alignment that any structure fie
 in bits.  If defined, this overrides @code{BIGGEST_ALIGNMENT} for
 structure fields only.
 
+@findex BIGGEST_DEFAULT_FIELD_ALIGNMENT
+@item BIGGEST_DEFAULT_FIELD_ALIGNMENT
+Biggest alignment that any structure or union field can require on this
+machine, in bits.  If defined, this overrides @code{BIGGEST_ALIGNMENT} for
+structure and union fields only, unless the field alignment has been set
+by the @code{__attribute__ ((aligned (@var{n})))} construct.
+
 @findex ADJUST_FIELD_ALIGN
 @item ADJUST_FIELD_ALIGN (@var{field}, @var{computed})
 An expression for the alignment of a structure field @var{field} if the


	Jakub

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]