On 05/01/2018 02:42 AM, Marc Glisse wrote:
> (I am not a reviewer, just commenting)
But your comments are definitely appreciated!

> 
> On Fri, 9 Feb 2018, Roger Sayle wrote:
> 
>> The following patch implements a number of __builtin_popcount related
>> optimizations.
>> (i) popcount(x) == 0 can be simplified to x==0, and popcount(x) != 0 to
>> x!=0.
>> (ii) popcount(x&1) can be simplified to x&1, and for unsigned x,
>> popcount(x>>31) to x>>31.
>> (iii) popcount (x&6) + popcount(y&16) can be simplified to
>> popcount((x&6)|(y&16))
>>
>> These may seem obscure transformations, but performing these types of
>> POPCOUNT operations are often the performance critical steps in some
>> cheminformatics applications.
>>
>> To implement the above transformations I've introduced the
>> tree_nonzero_bits function, which is a tree-level version of rtlanal's
>> nonzero_bits used by the RTL optimizers.
> 
> I am wondering if this brings much, compared to just using
> get_nonzero_bits (works on INTEGER_CST / SSA_NAME, matched by
> with_possible_nonzero_bits). If we do decide to introduce this function,
> we probably want to use it in other places that currently use
> get_nonzero_bits as well...
> 
>> +    case NOP_EXPR:
>> +    case CONVERT_EXPR:
> 
> We have CASE_CONVERT: for this pair.
I've fixed this in Roger's patch.

> 
>> +    case LSHIFT_EXPR:
>> +      if (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST)
> 
> Maybe check INTEGRAL_TYPE_P as well, like you did for PLUS_EXPR? Or was
> that also unnecessary for PLUS_EXPR?
While there may be cases where allowing an INTEGRAL_TYPE_P SSA_NAME for
the shift count would be helpful, I think it'd be exceedingly rare.

For operands of a PLUS_EXPR I think we're a lot more likely to be able
to do something useful with an SSA_NAME argument.


> 
>> +      return wi::neg_p (arg1)
>> +         ? wi::rshift (nzbits, -arg1, TYPE_SIGN (type))
>> +         : wi::lshift (nzbits, arg1);
> 
> I can see that fold-const.c already does something like that. I am
> surprised the sanitizer guys haven't asked that we just punt on negative
> values instead.
I'm leaving this as-is -- while I think negative shift counts are a bad
idea, handling them in any other way is likely going to result in a real
surprise in the result of the computation.


> 
>> +  /* popcount(X) + popcount(Y) is popcount(X|Y) when X&Y must be
>> zero.  */
>> +  (simplify
>> +    (plus (popcount @0) (popcount @1))
> 
> We probably want :s on both popcount: if they are used in other places
> than just this addition, it is likely cheaper not to introduce a new
> call to popcount.
Yea.  I also verified the Roger's tests still work with the :s added.

> 
>> +  /* pocount(X) == 0 is X == 0, and related (in)equalities.  */
> 
> po+p+count
Fixed.

> 
>> +  (for cmp (le eq ne gt)
>> +       rep (eq eq ne ne)
>> +    (simplify
>> +      (cmp (popcount @0) zerop)
> 
> Might as well use integer_zerop when we know we are dealing with integers.
And fixed.


I've also re-bootstrapped Roger's patch and will be committing it shortly.

jeff

Reply via email to