On Tue, 16 Sep 2014, Richard Biener wrote:
The following adds the ability to write predicates using patterns
with an example following negate_expr_p which already has a
use in comparison folding (via its if c-expr).
The syntax is as follows:
(match negate_expr_p
INTEGER_CST
(if (TYPE_OVERFLOW_WRAPS (type)
|| may_negate_without_overflow_p (t))))
(match negate_expr_p
(bit_not @0)
(if (INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_WRAPS (type))))
(match negate_expr_p
FIXED_CST)
(match negate_expr_p
(negate @0))
...
that is, you write '(match <id>' instead of '(simplify' and then
follow with a pattern and optional conditionals. There should
be no transform pattern (unchecked yet). Multiple matches for
the same <id> simply add to what is recognized as <id>.
The predicate is applied to a single 'tree' operand and looks
up SSA defs and utilizes the optional valueize hook.
Currently both GENERIC and GIMPLE variants result in name-mangling
and the proptotypes (unprototyped anywhere)
bool tree_negate_expr_p (tree t);
bool gimple_negate_expr_p (tree t, tree (*valueize)(tree) = NULL);
Ah, I haven't looked at the generated code, but I was expecting something
roughly like:
struct matcher
{
std::function<tree(tree)> valueize;
bool negate_expr(tree);
...
};
where we can call negate_expr recursively without caring about passing
valueize (if there are 2 matchers, one without a valueize function,
negate_expr can be static in that version). Although recursive calls sound
potentially slow, and having a thread_local counter in valueize to limit
the call depth may not be ideal.
Please note that I am not at all saying the above is a good design, just
dropping a random thought.
--
Marc Glisse