OSDN Git Service

* tree-ssa-forwprop.c (substitute_single_use_vars): Remove
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-copy.c
index 1a760ec..ff497a8 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
@@ -112,8 +112,8 @@ may_propagate_copy (tree dest, tree orig)
        return false;
       else if (!lang_hooks.types_compatible_p (type_d, type_o))
        return false;
-      else if (!alias_sets_conflict_p (get_alias_set (type_d),
-                                      get_alias_set (type_o)))
+      else if (get_alias_set (TREE_TYPE (type_d)) != 
+              get_alias_set (TREE_TYPE (type_o)))
        return false;
     }
 
@@ -131,8 +131,7 @@ may_propagate_copy (tree dest, tree orig)
 #ifdef ENABLE_CHECKING
          /* If we have one real and one virtual operand, then something has
             gone terribly wrong.  */
-         if (is_gimple_reg (orig))
-           abort ();
+         gcc_assert (!is_gimple_reg (orig));
 #endif
        }
 
@@ -146,17 +145,27 @@ may_propagate_copy (tree dest, tree orig)
       && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (orig))
     return false;
 
-  /* If DEST is an SSA_NAME that flows from an abnormal edge or if it
-     represents a hard register, then it cannot be replaced.  */
+  /* If DEST is an SSA_NAME that flows from an abnormal edge, then it
+     cannot be replaced.  */
   if (TREE_CODE (dest) == SSA_NAME
-      && (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (dest)
-         || DECL_HARD_REGISTER (SSA_NAME_VAR (dest))))
+      && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (dest))
     return false;
 
   /* Anything else is OK.  */
   return true;
 }
 
+/* Similarly, but we know that we're propagating into an ASM_EXPR.  */
+
+bool
+may_propagate_copy_into_asm (tree dest)
+{
+  /* Hard register operands of asms are special.  Do not bypass.  */
+  return !(TREE_CODE (dest) == SSA_NAME
+          && TREE_CODE (SSA_NAME_VAR (dest)) == VAR_DECL
+          && DECL_HARD_REGISTER (SSA_NAME_VAR (dest)));
+}
+
 
 /* Given two SSA_NAMEs pointers ORIG and NEW such that we are copy
    propagating NEW into ORIG, consolidate aliasing information so that
@@ -169,29 +178,44 @@ 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 *new_ptr_info;
+  struct ptr_info_def *orig_ptr_info;
 
+  gcc_assert (POINTER_TYPE_P (TREE_TYPE (orig)));
+  gcc_assert (POINTER_TYPE_P (TREE_TYPE (new)));
 #if defined ENABLE_CHECKING
-  if (!POINTER_TYPE_P (TREE_TYPE (orig))
-      || !POINTER_TYPE_P (TREE_TYPE (new))
-      || !lang_hooks.types_compatible_p (TREE_TYPE (orig), TREE_TYPE (new)))
-    abort ();
+  gcc_assert (lang_hooks.types_compatible_p (TREE_TYPE (orig),
+                                            TREE_TYPE (new)));
 
   /* If the pointed-to alias sets are different, these two pointers
      would never have the same memory tag.  In this case, NEW should
      not have been propagated into ORIG.  */
-  if (get_alias_set (TREE_TYPE (TREE_TYPE (new_sym)))
-      != get_alias_set (TREE_TYPE (TREE_TYPE (orig_sym))))
-    abort ();
+  gcc_assert (get_alias_set (TREE_TYPE (TREE_TYPE (new_sym)))
+             == 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 if (new_ann->type_mem_tag != orig_ann->type_mem_tag)
+  else
+    gcc_assert (new_ann->type_mem_tag == orig_ann->type_mem_tag);
+
+  /* Synchronize flow sensitive alias information.  If both pointers
+     had flow information and they are inconsistent, then something
+     has gone wrong.  */
+  new_ptr_info = get_ptr_info (new);
+  orig_ptr_info = get_ptr_info (orig);
+
+  if (new_ptr_info->name_mem_tag == NULL_TREE)
+    memcpy (new_ptr_info, orig_ptr_info, sizeof (*new_ptr_info));
+  else if (orig_ptr_info->name_mem_tag == NULL_TREE)
+    memcpy (orig_ptr_info, new_ptr_info, sizeof (*orig_ptr_info));
+  else if (orig_ptr_info->name_mem_tag != new_ptr_info->name_mem_tag)
     abort ();
-}
+}   
 
 
 /* Common code for propagate_value and replace_exp.
@@ -206,11 +230,10 @@ replace_exp_1 (use_operand_p op_p, tree val,
   tree op = USE_FROM_PTR (op_p);
 
 #if defined ENABLE_CHECKING
-  if (for_propagation
-      && TREE_CODE (op) == SSA_NAME
-      && TREE_CODE (val) == SSA_NAME
-      && !may_propagate_copy (op, val))
-    abort ();
+  gcc_assert (!(for_propagation
+               && TREE_CODE (op) == SSA_NAME
+               && TREE_CODE (val) == SSA_NAME
+               && !may_propagate_copy (op, val)));
 #endif
 
   if (TREE_CODE (val) == SSA_NAME)
@@ -249,10 +272,9 @@ void
 propagate_tree_value (tree *op_p, tree val)
 {
 #if defined ENABLE_CHECKING
-  if (TREE_CODE (val) == SSA_NAME
-      && TREE_CODE (*op_p) == SSA_NAME
-      && !may_propagate_copy (*op_p, val))
-    abort ();
+  gcc_assert (!(TREE_CODE (val) == SSA_NAME
+               && TREE_CODE (*op_p) == SSA_NAME
+               && !may_propagate_copy (*op_p, val)));
 #endif
 
   if (TREE_CODE (val) == SSA_NAME)