Commit 892a981f by Richard Sandiford Committed by Richard Sandiford

[2/7] Clean up vectorizer load/store costs

Add a bit more commentary and try to make the structure more obvious.
The horrendous:

      if (grouped_access_p
          && represents_group_p
          && !store_lanes_p
          && !STMT_VINFO_STRIDED_P (stmt_info)
          && !slp_node)

checks go away in patch 6.

Tested on aarch64-linux-gnu and x86_64-linux-gnu.

gcc/
	* tree-vect-stmts.c (vect_cost_group_size): Delete.
	(vect_model_store_cost): Avoid calling it.  Use first_stmt_p
	variable to indicate when once-per-group costs are being used.
	(vect_model_load_cost): Likewise.  Fix comment and misindented code.

From-SVN: r238034
parent c01e092f
2016-07-06 Richard Sandiford <richard.sandiford@arm.com> 2016-07-06 Richard Sandiford <richard.sandiford@arm.com>
* tree-vect-stmts.c (vect_cost_group_size): Delete.
(vect_model_store_cost): Avoid calling it. Use first_stmt_p
variable to indicate when once-per-group costs are being used.
(vect_model_load_cost): Likewise. Fix comment and misindented code.
2016-07-06 Richard Sandiford <richard.sandiford@arm.com>
* tree-vect-stmts.c (vectorizable_load): Remove unnecessary * tree-vect-stmts.c (vectorizable_load): Remove unnecessary
peeling-for-gaps condition. peeling-for-gaps condition.
......
...@@ -865,24 +865,6 @@ vect_model_promotion_demotion_cost (stmt_vec_info stmt_info, ...@@ -865,24 +865,6 @@ vect_model_promotion_demotion_cost (stmt_vec_info stmt_info,
"prologue_cost = %d .\n", inside_cost, prologue_cost); "prologue_cost = %d .\n", inside_cost, prologue_cost);
} }
/* Function vect_cost_group_size
For grouped load or store, return the group_size only if it is the first
load or store of a group, else return 1. This ensures that group size is
only returned once per group. */
static int
vect_cost_group_size (stmt_vec_info stmt_info)
{
gimple *first_stmt = GROUP_FIRST_ELEMENT (stmt_info);
if (first_stmt == STMT_VINFO_STMT (stmt_info))
return GROUP_SIZE (stmt_info);
return 1;
}
/* Function vect_model_store_cost /* Function vect_model_store_cost
Models cost for stores. In the case of grouped accesses, one access Models cost for stores. In the case of grouped accesses, one access
...@@ -895,47 +877,43 @@ vect_model_store_cost (stmt_vec_info stmt_info, int ncopies, ...@@ -895,47 +877,43 @@ vect_model_store_cost (stmt_vec_info stmt_info, int ncopies,
stmt_vector_for_cost *prologue_cost_vec, stmt_vector_for_cost *prologue_cost_vec,
stmt_vector_for_cost *body_cost_vec) stmt_vector_for_cost *body_cost_vec)
{ {
int group_size;
unsigned int inside_cost = 0, prologue_cost = 0; unsigned int inside_cost = 0, prologue_cost = 0;
struct data_reference *first_dr; struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
gimple *first_stmt; gimple *first_stmt = STMT_VINFO_STMT (stmt_info);
bool grouped_access_p = STMT_VINFO_GROUPED_ACCESS (stmt_info);
if (dt == vect_constant_def || dt == vect_external_def) if (dt == vect_constant_def || dt == vect_external_def)
prologue_cost += record_stmt_cost (prologue_cost_vec, 1, scalar_to_vec, prologue_cost += record_stmt_cost (prologue_cost_vec, 1, scalar_to_vec,
stmt_info, 0, vect_prologue); stmt_info, 0, vect_prologue);
/* Grouped access? */ /* Grouped stores update all elements in the group at once,
if (STMT_VINFO_GROUPED_ACCESS (stmt_info)) so we want the DR for the first statement. */
if (!slp_node && grouped_access_p)
{ {
if (slp_node) first_stmt = GROUP_FIRST_ELEMENT (stmt_info);
{ dr = STMT_VINFO_DATA_REF (vinfo_for_stmt (first_stmt));
first_stmt = SLP_TREE_SCALAR_STMTS (slp_node)[0];
group_size = 1;
}
else
{
first_stmt = GROUP_FIRST_ELEMENT (stmt_info);
group_size = vect_cost_group_size (stmt_info);
}
first_dr = STMT_VINFO_DATA_REF (vinfo_for_stmt (first_stmt));
}
/* Not a grouped access. */
else
{
group_size = 1;
first_dr = STMT_VINFO_DATA_REF (stmt_info);
} }
/* True if we should include any once-per-group costs as well as
the cost of the statement itself. For SLP we only get called
once per group anyhow. */
bool first_stmt_p = (first_stmt == STMT_VINFO_STMT (stmt_info));
/* We assume that the cost of a single store-lanes instruction is /* We assume that the cost of a single store-lanes instruction is
equivalent to the cost of GROUP_SIZE separate stores. If a grouped equivalent to the cost of GROUP_SIZE separate stores. If a grouped
access is instead being provided by a permute-and-store operation, access is instead being provided by a permute-and-store operation,
include the cost of the permutes. */ include the cost of the permutes.
if (!store_lanes_p && group_size > 1
&& !STMT_VINFO_STRIDED_P (stmt_info)) For SLP, the caller has already counted the permutation, if any. */
if (grouped_access_p
&& first_stmt_p
&& !store_lanes_p
&& !STMT_VINFO_STRIDED_P (stmt_info)
&& !slp_node)
{ {
/* Uses a high and low interleave or shuffle operations for each /* Uses a high and low interleave or shuffle operations for each
needed permute. */ needed permute. */
int group_size = GROUP_SIZE (vinfo_for_stmt (first_stmt));
int nstmts = ncopies * ceil_log2 (group_size) * group_size; int nstmts = ncopies * ceil_log2 (group_size) * group_size;
inside_cost = record_stmt_cost (body_cost_vec, nstmts, vec_perm, inside_cost = record_stmt_cost (body_cost_vec, nstmts, vec_perm,
stmt_info, 0, vect_body); stmt_info, 0, vect_body);
...@@ -957,7 +935,7 @@ vect_model_store_cost (stmt_vec_info stmt_info, int ncopies, ...@@ -957,7 +935,7 @@ vect_model_store_cost (stmt_vec_info stmt_info, int ncopies,
scalar_store, stmt_info, 0, vect_body); scalar_store, stmt_info, 0, vect_body);
} }
else else
vect_get_store_cost (first_dr, ncopies, &inside_cost, body_cost_vec); vect_get_store_cost (dr, ncopies, &inside_cost, body_cost_vec);
if (STMT_VINFO_STRIDED_P (stmt_info)) if (STMT_VINFO_STRIDED_P (stmt_info))
inside_cost += record_stmt_cost (body_cost_vec, inside_cost += record_stmt_cost (body_cost_vec,
...@@ -1026,8 +1004,8 @@ vect_get_store_cost (struct data_reference *dr, int ncopies, ...@@ -1026,8 +1004,8 @@ vect_get_store_cost (struct data_reference *dr, int ncopies,
/* Function vect_model_load_cost /* Function vect_model_load_cost
Models cost for loads. In the case of grouped accesses, the last access Models cost for loads. In the case of grouped accesses, one access has
has the overhead of the grouped access attributed to it. Since unaligned the overhead of the grouped access attributed to it. Since unaligned
accesses are supported for loads, we also account for the costs of the accesses are supported for loads, we also account for the costs of the
access scheme chosen. */ access scheme chosen. */
...@@ -1037,34 +1015,39 @@ vect_model_load_cost (stmt_vec_info stmt_info, int ncopies, ...@@ -1037,34 +1015,39 @@ vect_model_load_cost (stmt_vec_info stmt_info, int ncopies,
stmt_vector_for_cost *prologue_cost_vec, stmt_vector_for_cost *prologue_cost_vec,
stmt_vector_for_cost *body_cost_vec) stmt_vector_for_cost *body_cost_vec)
{ {
int group_size; gimple *first_stmt = STMT_VINFO_STMT (stmt_info);
gimple *first_stmt; struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info), *first_dr;
unsigned int inside_cost = 0, prologue_cost = 0; unsigned int inside_cost = 0, prologue_cost = 0;
bool grouped_access_p = STMT_VINFO_GROUPED_ACCESS (stmt_info);
/* Grouped accesses? */ /* Grouped loads read all elements in the group at once,
first_stmt = GROUP_FIRST_ELEMENT (stmt_info); so we want the DR for the first statement. */
if (STMT_VINFO_GROUPED_ACCESS (stmt_info) && first_stmt && !slp_node) if (!slp_node && grouped_access_p)
{ {
group_size = vect_cost_group_size (stmt_info); first_stmt = GROUP_FIRST_ELEMENT (stmt_info);
first_dr = STMT_VINFO_DATA_REF (vinfo_for_stmt (first_stmt)); dr = STMT_VINFO_DATA_REF (vinfo_for_stmt (first_stmt));
}
/* Not a grouped access. */
else
{
group_size = 1;
first_dr = dr;
} }
/* True if we should include any once-per-group costs as well as
the cost of the statement itself. For SLP we only get called
once per group anyhow. */
bool first_stmt_p = (first_stmt == STMT_VINFO_STMT (stmt_info));
/* We assume that the cost of a single load-lanes instruction is /* We assume that the cost of a single load-lanes instruction is
equivalent to the cost of GROUP_SIZE separate loads. If a grouped equivalent to the cost of GROUP_SIZE separate loads. If a grouped
access is instead being provided by a load-and-permute operation, access is instead being provided by a load-and-permute operation,
include the cost of the permutes. */ include the cost of the permutes.
if (!load_lanes_p && group_size > 1
&& !STMT_VINFO_STRIDED_P (stmt_info)) For SLP, the caller has already counted the permutation, if any. */
if (grouped_access_p
&& first_stmt_p
&& !load_lanes_p
&& !STMT_VINFO_STRIDED_P (stmt_info)
&& !slp_node)
{ {
/* Uses an even and odd extract operations or shuffle operations /* Uses an even and odd extract operations or shuffle operations
for each needed permute. */ for each needed permute. */
int group_size = GROUP_SIZE (vinfo_for_stmt (first_stmt));
int nstmts = ncopies * ceil_log2 (group_size) * group_size; int nstmts = ncopies * ceil_log2 (group_size) * group_size;
inside_cost = record_stmt_cost (body_cost_vec, nstmts, vec_perm, inside_cost = record_stmt_cost (body_cost_vec, nstmts, vec_perm,
stmt_info, 0, vect_body); stmt_info, 0, vect_body);
...@@ -1086,14 +1069,12 @@ vect_model_load_cost (stmt_vec_info stmt_info, int ncopies, ...@@ -1086,14 +1069,12 @@ vect_model_load_cost (stmt_vec_info stmt_info, int ncopies,
scalar_load, stmt_info, 0, vect_body); scalar_load, stmt_info, 0, vect_body);
} }
else else
vect_get_load_cost (first_dr, ncopies, vect_get_load_cost (dr, ncopies, first_stmt_p,
((!STMT_VINFO_GROUPED_ACCESS (stmt_info))
|| group_size > 1 || slp_node),
&inside_cost, &prologue_cost, &inside_cost, &prologue_cost,
prologue_cost_vec, body_cost_vec, true); prologue_cost_vec, body_cost_vec, true);
if (STMT_VINFO_STRIDED_P (stmt_info)) if (STMT_VINFO_STRIDED_P (stmt_info))
inside_cost += record_stmt_cost (body_cost_vec, ncopies, vec_construct, inside_cost += record_stmt_cost (body_cost_vec, ncopies, vec_construct,
stmt_info, 0, vect_body); stmt_info, 0, vect_body);
if (dump_enabled_p ()) if (dump_enabled_p ())
dump_printf_loc (MSG_NOTE, vect_location, dump_printf_loc (MSG_NOTE, vect_location,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment