Hi all,

This patch generalises the TARGET_MACRO_FUSION_PAIR_P hook usage to work on more than just compares and conditional branches for which it was initially designed for (for x86).

There are some instructions in arm and aarch64 that can be fused together when they're back to back in the instruction stream and I'd like to use this hook to keep them together.

I'll post an implementation of TARGET_MACRO_FUSION_PAIR_P for arm and aarch64 shortly...

Bootstrapped and tested on x86, aarch64-none-linux-gnu and arm-none-linux-gnueabihf.

Ok for trunk?

2014-06-27  Ramana Radhakrishnan <ramana.radhakrish...@arm.com>
                    Kyrylo Tkachov  <kyrylo.tkac...@arm.com>

    * sched-deps.c (try_group_insn): Generalise macro fusion hook usage
    to any two insns.  Update comment.
commit 1b096c837bf49dcfd9ff3e55168593d4a4aea48d
Author: Kyrylo Tkachov <kyrylo.tkac...@arm.com>
Date:   Fri Jun 13 11:41:41 2014 +0100

    [sched-deps] Generalise macro fusion hook usage

diff --git a/gcc/sched-deps.c b/gcc/sched-deps.c
index 7cafc8b..71e274d 100644
--- a/gcc/sched-deps.c
+++ b/gcc/sched-deps.c
@@ -2820,35 +2820,57 @@ sched_analyze_2 (struct deps_desc *deps, rtx x, rtx insn)
     sched_deps_info->finish_rhs ();
 }
 
-/* Try to group comparison and the following conditional jump INSN if
-   they're already adjacent. This is to prevent scheduler from scheduling
-   them apart.  */
+/* Try to group two fuseable insns together to prevent scheduler
+   from scheduling them apart.  */
 
 static void
 try_group_insn (rtx insn)
 {
-  unsigned int condreg1, condreg2;
-  rtx cc_reg_1;
   rtx prev;
 
-  if (!any_condjump_p (insn))
+  if (!targetm.sched.macro_fusion_pair_p)
     return;
 
-  targetm.fixed_condition_code_regs (&condreg1, &condreg2);
-  cc_reg_1 = gen_rtx_REG (CCmode, condreg1);
-  prev = prev_nonnote_nondebug_insn (insn);
-  if (!reg_referenced_p (cc_reg_1, PATTERN (insn))
-      || !prev
-      || !modified_in_p (cc_reg_1, prev))
-    return;
+  if (any_condjump_p (insn))
+    {
+      unsigned int condreg1, condreg2;
+      rtx cc_reg_1;
+      targetm.fixed_condition_code_regs (&condreg1, &condreg2);
+      cc_reg_1 = gen_rtx_REG (CCmode, condreg1);
+      prev = prev_nonnote_nondebug_insn (insn);
+      if (!reg_referenced_p (cc_reg_1, PATTERN (insn))
+	  || !prev
+	  || !modified_in_p (cc_reg_1, prev))
+	return;
+
+      goto succ;
 
+    }
+  else
+    {
+      rtx set_dest = single_set (insn);
+
+      prev = prev_nonnote_nondebug_insn (insn);
+      if (prev
+	  && set_dest
+	  && single_set (prev))
+	{
+	  set_dest = SET_DEST (set_dest);
+
+	  if (!modified_in_p (set_dest, prev))
+	    return;
+
+	  goto succ;
+	}
+    }
+
+  return;
+
+ succ:
   /* Different microarchitectures support macro fusions for different
      combinations of insn pairs.  */
-  if (!targetm.sched.macro_fusion_pair_p
-      || !targetm.sched.macro_fusion_pair_p (prev, insn))
-    return;
-
-  SCHED_GROUP_P (insn) = 1;
+  if (prev && targetm.sched.macro_fusion_pair_p (prev, insn))
+    SCHED_GROUP_P (insn) = 1;
 }
 
 /* Analyze an INSN with pattern X to find all dependencies.  */

Reply via email to