On 19/06/17 14:46, Richard Earnshaw (lists) wrote:
> Many parallel set insns are of the form of a single set that also sets
> the condition code flags. In this case the cost of such an insn is
> normally the cost of the part that doesn't set the flags, since updating
> the condition flags is simply a side effect.
>
> At present all such insns are treated as having unknown cost (ie 0) and
> combine assumes that such insns are infinitely more expensive than any
> other insn sequence with a non-zero cost.
>
> This patch addresses this problem by allowing insn_rtx_cost to ignore
> the condition setting part of a PARALLEL iff there is exactly one
> comparison set and one non-comparison set. If the only set operation is
> a comparison we still use that as the basis of the insn cost.
>
> * rtlanal.c (insn_rtx_cost): If a parallel contains exactly one
> comparison set and one other set, use the cost of the
> non-comparison set.
>
> Bootstrapped on aarch64-none-linuxgnu
>
> OK?
>
Ping?
R.
> R.
>
>
> insn-costs.patch
>
>
> diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
> index d9f57c3..5cae793 100644
> --- a/gcc/rtlanal.c
> +++ b/gcc/rtlanal.c
> @@ -5260,23 +5260,41 @@ insn_rtx_cost (rtx pat, bool speed)
> int i, cost;
> rtx set;
>
> - /* Extract the single set rtx from the instruction pattern.
> - We can't use single_set since we only have the pattern. */
> + /* Extract the single set rtx from the instruction pattern. We
> + can't use single_set since we only have the pattern. We also
> + consider PARALLELs of a normal set and and a single comparison.
> + In that case we use the cost of the non-comparison SET operation,
> + which is most-likely to be the real cost of this operation. */
> if (GET_CODE (pat) == SET)
> set = pat;
> else if (GET_CODE (pat) == PARALLEL)
> {
> set = NULL_RTX;
> + rtx comparison = NULL_RTX;
> +
> for (i = 0; i < XVECLEN (pat, 0); i++)
> {
> rtx x = XVECEXP (pat, 0, i);
> if (GET_CODE (x) == SET)
> {
> - if (set)
> - return 0;
> - set = x;
> + if (GET_CODE (SET_SRC (x)) == COMPARE)
> + {
> + if (comparison)
> + return 0;
> + comparison = x;
> + }
> + else
> + {
> + if (set)
> + return 0;
> + set = x;
> + }
> }
> }
> +
> + if (!set && comparison)
> + set = comparison;
> +
> if (!set)
> return 0;
> }
>