aboutsummaryrefslogtreecommitdiff
path: root/gcc/dwarf2out.c
diff options
context:
space:
mode:
authorGeoffrey Keating <geoffk@apple.com>2006-04-17 21:27:57 +0000
committerGeoffrey Keating <geoffk@gcc.gnu.org>2006-04-17 21:27:57 +0000
commite26303c2f718f8b5dec468efdf49e0d50e31e813 (patch)
tree25abddfe72573ab172094c7749da0960c05b3ab6 /gcc/dwarf2out.c
parentc60fe329d5e7273d8d7bef718244f72276124ded (diff)
downloadgcc-e26303c2f718f8b5dec468efdf49e0d50e31e813.zip
gcc-e26303c2f718f8b5dec468efdf49e0d50e31e813.tar.gz
gcc-e26303c2f718f8b5dec468efdf49e0d50e31e813.tar.bz2
dwarf2out.c (free_AT): Delete.
* dwarf2out.c (free_AT): Delete. (remove_AT): Update string ref counts. (remove_child_TAG): Don't call free_die. (free_die): Delete. (break_out_includes): Don't call free_die on DW_TAG_GNU_BINCL or DW_TAG_GNU_EINCL. (prune_unused_types_walk_attribs): Reset string refcounts. (prune_unused_types_update_strings): New. (prune_unused_types_prune): Don't make unnecessary stores. Don't call free_die. Do call prune_unused_types_update_strings. (prune_unused_types): Empty debug_str_hash. From-SVN: r113012
Diffstat (limited to 'gcc/dwarf2out.c')
-rw-r--r--gcc/dwarf2out.c119
1 files changed, 56 insertions, 63 deletions
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 3f857b6..818ddb8 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -4027,7 +4027,6 @@ static bool is_fortran (void);
static bool is_ada (void);
static void remove_AT (dw_die_ref, enum dwarf_attribute);
static void remove_child_TAG (dw_die_ref, enum dwarf_tag);
-static inline void free_die (dw_die_ref);
static void add_child_die (dw_die_ref, dw_die_ref);
static dw_die_ref new_die (enum dwarf_tag, dw_die_ref, tree);
static dw_die_ref lookup_type_die (tree);
@@ -5382,17 +5381,6 @@ is_ada (void)
return lang == DW_LANG_Ada95 || lang == DW_LANG_Ada83;
}
-/* Free up the memory used by A. */
-
-static inline void free_AT (dw_attr_ref);
-static inline void
-free_AT (dw_attr_ref a)
-{
- if (AT_class (a) == dw_val_class_str)
- if (a->dw_attr_val.v.val_str->refcount)
- a->dw_attr_val.v.val_str->refcount--;
-}
-
/* Remove the specified attribute if present. */
static void
@@ -5407,7 +5395,10 @@ remove_AT (dw_die_ref die, enum dwarf_attribute attr_kind)
for (ix = 0; VEC_iterate (dw_attr_node, die->die_attr, ix, a); ix++)
if (a->dw_attr == attr_kind)
{
- free_AT (a);
+ if (AT_class (a) == dw_val_class_str)
+ if (a->dw_attr_val.v.val_str->refcount)
+ a->dw_attr_val.v.val_str->refcount--;
+
/* VEC_ordered_remove should help reduce the number of abbrevs
that are needed. */
VEC_ordered_remove (dw_attr_node, die->die_attr, ix);
@@ -5432,7 +5423,6 @@ remove_child_TAG (dw_die_ref die, enum dwarf_tag tag)
die->die_child = next;
else
prev->die_sib = next;
- free_die (current);
current = next;
}
else
@@ -5443,33 +5433,6 @@ remove_child_TAG (dw_die_ref die, enum dwarf_tag tag)
}
}
-/* Free up the memory used by DIE, by removing its children and
- anything associated with its attributes. DIEs are garbage
- collected, so there is no actual freeing to do; the only real work is
- to decrease string reference counts. */
-
-static void
-free_die (dw_die_ref die)
-{
- dw_die_ref child_die = die->die_child;
-
- die->die_child = NULL;
-
- while (child_die != NULL)
- {
- dw_die_ref tmp_die = child_die;
- dw_attr_ref a;
- unsigned ix;
-
- child_die = child_die->die_sib;
-
- for (ix = 0; VEC_iterate (dw_attr_node, tmp_die->die_attr, ix, a); ix++)
- free_AT (a);
-
- free_die (tmp_die);
- }
-}
-
/* Add a child DIE below its parent. We build the lists up in reverse
addition order, and correct that in reverse_all_dies. */
@@ -6390,15 +6353,9 @@ break_out_includes (dw_die_ref die)
*ptr = c->die_sib;
if (c->die_tag == DW_TAG_GNU_BINCL)
- {
- unit = push_new_compile_unit (unit, c);
- free_die (c);
- }
+ unit = push_new_compile_unit (unit, c);
else if (c->die_tag == DW_TAG_GNU_EINCL)
- {
- unit = pop_compile_unit (unit);
- free_die (c);
- }
+ unit = pop_compile_unit (unit);
else
add_child_die (unit, c);
}
@@ -13918,6 +13875,10 @@ prune_unused_types_walk_attribs (dw_die_ref die)
a->dw_attr_val.v.val_unsigned =
maybe_emit_file (a->dw_attr_val.v.val_unsigned);
}
+ /* Set the string's refcount to 0 so that prune_unused_types_mark
+ accounts properly for it. */
+ if (AT_class (a) == dw_val_class_str)
+ a->dw_attr_val.v.val_str->refcount = 0;
}
}
@@ -14021,32 +13982,62 @@ prune_unused_types_walk (dw_die_ref die)
prune_unused_types_walk (c);
}
+/* Increment the string counts on strings referred to from DIE's
+ attributes. */
+
+static void
+prune_unused_types_update_strings (dw_die_ref die)
+{
+ dw_attr_ref a;
+ unsigned ix;
+
+ for (ix = 0; VEC_iterate (dw_attr_node, die->die_attr, ix, a); ix++)
+ if (AT_class (a) == dw_val_class_str)
+ {
+ struct indirect_string_node *s = a->dw_attr_val.v.val_str;
+ s->refcount++;
+ /* Avoid unnecessarily putting strings that are used less than
+ twice in the hash table. */
+ if (s->refcount == 2
+ || (s->refcount == 1
+ && (debug_str_section->common.flags & SECTION_MERGE) != 0))
+ {
+ void ** slot;
+ slot = htab_find_slot_with_hash (debug_str_hash, s->str,
+ htab_hash_string (s->str),
+ INSERT);
+ gcc_assert (*slot == NULL);
+ *slot = s;
+ }
+ }
+}
/* Remove from the tree DIE any dies that aren't marked. */
static void
prune_unused_types_prune (dw_die_ref die)
{
- dw_die_ref c, p, n;
+ dw_die_ref *p;
gcc_assert (die->die_mark);
- p = NULL;
- for (c = die->die_child; c; c = n)
+ p = &die->die_child;
+ while (*p)
{
- n = c->die_sib;
- if (c->die_mark)
+ dw_die_ref c = *p;
+ if (c && ! c->die_mark)
{
- prune_unused_types_prune (c);
- p = c;
+ do {
+ c = c->die_sib;
+ } while (c && ! c->die_mark);
+ *p = c;
}
- else
+
+ if (c)
{
- if (p)
- p->die_sib = n;
- else
- die->die_child = n;
- free_die (c);
+ prune_unused_types_update_strings (c);
+ prune_unused_types_prune (c);
+ p = &c->die_sib;
}
}
}
@@ -14077,7 +14068,9 @@ prune_unused_types (void)
for (i = 0; i < arange_table_in_use; i++)
prune_unused_types_mark (arange_table[i], 1);
- /* Get rid of nodes that aren't marked. */
+ /* Get rid of nodes that aren't marked; and update the string counts. */
+ if (debug_str_hash)
+ htab_empty (debug_str_hash);
prune_unused_types_prune (comp_unit_die);
for (node = limbo_die_list; node; node = node->next)
prune_unused_types_prune (node->die);