This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR52638
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 22 Mar 2012 12:33:28 +0100 (CET)
- Subject: [PATCH] Fix PR52638
This fixes PR52638, I made vect_init_vector handle scalar inits
to not duplicate this code all over the place.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.
Richard.
2012-03-22 Richard Guenther <rguenther@suse.de>
PR tree-optimization/52638
* tree-vect-stmts.c (vect_init_vector_1): New function, split
out from ...
(vect_init_vector): ... here. Handle scalar vector inits.
(vect_get_vec_def_for_operand): Adjust.
(vectorizable_load): Likewise.
Index: gcc/tree-vect-stmts.c
===================================================================
*** gcc/tree-vect-stmts.c (revision 185675)
--- gcc/tree-vect-stmts.c (working copy)
*************** vect_get_load_cost (struct data_referenc
*** 1136,1183 ****
}
}
! /* Function vect_init_vector.
!
! Insert a new stmt (INIT_STMT) that initializes a new vector variable with
! the vector elements of VECTOR_VAR. Place the initialization at BSI if it
! is not NULL. Otherwise, place the initialization at the loop preheader.
! Return the DEF of INIT_STMT.
! It will be used in the vectorization of STMT. */
!
! tree
! vect_init_vector (gimple stmt, tree vector_var, tree vector_type,
! gimple_stmt_iterator *gsi)
{
- stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt);
- tree new_var;
- gimple init_stmt;
- tree vec_oprnd;
- edge pe;
- tree new_temp;
- basic_block new_bb;
-
- new_var = vect_get_new_vect_var (vector_type, vect_simple_var, "cst_");
- add_referenced_var (new_var);
- init_stmt = gimple_build_assign (new_var, vector_var);
- new_temp = make_ssa_name (new_var, init_stmt);
- gimple_assign_set_lhs (init_stmt, new_temp);
if (gsi)
! vect_finish_stmt_generation (stmt, init_stmt, gsi);
else
{
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
if (loop_vinfo)
{
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
if (nested_in_vect_loop_p (loop, stmt))
loop = loop->inner;
pe = loop_preheader_edge (loop);
! new_bb = gsi_insert_on_edge_immediate (pe, init_stmt);
gcc_assert (!new_bb);
}
else
--- 1136,1166 ----
}
}
+ /* Insert the new stmt NEW_STMT at *GSI or at the appropriate place in
+ the loop preheader for the vectorized stmt STMT. */
! static void
! vect_init_vector_1 (gimple stmt, gimple new_stmt, gimple_stmt_iterator *gsi)
{
if (gsi)
! vect_finish_stmt_generation (stmt, new_stmt, gsi);
else
{
+ stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt);
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
if (loop_vinfo)
{
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+ basic_block new_bb;
+ edge pe;
if (nested_in_vect_loop_p (loop, stmt))
loop = loop->inner;
pe = loop_preheader_edge (loop);
! new_bb = gsi_insert_on_edge_immediate (pe, new_stmt);
gcc_assert (!new_bb);
}
else
*************** vect_init_vector (gimple stmt, tree vect
*** 1189,1204 ****
gcc_assert (bb_vinfo);
bb = BB_VINFO_BB (bb_vinfo);
gsi_bb_start = gsi_after_labels (bb);
! gsi_insert_before (&gsi_bb_start, init_stmt, GSI_SAME_STMT);
}
}
if (vect_print_dump_info (REPORT_DETAILS))
{
fprintf (vect_dump, "created new init_stmt: ");
! print_gimple_stmt (vect_dump, init_stmt, 0, TDF_SLIM);
}
vec_oprnd = gimple_assign_lhs (init_stmt);
return vec_oprnd;
}
--- 1172,1235 ----
gcc_assert (bb_vinfo);
bb = BB_VINFO_BB (bb_vinfo);
gsi_bb_start = gsi_after_labels (bb);
! gsi_insert_before (&gsi_bb_start, new_stmt, GSI_SAME_STMT);
}
}
if (vect_print_dump_info (REPORT_DETAILS))
{
fprintf (vect_dump, "created new init_stmt: ");
! print_gimple_stmt (vect_dump, new_stmt, 0, TDF_SLIM);
}
+ }
+
+ /* Function vect_init_vector.
+ Insert a new stmt (INIT_STMT) that initializes a new vector variable with
+ the vector elements of VECTOR_VAR. Place the initialization at BSI if it
+ is not NULL. Otherwise, place the initialization at the loop preheader.
+ Return the DEF of INIT_STMT.
+ It will be used in the vectorization of STMT. */
+
+ tree
+ vect_init_vector (gimple stmt, tree vector_var, tree vector_type,
+ gimple_stmt_iterator *gsi)
+ {
+ tree new_var;
+ gimple init_stmt;
+ tree vec_oprnd;
+ tree new_temp;
+
+ if (TREE_CODE (TREE_TYPE (vector_var)) != VECTOR_TYPE)
+ {
+ if (!types_compatible_p (TREE_TYPE (vector_type),
+ TREE_TYPE (vector_var)))
+ {
+ if (CONSTANT_CLASS_P (vector_var))
+ vector_var = fold_unary (VIEW_CONVERT_EXPR, TREE_TYPE (vector_type),
+ vector_var);
+ else
+ {
+ new_var = create_tmp_reg (TREE_TYPE (vector_type), NULL);
+ add_referenced_var (new_var);
+ init_stmt = gimple_build_assign_with_ops (NOP_EXPR,
+ new_var, vector_var,
+ NULL_TREE);
+ new_temp = make_ssa_name (new_var, init_stmt);
+ gimple_assign_set_lhs (init_stmt, new_temp);
+ vect_init_vector_1 (stmt, init_stmt, gsi);
+ vector_var = new_temp;
+ }
+ }
+ vector_var = build_vector_from_val (vector_type, vector_var);
+ }
+
+ new_var = vect_get_new_vect_var (vector_type, vect_simple_var, "cst_");
+ add_referenced_var (new_var);
+ init_stmt = gimple_build_assign (new_var, vector_var);
+ new_temp = make_ssa_name (new_var, init_stmt);
+ gimple_assign_set_lhs (init_stmt, new_temp);
+ vect_init_vector_1 (stmt, init_stmt, gsi);
vec_oprnd = gimple_assign_lhs (init_stmt);
return vec_oprnd;
}
*************** vect_get_vec_def_for_operand (tree op, g
*** 1225,1232 ****
stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt);
unsigned int nunits;
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
- tree vec_inv;
- tree vec_cst;
tree def;
enum vect_def_type dt;
bool is_simple_use;
--- 1256,1261 ----
*************** vect_get_vec_def_for_operand (tree op, g
*** 1271,1284 ****
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "Create vector_cst. nunits = %d", nunits);
! if (!types_compatible_p (TREE_TYPE (vector_type), TREE_TYPE (op)))
! {
! op = fold_unary (VIEW_CONVERT_EXPR, TREE_TYPE (vector_type), op);
! gcc_assert (op && CONSTANT_CLASS_P (op));
! }
!
! vec_cst = build_vector_from_val (vector_type, op);
! return vect_init_vector (stmt, vec_cst, vector_type, NULL);
}
/* Case 2: operand is defined outside the loop - loop invariant. */
--- 1300,1306 ----
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "Create vector_cst. nunits = %d", nunits);
! return vect_init_vector (stmt, op, vector_type, NULL);
}
/* Case 2: operand is defined outside the loop - loop invariant. */
*************** vect_get_vec_def_for_operand (tree op, g
*** 1294,1301 ****
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "Create vector_inv.");
! vec_inv = build_vector_from_val (vector_type, def);
! return vect_init_vector (stmt, vec_inv, vector_type, NULL);
}
/* Case 3: operand is defined inside the loop. */
--- 1316,1322 ----
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "Create vector_inv.");
! return vect_init_vector (stmt, def, vector_type, NULL);
}
/* Case 3: operand is defined inside the loop. */
*************** vectorizable_load (gimple stmt, gimple_s
*** 4875,4895 ****
/* 4. Handle invariant-load. */
if (inv_p && !bb_vinfo)
{
- tree tem, vec_inv;
gimple_stmt_iterator gsi2 = *gsi;
gcc_assert (!strided_load);
gsi_next (&gsi2);
! tem = scalar_dest;
! if (!useless_type_conversion_p (TREE_TYPE (vectype),
! TREE_TYPE (tem)))
! {
! tem = fold_convert (TREE_TYPE (vectype), tem);
! tem = force_gimple_operand_gsi (&gsi2, tem, true,
! NULL_TREE, true,
! GSI_SAME_STMT);
! }
! vec_inv = build_vector_from_val (vectype, tem);
! new_temp = vect_init_vector (stmt, vec_inv,
vectype, &gsi2);
new_stmt = SSA_NAME_DEF_STMT (new_temp);
}
--- 4896,4905 ----
/* 4. Handle invariant-load. */
if (inv_p && !bb_vinfo)
{
gimple_stmt_iterator gsi2 = *gsi;
gcc_assert (!strided_load);
gsi_next (&gsi2);
! new_temp = vect_init_vector (stmt, scalar_dest,
vectype, &gsi2);
new_stmt = SSA_NAME_DEF_STMT (new_temp);
}