If the first attempt at applying BB SLP to a region fails, the main loop in vect_slp_bb recomputes the region's bounds and datarefs for the next vector size. AFAICT this isn't needed any more; we should be able to reuse the datarefs from the first attempt instead.
Tested on aarch64-linux-gnu and x86_64-linux-gnu. OK to install? Richard 2019-10-19 Richard Sandiford <richard.sandif...@arm.com> gcc/ * tree-vect-slp.c (vect_slp_analyze_bb_1): Call save_datarefs when processing the given datarefs for the first time and check_datarefs subsequently. (vect_slp_bb_region): New function, split out of... (vect_slp_bb): ...here. Don't recompute the region bounds and dataref sets when retrying with a different vector size. Index: gcc/tree-vect-slp.c =================================================================== *** gcc/tree-vect-slp.c 2019-10-11 15:43:55.439484181 +0100 --- gcc/tree-vect-slp.c 2019-10-19 16:03:30.000000000 +0100 *************** vect_slp_analyze_bb_1 (gimple_stmt_itera *** 2852,2857 **** --- 2852,2858 ---- slp_instance instance; int i; poly_uint64 min_vf = 2; + bool first_time_p = shared->datarefs.is_empty (); /* The first group of checks is independent of the vector size. */ fatal = true; *************** vect_slp_analyze_bb_1 (gimple_stmt_itera *** 2871,2877 **** return NULL; BB_VINFO_DATAREFS (bb_vinfo) = datarefs; ! bb_vinfo->shared->save_datarefs (); /* Analyze the data references. */ --- 2872,2881 ---- return NULL; BB_VINFO_DATAREFS (bb_vinfo) = datarefs; ! if (first_time_p) ! bb_vinfo->shared->save_datarefs (); ! else ! bb_vinfo->shared->check_datarefs (); /* Analyze the data references. */ *************** vect_slp_analyze_bb_1 (gimple_stmt_itera *** 3007,3022 **** return bb_vinfo; } ! ! /* Main entry for the BB vectorizer. Analyze and transform BB, returns ! true if anything in the basic-block was vectorized. */ ! ! bool ! vect_slp_bb (basic_block bb) { bb_vec_info bb_vinfo; - gimple_stmt_iterator gsi; - bool any_vectorized = false; auto_vector_sizes vector_sizes; /* Autodetect first vector size we try. */ --- 3011,3028 ---- return bb_vinfo; } ! /* Subroutine of vect_slp_bb. Try to vectorize the statements between ! REGION_BEGIN (inclusive) and REGION_END (exclusive), returning true ! on success. The region has N_STMTS statements and has the datarefs ! given by DATAREFS. */ ! ! static bool ! vect_slp_bb_region (gimple_stmt_iterator region_begin, ! gimple_stmt_iterator region_end, ! vec<data_reference_p> datarefs, ! unsigned int n_stmts) { bb_vec_info bb_vinfo; auto_vector_sizes vector_sizes; /* Autodetect first vector size we try. */ *************** vect_slp_bb (basic_block bb) *** 3024,3069 **** targetm.vectorize.autovectorize_vector_sizes (&vector_sizes, false); unsigned int next_size = 0; ! gsi = gsi_start_bb (bb); poly_uint64 autodetected_vector_size = 0; while (1) { - if (gsi_end_p (gsi)) - break; - - gimple_stmt_iterator region_begin = gsi; - vec<data_reference_p> datarefs = vNULL; - int insns = 0; - - for (; !gsi_end_p (gsi); gsi_next (&gsi)) - { - gimple *stmt = gsi_stmt (gsi); - if (is_gimple_debug (stmt)) - continue; - insns++; - - if (gimple_location (stmt) != UNKNOWN_LOCATION) - vect_location = stmt; - - if (!vect_find_stmt_data_reference (NULL, stmt, &datarefs)) - break; - } - - /* Skip leading unhandled stmts. */ - if (gsi_stmt (region_begin) == gsi_stmt (gsi)) - { - gsi_next (&gsi); - continue; - } - - gimple_stmt_iterator region_end = gsi; - bool vectorized = false; bool fatal = false; - vec_info_shared shared; bb_vinfo = vect_slp_analyze_bb_1 (region_begin, region_end, ! datarefs, insns, fatal, &shared); if (bb_vinfo && dbg_cnt (vect_slp)) { --- 3030,3044 ---- targetm.vectorize.autovectorize_vector_sizes (&vector_sizes, false); unsigned int next_size = 0; ! vec_info_shared shared; poly_uint64 autodetected_vector_size = 0; while (1) { bool vectorized = false; bool fatal = false; bb_vinfo = vect_slp_analyze_bb_1 (region_begin, region_end, ! datarefs, n_stmts, fatal, &shared); if (bb_vinfo && dbg_cnt (vect_slp)) { *************** vect_slp_bb (basic_block bb) *** 3090,3097 **** } delete bb_vinfo; - any_vectorized |= vectorized; - if (next_size == 0) autodetected_vector_size = current_vector_size; --- 3065,3070 ---- *************** vect_slp_bb (basic_block bb) *** 3105,3137 **** /* If vect_slp_analyze_bb_1 signaled that analysis for all vector sizes will fail do not bother iterating. */ || fatal) { ! if (gsi_end_p (region_end)) ! break; ! /* Skip the unhandled stmt. */ ! gsi_next (&gsi); ! /* And reset vector sizes. */ ! current_vector_size = 0; ! next_size = 0; ! } ! else { ! /* Try the next biggest vector size. */ ! current_vector_size = vector_sizes[next_size++]; ! if (dump_enabled_p ()) ! { ! dump_printf_loc (MSG_NOTE, vect_location, ! "***** Re-trying analysis with " ! "vector size "); ! dump_dec (MSG_NOTE, current_vector_size); ! dump_printf (MSG_NOTE, "\n"); ! } ! /* Start over. */ ! gsi = region_begin; } } return any_vectorized; --- 3078,3145 ---- /* If vect_slp_analyze_bb_1 signaled that analysis for all vector sizes will fail do not bother iterating. */ || fatal) + return vectorized; + + /* Try the next biggest vector size. */ + current_vector_size = vector_sizes[next_size++]; + if (dump_enabled_p ()) { ! dump_printf_loc (MSG_NOTE, vect_location, ! "***** Re-trying analysis with " ! "vector size "); ! dump_dec (MSG_NOTE, current_vector_size); ! dump_printf (MSG_NOTE, "\n"); ! } ! } ! } ! /* Main entry for the BB vectorizer. Analyze and transform BB, returns ! true if anything in the basic-block was vectorized. */ ! bool ! vect_slp_bb (basic_block bb) ! { ! gimple_stmt_iterator gsi; ! bool any_vectorized = false; ! ! gsi = gsi_start_bb (bb); ! while (!gsi_end_p (gsi)) ! { ! gimple_stmt_iterator region_begin = gsi; ! vec<data_reference_p> datarefs = vNULL; ! int insns = 0; ! ! for (; !gsi_end_p (gsi); gsi_next (&gsi)) { ! gimple *stmt = gsi_stmt (gsi); ! if (is_gimple_debug (stmt)) ! continue; ! insns++; ! ! if (gimple_location (stmt) != UNKNOWN_LOCATION) ! vect_location = stmt; ! if (!vect_find_stmt_data_reference (NULL, stmt, &datarefs)) ! break; } + + /* Skip leading unhandled stmts. */ + if (gsi_stmt (region_begin) == gsi_stmt (gsi)) + { + gsi_next (&gsi); + continue; + } + + gimple_stmt_iterator region_end = gsi; + + if (vect_slp_bb_region (region_begin, region_end, datarefs, insns)) + any_vectorized = true; + + if (gsi_end_p (region_end)) + break; + + /* Skip the unhandled stmt. */ + gsi_next (&gsi); } return any_vectorized;