aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-32.c23
-rw-r--r--gcc/tree-vect-slp.c93
4 files changed, 105 insertions, 23 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 396111e..456a4cf 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2013-05-29 Richard Biener <rguenther@suse.de>
+
+ * tree-vect-slp.c (vect_bb_slp_scalar_cost): New function
+ computing scalar cost offsetted by stmts that are kept live
+ by scalar uses.
+ (vect_bb_vectorization_profitable_p): Use vect_bb_slp_scalar_cost
+ for computation of scalar cost.
+
2013-05-28 Steve Ellcey <sellcey@mips.com>
* config/mips/mips-cpus.def (mips32r2): Change processor type.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 869371a..533abbb 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2013-05-29 Richard Biener <rguenther@suse.de>
+
+ * gcc.dg/vect/bb-slp-32.c: New testcase.
+
2013-05-28 Balaji V. Iyer <balaji.v.iyer@intel.com>
* c-c++-common/cilk-plus/AN/array_test1.c: New test.
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-32.c b/gcc/testsuite/gcc.dg/vect/bb-slp-32.c
new file mode 100644
index 0000000..df80083
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-32.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_int } */
+/* { dg-additional-options "-fvect-cost-model" } */
+
+void bar (int *);
+int foo (int *p)
+{
+ int x[4];
+ int tem0, tem1, tem2, tem3;
+ tem0 = p[0] + 1;
+ x[0] = tem0;
+ tem1 = p[1] + 2;
+ x[1] = tem1;
+ tem2 = p[2] + 3;
+ x[2] = tem2;
+ tem3 = p[3] + 4;
+ x[3] = tem3;
+ bar (x);
+ return tem0 + tem1 + tem2 + tem3;
+}
+
+/* { dg-final { scan-tree-dump "vectorization is not profitable" "slp" } } */
+/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
index e3b38ff..5d8e85f 100644
--- a/gcc/tree-vect-slp.c
+++ b/gcc/tree-vect-slp.c
@@ -1898,6 +1898,69 @@ vect_slp_analyze_operations (bb_vec_info bb_vinfo)
return true;
}
+
+/* Compute the scalar cost of the SLP node NODE and its children
+ and return it. Do not account defs that are marked in LIFE and
+ update LIFE according to uses of NODE. */
+
+static unsigned
+vect_bb_slp_scalar_cost (slp_tree node, vec<bool, va_stack> life)
+{
+ unsigned scalar_cost = 0;
+ unsigned i;
+ gimple stmt;
+ slp_tree child;
+
+ FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (node), i, stmt)
+ {
+ unsigned stmt_cost;
+ ssa_op_iter op_iter;
+ def_operand_p def_p;
+ stmt_vec_info stmt_info;
+
+ if (life[i])
+ continue;
+
+ /* If there is a non-vectorized use of the defs then the scalar
+ stmt is kept live in which case we do not account it or any
+ required defs in the SLP children in the scalar cost. This
+ way we make the vectorization more costly when compared to
+ the scalar cost. */
+ FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, op_iter, SSA_OP_DEF)
+ {
+ imm_use_iterator use_iter;
+ gimple use_stmt;
+ FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, DEF_FROM_PTR (def_p))
+ if (!vinfo_for_stmt (use_stmt)
+ || !STMT_VINFO_VECTORIZABLE (vinfo_for_stmt (use_stmt)))
+ {
+ life[i] = true;
+ BREAK_FROM_IMM_USE_STMT (use_iter);
+ }
+ }
+ if (life[i])
+ continue;
+
+ stmt_info = vinfo_for_stmt (stmt);
+ if (STMT_VINFO_DATA_REF (stmt_info))
+ {
+ if (DR_IS_READ (STMT_VINFO_DATA_REF (stmt_info)))
+ stmt_cost = vect_get_stmt_cost (scalar_load);
+ else
+ stmt_cost = vect_get_stmt_cost (scalar_store);
+ }
+ else
+ stmt_cost = vect_get_stmt_cost (scalar_stmt);
+
+ scalar_cost += stmt_cost;
+ }
+
+ FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
+ scalar_cost += vect_bb_slp_scalar_cost (child, life);
+
+ return scalar_cost;
+}
+
/* Check if vectorization of the basic block is profitable. */
static bool
@@ -1908,10 +1971,6 @@ vect_bb_vectorization_profitable_p (bb_vec_info bb_vinfo)
int i, j;
unsigned int vec_inside_cost = 0, vec_outside_cost = 0, scalar_cost = 0;
unsigned int vec_prologue_cost = 0, vec_epilogue_cost = 0;
- unsigned int stmt_cost;
- gimple stmt;
- gimple_stmt_iterator si;
- basic_block bb = BB_VINFO_BB (bb_vinfo);
void *target_cost_data = BB_VINFO_TARGET_COST_DATA (bb_vinfo);
stmt_vec_info stmt_info = NULL;
stmt_vector_for_cost body_cost_vec;
@@ -1931,26 +1990,14 @@ vect_bb_vectorization_profitable_p (bb_vec_info bb_vinfo)
}
/* Calculate scalar cost. */
- for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
+ FOR_EACH_VEC_ELT (slp_instances, i, instance)
{
- stmt = gsi_stmt (si);
- stmt_info = vinfo_for_stmt (stmt);
-
- if (!stmt_info || !STMT_VINFO_VECTORIZABLE (stmt_info)
- || !PURE_SLP_STMT (stmt_info))
- continue;
-
- if (STMT_VINFO_DATA_REF (stmt_info))
- {
- if (DR_IS_READ (STMT_VINFO_DATA_REF (stmt_info)))
- stmt_cost = vect_get_stmt_cost (scalar_load);
- else
- stmt_cost = vect_get_stmt_cost (scalar_store);
- }
- else
- stmt_cost = vect_get_stmt_cost (scalar_stmt);
-
- scalar_cost += stmt_cost;
+ vec<bool, va_stack> life;
+ vec_stack_alloc (bool, life, SLP_INSTANCE_GROUP_SIZE (instance));
+ life.quick_grow_cleared (SLP_INSTANCE_GROUP_SIZE (instance));
+ scalar_cost += vect_bb_slp_scalar_cost (SLP_INSTANCE_TREE (instance),
+ life);
+ life.release ();
}
/* Complete the target-specific cost calculation. */