This fixes the last SLP analysis refactoring to _really_ pass the SLP node to the analysis functions. It also moves the premature out in the loop analysis code (it fails to consider pattern stmts for one). Finally this properly implements the slp_perm check for strided loads in vectorizable_load (now that slp_node is passed down) and it also adds dumping of hybrid detected stmts.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk. Richard. 2015-05-27 Richard Biener <rguent...@suse.de> * tree-vect-stmts.c (vectorizable_load): Initialize slp_perm earlier and remove ??? comment. (vect_analyze_stmt): If we are analyzing a pure SLP stmt and got called from loop analysis bail out. Always pass the SLP node to the vectorizable_* functions. * tree-vect-loop.c (vect_analyze_loop_operations): Remove the premature SLP check here. * tree-vect-slp.c (vect_detect_hybrid_slp_stmts): Dump hybrid detected SLP stmts. (vect_detect_hybrid_slp_1): Likewise. Index: gcc/tree-vect-stmts.c =================================================================== *** gcc/tree-vect-stmts.c (revision 223737) --- gcc/tree-vect-stmts.c (working copy) *************** vectorizable_load (gimple stmt, gimple_s *** 5940,5945 **** --- 5940,5948 ---- return false; } + if (slp && SLP_TREE_LOAD_PERMUTATION (slp_node).exists ()) + slp_perm = true; + group_size = GROUP_SIZE (vinfo_for_stmt (first_stmt)); if (!slp && !PURE_SLP_STMT (stmt_info) *************** vectorizable_load (gimple stmt, gimple_s *** 6004,6013 **** && (slp || PURE_SLP_STMT (stmt_info))) && (group_size > nunits || nunits % group_size != 0 ! /* ??? During analysis phase we are not called with the ! slp node/instance we are in so whether we'll end up ! with a permutation we don't know. Still we don't ! support load permutations. */ || slp_perm)) { dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, --- 6007,6013 ---- && (slp || PURE_SLP_STMT (stmt_info))) && (group_size > nunits || nunits % group_size != 0 ! /* We don't support load permutations. */ || slp_perm)) { dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, *************** vectorizable_load (gimple stmt, gimple_s *** 6402,6409 **** { grouped_load = false; vec_num = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node); - if (SLP_TREE_LOAD_PERMUTATION (slp_node).exists ()) - slp_perm = true; group_gap = GROUP_GAP (vinfo_for_stmt (first_stmt)); } else --- 6402,6407 ---- *************** vect_analyze_stmt (gimple stmt, bool *ne *** 7371,7403 **** *need_to_vectorize = true; } ! ok = true; ! if (!bb_vinfo ! && (STMT_VINFO_RELEVANT_P (stmt_info) ! || STMT_VINFO_DEF_TYPE (stmt_info) == vect_reduction_def)) ! ok = (vectorizable_simd_clone_call (stmt, NULL, NULL, NULL) ! || vectorizable_conversion (stmt, NULL, NULL, NULL) ! || vectorizable_shift (stmt, NULL, NULL, NULL) ! || vectorizable_operation (stmt, NULL, NULL, NULL) ! || vectorizable_assignment (stmt, NULL, NULL, NULL) ! || vectorizable_load (stmt, NULL, NULL, NULL, NULL) ! || vectorizable_call (stmt, NULL, NULL, NULL) ! || vectorizable_store (stmt, NULL, NULL, NULL) ! || vectorizable_reduction (stmt, NULL, NULL, NULL) ! || vectorizable_condition (stmt, NULL, NULL, NULL, 0, NULL)); ! else ! { ! if (bb_vinfo) ! ok = (vectorizable_simd_clone_call (stmt, NULL, NULL, node) ! || vectorizable_conversion (stmt, NULL, NULL, node) ! || vectorizable_shift (stmt, NULL, NULL, node) ! || vectorizable_operation (stmt, NULL, NULL, node) ! || vectorizable_assignment (stmt, NULL, NULL, node) ! || vectorizable_load (stmt, NULL, NULL, node, NULL) ! || vectorizable_call (stmt, NULL, NULL, node) ! || vectorizable_store (stmt, NULL, NULL, node) ! || vectorizable_condition (stmt, NULL, NULL, NULL, 0, node)); ! } if (!ok) { --- 7369,7408 ---- *need_to_vectorize = true; } ! if (PURE_SLP_STMT (stmt_info) && !node) ! { ! dump_printf_loc (MSG_NOTE, vect_location, ! "handled only by SLP analysis\n"); ! return true; ! } ! ! ok = true; ! if (!bb_vinfo ! && (STMT_VINFO_RELEVANT_P (stmt_info) ! || STMT_VINFO_DEF_TYPE (stmt_info) == vect_reduction_def)) ! ok = (vectorizable_simd_clone_call (stmt, NULL, NULL, node) ! || vectorizable_conversion (stmt, NULL, NULL, node) ! || vectorizable_shift (stmt, NULL, NULL, node) ! || vectorizable_operation (stmt, NULL, NULL, node) ! || vectorizable_assignment (stmt, NULL, NULL, node) ! || vectorizable_load (stmt, NULL, NULL, node, NULL) ! || vectorizable_call (stmt, NULL, NULL, node) ! || vectorizable_store (stmt, NULL, NULL, node) ! || vectorizable_reduction (stmt, NULL, NULL, node) ! || vectorizable_condition (stmt, NULL, NULL, NULL, 0, node)); ! else ! { ! if (bb_vinfo) ! ok = (vectorizable_simd_clone_call (stmt, NULL, NULL, node) ! || vectorizable_conversion (stmt, NULL, NULL, node) ! || vectorizable_shift (stmt, NULL, NULL, node) ! || vectorizable_operation (stmt, NULL, NULL, node) ! || vectorizable_assignment (stmt, NULL, NULL, node) ! || vectorizable_load (stmt, NULL, NULL, node, NULL) ! || vectorizable_call (stmt, NULL, NULL, node) ! || vectorizable_store (stmt, NULL, NULL, node) ! || vectorizable_condition (stmt, NULL, NULL, NULL, 0, node)); ! } if (!ok) { Index: gcc/tree-vect-loop.c =================================================================== *** gcc/tree-vect-loop.c (revision 223737) --- gcc/tree-vect-loop.c (working copy) *************** vect_analyze_loop_operations (loop_vec_i *** 1556,1566 **** gsi_next (&si)) { gimple stmt = gsi_stmt (si); - if (STMT_SLP_TYPE (vinfo_for_stmt (stmt))) - { - need_to_vectorize = true; - continue; - } if (!gimple_clobber_p (stmt) && !vect_analyze_stmt (stmt, &need_to_vectorize, NULL)) return false; --- 1556,1561 ---- Index: gcc/tree-vect-slp.c =================================================================== *** gcc/tree-vect-slp.c (revision 223737) --- gcc/tree-vect-slp.c (working copy) *************** vect_detect_hybrid_slp_stmts (slp_tree n *** 2027,2033 **** } if (stype == hybrid) ! STMT_SLP_TYPE (stmt_vinfo) = hybrid; FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), j, child) if (child) --- 2027,2040 ---- } if (stype == hybrid) ! { ! if (dump_enabled_p ()) ! { ! dump_printf_loc (MSG_NOTE, vect_location, "marking hybrid: "); ! dump_gimple_stmt (MSG_NOTE, TDF_SLIM, stmt, 0); ! } ! STMT_SLP_TYPE (stmt_vinfo) = hybrid; ! } FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), j, child) if (child) *************** vect_detect_hybrid_slp_1 (tree *tp, int *** 2051,2057 **** gimple def_stmt = SSA_NAME_DEF_STMT (*tp); if (flow_bb_inside_loop_p (loopp, gimple_bb (def_stmt)) && PURE_SLP_STMT (vinfo_for_stmt (def_stmt))) ! STMT_SLP_TYPE (vinfo_for_stmt (def_stmt)) = hybrid; } return NULL_TREE; --- 2058,2071 ---- gimple def_stmt = SSA_NAME_DEF_STMT (*tp); if (flow_bb_inside_loop_p (loopp, gimple_bb (def_stmt)) && PURE_SLP_STMT (vinfo_for_stmt (def_stmt))) ! { ! if (dump_enabled_p ()) ! { ! dump_printf_loc (MSG_NOTE, vect_location, "marking hybrid: "); ! dump_gimple_stmt (MSG_NOTE, TDF_SLIM, def_stmt, 0); ! } ! STMT_SLP_TYPE (vinfo_for_stmt (def_stmt)) = hybrid; ! } } return NULL_TREE;