On Thu, Jul 31, 2014 at 7:41 AM, Prathamesh Kulkarni
<bilbotheelffri...@gmail.com> wrote:
> On Wed, Jul 30, 2014 at 11:49 PM, Prathamesh Kulkarni
> <bilbotheelffri...@gmail.com> wrote:
>> On Wed, Jul 30, 2014 at 4:49 PM, Richard Biener
>> <richard.guent...@gmail.com> wrote:
>>> On Wed, Jul 30, 2014 at 1:11 PM, Richard Biener
>>> <richard.guent...@gmail.com> wrote:
>>>> On Wed, Jul 30, 2014 at 12:49 PM, Prathamesh Kulkarni
>>>> <bilbotheelffri...@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.

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.

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

Reply via email to