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