The following series will remove GENERIC stmt combining from SCCVN and make it rely on match-and-simplify instead. Thus the start of the series moves patterns from fold-const.c to match.pd (in theory all patterns with an expression depth of one or two apply).
I'm generating this series from cases that show up with the following patch (where I of course need to decide on a proper way of hookizing into maybe_push_res_to_seq ...). The final patch removing GENERIC stmt combining from SCCVN will just retain gimple_fold_stmt_to_constant_1 in try_to_simplfy. Richard. Index: gcc/gimple-match.h =================================================================== --- gcc/gimple-match.h (revision 224893) +++ gcc/gimple-match.h (working copy) @@ -40,6 +40,8 @@ private: int rep; }; +extern tree (*mprts_hook) (code_helper, tree, tree *); + bool gimple_simplify (gimple, code_helper *, tree *, gimple_seq *, tree (*)(tree), tree (*)(tree)); tree maybe_push_res_to_seq (code_helper, tree, tree *, Index: gcc/gimple-match-head.c =================================================================== --- gcc/gimple-match-head.c (revision 224893) +++ gcc/gimple-match-head.c (working copy) @@ -302,6 +302,8 @@ maybe_build_generic_op (enum tree_code c } } +tree (*mprts_hook) (code_helper, tree, tree *); + /* Push the exploded expression described by RCODE, TYPE and OPS as a statement to SEQ if necessary and return a gimple value denoting the value of the expression. If RES is not NULL @@ -319,6 +321,12 @@ maybe_push_res_to_seq (code_helper rcode || ((tree_code) rcode) == ADDR_EXPR) && is_gimple_val (ops[0])) return ops[0]; + if (mprts_hook) + { + tree tem = mprts_hook (rcode, type, ops); + if (tem) + return tem; + } if (!seq) return NULL_TREE; /* Play safe and do not allow abnormals to be mentioned in Index: gcc/tree-ssa-sccvn.c =================================================================== --- gcc/tree-ssa-sccvn.c (revision 224893) +++ gcc/tree-ssa-sccvn.c (working copy) @@ -72,6 +72,7 @@ along with GCC; see the file COPYING3. #include "ipa-ref.h" #include "plugin-api.h" #include "cgraph.h" +#include "gimple-match.h" /* This algorithm is based on the SCC algorithm presented by Keith Cooper and L. Taylor Simpson in "SCC-Based Value numbering" @@ -3492,6 +3498,16 @@ simplify_unary_expression (gassign *stmt return NULL_TREE; } +static tree +vn_lookup_simplify_result (code_helper rcode, tree type, tree *ops) +{ + if (!rcode.is_tree_code ()) + return NULL_TREE; + vn_nary_op_t vnresult = NULL; + return vn_nary_op_lookup_pieces (TREE_CODE_LENGTH ((tree_code) rcode), + (tree_code) rcode, type, ops, &vnresult); +} + /* Try to simplify RHS using equivalences and constant folding. */ static tree @@ -3506,13 +3522,16 @@ try_to_simplify (gassign *stmt) return NULL_TREE; /* First try constant folding based on our current lattice. */ + mprts_hook = vn_lookup_simplify_result; tem = gimple_fold_stmt_to_constant_1 (stmt, vn_valueize, vn_valueize); + mprts_hook = NULL; if (tem && (TREE_CODE (tem) == SSA_NAME || is_gimple_min_invariant (tem))) return tem; /* If that didn't work try combining multiple statements. */ + tem = NULL_TREE; switch (TREE_CODE_CLASS (code)) { case tcc_reference: @@ -3525,17 +3544,22 @@ try_to_simplify (gassign *stmt) /* We could do a little more with unary ops, if they expand into binary ops, but it's debatable whether it is worth it. */ case tcc_unary: - return simplify_unary_expression (stmt); + tem = simplify_unary_expression (stmt); + break; case tcc_comparison: case tcc_binary: - return simplify_binary_expression (stmt); + tem = simplify_binary_expression (stmt); + break; default: break; } - return NULL_TREE; + gcc_assert (!tem + || (TREE_CODE (tem) != SSA_NAME + && !is_gimple_min_invariant (tem))); + return tem; } /* Visit and value number USE, return true if the value number @@ -3689,6 +3713,7 @@ visit_use (tree use) tree result = vn_nary_op_lookup (simplified, NULL); if (result) { + gcc_assert (result == vn_nary_op_lookup_stmt (stmt, NULL)); changed = set_ssa_val_to (lhs, result); goto done; }