When the insn 1 and 2, 3 and 4 can be fusioned, then there is the following sequence:
;; insn | ;; 1 | sp=sp-0x18 ;; + 2 | [sp+0x10]=ra ;; 3 | [sp+0x8]=s0 ;; 4 | [sp+0x0]=s1 The fusion priority of the insn 2, 3, and 4 are the same. According to the current algorithm, since abs(0x10-0x8)<abs(0x10-0x0), the insn 2 is followed by the insn 3. It is obviously unreasonable to do so. Therefore, when we issue the insn 3 and 4, we should consider the fusion priority of the insn 1 instead of the insn 2. And the final instruction sequence is as follows: ;; insn | ;; 1 | sp=sp-0x18 ;; + 2 | [sp+0x10]=ra ;; 4 | [sp+0x8]=s1 ;; + 3 | [sp+0x0]=s0 gcc/ChangeLog: * haifa-sched.cc (rank_for_schedule): Likewise. --- gcc/haifa-sched.cc | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/gcc/haifa-sched.cc b/gcc/haifa-sched.cc index 1bc610f9a5f..0c8c2b18bd2 100644 --- a/gcc/haifa-sched.cc +++ b/gcc/haifa-sched.cc @@ -2640,12 +2640,18 @@ rank_for_schedule (const void *x, const void *y) int a = INSN_FUSION_PRIORITY (tmp); int b = INSN_FUSION_PRIORITY (tmp2); int last = -1; + rtx_insn *last_insn = last_nondebug_scheduled_insn; - if (last_nondebug_scheduled_insn - && !NOTE_P (last_nondebug_scheduled_insn) + /* If last_insn can be fusioned with the previous insn, then we + should use the previous insn fusion priority and priority. */ + if (last_insn && INSN_P (last_insn) && SCHED_GROUP_P (last_insn)) + last_insn = prev_nonnote_nondebug_insn_bb (last_insn); + + if (last_insn + && !NOTE_P (last_insn) && BLOCK_FOR_INSN (tmp) - == BLOCK_FOR_INSN (last_nondebug_scheduled_insn)) - last = INSN_FUSION_PRIORITY (last_nondebug_scheduled_insn); + == BLOCK_FOR_INSN (last_insn)) + last = INSN_FUSION_PRIORITY (last_insn); if (a != last && b != last) { @@ -2662,9 +2668,9 @@ rank_for_schedule (const void *x, const void *y) } else if (a == b) { - gcc_assert (last_nondebug_scheduled_insn - && !NOTE_P (last_nondebug_scheduled_insn)); - last = INSN_PRIORITY (last_nondebug_scheduled_insn); + gcc_assert (last_insn + && !NOTE_P (last_insn)); + last = INSN_PRIORITY (last_insn); a = abs (INSN_PRIORITY (tmp) - last); b = abs (INSN_PRIORITY (tmp2) - last); -- 2.17.1