This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH][2/2] early LTO debug, main part


On Wed, 7 Jun 2017, Richard Biener wrote:

> On Fri, 19 May 2017, Richard Biener wrote:
> 
> > 
> > This is a repost of the main part of the early LTO debug support.
> > The only changes relative to the last post is in the dwarf2out.c
> > pieces due to Jasons review and Jakubs introduction of
> > DW_OP_GNU_variable_value.
> > 
> > I've also adjusted testcases for fallout (the asan backtraces do
> > give files / line numbers because libbacktrace doesn't understand
> > the DWARF) plus added a -flto run over the libstdc++ pretty printer
> > testsuite -- after all the goal was to make those work with LTO,
> > and they now nicely do.
> > 
> > [LTO-]bootstrapped and tested on x86_64-unknown-linux-gnu.
> > 
> > I've also tested with -flto -g and compared to before the patch and
> > the outcome doesn't contain any surprises.
> > 
> > I've also ran the gdb testsuite with no differences (but I guess
> > it doesn't exercise LTO).
> > 
> > I've also built SPEC 2k6 with -flto -g.
> > 
> > I've also debugged optimized LTO bootstrapped cc1 a bit - not that
> > debugging (LTO) optimized cc1 is a pleasant experience, but at least
> > gdb doesn't crash.
> > 
> > Ok for trunk?
> 
> Ping.

Ping^2.

> > Both darwin and mingw maintainers were not concerned about LTO with -g
> > being broken for them.
> > 
> > This patch allows us to go forward with freeing more stuff after
> > the frontend finished, in particular remove LTO streaming of a lot
> > of type information that is referenced from trees (and, as a first
> > step, enable free-lang-data for non-LTO compiles).
> > 
> > Thanks,
> > Richard.
> > 
> > 2017-05-19  Richard Biener  <rguenther@suse.de>
> > 
> >         * debug.h (struct gcc_debug_hooks): Add die_ref_for_decl and
> >         register_external_die hooks.
> >         (debug_false_tree_charstarstar_uhwistar): Declare.
> >         (debug_nothing_tree_charstar_uhwi): Likewise.
> >         * debug.c (do_nothing_debug_hooks): Adjust.
> >         (debug_false_tree_charstarstar_uhwistar): New do nothing.
> >         (debug_nothing_tree_charstar_uhwi): Likewise.
> >         * dbxout.c (dbx_debug_hooks): Adjust.
> >         (xcoff_debug_hooks): Likewise.
> >         * sdbout.c (sdb_debug_hooks): Likewise.
> >         * vmsdbgout.c (vmsdbg_debug_hooks): Likewise.
> > 
> >         * dwarf2out.c (macinfo_label_base): New global.
> > 	(dwarf2out_register_external_die): New function for the
> > 	register_external_die hook.
> >         (dwarf2out_die_ref_for_decl): Likewise for die_ref_for_decl.
> >         (dwarf2_debug_hooks): Use them.
> >         (dwarf2_lineno_debug_hooks): Adjust.
> >         (struct die_struct): Add with_offset flag.
> >         (DEBUG_LTO_DWO_INFO_SECTION, DEBUG_LTO_INFO_SECTION,
> >         DEBUG_LTO_DWO_ABBREV_SECTION, DEBUG_LTO_ABBREV_SECTION,
> >         DEBUG_LTO_DWO_MACINFO_SECTION, DEBUG_LTO_MACINFO_SECTION,
> >         DEBUG_LTO_DWO_MACRO_SECTION, DEBUG_LTO_MACRO_SECTION,
> >         DEBUG_LTO_LINE_SECTION, DEBUG_LTO_DWO_STR_OFFSETS_SECTION,
> >         DEBUG_LTO_STR_DWO_SECTION, DEBUG_STR_LTO_SECTION): New macros
> >         defining section names for the early LTO debug variants.
> > 	(reset_indirect_string): New helper.
> >         (add_AT_external_die_ref): Helper for dwarf2out_register_external_die.
> >         (print_dw_val): Add support for offsetted symbol references.
> >         (compute_section_prefix_1): Split out worker to distinguish
> >         the comdat from the LTO case.
> >         (compute_section_prefix): Wrap old comdat case here.
> >         (output_die): Skip DIE symbol output for the LTO added one.
> >         Handle DIE symbol references with offset.
> >         (output_comp_unit): Guard section name mangling properly.
> >         For LTO debug sections emit a symbol at the section beginning
> >         which we use to refer to its DIEs.
> >         (add_abstract_origin_attribute): For DIEs registered via
> >         dwarf2out_register_external_die directly refer to the early
> >         DIE rather than indirectly through the shadow one we created.
> >         (gen_array_type_die): When generating early LTO debug do
> >         not emit DW_AT_string_length.
> >         (gen_formal_parameter_die): Do not re-create DIEs for PARM_DECLs
> >         late when in LTO.
> >         (gen_subprogram_die): Adjust the check for whether we face
> >         a concrete instance DIE for an inline we can reuse for the
> >         late LTO case.  Likewise avoid another specification DIE
> >         for early built declarations/definitions for the late LTO case.
> >         (gen_variable_die): Add type references for late duplicated VLA dies
> >         when in late LTO.
> >         (gen_inlined_subroutine_die): Do not call dwarf2out_abstract_function,
> >         we have the abstract instance already.
> >         (process_scope_var): Adjust decl DIE contexts in LTO which
> >         first puts them in limbo.
> >         (gen_decl_die): Do not generate type DIEs late apart from
> >         types for VLAs or for decls we do not yet have a DIE.
> >         (dwarf2out_early_global_decl): Make sure to create DIEs
> >         for abstract instances of a decl first.
> >         (dwarf2out_late_global_decl): Adjust comment.
> >         (output_macinfo_op): With multiple macro sections use
> > 	macinfo_label_base to distinguish labels.
> >         (output_macinfo): Likewise.  Update macinfo_label_base.
> > 	Pass in the line info label.
> > 	(note_variable_value_in_expr): When generating LTO resolve
> > 	all variable values here by generating DIEs as needed.
> >         (init_sections_and_labels): Add early LTO debug flag parameter
> >         and generate different sections and names if set.  Add generation
> >         counter for the labels so we can have multiple of them.
> >         (reset_dies): Helper to allow DIEs to be output multiple times.
> >         (dwarf2out_finish): When outputting DIEs to the fat part of an
> > 	LTO object first reset DIEs.
> >         (dwarf2out_early_finish): Output early DIEs when generating LTO.
> > 
> > Cleanups we can do (and need) when removing the "old" LTO path and add
> > the early LTO path.
> > 
> >         (set_decl_abstract_flags): Remove.
> >         (set_block_abstract_flags): Likewise.
> >         (dwarf2out_abstract_function): Treat the early generated DIEs
> >         as the abstract copy and only add DW_AT_inline and
> >         DW_AT_artificial here.
> > 
> > 	* tree.c (free_lang_data): Build a dummy TRANSLATION_UNIT_DECL
> > 	if we have none yet (Go fails to build one, PR78628).
> >         * lto-streamer-in.c: Include debug.h.
> >         (dref_queue): New global.
> >         (lto_read_tree_1): Stream in DIE references.
> >         (lto_input_tree): Register DIE references.
> > 	(input_function): Stream DECL_DEBUG_ARGS.
> >         * lto-streamer-out.c: Include debug.h.
> >         (lto_write_tree_1): Output DIE references.
> >         (DFS::DFS_write_tree_body): Follow DECL_ABSTRACT_ORIGIN.
> > 	Force a TRANSLATION_UNIT_DECL DECL_CONTEXT for file-scope decls.
> > 	(output_function): Stream DECL_DEBUG_ARGS.
> >         * tree-streamer-in.c (lto_input_ts_decl_common_tree_pointers):
> >         Stream DECL_ABSTRACT_ORIGIN.
> >         * tree-streamer-out.c (write_ts_decl_common_tree_pointers): Likewise.
> > 	(write_ts_decl_minimal_tree_pointers): Force a TRANSLATION_UNIT_DECL
> > 	DECL_CONTEXT for file-scope decls.
> >         * lto-streamer.h (struct dref_entry): Declare.
> >         (dref_queue): Likewise.
> > 
> >         * lto-wrapper.c (debug_obj): New global.
> >         (tool_cleanup): Unlink it if required.
> >         (debug_objcopy): New function.
> >         (run_gcc): Handle early debug sections in the IL files by
> >         extracting them to separate files, partially linkin them and
> >         feeding the result back as result to the linker.
> > 
> >         * config/darwin.h (DEBUG_LTO_INFO_SECTION, DEBUG_LTO_ABBREV_SECTION,
> >         DEBUG_LTO_MACINFO_SECTION, DEBUG_LTO_LINE_SECTION,
> >         DEBUG_STR_LTO_SECTION, DEBUG_LTO_MACRO_SECTION): Put early debug
> >         sections into a separate segment.
> >         * config/darwin.c (darwin_asm_named_section): Handle __GNU_DWARF_LTO
> >         segments.
> >         (darwin_asm_dwarf_section): Likewise.
> >         (darwin_asm_output_dwarf_offset): Likewise.
> > 
> > 	* config/i386/i386.c (make_resolver_func): Set DECL_IGNORED_P.
> > 
> >         lto/
> >         * lto.c (unify_scc): Truncate DIE reference queue for dropped SCCs.
> >         (lto_read_decls): Process TRANSLATION_UNIT_DECLs.  Remove
> >         TYPE_DECL debug processing, register DIE references from
> >         prevailing SCCs with the debug machinery.
> >         (lto_section_with_id): Handle LTO debug sections.
> > 
> > 	libstdc++/
> > 	* testsuite/libstdc++-prettyprinters/prettyprinters.exp: Run all
> > 	tests with -flto as well if supported.
> > 
> > 	* c-c++-common/asan/global-overflow-1.c: Adjust diagnostic location
> > 	regex to handle the LTO case.
> > 	* c-c++-common/asan/heap-overflow-1.c: Likewise.
> > 	* c-c++-common/asan/misalign-1.c: Likewise.
> > 	* c-c++-common/asan/misalign-2.c: Likewise.
> > 	* c-c++-common/asan/null-deref-1.c: Likewise.
> > 	* c-c++-common/asan/stack-overflow-1.c: Likewise.
> > 	* c-c++-common/asan/strncpy-overflow-1.c: Likewise.
> > 	* c-c++-common/asan/use-after-free-1.c: Likewise.
> > 	* g++.dg/asan/large-func-test-1.C: Likewise.
> > 	* gfortran.dg/save_6.f90: Add -flto -g variant of save_5.f90.
> > 
> > Index: early-lto-debug/gcc/dwarf2out.c
> > ===================================================================
> > *** early-lto-debug.orig/gcc/dwarf2out.c	2017-05-16 13:10:47.554202813 +0200
> > --- early-lto-debug/gcc/dwarf2out.c	2017-05-19 12:29:43.933873285 +0200
> > *************** static GTY(()) section *debug_aranges_se
> > *** 162,167 ****
> > --- 162,168 ----
> >   static GTY(()) section *debug_addr_section;
> >   static GTY(()) section *debug_macinfo_section;
> >   static const char *debug_macinfo_section_name;
> > + static unsigned macinfo_label_base = 1;
> >   static GTY(()) section *debug_line_section;
> >   static GTY(()) section *debug_skeleton_line_section;
> >   static GTY(()) section *debug_loc_section;
> > *************** static void dwarf2out_begin_function (tr
> > *** 2686,2691 ****
> > --- 2687,2696 ----
> >   static void dwarf2out_end_function (unsigned int);
> >   static void dwarf2out_register_main_translation_unit (tree unit);
> >   static void dwarf2out_set_name (tree, tree);
> > + static void dwarf2out_register_external_die (tree decl, const char *sym,
> > + 					     unsigned HOST_WIDE_INT off);
> > + static bool dwarf2out_die_ref_for_decl (tree decl, const char **sym,
> > + 					unsigned HOST_WIDE_INT *off);
> >   
> >   /* The debug hooks structure.  */
> >   
> > *************** const struct gcc_debug_hooks dwarf2_debu
> > *** 2720,2725 ****
> > --- 2725,2732 ----
> >     dwarf2out_late_global_decl,
> >     dwarf2out_type_decl,		/* type_decl */
> >     dwarf2out_imported_module_or_decl,
> > +   dwarf2out_die_ref_for_decl,
> > +   dwarf2out_register_external_die,
> >     debug_nothing_tree,		/* deferred_inline_function */
> >     /* The DWARF 2 backend tries to reduce debugging bloat by not
> >        emitting the abstract description of inline functions until
> > *************** const struct gcc_debug_hooks dwarf2_line
> > *** 2761,2766 ****
> > --- 2768,2775 ----
> >     debug_nothing_tree,		         /* late_global_decl */
> >     debug_nothing_tree_int,		 /* type_decl */
> >     debug_nothing_tree_tree_tree_bool,	 /* imported_module_or_decl */
> > +   debug_false_tree_charstarstar_uhwistar, /* die_ref_for_decl */
> > +   debug_nothing_tree_charstar_uhwi,	 /* register_external_die */
> >     debug_nothing_tree,		         /* deferred_inline_function */
> >     debug_nothing_tree,		         /* outlining_inline_function */
> >     debug_nothing_rtx_code_label,	         /* label */
> > *************** typedef struct GTY((chain_circular ("%h.
> > *** 2889,2894 ****
> > --- 2898,2906 ----
> >     /* 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 */
> > +   /* For an external ref to die_symbol if die_offset contains an extra
> > +      offset to that symbol.  */
> > +   BOOL_BITFIELD with_offset : 1;
> >     /* Whether this DIE was removed from the DIE tree, for example via
> >        prune_unused_types.  We don't consider those present from the
> >        DIE lookup routines.  */
> > *************** new_addr_loc_descr (rtx addr, enum dtpre
> > *** 3692,3703 ****
> > --- 3704,3727 ----
> >   #ifndef DEBUG_DWO_INFO_SECTION
> >   #define DEBUG_DWO_INFO_SECTION ".debug_info.dwo"
> >   #endif
> > + #ifndef DEBUG_LTO_DWO_INFO_SECTION
> > + #define DEBUG_LTO_DWO_INFO_SECTION ".gnu.debuglto_.debug_info.dwo"
> > + #endif
> > + #ifndef DEBUG_LTO_INFO_SECTION
> > + #define DEBUG_LTO_INFO_SECTION	".gnu.debuglto_.debug_info"
> > + #endif
> >   #ifndef DEBUG_ABBREV_SECTION
> >   #define DEBUG_ABBREV_SECTION	".debug_abbrev"
> >   #endif
> >   #ifndef DEBUG_DWO_ABBREV_SECTION
> >   #define DEBUG_DWO_ABBREV_SECTION ".debug_abbrev.dwo"
> >   #endif
> > + #ifndef DEBUG_LTO_DWO_ABBREV_SECTION
> > + #define DEBUG_LTO_DWO_ABBREV_SECTION ".gnu.debuglto_.debug_abbrev.dwo"
> > + #endif
> > + #ifndef DEBUG_LTO_ABBREV_SECTION
> > + #define DEBUG_LTO_ABBREV_SECTION ".gnu.debuglto_.debug_abbrev"
> > + #endif
> >   #ifndef DEBUG_ARANGES_SECTION
> >   #define DEBUG_ARANGES_SECTION	".debug_aranges"
> >   #endif
> > *************** new_addr_loc_descr (rtx addr, enum dtpre
> > *** 3710,3727 ****
> > --- 3734,3766 ----
> >   #ifndef DEBUG_DWO_MACINFO_SECTION
> >   #define DEBUG_DWO_MACINFO_SECTION      ".debug_macinfo.dwo"
> >   #endif
> > + #ifndef DEBUG_LTO_DWO_MACINFO_SECTION
> > + #define DEBUG_LTO_DWO_MACINFO_SECTION  ".gnu.debuglto_.debug_macinfo.dwo"
> > + #endif
> > + #ifndef DEBUG_LTO_MACINFO_SECTION
> > + #define DEBUG_LTO_MACINFO_SECTION      ".gnu.debuglto_.debug_macinfo"
> > + #endif
> >   #ifndef DEBUG_DWO_MACRO_SECTION
> >   #define DEBUG_DWO_MACRO_SECTION        ".debug_macro.dwo"
> >   #endif
> >   #ifndef DEBUG_MACRO_SECTION
> >   #define DEBUG_MACRO_SECTION	".debug_macro"
> >   #endif
> > + #ifndef DEBUG_LTO_DWO_MACRO_SECTION
> > + #define DEBUG_LTO_DWO_MACRO_SECTION    ".gnu.debuglto_.debug_macro.dwo"
> > + #endif
> > + #ifndef DEBUG_LTO_MACRO_SECTION
> > + #define DEBUG_LTO_MACRO_SECTION ".gnu.debuglto_.debug_macro"
> > + #endif
> >   #ifndef DEBUG_LINE_SECTION
> >   #define DEBUG_LINE_SECTION	".debug_line"
> >   #endif
> >   #ifndef DEBUG_DWO_LINE_SECTION
> >   #define DEBUG_DWO_LINE_SECTION ".debug_line.dwo"
> >   #endif
> > + #ifndef DEBUG_LTO_LINE_SECTION
> > + #define DEBUG_LTO_LINE_SECTION ".gnu.debuglto_.debug_line.dwo"
> > + #endif
> >   #ifndef DEBUG_LOC_SECTION
> >   #define DEBUG_LOC_SECTION	".debug_loc"
> >   #endif
> > *************** new_addr_loc_descr (rtx addr, enum dtpre
> > *** 3750,3761 ****
> > --- 3789,3809 ----
> >   #ifndef DEBUG_DWO_STR_OFFSETS_SECTION
> >   #define DEBUG_DWO_STR_OFFSETS_SECTION ".debug_str_offsets.dwo"
> >   #endif
> > + #ifndef DEBUG_LTO_DWO_STR_OFFSETS_SECTION
> > + #define DEBUG_LTO_DWO_STR_OFFSETS_SECTION ".gnu.debuglto_.debug_str_offsets.dwo"
> > + #endif
> >   #ifndef DEBUG_STR_DWO_SECTION
> >   #define DEBUG_STR_DWO_SECTION   ".debug_str.dwo"
> >   #endif
> > + #ifndef DEBUG_LTO_STR_DWO_SECTION
> > + #define DEBUG_LTO_STR_DWO_SECTION ".gnu.debuglto_.debug_str.dwo"
> > + #endif
> >   #ifndef DEBUG_STR_SECTION
> >   #define DEBUG_STR_SECTION  ".debug_str"
> >   #endif
> > + #ifndef DEBUG_LTO_STR_SECTION
> > + #define DEBUG_LTO_STR_SECTION ".gnu.debuglto_.debug_str"
> > + #endif
> >   #ifndef DEBUG_RANGES_SECTION
> >   #define DEBUG_RANGES_SECTION	".debug_ranges"
> >   #endif
> > *************** new_addr_loc_descr (rtx addr, enum dtpre
> > *** 3780,3785 ****
> > --- 3828,3837 ----
> >   /* Section flags for .debug_str.dwo section.  */
> >   #define DEBUG_STR_DWO_SECTION_FLAGS (SECTION_DEBUG | SECTION_EXCLUDE)
> >   
> > + /* Attribute used to refer to the macro section.  */
> > + #define DEBUG_MACRO_ATTRIBUTE (dwarf_version >= 5 ? DW_AT_macros \
> > + 		   : dwarf_strict ? DW_AT_macro_info : DW_AT_GNU_macros)
> > + 
> >   /* Labels we insert at beginning sections we can reference instead of
> >      the section names themselves.  */
> >   
> > *************** set_indirect_string (struct indirect_str
> > *** 4368,4373 ****
> > --- 4420,4443 ----
> >       }
> >   }
> >   
> > + /* A helper function for dwarf2out_finish, called to reset indirect
> > +    string decisions done for early LTO dwarf output before fat object
> > +    dwarf output.  */
> > + 
> > + int
> > + reset_indirect_string (indirect_string_node **h, void *)
> > + {
> > +   struct indirect_string_node *node = *h;
> > +   if (node->form == DW_FORM_strp || node->form == DW_FORM_GNU_str_index)
> > +     {
> > +       free (node->label);
> > +       node->label = NULL;
> > +       node->form = (dwarf_form) 0;
> > +       node->index = 0;
> > +     }
> > +   return 1;
> > + }
> > + 
> >   /* Find out whether a string should be output inline in DIE
> >      or out-of-line in .debug_str section.  */
> >   
> > *************** lookup_decl_die (tree decl)
> > *** 5413,5418 ****
> > --- 5483,5668 ----
> >     return *die;
> >   }
> >   
> > + 
> > + /* For DECL which might have early dwarf output query a SYMBOL + OFFSET
> > +    style reference.  Return true if we found one refering to a DIE for
> > +    DECL, otherwise return false.  */
> > + 
> > + static bool
> > + dwarf2out_die_ref_for_decl (tree decl, const char **sym,
> > + 			    unsigned HOST_WIDE_INT *off)
> > + {
> > +   dw_die_ref die;
> > + 
> > +   if (flag_wpa && !decl_die_table)
> > +     return false;
> > + 
> > +   if (TREE_CODE (decl) == BLOCK)
> > +     die = BLOCK_DIE (decl);
> > +   else
> > +     die = lookup_decl_die (decl);
> > +   if (!die)
> > +     return false;
> > + 
> > +   /* During WPA stage we currently use DIEs to store the
> > +      decl <-> label + offset map.  That's quite inefficient but it
> > +      works for now.  */
> > +   if (flag_wpa)
> > +     {
> > +       dw_die_ref ref = get_AT_ref (die, DW_AT_abstract_origin);
> > +       if (!ref)
> > + 	{
> > + 	  gcc_assert (die == comp_unit_die ());
> > + 	  return false;
> > + 	}
> > +       *off = ref->die_offset;
> > +       *sym = ref->die_id.die_symbol;
> > +       return true;
> > +     }
> > + 
> > +   /* Similar to get_ref_die_offset_label, but using the "correct"
> > +      label.  */
> > +   *off = die->die_offset;
> > +   while (die->die_parent)
> > +     die = die->die_parent;
> > +   /* For the containing CU DIE we compute a die_symbol in
> > +      compute_section_prefix.  */
> > +   gcc_assert (die->die_tag == DW_TAG_compile_unit
> > + 	      && die->die_id.die_symbol != NULL);
> > +   *sym = die->die_id.die_symbol;
> > +   return true;
> > + }
> > + 
> > + /* Add a reference of kind ATTR_KIND to a DIE at SYMBOL + OFFSET to DIE.  */
> > + 
> > + static void
> > + add_AT_external_die_ref (dw_die_ref die, enum dwarf_attribute attr_kind,
> > + 			 const char *symbol, HOST_WIDE_INT offset)
> > + {
> > +   /* Create a fake DIE that contains the reference.  Don't use
> > +      new_die because we don't want to end up in the limbo list.  */
> > +   dw_die_ref ref = ggc_cleared_alloc<die_node> ();
> > +   ref->die_tag = die->die_tag;
> > +   ref->die_id.die_symbol = IDENTIFIER_POINTER (get_identifier (symbol));
> > +   ref->die_offset = offset;
> > +   ref->with_offset = 1;
> > +   add_AT_die_ref (die, attr_kind, ref);
> > + }
> > + 
> > + /* Create a DIE for DECL if required and add a reference to a DIE
> > +    at SYMBOL + OFFSET which contains attributes dumped early.  */
> > + 
> > + static void
> > + dwarf2out_register_external_die (tree decl, const char *sym,
> > + 				 unsigned HOST_WIDE_INT off)
> > + {
> > +   if (debug_info_level == DINFO_LEVEL_NONE)
> > +     return;
> > + 
> > +   if (flag_wpa && !decl_die_table)
> > +     decl_die_table = hash_table<decl_die_hasher>::create_ggc (1000);
> > + 
> > +   dw_die_ref die
> > +     = TREE_CODE (decl) == BLOCK ? BLOCK_DIE (decl) : lookup_decl_die (decl);
> > +   gcc_assert (!die);
> > + 
> > +   tree ctx;
> > +   dw_die_ref parent = NULL;
> > +   /* Need to lookup a DIE for the decls context - the containing
> > +      function or translation unit.  */
> > +   if (TREE_CODE (decl) == BLOCK)
> > +     {
> > +       ctx = BLOCK_SUPERCONTEXT (decl);
> > +       /* ???  We do not output DIEs for all scopes thus skip as
> > + 	 many DIEs as needed.  */
> > +       while (TREE_CODE (ctx) == BLOCK
> > + 	     && !BLOCK_DIE (ctx))
> > + 	ctx = BLOCK_SUPERCONTEXT (ctx);
> > +     }
> > +   else
> > +     ctx = DECL_CONTEXT (decl);
> > +   while (ctx && TYPE_P (ctx))
> > +     ctx = TYPE_CONTEXT (ctx);
> > +   if (ctx)
> > +     {
> > +       if (TREE_CODE (ctx) == BLOCK)
> > + 	parent = BLOCK_DIE (ctx);
> > +       else if (TREE_CODE (ctx) == TRANSLATION_UNIT_DECL
> > + 	       /* Keep the 1:1 association during WPA.  */
> > + 	       && !flag_wpa)
> > + 	/* Otherwise all late annotations go to the main CU which
> > + 	   imports the original CUs.  */
> > + 	parent = comp_unit_die ();
> > +       else if (TREE_CODE (ctx) == FUNCTION_DECL
> > + 	       && TREE_CODE (decl) != PARM_DECL
> > + 	       && TREE_CODE (decl) != BLOCK)
> > + 	/* Leave function local entities parent determination to when
> > + 	   we process scope vars.  */
> > + 	;
> > +       else
> > + 	parent = lookup_decl_die (ctx);
> > +     }
> > +   else
> > +     /* ???  In some cases the C++ FE (at least) fails to
> > +        set DECL_CONTEXT properly.  Simply globalize stuff
> > +        in this case.  For example
> > +        __dso_handle created via iostream line 74 col 25.  */
> > +     parent = comp_unit_die ();
> > +   /* Create a DIE "stub".  */
> > +   switch (TREE_CODE (decl))
> > +     {
> > +     case TRANSLATION_UNIT_DECL:
> > +       if (! flag_wpa)
> > + 	{
> > + 	  die = comp_unit_die ();
> > + 	  dw_die_ref import = new_die (DW_TAG_imported_unit, die, NULL_TREE);
> > + 	  add_AT_external_die_ref (import, DW_AT_import, sym, off);
> > + 	  /* We re-target all CU decls to the LTRANS CU DIE, so no need
> > + 	     to create a DIE for the original CUs.  */
> > + 	  return;
> > + 	}
> > +       /* Keep the 1:1 association during WPA.  */
> > +       die = new_die (DW_TAG_compile_unit, NULL, decl);
> > +       break;
> > +     case NAMESPACE_DECL:
> > +       /* ???  LANG issue - DW_TAG_module for fortran.  Either look
> > + 	 at the input language (if we have enough DECL_CONTEXT to follow)
> > + 	 or use a bit in tree_decl_with_vis to record the distinction.  */
> > +       die = new_die (DW_TAG_namespace, parent, decl);
> > +       break;
> > +     case FUNCTION_DECL:
> > +       die = new_die (DW_TAG_subprogram, parent, decl);
> > +       break;
> > +     case VAR_DECL:
> > +       die = new_die (DW_TAG_variable, parent, decl);
> > +       break;
> > +     case RESULT_DECL:
> > +       die = new_die (DW_TAG_variable, parent, decl);
> > +       break;
> > +     case PARM_DECL:
> > +       die = new_die (DW_TAG_formal_parameter, parent, decl);
> > +       break;
> > +     case CONST_DECL:
> > +       die = new_die (DW_TAG_constant, parent, decl);
> > +       break;
> > +     case LABEL_DECL:
> > +       die = new_die (DW_TAG_label, parent, decl);
> > +       break;
> > +     case BLOCK:
> > +       die = new_die (DW_TAG_lexical_block, parent, decl);
> > +       break;
> > +     default:
> > +       gcc_unreachable ();
> > +     }
> > +   if (TREE_CODE (decl) == BLOCK)
> > +     BLOCK_DIE (decl) = die;
> > +   else
> > +     equate_decl_number_to_die (decl, die);
> > + 
> > +   /* Add a reference to the DIE providing early debug at $sym + off.  */
> > +   add_AT_external_die_ref (die, DW_AT_abstract_origin, sym, off);
> > + }
> > + 
> >   /* Returns a hash value for X (which really is a var_loc_list).  */
> >   
> >   inline hashval_t
> > *************** print_dw_val (dw_val_node *val, bool rec
> > *** 5900,5906 ****
> >   			       die->die_id.die_type_node->signature);
> >   	    }
> >   	  else if (die->die_id.die_symbol)
> > ! 	    fprintf (outfile, "die -> label: %s", die->die_id.die_symbol);
> >   	  else
> >   	    fprintf (outfile, "die -> %ld", die->die_offset);
> >   	  fprintf (outfile, " (%p)", (void *) die);
> > --- 6150,6160 ----
> >   			       die->die_id.die_type_node->signature);
> >   	    }
> >   	  else if (die->die_id.die_symbol)
> > ! 	    {
> > ! 	      fprintf (outfile, "die -> label: %s", die->die_id.die_symbol);
> > ! 	      if (die->with_offset)
> > ! 		fprintf (outfile, " + %ld", die->die_offset);
> > ! 	    }
> >   	  else
> >   	    fprintf (outfile, "die -> %ld", die->die_offset);
> >   	  fprintf (outfile, " (%p)", (void *) die);
> > *************** static unsigned int comdat_symbol_number
> > *** 7216,7222 ****
> >      children, and set comdat_symbol_id accordingly.  */
> >   
> >   static void
> > ! compute_section_prefix (dw_die_ref unit_die)
> >   {
> >     const char *die_name = get_AT_string (unit_die, DW_AT_name);
> >     const char *base = die_name ? lbasename (die_name) : "anonymous";
> > --- 7470,7476 ----
> >      children, and set comdat_symbol_id accordingly.  */
> >   
> >   static void
> > ! compute_section_prefix_1 (dw_die_ref unit_die, bool comdat_p)
> >   {
> >     const char *die_name = get_AT_string (unit_die, DW_AT_name);
> >     const char *base = die_name ? lbasename (die_name) : "anonymous";
> > *************** compute_section_prefix (dw_die_ref unit_
> > *** 7235,7241 ****
> >     unmark_all_dies (unit_die);
> >     md5_finish_ctx (&ctx, checksum);
> >   
> > !   sprintf (name, "%s.", base);
> >     clean_symbol_name (name);
> >   
> >     p = name + strlen (name);
> > --- 7489,7499 ----
> >     unmark_all_dies (unit_die);
> >     md5_finish_ctx (&ctx, checksum);
> >   
> > !   /* When we this for comp_unit_die () we have a DW_AT_name that might
> > !      not start with a letter but with anything valid for filenames and
> > !      clean_symbol_name doesn't fix that up.  Prepend 'g' if the first
> > !      character is not a letter.  */
> > !   sprintf (name, "%s%s.", ISALPHA (*base) ? "" : "g", base);
> >     clean_symbol_name (name);
> >   
> >     p = name + strlen (name);
> > *************** compute_section_prefix (dw_die_ref unit_
> > *** 7245,7251 ****
> >         p += 2;
> >       }
> >   
> > !   comdat_symbol_id = unit_die->die_id.die_symbol = xstrdup (name);
> >     comdat_symbol_number = 0;
> >   }
> >   
> > --- 7503,7517 ----
> >         p += 2;
> >       }
> >   
> > !   unit_die->die_id.die_symbol = xstrdup (name);
> > !   unit_die->comdat_type_p = comdat_p;
> > ! }
> > ! 
> > ! static void
> > ! compute_section_prefix (dw_die_ref unit_die)
> > ! {
> > !   compute_section_prefix_1 (unit_die, true);
> > !   comdat_symbol_id = unit_die->die_id.die_symbol;
> >     comdat_symbol_number = 0;
> >   }
> >   
> > *************** output_die (dw_die_ref die)
> > *** 9971,9977 ****
> >   
> >     /* If someone in another CU might refer to us, set up a symbol for
> >        them to point to.  */
> > !   if (! die->comdat_type_p && die->die_id.die_symbol)
> >       output_die_symbol (die);
> >   
> >     dw2_asm_output_data_uleb128 (die->die_abbrev, "(DIE (%#lx) %s)",
> > --- 10237,10247 ----
> >   
> >     /* If someone in another CU might refer to us, set up a symbol for
> >        them to point to.  */
> > !   if (! die->comdat_type_p && die->die_id.die_symbol
> > !       /* Don't output the symbol twice.  For LTO we want the label
> > !          on the section beginning, not on the actual DIE.  */
> > !       && (!flag_generate_lto
> > ! 	  || die->die_tag != DW_TAG_compile_unit))
> >       output_die_symbol (die);
> >   
> >     dw2_asm_output_data_uleb128 (die->die_abbrev, "(DIE (%#lx) %s)",
> > *************** output_die (dw_die_ref die)
> > *** 10164,10171 ****
> >   		    size = DWARF2_ADDR_SIZE;
> >   		  else
> >   		    size = DWARF_OFFSET_SIZE;
> > ! 		  dw2_asm_output_offset (size, sym, debug_info_section, "%s",
> > ! 					 name);
> >   		}
> >   	    }
> >   	  else
> > --- 10434,10453 ----
> >   		    size = DWARF2_ADDR_SIZE;
> >   		  else
> >   		    size = DWARF_OFFSET_SIZE;
> > ! 		  /* ???  We cannot unconditionally output die_offset if
> > ! 		     non-zero - at least -feliminate-dwarf2-dups will
> > ! 		     create references to those DIEs via symbols.  And we
> > ! 		     do not clear its DIE offset after outputting it
> > ! 		     (and the label refers to the actual DIEs, not the
> > ! 		     DWARF CU unit header which is when using label + offset
> > ! 		     would be the correct thing to do).
> > ! 		     ???  This is the reason for the with_offset flag.  */
> > ! 		  if (AT_ref (a)->with_offset)
> > ! 		    dw2_asm_output_offset (size, sym, AT_ref (a)->die_offset,
> > ! 					   debug_info_section, "%s", name);
> > ! 		  else
> > ! 		    dw2_asm_output_offset (size, sym, debug_info_section, "%s",
> > ! 					   name);
> >   		}
> >   	    }
> >   	  else
> > *************** output_comp_unit (dw_die_ref die, int ou
> > *** 10391,10397 ****
> >     calc_die_sizes (die);
> >   
> >     oldsym = die->die_id.die_symbol;
> > !   if (oldsym)
> >       {
> >         tmp = XALLOCAVEC (char, strlen (oldsym) + 24);
> >   
> > --- 10673,10679 ----
> >     calc_die_sizes (die);
> >   
> >     oldsym = die->die_id.die_symbol;
> > !   if (oldsym && die->comdat_type_p)
> >       {
> >         tmp = XALLOCAVEC (char, strlen (oldsym) + 24);
> >   
> > *************** output_comp_unit (dw_die_ref die, int ou
> > *** 10407,10412 ****
> > --- 10689,10721 ----
> >         info_section_emitted = true;
> >       }
> >   
> > +   /* For LTO cross unit DIE refs we want a symbol on the start of the
> > +      debuginfo section, not on the CU DIE.
> > +      ???  We could simply use the symbol as it would be output by output_die
> > +      and account for the extra offset produced by the CU header which has fixed
> > +      size.  OTOH it currently only supports linkonce globals which would
> > +      be less than ideal?.  */
> > +   if (flag_generate_lto && oldsym)
> > +     {
> > +       /* ???  No way to get visibility assembled without a decl.  */
> > +       tree decl = build_decl (UNKNOWN_LOCATION, VAR_DECL,
> > + 			      get_identifier (oldsym), char_type_node);
> > +       TREE_PUBLIC (decl) = true;
> > +       TREE_STATIC (decl) = true;
> > +       DECL_ARTIFICIAL (decl) = true;
> > +       DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
> > +       DECL_VISIBILITY_SPECIFIED (decl) = true;
> > +       targetm.asm_out.assemble_visibility (decl, VISIBILITY_HIDDEN);
> > + #ifdef ASM_WEAKEN_LABEL
> > +       /* We prefer a .weak because that handles duplicates from duplicate
> > +          archive members in a graceful way.  */
> > +       ASM_WEAKEN_LABEL (asm_out_file, oldsym);
> > + #else
> > +       targetm.asm_out.globalize_label (asm_out_file, oldsym);
> > + #endif
> > +       ASM_OUTPUT_LABEL (asm_out_file, oldsym);
> > +     }
> > + 
> >     /* Output debugging information.  */
> >     output_compilation_unit_header (dwo_id
> >   				  ? DW_UT_split_compile : DW_UT_compile);
> > *************** parameter_ref_descriptor (rtx rtl)
> > *** 14523,14528 ****
> > --- 14832,14840 ----
> >     if (dwarf_strict)
> >       return NULL;
> >     gcc_assert (TREE_CODE (DEBUG_PARAMETER_REF_DECL (rtl)) == PARM_DECL);
> > +   /* With LTO during LTRANS we get the late DIE that refers to the early
> > +      DIE, thus we add another indirection here.  This seems to confuse
> > +      gdb enough to make gcc.dg/guality/pr68860-1.c FAIL with LTO.  */
> >     ref = lookup_decl_die (DEBUG_PARAMETER_REF_DECL (rtl));
> >     ret = new_loc_descr (DW_OP_GNU_parameter_ref, 0, 0);
> >     if (ref)
> > *************** add_abstract_origin_attribute (dw_die_re
> > *** 20216,20222 ****
> >       }
> >   
> >     if (DECL_P (origin))
> > !     origin_die = lookup_decl_die (origin);
> >     else if (TYPE_P (origin))
> >       origin_die = lookup_type_die (origin);
> >     else if (TREE_CODE (origin) == BLOCK)
> > --- 20528,20547 ----
> >       }
> >   
> >     if (DECL_P (origin))
> > !     {
> > !       dw_die_ref c;
> > !       origin_die = lookup_decl_die (origin);
> > !       /* "Unwrap" the decls DIE which we put in the imported unit context.
> > !           ???  If we finish dwarf2out_function_decl refactoring we can
> > ! 	  do this in a better way from the start and only lazily emit
> > ! 	  the early DIE references.  */
> > !       if (in_lto_p
> > ! 	  && origin_die
> > ! 	  && (c = get_AT_ref (origin_die, DW_AT_abstract_origin))
> > ! 	  /* ???  Identify this better.  */
> > ! 	  && c->with_offset)
> > ! 	origin_die = c;
> > !     }
> >     else if (TYPE_P (origin))
> >       origin_die = lookup_type_die (origin);
> >     else if (TREE_CODE (origin) == BLOCK)
> > *************** gen_array_type_die (tree type, dw_die_re
> > *** 20775,20781 ****
> >         size = int_size_in_bytes (type);
> >         if (size >= 0)
> >   	add_AT_unsigned (array_die, DW_AT_byte_size, size);
> > !       else if (TYPE_DOMAIN (type) != NULL_TREE
> >   	       && TYPE_MAX_VALUE (TYPE_DOMAIN (type)) != NULL_TREE)
> >   	{
> >   	  tree szdecl = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
> > --- 21100,21109 ----
> >         size = int_size_in_bytes (type);
> >         if (size >= 0)
> >   	add_AT_unsigned (array_die, DW_AT_byte_size, size);
> > !       /* ???  We can't annotate types late, but for LTO we may not
> > ! 	 generate a location early either (gfortran.dg/save_6.f90).  */
> > !       else if (! (early_dwarf && flag_generate_lto)
> > ! 	       && TYPE_DOMAIN (type) != NULL_TREE
> >   	       && TYPE_MAX_VALUE (TYPE_DOMAIN (type)) != NULL_TREE)
> >   	{
> >   	  tree szdecl = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
> > *************** gen_formal_parameter_die (tree node, tre
> > *** 21188,21194 ****
> >   	 thing.  */
> >         if (parm_die && parm_die->die_parent != context_die)
> >   	{
> > ! 	  if (!DECL_ABSTRACT_P (node))
> >   	    {
> >   	      /* This can happen when creating an inlined instance, in
> >   		 which case we need to create a new DIE that will get
> > --- 21516,21524 ----
> >   	 thing.  */
> >         if (parm_die && parm_die->die_parent != context_die)
> >   	{
> > ! 	  /* ???  The DIE parent is the "abstract" copy and the context_die
> > ! 	     is the specification "copy".  */
> > ! 	  if (!DECL_ABSTRACT_P (node) && !in_lto_p)
> >   	    {
> >   	      /* This can happen when creating an inlined instance, in
> >   		 which case we need to create a new DIE that will get
> > *************** gen_type_die_for_member (tree type, tree
> > *** 21462,21468 ****
> >   /* Forward declare these functions, because they are mutually recursive
> >     with their set_block_* pairing functions.  */
> >   static void set_decl_origin_self (tree);
> > - static void set_decl_abstract_flags (tree, vec<tree> &);
> >   
> >   /* Given a pointer to some BLOCK node, if the BLOCK_ABSTRACT_ORIGIN for the
> >      given BLOCK node is NULL, set the BLOCK_ABSTRACT_ORIGIN for the node so
> > --- 21792,21797 ----
> > *************** set_decl_origin_self (tree decl)
> > *** 21535,21685 ****
> >       }
> >   }
> >   
> > ! /* Given a pointer to some BLOCK node, set the BLOCK_ABSTRACT flag to 1
> > !    and if it wasn't 1 before, push it to abstract_vec vector.
> > !    For all local decls and all local sub-blocks (recursively) do it
> > !    too.  */
> > ! 
> > ! static void
> > ! set_block_abstract_flags (tree stmt, vec<tree> &abstract_vec)
> > ! {
> > !   tree local_decl;
> > !   tree subblock;
> > !   unsigned int i;
> > ! 
> > !   if (!BLOCK_ABSTRACT (stmt))
> > !     {
> > !       abstract_vec.safe_push (stmt);
> > !       BLOCK_ABSTRACT (stmt) = 1;
> > !     }
> > ! 
> > !   for (local_decl = BLOCK_VARS (stmt);
> > !        local_decl != NULL_TREE;
> > !        local_decl = DECL_CHAIN (local_decl))
> > !     if (! DECL_EXTERNAL (local_decl))
> > !       set_decl_abstract_flags (local_decl, abstract_vec);
> > ! 
> > !   for (i = 0; i < BLOCK_NUM_NONLOCALIZED_VARS (stmt); i++)
> > !     {
> > !       local_decl = BLOCK_NONLOCALIZED_VAR (stmt, i);
> > !       if ((VAR_P (local_decl) && !TREE_STATIC (local_decl))
> > ! 	  || TREE_CODE (local_decl) == PARM_DECL)
> > ! 	set_decl_abstract_flags (local_decl, abstract_vec);
> > !     }
> > ! 
> > !   for (subblock = BLOCK_SUBBLOCKS (stmt);
> > !        subblock != NULL_TREE;
> > !        subblock = BLOCK_CHAIN (subblock))
> > !     set_block_abstract_flags (subblock, abstract_vec);
> > ! }
> > ! 
> > ! /* Given a pointer to some ..._DECL node, set DECL_ABSTRACT_P flag on it
> > !    to 1 and if it wasn't 1 before, push to abstract_vec vector.
> > !    In the case where the decl is a FUNCTION_DECL also set the abstract
> > !    flags for all of the parameters, local vars, local
> > !    blocks and sub-blocks (recursively).  */
> > ! 
> > ! static void
> > ! set_decl_abstract_flags (tree decl, vec<tree> &abstract_vec)
> > ! {
> > !   if (!DECL_ABSTRACT_P (decl))
> > !     {
> > !       abstract_vec.safe_push (decl);
> > !       DECL_ABSTRACT_P (decl) = 1;
> > !     }
> > ! 
> > !   if (TREE_CODE (decl) == FUNCTION_DECL)
> > !     {
> > !       tree arg;
> > ! 
> > !       for (arg = DECL_ARGUMENTS (decl); arg; arg = DECL_CHAIN (arg))
> > ! 	if (!DECL_ABSTRACT_P (arg))
> > ! 	  {
> > ! 	    abstract_vec.safe_push (arg);
> > ! 	    DECL_ABSTRACT_P (arg) = 1;
> > ! 	  }
> > !       if (DECL_INITIAL (decl) != NULL_TREE
> > ! 	  && DECL_INITIAL (decl) != error_mark_node)
> > ! 	set_block_abstract_flags (DECL_INITIAL (decl), abstract_vec);
> > !     }
> > ! }
> > ! 
> > ! /* Generate the DWARF2 info for the "abstract" instance of a function which we
> > !    may later generate inlined and/or out-of-line instances of.
> > ! 
> > !    FIXME: In the early-dwarf world, this function, and most of the
> > !           DECL_ABSTRACT code should be obsoleted.  The early DIE _is_
> > !           the abstract instance.  All we would need to do is annotate
> > !           the early DIE with the appropriate DW_AT_inline in late
> > !           dwarf (perhaps in gen_inlined_subroutine_die).
> > ! 
> > ! 	  However, we can't do this yet, because LTO streaming of DIEs
> > ! 	  has not been implemented yet.  */
> >   
> >   static void
> >   dwarf2out_abstract_function (tree decl)
> >   {
> >     dw_die_ref old_die;
> > -   tree save_fn;
> > -   tree context;
> > -   hash_table<decl_loc_hasher> *old_decl_loc_table;
> > -   hash_table<dw_loc_list_hasher> *old_cached_dw_loc_list_table;
> > -   int old_call_site_count, old_tail_call_site_count;
> > -   struct call_arg_loc_node *old_call_arg_locations;
> >   
> >     /* Make sure we have the actual abstract inline, not a clone.  */
> >     decl = DECL_ORIGIN (decl);
> >   
> >     old_die = lookup_decl_die (decl);
> > !   if (old_die && get_AT (old_die, DW_AT_inline))
> >       /* We've already generated the abstract instance.  */
> >       return;
> >   
> > !   /* We can be called while recursively when seeing block defining inlined subroutine
> > !      DIE.  Be sure to not clobber the outer location table nor use it or we would
> > !      get locations in abstract instantces.  */
> > !   old_decl_loc_table = decl_loc_table;
> > !   decl_loc_table = NULL;
> > !   old_cached_dw_loc_list_table = cached_dw_loc_list_table;
> > !   cached_dw_loc_list_table = NULL;
> > !   old_call_arg_locations = call_arg_locations;
> > !   call_arg_locations = NULL;
> > !   old_call_site_count = call_site_count;
> > !   call_site_count = -1;
> > !   old_tail_call_site_count = tail_call_site_count;
> > !   tail_call_site_count = -1;
> > ! 
> > !   /* Be sure we've emitted the in-class declaration DIE (if any) first, so
> > !      we don't get confused by DECL_ABSTRACT_P.  */
> > !   if (debug_info_level > DINFO_LEVEL_TERSE)
> >       {
> > !       context = decl_class_context (decl);
> > !       if (context)
> > ! 	gen_type_die_for_member
> > ! 	  (context, decl, decl_function_context (decl) ? NULL : comp_unit_die ());
> >       }
> >   
> > !   /* Pretend we've just finished compiling this function.  */
> > !   save_fn = current_function_decl;
> > !   current_function_decl = decl;
> > ! 
> > !   auto_vec<tree, 64> abstract_vec;
> > !   set_decl_abstract_flags (decl, abstract_vec);
> > !   dwarf2out_decl (decl);
> > !   unsigned int i;
> > !   tree t;
> > !   FOR_EACH_VEC_ELT (abstract_vec, i, t)
> > !     if (TREE_CODE (t) == BLOCK)
> > !       BLOCK_ABSTRACT (t) = 0;
> > !     else
> > !       DECL_ABSTRACT_P (t) = 0;
> > ! 
> > !   current_function_decl = save_fn;
> > !   decl_loc_table = old_decl_loc_table;
> > !   cached_dw_loc_list_table = old_cached_dw_loc_list_table;
> > !   call_arg_locations = old_call_arg_locations;
> > !   call_site_count = old_call_site_count;
> > !   tail_call_site_count = old_tail_call_site_count;
> >   }
> >   
> >   /* Helper function of premark_used_types() which gets called through
> > --- 21864,21908 ----
> >       }
> >   }
> >   
> > ! /* Mark the early DIE for DECL as the abstract instance.  */
> >   
> >   static void
> >   dwarf2out_abstract_function (tree decl)
> >   {
> >     dw_die_ref old_die;
> >   
> >     /* Make sure we have the actual abstract inline, not a clone.  */
> >     decl = DECL_ORIGIN (decl);
> >   
> > +   if (DECL_IGNORED_P (decl))
> > +     return;
> > + 
> >     old_die = lookup_decl_die (decl);
> > !   /* With early debug we always have an old DIE.  */
> > !   gcc_assert (old_die != NULL);
> > !   if (get_AT (old_die, DW_AT_inline))
> >       /* We've already generated the abstract instance.  */
> >       return;
> >   
> > !   /* Go ahead and put DW_AT_inline on the DIE.  */
> > !   if (DECL_DECLARED_INLINE_P (decl))
> >       {
> > !       if (cgraph_function_possibly_inlined_p (decl))
> > ! 	add_AT_unsigned (old_die, DW_AT_inline, DW_INL_declared_inlined);
> > !       else
> > ! 	add_AT_unsigned (old_die, DW_AT_inline, DW_INL_declared_not_inlined);
> > !     }
> > !   else
> > !     {
> > !       if (cgraph_function_possibly_inlined_p (decl))
> > ! 	add_AT_unsigned (old_die, DW_AT_inline, DW_INL_inlined);
> > !       else
> > ! 	add_AT_unsigned (old_die, DW_AT_inline, DW_INL_not_inlined);
> >       }
> >   
> > !   if (DECL_DECLARED_INLINE_P (decl)
> > !       && lookup_attribute ("artificial", DECL_ATTRIBUTES (decl)))
> > !     add_AT_flag (old_die, DW_AT_artificial, 1);
> >   }
> >   
> >   /* Helper function of premark_used_types() which gets called through
> > *************** gen_subprogram_die (tree decl, dw_die_re
> > *** 21901,21907 ****
> >         if (old_die && old_die->die_parent == NULL)
> >   	add_child_die (context_die, old_die);
> >   
> > !       if (old_die && get_AT_ref (old_die, DW_AT_abstract_origin))
> >   	{
> >   	  /* If we have a DW_AT_abstract_origin we have a working
> >   	     cached version.  */
> > --- 22124,22135 ----
> >         if (old_die && old_die->die_parent == NULL)
> >   	add_child_die (context_die, old_die);
> >   
> > !       dw_die_ref c;
> > !       if (old_die
> > ! 	  && (c = get_AT_ref (old_die, DW_AT_abstract_origin))
> > ! 	  /* ???  In LTO all origin DIEs still refer to the early
> > ! 	     debug copy.  Detect that.  */
> > ! 	  && get_AT (c, DW_AT_inline))
> >   	{
> >   	  /* If we have a DW_AT_abstract_origin we have a working
> >   	     cached version.  */
> > *************** gen_subprogram_die (tree decl, dw_die_re
> > *** 21969,21975 ****
> >   	   || (old_die->die_parent
> >   	       && old_die->die_parent->die_tag == DW_TAG_module)
> >   	   || context_die == NULL)
> > ! 	   && (DECL_ARTIFICIAL (decl)
> >   	       || (get_AT_file (old_die, DW_AT_decl_file) == file_index
> >   		   && (get_AT_unsigned (old_die, DW_AT_decl_line)
> >   		       == (unsigned) s.line)
> > --- 22197,22204 ----
> >   	   || (old_die->die_parent
> >   	       && old_die->die_parent->die_tag == DW_TAG_module)
> >   	   || context_die == NULL)
> > ! 	  /* ???  In LTO we do not see any of the location attributes.  */
> > ! 	   && ((DECL_ARTIFICIAL (decl) || in_lto_p)
> >   	       || (get_AT_file (old_die, DW_AT_decl_file) == file_index
> >   		   && (get_AT_unsigned (old_die, DW_AT_decl_line)
> >   		       == (unsigned) s.line)
> > *************** gen_variable_die (tree decl, tree origin
> > *** 22836,22841 ****
> > --- 23065,23088 ----
> >   	  /* If a DIE was dumped early, it still needs location info.
> >   	     Skip to where we fill the location bits.  */
> >   	  var_die = old_die;
> > + 
> > + 	  /* ???  In LTRANS we cannot annotate early created variably
> > + 	     modified type DIEs without copying them and adjusting all
> > + 	     references to them.  Thus we dumped them again, also add a
> > + 	     reference to them.  */
> > + 	  tree type = TREE_TYPE (decl_or_origin);
> > + 	  if (in_lto_p
> > + 	      && variably_modified_type_p
> > + 		   (type, decl_function_context (decl_or_origin)))
> > + 	    {
> > + 	      if (decl_by_reference_p (decl_or_origin))
> > + 		add_type_attribute (var_die, TREE_TYPE (type),
> > + 				    TYPE_UNQUALIFIED, false, context_die);
> > + 	      else
> > + 		add_type_attribute (var_die, type, decl_quals (decl_or_origin),
> > + 				    false, context_die);
> > + 	    }
> > + 
> >   	  goto gen_variable_die_location;
> >   	}
> >       }
> > *************** gen_inlined_subroutine_die (tree stmt, d
> > *** 23236,23247 ****
> >     gcc_checking_assert (DECL_ABSTRACT_P (decl)
> >   		       || cgraph_function_possibly_inlined_p (decl));
> >   
> > -   /* Emit info for the abstract instance first, if we haven't yet.  We
> > -      must emit this even if the block is abstract, otherwise when we
> > -      emit the block below (or elsewhere), we may end up trying to emit
> > -      a die whose origin die hasn't been emitted, and crashing.  */
> > -   dwarf2out_abstract_function (decl);
> > - 
> >     if (! BLOCK_ABSTRACT (stmt))
> >       {
> >         dw_die_ref subr_die
> > --- 23483,23488 ----
> > *************** process_scope_var (tree stmt, tree decl,
> > *** 24868,24874 ****
> >   					     stmt, context_die);
> >       }
> >     else
> > !     gen_decl_die (decl, origin, NULL, context_die);
> >   }
> >   
> >   /* Generate all of the decls declared within a given scope and (recursively)
> > --- 25109,25128 ----
> >   					     stmt, context_die);
> >       }
> >     else
> > !     {
> > !       if (decl && DECL_P (decl))
> > ! 	{
> > ! 	  die = lookup_decl_die (decl);
> > ! 
> > ! 	  /* Early created DIEs do not have a parent as the decls refer
> > ! 	     to the function as DECL_CONTEXT rather than the BLOCK.  */
> > ! 	  if (in_lto_p
> > ! 	      && die && die->die_parent == NULL)
> > ! 	    add_child_die (context_die, die);
> > ! 	}
> > ! 
> > !       gen_decl_die (decl, origin, NULL, context_die);
> > !     }
> >   }
> >   
> >   /* Generate all of the decls declared within a given scope and (recursively)
> > *************** gen_decl_die (tree decl, tree origin, st
> > *** 25288,25295 ****
> >   				     ? DECL_ORIGIN (origin)
> >   				     : DECL_ABSTRACT_ORIGIN (decl));
> >   
> > !       /* If we're emitting an out-of-line copy of an inline function,
> > ! 	 emit info for the abstract instance and set up to refer to it.  */
> >         else if (cgraph_function_possibly_inlined_p (decl)
> >   	       && ! DECL_ABSTRACT_P (decl)
> >   	       && ! class_or_namespace_scope_p (context_die)
> > --- 25542,25549 ----
> >   				     ? DECL_ORIGIN (origin)
> >   				     : DECL_ABSTRACT_ORIGIN (decl));
> >   
> > !       /* If we're emitting a possibly inlined function emit it as
> > !          abstract instance.  */
> >         else if (cgraph_function_possibly_inlined_p (decl)
> >   	       && ! DECL_ABSTRACT_P (decl)
> >   	       && ! class_or_namespace_scope_p (context_die)
> > *************** gen_decl_die (tree decl, tree origin, st
> > *** 25303,25309 ****
> >   	}
> >   
> >         /* Otherwise we're emitting the primary DIE for this decl.  */
> > !       else if (debug_info_level > DINFO_LEVEL_TERSE)
> >   	{
> >   	  /* Before we describe the FUNCTION_DECL itself, make sure that we
> >   	     have its containing type.  */
> > --- 25557,25565 ----
> >   	}
> >   
> >         /* Otherwise we're emitting the primary DIE for this decl.  */
> > !       else if (debug_info_level > DINFO_LEVEL_TERSE
> > ! 	       /* Do not generate stray type DIEs in late LTO dumping.  */
> > ! 	       && early_dwarf)
> >   	{
> >   	  /* Before we describe the FUNCTION_DECL itself, make sure that we
> >   	     have its containing type.  */
> > *************** gen_decl_die (tree decl, tree origin, st
> > *** 25370,25389 ****
> >         if (debug_info_level <= DINFO_LEVEL_TERSE)
> >   	break;
> >   
> > !       /* Output any DIEs that are needed to specify the type of this data
> > ! 	 object.  */
> > !       if (decl_by_reference_p (decl_or_origin))
> > ! 	gen_type_die (TREE_TYPE (TREE_TYPE (decl_or_origin)), context_die);
> > !       else
> > ! 	gen_type_die (TREE_TYPE (decl_or_origin), context_die);
> >   
> > !       /* And its containing type.  */
> > !       class_origin = decl_class_context (decl_or_origin);
> > !       if (class_origin != NULL_TREE)
> > ! 	gen_type_die_for_member (class_origin, decl_or_origin, context_die);
> >   
> > !       /* And its containing namespace.  */
> > !       context_die = declare_in_namespace (decl_or_origin, context_die);
> >   
> >         /* Now output the DIE to represent the data object itself.  This gets
> >   	 complicated because of the possibility that the VAR_DECL really
> > --- 25626,25661 ----
> >         if (debug_info_level <= DINFO_LEVEL_TERSE)
> >   	break;
> >   
> > !       /* Avoid generating stray type DIEs during late dwarf dumping.
> > !          All types have been dumped early.  */
> > !       if (! lookup_decl_die (decl_or_origin)
> > ! 	  /* ???  But in LTRANS we cannot annotate early created variably
> > ! 	     modified type DIEs without copying them and adjusting all
> > ! 	     references to them.  Dump them again as happens for inlining
> > ! 	     which copies both the decl and the types.  */
> > ! 	  /* ???  And even non-LTO needs to re-visit type DIEs to fill
> > ! 	     in VLA bound information for example.  */
> > ! 	  || (decl && variably_modified_type_p (TREE_TYPE (decl),
> > ! 						current_function_decl)))
> > ! 	{
> > ! 	  /* Output any DIEs that are needed to specify the type of this data
> > ! 	     object.  */
> > ! 	  if (decl_by_reference_p (decl_or_origin))
> > ! 	    gen_type_die (TREE_TYPE (TREE_TYPE (decl_or_origin)), context_die);
> > ! 	  else
> > ! 	    gen_type_die (TREE_TYPE (decl_or_origin), context_die);
> > ! 	}
> >   
> > !       if (early_dwarf)
> > ! 	{
> > ! 	  /* And its containing type.  */
> > ! 	  class_origin = decl_class_context (decl_or_origin);
> > ! 	  if (class_origin != NULL_TREE)
> > ! 	    gen_type_die_for_member (class_origin, decl_or_origin, context_die);
> >   
> > ! 	  /* And its containing namespace.  */
> > ! 	  context_die = declare_in_namespace (decl_or_origin, context_die);
> > ! 	}
> >   
> >         /* Now output the DIE to represent the data object itself.  This gets
> >   	 complicated because of the possibility that the VAR_DECL really
> > *************** gen_decl_die (tree decl, tree origin, st
> > *** 25413,25422 ****
> >         break;
> >   
> >       case PARM_DECL:
> > !       if (DECL_BY_REFERENCE (decl_or_origin))
> > ! 	gen_type_die (TREE_TYPE (TREE_TYPE (decl_or_origin)), context_die);
> > !       else
> > ! 	gen_type_die (TREE_TYPE (decl_or_origin), context_die);
> >         return gen_formal_parameter_die (decl, origin,
> >   				       true /* Emit name attribute.  */,
> >   				       context_die);
> > --- 25685,25707 ----
> >         break;
> >   
> >       case PARM_DECL:
> > !       /* Avoid generating stray type DIEs during late dwarf dumping.
> > !          All types have been dumped early.  */
> > !       if (! lookup_decl_die (decl_or_origin)
> > ! 	  /* ???  But in LTRANS we cannot annotate early created variably
> > ! 	     modified type DIEs without copying them and adjusting all
> > ! 	     references to them.  Dump them again as happens for inlining
> > ! 	     which copies both the decl and the types.  */
> > ! 	  /* ???  And even non-LTO needs to re-visit type DIEs to fill
> > ! 	     in VLA bound information for example.  */
> > ! 	  || (decl && variably_modified_type_p (TREE_TYPE (decl),
> > ! 						current_function_decl)))
> > ! 	{
> > ! 	  if (DECL_BY_REFERENCE (decl_or_origin))
> > ! 	    gen_type_die (TREE_TYPE (TREE_TYPE (decl_or_origin)), context_die);
> > ! 	  else
> > ! 	    gen_type_die (TREE_TYPE (decl_or_origin), context_die);
> > ! 	}
> >         return gen_formal_parameter_die (decl, origin,
> >   				       true /* Emit name attribute.  */,
> >   				       context_die);
> > *************** dwarf2out_early_global_decl (tree decl)
> > *** 25493,25498 ****
> > --- 25778,25793 ----
> >   	      dwarf2out_decl (context);
> >   	    }
> >   
> > + 	  /* Emit an abstract origin of a function first.  This happens
> > + 	     with C++ constructor clones for example and makes
> > + 	     dwarf2out_abstract_function happy which requires the early
> > + 	     DIE of the abstract instance to be present.  */
> > + 	  if (DECL_ABSTRACT_ORIGIN (decl))
> > + 	    {
> > + 	      current_function_decl = DECL_ABSTRACT_ORIGIN (decl);
> > + 	      dwarf2out_decl (DECL_ABSTRACT_ORIGIN (decl));
> > + 	    }
> > + 
> >   	  current_function_decl = decl;
> >   	}
> >         dwarf2out_decl (decl);
> > *************** dwarf2out_late_global_decl (tree decl)
> > *** 25515,25521 ****
> >       {
> >         dw_die_ref die = lookup_decl_die (decl);
> >   
> > !       /* We have to generate early debug late for LTO.  */
> >         if (! die && in_lto_p)
> >   	{
> >   	  dwarf2out_decl (decl);
> > --- 25810,25818 ----
> >       {
> >         dw_die_ref die = lookup_decl_die (decl);
> >   
> > !       /* We may have to generate early debug late for LTO in case debug
> > !          was not enabled at compile-time or the target doesn't support
> > ! 	 the LTO early debug scheme.  */
> >         if (! die && in_lto_p)
> >   	{
> >   	  dwarf2out_decl (decl);
> > *************** output_macinfo_op (macinfo_entry *ref)
> > *** 26892,26898 ****
> >       case DW_MACRO_import:
> >         dw2_asm_output_data (1, ref->code, "Import");
> >         ASM_GENERATE_INTERNAL_LABEL (label,
> > ! 				   DEBUG_MACRO_SECTION_LABEL, ref->lineno);
> >         dw2_asm_output_offset (DWARF_OFFSET_SIZE, label, NULL, NULL);
> >         break;
> >       default:
> > --- 27189,27196 ----
> >       case DW_MACRO_import:
> >         dw2_asm_output_data (1, ref->code, "Import");
> >         ASM_GENERATE_INTERNAL_LABEL (label,
> > ! 				   DEBUG_MACRO_SECTION_LABEL,
> > ! 				   ref->lineno + macinfo_label_base);
> >         dw2_asm_output_offset (DWARF_OFFSET_SIZE, label, NULL, NULL);
> >         break;
> >       default:
> > *************** save_macinfo_strings (void)
> > *** 27066,27072 ****
> >   /* Output macinfo section(s).  */
> >   
> >   static void
> > ! output_macinfo (void)
> >   {
> >     unsigned i;
> >     unsigned long length = vec_safe_length (macinfo_table);
> > --- 27364,27370 ----
> >   /* Output macinfo section(s).  */
> >   
> >   static void
> > ! output_macinfo (const char *debug_line_label, bool early_lto_debug)
> >   {
> >     unsigned i;
> >     unsigned long length = vec_safe_length (macinfo_table);
> > *************** output_macinfo (void)
> > *** 27092,27100 ****
> >   	dw2_asm_output_data (1, 3, "Flags: 64-bit, lineptr present");
> >         else
> >   	dw2_asm_output_data (1, 2, "Flags: 32-bit, lineptr present");
> > !       dw2_asm_output_offset (DWARF_OFFSET_SIZE,
> > !                              (!dwarf_split_debug_info ? debug_line_section_label
> > !                               : debug_skeleton_line_section_label),
> >                                debug_line_section, NULL);
> >       }
> >   
> > --- 27390,27396 ----
> >   	dw2_asm_output_data (1, 3, "Flags: 64-bit, lineptr present");
> >         else
> >   	dw2_asm_output_data (1, 2, "Flags: 32-bit, lineptr present");
> > !       dw2_asm_output_offset (DWARF_OFFSET_SIZE, debug_line_label,
> >                                debug_line_section, NULL);
> >       }
> >   
> > *************** output_macinfo (void)
> > *** 27148,27153 ****
> > --- 27444,27453 ----
> >     if (!macinfo_htab)
> >       return;
> >   
> > +   /* Save the number of transparent includes so we can adjust the
> > +      label number for the fat LTO object DWARF.  */
> > +   unsigned macinfo_label_base_adj = macinfo_htab->elements ();
> > + 
> >     delete macinfo_htab;
> >     macinfo_htab = NULL;
> >   
> > *************** output_macinfo (void)
> > *** 27167,27177 ****
> >   	  dw2_asm_output_data (1, 0, "End compilation unit");
> >   	  targetm.asm_out.named_section (debug_macinfo_section_name,
> >   					 SECTION_DEBUG
> > ! 					 | SECTION_LINKONCE,
> >   					 comdat_key);
> >   	  ASM_GENERATE_INTERNAL_LABEL (label,
> >   				       DEBUG_MACRO_SECTION_LABEL,
> > ! 				       ref->lineno);
> >   	  ASM_OUTPUT_LABEL (asm_out_file, label);
> >   	  ref->code = 0;
> >   	  ref->info = NULL;
> > --- 27467,27479 ----
> >   	  dw2_asm_output_data (1, 0, "End compilation unit");
> >   	  targetm.asm_out.named_section (debug_macinfo_section_name,
> >   					 SECTION_DEBUG
> > ! 					 | SECTION_LINKONCE
> > ! 					 | (early_lto_debug
> > ! 					    ? SECTION_EXCLUDE : 0),
> >   					 comdat_key);
> >   	  ASM_GENERATE_INTERNAL_LABEL (label,
> >   				       DEBUG_MACRO_SECTION_LABEL,
> > ! 				       ref->lineno + macinfo_label_base);
> >   	  ASM_OUTPUT_LABEL (asm_out_file, label);
> >   	  ref->code = 0;
> >   	  ref->info = NULL;
> > *************** output_macinfo (void)
> > *** 27192,27300 ****
> >         default:
> >   	gcc_unreachable ();
> >         }
> >   }
> >   
> > ! /* Initialize the various sections and labels for dwarf output.  */
> >   
> >   static void
> > ! init_sections_and_labels (void)
> >   {
> > !   if (!dwarf_split_debug_info)
> >       {
> > !       debug_info_section = get_section (DEBUG_INFO_SECTION,
> > !                                         SECTION_DEBUG, NULL);
> > !       debug_abbrev_section = get_section (DEBUG_ABBREV_SECTION,
> > !                                           SECTION_DEBUG, NULL);
> > !       debug_loc_section = get_section (dwarf_version >= 5
> > ! 				       ? DEBUG_LOCLISTS_SECTION
> > ! 				       : DEBUG_LOC_SECTION,
> > !                                        SECTION_DEBUG, NULL);
> > !       debug_macinfo_section_name
> > ! 	= (dwarf_strict && dwarf_version < 5)
> > ! 	  ? DEBUG_MACINFO_SECTION : DEBUG_MACRO_SECTION;
> > !       debug_macinfo_section = get_section (debug_macinfo_section_name,
> > ! 					   SECTION_DEBUG, NULL);
> >       }
> >     else
> >       {
> > !       debug_info_section = get_section (DEBUG_DWO_INFO_SECTION,
> > !                                         SECTION_DEBUG | SECTION_EXCLUDE, NULL);
> > !       debug_abbrev_section = get_section (DEBUG_DWO_ABBREV_SECTION,
> > !                                           SECTION_DEBUG | SECTION_EXCLUDE,
> > !                                           NULL);
> > !       debug_addr_section = get_section (DEBUG_ADDR_SECTION,
> > !                                         SECTION_DEBUG, NULL);
> > !       debug_skeleton_info_section = get_section (DEBUG_INFO_SECTION,
> > !                                                  SECTION_DEBUG, NULL);
> > !       debug_skeleton_abbrev_section = get_section (DEBUG_ABBREV_SECTION,
> > !                                                    SECTION_DEBUG, NULL);
> > !       ASM_GENERATE_INTERNAL_LABEL (debug_skeleton_abbrev_section_label,
> > !                                   DEBUG_SKELETON_ABBREV_SECTION_LABEL, 0);
> > ! 
> > !       /* Somewhat confusing detail: The skeleton_[abbrev|info] sections stay in
> > !          the main .o, but the skeleton_line goes into the split off dwo.  */
> > !       debug_skeleton_line_section
> > !         = get_section (DEBUG_DWO_LINE_SECTION,
> > ! 		       SECTION_DEBUG | SECTION_EXCLUDE, NULL);
> > !       ASM_GENERATE_INTERNAL_LABEL (debug_skeleton_line_section_label,
> > !                                    DEBUG_SKELETON_LINE_SECTION_LABEL, 0);
> > !       debug_str_offsets_section = get_section (DEBUG_DWO_STR_OFFSETS_SECTION,
> > !                                                SECTION_DEBUG | SECTION_EXCLUDE,
> > !                                                NULL);
> > !       ASM_GENERATE_INTERNAL_LABEL (debug_skeleton_info_section_label,
> > !                                    DEBUG_SKELETON_INFO_SECTION_LABEL, 0);
> > !       debug_loc_section = get_section (dwarf_version >= 5
> > ! 				       ? DEBUG_DWO_LOCLISTS_SECTION
> > ! 				       : DEBUG_DWO_LOC_SECTION,
> > !                                        SECTION_DEBUG | SECTION_EXCLUDE, NULL);
> > !       debug_str_dwo_section = get_section (DEBUG_STR_DWO_SECTION,
> > !                                            DEBUG_STR_DWO_SECTION_FLAGS, NULL);
> > !       debug_macinfo_section_name
> > ! 	= (dwarf_strict && dwarf_version < 5)
> > ! 	  ? DEBUG_DWO_MACINFO_SECTION : DEBUG_DWO_MACRO_SECTION;
> > !       debug_macinfo_section = get_section (debug_macinfo_section_name,
> >   					   SECTION_DEBUG | SECTION_EXCLUDE,
> >   					   NULL);
> > !     }
> > !   debug_aranges_section = get_section (DEBUG_ARANGES_SECTION,
> > ! 				       SECTION_DEBUG, NULL);
> > !   debug_line_section = get_section (DEBUG_LINE_SECTION,
> > ! 				    SECTION_DEBUG, NULL);
> > !   debug_pubnames_section = get_section (DEBUG_PUBNAMES_SECTION,
> > ! 					SECTION_DEBUG, NULL);
> > !   debug_pubtypes_section = get_section (DEBUG_PUBTYPES_SECTION,
> >   					SECTION_DEBUG, NULL);
> > !   debug_str_section = get_section (DEBUG_STR_SECTION,
> > ! 				   DEBUG_STR_SECTION_FLAGS, NULL);
> > !   if (!dwarf_split_debug_info && !DWARF2_ASM_LINE_DEBUG_INFO)
> > !     debug_line_str_section = get_section (DEBUG_LINE_STR_SECTION,
> > ! 					  DEBUG_STR_SECTION_FLAGS, NULL);
> > ! 
> > !   debug_ranges_section = get_section (dwarf_version >= 5
> > ! 				      ? DEBUG_RNGLISTS_SECTION
> > ! 				      : DEBUG_RANGES_SECTION,
> > ! 				      SECTION_DEBUG, NULL);
> > !   debug_frame_section = get_section (DEBUG_FRAME_SECTION,
> > ! 				     SECTION_DEBUG, NULL);
> >   
> >     ASM_GENERATE_INTERNAL_LABEL (abbrev_section_label,
> > ! 			       DEBUG_ABBREV_SECTION_LABEL, 0);
> >     ASM_GENERATE_INTERNAL_LABEL (debug_info_section_label,
> > ! 			       DEBUG_INFO_SECTION_LABEL, 0);
> >     ASM_GENERATE_INTERNAL_LABEL (debug_line_section_label,
> > ! 			       DEBUG_LINE_SECTION_LABEL, 0);
> >     ASM_GENERATE_INTERNAL_LABEL (ranges_section_label,
> > ! 			       DEBUG_RANGES_SECTION_LABEL, 0);
> >     if (dwarf_version >= 5 && dwarf_split_debug_info)
> >       ASM_GENERATE_INTERNAL_LABEL (ranges_base_label,
> > ! 				 DEBUG_RANGES_SECTION_LABEL, 1);
> >     ASM_GENERATE_INTERNAL_LABEL (debug_addr_section_label,
> > !                                DEBUG_ADDR_SECTION_LABEL, 0);
> >     ASM_GENERATE_INTERNAL_LABEL (macinfo_section_label,
> >   			       (dwarf_strict && dwarf_version < 5)
> >   			       ? DEBUG_MACINFO_SECTION_LABEL
> > ! 			       : DEBUG_MACRO_SECTION_LABEL, 0);
> > !   ASM_GENERATE_INTERNAL_LABEL (loc_section_label, DEBUG_LOC_SECTION_LABEL, 0);
> >   }
> >   
> >   /* Set up for Dwarf output at the start of compilation.  */
> > --- 27494,27685 ----
> >         default:
> >   	gcc_unreachable ();
> >         }
> > + 
> > +   macinfo_label_base += macinfo_label_base_adj;
> >   }
> >   
> > ! /* Initialize the various sections and labels for dwarf output and prefix
> > !    them with PREFIX if non-NULL.  */
> >   
> >   static void
> > ! init_sections_and_labels (bool early_lto_debug)
> >   {
> > !   /* As we may get called multiple times have a generation count for labels.  */
> > !   static unsigned generation = 0;
> > ! 
> > !   if (early_lto_debug)
> >       {
> > !       if (!dwarf_split_debug_info)
> > ! 	{
> > ! 	  debug_info_section = get_section (DEBUG_LTO_INFO_SECTION,
> > ! 					    SECTION_DEBUG | SECTION_EXCLUDE,
> > ! 					    NULL);
> > ! 	  debug_abbrev_section = get_section (DEBUG_LTO_ABBREV_SECTION,
> > ! 					      SECTION_DEBUG | SECTION_EXCLUDE,
> > ! 					      NULL);
> > ! 	  debug_macinfo_section_name = ((dwarf_strict && dwarf_version < 5)
> > ! 					? DEBUG_LTO_MACINFO_SECTION
> > ! 					: DEBUG_LTO_MACRO_SECTION);
> > ! 	  debug_macinfo_section = get_section (debug_macinfo_section_name,
> > ! 					       SECTION_DEBUG
> > ! 					       | SECTION_EXCLUDE, NULL);
> > ! 	  /* For macro info we have to refer to a debug_line section, so similar
> > ! 	     to split-dwarf emit a skeleton one for early debug.  */
> > ! 	  debug_skeleton_line_section
> > ! 	    = get_section (DEBUG_LTO_LINE_SECTION,
> > ! 			   SECTION_DEBUG | SECTION_EXCLUDE, NULL);
> > ! 	  ASM_GENERATE_INTERNAL_LABEL (debug_skeleton_line_section_label,
> > ! 				       DEBUG_SKELETON_LINE_SECTION_LABEL,
> > ! 				       generation);
> > ! 	}
> > !       else
> > ! 	{
> > ! 	  /* ???  Which of the following do we need early?  */
> > ! 	  debug_info_section = get_section (DEBUG_LTO_DWO_INFO_SECTION,
> > ! 					    SECTION_DEBUG | SECTION_EXCLUDE,
> > ! 					    NULL);
> > ! 	  debug_abbrev_section = get_section (DEBUG_LTO_DWO_ABBREV_SECTION,
> > ! 					      SECTION_DEBUG | SECTION_EXCLUDE,
> > ! 					      NULL);
> > ! 	  debug_skeleton_info_section = get_section (DEBUG_LTO_INFO_SECTION,
> > ! 						     SECTION_DEBUG
> > ! 						     | SECTION_EXCLUDE, NULL);
> > ! 	  debug_skeleton_abbrev_section = get_section (DEBUG_LTO_ABBREV_SECTION,
> > ! 						       SECTION_DEBUG
> > ! 						       | SECTION_EXCLUDE, NULL);
> > ! 	  ASM_GENERATE_INTERNAL_LABEL (debug_skeleton_abbrev_section_label,
> > ! 				       DEBUG_SKELETON_ABBREV_SECTION_LABEL,
> > ! 				       generation);
> > ! 
> > ! 	  /* Somewhat confusing detail: The skeleton_[abbrev|info] sections stay in
> > ! 	     the main .o, but the skeleton_line goes into the split off dwo.  */
> > ! 	  debug_skeleton_line_section
> > ! 	    = get_section (DEBUG_LTO_LINE_SECTION,
> > ! 			   SECTION_DEBUG | SECTION_EXCLUDE, NULL);
> > ! 	  ASM_GENERATE_INTERNAL_LABEL (debug_skeleton_line_section_label,
> > ! 				       DEBUG_SKELETON_LINE_SECTION_LABEL,
> > ! 				       generation);
> > ! 	  debug_str_offsets_section
> > ! 	    = get_section (DEBUG_LTO_DWO_STR_OFFSETS_SECTION,
> > ! 			   SECTION_DEBUG | SECTION_EXCLUDE,
> > ! 			   NULL);
> > ! 	  ASM_GENERATE_INTERNAL_LABEL (debug_skeleton_info_section_label,
> > ! 				       DEBUG_SKELETON_INFO_SECTION_LABEL,
> > ! 				       generation);
> > ! 	  debug_str_dwo_section = get_section (DEBUG_LTO_STR_DWO_SECTION,
> > ! 					       DEBUG_STR_DWO_SECTION_FLAGS, NULL);
> > ! 	  debug_macinfo_section_name
> > ! 	    = (dwarf_strict
> > ! 	       ? DEBUG_LTO_DWO_MACINFO_SECTION : DEBUG_LTO_DWO_MACRO_SECTION);
> > ! 	  debug_macinfo_section = get_section (debug_macinfo_section_name,
> > ! 					       SECTION_DEBUG | SECTION_EXCLUDE,
> > ! 					       NULL);
> > ! 	}
> > !       debug_str_section = get_section (DEBUG_LTO_STR_SECTION,
> > ! 				       DEBUG_STR_SECTION_FLAGS
> > ! 				       | SECTION_EXCLUDE, NULL);
> >       }
> >     else
> >       {
> > !       if (!dwarf_split_debug_info)
> > ! 	{
> > ! 	  debug_info_section = get_section (DEBUG_INFO_SECTION,
> > ! 					    SECTION_DEBUG, NULL);
> > ! 	  debug_abbrev_section = get_section (DEBUG_ABBREV_SECTION,
> > ! 					      SECTION_DEBUG, NULL);
> > ! 	  debug_loc_section = get_section (DEBUG_LOC_SECTION,
> > ! 					   SECTION_DEBUG, NULL);
> > ! 	  debug_macinfo_section_name
> > ! 	      = dwarf_strict ? DEBUG_MACINFO_SECTION : DEBUG_MACRO_SECTION;
> > ! 	  debug_macinfo_section = get_section (debug_macinfo_section_name,
> > ! 					       SECTION_DEBUG, NULL);
> > ! 	}
> > !       else
> > ! 	{
> > ! 	  debug_info_section = get_section (DEBUG_DWO_INFO_SECTION,
> > ! 					    SECTION_DEBUG | SECTION_EXCLUDE,
> > ! 					    NULL);
> > ! 	  debug_abbrev_section = get_section (DEBUG_DWO_ABBREV_SECTION,
> > ! 					      SECTION_DEBUG | SECTION_EXCLUDE,
> > ! 					      NULL);
> > ! 	  debug_addr_section = get_section (DEBUG_ADDR_SECTION,
> > ! 					    SECTION_DEBUG, NULL);
> > ! 	  debug_skeleton_info_section = get_section (DEBUG_INFO_SECTION,
> > ! 						     SECTION_DEBUG, NULL);
> > ! 	  debug_skeleton_abbrev_section = get_section (DEBUG_ABBREV_SECTION,
> > ! 						       SECTION_DEBUG, NULL);
> > ! 	  ASM_GENERATE_INTERNAL_LABEL (debug_skeleton_abbrev_section_label,
> > ! 				       DEBUG_SKELETON_ABBREV_SECTION_LABEL,
> > ! 				       generation);
> > ! 
> > ! 	  /* Somewhat confusing detail: The skeleton_[abbrev|info] sections
> > ! 	     stay in the main .o, but the skeleton_line goes into the
> > ! 	     split off dwo.  */
> > ! 	  debug_skeleton_line_section
> > ! 	      = get_section (DEBUG_DWO_LINE_SECTION,
> > ! 			     SECTION_DEBUG | SECTION_EXCLUDE, NULL);
> > ! 	  ASM_GENERATE_INTERNAL_LABEL (debug_skeleton_line_section_label,
> > ! 				       DEBUG_SKELETON_LINE_SECTION_LABEL,
> > ! 				       generation);
> > ! 	  debug_str_offsets_section
> > ! 	    = get_section (DEBUG_DWO_STR_OFFSETS_SECTION,
> > ! 			   SECTION_DEBUG | SECTION_EXCLUDE, NULL);
> > ! 	  ASM_GENERATE_INTERNAL_LABEL (debug_skeleton_info_section_label,
> > ! 				       DEBUG_SKELETON_INFO_SECTION_LABEL,
> > ! 				       generation);
> > ! 	  debug_loc_section = get_section (DEBUG_DWO_LOC_SECTION,
> >   					   SECTION_DEBUG | SECTION_EXCLUDE,
> >   					   NULL);
> > ! 	  debug_str_dwo_section = get_section (DEBUG_STR_DWO_SECTION,
> > ! 					       DEBUG_STR_DWO_SECTION_FLAGS,
> > ! 					       NULL);
> > ! 	  debug_macinfo_section_name
> > ! 	    = (dwarf_strict && dwarf_version < 5)
> > ! 	      ? DEBUG_DWO_MACINFO_SECTION : DEBUG_DWO_MACRO_SECTION;
> > ! 	  debug_macinfo_section = get_section (debug_macinfo_section_name,
> > ! 					       SECTION_DEBUG | SECTION_EXCLUDE,
> > ! 					       NULL);
> > ! 	}
> > !       debug_aranges_section = get_section (DEBUG_ARANGES_SECTION,
> > ! 					   SECTION_DEBUG, NULL);
> > !       debug_line_section = get_section (DEBUG_LINE_SECTION,
> >   					SECTION_DEBUG, NULL);
> > !       debug_pubnames_section = get_section (DEBUG_PUBNAMES_SECTION,
> > ! 					    SECTION_DEBUG, NULL);
> > !       debug_pubtypes_section = get_section (DEBUG_PUBTYPES_SECTION,
> > ! 					    SECTION_DEBUG, NULL);
> > !       debug_str_section = get_section (DEBUG_STR_SECTION,
> > ! 				       DEBUG_STR_SECTION_FLAGS, NULL);
> > !       debug_ranges_section = get_section (dwarf_version >= 5
> > ! 					  ? DEBUG_RNGLISTS_SECTION
> > ! 					  : DEBUG_RANGES_SECTION,
> > ! 					  SECTION_DEBUG, NULL);
> > !       debug_frame_section = get_section (DEBUG_FRAME_SECTION,
> > ! 					 SECTION_DEBUG, NULL);
> > !     }
> >   
> >     ASM_GENERATE_INTERNAL_LABEL (abbrev_section_label,
> > ! 			       DEBUG_ABBREV_SECTION_LABEL, generation);
> >     ASM_GENERATE_INTERNAL_LABEL (debug_info_section_label,
> > ! 			       DEBUG_INFO_SECTION_LABEL, generation);
> > !   info_section_emitted = false;
> >     ASM_GENERATE_INTERNAL_LABEL (debug_line_section_label,
> > ! 			       DEBUG_LINE_SECTION_LABEL, generation);
> >     ASM_GENERATE_INTERNAL_LABEL (ranges_section_label,
> > ! 			       DEBUG_RANGES_SECTION_LABEL, generation);
> >     if (dwarf_version >= 5 && dwarf_split_debug_info)
> >       ASM_GENERATE_INTERNAL_LABEL (ranges_base_label,
> > ! 				 DEBUG_RANGES_SECTION_LABEL, 2 + generation);
> >     ASM_GENERATE_INTERNAL_LABEL (debug_addr_section_label,
> > !                                DEBUG_ADDR_SECTION_LABEL, generation);
> >     ASM_GENERATE_INTERNAL_LABEL (macinfo_section_label,
> >   			       (dwarf_strict && dwarf_version < 5)
> >   			       ? DEBUG_MACINFO_SECTION_LABEL
> > ! 			       : DEBUG_MACRO_SECTION_LABEL, generation);
> > !   ASM_GENERATE_INTERNAL_LABEL (loc_section_label, DEBUG_LOC_SECTION_LABEL,
> > ! 			       generation);
> > ! 
> > !   ++generation;
> >   }
> >   
> >   /* Set up for Dwarf output at the start of compilation.  */
> > *************** flush_limbo_die_list (void)
> > *** 29641,29646 ****
> > --- 30026,30047 ----
> >       }
> >   }
> >   
> > + /* Reset DIEs so we can output them again.  */
> > + 
> > + static void
> > + reset_dies (dw_die_ref die)
> > + {
> > +   dw_die_ref c;
> > + 
> > +   /* Remove stuff we re-generate.  */
> > +   die->die_mark = 0;
> > +   die->die_offset = 0;
> > +   die->die_abbrev = 0;
> > +   remove_AT (die, DW_AT_sibling);
> > + 
> > +   FOR_EACH_CHILD (die, c, reset_dies (c));
> > + }
> > + 
> >   /* Output stuff that dwarf requires at the end of every file,
> >      and generate the DWARF-2 debugging info.  */
> >   
> > *************** dwarf2out_finish (const char *)
> > *** 29667,29672 ****
> > --- 30068,30113 ----
> >   
> >     gen_remaining_tmpl_value_param_die_attribute ();
> >   
> > +   if (flag_generate_lto)
> > +     {
> > +       gcc_assert (flag_fat_lto_objects);
> > + 
> > +       /* Prune stuff so that dwarf2out_finish runs successfully
> > + 	 for the fat part of the object.  */
> > +       reset_dies (comp_unit_die ());
> > +       for (limbo_die_node *node = cu_die_list; node; node = node->next)
> > + 	reset_dies (node->die);
> > + 
> > +       hash_table<comdat_type_hasher> comdat_type_table (100);
> > +       for (ctnode = comdat_type_list; ctnode != NULL; ctnode = ctnode->next)
> > + 	{
> > + 	  comdat_type_node **slot
> > + 	      = comdat_type_table.find_slot (ctnode, INSERT);
> > + 
> > + 	  /* Don't reset types twice.  */
> > + 	  if (*slot != HTAB_EMPTY_ENTRY)
> > + 	    continue;
> > + 
> > + 	  /* Add a pointer to the line table for the main compilation unit
> > + 	     so that the debugger can make sense of DW_AT_decl_file
> > + 	     attributes.  */
> > + 	  if (debug_info_level >= DINFO_LEVEL_TERSE)
> > + 	    reset_dies (ctnode->root_die);
> > + 
> > + 	  *slot = ctnode;
> > + 	}
> > + 
> > +       /* Reset die CU symbol so we don't output it twice.  */
> > +       comp_unit_die ()->die_id.die_symbol = NULL;
> > + 
> > +       /* Remove DW_AT_macro from the early output.  */
> > +       if (have_macinfo)
> > + 	remove_AT (comp_unit_die (), DEBUG_MACRO_ATTRIBUTE);
> > + 
> > +       /* Remove indirect string decisions.  */
> > +       debug_str_hash->traverse<void *, reset_indirect_string> (NULL);
> > +     }
> > + 
> >   #if ENABLE_ASSERT_CHECKING
> >     {
> >       dw_die_ref die = comp_unit_die (), c;
> > *************** dwarf2out_finish (const char *)
> > *** 29677,29683 ****
> >     move_marked_base_types ();
> >   
> >     /* Initialize sections and labels used for actual assembler output.  */
> > !   init_sections_and_labels ();
> >   
> >     /* Traverse the DIE's and add sibling attributes to those DIE's that
> >        have children.  */
> > --- 30118,30124 ----
> >     move_marked_base_types ();
> >   
> >     /* Initialize sections and labels used for actual assembler output.  */
> > !   init_sections_and_labels (false);
> >   
> >     /* Traverse the DIE's and add sibling attributes to those DIE's that
> >        have children.  */
> > *************** dwarf2out_finish (const char *)
> > *** 29772,29780 ****
> >   		    debug_line_section_label);
> >   
> >     if (have_macinfo)
> > !     add_AT_macptr (comp_unit_die (),
> > ! 		   dwarf_version >= 5 ? DW_AT_macros
> > ! 		   : dwarf_strict ? DW_AT_macro_info : DW_AT_GNU_macros,
> >   		   macinfo_section_label);
> >   
> >     if (dwarf_split_debug_info)
> > --- 30213,30219 ----
> >   		    debug_line_section_label);
> >   
> >     if (have_macinfo)
> > !     add_AT_macptr (comp_unit_die (), DEBUG_MACRO_ATTRIBUTE,
> >   		   macinfo_section_label);
> >   
> >     if (dwarf_split_debug_info)
> > *************** dwarf2out_finish (const char *)
> > *** 29979,29985 ****
> >       {
> >         switch_to_section (debug_macinfo_section);
> >         ASM_OUTPUT_LABEL (asm_out_file, macinfo_section_label);
> > !       output_macinfo ();
> >         dw2_asm_output_data (1, 0, "End compilation unit");
> >       }
> >   
> > --- 30418,30425 ----
> >       {
> >         switch_to_section (debug_macinfo_section);
> >         ASM_OUTPUT_LABEL (asm_out_file, macinfo_section_label);
> > !       output_macinfo (!dwarf_split_debug_info ? debug_line_section_label
> > ! 		      : debug_skeleton_line_section_label, false);
> >         dw2_asm_output_data (1, 0, "End compilation unit");
> >       }
> >   
> > *************** note_variable_value_in_expr (dw_die_ref
> > *** 30200,30205 ****
> > --- 30640,30659 ----
> >         {
> >   	tree decl = loc->dw_loc_oprnd1.v.val_decl_ref;
> >   	dw_die_ref ref = lookup_decl_die (decl);
> > + 	if (! ref && flag_generate_lto)
> > + 	  {
> > + 	    /* ???  This is somewhat a hack because we do not create DIEs
> > + 	       for variables not in BLOCK trees early but when generating
> > + 	       early LTO output we need the dw_val_class_decl_ref to be
> > + 	       fully resolved.  For fat LTO objects we'd also like to
> > + 	       undo this after LTO dwarf output.  */
> > + 	    gcc_assert (DECL_CONTEXT (decl));
> > + 	    dw_die_ref ctx = lookup_decl_die (DECL_CONTEXT (decl));
> > + 	    gcc_assert (ctx != NULL);
> > + 	    gen_decl_die (decl, NULL_TREE, NULL, ctx);
> > + 	    ref = lookup_decl_die (decl);
> > + 	    gcc_assert (ref != NULL);
> > + 	  }
> >   	if (ref)
> >   	  {
> >   	    loc->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
> > *************** dwarf2out_early_finish (const char *file
> > *** 30410,30415 ****
> > --- 30864,30982 ----
> >   
> >     /* The early debug phase is now finished.  */
> >     early_dwarf_finished = true;
> > + 
> > +   /* Do not generate DWARF assembler now when not producing LTO bytecode.  */
> > +   if (!flag_generate_lto)
> > +     return;
> > + 
> > +   /* Now as we are going to output for LTO initialize sections and labels
> > +      to the LTO variants.  We don't need a random-seed postfix as other
> > +      LTO sections as linking the LTO debug sections into one in a partial
> > +      link is fine.  */
> > +   init_sections_and_labels (true);
> > + 
> > +   /* The output below is modeled after dwarf2out_finish with all
> > +      location related output removed and some LTO specific changes.
> > +      Some refactoring might make both smaller and easier to match up.  */
> > + 
> > +   /* Traverse the DIE's and add add sibling attributes to those DIE's
> > +      that have children.  */
> > +   add_sibling_attributes (comp_unit_die ());
> > +   for (limbo_die_node *node = limbo_die_list; node; node = node->next)
> > +     add_sibling_attributes (node->die);
> > +   for (comdat_type_node *ctnode = comdat_type_list;
> > +        ctnode != NULL; ctnode = ctnode->next)
> > +     add_sibling_attributes (ctnode->root_die);
> > + 
> > +   if (have_macinfo)
> > +     add_AT_macptr (comp_unit_die (), DEBUG_MACRO_ATTRIBUTE,
> > + 		   macinfo_section_label);
> > + 
> > +   save_macinfo_strings ();
> > + 
> > +   /* Output all of the compilation units.  We put the main one last so that
> > +      the offsets are available to output_pubnames.  */
> > +   for (limbo_die_node *node = limbo_die_list; node; node = node->next)
> > +     output_comp_unit (node->die, 0, NULL);
> > + 
> > +   hash_table<comdat_type_hasher> comdat_type_table (100);
> > +   for (comdat_type_node *ctnode = comdat_type_list;
> > +        ctnode != NULL; ctnode = ctnode->next)
> > +     {
> > +       comdat_type_node **slot = comdat_type_table.find_slot (ctnode, INSERT);
> > + 
> > +       /* Don't output duplicate types.  */
> > +       if (*slot != HTAB_EMPTY_ENTRY)
> > +         continue;
> > + 
> > +       /* Add a pointer to the line table for the main compilation unit
> > +          so that the debugger can make sense of DW_AT_decl_file
> > +          attributes.  */
> > +       if (debug_info_level >= DINFO_LEVEL_TERSE)
> > +         add_AT_lineptr (ctnode->root_die, DW_AT_stmt_list,
> > +                         (!dwarf_split_debug_info
> > +                          ? debug_line_section_label
> > +                          : debug_skeleton_line_section_label));
> > + 
> > +       output_comdat_type_unit (ctnode);
> > +       *slot = ctnode;
> > +     }
> > + 
> > +   /* The AT_pubnames attribute needs to go in all skeleton dies, including
> > +      both the main_cu and all skeleton TUs.  Making this call unconditional
> > +      would end up either adding a second copy of the AT_pubnames attribute, or
> > +      requiring a special case in add_top_level_skeleton_die_attrs.  */
> > +   if (!dwarf_split_debug_info)
> > +     add_AT_pubnames (comp_unit_die ());
> > + 
> > +   /* Stick a unique symbol to the main debuginfo section.  */
> > +   compute_section_prefix_1 (comp_unit_die (), false);
> > + 
> > +   /* Output the main compilation unit.  We always need it if only for
> > +      the CU symbol.  */
> > +   output_comp_unit (comp_unit_die (), true, NULL);
> > + 
> > +   /* Output the abbreviation table.  */
> > +   if (vec_safe_length (abbrev_die_table) != 1)
> > +     {
> > +       switch_to_section (debug_abbrev_section);
> > +       ASM_OUTPUT_LABEL (asm_out_file, abbrev_section_label);
> > +       output_abbrev_section ();
> > +     }
> > + 
> > +   /* Have to end the macro section.  */
> > +   if (have_macinfo)
> > +     {
> > +       /* We have to save macinfo state if we need to output it again
> > + 	 for the FAT part of the object.  */
> > +       vec<macinfo_entry, va_gc> *saved_macinfo_table = macinfo_table;
> > +       if (flag_fat_lto_objects)
> > + 	macinfo_table = macinfo_table->copy ();
> > + 
> > +       switch_to_section (debug_macinfo_section);
> > +       ASM_OUTPUT_LABEL (asm_out_file, macinfo_section_label);
> > +       output_macinfo (debug_skeleton_line_section_label, true);
> > +       dw2_asm_output_data (1, 0, "End compilation unit");
> > + 
> > +       /* Emit a skeleton debug_line section.  */
> > +       switch_to_section (debug_skeleton_line_section);
> > +       ASM_OUTPUT_LABEL (asm_out_file, debug_skeleton_line_section_label);
> > +       output_line_info (true);
> > + 
> > +       if (flag_fat_lto_objects)
> > + 	{
> > + 	  vec_free (macinfo_table);
> > + 	  macinfo_table = saved_macinfo_table;
> > + 	}
> > +     }
> > + 
> > + 
> > +   /* If we emitted any indirect strings, output the string table too.  */
> > +   if (debug_str_hash || skeleton_debug_str_hash)
> > +     output_indirect_strings ();
> > + 
> > +   /* Switch back to the text section.  */
> > +   switch_to_section (text_section);
> >   }
> >   
> >   /* Reset all state within dwarf2out.c so that we can rerun the compiler
> > Index: early-lto-debug/gcc/debug.h
> > ===================================================================
> > *** early-lto-debug.orig/gcc/debug.h	2017-05-16 13:10:47.554202813 +0200
> > --- early-lto-debug/gcc/debug.h	2017-05-16 13:10:49.774239353 +0200
> > *************** struct gcc_debug_hooks
> > *** 147,152 ****
> > --- 147,160 ----
> >     void (* imported_module_or_decl) (tree decl, tree name,
> >   				    tree context, bool child);
> >   
> > +   /* Return true if a DIE for the tree is available and return a symbol
> > +      and offset that can be used to refer to it externally.  */
> > +   bool (* die_ref_for_decl) (tree, const char **, unsigned HOST_WIDE_INT *);
> > + 
> > +   /* Early debug information for the tree is available at symbol plus
> > +      offset externally.  */
> > +   void (* register_external_die) (tree, const char *, unsigned HOST_WIDE_INT);
> > + 
> >     /* DECL is an inline function, whose body is present, but which is
> >        not being output at this point.  */
> >     void (* deferred_inline_function) (tree decl);
> > *************** extern void debug_nothing_tree_tree_tree
> > *** 210,215 ****
> > --- 218,227 ----
> >   extern bool debug_true_const_tree (const_tree);
> >   extern void debug_nothing_rtx_insn (rtx_insn *);
> >   extern void debug_nothing_rtx_code_label (rtx_code_label *);
> > + extern bool debug_false_tree_charstarstar_uhwistar (tree, const char **,
> > + 						    unsigned HOST_WIDE_INT *);
> > + extern void debug_nothing_tree_charstar_uhwi (tree, const char *,
> > + 					      unsigned HOST_WIDE_INT);
> >   
> >   /* Hooks for various debug formats.  */
> >   extern const struct gcc_debug_hooks do_nothing_debug_hooks;
> > Index: early-lto-debug/gcc/debug.c
> > ===================================================================
> > *** early-lto-debug.orig/gcc/debug.c	2017-05-16 13:10:47.554202813 +0200
> > --- early-lto-debug/gcc/debug.c	2017-05-16 13:10:49.774239353 +0200
> > *************** const struct gcc_debug_hooks do_nothing_
> > *** 48,53 ****
> > --- 48,55 ----
> >     debug_nothing_tree,	         	 /* late_global_decl */
> >     debug_nothing_tree_int,		 /* type_decl */
> >     debug_nothing_tree_tree_tree_bool,	 /* imported_module_or_decl */
> > +   debug_false_tree_charstarstar_uhwistar, /* die_ref_for_decl */
> > +   debug_nothing_tree_charstar_uhwi,	 /* register_external_die */
> >     debug_nothing_tree,		         /* deferred_inline_function */
> >     debug_nothing_tree,		         /* outlining_inline_function */
> >     debug_nothing_rtx_code_label,	         /* label */
> > *************** debug_nothing_tree_int (tree decl ATTRIB
> > *** 146,148 ****
> > --- 148,163 ----
> >   			int local ATTRIBUTE_UNUSED)
> >   {
> >   }
> > + 
> > + bool
> > + debug_false_tree_charstarstar_uhwistar (tree, const char **,
> > + 					unsigned HOST_WIDE_INT *)
> > + {
> > +   return false;
> > + }
> > + 
> > + void
> > + debug_nothing_tree_charstar_uhwi (tree, const char *,
> > + 				  unsigned HOST_WIDE_INT)
> > + {
> > + }
> > Index: early-lto-debug/gcc/dbxout.c
> > ===================================================================
> > *** early-lto-debug.orig/gcc/dbxout.c	2017-05-16 13:10:47.554202813 +0200
> > --- early-lto-debug/gcc/dbxout.c	2017-05-16 13:10:49.778239419 +0200
> > *************** const struct gcc_debug_hooks dbx_debug_h
> > *** 372,377 ****
> > --- 372,379 ----
> >     dbxout_late_global_decl,		 /* late_global_decl */
> >     dbxout_type_decl,			 /* type_decl */
> >     debug_nothing_tree_tree_tree_bool,	 /* imported_module_or_decl */
> > +   debug_false_tree_charstarstar_uhwistar, /* die_ref_for_decl */
> > +   debug_nothing_tree_charstar_uhwi,	 /* register_external_die */
> >     debug_nothing_tree,		         /* deferred_inline_function */
> >     debug_nothing_tree,		         /* outlining_inline_function */
> >     debug_nothing_rtx_code_label,	         /* label */
> > *************** const struct gcc_debug_hooks xcoff_debug
> > *** 412,417 ****
> > --- 414,421 ----
> >     dbxout_late_global_decl,		 /* late_global_decl */
> >     dbxout_type_decl,			 /* type_decl */
> >     debug_nothing_tree_tree_tree_bool,	 /* imported_module_or_decl */
> > +   debug_false_tree_charstarstar_uhwistar, /* die_ref_for_decl */
> > +   debug_nothing_tree_charstar_uhwi,      /* register_external_die */
> >     debug_nothing_tree,		         /* deferred_inline_function */
> >     debug_nothing_tree,		         /* outlining_inline_function */
> >     debug_nothing_rtx_code_label,	         /* label */
> > Index: early-lto-debug/gcc/sdbout.c
> > ===================================================================
> > *** early-lto-debug.orig/gcc/sdbout.c	2017-05-16 13:10:47.554202813 +0200
> > --- early-lto-debug/gcc/sdbout.c	2017-05-16 13:10:49.778239419 +0200
> > *************** const struct gcc_debug_hooks sdb_debug_h
> > *** 302,307 ****
> > --- 302,309 ----
> >     sdbout_late_global_decl,		 /* late_global_decl */
> >     sdbout_symbol,			 /* type_decl */
> >     debug_nothing_tree_tree_tree_bool,	 /* imported_module_or_decl */
> > +   debug_false_tree_charstarstar_uhwistar, /* die_ref_for_decl */
> > +   debug_nothing_tree_charstar_uhwi,	 /* register_external_die */
> >     debug_nothing_tree,		         /* deferred_inline_function */
> >     debug_nothing_tree,		         /* outlining_inline_function */
> >     sdbout_label,			         /* label */
> > Index: early-lto-debug/gcc/lto/lto.c
> > ===================================================================
> > *** early-lto-debug.orig/gcc/lto/lto.c	2017-05-16 13:10:47.554202813 +0200
> > --- early-lto-debug/gcc/lto/lto.c	2017-05-16 13:10:49.778239419 +0200
> > *************** unify_scc (struct data_in *data_in, unsi
> > *** 1632,1637 ****
> > --- 1632,1640 ----
> >   	      free_node (scc->entries[i]);
> >   	    }
> >   
> > + 	  /* Drop DIE references.  */
> > + 	  dref_queue.truncate (0);
> > + 
> >   	  break;
> >   	}
> >   
> > *************** lto_read_decls (struct lto_file_decl_dat
> > *** 1707,1714 ****
> >   						     from);
> >   	  if (len == 1
> >   	      && (TREE_CODE (first) == IDENTIFIER_NODE
> > ! 		  || TREE_CODE (first) == INTEGER_CST
> > ! 		  || TREE_CODE (first) == TRANSLATION_UNIT_DECL))
> >   	    continue;
> >   
> >   	  /* Try to unify the SCC with already existing ones.  */
> > --- 1710,1716 ----
> >   						     from);
> >   	  if (len == 1
> >   	      && (TREE_CODE (first) == IDENTIFIER_NODE
> > ! 		  || TREE_CODE (first) == INTEGER_CST))
> >   	    continue;
> >   
> >   	  /* Try to unify the SCC with already existing ones.  */
> > *************** lto_read_decls (struct lto_file_decl_dat
> > *** 1747,1762 ****
> >   	      if (TREE_CODE (t) == INTEGER_CST
> >   		  && !TREE_OVERFLOW (t))
> >   		cache_integer_cst (t);
> > - 	      /* Register TYPE_DECLs with the debuginfo machinery.  */
> > - 	      if (!flag_wpa
> > - 		  && TREE_CODE (t) == TYPE_DECL)
> > - 		{
> > - 		  /* Dwarf2out needs location information.
> > - 		     TODO: Moving this out of the streamer loop may noticealy
> > - 		     improve ltrans linemap memory use.  */
> > - 		  data_in->location_cache.apply_location_cache ();
> > - 		  debug_hooks->type_decl (t, !DECL_FILE_SCOPE_P (t));
> > - 		}
> >   	      if (!flag_ltrans)
> >   		{
> >   		  /* Register variables and functions with the
> > --- 1749,1754 ----
> > *************** lto_read_decls (struct lto_file_decl_dat
> > *** 1772,1777 ****
> > --- 1764,1777 ----
> >   		    vec_safe_push (tree_with_vars, t);
> >   		}
> >   	    }
> > + 
> > + 	  /* Register DECLs with the debuginfo machinery.  */
> > + 	  while (!dref_queue.is_empty ())
> > + 	    {
> > + 	      dref_entry e = dref_queue.pop ();
> > + 	      debug_hooks->register_external_die (e.decl, e.sym, e.off);
> > + 	    }
> > + 
> >   	  if (seen_type)
> >   	    num_type_scc_trees += len;
> >   	}
> > *************** lto_section_with_id (const char *name, u
> > *** 1951,1957 ****
> >     if (strncmp (name, section_name_prefix, strlen (section_name_prefix)))
> >       return 0;
> >     s = strrchr (name, '.');
> > !   return s && sscanf (s, "." HOST_WIDE_INT_PRINT_HEX_PURE, id) == 1;
> >   }
> >   
> >   /* Create file_data of each sub file id */
> > --- 1951,1962 ----
> >     if (strncmp (name, section_name_prefix, strlen (section_name_prefix)))
> >       return 0;
> >     s = strrchr (name, '.');
> > !   if (!s)
> > !     return 0;
> > !   /* If the section is not suffixed with an ID return.  */
> > !   if ((size_t)(s - name) == strlen (section_name_prefix))
> > !     return 0;
> > !   return sscanf (s, "." HOST_WIDE_INT_PRINT_HEX_PURE, id) == 1;
> >   }
> >   
> >   /* Create file_data of each sub file id */
> > Index: early-lto-debug/gcc/lto-streamer-in.c
> > ===================================================================
> > *** early-lto-debug.orig/gcc/lto-streamer-in.c	2017-05-16 13:10:47.554202813 +0200
> > --- early-lto-debug/gcc/lto-streamer-in.c	2017-05-16 13:10:49.858240736 +0200
> > *************** along with GCC; see the file COPYING3.
> > *** 41,46 ****
> > --- 41,47 ----
> >   #include "except.h"
> >   #include "cgraph.h"
> >   #include "cfgloop.h"
> > + #include "debug.h"
> >   
> >   
> >   struct freeing_string_slot_hasher : string_slot_hasher
> > *************** input_function (tree fn_decl, struct dat
> > *** 1038,1043 ****
> > --- 1039,1054 ----
> >     DECL_RESULT (fn_decl) = stream_read_tree (ib, data_in);
> >     DECL_ARGUMENTS (fn_decl) = streamer_read_chain (ib, data_in);
> >   
> > +   /* Read debug args if available.  */
> > +   unsigned n_debugargs = streamer_read_uhwi (ib);
> > +   if (n_debugargs)
> > +     {
> > +       vec<tree, va_gc> **debugargs = decl_debug_args_insert (fn_decl);
> > +       vec_safe_grow (*debugargs, n_debugargs);
> > +       for (unsigned i = 0; i < n_debugargs; ++i)
> > + 	(**debugargs)[i] = stream_read_tree (ib, data_in);
> > +     }
> > + 
> >     /* Read the tree of lexical scopes for the function.  */
> >     DECL_INITIAL (fn_decl) = stream_read_tree (ib, data_in);
> >     unsigned block_leaf_count = streamer_read_uhwi (ib);
> > *************** lto_input_variable_constructor (struct l
> > *** 1318,1323 ****
> > --- 1329,1338 ----
> >   }
> >   
> >   
> > + /* Queue of acummulated decl -> DIE mappings.  Similar to locations those
> > +    are only applied to prevailing tree nodes during tree merging.  */
> > + vec<dref_entry> dref_queue;
> > + 
> >   /* Read the physical representation of a tree node EXPR from
> >      input block IB using the per-file context in DATA_IN.  */
> >   
> > *************** lto_read_tree_1 (struct lto_input_block
> > *** 1337,1342 ****
> > --- 1352,1374 ----
> >         && TREE_CODE (expr) != FUNCTION_DECL
> >         && TREE_CODE (expr) != TRANSLATION_UNIT_DECL)
> >       DECL_INITIAL (expr) = stream_read_tree (ib, data_in);
> > + 
> > +   /* Stream references to early generated DIEs.  Keep in sync with the
> > +      trees handled in dwarf2out_register_external_die.  */
> > +   if ((DECL_P (expr)
> > +        && TREE_CODE (expr) != FIELD_DECL
> > +        && TREE_CODE (expr) != DEBUG_EXPR_DECL
> > +        && TREE_CODE (expr) != TYPE_DECL)
> > +       || TREE_CODE (expr) == BLOCK)
> > +     {
> > +       const char *str = streamer_read_string (data_in, ib);
> > +       if (str)
> > + 	{
> > + 	  unsigned HOST_WIDE_INT off = streamer_read_uhwi (ib);
> > + 	  dref_entry e = { expr, str, off };
> > + 	  dref_queue.safe_push (e);
> > + 	}
> > +     }
> >   }
> >   
> >   /* Read the physical representation of a tree node with tag TAG from
> > *************** lto_input_tree (struct lto_input_block *
> > *** 1482,1487 ****
> > --- 1514,1526 ----
> >       {
> >         unsigned len, entry_len;
> >         lto_input_scc (ib, data_in, &len, &entry_len);
> > + 
> > +       /* Register DECLs with the debuginfo machinery.  */
> > +       while (!dref_queue.is_empty ())
> > + 	{
> > + 	  dref_entry e = dref_queue.pop ();
> > + 	  debug_hooks->register_external_die (e.decl, e.sym, e.off);
> > + 	}
> >       }
> >     return lto_input_tree_1 (ib, data_in, tag, 0);
> >   }
> > Index: early-lto-debug/gcc/lto-streamer-out.c
> > ===================================================================
> > *** early-lto-debug.orig/gcc/lto-streamer-out.c	2017-05-16 13:10:47.554202813 +0200
> > --- early-lto-debug/gcc/lto-streamer-out.c	2017-05-16 13:10:49.858240736 +0200
> > *************** along with GCC; see the file COPYING3.
> > *** 40,45 ****
> > --- 40,46 ----
> >   #include "cfgloop.h"
> >   #include "builtins.h"
> >   #include "gomp-constants.h"
> > + #include "debug.h"
> >   
> >   
> >   static void lto_write_tree (struct output_block*, tree, bool);
> > *************** lto_write_tree_1 (struct output_block *o
> > *** 406,411 ****
> > --- 407,432 ----
> >   			 (ob->decl_state->symtab_node_encoder, expr);
> >         stream_write_tree (ob, initial, ref_p);
> >       }
> > + 
> > +   /* Stream references to early generated DIEs.  Keep in sync with the
> > +      trees handled in dwarf2out_die_ref_for_decl.  */
> > +   if ((DECL_P (expr)
> > +        && TREE_CODE (expr) != FIELD_DECL
> > +        && TREE_CODE (expr) != DEBUG_EXPR_DECL
> > +        && TREE_CODE (expr) != TYPE_DECL)
> > +       || TREE_CODE (expr) == BLOCK)
> > +     {
> > +       const char *sym;
> > +       unsigned HOST_WIDE_INT off;
> > +       if (debug_info_level > DINFO_LEVEL_NONE
> > + 	  && debug_hooks->die_ref_for_decl (expr, &sym, &off))
> > + 	{
> > + 	  streamer_write_string (ob, ob->main_stream, sym, true);
> > + 	  streamer_write_uhwi (ob, off);
> > + 	}
> > +       else
> > + 	streamer_write_string (ob, ob->main_stream, NULL, true);
> > +     }
> >   }
> >   
> >   /* Write a physical representation of tree node EXPR to output block
> > *************** DFS::DFS_write_tree_body (struct output_
> > *** 745,751 ****
> >   	;
> >         else
> >   	DFS_follow_tree_edge (DECL_NAME (expr));
> > !       DFS_follow_tree_edge (DECL_CONTEXT (expr));
> >       }
> >   
> >     if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
> > --- 766,776 ----
> >   	;
> >         else
> >   	DFS_follow_tree_edge (DECL_NAME (expr));
> > !       if (TREE_CODE (expr) != TRANSLATION_UNIT_DECL
> > ! 	  && ! DECL_CONTEXT (expr))
> > ! 	DFS_follow_tree_edge ((*all_translation_units)[0]);
> > !       else
> > ! 	DFS_follow_tree_edge (DECL_CONTEXT (expr));
> >       }
> >   
> >     if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
> > *************** DFS::DFS_write_tree_body (struct output_
> > *** 765,770 ****
> > --- 790,796 ----
> >   	 declarations which should be eliminated by decl merging. Be sure none
> >   	 leaks to this point.  */
> >         gcc_assert (DECL_ABSTRACT_ORIGIN (expr) != error_mark_node);
> > +       DFS_follow_tree_edge (DECL_ABSTRACT_ORIGIN (expr));
> >   
> >         if ((VAR_P (expr)
> >   	   || TREE_CODE (expr) == PARM_DECL)
> > *************** output_function (struct cgraph_node *nod
> > *** 2061,2066 ****
> > --- 2087,2103 ----
> >     stream_write_tree (ob, DECL_RESULT (function), true);
> >     streamer_write_chain (ob, DECL_ARGUMENTS (function), true);
> >   
> > +   /* Output debug args if available. */
> > +   vec<tree, va_gc> **debugargs = decl_debug_args_lookup (function);
> > +   if (! debugargs)
> > +     streamer_write_uhwi (ob, 0);
> > +   else
> > +     {
> > +       streamer_write_uhwi (ob, (*debugargs)->length ());
> > +       for (unsigned i = 0; i < (*debugargs)->length (); ++i)
> > + 	stream_write_tree (ob, (**debugargs)[i], true);
> > +     }
> > + 
> >     /* Output DECL_INITIAL for the function, which contains the tree of
> >        lexical scopes.  */
> >     stream_write_tree (ob, DECL_INITIAL (function), true);
> > Index: early-lto-debug/gcc/lto-streamer.h
> > ===================================================================
> > *** early-lto-debug.orig/gcc/lto-streamer.h	2017-05-16 13:10:47.554202813 +0200
> > --- early-lto-debug/gcc/lto-streamer.h	2017-05-16 13:10:49.858240736 +0200
> > *************** DEFINE_DECL_STREAM_FUNCS (TYPE_DECL, typ
> > *** 1212,1215 ****
> > --- 1212,1225 ----
> >   DEFINE_DECL_STREAM_FUNCS (NAMESPACE_DECL, namespace_decl)
> >   DEFINE_DECL_STREAM_FUNCS (LABEL_DECL, label_decl)
> >   
> > + /* Entry for the delayed registering of decl -> DIE references.  */
> > + struct dref_entry {
> > +     tree decl;
> > +     const char *sym;
> > +     unsigned HOST_WIDE_INT off;
> > + };
> > + 
> > + extern vec<dref_entry> dref_queue;
> > + 
> > + 
> >   #endif /* GCC_LTO_STREAMER_H  */
> > Index: early-lto-debug/gcc/lto-wrapper.c
> > ===================================================================
> > *** early-lto-debug.orig/gcc/lto-wrapper.c	2017-05-16 13:10:47.554202813 +0200
> > --- early-lto-debug/gcc/lto-wrapper.c	2017-05-16 13:10:49.858240736 +0200
> > *************** static char **output_names;
> > *** 70,75 ****
> > --- 70,76 ----
> >   static char **offload_names;
> >   static char *offload_objects_file_name;
> >   static char *makefile;
> > + static char *debug_obj;
> >   
> >   const char tool_name[] = "lto-wrapper";
> >   
> > *************** tool_cleanup (bool)
> > *** 88,93 ****
> > --- 89,96 ----
> >       maybe_unlink (offload_objects_file_name);
> >     if (makefile)
> >       maybe_unlink (makefile);
> > +   if (debug_obj)
> > +     maybe_unlink (debug_obj);
> >     for (i = 0; i < nr; ++i)
> >       {
> >         maybe_unlink (input_names[i]);
> > *************** find_and_merge_options (int fd, off_t fi
> > *** 938,943 ****
> > --- 941,1007 ----
> >     return true;
> >   }
> >   
> > + /* Copy early debug info sections from INFILE to a new file whose name
> > +    is returned.  Return NULL on error.  */
> > + 
> > + const char *
> > + debug_objcopy (const char *infile)
> > + {
> > +   const char *outfile;
> > +   const char *errmsg;
> > +   int err;
> > + 
> > +   const char *p;
> > +   off_t inoff = 0;
> > +   long loffset;
> > +   int consumed;
> > +   if ((p = strrchr (infile, '@'))
> > +       && p != infile
> > +       && sscanf (p, "@%li%n", &loffset, &consumed) >= 1
> > +       && strlen (p) == (unsigned int) consumed)
> > +     {
> > +       char *fname = xstrdup (infile);
> > +       fname[p - infile] = '\0';
> > +       infile = fname;
> > +       inoff = (off_t) loffset;
> > +     }
> > +   int infd = open (infile, O_RDONLY);
> > +   if (infd == -1)
> > +     return NULL;
> > +   simple_object_read *inobj = simple_object_start_read (infd, inoff,
> > + 							"__GNU_LTO",
> > + 							&errmsg, &err);
> > +   if (!inobj)
> > +     return NULL;
> > + 
> > +   off_t off, len;
> > +   if (simple_object_find_section (inobj, ".gnu.debuglto_.debug_info",
> > + 				  &off, &len, &errmsg, &err) != 1)
> > +     {
> > +       if (errmsg)
> > + 	fatal_error (0, "%s: %s\n", errmsg, xstrerror (err));
> > + 
> > +       simple_object_release_read (inobj);
> > +       close (infd);
> > +       return NULL;
> > +     }
> > + 
> > +   outfile = make_temp_file ("debugobjtem");
> > +   errmsg = simple_object_copy_lto_debug_sections (inobj, outfile, &err);
> > +   if (errmsg)
> > +     {
> > +       unlink_if_ordinary (outfile);
> > +       fatal_error (0, "%s: %s\n", errmsg, xstrerror (err));
> > +     }
> > + 
> > +   simple_object_release_read (inobj);
> > +   close (infd);
> > + 
> > +   return outfile;
> > + }
> > + 
> > + 
> > + 
> >   /* Execute gcc. ARGC is the number of arguments. ARGV contains the arguments. */
> >   
> >   static void
> > *************** run_gcc (unsigned argc, char *argv[])
> > *** 962,969 ****
> >     int new_head_argc;
> >     bool have_lto = false;
> >     bool have_offload = false;
> > !   unsigned lto_argc = 0;
> > !   char **lto_argv;
> >   
> >     /* Get the driver and options.  */
> >     collect_gcc = getenv ("COLLECT_GCC");
> > --- 1026,1035 ----
> >     int new_head_argc;
> >     bool have_lto = false;
> >     bool have_offload = false;
> > !   unsigned lto_argc = 0, ltoobj_argc = 0;
> > !   char **lto_argv, **ltoobj_argv;
> > !   bool skip_debug = false;
> > !   unsigned n_debugobj;
> >   
> >     /* Get the driver and options.  */
> >     collect_gcc = getenv ("COLLECT_GCC");
> > *************** run_gcc (unsigned argc, char *argv[])
> > *** 982,987 ****
> > --- 1048,1054 ----
> >     /* Allocate array for input object files with LTO IL,
> >        and for possible preceding arguments.  */
> >     lto_argv = XNEWVEC (char *, argc);
> > +   ltoobj_argv = XNEWVEC (char *, argc);
> >   
> >     /* Look at saved options in the IL files.  */
> >     for (i = 1; i < argc; ++i)
> > *************** run_gcc (unsigned argc, char *argv[])
> > *** 1024,1030 ****
> >   				  collect_gcc))
> >   	{
> >   	  have_lto = true;
> > ! 	  lto_argv[lto_argc++] = argv[i];
> >   	}
> >         close (fd);
> >       }
> > --- 1091,1097 ----
> >   				  collect_gcc))
> >   	{
> >   	  have_lto = true;
> > ! 	  ltoobj_argv[ltoobj_argc++] = argv[i];
> >   	}
> >         close (fd);
> >       }
> > *************** run_gcc (unsigned argc, char *argv[])
> > *** 1085,1090 ****
> > --- 1152,1168 ----
> >   	}
> >       }
> >   
> > +   /* Output lto-wrapper invocation command.  */
> > +   if (verbose)
> > +     {
> > +       for (i = 0; i < argc; ++i)
> > + 	{
> > + 	  fputs (argv[i], stderr);
> > + 	  fputc (' ', stderr);
> > + 	}
> > +       fputc ('\n', stderr);
> > +     }
> > + 
> >     if (no_partition)
> >       {
> >         lto_mode = LTO_MODE_LTO;
> > *************** cont1:
> > *** 1274,1291 ****
> >           obstack_ptr_grow (&argv_obstack, "-fwpa");
> >       }
> >   
> > !   /* Append the input objects and possible preceding arguments.  */
> >     for (i = 0; i < lto_argc; ++i)
> >       obstack_ptr_grow (&argv_obstack, lto_argv[i]);
> >     obstack_ptr_grow (&argv_obstack, NULL);
> >   
> >     new_argv = XOBFINISH (&argv_obstack, const char **);
> >     argv_ptr = &new_argv[new_head_argc];
> >     fork_execute (new_argv[0], CONST_CAST (char **, new_argv), true);
> >   
> >     if (lto_mode == LTO_MODE_LTO)
> >       {
> >         printf ("%s\n", flto_out);
> >         free (flto_out);
> >         flto_out = NULL;
> >       }
> > --- 1352,1456 ----
> >           obstack_ptr_grow (&argv_obstack, "-fwpa");
> >       }
> >   
> > !   /* Append input arguments.  */
> >     for (i = 0; i < lto_argc; ++i)
> >       obstack_ptr_grow (&argv_obstack, lto_argv[i]);
> > +   /* Append the input objects.  */
> > +   for (i = 0; i < ltoobj_argc; ++i)
> > +     obstack_ptr_grow (&argv_obstack, ltoobj_argv[i]);
> >     obstack_ptr_grow (&argv_obstack, NULL);
> >   
> >     new_argv = XOBFINISH (&argv_obstack, const char **);
> >     argv_ptr = &new_argv[new_head_argc];
> >     fork_execute (new_argv[0], CONST_CAST (char **, new_argv), true);
> >   
> > +   /* Handle early generated debug information.  At compile-time
> > +      we output early DWARF debug info into .gnu.debuglto_ prefixed
> > +      sections.  LTRANS object DWARF debug info refers to that.
> > +      So we need to transfer the .gnu.debuglto_ sections to the final
> > +      link.  Ideally the linker plugin interface would allow us to
> > +      not claim those sections and instruct the linker to keep
> > +      them, renaming them in the process.  For now we extract and
> > +      rename those sections via a simple-object interface to produce
> > +      regular objects containing only the early debug info.  We
> > +      then partially link those to a single early debug info object
> > +      and pass that as additional output back to the linker plugin.  */
> > + 
> > +   /* Prepare the partial link to gather the compile-time generated
> > +      debug-info into a single input for the final link.  */
> > +   debug_obj = make_temp_file ("debugobj");
> > +   obstack_ptr_grow (&argv_obstack, collect_gcc);
> > +   for (i = 1; i < decoded_options_count; ++i)
> > +     {
> > +       /* Retain linker choice and -B.  */
> > +       if (decoded_options[i].opt_index == OPT_B
> > + 	  || decoded_options[i].opt_index == OPT_fuse_ld_bfd
> > + 	  || decoded_options[i].opt_index == OPT_fuse_ld_gold)
> > + 	append_linker_options (&argv_obstack, &decoded_options[i-1], 2);
> > +       /* Retain all target options, this preserves -m32 for example.  */
> > +       if (cl_options[decoded_options[i].opt_index].flags & CL_TARGET)
> > + 	append_linker_options (&argv_obstack, &decoded_options[i-1], 2);
> > +       /* Recognize -g0.  */
> > +       if (decoded_options[i].opt_index == OPT_g
> > + 	  && strcmp (decoded_options[i].arg, "0") == 0)
> > + 	skip_debug = true;
> > +     }
> > +   obstack_ptr_grow (&argv_obstack, "-r");
> > +   obstack_ptr_grow (&argv_obstack, "-nostdlib");
> > +   obstack_ptr_grow (&argv_obstack, "-o");
> > +   obstack_ptr_grow (&argv_obstack, debug_obj);
> > + 
> > +   /* Copy the early generated debug info from the objects to temporary
> > +      files and append those to the partial link commandline.  */
> > +   n_debugobj = 0;
> > +   if (! skip_debug)
> > +     for (i = 0; i < ltoobj_argc; ++i)
> > +       {
> > + 	const char *tem;
> > + 	if ((tem = debug_objcopy (ltoobj_argv[i])))
> > + 	  {
> > + 	    obstack_ptr_grow (&argv_obstack, tem);
> > + 	    n_debugobj++;
> > + 	  }
> > +       }
> > + 
> > +   /* Link them all into a single object.  Ideally this would reduce
> > +      disk space usage mainly due to .debug_str merging but unfortunately
> > +      GNU ld doesn't perform this with -r.  */
> > +   if (n_debugobj)
> > +     {
> > +       obstack_ptr_grow (&argv_obstack, NULL);
> > +       const char **debug_link_argv = XOBFINISH (&argv_obstack, const char **);
> > +       fork_execute (debug_link_argv[0],
> > + 		    CONST_CAST (char **, debug_link_argv), false);
> > + 
> > +       /* And dispose the temporaries.  */
> > +       for (i = 0; debug_link_argv[i]; ++i)
> > + 	;
> > +       for (--i; i > 0; --i)
> > + 	{
> > + 	  if (strcmp (debug_link_argv[i], debug_obj) == 0)
> > + 	    break;
> > + 	  maybe_unlink (debug_link_argv[i]);
> > + 	}
> > +     }
> > +   else
> > +     {
> > +       unlink_if_ordinary (debug_obj);
> > +       free (debug_obj);
> > +       debug_obj = NULL;
> > +       skip_debug = true;
> > +     }
> > + 
> >     if (lto_mode == LTO_MODE_LTO)
> >       {
> >         printf ("%s\n", flto_out);
> > +       if (!skip_debug)
> > + 	{
> > + 	  printf ("%s\n", debug_obj);
> > + 	  free (debug_obj);
> > + 	  debug_obj = NULL;
> > + 	}
> >         free (flto_out);
> >         flto_out = NULL;
> >       }
> > *************** cont:
> > *** 1434,1439 ****
> > --- 1599,1610 ----
> >   	  for (i = 0; i < nr; ++i)
> >   	    maybe_unlink (input_names[i]);
> >   	}
> > +       if (!skip_debug)
> > + 	{
> > + 	  printf ("%s\n", debug_obj);
> > + 	  free (debug_obj);
> > + 	  debug_obj = NULL;
> > + 	}
> >         for (i = 0; i < nr; ++i)
> >   	{
> >   	  fputs (output_names[i], stdout);
> > Index: early-lto-debug/gcc/tree-streamer-in.c
> > ===================================================================
> > *** early-lto-debug.orig/gcc/tree-streamer-in.c	2017-05-16 13:10:47.554202813 +0200
> > --- early-lto-debug/gcc/tree-streamer-in.c	2017-05-16 13:10:49.862240801 +0200
> > *************** lto_input_ts_decl_common_tree_pointers (
> > *** 688,697 ****
> >     DECL_SIZE (expr) = stream_read_tree (ib, data_in);
> >     DECL_SIZE_UNIT (expr) = stream_read_tree (ib, data_in);
> >     DECL_ATTRIBUTES (expr) = stream_read_tree (ib, data_in);
> > ! 
> > !   /* Do not stream DECL_ABSTRACT_ORIGIN.  We cannot handle debug information
> > !      for early inlining so drop it on the floor instead of ICEing in
> > !      dwarf2out.c.  */
> >   
> >     if ((VAR_P (expr) || TREE_CODE (expr) == PARM_DECL)
> >         && DECL_HAS_VALUE_EXPR_P (expr))
> > --- 688,694 ----
> >     DECL_SIZE (expr) = stream_read_tree (ib, data_in);
> >     DECL_SIZE_UNIT (expr) = stream_read_tree (ib, data_in);
> >     DECL_ATTRIBUTES (expr) = stream_read_tree (ib, data_in);
> > !   DECL_ABSTRACT_ORIGIN (expr) = stream_read_tree (ib, data_in);
> >   
> >     if ((VAR_P (expr) || TREE_CODE (expr) == PARM_DECL)
> >         && DECL_HAS_VALUE_EXPR_P (expr))
> > Index: early-lto-debug/gcc/tree-streamer-out.c
> > ===================================================================
> > *** early-lto-debug.orig/gcc/tree-streamer-out.c	2017-05-16 13:10:47.554202813 +0200
> > --- early-lto-debug/gcc/tree-streamer-out.c	2017-05-16 13:10:49.862240801 +0200
> > *************** write_ts_decl_minimal_tree_pointers (str
> > *** 566,572 ****
> >       stream_write_tree (ob, NULL_TREE, ref_p);
> >     else
> >       stream_write_tree (ob, DECL_NAME (expr), ref_p);
> > !   stream_write_tree (ob, DECL_CONTEXT (expr), ref_p);
> >   }
> >   
> >   
> > --- 566,576 ----
> >       stream_write_tree (ob, NULL_TREE, ref_p);
> >     else
> >       stream_write_tree (ob, DECL_NAME (expr), ref_p);
> > !   if (TREE_CODE (expr) != TRANSLATION_UNIT_DECL
> > !       && ! DECL_CONTEXT (expr))
> > !     stream_write_tree (ob, (*all_translation_units)[0], ref_p);
> > !   else
> > !     stream_write_tree (ob, DECL_CONTEXT (expr), ref_p);
> >   }
> >   
> >   
> > *************** write_ts_decl_common_tree_pointers (stru
> > *** 585,594 ****
> >        special handling in LTO, it must be handled by streamer hooks.  */
> >   
> >     stream_write_tree (ob, DECL_ATTRIBUTES (expr), ref_p);
> > ! 
> > !   /* Do not stream DECL_ABSTRACT_ORIGIN.  We cannot handle debug information
> > !      for early inlining so drop it on the floor instead of ICEing in
> > !      dwarf2out.c.  */
> >   
> >     if ((VAR_P (expr) || TREE_CODE (expr) == PARM_DECL)
> >         && DECL_HAS_VALUE_EXPR_P (expr))
> > --- 589,595 ----
> >        special handling in LTO, it must be handled by streamer hooks.  */
> >   
> >     stream_write_tree (ob, DECL_ATTRIBUTES (expr), ref_p);
> > !   stream_write_tree (ob, DECL_ABSTRACT_ORIGIN (expr), ref_p);
> >   
> >     if ((VAR_P (expr) || TREE_CODE (expr) == PARM_DECL)
> >         && DECL_HAS_VALUE_EXPR_P (expr))
> > Index: early-lto-debug/gcc/config/darwin.c
> > ===================================================================
> > *** early-lto-debug.orig/gcc/config/darwin.c	2017-05-16 13:10:47.554202813 +0200
> > --- early-lto-debug/gcc/config/darwin.c	2017-05-16 13:10:49.862240801 +0200
> > *************** darwin_asm_lto_end (void)
> > *** 1959,1965 ****
> >   }
> >   
> >   static void
> > ! darwin_asm_dwarf_section (const char *name, unsigned int flags, tree decl);
> >   
> >   /*  Called for the TARGET_ASM_NAMED_SECTION hook.  */
> >   
> > --- 1959,1966 ----
> >   }
> >   
> >   static void
> > ! darwin_asm_dwarf_section (const char *name, unsigned int flags,
> > ! 			  tree decl, bool is_for_lto);
> >   
> >   /*  Called for the TARGET_ASM_NAMED_SECTION hook.  */
> >   
> > *************** darwin_asm_named_section (const char *na
> > *** 2001,2007 ****
> >         vec_safe_push (lto_section_names, e);
> >      }
> >     else if (strncmp (name, "__DWARF,", 8) == 0)
> > !     darwin_asm_dwarf_section (name, flags, decl);
> >     else
> >       fprintf (asm_out_file, "\t.section %s\n", name);
> >   }
> > --- 2002,2010 ----
> >         vec_safe_push (lto_section_names, e);
> >      }
> >     else if (strncmp (name, "__DWARF,", 8) == 0)
> > !     darwin_asm_dwarf_section (name, flags, decl, false);
> > !   else if (strncmp (name, "__GNU_DWARF_LTO,", 16) == 0)
> > !     darwin_asm_dwarf_section (name, flags, decl, true);
> >     else
> >       fprintf (asm_out_file, "\t.section %s\n", name);
> >   }
> > *************** static GTY (()) vec<dwarf_sect_used_entr
> > *** 2783,2801 ****
> >   
> >   static void
> >   darwin_asm_dwarf_section (const char *name, unsigned int flags,
> > ! 			  tree ARG_UNUSED (decl))
> >   {
> >     unsigned i;
> > !   int namelen;
> > !   const char * sname;
> >     dwarf_sect_used_entry *ref;
> >     bool found = false;
> > !   gcc_assert ((flags & (SECTION_DEBUG | SECTION_NAMED))
> > ! 		    == (SECTION_DEBUG | SECTION_NAMED));
> > !   /* We know that the name starts with __DWARF,  */
> > !   sname = name + 8;
> > !   namelen = strchr (sname, ',') - sname;
> > !   gcc_assert (namelen);
> >     if (dwarf_sect_names_table == NULL)
> >       vec_alloc (dwarf_sect_names_table, 16);
> >     else
> > --- 2786,2822 ----
> >   
> >   static void
> >   darwin_asm_dwarf_section (const char *name, unsigned int flags,
> > ! 			  tree ARG_UNUSED (decl), bool is_for_lto)
> >   {
> >     unsigned i;
> > !   int namelen, extra = 0;
> > !   const char *sect, *lto_add = "";
> > !   char sname[64];
> >     dwarf_sect_used_entry *ref;
> >     bool found = false;
> > ! 
> > !   gcc_checking_assert ((flags & (SECTION_DEBUG | SECTION_NAMED))
> > ! 			== (SECTION_DEBUG | SECTION_NAMED));
> > ! 
> > !   /* We know that the name starts with __DWARF, or __GNU_DAWRF_LTO  */
> > !   sect = strchr (name, ',') + 1;
> > !   namelen = strchr (sect, ',') - sect;
> > !   gcc_checking_assert (namelen);
> > ! 
> > !   /* The section switch is output as written...  */
> > !   fprintf (asm_out_file, "\t.section %s\n", name);
> > ! 
> > !   /* ... but the string we keep to make section start labels needs
> > !      adjustment for lto cases.  */
> > !   if (is_for_lto)
> > !     {
> > !       lto_add = "_lto";
> > !       extra = 4;
> > !     }
> > ! 
> > !   snprintf (sname, 64, "%.*s%.*s", namelen, sect, extra, lto_add);
> > !   namelen += extra;
> > ! 
> >     if (dwarf_sect_names_table == NULL)
> >       vec_alloc (dwarf_sect_names_table, 16);
> >     else
> > *************** darwin_asm_dwarf_section (const char *na
> > *** 2813,2819 ****
> >   	  }
> >         }
> >   
> > -   fprintf (asm_out_file, "\t.section %s\n", name);
> >     if (!found)
> >       {
> >         dwarf_sect_used_entry e;
> > --- 2834,2839 ----
> > *************** darwin_asm_output_dwarf_offset (FILE *fi
> > *** 2866,2879 ****
> >   				HOST_WIDE_INT offset, section *base)
> >   {
> >     char sname[64];
> > !   int namelen;
> >   
> > !   gcc_assert (base->common.flags & SECTION_NAMED);
> > !   gcc_assert (strncmp (base->named.name, "__DWARF,", 8) == 0);
> > !   gcc_assert (strchr (base->named.name + 8, ','));
> > ! 
> > !   namelen = strchr (base->named.name + 8, ',') - (base->named.name + 8);
> > !   sprintf (sname, "*Lsection%.*s", namelen, base->named.name + 8);
> >     darwin_asm_output_dwarf_delta (file, size, lab, sname, offset);
> >   }
> >   
> > --- 2886,2909 ----
> >   				HOST_WIDE_INT offset, section *base)
> >   {
> >     char sname[64];
> > !   int namelen, extra = 0;
> > !   bool is_for_lto;
> > !   const char *lto_add = "";
> > ! 
> > !   gcc_checking_assert (base->common.flags & SECTION_NAMED);
> > !   is_for_lto = strncmp (base->named.name, "__GNU_DWARF_LTO,", 16) == 0;
> > !   gcc_checking_assert (is_for_lto
> > ! 		       || strncmp (base->named.name, "__DWARF,", 8) == 0);
> > !   const char *name = strchr (base->named.name, ',') + 1;
> > !   gcc_checking_assert (name);
> >   
> > !   namelen = strchr (name, ',') - (name);
> > !   if (is_for_lto)
> > !     {
> > !       lto_add = "_lto";
> > !       extra = 4;
> > !     }
> > !   snprintf (sname, 64, "*Lsection%.*s%.*s", namelen, name, extra, lto_add);
> >     darwin_asm_output_dwarf_delta (file, size, lab, sname, offset);
> >   }
> >   
> > Index: early-lto-debug/gcc/config/darwin.h
> > ===================================================================
> > *** early-lto-debug.orig/gcc/config/darwin.h	2017-05-16 13:10:47.554202813 +0200
> > --- early-lto-debug/gcc/config/darwin.h	2017-05-16 13:10:49.866240867 +0200
> > *************** extern GTY(()) int darwin_ms_struct;
> > *** 445,451 ****
> >   #define DEBUG_PUBTYPES_SECTION	"__DWARF,__debug_pubtypes,regular,debug"
> >   #define DEBUG_STR_SECTION	"__DWARF,__debug_str,regular,debug"
> >   #define DEBUG_RANGES_SECTION	"__DWARF,__debug_ranges,regular,debug"
> > ! #define DEBUG_MACRO_SECTION    "__DWARF,__debug_macro,regular,debug"
> >   
> >   #define TARGET_WANT_DEBUG_PUB_SECTIONS true
> >   
> > --- 445,458 ----
> >   #define DEBUG_PUBTYPES_SECTION	"__DWARF,__debug_pubtypes,regular,debug"
> >   #define DEBUG_STR_SECTION	"__DWARF,__debug_str,regular,debug"
> >   #define DEBUG_RANGES_SECTION	"__DWARF,__debug_ranges,regular,debug"
> > ! #define DEBUG_MACRO_SECTION     "__DWARF,__debug_macro,regular,debug"
> > ! 
> > ! #define DEBUG_LTO_INFO_SECTION	  "__GNU_DWARF_LTO,__debug_info,regular,debug"
> > ! #define DEBUG_LTO_ABBREV_SECTION  "__GNU_DWARF_LTO,__debug_abbrev,regular,debug"
> > ! #define DEBUG_LTO_MACINFO_SECTION "__GNU_DWARF_LTO,__debug_macinfo,regular,debug"
> > ! #define DEBUG_LTO_LINE_SECTION	  "__GNU_DWARF_LTO,__debug_line,regular,debug"
> > ! #define DEBUG_LTO_STR_SECTION	  "__GNU_DWARF_LTO,__debug_str,regular,debug"
> > ! #define DEBUG_LTO_MACRO_SECTION   "__GNU_DWARF_LTO,__debug_macro,regular,debug"
> >   
> >   #define TARGET_WANT_DEBUG_PUB_SECTIONS true
> >   
> > Index: early-lto-debug/gcc/vmsdbgout.c
> > ===================================================================
> > *** early-lto-debug.orig/gcc/vmsdbgout.c	2017-05-16 13:10:47.554202813 +0200
> > --- early-lto-debug/gcc/vmsdbgout.c	2017-05-16 13:10:49.866240867 +0200
> > *************** const struct gcc_debug_hooks vmsdbg_debu
> > *** 198,203 ****
> > --- 198,205 ----
> >      vmsdbgout_late_global_decl,
> >      vmsdbgout_type_decl,		  /* type_decl */
> >      debug_nothing_tree_tree_tree_bool, /* imported_module_or_decl */
> > +    debug_false_tree_charstarstar_uhwistar, /* die_ref_for_decl */
> > +    debug_nothing_tree_charstar_uhwi, /* register_external_die */
> >      debug_nothing_tree,		  /* deferred_inline_function */
> >      vmsdbgout_abstract_function,
> >      debug_nothing_rtx_code_label,  /* label */
> > Index: early-lto-debug/gcc/tree.c
> > ===================================================================
> > *** early-lto-debug.orig/gcc/tree.c	2017-05-16 13:10:47.554202813 +0200
> > --- early-lto-debug/gcc/tree.c	2017-05-16 13:10:49.870240933 +0200
> > *************** free_lang_data (void)
> > *** 5974,5979 ****
> > --- 5974,5983 ----
> >         || (!flag_generate_lto && !flag_generate_offload))
> >       return 0;
> >   
> > +   /* Provide a dummy TRANSLATION_UNIT_DECL if the FE failed to provide one.  */
> > +   if (vec_safe_is_empty (all_translation_units))
> > +     build_translation_unit_decl (NULL_TREE);
> > + 
> >     /* Allocate and assign alias sets to the standard integer types
> >        while the slots are still in the way the frontends generated them.  */
> >     for (i = 0; i < itk_none; ++i)
> > Index: early-lto-debug/gcc/testsuite/c-c++-common/asan/global-overflow-1.c
> > ===================================================================
> > *** early-lto-debug.orig/gcc/testsuite/c-c++-common/asan/global-overflow-1.c	2017-05-16 13:10:47.554202813 +0200
> > --- early-lto-debug/gcc/testsuite/c-c++-common/asan/global-overflow-1.c	2017-05-16 13:10:49.870240933 +0200
> > *************** int main() {
> > *** 23,28 ****
> >   }
> >   
> >   /* { dg-output "READ of size 1 at 0x\[0-9a-f\]+ thread T0.*(\n|\r\n|\r)" } */
> > ! /* { dg-output "    #0 0x\[0-9a-f\]+ +(in _*main (\[^\n\r]*global-overflow-1.c:20|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r).*" } */
> >   /* { dg-output "0x\[0-9a-f\]+ is located 0 bytes to the right of global variable" } */
> >   /* { dg-output ".*YYY\[^\n\r]* of size 10\[^\n\r]*(\n|\r\n|\r)" } */
> > --- 23,28 ----
> >   }
> >   
> >   /* { dg-output "READ of size 1 at 0x\[0-9a-f\]+ thread T0.*(\n|\r\n|\r)" } */
> > ! /* { dg-output "    #0 0x\[0-9a-f\]+ +(in _*main (\[^\n\r]*global-overflow-1.c:20|\[^\n\r]*:0|\[^\n\r]*\\+0x\[0-9a-z\]*)|\[(\])\[^\n\r]*(\n|\r\n|\r).*" } */
> >   /* { dg-output "0x\[0-9a-f\]+ is located 0 bytes to the right of global variable" } */
> >   /* { dg-output ".*YYY\[^\n\r]* of size 10\[^\n\r]*(\n|\r\n|\r)" } */
> > Index: early-lto-debug/gcc/testsuite/c-c++-common/asan/heap-overflow-1.c
> > ===================================================================
> > *** early-lto-debug.orig/gcc/testsuite/c-c++-common/asan/heap-overflow-1.c	2017-05-16 13:10:47.554202813 +0200
> > --- early-lto-debug/gcc/testsuite/c-c++-common/asan/heap-overflow-1.c	2017-05-16 13:10:49.870240933 +0200
> > *************** int main(int argc, char **argv) {
> > *** 24,31 ****
> >   }
> >   
> >   /* { dg-output "READ of size 1 at 0x\[0-9a-f\]+ thread T0.*(\n|\r\n|\r)" } */
> > ! /* { dg-output "    #0 0x\[0-9a-f\]+ +(in _*main (\[^\n\r]*heap-overflow-1.c:21|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */
> >   /* { dg-output "\[^\n\r]*0x\[0-9a-f\]+ is located 0 bytes to the right of 10-byte region\[^\n\r]*(\n|\r\n|\r)" } */
> >   /* { dg-output "\[^\n\r]*allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */
> >   /* { dg-output "    #0 0x\[0-9a-f\]+ +(in _*(interceptor_|wrap_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
> > ! /* { dg-output "    #1 0x\[0-9a-f\]+ +(in _*main (\[^\n\r]*heap-overflow-1.c:19|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
> > --- 24,31 ----
> >   }
> >   
> >   /* { dg-output "READ of size 1 at 0x\[0-9a-f\]+ thread T0.*(\n|\r\n|\r)" } */
> > ! /* { dg-output "    #0 0x\[0-9a-f\]+ +(in _*main (\[^\n\r]*heap-overflow-1.c:21|\[^\n\r]*:0|\[^\n\r]*\\+0x\[0-9a-z\]*)|\[(\]).*(\n|\r\n|\r)" } */
> >   /* { dg-output "\[^\n\r]*0x\[0-9a-f\]+ is located 0 bytes to the right of 10-byte region\[^\n\r]*(\n|\r\n|\r)" } */
> >   /* { dg-output "\[^\n\r]*allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */
> >   /* { dg-output "    #0 0x\[0-9a-f\]+ +(in _*(interceptor_|wrap_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
> > ! /* { dg-output "    #1 0x\[0-9a-f\]+ +(in _*main (\[^\n\r]*heap-overflow-1.c:19|\[^\n\r]*:0|\[^\n\r]*\\+0x\[0-9a-z\]*)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
> > Index: early-lto-debug/gcc/testsuite/c-c++-common/asan/misalign-1.c
> > ===================================================================
> > *** early-lto-debug.orig/gcc/testsuite/c-c++-common/asan/misalign-1.c	2017-05-16 13:10:47.554202813 +0200
> > --- early-lto-debug/gcc/testsuite/c-c++-common/asan/misalign-1.c	2017-05-16 13:10:49.870240933 +0200
> > *************** main ()
> > *** 39,43 ****
> >   /* { dg-output "ERROR: AddressSanitizer:\[^\n\r]*on address\[^\n\r]*" } */
> >   /* { dg-output "0x\[0-9a-f\]+ at pc 0x\[0-9a-f\]+ bp 0x\[0-9a-f\]+ sp 0x\[0-9a-f\]+\[^\n\r]*(\n|\r\n|\r)" } */
> >   /* { dg-output "\[^\n\r]*READ of size 4 at 0x\[0-9a-f\]+ thread T0\[^\n\r]*(\n|\r\n|\r)" } */
> > ! /* { dg-output "    #0 0x\[0-9a-f\]+ +(in _*foo(\[^\n\r]*misalign-1.c:1\[01]|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
> > ! /* { dg-output "    #1 0x\[0-9a-f\]+ +(in _*main (\[^\n\r]*misalign-1.c:3\[45]|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */
> > --- 39,43 ----
> >   /* { dg-output "ERROR: AddressSanitizer:\[^\n\r]*on address\[^\n\r]*" } */
> >   /* { dg-output "0x\[0-9a-f\]+ at pc 0x\[0-9a-f\]+ bp 0x\[0-9a-f\]+ sp 0x\[0-9a-f\]+\[^\n\r]*(\n|\r\n|\r)" } */
> >   /* { dg-output "\[^\n\r]*READ of size 4 at 0x\[0-9a-f\]+ thread T0\[^\n\r]*(\n|\r\n|\r)" } */
> > ! /* { dg-output "    #0 0x\[0-9a-f\]+ +(in _*foo(\[^\n\r]*misalign-1.c:1\[01]|\[^\n\r]*:0|\[^\n\r]*\\+0x\[0-9a-z\]*)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
> > ! /* { dg-output "    #1 0x\[0-9a-f\]+ +(in _*main (\[^\n\r]*misalign-1.c:3\[45]|\[^\n\r]*:0|\[^\n\r]*\\+0x\[0-9a-z\]*)|\[(\]).*(\n|\r\n|\r)" } */
> > Index: early-lto-debug/gcc/testsuite/c-c++-common/asan/misalign-2.c
> > ===================================================================
> > *** early-lto-debug.orig/gcc/testsuite/c-c++-common/asan/misalign-2.c	2017-05-16 13:10:47.554202813 +0200
> > --- early-lto-debug/gcc/testsuite/c-c++-common/asan/misalign-2.c	2017-05-16 13:10:49.870240933 +0200
> > *************** main ()
> > *** 39,43 ****
> >   /* { dg-output "ERROR: AddressSanitizer:\[^\n\r]*on address\[^\n\r]*" } */
> >   /* { dg-output "0x\[0-9a-f\]+ at pc 0x\[0-9a-f\]+ bp 0x\[0-9a-f\]+ sp 0x\[0-9a-f\]+\[^\n\r]*(\n|\r\n|\r)" } */
> >   /* { dg-output "\[^\n\r]*READ of size 4 at 0x\[0-9a-f\]+ thread T0\[^\n\r]*(\n|\r\n|\r)" } */
> > ! /* { dg-output "    #0 0x\[0-9a-f\]+ +(in _*baz(\[^\n\r]*misalign-2.c:2\[23]|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
> > ! /* { dg-output "    #1 0x\[0-9a-f\]+ +(in _*main (\[^\n\r]*misalign-2.c:3\[45]|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */
> > --- 39,43 ----
> >   /* { dg-output "ERROR: AddressSanitizer:\[^\n\r]*on address\[^\n\r]*" } */
> >   /* { dg-output "0x\[0-9a-f\]+ at pc 0x\[0-9a-f\]+ bp 0x\[0-9a-f\]+ sp 0x\[0-9a-f\]+\[^\n\r]*(\n|\r\n|\r)" } */
> >   /* { dg-output "\[^\n\r]*READ of size 4 at 0x\[0-9a-f\]+ thread T0\[^\n\r]*(\n|\r\n|\r)" } */
> > ! /* { dg-output "    #0 0x\[0-9a-f\]+ +(in _*baz(\[^\n\r]*misalign-2.c:2\[23]|\[^\n\r]*:0|\[^\n\r]*\\+0x\[0-9a-z\]*)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
> > ! /* { dg-output "    #1 0x\[0-9a-f\]+ +(in _*main (\[^\n\r]*misalign-2.c:3\[45]|\[^\n\r]*:0|\[^\n\r]*\\+0x\[0-9a-z\]*)|\[(\]).*(\n|\r\n|\r)" } */
> > Index: early-lto-debug/gcc/testsuite/c-c++-common/asan/null-deref-1.c
> > ===================================================================
> > *** early-lto-debug.orig/gcc/testsuite/c-c++-common/asan/null-deref-1.c	2017-05-16 13:10:47.554202813 +0200
> > --- early-lto-debug/gcc/testsuite/c-c++-common/asan/null-deref-1.c	2017-05-16 13:10:49.870240933 +0200
> > *************** int main()
> > *** 18,22 ****
> >   
> >   /* { dg-output "ERROR: AddressSanitizer:? SEGV on unknown address\[^\n\r]*" } */
> >   /* { dg-output "0x\[0-9a-f\]+ \[^\n\r]*pc 0x\[0-9a-f\]+.*(\n|\r\n|\r)" } */
> > ! /* { dg-output "    #0 0x\[0-9a-f\]+ +(in \[^\n\r]*NullDeref\[^\n\r]* (\[^\n\r]*null-deref-1.c:10|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
> > ! /* { dg-output "    #1 0x\[0-9a-f\]+ +(in _*main (\[^\n\r]*null-deref-1.c:15|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
> > --- 18,22 ----
> >   
> >   /* { dg-output "ERROR: AddressSanitizer:? SEGV on unknown address\[^\n\r]*" } */
> >   /* { dg-output "0x\[0-9a-f\]+ \[^\n\r]*pc 0x\[0-9a-f\]+.*(\n|\r\n|\r)" } */
> > ! /* { dg-output "    #0 0x\[0-9a-f\]+ +(in \[^\n\r]*NullDeref\[^\n\r]* (\[^\n\r]*null-deref-1.c:10|\[^\n\r]*:0|\[^\n\r]*\\+0x\[0-9a-z\]*)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
> > ! /* { dg-output "    #1 0x\[0-9a-f\]+ +(in _*main (\[^\n\r]*null-deref-1.c:15|\[^\n\r]*:0|\[^\n\r]*\\+0x\[0-9a-z\]*)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
> > Index: early-lto-debug/gcc/testsuite/c-c++-common/asan/stack-overflow-1.c
> > ===================================================================
> > *** early-lto-debug.orig/gcc/testsuite/c-c++-common/asan/stack-overflow-1.c	2017-05-16 13:10:47.554202813 +0200
> > --- early-lto-debug/gcc/testsuite/c-c++-common/asan/stack-overflow-1.c	2017-05-16 13:10:49.874240999 +0200
> > *************** int main() {
> > *** 18,23 ****
> >   }
> >   
> >   /* { dg-output "READ of size 1 at 0x\[0-9a-f\]+ thread T0\[^\n\r]*(\n|\r\n|\r)" } */
> > ! /* { dg-output "    #0 0x\[0-9a-f\]+ +(in _*main (\[^\n\r]*stack-overflow-1.c:16|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */
> >   /* { dg-output "\[^\n\r]*Address 0x\[0-9a-f\]+ is located in stack of thread T0.*(\n|\r\n|\r)" */
> >   /* { dg-output "\[^\n\r]*in main.*stack-overflow-1.c.*(\n|\r\n|\r)" */
> > --- 18,23 ----
> >   }
> >   
> >   /* { dg-output "READ of size 1 at 0x\[0-9a-f\]+ thread T0\[^\n\r]*(\n|\r\n|\r)" } */
> > ! /* { dg-output "    #0 0x\[0-9a-f\]+ +(in _*main (\[^\n\r]*stack-overflow-1.c:16|\[^\n\r]*:0|\[^\n\r]*\\+0x\[0-9a-z\]*)|\[(\]).*(\n|\r\n|\r)" } */
> >   /* { dg-output "\[^\n\r]*Address 0x\[0-9a-f\]+ is located in stack of thread T0.*(\n|\r\n|\r)" */
> >   /* { dg-output "\[^\n\r]*in main.*stack-overflow-1.c.*(\n|\r\n|\r)" */
> > Index: early-lto-debug/gcc/testsuite/c-c++-common/asan/strncpy-overflow-1.c
> > ===================================================================
> > *** early-lto-debug.orig/gcc/testsuite/c-c++-common/asan/strncpy-overflow-1.c	2017-05-16 13:10:47.554202813 +0200
> > --- early-lto-debug/gcc/testsuite/c-c++-common/asan/strncpy-overflow-1.c	2017-05-16 13:10:49.874240999 +0200
> > *************** int main(int argc, char **argv) {
> > *** 14,21 ****
> >   
> >   /* { dg-output "WRITE of size \[0-9\]* at 0x\[0-9a-f\]+ thread T0\[^\n\r]*(\n|\r\n|\r)" } */
> >   /* { dg-output "    #0 0x\[0-9a-f\]+ +(in _*(interceptor_|wrap_|)strncpy|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
> > ! /* { dg-output "    #1 0x\[0-9a-f\]+ +(in _*main (\[^\n\r]*strncpy-overflow-1.c:11|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */
> >   /* { dg-output "\[^\n\r]*0x\[0-9a-f\]+ is located 0 bytes to the right of 9-byte region\[^\n\r]*(\n|\r\n|\r)" } */
> >   /* { dg-output "\[^\n\r]*allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */
> >   /* { dg-output "    #0 0x\[0-9a-f\]+ +(in _*(interceptor_|wrap_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
> > ! /* { dg-output "    #1 0x\[0-9a-f\]+ +(in _*main (\[^\n\r]*strncpy-overflow-1.c:10|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
> > --- 14,21 ----
> >   
> >   /* { dg-output "WRITE of size \[0-9\]* at 0x\[0-9a-f\]+ thread T0\[^\n\r]*(\n|\r\n|\r)" } */
> >   /* { dg-output "    #0 0x\[0-9a-f\]+ +(in _*(interceptor_|wrap_|)strncpy|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
> > ! /* { dg-output "    #1 0x\[0-9a-f\]+ +(in _*main (\[^\n\r]*strncpy-overflow-1.c:11|\[^\n\r]*:0|\[^\n\r]*\\+0x\[0-9a-z\]*)|\[(\]).*(\n|\r\n|\r)" } */
> >   /* { dg-output "\[^\n\r]*0x\[0-9a-f\]+ is located 0 bytes to the right of 9-byte region\[^\n\r]*(\n|\r\n|\r)" } */
> >   /* { dg-output "\[^\n\r]*allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */
> >   /* { dg-output "    #0 0x\[0-9a-f\]+ +(in _*(interceptor_|wrap_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
> > ! /* { dg-output "    #1 0x\[0-9a-f\]+ +(in _*main (\[^\n\r]*strncpy-overflow-1.c:10|\[^\n\r]*:0|\[^\n\r]*\\+0x\[0-9a-z\]*)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
> > Index: early-lto-debug/gcc/testsuite/c-c++-common/asan/use-after-free-1.c
> > ===================================================================
> > *** early-lto-debug.orig/gcc/testsuite/c-c++-common/asan/use-after-free-1.c	2017-05-16 13:10:47.554202813 +0200
> > --- early-lto-debug/gcc/testsuite/c-c++-common/asan/use-after-free-1.c	2017-05-16 13:10:49.874240999 +0200
> > *************** int main() {
> > *** 12,22 ****
> >   /* { dg-output "ERROR: AddressSanitizer:? heap-use-after-free on address\[^\n\r]*" } */
> >   /* { dg-output "0x\[0-9a-f\]+ at pc 0x\[0-9a-f\]+ bp 0x\[0-9a-f\]+ sp 0x\[0-9a-f\]+\[^\n\r]*(\n|\r\n|\r)" } */
> >   /* { dg-output "\[^\n\r]*READ of size 1 at 0x\[0-9a-f\]+ thread T0\[^\n\r]*(\n|\r\n|\r)" } */
> > ! /* { dg-output "    #0 0x\[0-9a-f\]+ +(in _*main (\[^\n\r]*use-after-free-1.c:9|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */
> >   /* { dg-output "\[^\n\r]*0x\[0-9a-f\]+ is located 5 bytes inside of 10-byte region .0x\[0-9a-f\]+,0x\[0-9a-f\]+\[^\n\r]*(\n|\r\n|\r)" } */
> >   /* { dg-output "\[^\n\r]*freed by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */
> >   /* { dg-output "    #0 0x\[0-9a-f\]+ +(in _*(interceptor_|wrap_|)free|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
> > ! /* { dg-output "    #1 0x\[0-9a-f\]+ +(in _*main (\[^\n\r]*use-after-free-1.c:8|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */
> >   /* { dg-output "\[^\n\r]*previously allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */
> >   /* { dg-output "    #0 0x\[0-9a-f\]+ +(in _*(interceptor_|wrap_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
> > ! /* { dg-output "    #1 0x\[0-9a-f\]+ +(in _*main (\[^\n\r]*use-after-free-1.c:7|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
> > --- 12,22 ----
> >   /* { dg-output "ERROR: AddressSanitizer:? heap-use-after-free on address\[^\n\r]*" } */
> >   /* { dg-output "0x\[0-9a-f\]+ at pc 0x\[0-9a-f\]+ bp 0x\[0-9a-f\]+ sp 0x\[0-9a-f\]+\[^\n\r]*(\n|\r\n|\r)" } */
> >   /* { dg-output "\[^\n\r]*READ of size 1 at 0x\[0-9a-f\]+ thread T0\[^\n\r]*(\n|\r\n|\r)" } */
> > ! /* { dg-output "    #0 0x\[0-9a-f\]+ +(in _*main (\[^\n\r]*use-after-free-1.c:9|\[^\n\r]*:0|\[^\n\r]*\\+0x\[0-9a-z\]*)|\[(\]).*(\n|\r\n|\r)" } */
> >   /* { dg-output "\[^\n\r]*0x\[0-9a-f\]+ is located 5 bytes inside of 10-byte region .0x\[0-9a-f\]+,0x\[0-9a-f\]+\[^\n\r]*(\n|\r\n|\r)" } */
> >   /* { dg-output "\[^\n\r]*freed by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */
> >   /* { dg-output "    #0 0x\[0-9a-f\]+ +(in _*(interceptor_|wrap_|)free|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
> > ! /* { dg-output "    #1 0x\[0-9a-f\]+ +(in _*main (\[^\n\r]*use-after-free-1.c:8|\[^\n\r]*:0|\[^\n\r]*\\+0x\[0-9a-z\]*)|\[(\]).*(\n|\r\n|\r)" } */
> >   /* { dg-output "\[^\n\r]*previously allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */
> >   /* { dg-output "    #0 0x\[0-9a-f\]+ +(in _*(interceptor_|wrap_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
> > ! /* { dg-output "    #1 0x\[0-9a-f\]+ +(in _*main (\[^\n\r]*use-after-free-1.c:7|\[^\n\r]*:0|\[^\n\r]*\\+0x\[0-9a-z\]*)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
> > Index: early-lto-debug/gcc/testsuite/g++.dg/asan/large-func-test-1.C
> > ===================================================================
> > *** early-lto-debug.orig/gcc/testsuite/g++.dg/asan/large-func-test-1.C	2017-05-16 13:10:47.554202813 +0200
> > --- early-lto-debug/gcc/testsuite/g++.dg/asan/large-func-test-1.C	2017-05-16 13:10:49.874240999 +0200
> > *************** int main() {
> > *** 38,44 ****
> >   // { dg-output "ERROR: AddressSanitizer:? heap-buffer-overflow on address\[^\n\r]*" }
> >   // { dg-output "0x\[0-9a-f\]+ at pc 0x\[0-9a-f\]+ bp 0x\[0-9a-f\]+ sp 0x\[0-9a-f\]+\[^\n\r]*(\n|\r\n|\r)" }
> >   // { dg-output "\[^\n\r]*READ of size 4 at 0x\[0-9a-f\]+ thread T0\[^\n\r]*(\n|\r\n|\r)" }
> > ! // { dg-output "    #0 0x\[0-9a-f\]+ +(in \[^\n\r]*LargeFunction\[^\n\r]*(large-func-test-1.C:18|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" }
> >   // { dg-output "\[^\n\r]*0x\[0-9a-f\]+ is located 44 bytes to the right of 400-byte region.*(\n|\r\n|\r)" }
> >   // { dg-output "\[^\n\r]*allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" }
> >   // { dg-output "    #0( 0x\[0-9a-f\]+ +(in _*(interceptor_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" }
> > --- 38,44 ----
> >   // { dg-output "ERROR: AddressSanitizer:? heap-buffer-overflow on address\[^\n\r]*" }
> >   // { dg-output "0x\[0-9a-f\]+ at pc 0x\[0-9a-f\]+ bp 0x\[0-9a-f\]+ sp 0x\[0-9a-f\]+\[^\n\r]*(\n|\r\n|\r)" }
> >   // { dg-output "\[^\n\r]*READ of size 4 at 0x\[0-9a-f\]+ thread T0\[^\n\r]*(\n|\r\n|\r)" }
> > ! // { dg-output "    #0 0x\[0-9a-f\]+ +(in \[^\n\r]*LargeFunction\[^\n\r]*(large-func-test-1.C:18|\[^\n\r]*:0|\[^\n\r]*\\+0x\[0-9a-z\]*)|\[(\]).*(\n|\r\n|\r)" }
> >   // { dg-output "\[^\n\r]*0x\[0-9a-f\]+ is located 44 bytes to the right of 400-byte region.*(\n|\r\n|\r)" }
> >   // { dg-output "\[^\n\r]*allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" }
> >   // { dg-output "    #0( 0x\[0-9a-f\]+ +(in _*(interceptor_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" }
> > Index: early-lto-debug/libstdc++-v3/testsuite/libstdc++-prettyprinters/prettyprinters.exp
> > ===================================================================
> > *** early-lto-debug.orig/libstdc++-v3/testsuite/libstdc++-prettyprinters/prettyprinters.exp	2017-05-16 13:10:47.554202813 +0200
> > --- early-lto-debug/libstdc++-v3/testsuite/libstdc++-prettyprinters/prettyprinters.exp	2017-05-16 13:10:49.874240999 +0200
> > ***************
> > *** 15,20 ****
> > --- 15,21 ----
> >   # <http://www.gnu.org/licenses/>.
> >   
> >   load_lib gdb-test.exp
> > + load_lib target-supports.exp
> >   
> >   dg-init
> >   v3-build_support
> > *************** global PCH_CXXFLAGS
> > *** 46,51 ****
> > --- 47,60 ----
> >   gdb-dg-runtest [lsort [glob $srcdir/$subdir/*.cc]] \
> >     "" "$DEFAULT_CXXFLAGS $PCH_CXXFLAGS"
> >   
> > + if { [check_effective_target_lto] } {
> > +   append cxxflags " -flto"
> > +   # work around sourceware.org 20882
> > +   regsub {^(.*)-Wl,--gc-sections(.*)$} $cxxldflags {\1\2} cxxldflags
> > +   gdb-dg-runtest [lsort [glob $srcdir/$subdir/*.cc]] \
> > +     "" "$DEFAULT_CXXFLAGS -flto $PCH_CXXFLAGS"
> > + }
> > + 
> >   if [info exists guality_gdb_name] {
> >       unsetenv GUALITY_GDB_NAME
> >   }
> > Index: early-lto-debug/gcc/testsuite/gfortran.dg/save_6.f90
> > ===================================================================
> > *** /dev/null	1970-01-01 00:00:00.000000000 +0000
> > --- early-lto-debug/gcc/testsuite/gfortran.dg/save_6.f90	2017-05-18 09:39:31.394914888 +0200
> > ***************
> > *** 0 ****
> > --- 1,54 ----
> > + ! { dg-do run }
> > + ! { dg-require-effective-target lto }
> > + ! { dg-options "-fno-automatic -flto -g" }
> > + !
> > + ! PR fortran/55733
> > + !
> > + ! Check that -fno-automatic makes the local variable SAVEd
> > + ! Check that -flto -g works
> > + !
> > + 
> > + ! Scalar allocatable
> > + subroutine foo(i)
> > +   integer :: i
> > +   integer, allocatable :: j
> > +   if (i == 1) j = 42
> > +   if (.not. allocated (j)) call abort ()
> > +   if (j /= 42) call abort ()
> > + end
> > + 
> > + ! Deferred-length string scalar
> > + subroutine bar()
> > +   logical, save :: first = .true.
> > +   character(len=:), allocatable :: str
> > +   if (first) then
> > +     first = .false.
> > +     if (allocated (str)) call abort ()
> > +     str = "ABCDEF"
> > +   end if
> > +   if (.not. allocated (str)) call abort ()
> > +   if (len (str) /= 6) call abort ()
> > +   if (str(1:6) /= "ABCDEF") call abort ()
> > + end subroutine bar
> > + 
> > + ! Deferred-length string array
> > + subroutine bar_array()
> > +   logical, save :: first = .true.
> > +   character(len=:), allocatable :: str
> > +   if (first) then
> > +     first = .false.
> > +     if (allocated (str)) call abort ()
> > +     str = "ABCDEF"
> > +   end if
> > +   if (.not. allocated (str)) call abort ()
> > +   if (len (str) /= 6) call abort ()
> > +   if (str(1:6) /= "ABCDEF") call abort ()
> > + end subroutine bar_array
> > + 
> > + call foo(1)
> > + call foo(2)
> > + call bar()
> > + call bar_array()
> > + call bar()
> > + call bar_array()
> > + end
> > Index: early-lto-debug/gcc/config/i386/i386.c
> > ===================================================================
> > *** early-lto-debug.orig/gcc/config/i386/i386.c	2017-05-15 10:57:19.923567540 +0200
> > --- early-lto-debug/gcc/config/i386/i386.c	2017-05-19 11:27:19.565373271 +0200
> > *************** make_resolver_func (const tree default_d
> > *** 33840,33846 ****
> >     DECL_NAME (decl) = decl_name;
> >     TREE_USED (decl) = 1;
> >     DECL_ARTIFICIAL (decl) = 1;
> > !   DECL_IGNORED_P (decl) = 0;
> >     /* IFUNC resolvers have to be externally visible.  */
> >     TREE_PUBLIC (decl) = 1;
> >     DECL_UNINLINABLE (decl) = 1;
> > --- 33840,33846 ----
> >     DECL_NAME (decl) = decl_name;
> >     TREE_USED (decl) = 1;
> >     DECL_ARTIFICIAL (decl) = 1;
> > !   DECL_IGNORED_P (decl) = 1;
> >     /* IFUNC resolvers have to be externally visible.  */
> >     TREE_PUBLIC (decl) = 1;
> >     DECL_UNINLINABLE (decl) = 1;
> > 
> 
> 

-- 
Richard Biener <rguenther@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]