On Mon, Aug 24, 2020 at 8:20 AM Feng Xue OS via Gcc wrote:
>
> >> 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).
It's also what :s does but a slight bit more "local". When any operand is
marked :s and it has more than a single-use we only allow simplifications
that do not require insertion of extra stmts. So basically the above pattern
doesn't behave any different than if you omit your :v. Only if you'd
place :v on an inner expression there would be a difference. Correlating
the inner expression we'd not want to insert new expressions for with
a specific :s (or multiple ones) would be a more natural extension of what
:s provides.
Thus, for the above case (Form 1), you do not need :v at all and :s works.
Richard.
> Thanks,
> Feng