[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:
Claudiu Zissulescu 2020-02-13 12:32:05 +02:00
parent 8dca38c43c
commit e57764be55
6 changed files with 99 additions and 23 deletions

View File

@ -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

View File

@ -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"

View File

@ -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")

View File

@ -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"))))

View File

@ -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>

View File

@ -9,4 +9,4 @@ int foo (void)
}
/* { dg-final { scan-assembler "tst" } } */
/* { dg-final { scan-assembler "bset.eq" } } */
/* { dg-final { scan-assembler "bset" } } */