This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Optimize bfi by remove redundant zero_extend


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




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]