@@ -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