On Thu, Jul 31, 2014 at 11:09 AM, Prathamesh Kulkarni <bilbotheelffri...@gmail.com> wrote: > On Thu, Jul 31, 2014 at 2:15 PM, Richard Biener > <richard.guent...@gmail.com> wrote: >> 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. > 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. 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