public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Ajit Agarwal <aagarwa1@linux.ibm.com>
To: gcc-patches <gcc-patches@gcc.gnu.org>
Cc: Jeff Law <jeffreyalaw@gmail.com>,
	Segher Boessenkool <segher@kernel.crashing.org>,
	Peter Bergner <bergner@linux.ibm.com>,
	Richard Biener <richard.guenther@gmail.com>
Subject: Re: PATCH v5 4/4] ree: Improve ree pass for rs6000 target using defined ABI interfaces.
Date: Mon, 26 Jun 2023 18:12:58 +0530	[thread overview]
Message-ID: <ac9b47b4-1dd3-c99e-42f5-6f37b21b8286@linux.ibm.com> (raw)
In-Reply-To: <94db15dc-2ce3-bfc1-6483-fce5687bd991@linux.ibm.com>

All:

Ok for trunk. Please review.

Thanks & Regards
Ajit

On 01/06/23 10:53 am, Ajit Agarwal via Gcc-patches wrote:
> Hello All:
> 
> This new version of patch 4 use improve ree pass for rs6000 target using defined ABI interfaces.
> Bootstrapped and regtested on power64-linux-gnu.
> 
> Review comments incorporated.
> 
> Thanks & Regards
> Ajit
> 
> Improve ree pass for rs6000 target using defined abi interfaces
> 
> For rs6000 target we see redundant zero and sign
> extension and done to improve ree pass to eliminate
> such redundant zero and sign extension using defined
> ABI interfaces.
> 
> 2023-06-01  Ajit Kumar Agarwal  <aagarwa1@linux.ibm.com>
> 
> gcc/ChangeLog:
> 
> 	* ree.cc (combine_reaching_defs): Use of  zero_extend and sign_extend
> 	defined abi interfaces.
> 	(add_removable_extension): Use of defined abi interfaces for no
> 	reaching defs.
> 	(abi_extension_candidate_return_reg_p): New function.
> 	(abi_extension_candidate_p): New function.
> 	(abi_extension_candidate_argno_p): New function.
> 	(abi_handle_regs_without_defs_p): New function.
> 	(abi_target_promote_function_mode): New function.
> 
> gcc/testsuite/ChangeLog:
> 
>         * g++.target/powerpc/zext-elim-3.C
> ---
>  gcc/ree.cc                                    | 199 +++++++++++++++---
>  .../g++.target/powerpc/zext-elim-3.C          |  13 ++
>  2 files changed, 183 insertions(+), 29 deletions(-)
>  create mode 100644 gcc/testsuite/g++.target/powerpc/zext-elim-3.C
> 
> diff --git a/gcc/ree.cc b/gcc/ree.cc
> index fc04249fa84..2025a7c43da 100644
> --- a/gcc/ree.cc
> +++ b/gcc/ree.cc
> @@ -514,7 +514,8 @@ get_uses (rtx_insn *insn, rtx reg)
>      if (REGNO (DF_REF_REG (def)) == REGNO (reg))
>        break;
>  
> -  gcc_assert (def != NULL);
> +  if (def == NULL)
> +    return NULL;
>  
>    ref_chain = DF_REF_CHAIN (def);
>  
> @@ -750,6 +751,120 @@ get_extended_src_reg (rtx src)
>    return src;
>  }
>  
> +/* Return TRUE if target mode is equal to source mode of zero_extend
> +   or sign_extend otherwise false.  */
> +
> +static bool
> +abi_target_promote_function_mode (machine_mode mode)
> +{
> +  int unsignedp;
> +  machine_mode tgt_mode =
> +    targetm.calls.promote_function_mode (NULL_TREE, mode, &unsignedp,
> +					 NULL_TREE, 1);
> +
> +  if (tgt_mode == mode)
> +    return true;
> +  else
> +    return false;
> +}
> +
> +/* Return TRUE if the candidate insn is zero extend and regno is
> +   an return  registers.  */
> +
> +static bool
> +abi_extension_candidate_return_reg_p (rtx_insn *insn, int regno)
> +{
> +  rtx set = single_set (insn);
> +
> +  if (GET_CODE (SET_SRC (set)) !=  ZERO_EXTEND)
> +    return false;
> +
> +  if (FUNCTION_VALUE_REGNO_P (regno))
> +    return true;
> +
> +  return false;
> +}
> +
> +/* Return TRUE if reg source operand of zero_extend is argument registers
> +   and not return registers and source and destination operand are same
> +   and mode of source and destination operand are not same.  */
> +
> +static bool
> +abi_extension_candidate_p (rtx_insn *insn)
> +{
> +  rtx set = single_set (insn);
> +
> +  if (GET_CODE (SET_SRC (set)) !=  ZERO_EXTEND)
> +    return false;
> +
> +  machine_mode ext_dst_mode = GET_MODE (SET_DEST (set));
> +  rtx orig_src = XEXP (SET_SRC (set),0);
> +
> +  bool copy_needed
> +    = (REGNO (SET_DEST (set)) != REGNO (XEXP (SET_SRC (set), 0)));
> +
> +  if (!copy_needed && ext_dst_mode != GET_MODE (orig_src)
> +      && FUNCTION_ARG_REGNO_P (REGNO (orig_src))
> +      && !abi_extension_candidate_return_reg_p (insn, REGNO (orig_src)))
> +    return true;
> +
> +  return false;
> +}
> +
> +/* Return TRUE if the candidate insn is zero extend and regno is
> +   an argument registers.  */
> +
> +static bool
> +abi_extension_candidate_argno_p (rtx_code code, int regno)
> +{
> +  if (code !=  ZERO_EXTEND)
> +    return false;
> +
> +  if (FUNCTION_ARG_REGNO_P (regno))
> +    return true;
> +
> +  return false;
> +}
> +
> +/* Return TRUE if the candidate insn doesn't have defs and have
> + * uses without RTX_BIN_ARITH/RTX_COMM_ARITH/RTX_UNARY rtx class.  */
> +
> +static bool
> +abi_handle_regs_without_defs_p (rtx_insn *insn)
> +{
> +  if (side_effects_p (PATTERN (insn)))
> +    return false;
> +
> +  struct df_link *uses
> +    = get_uses (insn, SET_DEST (PATTERN (insn)));
> +
> +  if (!uses)
> +    return false;
> +
> +  for (df_link *use = uses; use; use = use->next)
> +    {
> +      if (!use->ref)
> +	return false;
> +
> +      if (BLOCK_FOR_INSN (insn)
> +	  != BLOCK_FOR_INSN (DF_REF_INSN (use->ref)))
> +	return false;
> +
> +      rtx_insn *use_insn = DF_REF_INSN (use->ref);
> +
> +      if (GET_CODE (PATTERN (use_insn)) == SET)
> +	{
> +	  rtx_code code = GET_CODE (SET_SRC (PATTERN (use_insn)));
> +
> +	  if (GET_RTX_CLASS (code) == RTX_BIN_ARITH
> +	      || GET_RTX_CLASS (code) == RTX_COMM_ARITH
> +	      || GET_RTX_CLASS (code) == RTX_UNARY)
> +	    return false;
> +	}
> +     }
> +  return true;
> +}
> +
>  /* This function goes through all reaching defs of the source
>     of the candidate for elimination (CAND) and tries to combine
>     the extension with the definition instruction.  The changes
> @@ -770,6 +885,11 @@ combine_reaching_defs (ext_cand *cand, const_rtx set_pat, ext_state *state)
>  
>    state->defs_list.truncate (0);
>    state->copies_list.truncate (0);
> +  rtx orig_src = XEXP (SET_SRC (cand->expr),0);
> +
> +  if (abi_extension_candidate_p (cand->insn)
> +      && (!get_defs (cand->insn, orig_src, NULL)))
> +    return abi_handle_regs_without_defs_p (cand->insn);
>  
>    outcome = make_defs_and_copies_lists (cand->insn, set_pat, state);
>  
> @@ -1036,6 +1156,15 @@ combine_reaching_defs (ext_cand *cand, const_rtx set_pat, ext_state *state)
>          }
>      }
>  
> +  rtx insn_set = single_set (cand->insn);
> +
> +  machine_mode mode = (GET_MODE (XEXP (SET_SRC (insn_set), 0)));
> +
> +  bool promote_p = abi_target_promote_function_mode (mode);
> +
> +  if (promote_p)
> +    return true;
> +
>    if (merge_successful)
>      {
>        /* Commit the changes here if possible
> @@ -1112,26 +1241,34 @@ add_removable_extension (const_rtx expr, rtx_insn *insn,
>        rtx reg = XEXP (src, 0);
>        struct df_link *defs, *def;
>        ext_cand *cand;
> +      defs = get_defs (insn, reg, NULL);
>  
>        /* Zero-extension of an undefined value is partly defined (it's
>  	 completely undefined for sign-extension, though).  So if there exists
>  	 a path from the entry to this zero-extension that leaves this register
>  	 uninitialized, removing the extension could change the behavior of
>  	 correct programs.  So first, check it is not the case.  */
> -      if (code == ZERO_EXTEND && !bitmap_bit_p (init_regs, REGNO (reg)))
> +      if (!defs && abi_extension_candidate_argno_p (code, REGNO (reg)))
>  	{
> -	  if (dump_file)
> -	    {
> -	      fprintf (dump_file, "Cannot eliminate extension:\n");
> -	      print_rtl_single (dump_file, insn);
> -	      fprintf (dump_file, " because it can operate on uninitialized"
> -			          " data\n");
> -	    }
> +	  ext_cand e = {expr, code, mode, insn};
> +	  insn_list->safe_push (e);
>  	  return;
>  	}
>  
> +       if ((code == ZERO_EXTEND
> +	    && !bitmap_bit_p (init_regs, REGNO (reg))))
> +	  {
> +	    if (dump_file)
> +	      {
> +		fprintf (dump_file, "Cannot eliminate extension:\n");
> +		print_rtl_single (dump_file, insn);
> +		fprintf (dump_file, " because it can operate on uninitialized"
> +				    " data\n");
> +	      }
> +	    return;
> +	  }
> +
>        /* Second, make sure we can get all the reaching definitions.  */
> -      defs = get_defs (insn, reg, NULL);
>        if (!defs)
>  	{
>  	  if (dump_file)
> @@ -1321,7 +1458,8 @@ find_and_remove_re (void)
>  	      && (REGNO (SET_DEST (set)) != REGNO (XEXP (SET_SRC (set), 0))))
>  	    {
>                reinsn_copy_list.safe_push (curr_cand->insn);
> -              reinsn_copy_list.safe_push (state.defs_list[0]);
> +	      if (state.defs_list.length() != 0)
> +		reinsn_copy_list.safe_push (state.defs_list[0]);
>  	    }
>  	  reinsn_del_list.safe_push (curr_cand->insn);
>  	  state.modified[INSN_UID (curr_cand->insn)].deleted = 1;
> @@ -1342,24 +1480,27 @@ find_and_remove_re (void)
>       Remember that the memory reference will be changed to refer to the
>       destination of the extention.  So we're actually emitting a copy
>       from the new destination to the old destination.  */
> -  for (unsigned int i = 0; i < reinsn_copy_list.length (); i += 2)
> -    {
> -      rtx_insn *curr_insn = reinsn_copy_list[i];
> -      rtx_insn *def_insn = reinsn_copy_list[i + 1];
> -
> -      /* Use the mode of the destination of the defining insn
> -	 for the mode of the copy.  This is necessary if the
> -	 defining insn was used to eliminate a second extension
> -	 that was wider than the first.  */
> -      rtx sub_rtx = *get_sub_rtx (def_insn);
> -      rtx set = single_set (curr_insn);
> -      rtx new_dst = gen_rtx_REG (GET_MODE (SET_DEST (sub_rtx)),
> -				 REGNO (XEXP (SET_SRC (set), 0)));
> -      rtx new_src = gen_rtx_REG (GET_MODE (SET_DEST (sub_rtx)),
> -				 REGNO (SET_DEST (set)));
> -      rtx new_set = gen_rtx_SET (new_dst, new_src);
> -      emit_insn_after (new_set, def_insn);
> -    }
> +   for (unsigned int i = 0; i < reinsn_copy_list.length (); i += 2)
> +     {
> +       rtx_insn *curr_insn = reinsn_copy_list[i];
> +
> +       if ((i+1) < reinsn_copy_list.length())
> +	 {
> +	   rtx_insn *def_insn = reinsn_copy_list[i + 1];
> +	   /* Use the mode of the destination of the defining insn
> +	      for the mode of the copy.  This is necessary if the
> +	      defining insn was used to eliminate a second extension
> +	      that was wider than the first.  */
> +	   rtx sub_rtx = *get_sub_rtx (def_insn);
> +	   rtx set = single_set (curr_insn);
> +	   rtx new_dst = gen_rtx_REG (GET_MODE (SET_DEST (sub_rtx)),
> +				      REGNO (XEXP (SET_SRC (set), 0)));
> +	   rtx new_src = gen_rtx_REG (GET_MODE (SET_DEST (sub_rtx)),
> +				      REGNO (SET_DEST (set)));
> +	   rtx new_set = gen_rtx_SET (new_dst, new_src);
> +	   emit_insn_after (new_set, def_insn);
> +	}
> +      }
>  
>    /* Delete all useless extensions here in one sweep.  */
>    FOR_EACH_VEC_ELT (reinsn_del_list, i, curr_insn)
> diff --git a/gcc/testsuite/g++.target/powerpc/zext-elim-3.C b/gcc/testsuite/g++.target/powerpc/zext-elim-3.C
> new file mode 100644
> index 00000000000..5a050df06ff
> --- /dev/null
> +++ b/gcc/testsuite/g++.target/powerpc/zext-elim-3.C
> @@ -0,0 +1,13 @@
> +/* { dg-options "-mcpu=power9 -O2" } */
> +
> +void *memset(void *b, int c, unsigned long len)
> +{
> +  unsigned long i;
> +
> +  for (i = 0; i < len; i++)
> +    ((unsigned char *)b)[i] = c;
> +
> +   return b;
> +}
> +
> +/* { dg-final { scan-assembler-not "\mrlwinm\M" } } */

  parent reply	other threads:[~2023-06-26 12:43 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-06-01  5:23 Ajit Agarwal
2023-06-01  6:04 ` Bernhard Reutner-Fischer
2023-06-26 12:36 ` [PING] " Ajit Agarwal
2023-06-26 12:42 ` Ajit Agarwal [this message]
2023-06-26 12:45   ` Ajit Agarwal
2023-07-18  7:58 ` [PING^2] " Ajit Agarwal
2023-08-01  8:18   ` [PING^3] " Ajit Agarwal
2023-08-21  6:46     ` [PING^4] " Ajit Agarwal
2023-09-12  7:21       ` [PING^5] " Ajit Agarwal

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=ac9b47b4-1dd3-c99e-42f5-6f37b21b8286@linux.ibm.com \
    --to=aagarwa1@linux.ibm.com \
    --cc=bergner@linux.ibm.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=jeffreyalaw@gmail.com \
    --cc=richard.guenther@gmail.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).