* Claudiu Zissulescu <claz...@gmail.com> [2018-09-17 15:50:27 +0300]:
> The 3-operand instructions accepts to place an immediate into the > second operand. However, this immediate will end up in the long > immediate field. This patch avoids constants to end up in the limm > field for particular instructions when compiling for size. > > gcc/ > xxxx-xx-xx Claudiu Zissulescu <claz...@synopsys.com> > > * config/arc/arc.md (*add_n): Clean up pattern, update instruction > constraints. > (ashlsi3_insn): Update instruction constraints. > (ashrsi3_insn): Likewise. > (rotrsi3): Likewise. > (add_shift): Likewise. > * config/arc/constraints.md (Csz): New 32 bit constraint. It > avoids placing in the limm field small constants which, otherwise, > could end into a small instruction. > --- > gcc/config/arc/arc.md | 51 +++++++++--------------- > gcc/config/arc/constraints.md | 6 +++ > gcc/testsuite/gcc.target/arc/tph_addx.c | 53 +++++++++++++++++++++++++ > 3 files changed, 78 insertions(+), 32 deletions(-) > create mode 100644 gcc/testsuite/gcc.target/arc/tph_addx.c Looks good. Thanks, Andrew > > diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md > index 2d108ef166d..c28a87cd3b0 100644 > --- a/gcc/config/arc/arc.md > +++ b/gcc/config/arc/arc.md > @@ -3056,30 +3056,17 @@ core_3, archs4x, archs4xd, archs4xd_slow" > (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")))] > + [(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")))] > "" > - "add%c2%? %0,%3,%1%&" > + "add%z2%?\\t%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") > - (match_operand:SI 2 "_2_4_8_operand" "")) > - (match_operand:SI 3 "nonmemory_operand" "0, > 0,c,Cal,c,Cal")))] > - "" > - "add%z2%? %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")]) > + (set_attr "length" "*,4,8") > + (set_attr "predicable" "yes,no,no") > + (set_attr "cond" "canuse,nocond,nocond") > + (set_attr "iscompact" "maybe,false,false")]) > > ;; N.B. sub[123] has the operands of the MINUS in the opposite order from > ;; what synth_mult likes. > @@ -3496,7 +3483,7 @@ core_3, archs4x, archs4xd, archs4xd_slow" > ; 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,cCal") > + (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")))] > "TARGET_BARREL_SHIFTER > && (register_operand (operands[1], SImode) > @@ -3509,7 +3496,7 @@ core_3, archs4x, archs4xd, archs4xd_slow" > > (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,cCal") > + (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")))] > "TARGET_BARREL_SHIFTER > && (register_operand (operands[1], SImode) > @@ -3536,7 +3523,7 @@ core_3, archs4x, archs4xd, archs4xd_slow" > > (define_insn "rotrsi3" > [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw, w, w") > - (rotatert:SI (match_operand:SI 1 "register_operand" " 0,cL,cCal") > + (rotatert:SI (match_operand:SI 1 "register_operand" " 0,cL,cCsz") > (match_operand:SI 2 "nonmemory_operand" "cL,cL,cCal")))] > "TARGET_BARREL_SHIFTER" > "ror%? %0,%1,%2" > @@ -4284,16 +4271,16 @@ core_3, archs4x, archs4xd, archs4xd_slow" > (define_peephole2 > [(set (match_operand:SI 0 "dest_reg_operand" "") > (ashift:SI (match_operand:SI 1 "register_operand" "") > - (match_operand:SI 2 "const_int_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" "")))] > - "(INTVAL (operands[2]) == 1 > - || INTVAL (operands[2]) == 2 > - || INTVAL (operands[2]) == 3) > - && (true_regnum (operands[4]) == true_regnum (operands[0]) > + "(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])))" > + && (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 > [(set (match_dup 3) > @@ -6329,7 +6316,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,Cal")))] > + (match_operand:SI 3 "nonmemory_operand" "0,r,Csz")))] > "" > "add%2%?\\t%0,%3,%1" > [(set_attr "length" "*,4,8") > diff --git a/gcc/config/arc/constraints.md b/gcc/config/arc/constraints.md > index f9ef3f94dfe..abfeedffe9a 100644 > --- a/gcc/config/arc/constraints.md > +++ b/gcc/config/arc/constraints.md > @@ -428,6 +428,12 @@ > && !arc_legitimate_pic_addr_p (op) > && !satisfies_constraint_I (op)")) > > +(define_constraint "Csz" > + "a 32 bit constant avoided when compiling for size." > + (match_test "immediate_operand (op, VOIDmode) > + && !arc_legitimate_pic_addr_p (op) > + && !(satisfies_constraint_I (op) && optimize_size)")) > + > ; Note that the 'cryptic' register constraints will not make reload use the > ; associated class to reload into, but this will not penalize reloading of > any > ; other operands, or using an alternate part of the same alternative. > diff --git a/gcc/testsuite/gcc.target/arc/tph_addx.c > b/gcc/testsuite/gcc.target/arc/tph_addx.c > new file mode 100644 > index 00000000000..f942ab19eb1 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/arc/tph_addx.c > @@ -0,0 +1,53 @@ > +/* { dg-do compile } */ > +/* { dg-options "-Os" } */ > + > +/* when compiling for size avoid the following peephole > +------------------------------------------------------------- > +Pattern 1 : r0 = r1 << {i} > + r3 = r4/INT + r0 ;;and commutative > + || > + \/ > + add{i} r3,r4/INT,r1 > +------------------------------------------------------------- > +*/ > + > +typedef int a; > +typedef int b ; > +struct c > +{ > + b d; > +}; > + > +struct e > +{ > + a f; > +}; > + > +int g(int family) > +{ > + switch (family) > + case 2: > + return sizeof(struct e); > + return 0; > +} > + > +int h(int family) > +{ > + return 1 + g(family) - 1 ; > +} > + > +extern void m (void); > + > +int i(int j) > +{ > + struct c *hdr; > + int k; > + int l; > + k = h(j); > + l = sizeof(struct c) + k * 2; > + hdr->d = l ; > + if (j) > + m(); > +} > + > +/* { dg-final { scan-assembler-not "add\d" } } */ > -- > 2.17.1 >