summaryrefslogtreecommitdiffstats
path: root/gcc/tree-dfa.c
diff options
context:
space:
mode:
authoramacleod <amacleod@138bc75d-0d04-0410-961f-82ee72b054a4>2006-06-08 01:18:16 +0000
committeramacleod <amacleod@138bc75d-0d04-0410-961f-82ee72b054a4>2006-06-08 01:18:16 +0000
commitd328c4ab4881495fcd2f85a8b3b946573b0d8d51 (patch)
treef792289fadf43fd192c8ce4c6629ffdae96b0e3b /gcc/tree-dfa.c
parenta8a6544d4748a449c17156615e7ab8e34b523921 (diff)
downloadppe42-gcc-d328c4ab4881495fcd2f85a8b3b946573b0d8d51.tar.gz
ppe42-gcc-d328c4ab4881495fcd2f85a8b3b946573b0d8d51.zip
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/tree-dfa.c')
-rw-r--r--gcc/tree-dfa.c73
1 files changed, 44 insertions, 29 deletions
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))
OpenPOWER on IntegriCloud