This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: [RFC] LTO and debug information
On Sat, 12 Dec 2009, Richard Guenther wrote:
> On Fri, 11 Dec 2009, Richard Guenther wrote:
>
> >
> > The following draft patch disables the debuginfo disabling when using
> > -flto or -fwhopr and fixes up things so that for C debugging (mostly)
> > works.
> >
> > The main question I have is how to proceed further here (with the
> > goal that simple debugging should be possible in 4.5). If we
> > apply this patch then we expose ICEs when -flto is used in
> > conjunction with -g because the patch doesn't fix all clashes
> > between free-lang-data and dwarf2out. Now I was thinking of
> > instead of ICEing to sorry () if we ICE, have debuginfo enabled
> > and had run free-lang-data. Or to keep -g non-operational for
> > LTO and add a -glto or -fi-really-want-to-debug option.
> >
> > Or of course hope I can reasonably fix the ICEs I run into and
> > deal with the remaining cases as bugs?
>
> The following variant of the patch with only one non-mergeable
> hunk (the gen_member_die one) allows me to build all of SPEC2006
> with LTO and debug information enabled. Running the C++
> testsuite with -g still reveals many ICEs mainly because we
> free too many TYPE/DECL_CONTEXTs.
>
> But even in its current state it will probably be useful to
> many people (not Fortran without the hack though - I'll see
> to add support for streaming TYPE_DECLs).
That was easy enough. So I'd like to commit the following.
Bootstrapped and tested on x86_64-unknown-linux-gnu. SPEC 2006
built fine with -O3 -fwhole-program -flto -g.
Ok?
Thanks,
Richard.
2009-12-12 Richard Guenther <rguenther@suse.de>
* tree.c (free_lang_data_in_binfo): Do not free BINFO_OFFSET
and BINFO_VPTR_FIELD.
(free_lang_data_in_type): Do not free TYPE_STUB_DECL if we
generate debug information.
(free_lang_data_in_decl): Do not free DECL_SIZE_UNIT,
DECL_SIZE, DECL_FIELD_OFFSET and DECL_FCONTEXT.
(free_lang_data): Do not disable debuginfo.
* lto-streamer-out.c (write_symbol_vec): Deal with
non-constant DECL_SIZE.
(pack_ts_base_value_fields): Write types with false
TREE_ASM_WRITTEN.
(lto_output_ts_type_tree_pointers): Stream TYPE_STUB_DECL.
* lto-streamer-in.c (lto_input_ts_type_tree_pointers): Stream
TYPE_STUB_DECL.
* dwarf2out.c (add_pure_or_virtual_attribute): Check for
DECL_CONTEXT.
(gen_type_die_for_member): Test for TYPE_STUB_DECL.
* opts.c (decode_options): Do not disable var-tracking for lto.
* doc/invoke.texi (-flto): Document -flto vs. -g experimental
status.
(-fwhopr): Document experimental status.
lto/
* lto.c (lto_fixup_field_decl): Fixup DECL_FIELD_OFFSET.
(lto_post_options): Do not disable debuginfo.
Index: gcc/tree.c
===================================================================
*** gcc/tree.c.orig 2009-12-12 01:14:07.000000000 +0100
--- gcc/tree.c 2009-12-13 17:31:30.000000000 +0100
*************** free_lang_data_in_binfo (tree binfo)
*** 4152,4164 ****
gcc_assert (TREE_CODE (binfo) == TREE_BINFO);
- BINFO_OFFSET (binfo) = NULL_TREE;
BINFO_VTABLE (binfo) = NULL_TREE;
- BINFO_VPTR_FIELD (binfo) = NULL_TREE;
BINFO_BASE_ACCESSES (binfo) = NULL;
BINFO_INHERITANCE_CHAIN (binfo) = NULL_TREE;
BINFO_SUBVTT_INDEX (binfo) = NULL_TREE;
- BINFO_VPTR_FIELD (binfo) = NULL_TREE;
for (i = 0; VEC_iterate (tree, BINFO_BASE_BINFOS (binfo), i, t); i++)
free_lang_data_in_binfo (t);
--- 4152,4161 ----
*************** free_lang_data_in_type (tree type)
*** 4253,4259 ****
}
TYPE_CONTEXT (type) = NULL_TREE;
! TYPE_STUB_DECL (type) = NULL_TREE;
}
--- 4250,4257 ----
}
TYPE_CONTEXT (type) = NULL_TREE;
! if (debug_info_level < DINFO_LEVEL_TERSE)
! TYPE_STUB_DECL (type) = NULL_TREE;
}
*************** free_lang_data_in_decl (tree decl)
*** 4380,4408 ****
}
}
! if (TREE_CODE (decl) == PARM_DECL
! || TREE_CODE (decl) == FIELD_DECL
! || TREE_CODE (decl) == RESULT_DECL)
! {
! tree unit_size = DECL_SIZE_UNIT (decl);
! tree size = DECL_SIZE (decl);
! if ((unit_size && TREE_CODE (unit_size) != INTEGER_CST)
! || (size && TREE_CODE (size) != INTEGER_CST))
! {
! DECL_SIZE_UNIT (decl) = NULL_TREE;
! DECL_SIZE (decl) = NULL_TREE;
! }
!
! if (TREE_CODE (decl) == FIELD_DECL
! && DECL_FIELD_OFFSET (decl)
! && TREE_CODE (DECL_FIELD_OFFSET (decl)) != INTEGER_CST)
! DECL_FIELD_OFFSET (decl) = NULL_TREE;
!
! /* DECL_FCONTEXT is only used for debug info generation. */
! if (TREE_CODE (decl) == FIELD_DECL)
! DECL_FCONTEXT (decl) = NULL_TREE;
! }
! else if (TREE_CODE (decl) == FUNCTION_DECL)
{
if (gimple_has_body_p (decl))
{
--- 4378,4384 ----
}
}
! if (TREE_CODE (decl) == FUNCTION_DECL)
{
if (gimple_has_body_p (decl))
{
*************** free_lang_data (void)
*** 4977,4989 ****
diagnostic_finalizer (global_dc) = default_diagnostic_finalizer;
diagnostic_format_decoder (global_dc) = default_tree_printer;
- /* FIXME. We remove sufficient language data that the debug
- info writer gets completely confused. Disable debug information
- for now. */
- debug_info_level = DINFO_LEVEL_NONE;
- write_symbols = NO_DEBUG;
- debug_hooks = &do_nothing_debug_hooks;
-
return 0;
}
--- 4953,4958 ----
Index: gcc/lto-streamer-out.c
===================================================================
*** gcc/lto-streamer-out.c.orig 2009-12-12 01:14:07.000000000 +0100
--- gcc/lto-streamer-out.c 2009-12-13 17:35:37.000000000 +0100
*************** pack_ts_base_value_fields (struct bitpac
*** 342,348 ****
bp_pack_value (bp, DECL_UNSIGNED (expr), 1);
else if (TYPE_P (expr))
bp_pack_value (bp, TYPE_UNSIGNED (expr), 1);
! bp_pack_value (bp, TREE_ASM_WRITTEN (expr), 1);
bp_pack_value (bp, TREE_NO_WARNING (expr), 1);
bp_pack_value (bp, TREE_USED (expr), 1);
bp_pack_value (bp, TREE_NOTHROW (expr), 1);
--- 342,349 ----
bp_pack_value (bp, DECL_UNSIGNED (expr), 1);
else if (TYPE_P (expr))
bp_pack_value (bp, TYPE_UNSIGNED (expr), 1);
! /* We write debug info two times, do not confuse the second one. */
! bp_pack_value (bp, TYPE_P (expr) ? 0 : TREE_ASM_WRITTEN (expr), 1);
bp_pack_value (bp, TREE_NO_WARNING (expr), 1);
bp_pack_value (bp, TREE_USED (expr), 1);
bp_pack_value (bp, TREE_NOTHROW (expr), 1);
*************** lto_output_ts_type_tree_pointers (struct
*** 966,971 ****
--- 967,973 ----
lto_output_tree_or_ref (ob, TYPE_BINFO (expr), ref_p);
lto_output_tree_or_ref (ob, TYPE_CONTEXT (expr), ref_p);
lto_output_tree_or_ref (ob, TYPE_CANONICAL (expr), ref_p);
+ lto_output_tree_or_ref (ob, TYPE_STUB_DECL (expr), ref_p);
}
*************** write_symbol_vec (struct lto_streamer_ca
*** 2335,2341 ****
break;
}
! if (kind == GCCPK_COMMON && DECL_SIZE (t))
size = (((uint64_t) TREE_INT_CST_HIGH (DECL_SIZE (t))) << 32)
| TREE_INT_CST_LOW (DECL_SIZE (t));
else
--- 2337,2345 ----
break;
}
! if (kind == GCCPK_COMMON
! && DECL_SIZE (t)
! && TREE_CODE (DECL_SIZE (t)) == INTEGER_CST)
size = (((uint64_t) TREE_INT_CST_HIGH (DECL_SIZE (t))) << 32)
| TREE_INT_CST_LOW (DECL_SIZE (t));
else
Index: gcc/dwarf2out.c
===================================================================
*** gcc/dwarf2out.c.orig 2009-12-12 01:14:07.000000000 +0100
--- gcc/dwarf2out.c 2009-12-13 19:13:04.000000000 +0100
*************** add_pure_or_virtual_attribute (dw_die_re
*** 16476,16482 ****
0));
/* GNU extension: Record what type this method came from originally. */
! if (debug_info_level > DINFO_LEVEL_TERSE)
add_AT_die_ref (die, DW_AT_containing_type,
lookup_type_die (DECL_CONTEXT (func_decl)));
}
--- 16476,16483 ----
0));
/* GNU extension: Record what type this method came from originally. */
! if (debug_info_level > DINFO_LEVEL_TERSE
! && DECL_CONTEXT (func_decl))
add_AT_die_ref (die, DW_AT_containing_type,
lookup_type_die (DECL_CONTEXT (func_decl)));
}
*************** gen_type_die_for_member (tree type, tree
*** 17396,17402 ****
/* If we're trying to avoid duplicate debug info, we may not have
emitted the member decl for this function. Emit it now. */
! if (TYPE_DECL_SUPPRESS_DEBUG (TYPE_STUB_DECL (type))
&& ! lookup_decl_die (member))
{
dw_die_ref type_die;
--- 17397,17404 ----
/* If we're trying to avoid duplicate debug info, we may not have
emitted the member decl for this function. Emit it now. */
! if (TYPE_STUB_DECL (type)
! && TYPE_DECL_SUPPRESS_DEBUG (TYPE_STUB_DECL (type))
&& ! lookup_decl_die (member))
{
dw_die_ref type_die;
Index: gcc/opts.c
===================================================================
*** gcc/opts.c.orig 2009-12-12 01:14:07.000000000 +0100
--- gcc/opts.c 2009-12-12 02:14:01.000000000 +0100
*************** decode_options (unsigned int argc, const
*** 1129,1138 ****
Otherwise, symbols will be privatized too early, causing link
errors later. */
flag_whole_program = 0;
-
- /* FIXME lto. Disable var-tracking until debug information
- is properly handled in free_lang_data. */
- flag_var_tracking = 0;
#else
error ("LTO support has not been enabled in this configuration");
#endif
--- 1129,1134 ----
Index: gcc/lto/lto.c
===================================================================
*** gcc/lto/lto.c.orig 2009-12-12 01:14:07.000000000 +0100
--- gcc/lto/lto.c 2009-12-12 02:14:01.000000000 +0100
*************** static void
*** 1376,1382 ****
lto_fixup_field_decl (tree t, void *data)
{
lto_fixup_decl_common (t, data);
! gcc_assert (no_fixup_p (DECL_FIELD_OFFSET (t)));
LTO_FIXUP_SUBTREE (DECL_BIT_FIELD_TYPE (t));
LTO_FIXUP_SUBTREE (DECL_QUALIFIER (t));
gcc_assert (no_fixup_p (DECL_FIELD_BIT_OFFSET (t)));
--- 1376,1382 ----
lto_fixup_field_decl (tree t, void *data)
{
lto_fixup_decl_common (t, data);
! LTO_FIXUP_SUBTREE (DECL_FIELD_OFFSET (t));
LTO_FIXUP_SUBTREE (DECL_BIT_FIELD_TYPE (t));
LTO_FIXUP_SUBTREE (DECL_QUALIFIER (t));
gcc_assert (no_fixup_p (DECL_FIELD_BIT_OFFSET (t)));
Index: gcc/lto/lto-lang.c
===================================================================
*** gcc/lto/lto-lang.c.orig 2009-12-12 01:14:07.000000000 +0100
--- gcc/lto/lto-lang.c 2009-12-12 02:14:01.000000000 +0100
*************** lto_handle_option (size_t scode, const c
*** 646,661 ****
static bool
lto_post_options (const char **pfilename ATTRIBUTE_UNUSED)
{
- /* FIXME lto: We have stripped enough type and other
- debugging information out of the IR that it may
- appear ill-formed to dwarf2out, etc. We must not
- attempt to generate debug info in lto1. A more
- graceful solution would disable the option flags
- rather than ignoring them, but we'd also have to
- worry about default debugging options. */
- write_symbols = NO_DEBUG;
- debug_info_level = DINFO_LEVEL_NONE;
-
/* -fltrans and -fwpa are mutually exclusive. Check for that here. */
if (flag_wpa && flag_ltrans)
error ("-fwpa and -fltrans are mutually exclusive");
--- 646,651 ----
Index: gcc/lto-streamer-in.c
===================================================================
*** gcc/lto-streamer-in.c.orig 2009-12-13 17:37:33.000000000 +0100
--- gcc/lto-streamer-in.c 2009-12-13 17:37:35.000000000 +0100
*************** lto_input_ts_type_tree_pointers (struct
*** 2167,2172 ****
--- 2167,2173 ----
TYPE_BINFO (expr) = lto_input_tree (ib, data_in);
TYPE_CONTEXT (expr) = lto_input_tree (ib, data_in);
TYPE_CANONICAL (expr) = lto_input_tree (ib, data_in);
+ TYPE_STUB_DECL (expr) = lto_input_tree (ib, data_in);
}
Index: gcc/doc/invoke.texi
===================================================================
*** gcc/doc/invoke.texi.orig 2009-12-13 19:07:29.000000000 +0100
--- gcc/doc/invoke.texi 2009-12-13 19:11:51.000000000 +0100
*************** types of hosts. The bytecode files are
*** 7321,7326 ****
--- 7321,7330 ----
strict version check, so bytecode files generated in one version of
GCC will not work with an older/newer version of GCC.
+ Link time optimization does not play well with generating debugging
+ information. Combining @option{-flto} or @option{-fwhopr} with
+ @option{-g} is experimental.
+
This option is disabled by default.
@item -fwhopr
*************** that otherwise would not fit in memory.
*** 7337,7342 ****
--- 7341,7348 ----
Disabled by default.
+ This option is experimental.
+
@item -fwpa
@opindex fwpa
This is an internal option used by GCC when compiling with