refactor SLP constant insertion and provde entry insert helper

This provides helpers to insert stmts on region entry abstracted
from loop/basic-block split out from vec_init_vector and used
from the SLP constant code generation path.  The SLP constant
code generation path is also changed to avoid needless SSA
copying since we can store VECTOR_CSTs directly in the vectorized
defs array, improving the IL from the vectorizer.

2020-07-03  Richard Biener  <rguenther@suse.de>

	* tree-vectorizer.h (vec_info::insert_on_entry): New.
	(vec_info::insert_seq_on_entry): Likewise.
	* tree-vectorizer.c (vec_info::insert_on_entry): Implement.
	(vec_info::insert_seq_on_entry): Likewise.
	* tree-vect-stmts.c (vect_init_vector_1): Use
	vec_info::insert_on_entry.
	(vect_finish_stmt_generation): Set modified bit after
	adjusting VUSE.
	* tree-vect-slp.c (vect_create_constant_vectors): Simplify
	by using vec_info::insert_seq_on_entry and bypassing
	vec_init_vector.
	(vect_schedule_slp_instance): Deal with all-constant
	children later.
This commit is contained in:
Richard Biener 2020-07-03 10:09:39 +02:00
parent 26b538cd81
commit 9e5508c2d0
4 changed files with 59 additions and 43 deletions

View File

@ -3786,26 +3786,20 @@ vect_create_constant_vectors (vec_info *vinfo, slp_tree op_node)
permute_results);
vec_cst = permute_results[number_of_vectors - j - 1];
}
tree init;
if (insert_after)
if (!gimple_seq_empty_p (ctor_seq))
{
gimple_stmt_iterator gsi = gsi_for_stmt (insert_after->stmt);
/* vect_init_vector inserts before. */
gsi_next (&gsi);
init = vect_init_vector (vinfo, NULL, vec_cst,
vector_type, &gsi);
}
else
init = vect_init_vector (vinfo, NULL, vec_cst,
vector_type, NULL);
if (ctor_seq != NULL)
{
gimple_stmt_iterator gsi
= gsi_for_stmt (SSA_NAME_DEF_STMT (init));
gsi_insert_seq_before (&gsi, ctor_seq, GSI_SAME_STMT);
if (insert_after)
{
gimple_stmt_iterator gsi
= gsi_for_stmt (insert_after->stmt);
gsi_insert_seq_after (&gsi, ctor_seq,
GSI_CONTINUE_LINKING);
}
else
vinfo->insert_seq_on_entry (NULL, ctor_seq);
ctor_seq = NULL;
}
voprnds.quick_push (init);
voprnds.quick_push (vec_cst);
insert_after = NULL;
number_of_places_left_in_vector = nunits;
constant_p = true;
@ -4418,10 +4412,11 @@ vect_schedule_slp_instance (vec_info *vinfo,
|| vect_stmt_dominates_stmt_p (last_stmt, vstmt))
last_stmt = vstmt;
}
/* This can happen when all children are pre-existing vectors. */
if (!last_stmt)
last_stmt = vect_find_first_scalar_stmt_in_slp (node)->stmt;
}
/* This can happen when all children are pre-existing vectors or
constants. */
if (!last_stmt)
last_stmt = vect_find_first_scalar_stmt_in_slp (node)->stmt;
if (is_a <gphi *> (last_stmt))
si = gsi_after_labels (gimple_bb (last_stmt));
else

View File

@ -1315,29 +1315,7 @@ vect_init_vector_1 (vec_info *vinfo, stmt_vec_info stmt_vinfo, gimple *new_stmt,
if (gsi)
vect_finish_stmt_generation (vinfo, stmt_vinfo, new_stmt, gsi);
else
{
loop_vec_info loop_vinfo = dyn_cast <loop_vec_info> (vinfo);
if (loop_vinfo)
{
class loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
basic_block new_bb;
edge pe;
if (stmt_vinfo && nested_in_vect_loop_p (loop, stmt_vinfo))
loop = loop->inner;
pe = loop_preheader_edge (loop);
new_bb = gsi_insert_on_edge_immediate (pe, new_stmt);
gcc_assert (!new_bb);
}
else
{
bb_vec_info bb_vinfo = dyn_cast <bb_vec_info> (vinfo);
gimple_stmt_iterator gsi_region_begin = bb_vinfo->region_begin;
gsi_insert_before (&gsi_region_begin, new_stmt, GSI_SAME_STMT);
}
}
vinfo->insert_on_entry (stmt_vinfo, new_stmt);
if (dump_enabled_p ())
dump_printf_loc (MSG_NOTE, vect_location,
@ -1592,6 +1570,7 @@ vect_finish_stmt_generation (vec_info *vinfo,
{
tree vdef = gimple_vdef (at_stmt);
gimple_set_vuse (vec_stmt, gimple_vuse (at_stmt));
gimple_set_modified (vec_stmt, true);
/* If we have an SSA vuse and insert a store, update virtual
SSA form to avoid triggering the renamer. Do so only
if we can easily see all uses - which is what almost always

View File

@ -625,6 +625,46 @@ vec_info::replace_stmt (gimple_stmt_iterator *gsi, stmt_vec_info stmt_info,
gsi_replace (gsi, new_stmt, true);
}
/* Insert stmts in SEQ on the VEC_INFO region entry. If CONTEXT is
not NULL it specifies whether to use the sub-region entry
determined by it, currently used for loop vectorization to insert
on the inner loop entry vs. the outer loop entry. */
void
vec_info::insert_seq_on_entry (stmt_vec_info context, gimple_seq seq)
{
if (loop_vec_info loop_vinfo = dyn_cast <loop_vec_info> (this))
{
class loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
basic_block new_bb;
edge pe;
if (context && nested_in_vect_loop_p (loop, context))
loop = loop->inner;
pe = loop_preheader_edge (loop);
new_bb = gsi_insert_seq_on_edge_immediate (pe, seq);
gcc_assert (!new_bb);
}
else
{
bb_vec_info bb_vinfo = as_a <bb_vec_info> (this);
gimple_stmt_iterator gsi_region_begin = bb_vinfo->region_begin;
gsi_insert_seq_before (&gsi_region_begin, seq, GSI_SAME_STMT);
}
}
/* Like insert_seq_on_entry but just inserts the single stmt NEW_STMT. */
void
vec_info::insert_on_entry (stmt_vec_info context, gimple *new_stmt)
{
gimple_seq seq = NULL;
gimple_stmt_iterator gsi = gsi_start (seq);
gsi_insert_before_without_update (&gsi, new_stmt, GSI_SAME_STMT);
insert_seq_on_entry (context, seq);
}
/* Create and initialize a new stmt_vec_info struct for STMT. */
stmt_vec_info

View File

@ -334,6 +334,8 @@ public:
void move_dr (stmt_vec_info, stmt_vec_info);
void remove_stmt (stmt_vec_info);
void replace_stmt (gimple_stmt_iterator *, stmt_vec_info, gimple *);
void insert_on_entry (stmt_vec_info, gimple *);
void insert_seq_on_entry (stmt_vec_info, gimple_seq);
/* The type of vectorization. */
vec_kind kind;