Message ID | mpty25tmf3q.fsf@arm.com |
---|---|
State | Committed |
Commit | 8de7958fbd126528c5a5a95a068c0692f6a643cc |
Headers | show |
Series | [1/5] vect: Use code_helper when building SLP nodes | expand |
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; > }
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; }