Skip to content

Commit a0e8c15

Browse files
artemiy-volkovMichielDerhaeg
authored andcommitted
arcv: fuse load/store + register post-{inc,dec}rement
With this patch, arcv_macro_fusion_pair_p () recognizes instruction pairs like: LOAD rd1, [rs1,offset] add/sub rd2, rs1, rs2/imm (where all regs are distinct) and: STORE rs2, [rs1,offset] add/sub rd, rs1, rs2/imm as fused macro-op pairs. In the case of a load, rd1 being equal to rd2, rs1, or rs2 would lead to data hazards, hence this is disallowed; for stores, rs1 and rs2 of the two instructions must match. Signed-off-by: Artemiy Volkov <artemiy@synopsys.com>
1 parent c68fd52 commit a0e8c15

File tree

1 file changed

+32
-0
lines changed

1 file changed

+32
-0
lines changed

gcc/config/riscv/riscv.cc

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10506,6 +10506,38 @@ arcv_macro_fusion_pair_p (rtx_insn *prev, rtx_insn *curr)
1050610506
return true;
1050710507
}
1050810508

10509+
/* Fuse load/store + register post-{inc,dec}rement:
10510+
* prev (ld) == (set (reg:X rd1) (mem:X (plus:X (reg:X rs1) (const_int))))
10511+
* or
10512+
* prev (st) == (set (mem:X (plus:X (reg:X rs1) (const_int))) (reg:X rs2))
10513+
* ...
10514+
*/
10515+
if ((GET_CODE (SET_SRC (curr_set)) == PLUS
10516+
|| GET_CODE (SET_SRC (curr_set)) == MINUS)
10517+
&& REG_P (XEXP (SET_SRC (curr_set), 0))
10518+
&& ((get_attr_type (prev) == TYPE_LOAD
10519+
&& REG_P (XEXP (SET_SRC (prev_set), 0))
10520+
&& REGNO (XEXP (SET_SRC (prev_set), 0))
10521+
== REGNO (XEXP (SET_SRC (curr_set), 0))
10522+
&& REGNO (XEXP (SET_SRC (prev_set), 0))
10523+
!= REGNO (SET_DEST (prev_set))
10524+
&& REGNO (SET_DEST (prev_set)) != REGNO (SET_DEST (curr_set))
10525+
/* curr (op-imm) == (set (reg:X rd2) (plus/minus (reg:X rs1) (const_int))) */
10526+
&& (CONST_INT_P (XEXP (SET_SRC (curr_set), 1))
10527+
/* or curr (op) == (set (reg:X rd2) (plus/minus (reg:X rs1) (reg:X rs2))) */
10528+
|| REGNO (SET_DEST (prev_set))
10529+
!= REGNO (XEXP (SET_SRC (curr_set), 1))))
10530+
|| (get_attr_type (prev) == TYPE_STORE
10531+
&& REG_P (XEXP (SET_DEST (prev_set), 0))
10532+
&& REGNO (XEXP (SET_DEST (prev_set), 0))
10533+
== REGNO (XEXP (SET_SRC (curr_set), 0))
10534+
/* curr (op-imm) == (set (reg:X rd2) (plus/minus (reg:X rs1) (const_int))) */
10535+
&& (CONST_INT_P (XEXP (SET_SRC (curr_set), 1))
10536+
/* or curr (op) == (set (reg:X rd2) (plus/minus (reg:X rs1) (reg:X rs2))) */
10537+
|| REGNO (XEXP (SET_DEST (prev_set), 0))
10538+
== REGNO (XEXP (SET_SRC (curr_set), 1))))))
10539+
return true;
10540+
1050910541
/* Fuse load-immediate with a store of the destination register. */
1051010542
if (get_attr_type (prev) == TYPE_MOVE
1051110543
&& get_attr_move_type (prev) == MOVE_TYPE_CONST

0 commit comments

Comments
 (0)