From 6eddf228932b9a7146aac7c930c0ed1eefe2be9f Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 29 May 2013 08:21:17 +0000 Subject: [PATCH] tree-vect-slp.c (vect_bb_slp_scalar_cost): New function computing scalar cost offsetted by stmts that are kept live by... 2013-05-29 Richard Biener * 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. * gcc.dg/vect/bb-slp-32.c: New testcase. From-SVN: r199402 --- gcc/ChangeLog | 8 +++ gcc/testsuite/ChangeLog | 4 ++ gcc/testsuite/gcc.dg/vect/bb-slp-32.c | 23 +++++++ gcc/tree-vect-slp.c | 93 ++++++++++++++++++++------- 4 files changed, 105 insertions(+), 23 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/vect/bb-slp-32.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 396111ed79f..456a4cf87f2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2013-05-29 Richard Biener + + * 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 * config/mips/mips-cpus.def (mips32r2): Change processor type. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 869371a1edd..533abbb3be8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2013-05-29 Richard Biener + + * gcc.dg/vect/bb-slp-32.c: New testcase. + 2013-05-28 Balaji V. Iyer * 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 00000000000..df8008396a0 --- /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 e3b38ff2d52..5d8e85f16a6 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 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 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. */ -- 2.30.2