diff options
Diffstat (limited to 'gcc-4.9/gcc/dwarf2out.c')
-rw-r--r-- | gcc-4.9/gcc/dwarf2out.c | 207 |
1 files changed, 158 insertions, 49 deletions
diff --git a/gcc-4.9/gcc/dwarf2out.c b/gcc-4.9/gcc/dwarf2out.c index 67b37eba5..088e522c7 100644 --- a/gcc-4.9/gcc/dwarf2out.c +++ b/gcc-4.9/gcc/dwarf2out.c @@ -95,6 +95,7 @@ along with GCC; see the file COPYING3. If not see #include "lra.h" #include "dumpfile.h" #include "opts.h" +#include "l-ipo.h" #include "tree-dfa.h" #include "gdb/gdb-index.h" @@ -961,7 +962,7 @@ dwarf2out_do_cfi_startproc (bool second) enc = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/0); ASM_GENERATE_INTERNAL_LABEL (lab, second ? "LLSDAC" : "LLSDA", - current_function_funcdef_no); + FUNC_LABEL_ID (cfun)); ref = gen_rtx_SYMBOL_REF (Pmode, lab); SYMBOL_REF_FLAGS (ref) = SYMBOL_FLAG_LOCAL; @@ -984,7 +985,7 @@ dwarf2out_alloc_current_fde (void) fde = ggc_alloc_cleared_dw_fde_node (); fde->decl = current_function_decl; - fde->funcdef_number = current_function_funcdef_no; + fde->funcdef_number = FUNC_LABEL_ID (cfun); fde->fde_index = vec_safe_length (fde_vec); fde->all_throwers_are_sibcalls = crtl->all_throwers_are_sibcalls; fde->uses_eh_lsda = crtl->uses_eh_lsda; @@ -1026,9 +1027,9 @@ dwarf2out_begin_prologue (unsigned int line ATTRIBUTE_UNUSED, fnsec = function_section (current_function_decl); switch_to_section (fnsec); ASM_GENERATE_INTERNAL_LABEL (label, FUNC_BEGIN_LABEL, - current_function_funcdef_no); + FUNC_LABEL_ID (cfun)); ASM_OUTPUT_DEBUG_LABEL (asm_out_file, FUNC_BEGIN_LABEL, - current_function_funcdef_no); + FUNC_LABEL_ID (cfun)); dup_label = xstrdup (label); current_function_func_begin_label = dup_label; @@ -1087,9 +1088,9 @@ dwarf2out_vms_end_prologue (unsigned int line ATTRIBUTE_UNUSED, /* Output a label to mark the endpoint of the code generated for this function. */ ASM_GENERATE_INTERNAL_LABEL (label, PROLOGUE_END_LABEL, - current_function_funcdef_no); + FUNC_LABEL_ID (cfun)); ASM_OUTPUT_DEBUG_LABEL (asm_out_file, PROLOGUE_END_LABEL, - current_function_funcdef_no); + FUNC_LABEL_ID (cfun)); cfun->fde->dw_fde_vms_end_prologue = xstrdup (label); } @@ -1110,9 +1111,9 @@ dwarf2out_vms_begin_epilogue (unsigned int line ATTRIBUTE_UNUSED, /* Output a label to mark the endpoint of the code generated for this function. */ ASM_GENERATE_INTERNAL_LABEL (label, EPILOGUE_BEGIN_LABEL, - current_function_funcdef_no); + FUNC_LABEL_ID (cfun)); ASM_OUTPUT_DEBUG_LABEL (asm_out_file, EPILOGUE_BEGIN_LABEL, - current_function_funcdef_no); + FUNC_LABEL_ID (cfun)); fde->dw_fde_vms_begin_epilogue = xstrdup (label); } @@ -1136,7 +1137,7 @@ dwarf2out_end_epilogue (unsigned int line ATTRIBUTE_UNUSED, /* Output a label to mark the endpoint of the code generated for this function. */ ASM_GENERATE_INTERNAL_LABEL (label, FUNC_END_LABEL, - current_function_funcdef_no); + FUNC_LABEL_ID (cfun)); ASM_OUTPUT_LABEL (asm_out_file, label); fde = cfun->fde; gcc_assert (fde != NULL); @@ -2435,6 +2436,41 @@ const struct gcc_debug_hooks dwarf2_debug_hooks = 1, /* start_end_main_source_file */ TYPE_SYMTAB_IS_DIE /* tree_type_symtab_field */ }; + +const struct gcc_debug_hooks auto_profile_debug_hooks = +{ + debug_nothing_charstar, + debug_nothing_charstar, + debug_nothing_void, + debug_nothing_int_charstar, + debug_nothing_int_charstar, + debug_nothing_int_charstar, + debug_nothing_int, + debug_nothing_int_int, /* begin_block */ + debug_nothing_int_int, /* end_block */ + dwarf2out_ignore_block, /* ignore_block */ + debug_nothing_int_charstar_int_bool, /* source_line */ + debug_nothing_int_charstar, /* begin_prologue */ + debug_nothing_int_charstar, /* end_prologue */ + debug_nothing_int_charstar, /* begin_epilogue */ + debug_nothing_int_charstar, /* end_epilogue */ + debug_nothing_tree, /* begin_function */ + debug_nothing_int, /* end_function */ + debug_nothing_tree, /* function_decl */ + debug_nothing_tree, /* global_decl */ + debug_nothing_tree_int, /* type_decl */ + debug_nothing_tree_tree_tree_bool, /* imported_module_or_decl */ + debug_nothing_tree, /* deferred_inline_function */ + debug_nothing_tree, /* outlining_inline_function */ + debug_nothing_rtx, /* label */ + debug_nothing_int, /* handle_pch */ + debug_nothing_rtx, /* var_location */ + debug_nothing_void, /* switch_text_section */ + debug_nothing_tree_tree, /* set_name */ + 0, /* start_end_main_source_file */ + TYPE_SYMTAB_IS_ADDRESS /* tree_type_symtab_field */ +}; + /* NOTE: In the comments in this file, many references are made to "Debugging Information Entries". This term is abbreviated as `DIE' @@ -4222,13 +4258,10 @@ add_addr_table_entry (void *addr, enum ate_kind kind) static void remove_addr_table_entry (addr_table_entry *entry) { - addr_table_entry *node; - gcc_assert (dwarf_split_debug_info && addr_index_table); - node = (addr_table_entry *) htab_find (addr_index_table, entry); /* After an index is assigned, the table is frozen. */ - gcc_assert (node->refcount > 0 && node->index == NO_INDEX_ASSIGNED); - node->refcount--; + gcc_assert (entry->refcount > 0 && entry->index == NO_INDEX_ASSIGNED); + entry->refcount--; } /* Given a location list, remove all addresses it refers to from the @@ -6830,14 +6863,13 @@ should_move_die_to_comdat (dw_die_ref die) case DW_TAG_structure_type: case DW_TAG_enumeration_type: case DW_TAG_union_type: - /* Don't move declarations, inlined instances, or types nested in a - subprogram. */ + /* Don't move declarations, inlined instances, types nested in a + subprogram, or types that contain subprogram definitions. */ if (is_declaration_die (die) || get_AT (die, DW_AT_abstract_origin) - || is_nested_in_subprogram (die)) + || is_nested_in_subprogram (die) + || contains_subprogram_definition (die)) return 0; - /* A type definition should never contain a subprogram definition. */ - gcc_assert (!contains_subprogram_definition (die)); return 1; case DW_TAG_array_type: case DW_TAG_interface_type: @@ -6926,6 +6958,7 @@ clone_as_declaration (dw_die_ref die) switch (a->dw_attr) { + case DW_AT_abstract_origin: case DW_AT_artificial: case DW_AT_containing_type: case DW_AT_external: @@ -7158,6 +7191,12 @@ generate_skeleton_bottom_up (skeleton_chain_node *parent) dw_die_ref clone = clone_die (c); move_all_children (c, clone); + /* If the original has a DW_AT_object_pointer attribute, + it would now point to a child DIE just moved to the + cloned tree, so we need to remove that attribute from + the original. */ + remove_AT (c, DW_AT_object_pointer); + replace_child (c, clone, prev); generate_skeleton_ancestor_tree (parent); add_child_die (parent->new_die, c); @@ -7299,28 +7338,38 @@ break_out_comdat_types (dw_die_ref die) } while (next != NULL); } -/* Like clone_tree, but additionally enter all the children into - the hash table decl_table. */ +/* Like clone_tree, but copy DW_TAG_subprogram DIEs as declarations. + Enter all the cloned children into the hash table decl_table. */ static dw_die_ref -clone_tree_hash (dw_die_ref die, decl_hash_type decl_table) +clone_tree_partial (dw_die_ref die, decl_hash_type decl_table) { dw_die_ref c; - dw_die_ref clone = clone_die (die); + dw_die_ref clone; struct decl_table_entry *entry; - decl_table_entry **slot = decl_table.find_slot_with_hash (die, - htab_hash_pointer (die), INSERT); + decl_table_entry **slot; + + if (die->die_tag == DW_TAG_subprogram) + clone = clone_as_declaration (die); + else + clone = clone_die (die); + + slot = decl_table.find_slot_with_hash (die, + htab_hash_pointer (die), INSERT); + /* Assert that DIE isn't in the hash table yet. If it would be there before, the ancestors would be necessarily there as well, therefore - clone_tree_hash wouldn't be called. */ + clone_tree_partial wouldn't be called. */ gcc_assert (*slot == HTAB_EMPTY_ENTRY); + entry = XCNEW (struct decl_table_entry); entry->orig = die; entry->copy = clone; *slot = entry; - FOR_EACH_CHILD (die, c, - add_child_die (clone, clone_tree_hash (c, decl_table))); + if (die->die_tag != DW_TAG_subprogram) + FOR_EACH_CHILD (die, c, + add_child_die (clone, clone_tree_partial (c, decl_table))); return clone; } @@ -7371,9 +7420,15 @@ copy_decls_walk (dw_die_ref unit, dw_die_ref die, decl_hash_type decl_table) entry->copy = copy; *slot = entry; - FOR_EACH_CHILD (targ, c, - add_child_die (copy, - clone_tree_hash (c, decl_table))); + /* If TARG is not a declaration DIE, we need to copy its + children. */ + if (!is_declaration_die (targ)) + { + FOR_EACH_CHILD ( + targ, c, + add_child_die (copy, + clone_tree_partial (c, decl_table))); + } /* Make sure the cloned tree is marked as part of the type unit. */ @@ -13804,7 +13859,7 @@ dw_loc_list (var_loc_list *loc_list, tree decl, int want_address) else { ASM_GENERATE_INTERNAL_LABEL (label_id, FUNC_END_LABEL, - current_function_funcdef_no); + FUNC_LABEL_ID (cfun)); endname = ggc_strdup (label_id); } @@ -16600,10 +16655,9 @@ add_src_coords_attributes (dw_die_ref die, tree decl) static void add_linkage_name (dw_die_ref die, tree decl) { - if (debug_info_level > DINFO_LEVEL_TERSE + if (debug_info_level > DINFO_LEVEL_NONE && (TREE_CODE (decl) == FUNCTION_DECL || TREE_CODE (decl) == VAR_DECL) && TREE_PUBLIC (decl) - && !DECL_ABSTRACT (decl) && !(TREE_CODE (decl) == VAR_DECL && DECL_REGISTER (decl)) && die->die_tag != DW_TAG_member) { @@ -16669,7 +16723,7 @@ dwarf2out_vms_debug_main_pointer (void) die->die_tag = DW_TAG_subprogram; add_name_attribute (die, VMS_DEBUG_MAIN_POINTER); ASM_GENERATE_INTERNAL_LABEL (label, PROLOGUE_END_LABEL, - current_function_funcdef_no); + FUNC_LABEL_ID (cfun)); add_AT_lbl_id (die, DW_AT_entry_pc, label); /* Make it the first child of comp_unit_die (). */ @@ -18139,9 +18193,9 @@ gen_subprogram_die (tree decl, dw_die_ref context_die) char label_id_low[MAX_ARTIFICIAL_LABEL_BYTES]; char label_id_high[MAX_ARTIFICIAL_LABEL_BYTES]; ASM_GENERATE_INTERNAL_LABEL (label_id_low, FUNC_BEGIN_LABEL, - current_function_funcdef_no); + FUNC_LABEL_ID (cfun)); ASM_GENERATE_INTERNAL_LABEL (label_id_high, FUNC_END_LABEL, - current_function_funcdef_no); + FUNC_LABEL_ID (cfun)); add_AT_low_high_pc (subr_die, label_id_low, label_id_high, false); } @@ -18891,12 +18945,16 @@ gen_label_die (tree decl, dw_die_ref context_die) static inline void add_call_src_coords_attributes (tree stmt, dw_die_ref die) { - expanded_location s = expand_location (BLOCK_SOURCE_LOCATION (stmt)); + location_t locus = BLOCK_SOURCE_LOCATION (stmt); + expanded_location s = expand_location (locus); if (dwarf_version >= 3 || !dwarf_strict) { add_AT_file (die, DW_AT_call_file, lookup_filename (s.file)); add_AT_unsigned (die, DW_AT_call_line, s.line); + unsigned discr = get_discriminator_from_locus (locus); + if (discr != 0) + add_AT_unsigned (die, DW_AT_GNU_discriminator, discr); } } @@ -20706,7 +20764,48 @@ gen_namelist_decl (tree name, dw_die_ref scope_die, tree item_decls) void dwarf2out_decl (tree decl) { - dw_die_ref context_die = comp_unit_die (); + dw_die_ref context_die; + + /* In LIPO mode, we may output some functions whose type is defined + in another function that will not be output. This can result in + undefined location list symbols in the debug type info. + Here we disable the output of the type info for this case. + It is safe since this function and its debug info should never + be referenced. */ + if (L_IPO_COMP_MODE) + { + tree decl_context, orig_decl; + + decl_context = DECL_CONTEXT (decl); + while (decl_context && + TREE_CODE (decl_context) != TRANSLATION_UNIT_DECL) + { + struct cgraph_node *node; + + /* Refer to cgraph_mark_functions_to_output() in cgraphunit.c, + if cgraph_is_aux_decl_external() is true, + this function will not be output in LIPO mode. */ + if (TREE_CODE (decl_context) == FUNCTION_DECL && + TREE_PUBLIC (decl_context) && + (node = cgraph_get_node (decl_context)) && + cgraph_is_aux_decl_external (node)) + return; + + if (TYPE_P (decl_context)) + { + decl_context = TYPE_CONTEXT (decl_context); + continue; + } + + orig_decl = DECL_ORIGIN (decl_context); + while (orig_decl != DECL_ORIGIN (orig_decl)) + orig_decl = DECL_ORIGIN (orig_decl); + + decl_context = DECL_CONTEXT (orig_decl); + } + } + + context_die = comp_unit_die (); switch (TREE_CODE (decl)) { @@ -21370,7 +21469,7 @@ set_cur_line_info_table (section *sec) { char label[MAX_ARTIFICIAL_LABEL_BYTES]; ASM_GENERATE_INTERNAL_LABEL (label, FUNC_END_LABEL, - current_function_funcdef_no); + FUNC_LABEL_ID (cfun)); end_label = ggc_strdup (label); } @@ -23099,11 +23198,16 @@ resolve_addr_in_expr (dw_loc_descr_ref loc) break; case DW_OP_GNU_addr_index: case DW_OP_GNU_const_index: - if ((loc->dw_loc_opc == DW_OP_GNU_addr_index - || (loc->dw_loc_opc == DW_OP_GNU_const_index && loc->dtprel)) - && resolve_one_addr (&loc->dw_loc_oprnd1.val_entry->addr.rtl, - NULL)) - return false; + if (loc->dw_loc_opc == DW_OP_GNU_addr_index + || (loc->dw_loc_opc == DW_OP_GNU_const_index && loc->dtprel)) + { + rtx rtl = loc->dw_loc_oprnd1.val_entry->addr.rtl; + if (resolve_one_addr (&rtl, NULL)) + return false; + remove_addr_table_entry (loc->dw_loc_oprnd1.val_entry); + loc->dw_loc_oprnd1.val_entry = + add_addr_table_entry (rtl, ate_kind_rtx); + } break; case DW_OP_const4u: case DW_OP_const8u: @@ -24195,18 +24299,23 @@ dwarf2out_finish (const char *filename) dwarf_strict ? DW_AT_macro_info : DW_AT_GNU_macros, macinfo_section_label); - if (dwarf_split_debug_info && addr_index_table != NULL) + if (dwarf_split_debug_info) { /* optimize_location_lists calculates the size of the lists, so index them first, and assign indices to the entries. Although optimize_location_lists will remove entries from the table, it only does so for duplicates, and therefore only reduces ref_counts to 1. */ - unsigned int index = 0; index_location_lists (comp_unit_die ()); - htab_traverse_noresize (addr_index_table, - index_addr_table_entry, &index); + + if (addr_index_table != NULL) + { + unsigned int index = 0; + htab_traverse_noresize (addr_index_table, + index_addr_table_entry, &index); + } } + if (have_location_lists) optimize_location_lists (comp_unit_die ()); |