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]
Other format: [Raw text]

RFC/Patch for PR fortran/17675


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;


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