This merges a set of conversion patterns and removes the corresponding code from both fold-const.c and tree-ssa-forwprop.c.
fold-const.c | 36 ---------------------------- match.pd | 42 +++++++++++++++++++++++++++++++++ tree-ssa-forwprop.c | 65 ---------------------------------------------------- 3 files changed, 42 insertions(+), 101 deletions(-) (hopefully it will always look that nice!) Bootstrapped and tested on x86_64-unknown-linux-gnu, I'll apply shortly. Thanks, Richard. 2014-10-29 Richard Biener <rguent...@suse.de> * match.pd: Implement a first set of conversion patterns. * fold-const.c (fold_unary_loc): Remove them here. * tree-ssa-forwprop.c (simplify_vce): Remove. (pass_forwprop::execute): Do not call simplify_vce. Index: gcc/match.pd =================================================================== --- gcc/match.pd (revision 216798) +++ gcc/match.pd (working copy) @@ -90,6 +90,48 @@ (define_predicates +/* Simplifications of conversions. */ + +/* Basic strip-useless-type-conversions / strip_nops. */ +(for cvt (convert view_convert) + (simplify + (cvt @0) + (if ((GIMPLE && useless_type_conversion_p (type, TREE_TYPE (@0))) + || (GENERIC && type == TREE_TYPE (@0))) + @0))) + +/* Contract view-conversions. */ +(simplify + (view_convert (view_convert @0)) + (view_convert @0)) + +/* For integral conversions with the same precision or pointer + conversions use a NOP_EXPR instead. */ +(simplify + (view_convert @0) + (if ((INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type)) + && (INTEGRAL_TYPE_P (TREE_TYPE (@0)) || POINTER_TYPE_P (TREE_TYPE (@0))) + && TYPE_PRECISION (type) == TYPE_PRECISION (TREE_TYPE (@0))) + (convert @0))) + +/* Strip inner integral conversions that do not change precision or size. */ +(simplify + (view_convert (convert@0 @1)) + (if ((INTEGRAL_TYPE_P (TREE_TYPE (@0)) || POINTER_TYPE_P (TREE_TYPE (@0))) + && (INTEGRAL_TYPE_P (TREE_TYPE (@1)) || POINTER_TYPE_P (TREE_TYPE (@1))) + && (TYPE_PRECISION (TREE_TYPE (@0)) == TYPE_PRECISION (TREE_TYPE (@1))) + && (TYPE_SIZE (TREE_TYPE (@0)) == TYPE_SIZE (TREE_TYPE (@1)))) + (view_convert @1))) + +/* Re-association barriers around constants and other re-association + barriers can be removed. */ +(simplify + (paren CONSTANT_CLASS_P@0) + @0) +(simplify + (paren (paren@1 @0)) + @1) + /* Simple example for a user-defined predicate - modeled after Index: gcc/fold-const.c =================================================================== --- gcc/fold-const.c (revision 216801) +++ gcc/fold-const.c (working copy) @@ -7661,14 +7661,6 @@ fold_unary_loc (location_t loc, enum tre switch (code) { - case PAREN_EXPR: - /* Re-association barriers around constants and other re-association - barriers can be removed. */ - if (CONSTANT_CLASS_P (op0) - || TREE_CODE (op0) == PAREN_EXPR) - return fold_convert_loc (loc, type, op0); - return NULL_TREE; - case NON_LVALUE_EXPR: if (!maybe_lvalue_p (op0)) return fold_convert_loc (loc, type, op0); @@ -7677,9 +7669,6 @@ fold_unary_loc (location_t loc, enum tre CASE_CONVERT: case FLOAT_EXPR: case FIX_TRUNC_EXPR: - if (TREE_TYPE (op0) == type) - return op0; - if (COMPARISON_CLASS_P (op0)) { /* If we have (type) (a CMP b) and type is an integral type, return @@ -7950,35 +7939,10 @@ fold_unary_loc (location_t loc, enum tre return tem ? tem : NULL_TREE; case VIEW_CONVERT_EXPR: - if (TREE_TYPE (op0) == type) - return op0; - if (TREE_CODE (op0) == VIEW_CONVERT_EXPR) - return fold_build1_loc (loc, VIEW_CONVERT_EXPR, - type, TREE_OPERAND (op0, 0)); if (TREE_CODE (op0) == MEM_REF) return fold_build2_loc (loc, MEM_REF, type, TREE_OPERAND (op0, 0), TREE_OPERAND (op0, 1)); - /* For integral conversions with the same precision or pointer - conversions use a NOP_EXPR instead. */ - if ((INTEGRAL_TYPE_P (type) - || POINTER_TYPE_P (type)) - && (INTEGRAL_TYPE_P (TREE_TYPE (op0)) - || POINTER_TYPE_P (TREE_TYPE (op0))) - && TYPE_PRECISION (type) == TYPE_PRECISION (TREE_TYPE (op0))) - return fold_convert_loc (loc, type, op0); - - /* Strip inner integral conversions that do not change the precision. */ - if (CONVERT_EXPR_P (op0) - && (INTEGRAL_TYPE_P (TREE_TYPE (op0)) - || POINTER_TYPE_P (TREE_TYPE (op0))) - && (INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (op0, 0))) - || POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (op0, 0)))) - && (TYPE_PRECISION (TREE_TYPE (op0)) - == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op0, 0))))) - return fold_build1_loc (loc, VIEW_CONVERT_EXPR, - type, TREE_OPERAND (op0, 0)); - return fold_view_convert_expr (type, op0); case NEGATE_EXPR: Index: gcc/tree-ssa-forwprop.c =================================================================== --- gcc/tree-ssa-forwprop.c (revision 216798) +++ gcc/tree-ssa-forwprop.c (working copy) @@ -3174,69 +3174,6 @@ combine_conversions (gimple_stmt_iterato return 0; } -/* Combine VIEW_CONVERT_EXPRs with their defining statement. */ - -static bool -simplify_vce (gimple_stmt_iterator *gsi) -{ - gimple stmt = gsi_stmt (*gsi); - tree type = TREE_TYPE (gimple_assign_lhs (stmt)); - - /* Drop useless VIEW_CONVERT_EXPRs. */ - tree op = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0); - if (useless_type_conversion_p (type, TREE_TYPE (op))) - { - gimple_assign_set_rhs1 (stmt, op); - update_stmt (stmt); - return true; - } - - if (TREE_CODE (op) != SSA_NAME) - return false; - - gimple def_stmt = SSA_NAME_DEF_STMT (op); - if (!is_gimple_assign (def_stmt)) - return false; - - tree def_op = gimple_assign_rhs1 (def_stmt); - switch (gimple_assign_rhs_code (def_stmt)) - { - CASE_CONVERT: - /* Strip integral conversions that do not change the precision. */ - if ((INTEGRAL_TYPE_P (TREE_TYPE (op)) - || POINTER_TYPE_P (TREE_TYPE (op))) - && (INTEGRAL_TYPE_P (TREE_TYPE (def_op)) - || POINTER_TYPE_P (TREE_TYPE (def_op))) - && (TYPE_PRECISION (TREE_TYPE (op)) - == TYPE_PRECISION (TREE_TYPE (def_op)))) - { - TREE_OPERAND (gimple_assign_rhs1 (stmt), 0) = def_op; - update_stmt (stmt); - return true; - } - break; - - case VIEW_CONVERT_EXPR: - /* Series of VIEW_CONVERT_EXPRs on register operands can - be contracted. */ - if (TREE_CODE (TREE_OPERAND (def_op, 0)) == SSA_NAME) - { - if (useless_type_conversion_p (type, - TREE_TYPE (TREE_OPERAND (def_op, 0)))) - gimple_assign_set_rhs1 (stmt, TREE_OPERAND (def_op, 0)); - else - TREE_OPERAND (gimple_assign_rhs1 (stmt), 0) - = TREE_OPERAND (def_op, 0); - update_stmt (stmt); - return true; - } - - default:; - } - - return false; -} - /* Combine an element access with a shuffle. Returns true if there were any changes made, else it returns false. */ @@ -3912,8 +3849,6 @@ pass_forwprop::execute (function *fun) changed = did_something != 0; } - else if (code == VIEW_CONVERT_EXPR) - changed = simplify_vce (&gsi); else if (code == VEC_PERM_EXPR) { int did_something = simplify_permutation (&gsi);