OSDN Git Service

* cp-tree.h (note_decl_for_pch): New function.
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-copy.c
index dc41e8e..8a03c24 100644 (file)
@@ -44,7 +44,7 @@ Boston, MA 02111-1307, USA.  */
    annotations up-to-date.
 
    We require that for any copy operation where the RHS and LHS have
-   a non-null memory tag that the memory tag be the same.   It is OK
+   a non-null memory tag the memory tag be the same.   It is OK
    for one or both of the memory tags to be NULL.
 
    We also require tracking if a variable is dereferenced in a load or
@@ -178,6 +178,7 @@ merge_alias_info (tree orig, tree new)
   tree orig_sym = SSA_NAME_VAR (orig);
   var_ann_t new_ann = var_ann (new_sym);
   var_ann_t orig_ann = var_ann (orig_sym);
+  struct ptr_info_def *orig_ptr_info;
 
   gcc_assert (POINTER_TYPE_P (TREE_TYPE (orig)));
   gcc_assert (POINTER_TYPE_P (TREE_TYPE (new)));
@@ -192,14 +193,51 @@ merge_alias_info (tree orig, tree new)
              == get_alias_set (TREE_TYPE (TREE_TYPE (orig_sym))));
 #endif
 
-  /* Merge type-based alias info.  */
+  /* Synchronize the type tags.  If both pointers had a tag and they
+     are different, then something has gone wrong.  */
   if (new_ann->type_mem_tag == NULL_TREE)
     new_ann->type_mem_tag = orig_ann->type_mem_tag;
   else if (orig_ann->type_mem_tag == NULL_TREE)
     orig_ann->type_mem_tag = new_ann->type_mem_tag;
   else
     gcc_assert (new_ann->type_mem_tag == orig_ann->type_mem_tag);
-}
+
+  orig_ptr_info = SSA_NAME_PTR_INFO (orig);
+  if (orig_ptr_info && orig_ptr_info->name_mem_tag)
+    {
+      struct ptr_info_def *new_ptr_info = get_ptr_info (new);
+
+      if (new_ptr_info->name_mem_tag == NULL_TREE)
+       {
+         /* If ORIG had a name tag, it means that was dereferenced in
+            the code, and since pointer NEW will now replace every
+            occurrence of ORIG, we have to make sure that NEW has an
+            appropriate tag.  If, NEW did not have a name tag, get it
+            from ORIG.  */
+         memcpy (new_ptr_info, orig_ptr_info, sizeof (*new_ptr_info));
+         new_ptr_info->pt_vars = BITMAP_GGC_ALLOC ();
+         bitmap_copy (new_ptr_info->pt_vars, orig_ptr_info->pt_vars);
+         new_ptr_info->name_mem_tag = orig_ptr_info->name_mem_tag;
+       }
+      else
+       {
+         /* If NEW already had a name tag, nothing needs to be done.
+            Note that pointer NEW may actually have a different set of
+            pointed-to variables.
+            
+            However, since NEW is being copy-propagated into ORIG, it must
+            always be true that the pointed-to set for pointer NEW is the
+            same, or a subset, of the pointed-to set for pointer ORIG.  If
+            this isn't the case, we shouldn't have been able to do the
+            propagation of NEW into ORIG.  */
+#if defined ENABLE_CHECKING
+         if (orig_ptr_info->pt_vars && new_ptr_info->pt_vars)
+           gcc_assert (bitmap_intersect_p (new_ptr_info->pt_vars,
+                                           orig_ptr_info->pt_vars));
+#endif
+       }
+    }
+}   
 
 
 /* Common code for propagate_value and replace_exp.