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]

[3.4 committed] HP-UX 10.x one-only support


After a considerable amount of consideration, I decided to install
the following backport of several patches to provide one-only support
under HP-UX 10.20.  Without this patch, C++ is essentially unusable
on HP-UX 10.x.  We have already had a change in the treatment of common
variables in 3.3 and 3.4, so another change probably isn't going to add
to the problems.

Tested on hppa1.1-hp-hpux10.20, hppa2.0w-hp-hpux11.11 and
hppa64-hp-hpux11.11.  Committed to 3.4 branch.

The regression still exists on the 3.3 branch.

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

2004-12-27  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>

	PR c++/14607.
	Backported from main.
	* configure.ac (HAVE_GAS_NSUBSPA_COMDAT): Add check for .NSUBSPA
	COMDAT support.
	* configure. config.in: Rebuilt.
	* config/pa/pa-protos.h (som_text_section_asm_op,
	som_readonly_data_section, som_one_only_readonly_data_section,
	som_one_only_data_section, forget_section): Declare.
	* pa.c (override_options): Set init_machine_status to
	pa_init_machine_status.
	(pa_init_machine_status): New function.
	(pa_output_function_epilogue): Call forget_section if TARGET_SOM and
	TARGET_GAS.
	(pa_asm_output_mi_thunk): Likewise.
	(som_text_section_asm_op): New function.
	(pa_select_section): Call som_one_only_readonly_data_section and
	som_one_only_data_section when appropriate.
	* pa.h (struct machine_function): Define.
	(EXTRA_SECTIONS, EXTRA_SECTION_FUNCTIONS,
	SOM_READONLY_DATA_SECTION_FUNCTION,
	SOM_ONE_ONLY_READONLY_DATA_SECTION_FUNCTION
	SOM_ONE_ONLY_DATA_SECTION_FUNCTION, FORGET_SECTION_FUNCTION): New
	macros.
	* som.h (ASM_OUTPUT_FUNCTION_PREFIX): Delete.
	(TEXT_SECTION_ASM_OP): Call som_text_section_asm_op.
	(READONLY_DATA_ASM_OP, EXTRA_SECTIONS, EXTRA_SECTION_FUNCTIONS): Delete.
	(READONLY_DATA_SECTION): Call som_readonly_data_section when not PIC.
	(SUPPORTS_SOM_COMDAT): New define.
	(SUPPORTS_ONE_ONLY): True if SUPPORTS_WEAK or SUPPORTS_SOM_COMDAT.
	(MAKE_DECL_ONE_ONLY): Rework common support.

Index: configure.ac
===================================================================
RCS file: /cvs/gcc/gcc/gcc/configure.ac,v
retrieving revision 2.6.2.18
diff -u -3 -p -r2.6.2.18 configure.ac
--- configure.ac	16 Dec 2004 00:15:00 -0000	2.6.2.18
+++ configure.ac	19 Dec 2004 20:54:33 -0000
@@ -1855,6 +1855,12 @@ gcc_GAS_CHECK_FEATURE([.weak], gcc_cv_as
  [	.weak foobar],,
 [AC_DEFINE(HAVE_GAS_WEAK, 1, [Define if your assembler supports .weak.])])
 
+gcc_GAS_CHECK_FEATURE([.nsubspa comdat], gcc_cv_as_nsubspa_comdat,
+ [2,15,91],,
+ [	.SPACE $TEXT$
+	.NSUBSPA $CODE$,COMDAT],,
+[AC_DEFINE(HAVE_GAS_NSUBSPA_COMDAT, 1, [Define if your assembler supports .nsubspa comdat option.])])
+
 # .hidden needs to be supported in both the assembler and the linker,
 # because GNU LD versions before 2.12.1 have buggy support for STV_HIDDEN.
 # This is irritatingly difficult to feature test for; we have to check the
Index: config/pa/pa-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/pa/pa-protos.h,v
retrieving revision 1.29.4.2
diff -u -3 -p -r1.29.4.2 pa-protos.h
--- config/pa/pa-protos.h	21 Jan 2004 22:16:47 -0000	1.29.4.2
+++ config/pa/pa-protos.h	19 Dec 2004 20:54:33 -0000
@@ -137,6 +137,7 @@ extern struct rtx_def *hppa_builtin_save
 
 extern void override_options (void);
 extern void output_ascii (FILE *, const char *, int);
+extern const char * som_text_section_asm_op (void);
 extern HOST_WIDE_INT compute_frame_size (HOST_WIDE_INT, int *);
 extern int and_mask_p (unsigned HOST_WIDE_INT);
 extern int cint_ok_for_move (HOST_WIDE_INT);
@@ -153,7 +154,6 @@ extern int cmpib_comparison_operator (rt
 #endif
 
 
-
 #ifdef TREE_CODE
 extern int reloc_needed (tree);
 #ifdef RTX_CODE
@@ -165,3 +165,9 @@ extern int function_arg_partial_nregs (C
 				       enum machine_mode,
 				       tree, int);
 #endif /* TREE_CODE */
+
+/* Functions in varasm.c used by pa.c.  */
+extern void som_readonly_data_section (void);
+extern void som_one_only_readonly_data_section (void);
+extern void som_one_only_data_section (void);
+extern void forget_section (void);
Index: config/pa/pa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/pa/pa.c,v
retrieving revision 1.235.4.7
diff -u -3 -p -r1.235.4.7 pa.c
--- config/pa/pa.c	11 Jul 2004 03:32:51 -0000	1.235.4.7
+++ config/pa/pa.c	19 Dec 2004 20:54:34 -0000
@@ -148,6 +148,7 @@ static void output_deferred_plabels (voi
 #ifdef HPUX_LONG_DOUBLE_LIBRARY
 static void pa_hpux_init_libfuncs (void);
 #endif
+static struct machine_function * pa_init_machine_status (void);
 
 /* Save the operands last given to a compare for use when we
    generate a scc or bcc insn.  */
@@ -370,6 +371,8 @@ override_options (void)
       targetm.asm_out.unaligned_op.si = NULL;
       targetm.asm_out.unaligned_op.di = NULL;
     }
+
+  init_machine_status = pa_init_machine_status;
 }
 
 static void
@@ -381,6 +384,16 @@ pa_init_builtins (void)
 #endif
 }
 
+/* Function to init struct machine_function.
+   This will be called, via a pointer variable,
+   from push_function_context.  */
+
+static struct machine_function *
+pa_init_machine_status (void)
+{
+  return ggc_alloc_cleared (sizeof (machine_function));
+}
+
 /* If FROM is a probable pointer register, mark TO as a probable
    pointer register with the same pointer alignment as FROM.  */
 
@@ -4098,6 +4111,14 @@ pa_output_function_epilogue (FILE *file,
 
   fputs ("\t.EXIT\n\t.PROCEND\n", file);
 
+  if (TARGET_SOM && TARGET_GAS)
+    {
+      /* We done with this subspace except possibly for some additional
+	 debug information.  Forget that we are in this subspace to ensure
+	 that the next function is output in its own subspace.  */
+      forget_section ();
+    }
+
   if (INSN_ADDRESSES_SET_P ())
     {
       insn = get_last_nonnote_insn ();
@@ -7897,8 +7918,9 @@ pa_asm_output_mi_thunk (FILE *file, tree
       fprintf (file, "\t.align 4\n");
       ASM_OUTPUT_LABEL (file, label);
       fprintf (file, "\t.word P'%s\n", fname);
-      function_section (thunk_fndecl);
     }
+  else if (TARGET_SOM && TARGET_GAS)
+    forget_section ();
 
   current_thunk_number++;
   nbytes = ((nbytes + FUNCTION_BOUNDARY / BITS_PER_UNIT - 1)
@@ -9058,6 +9080,50 @@ cmpib_comparison_operator (rtx op, enum 
 	      || GET_CODE (op) == LEU));
 }
 
+/* Return a string to output before text in the current function.
+
+   This function is only used with SOM.  Because we don't support
+   named subspaces, we can only create a new subspace or switch back
+   to the default text subspace.  */
+const char *
+som_text_section_asm_op (void)
+{
+  if (!TARGET_SOM)
+    return "";
+
+  if (TARGET_GAS)
+    {
+      if (cfun && !cfun->machine->in_nsubspa)
+	{
+	  /* We only want to emit a .nsubspa directive once at the
+	     start of the function.  */
+	  cfun->machine->in_nsubspa = 1;
+
+	  /* Create a new subspace for the text.  This provides
+	     better stub placement and one-only functions.  */
+	  if (cfun->decl
+	      && DECL_ONE_ONLY (cfun->decl)
+	      && !DECL_WEAK (cfun->decl))
+	    return
+ "\t.SPACE $TEXT$\n\t.NSUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,SORT=24,COMDAT";
+
+	  return "\t.SPACE $TEXT$\n\t.NSUBSPA $CODE$";
+	}
+      else
+	{
+	  /* There isn't a current function or the body of the current
+	     function has been completed.  So, we are changing to the
+	     text section to output debugging information.  Do this in
+	     the default text section.  We need to forget that we are
+	     in the text section so that the function text_section in
+	     varasm.c will call us the next time around.  */
+	  forget_section ();
+	}
+    }
+
+  return "\t.SPACE $TEXT$\n\t.SUBSPA $CODE$";
+}
+
 /* On hpux10, the linker will give an error if we have a reference
    in the read-only data section to a symbol defined in a shared
    library.  Therefore, expressions that might require a reloc can
@@ -9074,11 +9140,23 @@ pa_select_section (tree exp, int reloc,
       && (DECL_INITIAL (exp) == error_mark_node
           || TREE_CONSTANT (DECL_INITIAL (exp)))
       && !reloc)
-    readonly_data_section ();
+    {
+      if (TARGET_SOM
+	  && DECL_ONE_ONLY (exp)
+	  && !DECL_WEAK (exp))
+	som_one_only_readonly_data_section ();
+      else
+	readonly_data_section ();
+    }
   else if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'c'
 	   && !(TREE_CODE (exp) == STRING_CST && flag_writable_strings)
 	   && !reloc)
     readonly_data_section ();
+  else if (TARGET_SOM
+	   && TREE_CODE (exp) == VAR_DECL
+	   && DECL_ONE_ONLY (exp)
+	   && !DECL_WEAK (exp))
+    som_one_only_data_section ();
   else
     data_section ();
 }
Index: config/pa/pa.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/pa/pa.h,v
retrieving revision 1.208.4.6
diff -u -3 -p -r1.208.4.6 pa.h
--- config/pa/pa.h	22 Jun 2004 00:18:08 -0000	1.208.4.6
+++ config/pa/pa.h	19 Dec 2004 20:54:34 -0000
@@ -424,6 +424,12 @@ do {								\
 #define CAN_DEBUG_WITHOUT_FP
 
 /* target machine storage layout */
+typedef struct machine_function GTY(())
+{
+  /* Flag indicating that a .NSUBSPA directive has been output for
+     this function.  */
+  int in_nsubspa;
+} machine_function;
 
 /* Define this macro if it is advisable to hold scalars in registers
    in a wider mode than that declared by the program.  In such cases, 
@@ -1682,12 +1688,78 @@ do { 									\
     goto LABEL
 
 #define TARGET_ASM_SELECT_SECTION  pa_select_section
-   
+
 /* Return a nonzero value if DECL has a section attribute.  */
 #define IN_NAMED_SECTION_P(DECL) \
   ((TREE_CODE (DECL) == FUNCTION_DECL || TREE_CODE (DECL) == VAR_DECL) \
    && DECL_SECTION_NAME (DECL) != NULL_TREE)
 
+/* The following extra sections and extra section functions are only used
+   for SOM, but they must be provided unconditionally because pa.c's calls
+   to the functions might not get optimized out when other object formats
+   are in use.  */
+
+#define EXTRA_SECTIONS							\
+  in_som_readonly_data,							\
+  in_som_one_only_readonly_data,					\
+  in_som_one_only_data
+
+#define EXTRA_SECTION_FUNCTIONS						\
+  SOM_READONLY_DATA_SECTION_FUNCTION					\
+  SOM_ONE_ONLY_READONLY_DATA_SECTION_FUNCTION				\
+  SOM_ONE_ONLY_DATA_SECTION_FUNCTION					\
+  FORGET_SECTION_FUNCTION
+
+/* SOM puts readonly data in the default $LIT$ subspace when PIC code
+   is not being generated.  */
+#define SOM_READONLY_DATA_SECTION_FUNCTION				\
+void									\
+som_readonly_data_section (void)					\
+{									\
+  if (!TARGET_SOM)							\
+    return;								\
+  if (in_section != in_som_readonly_data)				\
+    {									\
+      in_section = in_som_readonly_data;				\
+      fputs ("\t.SPACE $TEXT$\n\t.SUBSPA $LIT$\n", asm_out_file);	\
+    }									\
+}
+
+/* When secondary definitions are not supported, SOM makes readonly data one
+   only by creating a new $LIT$ subspace in $TEXT$ with the comdat flag.  */
+#define SOM_ONE_ONLY_READONLY_DATA_SECTION_FUNCTION			\
+void									\
+som_one_only_readonly_data_section (void)				\
+{									\
+  if (!TARGET_SOM)							\
+    return;								\
+  in_section = in_som_one_only_readonly_data;				\
+  fputs ("\t.SPACE $TEXT$\n"						\
+	 "\t.NSUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=0x2c,SORT=16,COMDAT\n",\
+	 asm_out_file);							\
+}
+
+/* When secondary definitions are not supported, SOM makes data one only by
+   creating a new $DATA$ subspace in $PRIVATE$ with the comdat flag.  */
+#define SOM_ONE_ONLY_DATA_SECTION_FUNCTION				\
+void									\
+som_one_only_data_section (void)					\
+{									\
+  if (!TARGET_SOM)							\
+    return;								\
+  in_section = in_som_one_only_data;					\
+  fputs ("\t.SPACE $PRIVATE$\n"						\
+	 "\t.NSUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31,SORT=24,COMDAT\n",	\
+	 asm_out_file);							\
+}
+
+#define FORGET_SECTION_FUNCTION						\
+void									\
+forget_section (void)							\
+{									\
+  in_section = no_section;						\
+}
+
 /* Define this macro if references to a symbol must be treated
    differently depending on something about the variable or
    function named by the symbol (such as what section it is in).
Index: config/pa/som.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/pa/som.h,v
retrieving revision 1.47
diff -u -3 -p -r1.47 som.h
--- config/pa/som.h	2 Nov 2003 01:01:24 -0000	1.47
+++ config/pa/som.h	19 Dec 2004 20:54:34 -0000
@@ -1,5 +1,5 @@
 /* Definitions for SOM assembler support.
-   Copyright (C) 1999, 2001, 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -129,19 +129,6 @@ do {								\
 #endif
 
 
-/* NAME refers to the function's name.  If we are placing each function into
-   its own section, we need to switch to the section for this function.  Note
-   that the section name will have a "." prefix.  */
-#define ASM_OUTPUT_FUNCTION_PREFIX(FILE, NAME) \
-  {									\
-    const char *name = (*targetm.strip_name_encoding) (NAME);		\
-    if (TARGET_GAS && in_section == in_text) 				\
-      fputs ("\t.NSUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY\n", FILE); \
-    else if (TARGET_GAS)						\
-      fprintf (FILE,							\
-	       "\t.SUBSPA .%s\n", name);				\
-  }
-    
 #define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
     do { tree fntype = TREE_TYPE (TREE_TYPE (DECL));			\
 	 tree tree_type = TREE_TYPE (DECL);				\
@@ -219,29 +206,14 @@ do {								\
 
 #define TARGET_ASM_FILE_START pa_som_file_start
 
-/* Output before code.  */
-
-/* Supposedly the assembler rejects the command if there is no tab!  */
-#define TEXT_SECTION_ASM_OP "\t.SPACE $TEXT$\n\t.SUBSPA $CODE$\n"
+/* String to output before text.  */
+#define TEXT_SECTION_ASM_OP som_text_section_asm_op ()
 
-/* Output before read-only data.  */
+/* String to output before writable data.  */
+#define DATA_SECTION_ASM_OP "\t.SPACE $PRIVATE$\n\t.SUBSPA $DATA$\n"
 
-/* Supposedly the assembler rejects the command if there is no tab!  */
-#define READONLY_DATA_ASM_OP "\t.SPACE $TEXT$\n\t.SUBSPA $LIT$\n"
-
-#define EXTRA_SECTIONS in_readonly_data
-
-#define EXTRA_SECTION_FUNCTIONS						\
-extern void readonly_data (void);					\
-void									\
-readonly_data (void)							\
-{									\
-  if (in_section != in_readonly_data)					\
-    {									\
-      in_section = in_readonly_data;					\
-      fprintf (asm_out_file, "%s\n", READONLY_DATA_ASM_OP);		\
-    }									\
-}
+/* String to output before uninitialized data.  */
+#define BSS_SECTION_ASM_OP "\t.SPACE $PRIVATE$\n\t.SUBSPA $BSS$\n"
 
 /* FIXME: HPUX ld generates incorrect GOT entries for "T" fixups
    which reference data within the $TEXT$ space (for example constant
@@ -255,17 +227,8 @@ readonly_data (void)							\
    $TEXT$ space during PIC generation.  Instead place all constant
    data into the $PRIVATE$ subspace (this reduces sharing, but it
    works correctly).  */
-
-#define READONLY_DATA_SECTION (flag_pic ? data_section : readonly_data)
-
-/* Output before writable data.  */
-
-/* Supposedly the assembler rejects the command if there is no tab!  */
-#define DATA_SECTION_ASM_OP "\t.SPACE $PRIVATE$\n\t.SUBSPA $DATA$\n"
-
-/* Output before uninitialized data.  */
-
-#define BSS_SECTION_ASM_OP "\t.SPACE $PRIVATE$\n\t.SUBSPA $BSS$\n"
+#define READONLY_DATA_SECTION \
+  (flag_pic ? data_section : som_readonly_data_section)
 
 /* We must not have a reference to an external symbol defined in a
    shared library in a readonly section, else the SOM linker will
@@ -361,11 +324,30 @@ do {						\
 #define SUPPORTS_WEAK 0
 #endif
 
-/* We can support one only if we support weak.  */
-#define SUPPORTS_ONE_ONLY SUPPORTS_WEAK
+/* CVS GAS as of 4/28/04 supports a comdat parameter for the .nsubspa
+   directive.  This provides one-only linkage semantics even though we
+   don't have weak support.  */
+#ifdef HAVE_GAS_NSUBSPA_COMDAT
+#define SUPPORTS_SOM_COMDAT (TARGET_GAS)
+#else
+#define SUPPORTS_SOM_COMDAT 0
+#endif
+
+/* We can support one only if we support weak or comdat.  */
+#define SUPPORTS_ONE_ONLY (SUPPORTS_WEAK || SUPPORTS_SOM_COMDAT)
 
-/* Use weak (secondary definitions) to make one only declarations.  */
-#define MAKE_DECL_ONE_ONLY(DECL) (DECL_WEAK (DECL) = 1)
+/* We use DECL_COMMON for uninitialized one-only variables as we don't
+   have linkonce .bss.  We use SOM secondary definitions or comdat for
+   initialized variables and functions.  */
+#define MAKE_DECL_ONE_ONLY(DECL) \
+  do {									\
+    if (TREE_CODE (DECL) == VAR_DECL					\
+        && (DECL_INITIAL (DECL) == 0					\
+            || DECL_INITIAL (DECL) == error_mark_node))			\
+      DECL_COMMON (DECL) = 1;						\
+    else if (SUPPORTS_WEAK)						\
+      DECL_WEAK (DECL) = 1;						\
+  } while (0)
 
 /* This is how we tell the assembler that a symbol is weak.  The SOM
    weak implementation uses the secondary definition (sdef) flag.


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