From: Richard Biener Date: Fri, 3 Jul 2020 08:09:39 +0000 (+0200) Subject: refactor SLP constant insertion and provde entry insert helper X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=9e5508c2d006f2d4f8670e6c3fed770ac1c85e64;p=gcc.git 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 * 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. --- diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c index eff68f76bc3..727eba0b12f 100644 --- a/gcc/tree-vect-slp.c +++ b/gcc/tree-vect-slp.c @@ -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 (last_stmt)) si = gsi_after_labels (gimple_bb (last_stmt)); else diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index d68547ed1b5..9228f9cde4a 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -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 (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 (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 diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c index 78d9da689c8..26a184696aa 100644 --- a/gcc/tree-vectorizer.c +++ b/gcc/tree-vectorizer.c @@ -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 (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 (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 diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h index dfe88cc8af3..7c6de8397b3 100644 --- a/gcc/tree-vectorizer.h +++ b/gcc/tree-vectorizer.h @@ -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;