This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Allow USE in PARALLELs in store_data_bypass_p (take 2)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Eric Botcazou <ebotcazou at adacore dot com>
- Cc: gcc-patches at gcc dot gnu dot org, Jeff Law <law at redhat dot com>
- Date: Mon, 11 Dec 2017 12:52:04 +0100
- Subject: [PATCH] Allow USE in PARALLELs in store_data_bypass_p (take 2)
- Authentication-results: sourceware.org; auth=none
- References: <20171206193659.GI2353@tucnak> <1814092.kl1q82DlzE@polaris> <20171211105137.GI2353@tucnak> <1569994.Mf6OSsmv4a@polaris>
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
On Mon, Dec 11, 2017 at 12:09:14PM +0100, Eric Botcazou wrote:
> > Is that long enough to be worth it? I mean, in all other places (rtlanal.c,
> > recog.c, ...) we use similar code in all spots where it is needed, adding
> > an inline would just mean yet another thing to remember. Or do you mean
> > CLOBBER_OR_USE_P macro?
>
> No, the whole function, it seems to duplicate everything in the 2 main arms.
Ah, that makes a lot of sense. So like this?
2017-12-11 Jakub Jelinek <jakub@redhat.com>
* recog.c (store_data_bypass_p_1): New function.
(store_data_bypass_p): Handle USE in a PARALLEL like CLOBBER. Use
store_data_bypass_p_1 to avoid code duplication. Formatting fixes.
--- gcc/recog.c.jj 2017-12-06 16:32:53.605660887 +0100
+++ gcc/recog.c 2017-12-11 12:49:05.350575530 +0100
@@ -3657,93 +3657,70 @@ 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 and OUT_INSN
- must be either a single_set or a PARALLEL with SETs inside. */
+/* Helper function for store_data_bypass_p, handle just a single SET
+ IN_SET. */
-int
-store_data_bypass_p (rtx_insn *out_insn, rtx_insn *in_insn)
+static bool
+store_data_bypass_p_1 (rtx_insn *out_insn, rtx in_set)
{
- rtx out_set, in_set;
- rtx out_pat, in_pat;
- rtx out_exp, in_exp;
- int i, j;
+ if (!MEM_P (SET_DEST (in_set)))
+ return false;
- in_set = single_set (in_insn);
- if (in_set)
+ rtx out_set = single_set (out_insn);
+ if (out_set)
{
- if (!MEM_P (SET_DEST (in_set)))
+ if (reg_mentioned_p (SET_DEST (out_set), 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
{
- in_pat = PATTERN (in_insn);
- gcc_assert (GET_CODE (in_pat) == PARALLEL);
+ rtx out_pat = PATTERN (out_insn);
+
+ if (GET_CODE (out_pat) != PARALLEL)
+ return false;
- for (i = 0; i < XVECLEN (in_pat, 0); i++)
+ for (int i = 0; i < XVECLEN (out_pat, 0); i++)
{
- in_exp = XVECEXP (in_pat, 0, i);
+ rtx out_exp = XVECEXP (out_pat, 0, i);
- if (GET_CODE (in_exp) == CLOBBER)
+ if (GET_CODE (out_exp) == CLOBBER || GET_CODE (out_exp) == USE)
continue;
- gcc_assert (GET_CODE (in_exp) == SET);
+ gcc_assert (GET_CODE (out_exp) == SET);
- if (!MEM_P (SET_DEST (in_exp)))
+ if (reg_mentioned_p (SET_DEST (out_exp), SET_DEST (in_set)))
return false;
+ }
+ }
+
+ return true;
+}
- 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;
- }
- }
- }
+/* 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 and OUT_INSN
+ must be either a single_set or a PARALLEL with SETs inside. */
+
+int
+store_data_bypass_p (rtx_insn *out_insn, rtx_insn *in_insn)
+{
+ rtx in_set = single_set (in_insn);
+ if (in_set)
+ return store_data_bypass_p_1 (out_insn, in_set);
+
+ rtx in_pat = PATTERN (in_insn);
+ gcc_assert (GET_CODE (in_pat) == PARALLEL);
+
+ for (int i = 0; i < XVECLEN (in_pat, 0); i++)
+ {
+ rtx in_exp = XVECEXP (in_pat, 0, i);
+
+ if (GET_CODE (in_exp) == CLOBBER || GET_CODE (in_exp) == USE)
+ continue;
+
+ gcc_assert (GET_CODE (in_exp) == SET);
+
+ if (!store_data_bypass_p_1 (out_insn, in_exp))
+ return false;
}
return true;
Jakub