PR/21391
* testsuite/gcc.dg/
20060410.c: New.
* 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.
From-SVN: r112845
+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
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)
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);
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);
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;
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). */
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
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;
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 */
#define GCC_FUNCTION_H
#include "tree.h"
+#include "hashtab.h"
struct var_refs_queue 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
extern bool reference_callee_copied (CUMULATIVE_ARGS *, enum machine_mode,
tree, bool);
+extern void used_types_insert (tree, struct function *);
+
#endif /* GCC_FUNCTION_H */
+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):
--- /dev/null
+/* { 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" } } */