mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-25 01:30:44 +08:00
[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 <claziss@synopsys.com> * 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 <claziss@synopsys.com> * gcc.target/arc/or-cnst-size2.c: Update test.
This commit is contained in:
parent
8dca38c43c
commit
e57764be55
@ -1,3 +1,15 @@
|
||||
2020-02-13 Claudiu Zissulescu <claziss@synopsys.com>
|
||||
|
||||
* 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 <claziss@synopsys.com>
|
||||
|
||||
* config/arc/arc.md (mulsidi_600): Correctly select mlo/mhi
|
||||
|
@ -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"
|
||||
|
@ -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")
|
||||
|
@ -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"))))
|
||||
|
@ -1,3 +1,7 @@
|
||||
2020-02-13 Claudiu Zissulescu <claziss@synopsys.com>
|
||||
|
||||
* gcc.target/arc/or-cnst-size2.c: Update test.
|
||||
|
||||
2020-02-13 Claudiu Zissulescu <claziss@synopsys.com>
|
||||
Petro Karashchenko <petro.karashchenko@ring.com>
|
||||
|
||||
|
@ -9,4 +9,4 @@ int foo (void)
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler "tst" } } */
|
||||
/* { dg-final { scan-assembler "bset.eq" } } */
|
||||
/* { dg-final { scan-assembler "bset" } } */
|
||||
|
Loading…
x
Reference in New Issue
Block a user