tree-flow-inline.h (may_propagate_copy): Move...
authorRichard Henderson <rth@redhat.com>
Wed, 7 Jul 2004 20:16:00 +0000 (13:16 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Wed, 7 Jul 2004 20:16:00 +0000 (13:16 -0700)
        * tree-flow-inline.h (may_propagate_copy): Move...
        * tree-ssa-copy.c (may_propagate_copy): ... here.  Fail if we
        attempt to copy between types requiring conversion.
        * tree-flow.h (may_propagate_copy): Update decl.
        * tree-ssa-dom.c (cprop_operand): Tidy redundant tests.

From-SVN: r84225

gcc/ChangeLog
gcc/tree-flow-inline.h
gcc/tree-flow.h
gcc/tree-ssa-copy.c
gcc/tree-ssa-dom.c

index 63de4dcad6afc72e8d6c55052bc0af85332d1698..659885e4d7d0f4e9754682aecf512bb2e75456c0 100644 (file)
@@ -1,3 +1,11 @@
+2004-07-07  Richard Henderson  <rth@redhat.com>
+
+       * tree-flow-inline.h (may_propagate_copy): Move...
+       * tree-ssa-copy.c (may_propagate_copy): ... here.  Fail if we
+       attempt to copy between types requiring conversion.
+       * tree-flow.h (may_propagate_copy): Update decl.
+       * tree-ssa-dom.c (cprop_operand): Tidy redundant tests.
+
 2004-07-07  Jakub Jelinek  <jakub@redhat.com>
 
        * config/i386/i386.c (override_options): Don't set x86_prefetch_sse
index bda65ca7f5c89234c9a9887863ac1810448b8ac4..e68e63eb8ed7f75888ca256c6d3b3e505ddd0790 100644 (file)
@@ -467,97 +467,6 @@ is_label_stmt (tree t)
   return false;
 }
 
-/* Return true if we may propagate ORIG into DEST, false otherwise.  */
-static inline bool
-may_propagate_copy (tree dest, tree orig)
-{
-  /* FIXME.  GIMPLE is allowing pointer assignments and comparisons of
-     pointers that have different alias sets.  This means that these
-     pointers will have different memory tags associated to them.
-     
-     If we allow copy propagation in these cases, statements de-referencing
-     the new pointer will now have a reference to a different memory tag
-     with potentially incorrect SSA information.
-
-     This was showing up in libjava/java/util/zip/ZipFile.java with code
-     like:
-
-       struct java.io.BufferedInputStream *T.660;
-       struct java.io.BufferedInputStream *T.647;
-       struct java.io.InputStream *is;
-       struct java.io.InputStream *is.662;
-       [ ... ]
-       T.660 = T.647;
-       is = T.660;     <-- This ought to be type-casted
-       is.662 = is;
-
-     Also, f/name.c exposed a similar problem with a COND_EXPR predicate
-     that was causing DOM to generate and equivalence with two pointers of
-     alias-incompatible types:
-
-       struct _ffename_space *n;
-       struct _ffename *ns;
-       [ ... ]
-       if (n == ns)
-         goto lab;
-       ...
-       lab:
-       return n;
-
-     I think that GIMPLE should emit the appropriate type-casts.  For the
-     time being, blocking copy-propagation in these cases is the safe thing
-     to do.  */
-  if (TREE_CODE (dest) == SSA_NAME
-      && TREE_CODE (orig) == SSA_NAME
-      && POINTER_TYPE_P (TREE_TYPE (dest))
-      && POINTER_TYPE_P (TREE_TYPE (orig)))
-    {
-      tree mt_dest = var_ann (SSA_NAME_VAR (dest))->type_mem_tag;
-      tree mt_orig = var_ann (SSA_NAME_VAR (orig))->type_mem_tag;
-      if (mt_dest && mt_orig && mt_dest != mt_orig)
-       return false;
-    }
-
-  /* If the destination is a SSA_NAME for a virtual operand, then we have
-     some special cases to handle.  */
-  if (TREE_CODE (dest) == SSA_NAME && !is_gimple_reg (dest))
-    {
-      /* If both operands are SSA_NAMEs referring to virtual operands, then
-        we can always propagate.  */
-      if (TREE_CODE (orig) == SSA_NAME)
-       {
-         if (!is_gimple_reg (orig))
-           return true;
-
-#ifdef ENABLE_CHECKING
-         /* If we have one real and one virtual operand, then something has
-            gone terribly wrong.  */
-         if (is_gimple_reg (orig))
-           abort ();
-#endif
-       }
-
-      /* We have a "copy" from something like a constant into a virtual
-        operand.  Reject these.  */
-      return false;
-    }
-
-  /* If ORIG flows in from an abnormal edge, it cannot be propagated.  */
-  if (TREE_CODE (orig) == SSA_NAME
-      && 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 (TREE_CODE (dest) == SSA_NAME
-      && (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (dest)
-         || DECL_HARD_REGISTER (SSA_NAME_VAR (dest))))
-    return false;
-
-  /* Anything else is OK.  */
-  return true;
-}
-
 /* Set the default definition for VAR to DEF.  */
 static inline void
 set_default_def (tree var, tree def)
index aae57bc3cd0ce970a1deccd978947a3815b7e3ea..dc4ddb2d7a4fc7367b9a5886b89ffd4291d0facc 100644 (file)
@@ -591,10 +591,10 @@ extern void debug_dominator_optimization_stats (void);
 extern void propagate_value (use_operand_p, tree);
 extern void propagate_tree_value (tree *, tree);
 extern void replace_exp (use_operand_p, tree);
+extern bool may_propagate_copy (tree, tree);
 
 /* In tree-flow-inline.h  */
 static inline int phi_arg_from_edge (tree, edge);
-static inline bool may_propagate_copy (tree, tree);
 static inline bool is_call_clobbered (tree);
 static inline void mark_call_clobbered (tree);
 
index 1f87c1be4bff770f983d88864fdf939664303365..5d96fae8e5b582243ffc45e42de608f85ee1501c 100644 (file)
@@ -55,6 +55,103 @@ Boston, MA 02111-1307, USA.  */
    APIs defined in this file.  */
 
 
+/* Return true if we may propagate ORIG into DEST, false otherwise.  */
+
+bool
+may_propagate_copy (tree dest, tree orig)
+{
+  tree type_d = TREE_TYPE (dest);
+  tree type_o = TREE_TYPE (orig);
+
+  /* Do not copy between types for which we *do* need a conversion.  */
+  if (!tree_ssa_useless_type_conversion_1 (type_d, type_o))
+    return false;
+
+  /* FIXME.  GIMPLE is allowing pointer assignments and comparisons of
+     pointers that have different alias sets.  This means that these
+     pointers will have different memory tags associated to them.
+     
+     If we allow copy propagation in these cases, statements de-referencing
+     the new pointer will now have a reference to a different memory tag
+     with potentially incorrect SSA information.
+
+     This was showing up in libjava/java/util/zip/ZipFile.java with code
+     like:
+
+       struct java.io.BufferedInputStream *T.660;
+       struct java.io.BufferedInputStream *T.647;
+       struct java.io.InputStream *is;
+       struct java.io.InputStream *is.662;
+       [ ... ]
+       T.660 = T.647;
+       is = T.660;     <-- This ought to be type-casted
+       is.662 = is;
+
+     Also, f/name.c exposed a similar problem with a COND_EXPR predicate
+     that was causing DOM to generate and equivalence with two pointers of
+     alias-incompatible types:
+
+       struct _ffename_space *n;
+       struct _ffename *ns;
+       [ ... ]
+       if (n == ns)
+         goto lab;
+       ...
+       lab:
+       return n;
+
+     I think that GIMPLE should emit the appropriate type-casts.  For the
+     time being, blocking copy-propagation in these cases is the safe thing
+     to do.  */
+  if (TREE_CODE (dest) == SSA_NAME && TREE_CODE (orig) == SSA_NAME
+      && POINTER_TYPE_P (type_d) && POINTER_TYPE_P (type_o))
+    {
+      tree mt_dest = var_ann (SSA_NAME_VAR (dest))->type_mem_tag;
+      tree mt_orig = var_ann (SSA_NAME_VAR (orig))->type_mem_tag;
+      if (mt_dest && mt_orig && mt_dest != mt_orig)
+       return false;
+    }
+
+  /* If the destination is a SSA_NAME for a virtual operand, then we have
+     some special cases to handle.  */
+  if (TREE_CODE (dest) == SSA_NAME && !is_gimple_reg (dest))
+    {
+      /* If both operands are SSA_NAMEs referring to virtual operands, then
+        we can always propagate.  */
+      if (TREE_CODE (orig) == SSA_NAME)
+       {
+         if (!is_gimple_reg (orig))
+           return true;
+
+#ifdef ENABLE_CHECKING
+         /* If we have one real and one virtual operand, then something has
+            gone terribly wrong.  */
+         if (is_gimple_reg (orig))
+           abort ();
+#endif
+       }
+
+      /* We have a "copy" from something like a constant into a virtual
+        operand.  Reject these.  */
+      return false;
+    }
+
+  /* If ORIG flows in from an abnormal edge, it cannot be propagated.  */
+  if (TREE_CODE (orig) == SSA_NAME
+      && 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 (TREE_CODE (dest) == SSA_NAME
+      && (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (dest)
+         || DECL_HARD_REGISTER (SSA_NAME_VAR (dest))))
+    return false;
+
+  /* Anything else is OK.  */
+  return true;
+}
+
 /* Given two SSA_NAMEs, replace the annotations for the one referred to by OP 
    with VAR's annotations.
 
index 356daacb21c08c1e6f672e2ded582701bbf16bb3..c03e2bb06752cb6063d0cdf0c9af009edf3b8e09 100644 (file)
@@ -2906,24 +2906,24 @@ cprop_operand (stmt_ann_t ann, use_operand_p op_p, varray_type const_and_copies)
          val_type = TREE_TYPE (val_type);
        }
 
-      /* Make sure underlying types match before propagating a
-        constant by converting the constant to the proper type.  Note
-        that convert may return a non-gimple expression, in which case
-        we ignore this propagation opportunity.  */
-     if (!lang_hooks.types_compatible_p (op_type, val_type)
-           && TREE_CODE (val) != SSA_NAME)
+      /* Make sure underlying types match before propagating a constant by
+        converting the constant to the proper type.  Note that convert may
+        return a non-gimple expression, in which case we ignore this
+        propagation opportunity.  */
+      if (TREE_CODE (val) != SSA_NAME)
        {
-         val = fold_convert (TREE_TYPE (op), val);
-         if (!is_gimple_min_invariant (val)
-             && TREE_CODE (val) != SSA_NAME)
-           return false;
+         if (!lang_hooks.types_compatible_p (op_type, val_type))
+           {
+             val = fold_convert (TREE_TYPE (op), val);
+             if (!is_gimple_min_invariant (val))
+               return false;
+           }
        }
 
       /* Certain operands are not allowed to be copy propagated due
         to their interaction with exception handling and some GCC
         extensions.  */
-      if (TREE_CODE (val) == SSA_NAME
-         && !may_propagate_copy (op, val))
+      else if (!may_propagate_copy (op, val))
        return false;
 
       /* Dump details.  */