This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [match-and-simplify] express conversions in transform ?


On Tue, Aug 19, 2014 at 4:35 PM, Richard Biener
<richard.guenther@gmail.com> wrote:
> On Tue, Aug 19, 2014 at 12:18 PM, Prathamesh Kulkarni
> <bilbotheelffriend@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) ?

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
Index: genmatch.c
===================================================================
--- genmatch.c	(revision 214258)
+++ genmatch.c	(working copy)
@@ -859,6 +859,18 @@ check_no_user_id (simplify *s)
 
 /* Code gen off the AST.  */
 
+bool
+conversion_op_p (e_operation *oper)
+{
+  if (strcmp (oper->op->id, "CONVERT_EXPR") != 0
+      && strcmp (oper->op->id, "FIX_TRUNC_EXPR") != 0
+      && strcmp (oper->op->id, "FLOAT_EXPR") != 0)
+    return false;
+
+  // ??? how to assert convert should use 'type' 
+  return false;
+}
+
 void
 expr::gen_transform (FILE *f, const char *dest, bool gimple, int depth)
 {
@@ -875,9 +887,13 @@ expr::gen_transform (FILE *f, const char
       /* ???  Have another helper that is like gimple_build but may
 	 fail if seq == NULL.  */
       fprintf (f, "  if (!seq)\n"
-	       "    {\n"
-	       "      res = gimple_simplify (%s, TREE_TYPE (ops%d[0])",
+	       "    {\n");
+      if (!conversion_op_p (operation))
+	fprintf (f, "      res = gimple_simplify (%s, TREE_TYPE (ops%d[0])",
 	       operation->op->id, depth);
+      else
+	fprintf (f, "      res = gimple_simplify (%s, type", operation->op->id);
+
       for (unsigned i = 0; i < ops.length (); ++i)
 	fprintf (f, ", ops%d[%u]", depth, i);
       fprintf (f, ", seq, valueize);\n");

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]