From 83b34c62d37b8b2626d357878bc4cf1fe2020851 Mon Sep 17 00:00:00 2001 From: ian Date: Mon, 3 Oct 2005 08:43:45 +0000 Subject: [PATCH] * gimplify.c (find_single_pointer_decl_1): New static function. (find_single_pointer_decl): New static function. (internal_get_tmp_var): For a formal variable, set restrict base information if appropriate. * alias.c (find_base_decl): If a VAR_DECL has a restrict base, return it. * tree.h (DECL_BASED_ON_RESTRICT_P): Define. (DECL_GET_RESTRICT_BASE): Define. (SET_DECL_RESTRICT_BASE): Define. (decl_restrict_base_lookup): Declare. (decl_restrict_base_insert): Declare. (struct tree_decl_with_vis): Add based_on_restrict_p field. * tree.c (restrict_base_for_decl): New static variable. (init_ttree): Initialize restrict_base_for_decl. (copy_node_stat): Copy restrict base information. (decl_restrict_base_lookup): New function. (decl_restrict_base_insert): New function. (print_restrict_base_statistics): New static function. (dump_tree_statistics): Call print_restrict_base_statistics. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@104890 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 22 +++++++++++++++++++++ gcc/alias.c | 9 +++++++-- gcc/gimplify.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ gcc/tree.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- gcc/tree.h | 19 +++++++++++++++++-- 5 files changed, 162 insertions(+), 5 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e27296f..6a566332 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,25 @@ +2005-10-03 Ian Lance Taylor + + * gimplify.c (find_single_pointer_decl_1): New static function. + (find_single_pointer_decl): New static function. + (internal_get_tmp_var): For a formal variable, set restrict base + information if appropriate. + * alias.c (find_base_decl): If a VAR_DECL has a restrict base, + return it. + * tree.h (DECL_BASED_ON_RESTRICT_P): Define. + (DECL_GET_RESTRICT_BASE): Define. + (SET_DECL_RESTRICT_BASE): Define. + (decl_restrict_base_lookup): Declare. + (decl_restrict_base_insert): Declare. + (struct tree_decl_with_vis): Add based_on_restrict_p field. + * tree.c (restrict_base_for_decl): New static variable. + (init_ttree): Initialize restrict_base_for_decl. + (copy_node_stat): Copy restrict base information. + (decl_restrict_base_lookup): New function. + (decl_restrict_base_insert): New function. + (print_restrict_base_statistics): New static function. + (dump_tree_statistics): Call print_restrict_base_statistics. + 2005-10-02 Diego Novillo PR 24142 diff --git a/gcc/alias.c b/gcc/alias.c index 49f712e..4806019 100644 --- a/gcc/alias.c +++ b/gcc/alias.c @@ -395,9 +395,14 @@ find_base_decl (tree t) if (t == 0 || t == error_mark_node || ! POINTER_TYPE_P (TREE_TYPE (t))) return 0; - /* If this is a declaration, return it. */ + /* If this is a declaration, return it. If T is based on a restrict + qualified decl, return that decl. */ if (DECL_P (t)) - return t; + { + if (TREE_CODE (t) == VAR_DECL && DECL_BASED_ON_RESTRICT_P (t)) + t = DECL_GET_RESTRICT_BASE (t); + return t; + } /* Handle general expressions. It would be nice to deal with COMPONENT_REFs here. If we could tell that `a' and `b' were the diff --git a/gcc/gimplify.c b/gcc/gimplify.c index e5d50e2..7047918 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -298,6 +298,48 @@ create_artificial_label (void) return lab; } +/* Subroutine for find_single_pointer_decl. */ + +static tree +find_single_pointer_decl_1 (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, + void *data) +{ + tree *pdecl = (tree *) data; + + if (DECL_P (*tp) && POINTER_TYPE_P (TREE_TYPE (*tp))) + { + if (*pdecl) + { + /* We already found a pointer decl; return anything other + than NULL_TREE to unwind from walk_tree signalling that + we have a duplicate. */ + return *tp; + } + *pdecl = *tp; + } + + return NULL_TREE; +} + +/* Find the single DECL of pointer type in the tree T and return it. + If there are zero or more than one such DECLs, return NULL. */ + +static tree +find_single_pointer_decl (tree t) +{ + tree decl = NULL_TREE; + + if (walk_tree (&t, find_single_pointer_decl_1, &decl, NULL)) + { + /* find_single_pointer_decl_1 returns a non-zero value, causing + walk_tree to return a non-zero value, to indicate that it + found more than one pointer DECL. */ + return NULL_TREE; + } + + return decl; +} + /* Create a new temporary name with PREFIX. Returns an identifier. */ static GTY(()) unsigned int tmp_var_id_num; @@ -470,6 +512,24 @@ internal_get_tmp_var (tree val, tree *pre_p, tree *post_p, bool is_formal) t = lookup_tmp_var (val, is_formal); + if (is_formal) + { + tree u = find_single_pointer_decl (val); + + if (u && TREE_CODE (u) == VAR_DECL && DECL_BASED_ON_RESTRICT_P (u)) + u = DECL_GET_RESTRICT_BASE (u); + if (u && TYPE_RESTRICT (TREE_TYPE (u))) + { + if (DECL_BASED_ON_RESTRICT_P (t)) + gcc_assert (u == DECL_GET_RESTRICT_BASE (t)); + else + { + DECL_BASED_ON_RESTRICT_P (t) = 1; + SET_DECL_RESTRICT_BASE (t, u); + } + } + } + if (TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE) DECL_COMPLEX_GIMPLE_REG_P (t) = 1; diff --git a/gcc/tree.c b/gcc/tree.c index 9c4b29c..f7f6503 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -144,6 +144,9 @@ static GTY ((if_marked ("tree_map_marked_p"), param_is (struct tree_map))) static GTY ((if_marked ("tree_int_map_marked_p"), param_is (struct tree_int_map))) htab_t init_priority_for_decl; +static GTY ((if_marked ("tree_map_marked_p"), param_is (struct tree_map))) + htab_t restrict_base_for_decl; + struct tree_int_map GTY(()) { tree from; @@ -187,6 +190,8 @@ init_ttree (void) tree_map_eq, 0); init_priority_for_decl = htab_create_ggc (512, tree_int_map_hash, tree_int_map_eq, 0); + restrict_base_for_decl = htab_create_ggc (256, tree_map_hash, + tree_map_eq, 0); int_cst_hash_table = htab_create_ggc (1024, int_cst_hash_hash, int_cst_hash_eq, NULL); @@ -568,7 +573,11 @@ copy_node_stat (tree node MEM_STAT_DECL) SET_DECL_INIT_PRIORITY (t, DECL_INIT_PRIORITY (node)); DECL_HAS_INIT_PRIORITY_P (t) = 1; } - + if (TREE_CODE (node) == VAR_DECL && DECL_BASED_ON_RESTRICT_P (node)) + { + SET_DECL_RESTRICT_BASE (t, DECL_GET_RESTRICT_BASE (node)); + DECL_BASED_ON_RESTRICT_P (t) = 1; + } } else if (TREE_CODE_CLASS (code) == tcc_type) { @@ -3777,6 +3786,36 @@ decl_init_priority_insert (tree from, unsigned short to) *(struct tree_int_map **) loc = h; } +/* Look up a restrict qualified base decl for FROM. */ + +tree +decl_restrict_base_lookup (tree from) +{ + struct tree_map *h; + struct tree_map in; + + in.from = from; + h = htab_find_with_hash (restrict_base_for_decl, &in, + htab_hash_pointer (from)); + return h ? h->to : NULL_TREE; +} + +/* Record the restrict qualified base TO for FROM. */ + +void +decl_restrict_base_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 (restrict_base_for_decl, h, h->hash, INSERT); + *(struct tree_map **) loc = h; +} + /* Print out the statistics for the DECL_DEBUG_EXPR hash table. */ static void @@ -3798,6 +3837,21 @@ print_value_expr_statistics (void) (long) htab_elements (value_expr_for_decl), htab_collisions (value_expr_for_decl)); } + +/* Print out statistics for the RESTRICT_BASE_FOR_DECL hash table, but + don't print anything if the table is empty. */ + +static void +print_restrict_base_statistics (void) +{ + if (htab_elements (restrict_base_for_decl) != 0) + fprintf (stderr, + "RESTRICT_BASE hash: size %ld, %ld elements, %f collisions\n", + (long) htab_size (restrict_base_for_decl), + (long) htab_elements (restrict_base_for_decl), + htab_collisions (restrict_base_for_decl)); +} + /* Lookup a debug expression for FROM, and return it if we find one. */ tree @@ -5725,6 +5779,7 @@ dump_tree_statistics (void) print_type_hash_statistics (); print_debug_expr_statistics (); print_value_expr_statistics (); + print_restrict_base_statistics (); lang_hooks.print_statistics (); } diff --git a/gcc/tree.h b/gcc/tree.h index 198c443..08f33fe 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -2425,6 +2425,20 @@ struct tree_parm_decl GTY(()) an address constant. */ #define DECL_NON_ADDR_CONST_P(NODE) (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.non_addr_const_p) +/* DECL_BASED_ON_RESTRICT_P records whether a VAR_DECL is a temporary + based on a variable with a restrict qualified type. If it is, + DECL_RESTRICT_BASE returns the restrict qualified variable on which + it is based. */ + +#define DECL_BASED_ON_RESTRICT_P(NODE) \ + (VAR_DECL_CHECK (NODE)->decl_with_vis.based_on_restrict_p) +#define DECL_GET_RESTRICT_BASE(NODE) \ + (decl_restrict_base_lookup (VAR_DECL_CHECK (NODE))) +#define SET_DECL_RESTRICT_BASE(NODE, VAL) \ + (decl_restrict_base_insert (VAR_DECL_CHECK (NODE), (VAL))) + +extern tree decl_restrict_base_lookup (tree); +extern void decl_restrict_base_insert (tree, tree); /* Used in a DECL to indicate that, even if it TREE_PUBLIC, it need not be put out unless it is needed in this translation unit. @@ -2500,7 +2514,8 @@ struct tree_decl_with_vis GTY(()) unsigned common_flag:1; unsigned in_text_section : 1; unsigned gimple_formal_temp : 1; - unsigned non_addr_const_p : 1; + unsigned non_addr_const_p : 1; + unsigned based_on_restrict_p : 1; /* Used by C++. Might become a generic decl flag. */ unsigned shadowed_for_var_p : 1; @@ -2517,7 +2532,7 @@ struct tree_decl_with_vis GTY(()) /* Belongs to VAR_DECL exclusively. */ ENUM_BITFIELD(tls_model) tls_model : 3; - /* 13 unused bits. */ + /* 11 unused bits. */ }; /* In a VAR_DECL that's static, -- 2.7.4