On Thu, Aug 21, 2014 at 11:57 AM, Richard Biener <richard.guent...@gmail.com> wrote: > On Thu, Aug 21, 2014 at 10:42 AM, Prathamesh Kulkarni > <bilbotheelffri...@gmail.com> wrote: >> On Tue, Aug 19, 2014 at 4:35 PM, Richard Biener >> <richard.guent...@gmail.com> wrote: >>> On Tue, Aug 19, 2014 at 12:18 PM, Prathamesh Kulkarni >>> <bilbotheelffri...@gmail.com> wrote: >>>> I was wondering how to write transform that involves conversions >>>> (without using c_expr) ? >>>> for eg: >>>> (T1)(~(T2) X) -> ~(T1) X >>>> // T1, T2 has same precision and X is an integral type not narrower than >>>> T1, T2 >>>> >>>> this could be written as: >>>> (simplify >>>> (convert (bit_not (convert@0 integral_op_p@1))) >>>> if-expr >>>> transform) >>>> >>>> How would the transform be written ? >>>> with c_expr we could probably write as: (is that correct?) >>>> (bit_not { fold_convert (type, @1); }) >>> >>> No, unfortunately while that's correct for GENERIC it doesn't work >>> for GIMPLE code-gen. c_exprs are required to evaluate to >>> "atomics", that is, non-expressions. >>> >>>> I was wondering whether we should have an explicit support for >>>> conversions (something equivalent of "casting") ? >>>> sth like: >>>> (bit_not (cast type @0)) >>> >>> Indeed simply writing >>> >>> (bit_not (convert @1)) >>> >>> will make the code-generator "convert" @0 to its own type >>> (I knew the hack to simply use the first operands type is not >>> going to work in all cases... ;). Other conversion operators >>> include FIX_TRUNC_EXPR (float -> int), FLOAT_EXPR >>> (int -> float). >>> >>> For most cases it works by accident as the outermost expression >>> knows its type via 'type'. >>> >>> In the cases where we need to specify a type I'd like to avoid >>> making the type-converting operators take an additional operand. >>> Instead can we make it use a operator flag-with-argument? Like >>> >>> (bit_not (convert:type @1)) >>> >>> or for the type of a capture (convert:t@2 @1). >>> >>> We can also put in some more intelligence in automatically >>> determining the type to convert to. In your example we >>> know the bit_not is of type 'type' and this has to match >>> the type of its operands thus the 'convert' needs to convert >>> to 'type' as well. I'm sure there are cases we can't >>> auto-compute though, like chains of conversions (but not sure >>> they matter in practice). >>> >>> So let's try that - Micha will like more intelligence in the generator ;) >>> >>> I suggest to add a predicate to the generator conversion_op_p >>> to catch the various converting operators and then assert that >>> during code-gen we are going to create it with 'type' (outermost >>> type), not TREE_TYPE (ops[0]). Then start from the cases >>> we want to support and special-case (which requires passing >>> down the type of the enclosing expression). >> Um sorry, I am not sure if I understood that correctly. >> How would conversion_op_p know when to use 'type' and not TREE_TYPE (ops[0]) >> ? >> conversion_op_p would be used somewhat similar to in the attached >> patch (illustrate only) ? > > Yeah, kind of. Attached is my try which handles > > (bit_not (convert (plus @0 (convert @1)))) > > fine (converting @1 to the type of @0) but obviously not > > (convert (convert @1)) > > which is impossible to auto-guess and not > > (bit_not (convert (plus (convert @0) @1))) > > though that can be made work by first generating code for @1 > and then for (convert @0) so it can access the type of @1 > to convert to its type. > > I'll give the patch proper testing and will install it.
And if we really need sth like (convert (convert @0)) then this can either use a c-expr or we can invent sth like (convert (match-type @1 (convert @0))) that is, add a "fake" binary operation to guess the type. Richard. > Thanks, > Richard. > >> Thanks, >> Prathamesh >>> >>> Thanks, >>> Richard. >>> >>>> in case we want to cast to a type of another capture >>>> we could use: >>>> (foo (cast (type @0) @1)) ? // cast @1 to @0's type >>>> here type would be an operator that extracts type of the capture. >>>> >>>> Another use of having type as an operator I guess would be for >>>> type-matching (not sure if it's useful). >>>> for instance: >>>> (foo (bar @0 @1) @(type @0)@1) >>>> that checks if @0, @1 have same types. >>>> >>>> I was wondering on the same lines if we could introduce new >>>> keyword "precision" analogous to type ? >>>> (precision @0) would be short-hand for >>>> TYPE_PRECISION (TREE_TYPE (@0)) >>>> >>>> So far I found couple patterns in fold_unary_loc with conversions >>>> in transform: >>>> (T1)(X p+ Y) into ((T1)X p+ Y) >>>> (T1)(~(T2) X) -> ~(T1) X >>>> (T1) (X * Y) -> (T1) X * (T1) Y >>>> >>>> Thanks, >>>> Prathamesh