aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/recog.c52
2 files changed, 46 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3dd3a44..f181753 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/recog.c b/gcc/recog.c
index 3038126..3b9d961 100644
--- a/gcc/recog.c
+++ b/gcc/recog.c
@@ -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;
}