diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 05581772ec23f35f820faf953951efb487b4c5ec..209b378d34d86fa9c0896d200fc9fb0aa86749ea 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2006-04-10 Aldy Hernandez <aldyh@redhat.com> + + PR/21391 + * dwarf2out.c (struct die_struct): Add die_perennial_p field. + (premark_used_types_helper): New. + (premark_used_types): New. + (gen_subprogram_die): Call premark_used_types. + (prune_unused_types_walk): Do not prune perennial dies. + * function.c (used_types_insert): New. + * function.h (struct function): Add used_types_hash field. + (used_types_insert): Add prototype. + * Makefile.in (FUNCTION_H): Depend on HASHTAB_H. + * c-parser.c (c_parser_cast_expression): Save casted types in used + types hash table. + 2006-04-11 Mark Mitchell <mark@codesourcery.com> PR target/26459 diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 25559e4ab33cdb0b1e72c17eae7fcd52b77b725b..d29fcaa961d9a604afb1cbfd7216614b344d7506 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -751,7 +751,7 @@ RECOG_H = recog.h ALIAS_H = alias.h EMIT_RTL_H = emit-rtl.h FLAGS_H = flags.h options.h -FUNCTION_H = function.h $(TREE_H) +FUNCTION_H = function.h $(TREE_H) $(HASHTAB_H) EXPR_H = expr.h insn-config.h $(FUNCTION_H) $(RTL_H) $(FLAGS_H) $(TREE_H) $(MACHMODE_H) $(EMIT_RTL_H) OPTABS_H = optabs.h insn-codes.h REGS_H = regs.h varray.h $(MACHMODE_H) $(OBSTACK_H) $(BASIC_BLOCK_H) $(FUNCTION_H) diff --git a/gcc/c-parser.c b/gcc/c-parser.c index b5722738ac90c09ae15b2e5110645c0e6ca80ec7..0c90fa84bd875c75796b86c2258246451a7af4cd 100644 --- a/gcc/c-parser.c +++ b/gcc/c-parser.c @@ -4660,6 +4660,11 @@ c_parser_cast_expression (c_parser *parser, struct c_expr *after) ret.original_code = ERROR_MARK; return ret; } + + /* Save casted types in the function's used types hash table. */ + if (debug_info_level > DINFO_LEVEL_NONE) + used_types_insert (type_name->specs->type, cfun); + if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) return c_parser_postfix_expression_after_paren_type (parser, type_name); diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 3a02acf725e95c1660eeca6a25373855fe14bf74..f7de3d7cfde756794745e79d9e322dd9df4cffd2 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -354,6 +354,7 @@ static void dwarf2out_stack_adjust (rtx, bool); static void flush_queued_reg_saves (void); static bool clobbers_queued_reg_save (rtx); static void dwarf2out_frame_debug_expr (rtx, const char *); +static void premark_used_types (void); /* Support for complex CFA locations. */ static void output_cfa_loc (dw_cfi_ref); @@ -3697,6 +3698,8 @@ typedef struct die_struct GTY(()) dw_offset die_offset; unsigned long die_abbrev; int die_mark; + /* Die is used and must not be pruned as unused. */ + int die_perennial_p; unsigned int decl_id; } die_node; @@ -11511,6 +11514,32 @@ dwarf2out_abstract_function (tree decl) current_function_decl = save_fn; } +/* Helper function of premark_used_types() which gets called through + htab_traverse_resize(). + + Marks the DIE of a given type in *SLOT as perennial, so it never gets + marked as unused by prune_unused_types. */ +static int +premark_used_types_helper (void **slot, void *data ATTRIBUTE_UNUSED) +{ + tree type; + dw_die_ref die; + + type = *slot; + die = lookup_type_die (type); + if (die != NULL) + die->die_perennial_p = 1; + return 1; +} + +/* Mark all members of used_types_hash as perennial. */ +static void +premark_used_types (void) +{ + if (cfun && cfun->used_types_hash) + htab_traverse (cfun->used_types_hash, premark_used_types_helper, NULL); +} + /* Generate a DIE to represent a declared function (either file-scope or block-local). */ @@ -11526,6 +11555,8 @@ gen_subprogram_die (tree decl, dw_die_ref context_die) int declaration = (current_function_decl != decl || class_or_namespace_scope_p (context_die)); + premark_used_types(); + /* It is possible to have both DECL_ABSTRACT and DECLARATION be true if we started to generate the abstract instance of an inline, decided to output its containing class, and proceeded to emit the declaration of the inline @@ -13965,6 +13996,9 @@ prune_unused_types_walk (dw_die_ref die) case DW_TAG_subrange_type: case DW_TAG_ptr_to_member_type: case DW_TAG_file_type: + if (die->die_perennial_p) + break; + /* It's a type node --- don't mark it. */ return; diff --git a/gcc/function.c b/gcc/function.c index fd5eeb983fe325675ebe1d89115362df16247f17..ecdf28232b5bb01981584f222d9b9ef2caafe420 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -5587,6 +5587,23 @@ rest_of_handle_check_leaf_regs (void) return 0; } +/* Insert a type into the used types hash table. */ +void +used_types_insert (tree t, struct function *func) +{ + if (t != NULL && func != NULL) + { + void **slot; + + if (func->used_types_hash == NULL) + func->used_types_hash = htab_create_ggc (37, htab_hash_pointer, + htab_eq_pointer, NULL); + slot = htab_find_slot (func->used_types_hash, t, INSERT); + if (*slot == NULL) + *slot = t; + } +} + struct tree_opt_pass pass_leaf_regs = { NULL, /* name */ diff --git a/gcc/function.h b/gcc/function.h index 4a60eb2d705824455192f151ea1c6290c007a969..282e04c1047249889751bff1a47ec8a8b0f3e4b8 100644 --- a/gcc/function.h +++ b/gcc/function.h @@ -23,6 +23,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA #define GCC_FUNCTION_H #include "tree.h" +#include "hashtab.h" struct var_refs_queue GTY(()) { @@ -312,6 +313,9 @@ struct function GTY(()) /* Language-specific code can use this to store whatever it likes. */ struct language_function * language; + /* Used types hash table. */ + htab_t GTY ((param_is (union tree_node))) used_types_hash; + /* For reorg. */ /* If some insns can be deferred to the delay slots of the epilogue, the @@ -566,4 +570,6 @@ extern bool pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode, extern bool reference_callee_copied (CUMULATIVE_ARGS *, enum machine_mode, tree, bool); +extern void used_types_insert (tree, struct function *); + #endif /* GCC_FUNCTION_H */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9f16bfec7e42a0ed268003d01e673254ae4f27db..237a690b657802794b959f3ad25e5045cd3620b5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2006-04-10 Aldy Hernandez <aldyh@redhat.com> + + PR/21391 + * gcc.dg/20060410.c: New. + 2006-04-10 Matthias Klose <doko@debian.org> * testsuite/lib/gcc-defs.exp (gcc-set-multilib-library-path): diff --git a/gcc/testsuite/gcc.dg/20060410.c b/gcc/testsuite/gcc.dg/20060410.c new file mode 100644 index 0000000000000000000000000000000000000000..88253bb43f3e4441793944d2f071dd9f24ed0d35 --- /dev/null +++ b/gcc/testsuite/gcc.dg/20060410.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-g" } */ + +/* Make sure we didn't eliminate foo because we thought it was unused. */ + +struct foo +{ + int i; +}; + +int bar (void) +{ + return ((struct foo *)0x1234)->i; +} + +/* { dg-final { scan-assembler "foo" } } */