On 11/04/2013 08:00 PM, Zhenqiang Chen wrote:
> Thanks. I add a new hook. The default function will return -1 if the target
> does not care about the order.
> 
> +DEFHOOK
> +(select_ccmp_cmp_order,
> + "For some target (like ARM), the order of two compares is sensitive for\n\
> +conditional compare.  cmp0-cmp1 might be an invalid combination.  But when\n\
> +swapping the order, cmp1-cmp0 is valid.  The function will return\n\
> +  -1: if @code{code1} and @code{code2} are valid combination.\n\
> +   1: if @code{code2} and @code{code1} are valid combination.\n\
> +   0: both are invalid.",
> + int, (int code1, int code2),
> + default_select_ccmp_cmp_order)

Fair enough.  I'd originally been thinking that returning a tri-state value
akin to the comparison callback to qsort would allow easy sorting of a whole
list of comparisons.  But probably just as easy to open-code while checking for
invalid combinations.

Checking for invalid while sorting means that we can then disallow returning
NULL from the other two hooks.  Because the backend has already had a chance to
indicate failure.

> For gen_ccmp_next, I add another parameter CC_P to indicate the result is
> used as CC or not. If CC_P is false, the gen_ccmp_next will return a general
> register. This is for code like
> 
> int test (int a, int b)
> {
>   return a > 0 && b > 0;
> }
> During expand, there might have no branch at all. So gen_ccmp_next can not
> return CC for "a > 0 && b > 0".

Uh, no, this is a terrible idea.  There's no need for gen_ccmp_next to re-do
the work of cstore_optab.

I believe you can use emit_store_flag as a high-level interface here, since
there are technically vagaries due to STORE_FLAG_VALUE.  If that turns out to
crash or fail in some way, we can talk about using cstore_optab directly given
some restrictions.

It also means that you shouldn't need all of and_scc_scc, ior_scc_scc,
ccmp_and_scc_scc, ccmp_ior_scc_scc.

Although I don't see cstorecc4 defined for ARM, so there is something missing.


> +static int
> +arm_select_ccmp_cmp_order (int cond1, int cond2)
> +{
> +  if (cond1 == cond2)
> +    return -1;
> +  if (comparison_dominates_p ((enum rtx_code) cond1, (enum rtx_code) cond2))
> +    return 1;
> +  if (comparison_dominates_p ((enum rtx_code) cond2, (enum rtx_code) cond1))
> +    return -1;
> +  return 0;
> +
> +}

This sort does not look stable.  In particular,

  if (cond1 == cond2)
    return 1;

would seem to better preserve the original order of the comparisons.


r~

Reply via email to