Commit 4f475391 by Andrew Waterman Committed by Jim Wilson

RISC-V: Short-forward-branch opt for SiFive 7 series cores.

	gcc/
	* config/riscv/constraints.md (L): New.
	* config/riscv/predicates.md (lui_operand): New.
	(sfb_alu_operand): New.
	* config/riscv/riscv-protos.h (riscv_expand_conditional_move): Declare.
	* config/riscv/riscv.c (riscv_expand_conditional_move): New.
	* config/riscv/riscv.h (TARGET_SFB_ALU): New.
	* config/riscv/risc.md (type): Add sfb_alu.
	(branch<mode>): Renamed from branch_order<mode>.  Change predicate for
	operand 3 to reg_or_0_operand.  In output string, change %3 to %z3.
	(branch_zero<mode>): Delete.
	(mov<mode>cc): New.
	(mov<GPR:mode><X:mode>cc): Likewise.
	* config/riscv/sifive-7.md (sifive_7_sfb_alu): New.  Use in bypasses.

From-SVN: r270758
parent 598f50d7
2019-04-30 Jim Wilson <jimw@sifive.com>
* config/riscv/constraints.md (L): New.
* config/riscv/predicates.md (lui_operand): New.
(sfb_alu_operand): New.
* config/riscv/riscv-protos.h (riscv_expand_conditional_move): Declare.
* config/riscv/riscv.c (riscv_expand_conditional_move): New.
* config/riscv/riscv.h (TARGET_SFB_ALU): New.
* config/riscv/risc.md (type): Add sfb_alu.
(branch<mode>): Renamed from branch_order<mode>. Change predicate for
operand 3 to reg_or_0_operand. In output string, change %3 to %z3.
(branch_zero<mode>): Delete.
(mov<mode>cc): New.
(mov<GPR:mode><X:mode>cc): Likewise.
* config/riscv/sifive-7.md (sifive_7_sfb_alu): New. Use in bypasses.
2019-04-30 Nathan Sidwell <nathan@acm.org> 2019-04-30 Nathan Sidwell <nathan@acm.org>
* tree.h (MARK_TS_EXP): New. * tree.h (MARK_TS_EXP): New.
......
...@@ -49,6 +49,11 @@ ...@@ -49,6 +49,11 @@
(and (match_code "const_int") (and (match_code "const_int")
(match_test "IN_RANGE (ival, 0, 31)"))) (match_test "IN_RANGE (ival, 0, 31)")))
(define_constraint "L"
"A U-type 20-bit signed immediate."
(and (match_code "const_int")
(match_test "LUI_OPERAND (ival)")))
;; Floating-point constant +0.0, used for FCVT-based moves when FMV is ;; Floating-point constant +0.0, used for FCVT-based moves when FMV is
;; not available in RV32. ;; not available in RV32.
(define_constraint "G" (define_constraint "G"
......
...@@ -27,6 +27,14 @@ ...@@ -27,6 +27,14 @@
(ior (match_operand 0 "const_arith_operand") (ior (match_operand 0 "const_arith_operand")
(match_operand 0 "register_operand"))) (match_operand 0 "register_operand")))
(define_predicate "lui_operand"
(and (match_code "const_int")
(match_test "LUI_OPERAND (INTVAL (op))")))
(define_predicate "sfb_alu_operand"
(ior (match_operand 0 "arith_operand")
(match_operand 0 "lui_operand")))
(define_predicate "const_csr_operand" (define_predicate "const_csr_operand"
(and (match_code "const_int") (and (match_code "const_int")
(match_test "IN_RANGE (INTVAL (op), 0, 31)"))) (match_test "IN_RANGE (INTVAL (op), 0, 31)")))
......
...@@ -59,6 +59,7 @@ extern const char *riscv_output_return (); ...@@ -59,6 +59,7 @@ extern const char *riscv_output_return ();
extern void riscv_expand_int_scc (rtx, enum rtx_code, rtx, rtx); extern void riscv_expand_int_scc (rtx, enum rtx_code, rtx, rtx);
extern void riscv_expand_float_scc (rtx, enum rtx_code, rtx, rtx); extern void riscv_expand_float_scc (rtx, enum rtx_code, rtx, rtx);
extern void riscv_expand_conditional_branch (rtx, enum rtx_code, rtx, rtx); extern void riscv_expand_conditional_branch (rtx, enum rtx_code, rtx, rtx);
extern void riscv_expand_conditional_move (rtx, rtx, rtx, rtx_code, rtx, rtx);
#endif #endif
extern rtx riscv_legitimize_call_address (rtx); extern rtx riscv_legitimize_call_address (rtx);
extern void riscv_set_return_address (rtx, rtx); extern void riscv_set_return_address (rtx, rtx);
......
...@@ -2324,6 +2324,18 @@ riscv_expand_conditional_branch (rtx label, rtx_code code, rtx op0, rtx op1) ...@@ -2324,6 +2324,18 @@ riscv_expand_conditional_branch (rtx label, rtx_code code, rtx op0, rtx op1)
emit_jump_insn (gen_condjump (condition, label)); emit_jump_insn (gen_condjump (condition, label));
} }
/* If (CODE OP0 OP1) holds, move CONS to DEST; else move ALT to DEST. */
void
riscv_expand_conditional_move (rtx dest, rtx cons, rtx alt, rtx_code code,
rtx op0, rtx op1)
{
riscv_emit_int_compare (&code, &op0, &op1);
rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
emit_insn (gen_rtx_SET (dest, gen_rtx_IF_THEN_ELSE (GET_MODE (dest), cond,
cons, alt)));
}
/* Implement TARGET_FUNCTION_ARG_BOUNDARY. Every parameter gets at /* Implement TARGET_FUNCTION_ARG_BOUNDARY. Every parameter gets at
least PARM_BOUNDARY bits of alignment, but will be given anything up least PARM_BOUNDARY bits of alignment, but will be given anything up
to PREFERRED_STACK_BOUNDARY bits if the type requires it. */ to PREFERRED_STACK_BOUNDARY bits if the type requires it. */
......
...@@ -662,6 +662,17 @@ typedef struct { ...@@ -662,6 +662,17 @@ typedef struct {
#define BRANCH_COST(speed_p, predictable_p) \ #define BRANCH_COST(speed_p, predictable_p) \
((!(speed_p) || (predictable_p)) ? 2 : riscv_branch_cost) ((!(speed_p) || (predictable_p)) ? 2 : riscv_branch_cost)
/* True if the target optimizes short forward branches around integer
arithmetic instructions into predicated operations, e.g., for
conditional-move operations. The macro assumes that all branch
instructions (BEQ, BNE, BLT, BLTU, BGE, BGEU, C.BEQZ, and C.BNEZ)
support this feature. The macro further assumes that any integer
arithmetic and logical operation (ADD[I], SUB, SLL[I], SRL[I], SRA[I],
SLT[I][U], AND[I], XOR[I], OR[I], LUI, AUIPC, and their compressed
counterparts, including C.MV and C.LI) can be in the branch shadow. */
#define TARGET_SFB_ALU (riscv_microarchitecture == sifive_7)
#define LOGICAL_OP_NON_SHORT_CIRCUIT 0 #define LOGICAL_OP_NON_SHORT_CIRCUIT 0
/* Control the assembler format that we output. */ /* Control the assembler format that we output. */
......
...@@ -156,7 +156,7 @@ ...@@ -156,7 +156,7 @@
(define_attr "type" (define_attr "type"
"unknown,branch,jump,call,load,fpload,store,fpstore, "unknown,branch,jump,call,load,fpload,store,fpstore,
mtc,mfc,const,arith,logical,shift,slt,imul,idiv,move,fmove,fadd,fmul, mtc,mfc,const,arith,logical,shift,slt,imul,idiv,move,fmove,fadd,fmul,
fmadd,fdiv,fcmp,fcvt,fsqrt,multi,auipc,nop,ghost" fmadd,fdiv,fcmp,fcvt,fsqrt,multi,auipc,sfb_alu,nop,ghost"
(cond [(eq_attr "got" "load") (const_string "load") (cond [(eq_attr "got" "load") (const_string "load")
;; If a doubleword move uses these expensive instructions, ;; If a doubleword move uses these expensive instructions,
...@@ -1804,31 +1804,52 @@ ...@@ -1804,31 +1804,52 @@
;; Conditional branches ;; Conditional branches
(define_insn "*branch_order<mode>" (define_insn "*branch<mode>"
[(set (pc) [(set (pc)
(if_then_else (if_then_else
(match_operator 1 "order_operator" (match_operator 1 "order_operator"
[(match_operand:X 2 "register_operand" "r") [(match_operand:X 2 "register_operand" "r")
(match_operand:X 3 "register_operand" "r")]) (match_operand:X 3 "reg_or_0_operand" "rJ")])
(label_ref (match_operand 0 "" "")) (label_ref (match_operand 0 "" ""))
(pc)))] (pc)))]
"" ""
"b%C1\t%2,%3,%0" "b%C1\t%2,%z3,%0"
[(set_attr "type" "branch") [(set_attr "type" "branch")
(set_attr "mode" "none")]) (set_attr "mode" "none")])
(define_insn "*branch_zero<mode>" ;; Patterns for implementations that optimize short forward branches.
[(set (pc)
(if_then_else (define_expand "mov<mode>cc"
(match_operator 1 "signed_order_operator" [(set (match_operand:GPR 0 "register_operand")
[(match_operand:X 2 "register_operand" "r") (if_then_else:GPR (match_operand 1 "comparison_operator")
(const_int 0)]) (match_operand:GPR 2 "register_operand")
(label_ref (match_operand 0 "" "")) (match_operand:GPR 3 "sfb_alu_operand")))]
(pc)))] "TARGET_SFB_ALU"
"" {
"b%C1z\t%2,%0" rtx cmp = operands[1];
[(set_attr "type" "branch") /* We only handle word mode integer compares for now. */
(set_attr "mode" "none")]) if (GET_MODE (XEXP (cmp, 0)) != word_mode)
FAIL;
riscv_expand_conditional_move (operands[0], operands[2], operands[3],
GET_CODE (cmp), XEXP (cmp, 0), XEXP (cmp, 1));
DONE;
})
(define_insn "*mov<GPR:mode><X:mode>cc"
[(set (match_operand:GPR 0 "register_operand" "=r,r")
(if_then_else:GPR
(match_operator 5 "order_operator"
[(match_operand:X 1 "register_operand" "r,r")
(match_operand:X 2 "reg_or_0_operand" "rJ,rJ")])
(match_operand:GPR 3 "register_operand" "0,0")
(match_operand:GPR 4 "sfb_alu_operand" "rJ,IL")))]
"TARGET_SFB_ALU"
"@
b%C5 %1,%z2,1f; mv %0,%z4; 1: # movcc
b%C5 %1,%z2,1f; li %0,%4; 1: # movcc"
[(set_attr "length" "8")
(set_attr "type" "sfb_alu")
(set_attr "mode" "<GPR:MODE>")])
;; Used to implement built-in functions. ;; Used to implement built-in functions.
(define_expand "condjump" (define_expand "condjump"
......
...@@ -37,6 +37,11 @@ ...@@ -37,6 +37,11 @@
(eq_attr "type" "branch")) (eq_attr "type" "branch"))
"sifive_7_B") "sifive_7_B")
(define_insn_reservation "sifive_7_sfb_alu" 2
(and (eq_attr "tune" "sifive_7")
(eq_attr "type" "sfb_alu"))
"sifive_7_A+sifive_7_B")
(define_insn_reservation "sifive_7_jump" 1 (define_insn_reservation "sifive_7_jump" 1
(and (eq_attr "tune" "sifive_7") (and (eq_attr "tune" "sifive_7")
(eq_attr "type" "jump,call")) (eq_attr "type" "jump,call"))
...@@ -101,10 +106,13 @@ ...@@ -101,10 +106,13 @@
(eq_attr "type" "mfc")) (eq_attr "type" "mfc"))
"sifive_7_A") "sifive_7_A")
(define_bypass 1 "sifive_7_load,sifive_7_alu,sifive_7_mul,sifive_7_f2i" (define_bypass 1 "sifive_7_load,sifive_7_alu,sifive_7_mul,sifive_7_f2i,sifive_7_sfb_alu"
"sifive_7_alu,sifive_7_branch") "sifive_7_alu,sifive_7_branch")
(define_bypass 1 "sifive_7_load,sifive_7_alu,sifive_7_mul,sifive_7_f2i" (define_bypass 1 "sifive_7_alu,sifive_7_sfb_alu"
"sifive_7_sfb_alu")
(define_bypass 1 "sifive_7_load,sifive_7_alu,sifive_7_mul,sifive_7_f2i,sifive_7_sfb_alu"
"sifive_7_store" "riscv_store_data_bypass_p") "sifive_7_store" "riscv_store_data_bypass_p")
(define_bypass 2 "sifive_7_i2f" (define_bypass 2 "sifive_7_i2f"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment