This is the mail archive of the
fortran@gcc.gnu.org
mailing list for the GNU Fortran project.
RFC/Patch for PR fortran/17675
- From: Steve Ellcey <sje at cup dot hp dot com>
- To: fortran at gcc dot gnu dot org, gcc-patches at gcc dot gnu dot org
- Date: Mon, 20 Dec 2004 16:34:15 -0800 (PST)
- Subject: RFC/Patch for PR fortran/17675
- Reply-to: sje at cup dot hp dot com
Here is a patch I created to fix PR fortran/17675. I have some
questions about it and I imagine some changes will be desired before it
is checked in. On IA64 HP-UX this patch reduced my fortran test suite
failures from 95 to 31.
This code is only activated for machines with STRICT_ALIGNMENT set,
should we try to do anything for machines where SLOW_UNALIGNED_ACCESS
is set? Should we add padding for all machines? If alignment doesn't
matter on a machine then I assume the alignment for all types would
be the same and this code would never add any padding.
What is the best way to determine the correct padding to use. I simply
found the type with the largest required alignment, added sufficient
padding to align that field, and let the rest fall where they had to.
Is there a better way to ensure that the maximum amount of data is
properly aligned?
Another question I had was that this change is going to result in a
union tree type being built by create_common with no field at offset
zero. I don't know if that is OK or not. Is a dummy field needed or is
it OK to have a hole in the tree that is created to represent a common
block.
Comments on the patch?
Steve Ellcey
sje@cup.hp.com
2004-12-20 Steve Ellcey <sje@cup.hp.com>
* gcc/fortran/trans-common.c (finish_equivalences): Add padding
to front of common to try and align contents.
*** gcc.orig/gcc/fortran/trans-common.c Mon Dec 20 16:03:31 2004
--- gcc/gcc/fortran/trans-common.c Mon Dec 20 16:31:23 2004
*************** finish_equivalences (gfc_namespace *ns)
*** 753,758 ****
--- 753,789 ----
for (v = current_segment; v; v = v->next)
v->offset -= min_offset;
+ if (STRICT_ALIGNMENT)
+ {
+ /* Find the type with the strictest alignment requirements and
+ ensure it is aligned. Hope that makes most of the others
+ fall into place. */
+
+ unsigned HOST_WIDE_INT max_alignment = 0;
+ HOST_WIDE_INT max_align_offset = 0;
+ HOST_WIDE_INT padding = 0;
+ for (v = current_segment; v; v = v->next)
+ {
+ if (TYPE_ALIGN (v->field) > max_alignment)
+ {
+ max_alignment = TYPE_ALIGN (v->field);
+ max_align_offset = v->offset;
+ }
+ }
+
+ /* If the field with the largest needed alignment isn't already
+ aligned, add padding to front of common (increase everyone's
+ offset) to align that field and hope everything else falls into
+ place. */
+
+ if ((max_align_offset % max_alignment) != 0)
+ {
+ padding = max_alignment - (max_align_offset % max_alignment);
+ for (v = current_segment; v; v = v->next)
+ v->offset += padding;
+ }
+ }
+
current_common = current_segment;
create_common (NULL);
break;