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]

[committed] Revamp handling of uninitialized data on PA


PR 16820 got me looking at the handling of uninitialized data on PA.
I found two areas that weren't being addressed correctly:

1) With SOM, we were placing uninitialized global variables in the data
   section.

2) The HP linker has its own idea on how global common storage should
   be aligned.  MAX_OFILE_ALIGNMENT needed to be updated to reflect this
   reality.

This patch adds a new define for ASM_OUTPUT_ALIGNED_BSS to put global
data in the bss section.  This reduces object module sizes quite a bit.
Secondly, I updated the defines for MAX_OFILE_ALIGNMENT under hpux.
A warning now is generated if a user tries to align global common data
with an alignment greater than that supported by the HP linker.  Finally,
I changed the ASM_OUTPUT_ALIGNED_COMMON and ASM_OUTPUT_ALIGNED_LOCAL
macros to use function calls.  This eliminates the multiple
implementations in pa.h, pa64-hpux.h and pa-pro-end.h.

Tested on hppa2.0w-hp-hpux11.11, hppa64-hp-hpux11.11 and hppa-unknown-linux-gnu.

Dave
-- 
J. David Anglin                                  dave.anglin@nrc-cnrc.gc.ca
National Research Council of Canada              (613) 990-0752 (FAX: 952-6602)

2004-08-05  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>

	* pa.c (pa_asm_output_aligned_bss, pa_asm_output_aligned_common,
	pa_asm_output_aligned_local): New functions.
	* pa-protos.h: Add prototypes for pa_asm_output_aligned_bss,
	pa_asm_output_aligned_common and pa_asm_output_aligned_local.
	* pa-pro-end.h (ASM_OUTPUT_ALIGNED_COMMON): Use
	pa_asm_output_aligned_common.
	(ASM_OUTPUT_ALIGNED_LOCAL): Use pa_asm_output_aligned_local.
	* pa.h (ASM_OUTPUT_ALIGNED_BSS): New macro.
	(ASM_OUTPUT_ALIGNED_COMMON): Use pa_asm_output_aligned_common.
	(ASM_OUTPUT_ALIGNED_LOCAL): Use pa_asm_output_aligned_local.
	* pa64-hpux.h (MAX_OFILE_ALIGNMENT): New macro.
	(ASM_OUTPUT_ALIGNED_COMMON): Use pa_asm_output_aligned_common.
	(ASM_OUTPUT_ALIGNED_LOCAL): Use pa_asm_output_aligned_local.
	* som.h (MAX_OFILE_ALIGNMENT): Provide maximum alignment of global
	common data.

Index: config/pa/pa-pro-end.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/pa/pa-pro-end.h,v
retrieving revision 1.13
diff -u -3 -p -r1.13 pa-pro-end.h
--- config/pa/pa-pro-end.h	23 Aug 2003 01:32:54 -0000	1.13
+++ config/pa/pa-pro-end.h	5 Aug 2004 18:00:48 -0000
@@ -1,5 +1,5 @@
 /* Definitions of target machine for GNU compiler, for PRO.
-   Copyright (C) 1996, 1997, 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 1996, 1997, 2002, 2003, 2004 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -52,27 +52,13 @@ Boston, MA 02111-1307, USA.  */
 #undef STARTFILE_SPEC
 #define STARTFILE_SPEC ""
 
-/* The following two macros are identical to the ones in pa.h.  We need
-   to override the macros in elfos.h on the rtems and pro ports.  */
-
-/* This says how to output an assembler line to define a global common symbol
-   with size SIZE (in bytes) and alignment ALIGN (in bits).  */
-
+/* We need to override the following two macros defined in elfos.h since
+   the .comm directive has a different syntax and it can't be used for
+   local common symbols.  */
 #undef ASM_OUTPUT_ALIGNED_COMMON
-#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGNED)		\
-{ bss_section ();							\
-  assemble_name ((FILE), (NAME));					\
-  fprintf ((FILE), "\t.comm "HOST_WIDE_INT_PRINT_UNSIGNED"\n",		\
-	   MAX ((unsigned HOST_WIDE_INT)(SIZE),				\
-		((unsigned HOST_WIDE_INT)(ALIGNED) / BITS_PER_UNIT)));}
-
-/* This says how to output an assembler line to define a local common symbol
-   with size SIZE (in bytes) and alignment ALIGN (in bits).  */
+#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN)              \
+  pa_asm_output_aligned_common (FILE, NAME, SIZE, ALIGN)
 
 #undef ASM_OUTPUT_ALIGNED_LOCAL
-#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGNED)		\
-{ bss_section ();							\
-  fprintf ((FILE), "\t.align %d\n", ((ALIGNED) / BITS_PER_UNIT));	\
-  assemble_name ((FILE), (NAME));					\
-  fprintf ((FILE), "\n\t.block "HOST_WIDE_INT_PRINT_UNSIGNED"\n",	\
-	   (unsigned HOST_WIDE_INT)(SIZE));}
+#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN)               \
+  pa_asm_output_aligned_local (FILE, NAME, SIZE, ALIGN)
Index: config/pa/pa-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/pa/pa-protos.h,v
retrieving revision 1.35
diff -u -3 -p -r1.35 pa-protos.h
--- config/pa/pa-protos.h	20 Jul 2004 19:52:10 -0000	1.35
+++ config/pa/pa-protos.h	5 Aug 2004 18:00:48 -0000
@@ -152,6 +152,7 @@ extern int cmpib_comparison_operator (rt
 #endif
 
 
+/* Miscellaneous functions in pa.c.  */
 #ifdef TREE_CODE
 extern int reloc_needed (tree);
 #ifdef RTX_CODE
@@ -165,6 +166,16 @@ extern int function_arg_partial_nregs (C
 extern bool pa_return_in_memory (tree, tree);
 #endif /* TREE_CODE */
 
+extern void pa_asm_output_aligned_bss (FILE *, const char *,
+				       unsigned HOST_WIDE_INT,
+				       unsigned int);
+extern void pa_asm_output_aligned_common (FILE *, const char *,
+					  unsigned HOST_WIDE_INT,
+					  unsigned int);
+extern void pa_asm_output_aligned_local (FILE *, const char *,
+					 unsigned HOST_WIDE_INT,
+					 unsigned int);
+
 /* Functions in varasm.c used by pa.c.  */
 extern void readonly_data (void);
 extern void one_only_readonly_data_section (void);
Index: config/pa/pa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/pa/pa.c,v
retrieving revision 1.267
diff -u -3 -p -r1.267 pa.c
--- config/pa/pa.c	29 Jul 2004 15:59:25 -0000	1.267
+++ config/pa/pa.c	5 Aug 2004 18:00:49 -0000
@@ -8169,6 +8169,79 @@ pa_asm_out_destructor (rtx symbol, int p
 }
 #endif
 
+/* This function places uninitialized global data in the bss section.
+   The ASM_OUTPUT_ALIGNED_BSS macro needs to be defined to call this
+   function on the SOM port to prevent uninitialized global data from
+   being placed in the data section.  */
+   
+void
+pa_asm_output_aligned_bss (FILE *stream,
+			   const char *name,
+			   unsigned HOST_WIDE_INT size,
+			   unsigned int align)
+{
+  bss_section ();
+  fprintf (stream, "\t.align %u\n", align / BITS_PER_UNIT);
+
+#ifdef ASM_OUTPUT_TYPE_DIRECTIVE
+  ASM_OUTPUT_TYPE_DIRECTIVE (stream, name, "object");
+#endif
+
+#ifdef ASM_OUTPUT_SIZE_DIRECTIVE
+  ASM_OUTPUT_SIZE_DIRECTIVE (stream, name, size);
+#endif
+
+  fprintf (stream, "\t.align %u\n", align / BITS_PER_UNIT);
+  ASM_OUTPUT_LABEL (stream, name);
+  fprintf (stream, "\t.block "HOST_WIDE_INT_PRINT_UNSIGNED"\n", size);
+}
+
+/* Both the HP and GNU assemblers under HP-UX provide a .comm directive
+   that doesn't allow the alignment of global common storage to be directly
+   specified.  The SOM linker aligns common storage based on the rounded
+   value of the NUM_BYTES parameter in the .comm directive.  It's not
+   possible to use the .align directive as it doesn't affect the alignment
+   of the label associated with a .comm directive.  */
+
+void
+pa_asm_output_aligned_common (FILE *stream,
+			      const char *name,
+			      unsigned HOST_WIDE_INT size,
+			      unsigned int align)
+{
+  bss_section ();
+
+  assemble_name (stream, name);
+  fprintf (stream, "\t.comm "HOST_WIDE_INT_PRINT_UNSIGNED"\n",
+           MAX (size, align / BITS_PER_UNIT));
+}
+
+/* We can't use .comm for local common storage as the SOM linker effectively
+   treats the symbol as universal and uses the same storage for local symbols
+   with the same name in different object files.  The .block directive
+   reserves an uninitialized block of storage.  However, it's not common
+   storage.  Fortunately, GCC never requests common storage with the same
+   name in any given translation unit.  */
+
+void
+pa_asm_output_aligned_local (FILE *stream,
+			     const char *name,
+			     unsigned HOST_WIDE_INT size,
+			     unsigned int align)
+{
+  bss_section ();
+  fprintf (stream, "\t.align %u\n", align / BITS_PER_UNIT);
+
+#ifdef LOCAL_ASM_OP
+  fprintf (stream, "%s", LOCAL_ASM_OP);
+  assemble_name (stream, name);
+  fprintf (stream, "\n");
+#endif
+
+  ASM_OUTPUT_LABEL (stream, name);
+  fprintf (stream, "\t.block "HOST_WIDE_INT_PRINT_UNSIGNED"\n", size);
+}
+
 /* Returns 1 if the 6 operands specified in OPERANDS are suitable for
    use in fmpysub instructions.  */
 int
Index: config/pa/pa.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/pa/pa.h,v
retrieving revision 1.228
diff -u -3 -p -r1.228 pa.h
--- config/pa/pa.h	20 Jul 2004 19:52:10 -0000	1.228
+++ config/pa/pa.h	5 Aug 2004 18:00:49 -0000
@@ -1902,25 +1902,28 @@ do { 									\
   fprintf (FILE, "\t.blockz "HOST_WIDE_INT_PRINT_UNSIGNED"\n",		\
 	   (unsigned HOST_WIDE_INT)(SIZE))
 
+/* This says how to output an assembler line to define an uninitialized
+   global variable with size SIZE (in bytes) and alignment ALIGN (in bits).
+   This macro exists to properly support languages like C++ which do not
+   have common data.  */
+
+#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN)		\
+  pa_asm_output_aligned_bss (FILE, NAME, SIZE, ALIGN)
+  
 /* This says how to output an assembler line to define a global common symbol
    with size SIZE (in bytes) and alignment ALIGN (in bits).  */
 
-#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGNED)  		\
-{ bss_section ();							\
-  assemble_name ((FILE), (NAME));					\
-  fprintf ((FILE), "\t.comm "HOST_WIDE_INT_PRINT_UNSIGNED"\n",		\
-	   MAX ((unsigned HOST_WIDE_INT)(SIZE),				\
-		((unsigned HOST_WIDE_INT)(ALIGNED) / BITS_PER_UNIT)));}
+#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN)  		\
+  pa_asm_output_aligned_common (FILE, NAME, SIZE, ALIGN)
 
 /* This says how to output an assembler line to define a local common symbol
-   with size SIZE (in bytes) and alignment ALIGN (in bits).  */
+   with size SIZE (in bytes) and alignment ALIGN (in bits).  This macro
+   controls how the assembler definitions of uninitialized static variables
+   are output.  */
 
-#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGNED)		\
-{ bss_section ();							\
-  fprintf ((FILE), "\t.align %d\n", ((ALIGNED) / BITS_PER_UNIT));	\
-  assemble_name ((FILE), (NAME));					\
-  fprintf ((FILE), "\n\t.block "HOST_WIDE_INT_PRINT_UNSIGNED"\n",	\
-	   (unsigned HOST_WIDE_INT)(SIZE));}
+#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN)		\
+  pa_asm_output_aligned_local (FILE, NAME, SIZE, ALIGN)
+  
   
 #define ASM_PN_FORMAT "%s___%lu"
 
Index: config/pa/pa64-hpux.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/pa/pa64-hpux.h,v
retrieving revision 1.34
diff -u -3 -p -r1.34 pa64-hpux.h
--- config/pa/pa64-hpux.h	16 Apr 2004 16:48:27 -0000	1.34
+++ config/pa/pa64-hpux.h	5 Aug 2004 18:00:49 -0000
@@ -109,6 +109,17 @@ Boston, MA 02111-1307, USA.  */
 #define MD_STARTFILE_PREFIX_1 "/opt/langtools/lib/pa20_64/"
 #endif
 
+/* This macro specifies the biggest alignment supported by the object
+   file format of this machine.
+
+   The .align directive in the HP assembler allows alignments up to
+   4096 bytes.  However, the maximum alignment of a global common symbol
+   is 16 bytes using HP ld.  For consistency, we use the same limit
+   with GNU ld.  */
+#undef MAX_OFILE_ALIGNMENT
+#define MAX_OFILE_ALIGNMENT                                             \
+  (TREE_PUBLIC (decl) && DECL_COMMON (decl) ? 128 : 32768)
+
 /* Due to limitations in the target structure, it isn't currently possible
    to dynamically switch between the GNU and HP assemblers.  */
 #undef TARGET_GAS
@@ -137,25 +148,16 @@ Boston, MA 02111-1307, USA.  */
 #define HP_FINI_ARRAY_SECTION_ASM_OP	"\t.section\t.fini"
 #define GNU_FINI_ARRAY_SECTION_ASM_OP	"\t.section\t.fini_array"
 
+/* We need to override the following two macros defined in elfos.h since
+   the .comm directive has a different syntax and it can't be used for
+   local common symbols.  */
 #undef ASM_OUTPUT_ALIGNED_COMMON
 #define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN)		\
-do {									\
-  bss_section ();							\
-  assemble_name ((FILE), (NAME));					\
-  fprintf ((FILE), "\t.comm "HOST_WIDE_INT_PRINT_UNSIGNED"\n",		\
-	   MAX ((unsigned HOST_WIDE_INT)(SIZE),				\
-		((unsigned HOST_WIDE_INT)(ALIGN) / BITS_PER_UNIT)));	\
-} while (0)
+  pa_asm_output_aligned_common (FILE, NAME, SIZE, ALIGN)
 
 #undef ASM_OUTPUT_ALIGNED_LOCAL
 #define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN)		\
-do {									\
-  bss_section ();							\
-  fprintf ((FILE), "\t.align %d\n", ((ALIGN) / BITS_PER_UNIT));		\
-  assemble_name ((FILE), (NAME));					\
-  fprintf ((FILE), "\n\t.block "HOST_WIDE_INT_PRINT_UNSIGNED"\n",	\
-	   (unsigned HOST_WIDE_INT)(SIZE));				\
-} while (0)
+  pa_asm_output_aligned_local (FILE, NAME, SIZE, ALIGN)
 
 /* The define in pa.h doesn't work with the alias attribute.  The
    default is ok with the following define for GLOBAL_ASM_OP.  */
Index: config/pa/som.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/pa/som.h,v
retrieving revision 1.48
diff -u -3 -p -r1.48 som.h
--- config/pa/som.h	20 Jul 2004 19:52:11 -0000	1.48
+++ config/pa/som.h	5 Aug 2004 18:00:49 -0000
@@ -371,8 +371,17 @@ do {						\
     (*p++) ();					\
 } while (0)
 
-/* The .align directive in the HP assembler allows up to a 32 alignment.  */
-#define MAX_OFILE_ALIGNMENT 32768
+/* This macro specifies the biggest alignment supported by the object
+   file format of this machine.
+
+   The .align directive in the HP assembler allows alignments up to 4096
+   bytes.  However, the maximum alignment of a global common symbol is 8
+   bytes for objects smaller than the page size (4096 bytes).  For larger
+   objects, the linker provides an alignment of 32 bytes.  */
+#define MAX_OFILE_ALIGNMENT						\
+  (TREE_PUBLIC (decl) && DECL_COMMON (decl)				\
+   ? (host_integerp (DECL_SIZE_UNIT (decl), 1) >= 4096 ? 256 : 64)	\
+   : 32768)
 
 /* The SOM linker hardcodes paths into binaries.  As a result, dotdots
    must be removed from library prefixes to prevent binaries from depending


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