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.tkac...@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;
>  }
>  
> 

Reply via email to