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~