@@ -11784,6 +11784,78 @@ riscv_macro_fusion_pair_p (rtx_insn *prev, rtx_insn *curr)
1178411784 return false;
1178511785}
1178611786
11787+ /* If INSN is a load or store of address in the form of [base+offset],
11788+ extract the two parts and set to BASE and OFFSET. IS_LOAD is set
11789+ to TRUE if it's a load. Return TRUE if INSN is such an instruction,
11790+ otherwise return FALSE. */
11791+
11792+ static bool
11793+ fusion_load_store (rtx_insn *insn, rtx *base, rtx *offset, bool *is_load)
11794+ {
11795+ rtx x, dest, src;
11796+
11797+ gcc_assert (INSN_P (insn));
11798+ x = PATTERN (insn);
11799+ if (GET_CODE (x) != SET)
11800+ return false;
11801+
11802+ src = SET_SRC (x);
11803+ dest = SET_DEST (x);
11804+ if (REG_P (src) && MEM_P (dest))
11805+ {
11806+ *is_load = false;
11807+ extract_base_offset_in_addr (dest, base, offset);
11808+ }
11809+ else if (MEM_P (src) && REG_P (dest))
11810+ {
11811+ *is_load = true;
11812+ extract_base_offset_in_addr (src, base, offset);
11813+ }
11814+ else
11815+ return false;
11816+
11817+ return (*base != NULL_RTX && *offset != NULL_RTX);
11818+ }
11819+
11820+ static void
11821+ riscv_sched_fusion_priority (rtx_insn *insn, int max_pri, int *fusion_pri,
11822+ int *pri)
11823+ {
11824+ int tmp, off_val;
11825+ bool is_load;
11826+ rtx base, offset;
11827+
11828+ gcc_assert (INSN_P (insn));
11829+
11830+ tmp = max_pri - 1;
11831+ if (!fusion_load_store (insn, &base, &offset, &is_load))
11832+ {
11833+ *pri = tmp;
11834+ *fusion_pri = tmp;
11835+ return;
11836+ }
11837+
11838+ tmp /= 2;
11839+
11840+ /* INSN with smaller base register goes first. */
11841+ tmp -= ((REGNO (base) & 0xff) << 20);
11842+
11843+ /* INSN with smaller offset goes first. */
11844+ off_val = (int)(INTVAL (offset));
11845+
11846+ /* Put loads/stores operating on adjacent words into the same
11847+ * scheduling group. */
11848+ *fusion_pri = tmp - ((off_val / (UNITS_PER_WORD * 2)) << 1) + is_load;
11849+
11850+ if (off_val >= 0)
11851+ tmp -= (off_val & 0xfffff);
11852+ else
11853+ tmp += ((- off_val) & 0xfffff);
11854+
11855+ *pri = tmp;
11856+ return;
11857+ }
11858+
1178711859/* Adjust the cost/latency of instructions for scheduling.
1178811860 For now this is just used to change the latency of vector instructions
1178911861 according to their LMUL. We assume that an insn with LMUL == 8 requires
@@ -16468,6 +16540,9 @@ riscv_prefetch_offset_address_p (rtx x, machine_mode mode)
1646816540#undef TARGET_SCHED_INIT
1646916541#define TARGET_SCHED_INIT riscv_sched_init
1647016542
16543+ #undef TARGET_SCHED_FUSION_PRIORITY
16544+ #define TARGET_SCHED_FUSION_PRIORITY riscv_sched_fusion_priority
16545+
1647116546#undef TARGET_SCHED_VARIABLE_ISSUE
1647216547#define TARGET_SCHED_VARIABLE_ISSUE riscv_sched_variable_issue
1647316548
0 commit comments