Commit 526d73ab by Jan Hubicka Committed by Jan Hubicka

re PR debug/39267 (gdb testsuite regressions)


	PR debug/39267
	* tree.h (BLOCK_NONLOCALIZED_VARS, BLOCK_NUM_NONLOCALIZED_VARS,
	BLOCK_NONLOCALIZED_VAR): New macros.
	(tree_block): Add nonlocalized_vars.
	* dwarf2out.c (gen_formal_parameter_die, gen_variable_die, gen_decl_die): Add
	origin argument; allow generation of die with origin at hand only.
	(gen_member_die, gen_type_die_with_usage, force_decl_die,
	declare_in_namespace, gen_namescpace_die, dwarf2out_decl): Update use of gen_*.
	(gen_block_die): Fix checking for unused blocks.
	(process_scope_var): Break out from .... ; work with origins only.
	(decls_for_scope) ... here; process nonlocalized list.
	(dwarf2out_ignore_block): Look for nonlocalized vars.
	* tree-ssa-live.c (remove_unused_scope_block_p): Look for nonlocalized vars.
	(dump_scope_block): Dump them.
	* tree-inline.c (remap_decls): Handle nonlocalized vars.
	(remap_block): Likewise.
	(can_be_nonlocal): New predicate.
	(copy_bind_expr, copy_gimple_bind): Update use of remap_block.

From-SVN: r144529
parent 7a9d3fe8
2009-03-01 Jan Hubicka <jh@suse.cz>
PR debug/39267
* tree.h (BLOCK_NONLOCALIZED_VARS, BLOCK_NUM_NONLOCALIZED_VARS,
BLOCK_NONLOCALIZED_VAR): New macros.
(tree_block): Add nonlocalized_vars.
* dwarf2out.c (gen_formal_parameter_die, gen_variable_die, gen_decl_die): Add
origin argument; allow generation of die with origin at hand only.
(gen_member_die, gen_type_die_with_usage, force_decl_die,
declare_in_namespace, gen_namescpace_die, dwarf2out_decl): Update use of gen_*.
(gen_block_die): Fix checking for unused blocks.
(process_scope_var): Break out from .... ; work with origins only.
(decls_for_scope) ... here; process nonlocalized list.
(dwarf2out_ignore_block): Look for nonlocalized vars.
* tree-ssa-live.c (remove_unused_scope_block_p): Look for nonlocalized vars.
(dump_scope_block): Dump them.
* tree-inline.c (remap_decls): Handle nonlocalized vars.
(remap_block): Likewise.
(can_be_nonlocal): New predicate.
(copy_bind_expr, copy_gimple_bind): Update use of remap_block.
2009-03-01 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> 2009-03-01 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
* configure: Regenerate. * configure: Regenerate.
......
...@@ -5153,11 +5153,11 @@ static void gen_inlined_enumeration_type_die (tree, dw_die_ref); ...@@ -5153,11 +5153,11 @@ static void gen_inlined_enumeration_type_die (tree, dw_die_ref);
static void gen_inlined_structure_type_die (tree, dw_die_ref); static void gen_inlined_structure_type_die (tree, dw_die_ref);
static void gen_inlined_union_type_die (tree, dw_die_ref); static void gen_inlined_union_type_die (tree, dw_die_ref);
static dw_die_ref gen_enumeration_type_die (tree, dw_die_ref); static dw_die_ref gen_enumeration_type_die (tree, dw_die_ref);
static dw_die_ref gen_formal_parameter_die (tree, dw_die_ref); static dw_die_ref gen_formal_parameter_die (tree, tree, dw_die_ref);
static void gen_unspecified_parameters_die (tree, dw_die_ref); static void gen_unspecified_parameters_die (tree, dw_die_ref);
static void gen_formal_types_die (tree, dw_die_ref); static void gen_formal_types_die (tree, dw_die_ref);
static void gen_subprogram_die (tree, dw_die_ref); static void gen_subprogram_die (tree, dw_die_ref);
static void gen_variable_die (tree, dw_die_ref); static void gen_variable_die (tree, tree, dw_die_ref);
static void gen_const_die (tree, dw_die_ref); static void gen_const_die (tree, dw_die_ref);
static void gen_label_die (tree, dw_die_ref); static void gen_label_die (tree, dw_die_ref);
static void gen_lexical_block_die (tree, dw_die_ref, int); static void gen_lexical_block_die (tree, dw_die_ref, int);
...@@ -5177,7 +5177,7 @@ static void gen_block_die (tree, dw_die_ref, int); ...@@ -5177,7 +5177,7 @@ static void gen_block_die (tree, dw_die_ref, int);
static void decls_for_scope (tree, dw_die_ref, int); static void decls_for_scope (tree, dw_die_ref, int);
static int is_redundant_typedef (const_tree); static int is_redundant_typedef (const_tree);
static void gen_namespace_die (tree); static void gen_namespace_die (tree);
static void gen_decl_die (tree, dw_die_ref); static void gen_decl_die (tree, tree, dw_die_ref);
static dw_die_ref force_decl_die (tree); static dw_die_ref force_decl_die (tree);
static dw_die_ref force_type_die (tree); static dw_die_ref force_type_die (tree);
static dw_die_ref setup_namespace_context (tree, dw_die_ref); static dw_die_ref setup_namespace_context (tree, dw_die_ref);
...@@ -13293,15 +13293,16 @@ gen_enumeration_type_die (tree type, dw_die_ref context_die) ...@@ -13293,15 +13293,16 @@ gen_enumeration_type_die (tree type, dw_die_ref context_die)
argument type of some subprogram type. */ argument type of some subprogram type. */
static dw_die_ref static dw_die_ref
gen_formal_parameter_die (tree node, dw_die_ref context_die) gen_formal_parameter_die (tree node, tree origin, dw_die_ref context_die)
{ {
tree node_or_origin = node ? node : origin;
dw_die_ref parm_die dw_die_ref parm_die
= new_die (DW_TAG_formal_parameter, context_die, node); = new_die (DW_TAG_formal_parameter, context_die, node);
tree origin;
switch (TREE_CODE_CLASS (TREE_CODE (node))) switch (TREE_CODE_CLASS (TREE_CODE (node_or_origin)))
{ {
case tcc_declaration: case tcc_declaration:
if (!origin)
origin = decl_ultimate_origin (node); origin = decl_ultimate_origin (node);
if (origin != NULL) if (origin != NULL)
add_abstract_origin_attribute (parm_die, origin); add_abstract_origin_attribute (parm_die, origin);
...@@ -13321,15 +13322,17 @@ gen_formal_parameter_die (tree node, dw_die_ref context_die) ...@@ -13321,15 +13322,17 @@ gen_formal_parameter_die (tree node, dw_die_ref context_die)
add_AT_flag (parm_die, DW_AT_artificial, 1); add_AT_flag (parm_die, DW_AT_artificial, 1);
} }
if (node)
equate_decl_number_to_die (node, parm_die); equate_decl_number_to_die (node, parm_die);
if (! DECL_ABSTRACT (node)) if (! DECL_ABSTRACT (node_or_origin))
add_location_or_const_value_attribute (parm_die, node, DW_AT_location); add_location_or_const_value_attribute (parm_die, node_or_origin,
DW_AT_location);
break; break;
case tcc_type: case tcc_type:
/* We were called with some kind of a ..._TYPE node. */ /* We were called with some kind of a ..._TYPE node. */
add_type_attribute (parm_die, node, 0, 0, context_die); add_type_attribute (parm_die, node_or_origin, 0, 0, context_die);
break; break;
default: default:
...@@ -13382,7 +13385,7 @@ gen_formal_types_die (tree function_or_method_type, dw_die_ref context_die) ...@@ -13382,7 +13385,7 @@ gen_formal_types_die (tree function_or_method_type, dw_die_ref context_die)
break; break;
/* Output a (nameless) DIE to represent the formal parameter itself. */ /* Output a (nameless) DIE to represent the formal parameter itself. */
parm_die = gen_formal_parameter_die (formal_type, context_die); parm_die = gen_formal_parameter_die (formal_type, NULL, context_die);
if ((TREE_CODE (function_or_method_type) == METHOD_TYPE if ((TREE_CODE (function_or_method_type) == METHOD_TYPE
&& link == first_parm_type) && link == first_parm_type)
|| (arg && DECL_ARTIFICIAL (arg))) || (arg && DECL_ARTIFICIAL (arg)))
...@@ -13442,7 +13445,7 @@ gen_type_die_for_member (tree type, tree member, dw_die_ref context_die) ...@@ -13442,7 +13445,7 @@ gen_type_die_for_member (tree type, tree member, dw_die_ref context_die)
} }
} }
else else
gen_variable_die (member, type_die); gen_variable_die (member, NULL_TREE, type_die);
pop_decl_scope (); pop_decl_scope ();
} }
...@@ -13787,7 +13790,7 @@ gen_subprogram_die (tree decl, dw_die_ref context_die) ...@@ -13787,7 +13790,7 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
"__builtin_va_alist")) "__builtin_va_alist"))
gen_unspecified_parameters_die (parm, subr_die); gen_unspecified_parameters_die (parm, subr_die);
else else
gen_decl_die (parm, subr_die); gen_decl_die (parm, NULL, subr_die);
} }
/* Decide whether we need an unspecified_parameters DIE at the end. /* Decide whether we need an unspecified_parameters DIE at the end.
...@@ -13829,7 +13832,7 @@ gen_subprogram_die (tree decl, dw_die_ref context_die) ...@@ -13829,7 +13832,7 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
{ {
/* Emit a DW_TAG_variable DIE for a named return value. */ /* Emit a DW_TAG_variable DIE for a named return value. */
if (DECL_NAME (DECL_RESULT (decl))) if (DECL_NAME (DECL_RESULT (decl)))
gen_decl_die (DECL_RESULT (decl), subr_die); gen_decl_die (DECL_RESULT (decl), NULL, subr_die);
current_function_has_inlines = 0; current_function_has_inlines = 0;
decls_for_scope (outer_scope, subr_die, 0); decls_for_scope (outer_scope, subr_die, 0);
...@@ -13871,17 +13874,18 @@ common_block_die_table_eq (const void *x, const void *y) ...@@ -13871,17 +13874,18 @@ common_block_die_table_eq (const void *x, const void *y)
return d->decl_id == e->decl_id && d->die_parent == e->die_parent; return d->decl_id == e->decl_id && d->die_parent == e->die_parent;
} }
/* Generate a DIE to represent a declared data object. */ /* Generate a DIE to represent a declared data object.
Either DECL or ORIGIN must be non-null. */
static void static void
gen_variable_die (tree decl, dw_die_ref context_die) gen_variable_die (tree decl, tree origin, dw_die_ref context_die)
{ {
HOST_WIDE_INT off; HOST_WIDE_INT off;
tree com_decl; tree com_decl;
tree decl_or_origin = decl ? decl : origin;
dw_die_ref var_die; dw_die_ref var_die;
tree origin = decl_ultimate_origin (decl); dw_die_ref old_die = decl ? lookup_decl_die (decl) : NULL;
dw_die_ref old_die = lookup_decl_die (decl); int declaration = (DECL_EXTERNAL (decl_or_origin)
int declaration = (DECL_EXTERNAL (decl)
/* If DECL is COMDAT and has not actually been /* If DECL is COMDAT and has not actually been
emitted, we cannot take its address; there emitted, we cannot take its address; there
might end up being no definition anywhere in might end up being no definition anywhere in
...@@ -13899,11 +13903,15 @@ gen_variable_die (tree decl, dw_die_ref context_die) ...@@ -13899,11 +13903,15 @@ gen_variable_die (tree decl, dw_die_ref context_die)
Here, S<int>::i is not DECL_EXTERNAL, but no Here, S<int>::i is not DECL_EXTERNAL, but no
definition is required, so the compiler will definition is required, so the compiler will
not emit a definition. */ not emit a definition. */
|| (TREE_CODE (decl) == VAR_DECL || (TREE_CODE (decl_or_origin) == VAR_DECL
&& DECL_COMDAT (decl) && !TREE_ASM_WRITTEN (decl)) && DECL_COMDAT (decl_or_origin)
&& !TREE_ASM_WRITTEN (decl_or_origin))
|| class_or_namespace_scope_p (context_die)); || class_or_namespace_scope_p (context_die));
com_decl = fortran_common (decl, &off); if (!origin)
origin = decl_ultimate_origin (decl);
com_decl = fortran_common (decl_or_origin, &off);
/* Symbol in common gets emitted as a child of the common block, in the form /* Symbol in common gets emitted as a child of the common block, in the form
of a data member. */ of a data member. */
...@@ -13914,7 +13922,7 @@ gen_variable_die (tree decl, dw_die_ref context_die) ...@@ -13914,7 +13922,7 @@ gen_variable_die (tree decl, dw_die_ref context_die)
dw_loc_descr_ref loc; dw_loc_descr_ref loc;
die_node com_die_arg; die_node com_die_arg;
var_die = lookup_decl_die (decl); var_die = lookup_decl_die (decl_or_origin);
if (var_die) if (var_die)
{ {
if (get_AT (var_die, DW_AT_location) == NULL) if (get_AT (var_die, DW_AT_location) == NULL)
...@@ -14071,20 +14079,22 @@ gen_variable_die (tree decl, dw_die_ref context_die) ...@@ -14071,20 +14079,22 @@ gen_variable_die (tree decl, dw_die_ref context_die)
if (declaration) if (declaration)
add_AT_flag (var_die, DW_AT_declaration, 1); add_AT_flag (var_die, DW_AT_declaration, 1);
if (DECL_ABSTRACT (decl) || declaration) if (decl && (DECL_ABSTRACT (decl) || declaration))
equate_decl_number_to_die (decl, var_die); equate_decl_number_to_die (decl, var_die);
if (! declaration && ! DECL_ABSTRACT (decl)) if (! declaration && ! DECL_ABSTRACT (decl_or_origin))
{ {
if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl) if (TREE_CODE (decl_or_origin) == VAR_DECL && TREE_STATIC (decl_or_origin)
&& !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))) && !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl_or_origin)))
defer_location (decl, var_die); defer_location (decl_or_origin, var_die);
else else
add_location_or_const_value_attribute (var_die, decl, DW_AT_location); add_location_or_const_value_attribute (var_die,
add_pubname (decl, var_die); decl_or_origin,
DW_AT_location);
add_pubname (decl_or_origin, var_die);
} }
else else
tree_add_const_value_attribute (var_die, decl); tree_add_const_value_attribute (var_die, decl_or_origin);
} }
/* Generate a DIE to represent a named constant. */ /* Generate a DIE to represent a named constant. */
...@@ -14209,7 +14219,7 @@ gen_lexical_block_die (tree stmt, dw_die_ref context_die, int depth) ...@@ -14209,7 +14219,7 @@ gen_lexical_block_die (tree stmt, dw_die_ref context_die, int depth)
{ {
dw_die_ref stmt_die = new_die (DW_TAG_lexical_block, context_die, stmt); dw_die_ref stmt_die = new_die (DW_TAG_lexical_block, context_die, stmt);
if (! BLOCK_ABSTRACT (stmt)) if (! BLOCK_ABSTRACT (stmt) && TREE_ASM_WRITTEN (stmt))
add_high_low_attributes (stmt, stmt_die); add_high_low_attributes (stmt, stmt_die);
decls_for_scope (stmt, stmt_die, depth); decls_for_scope (stmt, stmt_die, depth);
...@@ -14234,6 +14244,7 @@ gen_inlined_subroutine_die (tree stmt, dw_die_ref context_die, int depth) ...@@ -14234,6 +14244,7 @@ gen_inlined_subroutine_die (tree stmt, dw_die_ref context_die, int depth)
= new_die (DW_TAG_inlined_subroutine, context_die, stmt); = new_die (DW_TAG_inlined_subroutine, context_die, stmt);
add_abstract_origin_attribute (subr_die, decl); add_abstract_origin_attribute (subr_die, decl);
if (TREE_ASM_WRITTEN (stmt))
add_high_low_attributes (stmt, subr_die); add_high_low_attributes (stmt, subr_die);
add_call_src_coords_attributes (stmt, subr_die); add_call_src_coords_attributes (stmt, subr_die);
...@@ -14466,7 +14477,7 @@ gen_member_die (tree type, dw_die_ref context_die) ...@@ -14466,7 +14477,7 @@ gen_member_die (tree type, dw_die_ref context_die)
if (child) if (child)
splice_child_die (context_die, child); splice_child_die (context_die, child);
else else
gen_decl_die (member, context_die); gen_decl_die (member, NULL, context_die);
} }
/* Now output info about the function members (if any). */ /* Now output info about the function members (if any). */
...@@ -14480,7 +14491,7 @@ gen_member_die (tree type, dw_die_ref context_die) ...@@ -14480,7 +14491,7 @@ gen_member_die (tree type, dw_die_ref context_die)
if (child) if (child)
splice_child_die (context_die, child); splice_child_die (context_die, child);
else else
gen_decl_die (member, context_die); gen_decl_die (member, NULL, context_die);
} }
} }
...@@ -14655,7 +14666,7 @@ gen_type_die_with_usage (tree type, dw_die_ref context_die, ...@@ -14655,7 +14666,7 @@ gen_type_die_with_usage (tree type, dw_die_ref context_die,
gcc_assert (DECL_ORIGINAL_TYPE (TYPE_NAME (type)) != type); gcc_assert (DECL_ORIGINAL_TYPE (TYPE_NAME (type)) != type);
TREE_ASM_WRITTEN (type) = 1; TREE_ASM_WRITTEN (type) = 1;
gen_decl_die (TYPE_NAME (type), context_die); gen_decl_die (TYPE_NAME (type), NULL, context_die);
return; return;
} }
...@@ -14858,7 +14869,6 @@ static void ...@@ -14858,7 +14869,6 @@ static void
gen_block_die (tree stmt, dw_die_ref context_die, int depth) gen_block_die (tree stmt, dw_die_ref context_die, int depth)
{ {
int must_output_die = 0; int must_output_die = 0;
tree decl;
bool inlined_func; bool inlined_func;
/* Ignore blocks that are NULL. */ /* Ignore blocks that are NULL. */
...@@ -14893,21 +14903,16 @@ gen_block_die (tree stmt, dw_die_ref context_die, int depth) ...@@ -14893,21 +14903,16 @@ gen_block_die (tree stmt, dw_die_ref context_die, int depth)
if (debug_info_level > DINFO_LEVEL_TERSE) if (debug_info_level > DINFO_LEVEL_TERSE)
/* We are not in terse mode so *any* local declaration counts /* We are not in terse mode so *any* local declaration counts
as being a "significant" one. */ as being a "significant" one. */
must_output_die = (BLOCK_VARS (stmt) != NULL must_output_die = ((BLOCK_VARS (stmt) != NULL
|| BLOCK_NUM_NONLOCALIZED_VARS (stmt))
&& (TREE_USED (stmt) && (TREE_USED (stmt)
|| TREE_ASM_WRITTEN (stmt) || TREE_ASM_WRITTEN (stmt)
|| BLOCK_ABSTRACT (stmt))); || BLOCK_ABSTRACT (stmt)));
else else if ((TREE_USED (stmt)
/* We are in terse mode, so only local (nested) function || TREE_ASM_WRITTEN (stmt)
definitions count as "significant" local declarations. */ || BLOCK_ABSTRACT (stmt))
for (decl = BLOCK_VARS (stmt); && !dwarf2out_ignore_block (stmt))
decl != NULL; decl = TREE_CHAIN (decl))
if (TREE_CODE (decl) == FUNCTION_DECL
&& DECL_INITIAL (decl))
{
must_output_die = 1; must_output_die = 1;
break;
}
} }
/* It would be a waste of space to generate a Dwarf DW_TAG_lexical_block /* It would be a waste of space to generate a Dwarf DW_TAG_lexical_block
...@@ -14928,6 +14933,35 @@ gen_block_die (tree stmt, dw_die_ref context_die, int depth) ...@@ -14928,6 +14933,35 @@ gen_block_die (tree stmt, dw_die_ref context_die, int depth)
decls_for_scope (stmt, context_die, depth); decls_for_scope (stmt, context_die, depth);
} }
/* Process variable DECL (or variable with origin ORIGIN) within
block STMT and add it to CONTEXT_DIE. */
static void
process_scope_var (tree stmt, tree decl, tree origin, dw_die_ref context_die)
{
dw_die_ref die;
tree decl_or_origin = decl ? decl : origin;
tree ultimate_origin = origin ? decl_ultimate_origin (origin) : NULL;
if (ultimate_origin)
origin = ultimate_origin;
if (TREE_CODE (decl_or_origin) == FUNCTION_DECL)
die = lookup_decl_die (decl_or_origin);
else if (TREE_CODE (decl_or_origin) == TYPE_DECL
&& TYPE_DECL_IS_STUB (decl_or_origin))
die = lookup_type_die (TREE_TYPE (decl_or_origin));
else
die = NULL;
if (die != NULL && die->die_parent == NULL)
add_child_die (context_die, die);
else if (TREE_CODE (decl_or_origin) == IMPORTED_DECL)
dwarf2out_imported_module_or_decl_1 (decl_or_origin, DECL_NAME (decl_or_origin),
stmt, context_die);
else
gen_decl_die (decl, origin, context_die);
}
/* Generate all of the decls declared within a given scope and (recursively) /* Generate all of the decls declared within a given scope and (recursively)
all of its sub-blocks. */ all of its sub-blocks. */
...@@ -14935,38 +14969,22 @@ static void ...@@ -14935,38 +14969,22 @@ static void
decls_for_scope (tree stmt, dw_die_ref context_die, int depth) decls_for_scope (tree stmt, dw_die_ref context_die, int depth)
{ {
tree decl; tree decl;
unsigned int i;
tree subblocks; tree subblocks;
/* Ignore NULL blocks. */ /* Ignore NULL blocks. */
if (stmt == NULL_TREE) if (stmt == NULL_TREE)
return; return;
if (TREE_USED (stmt))
{
/* Output the DIEs to represent all of the data objects and typedefs /* Output the DIEs to represent all of the data objects and typedefs
declared directly within this block but not within any nested declared directly within this block but not within any nested
sub-blocks. Also, nested function and tag DIEs have been sub-blocks. Also, nested function and tag DIEs have been
generated with a parent of NULL; fix that up now. */ generated with a parent of NULL; fix that up now. */
for (decl = BLOCK_VARS (stmt); decl != NULL; decl = TREE_CHAIN (decl)) for (decl = BLOCK_VARS (stmt); decl != NULL; decl = TREE_CHAIN (decl))
{ process_scope_var (stmt, decl, NULL_TREE, context_die);
dw_die_ref die; for (i = 0; i < BLOCK_NUM_NONLOCALIZED_VARS (stmt); i++)
process_scope_var (stmt, NULL, BLOCK_NONLOCALIZED_VAR (stmt, i),
if (TREE_CODE (decl) == FUNCTION_DECL) context_die);
die = lookup_decl_die (decl);
else if (TREE_CODE (decl) == TYPE_DECL && TYPE_DECL_IS_STUB (decl))
die = lookup_type_die (TREE_TYPE (decl));
else
die = NULL;
if (die != NULL && die->die_parent == NULL)
add_child_die (context_die, die);
else if (TREE_CODE (decl) == IMPORTED_DECL)
dwarf2out_imported_module_or_decl_1 (decl, DECL_NAME (decl),
stmt, context_die);
else
gen_decl_die (decl, context_die);
}
}
/* If we're at -g1, we're not interested in subblocks. */ /* If we're at -g1, we're not interested in subblocks. */
if (debug_info_level <= DINFO_LEVEL_TERSE) if (debug_info_level <= DINFO_LEVEL_TERSE)
...@@ -15049,7 +15067,7 @@ force_decl_die (tree decl) ...@@ -15049,7 +15067,7 @@ force_decl_die (tree decl)
gen_decl_die() call. */ gen_decl_die() call. */
saved_external_flag = DECL_EXTERNAL (decl); saved_external_flag = DECL_EXTERNAL (decl);
DECL_EXTERNAL (decl) = 1; DECL_EXTERNAL (decl) = 1;
gen_decl_die (decl, context_die); gen_decl_die (decl, NULL, context_die);
DECL_EXTERNAL (decl) = saved_external_flag; DECL_EXTERNAL (decl) = saved_external_flag;
break; break;
...@@ -15132,7 +15150,7 @@ declare_in_namespace (tree thing, dw_die_ref context_die) ...@@ -15132,7 +15150,7 @@ declare_in_namespace (tree thing, dw_die_ref context_die)
if (is_fortran ()) if (is_fortran ())
return ns_context; return ns_context;
if (DECL_P (thing)) if (DECL_P (thing))
gen_decl_die (thing, ns_context); gen_decl_die (thing, NULL, ns_context);
else else
gen_type_die (thing, ns_context); gen_type_die (thing, ns_context);
} }
...@@ -15183,14 +15201,15 @@ gen_namespace_die (tree decl) ...@@ -15183,14 +15201,15 @@ gen_namespace_die (tree decl)
/* Generate Dwarf debug information for a decl described by DECL. */ /* Generate Dwarf debug information for a decl described by DECL. */
static void static void
gen_decl_die (tree decl, dw_die_ref context_die) gen_decl_die (tree decl, tree origin, dw_die_ref context_die)
{ {
tree origin; tree decl_or_origin = decl ? decl : origin;
tree class_origin = NULL;
if (DECL_P (decl) && DECL_IGNORED_P (decl)) if (DECL_P (decl_or_origin) && DECL_IGNORED_P (decl_or_origin))
return; return;
switch (TREE_CODE (decl)) switch (TREE_CODE (decl_or_origin))
{ {
case ERROR_MARK: case ERROR_MARK:
break; break;
...@@ -15215,8 +15234,10 @@ gen_decl_die (tree decl, dw_die_ref context_die) ...@@ -15215,8 +15234,10 @@ gen_decl_die (tree decl, dw_die_ref context_die)
case FUNCTION_DECL: case FUNCTION_DECL:
/* Don't output any DIEs to represent mere function declarations, /* Don't output any DIEs to represent mere function declarations,
unless they are class members or explicit block externs. */ unless they are class members or explicit block externs. */
if (DECL_INITIAL (decl) == NULL_TREE && DECL_CONTEXT (decl) == NULL_TREE if (DECL_INITIAL (decl_or_origin) == NULL_TREE
&& (current_function_decl == NULL_TREE || DECL_ARTIFICIAL (decl))) && DECL_CONTEXT (decl_or_origin) == NULL_TREE
&& (current_function_decl == NULL_TREE
|| DECL_ARTIFICIAL (decl_or_origin)))
break; break;
#if 0 #if 0
...@@ -15228,8 +15249,8 @@ gen_decl_die (tree decl, dw_die_ref context_die) ...@@ -15228,8 +15249,8 @@ gen_decl_die (tree decl, dw_die_ref context_die)
#endif #endif
/* If we're emitting a clone, emit info for the abstract instance. */ /* If we're emitting a clone, emit info for the abstract instance. */
if (DECL_ORIGIN (decl) != decl) if (origin || DECL_ORIGIN (decl) != decl)
dwarf2out_abstract_function (DECL_ABSTRACT_ORIGIN (decl)); dwarf2out_abstract_function (origin ? origin : DECL_ABSTRACT_ORIGIN (decl));
/* If we're emitting an out-of-line copy of an inline function, /* If we're emitting an out-of-line copy of an inline function,
emit info for the abstract instance and set up to refer to it. */ emit info for the abstract instance and set up to refer to it. */
...@@ -15257,6 +15278,7 @@ gen_decl_die (tree decl, dw_die_ref context_die) ...@@ -15257,6 +15278,7 @@ gen_decl_die (tree decl, dw_die_ref context_die)
gen_type_die (DECL_CONTEXT (decl), context_die); gen_type_die (DECL_CONTEXT (decl), context_die);
/* And its containing type. */ /* And its containing type. */
if (!origin)
origin = decl_class_context (decl); origin = decl_class_context (decl);
if (origin != NULL_TREE) if (origin != NULL_TREE)
gen_type_die_for_member (origin, decl, context_die); gen_type_die_for_member (origin, decl, context_die);
...@@ -15266,6 +15288,7 @@ gen_decl_die (tree decl, dw_die_ref context_die) ...@@ -15266,6 +15288,7 @@ gen_decl_die (tree decl, dw_die_ref context_die)
} }
/* Now output a DIE to represent the function itself. */ /* Now output a DIE to represent the function itself. */
if (decl)
gen_subprogram_die (decl, context_die); gen_subprogram_die (decl, context_die);
break; break;
...@@ -15309,28 +15332,30 @@ gen_decl_die (tree decl, dw_die_ref context_die) ...@@ -15309,28 +15332,30 @@ gen_decl_die (tree decl, dw_die_ref context_die)
/* Output any DIEs that are needed to specify the type of this data /* Output any DIEs that are needed to specify the type of this data
object. */ object. */
if (TREE_CODE (decl) == RESULT_DECL && DECL_BY_REFERENCE (decl)) if (TREE_CODE (decl_or_origin) == RESULT_DECL
gen_type_die (TREE_TYPE (TREE_TYPE (decl)), context_die); && DECL_BY_REFERENCE (decl_or_origin))
gen_type_die (TREE_TYPE (TREE_TYPE (decl_or_origin)), context_die);
else else
gen_type_die (TREE_TYPE (decl), context_die); gen_type_die (TREE_TYPE (decl_or_origin), context_die);
/* And its containing type. */ /* And its containing type. */
origin = decl_class_context (decl); class_origin = decl_class_context (decl_or_origin);
if (origin != NULL_TREE) if (class_origin != NULL_TREE)
gen_type_die_for_member (origin, decl, context_die); gen_type_die_for_member (class_origin, decl_or_origin, context_die);
/* And its containing namespace. */ /* And its containing namespace. */
context_die = declare_in_namespace (decl, context_die); context_die = declare_in_namespace (decl_or_origin, context_die);
/* Now output the DIE to represent the data object itself. This gets /* Now output the DIE to represent the data object itself. This gets
complicated because of the possibility that the VAR_DECL really complicated because of the possibility that the VAR_DECL really
represents an inlined instance of a formal parameter for an inline represents an inlined instance of a formal parameter for an inline
function. */ function. */
if (!origin)
origin = decl_ultimate_origin (decl); origin = decl_ultimate_origin (decl);
if (origin != NULL_TREE && TREE_CODE (origin) == PARM_DECL) if (origin != NULL_TREE && TREE_CODE (origin) == PARM_DECL)
gen_formal_parameter_die (decl, context_die); gen_formal_parameter_die (decl, origin, context_die);
else else
gen_variable_die (decl, context_die); gen_variable_die (decl, origin, context_die);
break; break;
case FIELD_DECL: case FIELD_DECL:
...@@ -15346,11 +15371,11 @@ gen_decl_die (tree decl, dw_die_ref context_die) ...@@ -15346,11 +15371,11 @@ gen_decl_die (tree decl, dw_die_ref context_die)
break; break;
case PARM_DECL: case PARM_DECL:
if (DECL_BY_REFERENCE (decl)) if (DECL_BY_REFERENCE (decl_or_origin))
gen_type_die (TREE_TYPE (TREE_TYPE (decl)), context_die); gen_type_die (TREE_TYPE (TREE_TYPE (decl_or_origin)), context_die);
else else
gen_type_die (TREE_TYPE (decl), context_die); gen_type_die (TREE_TYPE (decl_or_origin), context_die);
gen_formal_parameter_die (decl, context_die); gen_formal_parameter_die (decl, origin, context_die);
break; break;
case NAMESPACE_DECL: case NAMESPACE_DECL:
...@@ -15641,7 +15666,7 @@ dwarf2out_decl (tree decl) ...@@ -15641,7 +15666,7 @@ dwarf2out_decl (tree decl)
return; return;
} }
gen_decl_die (decl, context_die); gen_decl_die (decl, NULL, context_die);
} }
/* Output a marker (i.e. a label) for the beginning of the generated code for /* Output a marker (i.e. a label) for the beginning of the generated code for
...@@ -15676,11 +15701,19 @@ static bool ...@@ -15676,11 +15701,19 @@ static bool
dwarf2out_ignore_block (const_tree block) dwarf2out_ignore_block (const_tree block)
{ {
tree decl; tree decl;
unsigned int i;
for (decl = BLOCK_VARS (block); decl; decl = TREE_CHAIN (decl)) for (decl = BLOCK_VARS (block); decl; decl = TREE_CHAIN (decl))
if (TREE_CODE (decl) == FUNCTION_DECL if (TREE_CODE (decl) == FUNCTION_DECL
|| (TREE_CODE (decl) == TYPE_DECL && TYPE_DECL_IS_STUB (decl))) || (TREE_CODE (decl) == TYPE_DECL && TYPE_DECL_IS_STUB (decl)))
return 0; return 0;
for (i = 0; i < BLOCK_NUM_NONLOCALIZED_VARS (block); i++)
{
decl = BLOCK_NONLOCALIZED_VAR (block, i);
if (TREE_CODE (decl) == FUNCTION_DECL
|| (TREE_CODE (decl) == TYPE_DECL && TYPE_DECL_IS_STUB (decl)))
return 0;
}
return 1; return 1;
} }
......
...@@ -122,7 +122,6 @@ eni_weights eni_time_weights; ...@@ -122,7 +122,6 @@ eni_weights eni_time_weights;
static tree declare_return_variable (copy_body_data *, tree, tree, tree *); static tree declare_return_variable (copy_body_data *, tree, tree, tree *);
static bool inlinable_function_p (tree); static bool inlinable_function_p (tree);
static void remap_block (tree *, copy_body_data *); static void remap_block (tree *, copy_body_data *);
static tree remap_decls (tree, copy_body_data *);
static void copy_bind_expr (tree *, int *, copy_body_data *); static void copy_bind_expr (tree *, int *, copy_body_data *);
static tree mark_local_for_remap_r (tree *, int *, void *); static tree mark_local_for_remap_r (tree *, int *, void *);
static void unsave_expr_1 (tree); static void unsave_expr_1 (tree);
...@@ -427,8 +426,43 @@ remap_type (tree type, copy_body_data *id) ...@@ -427,8 +426,43 @@ remap_type (tree type, copy_body_data *id)
return tmp; return tmp;
} }
/* Decide if DECL can be put into BLOCK_NONLOCAL_VARs. */
static bool
can_be_nonlocal (tree decl, copy_body_data *id)
{
/* We can not duplicate function decls. */
if (TREE_CODE (decl) == FUNCTION_DECL)
return true;
/* Local static vars must be non-local or we get multiple declaration
problems. */
if (TREE_CODE (decl) == VAR_DECL
&& !auto_var_in_fn_p (decl, id->src_fn))
return true;
/* At the moment dwarf2out can handle only these types of nodes. We
can support more later. */
if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != PARM_DECL)
return false;
/* We must use global type. */
if (TREE_TYPE (decl) != remap_type (TREE_TYPE (decl), id))
return false;
/* Wihtout SSA we can't tell if variable is used. */
if (!gimple_in_ssa_p (cfun))
return false;
/* Live variables must be copied so we can attach DECL_RTL. */
if (var_ann (decl))
return false;
return true;
}
static tree static tree
remap_decls (tree decls, copy_body_data *id) remap_decls (tree decls, VEC(tree,gc) **nonlocalized_list, copy_body_data *id)
{ {
tree old_var; tree old_var;
tree new_decls = NULL_TREE; tree new_decls = NULL_TREE;
...@@ -437,16 +471,18 @@ remap_decls (tree decls, copy_body_data *id) ...@@ -437,16 +471,18 @@ remap_decls (tree decls, copy_body_data *id)
for (old_var = decls; old_var; old_var = TREE_CHAIN (old_var)) for (old_var = decls; old_var; old_var = TREE_CHAIN (old_var))
{ {
tree new_var; tree new_var;
tree origin_var = DECL_ORIGIN (old_var);
/* We cannot chain the local static declarations into the local_decls if (can_be_nonlocal (old_var, id))
as we can't duplicate them or break one decl rule. Go ahead
and link them into local_decls. */
if (!auto_var_in_fn_p (old_var, id->src_fn)
&& !DECL_EXTERNAL (old_var))
{ {
if (TREE_CODE (old_var) == VAR_DECL
&& (var_ann (old_var) || !gimple_in_ssa_p (cfun)))
cfun->local_decls = tree_cons (NULL_TREE, old_var, cfun->local_decls = tree_cons (NULL_TREE, old_var,
cfun->local_decls); cfun->local_decls);
if (debug_info_level > DINFO_LEVEL_TERSE
&& !DECL_IGNORED_P (old_var)
&& nonlocalized_list)
VEC_safe_push (tree, gc, *nonlocalized_list, origin_var);
continue; continue;
} }
...@@ -456,8 +492,16 @@ remap_decls (tree decls, copy_body_data *id) ...@@ -456,8 +492,16 @@ remap_decls (tree decls, copy_body_data *id)
/* If we didn't remap this variable, we can't mess with its /* If we didn't remap this variable, we can't mess with its
TREE_CHAIN. If we remapped this variable to the return slot, it's TREE_CHAIN. If we remapped this variable to the return slot, it's
already declared somewhere else, so don't declare it here. */ already declared somewhere else, so don't declare it here. */
if (!new_var || new_var == id->retvar)
if (new_var == id->retvar)
; ;
else if (!new_var)
{
if (debug_info_level > DINFO_LEVEL_TERSE
&& !DECL_IGNORED_P (old_var)
&& nonlocalized_list)
VEC_safe_push (tree, gc, *nonlocalized_list, origin_var);
}
else else
{ {
gcc_assert (DECL_P (new_var)); gcc_assert (DECL_P (new_var));
...@@ -485,10 +529,14 @@ remap_block (tree *block, copy_body_data *id) ...@@ -485,10 +529,14 @@ remap_block (tree *block, copy_body_data *id)
TREE_USED (new_block) = TREE_USED (old_block); TREE_USED (new_block) = TREE_USED (old_block);
BLOCK_ABSTRACT_ORIGIN (new_block) = old_block; BLOCK_ABSTRACT_ORIGIN (new_block) = old_block;
BLOCK_SOURCE_LOCATION (new_block) = BLOCK_SOURCE_LOCATION (old_block); BLOCK_SOURCE_LOCATION (new_block) = BLOCK_SOURCE_LOCATION (old_block);
BLOCK_NONLOCALIZED_VARS (new_block)
= VEC_copy (tree, gc, BLOCK_NONLOCALIZED_VARS (old_block));
*block = new_block; *block = new_block;
/* Remap its variables. */ /* Remap its variables. */
BLOCK_VARS (new_block) = remap_decls (BLOCK_VARS (old_block), id); BLOCK_VARS (new_block) = remap_decls (BLOCK_VARS (old_block),
&BLOCK_NONLOCALIZED_VARS (new_block),
id);
fn = id->dst_fn; fn = id->dst_fn;
...@@ -549,7 +597,7 @@ copy_bind_expr (tree *tp, int *walk_subtrees, copy_body_data *id) ...@@ -549,7 +597,7 @@ copy_bind_expr (tree *tp, int *walk_subtrees, copy_body_data *id)
if (BIND_EXPR_VARS (*tp)) if (BIND_EXPR_VARS (*tp))
/* This will remap a lot of the same decls again, but this should be /* This will remap a lot of the same decls again, but this should be
harmless. */ harmless. */
BIND_EXPR_VARS (*tp) = remap_decls (BIND_EXPR_VARS (*tp), id); BIND_EXPR_VARS (*tp) = remap_decls (BIND_EXPR_VARS (*tp), NULL, id);
} }
...@@ -595,7 +643,7 @@ copy_gimple_bind (gimple stmt, copy_body_data *id) ...@@ -595,7 +643,7 @@ copy_gimple_bind (gimple stmt, copy_body_data *id)
harmless. */ harmless. */
new_vars = gimple_bind_vars (stmt); new_vars = gimple_bind_vars (stmt);
if (new_vars) if (new_vars)
new_vars = remap_decls (new_vars, id); new_vars = remap_decls (new_vars, NULL, id);
new_bind = gimple_build_bind (new_vars, new_body, new_block); new_bind = gimple_build_bind (new_vars, new_body, new_block);
...@@ -3317,12 +3365,10 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id) ...@@ -3317,12 +3365,10 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
cfun->local_decls = tree_cons (NULL_TREE, var, cfun->local_decls = tree_cons (NULL_TREE, var,
cfun->local_decls); cfun->local_decls);
} }
else else if (!can_be_nonlocal (var, id))
{
cfun->local_decls = tree_cons (NULL_TREE, remap_decl (var, id), cfun->local_decls = tree_cons (NULL_TREE, remap_decl (var, id),
cfun->local_decls); cfun->local_decls);
} }
}
/* This is it. Duplicate the callee body. Assume callee is /* This is it. Duplicate the callee body. Assume callee is
pre-gimplified. Note that we must not alter the caller pre-gimplified. Note that we must not alter the caller
...@@ -3911,7 +3957,7 @@ replace_locals_stmt (gimple_stmt_iterator *gsip, ...@@ -3911,7 +3957,7 @@ replace_locals_stmt (gimple_stmt_iterator *gsip,
/* This will remap a lot of the same decls again, but this should be /* This will remap a lot of the same decls again, but this should be
harmless. */ harmless. */
if (gimple_bind_vars (stmt)) if (gimple_bind_vars (stmt))
gimple_bind_set_vars (stmt, remap_decls (gimple_bind_vars (stmt), id)); gimple_bind_set_vars (stmt, remap_decls (gimple_bind_vars (stmt), NULL, id));
} }
/* Keep iterating. */ /* Keep iterating. */
...@@ -4329,7 +4375,7 @@ tree_function_versioning (tree old_decl, tree new_decl, varray_type tree_map, ...@@ -4329,7 +4375,7 @@ tree_function_versioning (tree old_decl, tree new_decl, varray_type tree_map,
tree var = TREE_VALUE (t_step); tree var = TREE_VALUE (t_step);
if (TREE_STATIC (var) && !TREE_ASM_WRITTEN (var)) if (TREE_STATIC (var) && !TREE_ASM_WRITTEN (var))
cfun->local_decls = tree_cons (NULL_TREE, var, cfun->local_decls); cfun->local_decls = tree_cons (NULL_TREE, var, cfun->local_decls);
else else if (!can_be_nonlocal (var, &id))
cfun->local_decls = cfun->local_decls =
tree_cons (NULL_TREE, remap_decl (var, &id), tree_cons (NULL_TREE, remap_decl (var, &id),
cfun->local_decls); cfun->local_decls);
......
...@@ -583,7 +583,7 @@ remove_unused_scope_block_p (tree scope) ...@@ -583,7 +583,7 @@ remove_unused_scope_block_p (tree scope)
else if (debug_info_level == DINFO_LEVEL_NONE else if (debug_info_level == DINFO_LEVEL_NONE
|| debug_info_level == DINFO_LEVEL_TERSE) || debug_info_level == DINFO_LEVEL_TERSE)
; ;
else if (BLOCK_VARS (scope)) else if (BLOCK_VARS (scope) || BLOCK_NUM_NONLOCALIZED_VARS (scope))
unused = false; unused = false;
/* See if this block is important for representation of inlined function. /* See if this block is important for representation of inlined function.
Inlined functions are always represented by block with Inlined functions are always represented by block with
...@@ -613,6 +613,7 @@ static void ...@@ -613,6 +613,7 @@ static void
dump_scope_block (FILE *file, int indent, tree scope, int flags) dump_scope_block (FILE *file, int indent, tree scope, int flags)
{ {
tree var, t; tree var, t;
unsigned int i;
fprintf (file, "\n%*s{ Scope block #%i%s%s",indent, "" , BLOCK_NUMBER (scope), fprintf (file, "\n%*s{ Scope block #%i%s%s",indent, "" , BLOCK_NUMBER (scope),
TREE_USED (scope) ? "" : " (unused)", TREE_USED (scope) ? "" : " (unused)",
...@@ -648,6 +649,13 @@ dump_scope_block (FILE *file, int indent, tree scope, int flags) ...@@ -648,6 +649,13 @@ dump_scope_block (FILE *file, int indent, tree scope, int flags)
print_generic_decl (file, var, flags); print_generic_decl (file, var, flags);
fprintf (file, "%s\n", used ? "" : " (unused)"); fprintf (file, "%s\n", used ? "" : " (unused)");
} }
for (i = 0; i < BLOCK_NUM_NONLOCALIZED_VARS (scope); i++)
{
fprintf (file, "%*s",indent, "");
print_generic_decl (file, BLOCK_NONLOCALIZED_VAR (scope, i),
flags);
fprintf (file, " (nonlocalized)\n");
}
for (t = BLOCK_SUBBLOCKS (scope); t ; t = BLOCK_CHAIN (t)) for (t = BLOCK_SUBBLOCKS (scope); t ; t = BLOCK_CHAIN (t))
dump_scope_block (file, indent + 2, t, flags); dump_scope_block (file, indent + 2, t, flags);
fprintf (file, "\n%*s}\n",indent, ""); fprintf (file, "\n%*s}\n",indent, "");
......
...@@ -1968,6 +1968,9 @@ struct varray_head_tag; ...@@ -1968,6 +1968,9 @@ struct varray_head_tag;
/* In a BLOCK node. */ /* In a BLOCK node. */
#define BLOCK_VARS(NODE) (BLOCK_CHECK (NODE)->block.vars) #define BLOCK_VARS(NODE) (BLOCK_CHECK (NODE)->block.vars)
#define BLOCK_NONLOCALIZED_VARS(NODE) (BLOCK_CHECK (NODE)->block.nonlocalized_vars)
#define BLOCK_NUM_NONLOCALIZED_VARS(NODE) VEC_length (tree, BLOCK_NONLOCALIZED_VARS (NODE))
#define BLOCK_NONLOCALIZED_VAR(NODE,N) VEC_index (tree, BLOCK_NONLOCALIZED_VARS (NODE), N)
#define BLOCK_SUBBLOCKS(NODE) (BLOCK_CHECK (NODE)->block.subblocks) #define BLOCK_SUBBLOCKS(NODE) (BLOCK_CHECK (NODE)->block.subblocks)
#define BLOCK_SUPERCONTEXT(NODE) (BLOCK_CHECK (NODE)->block.supercontext) #define BLOCK_SUPERCONTEXT(NODE) (BLOCK_CHECK (NODE)->block.supercontext)
/* Note: when changing this, make sure to find the places /* Note: when changing this, make sure to find the places
...@@ -2022,6 +2025,8 @@ struct tree_block GTY(()) ...@@ -2022,6 +2025,8 @@ struct tree_block GTY(())
location_t locus; location_t locus;
tree vars; tree vars;
VEC(tree,gc) *nonlocalized_vars;
tree subblocks; tree subblocks;
tree supercontext; tree supercontext;
tree abstract_origin; tree abstract_origin;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment