This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: writing patterns
- From: Prathamesh Kulkarni <bilbotheelffriend at gmail dot com>
- To: Richard Biener <richard dot guenther at gmail dot com>
- Cc: GCC Development <gcc at gcc dot gnu dot org>
- Date: Thu, 31 Jul 2014 14:49:24 +0530
- Subject: Re: writing patterns
- Authentication-results: sourceware.org; auth=none
- References: <CAJXstsDfsQbj4e-RVyGC0grF_UDx5J0pYh=M9H9w=VYA-HBY4w at mail dot gmail dot com> <CAFiYyc0mAyTVrn07+ZSzgRT3of=O90iKkM_HVo1MfTvZaJemvw at mail dot gmail dot com> <CAFiYyc2JyG=jam0XTB3hdyCvmPoN_LFLXW8ca=vcwZnejczj_w at mail dot gmail dot com> <CAJXstsDXyHwQK+dSwyuHPXoDqKv=bceDTL4Yr2Od4YYF6ROXYQ at mail dot gmail dot com> <CAJXstsCfBYf3Z6siL3R6dJ8xrCq6VqJi_c5+uZHVv6QPkLaptQ at mail dot gmail dot com> <CAFiYyc3OC38E2WNpMKfZLGfGLac69QLPJEnbFhLBteOuMPoKwg at mail dot gmail dot com> <CAJXstsAfYKqPwQq58sSaCRPoiMoc9Bs0794qXwvwVvjEG-hdMQ at mail dot gmail dot com> <CAFiYyc2DNWViyx9hK9GkuLzN=9pXLPSXfFwb75w+gvXv12Vr3Q at mail dot gmail dot com>
On Thu, Jul 31, 2014 at 2:44 PM, Richard Biener
<richard.guenther@gmail.com> wrote:
> On Thu, Jul 31, 2014 at 11:09 AM, Prathamesh Kulkarni
> <bilbotheelffriend@gmail.com> wrote:
>> On Thu, Jul 31, 2014 at 2:15 PM, Richard Biener
>> <richard.guenther@gmail.com> wrote:
>>> On Thu, Jul 31, 2014 at 7:41 AM, Prathamesh Kulkarni
>>> <bilbotheelffriend@gmail.com> wrote:
>>>> On Wed, Jul 30, 2014 at 11:49 PM, Prathamesh Kulkarni
>>>> <bilbotheelffriend@gmail.com> wrote:
>>>>> On Wed, Jul 30, 2014 at 4:49 PM, Richard Biener
>>>>> <richard.guenther@gmail.com> wrote:
>>>>>> On Wed, Jul 30, 2014 at 1:11 PM, Richard Biener
>>>>>> <richard.guenther@gmail.com> wrote:
>>>>>>> On Wed, Jul 30, 2014 at 12:49 PM, Prathamesh Kulkarni
>>>>>>> <bilbotheelffriend@gmail.com> wrote:
>>>>>>>> Hi,
>>>>>>>> Sorry to ask a stupid question, but I am having issues writing patterns
>>>>>>>> involving casts. I am trying to write patterns from simplify_rotate.
>>>>>>>>
>>>>>>>> Could you show me how to write a patterns that involve
>>>>>>>> casts ?
>>>>>>>> for eg:
>>>>>>>> ((T) ((T2) X << CNT1)) + ((T) ((T2) X >> CNT2)) iff CNT1 + CNT2 == B
>>>>>>>> T -> some unsigned type with bitsize B, and some type T2 wider than T.
>>>>>>>> How to express this in the pattern ?
>>>>>>>
>>>>>>> [copying gcc@ because of the syntax stuff]
>>>>>>>
>>>>>>> for example with (leaving captures as the appear in the pattern above)
>>>>>>>
>>>>>>> (match_and_simplify
>>>>>>> (plus (convert@2 (lshift (convert@0 X) CNT1))
>>>>>>> (convert (rshift (convert@1 X) CNT2)))
>>>>>>> /* Types T2 have to match */
>>>>>>> (if (types_compatible_p (TREE_TYPE (@0), TREE_TYPE (@1))
>>>>>>> /* Type T should be unsigned. */
>>>>>>> && TYPE_UNSIGNED (TREE_TYPE (@2))
>>>>>>> /* T2 should be wider than T. */
>>>>>>> && TYPE_PRECISION (TREE_TYPE (@0)) > TYPE_PRECISION (TREE_TYPE (@2))
>>>>>>> /* CNT1 + CNT2 == B */
>>>>>>> && wi::eq_p (TYPE_PRECISION (TREE_TYPE (@2)),
>>>>>>> wi::add (CNT1, CNT2))))
>>>>>>> (lrotate CNT1))
>>>>>>
>>>>>> Note that this will _explicitely_ require a conversion. That is, if T == T2
>>>>>> it won't match because the conversion to T will not be there, nor if X
>>>>>> is already of type T2.
>>>>>>
>>>>>> Which means that we want to match multiple variants of this
>>>>>> (with conversions in place or not). Hmm. Maybe with extending 'for' like
>>>>>>
>>>>>> (for cvt1 in convert *
>>>>>> (fot cvt2 in convert *
>>>>>> (plus@2 (cvt1 (lshift@0 (cvt2 X) CNT1))
>>>>>> (cvt1 (rshift@1 (cvt2 X) CNT2)))
>>>>>> ...
>>>>>>
>>>>>> adding an "empty" operator to the list of operators to substitute for cvt1
>>>>>> and allowing nested for. The "empty" operator would necessarily be
>>>>>> unary and be just un-wrapped.
>>>>> Would it be better to have syntax (say using ?) for denoting that an
>>>>> operator is optional ?
>>>>> operator should be unary, and it's operand must be an expression.
>>>>>
>>>>> so the pattern becomes sth like:
>>>>> (plus@2 (convert? (lshift@0 (convert? X) CNT1))
>>>>> (convert? (rshift@1 (convert? X) CNT2)))
>>>>>
>>>> Let me rephrase it.
>>>> An operator can be marked optional, if
>>>> a) it's unary
>>>> b) if in outermost-expr, the operand must be an expression
>>>>
>>>> I want to reject case like:
>>>> (negate? @0)
>>>>
>>>> (op? operand)
>>>> generates code :
>>>> match (op)
>>>> match (operand)
>>>>
>>>> and once without op
>>>> match (operand)
>>>>
>>>> Implementation-wise I think, we could duplicate the AST, like we do
>>>> for "for pattern".
>>>> Would that be okay ?
>>>
>>> I thought of something similar but how exactly would you do the
>>> duplication in the above example? The point is that we know
>>> that the conversions will exist in pairs, that is, either
>>> the two outer and no inner or no outer and both inner or
>>> both outer and both inner. You can express that with the
>>> nested for - with just a '?' you can't do that. Of course you could
>>> do sth like
>>>
>>> (plus@2 (convert?1 (lshift@0 (convert?2 X) CNT1))
>>> (convert?1 (rshift@1 (convert?2 X) CNT2)))
>>>
>>> that is, add an index to ?s and tie them together. We want to
>>> avoid generating useless patterns - in this case 4 are sufficient
>>> but if we generate all possible combinations we'd have an additional
>>> 12 useless patterns.
>> Ah yes, didn't realize that, thanks.
>>>
>>> But using '?' indeed looks better than (ab)using 'for'. Note that
>>> it is _only_ 'convert' that I can see this useful for (or can you
>>> think of other cases?). So maybe we instead want to make
>>> it a special operator like
>>>
>>> (plus@2 (opt_convert 1 (lshift@0 (opt_convert 2 X) CNT1))
>>> (opt_convert 1 (rshift@1 (opt_convert 2 X) CONT2)))
>>>
>>> with an additional operand specifying the group (or simply
>>> have opt_convert1 and opt_convert2 operands - hoping for
>>> more "groups" to never happen ;)).
>>>
>>> Actually I like opt_convert[123] most.
>> I like opt_convert[123] too.
>> Implementation-wise I don't think it would be more difficult to
>> generalize it for other operators ...
>
> Of course, but I don't see the need for that. Conversions are really
> special in this regard.
>
>> I was thinking about this ... Instead of grouping by indexes,
>> how about defining operator aliases ?
>> sth like:
>> (define_op cvt1 convert)
>> (define_op cvt2 convert)
>>
>> and then the pattern becomes:
>>
>> (plus@2 (cvt1? (lshift@0 (cvt2? X) CNT1))
>> (cvt1? (rshift@1 (cvt2? X) CNT2)))
>>
>> that would avoid generating useless patterns (since cvt1, cvt2 are
>> "different"), however during code-gen
>> both shall map to CONVERT_EXPR (and once without it since its optional).
>
> Yeah, that would work if we'd implement it that way. Still I don't like
> a general '?' facility unless we come up with really good uses apart from
> conversions.
Agreed. I will start with implementing opt_convert.
Thanks,
Prathamesh.
>
> Richard.
>
>> Thanks,
>> Prathamesh
>>
>>>
>>> Richard.
>>>
>>>> Thanks,
>>>> Prathamesh
>>>>
>>>>
>>>>> Thanks,
>>>>> Prathamesh
>>>>>
>>>>>>
>>>>>> Extending for in this way avoids treating conversions specially
>>>>>> (I don't see an easy way to do very good at that automagically). We
>>>>>> need multiple patterns in the decision tree here anyway.
>>>>>>
>>>>>> Now guess sth fancy in place of '*' ...
>>>>>>
>>>>>> Lisp style would be less free-form like
>>>>>>
>>>>>> (for cvt (convert ())
>>>>>>
>>>>>> where we could use an empty list for the "empty" operator.
>>>>>>
>>>>>> Is nested for support already implemented?
>>>>>>
>>>>>> Thanks,
>>>>>> Richard.
>>>>>>
>>>>>>> which suggests that we may want to add some type capturing / matching
>>>>>>> so we can maybe write
>>>>>>>
>>>>>>> (plus (convert@T (lshift (convert@T2 X) CNT1))
>>>>>>> (convert (rshift (convert@T2 X) CNT2)))
>>>>>>> (if (/* T2s will be matched automagically */
>>>>>>> && TYPE_UNSIGNED (@T)
>>>>>>> && TYPE_PRECISION (@T2) > TYPE_PRECISION (@T)
>>>>>>> && wi::eq_p (TYPE_PRECISION (@T), wi::add (CNT1, CNT2))))
>>>>>>>
>>>>>>> which is less to type and supports requiring matching types. Maybe
>>>>>>> require @T[0-9]+ here thus use @T0 and disallow plain @T. We could
>>>>>>> then also use @T for the implicitely "captured" outermost type we
>>>>>>> refer to as plain 'type' right now.
>>>>>>>
>>>>>>> I suggest to go ahead without a new syntax for now and see if it
>>>>>>> gets unwieldingly ugly without first.
>>>>>>>
>>>>>>>> For this week, I have planned:
>>>>>>>> a) writing patterns from simplify_rotate
>>>>>>>> b) replacing op in c_expr
>>>>>>>> c) writing more test-cases.
>>>>>>>>
>>>>>>>> If there's anything else you would like me to do, I would be happy
>>>>>>>> to know.
>>>>>>>
>>>>>>> Just keep an eye open for things like above - easy ways to reduce
>>>>>>> typing for patterns.
>>>>>>>
>>>>>>> Btw, I suggest to split up match.pd by code you converted from. Thus
>>>>>>> for simplify_rotate add
>>>>>>>
>>>>>>> match-simplify-rotate.pd
>>>>>>>
>>>>>>> with the patterns and do a #include "match-simplify-rotate.pd"
>>>>>>> in match.pd. That will make it easier to match the two later.
>>>>>>>
>>>>>>> Thanks,
>>>>>>> Richard.
>>>>>>>
>>>>>>>
>>>>>>>> Thanks,
>>>>>>>> Prathamesh