public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: "Fei Gao" <gaofei@eswincomputing.com>
To: gaofei <gaofei@eswincomputing.com>,
	 jeffreyalaw <jeffreyalaw@gmail.com>,
	 gcc-patches <gcc-patches@gcc.gnu.org>
Cc: "Kito Cheng" <kito.cheng@gmail.com>,
	 "Palmer Dabbelt" <palmer@dabbelt.com>,
	 zengxiao <zengxiao@eswincomputing.com>
Subject: Re: Re: [PATCH 2/4] [ifcvt] optimize x=c ? (y op z) : y by RISC-V Zicond like insns
Date: Tue, 5 Dec 2023 16:36:20 +0800	[thread overview]
Message-ID: <20231205163619509102211@eswincomputing.com> (raw)
In-Reply-To: <20231129190906939899194@eswincomputing.com>



On 2023-11-29 19:09  Fei Gao <gaofei@eswincomputing.com> wrote:
>
>On 2023-11-29 13:26  Jeff Law <jeffreyalaw@gmail.com> wrote:
>>
>>
>>
>>On 11/27/23 19:32, Fei Gao wrote:
>>> op=[PLUS, MINUS, IOR, XOR, ASHIFT, ASHIFTRT, LSHIFTRT, ROTATE, ROTATERT]
>>>
>>> SIGN_EXTEND, ZERO_EXTEND and SUBREG has been considered
>>> to support SImode in 64-bit machine.
>>Let's defer these for now.  We're supposed to be wrapping up work that
>>was posted before stage1 closed.  If these opcodes were trivial to
>>support, then I would let them through, but SUBREGs for example can be
>>problematical as their semantics can be complex.
>
>I can delete the  32bit-support in 64 bit machine.
>Or split this patch into 2 parts word-size support and 32bit-support in 64 bit machine.
>Or keep current status if the following words persuades you :)
>
>Regarding complexity, the current patch differs from 1st version by "to_replace" and reduces
>complexity significantly. noce_simple_bbs() ensures we have only single set for insn_a like x=sext(subreg(y) op subreg(z)).
>Instead of constructing an insn considering complex extension and subreg from scratch, to_replace locates the rtx z
>in noce_bbs_ok_for_cond_zero_arith,
>and then replace it with czero result. In this way, extension and subreg are as simple as reg cases.
>All the cases for extension and subreg have been uploaded in this patch.
>They can be found by searching "int" in gcc.target/riscv/zicond_ifcvt_opt.c
>
>Could you please let me known which you prefer? 
I split the patches. See new series https://patchwork.sourceware.org/project/gcc/list/?series=27924
>
>>
>>
>>>
>>> Conditional op, if zero
>>> rd = (rc == 0) ? (rs1 op rs2) : rs1
>>> -->
>>> czero.nez rd, rs2, rc
>>> op rd, rs1, rd
>>>
>>> Conditional op, if non-zero
>>> rd = (rc != 0) ? (rs1 op rs2) : rs1
>>> -->
>>> czero.eqz rd, rs2, rc
>>> op rd, rs1, rd
>>>
>>> Co-authored-by: Xiao Zeng<zengxiao@eswincomputing.com>
>>>
>>> gcc/ChangeLog:
>>>
>>>          * ifcvt.cc (noce_try_cond_zero_arith):handler for condtional zero based ifcvt
>>>          (noce_emit_czero): helper for noce_try_cond_zero_arith
>>>          (noce_cond_zero_binary_op_supported): check supported OPs for condtional zero based ifcvt
>>>          (get_base_reg): get base reg of a subreg or the reg itself
>>>          (noce_bbs_ok_for_cond_zero_arith): check if BBs are OK for condtional zero based ifcvt
>>>          (noce_process_if_block): add noce_try_cond_zero_arith
>>>
>>> gcc/testsuite/ChangeLog:
>>>
>>>          * gcc.target/riscv/zicond_ifcvt_opt.c: New test.
>>> ---
>>>   gcc/ifcvt.cc                                  | 210 ++++++
>>>   .../gcc.target/riscv/zicond_ifcvt_opt.c       | 682 ++++++++++++++++++
>>>   2 files changed, 892 insertions(+)
>>>   create mode 100644 gcc/testsuite/gcc.target/riscv/zicond_ifcvt_opt.c
>>>
>>> diff --git a/gcc/ifcvt.cc b/gcc/ifcvt.cc
>>> index a0af553b9ff..8f6a0e7f5fe 100644
>>> --- a/gcc/ifcvt.cc
>>> +++ b/gcc/ifcvt.cc
>>> @@ -787,6 +787,7 @@ static rtx noce_get_alt_condition (struct noce_if_info *, rtx, rtx_insn **);
>>>   static bool noce_try_minmax (struct noce_if_info *);
>>>   static bool noce_try_abs (struct noce_if_info *);
>>>   static bool noce_try_sign_mask (struct noce_if_info *);
>>> +static int noce_try_cond_zero_arith (struct noce_if_info *);
>>>  
>>>   /* Return the comparison code for reversed condition for IF_INFO,
>>>      or UNKNOWN if reversing the condition is not possible.  */
>>> @@ -1831,6 +1832,40 @@ noce_emit_cmove (struct noce_if_info *if_info, rtx x, enum rtx_code code,
>>>       return NULL_RTX;
>>>   }
>>>  
>>> +/*  Emit a conditional zero, returning TARGET or NULL_RTX upon failure.
>>> +    IF_INFO describes the if-conversion scenario under consideration.
>>> +    CZERO_CODE selects the condition (EQ/NE).
>>> +    NON_ZERO_OP is the nonzero operand of the conditional move
>>> +    TARGET is the desired output register.  */
>>> +
>>> +static rtx
>>> +noce_emit_czero (struct noce_if_info *if_info, enum rtx_code czero_code,
>>> +	rtx non_zero_op, rtx target)
>>[ ... ]
>>The code you wrote is safe in that if constructs a suitable if-then-else
>>as a single object, starts a new sequence the uses emit_insn to put that
>>object onto a sequence.  Then you extract that one and only one insn
>>from the sequence and validate it can be recognized.
>>
>>In cases where you want to do something like this and know you're going
>>to emit one and only one insn you can use 'make_insn_raw' without
>>generating a new sequence.
>>
>>I would suggest you replace all the code starting with start_sequence()
>>and ending with end_sequence () (inclusive) with something like
>>
>>insn = make_insn_raw (set);
>>if (recog_memoized (insn) >= 0)
>>   {
>>     emit_insn (insn);
>>     return target;
>>   }
>>return NULL_RTX;
>Thanks for your advice, I will take it in next version. 
I used add_insn instead of emit_insn to avoid a segment fault caused by invalid
NEXT_INSN (insn) of the raw insn.

BR, 
Fei
>
>>
>>
>>Note that in the future (gcc-15) when this code is generalized to use
>>the expander it will potentially generate multiple insns at which point
>>we'll have to put them on a sequence and validate they all are
>>recognizable.  But we'll tackle that at the appropriate time.
>Sure. 
>
>>
>>
>>> +
>>> +  return false;
>>> +}
>>> +
>>> +/*  Helper function to return REG itself or inner expression of a SUBREG,
>>> +    otherwise NULL_RTX for other RTX_CODE.  */
>>> +
>>> +static rtx
>>> +get_base_reg (rtx exp)
>>> +{
>>> +  if (REG_P (exp))
>>> +    return exp;
>>> +  else if (SUBREG_P (exp))
>>> +    return SUBREG_REG (exp);
>>> +
>>> +  return NULL_RTX;
>>> +
>>I would advise against handling subregs at this point.  What you're
>>doing is probably too simplistic given the semantics of subregs.
>>
>>
>>
>>> +
>>> +  /* Strip sign_extend if any.  */
>>> +  if (GET_CODE (a) == SIGN_EXTEND || GET_CODE (a) == ZERO_EXTEND)
>>> +    bin_exp = XEXP (a, 0);
>>> +  else
>>> +    bin_exp = a;
>>Similarly while I do think we're going to want to handle extensions,
>>let's not try and add them at this point.  We want to get this wrapped
>>up & integrated so that everyone can move their focus to bugfixing for
>>gcc-14.
>Same reply with the one regarding  *SIGN_EXTEND, ZERO_EXTEND and SUBREG* at
>the beginning.
>
>>
>>> +
>>> +/*  Try to covert if-then-else with conditional zero,
>>> +    returning TURE on success or FALSE on failure.
>>> +    IF_INFO describes the if-conversion scenario under consideration.  */
>>> +
>>> +static int
>>> +noce_try_cond_zero_arith (struct noce_if_info *if_info)
>>> +{
>>> +  rtx target, a;
>>> +  rtx_insn *seq;
>>> +  machine_mode mode = GET_MODE (if_info->x);
>>> +  rtx common = NULL_RTX;
>>> +  enum rtx_code czero_code = UNKNOWN;
>>> +  rtx non_zero_op = NULL_RTX;
>>> +  rtx *to_replace = NULL;
>>> +
>>> +  if (!noce_bbs_ok_for_cond_zero_arith (if_info, &common, &czero_code, &a,
>>> +	&to_replace))
>>> +    return false;
>>> +
>>> +  /* Disallow CONST_INT currently for simplicity*/
>>> +  if (to_replace == NULL || !REG_P (*to_replace))
>>> +    return false;If you're not going to allow CONST_INT reject them in the
>>ok_for_condzero_arith routine.  Presumably you're rejecting constants
>>because zicond doesn't allow them in the arms.  We'll want to handle
>>them in the future and can do so easily once we're using the expander.
>
>I remembered the shift-by-6 case mentioned by you, see [PATCH 3/4] for const_int support:)
>https://www.mail-archive.com/gcc-patches@gcc.gnu.org/msg327149.html
>
>Also AND is supported  in 
>https://www.mail-archive.com/gcc-patches@gcc.gnu.org/msg327219.html
>
>Could you please reveiw 2 patches above so I will repost together if needed? 
>>
>>
>>
>>> +
>>> +  non_zero_op = *to_replace;
>>> +
>>> +  start_sequence ();
>>> +
>>> +  /* If x is used in both input and out like x = c ? x + z : x,
>>> +     use a new reg to avoid modifying x  */
>>> +  if (common && rtx_equal_p (common, if_info->x))
>>> +    target = gen_reg_rtx (mode);
>>> +  else
>>> +    target = if_info->x;
>>> +
>>> +  target = noce_emit_czero (if_info, czero_code, non_zero_op, target);
>>> +  if (!target || !to_replace)
>>> +    {
>>> +      end_sequence ();
>>> +      return false;
>>> +    }
>>> +
>>> +  *to_replace = target;
>>> +  emit_insn (gen_rtx_SET (if_info->x, a));
>>This isn't necessarily safe.  Use emit_move_insn instead.
>OK. 
>
>Thanks & BR
>Fei
>
>>
>>This is pretty close.  Hopefully one more iteration and it can be
>>integrated.
>>
>>jeff

  reply	other threads:[~2023-12-05  8:36 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-11-28  2:32 [PATCH 1/4] [RISC-V] prefer Zicond primitive semantics to SFB Fei Gao
2023-11-28  2:32 ` [PATCH 2/4] [ifcvt] optimize x=c ? (y op z) : y by RISC-V Zicond like insns Fei Gao
2023-11-29  5:26   ` Jeff Law
2023-11-29 11:09     ` Fei Gao
2023-12-05  8:36       ` Fei Gao [this message]
2023-11-28  2:32 ` [PATCH 3/4] [ifcvt] optimize x=c ? (y op const_int) " Fei Gao
2023-11-28  2:32 ` [PATCH 4/4] [V2] [ifcvt] prefer SFB to Zicond for x=c ? (y op CONST) : y Fei Gao
2023-11-28  5:00   ` Jeff Law
2023-11-28  3:09 ` [PATCH 1/4] [RISC-V] prefer Zicond primitive semantics to SFB Kito Cheng
2023-11-28  5:03   ` Jeff Law
2023-12-04  7:01     ` Fei Gao

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=20231205163619509102211@eswincomputing.com \
    --to=gaofei@eswincomputing.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=jeffreyalaw@gmail.com \
    --cc=kito.cheng@gmail.com \
    --cc=palmer@dabbelt.com \
    --cc=zengxiao@eswincomputing.com \
    /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).