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] PR target/71549: Convert V1TImode register to TImode in debug insn


On Mon, Jun 20, 2016 at 1:55 PM, H.J. Lu <hongjiu.lu@intel.com> wrote:
> TImode register referenced in debug insn can be converted to V1TImode
> by scalar to vector optimization.  We need to convert a debug insn if
> it has a variable in a TImode register.
>
> Tested on x86-64.  OK for trunk?

Ilya, does this approach look good to you? Also, does DImode STV
conversion need similar handling of debug insns?

Uros.

>
> H.J.
> ----
> gcc/
>
>         PR target/71549
>         * config/i386/i386.c (timode_scalar_to_vector_candidate_p):
>         Return true if debug insn has a variable in TImode register.
>         (timode_remove_non_convertible_regs): Skip debug insn.
>         (scalar_chain::convert_insn): Change return type to bool.
>         (scalar_chain::add_insn): Don't check registers in debug insn.
>         (dimode_scalar_chain::convert_insn): Change return type to bool
>         and always return true.
>         (timode_scalar_chain::convert_insn): Change return type to bool.
>         Convert V1TImode register to SUBREG TImode in debug insn.  Return
>         false if debug insn isn't converted.  Otherwise, return true.
>         (scalar_chain::convert): Increment converted_insns only if
>         convert_insn returns true.
>
> gcc/testsuite/
>
>         PR target/71549
>         * gcc.target/i386/pr71549.c: New test.
> ---
>  gcc/config/i386/i386.c                  | 58 ++++++++++++++++++++++++++++-----
>  gcc/testsuite/gcc.target/i386/pr71549.c | 24 ++++++++++++++
>  2 files changed, 74 insertions(+), 8 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr71549.c
>
> diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
> index 56a5b9c..e17fc53 100644
> --- a/gcc/config/i386/i386.c
> +++ b/gcc/config/i386/i386.c
> @@ -2845,6 +2845,16 @@ dimode_scalar_to_vector_candidate_p (rtx_insn *insn)
>  static bool
>  timode_scalar_to_vector_candidate_p (rtx_insn *insn)
>  {
> +  if (DEBUG_INSN_P (insn))
> +    {
> +      /* If a variable is put in a TImode register, which may be
> +        converted to V1TImode, we need to convert this debug insn.  */
> +      rtx val = PATTERN (insn);
> +      return (GET_MODE (val) == TImode
> +             && GET_CODE (val) == VAR_LOCATION
> +             && REG_P (PAT_VAR_LOCATION_LOC (val)));
> +    }
> +
>    rtx def_set = single_set (insn);
>
>    if (!def_set)
> @@ -3012,7 +3022,12 @@ timode_remove_non_convertible_regs (bitmap candidates)
>
>    EXECUTE_IF_SET_IN_BITMAP (candidates, 0, id, bi)
>      {
> -      rtx def_set = single_set (DF_INSN_UID_GET (id)->insn);
> +      rtx_insn *insn = DF_INSN_UID_GET (id)->insn;
> +      /* Debug insn isn't a SET insn.  */
> +      if (DEBUG_INSN_P (insn))
> +       continue;
> +
> +      rtx def_set = single_set (insn);
>        rtx dest = SET_DEST (def_set);
>        rtx src = SET_SRC (def_set);
>
> @@ -3111,7 +3126,7 @@ class scalar_chain
>    void add_insn (bitmap candidates, unsigned insn_uid);
>    void analyze_register_chain (bitmap candidates, df_ref ref);
>    virtual void mark_dual_mode_def (df_ref def) = 0;
> -  virtual void convert_insn (rtx_insn *insn) = 0;
> +  virtual bool convert_insn (rtx_insn *insn) = 0;
>    virtual void convert_registers () = 0;
>  };
>
> @@ -3123,7 +3138,7 @@ class dimode_scalar_chain : public scalar_chain
>    void mark_dual_mode_def (df_ref def);
>    rtx replace_with_subreg (rtx x, rtx reg, rtx subreg);
>    void replace_with_subreg_in_insn (rtx_insn *insn, rtx reg, rtx subreg);
> -  void convert_insn (rtx_insn *insn);
> +  bool convert_insn (rtx_insn *insn);
>    void convert_op (rtx *op, rtx_insn *insn);
>    void convert_reg (unsigned regno);
>    void make_vector_copies (unsigned regno);
> @@ -3139,7 +3154,7 @@ class timode_scalar_chain : public scalar_chain
>
>   private:
>    void mark_dual_mode_def (df_ref def);
> -  void convert_insn (rtx_insn *insn);
> +  bool convert_insn (rtx_insn *insn);
>    /* We don't convert registers to difference size.  */
>    void convert_registers () {}
>  };
> @@ -3276,6 +3291,10 @@ scalar_chain::add_insn (bitmap candidates, unsigned int insn_uid)
>    bitmap_set_bit (insns, insn_uid);
>
>    rtx_insn *insn = DF_INSN_UID_GET (insn_uid)->insn;
> +  /* Debug insn isn't a SET insn.  */
> +  if (DEBUG_INSN_P (insn))
> +    return;
> +
>    rtx def_set = single_set (insn);
>    if (def_set && REG_P (SET_DEST (def_set))
>        && !HARD_REGISTER_P (SET_DEST (def_set)))
> @@ -3708,7 +3727,7 @@ dimode_scalar_chain::convert_op (rtx *op, rtx_insn *insn)
>
>  /* Convert INSN to vector mode.  */
>
> -void
> +bool
>  dimode_scalar_chain::convert_insn (rtx_insn *insn)
>  {
>    rtx def_set = single_set (insn);
> @@ -3788,13 +3807,34 @@ dimode_scalar_chain::convert_insn (rtx_insn *insn)
>    INSN_CODE (insn) = -1;
>    recog_memoized (insn);
>    df_insn_rescan (insn);
> +
> +  return true;
>  }
>
>  /* Convert INSN from TImode to V1T1mode.  */
>
> -void
> +bool
>  timode_scalar_chain::convert_insn (rtx_insn *insn)
>  {
> +  if (DEBUG_INSN_P (insn))
> +    {
> +      /* It must be a debug insn with a TImode variable in register.  */
> +      rtx val = PATTERN (insn);
> +      gcc_assert (GET_MODE (val) == TImode
> +                 && GET_CODE (val) == VAR_LOCATION);
> +      rtx loc = PAT_VAR_LOCATION_LOC (val);
> +      gcc_assert (REG_P (loc));
> +      /* Convert V1TImode register, which has been updated by a SET
> +        insn before, to SUBREG TImode.  */
> +      if (GET_MODE (loc) == V1TImode)
> +       {
> +         PAT_VAR_LOCATION_LOC (val) = gen_rtx_SUBREG (TImode, loc, 0);
> +         df_insn_rescan (insn);
> +         return true;
> +       }
> +      return false;
> +    }
> +
>    rtx def_set = single_set (insn);
>    rtx src = SET_SRC (def_set);
>    rtx dst = SET_DEST (def_set);
> @@ -3858,6 +3898,8 @@ timode_scalar_chain::convert_insn (rtx_insn *insn)
>    INSN_CODE (insn) = -1;
>    recog_memoized (insn);
>    df_insn_rescan (insn);
> +
> +  return true;
>  }
>
>  void
> @@ -3893,8 +3935,8 @@ scalar_chain::convert ()
>
>    EXECUTE_IF_SET_IN_BITMAP (insns, 0, id, bi)
>      {
> -      convert_insn (DF_INSN_UID_GET (id)->insn);
> -      converted_insns++;
> +      if (convert_insn (DF_INSN_UID_GET (id)->insn))
> +       converted_insns++;
>      }
>
>    return converted_insns;
> diff --git a/gcc/testsuite/gcc.target/i386/pr71549.c b/gcc/testsuite/gcc.target/i386/pr71549.c
> new file mode 100644
> index 0000000..8aac891
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr71549.c
> @@ -0,0 +1,24 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -g" } */
> +
> +struct S1
> +{
> +  int f0;
> +  int f1;
> +  int f2;
> +  int:4;
> +} a, b;
> +
> +void
> +fn1 (struct S1 p1)
> +{
> +  a = p1;
> +  int c = p1.f0;
> +}
> +
> +int
> +main ()
> +{
> +  fn1 (b);
> +  return 0;
> +}
> --
> 2.5.5
>


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