>> 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.