diff options
author | amacleod <amacleod@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-06-08 01:18:16 +0000 |
---|---|---|
committer | amacleod <amacleod@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-06-08 01:18:16 +0000 |
commit | d328c4ab4881495fcd2f85a8b3b946573b0d8d51 (patch) | |
tree | f792289fadf43fd192c8ce4c6629ffdae96b0e3b /gcc | |
parent | a8a6544d4748a449c17156615e7ab8e34b523921 (diff) | |
download | gcc-d328c4ab4881495fcd2f85a8b3b946573b0d8d51.tar.gz |
2006-06-07 Andrew MacLeod <amacleod@redhat.com>
PR middle-end/27793
* tree-dfa.c (referenced_vars_dup_list): New. List of duplicate
referenced_variables with matching DECL_UID's.
(find_referenced_vars): Make sure duplicate list is empty to start.
(referenced_var_p): Remove.
(referenced_var_check_and_insert): Renamed from referenced_var_insert.
Check if var is in the list, and add if needed. Update the duplicate
list if a different var is in the list with the same DECL_UID.
(add_referenced_var): Call routine to check and insert.
* tree-ssa.c (delete_tree_ssa): Clear var_ann's on duplicates.
* tree-flow.h (referenced_vars_dup_list): External declaration.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@114480 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/tree-dfa.c | 73 | ||||
-rw-r--r-- | gcc/tree-flow.h | 2 | ||||
-rw-r--r-- | gcc/tree-ssa.c | 11 |
4 files changed, 71 insertions, 29 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3fbae4ccabd..6a44f7d5bc0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2006-06-07 Andrew MacLeod <amacleod@redhat.com> + + PR middle-end/27793 + * tree-dfa.c (referenced_vars_dup_list): New. List of duplicate + referenced_variables with matching DECL_UID's. + (find_referenced_vars): Make sure duplicate list is empty to start. + (referenced_var_p): Remove. + (referenced_var_check_and_insert): Renamed from referenced_var_insert. + Check if var is in the list, and add if needed. Update the duplicate + list if a different var is in the list with the same DECL_UID. + (add_referenced_var): Call routine to check and insert. + * tree-ssa.c (delete_tree_ssa): Clear var_ann's on duplicates. + * tree-flow.h (referenced_vars_dup_list): External declaration. + 2006-06-07 Fred Fish <fnf@specifix.com> * config/mips/t-elf (MULTILIB_MATCHES): Combine two entries diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c index 621a0d3d330..b5a01785eac 100644 --- a/gcc/tree-dfa.c +++ b/gcc/tree-dfa.c @@ -75,6 +75,8 @@ static tree find_vars_r (tree *, int *, void *); /* Array of all variables referenced in the function. */ htab_t referenced_vars; +/* List of referenced variables with duplicate UID's. */ +VEC(tree,gc) *referenced_vars_dup_list; /* Default definition for this symbols. If set for symbol, it means that the first reference to this variable in the function is a @@ -100,6 +102,7 @@ find_referenced_vars (void) basic_block bb; block_stmt_iterator si; + gcc_assert (VEC_length (tree, referenced_vars_dup_list) == 0); FOR_EACH_BB (bb) for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si)) { @@ -606,22 +609,6 @@ find_vars_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED) return NULL_TREE; } -/* Lookup VAR in the referenced_vars hashtable and return true if it is - present. */ - -static inline bool -referenced_var_p (tree var) -{ - struct int_tree_map *h, in; - in.uid = DECL_UID (var); - h = (struct int_tree_map *) htab_find_with_hash (referenced_vars, - &in, - in.uid); - if (h) - return h->to != NULL_TREE; - return false; -} - /* Lookup UID in the referenced_vars hashtable and return the associated variable. */ @@ -637,22 +624,52 @@ referenced_var_lookup (unsigned int uid) return NULL_TREE; } -/* Insert the pair UID, TO into the referenced_vars hashtable. */ +/* Check if TO is in the referenced_vars hash table and insert it if not. + Return true if it required insertion. */ -static void -referenced_var_insert (unsigned int uid, tree to) +static bool +referenced_var_check_and_insert (tree to) { - struct int_tree_map *h; + struct int_tree_map *h, in; void **loc; + unsigned int uid = DECL_UID (to); + + in.uid = uid; + in.to = to; + h = (struct int_tree_map *) htab_find_with_hash (referenced_vars, &in, uid); + + if (h) + { + unsigned u; + tree t = NULL_TREE; + + /* DECL_UID has already been entered in the table. Verify that it is + the same entry as TO. */ + gcc_assert (h->to != NULL); + if (h->to == to) + return false; + + /* PRs 26757 and 27793. Maintain a list of duplicate variable pointers + with the same DECL_UID. There isn't usually very many. + TODO. Once the C++ front end doesn't create duplicate DECL UID's, this + code can be removed. */ + for (u = 0; u < VEC_length (tree, referenced_vars_dup_list); u++) + { + t = VEC_index (tree, referenced_vars_dup_list, u); + if (t == to) + break; + } + if (t != to) + VEC_safe_push (tree, gc, referenced_vars_dup_list, to); + return false; + } h = GGC_NEW (struct int_tree_map); h->uid = uid; h->to = to; loc = htab_find_slot_with_hash (referenced_vars, h, uid, INSERT); - /* This assert can only trigger if a variable with the same UID has been - inserted already. */ - gcc_assert ((*(struct int_tree_map **)loc) == NULL); *(struct int_tree_map **) loc = h; + return true; } /* Lookup VAR UID in the default_defs hashtable and return the associated @@ -715,13 +732,11 @@ add_referenced_var (tree var) v_ann = get_var_ann (var); gcc_assert (DECL_P (var)); - if (!referenced_var_p (var)) + /* Insert VAR into the referenced_vars has table if it isn't present. */ + if (referenced_var_check_and_insert (var)) { - /* This is the first time we find this variable, add it to the - REFERENCED_VARS array and annotate it with attributes that are - intrinsic to the variable. */ - - referenced_var_insert (DECL_UID (var), var); + /* This is the first time we found this variable, annotate it with + attributes that are intrinsic to the variable. */ /* Tag's don't have DECL_INITIAL. */ if (MTAG_P (var)) diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h index 6a953ab723e..abb585aba1c 100644 --- a/gcc/tree-flow.h +++ b/gcc/tree-flow.h @@ -419,6 +419,8 @@ typedef struct /* Array of all variables referenced in the function. */ extern GTY((param_is (struct int_tree_map))) htab_t referenced_vars; +/* List of referenced variables in the function with duplicate UID's. */ +extern VEC(tree,gc) *referenced_vars_dup_list; /* Default defs for undefined symbols. */ extern GTY((param_is (struct int_tree_map))) htab_t default_defs; diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c index 14466124318..9eb1b215d17 100644 --- a/gcc/tree-ssa.c +++ b/gcc/tree-ssa.c @@ -853,6 +853,7 @@ delete_tree_ssa (void) block_stmt_iterator bsi; referenced_var_iterator rvi; tree var; + unsigned u; /* Release any ssa_names still in use. */ for (i = 0; i < num_ssa_names; i++) @@ -887,6 +888,16 @@ delete_tree_ssa (void) ggc_free (var->common.ann); var->common.ann = NULL; } + + /* Remove any referenced variables which had duplicate UID's. */ + for (u = 0; u < VEC_length (tree, referenced_vars_dup_list); u++) + { + var = VEC_index (tree, referenced_vars_dup_list, u); + ggc_free (var->common.ann); + var->common.ann = NULL; + } + VEC_free (tree, gc, referenced_vars_dup_list); + htab_delete (referenced_vars); referenced_vars = NULL; |