diff options
-rw-r--r-- | gcc/ChangeLog | 19 | ||||
-rw-r--r-- | gcc/cfgexpand.c | 2 | ||||
-rw-r--r-- | gcc/dwarf2out.c | 5 | ||||
-rw-r--r-- | gcc/expr.c | 2 | ||||
-rw-r--r-- | gcc/function.c | 3 | ||||
-rw-r--r-- | gcc/gimplify.c | 5 | ||||
-rw-r--r-- | gcc/tree-mudflap.c | 2 | ||||
-rw-r--r-- | gcc/tree.c | 61 | ||||
-rw-r--r-- | gcc/tree.h | 12 |
9 files changed, 99 insertions, 12 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ad10c835cc3..dbffb903cd8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,22 @@ +2005-06-04 Daniel Berlin <dberlin@dberlin.org> + + * cfgexpand.c (expand_one_var): Use DECL_HAS_VALUE_EXPR_P. + * dwarf2out.c (loc_descriptor_from_tree_1): Ditto. + * expr.c (expand_var): Ditto. + * function.c (gimplify_parameters): Use SET_DECL_VALUE_EXPR too. + * gimplify.c (gimplify_decl_expr): Ditto. + (gimplify_expr): Ditto. + * tree-mudflap.c (mf_decl_eligible_p): Use DECL_HAS_VALUE_EXPR_P. + * tree.c (value_expr_for_decl): New. + (print_value_expr_statistics): New. + (init_ttree): Init value_expr_for_decl. + (decl_value_expr_lookup): New. + (decl_value_expr_insert): Ditto. + (copy_node_stat): Copy DECL_VALUE_EXPR status. + * tree.h (DECL_VALUE_EXPR): Use hashtable. + (SET_DECL_VALUE_EXPR): New. + (DECL_HAS_VALUE_EXPR_P): New. + 2005-06-04 Steven Bosscher <stevenb@suse.de> * lcm.c: Move all mode-switching related functions from here... diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index 4e4a8e208c3..63a4136f238 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -657,7 +657,7 @@ expand_one_var (tree var, bool toplevel) lang_hooks.expand_decl (var); else if (DECL_EXTERNAL (var)) ; - else if (DECL_VALUE_EXPR (var)) + else if (DECL_HAS_VALUE_EXPR_P (var)) ; else if (TREE_STATIC (var)) expand_one_static_var (var); diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 1afe52e540d..af62a770e72 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -8972,8 +8972,9 @@ loc_descriptor_from_tree_1 (tree loc, int want_address) /* FALLTHRU */ case PARM_DECL: - if (DECL_VALUE_EXPR (loc)) - return loc_descriptor_from_tree_1 (DECL_VALUE_EXPR (loc), want_address); + if (DECL_HAS_VALUE_EXPR_P (loc)) + return loc_descriptor_from_tree_1 (DECL_VALUE_EXPR (loc), + want_address); /* FALLTHRU */ case RESULT_DECL: diff --git a/gcc/expr.c b/gcc/expr.c index 5cb883a7ef0..e67d65df6a5 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -6116,7 +6116,7 @@ expand_var (tree var) ? !TREE_ASM_WRITTEN (var) : !DECL_RTL_SET_P (var)) { - if (TREE_CODE (var) == VAR_DECL && DECL_VALUE_EXPR (var)) + if (TREE_CODE (var) == VAR_DECL && DECL_HAS_VALUE_EXPR_P (var)) /* Should be ignored. */; else if (lang_hooks.expand_decl (var)) /* OK. */; diff --git a/gcc/function.c b/gcc/function.c index 6496e4cd954..6337b5dab1d 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -3147,7 +3147,8 @@ gimplify_parameters (void) t = build2 (MODIFY_EXPR, void_type_node, local, parm); gimplify_and_add (t, &stmts); - DECL_VALUE_EXPR (parm) = local; + SET_DECL_VALUE_EXPR (parm, local); + DECL_HAS_VALUE_EXPR_P (parm) = 1; } } } diff --git a/gcc/gimplify.c b/gcc/gimplify.c index c86d9d00af4..6834e1a3c5f 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -1011,7 +1011,8 @@ gimplify_decl_expr (tree *stmt_p) addr = create_tmp_var (ptr_type, get_name (decl)); DECL_IGNORED_P (addr) = 0; t = build_fold_indirect_ref (addr); - DECL_VALUE_EXPR (decl) = t; + SET_DECL_VALUE_EXPR (decl, t); + DECL_HAS_VALUE_EXPR_P (decl) = 1; args = tree_cons (NULL, DECL_SIZE_UNIT (decl), NULL); t = built_in_decls[BUILT_IN_ALLOCA]; @@ -4183,7 +4184,7 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p, /* If this is a local variable sized decl, it must be accessed indirectly. Perform that substitution. */ - if (DECL_VALUE_EXPR (tmp)) + if (DECL_HAS_VALUE_EXPR_P (tmp)) { *expr_p = unshare_expr (DECL_VALUE_EXPR (tmp)); ret = GS_OK; diff --git a/gcc/tree-mudflap.c b/gcc/tree-mudflap.c index 0234c5976e6..f7ab16e3233 100644 --- a/gcc/tree-mudflap.c +++ b/gcc/tree-mudflap.c @@ -710,7 +710,7 @@ mf_decl_eligible_p (tree decl) /* The type of the variable must be complete. */ && COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (decl)) /* The decl hasn't been decomposed somehow. */ - && DECL_VALUE_EXPR (decl) == NULL); + && !DECL_HAS_VALUE_EXPR_P (decl)); } diff --git a/gcc/tree.c b/gcc/tree.c index 0592704b272..fc0bf99552f 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -143,6 +143,9 @@ struct tree_map GTY(()) static GTY ((if_marked ("tree_map_marked_p"), param_is (struct tree_map))) htab_t debug_expr_for_decl; +static GTY ((if_marked ("tree_map_marked_p"), param_is (struct tree_map))) + htab_t value_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 *); @@ -152,6 +155,7 @@ 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 void print_value_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 *); @@ -174,6 +178,9 @@ init_ttree (void) debug_expr_for_decl = htab_create_ggc (512, tree_map_hash, tree_map_eq, 0); + value_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); @@ -465,7 +472,16 @@ copy_node_stat (tree node MEM_STAT_DECL) t->common.ann = 0; if (TREE_CODE_CLASS (code) == tcc_declaration) - DECL_UID (t) = next_decl_uid++; + { + DECL_UID (t) = next_decl_uid++; + if ((TREE_CODE (node) == PARM_DECL || TREE_CODE (node) == VAR_DECL) + && DECL_HAS_VALUE_EXPR_P (node)) + { + SET_DECL_VALUE_EXPR (t, DECL_VALUE_EXPR (node)); + DECL_HAS_VALUE_EXPR_P (t) = 1; + } + + } else if (TREE_CODE_CLASS (code) == tcc_type) { TYPE_UID (t) = next_type_uid++; @@ -3493,6 +3509,16 @@ print_debug_expr_statistics (void) htab_collisions (debug_expr_for_decl)); } +/* Print out the statistics for the DECL_VALUE_EXPR hash table. */ + +static void +print_value_expr_statistics (void) +{ + fprintf (stderr, "DECL_VALUE_EXPR hash: size %ld, %ld elements, %f collisions\n", + (long) htab_size (value_expr_for_decl), + (long) htab_elements (value_expr_for_decl), + htab_collisions (value_expr_for_decl)); +} /* Lookup a debug expression for FROM, and return it if we find one. */ tree @@ -3522,7 +3548,37 @@ decl_debug_expr_insert (tree from, tree to) loc = htab_find_slot_with_hash (debug_expr_for_decl, h, h->hash, INSERT); *(struct tree_map **) loc = h; } - + +/* Lookup a value expression for FROM, and return it if we find one. */ + +tree +decl_value_expr_lookup (tree from) +{ + struct tree_map *h, in; + in.from = from; + + h = htab_find_with_hash (value_expr_for_decl, &in, htab_hash_pointer (from)); + if (h) + return h->to; + return NULL_TREE; +} + +/* Insert a mapping FROM->TO in the value expression hashtable. */ + +void +decl_value_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 (value_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'. */ @@ -5355,6 +5411,7 @@ dump_tree_statistics (void) #endif print_type_hash_statistics (); print_debug_expr_statistics (); + print_value_expr_statistics (); lang_hooks.print_statistics (); } diff --git a/gcc/tree.h b/gcc/tree.h index ced72b17bce..fd3e45d6781 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -2187,12 +2187,19 @@ extern void decl_debug_expr_insert (tree, tree); entire function. */ #define DECL_SAVED_TREE(NODE) (FUNCTION_DECL_CHECK (NODE)->decl.saved_tree) +extern tree decl_value_expr_lookup (tree); +extern void decl_value_expr_insert (tree, tree); + /* In a VAR_DECL or PARM_DECL, the location at which the value may be found, if transformations have made this more complicated than evaluating the decl itself. This should only be used for debugging; once this field has been set, the decl itself may not legitimately appear in the function. */ +#define DECL_HAS_VALUE_EXPR_P(NODE) \ + (TREE_CHECK2 (NODE, VAR_DECL, PARM_DECL)->decl.has_value_expr) #define DECL_VALUE_EXPR(NODE) \ - (TREE_CHECK2 (NODE, VAR_DECL, PARM_DECL)->decl.saved_tree) + (decl_value_expr_lookup (TREE_CHECK2 (NODE, VAR_DECL, PARM_DECL))) +#define SET_DECL_VALUE_EXPR(NODE, VAL) \ + (decl_value_expr_insert (TREE_CHECK2 (NODE, VAR_DECL, PARM_DECL), VAL)) /* Nonzero in a FUNCTION_DECL means this function should be treated as if it were a malloc, meaning it returns a pointer that is @@ -2412,7 +2419,8 @@ struct tree_decl GTY(()) unsigned returns_twice_flag : 1; unsigned seen_in_bind_expr : 1; unsigned novops_flag : 1; - /* 9 unused bits. */ + unsigned has_value_expr:1; + /* 8 unused bits. */ union tree_decl_u1 { /* In a FUNCTION_DECL for which DECL_BUILT_IN holds, this is |