summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog21
-rw-r--r--gcc/c-objc-common.c2
-rw-r--r--gcc/dwarf2out.c2
-rw-r--r--gcc/toplev.c2
-rw-r--r--gcc/tree-outof-ssa.c6
-rw-r--r--gcc/tree-sra.c4
-rw-r--r--gcc/tree.c94
-rw-r--r--gcc/tree.h9
-rw-r--r--gcc/var-tracking.c3
9 files changed, 132 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9672b492afa..7b6f3ff390c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,24 @@
+2005-05-30 Daniel Berlin <dberlin@dberlin.org>
+
+ * c-objc-common.c (c_tree_printer): Check flag before hashtable.
+ Use DECL_DEBUG_EXPR and SET_DECL_DEBUG_EXPR.
+ * dwarf2out.c (dwarf2out_var_location): Ditto.
+ * toplev.c (default_tree_printer): Ditto.
+ * tree-outof-ssa.c (create_temp): Ditto.
+ * tree-sra.c (instantiate_element): Ditto.
+ * var-tracking.c (track_expr_p): Ditto.
+ * tree.c (struct tree_map): New structure.
+ (debug_expr_for_decl): New.
+ (tree_map_eq): New function.
+ (tree_map_hash): Ditto.
+ (tree_map_marked_p): Ditto.
+ (print_debug_expr_statistics): Ditto.
+ (decl_debug_expr_lookup): Ditto.
+ (decl_debug_expr_insert): Ditto.
+ (dump_tree_statistics): Dump debug_expr hashtable stats.
+ * tree.h (DECL_DEBUG_EXPR): Change
+ (SET_DECL_DEBUG_EXPR): Add.
+
2005-06-01 Alan Modra <amodra@bigpond.net.au>
* configure.ac: Add --enable-secureplt.
diff --git a/gcc/c-objc-common.c b/gcc/c-objc-common.c
index 0dc8f55ddfc..95a0a3a7130 100644
--- a/gcc/c-objc-common.c
+++ b/gcc/c-objc-common.c
@@ -171,7 +171,7 @@ c_tree_printer (pretty_printer *pp, text_info *text)
switch (*text->format_spec)
{
case 'D':
- if (DECL_DEBUG_EXPR (t) && DECL_DEBUG_EXPR_IS_FROM (t))
+ if (DECL_DEBUG_EXPR_IS_FROM (t) && DECL_DEBUG_EXPR (t))
{
t = DECL_DEBUG_EXPR (t);
if (!DECL_P (t))
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 32711c7227c..1afe52e540d 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -13283,7 +13283,7 @@ dwarf2out_var_location (rtx loc_note)
last_insn = loc_note;
last_label = newloc->label;
decl = NOTE_VAR_LOCATION_DECL (loc_note);
- if (DECL_DEBUG_EXPR (decl) && DECL_DEBUG_EXPR_IS_FROM (decl)
+ if (DECL_DEBUG_EXPR_IS_FROM (decl) && DECL_DEBUG_EXPR (decl)
&& DECL_P (DECL_DEBUG_EXPR (decl)))
decl = DECL_DEBUG_EXPR (decl);
add_var_loc_to_decl (decl, newloc);
diff --git a/gcc/toplev.c b/gcc/toplev.c
index 196595c6805..6cda6bba35b 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -1575,7 +1575,7 @@ default_tree_printer (pretty_printer * pp, text_info *text)
{
case 'D':
t = va_arg (*text->args_ptr, tree);
- if (DECL_DEBUG_EXPR (t) && DECL_DEBUG_EXPR_IS_FROM (t))
+ if (DECL_DEBUG_EXPR_IS_FROM (t) && DECL_DEBUG_EXPR (t))
t = DECL_DEBUG_EXPR (t);
break;
diff --git a/gcc/tree-outof-ssa.c b/gcc/tree-outof-ssa.c
index 52505c1aee4..de3af73b3b3 100644
--- a/gcc/tree-outof-ssa.c
+++ b/gcc/tree-outof-ssa.c
@@ -158,14 +158,14 @@ create_temp (tree t)
name = "temp";
tmp = create_tmp_var (type, name);
- if (DECL_DEBUG_EXPR (t) && DECL_DEBUG_EXPR_IS_FROM (t))
+ if (DECL_DEBUG_EXPR_IS_FROM (t) && DECL_DEBUG_EXPR (t))
{
- DECL_DEBUG_EXPR (tmp) = DECL_DEBUG_EXPR (t);
+ SET_DECL_DEBUG_EXPR (tmp, DECL_DEBUG_EXPR (t));
DECL_DEBUG_EXPR_IS_FROM (tmp) = 1;
}
else if (!DECL_IGNORED_P (t))
{
- DECL_DEBUG_EXPR (tmp) = t;
+ SET_DECL_DEBUG_EXPR (tmp, t);
DECL_DEBUG_EXPR_IS_FROM (tmp) = 1;
}
DECL_ARTIFICIAL (tmp) = DECL_ARTIFICIAL (t);
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 78cd03b7bf5..811f675fd38 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -1126,9 +1126,9 @@ instantiate_element (struct sra_elt *elt)
DECL_NAME (var) = get_identifier (pretty_name);
obstack_free (&sra_obstack, pretty_name);
- DECL_DEBUG_EXPR (var) = generate_element_ref (elt);
+ SET_DECL_DEBUG_EXPR (var, generate_element_ref (elt));
DECL_DEBUG_EXPR_IS_FROM (var) = 1;
-
+
DECL_IGNORED_P (var) = 0;
TREE_NO_WARNING (var) = TREE_NO_WARNING (base);
}
diff --git a/gcc/tree.c b/gcc/tree.c
index 133feb89881..b34d07c548f 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -131,19 +131,36 @@ static GTY (()) tree int_cst_node;
static GTY ((if_marked ("ggc_marked_p"), param_is (union tree_node)))
htab_t int_cst_hash_table;
+/* General tree->tree mapping structure for use in hash tables. */
+
+struct tree_map GTY(())
+{
+ hashval_t hash;
+ tree from;
+ tree to;
+};
+
+static GTY ((if_marked ("tree_map_marked_p"), param_is (struct tree_map)))
+ htab_t debug_expr_for_decl;
+
static void set_type_quals (tree, int);
static int type_hash_eq (const void *, const void *);
static hashval_t type_hash_hash (const void *);
+static int tree_map_eq (const void *, const void *);
+static hashval_t tree_map_hash (const void *);
static hashval_t int_cst_hash_hash (const void *);
static int int_cst_hash_eq (const void *, const void *);
static void print_type_hash_statistics (void);
+static void print_debug_expr_statistics (void);
static tree make_vector_type (tree, int, enum machine_mode);
static int type_hash_marked_p (const void *);
+static int tree_map_marked_p (const void *);
static unsigned int type_hash_list (tree, hashval_t);
static unsigned int attribute_hash_list (tree, hashval_t);
tree global_trees[TI_MAX];
tree integer_types[itk_none];
+
/* Init tree.c. */
@@ -153,9 +170,15 @@ init_ttree (void)
/* Initialize the hash table of types. */
type_hash_table = htab_create_ggc (TYPE_HASH_INITIAL_SIZE, type_hash_hash,
type_hash_eq, 0);
+
+ debug_expr_for_decl = htab_create_ggc (512, tree_map_hash,
+ tree_map_eq, 0);
+
int_cst_hash_table = htab_create_ggc (1024, int_cst_hash_hash,
int_cst_hash_eq, NULL);
+
int_cst_node = make_node (INTEGER_CST);
+
}
@@ -3430,6 +3453,76 @@ build_variant_type_copy (tree type)
return t;
}
+/* Return true if the from tree in both tree maps are equal. */
+
+static int
+tree_map_eq (const void *va, const void *vb)
+{
+ const struct tree_map *a = va, *b = vb;
+ return (a->from == b->from);
+}
+
+/* Hash a from tree in a tree_map. */
+
+static hashval_t
+tree_map_hash (const void *item)
+{
+ return (((const struct tree_map *) item)->hash);
+}
+
+/* Return true if this tree map structure is marked for garbage collection
+ purposes. We simply return true if the from tree is marked, so that this
+ structure goes away when the from tree goes away. */
+
+static int
+tree_map_marked_p (const void *p)
+{
+ tree from = ((struct tree_map *) p)->from;
+
+ return ggc_marked_p (from);
+}
+
+/* Print out the statistics for the DECL_DEBUG_EXPR hash table. */
+
+static void
+print_debug_expr_statistics (void)
+{
+ fprintf (stderr, "DECL_DEBUG_EXPR hash: size %ld, %ld elements, %f collisions\n",
+ (long) htab_size (debug_expr_for_decl),
+ (long) htab_elements (debug_expr_for_decl),
+ htab_collisions (debug_expr_for_decl));
+}
+
+/* Lookup a debug expression for FROM, and return it if we find one. */
+
+tree
+decl_debug_expr_lookup (tree from)
+{
+ struct tree_map *h, in;
+ in.from = from;
+
+ h = htab_find_with_hash (debug_expr_for_decl, &in, htab_hash_pointer (from));
+ if (h)
+ return h->to;
+ return NULL_TREE;
+}
+
+/* Insert a mapping FROM->TO in the debug expression hashtable. */
+
+void
+decl_debug_expr_insert (tree from, tree to)
+{
+ struct tree_map *h;
+ void **loc;
+
+ h = ggc_alloc (sizeof (struct tree_map));
+ h->hash = htab_hash_pointer (from);
+ h->from = from;
+ h->to = to;
+ loc = htab_find_slot_with_hash (debug_expr_for_decl, h, h->hash, INSERT);
+ *(struct tree_map **) loc = h;
+}
+
/* Hashing of types so that we don't make duplicates.
The entry point is `type_hash_canon'. */
@@ -5261,6 +5354,7 @@ dump_tree_statistics (void)
fprintf (stderr, "(No per-node statistics)\n");
#endif
print_type_hash_statistics ();
+ print_debug_expr_statistics ();
lang_hooks.print_statistics ();
}
diff --git a/gcc/tree.h b/gcc/tree.h
index e72a20fddca..e842f694025 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -2053,10 +2053,17 @@ struct tree_binfo GTY (())
writing debugging information about vfield and vbase decls for C++. */
#define DECL_FCONTEXT(NODE) (FIELD_DECL_CHECK (NODE)->decl.vindex)
+extern tree decl_debug_expr_lookup (tree);
+extern void decl_debug_expr_insert (tree, tree);
+
/* For VAR_DECL, this is set to either an expression that it was split
from (if DECL_DEBUG_EXPR_IS_FROM is true), otherwise a tree_list of
subexpressions that it was split into. */
-#define DECL_DEBUG_EXPR(NODE) (DECL_CHECK (NODE)->decl.vindex)
+#define DECL_DEBUG_EXPR(NODE) \
+ (decl_debug_expr_lookup (VAR_DECL_CHECK (NODE)))
+
+#define SET_DECL_DEBUG_EXPR(NODE, VAL) \
+ (decl_debug_expr_insert (VAR_DECL_CHECK (NODE), (VAL)))
#define DECL_DEBUG_EXPR_IS_FROM(NODE) \
(DECL_CHECK (NODE)->decl.debug_expr_is_from)
diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c
index a6a9c15d79e..626a8e04dd9 100644
--- a/gcc/var-tracking.c
+++ b/gcc/var-tracking.c
@@ -1441,8 +1441,7 @@ track_expr_p (tree expr)
don't need to track this expression if the ultimate declaration is
ignored. */
realdecl = expr;
- if (DECL_DEBUG_EXPR (realdecl)
- && DECL_DEBUG_EXPR_IS_FROM (realdecl))
+ if (DECL_DEBUG_EXPR_IS_FROM (realdecl) && DECL_DEBUG_EXPR (realdecl))
{
realdecl = DECL_DEBUG_EXPR (realdecl);
/* ??? We don't yet know how to emit DW_OP_piece for variable
OpenPOWER on IntegriCloud