final.c (debug_flush_symbol_queue): New function.

* final.c (debug_flush_symbol_queue): New function.
        (debug_queue_symbol): New function.
        (debug_free_queue): New function.
        (debug_nesting): New variable.
        (symbol_queue): New variable.
        (symbol_queue_index): Same.
        (symbol_queue_size): Same.
        * debug.h (debug_flush_symbol_queue): New.
        (debug_queue_symbol): New.
        (debug_free_queue): New.
        (debug_nesting): New.
        (symbol_queue_index): New.
        * dbxout.c (DBXOUT_DECR_NESTING): New macro.
        (DBXOUT_DECR_NESTING_AND_RETURN): New macro.
        (dbxout_init): Delay symbol output.
        (dbxout_global_decl): Save, set and reset TREE_USED bit around dbxout_symbol()
        call.
        (dbxout_begin_function): Same.
        (dbxout_finish): Free symbol queue.
        (dbxout_type): Put appropriate symbols in queue.
        (dbxout_symbol): Put info for symbol's type in queue. Decrement/Increment
        nesting counts flush symbol queue appropriately.
        (dbxout_parms): Increment dbxout nesting.
        (dbxout_reg_parms): Same.
        * flags.h (flag_debug_only_used_symbols): New.
        * toplev.c (flag_debug_only_used_symbols): New variable.
        (lang_independent_options): Add entries for new option -feliminate-unused-debug-symbols.
        * common.opt: Add entry for -feliminate-unused-debug-symbols.
        * opts.c (common_handle_options): Same.
        * config/rs6000/darwin.h (CC1_SPEC): Interpret -gused as -feliminate-unused-debug-symbols.
        * doc/invoke.texi (Debugging Options): Document -feliminate-unused-debug-symbols.

From-SVN: r68556
This commit is contained in:
Devang Patel 2003-06-26 20:04:40 -07:00 committed by Devang Patel
parent 6ba701c8e9
commit 6a08f7b337
9 changed files with 292 additions and 22 deletions

View File

@ -1,3 +1,37 @@
2003-06-26 Devang Patel <dpatel@apple.com>
* final.c (debug_flush_symbol_queue): New function.
(debug_queue_symbol): New function.
(debug_free_queue): New function.
(debug_nesting): New variable.
(symbol_queue): New variable.
(symbol_queue_index): Same.
(symbol_queue_size): Same.
* debug.h (debug_flush_symbol_queue): New.
(debug_queue_symbol): New.
(debug_free_queue): New.
(debug_nesting): New.
(symbol_queue_index): New.
* dbxout.c (DBXOUT_DECR_NESTING): New macro.
(DBXOUT_DECR_NESTING_AND_RETURN): New macro.
(dbxout_init): Delay symbol output.
(dbxout_global_decl): Save, set and reset TREE_USED bit around dbxout_symbol()
call.
(dbxout_begin_function): Same.
(dbxout_finish): Free symbol queue.
(dbxout_type): Put appropriate symbols in queue.
(dbxout_symbol): Put info for symbol's type in queue. Decrement/Increment
nesting counts flush symbol queue appropriately.
(dbxout_parms): Increment dbxout nesting.
(dbxout_reg_parms): Same.
* flags.h (flag_debug_only_used_symbols): New.
* toplev.c (flag_debug_only_used_symbols): New variable.
(lang_independent_options): Add entries for new option -feliminate-unused-debug-symbols.
* common.opt: Add entry for -feliminate-unused-debug-symbols.
* opts.c (common_handle_options): Same.
* config/rs6000/darwin.h (CC1_SPEC): Interpret -gused as -feliminate-unused-debug-symbols.
* doc/invoke.texi (Debugging Options): Document -feliminate-unused-debug-symbols.
2003-06-26 Roger Sayle <roger@eyesopen.com>
Jakub Jelinek <jakub@redhat.com>

View File

@ -241,6 +241,9 @@ Common
feliminate-dwarf2-dups
Common
feliminate-unused-debug-symbols
Common
feliminate-unused-debug-types
Common

View File

@ -93,6 +93,7 @@ do { \
#define CC1_SPEC "\
%{gused: -feliminate-unused-debug-symbols %<gused }\
%{static: %{Zdynamic: %e conflicting code gen style switches are used}}\
%{!static:%{!mdynamic-no-pic:-fPIC}}"

View File

@ -93,6 +93,17 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "xcoffout.h"
#endif
extern int flag_debug_only_used_symbols;
#undef DBXOUT_DECR_NESTING
#define DBXOUT_DECR_NESTING \
if (--debug_nesting == 0 && symbol_queue_index > 0) \
debug_flush_symbol_queue ()
#undef DBXOUT_DECR_NESTING_AND_RETURN
#define DBXOUT_DECR_NESTING_AND_RETURN(x) \
do {--debug_nesting; return (x);} while (0)
#ifndef ASM_STABS_OP
#define ASM_STABS_OP "\t.stabs\t"
#endif
@ -505,9 +516,6 @@ dbxout_init (input_file_name)
#ifdef DBX_OUTPUT_STANDARD_TYPES
DBX_OUTPUT_STANDARD_TYPES (syms);
#else
dbxout_symbol (TYPE_NAME (integer_type_node), 0);
dbxout_symbol (TYPE_NAME (char_type_node), 0);
#endif
/* Get all permanent types that have typedef names,
@ -705,7 +713,12 @@ dbxout_global_decl (decl)
if (TREE_CODE (decl) == VAR_DECL
&& ! DECL_EXTERNAL (decl)
&& DECL_RTL_SET_P (decl)) /* Not necessary? */
dbxout_symbol (decl, 0);
{
int saved_tree_used = TREE_USED (decl);
TREE_USED (decl) = 1;
dbxout_symbol (decl, 0);
TREE_USED (decl) = saved_tree_used;
}
}
/* At the end of compilation, finish writing the symbol table.
@ -719,6 +732,8 @@ dbxout_finish (filename)
#ifdef DBX_OUTPUT_MAIN_SOURCE_FILE_END
DBX_OUTPUT_MAIN_SOURCE_FILE_END (asmfile, filename);
#endif /* DBX_OUTPUT_MAIN_SOURCE_FILE_END */
debug_free_queue ();
}
/* Output floating point type values used by the 'R' stab letter.
@ -1125,6 +1140,7 @@ dbxout_range_type (type)
}
}
/* Output a reference to a type. If the type has not yet been
described in the dbx output, output its definition now.
For a type already defined, just refer to its definition
@ -1200,6 +1216,21 @@ dbxout_type (type, full)
#endif
}
if (flag_debug_only_used_symbols)
{
if ((TREE_CODE (type) == RECORD_TYPE
|| TREE_CODE (type) == UNION_TYPE
|| TREE_CODE (type) == QUAL_UNION_TYPE
|| TREE_CODE (type) == ENUMERAL_TYPE)
&& TYPE_STUB_DECL (type)
&& TREE_CODE_CLASS (TREE_CODE (TYPE_STUB_DECL (type))) == 'd'
&& ! DECL_IGNORED_P (TYPE_STUB_DECL (type)))
debug_queue_symbol (TYPE_STUB_DECL (type));
else if (TYPE_NAME (type)
&& TREE_CODE (TYPE_NAME (type)) == TYPE_DECL)
debug_queue_symbol (TYPE_NAME (type));
}
/* Output the number of this type, to refer to it. */
dbxout_type_index (type);
@ -1283,6 +1314,18 @@ dbxout_type (type, full)
}
else if (main_variant != TYPE_MAIN_VARIANT (type))
{
if (flag_debug_only_used_symbols)
{
tree orig_type = DECL_ORIGINAL_TYPE (TYPE_NAME (type));
if ((TREE_CODE (orig_type) == RECORD_TYPE
|| TREE_CODE (orig_type) == UNION_TYPE
|| TREE_CODE (orig_type) == QUAL_UNION_TYPE
|| TREE_CODE (orig_type) == ENUMERAL_TYPE)
&& TYPE_STUB_DECL (orig_type)
&& ! DECL_IGNORED_P (TYPE_STUB_DECL (orig_type)))
debug_queue_symbol (TYPE_STUB_DECL (orig_type));
}
/* 'type' is a typedef; output the type it refers to. */
dbxout_type (DECL_ORIGINAL_TYPE (TYPE_NAME (type)), 0);
return;
@ -1992,6 +2035,9 @@ dbxout_symbol (decl, local)
tree context = NULL_TREE;
int result = 0;
/* "Intercept" dbxout_symbol() calls like we do all debug_hooks. */
++debug_nesting;
/* Cast avoids warning in old compilers. */
current_sym_code = (STAB_CODE_TYPE) 0;
current_sym_value = 0;
@ -2001,7 +2047,62 @@ dbxout_symbol (decl, local)
if ((DECL_NAME (decl) == 0 && TREE_CODE (decl) != TYPE_DECL)
|| DECL_IGNORED_P (decl))
return 0;
DBXOUT_DECR_NESTING_AND_RETURN (0);
/* If we are to generate only the symbols actualy used then such
symbol nodees are flagged with TREE_USED. Ignore any that
aren't flaged as TREE_USED. */
if (flag_debug_only_used_symbols)
{
tree t;
if (!TREE_USED (decl)
&& (TREE_CODE (decl) != VAR_DECL || !DECL_INITIAL (decl)))
DBXOUT_DECR_NESTING_AND_RETURN (0);
/* We now have a used symbol. We need to generate the info for
the symbol's type in addition to the symbol itself. These
type symbols are queued to be generated after were done with
the symbol itself (done because the symbol's info is generated
with fprintf's, etc. as it determines what's needed).
Note, because the TREE_TYPE(type) might be something like a
pointer to a named type we need to look for the first name
we see following the TREE_TYPE chain. */
t = type;
while (POINTER_TYPE_P (t))
t = TREE_TYPE (t);
/* RECORD_TYPE, UNION_TYPE, QUAL_UNION_TYPE, and ENUMERAL_TYPE
need special treatment. The TYPE_STUB_DECL field in these
types generally represents the tag name type we want to
output. In addition there could be a typedef type with
a different name. In that case we also want to output
that. */
if ((TREE_CODE (t) == RECORD_TYPE
|| TREE_CODE (t) == UNION_TYPE
|| TREE_CODE (t) == QUAL_UNION_TYPE
|| TREE_CODE (t) == ENUMERAL_TYPE)
&& TYPE_STUB_DECL (t)
&& TYPE_STUB_DECL (t) != decl
&& TREE_CODE_CLASS (TREE_CODE (TYPE_STUB_DECL (t))) == 'd'
&& ! DECL_IGNORED_P (TYPE_STUB_DECL (t)))
{
debug_queue_symbol (TYPE_STUB_DECL (t));
if (TYPE_NAME (t)
&& TYPE_NAME (t) != TYPE_STUB_DECL (t)
&& TYPE_NAME (t) != decl
&& TREE_CODE_CLASS (TREE_CODE (TYPE_NAME (t))) == 'd')
debug_queue_symbol (TYPE_NAME (t));
}
else if (TYPE_NAME (t)
&& TYPE_NAME (t) != decl
&& TREE_CODE_CLASS (TREE_CODE (TYPE_NAME (t))) == 'd')
debug_queue_symbol (TYPE_NAME (t));
}
dbxout_prepare_symbol (decl);
@ -2019,7 +2120,7 @@ dbxout_symbol (decl, local)
case FUNCTION_DECL:
if (DECL_RTL (decl) == 0)
return 0;
DBXOUT_DECR_NESTING_AND_RETURN (0);
if (DECL_EXTERNAL (decl))
break;
/* Don't mention a nested function under its parent. */
@ -2056,22 +2157,10 @@ dbxout_symbol (decl, local)
break;
case TYPE_DECL:
#if 0
/* This seems all wrong. Outputting most kinds of types gives no name
at all. A true definition gives no name; a cross-ref for a
structure can give the tag name, but not a type name.
It seems that no typedef name is defined by outputting a type. */
/* If this typedef name was defined by outputting the type,
don't duplicate it. */
if (typevec[TYPE_SYMTAB_ADDRESS (type)].status == TYPE_DEFINED
&& TYPE_NAME (TREE_TYPE (decl)) == decl)
return 0;
#endif
/* Don't output the same typedef twice.
And don't output what language-specific stuff doesn't want output. */
if (TREE_ASM_WRITTEN (decl) || TYPE_DECL_SUPPRESS_DEBUG (decl))
return 0;
DBXOUT_DECR_NESTING_AND_RETURN (0);
FORCE_TEXT;
result = 1;
@ -2097,6 +2186,8 @@ dbxout_symbol (decl, local)
/* Distinguish the implicit typedefs of C++
from explicit ones that might be found in C. */
&& DECL_ARTIFICIAL (decl)
/* Do not generate a tag for incomplete records. */
&& COMPLETE_TYPE_P (type)
/* Do not generate a tag for records of variable size,
since this type can not be properly described in the
DBX format, and it confuses some tools such as objdump. */
@ -2218,7 +2309,7 @@ dbxout_symbol (decl, local)
/* Named return value, treat like a VAR_DECL. */
case VAR_DECL:
if (! DECL_RTL_SET_P (decl))
return 0;
DBXOUT_DECR_NESTING_AND_RETURN (0);
/* Don't mention a variable that is external.
Let the file that defines it describe it. */
if (DECL_EXTERNAL (decl))
@ -2245,6 +2336,7 @@ dbxout_symbol (decl, local)
fprintf (asmfile, "%s\"%s:c=i" HOST_WIDE_INT_PRINT_DEC
"\",0x%x,0,0,0\n",
ASM_STABS_OP, name, ival, N_LSYM);
DBXOUT_DECR_NESTING;
return 1;
}
else if (TREE_CODE (TREE_TYPE (decl)) == REAL_TYPE)
@ -2268,6 +2360,7 @@ dbxout_symbol (decl, local)
default:
break;
}
DBXOUT_DECR_NESTING;
return result;
}
@ -2604,6 +2697,8 @@ void
dbxout_parms (parms)
tree parms;
{
++debug_nesting;
for (; parms; parms = TREE_CHAIN (parms))
if (DECL_NAME (parms) && TREE_TYPE (parms) != error_mark_node)
{
@ -2861,6 +2956,7 @@ dbxout_parms (parms)
dbxout_finish_symbol (parms);
}
}
DBXOUT_DECR_NESTING;
}
/* Output definitions for the places where parms live during the function,
@ -2878,6 +2974,8 @@ void
dbxout_reg_parms (parms)
tree parms;
{
++debug_nesting;
for (; parms; parms = TREE_CHAIN (parms))
if (DECL_NAME (parms) && PARM_PASSED_IN_MEMORY (parms))
{
@ -2898,6 +2996,7 @@ dbxout_reg_parms (parms)
dbxout_symbol_location (parms, TREE_TYPE (parms),
0, DECL_RTL (parms));
}
DBXOUT_DECR_NESTING;
}
/* Given a chain of ..._TYPE nodes (as come in a parameter list),
@ -3035,7 +3134,19 @@ static void
dbxout_begin_function (decl)
tree decl;
{
dbxout_symbol (decl, 0);
int saved_tree_used1 = TREE_USED (decl);
TREE_USED (decl) = 1;
if (DECL_NAME (DECL_RESULT (decl)) != 0)
{
int saved_tree_used2 = TREE_USED (DECL_RESULT (decl));
TREE_USED (DECL_RESULT (decl)) = 1;
dbxout_symbol (decl, 0);
TREE_USED (DECL_RESULT (decl)) = saved_tree_used2;
}
else
dbxout_symbol (decl, 0);
TREE_USED (decl) = saved_tree_used1;
dbxout_parms (DECL_ARGUMENTS (decl));
if (DECL_NAME (DECL_RESULT (decl)) != 0)
dbxout_symbol (DECL_RESULT (decl), 1);

View File

@ -146,4 +146,10 @@ extern void dwarf2out_frame_finish PARAMS ((void));
translation unit. */
extern int dwarf2out_do_frame PARAMS ((void));
extern void debug_flush_symbol_queue PARAMS ((void));
extern void debug_queue_symbol PARAMS ((tree));
extern void debug_free_queue PARAMS ((void));
extern int debug_nesting;
extern int symbol_queue_index;
#endif /* !GCC_DEBUG_H */

View File

@ -244,7 +244,7 @@ in the following sections.
-fdump-tree-optimized@r{[}-@var{n}@r{]} @gol
-fdump-tree-inlined@r{[}-@var{n}@r{]} @gol
-feliminate-dwarf2-dups -feliminate-unused-debug-types @gol
-fmem-report -fprofile-arcs @gol
-feliminate-unused-debug-symbols -fmem-report -fprofile-arcs @gol
-frandom-seed=@var{string} -fsched-verbose=@var{n} @gol
-ftest-coverage -ftime-report @gol
-g -g@var{level} -gcoff -gdwarf -gdwarf-1 -gdwarf-1+ -gdwarf-2 @gol
@ -2916,6 +2916,11 @@ systems. On MIPS, Alpha and System V Release 4 systems this option
produces stabs debugging output which is not understood by DBX or SDB@.
On System V Release 4 systems this option requires the GNU assembler.
@item -feliminate-unused-debug-symbols
@opindex feliminate-unused-debug-symbols
Produce debugging information in stabs format (if that is supported),
for only symbols that are actualy used.
@item -gstabs+
@opindex gstabs+
Produce debugging information in stabs format (if that is supported),

View File

@ -81,6 +81,10 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "dwarf2out.h"
#endif
#ifdef DBX_DEBUGGING_INFO
#include "dbxout.h"
#endif
/* If we aren't using cc0, CC_STATUS_INIT shouldn't exist. So define a
null default for it to save conditionalization later. */
#ifndef CC_STATUS_INIT
@ -3847,3 +3851,85 @@ leaf_renumber_regs_insn (in_rtx)
}
}
#endif
/* When -gused is used, emit debug info for only used symbols. But in
addition to the standard intercepted debug_hooks there are some direct
calls into this file, i.e., dbxout_symbol, dbxout_parms, and dbxout_reg_params.
Those routines may also be called from a higher level intercepted routine. So
to prevent recording data for an inner call to one of these for an intercept,
we maintain a intercept nesting counter (debug_nesting). We only save the
intercepted arguments if the nesting is 1. */
int debug_nesting = 0;
static tree *symbol_queue;
int symbol_queue_index = 0;
static int symbol_queue_size = 0;
/* Generate the symbols for any queued up type symbols we encountered
while generating the type info for some originally used symbol.
This might generate additional entries in the queue. Only when
the nesting depth goes to 0 is this routine called. */
void
debug_flush_symbol_queue ()
{
int i;
/* Make sure that additionally queued items are not flushed
prematurely. */
++debug_nesting;
for (i = 0; i < symbol_queue_index; ++i)
{
/* If we pushed queued symbols then such symbols are must be
output no matter what anyone else says. Specifically,
we need to make sure dbxout_symbol() thinks the symbol was
used and also we need to override TYPE_DECL_SUPPRESS_DEBUG
which may be set for outside reasons. */
int saved_tree_used = TREE_USED (symbol_queue[i]);
int saved_suppress_debug = TYPE_DECL_SUPPRESS_DEBUG (symbol_queue[i]);
TREE_USED (symbol_queue[i]) = 1;
TYPE_DECL_SUPPRESS_DEBUG (symbol_queue[i]) = 0;
#ifdef DBX_DEBUGGING_INFO
dbxout_symbol (symbol_queue[i], 0);
#endif
TREE_USED (symbol_queue[i]) = saved_tree_used;
TYPE_DECL_SUPPRESS_DEBUG (symbol_queue[i]) = saved_suppress_debug;
}
symbol_queue_index = 0;
--debug_nesting;
}
/* Queue a type symbol needed as part of the definition of a decl
symbol. These symbols are generated when debug_flush_symbol_queue()
is called. */
void
debug_queue_symbol (tree decl)
{
if (symbol_queue_index >= symbol_queue_size)
{
symbol_queue_size += 10;
symbol_queue = (tree *) xrealloc (symbol_queue,
symbol_queue_size * sizeof (tree));
}
symbol_queue[symbol_queue_index++] = decl;
}
/* Free symbol queue */
void
debug_free_queue ()
{
if (symbol_queue)
{
free (symbol_queue);
symbol_queue = NULL;
symbol_queue_size = 0;
}
}

View File

@ -737,6 +737,10 @@ common_handle_option (size_t scode, const char *arg,
flag_eliminate_unused_debug_types = value;
break;
case OPT_feliminate_unused_debug_symbols:
flag_debug_only_used_symbols = value;
break;
case OPT_fexceptions:
flag_exceptions = value;
break;

View File

@ -402,6 +402,9 @@ int flag_eliminate_dwarf2_dups = 0;
int flag_eliminate_unused_debug_types = 1;
/* Nonzero means emit debugging information only for symbols which are used. */
int flag_debug_only_used_symbols = 0;
/* Nonzero if generating code to do profiling. */
int profile_flag = 0;
@ -1056,6 +1059,8 @@ static const lang_independent_options f_options[] =
N_("Perform DWARF2 duplicate elimination") },
{"eliminate-unused-debug-types", &flag_dummy, 1,
N_("Perform unused type elimination in debug info") },
{"eliminate-unused-debug-symbols", &flag_dummy, 1,
N_("Perform unused type elimination in debug info") },
{"float-store", &flag_dummy, 1,
N_("Do not store floats in registers") },
{"defer-pop", &flag_dummy, 1,
@ -4584,6 +4589,21 @@ general_init (char *argv0)
init_ggc ();
init_stringpool ();
init_ttree ();
/* APPLE LOCAL setrlimit */
#ifdef RLIMIT_STACK
/* Get rid of any avoidable limit on stack size. */
{
struct rlimit rlim;
/* Set the stack limit huge. (Compiles normally work within
a megabyte of stack, but the normal limit on OSX is 512K for
some reason.) */
getrlimit (RLIMIT_STACK, &rlim);
rlim.rlim_cur = rlim.rlim_max;
setrlimit (RLIMIT_STACK, &rlim);
}
#endif /* RLIMIT_STACK defined */
}
/* Parse command line options and set default flag values, called