mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-23 01:50:33 +08:00
re PR target/83008 ([performance] Is it better to avoid extra instructions in data passing between loops?)
2018-01-30 Richard Biener <rguenther@suse.de> PR tree-optimization/83008 * tree-vect-slp.c (vect_analyze_slp_cost_1): Properly cost invariant and constant vector uses in stmts when they need more than one stmt. From-SVN: r257181
This commit is contained in:
parent
924d6d0b69
commit
85bb2f9a30
@ -1,3 +1,10 @@
|
||||
2018-01-30 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/83008
|
||||
* tree-vect-slp.c (vect_analyze_slp_cost_1): Properly cost
|
||||
invariant and constant vector uses in stmts when they need
|
||||
more than one stmt.
|
||||
|
||||
2018-01-30 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
|
||||
|
||||
PR bootstrap/84017
|
||||
|
@ -1911,18 +1911,56 @@ vect_analyze_slp_cost_1 (slp_instance instance, slp_tree node,
|
||||
enum vect_def_type dt;
|
||||
if (!op || op == lhs)
|
||||
continue;
|
||||
if (vect_is_simple_use (op, stmt_info->vinfo, &def_stmt, &dt))
|
||||
if (vect_is_simple_use (op, stmt_info->vinfo, &def_stmt, &dt)
|
||||
&& (dt == vect_constant_def || dt == vect_external_def))
|
||||
{
|
||||
/* Without looking at the actual initializer a vector of
|
||||
constants can be implemented as load from the constant pool.
|
||||
??? We need to pass down stmt_info for a vector type
|
||||
even if it points to the wrong stmt. */
|
||||
if (dt == vect_constant_def)
|
||||
record_stmt_cost (prologue_cost_vec, 1, vector_load,
|
||||
stmt_info, 0, vect_prologue);
|
||||
else if (dt == vect_external_def)
|
||||
record_stmt_cost (prologue_cost_vec, 1, vec_construct,
|
||||
stmt_info, 0, vect_prologue);
|
||||
When all elements are the same we can use a splat. */
|
||||
tree vectype = get_vectype_for_scalar_type (TREE_TYPE (op));
|
||||
unsigned group_size = SLP_TREE_SCALAR_STMTS (node).length ();
|
||||
unsigned num_vects_to_check;
|
||||
unsigned HOST_WIDE_INT const_nunits;
|
||||
unsigned nelt_limit;
|
||||
if (TYPE_VECTOR_SUBPARTS (vectype).is_constant (&const_nunits)
|
||||
&& ! multiple_p (const_nunits, group_size))
|
||||
{
|
||||
num_vects_to_check = SLP_TREE_NUMBER_OF_VEC_STMTS (node);
|
||||
nelt_limit = const_nunits;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If either the vector has variable length or the vectors
|
||||
are composed of repeated whole groups we only need to
|
||||
cost construction once. All vectors will be the same. */
|
||||
num_vects_to_check = 1;
|
||||
nelt_limit = group_size;
|
||||
}
|
||||
tree elt = NULL_TREE;
|
||||
unsigned nelt = 0;
|
||||
for (unsigned j = 0; j < num_vects_to_check * nelt_limit; ++j)
|
||||
{
|
||||
unsigned si = j % group_size;
|
||||
if (nelt == 0)
|
||||
elt = gimple_op (SLP_TREE_SCALAR_STMTS (node)[si], i);
|
||||
/* ??? We're just tracking whether all operands of a single
|
||||
vector initializer are the same, ideally we'd check if
|
||||
we emitted the same one already. */
|
||||
else if (elt != gimple_op (SLP_TREE_SCALAR_STMTS (node)[si], i))
|
||||
elt = NULL_TREE;
|
||||
nelt++;
|
||||
if (nelt == nelt_limit)
|
||||
{
|
||||
/* ??? We need to pass down stmt_info for a vector type
|
||||
even if it points to the wrong stmt. */
|
||||
record_stmt_cost (prologue_cost_vec, 1,
|
||||
dt == vect_external_def
|
||||
? (elt ? scalar_to_vec : vec_construct)
|
||||
: vector_load,
|
||||
stmt_info, 0, vect_prologue);
|
||||
nelt = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user