]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
hpux.h (TARGET_HPUX_LD): New, define true.
authorSteve Ellcey <sje@cup.hp.com>
Mon, 9 Sep 2002 22:03:31 +0000 (22:03 +0000)
committerSteve Ellcey <sje@gcc.gnu.org>
Mon, 9 Sep 2002 22:03:31 +0000 (22:03 +0000)
* config/ia64/hpux.h (TARGET_HPUX_LD): New, define true.
(ASM_FILE_END) New.
* config/ia64/ia64.h (TARGET_HPUX_LD): New, define false.
* config/ia64/ia64-protos.h (ia64_hpux_asm_file_end): New.
* config/ia64/ia64.c (ia64_asm_output_external): Create list
of external functions if TARGET_HPUX_LD is true.
(ia64_hpux_add_extern_decl): New, routine to put names on
list of external functions.
(ia64_hpux_asm_file_end): Put out declarations for external
functions if and only if they are used.

From-SVN: r56986

gcc/ChangeLog
gcc/config/ia64/hpux.h
gcc/config/ia64/ia64-protos.h
gcc/config/ia64/ia64.c
gcc/config/ia64/ia64.h

index 6df6abd98d62e372f74384431229d09b1cf4ea0d..3daf7425a0fa4c679825287ce7c99d033f00913f 100644 (file)
@@ -1,3 +1,16 @@
+2002-09-09  Steve Ellcey  <sje@cup.hp.com>
+
+       * config/ia64/hpux.h (TARGET_HPUX_LD): New, define true.
+       (ASM_FILE_END) New.
+       * config/ia64/ia64.h (TARGET_HPUX_LD): New, define false.
+       * config/ia64/ia64-protos.h (ia64_hpux_asm_file_end): New.
+       * config/ia64/ia64.c (ia64_asm_output_external): Create list
+       of external functions if TARGET_HPUX_LD is true.
+       (ia64_hpux_add_extern_decl): New, routine to put names on
+       list of external functions.
+       (ia64_hpux_asm_file_end): Put out declarations for external
+       functions if and only if they are used.
+
 2002-09-09  John David Anglin  <dave@hiauly1.hia.nrc.ca>
 
        * pa.md (exception_receiver, builtin_setjmp_receiver): Add blockage
index 968d0ed9147f83c102dc2f802916aa62d1a07155..0b639d19a6030a3a81a58b799c47a05c4d0aa038 100644 (file)
@@ -127,3 +127,14 @@ do {                                                       \
 
 #define REGISTER_TARGET_PRAGMAS(PFILE) \
   cpp_register_pragma (PFILE, 0, "builtin", ia64_hpux_handle_builtin_pragma)
+
+/* Tell ia64.c that we are using the HP linker and we should delay output of
+   function extern declarations so that we don't output them for functions
+   which are never used (and may not be defined).  */
+
+#undef TARGET_HPUX_LD
+#define TARGET_HPUX_LD 1
+
+/* Put out the needed function declarations at the end.  */
+
+#define ASM_FILE_END(STREAM) ia64_hpux_asm_file_end(STREAM)
index f4d264cef6fad72660ef4bc18f42c8b8dd8c9fba..0e0ef04f055d68540a688b0502863030204f8235 100644 (file)
@@ -148,3 +148,5 @@ extern enum direction ia64_hpux_function_arg_padding PARAMS ((enum machine_mode,
 #ifdef GCC_C_PRAGMA_H
 extern void ia64_hpux_handle_builtin_pragma PARAMS ((cpp_reader *));
 #endif
+
+extern void ia64_hpux_asm_file_end PARAMS ((FILE *));
index 08a2dfacbaf946511b7b5a2479cbde1d6b7e394f..c27a6fbb0cb4d2afbd49121541a688d8f2c7aefc 100644 (file)
@@ -171,6 +171,9 @@ static void ia64_aix_unique_section PARAMS ((tree, int))
 static void ia64_aix_select_rtx_section PARAMS ((enum machine_mode, rtx,
                                                 unsigned HOST_WIDE_INT))
      ATTRIBUTE_UNUSED;
+
+static void ia64_hpux_add_extern_decl PARAMS ((const char *name))
+     ATTRIBUTE_UNUSED;
 \f
 /* Table of valid machine attributes.  */
 static const struct attribute_spec ia64_attribute_table[] =
@@ -4039,8 +4042,13 @@ ia64_asm_output_external (file, decl, name)
 {
   int save_referenced;
 
-  /* GNU as does not need anything here.  */
-  if (TARGET_GNU_AS)
+  /* GNU as does not need anything here, but the HP linker does need
+     something for external functions.  */
+
+  if (TARGET_GNU_AS
+      && (!TARGET_HPUX_LD
+         || TREE_CODE (decl) != FUNCTION_DECL
+         || strstr(name, "__builtin_") == name))
     return;
 
   /* ??? The Intel assembler creates a reference that needs to be satisfied by
@@ -4055,13 +4063,18 @@ ia64_asm_output_external (file, decl, name)
       || ! strcmp (name, "__builtin_args_info"))
     return;
 
-  /* assemble_name will set TREE_SYMBOL_REFERENCED, so we must save and
-     restore it.  */
-  save_referenced = TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl));
-  if (TREE_CODE (decl) == FUNCTION_DECL)
-    ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
-  (*targetm.asm_out.globalize_label) (file, name);
-  TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)) = save_referenced;
+  if (TARGET_HPUX_LD)
+    ia64_hpux_add_extern_decl (name);
+  else
+    {
+      /* assemble_name will set TREE_SYMBOL_REFERENCED, so we must save and
+         restore it.  */
+      save_referenced = TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl));
+      if (TREE_CODE (decl) == FUNCTION_DECL)
+        ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
+      (*targetm.asm_out.globalize_label) (file, name);
+      TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)) = save_referenced;
+    }
 }
 \f
 /* Parse the -mfixed-range= option string.  */
@@ -8050,6 +8063,57 @@ ia64_hpux_function_arg_padding (mode, type)
        : GET_MODE_BITSIZE (mode) < PARM_BOUNDARY)
       ? downward : upward);
 }
+
+/* Linked list of all external functions that are to be emitted by GCC.
+   We output the name if and only if TREE_SYMBOL_REFERENCED is set in
+   order to avoid putting out names that are never really used.  */
+
+struct extern_func_list
+{
+  struct extern_func_list *next; /* next external */
+  char *name;                    /* name of the external */
+} *extern_func_head = 0;
+
+static void
+ia64_hpux_add_extern_decl (name)
+        const char *name;
+{
+  struct extern_func_list *p;
+
+  p = (struct extern_func_list *) xmalloc (sizeof (struct extern_func_list));
+  p->name = xmalloc (strlen (name) + 1);
+  strcpy(p->name, name);
+  p->next = extern_func_head;
+  extern_func_head = p;
+}
+
+/* Print out the list of used global functions.  */
+
+void
+ia64_hpux_asm_file_end (file)
+       FILE *file;
+{
+  while (extern_func_head)
+    {
+      char *real_name;
+      tree decl;
+
+      real_name = (* targetm.strip_name_encoding) (extern_func_head->name);
+      decl = get_identifier (real_name);
+      if (decl && ! TREE_ASM_WRITTEN (decl) && TREE_SYMBOL_REFERENCED (decl))
+        {
+         TREE_ASM_WRITTEN (decl) = 1;
+         (*targetm.asm_out.globalize_label) (file, real_name);
+         fprintf (file, "%s", TYPE_ASM_OP);
+         assemble_name (file, real_name);
+         putc (',', file);
+         fprintf (file, TYPE_OPERAND_FMT, "function");
+         putc ('\n', file);
+        }
+      extern_func_head = extern_func_head->next;
+    }
+}
+
 \f
 /* Switch to the section to which we should output X.  The only thing
    special we do here is to honor small data.  */
index bf5b995b157cd8826870c5291b35b877f8da30f9..5ab1c444baf4c64c8aaff58f2f928f60d2126c1a 100644 (file)
@@ -127,6 +127,8 @@ extern int ia64_tls_size;
 #define TARGET_TLS22           (ia64_tls_size == 22)
 #define TARGET_TLS64           (ia64_tls_size == 64)
 
+#define TARGET_HPUX_LD         0
+
 /* This macro defines names of command options to set and clear bits in
    `target_flags'.  Its definition is an initializer with a subgrouping for
    each command option.  */