This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Optimize bfi by remove redundant zero_extend
- From: Renlin Li <renlin dot li at arm dot com>
- To: Richard Henderson <rth at redhat dot com>, "gcc-patches at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>
- Date: Wed, 25 Feb 2015 10:27:42 +0000
- Subject: Re: [PATCH] Optimize bfi by remove redundant zero_extend
- Authentication-results: sourceware.org; auth=none
- References: <54DE25BD dot 1030401 at arm dot com> <54DE2EB7 dot 6040303 at redhat dot com>
On 13/02/15 17:04, Richard Henderson wrote:
On 02/13/2015 08:26 AM, Renlin Li wrote:
+ /* Complete overlap. We can remove the source ZERO_EXTEND. */
+ if (width == inner_size
+ && (regno < FIRST_PSEUDO_REGISTER)
+ && HARD_REGNO_MODE_OK (regno, mode))
+ {
+ rtx reg = gen_rtx_REG (mode, regno);
+ return gen_rtx_SET (VOIDmode, dest, reg);
What in the world are you doing here with the hard registers?
r~
Ah, So we don't have the convention to play with hard register in this pass?
This AND rtx here will be transformed into a zero_extend rtx from
sub_reg expression, and further into the form I have mentioned above, as
the hard register support this.
(and:SI (reg:SI 1 x1 [ y ])
(const_int 255 [0xff])))
I have modified my patch a little bit, Is the following method Okay?
if (GET_CODE (dest) == ZERO_EXTRACT
&& CONST_INT_P (XEXP (dest, 1))
&& CONST_INT_P (XEXP (dest, 2))
&& GET_CODE (src) == ZERO_EXTEND)
{
HOST_WIDE_INT width = INTVAL (XEXP (dest, 1));
mode = GET_MODE (dest);
/* handle sub_reg rtx. */
if (GET_CODE (XEXP (src, 0)) == SUBREG && REG_P (XEXP (XEXP (src,
0), 0)))
{
rtx reg = XEXP (XEXP (src, 0), 0);
unsigned int inner_size = GET_MODE_BITSIZE (GET_MODE (XEXP (src,
0)));
/* Complete overlap. We can remove the source ZERO_EXTEND. */
if (width == inner_size
&& mode == GET_MODE (reg))
return gen_rtx_SET (VOIDmode, dest, reg);
}
/* handle hard register case as sub_reg further is simplied. */
else if (REG_P (XEXP (src, 0)))
{
rtx tmp = XEXP (src, 0);
unsigned int inner_size = GET_MODE_BITSIZE (GET_MODE (tmp));
/* Complete overlap. We can remove the source ZERO_EXTEND. */
if (width == inner_size && can_change_dest_mode (tmp, 0, mode))
{
rtx reg = gen_rtx_REG (mode, REGNO (tmp));
return gen_rtx_SET (VOIDmode, dest, reg);
}
}
}
Is there a better way to do this here or somewhere else? or it's good
to implement it as a specific rtx insn?
A define split won't work in this case. This should handled in combine pass.
Thank you for any suggestions!
Regards,
Renlin Li