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

Reply via email to