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. */