This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: pruning unused debugging types (enums/PR23336)


On Fri, Mar 31, 2006 at 07:30:07AM -0800, Richard Henderson wrote:
> On Sat, Feb 18, 2006 at 07:23:30AM -0400, Aldy Hernandez wrote:
> > 	* function.h (struct function): Add used_types_hash field.
> > 	Include hashtab.h.
> > 	(used_types_insert): Protoize.
> > 	* function.c (used_types_insert): New.
> > 	* c-parser.c (c_parser_cast_expression): Call used_types_insert.
> > 	* 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 mark perennial types.
> > 	* Makefile.in (FUNCTION_H): Depend on HASHTAB_H.
> 
> Ok.

I fixed a few tidbits that turned up after bootstrapping again after
a month of bit rot.  I also fixed a GC problem because I wasn't ggc_allocating
the hash table memory; plus I also only fill in the used types hash table
if we're generating debug information.

Bootstrapped and regtested on ppc-linux.

Committing to mainline.  Below is the final patch.

On to the C++ bits.

Aldy

	* 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.

Index: testsuite/gcc.dg/20060410.c
===================================================================
--- testsuite/gcc.dg/20060410.c	(revision 0)
+++ testsuite/gcc.dg/20060410.c	(revision 0)
@@ -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" } } */
Index: dwarf2out.c
===================================================================
--- dwarf2out.c	(revision 112618)
+++ dwarf2out.c	(working copy)
@@ -354,6 +354,7 @@ static void dwarf2out_stack_adjust (rtx,
 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);
@@ -3695,6 +3696,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;
@@ -11531,6 +11534,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).  */
 
@@ -11546,6 +11575,8 @@ gen_subprogram_die (tree decl, dw_die_re
   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
@@ -13984,6 +14015,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;
 
Index: function.c
===================================================================
--- function.c	(revision 112618)
+++ function.c	(working copy)
@@ -5589,6 +5589,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 */
Index: function.h
===================================================================
--- function.h	(revision 112618)
+++ function.h	(working copy)
@@ -23,6 +23,7 @@ Software Foundation, 51 Franklin Street,
 #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 (CUMULATIV
 extern bool reference_callee_copied (CUMULATIVE_ARGS *, enum machine_mode,
 				     tree, bool);
 
+extern void used_types_insert (tree, struct function *);
+
 #endif  /* GCC_FUNCTION_H */
Index: Makefile.in
===================================================================
--- Makefile.in	(revision 112618)
+++ Makefile.in	(working copy)
@@ -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)
Index: c-parser.c
===================================================================
--- c-parser.c	(revision 112618)
+++ c-parser.c	(working copy)
@@ -4660,6 +4660,11 @@ c_parser_cast_expression (c_parser *pars
 	  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);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]