public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Aldy Hernandez <aldyh@redhat.com>
To: Richard Biener <richard.guenther@gmail.com>
Cc: Jason Merrill <jason@redhat.com>, gcc-patches <gcc-patches@gcc.gnu.org>
Subject: Re: [debug-early] reuse variable DIEs and fix their context
Date: Fri, 05 Sep 2014 02:38:00 -0000	[thread overview]
Message-ID: <5409220E.6070100@redhat.com> (raw)
In-Reply-To: <CAFiYyc289dLpQxNSETGkMVOzqP9c0OA4=D+F-9gzw_1OqiN7xg@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 2307 bytes --]

On 09/04/14 03:42, Richard Biener wrote:
> On Wed, Sep 3, 2014 at 7:54 PM, Aldy Hernandez <aldyh@redhat.com> wrote:

> Flow-wise I still want to move hand-off to the cgraph code to toplev.c,
> out from the FEs final_write_gloabals hook:
>
>    /* This must also call finalize_compilation_unit.  */
>    lang_hooks.decls.final_write_globals ();
>
> that would make clearer how control flows.

Neat.  I like it.

> I'd also rather split the hook into two ... (and call the 2nd non-early
> phase hook from where we output the code).  What does that phase
> output for global decls anyway?

This is also a very good idea, and it makes the intent clearer.

> Otherwise looks like a good incremental improvement to me.

Since we're pretty much on the same page, I've committed this revision 
you just looked at, so we can talk about the changes you mention above 
separately, namely:

a) Divorcing final_write_globals and finalize_compilation.
b) Splitting the global_decl hook into two.

So this is what I have in mind (patch attached).  I'd like to split
LANG_HOOKS_WRITE_GLOBALS in favor of 
LANG_HOOKS_{EARLY,LATE}_WRITE_GLOBALS, as well as splitting the 
global_decl debug hook into {early,late}_global_decl.  I've commented 
things throughout to make it very clear what we're getting at.

I chose to dispense with the old names to make it very clear what the 
hook should do, and to make sure I didn't miss any places.

Toplev will now look much cleaner:

+  /* Emit early debugging information as well as globals.  */
+  timevar_start (TV_PHASE_DEFERRED);
+  lang_hooks.decls.early_write_globals ();
+  timevar_stop (TV_PHASE_DEFERRED);
+
+  /* We're done parsing; proceed to optimize and emit assembly.  */
+  timevar_start (TV_PHASE_OPT_GEN);
+  symtab->finalize_compilation_unit ();
+  timevar_stop (TV_PHASE_OPT_GEN);
+
+  /* Amend any debugging information generated previously.  */
+  timevar_start (TV_PHASE_DBGINFO);
+  lang_hooks.decls.late_write_globals ();
+  timevar_stop (TV_PHASE_DBGINFO);

Preeeeety... if I do say so myself.

The attached patch is untested, and will fail miserably on anything but 
C (lto, c++, etc).  But it shows how I'd like to approach this.

Would you bless this approach, so I can continue with the other 
languages and LTO?

As usual, thanks for your feedback.
Aldy

[-- Attachment #2: curr --]
[-- Type: text/plain, Size: 27346 bytes --]

diff --git a/gcc/ada/gcc-interface/misc.c b/gcc/ada/gcc-interface/misc.c
index 240ca44..fd88e44 100644
--- a/gcc/ada/gcc-interface/misc.c
+++ b/gcc/ada/gcc-interface/misc.c
@@ -894,8 +894,9 @@ gnat_init_ts (void)
 #define LANG_HOOKS_GETDECLS		lhd_return_null_tree_v
 #undef  LANG_HOOKS_PUSHDECL
 #define LANG_HOOKS_PUSHDECL		gnat_return_tree
-#undef  LANG_HOOKS_WRITE_GLOBALS
-#define LANG_HOOKS_WRITE_GLOBALS	gnat_write_global_declarations
+/* FIXME: Add Ada support.  */
+#undef  LANG_HOOKS_EARLY_WRITE_GLOBALS
+#define LANG_HOOKS_EARLY_WRITE_GLOBALS	gnat_write_global_declarations
 #undef  LANG_HOOKS_GET_ALIAS_SET
 #define LANG_HOOKS_GET_ALIAS_SET	gnat_get_alias_set
 #undef  LANG_HOOKS_PRINT_DECL
diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
index 1e09404..79ea89c 100644
--- a/gcc/c/c-decl.c
+++ b/gcc/c/c-decl.c
@@ -10310,7 +10310,7 @@ c_write_global_declarations_1 (tree globals)
   for (decl = globals; decl; decl = DECL_CHAIN (decl))
     {
       check_global_declaration_1 (decl);
-      debug_hooks->global_decl (decl, /*early=*/true);
+      debug_hooks->early_global_decl (decl);
     }
 }
 
@@ -10322,8 +10322,10 @@ c_write_global_declarations_2 (tree globals)
 {
   tree decl;
 
+  /* FIXME: Rewrite to iterate through varpool/cgraph nodes, instead
+     of `globals'.  */
   for (decl = globals; decl ; decl = DECL_CHAIN (decl))
-    debug_hooks->global_decl (decl, /*early=*/false);
+    debug_hooks->late_global_decl (decl);
 }
 
 /* Callback to collect a source_ref from a DECL.  */
@@ -10374,17 +10376,12 @@ for_each_global_decl (void (*callback) (tree decl))
 }
 
 void
-c_write_global_declarations (void)
+c_early_write_global_declarations (void)
 {
-  tree t;
-  unsigned i;
-
   /* We don't want to do this if generating a PCH.  */
   if (pch_file)
     return;
 
-  timevar_start (TV_PHASE_DEFERRED);
-
   /* Do the Objective-C stuff.  This is where all the Objective-C
      module stuff gets generated (symtab, class/protocol/selector
      lists etc).  */
@@ -10422,24 +10419,24 @@ c_write_global_declarations (void)
 
   /* Process all file scopes in this compilation, and the external_scope,
      through wrapup_global_declarations and check_global_declarations.  */
+  tree t;
+  unsigned i;
   FOR_EACH_VEC_ELT (*all_translation_units, i, t)
     c_write_global_declarations_1 (BLOCK_VARS (DECL_INITIAL (t)));
   c_write_global_declarations_1 (BLOCK_VARS (ext_block));
+}
 
-  timevar_stop (TV_PHASE_DEFERRED);
-  timevar_start (TV_PHASE_OPT_GEN);
-
-  /* We're done parsing; proceed to optimize and emit assembly.
-     FIXME: shouldn't be the front end's responsibility to call this.  */
-  symtab->finalize_compilation_unit ();
-
-  timevar_stop (TV_PHASE_OPT_GEN);
-  timevar_start (TV_PHASE_DBGINFO);
-
+void
+c_late_write_global_declarations (void)
+{
   /* After cgraph has had a chance to emit everything that's going to
-     be emitted, output debug information for globals.  */
+     be emitted, amend any debug information for globals with
+     appropriate location information.  */
   if (!seen_error ())
     {
+      unsigned int i;
+      tree t;
+
       timevar_push (TV_SYMOUT);
       FOR_EACH_VEC_ELT (*all_translation_units, i, t)
 	c_write_global_declarations_2 (BLOCK_VARS (DECL_INITIAL (t)));
@@ -10448,7 +10445,6 @@ c_write_global_declarations (void)
     }
 
   ext_block = NULL;
-  timevar_stop (TV_PHASE_DBGINFO);
 }
 
 /* Register reserved keyword WORD as qualifier for address space AS.  */
diff --git a/gcc/c/c-objc-common.h b/gcc/c/c-objc-common.h
index 92cf60f..acabeec 100644
--- a/gcc/c/c-objc-common.h
+++ b/gcc/c/c-objc-common.h
@@ -92,8 +92,10 @@ along with GCC; see the file COPYING3.  If not see
 
 #undef LANG_HOOKS_GETDECLS
 #define LANG_HOOKS_GETDECLS lhd_return_null_tree_v
-#undef LANG_HOOKS_WRITE_GLOBALS
-#define LANG_HOOKS_WRITE_GLOBALS c_write_global_declarations
+#undef LANG_HOOKS_EARLY_WRITE_GLOBALS
+#define LANG_HOOKS_EARLY_WRITE_GLOBALS c_early_write_global_declarations
+#undef LANG_HOOKS_LATE_WRITE_GLOBALS
+#define LANG_HOOKS_LATE_WRITE_GLOBALS c_late_write_global_declarations
 
 /* Hooks for tree gimplification.  */
 #undef LANG_HOOKS_GIMPLIFY_EXPR
diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h
index 6004d50..9dada9c 100644
--- a/gcc/c/c-tree.h
+++ b/gcc/c/c-tree.h
@@ -669,7 +669,8 @@ extern enum machine_mode c_default_pointer_mode;
 
 /* In c-decl.c */
 extern void c_finish_incomplete_decl (tree);
-extern void c_write_global_declarations (void);
+extern void c_early_write_global_declarations (void);
+extern void c_late_write_global_declarations (void);
 extern tree c_omp_reduction_id (enum tree_code, tree);
 extern tree c_omp_reduction_decl (tree);
 extern tree c_omp_reduction_lookup (tree, tree);
diff --git a/gcc/cp/cp-objcp-common.h b/gcc/cp/cp-objcp-common.h
index 246800e..2435e06 100644
--- a/gcc/cp/cp-objcp-common.h
+++ b/gcc/cp/cp-objcp-common.h
@@ -83,8 +83,9 @@ extern void cp_common_init_ts (void);
 #define LANG_HOOKS_PRINT_ERROR_FUNCTION	cxx_print_error_function
 #undef LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL
 #define LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL cxx_warn_unused_global_decl
-#undef LANG_HOOKS_WRITE_GLOBALS
-#define LANG_HOOKS_WRITE_GLOBALS cp_write_global_declarations
+/* FIXME: Add C++ support.  */
+#undef LANG_HOOKS_EARLY_WRITE_GLOBALS
+#define LANG_HOOKS_EARLY_WRITE_GLOBALS cp_write_global_declarations
 #undef  LANG_HOOKS_BUILTIN_FUNCTION
 #define LANG_HOOKS_BUILTIN_FUNCTION cxx_builtin_function
 #undef  LANG_HOOKS_BUILTIN_FUNCTION_EXT_SCOPE
diff --git a/gcc/dbxout.c b/gcc/dbxout.c
index 208cec9..e517311 100644
--- a/gcc/dbxout.c
+++ b/gcc/dbxout.c
@@ -325,7 +325,7 @@ static int dbxout_symbol_location (tree, tree, const char *, rtx);
 static void dbxout_symbol_name (tree, const char *, int);
 static void dbxout_common_name (tree, const char *, stab_code_type);
 static const char *dbxout_common_check (tree, int *);
-static void dbxout_global_decl (tree, bool);
+static void dbxout_global_decl (tree);
 static void dbxout_type_decl (tree, int);
 static void dbxout_handle_pch (unsigned);
 static void debug_free_queue (void);
@@ -366,7 +366,8 @@ const struct gcc_debug_hooks dbx_debug_hooks =
 #endif
   debug_nothing_int,		         /* end_function */
   dbxout_function_decl,
-  dbxout_global_decl,		         /* global_decl */
+  debug_nothing_tree,		         /* early_global_decl */
+  dbxout_global_decl,		         /* late_global_decl */
   dbxout_type_decl,			 /* type_decl */
   debug_nothing_tree_tree_tree_bool,	 /* imported_module_or_decl */
   debug_nothing_tree,		         /* deferred_inline_function */
@@ -402,7 +403,8 @@ const struct gcc_debug_hooks xcoff_debug_hooks =
   debug_nothing_tree,		         /* begin_function */
   xcoffout_end_function,
   debug_nothing_tree,		         /* function_decl */
-  dbxout_global_decl,		         /* global_decl */
+  debug_nothing_tree,		         /* early_global_decl */
+  dbxout_global_decl,		         /* late_global_decl */
   dbxout_type_decl,			 /* type_decl */
   debug_nothing_tree_tree_tree_bool,	 /* imported_module_or_decl */
   debug_nothing_tree,		         /* deferred_inline_function */
@@ -1320,7 +1322,7 @@ dbxout_function_decl (tree decl)
 /* Debug information for a global DECL.  Called from toplev.c after
    compilation proper has finished.  */
 static void
-dbxout_global_decl (tree decl, bool early ATTRIBUTE_UNUSED)
+dbxout_global_decl (tree decl)
 {
   if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl))
     {
diff --git a/gcc/debug.c b/gcc/debug.c
index b5818de..2beb10f 100644
--- a/gcc/debug.c
+++ b/gcc/debug.c
@@ -43,7 +43,8 @@ const struct gcc_debug_hooks do_nothing_debug_hooks =
   debug_nothing_tree,		         /* begin_function */
   debug_nothing_int,		         /* end_function */
   debug_nothing_tree,		         /* function_decl */
-  debug_nothing_tree_bool,	         /* global_decl */
+  debug_nothing_tree,			 /* early_global_decl */
+  debug_nothing_tree,	         	 /* late_global_decl */
   debug_nothing_tree_int,		 /* type_decl */
   debug_nothing_tree_tree_tree_bool,	 /* imported_module_or_decl */
   debug_nothing_tree,		         /* deferred_inline_function */
diff --git a/gcc/debug.h b/gcc/debug.h
index 9440515..227618d 100644
--- a/gcc/debug.h
+++ b/gcc/debug.h
@@ -92,12 +92,22 @@ struct gcc_debug_hooks
      function.  */
   void (* function_decl) (tree decl);
 
-  /* Debug information for a global DECL.  Called from toplev.c after
-     compilation proper has finished.  EARLY is true if global_decl()
-     is being called early on in the compilation process (i.e., before
-     cgraph information is available and before code is
-     generated).  */
-  void (* global_decl) (tree decl, bool early);
+  /* Debug information for a global DECL.  Called before the
+     compilation proper has run (i.e., before cgraph information is
+     available, usually after parsing has completed).
+
+     This hooks gets called to emit initial debugging information
+     after parsing has happened, but before we have complete location
+     information.  When the compilation proper has finished,
+     late_global_decl (below) is called and the debugging information
+     generated by this hook is amended accordingly.  */
+  void (* early_global_decl) (tree decl);
+
+  /* This hook is called after the compilation proper has finished and
+     is used to ammend debugging information which was initially
+     generated by early_global_decl above (with location information
+     and such).  */
+  void (* late_global_decl) (tree decl);
 
   /* Debug information for a type DECL.  Called from toplev.c after
      compilation proper, also from various language front ends to
@@ -191,8 +201,6 @@ extern void dwarf2out_switch_text_section (void);
 const char *remap_debug_filename (const char *);
 void add_debug_prefix_map (const char *);
 
-extern void dwarf2out_early_decl (tree);
-
 /* For -fdump-go-spec.  */
 
 extern const struct gcc_debug_hooks *
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 918f261..f3f8481 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -2430,7 +2430,8 @@ static void dwarf2out_function_decl (tree);
 static void dwarf2out_begin_block (unsigned, unsigned);
 static void dwarf2out_end_block (unsigned, unsigned);
 static bool dwarf2out_ignore_block (const_tree);
-static void dwarf2out_global_decl (tree, bool);
+static void dwarf2out_early_global_decl (tree);
+static void dwarf2out_late_global_decl (tree);
 static void dwarf2out_type_decl (tree, int);
 static void dwarf2out_imported_module_or_decl (tree, tree, tree, bool);
 static void dwarf2out_imported_module_or_decl_1 (tree, tree, tree,
@@ -2468,7 +2469,8 @@ const struct gcc_debug_hooks dwarf2_debug_hooks =
   dwarf2out_begin_function,
   dwarf2out_end_function,	/* end_function */
   dwarf2out_function_decl,	/* function_decl */
-  dwarf2out_global_decl,
+  dwarf2out_early_global_decl,	/* early_global_decl */
+  dwarf2out_late_global_decl,	/* late_global_decl */
   dwarf2out_type_decl,		/* type_decl */
   dwarf2out_imported_module_or_decl,
   debug_nothing_tree,		/* deferred_inline_function */
@@ -2609,7 +2611,7 @@ typedef struct GTY((chain_circular ("%h.die_sib"))) die_struct {
   /* Die is used and must not be pruned as unused.  */
   BOOL_BITFIELD die_perennial_p : 1;
   BOOL_BITFIELD comdat_type_p : 1; /* DIE has a type signature */
-  /* Die was generated early via dwarf2out_early_decl.  */
+  /* Die was generated early via dwarf2out_early_global_decl.  */
   BOOL_BITFIELD dumped_early : 1;
   /* Lots of spare bits.  */
 }
@@ -20817,29 +20819,65 @@ gen_decl_die (tree decl, tree origin, dw_die_ref context_die)
   return NULL;
 }
 \f
-/* Output debug information for global decl DECL.  Called from
-   toplev.c after compilation proper has finished.
-
-   dwarf2out_decl() will be called twice on each global symbol: once
-   immediately after parsing (EARLY=true), and once after the full
-   compilation has finished (EARLY=false).  There are checks in
-   dwarf2out_decl() to make sure that if we have a DECL DIE upon
-   entry, that the previously created DIE is reused.  No new DECL DIEs
-   should be created when EARLY=false.
-
-   The second time dwarf2out_decl() is called (or for that matter, the
-   second time any DECL DIE is seen throughout dwarf2out), only
-   information not previously available (e.g. location) is tacked onto
-   the early dumped DIE.  That's the plan anyhow ;-).  */
+/* Output initial debug information for global decl DECL.  Called from
+   toplev.c after parsing has finished.  After the compilation proper
+   has finished, the debugging information generated here is amended
+   with location information and other things (see
+   dwarf2out_late_global_decl).  */
 
 static void
-dwarf2out_global_decl (tree decl, bool early)
+dwarf2out_early_global_decl (tree decl)
 {
-  if (early)
+  /* gen_decl_die() will set DECL_ABSTRACT because
+     cgraph_function_possibly_inlined_p() returns true.  This is in
+     turn will cause DW_AT_inline attributes to be set.
+
+     This happens because at early dwarf generation, there is no
+     cgraph information, causing cgraph_function_possibly_inlined_p()
+     to return true.  Trick cgraph_function_possibly_inlined_p()
+     while we generate dwarf early.  */
+  bool save = symtab->global_info_ready;
+  symtab->global_info_ready = true;
+
+  /* We don't handle TYPE_DECLs.  If required, they'll be reached via
+     other DECLs and they can point to template types or other things
+     that dwarf2out can't handle when done via dwarf2out_decl.  */
+  if (TREE_CODE (decl) != TYPE_DECL
+      && TREE_CODE (decl) != PARM_DECL)
     {
-      dwarf2out_early_decl (decl);
-      return;
+      if (TREE_CODE (decl) == FUNCTION_DECL)
+	{
+	  /* A missing cfun means the symbol is unused and was removed
+	     from the callgraph.  */
+	  if (!DECL_STRUCT_FUNCTION (decl))
+	    goto early_decl_exit;
+
+	  push_cfun (DECL_STRUCT_FUNCTION (decl));
+	  current_function_decl = decl;
+	}
+      dw_die_ref die = dwarf2out_decl (decl);
+      if (die)
+	die->dumped_early = true;
+      if (TREE_CODE (decl) == FUNCTION_DECL)
+	{
+	  pop_cfun ();
+	  current_function_decl = NULL;
+	}
     }
+ early_decl_exit:
+  symtab->global_info_ready = save;
+  return;
+}
+
+/* After the compilation proper has finished, augment any debugging
+   information generated in dwarf2out_early_global_decl().  No new
+   DECL DIEs should be generated at this point.  Instead, DIEs
+   generated in dwarf2out_early_global_decl should be reused and
+   amended.  */
+
+static void
+dwarf2out_late_global_decl (tree decl)
+{
   /* Output DWARF2 information for file-scope tentative data object
      declarations, file-scope (extern) function declarations (which
      had no corresponding body) and file-scope tagged type declarations
@@ -21181,52 +21219,6 @@ dwarf2out_decl (tree decl)
   return die;
 }
 
-/* Early dumping of DECLs before we lose language data.  */
-
-void
-dwarf2out_early_decl (tree decl)
-{
-  /* gen_decl_die() will set DECL_ABSTRACT because
-     cgraph_function_possibly_inlined_p() returns true.  This is in
-     turn will cause DW_AT_inline attributes to be set.
-
-     This happens because at early dwarf generation, there is no
-     cgraph information, causing cgraph_function_possibly_inlined_p()
-     to return true.  Trick cgraph_function_possibly_inlined_p()
-     while we generate dwarf early.  */
-  bool save = symtab->global_info_ready;
-  symtab->global_info_ready = true;
-
-  /* We don't handle TYPE_DECLs.  If required, they'll be reached via
-     other DECLs and they can point to template types or other things
-     that dwarf2out can't handle when done via dwarf2out_decl.  */
-  if (TREE_CODE (decl) != TYPE_DECL
-      && TREE_CODE (decl) != PARM_DECL)
-    {
-      if (TREE_CODE (decl) == FUNCTION_DECL)
-	{
-	  /* A missing cfun means the symbol is unused and was removed
-	     from the callgraph.  */
-	  if (!DECL_STRUCT_FUNCTION (decl))
-	    goto early_decl_exit;
-
-	  push_cfun (DECL_STRUCT_FUNCTION (decl));
-	  current_function_decl = decl;
-	}
-      dw_die_ref die = dwarf2out_decl (decl);
-      if (die)
-	die->dumped_early = true;
-      if (TREE_CODE (decl) == FUNCTION_DECL)
-	{
-	  pop_cfun ();
-	  current_function_decl = NULL;
-	}
-    }
- early_decl_exit:
-  symtab->global_info_ready = save;
-  return;
-}
-
 /* Write the debugging output for DECL.  */
 
 static void
diff --git a/gcc/fortran/f95-lang.c b/gcc/fortran/f95-lang.c
index da3a0d0..d435c07 100644
--- a/gcc/fortran/f95-lang.c
+++ b/gcc/fortran/f95-lang.c
@@ -108,7 +108,8 @@ static const struct attribute_spec gfc_attribute_table[] =
 #undef LANG_HOOKS_NAME
 #undef LANG_HOOKS_INIT
 #undef LANG_HOOKS_FINISH
-#undef LANG_HOOKS_WRITE_GLOBALS
+#undef LANG_HOOKS_EARLY_WRITE_GLOBALS
+#undef LANG_HOOKS_LATE_WRITE_GLOBALS
 #undef LANG_HOOKS_OPTION_LANG_MASK
 #undef LANG_HOOKS_INIT_OPTIONS_STRUCT
 #undef LANG_HOOKS_INIT_OPTIONS
@@ -142,7 +143,8 @@ static const struct attribute_spec gfc_attribute_table[] =
 #define LANG_HOOKS_NAME                 "GNU Fortran"
 #define LANG_HOOKS_INIT                 gfc_init
 #define LANG_HOOKS_FINISH               gfc_finish
-#define LANG_HOOKS_WRITE_GLOBALS	gfc_write_global_declarations
+/* FIXME: Add Fortran support.  */
+#define LANG_HOOKS_EARLY_WRITE_GLOBALS	gfc_write_global_declarations
 #define LANG_HOOKS_OPTION_LANG_MASK	gfc_option_lang_mask
 #define LANG_HOOKS_INIT_OPTIONS_STRUCT  gfc_init_options_struct
 #define LANG_HOOKS_INIT_OPTIONS         gfc_init_options
diff --git a/gcc/go/go-lang.c b/gcc/go/go-lang.c
index 24b6437..a2aec63 100644
--- a/gcc/go/go-lang.c
+++ b/gcc/go/go-lang.c
@@ -534,7 +534,8 @@ go_localize_identifier (const char *ident)
 #undef LANG_HOOKS_GLOBAL_BINDINGS_P
 #undef LANG_HOOKS_PUSHDECL
 #undef LANG_HOOKS_GETDECLS
-#undef LANG_HOOKS_WRITE_GLOBALS
+#undef LANG_HOOKS_EARLY_WRITE_GLOBALS
+#undef LANG_HOOKS_LATE_WRITE_GLOBALS
 #undef LANG_HOOKS_GIMPLIFY_EXPR
 #undef LANG_HOOKS_EH_PERSONALITY
 
@@ -551,7 +552,8 @@ go_localize_identifier (const char *ident)
 #define LANG_HOOKS_GLOBAL_BINDINGS_P	go_langhook_global_bindings_p
 #define LANG_HOOKS_PUSHDECL		go_langhook_pushdecl
 #define LANG_HOOKS_GETDECLS		go_langhook_getdecls
-#define LANG_HOOKS_WRITE_GLOBALS	go_langhook_write_globals
+/* FIXME: Add Go support.  */
+#define LANG_HOOKS_EARLY_WRITE_GLOBALS	go_langhook_write_globals
 #define LANG_HOOKS_GIMPLIFY_EXPR	go_langhook_gimplify_expr
 #define LANG_HOOKS_EH_PERSONALITY	go_langhook_eh_personality
 
diff --git a/gcc/godump.c b/gcc/godump.c
index 01f8410..888dcb0 100644
--- a/gcc/godump.c
+++ b/gcc/godump.c
@@ -496,9 +496,9 @@ go_function_decl (tree decl)
 /* A global variable decl.  */
 
 static void
-go_global_decl (tree decl, bool early)
+go_global_decl (tree decl)
 {
-  real_debug_hooks->global_decl (decl, early);
+  real_debug_hooks->late_global_decl (decl);
   go_decl (decl);
 }
 
@@ -1240,7 +1240,7 @@ dump_go_spec_init (const char *filename, const struct gcc_debug_hooks *hooks)
   go_debug_hooks.define = go_define;
   go_debug_hooks.undef = go_undef;
   go_debug_hooks.function_decl = go_function_decl;
-  go_debug_hooks.global_decl = go_global_decl;
+  go_debug_hooks.late_global_decl = go_global_decl;
   go_debug_hooks.type_decl = go_type_decl;
 
   macro_hash = htab_create (100, macro_hash_hashval, macro_hash_eq,
diff --git a/gcc/java/lang.c b/gcc/java/lang.c
index 8a68691..5cdaa15 100644
--- a/gcc/java/lang.c
+++ b/gcc/java/lang.c
@@ -142,8 +142,9 @@ struct GTY(()) language_function {
 #define LANG_HOOKS_DECL_PRINTABLE_NAME lang_printable_name
 #undef LANG_HOOKS_PRINT_ERROR_FUNCTION
 #define LANG_HOOKS_PRINT_ERROR_FUNCTION	java_print_error_function
-#undef LANG_HOOKS_WRITE_GLOBALS
-#define LANG_HOOKS_WRITE_GLOBALS java_write_globals
+/* FIXME: Add Java support.  */
+#undef LANG_HOOKS_EARLY_WRITE_GLOBALS
+#define LANG_HOOKS_EARLY_WRITE_GLOBALS java_write_globals
 
 #undef LANG_HOOKS_TYPE_FOR_MODE
 #define LANG_HOOKS_TYPE_FOR_MODE java_type_for_mode
diff --git a/gcc/langhooks-def.h b/gcc/langhooks-def.h
index e77d2d9..410690b 100644
--- a/gcc/langhooks-def.h
+++ b/gcc/langhooks-def.h
@@ -204,7 +204,8 @@ extern tree lhd_make_node (enum tree_code);
 #define LANG_HOOKS_GETDECLS	getdecls
 #define LANG_HOOKS_FUNCTION_DECL_EXPLICIT_P hook_bool_tree_false
 #define LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL lhd_warn_unused_global_decl
-#define LANG_HOOKS_WRITE_GLOBALS write_global_declarations
+#define LANG_HOOKS_EARLY_WRITE_GLOBALS early_write_global_declarations
+#define LANG_HOOKS_LATE_WRITE_GLOBALS late_write_global_declarations
 #define LANG_HOOKS_DECL_OK_FOR_SIBCALL	lhd_decl_ok_for_sibcall
 #define LANG_HOOKS_OMP_PRIVATIZE_BY_REFERENCE hook_bool_const_tree_false
 #define LANG_HOOKS_OMP_PREDETERMINED_SHARING lhd_omp_predetermined_sharing
@@ -228,7 +229,8 @@ extern tree lhd_make_node (enum tree_code);
   LANG_HOOKS_FUNCTION_PARM_EXPANDED_FROM_PACK_P, \
   LANG_HOOKS_GET_GENERIC_FUNCTION_DECL, \
   LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL, \
-  LANG_HOOKS_WRITE_GLOBALS, \
+  LANG_HOOKS_EARLY_WRITE_GLOBALS, \
+  LANG_HOOKS_LATE_WRITE_GLOBALS, \
   LANG_HOOKS_DECL_OK_FOR_SIBCALL, \
   LANG_HOOKS_OMP_PRIVATIZE_BY_REFERENCE, \
   LANG_HOOKS_OMP_PREDETERMINED_SHARING, \
diff --git a/gcc/langhooks.c b/gcc/langhooks.c
index 8ff91ba..c0d7459 100644
--- a/gcc/langhooks.c
+++ b/gcc/langhooks.c
@@ -290,45 +290,48 @@ lhd_decl_ok_for_sibcall (const_tree decl ATTRIBUTE_UNUSED)
   return true;
 }
 
-/* lang_hooks.decls.final_write_globals: perform final processing on
+/* FIXME: Rewrite this to use <vec>.  Remove this eventually (see note
+   in late_write_global_declarations).  */
+static tree *globals_vec;
+static int globals_vec_len;
+
+/* lang_hooks.decls.early_write_globals: perform final processing on
    global variables.  */
 void
-write_global_declarations (void)
+early_write_global_declarations (void)
 {
-  tree globals, decl, *vec;
-  int len, i;
+  tree globals, decl;
 
-  timevar_start (TV_PHASE_DEFERRED);
   /* Really define vars that have had only a tentative definition.
      Really output inline functions that must actually be callable
      and have not been output so far.  */
 
   globals = lang_hooks.decls.getdecls ();
-  len = list_length (globals);
-  vec = XNEWVEC (tree, len);
+  globals_vec_len = list_length (globals);
+  globals_vec = XNEWVEC (tree, globals_vec_len);
 
   /* Process the decls in reverse order--earliest first.
      Put them into VEC from back to front, then take out from front.  */
+  int i;
+  for (i = 0, decl = globals; i < globals_vec_len;
+       i++, decl = DECL_CHAIN (decl))
+    globals_vec[globals_vec_len - i - 1] = decl;
 
-  for (i = 0, decl = globals; i < len; i++, decl = DECL_CHAIN (decl))
-    vec[len - i - 1] = decl;
-
-  wrapup_global_declarations (vec, len);
-  check_global_declarations (vec, len);
-  timevar_stop (TV_PHASE_DEFERRED);
-
-  timevar_start (TV_PHASE_OPT_GEN);
-  /* This lang hook is dual-purposed, and also finalizes the
-     compilation unit.  */
-  symtab->finalize_compilation_unit ();
-  timevar_stop (TV_PHASE_OPT_GEN);
+  wrapup_global_declarations (globals_vec, globals_vec_len);
+  check_global_declarations (globals_vec, globals_vec_len);
+}
 
-  timevar_start (TV_PHASE_DBGINFO);
-  emit_debug_global_declarations (vec, len);
-  timevar_stop (TV_PHASE_DBGINFO);
+/* lang_hooks.decls.late_write_globals: perform final processing on
+   global variables.  */
+void
+late_write_global_declarations (void)
+{
+  /* FIXME: Rewrite this to use the cgraph/varpool iterators instead
+     of globals_vec.  */
+  emit_debug_global_declarations (globals_vec, globals_vec_len);
 
   /* Clean up.  */
-  free (vec);
+  free (globals_vec);
 }
 
 /* Called to perform language-specific initialization of CTX.  */
diff --git a/gcc/langhooks.h b/gcc/langhooks.h
index 72fa85e..7e33f3a 100644
--- a/gcc/langhooks.h
+++ b/gcc/langhooks.h
@@ -181,9 +181,16 @@ struct lang_hooks_for_decls
      We will already have checked that it has static binding.  */
   bool (*warn_unused_global) (const_tree);
 
-  /* Obtain a list of globals and do final output on them at end
-     of compilation */
-  void (*final_write_globals) (void);
+  /* Obtain a list of globals and do final output on them after
+     parsing (before compilation).  This also involves outputting
+     initial debugging information after parsing.  */
+  void (*early_write_globals) (void);
+
+  /* Perform any final output of globals after compilation (cgraph
+     information is available).  This usually involves amending any
+     debugging information originally outputted by the
+     early_write_globals hook above.  */
+  void (*late_write_globals) (void);
 
   /* True if this decl may be called via a sibcall.  */
   bool (*ok_for_sibcall) (const_tree);
diff --git a/gcc/lto/lto-lang.c b/gcc/lto/lto-lang.c
index 1f39949..de65854 100644
--- a/gcc/lto/lto-lang.c
+++ b/gcc/lto/lto-lang.c
@@ -1093,7 +1093,7 @@ lto_write_globals (void)
   varpool_node *vnode;
   FOR_EACH_DEFINED_VARIABLE (vnode)
     if (!decl_function_context (vnode->decl))
-      debug_hooks->global_decl (vnode->decl, /*early=*/false);
+      debug_hooks->late_global_decl (vnode->decl);
 }
 
 static tree
@@ -1275,8 +1275,10 @@ static void lto_init_ts (void)
 #define LANG_HOOKS_PUSHDECL lto_pushdecl
 #undef LANG_HOOKS_GETDECLS
 #define LANG_HOOKS_GETDECLS lto_getdecls
-#undef LANG_HOOKS_WRITE_GLOBALS
-#define LANG_HOOKS_WRITE_GLOBALS lto_write_globals
+#undef LANG_HOOKS_EARLY_WRITE_GLOBALS
+#define LANG_HOOKS_EARLY_WRITE_GLOBALS debug_nothing_void
+#undef LANG_HOOKS_LATE_WRITE_GLOBALS
+#define LANG_HOOKS_LATE_WRITE_GLOBALS lto_write_globals
 #undef LANG_HOOKS_REGISTER_BUILTIN_TYPE
 #define LANG_HOOKS_REGISTER_BUILTIN_TYPE lto_register_builtin_type
 #undef LANG_HOOKS_BUILTIN_FUNCTION
diff --git a/gcc/toplev.c b/gcc/toplev.c
index ceefa1b..151bc04 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -532,7 +532,7 @@ emit_debug_global_declarations (tree *vec, int len)
 
   timevar_push (TV_SYMOUT);
   for (i = 0; i < len; i++)
-    debug_hooks->global_decl (vec[i], /*early=*/false);
+    debug_hooks->late_global_decl (vec[i]);
   timevar_pop (TV_SYMOUT);
 }
 
@@ -560,8 +560,20 @@ compile_file (void)
 
   ggc_protect_identifiers = false;
 
-  /* This must also call finalize_compilation_unit.  */
-  lang_hooks.decls.final_write_globals ();
+  /* Emit early debugging information as well as globals.  */
+  timevar_start (TV_PHASE_DEFERRED);
+  lang_hooks.decls.early_write_globals ();
+  timevar_stop (TV_PHASE_DEFERRED);
+
+  /* We're done parsing; proceed to optimize and emit assembly.  */
+  timevar_start (TV_PHASE_OPT_GEN);
+  symtab->finalize_compilation_unit ();
+  timevar_stop (TV_PHASE_OPT_GEN);
+
+  /* Amend any debugging information generated previously.  */
+  timevar_start (TV_PHASE_DBGINFO);
+  lang_hooks.decls.late_write_globals ();
+  timevar_stop (TV_PHASE_DBGINFO);
 
   if (seen_error ())
     return;
diff --git a/gcc/toplev.h b/gcc/toplev.h
index 1b54578..807b3f1 100644
--- a/gcc/toplev.h
+++ b/gcc/toplev.h
@@ -43,7 +43,6 @@ extern bool wrapup_global_declarations (tree *, int);
 extern void check_global_declaration_1 (tree);
 extern void check_global_declarations (tree *, int);
 extern void emit_debug_global_declarations (tree *, int);
-extern void write_global_declarations (void);
 
 extern void dump_memory_report (bool);
 extern void dump_profile_report (void);

  reply	other threads:[~2014-09-05  2:38 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-08-27  2:43 Aldy Hernandez
2014-08-28 13:58 ` Richard Biener
2014-08-28 17:35   ` Aldy Hernandez
2014-08-28 18:01     ` Jason Merrill
2014-08-28 19:13       ` Richard Biener
2014-08-28 20:14         ` Jason Merrill
2014-08-29  9:09           ` Richard Biener
2014-09-03 17:55       ` Aldy Hernandez
2014-09-04 10:42         ` Richard Biener
2014-09-05  2:38           ` Aldy Hernandez [this message]
2014-09-05  9:00             ` Richard Biener
2014-09-09  0:01               ` Aldy Hernandez
2014-09-09  9:16                 ` Richard Biener
2014-09-12  0:51                   ` Aldy Hernandez
2014-09-12  8:13                     ` Richard Biener
2014-09-12 15:15                     ` Jason Merrill
2014-09-12 17:11                       ` Aldy Hernandez
2014-09-12 17:33                         ` Jason Merrill
2014-09-12 17:48                           ` Aldy Hernandez
2014-09-12 17:56                             ` Jason Merrill
2014-09-16 15:49                               ` Aldy Hernandez
2014-09-15  9:32                         ` Richard Biener
2014-09-15 18:46                           ` Jason Merrill
2014-12-18 19:26                       ` Aldy Hernandez
2014-12-19 11:20                         ` Richard Biener
2014-12-19 18:58                           ` Jan Hubicka
2014-12-19 19:01                             ` Jan Hubicka
2014-12-19 19:02                               ` Aldy Hernandez
2014-12-19 19:31                                 ` Jason Merrill
2014-12-19 19:50                                   ` Jan Hubicka
2014-12-20 10:09                                   ` Aldy Hernandez
2015-01-08 12:24                                     ` Richard Biener
2014-12-19 19:03                             ` Aldy Hernandez
2014-09-04 17:53         ` H.J. Lu
2014-09-04 17:54           ` Aldy Hernandez
2014-09-04 18:23             ` Richard Biener
2014-09-04 18:35               ` Aldy Hernandez
2014-09-04 18:38                 ` Christophe Lyon
2014-09-04 19:42                 ` Jan-Benedict Glaw
2015-01-08 15:20 Aldy Hernandez

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5409220E.6070100@redhat.com \
    --to=aldyh@redhat.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=jason@redhat.com \
    --cc=richard.guenther@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).