recog.c (store_data_bypass_p): Add support to allow IN_INSN to be a PARALLEL containi...
authorPete Steinmetz <steinmtz@us.ibm.com>
Mon, 30 Oct 2006 19:43:55 +0000 (19:43 +0000)
committerPeter Bergner <bergner@gcc.gnu.org>
Mon, 30 Oct 2006 19:43:55 +0000 (13:43 -0600)
* recog.c (store_data_bypass_p): Add support to allow IN_INSN to
be a PARALLEL containing sets.  Return false when out_pat is not
a PARALLEL insn.

From-SVN: r118199

gcc/ChangeLog
gcc/recog.c

index d9232af3567e4b9f2feced49bfc6dccc5ff49a5a..c9b6244125b2ccb42307f77bed848c23bd52bee9 100644 (file)
@@ -1,3 +1,9 @@
+2006-10-30  Pete Steinmetz  <steinmtz@us.ibm.com>
+
+       * recog.c (store_data_bypass_p): Add support to allow IN_INSN to
+       be a PARALLEL containing sets.  Return false when out_pat is not
+       a PARALLEL insn.
+
 2006-10-30  Richard Sandiford  <richard@codesourcery.com>
 
        * config/mips/mips.md (mul<mode>3): Split into...
index cd1cb7d6bee4eb32e19042744c8b489692302977..a3948a729e09ae7b1c402983ede93f820b8db55a 100644 (file)
@@ -3344,47 +3344,92 @@ peephole2_optimize (void)
 /* Common predicates for use with define_bypass.  */
 
 /* True if the dependency between OUT_INSN and IN_INSN is on the store
-   data not the address operand(s) of the store.  IN_INSN must be
-   single_set.  OUT_INSN must be either a single_set or a PARALLEL with
-   SETs inside.  */
+   data not the address operand(s) of the store.  IN_INSN and OUT_INSN
+   must be either a single_set or a PARALLEL with SETs inside.  */
 
 int
 store_data_bypass_p (rtx out_insn, rtx in_insn)
 {
   rtx out_set, in_set;
+  rtx out_pat, in_pat;
+  rtx out_exp, in_exp;
+  int i, j;
 
   in_set = single_set (in_insn);
-  gcc_assert (in_set);
-
-  if (!MEM_P (SET_DEST (in_set)))
-    return false;
-
-  out_set = single_set (out_insn);
-  if (out_set)
+  if (in_set)
     {
-      if (reg_mentioned_p (SET_DEST (out_set), SET_DEST (in_set)))
+      if (!MEM_P (SET_DEST (in_set)))
        return false;
+
+      out_set = single_set (out_insn);
+      if (out_set)
+        {
+          if (reg_mentioned_p (SET_DEST (out_set), SET_DEST (in_set)))
+            return false;
+        }
+      else
+        {
+          out_pat = PATTERN (out_insn);
+
+         if (GET_CODE (out_pat) != PARALLEL)
+           return false;
+
+          for (i = 0; i < XVECLEN (out_pat, 0); i++)
+          {
+            out_exp = XVECEXP (out_pat, 0, i);
+
+            if (GET_CODE (out_exp) == CLOBBER)
+              continue;
+
+            gcc_assert (GET_CODE (out_exp) == SET);
+
+            if (reg_mentioned_p (SET_DEST (out_exp), SET_DEST (in_set)))
+              return false;
+          }
+      }
     }
   else
     {
-      rtx out_pat;
-      int i;
-
-      out_pat = PATTERN (out_insn);
-      gcc_assert (GET_CODE (out_pat) == PARALLEL);
+      in_pat = PATTERN (in_insn);
+      gcc_assert (GET_CODE (in_pat) == PARALLEL);
 
-      for (i = 0; i < XVECLEN (out_pat, 0); i++)
+      for (i = 0; i < XVECLEN (in_pat, 0); i++)
        {
-         rtx exp = XVECEXP (out_pat, 0, i);
+         in_exp = XVECEXP (in_pat, 0, i);
 
-         if (GET_CODE (exp) == CLOBBER)
+         if (GET_CODE (in_exp) == CLOBBER)
            continue;
 
-         gcc_assert (GET_CODE (exp) == SET);
+         gcc_assert (GET_CODE (in_exp) == SET);
 
-         if (reg_mentioned_p (SET_DEST (exp), SET_DEST (in_set)))
+         if (!MEM_P (SET_DEST (in_exp)))
            return false;
-       }
+
+          out_set = single_set (out_insn);
+          if (out_set)
+            {
+              if (reg_mentioned_p (SET_DEST (out_set), SET_DEST (in_exp)))
+                return false;
+            }
+          else
+            {
+              out_pat = PATTERN (out_insn);
+              gcc_assert (GET_CODE (out_pat) == PARALLEL);
+
+              for (j = 0; j < XVECLEN (out_pat, 0); j++)
+                {
+                  out_exp = XVECEXP (out_pat, 0, j);
+
+                  if (GET_CODE (out_exp) == CLOBBER)
+                    continue;
+
+                  gcc_assert (GET_CODE (out_exp) == SET);
+
+                  if (reg_mentioned_p (SET_DEST (out_exp), SET_DEST (in_exp)))
+                    return false;
+                }
+            }
+        }
     }
 
   return true;