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]

[patch] Fix PA PR c++/19797


> > Are you suggesting that it would be better to do any necessary
> > tracking of referenced symbols in the backend?  In the PA case, we only
> > need to do this for externals and the number usually isn't that large.
> 
> I was thinking that you should be using flags in the SYMBOL_REF instead.

The enclosed change adds a target symbol_ref flag to track referenced
symbol_refs.  This allows the output for ASM_OUTPUT_EXTERNAL to be
deferred to the file end.  At that time, only referenced externals
are output.

The flag for tracking referenced symbols could be moved to the main
code body if there was a general need to do this tracking.

I made various cleanups to try to ensure that ASM_OUTPUT_SYMBOL_REF
is always used to output symbol_refs.  There are still some places
where a symbol_ref is implicitly output (e.g., ASM_DECLARE_FUNCTION_NAME)
using assemble_name instead of output_addr_const.

I tried to eliminate all use of TREE_SYMBOL_REFERENCED in the PA backend.
However, I wasn't able to eliminate the use in ASM_OUTPUT_EXTERNAL_LIBCALL.
This is because the symbol_refs used for the same identifier in
ASM_OUTPUT_EXTERNAL_LIBCALL and ASM_DECLARE_FUNCTION_NAME differ.  Thus,
marking exported symbol_refs doesn't work.

Tested on hppa2.0w-hp-hpux11.11, hppa64-hp-hpux11.11 and
hppa-unknown-linux-gnu with no regressions.  Committed to 4.0
and 4.1.

Thanks to Joseph Myers for his initial patch.

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

2005-03-04  John David Anglin  <dave.danglin@nrc-cnrc.gc.ca>
	    Joseph S. Myers  <joseph@codesourcery.com>

	PR c++/19797
	* elf.h, pa64-hpux.h, som.h (ASM_OUTPUT_EXTERNAL_REAL): Define.
	(ASM_OUTPUT_EXTERNAL): Call pa_hpux_asm_output_external.
	* pa-protos.h (pa_hpux_asm_output_external): Add prototype.
	* pa.c (get_plabel): Change argument to symbol_ref.  Call
	maybe_get_identifier instead of get_identifier.
	(pa_hpux_asm_output_external, pa_hpux_file_end): New functions.
	(struct deferred_plabel): Replace name field with symbol field.
	(TARGET_ASM_FILE_END): Define as pa_hpux_file_end if
	ASM_OUTPUT_EXTERNAL_REAL is defined.
	(output_global_address): Use output_addr_const for output of all
	symbol_refs.
	(output_deferred_plabels): Use symbol_ref instead of name for address
	output.
	* pa.h (SYMBOL_FLAG_REFERENCED, SYMBOL_REF_REFERENCED_P,
	ASM_OUTPUT_SYMBOL_REF): New macros.
	* som.h (ASM_OUTPUT_EXTERNAL_LIBCALL): Use assemble_name_raw.  Update
	comment.
	(ASM_WEAKEN_LABEL): Use targetm.asm_out.globalize_label to globalize
	label.

	* g++.dg/abi/vague1.C: Remove xfail hppa*-*-hpux*.

Index: config/pa/elf.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/pa/elf.h,v
retrieving revision 1.16
diff -u -3 -p -r1.16 elf.h
--- config/pa/elf.h	27 Feb 2005 04:22:06 -0000	1.16
+++ config/pa/elf.h	4 Mar 2005 14:31:50 -0000
@@ -59,6 +59,8 @@ do {  \
    be imported as an ENTRY symbol.  */
 
 #define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) \
+  pa_hpux_asm_output_external ((FILE), (DECL), (NAME))
+#define ASM_OUTPUT_EXTERNAL_REAL(FILE, DECL, NAME) \
   do { fputs ("\t.IMPORT ", FILE);					\
        assemble_name_raw (FILE, NAME);					\
        if (FUNCTION_NAME_P (NAME))     					\
Index: config/pa/pa-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/pa/pa-protos.h,v
retrieving revision 1.40
diff -u -3 -p -r1.40 pa-protos.h
--- config/pa/pa-protos.h	15 Jan 2005 22:57:16 -0000	1.40
+++ config/pa/pa-protos.h	4 Mar 2005 14:31:51 -0000
@@ -174,6 +174,7 @@ extern void pa_asm_output_aligned_common
 extern void pa_asm_output_aligned_local (FILE *, const char *,
 					 unsigned HOST_WIDE_INT,
 					 unsigned int);
+extern void pa_hpux_asm_output_external (FILE *, tree, const char *);
 
 /* Functions in varasm.c used by pa.c.  */
 extern void som_readonly_data_section (void);
Index: config/pa/pa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/pa/pa.c,v
retrieving revision 1.287
diff -u -3 -p -r1.287 pa.c
--- config/pa/pa.c	20 Feb 2005 17:37:37 -0000	1.287
+++ config/pa/pa.c	4 Mar 2005 14:31:51 -0000
@@ -126,8 +126,7 @@ static tree hppa_gimplify_va_arg_expr (t
 static bool pa_scalar_mode_supported_p (enum machine_mode);
 static void copy_fp_args (rtx) ATTRIBUTE_UNUSED;
 static int length_fp_args (rtx) ATTRIBUTE_UNUSED;
-static struct deferred_plabel *get_plabel (const char *)
-     ATTRIBUTE_UNUSED;
+static struct deferred_plabel *get_plabel (rtx) ATTRIBUTE_UNUSED;
 static inline void pa_file_start_level (void) ATTRIBUTE_UNUSED;
 static inline void pa_file_start_space (int) ATTRIBUTE_UNUSED;
 static inline void pa_file_start_file (int) ATTRIBUTE_UNUSED;
@@ -138,6 +137,9 @@ static void pa_linux_file_start (void) A
 static void pa_hpux64_gas_file_start (void) ATTRIBUTE_UNUSED;
 static void pa_hpux64_hpas_file_start (void) ATTRIBUTE_UNUSED;
 static void output_deferred_plabels (void);
+#ifdef ASM_OUTPUT_EXTERNAL_REAL
+static void pa_hpux_file_end (void);
+#endif
 #ifdef HPUX_LONG_DOUBLE_LIBRARY
 static void pa_hpux_init_libfuncs (void);
 #endif
@@ -195,7 +197,7 @@ static int last_address;
 struct deferred_plabel GTY(())
 {
   rtx internal_label;
-  const char *name;
+  rtx symbol;
 };
 static GTY((length ("n_deferred_plabels"))) struct deferred_plabel *
   deferred_plabels;
@@ -245,7 +247,11 @@ static size_t n_deferred_plabels = 0;
 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
 
 #undef TARGET_ASM_FILE_END
+#ifdef ASM_OUTPUT_EXTERNAL_REAL
+#define TARGET_ASM_FILE_END pa_hpux_file_end
+#else
 #define TARGET_ASM_FILE_END output_deferred_plabels
+#endif
 
 #if !defined(USE_COLLECT2)
 #undef TARGET_ASM_CONSTRUCTOR
@@ -5430,10 +5436,10 @@ output_global_address (FILE *file, rtx x
     x = XEXP (x, 0);
 
   if (GET_CODE (x) == SYMBOL_REF && read_only_operand (x, VOIDmode))
-    assemble_name (file, XSTR (x, 0));
+    output_addr_const (file, x);
   else if (GET_CODE (x) == SYMBOL_REF && !flag_pic)
     {
-      assemble_name (file, XSTR (x, 0));
+      output_addr_const (file, x);
       fputs ("-$global$", file);
     }
   else if (GET_CODE (x) == CONST)
@@ -5594,21 +5600,24 @@ pa_hpux64_hpas_file_start (void)
 #undef aputs
 
 static struct deferred_plabel *
-get_plabel (const char *fname)
+get_plabel (rtx symbol)
 {
+  const char *fname = XSTR (symbol, 0);
   size_t i;
 
   /* See if we have already put this function on the list of deferred
      plabels.  This list is generally small, so a liner search is not
      too ugly.  If it proves too slow replace it with something faster.  */
   for (i = 0; i < n_deferred_plabels; i++)
-    if (strcmp (fname, deferred_plabels[i].name) == 0)
+    if (strcmp (fname, XSTR (deferred_plabels[i].symbol, 0)) == 0)
       break;
 
   /* If the deferred plabel list is empty, or this entry was not found
      on the list, create a new entry on the list.  */
   if (deferred_plabels == NULL || i == n_deferred_plabels)
     {
+      tree id;
+
       if (deferred_plabels == 0)
 	deferred_plabels = (struct deferred_plabel *)
 	  ggc_alloc (sizeof (struct deferred_plabel));
@@ -5620,12 +5629,13 @@ get_plabel (const char *fname)
 
       i = n_deferred_plabels++;
       deferred_plabels[i].internal_label = gen_label_rtx ();
-      deferred_plabels[i].name = ggc_strdup (fname);
+      deferred_plabels[i].symbol = symbol;
 
-      /* Gross.  We have just implicitly taken the address of
-	 this function, mark it as such.  */
-      fname = targetm.strip_name_encoding (fname);
-      TREE_SYMBOL_REFERENCED (get_identifier (fname)) = 1;
+      /* Gross.  We have just implicitly taken the address of this
+	 function.  Mark it in the same manner as assemble_name.  */
+      id = maybe_get_identifier (targetm.strip_name_encoding (fname));
+      if (id)
+	mark_referenced (id);
     }
 
   return &deferred_plabels[i];
@@ -5649,7 +5659,7 @@ output_deferred_plabels (void)
     {
       (*targetm.asm_out.internal_label) (asm_out_file, "L",
 		 CODE_LABEL_NUMBER (deferred_plabels[i].internal_label));
-      assemble_integer (gen_rtx_SYMBOL_REF (Pmode, deferred_plabels[i].name),
+      assemble_integer (deferred_plabels[i].symbol,
 			TARGET_64BIT ? 8 : 4, TARGET_64BIT ? 64 : 32, 1);
     }
 }
@@ -7470,7 +7480,7 @@ output_call (rtx insn, rtx call_dest, in
 	  /* ??? As far as I can tell, the HP linker doesn't support the
 	     long pc-relative sequence described in the 64-bit runtime
 	     architecture.  So, we use a slightly longer indirect call.  */
-	  struct deferred_plabel *p = get_plabel (XSTR (call_dest, 0));
+	  struct deferred_plabel *p = get_plabel (call_dest);
 
 	  xoperands[0] = p->internal_label;
 	  xoperands[1] = gen_label_rtx ();
@@ -7599,7 +7609,7 @@ output_call (rtx insn, rtx call_dest, in
 		     essentially an inline implementation of $$dyncall.
 		     We don't actually try to call $$dyncall as this is
 		     as difficult as calling the function itself.  */
-		  struct deferred_plabel *p = get_plabel (XSTR (call_dest, 0));
+		  struct deferred_plabel *p = get_plabel (call_dest);
 
 		  xoperands[0] = p->internal_label;
 		  xoperands[1] = gen_label_rtx ();
@@ -9492,4 +9502,63 @@ pa_return_in_memory (tree type, tree fnt
 	  || int_size_in_bytes (type) <= 0);
 }
 
+/* Structure to hold declaration and name of external symbols that are
+   emitted by GCC.  We generate a vector of these symbols and output them
+   at the end of the file if and only if SYMBOL_REF_REFERENCED_P is true.
+   This avoids putting out names that are never really used.  */
+
+struct extern_symbol GTY(())
+{
+  tree decl;
+  const char *name;
+};
+typedef struct extern_symbol *extern_symbol;
+
+/* Define gc'd vector type for extern_symbol.  */
+DEF_VEC_GC_P(extern_symbol);
+
+/* Vector of extern_symbol pointers.  */
+static GTY(()) VEC(extern_symbol) *extern_symbols;
+
+#ifdef ASM_OUTPUT_EXTERNAL_REAL
+/* Mark DECL (name NAME) as an external reference (assembler output
+   file FILE).  This saves the names to output at the end of the file
+   if actually referenced.  */
+
+void
+pa_hpux_asm_output_external (FILE *file, tree decl, const char *name)
+{
+  extern_symbol p = ggc_alloc (sizeof (struct extern_symbol));
+
+  gcc_assert (file == asm_out_file);
+  p->decl = decl;
+  p->name = name;
+  VEC_safe_push (extern_symbol, extern_symbols, p);
+}
+
+/* Output text required at the end of an assembler file.
+   This includes deferred plabels and .import directives for
+   all external symbols that were actually referenced.  */
+
+static void
+pa_hpux_file_end (void)
+{
+  unsigned int i;
+  extern_symbol p;
+
+  output_deferred_plabels ();
+
+  for (i = 0; VEC_iterate (extern_symbol, extern_symbols, i, p); i++)
+    {
+      tree decl = p->decl;
+
+      if (!TREE_ASM_WRITTEN (decl)
+	  && SYMBOL_REF_REFERENCED_P (XEXP (DECL_RTL (decl), 0)))
+	ASM_OUTPUT_EXTERNAL_REAL (asm_out_file, decl, p->name);
+    }
+
+  extern_symbols = NULL;
+}
+#endif
+
 #include "gt-pa.h"
Index: config/pa/pa.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/pa/pa.h,v
retrieving revision 1.243
diff -u -3 -p -r1.243 pa.h
--- config/pa/pa.h	1 Mar 2005 04:34:00 -0000	1.243
+++ config/pa/pa.h	4 Mar 2005 14:31:52 -0000
@@ -1262,6 +1262,13 @@ extern int may_call_alloca;
 	     || cint_ok_for_move (INTVAL (X))))			\
    && !function_label_operand (X, VOIDmode))
 
+/* Target flags set on a symbol_ref.  */
+
+/* Set by ASM_OUTPUT_SYMBOL_REF when a symbol_ref is output.  */
+#define SYMBOL_FLAG_REFERENCED (1 << SYMBOL_FLAG_MACH_DEP_SHIFT)
+#define SYMBOL_REF_REFERENCED_P(RTX) \
+  ((SYMBOL_REF_FLAGS (RTX) & SYMBOL_FLAG_REFERENCED) != 0)
+
 /* Subroutines for EXTRA_CONSTRAINT.
 
    Return 1 iff OP is a pseudo which did not get a hard register and
@@ -1954,6 +1961,14 @@ forget_section (void)							\
     fputs (xname, FILE);		\
   } while (0)
 
+/* This how we output the symbol_ref X.  */
+
+#define ASM_OUTPUT_SYMBOL_REF(FILE,X) \
+  do {                                                 \
+    SYMBOL_REF_FLAGS (X) |= SYMBOL_FLAG_REFERENCED;    \
+    assemble_name (FILE, XSTR (X, 0));                 \
+  } while (0)
+
 /* This is how to store into the string LABEL
    the symbol_ref name of an internal numbered label where
    PREFIX is the class of label and NUM is the number within the class.
Index: config/pa/pa64-hpux.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/pa/pa64-hpux.h,v
retrieving revision 1.40
diff -u -3 -p -r1.40 pa64-hpux.h
--- config/pa/pa64-hpux.h	27 Feb 2005 04:22:06 -0000	1.40
+++ config/pa/pa64-hpux.h	4 Mar 2005 14:31:52 -0000
@@ -201,6 +201,8 @@ do {								\
    HP assembler's .IMPORT directive but relates more directly to
    ELF object file types.  */
 #define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME)			\
+  pa_hpux_asm_output_external ((FILE), (DECL), (NAME))
+#define ASM_OUTPUT_EXTERNAL_REAL(FILE, DECL, NAME)		\
 do {								\
   if (FUNCTION_NAME_P (NAME))					\
     ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "function");		\
Index: config/pa/som.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/pa/som.h,v
retrieving revision 1.56
diff -u -3 -p -r1.56 som.h
--- config/pa/som.h	27 Feb 2005 04:22:06 -0000	1.56
+++ config/pa/som.h	4 Mar 2005 14:31:52 -0000
@@ -230,6 +230,8 @@ do {								\
    be imported as an ENTRY symbol.  */
 
 #define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) \
+  pa_hpux_asm_output_external ((FILE), (DECL), (NAME))
+#define ASM_OUTPUT_EXTERNAL_REAL(FILE, DECL, NAME) \
   do { fputs ("\t.IMPORT ", FILE);					\
        assemble_name_raw (FILE, NAME);					\
        if (FUNCTION_NAME_P (NAME))					\
@@ -239,14 +241,22 @@ do {								\
      } while (0)
 
 /* The bogus HP assembler requires ALL external references to be
-   "imported", even library calls. They look a bit different, so
+   "imported", even library calls.  They look a bit different, so
    here's this macro.
 
    Also note not all libcall names are passed to pa_encode_section_info
    (__main for example).  To make sure all libcall names have section
-   info recorded in them, we do it here.  We must also ensure that
-   we don't import a libcall that has been previously exported since
-   the HP assembler may change an ENTRY symbol to a CODE symbol.  */
+   info recorded in them, we do it here.
+
+   We must also ensure that a libcall that has been previously
+   exported is not subsequently imported since the HP assembler may
+   change the type from an ENTRY to a CODE symbol.  This would make
+   the symbol local.  We are forced to use the identifier node
+   associated with the real assembler name for this check as the
+   symbol_ref available in ASM_DECLARE_FUNCTION_NAME is not the
+   same as the one used here.  As a result, we can't use flags
+   in the symbol_ref for this check.  The identifier check assumes
+   assemble_external_libcall is called before the symbol is used.  */
 
 #define ASM_OUTPUT_EXTERNAL_LIBCALL(FILE, RTL) \
   do { const char *name;						\
@@ -260,7 +270,7 @@ do {								\
        if (!id || !TREE_SYMBOL_REFERENCED (id))				\
 	 {								\
 	   fputs ("\t.IMPORT ", FILE);					\
-	   assemble_name (FILE, XSTR ((RTL), 0));		       	\
+	   assemble_name_raw (FILE, XSTR ((RTL), 0));		       	\
 	   fputs (",CODE\n", FILE);					\
 	 }								\
      } while (0)
@@ -357,12 +367,7 @@ do {						\
   do { fputs ("\t.weak\t", FILE);				\
        assemble_name (FILE, NAME);				\
        fputc ('\n', FILE);					\
-       if (! FUNCTION_NAME_P (NAME))				\
-	 {							\
-	   fputs ("\t.EXPORT ", FILE);				\
-	   assemble_name (FILE, NAME);				\
-	   fputs (",DATA\n", FILE);				\
-	 }							\
+       targetm.asm_out.globalize_label (FILE, NAME);		\
   } while (0)
 
 /* We can't handle weak aliases, and therefore can't support pragma weak.
Index: testsuite/g++.dg/abi/vague1.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.dg/abi/vague1.C,v
retrieving revision 1.3
diff -u -3 -p -r1.3 vague1.C
--- testsuite/g++.dg/abi/vague1.C	4 Jun 2003 15:35:58 -0000	1.3
+++ testsuite/g++.dg/abi/vague1.C	4 Mar 2005 14:31:52 -0000
@@ -3,8 +3,6 @@
 
 // Disable debug info so we don't get confused by the symbol name there.
 // { dg-options "-g0" }
-// The test fails on hppa*-*-hpux* because the symbol _ZN1AIiE1tE is imported.
-// { dg-final { scan-assembler-not "_ZN1AIiE1tE" { xfail hppa*-*-hpux* } } }
 
 template <class T> struct A {
   static const T t = 0;


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