>>   There is a match-folding issue derived from pr94234.  A piece of code like:
>> 
>>   int foo (int n)
>>   {
>>      int t1 = 8 * n;
>>      int t2 = 8 * (n - 1);
>> 
>>      return t1 - t2;
>>   }
>> 
>>  It can be perfectly caught by the rule "(A * C) +- (B * C) -> (A +- B) * 
>> C", and
>>  be folded to constant "8". But this folding will fail if both v1 and v2 have
>>  multiple uses, as the following code.
>> 
>>   int foo (int n)
>>   {
>>      int t1 = 8 * n;
>>      int t2 = 8 * (n - 1);
>> 
>>      use_fn (t1, t2);
>>      return t1 - t2;
>>   }
>> 
>>  Given an expression with non-single-use operands, folding it will introduce
>>  duplicated computation in most situations, and is deemed to be unprofitable.
>>  But it is always beneficial if final result is a constant or existing SSA 
>> value.
>> 
>>  And the rule is:
>>   (simplify
>>    (plusminus (mult:cs@3 @0 @1) (mult:cs@4 @0 @2))
>>    (if ((!ANY_INTEGRAL_TYPE_P (type)
>>         || TYPE_OVERFLOW_WRAPS (type)
>>         || (INTEGRAL_TYPE_P (type)
>>             && tree_expr_nonzero_p (@0)
>>             && expr_not_equal_to (@0, wi::minus_one (TYPE_PRECISION 
>> (type)))))
>>        /* If @1 +- @2 is constant require a hard single-use on either
>>           original operand (but not on both).  */
>>        && (single_use (@3) || single_use (@4)))   <----- control whether 
>> match or not
>>     (mult (plusminus @1 @2) @0)))
>> 
>>  Current matcher only provides a way to check something before folding,
>>  but no mechanism to affect decision after folding. If has, for the above
>>  case, we can let it go when we find result is a constant.
> 
> :s already has a counter-measure where it still folds if the output is at
> most one operation. So this transformation has a counter-counter-measure
> of checking single_use explicitly. And now we want a counter^3-measure...
> 
Counter-measure is key factor to matching-cost.  ":s" seems to be somewhat
coarse-grained. And here we do need more control over it.

But ideally, we could decouple these counter-measures from definitions of
match-rule, and let gimple-matcher get a more reasonable match-or-not
decision based on these counters. Anyway, it is another story.

>>  Like the way to describe input operand using flags, we could also add
>>  a new flag to specify this kind of constraint on output that we expect
>>  it is a simple gimple value.
>> 
>>  Proposed syntax is
>> 
>>   (opcode:v{ condition } ....)
>> 
>>  The char "v" stands for gimple value, if more descriptive, other char is
>>  preferred. "condition" enclosed by { } is an optional c-syntax condition
>>  expression. If present, only when "condition" is met, matcher will check
>>  whether folding result is a gimple value using
>>  gimple_simplified_result_is_gimple_val ().
>> 
>>  Since there is no SSA concept in GENERIC, this is only for GIMPLE-match,
>>  not GENERIC-match.
>> 
>>  With this syntax, the rule is changed to
>> 
>>  #Form 1:
>>   (simplify
>>    (plusminus (mult:cs@3 @0 @1) (mult:cs@4 @0 @2))
>>    (if ((!ANY_INTEGRAL_TYPE_P (type)
>>         || TYPE_OVERFLOW_WRAPS (type)
>>         || (INTEGRAL_TYPE_P (type)
>>             && tree_expr_nonzero_p (@0)
>>             && expr_not_equal_to (@0, wi::minus_one (TYPE_PRECISION 
>> (type))))))
>>        ( if (!single_use (@3) && !single_use (@4))
>>           (mult:v (plusminus @1 @2) @0)))
>>           (mult (plusminus @1 @2) @0)))))
> 
> That seems to match what you can do with '!' now (that's very recent).
>>  #Form 2:
>>   (simplify
>>    (plusminus (mult:cs@3 @0 @1) (mult:cs@4 @0 @2))
>>    (if ((!ANY_INTEGRAL_TYPE_P (type)
>>         || TYPE_OVERFLOW_WRAPS (type)
>>         || (INTEGRAL_TYPE_P (type)
>>             && tree_expr_nonzero_p (@0)
>>             && expr_not_equal_to (@0, wi::minus_one (TYPE_PRECISION 
>> (type))))))
>>       (mult:v{ !single_use (@3) && !single_use (@4 } (plusminus @1 @2) @0))))
> 
> Indeed, something more flexible than '!' would be nice, but I am not so
> sure about this versioxzln. If we are going to allow inserting code after
> resimplification and before validation, maybe we should go even further
> and let people insert arbitrary code there...
Yes. I think so and tried to do that.  For sure, result of resimplification 
must be
core data referenced by such user code. But it is hard to unify result
representation for GIMPLE and GENERIC matcher. And one more consideration
is that how often is this generalized usage.

Thanks,
Feng

Reply via email to