public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
From: Richard Sandiford <richard.sandiford@arm.com>
To: "Qian\, Jianhua" <qianjh@cn.fujitsu.com>
Cc: Segher Boessenkool <segher@kernel.crashing.org>,
	"gcc\@gcc.gnu.org" <gcc@gcc.gnu.org>
Subject: Re: A problem with one instruction multiple latencies and pipelines
Date: Mon, 14 Sep 2020 10:55:35 +0100	[thread overview]
Message-ID: <mptwo0wadig.fsf@arm.com> (raw)
In-Reply-To: <8417a22bbdd44efcb2309e07510d1515@G08CNEXMBPEKD06.g08.fujitsu.local> (Jianhua Qian's message of "Mon, 14 Sep 2020 05:41:38 +0000")

"Qian, Jianhua" <qianjh@cn.fujitsu.com> writes:
> Hi Richard and Segher
>
> I don't know if I exactly understood your discussion.
> If I misunderstood, please let me know.
>
> I am trying to test these two cases.
> Case 1. keep the TYPE attribute unchanged, add new attributes
>     It works well as below.
>     (define_attr "shift_imm_value" "shift_imm_none,shift_imm_0,shift_imm_1to4,shift_imm_ge5" (const_string "shift_imm_none"))

I'm not sure the shift_imm_0 case is useful here FWIW.  alu_shift_imm
should only be used with nonzero shift amounts.

Also, the associated C++ enums are automatically prefixed with the name
of the attribute, so I think the values should just be 1to4, ge5, etc.,
with no prefix.

>     (define_insn "*add_<shift>_<mode>"
>       [(set (match_operand:GPI 0 "register_operand" "=r")
>             (plus:GPI (ASHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
>                                   (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
>                       (match_operand:GPI 3 "register_operand" "r")))]
>       ""
>       "add\\t%<w>0, %<w>3, %<w>1, <shift> %2"
>       [(set_attr "type" "alu_shift_imm")
>        (set (attr "shift_imm_value")
>             (cond [(eq (symbol_ref "XINT(operands[2],0)") (const_int 0)) (const_string "shift_imm_0")
>                    (and (ge (symbol_ref "XINT(operands[2],0)") (const_int 1)) (le (symbol_ref "XINT(operands[2],0)") (const_int 4))) (const_string "shift_imm_1to4")]
>                    (const_string "shift_imm_ge5")))]
>     )

I'll come back to this below.

>
>     (define_insn_reservation "a64fx_alu_shift1to4" 2
>       (and (eq_attr "tune" "a64fx")
>            (eq_attr "type" "alu_shift_imm")
>            (eq_attr "shift_imm_value" "shift_imm_1to4"))
>       "(a64fx_exa,a64fx_exa)|(a64fx_exb,a64fx_exb)")
>
>
> Case2. expand the TYPE attribute
>     I replaced the alu_shift_imm to alu_shift_imm, alu_shift_imm1to4, and I got the error message " bad number of entries in SET_ATTR_ALTERNATIVE, was 2 expected 1"
>     (define_attr "type"
>       ...
>       alu_shift_imm,\
>       alu_shift_imm1to4,\
>       ...
>
>     (define_insn "*add_<shift>_<mode>"
>       [(set (match_operand:GPI 0 "register_operand" "=r")
>             (plus:GPI (ASHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
>                                   (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
>                       (match_operand:GPI 3 "register_operand" "r")))]
>       ""
>       "add\\t%<w>0, %<w>3, %<w>1, <shift> %2"
>       [(set_attr "type" "alu_shift_imm,alu_shift_imm1to4")]
>     )
>
>     It means that one "type" value should be matched by one operand constraint pattern. So this will raise two problems.
>       1. One instruction should be classified to multiple patterns
>          - define multiple operand constraints, such as "(match_operand:QI 2 "aarch64_shift_imm_<mode>" "0, 1to4, ...")"
>          - or, use "cond" at set_attr just like Case1.
>       2. Whatever you do with the first problem, the type attribute cannot be set with "alu_shift_imm"
>         and "alu_shift_imm1to4" at the same time by one operand constraint pattern.

Right.  Something needs to tell the compiler how to distinguish between
the two cases.

>             - If we cannot resolve it, the existing CPUs' descriptions need to be changed. This is not what I expected.
>             - If we want to add new attribute to resolve this problem, why not use the Case1 directly?

It's a trade-off.  At the moment the rule for arm and aarch64 is simple:
the "type" attribute specifies the complete scheduling type.  If we
instead change policy and divide the information among several attributes,
those attributes will have increasingly complex relationships with one
another.  It will become easier to specify a meaningless combination
by mistake, or to forget to specify one of the relevant attributes.

I agree it's not so bad with just one extra attribute.  The question
is more: if we change the policy, what would things look like if there
were more attributes of a similar nature?

On the other side, lumping everything into one attributes gives a
long list of values.  I think the difference of opinion is that Segher
finds this argument more compelling while I find the other argument
more compelling ;-)

That said, there are really two issues here:

(1) how should the define_insn describe the instruction?
(2) how should scheduling descriptions test for it?

The same answer for (1) can support multiple answers for (2).

For (1), I think we should do what I mentioned in my first reply
and add something like (different name from last time):

  ;; config/arm/types.md
  (define_attr "autodetect_type" "none,alu_shift_op2")

This attribute would in principle be a home for any case in which
the scheduling type needs to be derived from other information
(in this case using the contents of operand 2 to infer the alu_shift
kind).  So going back to what I said above: we would be changing policy
so that define_insns can use one of *two* attributes to specify the
scheduling type:

- they can use "type" to specify an exact scheduling type directly
- they can use "autodetect_type" to specify a method for deriving the
  scheduling type from other information

The *add_<shift>_<mode> define_insn above would then use:

  [(set_attr "autodetect_type" "alu_shift_op2")]

The advantage of this IMO is that we still only have two attributes,
even if we need to autodetect other cases in future.  It also means
that there is only one copy of the condition to pick between (say)
1to4 and ge5.

This approach to (1) supports both approaches to (2).  If the
CPU models continue to use a single type attribute, we can use
autodetect_type to choose an appropriate default, using the method
I mentioned in my first reply:

  ;; config/arm/types.md
  (define_attr "type" "…long list…"
    (cond [(eq_attr "autodetect_type" "alu_shift_op2")
           (if_then_else (match_operand 2 "const_1_to_4_operand")
                         (const_string "alu_shift_imm_1to4")
                         (const_string "alu_shift_imm_ge5"))]
          (const_string "untyped")))

where:

- const_1_to_4_operand is a new predicate.  It could be defined in a
  new config/arm/common.md file that is shared by both arm and aarch64.

- alu_shift_imm is replaced by two new attributes: alu_shift_imm_1to4
  and alu_shift_imm_ge5.

(In principle, this condition could also handle alu_shift_reg,
if that proved to be useful later.)

If we instead use multiple attributes, the definitions would be:

(define_attr "type" "…"
  (cond [(eq_attr "autodetect_type" "alu_shift_op2")
         (const_string "alu_shift_imm")]
        (const_string "untyped")))

(define_attr "shift_imm_value" "none,1to4,ge5"
  (cond [(eq_attr "autodetect_type" "alu_shift_op2")
         (if_then_else (match_operand 2 "const_1_to_4_operand")
                       (const_string "1to4")
                       (const_string "ge5"))]
        (const_string "none"))

I still prefer the single type attribute, for the reasons above.

FWIW, this script updates the CPU descriptions so that every test
for alu_shift_imm is replaced by a test for the two new attributes:

find gcc/config/arm gcc/config/aarch64 -name '*.md' |
  while read arg; do
    case $arg in
      */arm.md | */aarch64.md | */types.md | */thumb1.md | */thumb2.md | \
      */arm-fixed.md)
	;;
      *)
	sed -i s/alu_shift_imm/alu_shift_imm_1to4,alu_shift_imm_ge5/g $arg
	;;
    esac
  done

(not idempotent :-))

Then you'd need to update the non-CPU files that were excluded by the
case statement above.

Although this looks/sounds complicated, the advantage is that everything
remains up-to-date.  If we instead added a second attribute and only
defined it for instructions like *add_<shift>_<mode>, other instructions
(including config/arm instructions) would still have type alu_shift_imm
but would have a shift_imm_value of "none".

Sorry for the long message.

Thanks,
Richard

  reply	other threads:[~2020-09-14  9:55 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-09-07  6:08 Qian, Jianhua
2020-09-07  7:40 ` Richard Biener
2020-09-07  8:45   ` Qian, Jianhua
2020-09-07 11:58     ` Richard Biener
2020-09-07 20:20 ` Richard Sandiford
2020-09-08  5:34   ` Qian, Jianhua
2020-09-09 21:22   ` Segher Boessenkool
2020-09-10  5:01     ` Qian, Jianhua
2020-09-10 10:04     ` Richard Sandiford
2020-09-10 23:00       ` Segher Boessenkool
2020-09-11  7:44         ` Richard Sandiford
2020-09-11 13:58           ` Segher Boessenkool
2020-09-14  5:41             ` Qian, Jianhua
2020-09-14  9:55               ` Richard Sandiford [this message]
2020-09-14 18:41                 ` Segher Boessenkool
2020-09-14 19:35                   ` Richard Sandiford
2020-09-14 22:14                     ` Segher Boessenkool
2020-09-11 13:30 ` Richard Earnshaw
2020-09-14  2:53   ` Qian, Jianhua
2020-09-14  9:08     ` Richard Earnshaw

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=mptwo0wadig.fsf@arm.com \
    --to=richard.sandiford@arm.com \
    --cc=gcc@gcc.gnu.org \
    --cc=qianjh@cn.fujitsu.com \
    --cc=segher@kernel.crashing.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).