re PR middle-end/17982 (stop calling assemble_external before final assembly output...
authorZack Weinberg <zack@gcc.gnu.org>
Wed, 8 Dec 2004 19:13:35 +0000 (19:13 +0000)
committerZack Weinberg <zack@gcc.gnu.org>
Wed, 8 Dec 2004 19:13:35 +0000 (19:13 +0000)
PR 17982
* varasm.c (pending_assemble_externals): New static.
(assemble_external_real): Meat of assemble_external split out
to this new function.
(process_pending_assemble_externals): New function.
(assemble_external): Use gcc_assert.  If flag_unit_at_a_time
is true and the basic test passes, merely cons the decl onto
the pending list to be handled later.
* tree.h: Declare process_pending_assemble_externals.
* cgraphunit.c (cgraph_optimize): Call it.

* config/h8300/h8300.h: Do not define ASM_OUTPUT_EXTERNAL.

From-SVN: r91914

gcc/ChangeLog
gcc/cgraphunit.c
gcc/config/h8300/h8300.h
gcc/tree.h
gcc/varasm.c

index 7972254..e780766 100644 (file)
@@ -1,3 +1,18 @@
+2004-12-08  Zack Weinberg  <zack@codesourcery.com>
+
+       PR 17982
+       * varasm.c (pending_assemble_externals): New static.
+       (assemble_external_real): Meat of assemble_external split out
+       to this new function.
+       (process_pending_assemble_externals): New function.
+       (assemble_external): Use gcc_assert.  If flag_unit_at_a_time
+       is true and the basic test passes, merely cons the decl onto
+       the pending list to be handled later.
+       * tree.h: Declare process_pending_assemble_externals.
+       * cgraphunit.c (cgraph_optimize): Call it.
+
+       * config/h8300/h8300.h: Do not define ASM_OUTPUT_EXTERNAL.
+
 2004-12-08  Kazu Hirata  <kazu@cs.umass.edu>
 
        * cfgloopmanip.c (create_preheader): Speed up by "unrolling"
 
 2004-12-07  David Mosberger  <davidm@hpl.hp.com>
 
-        PR target/18443
-        * config/ia64/ia64.c (ia64_assemble_integer): Add support for
-        emitting unaligned pointer-sized integers.
+       PR target/18443
+       * config/ia64/ia64.c (ia64_assemble_integer): Add support for
+       emitting unaligned pointer-sized integers.
 
 2004-12-07  Steven Bosscher  <stevenb@suse.de>
 
index 43564b0..22b3381 100644 (file)
@@ -1750,6 +1750,9 @@ cgraph_optimize (void)
 #endif
   if (!flag_unit_at_a_time)
     return;
+
+  process_pending_assemble_externals ();
+
   timevar_push (TV_CGRAPHOPT);
   if (!quiet_flag)
     fprintf (stderr, "Performing intraprocedural optimizations\n");
index d7b73e8..85886dd 100644 (file)
@@ -1160,8 +1160,6 @@ struct cum_arg
 { {"er0", 0}, {"er1", 1}, {"er2", 2}, {"er3", 3}, {"er4", 4}, \
   {"er5", 5}, {"er6", 6}, {"er7", 7}, {"r7", 7} }
 
-#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME)
-
 /* Globalizing directive for a label.  */
 #define GLOBAL_ASM_OP "\t.global "
 
index aec7b4b..7f42aa5 100644 (file)
@@ -3701,6 +3701,7 @@ extern void mark_referenced (tree);
 extern void mark_decl_referenced (tree);
 extern void notice_global_symbol (tree);
 extern void set_user_assembler_name (tree, const char *);
+extern void process_pending_assemble_externals (void);
 
 /* In stmt.c */
 extern void expand_computed_goto (tree);
index d900273..f80ce93 100644 (file)
@@ -1759,6 +1759,12 @@ contains_pointers_p (tree type)
     }
 }
 
+/* In unit-at-a-time mode, we delay assemble_external processing until
+   the compilation unit is finalized.  This is the best we can do for
+   right now (i.e. stage 3 of GCC 4.0) - the right thing is to delay
+   it all the way to final.  See PR 17982 for further discussion.  */
+static GTY(()) tree pending_assemble_externals;
+
 #ifdef ASM_OUTPUT_EXTERNAL
 /* True if DECL is a function decl for which no out-of-line copy exists.
    It is assumed that DECL's assembler name has been set.  */
@@ -1780,8 +1786,37 @@ incorporeal_function_p (tree decl)
     }
   return false;
 }
+
+/* Actually do the tests to determine if this is necessary, and invoke
+   ASM_OUTPUT_EXTERNAL.  */
+static void
+assemble_external_real (tree decl)
+{
+  rtx rtl = DECL_RTL (decl);
+
+  if (MEM_P (rtl) && GET_CODE (XEXP (rtl, 0)) == SYMBOL_REF
+      && !SYMBOL_REF_USED (XEXP (rtl, 0))
+      && !incorporeal_function_p (decl))
+    {
+      /* Some systems do require some output.  */
+      SYMBOL_REF_USED (XEXP (rtl, 0)) = 1;
+      ASM_OUTPUT_EXTERNAL (asm_out_file, decl, XSTR (XEXP (rtl, 0), 0));
+    }
+}
 #endif
 
+void
+process_pending_assemble_externals (void)
+{
+#ifdef ASM_OUTPUT_EXTERNAL
+  tree list;
+  for (list = pending_assemble_externals; list; list = TREE_CHAIN (list))
+    assemble_external_real (TREE_VALUE (list));
+
+  pending_assemble_externals = 0;
+#endif
+}
+
 /* Output something to declare an external symbol to the assembler.
    (Most assemblers don't need this, so we normally output nothing.)
    Do nothing if DECL is not external.  */
@@ -1793,23 +1828,17 @@ assemble_external (tree decl ATTRIBUTE_UNUSED)
      main body of this code is only rarely exercised.  To provide some
      testing, on all platforms, we make sure that the ASM_OUT_FILE is
      open.  If it's not, we should not be calling this function.  */
-  if (!asm_out_file)
-    abort ();
+  gcc_assert (asm_out_file);
 
 #ifdef ASM_OUTPUT_EXTERNAL
-  if (DECL_P (decl) && DECL_EXTERNAL (decl) && TREE_PUBLIC (decl))
-    {
-      rtx rtl = DECL_RTL (decl);
+  if (!DECL_P (decl) || !DECL_EXTERNAL (decl) || !TREE_PUBLIC (decl))
+    return;
 
-      if (MEM_P (rtl) && GET_CODE (XEXP (rtl, 0)) == SYMBOL_REF
-         && !SYMBOL_REF_USED (XEXP (rtl, 0))
-         && !incorporeal_function_p (decl))
-       {
-         /* Some systems do require some output.  */
-         SYMBOL_REF_USED (XEXP (rtl, 0)) = 1;
-         ASM_OUTPUT_EXTERNAL (asm_out_file, decl, XSTR (XEXP (rtl, 0), 0));
-       }
-    }
+  if (flag_unit_at_a_time)
+    pending_assemble_externals = tree_cons (0, decl,
+                                           pending_assemble_externals);
+  else
+    assemble_external_real (decl);
 #endif
 }