This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: predicates on expressions ?
- From: Prathamesh Kulkarni <bilbotheelffriend at gmail dot com>
- To: Richard Biener <richard dot guenther at gmail dot com>
- Cc: Diego Novillo <dnovillo at google dot com>, gcc <gcc at gcc dot gnu dot org>, Maxim Kuvyrkov <maxim dot kuvyrkov at linaro dot org>
- Date: Tue, 15 Jul 2014 18:31:16 +0530
- Subject: Re: predicates on expressions ?
- Authentication-results: sourceware.org; auth=none
- References: <CAJXstsDuzBPFUYiNv5L2n118cA8CLUPa2EPed1gCwa6PYB4C2w at mail dot gmail dot com> <CAFiYyc2imdRW4oCieE3Caxk7=+j=aruGCqD0E2VQUyY==FxGBA at mail dot gmail dot com> <CAJXstsA_c2d7+6SemZNiuFX0BgVVe2vzVpYv5iWOG2NMRNkLkA at mail dot gmail dot com> <CAFiYyc2zK8tgga3XTRNO2F=hNJS4JuNb8+h4f5_gxmcAwABtMQ at mail dot gmail dot com> <CAJXstsCBG4hPrs1hoiOe3PVsdMGV0gi45J7asVeTa6OT7_UOaA at mail dot gmail dot com> <CAFiYyc1GSfd_KBoV9fyK5zPOWMDp_4Ews7F4FbFcLQ48Uhsk+A at mail dot gmail dot com>
On Tue, Jul 15, 2014 at 6:28 PM, Richard Biener
<richard.guenther@gmail.com> wrote:
> On Tue, Jul 15, 2014 at 2:47 PM, Prathamesh Kulkarni
> <bilbotheelffriend@gmail.com> wrote:
>> On Tue, Jul 15, 2014 at 2:07 PM, Richard Biener
>> <richard.guenther@gmail.com> wrote:
>>> On Mon, Jul 14, 2014 at 10:52 PM, Prathamesh Kulkarni
>>> <bilbotheelffriend@gmail.com> wrote:
>>>> On Mon, Jul 14, 2014 at 6:35 PM, Richard Biener
>>>> <richard.guenther@gmail.com> wrote:
>>>>> On Mon, Jul 14, 2014 at 12:07 PM, Prathamesh Kulkarni
>>>>> <bilbotheelffriend@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.
Okay thanks, I get it now.
I will get started with implementing outer-if
Thanks and Regards,
Prathamesh
>
> Richard.
>
>> Thanks and Regards,
>> Prathamesh
>>>
>>> Thanks,
>>> Richard.
>>>
>>>> Thanks and Regards,
>>>> Prathamesh
>>>>>
>>>>> Richard.
>>>>>
>>>>>> Thanks and Regards,
>>>>>> Prathamesh