On November 12, 2021 6:57:29 PM GMT+01:00, Richard Sandiford via Gcc-patches <gcc-patches@gcc.gnu.org> wrote: >This patch uses code_helper to represent the common (and >alternative) operations when building an SLP node. It's not >much of a saving on its own, but it helps with later patches. > >Regstrapped on aarch64-linux-gnu and x86_64-linux-gnu. OK to install?
Ok. Richard. >Richard > > >gcc/ > * tree-vect-slp.c (vect_build_slp_tree_1): Use code_helper > to record the operations performed by statements, only using > CALL_EXPR for things that don't map to built-in or internal > functions. For shifts, require all shift amounts to be equal > if optab_vector is not supported but optab_scalar is. >--- > gcc/tree-vect-slp.c | 77 +++++++++++++++------------------------------ > 1 file changed, 26 insertions(+), 51 deletions(-) > >diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c >index 94c75497495..f4123cf830a 100644 >--- a/gcc/tree-vect-slp.c >+++ b/gcc/tree-vect-slp.c >@@ -876,17 +876,13 @@ vect_build_slp_tree_1 (vec_info *vinfo, unsigned char >*swap, > { > unsigned int i; > stmt_vec_info first_stmt_info = stmts[0]; >- enum tree_code first_stmt_code = ERROR_MARK; >- enum tree_code alt_stmt_code = ERROR_MARK; >- enum tree_code rhs_code = ERROR_MARK; >- enum tree_code first_cond_code = ERROR_MARK; >+ code_helper first_stmt_code = ERROR_MARK; >+ code_helper alt_stmt_code = ERROR_MARK; >+ code_helper rhs_code = ERROR_MARK; >+ code_helper first_cond_code = ERROR_MARK; > tree lhs; > bool need_same_oprnds = false; > tree vectype = NULL_TREE, first_op1 = NULL_TREE; >- optab optab; >- int icode; >- machine_mode optab_op2_mode; >- machine_mode vec_mode; > stmt_vec_info first_load = NULL, prev_first_load = NULL; > bool first_stmt_load_p = false, load_p = false; > bool first_stmt_phi_p = false, phi_p = false; >@@ -966,13 +962,16 @@ vect_build_slp_tree_1 (vec_info *vinfo, unsigned char >*swap, > gcall *call_stmt = dyn_cast <gcall *> (stmt); > if (call_stmt) > { >- rhs_code = CALL_EXPR; >+ combined_fn cfn = gimple_call_combined_fn (call_stmt); >+ if (cfn != CFN_LAST) >+ rhs_code = cfn; >+ else >+ rhs_code = CALL_EXPR; > >- if (gimple_call_internal_p (stmt, IFN_MASK_LOAD)) >+ if (cfn == CFN_MASK_LOAD) > load_p = true; >- else if ((gimple_call_internal_p (call_stmt) >- && (!vectorizable_internal_fn_p >- (gimple_call_internal_fn (call_stmt)))) >+ else if ((internal_fn_p (cfn) >+ && !vectorizable_internal_fn_p (as_internal_fn (cfn))) > || gimple_call_tail_p (call_stmt) > || gimple_call_noreturn_p (call_stmt) > || gimple_call_chain (call_stmt)) >@@ -1013,32 +1012,11 @@ vect_build_slp_tree_1 (vec_info *vinfo, unsigned char >*swap, > || rhs_code == LROTATE_EXPR > || rhs_code == RROTATE_EXPR) > { >- vec_mode = TYPE_MODE (vectype); >- > /* First see if we have a vector/vector shift. */ >- optab = optab_for_tree_code (rhs_code, vectype, >- optab_vector); >- >- if (!optab >- || optab_handler (optab, vec_mode) == CODE_FOR_nothing) >+ if (!directly_supported_p (rhs_code, vectype, optab_vector)) > { > /* No vector/vector shift, try for a vector/scalar shift. */ >- optab = optab_for_tree_code (rhs_code, vectype, >- optab_scalar); >- >- if (!optab) >- { >- if (dump_enabled_p ()) >- dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, >- "Build SLP failed: no optab.\n"); >- if (is_a <bb_vec_info> (vinfo) && i != 0) >- continue; >- /* Fatal mismatch. */ >- matches[0] = false; >- return false; >- } >- icode = (int) optab_handler (optab, vec_mode); >- if (icode == CODE_FOR_nothing) >+ if (!directly_supported_p (rhs_code, vectype, optab_scalar)) > { > if (dump_enabled_p ()) > dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, >@@ -1050,12 +1028,8 @@ vect_build_slp_tree_1 (vec_info *vinfo, unsigned char >*swap, > matches[0] = false; > return false; > } >- optab_op2_mode = insn_data[icode].operand[2].mode; >- if (!VECTOR_MODE_P (optab_op2_mode)) >- { >- need_same_oprnds = true; >- first_op1 = gimple_assign_rhs2 (stmt); >- } >+ need_same_oprnds = true; >+ first_op1 = gimple_assign_rhs2 (stmt); > } > } > else if (rhs_code == WIDEN_LSHIFT_EXPR) >@@ -1081,8 +1055,7 @@ vect_build_slp_tree_1 (vec_info *vinfo, unsigned char >*swap, > return false; > } > } >- else if (call_stmt >- && gimple_call_internal_p (call_stmt, IFN_DIV_POW2)) >+ else if (rhs_code == CFN_DIV_POW2) > { > need_same_oprnds = true; > first_op1 = gimple_call_arg (call_stmt, 1); >@@ -1139,10 +1112,10 @@ vect_build_slp_tree_1 (vec_info *vinfo, unsigned char >*swap, > continue; > } > >- if (!load_p && rhs_code == CALL_EXPR) >+ if (!load_p && call_stmt) > { > if (!compatible_calls_p (as_a <gcall *> (stmts[0]->stmt), >- as_a <gcall *> (stmt))) >+ call_stmt)) > { > if (dump_enabled_p ()) > dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, >@@ -1243,10 +1216,11 @@ vect_build_slp_tree_1 (vec_info *vinfo, unsigned char >*swap, > > /* Not memory operation. */ > if (!phi_p >- && TREE_CODE_CLASS (rhs_code) != tcc_binary >- && TREE_CODE_CLASS (rhs_code) != tcc_unary >- && TREE_CODE_CLASS (rhs_code) != tcc_expression >- && TREE_CODE_CLASS (rhs_code) != tcc_comparison >+ && rhs_code.is_tree_code () >+ && TREE_CODE_CLASS (tree_code (rhs_code)) != tcc_binary >+ && TREE_CODE_CLASS (tree_code (rhs_code)) != tcc_unary >+ && TREE_CODE_CLASS (tree_code (rhs_code)) != tcc_expression >+ && TREE_CODE_CLASS (tree_code (rhs_code)) != tcc_comparison > && rhs_code != VIEW_CONVERT_EXPR > && rhs_code != CALL_EXPR > && rhs_code != BIT_FIELD_REF) >@@ -1308,7 +1282,8 @@ vect_build_slp_tree_1 (vec_info *vinfo, unsigned char >*swap, > /* If we allowed a two-operation SLP node verify the target can cope > with the permute we are going to use. */ > if (alt_stmt_code != ERROR_MARK >- && TREE_CODE_CLASS (alt_stmt_code) != tcc_reference) >+ && (!alt_stmt_code.is_tree_code () >+ || TREE_CODE_CLASS (tree_code (alt_stmt_code)) != tcc_reference)) > { > *two_operators = true; > }