diff options
author | Martin Liska <mliska@suse.cz> | 2020-03-09 13:23:03 +0100 |
---|---|---|
committer | Martin Liska <mliska@suse.cz> | 2020-06-17 12:04:22 +0200 |
commit | 502d63b6d6141597bb18fd23c87736a1b384cf8f (patch) | |
tree | eba6680f649788bfbb44d1ec63183781460c997f /gcc/tree-ssa-reassoc.c | |
parent | 2021af0c23acaa827b5a8c5c5ba82b713f9cff1e (diff) | |
download | gcc-502d63b6d6141597bb18fd23c87736a1b384cf8f.zip gcc-502d63b6d6141597bb18fd23c87736a1b384cf8f.tar.gz gcc-502d63b6d6141597bb18fd23c87736a1b384cf8f.tar.bz2 |
Lower VEC_COND_EXPR into internal functions.
gcc/ChangeLog:
* Makefile.in: Add new file.
* expr.c (expand_expr_real_2): Add gcc_unreachable as we should
not meet this condition.
(do_store_flag): Likewise.
* gimplify.c (gimplify_expr): Gimplify first argument of
VEC_COND_EXPR to be a SSA name.
* internal-fn.c (vec_cond_mask_direct): New.
(vec_cond_direct): Likewise.
(vec_condu_direct): Likewise.
(vec_condeq_direct): Likewise.
(expand_vect_cond_optab_fn): New.
(expand_vec_cond_optab_fn): Likewise.
(expand_vec_condu_optab_fn): Likewise.
(expand_vec_condeq_optab_fn): Likewise.
(expand_vect_cond_mask_optab_fn): Likewise.
(expand_vec_cond_mask_optab_fn): Likewise.
(direct_vec_cond_mask_optab_supported_p): Likewise.
(direct_vec_cond_optab_supported_p): Likewise.
(direct_vec_condu_optab_supported_p): Likewise.
(direct_vec_condeq_optab_supported_p): Likewise.
* internal-fn.def (VCOND): New OPTAB.
(VCONDU): Likewise.
(VCONDEQ): Likewise.
(VCOND_MASK): Likewise.
* optabs.c (get_rtx_code): Make it global.
(expand_vec_cond_mask_expr): Removed.
(expand_vec_cond_expr): Removed.
* optabs.h (expand_vec_cond_expr): Likewise.
(vector_compare_rtx): Make it global.
* passes.def: Add new pass_gimple_isel pass.
* tree-cfg.c (verify_gimple_assign_ternary): Add check
for VEC_COND_EXPR about first argument.
* tree-pass.h (make_pass_gimple_isel): New.
* tree-ssa-forwprop.c (pass_forwprop::execute): Prevent
propagation of the first argument of a VEC_COND_EXPR.
* tree-ssa-reassoc.c (ovce_extract_ops): Support SSA_NAME as
first argument of a VEC_COND_EXPR.
(optimize_vec_cond_expr): Likewise.
* tree-vect-generic.c (expand_vector_divmod): Make SSA_NAME
for a first argument of created VEC_COND_EXPR.
(expand_vector_condition): Fix coding style.
* tree-vect-stmts.c (vectorizable_condition): Gimplify
first argument.
* gimple-isel.cc: New file.
gcc/testsuite/ChangeLog:
* g++.dg/vect/vec-cond-expr-eh.C: New test.
Diffstat (limited to 'gcc/tree-ssa-reassoc.c')
-rw-r--r-- | gcc/tree-ssa-reassoc.c | 64 |
1 files changed, 38 insertions, 26 deletions
diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c index af8faf2..2cc50f4 100644 --- a/gcc/tree-ssa-reassoc.c +++ b/gcc/tree-ssa-reassoc.c @@ -3831,7 +3831,8 @@ optimize_range_tests (enum tree_code opcode, to type of comparison. */ static tree_code -ovce_extract_ops (tree var, gassign **rets, bool *reti, tree *type) +ovce_extract_ops (tree var, gassign **rets, bool *reti, tree *type, + tree *lhs, tree *rhs, gassign **vcond) { if (TREE_CODE (var) != SSA_NAME) return ERROR_MARK; @@ -3839,6 +3840,8 @@ ovce_extract_ops (tree var, gassign **rets, bool *reti, tree *type) gassign *stmt = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (var)); if (stmt == NULL) return ERROR_MARK; + if (*vcond) + *vcond = stmt; /* ??? If we start creating more COND_EXPR, we could perform this same optimization with them. For now, simplify. */ @@ -3847,9 +3850,20 @@ ovce_extract_ops (tree var, gassign **rets, bool *reti, tree *type) tree cond = gimple_assign_rhs1 (stmt); tree_code cmp = TREE_CODE (cond); - if (TREE_CODE_CLASS (cmp) != tcc_comparison) + if (cmp != SSA_NAME) return ERROR_MARK; + gassign *assign = dyn_cast<gassign *> (SSA_NAME_DEF_STMT (cond)); + if (stmt == NULL + || TREE_CODE_CLASS (gimple_assign_rhs_code (assign)) != tcc_comparison) + return ERROR_MARK; + + cmp = gimple_assign_rhs_code (assign); + if (lhs) + *lhs = gimple_assign_rhs1 (assign); + if (rhs) + *rhs = gimple_assign_rhs2 (assign); + /* ??? For now, allow only canonical true and false result vectors. We could expand this to other constants should the need arise, but at the moment we don't create them. */ @@ -3870,7 +3884,7 @@ ovce_extract_ops (tree var, gassign **rets, bool *reti, tree *type) /* Success! */ if (rets) - *rets = stmt; + *rets = assign; if (reti) *reti = inv; if (type) @@ -3894,10 +3908,11 @@ optimize_vec_cond_expr (tree_code opcode, vec<operand_entry *> *ops) { tree elt0 = (*ops)[i]->op; - gassign *stmt0; + gassign *stmt0, *vcond0; bool invert; - tree type; - tree_code cmp0 = ovce_extract_ops (elt0, &stmt0, &invert, &type); + tree type, lhs0, rhs0; + tree_code cmp0 = ovce_extract_ops (elt0, &stmt0, &invert, &type, &lhs0, + &rhs0, &vcond0); if (cmp0 == ERROR_MARK) continue; @@ -3905,26 +3920,20 @@ optimize_vec_cond_expr (tree_code opcode, vec<operand_entry *> *ops) { tree &elt1 = (*ops)[j]->op; - gassign *stmt1; - tree_code cmp1 = ovce_extract_ops (elt1, &stmt1, NULL, NULL); + gassign *stmt1, *vcond1; + tree lhs1, rhs1; + tree_code cmp1 = ovce_extract_ops (elt1, &stmt1, NULL, NULL, &lhs1, + &rhs1, &vcond1); if (cmp1 == ERROR_MARK) continue; - tree cond0 = gimple_assign_rhs1 (stmt0); - tree x0 = TREE_OPERAND (cond0, 0); - tree y0 = TREE_OPERAND (cond0, 1); - - tree cond1 = gimple_assign_rhs1 (stmt1); - tree x1 = TREE_OPERAND (cond1, 0); - tree y1 = TREE_OPERAND (cond1, 1); - tree comb; if (opcode == BIT_AND_EXPR) - comb = maybe_fold_and_comparisons (type, cmp0, x0, y0, cmp1, x1, - y1); + comb = maybe_fold_and_comparisons (type, cmp0, lhs0, rhs0, + cmp1, lhs1, rhs1); else if (opcode == BIT_IOR_EXPR) - comb = maybe_fold_or_comparisons (type, cmp0, x0, y0, cmp1, x1, - y1); + comb = maybe_fold_or_comparisons (type, cmp0, lhs0, rhs0, + cmp1, lhs1, rhs1); else gcc_unreachable (); if (comb == NULL) @@ -3934,19 +3943,22 @@ optimize_vec_cond_expr (tree_code opcode, vec<operand_entry *> *ops) if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, "Transforming "); - print_generic_expr (dump_file, cond0); + print_generic_expr (dump_file, gimple_assign_lhs (stmt0)); fprintf (dump_file, " %c ", opcode == BIT_AND_EXPR ? '&' : '|'); - print_generic_expr (dump_file, cond1); + print_generic_expr (dump_file, gimple_assign_lhs (stmt1)); fprintf (dump_file, " into "); print_generic_expr (dump_file, comb); fputc ('\n', dump_file); } - gimple_assign_set_rhs1 (stmt0, comb); + gimple_stmt_iterator gsi = gsi_for_stmt (vcond0); + tree exp = force_gimple_operand_gsi (&gsi, comb, true, NULL_TREE, + true, GSI_SAME_STMT); if (invert) - std::swap (*gimple_assign_rhs2_ptr (stmt0), - *gimple_assign_rhs3_ptr (stmt0)); - update_stmt (stmt0); + swap_ssa_operands (vcond0, gimple_assign_rhs2_ptr (vcond0), + gimple_assign_rhs3_ptr (vcond0)); + gimple_assign_set_rhs1 (vcond0, exp); + update_stmt (vcond0); elt1 = error_mark_node; any_changes = true; |