From 0a08c1bc5935fb4b2a86b7f9b5abe6818d869dfd Mon Sep 17 00:00:00 2001 From: rguenth Date: Tue, 3 Nov 2015 15:59:17 +0000 Subject: [PATCH] 2015-11-03 Richard Biener * tree-vect-data-refs.c (vect_analyze_data_refs): Do not collect data references here. * tree-vect-loop.c: Include cgraph.h. (vect_analyze_loop_2): Collect data references here. * tree-vect-slp.c (find_bb_location): Inline ... (vect_slp_bb): ... here. Renamed from vect_slp_analyze_bb. Factor in vect_slp_transform_bb. (vect_slp_transform_bb): Removed. (vect_slp_analyze_bb_1): Collect data references here. * tree-vectorizer.c (pass_slp_vectorize::execute): Call vect_slp_bb. * tree-vectorizer.h (vect_slp_bb): Declare. (vect_slp_analyze_bb): Remove. (vect_slp_transform_bb): Remove. (find_bb_location): Remove. (vect_analyze_data_refs): Remove stmt count reference parameter. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@229712 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 19 +++++++ gcc/tree-vect-data-refs.c | 104 ++----------------------------------- gcc/tree-vect-loop.c | 72 ++++++++++++++++++++++++-- gcc/tree-vect-slp.c | 128 ++++++++++++++++++++-------------------------- gcc/tree-vectorizer.c | 15 ++---- gcc/tree-vectorizer.h | 7 +-- 6 files changed, 150 insertions(+), 195 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 97a1101..d00b074 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,22 @@ +2015-11-03 Richard Biener + + * tree-vect-data-refs.c (vect_analyze_data_refs): Do not collect + data references here. + * tree-vect-loop.c: Include cgraph.h. + (vect_analyze_loop_2): Collect data references here. + * tree-vect-slp.c (find_bb_location): Inline ... + (vect_slp_bb): ... here. Renamed from vect_slp_analyze_bb. + Factor in vect_slp_transform_bb. + (vect_slp_transform_bb): Removed. + (vect_slp_analyze_bb_1): Collect data references here. + * tree-vectorizer.c (pass_slp_vectorize::execute): Call + vect_slp_bb. + * tree-vectorizer.h (vect_slp_bb): Declare. + (vect_slp_analyze_bb): Remove. + (vect_slp_transform_bb): Remove. + (find_bb_location): Remove. + (vect_analyze_data_refs): Remove stmt count reference parameter. + 2015-11-03 Evgeny Stupachenko * multiple_target.c (create_dispatcher_calls): Add target check diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c index 7d3abcf..3de71fb 100644 --- a/gcc/tree-vect-data-refs.c +++ b/gcc/tree-vect-data-refs.c @@ -3245,120 +3245,24 @@ vect_check_gather_scatter (gimple *stmt, loop_vec_info loop_vinfo, tree *basep, */ bool -vect_analyze_data_refs (vec_info *vinfo, int *min_vf, unsigned *n_stmts) +vect_analyze_data_refs (vec_info *vinfo, int *min_vf) { struct loop *loop = NULL; - basic_block bb = NULL; unsigned int i; - vec datarefs; struct data_reference *dr; tree scalar_type; if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, - "=== vect_analyze_data_refs ===\n"); + "=== vect_analyze_data_refs ===\n"); if (loop_vec_info loop_vinfo = dyn_cast (vinfo)) - { - basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo); - - loop = LOOP_VINFO_LOOP (loop_vinfo); - datarefs = LOOP_VINFO_DATAREFS (loop_vinfo); - if (!find_loop_nest (loop, &LOOP_VINFO_LOOP_NEST (loop_vinfo))) - { - if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "not vectorized: loop contains function calls" - " or data references that cannot be analyzed\n"); - return false; - } - - for (i = 0; i < loop->num_nodes; i++) - { - gimple_stmt_iterator gsi; - - for (gsi = gsi_start_bb (bbs[i]); !gsi_end_p (gsi); gsi_next (&gsi)) - { - gimple *stmt = gsi_stmt (gsi); - if (is_gimple_debug (stmt)) - continue; - ++*n_stmts; - if (!find_data_references_in_stmt (loop, stmt, &datarefs)) - { - if (is_gimple_call (stmt) && loop->safelen) - { - tree fndecl = gimple_call_fndecl (stmt), op; - if (fndecl != NULL_TREE) - { - struct cgraph_node *node = cgraph_node::get (fndecl); - if (node != NULL && node->simd_clones != NULL) - { - unsigned int j, n = gimple_call_num_args (stmt); - for (j = 0; j < n; j++) - { - op = gimple_call_arg (stmt, j); - if (DECL_P (op) - || (REFERENCE_CLASS_P (op) - && get_base_address (op))) - break; - } - op = gimple_call_lhs (stmt); - /* Ignore #pragma omp declare simd functions - if they don't have data references in the - call stmt itself. */ - if (j == n - && !(op - && (DECL_P (op) - || (REFERENCE_CLASS_P (op) - && get_base_address (op))))) - continue; - } - } - } - LOOP_VINFO_DATAREFS (loop_vinfo) = datarefs; - if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "not vectorized: loop contains function " - "calls or data references that cannot " - "be analyzed\n"); - return false; - } - } - } - - LOOP_VINFO_DATAREFS (loop_vinfo) = datarefs; - } - else - { - bb_vec_info bb_vinfo = as_a (vinfo); - gimple_stmt_iterator gsi; - - bb = BB_VINFO_BB (bb_vinfo); - for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) - { - gimple *stmt = gsi_stmt (gsi); - if (is_gimple_debug (stmt)) - continue; - ++*n_stmts; - if (!find_data_references_in_stmt (NULL, stmt, - &BB_VINFO_DATAREFS (bb_vinfo))) - { - /* Mark the rest of the basic-block as unvectorizable. */ - for (; !gsi_end_p (gsi); gsi_next (&gsi)) - { - stmt = gsi_stmt (gsi); - STMT_VINFO_VECTORIZABLE (vinfo_for_stmt (stmt)) = false; - } - break; - } - } - - datarefs = BB_VINFO_DATAREFS (bb_vinfo); - } + loop = LOOP_VINFO_LOOP (loop_vinfo); /* Go through the data-refs, check that the analysis succeeded. Update pointer from stmt_vec_info struct to DR and vectype. */ + vec datarefs = vinfo->datarefs; FOR_EACH_VEC_ELT (datarefs, i, dr) { gimple *stmt; diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c index bdf93ba..43ada18 100644 --- a/gcc/tree-vect-loop.c +++ b/gcc/tree-vect-loop.c @@ -46,6 +46,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-scalar-evolution.h" #include "tree-vectorizer.h" #include "gimple-fold.h" +#include "cgraph.h" /* Loop Vectorization Pass. @@ -1584,13 +1585,74 @@ vect_analyze_loop_2 (loop_vec_info loop_vinfo) unsigned int n_stmts = 0; /* Find all data references in the loop (which correspond to vdefs/vuses) - and analyze their evolution in the loop. Also adjust the minimal - vectorization factor according to the loads and stores. + and analyze their evolution in the loop. */ - FORNOW: Handle only simple, array references, which - alignment can be forced, and aligned pointer-references. */ + basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo); + + loop_p loop = LOOP_VINFO_LOOP (loop_vinfo); + if (!find_loop_nest (loop, &LOOP_VINFO_LOOP_NEST (loop_vinfo))) + { + if (dump_enabled_p ()) + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "not vectorized: loop contains function calls" + " or data references that cannot be analyzed\n"); + return false; + } + + for (unsigned i = 0; i < loop->num_nodes; i++) + for (gimple_stmt_iterator gsi = gsi_start_bb (bbs[i]); + !gsi_end_p (gsi); gsi_next (&gsi)) + { + gimple *stmt = gsi_stmt (gsi); + if (is_gimple_debug (stmt)) + continue; + ++n_stmts; + if (!find_data_references_in_stmt (loop, stmt, + &LOOP_VINFO_DATAREFS (loop_vinfo))) + { + if (is_gimple_call (stmt) && loop->safelen) + { + tree fndecl = gimple_call_fndecl (stmt), op; + if (fndecl != NULL_TREE) + { + cgraph_node *node = cgraph_node::get (fndecl); + if (node != NULL && node->simd_clones != NULL) + { + unsigned int j, n = gimple_call_num_args (stmt); + for (j = 0; j < n; j++) + { + op = gimple_call_arg (stmt, j); + if (DECL_P (op) + || (REFERENCE_CLASS_P (op) + && get_base_address (op))) + break; + } + op = gimple_call_lhs (stmt); + /* Ignore #pragma omp declare simd functions + if they don't have data references in the + call stmt itself. */ + if (j == n + && !(op + && (DECL_P (op) + || (REFERENCE_CLASS_P (op) + && get_base_address (op))))) + continue; + } + } + } + if (dump_enabled_p ()) + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "not vectorized: loop contains function " + "calls or data references that cannot " + "be analyzed\n"); + return false; + } + } + + /* Analyze the data references and also adjust the minimal + vectorization factor according to the loads and stores. */ - ok = vect_analyze_data_refs (loop_vinfo, &min_vf, &n_stmts); + ok = vect_analyze_data_refs (loop_vinfo, &min_vf); if (!ok) { if (dump_enabled_p ()) diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c index 53f7f46..35808eb 100644 --- a/gcc/tree-vect-slp.c +++ b/gcc/tree-vect-slp.c @@ -40,28 +40,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-vectorizer.h" #include "langhooks.h" #include "gimple-walk.h" - -/* Extract the location of the basic block in the source code. - Return the basic block location if succeed and NULL if not. */ - -source_location -find_bb_location (basic_block bb) -{ - gimple *stmt = NULL; - gimple_stmt_iterator si; - - if (!bb) - return UNKNOWN_LOCATION; - - for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si)) - { - stmt = gsi_stmt (si); - if (gimple_location (stmt) != UNKNOWN_LOCATION) - return gimple_location (stmt); - } - - return UNKNOWN_LOCATION; -} +#include "dbgcnt.h" /* Recursively free the memory allocated for the SLP tree rooted at NODE. */ @@ -2361,7 +2340,31 @@ vect_slp_analyze_bb_1 (basic_block bb) if (!bb_vinfo) return NULL; - if (!vect_analyze_data_refs (bb_vinfo, &min_vf, &n_stmts)) + /* Gather all data references in the basic-block. */ + + for (gimple_stmt_iterator gsi = gsi_start_bb (bb); + !gsi_end_p (gsi); gsi_next (&gsi)) + { + gimple *stmt = gsi_stmt (gsi); + if (is_gimple_debug (stmt)) + continue; + ++n_stmts; + if (!find_data_references_in_stmt (NULL, stmt, + &BB_VINFO_DATAREFS (bb_vinfo))) + { + /* Mark the rest of the basic-block as unvectorizable. */ + for (; !gsi_end_p (gsi); gsi_next (&gsi)) + { + stmt = gsi_stmt (gsi); + STMT_VINFO_VECTORIZABLE (vinfo_for_stmt (stmt)) = false; + } + break; + } + } + + /* Analyze the data references. */ + + if (!vect_analyze_data_refs (bb_vinfo, &min_vf)) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, @@ -2499,8 +2502,11 @@ vect_slp_analyze_bb_1 (basic_block bb) } -bb_vec_info -vect_slp_analyze_bb (basic_block bb) +/* 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; int insns = 0; @@ -2517,6 +2523,8 @@ vect_slp_analyze_bb (basic_block bb) && !gimple_nop_p (stmt) && gimple_code (stmt) != GIMPLE_LABEL) insns++; + if (gimple_location (stmt) != UNKNOWN_LOCATION) + vect_location = gimple_location (stmt); } if (insns > PARAM_VALUE (PARAM_SLP_MAX_INSNS_IN_BB)) @@ -2526,7 +2534,7 @@ vect_slp_analyze_bb (basic_block bb) "not vectorized: too many instructions in " "basic block.\n"); - return NULL; + return false; } /* Autodetect first vector size we try. */ @@ -2537,14 +2545,33 @@ vect_slp_analyze_bb (basic_block bb) { bb_vinfo = vect_slp_analyze_bb_1 (bb); if (bb_vinfo) - return bb_vinfo; + { + if (!dbg_cnt (vect_slp)) + { + destroy_bb_vec_info (bb_vinfo); + return false; + } + + if (dump_enabled_p ()) + dump_printf_loc (MSG_NOTE, vect_location, "SLPing BB\n"); + + vect_schedule_slp (bb_vinfo); + + if (dump_enabled_p ()) + dump_printf_loc (MSG_NOTE, vect_location, + "BASIC BLOCK VECTORIZED\n"); + + destroy_bb_vec_info (bb_vinfo); + + return true; + } destroy_bb_vec_info (bb_vinfo); vector_sizes &= ~current_vector_size; if (vector_sizes == 0 || current_vector_size == 0) - return NULL; + return false; /* Try the next biggest vector size. */ current_vector_size = 1 << floor_log2 (vector_sizes); @@ -3533,48 +3560,3 @@ vect_schedule_slp (vec_info *vinfo) return is_store; } - - -/* Vectorize the basic block. */ - -void -vect_slp_transform_bb (basic_block bb) -{ - bb_vec_info bb_vinfo = vec_info_for_bb (bb); - gimple_stmt_iterator si; - - gcc_assert (bb_vinfo); - - if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, "SLPing BB\n"); - - for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si)) - { - gimple *stmt = gsi_stmt (si); - stmt_vec_info stmt_info; - - if (dump_enabled_p ()) - { - dump_printf_loc (MSG_NOTE, vect_location, - "------>SLPing statement: "); - dump_gimple_stmt (MSG_NOTE, TDF_SLIM, stmt, 0); - dump_printf (MSG_NOTE, "\n"); - } - - stmt_info = vinfo_for_stmt (stmt); - gcc_assert (stmt_info); - - /* Schedule all the SLP instances when the first SLP stmt is reached. */ - if (STMT_SLP_TYPE (stmt_info)) - { - vect_schedule_slp (bb_vinfo); - break; - } - } - - if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, - "BASIC BLOCK VECTORIZED\n"); - - destroy_bb_vec_info (bb_vinfo); -} diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c index b80a8dd..7b3d9a3 100644 --- a/gcc/tree-vectorizer.c +++ b/gcc/tree-vectorizer.c @@ -696,18 +696,9 @@ pass_slp_vectorize::execute (function *fun) FOR_EACH_BB_FN (bb, fun) { - vect_location = find_bb_location (bb); - - if (vect_slp_analyze_bb (bb)) - { - if (!dbg_cnt (vect_slp)) - break; - - vect_slp_transform_bb (bb); - if (dump_enabled_p ()) - dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location, - "basic block vectorized\n"); - } + if (vect_slp_bb (bb)) + dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location, + "basic block vectorized\n"); } free_stmt_vec_info_vec (); diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h index bf01ded..f77a4eb 100644 --- a/gcc/tree-vectorizer.h +++ b/gcc/tree-vectorizer.h @@ -1010,7 +1010,7 @@ extern bool vect_analyze_data_ref_accesses (vec_info *); extern bool vect_prune_runtime_alias_test_list (loop_vec_info); extern tree vect_check_gather_scatter (gimple *, loop_vec_info, tree *, tree *, int *); -extern bool vect_analyze_data_refs (vec_info *, int *, unsigned *); +extern bool vect_analyze_data_refs (vec_info *, int *); extern tree vect_create_data_ref_ptr (gimple *, tree, struct loop *, tree, tree *, gimple_stmt_iterator *, gimple **, bool, bool *, @@ -1072,10 +1072,7 @@ extern bool vect_make_slp_decision (loop_vec_info); extern void vect_detect_hybrid_slp (loop_vec_info); extern void vect_get_slp_defs (vec , slp_tree, vec > *, int); - -extern source_location find_bb_location (basic_block); -extern bb_vec_info vect_slp_analyze_bb (basic_block); -extern void vect_slp_transform_bb (basic_block); +extern bool vect_slp_bb (basic_block); /* In tree-vect-patterns.c. */ /* Pattern recognition functions. -- 2.7.4