Skip to content

Commit 310e813

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 0e5512b commit 310e813

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
@@ -11133,6 +11133,38 @@ arcv_macro_fusion_pair_p (rtx_insn *prev, rtx_insn *curr)
1113311133
return true;
1113411134
}
1113511135

11136+
/* Fuse load/store + register post-{inc,dec}rement:
11137+
* prev (ld) == (set (reg:X rd1) (mem:X (plus:X (reg:X rs1) (const_int))))
11138+
* or
11139+
* prev (st) == (set (mem:X (plus:X (reg:X rs1) (const_int))) (reg:X rs2))
11140+
* ...
11141+
*/
11142+
if ((GET_CODE (SET_SRC (curr_set)) == PLUS
11143+
|| GET_CODE (SET_SRC (curr_set)) == MINUS)
11144+
&& REG_P (XEXP (SET_SRC (curr_set), 0))
11145+
&& ((get_attr_type (prev) == TYPE_LOAD
11146+
&& REG_P (XEXP (SET_SRC (prev_set), 0))
11147+
&& REGNO (XEXP (SET_SRC (prev_set), 0))
11148+
== REGNO (XEXP (SET_SRC (curr_set), 0))
11149+
&& REGNO (XEXP (SET_SRC (prev_set), 0))
11150+
!= REGNO (SET_DEST (prev_set))
11151+
&& REGNO (SET_DEST (prev_set)) != REGNO (SET_DEST (curr_set))
11152+
/* curr (op-imm) == (set (reg:X rd2) (plus/minus (reg:X rs1) (const_int))) */
11153+
&& (CONST_INT_P (XEXP (SET_SRC (curr_set), 1))
11154+
/* or curr (op) == (set (reg:X rd2) (plus/minus (reg:X rs1) (reg:X rs2))) */
11155+
|| REGNO (SET_DEST (prev_set))
11156+
!= REGNO (XEXP (SET_SRC (curr_set), 1))))
11157+
|| (get_attr_type (prev) == TYPE_STORE
11158+
&& REG_P (XEXP (SET_DEST (prev_set), 0))
11159+
&& REGNO (XEXP (SET_DEST (prev_set), 0))
11160+
== REGNO (XEXP (SET_SRC (curr_set), 0))
11161+
/* curr (op-imm) == (set (reg:X rd2) (plus/minus (reg:X rs1) (const_int))) */
11162+
&& (CONST_INT_P (XEXP (SET_SRC (curr_set), 1))
11163+
/* or curr (op) == (set (reg:X rd2) (plus/minus (reg:X rs1) (reg:X rs2))) */
11164+
|| REGNO (XEXP (SET_DEST (prev_set), 0))
11165+
== REGNO (XEXP (SET_SRC (curr_set), 1))))))
11166+
return true;
11167+
1113611168
/* Fuse load-immediate with a store of the destination register. */
1113711169
if (get_attr_type (prev) == TYPE_MOVE
1113811170
&& get_attr_move_type (prev) == MOVE_TYPE_CONST

0 commit comments

Comments
 (0)