gimplify.c (find_single_pointer_decl_1): New static function.
* 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. From-SVN: r104890
This commit is contained in:
parent
644cb69f80
commit
0b494699b4
@ -1,3 +1,25 @@
|
||||
2005-10-03 Ian Lance Taylor <ian@airs.com>
|
||||
|
||||
* 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 <dnovillo@redhat.com>
|
||||
|
||||
PR 24142
|
||||
|
@ -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))
|
||||
{
|
||||
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
|
||||
|
@ -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;
|
||||
|
||||
|
57
gcc/tree.c
57
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 ();
|
||||
}
|
||||
|
||||
|
17
gcc/tree.h
17
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.
|
||||
@ -2501,6 +2515,7 @@ struct tree_decl_with_vis GTY(())
|
||||
unsigned in_text_section : 1;
|
||||
unsigned gimple_formal_temp : 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,
|
||||
|
Loading…
Reference in New Issue
Block a user