On Tue, Jul 15, 2014 at 2:47 PM, Prathamesh Kulkarni <bilbotheelffri...@gmail.com> wrote: > On Tue, Jul 15, 2014 at 2:07 PM, Richard Biener > <richard.guent...@gmail.com> wrote: >> On Mon, Jul 14, 2014 at 10:52 PM, Prathamesh Kulkarni >> <bilbotheelffri...@gmail.com> wrote: >>> On Mon, Jul 14, 2014 at 6:35 PM, Richard Biener >>> <richard.guent...@gmail.com> wrote: >>>> On Mon, Jul 14, 2014 at 12:07 PM, Prathamesh Kulkarni >>>> <bilbotheelffri...@gmail.com> wrote: >>>>> I was wondering if it was a good idea to implement >>>>> predicate on expressions ? >>>>> >>>>> Sth like: >>>>> (match_and_simplify >>>>> (op (op2:predicate @0)) >>>>> transform) >>>>> >>>>> instead of: >>>>> (match_and_simplify >>>>> (op (op2@1 @0)) >>>>> if (predicate (@1)) >>>>> transform) >>>>> >>>>> When predicate is simple as just being a macro/function, >>>>> we could use this style and when the predicate is more complex >>>>> resort to using if-expr (or write the predicate as macro in >>>>> gimple-match-head.c >>>>> and use the macro in pattern instead ...) >>>>> >>>>> Example: >>>>> we could rewrite the pattern >>>>> (match_and_simplify >>>>> (plus:c @0 (negate @1)) >>>>> if (!TYPE_SATURATING (type)) >>>>> (minus @0 @1)) >>>>> >>>>> to >>>>> >>>>> (match_and_simplify >>>>> (plus:c:NOT_TYPE_SATURATING_P @0 (negate @1)) >>>>> (minus @0 @1)) >>>>> >>>>> with NOT_TYPE_SATURATING_P predicate defined >>>>> appropriately in gimple-match-head.c >>>>> >>>>> However I am not entirely sure if adding predicates on expressions >>>>> would be very useful.... >>>> >>>> Well. I think there are two aspects to this. First is pattern >>>> readability where I think that the if-expr form is more readable. >>>> Second is the ability to do less work in the code generated >>>> from the decision tree. >>>> >>>> For example most of the patterns from associate_plusminus >>>> still miss the !TYPE_SATURATING && !FLOAT_TYPE_P && >>>> !FIXED_POINT_TYPE_P if-expr. That is, we'd have >>>> >>>> /* (A +- B) - A -> +-B. */ >>>> (match_and_simplify >>>> (minus (plus @0 @1) @0) >>>> if (!TYPE_SATURATING (type) >>>> && !FLOAT_TYPE_P (type) && !FIXED_POINT_TYPE_P (type)) >>>> @1) >>>> (match_and_simplify >>>> (minus (minus @0 @1) @0) >>>> if (!TYPE_SATURATING (type) >>>> && !FLOAT_TYPE_P (type) && !FIXED_POINT_TYPE_P (type)) >>>> (negate @1)) >>>> /* (A +- B) -+ B -> A. */ >>>> (match_and_simplify >>>> (minus (plus @0 @1) @1) >>>> if (!TYPE_SATURATING (type) >>>> && !FLOAT_TYPE_P (type) && !FIXED_POINT_TYPE_P (type)) >>>> @0) >>>> (match_and_simplify >>>> (plus:c (minus @0 @1) @1) >>>> if (!TYPE_SATURATING (type) >>>> && !FLOAT_TYPE_P (type) && !FIXED_POINT_TYPE_P (type)) >>>> @0) >>>> >>>> with code-generation checking the if-expr after matching. And >>>> with using expression predicates we'd be able to check the >>>> predicate when matching the outermost 'minus' and "CSE" >>>> the predicate check for the first three patterns. Runtime-wise >>>> it depends on whether there is a point to back-track to. >>>> >>>> I would say it's more interesting to support >>>> >>>> if (!TYPE_SATURATING (type) && !FLOAT_TYPE_P (type) && >>>> !FiXED_POINT_TYPE_P (type)) >>>> (match_and_simplify ....) >>>> (match_and_simplify ....) >>>> .... >>>> >>>> and treat this if-expression like a predicate on the outermost >>>> expression. That's getting both benefits >>>> (bah, the free-form if-expr makes it ugly, what do we use as >>>> grouping syntax? I guess wrapping the whole thing in ()s, >>>> similar to (for ...)). >>> Um, I was wondering instead of defining new syntax >>> if it would be better to make genmatch detect common if-expr >>> and hoist them ? I suppose we could compare if-expr's lexicographically ? >>> >>> However I guess having some syntax to group common if-expr patterns >>> explicitly would >>> avoid the need for writing the if-expr in each pattern. >> >> Yeah, the main motiviation is to make the patterns itself easier to read >> and group them by boiler-plate if-exprs. >> >>> For now should we go with free-form if ? >> >> I'd say >> >> (if (!TYPE_SATURATING (type) ....) >> <patterns...> >> ) >> >> thus wrap the if inside ()s. Otherwise there would be no way to >> "end" an if. > maybe use braces ? > if (c_expr) > { > patterns > } > but (if ...) is better. >> >>> If desired, we could change syntax later to >>> something else (only parsing code need change, the rest would be in place). >>> If we change the syntax for outer-if, for consistency should we also >>> change syntax of inner if ? >> >> Probably yes, let's wrap the inner if inside ()s as well. > Okay. >> >> Code-generation-wise we should record a vector of if-exprs and thus >> evaluate the outer ifs at the same place we evaluate inner if-exprs. > Um, I don't get this. > say we have the following pattern: > (if cond > (match_and_simplify > match1 > transform1) > > (match_and_simplify > match2 > transform2)) > > The generated code would be the following ? > if (cond) > { > match1 > transform1 > > match2 > transform2 > } > > Currently we do: > match1 > if (cond) > transform1 > > match2 > if (cond) > transform2
I was thinking about (if cond1 (match_and_simplify match1 if cond2 transform1) (match_and_simplify match2 if cond3 transform2)) where we should generate match1 if (cond1 && cond2) transform1 match2 if (cond1 && cond3) transform2 and eventually even allow nested outer ifs (why not) (if (FLOAT_TYPE_P (type)) (if (...) (match... ) (match ...) ) like some of the simplifications are grouped in fold-const.c. Easiest would be to make the simplifier if-expr a vector of if-expr, replicating the currently active outer if conditions. Richard. > Thanks and Regards, > Prathamesh >> >> Thanks, >> Richard. >> >>> Thanks and Regards, >>> Prathamesh >>>> >>>> Richard. >>>> >>>>> Thanks and Regards, >>>>> Prathamesh