2006-06-07 Andrew MacLeod <amacleod@redhat.com>
authoramacleod <amacleod@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 8 Jun 2006 01:18:16 +0000 (01:18 +0000)
committeramacleod <amacleod@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 8 Jun 2006 01:18:16 +0000 (01:18 +0000)
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

gcc/ChangeLog
gcc/tree-dfa.c
gcc/tree-flow.h
gcc/tree-ssa.c

index 3fbae4c..6a44f7d 100644 (file)
@@ -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
index 621a0d3..b5a0178 100644 (file)
@@ -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))
index 6a953ab..abb585a 100644 (file)
@@ -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;
index 1446612..9eb1b21 100644 (file)
@@ -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;