Reduce Dwarf Debug Size

Lawrence Crowl crowl@google.com
Fri Mar 23 21:05:00 GMT 2007


This patch is a resubmit of the earlier patch.  It addresses the
concerns voice, where possible.

==

A major contribution to object and executable size is DWARF debug
information size.  A major contribution to debug information
size is struct descriptions replicated in several object files.
This patch adds an option to reduce the size of this information,
which mainly benefits C++.

The basic idea is to not emit struct debugging information in the
current compilation unit when that information will be generated
by another compilation unit.  The primary criteria is whether the
base name of the file containing the struct definition matches the
base name of the main file being compiled.  For example, if struct
foo is defined in bar.h, then when used in bar.c, the compiler will
generate the struct debugging information.  On the other hand, when
used in ping.c, the compiler will not generate the information.
In simple terms, the option matches the filename of the header
defining the struct to the filename of the compilation unit.

This simple approach is complicated by templates, system headers,
indirect use of structs, etc.

Because there is less information, there is a chance that debugging
may be impaired.  Therefore, the compiler's default behavior is
unchanged and the option has a value that enables you to chose the
size versus debuggibility, that is, to choose the criteria by which
struct debugging information will be emitted.  The most important
choices are as follows.

   By default, the compiler's and debugger's behavior does not
   change.

   With -g -femit-struct-debug-reduced, the compiler conservatively
   suppresses some struct debug information.  Debugging behavior
   should be mostly unimpaired, except perhaps for interactions
   with non-system libraries built without -g.

   With -g -femit-struct-debug-baseonly, the compiler emits struct
   information on strictly matching file base names.  Debugging
   templates or structs defined in system headers will be impaired.

Experimentally, the size savings can be significant.  On one very
large application, the sizes were:

  debug executable
   size   size
   100%   100%   with only -g
    60%    73%   with -g -femit-struct-debug-reduced
    37%    58%   with -g -femit-struct-debug-baseonly

The option documentation in texinfo is:

   -femit-struct-debug-baseonly
      Emit debug information for struct-like types only when the
      base name of the compilation source file matches the base
      name of file in which the struct was defined.

      This option substantially reduces the size of debugging
      information, but at significant potential loss in type
      information to the debugger.  See -femit-struct-debug-reduced
      for a less aggressive option.  See -femit-struct-debug-detailed
      for more detailed control.

      This option works only with DWARF 2.

   -femit-struct-debug-reduced
      Emit debug information for struct-like types only when the
      base name of the compilation source file matches the base name
      of file in which the type was defined, unless the struct is
      a template or defined in a system header.

      This option significantly reduces the size of debugging
      information, with some potential loss in type information to
      the debugger.  See -femit-struct-debug-baseonly for a more
      aggressive option.  See -femit-struct-debug-detailed for more
      detailed control.

      This option works only with DWARF 2.

   -femit-struct-debug-detailed[=spec-list]
      Specify the struct-like types for which the compiler will
      generate debug information.  The intent is to reduce duplicate
      struct debug information between different object files within
      the same program.

      This option is a detailed version of
      -femit-struct-debug-reduced and -femit-struct-debug-baseonly,
      which will serve for most needs.

      A specification has the syntax
      [dir:|ind:][ord:|gen:](any|sys|base|none)

      The optional first word limits the specification to structs
      that are used directly (dir:) or used indirectly (ind:).
      A struct type is used directly when it is the type of a
      variable, member.  Indirect uses arise through pointers to
      structs.  That is, when use of an incomplete struct would be
      legal, the use is indirect.  An example is struct one direct;
      struct two * indirect;.

      The optional second word limits the specification to ordinary
      structs (ord:) or generic structs (gen:).  Generic structs are
      a bit complicated to explain.  For C++, these are non-explicit
      specializations of template classes, or non-template classes
      within the above.  Other programming languages have generics,
      but -femit-struct-debug-detailed does not yet implement them.

      The third word specifies the source files for those structs for
      which the compiler will emit debug information.  The values
      none and any have the normal meaning.  The value base means
      that the base of name of the file in which the type declaration
      appears must match the base of the name of the main compilation
      file.  In practice, this means that types declared in foo.c
      and foo.h will have debug information, but types declared
      in other header will not.  The value sys means those types
      satisfying base or declared in system or compiler headers.

      You may need to experiment to determine the best settings
      for your application.

      The default is -femit-struct-debug-detailed=all.

      This option works only with DWARF 2.

-- 
Lawrence Crowl
-------------- next part --------------
2007-03-23  Lawrence Crowl  <crowl@google.com>

	* doc/invoke.texi (Debugging Options): Add
	documentation for the -femit-struct-debug options
	-femit-struct-debug-baseonly, -femit-struct-debug-reduced,
	and -femit-struct-debug-detailed[=...].

	* c-opts.c (c_common_handle_option):
	Add OPT_femit_struct_debug_baseonly,
	OPT_femit_struct_debug_reduced, and
	OPT_femit_struct_debug_detailed_.
	* c.opt: Add specifications for
	-femit-struct-debug-baseonly, -femit-struct-debug-reduced,
	and -femit-struct-debug-detailed[=...].
	* opts.c (set_struct_debug_option): Parse the
	-femit-struct-debug-... options.
	* opts.c (matches_main_base): Add variables
	(main_input_basename, main_input_baselength) and functions
	(base_of_path, matches_main_base) to compare header base
	name to compilation unit base name.
	* opts.c (should_emit_struct_debug): Add a function
	(should_emit_struct_debug) to determine to emit a structure
	based on the option.  Also add a disabled function
	(dump_struct_debug) to debug this function.
	* opts.c (handle_options): Save the base name of the
	compilation unit.

	* langhooks-def.h (LANG_HOOKS_GENERIC_TYPE_P): Define.
        (LANG_HOOKS_FOR_TYPES_INITIALIZER): Add.
	This hook indicates if a type is generic.  Set it by default
	to "never generic".
	* langhooks.h (struct lang_hooks_for_types): Add a new hook
	to determine if a struct type is generic or not.
	* cp/cp-tree.h (class_tmpl_impl_spec_p): Declare a C++ hook.
	* cp/tree.c (class_tmpl_impl_spec_p): Implement the C++ hook.
	* cp/cp-lang.c: Override null C hook with live C++ hook.

	* flags.h: Add an enumeration to describe a program's use
	of a structure type.
	* dwarf2out.c (gen_struct_or_union_type_die):
	Add a new parameter to indicate the program's usage of
	the type.  Filter structs based on the
	-femit-struct-debug-... specification.
	(gen_type_die): Split into two routines, gen_type_die and
	gen_type_die_with_usage.  gen_type_die is now a wrapper
	that assumes direct usage.
	(gen_type_die_with_usage): Replace calls to gen_type_die
	with gen_type_die_with_usage adding the program usage of
	the referenced type.
	(dwarf2out_imported_module_or_decl): Suppress struct debug
	information using should_emit_struct_debug when appropriate.
-------------- next part --------------
2007-03-23  Lawrence Crowl  <crowl@google.com>

	* g++.dg/other/fesd-any.C: Test -femit-struct-debug-detailed=any.
	* g++.dg/other/fesd-any.h: Test -femit-struct-debug-detailed=any.
	* g++.dg/other/fesd-baseonly.C: Test -femit-struct-debug-baseonly.
	* g++.dg/other/fesd-baseonly.h: Test -femit-struct-debug-baseonly.
	* g++.dg/other/fesd-none.C: Test -femit-struct-debug-detailed=none.
	* g++.dg/other/fesd-none.h: Test -femit-struct-debug-detailed=none.
	* g++.dg/other/fesd-reduced.C: Test -femit-struct-debug-reduced.
	* g++.dg/other/fesd-reduced.h: Test -femit-struct-debug-reduced.
	* g++.dg/other/fesd-sys.C: Test -femit-struct-debug-detailed=sys.
	* g++.dg/other/fesd-sys.h: Test -femit-struct-debug-detailed=sys.
	* g++.dg/other/fesd.h: Common to -femit-struct-debug-... tests.

	* gcc.dg/fesd-any.c: Test -femit-struct-debug-detailed=any.
	* gcc.dg/fesd-any.h: Test -femit-struct-debug-detailed=any.
	* gcc.dg/fesd-baseonly.c: Test -femit-struct-debug-baseonly.
	* gcc.dg/fesd-baseonly.h: Test -femit-struct-debug-baseonly.
	* gcc.dg/fesd-none.c: Test -femit-struct-debug-detailed=none.
	* gcc.dg/fesd-none.h: Test -femit-struct-debug-detailed=none.
	* gcc.dg/fesd-reduced.c: Test -femit-struct-debug-reduced.
	* gcc.dg/fesd-reduced.h: Test -femit-struct-debug-reduced.
	* gcc.dg/fesd-sys.c: Test -femit-struct-debug-detailed=sys.
	* gcc.dg/fesd-sys.h: Test -femit-struct-debug-detailed=sys.
	* gcc.dg/fesd.h: Common to -femit-struct-debug-... tests.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: gcc-fesd.patch
Type: text/x-patch
Size: 118918 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20070323/def664a5/attachment.bin>


More information about the Gcc-patches mailing list