Hi, I had a little trouble understanding the sched_fusion code, so I refactored it and added some comments. I think this is a bit easier to read, but I'm equally happy dropping the patch.
Bootstrapped on aarch64-none-linux-gnu. OK? Thanks, James --- 2016-06-03 James Greenhalgh <james.greenha...@arm.com> * config/aarch64/aarch64.c (aarch64_mode_valid_for_sched_fusion_p): Make easier on the eye. (sched_fusion_type): Rename to... (aarch64_sched_fusion_type): ...this. (fusion_load_store): Rename to... (aarch64_fusion_load_store): ...this. Simplify some logic. (aarch64_sched_fusion_priority): Rename some variables.
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index ad07fe1..9435ca1 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -3836,8 +3836,10 @@ offset_12bit_unsigned_scaled_p (machine_mode mode, HOST_WIDE_INT offset) static bool aarch64_mode_valid_for_sched_fusion_p (machine_mode mode) { - return mode == SImode || mode == DImode - || mode == SFmode || mode == DFmode + return mode == SImode + || mode == DImode + || mode == SFmode + || mode == DFmode || (aarch64_vector_mode_supported_p (mode) && GET_MODE_SIZE (mode) == 8); } @@ -13193,7 +13195,7 @@ extract_base_offset_in_addr (rtx mem, rtx *base, rtx *offset) } /* Types for scheduling fusion. */ -enum sched_fusion_type +enum aarch64_sched_fusion_type { SCHED_FUSION_NONE = 0, SCHED_FUSION_LD_SIGN_EXTEND, @@ -13207,13 +13209,14 @@ enum sched_fusion_type extract the two parts and set to BASE and OFFSET. Return scheduling fusion type this INSN is. */ -static enum sched_fusion_type -fusion_load_store (rtx_insn *insn, rtx *base, rtx *offset) +static enum aarch64_sched_fusion_type +aarch64_fusion_load_store (rtx_insn *insn, rtx *base, rtx *offset) { rtx x, dest, src; - enum sched_fusion_type fusion = SCHED_FUSION_LD; + enum aarch64_sched_fusion_type fusion = SCHED_FUSION_LD; gcc_assert (INSN_P (insn)); + x = PATTERN (insn); if (GET_CODE (x) != SET) return SCHED_FUSION_NONE; @@ -13226,24 +13229,22 @@ fusion_load_store (rtx_insn *insn, rtx *base, rtx *offset) if (!aarch64_mode_valid_for_sched_fusion_p (dest_mode)) return SCHED_FUSION_NONE; - if (GET_CODE (src) == SIGN_EXTEND) - { - fusion = SCHED_FUSION_LD_SIGN_EXTEND; - src = XEXP (src, 0); - if (GET_CODE (src) != MEM || GET_MODE (src) != SImode) - return SCHED_FUSION_NONE; - } - else if (GET_CODE (src) == ZERO_EXTEND) + if (GET_CODE (src) == SIGN_EXTEND + || GET_CODE (src) == ZERO_EXTEND) { - fusion = SCHED_FUSION_LD_ZERO_EXTEND; + fusion = GET_CODE (src) == SIGN_EXTEND + ? SCHED_FUSION_LD_SIGN_EXTEND + : SCHED_FUSION_LD_ZERO_EXTEND; src = XEXP (src, 0); - if (GET_CODE (src) != MEM || GET_MODE (src) != SImode) + if (GET_CODE (src) != MEM + || GET_MODE (src) != SImode) return SCHED_FUSION_NONE; } if (GET_CODE (src) == MEM && REG_P (dest)) extract_base_offset_in_addr (src, base, offset); - else if (GET_CODE (dest) == MEM && (REG_P (src) || src == const0_rtx)) + else if (GET_CODE (dest) == MEM + && (REG_P (src) || src == const0_rtx)) { fusion = SCHED_FUSION_ST; extract_base_offset_in_addr (dest, base, offset); @@ -13270,36 +13271,35 @@ static void aarch64_sched_fusion_priority (rtx_insn *insn, int max_pri, int *fusion_pri, int *pri) { - int tmp, off_val; + int off_val; rtx base, offset; - enum sched_fusion_type fusion; + enum aarch64_sched_fusion_type fusion; + + /* The highest priority we want to return is (MAX_PRI - 1). */ + max_pri--; gcc_assert (INSN_P (insn)); - tmp = max_pri - 1; - fusion = fusion_load_store (insn, &base, &offset); + fusion = aarch64_fusion_load_store (insn, &base, &offset); + if (fusion == SCHED_FUSION_NONE) { - *pri = tmp; - *fusion_pri = tmp; + *pri = max_pri; + *fusion_pri = max_pri; return; } - /* Set FUSION_PRI according to fusion type and base register. */ - *fusion_pri = tmp - fusion * FIRST_PSEUDO_REGISTER - REGNO (base); - - /* Calculate PRI. */ - tmp /= 2; + /* Set FUSION_PRI according to fusion type and base register. + This gives a two level sort on fusion priorities, first by type of + fusion, then by REGNO (base) within that band. */ + *fusion_pri = max_pri - (fusion * FIRST_PSEUDO_REGISTER) - REGNO (base); /* INSN with smaller offset goes first. */ off_val = (int)(INTVAL (offset)); if (off_val >= 0) - tmp -= (off_val & 0xfffff); + *pri = (max_pri / 2) - (off_val & 0xfffff); else - tmp += ((- off_val) & 0xfffff); - - *pri = tmp; - return; + *pri = (max_pri / 2) + ((- off_val) & 0xfffff); } /* Given OPERANDS of consecutive load/store, check if we can merge