Commit 6d098c57 by Richard Biener Committed by Richard Biener

tree-vectorizer.h (_loop_vec_info): Add scalar_cost_vec and single_scalar_iteration_cost members.

2015-06-22  Richard Biener  <rguenther@suse.de>

	* tree-vectorizer.h (_loop_vec_info): Add scalar_cost_vec
	and single_scalar_iteration_cost members.
	(LOOP_VINFO_SCALAR_ITERATION_COST): New.
	(LOOP_VINFO_SINGLE_SCALAR_ITERATION_COST): Likewise.
	(vect_get_single_scalar_iteration_cost): Remove.
	* tree-vect-data-refs.c (vect_peeling_hash_get_lowest_cost):
	Use LOOP_VINFO_SCALAR_ITERATION_COST.
	* tree-vect-loop.c (destroy_loop_vec_info): Free
	scalar_cost_vec.
	(vect_get_single_scalar_iteration_cost): Compute result into
	LOOP_VINFO_SINGLE_SCALAR_ITERATION_COST and
	LOOP_VINFO_SCALAR_ITERATION_COST.  Make static.
	(vect_analyze_loop_2): Call vect_get_single_scalar_iteration_cost.
	(vect_estimate_min_profitable_iters): Use them.

From-SVN: r224723
parent 606e3099
2015-06-22 Richard Biener <rguenther@suse.de>
* tree-vectorizer.h (_loop_vec_info): Add scalar_cost_vec
and single_scalar_iteration_cost members.
(LOOP_VINFO_SCALAR_ITERATION_COST): New.
(LOOP_VINFO_SINGLE_SCALAR_ITERATION_COST): Likewise.
(vect_get_single_scalar_iteration_cost): Remove.
* tree-vect-data-refs.c (vect_peeling_hash_get_lowest_cost):
Use LOOP_VINFO_SCALAR_ITERATION_COST.
* tree-vect-loop.c (destroy_loop_vec_info): Free
scalar_cost_vec.
(vect_get_single_scalar_iteration_cost): Compute result into
LOOP_VINFO_SINGLE_SCALAR_ITERATION_COST and
LOOP_VINFO_SCALAR_ITERATION_COST. Make static.
(vect_analyze_loop_2): Call vect_get_single_scalar_iteration_cost.
(vect_estimate_min_profitable_iters): Use them.
2015-06-22 Christian Bruel <christian.bruel@st.com> 2015-06-22 Christian Bruel <christian.bruel@st.com>
PR target/52144 PR target/52144
......
...@@ -1165,11 +1165,10 @@ vect_peeling_hash_get_lowest_cost (_vect_peel_info **slot, ...@@ -1165,11 +1165,10 @@ vect_peeling_hash_get_lowest_cost (_vect_peel_info **slot,
SET_DR_MISALIGNMENT (dr, save_misalignment); SET_DR_MISALIGNMENT (dr, save_misalignment);
} }
auto_vec<stmt_info_for_cost> scalar_cost_vec;
vect_get_single_scalar_iteration_cost (loop_vinfo, &scalar_cost_vec);
outside_cost += vect_get_known_peeling_cost outside_cost += vect_get_known_peeling_cost
(loop_vinfo, elem->npeel, &dummy, (loop_vinfo, elem->npeel, &dummy,
&scalar_cost_vec, &prologue_cost_vec, &epilogue_cost_vec); &LOOP_VINFO_SCALAR_ITERATION_COST (loop_vinfo),
&prologue_cost_vec, &epilogue_cost_vec);
/* Prologue and epilogue costs are added to the target model later. /* Prologue and epilogue costs are added to the target model later.
These costs depend only on the scalar iteration cost, the These costs depend only on the scalar iteration cost, the
......
...@@ -1095,12 +1095,82 @@ destroy_loop_vec_info (loop_vec_info loop_vinfo, bool clean_stmts) ...@@ -1095,12 +1095,82 @@ destroy_loop_vec_info (loop_vec_info loop_vinfo, bool clean_stmts)
LOOP_VINFO_PEELING_HTAB (loop_vinfo) = NULL; LOOP_VINFO_PEELING_HTAB (loop_vinfo) = NULL;
destroy_cost_data (LOOP_VINFO_TARGET_COST_DATA (loop_vinfo)); destroy_cost_data (LOOP_VINFO_TARGET_COST_DATA (loop_vinfo));
loop_vinfo->scalar_cost_vec.release ();
free (loop_vinfo); free (loop_vinfo);
loop->aux = NULL; loop->aux = NULL;
} }
/* Calculate the cost of one scalar iteration of the loop. */
static void
vect_get_single_scalar_iteration_cost (loop_vec_info loop_vinfo)
{
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
int nbbs = loop->num_nodes, factor, scalar_single_iter_cost = 0;
int innerloop_iters, i;
/* Count statements in scalar loop. Using this as scalar cost for a single
iteration for now.
TODO: Add outer loop support.
TODO: Consider assigning different costs to different scalar
statements. */
/* FORNOW. */
innerloop_iters = 1;
if (loop->inner)
innerloop_iters = 50; /* FIXME */
for (i = 0; i < nbbs; i++)
{
gimple_stmt_iterator si;
basic_block bb = bbs[i];
if (bb->loop_father == loop->inner)
factor = innerloop_iters;
else
factor = 1;
for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
{
gimple stmt = gsi_stmt (si);
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
if (!is_gimple_assign (stmt) && !is_gimple_call (stmt))
continue;
/* Skip stmts that are not vectorized inside the loop. */
if (stmt_info
&& !STMT_VINFO_RELEVANT_P (stmt_info)
&& (!STMT_VINFO_LIVE_P (stmt_info)
|| !VECTORIZABLE_CYCLE_DEF (STMT_VINFO_DEF_TYPE (stmt_info)))
&& !STMT_VINFO_IN_PATTERN_P (stmt_info))
continue;
vect_cost_for_stmt kind;
if (STMT_VINFO_DATA_REF (vinfo_for_stmt (stmt)))
{
if (DR_IS_READ (STMT_VINFO_DATA_REF (vinfo_for_stmt (stmt))))
kind = scalar_load;
else
kind = scalar_store;
}
else
kind = scalar_stmt;
scalar_single_iter_cost
+= record_stmt_cost (&LOOP_VINFO_SCALAR_ITERATION_COST (loop_vinfo),
factor, kind, NULL, 0, vect_prologue);
}
}
LOOP_VINFO_SINGLE_SCALAR_ITERATION_COST (loop_vinfo)
= scalar_single_iter_cost;
}
/* Function vect_analyze_loop_1. /* Function vect_analyze_loop_1.
Apply a set of analyses on LOOP, and create a loop_vec_info struct Apply a set of analyses on LOOP, and create a loop_vec_info struct
...@@ -1834,6 +1904,9 @@ vect_analyze_loop_2 (loop_vec_info loop_vinfo) ...@@ -1834,6 +1904,9 @@ vect_analyze_loop_2 (loop_vec_info loop_vinfo)
return false; return false;
} }
/* Compute the scalar iteration cost. */
vect_get_single_scalar_iteration_cost (loop_vinfo);
/* This pass will decide on using loop versioning and/or loop peeling in /* This pass will decide on using loop versioning and/or loop peeling in
order to enhance the alignment of data references in the loop. */ order to enhance the alignment of data references in the loop. */
...@@ -2706,74 +2779,6 @@ vect_force_simple_reduction (loop_vec_info loop_info, gimple phi, ...@@ -2706,74 +2779,6 @@ vect_force_simple_reduction (loop_vec_info loop_info, gimple phi,
double_reduc, true); double_reduc, true);
} }
/* Calculate the cost of one scalar iteration of the loop. */
int
vect_get_single_scalar_iteration_cost (loop_vec_info loop_vinfo,
stmt_vector_for_cost *scalar_cost_vec)
{
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
int nbbs = loop->num_nodes, factor, scalar_single_iter_cost = 0;
int innerloop_iters, i;
/* Count statements in scalar loop. Using this as scalar cost for a single
iteration for now.
TODO: Add outer loop support.
TODO: Consider assigning different costs to different scalar
statements. */
/* FORNOW. */
innerloop_iters = 1;
if (loop->inner)
innerloop_iters = 50; /* FIXME */
for (i = 0; i < nbbs; i++)
{
gimple_stmt_iterator si;
basic_block bb = bbs[i];
if (bb->loop_father == loop->inner)
factor = innerloop_iters;
else
factor = 1;
for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
{
gimple stmt = gsi_stmt (si);
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
if (!is_gimple_assign (stmt) && !is_gimple_call (stmt))
continue;
/* Skip stmts that are not vectorized inside the loop. */
if (stmt_info
&& !STMT_VINFO_RELEVANT_P (stmt_info)
&& (!STMT_VINFO_LIVE_P (stmt_info)
|| !VECTORIZABLE_CYCLE_DEF (STMT_VINFO_DEF_TYPE (stmt_info)))
&& !STMT_VINFO_IN_PATTERN_P (stmt_info))
continue;
vect_cost_for_stmt kind;
if (STMT_VINFO_DATA_REF (vinfo_for_stmt (stmt)))
{
if (DR_IS_READ (STMT_VINFO_DATA_REF (vinfo_for_stmt (stmt))))
kind = scalar_load;
else
kind = scalar_store;
}
else
kind = scalar_stmt;
scalar_single_iter_cost
+= record_stmt_cost (scalar_cost_vec, factor, kind,
NULL, 0, vect_prologue);
}
}
return scalar_single_iter_cost;
}
/* Calculate cost of peeling the loop PEEL_ITERS_PROLOGUE times. */ /* Calculate cost of peeling the loop PEEL_ITERS_PROLOGUE times. */
int int
vect_get_known_peeling_cost (loop_vec_info loop_vinfo, int peel_iters_prologue, vect_get_known_peeling_cost (loop_vec_info loop_vinfo, int peel_iters_prologue,
...@@ -2901,9 +2906,8 @@ vect_estimate_min_profitable_iters (loop_vec_info loop_vinfo, ...@@ -2901,9 +2906,8 @@ vect_estimate_min_profitable_iters (loop_vec_info loop_vinfo,
TODO: Consider assigning different costs to different scalar TODO: Consider assigning different costs to different scalar
statements. */ statements. */
auto_vec<stmt_info_for_cost> scalar_cost_vec;
scalar_single_iter_cost scalar_single_iter_cost
= vect_get_single_scalar_iteration_cost (loop_vinfo, &scalar_cost_vec); = LOOP_VINFO_SINGLE_SCALAR_ITERATION_COST (loop_vinfo);
/* Add additional cost for the peeled instructions in prologue and epilogue /* Add additional cost for the peeled instructions in prologue and epilogue
loop. loop.
...@@ -2941,7 +2945,7 @@ vect_estimate_min_profitable_iters (loop_vec_info loop_vinfo, ...@@ -2941,7 +2945,7 @@ vect_estimate_min_profitable_iters (loop_vec_info loop_vinfo,
NULL, 0, vect_epilogue); NULL, 0, vect_epilogue);
stmt_info_for_cost *si; stmt_info_for_cost *si;
int j; int j;
FOR_EACH_VEC_ELT (scalar_cost_vec, j, si) FOR_EACH_VEC_ELT (LOOP_VINFO_SCALAR_ITERATION_COST (loop_vinfo), j, si)
{ {
struct _stmt_vec_info *stmt_info struct _stmt_vec_info *stmt_info
= si->stmt ? vinfo_for_stmt (si->stmt) : NULL; = si->stmt ? vinfo_for_stmt (si->stmt) : NULL;
...@@ -2968,7 +2972,8 @@ vect_estimate_min_profitable_iters (loop_vec_info loop_vinfo, ...@@ -2968,7 +2972,8 @@ vect_estimate_min_profitable_iters (loop_vec_info loop_vinfo,
(void) vect_get_known_peeling_cost (loop_vinfo, peel_iters_prologue, (void) vect_get_known_peeling_cost (loop_vinfo, peel_iters_prologue,
&peel_iters_epilogue, &peel_iters_epilogue,
&scalar_cost_vec, &LOOP_VINFO_SCALAR_ITERATION_COST
(loop_vinfo),
&prologue_cost_vec, &prologue_cost_vec,
&epilogue_cost_vec); &epilogue_cost_vec);
......
...@@ -328,6 +328,12 @@ typedef struct _loop_vec_info { ...@@ -328,6 +328,12 @@ typedef struct _loop_vec_info {
/* Hash table used to choose the best peeling option. */ /* Hash table used to choose the best peeling option. */
hash_table<peel_info_hasher> *peeling_htab; hash_table<peel_info_hasher> *peeling_htab;
/* Cost vector for a single scalar iteration. */
vec<stmt_info_for_cost> scalar_cost_vec;
/* Cost of a single scalar iteration. */
int single_scalar_iteration_cost;
/* Cost data used by the target cost model. */ /* Cost data used by the target cost model. */
void *target_cost_data; void *target_cost_data;
...@@ -406,6 +412,8 @@ typedef struct _loop_vec_info { ...@@ -406,6 +412,8 @@ typedef struct _loop_vec_info {
#define LOOP_VINFO_PEELING_FOR_NITER(L) (L)->peeling_for_niter #define LOOP_VINFO_PEELING_FOR_NITER(L) (L)->peeling_for_niter
#define LOOP_VINFO_NO_DATA_DEPENDENCIES(L) (L)->no_data_dependencies #define LOOP_VINFO_NO_DATA_DEPENDENCIES(L) (L)->no_data_dependencies
#define LOOP_VINFO_SCALAR_LOOP(L) (L)->scalar_loop #define LOOP_VINFO_SCALAR_LOOP(L) (L)->scalar_loop
#define LOOP_VINFO_SCALAR_ITERATION_COST(L) (L)->scalar_cost_vec
#define LOOP_VINFO_SINGLE_SCALAR_ITERATION_COST(L) (L)->single_scalar_iteration_cost
#define LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT(L) \ #define LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT(L) \
((L)->may_misalign_stmts.length () > 0) ((L)->may_misalign_stmts.length () > 0)
...@@ -1101,8 +1109,6 @@ extern int vect_get_known_peeling_cost (loop_vec_info, int, int *, ...@@ -1101,8 +1109,6 @@ extern int vect_get_known_peeling_cost (loop_vec_info, int, int *,
stmt_vector_for_cost *, stmt_vector_for_cost *,
stmt_vector_for_cost *, stmt_vector_for_cost *,
stmt_vector_for_cost *); stmt_vector_for_cost *);
extern int vect_get_single_scalar_iteration_cost (loop_vec_info,
stmt_vector_for_cost *);
/* In tree-vect-slp.c. */ /* In tree-vect-slp.c. */
extern void vect_free_slp_instance (slp_instance); extern void vect_free_slp_instance (slp_instance);
......
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