aboutsummaryrefslogtreecommitdiff
path: root/gcc/recog.c
diff options
context:
space:
mode:
authorPete Steinmetz <steinmtz@us.ibm.com>2006-10-30 19:43:55 +0000
committerPeter Bergner <bergner@gcc.gnu.org>2006-10-30 13:43:55 -0600
commitff81aa23e51c3d3c1fb52449c583bafeca04ca3f (patch)
tree4bdc4ff78f1ee12eb48985bce03975458389b445 /gcc/recog.c
parent779958a2002bc1247b7bd8ca54808d98791ac6c3 (diff)
downloadgcc-ff81aa23e51c3d3c1fb52449c583bafeca04ca3f.zip
gcc-ff81aa23e51c3d3c1fb52449c583bafeca04ca3f.tar.gz
gcc-ff81aa23e51c3d3c1fb52449c583bafeca04ca3f.tar.bz2
recog.c (store_data_bypass_p): Add support to allow IN_INSN to be a PARALLEL containing sets.
* 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
Diffstat (limited to 'gcc/recog.c')
-rw-r--r--gcc/recog.c89
1 files changed, 67 insertions, 22 deletions
diff --git a/gcc/recog.c b/gcc/recog.c
index cd1cb7d..a3948a7 100644
--- a/gcc/recog.c
+++ b/gcc/recog.c
@@ -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;