Hello Vineet: This patch is without sign_extension implementation. I have sent patch 8 that incorporates sign_extension using abi interfaces.
Please review. Thanks & Regards Ajit On 19/09/23 2:48 pm, Ajit Agarwal wrote: > > > On 19/09/23 2:36 pm, Xi Ruoyao wrote: >> On Tue, 2023-09-19 at 14:29 +0530, Ajit Agarwal wrote: >>> This new version of patch 7 use improve ree pass for rs6000 target >>> using defined ABI interfaces. >>> Bootstrapped and regtested on power64-linux-gnu. >> >> You should drop the "4/4" in subject if it does not depends on other >> non-committed patches. Otherwise you should send all the non-committed >> dependencies in a series. >> >> If you just have the 4/4 there without {1..3}/4, people will believe >> this is an incomplete patch submission and likely ignore it. >> > > There are 4 oatches that are already under review and all the provious > patches are under review. > > I will send 3/4 patches again for review. > > Thanks & Regards > Ajit >>> Review comments incorporated. >>> >>> Thanks & Regards >>> Ajit >>> >>> ree: 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-09-19 Ajit Kumar Agarwal <aagar...@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 | 148 >>> +++++++++++++++++- >>> .../g++.target/powerpc/zext-elim-3.C | 13 ++ >>> 2 files changed, 158 insertions(+), 3 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..79fc54f38a3 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,122 @@ 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 >>> + a 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 (targetm.calls.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 dst_mode = GET_MODE (SET_DEST (set)); >>> + rtx orig_src = XEXP (SET_SRC (set), 0); >>> + >>> + if (!FUNCTION_ARG_REGNO_P (REGNO (orig_src)) >>> + || abi_extension_candidate_return_reg_p (insn, REGNO >>> (orig_src))) >>> + return false; >>> + >>> + /* Mode of destination and source of zero_extend should be >>> different. */ >>> + if (dst_mode == GET_MODE (orig_src)) >>> + return false; >>> + >>> + /* REGNO of source and destination of zero_extend should be same. >>> */ >>> + if (REGNO (SET_DEST (set)) != REGNO (orig_src)) >>> + return false; >>> + >>> + return true; >>> +} >>> + >>> +/* 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 && code != SIGN_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 +887,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 +1158,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,6 +1243,7 @@ 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 >>> @@ -1131,9 +1263,14 @@ add_removable_extension (const_rtx expr, >>> rtx_insn *insn, >>> } >>> >>> /* Second, make sure we can get all the reaching definitions. >>> */ >>> - defs = get_defs (insn, reg, NULL); >>> if (!defs) >>> { >>> + if (abi_extension_candidate_argno_p (code, REGNO (reg))) >>> + { >>> + ext_cand e = {expr, code, mode, insn}; >>> + insn_list->safe_push (e); >>> + return; >>> + } >>> if (dump_file) >>> { >>> fprintf (dump_file, "Cannot eliminate extension:\n"); >>> @@ -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; >>> @@ -1345,6 +1483,10 @@ find_and_remove_re (void) >>> 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 ()) >>> + continue; >>> + >>> rtx_insn *def_insn = reinsn_copy_list[i + 1]; >>> >>> /* Use the mode of the destination of the defining 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" } } */ >>