tree-vect-data-refs.c (vect_analyze_data_refs): Do not collect data references here.

2015-11-03  Richard Biener  <rguenther@suse.de>

	* 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.

From-SVN: r229712
This commit is contained in:
Richard Biener 2015-11-03 15:59:17 +00:00 committed by Richard Biener
parent 7372dfe4bb
commit 428db0baaa
6 changed files with 150 additions and 195 deletions

View File

@ -1,3 +1,22 @@
2015-11-03 Richard Biener <rguenther@suse.de>
* 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 <evstupac@gmail.com> 2015-11-03 Evgeny Stupachenko <evstupac@gmail.com>
* multiple_target.c (create_dispatcher_calls): Add target check * multiple_target.c (create_dispatcher_calls): Add target check

View File

@ -3245,12 +3245,10 @@ vect_check_gather_scatter (gimple *stmt, loop_vec_info loop_vinfo, tree *basep,
*/ */
bool 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; struct loop *loop = NULL;
basic_block bb = NULL;
unsigned int i; unsigned int i;
vec<data_reference_p> datarefs;
struct data_reference *dr; struct data_reference *dr;
tree scalar_type; tree scalar_type;
@ -3259,106 +3257,12 @@ vect_analyze_data_refs (vec_info *vinfo, int *min_vf, unsigned *n_stmts)
"=== vect_analyze_data_refs ===\n"); "=== vect_analyze_data_refs ===\n");
if (loop_vec_info loop_vinfo = dyn_cast <loop_vec_info> (vinfo)) if (loop_vec_info loop_vinfo = dyn_cast <loop_vec_info> (vinfo))
{
basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
loop = LOOP_VINFO_LOOP (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 <bb_vec_info> (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);
}
/* Go through the data-refs, check that the analysis succeeded. Update /* Go through the data-refs, check that the analysis succeeded. Update
pointer from stmt_vec_info struct to DR and vectype. */ pointer from stmt_vec_info struct to DR and vectype. */
vec<data_reference_p> datarefs = vinfo->datarefs;
FOR_EACH_VEC_ELT (datarefs, i, dr) FOR_EACH_VEC_ELT (datarefs, i, dr)
{ {
gimple *stmt; gimple *stmt;

View File

@ -46,6 +46,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-scalar-evolution.h" #include "tree-scalar-evolution.h"
#include "tree-vectorizer.h" #include "tree-vectorizer.h"
#include "gimple-fold.h" #include "gimple-fold.h"
#include "cgraph.h"
/* Loop Vectorization Pass. /* Loop Vectorization Pass.
@ -1584,13 +1585,74 @@ vect_analyze_loop_2 (loop_vec_info loop_vinfo)
unsigned int n_stmts = 0; unsigned int n_stmts = 0;
/* Find all data references in the loop (which correspond to vdefs/vuses) /* Find all data references in the loop (which correspond to vdefs/vuses)
and analyze their evolution in the loop. Also adjust the minimal and analyze their evolution in the loop. */
vectorization factor according to the loads and stores.
FORNOW: Handle only simple, array references, which basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
alignment can be forced, and aligned pointer-references. */
ok = vect_analyze_data_refs (loop_vinfo, &min_vf, &n_stmts); 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);
if (!ok) if (!ok)
{ {
if (dump_enabled_p ()) if (dump_enabled_p ())

View File

@ -40,28 +40,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-vectorizer.h" #include "tree-vectorizer.h"
#include "langhooks.h" #include "langhooks.h"
#include "gimple-walk.h" #include "gimple-walk.h"
#include "dbgcnt.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;
}
/* Recursively free the memory allocated for the SLP tree rooted at NODE. */ /* 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) if (!bb_vinfo)
return NULL; 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 ()) if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@ -2499,8 +2502,11 @@ vect_slp_analyze_bb_1 (basic_block bb)
} }
bb_vec_info /* Main entry for the BB vectorizer. Analyze and transform BB, returns
vect_slp_analyze_bb (basic_block bb) true if anything in the basic-block was vectorized. */
bool
vect_slp_bb (basic_block bb)
{ {
bb_vec_info bb_vinfo; bb_vec_info bb_vinfo;
int insns = 0; int insns = 0;
@ -2517,6 +2523,8 @@ vect_slp_analyze_bb (basic_block bb)
&& !gimple_nop_p (stmt) && !gimple_nop_p (stmt)
&& gimple_code (stmt) != GIMPLE_LABEL) && gimple_code (stmt) != GIMPLE_LABEL)
insns++; insns++;
if (gimple_location (stmt) != UNKNOWN_LOCATION)
vect_location = gimple_location (stmt);
} }
if (insns > PARAM_VALUE (PARAM_SLP_MAX_INSNS_IN_BB)) 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 " "not vectorized: too many instructions in "
"basic block.\n"); "basic block.\n");
return NULL; return false;
} }
/* Autodetect first vector size we try. */ /* 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); bb_vinfo = vect_slp_analyze_bb_1 (bb);
if (bb_vinfo) 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); destroy_bb_vec_info (bb_vinfo);
vector_sizes &= ~current_vector_size; vector_sizes &= ~current_vector_size;
if (vector_sizes == 0 if (vector_sizes == 0
|| current_vector_size == 0) || current_vector_size == 0)
return NULL; return false;
/* Try the next biggest vector size. */ /* Try the next biggest vector size. */
current_vector_size = 1 << floor_log2 (vector_sizes); current_vector_size = 1 << floor_log2 (vector_sizes);
@ -3533,48 +3560,3 @@ vect_schedule_slp (vec_info *vinfo)
return is_store; 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);
}

View File

@ -696,19 +696,10 @@ pass_slp_vectorize::execute (function *fun)
FOR_EACH_BB_FN (bb, fun) FOR_EACH_BB_FN (bb, fun)
{ {
vect_location = find_bb_location (bb); if (vect_slp_bb (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, dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location,
"basic block vectorized\n"); "basic block vectorized\n");
} }
}
free_stmt_vec_info_vec (); free_stmt_vec_info_vec ();

View File

@ -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 bool vect_prune_runtime_alias_test_list (loop_vec_info);
extern tree vect_check_gather_scatter (gimple *, loop_vec_info, tree *, tree *, extern tree vect_check_gather_scatter (gimple *, loop_vec_info, tree *, tree *,
int *); 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, extern tree vect_create_data_ref_ptr (gimple *, tree, struct loop *, tree,
tree *, gimple_stmt_iterator *, tree *, gimple_stmt_iterator *,
gimple **, bool, bool *, 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_detect_hybrid_slp (loop_vec_info);
extern void vect_get_slp_defs (vec<tree> , slp_tree, extern void vect_get_slp_defs (vec<tree> , slp_tree,
vec<vec<tree> > *, int); vec<vec<tree> > *, int);
extern bool vect_slp_bb (basic_block);
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);
/* In tree-vect-patterns.c. */ /* In tree-vect-patterns.c. */
/* Pattern recognition functions. /* Pattern recognition functions.