diff options
author | Richard Guenther <rguenther@suse.de> | 2016-05-20 09:17:16 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2016-05-20 09:17:16 +0000 |
commit | 483c642948802336899b14fa57b2e76c760c3c36 (patch) | |
tree | e061dbe5dac8633c8babd3bf14639f9e128c156e /gcc/tree-ssa.c | |
parent | eb066284cb8cdf7f46f455c3e975cf1b349a0487 (diff) | |
download | gcc-483c642948802336899b14fa57b2e76c760c3c36.zip gcc-483c642948802336899b14fa57b2e76c760c3c36.tar.gz gcc-483c642948802336899b14fa57b2e76c760c3c36.tar.bz2 |
re PR target/29756 (SSE intrinsics hard to use without redundant temporaries appearing)
2016-05-20 Richard Guenther <rguenther@suse.de>
PR tree-optimization/29756
* tree.def (BIT_INSERT_EXPR): New tcc_expression tree code.
* expr.c (expand_expr_real_2): Handle BIT_INSERT_EXPR.
* fold-const.c (operand_equal_p): Likewise.
(fold_ternary_loc): Add constant folding of BIT_INSERT_EXPR.
* gimplify.c (gimplify_expr): Handle BIT_INSERT_EXPR.
* tree-inline.c (estimate_operator_cost): Likewise.
* tree-pretty-print.c (dump_generic_node): Likewise.
* tree-ssa-operands.c (get_expr_operands): Likewise.
* cfgexpand.c (expand_debug_expr): Likewise.
* gimple-pretty-print.c (dump_ternary_rhs): Likewise.
* gimple.c (get_gimple_rhs_num_ops): Handle BIT_INSERT_EXPR.
* tree-cfg.c (verify_gimple_assign_ternary): Verify BIT_INSERT_EXPR.
* tree-ssa.c (non_rewritable_lvalue_p): We can rewrite
vector inserts using BIT_FIELD_REF or MEM_REF on the lhs.
(execute_update_addresses_taken): Do it.
* gcc.dg/tree-ssa/vector-6.c: New testcase.
From-SVN: r236501
Diffstat (limited to 'gcc/tree-ssa.c')
-rw-r--r-- | gcc/tree-ssa.c | 95 |
1 files changed, 89 insertions, 6 deletions
diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c index 0a59dd20..cf6e764 100644 --- a/gcc/tree-ssa.c +++ b/gcc/tree-ssa.c @@ -1275,21 +1275,48 @@ non_rewritable_lvalue_p (tree lhs) && DECL_P (TREE_OPERAND (lhs, 0))) return false; - /* A decl that is wrapped inside a MEM-REF that covers - it full is also rewritable. - ??? The following could be relaxed allowing component + /* ??? The following could be relaxed allowing component references that do not change the access size. */ if (TREE_CODE (lhs) == MEM_REF - && TREE_CODE (TREE_OPERAND (lhs, 0)) == ADDR_EXPR - && integer_zerop (TREE_OPERAND (lhs, 1))) + && TREE_CODE (TREE_OPERAND (lhs, 0)) == ADDR_EXPR) { tree decl = TREE_OPERAND (TREE_OPERAND (lhs, 0), 0); - if (DECL_P (decl) + + /* A decl that is wrapped inside a MEM-REF that covers + it full is also rewritable. */ + if (integer_zerop (TREE_OPERAND (lhs, 1)) + && DECL_P (decl) && DECL_SIZE (decl) == TYPE_SIZE (TREE_TYPE (lhs)) && (TREE_THIS_VOLATILE (decl) == TREE_THIS_VOLATILE (lhs))) return false; + + /* A vector-insert using a MEM_REF or ARRAY_REF is rewritable + using a BIT_INSERT_EXPR. */ + if (DECL_P (decl) + && VECTOR_TYPE_P (TREE_TYPE (decl)) + && TYPE_MODE (TREE_TYPE (decl)) != BLKmode + && types_compatible_p (TREE_TYPE (lhs), + TREE_TYPE (TREE_TYPE (decl))) + && tree_fits_uhwi_p (TREE_OPERAND (lhs, 1)) + && tree_int_cst_lt (TREE_OPERAND (lhs, 1), + TYPE_SIZE_UNIT (TREE_TYPE (decl))) + && (tree_to_uhwi (TREE_OPERAND (lhs, 1)) + % tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (lhs)))) == 0) + return false; } + /* A vector-insert using a BIT_FIELD_REF is rewritable using + BIT_INSERT_EXPR. */ + if (TREE_CODE (lhs) == BIT_FIELD_REF + && DECL_P (TREE_OPERAND (lhs, 0)) + && VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (lhs, 0))) + && TYPE_MODE (TREE_TYPE (TREE_OPERAND (lhs, 0))) != BLKmode + && types_compatible_p (TREE_TYPE (lhs), + TREE_TYPE (TREE_TYPE (TREE_OPERAND (lhs, 0)))) + && (tree_to_uhwi (TREE_OPERAND (lhs, 2)) + % tree_to_uhwi (TYPE_SIZE (TREE_TYPE (lhs)))) == 0) + return false; + return true; } @@ -1511,6 +1538,62 @@ execute_update_addresses_taken (void) continue; } + /* Rewrite a vector insert via a BIT_FIELD_REF on the LHS + into a BIT_INSERT_EXPR. */ + if (TREE_CODE (lhs) == BIT_FIELD_REF + && DECL_P (TREE_OPERAND (lhs, 0)) + && bitmap_bit_p (suitable_for_renaming, + DECL_UID (TREE_OPERAND (lhs, 0))) + && VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (lhs, 0))) + && TYPE_MODE (TREE_TYPE (TREE_OPERAND (lhs, 0))) != BLKmode + && types_compatible_p (TREE_TYPE (lhs), + TREE_TYPE (TREE_TYPE + (TREE_OPERAND (lhs, 0)))) + && (tree_to_uhwi (TREE_OPERAND (lhs, 2)) + % tree_to_uhwi (TYPE_SIZE (TREE_TYPE (lhs))) == 0)) + { + tree var = TREE_OPERAND (lhs, 0); + tree val = gimple_assign_rhs1 (stmt); + tree bitpos = TREE_OPERAND (lhs, 2); + gimple_assign_set_lhs (stmt, var); + gimple_assign_set_rhs_with_ops + (&gsi, BIT_INSERT_EXPR, var, val, bitpos); + stmt = gsi_stmt (gsi); + unlink_stmt_vdef (stmt); + update_stmt (stmt); + continue; + } + + /* Rewrite a vector insert using a MEM_REF on the LHS + into a BIT_INSERT_EXPR. */ + if (TREE_CODE (lhs) == MEM_REF + && TREE_CODE (TREE_OPERAND (lhs, 0)) == ADDR_EXPR + && (sym = TREE_OPERAND (TREE_OPERAND (lhs, 0), 0)) + && DECL_P (sym) + && bitmap_bit_p (suitable_for_renaming, DECL_UID (sym)) + && VECTOR_TYPE_P (TREE_TYPE (sym)) + && TYPE_MODE (TREE_TYPE (sym)) != BLKmode + && types_compatible_p (TREE_TYPE (lhs), + TREE_TYPE (TREE_TYPE (sym))) + && tree_fits_uhwi_p (TREE_OPERAND (lhs, 1)) + && tree_int_cst_lt (TREE_OPERAND (lhs, 1), + TYPE_SIZE_UNIT (TREE_TYPE (sym))) + && (tree_to_uhwi (TREE_OPERAND (lhs, 1)) + % tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (lhs)))) == 0) + { + tree val = gimple_assign_rhs1 (stmt); + tree bitpos + = wide_int_to_tree (bitsizetype, + mem_ref_offset (lhs) * BITS_PER_UNIT); + gimple_assign_set_lhs (stmt, sym); + gimple_assign_set_rhs_with_ops + (&gsi, BIT_INSERT_EXPR, sym, val, bitpos); + stmt = gsi_stmt (gsi); + unlink_stmt_vdef (stmt); + update_stmt (stmt); + continue; + } + /* We shouldn't have any fancy wrapping of component-refs on the LHS, but look through VIEW_CONVERT_EXPRs as that is easy. */ |