recog.c (if_test_bypass_p): Accept multiple set insns for OUT, and any jump or call...
authorRichard Henderson <rth@redhat.com>
Mon, 6 May 2002 20:08:30 +0000 (13:08 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Mon, 6 May 2002 20:08:30 +0000 (13:08 -0700)
        * recog.c (if_test_bypass_p): Accept multiple set insns for OUT,
        and any jump or call for IN.

From-SVN: r53234

gcc/ChangeLog
gcc/recog.c

index 3dd3a44..f181753 100644 (file)
@@ -1,3 +1,8 @@
+2002-05-06  Richard Henderson  <rth@redhat.com>
+
+       * recog.c (if_test_bypass_p): Accept multiple set insns for OUT,
+       and any jump or call for IN.
+
 2002-05-06  Bernd Schmidt  <bernds@redhat.com>
 
        * config/i386/i386.h (CPP_CPUCOMMON_SPEC): Define __SSE2_BUILTINS__ if  
index 3038126..3b9d961 100644 (file)
@@ -3329,9 +3329,10 @@ store_data_bypass_p (out_insn, in_insn)
   return true;
 }
 
-/* True if the dependency between OUT_INSN and IN_INSN is in the 
-   IF_THEN_ELSE condition, and not the THEN or ELSE branch.
-   Both OUT_INSN and IN_INSN must be single_set.  */
+/* True if the dependency between OUT_INSN and IN_INSN is in the IF_THEN_ELSE
+   condition, and not the THEN or ELSE branch.  OUT_INSN may be either a single
+   or multiple set; IN_INSN should be single_set for truth, but for convenience
+   of insn categorization may be any JUMP or CALL insn.  */
 
 int
 if_test_bypass_p (out_insn, in_insn)
@@ -3339,20 +3340,49 @@ if_test_bypass_p (out_insn, in_insn)
 {
   rtx out_set, in_set;
 
-  out_set = single_set (out_insn);
-  if (! out_set)
-    abort ();
-
   in_set = single_set (in_insn);
   if (! in_set)
-    abort ();
+    {
+      if (GET_CODE (in_insn) == JUMP_INSN || GET_CODE (in_insn) == CALL_INSN)
+       return false;
+      abort ();
+    }
 
   if (GET_CODE (SET_SRC (in_set)) != IF_THEN_ELSE)
     return false;
+  in_set = SET_SRC (in_set);
 
-  if (reg_mentioned_p (SET_DEST (out_set), XEXP (in_set, 1))
-      || reg_mentioned_p (SET_DEST (out_set), XEXP (in_set, 2)))
-    return false;
+  out_set = single_set (out_insn);
+  if (out_set)
+    {
+      if (reg_mentioned_p (SET_DEST (out_set), XEXP (in_set, 1))
+         || reg_mentioned_p (SET_DEST (out_set), XEXP (in_set, 2)))
+        return false;
+    }
+  else
+    {
+      rtx out_pat;
+      int i;
+
+      out_pat = PATTERN (out_insn);
+      if (GET_CODE (out_pat) != PARALLEL)
+       abort ();
+
+      for (i = 0; i < XVECLEN (out_pat, 0); i++)
+       {
+         rtx exp = XVECEXP (out_pat, 0, i);
+
+         if (GET_CODE (exp) == CLOBBER)
+           continue;
+
+         if (GET_CODE (exp) != SET)
+           abort ();
+
+         if (reg_mentioned_p (SET_DEST (out_set), XEXP (in_set, 1))
+             || reg_mentioned_p (SET_DEST (out_set), XEXP (in_set, 2)))
+           return false;
+       }
+    }
 
   return true;
 }