This is the mail archive of the
mailing list for the GCC project.
Re: writing patterns
- From: Richard Biener <richard dot guenther at gmail dot com>
- To: Prathamesh Kulkarni <bilbotheelffriend at gmail dot com>, GCC Development <gcc at gcc dot gnu dot org>
- Date: Wed, 30 Jul 2014 13:19:49 +0200
- 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>
On Wed, Jul 30, 2014 at 1:11 PM, Richard Biener
> 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.
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.