From e57764be555e4a6162ac2776a98d91f93307eccf Mon Sep 17 00:00:00 2001 From: Claudiu Zissulescu Date: Thu, 13 Feb 2020 12:32:05 +0200 Subject: [PATCH] [ARC] Use TARGET_INSN_COST. TARGET_INSN_COST gives us a better control over the instruction costs than classical RTX_COSTS. A simple cost scheme is in place for the time being, when optimizing for size, the cost is given by the instruction length. When optimizing for speed, the cost is 1 for any recognized instruction, and 2 for any load/store instruction. The latter one can be overwritten by using cost attribute for an instruction. Due to this change, we need to update also a number of instruction patterns with a new predicate to better reflect the costs. gcc/ xxxx-xx-xx Claudiu Zissulescu * config/arc/arc.c (arc_insn_cost): New function. (TARGET_INSN_COST): Define. * config/arc/arc.md (cost): New attribute. (add_n): Use arc_nonmemory_operand. (ashlsi3_insn): Likewise, also update constraints. (ashrsi3_insn): Likewise. (rotrsi3): Likewise. (add_shift): Likewise. * config/arc/predicates.md (arc_nonmemory_operand): New predicate. testsuite/ xxxx-xx-xx Claudiu Zissulescu * gcc.target/arc/or-cnst-size2.c: Update test. --- gcc/ChangeLog | 12 +++++ gcc/config/arc/arc.c | 52 ++++++++++++++++++++ gcc/config/arc/arc.md | 47 +++++++++--------- gcc/config/arc/predicates.md | 5 ++ gcc/testsuite/ChangeLog | 4 ++ gcc/testsuite/gcc.target/arc/or-cnst-size2.c | 2 +- 6 files changed, 99 insertions(+), 23 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6209e7615de..96a6b8037d5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2020-02-13 Claudiu Zissulescu + + * config/arc/arc.c (arc_insn_cost): New function. + (TARGET_INSN_COST): Define. + * config/arc/arc.md (cost): New attribute. + (add_n): Use arc_nonmemory_operand. + (ashlsi3_insn): Likewise, also update constraints. + (ashrsi3_insn): Likewise. + (rotrsi3): Likewise. + (add_shift): Likewise. + * config/arc/predicates.md (arc_nonmemory_operand): New predicate. + 2020-02-13 Claudiu Zissulescu * config/arc/arc.md (mulsidi_600): Correctly select mlo/mhi diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c index bc342350440..7a9fe08f31d 100644 --- a/gcc/config/arc/arc.c +++ b/gcc/config/arc/arc.c @@ -11757,6 +11757,55 @@ arc_can_use_return_insn (void) && !ARC_INTERRUPT_P (arc_compute_function_type (cfun))); } +/* Helper for INSN_COST. + + Per Segher Boessenkool: rtx_costs computes the cost for any rtx (an + insn, a set, a set source, any random piece of one). set_src_cost, + set_rtx_cost, etc. are helper functions that use that. + + Those functions do not work for parallels. Also, costs are not + additive like this simplified model assumes. Also, more complex + backends tend to miss many cases in their rtx_costs function. + + Many passes that want costs want to know the cost of a full insn. Like + combine. That's why I created insn_cost: it solves all of the above + problems. */ + +static int +arc_insn_cost (rtx_insn *insn, bool speed) +{ + int cost; + if (recog_memoized (insn) < 0) + return 0; + + /* If optimizing for size, we want the insn size. */ + if (!speed) + return get_attr_length (insn); + + /* Use cost if provided. */ + cost = get_attr_cost (insn); + if (cost > 0) + return cost; + + /* For speed make a simple cost model: memory access is more + expensive than any other instruction. */ + enum attr_type type = get_attr_type (insn); + + switch (type) + { + case TYPE_LOAD: + case TYPE_STORE: + cost = COSTS_N_INSNS (2); + break; + + default: + cost = COSTS_N_INSNS (1); + break; + } + + return cost; +} + #undef TARGET_USE_ANCHORS_FOR_SYMBOL_P #define TARGET_USE_ANCHORS_FOR_SYMBOL_P arc_use_anchors_for_symbol_p @@ -11778,6 +11827,9 @@ arc_can_use_return_insn (void) #undef TARGET_MEMORY_MOVE_COST #define TARGET_MEMORY_MOVE_COST arc_memory_move_cost +#undef TARGET_INSN_COST +#define TARGET_INSN_COST arc_insn_cost + struct gcc_target targetm = TARGET_INITIALIZER; #include "gt-arc.h" diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md index 4c269f565ba..3a7bf7d6f5d 100644 --- a/gcc/config/arc/arc.md +++ b/gcc/config/arc/arc.md @@ -228,6 +228,10 @@ ] ) +;; What is the insn_cost for this insn? The target hook can still override +;; this. For optimizing for size the "length" attribute is used instead. +(define_attr "cost" "" (const_int 0)) + (define_attr "is_sfunc" "no,yes" (const_string "no")) ;; Insn type. Used to default other attribute values. @@ -3127,9 +3131,9 @@ core_3, archs4x, archs4xd, archs4xd_slow" [(set (match_operand:SI 0 "dest_reg_operand" "=q,r,r") (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "q,r,r") (match_operand:SI 2 "_2_4_8_operand" "")) - (match_operand:SI 3 "nonmemory_operand" "0,r,Csz")))] + (match_operand:SI 3 "arc_nonmemory_operand" "0,r,Csz")))] "" - "add%z2%?\\t%0,%3,%1%&" + "add%z2%?\\t%0,%3,%1" [(set_attr "type" "shift") (set_attr "length" "*,4,8") (set_attr "predicable" "yes,no,no") @@ -3560,26 +3564,26 @@ core_3, archs4x, archs4xd, archs4xd_slow" ; to truncate a symbol in a u6 immediate; but that's rather exotic, so only ; provide one alternatice for this, without condexec support. (define_insn "*ashlsi3_insn" - [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,Rcqq,Rcqq,Rcw, w, w") - (ashift:SI (match_operand:SI 1 "nonmemory_operand" "!0,Rcqq, 0, 0, c,cCsz") - (match_operand:SI 2 "nonmemory_operand" "K, K,RcqqM, cL,cL,cCal")))] + [(set (match_operand:SI 0 "dest_reg_operand" "=q,q, q, r, r, r") + (ashift:SI (match_operand:SI 1 "arc_nonmemory_operand" "!0,q, 0, 0, r,rCsz") + (match_operand:SI 2 "nonmemory_operand" "K,K,qM,rL,rL,rCal")))] "TARGET_BARREL_SHIFTER && (register_operand (operands[1], SImode) || register_operand (operands[2], SImode))" - "asl%? %0,%1,%2%&" + "asl%?\\t%0,%1,%2" [(set_attr "type" "shift") (set_attr "iscompact" "maybe,maybe,maybe,false,false,false") (set_attr "predicable" "no,no,no,yes,no,no") (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond")]) (define_insn "*ashrsi3_insn" - [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,Rcqq,Rcqq,Rcw, w, w") - (ashiftrt:SI (match_operand:SI 1 "nonmemory_operand" "!0,Rcqq, 0, 0, c,cCsz") - (match_operand:SI 2 "nonmemory_operand" "K, K,RcqqM, cL,cL,cCal")))] + [(set (match_operand:SI 0 "dest_reg_operand" "=q,q, q, r, r, r") + (ashiftrt:SI (match_operand:SI 1 "arc_nonmemory_operand" "!0,q, 0, 0, r,rCsz") + (match_operand:SI 2 "nonmemory_operand" "K,K,qM,rL,rL,rCal")))] "TARGET_BARREL_SHIFTER && (register_operand (operands[1], SImode) || register_operand (operands[2], SImode))" - "asr%? %0,%1,%2%&" + "asr%?\\t%0,%1,%2" [(set_attr "type" "shift") (set_attr "iscompact" "maybe,maybe,maybe,false,false,false") (set_attr "predicable" "no,no,no,yes,no,no") @@ -3600,11 +3604,11 @@ core_3, archs4x, archs4xd, archs4xd_slow" (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond")]) (define_insn "rotrsi3" - [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw, w, w") - (rotatert:SI (match_operand:SI 1 "register_operand" " 0,cL,cCsz") - (match_operand:SI 2 "nonmemory_operand" "cL,cL,cCal")))] + [(set (match_operand:SI 0 "dest_reg_operand" "=r, r, r") + (rotatert:SI (match_operand:SI 1 "arc_nonmemory_operand" " 0,rL,rCsz") + (match_operand:SI 2 "nonmemory_operand" "rL,rL,rCal")))] "TARGET_BARREL_SHIFTER" - "ror%? %0,%1,%2" + "ror%?\\t%0,%1,%2" [(set_attr "type" "shift,shift,shift") (set_attr "predicable" "yes,no,no") (set_attr "length" "4,4,8")]) @@ -4336,16 +4340,15 @@ core_3, archs4x, archs4xd, archs4xd_slow" (ashift:SI (match_operand:SI 1 "register_operand" "") (match_operand:SI 2 "_1_2_3_operand" ""))) (set (match_operand:SI 3 "dest_reg_operand" "") - (plus:SI (match_operand:SI 4 "nonmemory_operand" "") - (match_operand:SI 5 "nonmemory_operand" "")))] + (plus:SI (match_operand:SI 4 "arc_nonmemory_operand" "") + (match_operand:SI 5 "arc_nonmemory_operand" "")))] "(true_regnum (operands[4]) == true_regnum (operands[0]) || true_regnum (operands[5]) == true_regnum (operands[0])) && (peep2_reg_dead_p (2, operands[0]) - || (true_regnum (operands[3]) == true_regnum (operands[0]))) - && !(optimize_size && satisfies_constraint_I (operands[4])) - && !(optimize_size && satisfies_constraint_I (operands[5]))" - ;; the preparation statements take care to put proper operand in operands[4] - ;; operands[4] will always contain the correct operand. This is added to satisfy commutativity + || (true_regnum (operands[3]) == true_regnum (operands[0])))" + ;; the preparation statements take care to put proper operand in + ;; operands[4] operands[4] will always contain the correct + ;; operand. This is added to satisfy commutativity [(set (match_dup 3) (plus:SI (mult:SI (match_dup 1) (match_dup 2)) @@ -6422,7 +6425,7 @@ core_3, archs4x, archs4xd, archs4xd_slow" [(set (match_operand:SI 0 "register_operand" "=q,r,r") (plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "q,r,r") (match_operand:SI 2 "_1_2_3_operand" "")) - (match_operand:SI 3 "nonmemory_operand" "0,r,Csz")))] + (match_operand:SI 3 "arc_nonmemory_operand" "0,r,Csz")))] "" "add%2%?\\t%0,%3,%1" [(set_attr "length" "*,4,8") diff --git a/gcc/config/arc/predicates.md b/gcc/config/arc/predicates.md index 3c03436c901..2ad476d5755 100644 --- a/gcc/config/arc/predicates.md +++ b/gcc/config/arc/predicates.md @@ -795,3 +795,8 @@ { return arc_check_multi (op, false); }) + +(define_predicate "arc_nonmemory_operand" + (ior (match_test "register_operand (op, mode)") + (and (match_code "const_int, symbol_ref") + (match_test "!optimize_size")))) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b3e2e3cd115..572042662d6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2020-02-13 Claudiu Zissulescu + + * gcc.target/arc/or-cnst-size2.c: Update test. + 2020-02-13 Claudiu Zissulescu Petro Karashchenko diff --git a/gcc/testsuite/gcc.target/arc/or-cnst-size2.c b/gcc/testsuite/gcc.target/arc/or-cnst-size2.c index 33af97bbdbf..8fa1e65c7f6 100644 --- a/gcc/testsuite/gcc.target/arc/or-cnst-size2.c +++ b/gcc/testsuite/gcc.target/arc/or-cnst-size2.c @@ -9,4 +9,4 @@ int foo (void) } /* { dg-final { scan-assembler "tst" } } */ -/* { dg-final { scan-assembler "bset.eq" } } */ +/* { dg-final { scan-assembler "bset" } } */ -- 2.30.2