This is the mail archive of the
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 11:11:49 +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>
On Wed, Jul 30, 2014 at 11:49 PM, Prathamesh Kulkarni
> On Wed, Jul 30, 2014 at 4:49 PM, Richard Biener
> <firstname.lastname@example.org> wrote:
>> On Wed, Jul 30, 2014 at 1:11 PM, Richard Biener
>> <email@example.com> wrote:
>>> On Wed, Jul 30, 2014 at 12:49 PM, Prathamesh Kulkarni
>>> <firstname.lastname@example.org> wrote:
>>>> 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)
>>> (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:
generates code :
and once without op
Implementation-wise I think, we could duplicate the AST, like we do
for "for pattern".
Would that be okay ?
>> 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?
>>> 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
>>> with the patterns and do a #include "match-simplify-rotate.pd"
>>> in match.pd. That will make it easier to match the two later.