From 526d73abffb96e977cd32581125fa323f795a499 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Sun, 1 Mar 2009 19:47:08 +0100 Subject: [PATCH] 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 --- gcc/ChangeLog | 21 ++++ gcc/dwarf2out.c | 239 +++++++++++++++++++++++++------------------- gcc/tree-inline.c | 88 ++++++++++++---- gcc/tree-ssa-live.c | 10 +- gcc/tree.h | 5 + 5 files changed, 238 insertions(+), 125 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2fa2f4fe00a..6f47c0a840e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,24 @@ +2009-03-01 Jan Hubicka + + 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 * configure: Regenerate. diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 48178b7cbcb..848926b6383 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -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_union_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_formal_types_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_label_die (tree, dw_die_ref); 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); static void decls_for_scope (tree, dw_die_ref, int); static int is_redundant_typedef (const_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_type_die (tree); static dw_die_ref setup_namespace_context (tree, dw_die_ref); @@ -13293,16 +13293,17 @@ gen_enumeration_type_die (tree type, dw_die_ref context_die) argument type of some subprogram type. */ 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 = 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: - origin = decl_ultimate_origin (node); + if (!origin) + origin = decl_ultimate_origin (node); if (origin != NULL) add_abstract_origin_attribute (parm_die, origin); else @@ -13321,15 +13322,17 @@ gen_formal_parameter_die (tree node, dw_die_ref context_die) add_AT_flag (parm_die, DW_AT_artificial, 1); } - equate_decl_number_to_die (node, parm_die); - if (! DECL_ABSTRACT (node)) - add_location_or_const_value_attribute (parm_die, node, DW_AT_location); + if (node) + equate_decl_number_to_die (node, parm_die); + if (! DECL_ABSTRACT (node_or_origin)) + add_location_or_const_value_attribute (parm_die, node_or_origin, + DW_AT_location); break; case tcc_type: /* 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; default: @@ -13382,7 +13385,7 @@ gen_formal_types_die (tree function_or_method_type, dw_die_ref context_die) break; /* 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 && link == first_parm_type) || (arg && DECL_ARTIFICIAL (arg))) @@ -13442,7 +13445,7 @@ gen_type_die_for_member (tree type, tree member, dw_die_ref context_die) } } else - gen_variable_die (member, type_die); + gen_variable_die (member, NULL_TREE, type_die); pop_decl_scope (); } @@ -13787,7 +13790,7 @@ gen_subprogram_die (tree decl, dw_die_ref context_die) "__builtin_va_alist")) gen_unspecified_parameters_die (parm, subr_die); 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. @@ -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. */ 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; decls_for_scope (outer_scope, subr_die, 0); @@ -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; } -/* 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 -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; tree com_decl; + tree decl_or_origin = decl ? decl : origin; dw_die_ref var_die; - tree origin = decl_ultimate_origin (decl); - dw_die_ref old_die = lookup_decl_die (decl); - int declaration = (DECL_EXTERNAL (decl) + dw_die_ref old_die = decl ? lookup_decl_die (decl) : NULL; + int declaration = (DECL_EXTERNAL (decl_or_origin) /* If DECL is COMDAT and has not actually been emitted, we cannot take its address; there might end up being no definition anywhere in @@ -13899,11 +13903,15 @@ gen_variable_die (tree decl, dw_die_ref context_die) Here, S::i is not DECL_EXTERNAL, but no definition is required, so the compiler will not emit a definition. */ - || (TREE_CODE (decl) == VAR_DECL - && DECL_COMDAT (decl) && !TREE_ASM_WRITTEN (decl)) + || (TREE_CODE (decl_or_origin) == VAR_DECL + && DECL_COMDAT (decl_or_origin) + && !TREE_ASM_WRITTEN (decl_or_origin)) || 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 of a data member. */ @@ -13914,7 +13922,7 @@ gen_variable_die (tree decl, dw_die_ref context_die) dw_loc_descr_ref loc; die_node com_die_arg; - var_die = lookup_decl_die (decl); + var_die = lookup_decl_die (decl_or_origin); if (var_die) { if (get_AT (var_die, DW_AT_location) == NULL) @@ -14071,20 +14079,22 @@ gen_variable_die (tree decl, dw_die_ref context_die) if (declaration) 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); - if (! declaration && ! DECL_ABSTRACT (decl)) + if (! declaration && ! DECL_ABSTRACT (decl_or_origin)) { - if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl) - && !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))) - defer_location (decl, var_die); + if (TREE_CODE (decl_or_origin) == VAR_DECL && TREE_STATIC (decl_or_origin) + && !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl_or_origin))) + defer_location (decl_or_origin, var_die); else - add_location_or_const_value_attribute (var_die, decl, DW_AT_location); - add_pubname (decl, var_die); + add_location_or_const_value_attribute (var_die, + decl_or_origin, + DW_AT_location); + add_pubname (decl_or_origin, var_die); } 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. */ @@ -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); - if (! BLOCK_ABSTRACT (stmt)) + if (! BLOCK_ABSTRACT (stmt) && TREE_ASM_WRITTEN (stmt)) add_high_low_attributes (stmt, stmt_die); decls_for_scope (stmt, stmt_die, depth); @@ -14234,7 +14244,8 @@ gen_inlined_subroutine_die (tree stmt, dw_die_ref context_die, int depth) = new_die (DW_TAG_inlined_subroutine, context_die, stmt); add_abstract_origin_attribute (subr_die, decl); - add_high_low_attributes (stmt, subr_die); + if (TREE_ASM_WRITTEN (stmt)) + add_high_low_attributes (stmt, subr_die); add_call_src_coords_attributes (stmt, subr_die); decls_for_scope (stmt, subr_die, depth); @@ -14466,7 +14477,7 @@ gen_member_die (tree type, dw_die_ref context_die) if (child) splice_child_die (context_die, child); else - gen_decl_die (member, context_die); + gen_decl_die (member, NULL, context_die); } /* Now output info about the function members (if any). */ @@ -14480,7 +14491,7 @@ gen_member_die (tree type, dw_die_ref context_die) if (child) splice_child_die (context_die, child); 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, gcc_assert (DECL_ORIGINAL_TYPE (TYPE_NAME (type)) != type); TREE_ASM_WRITTEN (type) = 1; - gen_decl_die (TYPE_NAME (type), context_die); + gen_decl_die (TYPE_NAME (type), NULL, context_die); return; } @@ -14858,7 +14869,6 @@ static void gen_block_die (tree stmt, dw_die_ref context_die, int depth) { int must_output_die = 0; - tree decl; bool inlined_func; /* Ignore blocks that are NULL. */ @@ -14893,21 +14903,16 @@ gen_block_die (tree stmt, dw_die_ref context_die, int depth) 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 + must_output_die = ((BLOCK_VARS (stmt) != NULL + || BLOCK_NUM_NONLOCALIZED_VARS (stmt)) && (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; - } + else if ((TREE_USED (stmt) + || TREE_ASM_WRITTEN (stmt) + || BLOCK_ABSTRACT (stmt)) + && !dwarf2out_ignore_block (stmt)) + must_output_die = 1; } /* 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) 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) all of its sub-blocks. */ @@ -14935,38 +14969,22 @@ static void decls_for_scope (tree stmt, dw_die_ref context_die, int depth) { tree decl; + unsigned int i; tree subblocks; /* Ignore NULL blocks. */ if (stmt == NULL_TREE) return; - if (TREE_USED (stmt)) - { - /* Output the DIEs to represent all of the data objects and typedefs - declared directly within this block but not within any nested - sub-blocks. Also, nested function and tag DIEs have been - generated with a parent of NULL; fix that up now. */ - for (decl = BLOCK_VARS (stmt); decl != NULL; decl = TREE_CHAIN (decl)) - { - dw_die_ref die; - - if (TREE_CODE (decl) == FUNCTION_DECL) - 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); - } - } + /* Output the DIEs to represent all of the data objects and typedefs + declared directly within this block but not within any nested + sub-blocks. Also, nested function and tag DIEs have been + generated with a parent of NULL; fix that up now. */ + for (decl = BLOCK_VARS (stmt); decl != NULL; decl = TREE_CHAIN (decl)) + process_scope_var (stmt, decl, NULL_TREE, context_die); + for (i = 0; i < BLOCK_NUM_NONLOCALIZED_VARS (stmt); i++) + process_scope_var (stmt, NULL, BLOCK_NONLOCALIZED_VAR (stmt, i), + context_die); /* If we're at -g1, we're not interested in subblocks. */ if (debug_info_level <= DINFO_LEVEL_TERSE) @@ -15049,7 +15067,7 @@ force_decl_die (tree decl) gen_decl_die() call. */ saved_external_flag = DECL_EXTERNAL (decl); DECL_EXTERNAL (decl) = 1; - gen_decl_die (decl, context_die); + gen_decl_die (decl, NULL, context_die); DECL_EXTERNAL (decl) = saved_external_flag; break; @@ -15132,7 +15150,7 @@ declare_in_namespace (tree thing, dw_die_ref context_die) if (is_fortran ()) return ns_context; if (DECL_P (thing)) - gen_decl_die (thing, ns_context); + gen_decl_die (thing, NULL, ns_context); else gen_type_die (thing, ns_context); } @@ -15183,14 +15201,15 @@ gen_namespace_die (tree decl) /* Generate Dwarf debug information for a decl described by DECL. */ 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; - switch (TREE_CODE (decl)) + switch (TREE_CODE (decl_or_origin)) { case ERROR_MARK: break; @@ -15215,8 +15234,10 @@ gen_decl_die (tree decl, dw_die_ref context_die) case FUNCTION_DECL: /* Don't output any DIEs to represent mere function declarations, unless they are class members or explicit block externs. */ - if (DECL_INITIAL (decl) == NULL_TREE && DECL_CONTEXT (decl) == NULL_TREE - && (current_function_decl == NULL_TREE || DECL_ARTIFICIAL (decl))) + if (DECL_INITIAL (decl_or_origin) == NULL_TREE + && DECL_CONTEXT (decl_or_origin) == NULL_TREE + && (current_function_decl == NULL_TREE + || DECL_ARTIFICIAL (decl_or_origin))) break; #if 0 @@ -15228,8 +15249,8 @@ gen_decl_die (tree decl, dw_die_ref context_die) #endif /* If we're emitting a clone, emit info for the abstract instance. */ - if (DECL_ORIGIN (decl) != decl) - dwarf2out_abstract_function (DECL_ABSTRACT_ORIGIN (decl)); + if (origin || DECL_ORIGIN (decl) != decl) + dwarf2out_abstract_function (origin ? origin : DECL_ABSTRACT_ORIGIN (decl)); /* 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. */ @@ -15257,7 +15278,8 @@ gen_decl_die (tree decl, dw_die_ref context_die) gen_type_die (DECL_CONTEXT (decl), context_die); /* And its containing type. */ - origin = decl_class_context (decl); + if (!origin) + origin = decl_class_context (decl); if (origin != NULL_TREE) gen_type_die_for_member (origin, decl, context_die); @@ -15266,7 +15288,8 @@ gen_decl_die (tree decl, dw_die_ref context_die) } /* Now output a DIE to represent the function itself. */ - gen_subprogram_die (decl, context_die); + if (decl) + gen_subprogram_die (decl, context_die); break; case TYPE_DECL: @@ -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 object. */ - if (TREE_CODE (decl) == RESULT_DECL && DECL_BY_REFERENCE (decl)) - gen_type_die (TREE_TYPE (TREE_TYPE (decl)), context_die); + if (TREE_CODE (decl_or_origin) == RESULT_DECL + && DECL_BY_REFERENCE (decl_or_origin)) + gen_type_die (TREE_TYPE (TREE_TYPE (decl_or_origin)), context_die); else - gen_type_die (TREE_TYPE (decl), context_die); + gen_type_die (TREE_TYPE (decl_or_origin), context_die); /* And its containing type. */ - origin = decl_class_context (decl); - if (origin != NULL_TREE) - gen_type_die_for_member (origin, decl, context_die); + class_origin = decl_class_context (decl_or_origin); + if (class_origin != NULL_TREE) + gen_type_die_for_member (class_origin, decl_or_origin, context_die); /* 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 complicated because of the possibility that the VAR_DECL really represents an inlined instance of a formal parameter for an inline function. */ - origin = decl_ultimate_origin (decl); + if (!origin) + origin = decl_ultimate_origin (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 - gen_variable_die (decl, context_die); + gen_variable_die (decl, origin, context_die); break; case FIELD_DECL: @@ -15346,11 +15371,11 @@ gen_decl_die (tree decl, dw_die_ref context_die) break; case PARM_DECL: - if (DECL_BY_REFERENCE (decl)) - gen_type_die (TREE_TYPE (TREE_TYPE (decl)), context_die); + if (DECL_BY_REFERENCE (decl_or_origin)) + gen_type_die (TREE_TYPE (TREE_TYPE (decl_or_origin)), context_die); else - gen_type_die (TREE_TYPE (decl), context_die); - gen_formal_parameter_die (decl, context_die); + gen_type_die (TREE_TYPE (decl_or_origin), context_die); + gen_formal_parameter_die (decl, origin, context_die); break; case NAMESPACE_DECL: @@ -15641,7 +15666,7 @@ dwarf2out_decl (tree decl) 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 @@ -15676,11 +15701,19 @@ static bool dwarf2out_ignore_block (const_tree block) { tree decl; + unsigned int i; for (decl = BLOCK_VARS (block); decl; decl = TREE_CHAIN (decl)) if (TREE_CODE (decl) == FUNCTION_DECL || (TREE_CODE (decl) == TYPE_DECL && TYPE_DECL_IS_STUB (decl))) 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; } diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 8ff784abd48..88154bf91f3 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -122,7 +122,6 @@ eni_weights eni_time_weights; static tree declare_return_variable (copy_body_data *, tree, tree, tree *); static bool inlinable_function_p (tree); 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 tree mark_local_for_remap_r (tree *, int *, void *); static void unsave_expr_1 (tree); @@ -427,8 +426,43 @@ remap_type (tree type, copy_body_data *id) 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 -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 new_decls = NULL_TREE; @@ -437,16 +471,18 @@ remap_decls (tree decls, copy_body_data *id) for (old_var = decls; old_var; old_var = TREE_CHAIN (old_var)) { tree new_var; + tree origin_var = DECL_ORIGIN (old_var); - /* We cannot chain the local static declarations into the local_decls - 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 (can_be_nonlocal (old_var, id)) { - cfun->local_decls = tree_cons (NULL_TREE, old_var, - cfun->local_decls); + 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); + if (debug_info_level > DINFO_LEVEL_TERSE + && !DECL_IGNORED_P (old_var) + && nonlocalized_list) + VEC_safe_push (tree, gc, *nonlocalized_list, origin_var); continue; } @@ -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 TREE_CHAIN. If we remapped this variable to the return slot, it's 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 { gcc_assert (DECL_P (new_var)); @@ -485,10 +529,14 @@ remap_block (tree *block, copy_body_data *id) TREE_USED (new_block) = TREE_USED (old_block); BLOCK_ABSTRACT_ORIGIN (new_block) = 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; /* 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; @@ -549,7 +597,7 @@ copy_bind_expr (tree *tp, int *walk_subtrees, copy_body_data *id) if (BIND_EXPR_VARS (*tp)) /* This will remap a lot of the same decls again, but this should be 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) harmless. */ new_vars = gimple_bind_vars (stmt); 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); @@ -3317,11 +3365,9 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id) cfun->local_decls = tree_cons (NULL_TREE, var, cfun->local_decls); } - else - { - cfun->local_decls = tree_cons (NULL_TREE, remap_decl (var, id), - cfun->local_decls); - } + else if (!can_be_nonlocal (var, id)) + cfun->local_decls = tree_cons (NULL_TREE, remap_decl (var, id), + cfun->local_decls); } /* This is it. Duplicate the callee body. Assume callee is @@ -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 harmless. */ 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. */ @@ -4329,7 +4375,7 @@ tree_function_versioning (tree old_decl, tree new_decl, varray_type tree_map, tree var = TREE_VALUE (t_step); if (TREE_STATIC (var) && !TREE_ASM_WRITTEN (var)) cfun->local_decls = tree_cons (NULL_TREE, var, 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); diff --git a/gcc/tree-ssa-live.c b/gcc/tree-ssa-live.c index 15166cc8f5e..28a829caedf 100644 --- a/gcc/tree-ssa-live.c +++ b/gcc/tree-ssa-live.c @@ -583,7 +583,7 @@ remove_unused_scope_block_p (tree scope) else if (debug_info_level == DINFO_LEVEL_NONE || debug_info_level == DINFO_LEVEL_TERSE) ; - else if (BLOCK_VARS (scope)) + else if (BLOCK_VARS (scope) || BLOCK_NUM_NONLOCALIZED_VARS (scope)) unused = false; /* See if this block is important for representation of inlined function. Inlined functions are always represented by block with @@ -613,6 +613,7 @@ static void dump_scope_block (FILE *file, int indent, tree scope, int flags) { tree var, t; + unsigned int i; fprintf (file, "\n%*s{ Scope block #%i%s%s",indent, "" , BLOCK_NUMBER (scope), TREE_USED (scope) ? "" : " (unused)", @@ -648,6 +649,13 @@ dump_scope_block (FILE *file, int indent, tree scope, int flags) print_generic_decl (file, var, flags); 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)) dump_scope_block (file, indent + 2, t, flags); fprintf (file, "\n%*s}\n",indent, ""); diff --git a/gcc/tree.h b/gcc/tree.h index 1e86bf9bc61..761f4af2f77 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -1968,6 +1968,9 @@ struct varray_head_tag; /* In a BLOCK node. */ #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_SUPERCONTEXT(NODE) (BLOCK_CHECK (NODE)->block.supercontext) /* Note: when changing this, make sure to find the places @@ -2022,6 +2025,8 @@ struct tree_block GTY(()) location_t locus; tree vars; + VEC(tree,gc) *nonlocalized_vars; + tree subblocks; tree supercontext; tree abstract_origin; -- 2.30.2