[PATCH][ARM] Refactor MOVW/MOVT fusion logic to allow extension

Richard Earnshaw (lists) Richard.Earnshaw@arm.com
Fri Aug 26 10:14:00 GMT 2016


On 24/08/16 16:26, Kyrill Tkachov wrote:
> Hi all,
> 
> If we want to add more macro fusion cases in the arm backend we need to
> rework the aarch_macro_fusion_pair_p a bit
> to not return early during the MOVW/MOVT fusion checks.  This simple
> patch does that by adding a helper function
> that can be called with the two sets to check if they satisfy the fusion
> logic.  There is no change in codegen.
> 
> Bootstrapped and tested on arm-none-linux-gnueabihf.
> 
> Ok for trunk?
> Thanks,
> Kyrill
> 
> 2016-08-23  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
> 
>     * config/arm/arm.c (arm_sets_movw_movt_fusible_p): New function.
>     (aarch_macro_fusion_pair_p): Use above to avoid early return.
> 

OK.

R.

> arm-fusion-movw-movt-refactor.patch
> 
> 
> diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
> index 2deb62b2f724ef9c17f585046480e47abcd341b0..bb6ada9e0f62efae95fdeb11dfcee14dba3299b0 100644
> --- a/gcc/config/arm/arm.c
> +++ b/gcc/config/arm/arm.c
> @@ -29903,11 +29903,57 @@ arm_macro_fusion_p (void)
>    return current_tune->fusible_ops != tune_params::FUSE_NOTHING;
>  }
>  
> +/* Return true if the two back-to-back sets PREV_SET, CURR_SET are suitable
> +   for MOVW / MOVT macro fusion.  */
> +
> +static bool
> +arm_sets_movw_movt_fusible_p (rtx prev_set, rtx curr_set)
> +{
> +  /* We are trying to fuse
> +     movw imm / movt imm
> +    instructions as a group that gets scheduled together.  */
> +
> +  rtx set_dest = SET_DEST (curr_set);
> +
> +  if (GET_MODE (set_dest) != SImode)
> +    return false;
> +
> +  /* We are trying to match:
> +     prev (movw)  == (set (reg r0) (const_int imm16))
> +     curr (movt) == (set (zero_extract (reg r0)
> +					(const_int 16)
> +					(const_int 16))
> +			  (const_int imm16_1))
> +     or
> +     prev (movw) == (set (reg r1)
> +			  (high (symbol_ref ("SYM"))))
> +    curr (movt) == (set (reg r0)
> +			(lo_sum (reg r1)
> +				(symbol_ref ("SYM"))))  */
> +
> +    if (GET_CODE (set_dest) == ZERO_EXTRACT)
> +      {
> +	if (CONST_INT_P (SET_SRC (curr_set))
> +	    && CONST_INT_P (SET_SRC (prev_set))
> +	    && REG_P (XEXP (set_dest, 0))
> +	    && REG_P (SET_DEST (prev_set))
> +	    && REGNO (XEXP (set_dest, 0)) == REGNO (SET_DEST (prev_set)))
> +	  return true;
> +
> +      }
> +    else if (GET_CODE (SET_SRC (curr_set)) == LO_SUM
> +	     && REG_P (SET_DEST (curr_set))
> +	     && REG_P (SET_DEST (prev_set))
> +	     && GET_CODE (SET_SRC (prev_set)) == HIGH
> +	     && REGNO (SET_DEST (curr_set)) == REGNO (SET_DEST (prev_set)))
> +      return true;
> +
> +  return false;
> +}
>  
>  static bool
>  aarch_macro_fusion_pair_p (rtx_insn* prev, rtx_insn* curr)
>  {
> -  rtx set_dest;
>    rtx prev_set = single_set (prev);
>    rtx curr_set = single_set (curr);
>  
> @@ -29925,45 +29971,10 @@ aarch_macro_fusion_pair_p (rtx_insn* prev, rtx_insn* curr)
>        && aarch_crypto_can_dual_issue (prev, curr))
>      return true;
>  
> -  if (current_tune->fusible_ops & tune_params::FUSE_MOVW_MOVT)
> -    {
> -      /* We are trying to fuse
> -	 movw imm / movt imm
> -	 instructions as a group that gets scheduled together.  */
> -
> -      set_dest = SET_DEST (curr_set);
> -
> -      if (GET_MODE (set_dest) != SImode)
> -	return false;
> +  if (current_tune->fusible_ops & tune_params::FUSE_MOVW_MOVT
> +      && arm_sets_movw_movt_fusible_p (prev_set, curr_set))
> +    return true;
>  
> -      /* We are trying to match:
> -	 prev (movw)  == (set (reg r0) (const_int imm16))
> -	 curr (movt) == (set (zero_extract (reg r0)
> -					  (const_int 16)
> -					   (const_int 16))
> -			     (const_int imm16_1))
> -	 or
> -	 prev (movw) == (set (reg r1)
> -			      (high (symbol_ref ("SYM"))))
> -	 curr (movt) == (set (reg r0)
> -			     (lo_sum (reg r1)
> -				     (symbol_ref ("SYM"))))  */
> -      if (GET_CODE (set_dest) == ZERO_EXTRACT)
> -	{
> -	  if (CONST_INT_P (SET_SRC (curr_set))
> -	      && CONST_INT_P (SET_SRC (prev_set))
> -	      && REG_P (XEXP (set_dest, 0))
> -	      && REG_P (SET_DEST (prev_set))
> -	      && REGNO (XEXP (set_dest, 0)) == REGNO (SET_DEST (prev_set)))
> -	    return true;
> -	}
> -      else if (GET_CODE (SET_SRC (curr_set)) == LO_SUM
> -	       && REG_P (SET_DEST (curr_set))
> -	       && REG_P (SET_DEST (prev_set))
> -	       && GET_CODE (SET_SRC (prev_set)) == HIGH
> -	       && REGNO (SET_DEST (curr_set)) == REGNO (SET_DEST (prev_set)))
> -	     return true;
> -    }
>    return false;
>  }
>  
> 



More information about the Gcc-patches mailing list