re PR debug/39267 (gdb testsuite regressions)

PR debug/39267
	* tree.h (TREE_PROTECTED): Fix comment.
	(BLOCK_HANDLER_BLOCK): Remove.
	(struct tree_block): Remove handler_block add body_block.
	(inlined_function_outer_scope_p): New.
	(is_body_block): Remove.
	* dbxout.c (dbxout_block): Remove BLOCK_HANDLER_BLOCK.
	* dwarf2out.c (is_inlined_entry_point): Remove.
	(add_high_low_attributes): Use inlined_function_outer_scope_p.
	(gen_block_die): Use is_inlined_entry_point check; remove body block code.
	* langhooks.h (struct lang_hooks): Remove no_bodu_blocks.
	* gimplify.c (gimplify_expr): Gimplify body blocks.
	* tree-ssa-live.c (remove_unused_scope_block_p): Allow removing wrapper block
	with multiple subblocks.
	(dump_scope_block): Prettier output; dump more flags and info.
	(dump_scope_blocks): New.
	(remove_unused_locals): Use dump_scope_blocks.
	* tree-flow.h (dump_scope_blocks): Declare.
	* tree-cfg.c (execute_build_cfg): Dump scope blocks.
	* stmt.c (is_body_block): Remove.
	* tree-inline.c (remap_block): Copy BODY_BLOCK info.
	* langhooks-def.h (LANG_HOOKS_NO_BODY_BLOCKS): Remove.

From-SVN: r144474
This commit is contained in:
Jan Hubicka 2009-02-27 20:49:42 +01:00 committed by Jan Hubicka
parent c20993b995
commit cff7525fb0
12 changed files with 140 additions and 162 deletions

View File

@ -1,3 +1,28 @@
2009-02-27 Jan Hubicka <jh@suse.cz>
PR debug/39267
* tree.h (TREE_PROTECTED): Fix comment.
(BLOCK_HANDLER_BLOCK): Remove.
(struct tree_block): Remove handler_block add body_block.
(inlined_function_outer_scope_p): New.
(is_body_block): Remove.
* dbxout.c (dbxout_block): Remove BLOCK_HANDLER_BLOCK.
* dwarf2out.c (is_inlined_entry_point): Remove.
(add_high_low_attributes): Use inlined_function_outer_scope_p.
(gen_block_die): Use is_inlined_entry_point check; remove body block code.
* langhooks.h (struct lang_hooks): Remove no_bodu_blocks.
* gimplify.c (gimplify_expr): Gimplify body blocks.
* tree-ssa-live.c (remove_unused_scope_block_p): Allow removing wrapper block
with multiple subblocks.
(dump_scope_block): Prettier output; dump more flags and info.
(dump_scope_blocks): New.
(remove_unused_locals): Use dump_scope_blocks.
* tree-flow.h (dump_scope_blocks): Declare.
* tree-cfg.c (execute_build_cfg): Dump scope blocks.
* stmt.c (is_body_block): Remove.
* tree-inline.c (remap_block): Copy BODY_BLOCK info.
* langhooks-def.h (LANG_HOOKS_NO_BODY_BLOCKS): Remove.
2009-02-27 Sebastian Pop <sebastian.pop@amd.com>
PR middle-end/39308

View File

@ -7740,6 +7740,7 @@ complete_array_type (tree *ptype, tree initial_value, bool do_default)
tree curindex;
unsigned HOST_WIDE_INT cnt;
constructor_elt *ce;
bool fold_p = false;
if (VEC_index (constructor_elt, v, 0)->index)
maxindex = fold_convert (sizetype,
@ -7751,14 +7752,20 @@ complete_array_type (tree *ptype, tree initial_value, bool do_default)
VEC_iterate (constructor_elt, v, cnt, ce);
cnt++)
{
bool curfold_p = false;
if (ce->index)
curindex = fold_convert (sizetype, ce->index);
curindex = ce->index, curfold_p = true;
else
curindex = size_binop (PLUS_EXPR, curindex, size_one_node);
{
if (fold_p)
curindex = fold_convert (sizetype, curindex);
curindex = size_binop (PLUS_EXPR, curindex, size_one_node);
}
if (tree_int_cst_lt (maxindex, curindex))
maxindex = curindex;
maxindex = curindex, fold_p = curfold_p;
}
if (fold_p)
maxindex = fold_convert (sizetype, maxindex);
}
}
else

View File

@ -53,8 +53,6 @@ extern void c_initialize_diagnostics (diagnostic_context *);
#define LANG_HOOKS_FINISH_INCOMPLETE_DECL c_finish_incomplete_decl
#undef LANG_HOOKS_STATICP
#define LANG_HOOKS_STATICP c_staticp
#undef LANG_HOOKS_NO_BODY_BLOCKS
#define LANG_HOOKS_NO_BODY_BLOCKS true
#undef LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL
#define LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL c_warn_unused_global_decl
#undef LANG_HOOKS_PRINT_IDENTIFIER

View File

@ -3625,20 +3625,6 @@ dbxout_block (tree block, int depth, tree args)
scope_start = buf;
}
if (BLOCK_HANDLER_BLOCK (block))
{
/* A catch block. Must precede N_LBRAC. */
tree decl = BLOCK_VARS (block);
while (decl)
{
dbxout_begin_complex_stabs ();
stabstr_I (DECL_NAME (decl));
stabstr_S (":C1");
dbxout_finish_complex_stabs (0, N_CATCH, 0,
scope_start, 0);
decl = TREE_CHAIN (decl);
}
}
dbx_output_lbrac (scope_start, begin_label);
}

View File

@ -14135,35 +14135,6 @@ add_call_src_coords_attributes (tree stmt, dw_die_ref die)
}
/* If STMT's abstract origin is a function declaration and STMT's
first subblock's abstract origin is the function's outermost block,
then we're looking at the main entry point. */
static bool
is_inlined_entry_point (const_tree stmt)
{
tree decl, block;
if (!stmt || TREE_CODE (stmt) != BLOCK)
return false;
decl = block_ultimate_origin (stmt);
if (!decl || TREE_CODE (decl) != FUNCTION_DECL)
return false;
block = BLOCK_SUBBLOCKS (stmt);
if (block)
{
if (TREE_CODE (block) != BLOCK)
return false;
block = block_ultimate_origin (block);
}
return block == DECL_INITIAL (decl);
}
/* A helper function for gen_lexical_block_die and gen_inlined_subroutine_die.
Add low_pc and high_pc attributes to the DIE for a block STMT. */
@ -14176,7 +14147,7 @@ add_high_low_attributes (tree stmt, dw_die_ref die)
{
tree chain;
if (is_inlined_entry_point (stmt))
if (inlined_function_outer_scope_p (stmt))
{
ASM_GENERATE_INTERNAL_LABEL (label, BLOCK_BEGIN_LABEL,
BLOCK_NUMBER (stmt));
@ -14861,14 +14832,15 @@ static void
gen_block_die (tree stmt, dw_die_ref context_die, int depth)
{
int must_output_die = 0;
tree origin;
tree decl;
enum tree_code origin_code;
bool inlined_func;
/* Ignore blocks that are NULL. */
if (stmt == NULL_TREE)
return;
inlined_func = inlined_function_outer_scope_p (stmt);
/* If the block is one fragment of a non-contiguous block, do not
process the variables, since they will have been done by the
origin block. Do process subblocks. */
@ -14882,52 +14854,34 @@ gen_block_die (tree stmt, dw_die_ref context_die, int depth)
return;
}
/* Determine the "ultimate origin" of this block. This block may be an
inlined instance of an inlined instance of inline function, so we have
to trace all of the way back through the origin chain to find out what
sort of node actually served as the original seed for the creation of
the current block. */
origin = block_ultimate_origin (stmt);
origin_code = (origin != NULL) ? TREE_CODE (origin) : ERROR_MARK;
/* Determine if we need to output any Dwarf DIEs at all to represent this
block. */
if (origin_code == FUNCTION_DECL)
if (inlined_func)
/* The outer scopes for inlinings *must* always be represented. We
generate DW_TAG_inlined_subroutine DIEs for them. (See below.) */
must_output_die = 1;
else
{
/* In the case where the current block represents an inlining of the
"body block" of an inline function, we must *NOT* output any DIE for
this block because we have already output a DIE to represent the whole
inlined function scope and the "body block" of any function doesn't
really represent a different scope according to ANSI C rules. So we
check here to make sure that this block does not represent a "body
block inlining" before trying to set the MUST_OUTPUT_DIE flag. */
if (! is_body_block (origin ? origin : stmt))
{
/* Determine if this block directly contains any "significant"
local declarations which we will need to output DIEs for. */
if (debug_info_level > DINFO_LEVEL_TERSE)
/* We are not in terse mode so *any* local declaration counts
as being a "significant" one. */
must_output_die = (BLOCK_VARS (stmt) != NULL
&& (TREE_USED (stmt)
|| TREE_ASM_WRITTEN (stmt)
|| BLOCK_ABSTRACT (stmt)));
else
/* We are in terse mode, so only local (nested) function
definitions count as "significant" local declarations. */
for (decl = BLOCK_VARS (stmt);
decl != NULL; decl = TREE_CHAIN (decl))
if (TREE_CODE (decl) == FUNCTION_DECL
&& DECL_INITIAL (decl))
{
must_output_die = 1;
break;
}
}
/* Determine if this block directly contains any "significant"
local declarations which we will need to output DIEs for. */
if (debug_info_level > DINFO_LEVEL_TERSE)
/* We are not in terse mode so *any* local declaration counts
as being a "significant" one. */
must_output_die = (BLOCK_VARS (stmt) != NULL
&& (TREE_USED (stmt)
|| TREE_ASM_WRITTEN (stmt)
|| BLOCK_ABSTRACT (stmt)));
else
/* We are in terse mode, so only local (nested) function
definitions count as "significant" local declarations. */
for (decl = BLOCK_VARS (stmt);
decl != NULL; decl = TREE_CHAIN (decl))
if (TREE_CODE (decl) == FUNCTION_DECL
&& DECL_INITIAL (decl))
{
must_output_die = 1;
break;
}
}
/* It would be a waste of space to generate a Dwarf DW_TAG_lexical_block
@ -14939,7 +14893,7 @@ gen_block_die (tree stmt, dw_die_ref context_die, int depth)
instances and local (nested) function definitions. */
if (must_output_die)
{
if (origin_code == FUNCTION_DECL)
if (inlined_func)
gen_inlined_subroutine_die (stmt, context_die, depth);
else
gen_lexical_block_die (stmt, context_die, depth);

View File

@ -97,7 +97,6 @@ extern void lhd_omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *,
#define LANG_HOOKS_STATICP lhd_staticp
#define LANG_HOOKS_DUP_LANG_SPECIFIC_DECL lhd_do_nothing_t
#define LANG_HOOKS_SET_DECL_ASSEMBLER_NAME lhd_set_decl_assembler_name
#define LANG_HOOKS_NO_BODY_BLOCKS false
#define LANG_HOOKS_PRINT_STATISTICS lhd_do_nothing
#define LANG_HOOKS_PRINT_XNODE lhd_print_tree_nothing
#define LANG_HOOKS_PRINT_DECL lhd_print_tree_nothing
@ -246,7 +245,6 @@ extern tree lhd_make_node (enum tree_code);
LANG_HOOKS_STATICP, \
LANG_HOOKS_DUP_LANG_SPECIFIC_DECL, \
LANG_HOOKS_SET_DECL_ASSEMBLER_NAME, \
LANG_HOOKS_NO_BODY_BLOCKS, \
LANG_HOOKS_PRINT_STATISTICS, \
LANG_HOOKS_PRINT_XNODE, \
LANG_HOOKS_PRINT_DECL, \

View File

@ -317,11 +317,6 @@ struct lang_hooks
assembler does not talk about it. */
void (*set_decl_assembler_name) (tree);
/* Nonzero if this front end does not generate a dummy BLOCK between
the outermost scope of the function and the FUNCTION_DECL. See
is_body_block in stmt.c, and its callers. */
bool no_body_blocks;
/* The front end can add its own statistics to -fmem-report with
this hook. It should output to stderr. */
void (*print_statistics) (void);

View File

@ -1724,38 +1724,6 @@ expand_return (tree retval)
}
}
/* Given a pointer to a BLOCK node return nonzero if (and only if) the node
in question represents the outermost pair of curly braces (i.e. the "body
block") of a function or method.
For any BLOCK node representing a "body block" of a function or method, the
BLOCK_SUPERCONTEXT of the node will point to another BLOCK node which
represents the outermost (function) scope for the function or method (i.e.
the one which includes the formal parameters). The BLOCK_SUPERCONTEXT of
*that* node in turn will point to the relevant FUNCTION_DECL node. */
int
is_body_block (const_tree stmt)
{
if (lang_hooks.no_body_blocks)
return 0;
if (TREE_CODE (stmt) == BLOCK)
{
tree parent = BLOCK_SUPERCONTEXT (stmt);
if (parent && TREE_CODE (parent) == BLOCK)
{
tree grandparent = BLOCK_SUPERCONTEXT (parent);
if (grandparent && TREE_CODE (grandparent) == FUNCTION_DECL)
return 1;
}
}
return 0;
}
/* Emit code to restore vital registers at the beginning of a nonlocal goto
handler. */
static void

View File

@ -221,6 +221,11 @@ execute_build_cfg (void)
build_gimple_cfg (body);
gimple_set_body (current_function_decl, NULL);
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Scope blocks:\n");
dump_scope_blocks (dump_file, dump_flags);
}
return 0;
}

View File

@ -1153,6 +1153,7 @@ void compute_call_used_vars (void);
/* In tree-ssa-live.c */
extern void remove_unused_locals (void);
extern void dump_scope_blocks (FILE *, int);
/* In tree-ssa-address.c */

View File

@ -541,8 +541,13 @@ remove_unused_scope_block_p (tree scope)
{
tree next = BLOCK_CHAIN (*t);
tree supercontext = BLOCK_SUPERCONTEXT (*t);
*t = BLOCK_SUBBLOCKS (*t);
gcc_assert (!BLOCK_CHAIN (*t));
while (BLOCK_CHAIN (*t))
{
BLOCK_SUPERCONTEXT (*t) = supercontext;
t = &BLOCK_CHAIN (*t);
}
BLOCK_CHAIN (*t) = next;
BLOCK_SUPERCONTEXT (*t) = supercontext;
t = &BLOCK_CHAIN (*t);
@ -556,23 +561,40 @@ remove_unused_scope_block_p (tree scope)
t = &BLOCK_CHAIN (*t);
nsubblocks ++;
}
if (!unused)
;
/* Outer scope is always used. */
if (!BLOCK_SUPERCONTEXT (scope)
|| TREE_CODE (BLOCK_SUPERCONTEXT (scope)) == FUNCTION_DECL)
else if (!BLOCK_SUPERCONTEXT (scope)
|| TREE_CODE (BLOCK_SUPERCONTEXT (scope)) == FUNCTION_DECL)
unused = false;
/* If there are more than one live subblocks, it is used. */
else if (nsubblocks > 1)
/* Innermost blocks with no live variables nor statements can be always
eliminated. */
else if (!nsubblocks)
;
/* If there are live subblocks and we still have some unused variables
or types declared, we must keep them.
Before inliing we must not depend on debug info verbosity to keep
DECL_UIDs stable. */
else if (!cfun->after_inlining && BLOCK_VARS (scope))
unused = false;
/* When there is only one subblock, see if it is just wrapper we can
ignore. Wrappers are not declaring any variables and not changing
abstract origin. */
else if (nsubblocks == 1
&& (BLOCK_VARS (scope)
|| ((debug_info_level == DINFO_LEVEL_NORMAL
|| debug_info_level == DINFO_LEVEL_VERBOSE)
&& ((BLOCK_ABSTRACT_ORIGIN (scope)
!= BLOCK_ABSTRACT_ORIGIN (BLOCK_SUPERCONTEXT (scope)))))))
/* For terse debug info we can eliminate info on unused variables. */
else if (debug_info_level == DINFO_LEVEL_NONE
|| debug_info_level == DINFO_LEVEL_TERSE)
;
else if (BLOCK_VARS (scope))
unused = false;
/* See if this block is important for representation of inlined function.
Inlined functions are always represented by block with
block_ultimate_origin being set to FUNCTION_DECL and DECL_SOURCE_LOCATION
set... */
else if (inlined_function_outer_scope_p (scope))
unused = false;
else
/* Verfify that only blocks with source location set
are entry points to the inlined functions. */
gcc_assert (BLOCK_SOURCE_LOCATION (scope) == UNKNOWN_LOCATION);
return unused;
}
@ -592,14 +614,27 @@ dump_scope_block (FILE *file, int indent, tree scope, int flags)
{
tree var, t;
fprintf (file, "\n%*sScope block #%i %s\n",indent, "" , BLOCK_NUMBER (scope),
TREE_USED (scope) ? "" : "(unused)");
if (BLOCK_ABSTRACT_ORIGIN (scope) && DECL_P (block_ultimate_origin (scope)))
fprintf (file, "\n%*s{ Scope block #%i%s%s",indent, "" , BLOCK_NUMBER (scope),
TREE_USED (scope) ? "" : " (unused)",
BLOCK_ABSTRACT (scope) ? " (abstract)": "");
if (BLOCK_SOURCE_LOCATION (scope) != UNKNOWN_LOCATION)
{
fprintf (file, "\n%*sOriginating from ",indent + 1, "");
print_generic_decl (file, block_ultimate_origin (scope), flags);
fprintf (file, "\n");
expanded_location s = expand_location (BLOCK_SOURCE_LOCATION (scope));
fprintf (file, " %s:%i", s.file, s.line);
}
if (BLOCK_ABSTRACT_ORIGIN (scope))
{
tree origin = block_ultimate_origin (scope);
if (origin)
{
fprintf (file, " Originating from :");
if (DECL_P (origin))
print_generic_decl (file, origin, flags);
else
fprintf (file, "#%i", BLOCK_NUMBER (origin));
}
}
fprintf (file, " \n");
for (var = BLOCK_VARS (scope); var; var = TREE_CHAIN (var))
{
bool used = false;
@ -615,8 +650,14 @@ dump_scope_block (FILE *file, int indent, tree scope, int flags)
}
for (t = BLOCK_SUBBLOCKS (scope); t ; t = BLOCK_CHAIN (t))
dump_scope_block (file, indent + 2, t, flags);
fprintf (file, "\n%*s}\n",indent, "");
}
void
dump_scope_blocks (FILE *file, int flags)
{
dump_scope_block (file, 0, DECL_INITIAL (current_function_decl), flags);
}
/* Remove local variables that are not referenced in the IL. */
@ -760,7 +801,7 @@ remove_unused_locals (void)
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Scope blocks after cleanups:\n");
dump_scope_block (dump_file, 0, DECL_INITIAL (current_function_decl), false);
dump_scope_blocks (dump_file, dump_flags);
}
}

View File

@ -1324,8 +1324,7 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int,
/* Used in classes in C++. */
#define TREE_PRIVATE(NODE) ((NODE)->base.private_flag)
/* Used in classes in C++.
In a BLOCK node, this is BLOCK_HANDLER_BLOCK. */
/* Used in classes in C++. */
#define TREE_PROTECTED(NODE) ((NODE)->base.protected_flag)
/* Nonzero in a _DECL if the use of the name is defined as a
@ -1977,11 +1976,6 @@ struct varray_head_tag;
#define BLOCK_ABSTRACT_ORIGIN(NODE) (BLOCK_CHECK (NODE)->block.abstract_origin)
#define BLOCK_ABSTRACT(NODE) (BLOCK_CHECK (NODE)->block.abstract_flag)
/* Nonzero means that this block is prepared to handle exceptions
listed in the BLOCK_VARS slot. */
#define BLOCK_HANDLER_BLOCK(NODE) \
(BLOCK_CHECK (NODE)->block.handler_block_flag)
/* An index number for this block. These values are not guaranteed to
be unique across functions -- whether or not they are depends on
the debugging output format in use. */
@ -2022,9 +2016,8 @@ struct tree_block GTY(())
{
struct tree_common common;
unsigned handler_block_flag : 1;
unsigned abstract_flag : 1;
unsigned block_num : 30;
unsigned block_num : 31;
location_t locus;
@ -4657,6 +4650,14 @@ function_args_iter_next (function_args_iterator *i)
i->next = TREE_CHAIN (i->next);
}
/* We set BLOCK_SOURCE_LOCATION only to inlined function entry points. */
static inline bool
inlined_function_outer_scope_p (const_tree block)
{
return BLOCK_SOURCE_LOCATION (block) != UNKNOWN_LOCATION;
}
/* Loop over all function arguments of FNTYPE. In each iteration, PTR is set
to point to the next tree element. ITER is an instance of
function_args_iterator used to iterate the arguments. */
@ -4710,7 +4711,6 @@ extern void expand_goto (tree);
extern rtx expand_stack_save (void);
extern void expand_stack_restore (tree);
extern void expand_return (tree);
extern int is_body_block (const_tree);
/* In tree-eh.c */
extern void using_eh_for_cleanups (void);