common.opt (debug_struct_ordinary, [...]): New Variable entries.

* common.opt (debug_struct_ordinary, debug_struct_generic): New
	Variable entries.
	* dwarf2out.c (matches_main_base, dump_struct_debug, DUMP_GSTRUCT,
	should_emit_struct_debug): Move from opts.c.
	* flag-types.h (enum debug_struct_file): Move from opts.c.
	* flags.h (should_emit_struct_debug): Remove.
	(base_of_path): Declare.
	(set_struct_debug_option): Add gcc_options parameter.
	* optc-gen.awk, opth-gen.awk: Handle array variables.
	* opts.c (enum debug_struct_file, debug_struct_ordinary,
	debug_struct_generic): Remove.
	(set_struct_debug_option): Add gcc_options parameter.
	(base_of_path): Remove static.
	(main_input_basename, main_input_baselength, matches_main_base,
	dump_struct_debug, DUMP_GSTRUCT, should_emit_struct_debug):
	Remove.
	* toplev.c (main_input_basename, main_input_baselength): Define
	here.
	* toplev.h (main_input_basename, main_input_baselength): Declare
	here.

c-family:
	* c-opts.c (c_common_handle_option): Update calls to
	set_struct_debug_option.

From-SVN: r166944
This commit is contained in:
Joseph Myers 2010-11-19 13:30:38 +00:00 committed by Joseph Myers
parent 6a1f6c9c86
commit 69ccdddbb8
12 changed files with 195 additions and 155 deletions

View File

@ -1,3 +1,26 @@
2010-11-19 Joseph Myers <joseph@codesourcery.com>
* common.opt (debug_struct_ordinary, debug_struct_generic): New
Variable entries.
* dwarf2out.c (matches_main_base, dump_struct_debug, DUMP_GSTRUCT,
should_emit_struct_debug): Move from opts.c.
* flag-types.h (enum debug_struct_file): Move from opts.c.
* flags.h (should_emit_struct_debug): Remove.
(base_of_path): Declare.
(set_struct_debug_option): Add gcc_options parameter.
* optc-gen.awk, opth-gen.awk: Handle array variables.
* opts.c (enum debug_struct_file, debug_struct_ordinary,
debug_struct_generic): Remove.
(set_struct_debug_option): Add gcc_options parameter.
(base_of_path): Remove static.
(main_input_basename, main_input_baselength, matches_main_base,
dump_struct_debug, DUMP_GSTRUCT, should_emit_struct_debug):
Remove.
* toplev.c (main_input_basename, main_input_baselength): Define
here.
* toplev.h (main_input_basename, main_input_baselength): Declare
here.
2010-11-19 Joseph Myers <joseph@codesourcery.com>
* common.opt (flag_instrument_functions_exclude_functions,

View File

@ -1,3 +1,8 @@
2010-11-19 Joseph Myers <joseph@codesourcery.com>
* c-opts.c (c_common_handle_option): Update calls to
set_struct_debug_option.
2010-11-19 Nicola Pero <nicola.pero@meta-innovation.com>
* c-common.h (objc_declare_protocols): Added additional argument.

View File

@ -654,15 +654,16 @@ c_common_handle_option (size_t scode, const char *arg, int value,
break;
case OPT_femit_struct_debug_baseonly:
set_struct_debug_option ("base");
set_struct_debug_option (&global_options, "base");
break;
case OPT_femit_struct_debug_reduced:
set_struct_debug_option ("dir:ord:sys,dir:gen:any,ind:base");
set_struct_debug_option (&global_options,
"dir:ord:sys,dir:gen:any,ind:base");
break;
case OPT_femit_struct_debug_detailed_:
set_struct_debug_option (arg);
set_struct_debug_option (&global_options, arg);
break;
case OPT_idirafter:

View File

@ -113,6 +113,19 @@ void *flag_instrument_functions_exclude_functions
Variable
void *flag_instrument_functions_exclude_files
; Generic structs (e.g. templates not explicitly specialized)
; may not have a compilation unit associated with them, and so
; may need to be treated differently from ordinary structs.
;
; Structs only handled by reference (indirectly), will also usually
; not need as much debugging information.
Variable
enum debug_struct_file debug_struct_ordinary[DINFO_USAGE_NUM_ENUMS] = { DINFO_STRUCT_FILE_ANY, DINFO_STRUCT_FILE_ANY, DINFO_STRUCT_FILE_ANY }
Variable
enum debug_struct_file debug_struct_generic[DINFO_USAGE_NUM_ENUMS] = { DINFO_STRUCT_FILE_ANY, DINFO_STRUCT_FILE_ANY, DINFO_STRUCT_FILE_ANY }
###
Driver

View File

@ -546,6 +546,89 @@ static struct dw_loc_descr_struct *mem_loc_descriptor
#define DWARF_FRAME_REGNUM(REG) DBX_REGISTER_NUMBER (REG)
#endif
/* Match the base name of a file to the base name of a compilation unit. */
static int
matches_main_base (const char *path)
{
/* Cache the last query. */
static const char *last_path = NULL;
static int last_match = 0;
if (path != last_path)
{
const char *base;
int length = base_of_path (path, &base);
last_path = path;
last_match = (length == main_input_baselength
&& memcmp (base, main_input_basename, length) == 0);
}
return last_match;
}
#ifdef DEBUG_DEBUG_STRUCT
static int
dump_struct_debug (tree type, enum debug_info_usage usage,
enum debug_struct_file criterion, int generic,
int matches, int result)
{
/* Find the type name. */
tree type_decl = TYPE_STUB_DECL (type);
tree t = type_decl;
const char *name = 0;
if (TREE_CODE (t) == TYPE_DECL)
t = DECL_NAME (t);
if (t)
name = IDENTIFIER_POINTER (t);
fprintf (stderr, " struct %d %s %s %s %s %d %p %s\n",
criterion,
DECL_IN_SYSTEM_HEADER (type_decl) ? "sys" : "usr",
matches ? "bas" : "hdr",
generic ? "gen" : "ord",
usage == DINFO_USAGE_DFN ? ";" :
usage == DINFO_USAGE_DIR_USE ? "." : "*",
result,
(void*) type_decl, name);
return result;
}
#define DUMP_GSTRUCT(type, usage, criterion, generic, matches, result) \
dump_struct_debug (type, usage, criterion, generic, matches, result)
#else
#define DUMP_GSTRUCT(type, usage, criterion, generic, matches, result) \
(result)
#endif
static bool
should_emit_struct_debug (tree type, enum debug_info_usage usage)
{
enum debug_struct_file criterion;
tree type_decl;
bool generic = lang_hooks.types.generic_p (type);
if (generic)
criterion = debug_struct_generic[usage];
else
criterion = debug_struct_ordinary[usage];
if (criterion == DINFO_STRUCT_FILE_NONE)
return DUMP_GSTRUCT (type, usage, criterion, generic, false, false);
if (criterion == DINFO_STRUCT_FILE_ANY)
return DUMP_GSTRUCT (type, usage, criterion, generic, false, true);
type_decl = TYPE_STUB_DECL (type);
if (criterion == DINFO_STRUCT_FILE_SYS && DECL_IN_SYSTEM_HEADER (type_decl))
return DUMP_GSTRUCT (type, usage, criterion, generic, false, true);
if (matches_main_base (DECL_SOURCE_FILE (type_decl)))
return DUMP_GSTRUCT (type, usage, criterion, generic, true, true);
return DUMP_GSTRUCT (type, usage, criterion, generic, false, false);
}
/* Hook used by __throw. */
rtx

View File

@ -58,6 +58,41 @@ enum debug_info_usage
DINFO_USAGE_NUM_ENUMS /* The number of enumerators. */
};
/* A major contribution to object and executable size is debug
information size. A major contribution to debug information size
is struct descriptions replicated in several object files. The
following flags attempt to reduce this information. 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.
Debug information for a struct defined in the current source
file should be generated in the object file. Likewise the
debug information for a struct defined in a header should be
generated in the object file of the corresponding source file.
Both of these case are handled when the base name of the file of
the struct definition matches the base name of the source file
of the current compilation unit. This matching emits minimal
struct debugging information.
The base file name matching rule above will fail to emit debug
information for structs defined in system headers. So a second
category of files includes system headers in addition to files
with matching bases.
The remaining types of files are library headers and application
headers. We cannot currently distinguish these two types. */
enum debug_struct_file
{
DINFO_STRUCT_FILE_NONE, /* Debug no structs. */
DINFO_STRUCT_FILE_BASE, /* Debug structs defined in files with the
same base name as the compilation unit. */
DINFO_STRUCT_FILE_SYS, /* Also debug structs defined in system
header files. */
DINFO_STRUCT_FILE_ANY /* Debug structs defined in all files. */
};
/* Enumerate visibility settings. This is deliberately ordered from most
to least visibility. */
#ifndef SYMBOL_VISIBILITY_DEFINED

View File

@ -37,8 +37,9 @@ extern const char *const debug_type_names[];
/* Specify how much debugging info to generate. */
extern enum debug_info_level debug_info_level;
extern bool should_emit_struct_debug (tree type_decl, enum debug_info_usage);
extern void set_struct_debug_option (const char *value);
extern int base_of_path (const char *path, const char **base_out);
extern void set_struct_debug_option (struct gcc_options *opts,
const char *value);
/* Nonzero means use GNU-only extensions in the generated symbolic
debugging information. */

View File

@ -91,6 +91,7 @@ for (i = 0; i < n_extra_vars; i++) {
sub(".*= *", "", init)
sub(" *=.*", "", var)
sub("^.*[ *]", "", var)
sub("\\[.*\\]$", "", var)
} else {
init = "0"
}

View File

@ -86,13 +86,17 @@ for (i = 0; i < n_extra_vars; i++) {
orig_var = var
name = var
type = var
type_after = var
sub("^.*[ *]", "", name)
sub("\\[.*\\]$", "", name)
sub("\\[.*\\]$", "", type)
sub(" *" name "$", "", type)
sub("^.*" name, "", type_after)
var_seen[name] = 1
print "#ifdef GENERATOR_FILE"
print "extern " orig_var ";"
print "#else"
print " " type " x_" name ";"
print " " type " x_" name type_after ";"
print "#define " name " global_options.x_" name
print "#endif"
}

View File

@ -53,53 +53,6 @@ enum debug_info_type write_symbols = NO_DEBUG;
the definitions of the different possible levels. */
enum debug_info_level debug_info_level = DINFO_LEVEL_NONE;
/* A major contribution to object and executable size is debug
information size. A major contribution to debug information size
is struct descriptions replicated in several object files. The
following flags attempt to reduce this information. 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.
Debug information for a struct defined in the current source
file should be generated in the object file. Likewise the
debug information for a struct defined in a header should be
generated in the object file of the corresponding source file.
Both of these case are handled when the base name of the file of
the struct definition matches the base name of the source file
of the current compilation unit. This matching emits minimal
struct debugging information.
The base file name matching rule above will fail to emit debug
information for structs defined in system headers. So a second
category of files includes system headers in addition to files
with matching bases.
The remaining types of files are library headers and application
headers. We cannot currently distinguish these two types. */
enum debug_struct_file
{
DINFO_STRUCT_FILE_NONE, /* Debug no structs. */
DINFO_STRUCT_FILE_BASE, /* Debug structs defined in files with the
same base name as the compilation unit. */
DINFO_STRUCT_FILE_SYS, /* Also debug structs defined in system
header files. */
DINFO_STRUCT_FILE_ANY /* Debug structs defined in all files. */
};
/* Generic structs (e.g. templates not explicitly specialized)
may not have a compilation unit associated with them, and so
may need to be treated differently from ordinary structs.
Structs only handled by reference (indirectly), will also usually
not need as much debugging information. */
static enum debug_struct_file debug_struct_ordinary[DINFO_USAGE_NUM_ENUMS]
= { DINFO_STRUCT_FILE_ANY, DINFO_STRUCT_FILE_ANY, DINFO_STRUCT_FILE_ANY };
static enum debug_struct_file debug_struct_generic[DINFO_USAGE_NUM_ENUMS]
= { DINFO_STRUCT_FILE_ANY, DINFO_STRUCT_FILE_ANY, DINFO_STRUCT_FILE_ANY };
/* Run the second compilation of -fcompare-debug. Not defined using
Var in common.opt because this is used in Ada code and so must be
an actual variable not a macro. */
@ -113,7 +66,7 @@ int flag_compare_debug;
? ((string += sizeof prefix - 1), 1) : 0)
void
set_struct_debug_option (const char *spec)
set_struct_debug_option (struct gcc_options *opts, const char *spec)
{
/* various labels for comparison */
static char dfn_lbl[] = "dfn:", dir_lbl[] = "dir:", ind_lbl[] = "ind:";
@ -158,27 +111,27 @@ set_struct_debug_option (const char *spec)
{
if (ord)
{
debug_struct_ordinary[DINFO_USAGE_DFN] = files;
debug_struct_ordinary[DINFO_USAGE_DIR_USE] = files;
debug_struct_ordinary[DINFO_USAGE_IND_USE] = files;
opts->x_debug_struct_ordinary[DINFO_USAGE_DFN] = files;
opts->x_debug_struct_ordinary[DINFO_USAGE_DIR_USE] = files;
opts->x_debug_struct_ordinary[DINFO_USAGE_IND_USE] = files;
}
if (gen)
{
debug_struct_generic[DINFO_USAGE_DFN] = files;
debug_struct_generic[DINFO_USAGE_DIR_USE] = files;
debug_struct_generic[DINFO_USAGE_IND_USE] = files;
opts->x_debug_struct_generic[DINFO_USAGE_DFN] = files;
opts->x_debug_struct_generic[DINFO_USAGE_DIR_USE] = files;
opts->x_debug_struct_generic[DINFO_USAGE_IND_USE] = files;
}
}
else
{
if (ord)
debug_struct_ordinary[usage] = files;
opts->x_debug_struct_ordinary[usage] = files;
if (gen)
debug_struct_generic[usage] = files;
opts->x_debug_struct_generic[usage] = files;
}
if (*spec == ',')
set_struct_debug_option (spec+1);
set_struct_debug_option (opts, spec+1);
else
{
/* No more -femit-struct-debug-detailed specifications.
@ -186,10 +139,10 @@ set_struct_debug_option (const char *spec)
if (*spec != '\0')
error ("argument %qs to %<-femit-struct-debug-detailed%> unknown",
spec);
if (debug_struct_ordinary[DINFO_USAGE_DIR_USE]
< debug_struct_ordinary[DINFO_USAGE_IND_USE]
|| debug_struct_generic[DINFO_USAGE_DIR_USE]
< debug_struct_generic[DINFO_USAGE_IND_USE])
if (opts->x_debug_struct_ordinary[DINFO_USAGE_DIR_USE]
< opts->x_debug_struct_ordinary[DINFO_USAGE_IND_USE]
|| opts->x_debug_struct_generic[DINFO_USAGE_DIR_USE]
< opts->x_debug_struct_generic[DINFO_USAGE_IND_USE])
error ("%<-femit-struct-debug-detailed=dir:...%> must allow at least"
" as much as %<-femit-struct-debug-detailed=ind:...%>");
}
@ -197,7 +150,7 @@ set_struct_debug_option (const char *spec)
/* Find the base name of a path, stripping off both directories and
a single final extension. */
static int
int
base_of_path (const char *path, const char **base_out)
{
const char *base = path;
@ -221,93 +174,6 @@ base_of_path (const char *path, const char **base_out)
return dot - base;
}
/* Match the base name of a file to the base name of a compilation unit. */
static const char *main_input_basename;
static int main_input_baselength;
static int
matches_main_base (const char *path)
{
/* Cache the last query. */
static const char *last_path = NULL;
static int last_match = 0;
if (path != last_path)
{
const char *base;
int length = base_of_path (path, &base);
last_path = path;
last_match = (length == main_input_baselength
&& memcmp (base, main_input_basename, length) == 0);
}
return last_match;
}
#ifdef DEBUG_DEBUG_STRUCT
static int
dump_struct_debug (tree type, enum debug_info_usage usage,
enum debug_struct_file criterion, int generic,
int matches, int result)
{
/* Find the type name. */
tree type_decl = TYPE_STUB_DECL (type);
tree t = type_decl;
const char *name = 0;
if (TREE_CODE (t) == TYPE_DECL)
t = DECL_NAME (t);
if (t)
name = IDENTIFIER_POINTER (t);
fprintf (stderr, " struct %d %s %s %s %s %d %p %s\n",
criterion,
DECL_IN_SYSTEM_HEADER (type_decl) ? "sys" : "usr",
matches ? "bas" : "hdr",
generic ? "gen" : "ord",
usage == DINFO_USAGE_DFN ? ";" :
usage == DINFO_USAGE_DIR_USE ? "." : "*",
result,
(void*) type_decl, name);
return result;
}
#define DUMP_GSTRUCT(type, usage, criterion, generic, matches, result) \
dump_struct_debug (type, usage, criterion, generic, matches, result)
#else
#define DUMP_GSTRUCT(type, usage, criterion, generic, matches, result) \
(result)
#endif
bool
should_emit_struct_debug (tree type, enum debug_info_usage usage)
{
enum debug_struct_file criterion;
tree type_decl;
bool generic = lang_hooks.types.generic_p (type);
if (generic)
criterion = debug_struct_generic[usage];
else
criterion = debug_struct_ordinary[usage];
if (criterion == DINFO_STRUCT_FILE_NONE)
return DUMP_GSTRUCT (type, usage, criterion, generic, false, false);
if (criterion == DINFO_STRUCT_FILE_ANY)
return DUMP_GSTRUCT (type, usage, criterion, generic, false, true);
type_decl = TYPE_STUB_DECL (type);
if (criterion == DINFO_STRUCT_FILE_SYS && DECL_IN_SYSTEM_HEADER (type_decl))
return DUMP_GSTRUCT (type, usage, criterion, generic, false, true);
if (matches_main_base (DECL_SOURCE_FILE (type_decl)))
return DUMP_GSTRUCT (type, usage, criterion, generic, true, true);
return DUMP_GSTRUCT (type, usage, criterion, generic, false, false);
}
/* Nonzero means use GNU-only extensions in the generated symbolic
debugging information. Currently, this only has an effect when
write_symbols is set to DBX_DEBUG, XCOFF_DEBUG, or DWARF_DEBUG. */

View File

@ -133,6 +133,12 @@ unsigned int save_decoded_options_count;
const char *main_input_filename;
/* Pointer to base name in main_input_filename, with directories and a
single final extension removed, and the length of this base
name. */
const char *main_input_basename;
int main_input_baselength;
/* Used to enable -fvar-tracking, -fweb and -frename-registers according
to optimize in process_options (). */
#define AUTODETECT_VALUE 2

View File

@ -73,6 +73,8 @@ extern unsigned local_tick;
/* Top-level source file. */
extern const char *main_input_filename;
extern const char *main_input_basename;
extern int main_input_baselength;
extern const char *profile_data_prefix;
extern bool exit_after_options;