diff options
Diffstat (limited to 'gcc/tree-ssa-forwprop.c')
-rw-r--r-- | gcc/tree-ssa-forwprop.c | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c index e8a92ed6c16..a12c8e0c6ff 100644 --- a/gcc/tree-ssa-forwprop.c +++ b/gcc/tree-ssa-forwprop.c @@ -2996,6 +2996,69 @@ combine_conversions (gimple_stmt_iterator *gsi) 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. */ @@ -3493,6 +3556,8 @@ ssa_forward_propagate_and_combine (void) 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); |