This hooks the machinery into the GENERIC folders in fold-const.c. For re-simplification and tree building generic_simplify uses the fold_buildN API which remains the API to use - this is also why I don't expose generic_simplify in any header.
To give you an example how it looks like, the following code is generated for /* fold_negate_exprs convert - (~A) to A + 1. */ (simplify (negate (bit_not @0)) (if (INTEGRAL_TYPE_P (type)) (plus @0 { build_int_cst (TREE_TYPE (@0), 1); } ))) tree generic_simplify (enum tree_code code, tree type ATTRIBUTE_UNUSED, tree op0) { if ((op0 && TREE_SIDE_EFFECTS (op0))) return NULL_TREE; switch (code) { ... case NEGATE_EXPR: { switch (TREE_CODE (op0)) { case BIT_NOT_EXPR: { tree o20 = TREE_OPERAND (op0, 0); { /* #line 136 "/space/rguenther/src/svn/match-and-simplify/gcc/match.pd" */ tree captures[2] ATTRIBUTE_UNUSED = {}; captures[0] = o20; /* #line 135 "/space/rguenther/src/svn/match-and-simplify/gcc/match.pd" */ if (INTEGRAL_TYPE_P (type)) { if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "Applying pattern match.pd:136, %s:%d\n", __FILE__, __LINE__); tree res_op0; res_op0 = captures[0]; tree res_op1; res_op1 = build_int_cst (TREE_TYPE (captures[0]), 1); return fold_build2 (PLUS_EXPR, type, res_op0, res_op1); } } break; } ... where you can see the side-effects issue I mentioned earlier. Ok for trunk? Thanks, Richard. 2014-10-15 Richard Biener <rguent...@suse.de> * fold-const.c (fold_unary_loc): Dispatch to generic_simplify. (fold_binary_loc): Likewise. (fold_ternary_loc): Likewise. Index: gcc/fold-const.c =================================================================== --- gcc/fold-const.c (svn+ssh://rgue...@gcc.gnu.org/svn/gcc/trunk/gcc/fold-const.c) (revision 216234) +++ gcc/fold-const.c (.../gcc/fold-const.c) (working copy) @@ -7564,6 +7563,11 @@ fold_unary_loc (location_t loc, enum tre gcc_assert (IS_EXPR_CODE_CLASS (kind) && TREE_CODE_LENGTH (code) == 1); + extern tree generic_simplify (enum tree_code, tree, tree); + tem = generic_simplify (code, type, op0); + if (tem) + return tem; + arg0 = op0; if (arg0) { @@ -9909,6 +9913,11 @@ fold_binary_loc (location_t loc, } } + extern tree generic_simplify (enum tree_code, tree, tree, tree); + tem = generic_simplify (code, type, op0, op1); + if (tem) + return tem; + /* If this is a commutative operation, and ARG0 is a constant, move it to ARG1 to reduce the number of tests below. */ if (commutative_tree_code (code) @@ -13799,6 +13808,11 @@ fold_ternary_loc (location_t loc, enum t gcc_assert (IS_EXPR_CODE_CLASS (kind) && TREE_CODE_LENGTH (code) == 3); + extern tree generic_simplify (enum tree_code, tree, tree, tree, tree); + tem = generic_simplify (code, type, op0, op1, op2); + if (tem) + return tem; + /* Strip any conversions that don't change the mode. This is safe for every expression, except for a comparison expression because its signedness is derived from its operands. So, in the latter