* tree.h (struct record_layout_info_s): New field unpadded_align.
authorkenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 2 Jun 2001 11:14:06 +0000 (11:14 +0000)
committerkenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 2 Jun 2001 11:14:06 +0000 (11:14 +0000)
(set_lang_adjust_rli): New declaration.
* stor-layout.c (layout_decl): If DECL is packed, but at alignment
it would have if not packed, do not downgrade DECL_ALIGN.
(lang_adjust_rli, set_lang_adjust_rli): New.
(start_record_layout): Initialize new field unpadded_align.
(debug_rli): Display it.
(place_union_field, place_field): Set it.
(layout_type, case RECORD_TYPE): Call via lang_adjust_rli if set.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@42796 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/stor-layout.c
gcc/tree.h

index 77305ee..fad7c99 100644 (file)
@@ -1,5 +1,15 @@
 Sat Jun  2 06:53:50 2001  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>
 
+       * tree.h (struct record_layout_info_s): New field unpadded_align.
+       (set_lang_adjust_rli): New declaration.
+       * stor-layout.c (layout_decl): If DECL is packed, but at alignment
+       it would have if not packed, do not downgrade DECL_ALIGN.
+       (lang_adjust_rli, set_lang_adjust_rli): New.
+       (start_record_layout): Initialize new field unpadded_align.
+       (debug_rli): Display it.
+       (place_union_field, place_field): Set it.
+       (layout_type, case RECORD_TYPE): Call via lang_adjust_rli if set.
+
        * print-tree.c (print_node): Don't print "regdecl" when bit doesn't
        mean that; use proper names instead.
        Print DECL_NO_STATIC_CHAIN.
index a278eb1..52e23cb 100644 (file)
@@ -381,7 +381,7 @@ layout_decl (decl, known_align)
       DECL_BIT_FIELD_TYPE (decl) = DECL_BIT_FIELD (decl) ? type : 0;
       if (maximum_field_alignment != 0)
        DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), maximum_field_alignment);
-      else if (DECL_PACKED (decl))
+      else if (DECL_PACKED (decl) && known_align % DECL_ALIGN (decl) != 0)
        {
          DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), BITS_PER_UNIT);
          DECL_USER_ALIGN (decl) = 0;
@@ -444,6 +444,18 @@ layout_decl (decl, known_align)
     }
 }
 \f
+/* Hook for a front-end function that can modify the record layout as needed
+   immediately before it is finalized.  */
+
+void (*lang_adjust_rli) PARAMS ((record_layout_info)) = 0;
+
+void
+set_lang_adjust_rli (f)
+     void (*f) PARAMS ((record_layout_info));
+{
+  lang_adjust_rli = f;
+}
+
 /* Begin laying out type T, which may be a RECORD_TYPE, UNION_TYPE, or
    QUAL_UNION_TYPE.  Return a pointer to a struct record_layout_info which
    is to be passed to all other layout functions for this record.  It is the
@@ -464,7 +476,7 @@ start_record_layout (t)
      declaration, for example) use it -- otherwise, start with a
      one-byte alignment.  */
   rli->record_align = MAX (BITS_PER_UNIT, TYPE_ALIGN (t));
-  rli->unpacked_align = rli->record_align;
+  rli->unpacked_align = rli->unpadded_align = rli->record_align;
   rli->offset_align = MAX (rli->record_align, BIGGEST_ALIGNMENT);
 
 #ifdef STRUCTURE_SIZE_BOUNDARY
@@ -571,8 +583,9 @@ debug_rli (rli)
   print_node_brief (stderr, "\noffset", rli->offset, 0);
   print_node_brief (stderr, " bitpos", rli->bitpos, 0);
 
-  fprintf (stderr, "\nrec_align = %u, unpack_align = %u, off_align = %u\n",
-          rli->record_align, rli->unpacked_align, rli->offset_align);
+  fprintf (stderr, "\naligns: rec = %u, unpack = %u, unpad = %u, off = %u\n",
+          rli->record_align, rli->unpacked_align, rli->unpadded_align,
+          rli->offset_align);
   if (rli->packed_maybe_necessary)
     fprintf (stderr, "packed may be necessary\n");
 
@@ -639,13 +652,18 @@ place_union_field (rli, field)
 
   /* Union must be at least as aligned as any field requires.  */
   rli->record_align = MAX (rli->record_align, desired_align);
+  rli->unpadded_align = MAX (rli->unpadded_align, desired_align);
 
 #ifdef PCC_BITFIELD_TYPE_MATTERS
   /* On the m88000, a bit field of declare type `int' forces the
      entire union to have `int' alignment.  */
   if (PCC_BITFIELD_TYPE_MATTERS && DECL_BIT_FIELD_TYPE (field))
-    rli->record_align = MAX (rli->record_align, 
-                            TYPE_ALIGN (TREE_TYPE (field)));
+    {
+      rli->record_align = MAX (rli->record_align, 
+                              TYPE_ALIGN (TREE_TYPE (field)));
+      rli->unpadded_align = MAX (rli->unpadded_align,
+                                TYPE_ALIGN (TREE_TYPE (field)));
+    }
 #endif
 
   /* We assume the union's size will be a multiple of a byte so we don't
@@ -773,9 +791,9 @@ place_field (rli, field)
            type_align = MIN (type_align, BITS_PER_UNIT);
 
          rli->record_align = MAX (rli->record_align, type_align);
+         rli->unpadded_align = MAX (rli->unpadded_align, DECL_ALIGN (field));
          if (warn_packed)
-           rli->unpacked_align = MAX (rli->unpacked_align, 
-                                      TYPE_ALIGN (type));
+           rli->unpacked_align = MAX (rli->unpacked_align, TYPE_ALIGN (type));
        }
     }
   else
@@ -783,6 +801,7 @@ place_field (rli, field)
     {
       rli->record_align = MAX (rli->record_align, desired_align);
       rli->unpacked_align = MAX (rli->unpacked_align, TYPE_ALIGN (type));
+      rli->unpadded_align = MAX (rli->unpadded_align, DECL_ALIGN (field));
     }
 
   if (warn_packed && DECL_PACKED (field))
@@ -1498,6 +1517,9 @@ layout_type (type)
        if (TREE_CODE (type) == QUAL_UNION_TYPE)
          TYPE_FIELDS (type) = nreverse (TYPE_FIELDS (type));
 
+       if (lang_adjust_rli)
+         (*lang_adjust_rli) (rli);
+
        /* Finish laying out the record.  */
        finish_record_layout (rli);
       }
index 6821b06..af784ad 100644 (file)
@@ -2118,12 +2118,17 @@ typedef struct record_layout_info_s
   unsigned int record_align;
   /* The alignment of the record so far, not including padding, in bits.  */
   unsigned int unpacked_align;
+  /* The alignment of the record so far, allowing for the record to be
+     padded only at the end, in bits.  */
+  unsigned int unpadded_align;
   /* The static variables (i.e., class variables, as opposed to
      instance variables) encountered in T.  */
   tree pending_statics;
   int packed_maybe_necessary;
 } *record_layout_info;
 
+extern void set_lang_adjust_rli                PARAMS ((void (*) PARAMS
+                                                ((record_layout_info))));
 extern record_layout_info start_record_layout PARAMS ((tree));
 extern tree bit_from_pos               PARAMS ((tree, tree));
 extern tree byte_from_pos              PARAMS ((tree, tree));