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
This commit is contained in:
parent
598f50d789
commit
4f47539144
@ -1,3 +1,19 @@
|
||||
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>
|
||||
|
||||
* tree.h (MARK_TS_EXP): New.
|
||||
|
@ -49,6 +49,11 @@
|
||||
(and (match_code "const_int")
|
||||
(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
|
||||
;; not available in RV32.
|
||||
(define_constraint "G"
|
||||
|
@ -27,6 +27,14 @@
|
||||
(ior (match_operand 0 "const_arith_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"
|
||||
(and (match_code "const_int")
|
||||
(match_test "IN_RANGE (INTVAL (op), 0, 31)")))
|
||||
|
@ -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_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_move (rtx, rtx, rtx, rtx_code, rtx, rtx);
|
||||
#endif
|
||||
extern rtx riscv_legitimize_call_address (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)
|
||||
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
|
||||
least PARM_BOUNDARY bits of alignment, but will be given anything up
|
||||
to PREFERRED_STACK_BOUNDARY bits if the type requires it. */
|
||||
|
@ -662,6 +662,17 @@ typedef struct {
|
||||
#define BRANCH_COST(speed_p, predictable_p) \
|
||||
((!(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
|
||||
|
||||
/* Control the assembler format that we output. */
|
||||
|
@ -156,7 +156,7 @@
|
||||
(define_attr "type"
|
||||
"unknown,branch,jump,call,load,fpload,store,fpstore,
|
||||
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")
|
||||
|
||||
;; If a doubleword move uses these expensive instructions,
|
||||
@ -1804,31 +1804,52 @@
|
||||
|
||||
;; Conditional branches
|
||||
|
||||
(define_insn "*branch_order<mode>"
|
||||
(define_insn "*branch<mode>"
|
||||
[(set (pc)
|
||||
(if_then_else
|
||||
(match_operator 1 "order_operator"
|
||||
[(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 "" ""))
|
||||
(pc)))]
|
||||
""
|
||||
"b%C1\t%2,%3,%0"
|
||||
"b%C1\t%2,%z3,%0"
|
||||
[(set_attr "type" "branch")
|
||||
(set_attr "mode" "none")])
|
||||
|
||||
(define_insn "*branch_zero<mode>"
|
||||
[(set (pc)
|
||||
(if_then_else
|
||||
(match_operator 1 "signed_order_operator"
|
||||
[(match_operand:X 2 "register_operand" "r")
|
||||
(const_int 0)])
|
||||
(label_ref (match_operand 0 "" ""))
|
||||
(pc)))]
|
||||
""
|
||||
"b%C1z\t%2,%0"
|
||||
[(set_attr "type" "branch")
|
||||
(set_attr "mode" "none")])
|
||||
;; Patterns for implementations that optimize short forward branches.
|
||||
|
||||
(define_expand "mov<mode>cc"
|
||||
[(set (match_operand:GPR 0 "register_operand")
|
||||
(if_then_else:GPR (match_operand 1 "comparison_operator")
|
||||
(match_operand:GPR 2 "register_operand")
|
||||
(match_operand:GPR 3 "sfb_alu_operand")))]
|
||||
"TARGET_SFB_ALU"
|
||||
{
|
||||
rtx cmp = operands[1];
|
||||
/* We only handle word mode integer compares for now. */
|
||||
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.
|
||||
(define_expand "condjump"
|
||||
|
@ -37,6 +37,11 @@
|
||||
(eq_attr "type" "branch"))
|
||||
"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
|
||||
(and (eq_attr "tune" "sifive_7")
|
||||
(eq_attr "type" "jump,call"))
|
||||
@ -101,10 +106,13 @@
|
||||
(eq_attr "type" "mfc"))
|
||||
"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")
|
||||
|
||||
(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")
|
||||
|
||||
(define_bypass 2 "sifive_7_i2f"
|
||||
|
Loading…
Reference in New Issue
Block a user