regrename patch: PR 42220

Richard Guenther richard.guenther@gmail.com
Wed Mar 3 13:03:00 GMT 2010


On Wed, Mar 3, 2010 at 1:50 PM, Bernd Schmidt <bernds_cb1@t-online.de> wrote:
> PR 42220 exposes another problem with my previous regrename patchkit.
> Registers that have not previously been marked live can occur in in-out
> operands, not only in artificial in-out operands (with predication,
> fixed in a previous patch already).  This happens because reload deletes
> all the CLOBBER insns that would otherwise help with the liveness
> analysis.  A multi-insn sequence to initialize a complex value with insv
> patterns, as in the PR, will appear to read a register that is not live.
>
> This patch extends the mechanisms that were introduced for the
> previously discovered incarnation of the problem.  If the in-out operand
> occurs multiple times (due to match_dup), we have to give up, otherwise
> we just treat it as an output if we know nothing about the reg.
>
> A slightly different version was bootstrapped and tested on i686-linux.
>  Ok after retesting?

Ok.  Please add PR rtl-optimization/42220 to the changelog entry.

Thanks,
Richard.

>
> Bernd
> --
> This footer brought to you by insane German lawmakers.
> Analog Devices GmbH      Wilhelm-Wagenfeld-Str. 6      80807 Muenchen
> Sitz der Gesellschaft Muenchen, Registergericht Muenchen HRB 40368
> Geschaeftsfuehrer Thomas Wessel, William A. Martin, Margaret Seif
>
>        * regrename.c (scan_rtx) <case STRICT_LOW_PART, ZERO_EXTRACT>:
>        Use verify_reg_tracked to determine if we should use OP_OUT rather
>        than OP_INOUT.
>        (build_def_use): If we see an in-out operand for a register that we
>        know nothing about, treat is an output if possible, fail the block if
>        not.
>
> Index: regrename.c
> ===================================================================
> --- regrename.c (revision 157143)
> +++ regrename.c (working copy)
> @@ -889,13 +893,15 @@ scan_rtx (rtx insn, rtx *loc, enum reg_c
>       return;
>
>     case STRICT_LOW_PART:
> -      scan_rtx (insn, &XEXP (x, 0), cl, action, OP_INOUT);
> +      scan_rtx (insn, &XEXP (x, 0), cl, action,
> +               verify_reg_tracked (XEXP (x, 0)) ? OP_INOUT : OP_OUT);
>       return;
>
>     case ZERO_EXTRACT:
>     case SIGN_EXTRACT:
>       scan_rtx (insn, &XEXP (x, 0), cl, action,
> -               type == OP_IN ? OP_IN : OP_INOUT);
> +               (type == OP_IN ? OP_IN :
> +                verify_reg_tracked (XEXP (x, 0)) ? OP_INOUT : OP_OUT));
>       scan_rtx (insn, &XEXP (x, 1), cl, action, OP_IN);
>       scan_rtx (insn, &XEXP (x, 2), cl, action, OP_IN);
>       return;
> @@ -1067,6 +1073,7 @@ build_def_use (basic_block bb)
>          int n_ops;
>          rtx note;
>          rtx old_operands[MAX_RECOG_OPERANDS];
> +         bool has_dup[MAX_RECOG_OPERANDS];
>          rtx old_dups[MAX_DUP_OPERANDS];
>          int i;
>          int alt;
> @@ -1105,6 +1112,10 @@ build_def_use (basic_block bb)
>          n_ops = recog_data.n_operands;
>          untracked_operands = 0;
>
> +         memset (has_dup, 0, sizeof has_dup);
> +         for (i = 0; i < recog_data.n_dups; i++)
> +           has_dup[(int)recog_data.dup_num[i]] = true;
> +
>          /* Simplify the code below by rewriting things to reflect
>             matching constraints.  Also promote OP_OUT to OP_INOUT in
>             predicated instructions, but only for register operands
> @@ -1137,6 +1147,20 @@ build_def_use (basic_block bb)
>                      untracked_operands |= 1 << matches;
>                    }
>                }
> +             /* If there's an in-out operand with a register that is not
> +                being tracked at all yet, convert it to an earlyclobber
> +                output operand.
> +                This only works if the operand isn't duplicated, i.e. for
> +                a ZERO_EXTRACT in a SET_DEST.  */
> +             if (recog_data.operand_type[i] == OP_INOUT
> +                 && !(untracked_operands & (1 << i))
> +                 && !verify_reg_tracked (recog_data.operand[i]))
> +               {
> +                 if (has_dup[i])
> +                   fail_current_block = true;
> +                 recog_data.operand_type[i] = OP_OUT;
> +                 recog_op_alt[i][alt].earlyclobber = 1;
> +               }
>            }
>
>          if (fail_current_block)
>
>



More information about the Gcc-patches mailing list