OSDN Git Service

Add PR number in this entry:
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-alias.c
index c65fe8d..30c1e9d 100644 (file)
@@ -344,12 +344,20 @@ struct count_ptr_d
    (ALIGN/MISALIGNED_)INDIRECT_REF nodes for the pointer passed in DATA.  */
 
 static tree
-count_ptr_derefs (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, void *data)
+count_ptr_derefs (tree *tp, int *walk_subtrees, void *data)
 {
   struct count_ptr_d *count_p = (struct count_ptr_d *) data;
 
+  /* Do not walk inside ADDR_EXPR nodes.  In the expression &ptr->fld,
+     pointer 'ptr' is *not* dereferenced, it is simply used to compute
+     the address of 'fld' as 'ptr + offsetof(fld)'.  */
+  if (TREE_CODE (*tp) == ADDR_EXPR)
+    {
+      *walk_subtrees = 0;
+      return NULL_TREE;
+    }
+
   if (INDIRECT_REF_P (*tp) && TREE_OPERAND (*tp, 0) == count_p->ptr)
-/*       || (TREE_CODE (*tp) == MEM_REF && MEM_REF_SYMBOL (*tp) == count_p->ptr)) */
     count_p->count++;
 
   return NULL_TREE;
@@ -560,7 +568,6 @@ delete_alias_info (struct alias_info *ai)
   delete_points_to_sets ();
 }
 
-
 /* Create name tags for all the pointers that have been dereferenced.
    We only create a name tag for a pointer P if P is found to point to
    a set of variables (so that we can alias them to *P) or if it is
@@ -574,7 +581,10 @@ static void
 create_name_tags (void)
 {
   size_t i;
+  VEC (tree, heap) *with_ptvars = NULL;
+  tree ptr;
 
+  /* Collect the list of pointers with a non-empty points to set.  */
   for (i = 1; i < num_ssa_names; i++)
     {
       tree ptr = ssa_name (i);
@@ -595,68 +605,71 @@ create_name_tags (void)
          continue;
        }
 
-      if (pi->pt_vars && !bitmap_empty_p (pi->pt_vars))
+      /* Set pt_anything on the pointers without pt_vars filled in so
+        that they are assigned a type tag.  */
+      
+      if (pi->pt_vars && !bitmap_empty_p (pi->pt_vars))        
+       VEC_safe_push (tree, heap, with_ptvars, ptr);
+      else
+       set_pt_anything (ptr);
+    }
+  
+  /* If we didn't find any pointers with pt_vars set, we're done.  */
+  if (!with_ptvars)
+    return;
+
+  /* Now go through the pointers with pt_vars, and find a name tag
+     with the same pt_vars as this pointer, or create one if one
+     doesn't exist.  */
+  for (i = 0; VEC_iterate (tree, with_ptvars, i, ptr); i++)
+    {
+      struct ptr_info_def *pi = SSA_NAME_PTR_INFO (ptr);
+      size_t j;
+      tree ptr2;
+      tree old_name_tag = pi->name_mem_tag;
+      
+      /* If PTR points to a set of variables, check if we don't
+        have another pointer Q with the same points-to set before
+        creating a tag.  If so, use Q's tag instead of creating a
+        new one.
+        
+        This is important for not creating unnecessary symbols
+        and also for copy propagation.  If we ever need to
+        propagate PTR into Q or vice-versa, we would run into
+        problems if they both had different name tags because
+        they would have different SSA version numbers (which
+        would force us to take the name tags in and out of SSA).  */
+      for (j = 0; j < i && VEC_iterate (tree, with_ptvars, j, ptr2); j++)
        {
-         size_t j;
-         tree old_name_tag = pi->name_mem_tag;
-
-         /* If PTR points to a set of variables, check if we don't
-            have another pointer Q with the same points-to set before
-            creating a tag.  If so, use Q's tag instead of creating a
-            new one.
-
-            This is important for not creating unnecessary symbols
-            and also for copy propagation.  If we ever need to
-            propagate PTR into Q or vice-versa, we would run into
-            problems if they both had different name tags because
-            they would have different SSA version numbers (which
-            would force us to take the name tags in and out of SSA).  */
-         for (j = 1; j < i; j++)
+         struct ptr_info_def *qi = SSA_NAME_PTR_INFO (ptr2);
+         
+         if (bitmap_equal_p (pi->pt_vars, qi->pt_vars))
            {
-             tree q = ssa_name (j);
-             struct ptr_info_def *qi;
-
-             if (!q || !POINTER_TYPE_P (TREE_TYPE (q)))
-               continue;
-
-             qi = SSA_NAME_PTR_INFO (q);
-
-             if (qi
-                 && qi->pt_vars
-                 && qi->name_mem_tag
-                 && bitmap_equal_p (pi->pt_vars, qi->pt_vars))
-               {
-                 pi->name_mem_tag = qi->name_mem_tag;
-                 break;
-               }
+             pi->name_mem_tag = qi->name_mem_tag;
+             break;
            }
-
-         /* If we didn't find a pointer with the same points-to set
-            as PTR, create a new name tag if needed.  */
-         if (pi->name_mem_tag == NULL_TREE)
-           pi->name_mem_tag = get_nmt_for (ptr);
-
-         /* If the new name tag computed for PTR is different than
-            the old name tag that it used to have, then the old tag
-            needs to be removed from the IL, so we mark it for
-            renaming.  */
-         if (old_name_tag && old_name_tag != pi->name_mem_tag)
-           mark_sym_for_renaming (old_name_tag);
-       }
-      else
-       {
-         /* If the pointer does not point to a known spot, we should
-            use type tags.  */
-         set_pt_anything (ptr);
-         continue;
        }
-
+      
+      /* If we didn't find a pointer with the same points-to set
+        as PTR, create a new name tag if needed.  */
+      if (pi->name_mem_tag == NULL_TREE)
+       pi->name_mem_tag = get_nmt_for (ptr);
+      
+      /* If the new name tag computed for PTR is different than
+        the old name tag that it used to have, then the old tag
+        needs to be removed from the IL, so we mark it for
+        renaming.  */
+      if (old_name_tag && old_name_tag != pi->name_mem_tag)
+       mark_sym_for_renaming (old_name_tag);
+      
       TREE_THIS_VOLATILE (pi->name_mem_tag)
-         |= TREE_THIS_VOLATILE (TREE_TYPE (TREE_TYPE (ptr)));
-
+       |= TREE_THIS_VOLATILE (TREE_TYPE (TREE_TYPE (ptr)));
+      
       /* Mark the new name tag for renaming.  */
       mark_sym_for_renaming (pi->name_mem_tag);
     }
+
+  VEC_free (tree, heap, with_ptvars);
 }
 
 
@@ -1503,23 +1516,6 @@ may_alias_p (tree ptr, HOST_WIDE_INT mem_alias_set,
 
   alias_stats.tbaa_queries++;
 
-  /* If VAR is a pointer with the same alias set as PTR, then dereferencing
-     PTR can't possibly affect VAR.  Note, that we are specifically testing
-     for PTR's alias set here, not its pointed-to type.  We also can't
-     do this check with relaxed aliasing enabled.  */
-  if (POINTER_TYPE_P (TREE_TYPE (var))
-      && var_alias_set != 0
-      && mem_alias_set != 0)
-    {
-      HOST_WIDE_INT ptr_alias_set = get_alias_set (ptr);
-      if (ptr_alias_set == var_alias_set)
-       {
-         alias_stats.alias_noalias++;
-         alias_stats.tbaa_resolved++;
-         return false;
-       }
-    }
-
   /* If the alias sets don't conflict then MEM cannot alias VAR.  */
   if (!alias_sets_conflict_p (mem_alias_set, var_alias_set))
     {
@@ -2137,7 +2133,7 @@ dump_points_to_info (FILE *file)
 }
 
 
-/* Dump points-to info pointed by PTO into STDERR.  */
+/* Dump points-to info pointed to by PTO into STDERR.  */
 
 void
 debug_points_to_info (void)
@@ -2211,6 +2207,40 @@ may_be_aliased (tree var)
 }
 
 
+/* Given two symbols return TRUE if one is in the alias set of the other.  */
+bool
+is_aliased_with (tree tag, tree sym)
+{
+  size_t i;
+  varray_type aliases;
+
+  if (var_ann (sym)->is_alias_tag)
+    {
+      aliases = var_ann (tag)->may_aliases;
+
+      if (aliases == NULL)
+       return false;
+
+      for (i = 0; i < VARRAY_ACTIVE_SIZE (aliases); i++)
+       if (VARRAY_TREE (aliases, i) == sym)
+         return true;
+    }
+  else
+    {
+      aliases = var_ann (sym)->may_aliases;
+
+      if (aliases == NULL)
+       return false;
+
+      for (i = 0; i < VARRAY_ACTIVE_SIZE (aliases); i++)
+       if (VARRAY_TREE (aliases, i) == tag)
+         return true;
+    }
+
+  return false;
+}
+
+
 /* Add VAR to the list of may-aliases of PTR's type tag.  If PTR
    doesn't already have a type tag, create one.  */