public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: "Fei Gao" <gaofei@eswincomputing.com>
To: 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: Wed, 29 Nov 2023 19:09:08 +0800	[thread overview]
Message-ID: <20231129190906939899194@eswincomputing.com> (raw)
In-Reply-To: <27e492b4-feb9-4e80-8911-cc79d1d874b3@gmail.com>

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?

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

>
>
>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-11-29 11:09 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 [this message]
2023-12-05  8:36       ` Fei Gao
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=20231129190906939899194@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).