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;
 }
 
-/* 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);
