>> So I came along the need to add another predicate for REAL_CST
>> leafs which makes me wonder if we should support tree codes
>> as predicates.  Thus instead of writing
>>
>> (match_and_simplify
>>   (plus (plus @0 INTEGER_CST_P@1) INTEGER_CST_P@2)
>>   (plus @0 (plus @1 @2)))
>>
>> write
>>
>> (match_and_simplify
>>   (plus (plus @0 INTEGER_CST@1) INTEGER_CST@2)
>>   (plus @0 (plus @1 @2)))
>>
>> we have conveniently choosen lower-case without _EXPR for
>> expression codes thus the uppercase original form is available
>> to be used as pre-defined predicate (code generated is
>> TREE_CODE (x) == <predicate-name>).
>>
>> Just an idea ...
> It appears to be good. However would we want predicates that are
> slightly more complex ?
> For example, integer_onep @0 ?

In principle predicates are not different from expressions:

 (plus @0 INTEGER_CST)

is similar to

 (plus @0 (INTEGER_CST))

that is, if INTEGER_CST is treated as zero-operand "expression".

> I was wondering if it would be a good idea to make predicate an
> attribute of operand (expr, capture)
> rather than keep predicate as a separate operand ? (since predicates
> are only used for checking the operand they are
> applied to).
>
> The hierarchy be something like:
>
> struct predicate_operand: public operand
> {
>   predicate_operand (const char *ident_, enum operand::type ty) :
> operand (ty), ident (ident_) {}
>   const char *ident;
>   virtual void gen_gimple_match (FILE *f, const char *, const char *);
>   virtual void gen_gimple_transform (FILE *, const char *) = 0;
> };
>
> struct capture : public predicate_operand
> {
>   capture (const char *where_, operand *what_, const char *pred = 0)
>       : predicate_operand (pred, OP_CAPTURE), where (where_), what (what_) {}
>   const char *where;
>   operand *what;
>   virtual void gen_gimple_match (FILE *f, const char *, const char *);
>   virtual void gen_gimple_transform (FILE *f, const char *);
> };
> And make capture::gen_gimple_match call
> predicate_operand::gen_gimple_match if ident is non-null.
> similarly for expr.

I don't understand.  predicate is already derived from operand, so is
capture.  How would you write

(plus @0 integer_zerop)

differently?  Here 'integer_zerop' is an operand of the plus expression.

To me predicate (and capture without expression or predicate)
differs from expression in that predicate is clearly a leaf of the
expression tree while we have to recurse into expression operands.

Now, if we want to support applying predicates to the midst of an
expression, like

(plus predicate(minus @0 @1)
        @2)
(...)

then this would no longer be true.  At the moment you'd write

(plus (minus@3 @0 @1)
        @2)
  if (predicate (@3))
(...)

which makes it clearer IMHO (with the decision tree building
you'd apply the predicates after matching the expression tree
anyway I suppose, so code generation would be equivalent).

One exception may be types of (sub-)expressions which we
can also check cheaply (and eventually build into the decision
tree) (cheaply == doesn't involve function calls).

So for the if-expressions like

(match_and_simplify
  (plus @0 (negate @1))
  if (!TYPE_SATURATING (TREE_TYPE (@0)))
  (minus @0 @1))

we'd ideally want to group all patterns with the same
type-related if-expression to improve the matching
process.  That eventually asks for sth like

if (!TYPE_SATURATING (TREE_TYPE (@0)))
  {
  (match_and_simplify
       (plus @0 (negate @1))
  (minus @0 @1))

  (match_and_simplify
       (plus (negate @0) @1)
  (minus @1 @0)
  }

thus have multiple patterns with a common "outer" if-expression.
If you look into fold-const.c we have this kind of grouping used
there to group for example cases valid only for !FLOAT_TYPE_P
or INTEGRAL_TYPE_P.

IMHO we can think about this when the individual if-expressions
become too many.  I don't like the idea of applying predicates
to non-leafs in the match expression itself.

Richard.

Reply via email to