[ARC] Recognise add_n and sub_n in combine again
Since the combine pass canonicalises shift-add insns using plus and ashift (as opposed to plus and mult which it previously used to do), it no longer creates *add_n or *sub_n insns, as the patterns match plus and mult only. The outcome of this is that some opportunities to generate add{1,2,3} and sub{1,2,3} instructions are missed. This change adds additional *add_n and *sub_n insns that match the plus-ashift pattern. The original *add_n and *sub_n insns are still left in, as they are sometimes generated later on by constant propagation. The idea of adding these insns is modelled on the changes in: https://gcc.gnu.org/ml/gcc-patches/2015-05/msg01882.html which addresses a similar issue for the PA target. For the small test cases that are added, even if the combine pass misses the opportunity to generate addN or subN, constant propagation manages to do so, so the rtl of the combine pass is checked. gcc/ChangeLog: * config/arc/arc.c (arc_print_operand): Handle constant operands. (arc_rtx_costs): Add costs for new patterns. * config/arc/arc.md: Additional *add_n and *sub_n patterns. * config/arc/predicates.md: Add _1_2_3_operand predicate. gcc/testsuite/ChangeLog: * gcc.target/arc/add_n-combine.c: New test. * gcc.target/arc/sub_n-combine.c: New test. From-SVN: r248735
This commit is contained in:
parent
046a84762b
commit
1e466f0496
7 changed files with 128 additions and 4 deletions
|
@ -1,3 +1,10 @@
|
|||
2017-05-31 Graham Markall <graham.markall@embecosm.com>
|
||||
|
||||
* config/arc/arc.c (arc_print_operand): Handle constant operands.
|
||||
(arc_rtx_costs): Add costs for new patterns.
|
||||
* config/arc/arc.md: Additional *add_n and *sub_n patterns.
|
||||
* config/arc/predicates.md: Add _1_2_3_operand predicate.
|
||||
|
||||
2017-05-31 Richard Sandiford <richard.sandiford@linaro.org>
|
||||
|
||||
* tree-ssa-strlen.c (get_next_strinfo): New function.
|
||||
|
|
|
@ -3483,6 +3483,14 @@ arc_print_operand (FILE *file, rtx x, int code)
|
|||
|
||||
return;
|
||||
|
||||
case 'c':
|
||||
if (GET_CODE (x) == CONST_INT)
|
||||
fprintf (file, "%d", INTVAL (x) );
|
||||
else
|
||||
output_operand_lossage ("invalid operands to %%c code");
|
||||
|
||||
return;
|
||||
|
||||
case 'M':
|
||||
if (GET_CODE (x) == CONST_INT)
|
||||
fprintf (file, "%d",exact_log2(~INTVAL (x)) );
|
||||
|
@ -4895,8 +4903,10 @@ arc_rtx_costs (rtx x, machine_mode mode, int outer_code,
|
|||
*total = COSTS_N_INSNS (2);
|
||||
return false;
|
||||
case PLUS:
|
||||
if (GET_CODE (XEXP (x, 0)) == MULT
|
||||
&& _2_4_8_operand (XEXP (XEXP (x, 0), 1), VOIDmode))
|
||||
if ((GET_CODE (XEXP (x, 0)) == ASHIFT
|
||||
&& _1_2_3_operand (XEXP (XEXP (x, 0), 1), VOIDmode))
|
||||
|| (GET_CODE (XEXP (x, 0)) == MULT
|
||||
&& _2_4_8_operand (XEXP (XEXP (x, 0), 1), VOIDmode)))
|
||||
{
|
||||
*total += (rtx_cost (XEXP (x, 1), mode, PLUS, 0, speed)
|
||||
+ rtx_cost (XEXP (XEXP (x, 0), 0), mode, PLUS, 1, speed));
|
||||
|
@ -4904,8 +4914,10 @@ arc_rtx_costs (rtx x, machine_mode mode, int outer_code,
|
|||
}
|
||||
return false;
|
||||
case MINUS:
|
||||
if (GET_CODE (XEXP (x, 1)) == MULT
|
||||
&& _2_4_8_operand (XEXP (XEXP (x, 1), 1), VOIDmode))
|
||||
if ((GET_CODE (XEXP (x, 1)) == ASHIFT
|
||||
&& _1_2_3_operand (XEXP (XEXP (x, 1), 1), VOIDmode))
|
||||
|| (GET_CODE (XEXP (x, 1)) == MULT
|
||||
&& _2_4_8_operand (XEXP (XEXP (x, 1), 1), VOIDmode)))
|
||||
{
|
||||
*total += (rtx_cost (XEXP (x, 0), mode, PLUS, 0, speed)
|
||||
+ rtx_cost (XEXP (XEXP (x, 1), 0), mode, PLUS, 1, speed));
|
||||
|
|
|
@ -2993,6 +2993,19 @@
|
|||
(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
|
||||
(set (match_dup 3) (match_dup 4))])
|
||||
|
||||
(define_insn "*add_n"
|
||||
[(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcw,W,W,w,w")
|
||||
(plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "Rcqq,c,c,c,c,c")
|
||||
(match_operand:SI 2 "_1_2_3_operand" ""))
|
||||
(match_operand:SI 3 "nonmemory_operand" "0,0,c,?Cal,?c,??Cal")))]
|
||||
""
|
||||
"add%c2%? %0,%3,%1%&"
|
||||
[(set_attr "type" "shift")
|
||||
(set_attr "length" "*,4,4,8,4,8")
|
||||
(set_attr "predicable" "yes,yes,no,no,no,no")
|
||||
(set_attr "cond" "canuse,canuse,nocond,nocond,nocond,nocond")
|
||||
(set_attr "iscompact" "maybe,false,false,false,false,false")])
|
||||
|
||||
(define_insn "*add_n"
|
||||
[(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcw,W,W,w,w")
|
||||
(plus:SI (mult:SI (match_operand:SI 1 "register_operand" "Rcqq,c,c,c,c,c")
|
||||
|
@ -3008,6 +3021,19 @@
|
|||
|
||||
;; N.B. sub[123] has the operands of the MINUS in the opposite order from
|
||||
;; what synth_mult likes.
|
||||
(define_insn "*sub_n"
|
||||
[(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
|
||||
(minus:SI (match_operand:SI 1 "nonmemory_operand" "0,c,?Cal")
|
||||
(ashift:SI (match_operand:SI 2 "register_operand" "c,c,c")
|
||||
(match_operand:SI 3 "_1_2_3_operand" ""))))]
|
||||
""
|
||||
"sub%c3%? %0,%1,%2"
|
||||
[(set_attr "type" "shift")
|
||||
(set_attr "length" "4,4,8")
|
||||
(set_attr "predicable" "yes,no,no")
|
||||
(set_attr "cond" "canuse,nocond,nocond")
|
||||
(set_attr "iscompact" "false")])
|
||||
|
||||
(define_insn "*sub_n"
|
||||
[(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
|
||||
(minus:SI (match_operand:SI 1 "nonmemory_operand" "0,c,?Cal")
|
||||
|
|
|
@ -615,6 +615,11 @@
|
|||
(match_test "TARGET_ARC700 || TARGET_EA_SET")))
|
||||
)
|
||||
|
||||
(define_predicate "_1_2_3_operand"
|
||||
(and (match_code "const_int")
|
||||
(match_test "INTVAL (op) == 1 || INTVAL (op) == 2 || INTVAL (op) == 3"))
|
||||
)
|
||||
|
||||
(define_predicate "_2_4_8_operand"
|
||||
(and (match_code "const_int")
|
||||
(match_test "INTVAL (op) == 2 || INTVAL (op) == 4 || INTVAL (op) == 8"))
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2017-05-31 Graham Markall <graham.markall@embecosm.com>
|
||||
|
||||
* gcc.target/arc/add_n-combine.c: New test.
|
||||
* gcc.target/arc/sub_n-combine.c: New test.
|
||||
|
||||
2017-05-31 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR target/80880
|
||||
|
|
48
gcc/testsuite/gcc.target/arc/add_n-combine.c
Normal file
48
gcc/testsuite/gcc.target/arc/add_n-combine.c
Normal file
|
@ -0,0 +1,48 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -fdump-rtl-combine" } */
|
||||
|
||||
struct b1 {
|
||||
char c;
|
||||
char bg;
|
||||
};
|
||||
|
||||
struct bj1 {
|
||||
char bk;
|
||||
struct b1 bn[];
|
||||
};
|
||||
|
||||
struct b2 {
|
||||
short c;
|
||||
char bg;
|
||||
};
|
||||
|
||||
struct bj2 {
|
||||
short bk;
|
||||
struct b2 bn[];
|
||||
};
|
||||
|
||||
struct b3 {
|
||||
int c;
|
||||
char bg;
|
||||
};
|
||||
|
||||
struct bj3 {
|
||||
int bk;
|
||||
struct b3 bn[];
|
||||
};
|
||||
|
||||
|
||||
struct bj1 at1;
|
||||
struct bj2 at2;
|
||||
struct bj3 at3;
|
||||
|
||||
int bu;
|
||||
void a();
|
||||
|
||||
void f() {
|
||||
a(at1.bn[bu]);
|
||||
a(at2.bn[bu]);
|
||||
a(at3.bn[bu]);
|
||||
}
|
||||
|
||||
/* { dg-final { scan-rtl-dump-times "\\*add_n" 3 "combine" } } */
|
21
gcc/testsuite/gcc.target/arc/sub_n-combine.c
Normal file
21
gcc/testsuite/gcc.target/arc/sub_n-combine.c
Normal file
|
@ -0,0 +1,21 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -fdump-rtl-combine" } */
|
||||
|
||||
int a;
|
||||
|
||||
double b1() {
|
||||
int c = a << 1;
|
||||
return 1 - c;
|
||||
}
|
||||
|
||||
double b2() {
|
||||
int c = a << 2;
|
||||
return 1 - c;
|
||||
}
|
||||
|
||||
double b3() {
|
||||
int c = a << 3;
|
||||
return 1 - c;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-rtl-dump-times "\\*sub_n" 3 "combine" } } */
|
Loading…
Add table
Reference in a new issue