This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] PR target/71549: Convert V1TImode register to TImode in debug insn
- From: Uros Bizjak <ubizjak at gmail dot com>
- To: "H.J. Lu" <hjl dot tools at gmail dot com>, ÐÐÑÑ ÐÐÐÐÐÐÑ <enkovich dot gnu at gmail dot com>
- Cc: "gcc-patches at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>
- Date: Mon, 20 Jun 2016 15:39:47 +0200
- Subject: Re: [PATCH] PR target/71549: Convert V1TImode register to TImode in debug insn
- Authentication-results: sourceware.org; auth=none
- References: <20160620115515 dot GA4587 at intel dot com>
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
>