This delays asm_out_file initialization to until after IPA.
OK, not actually for LTO for which the situation is more complicated
since during IPA phases we write LTO IL and very early we output
early debug DIEs.

The RTL FE bits are a bit ugly and require checking for
multiple invocations of init_asm_output since it directly
runs the RTL passes for reach parsed function rather than
somehow funneling all of it through the cgraph machinery.

All -gstabs tests ICE because stabs outputs assembly in dbxout_init.
That needs to be put into dbxout_assembly_start (which doesn't
exist yet).  But .. can we kill stabs please?

Given all of the above - not sure if I want to pursue this
further at this point.

        * toplev.h (init_asm_output): Declare.
        * toplev.c (init_asm_output): Export.
        (lang_dependent_init): Do not call it here,
        * cgrapunit.c (symbol_table::compile): but here.
        ...
---
 gcc/cgraph.h         |  4 ++--
 gcc/cgraphunit.c     | 17 ++++++++++++++---
 gcc/lto/lto.c        |  2 +-
 gcc/run-rtl-passes.c |  3 +++
 gcc/toplev.c         | 13 +++++--------
 gcc/toplev.h         |  1 +
 6 files changed, 26 insertions(+), 14 deletions(-)

diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index cfae6e91da9..db4a248e337 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -2278,7 +2278,7 @@ public:
   inline asm_node *finalize_toplevel_asm (tree asm_str);
 
   /* Analyze the whole compilation unit once it is parsed completely.  */
-  void finalize_compilation_unit (void);
+  void finalize_compilation_unit (const char *);
 
   /* C++ frontend produce same body aliases all over the place, even before PCH
      gets streamed out. It relies on us linking the aliases with their function
@@ -2288,7 +2288,7 @@ public:
   void process_same_body_aliases (void);
 
   /* Perform simple optimizations based on callgraph.  */
-  void compile (void);
+  void compile (const char *);
 
   /* Process CGRAPH_NEW_FUNCTIONS and perform actions necessary to add these
      functions into callgraph in a way so they look like ordinary reachable
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index ea9a34bda6f..7836761f21b 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -2731,7 +2731,7 @@ symbol_table::output_weakrefs (void)
 /* Perform simple optimizations based on callgraph.  */
 
 void
-symbol_table::compile (void)
+symbol_table::compile (const char *name)
 {
   if (seen_error ())
     return;
@@ -2753,6 +2753,8 @@ symbol_table::compile (void)
   if (!seen_error ())
   {
     timevar_start (TV_CGRAPH_IPA_PASSES);
+    if (flag_wpa)
+      init_asm_output (name);
     ipa_passes ();
     timevar_stop (TV_CGRAPH_IPA_PASSES);
   }
@@ -2776,6 +2778,12 @@ symbol_table::compile (void)
   timevar_pop (TV_CGRAPHOPT);
 
   /* Output everything.  */
+  if (!flag_wpa && !flag_generate_lto && !flag_generate_offload)
+    {
+      /* ???  The RTL FE may already have opened asm_out_file.  */
+      if (!asm_out_file)
+       init_asm_output (name);
+    }
   switch_to_section (text_section);
   (*debug_hooks->assembly_start) ();
   if (!quiet_flag)
@@ -2943,7 +2951,7 @@ debuginfo_early_stop (void)
 /* Analyze the whole compilation unit once it is parsed completely.  */
 
 void
-symbol_table::finalize_compilation_unit (void)
+symbol_table::finalize_compilation_unit (const char *name)
 {
   timevar_push (TV_CGRAPH);
 
@@ -2994,13 +3002,16 @@ symbol_table::finalize_compilation_unit (void)
 
       /* Clean up anything that needs cleaning up after initial debug
         generation.  */
+
+      if (flag_generate_lto || flag_generate_offload)
+       init_asm_output (name);
       debuginfo_early_start ();
       (*debug_hooks->early_finish) (main_input_filename);
       debuginfo_early_stop ();
     }
 
   /* Finally drive the pass manager.  */
-  compile ();
+  compile (name);
 
   timevar_pop (TV_CGRAPH);
 }
diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c
index 1c37814bde4..b92658e0576 100644
--- a/gcc/lto/lto.c
+++ b/gcc/lto/lto.c
@@ -650,7 +650,7 @@ lto_main (void)
 
          /* Let the middle end know that we have read and merged all of
             the input files.  */
-         symtab->compile ();
+         symtab->compile (main_input_filename);
 
          timevar_stop (TV_PHASE_OPT_GEN);
 
diff --git a/gcc/run-rtl-passes.c b/gcc/run-rtl-passes.c
index fdb24816b4d..b1c5c646125 100644
--- a/gcc/run-rtl-passes.c
+++ b/gcc/run-rtl-passes.c
@@ -35,6 +35,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "insn-attr-common.h" /* for INSN_SCHEDULING.  */
 #include "insn-attr.h" /* for init_sched_attrs.  */
 #include "run-rtl-passes.h"
+#include "toplev.h"
 
 /* Run the backend passes, starting at the given pass.
    Take ownership of INITIAL_PASS_NAME.  */
@@ -46,6 +47,8 @@ run_rtl_passes (char *initial_pass_name)
   max_regno = max_reg_num ();
 
   /* cgraphunit.c normally handles this.  */
+  if (!asm_out_file)
+    init_asm_output (main_input_filename);
   switch_to_section (text_section);
   (*debug_hooks->assembly_start) ();
 
diff --git a/gcc/toplev.c b/gcc/toplev.c
index 95eea63380f..be13c29f381 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -105,11 +105,10 @@ static void do_compile ();
 static void process_options (void);
 static void backend_init (void);
 static int lang_dependent_init (const char *);
-static void init_asm_output (const char *);
 static void finalize (bool);
 
 static void crash_signal (int) ATTRIBUTE_NORETURN;
-static void compile_file (void);
+static void compile_file (const char *);
 
 /* True if we don't need a backend (e.g. preprocessing only).  */
 static bool no_backend;
@@ -449,7 +448,7 @@ wrapup_global_declarations (tree *vec, int len)
    output and various debugging dumps.  */
 
 static void
-compile_file (void)
+compile_file (const char *name)
 {
   timevar_start (TV_PHASE_PARSING);
   timevar_push (TV_PARSE_GLOBAL);
@@ -480,7 +479,7 @@ compile_file (void)
   if (!in_lto_p)
     {
       timevar_start (TV_PHASE_OPT_GEN);
-      symtab->finalize_compilation_unit ();
+      symtab->finalize_compilation_unit (name);
       timevar_stop (TV_PHASE_OPT_GEN);
     }
 
@@ -831,7 +830,7 @@ print_switch_values (print_switch_fn_type print_fn)
    on, because then the driver will have provided the name of a
    temporary file or bit bucket for us.  NAME is the file specified on
    the command line, possibly NULL.  */
-static void
+void
 init_asm_output (const char *name)
 {
   if (name == NULL && asm_file_name == 0)
@@ -2001,8 +2000,6 @@ lang_dependent_init (const char *name)
 
   if (!flag_wpa)
     {
-      init_asm_output (name);
-
       if (!flag_generate_lto && !flag_compare_debug)
        {
          /* If stack usage information is desired, open the output file.  */
@@ -2304,7 +2301,7 @@ do_compile ()
 
           timevar_stop (TV_PHASE_SETUP);
 
-          compile_file ();
+         compile_file (main_input_filename);
         }
       else
         {
diff --git a/gcc/toplev.h b/gcc/toplev.h
index d6c316962b0..556669a475e 100644
--- a/gcc/toplev.h
+++ b/gcc/toplev.h
@@ -52,6 +52,7 @@ extern void rest_of_decl_compilation (tree, int, int);
 extern void rest_of_type_compilation (tree, int);
 extern void init_optimization_passes (void);
 extern bool enable_rtl_dump_file (void);
+extern void init_asm_output (const char *);
 
 /* In except.c.  Initialize exception handling.  This is used by the Ada
    and LTO front ends to initialize EH "on demand".  See lto-streamer-in.c
-- 
2.26.2

Reply via email to