From 6d098c572aef870f6a068d7e6697fde5a4ed2ccc Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Mon, 22 Jun 2015 10:44:02 +0000 Subject: [PATCH] tree-vectorizer.h (_loop_vec_info): Add scalar_cost_vec and single_scalar_iteration_cost members. 2015-06-22 Richard Biener * 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 --- gcc/ChangeLog | 17 +++++ gcc/tree-vect-data-refs.c | 5 +- gcc/tree-vect-loop.c | 149 ++++++++++++++++++++------------------ gcc/tree-vectorizer.h | 10 ++- 4 files changed, 104 insertions(+), 77 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 14f3121a82d..9dc3b9159e4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,20 @@ +2015-06-22 Richard Biener + + * 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 PR target/52144 diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c index b626e383f3b..ae474566992 100644 --- a/gcc/tree-vect-data-refs.c +++ b/gcc/tree-vect-data-refs.c @@ -1165,11 +1165,10 @@ vect_peeling_hash_get_lowest_cost (_vect_peel_info **slot, SET_DR_MISALIGNMENT (dr, save_misalignment); } - auto_vec scalar_cost_vec; - vect_get_single_scalar_iteration_cost (loop_vinfo, &scalar_cost_vec); outside_cost += vect_get_known_peeling_cost (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. These costs depend only on the scalar iteration cost, the diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c index 4b01ade1398..1256fe2acf3 100644 --- a/gcc/tree-vect-loop.c +++ b/gcc/tree-vect-loop.c @@ -1095,12 +1095,82 @@ destroy_loop_vec_info (loop_vec_info loop_vinfo, bool clean_stmts) LOOP_VINFO_PEELING_HTAB (loop_vinfo) = NULL; destroy_cost_data (LOOP_VINFO_TARGET_COST_DATA (loop_vinfo)); + loop_vinfo->scalar_cost_vec.release (); free (loop_vinfo); 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. 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) 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 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, 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. */ int 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, TODO: Consider assigning different costs to different scalar statements. */ - auto_vec scalar_cost_vec; 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 loop. @@ -2941,7 +2945,7 @@ vect_estimate_min_profitable_iters (loop_vec_info loop_vinfo, NULL, 0, vect_epilogue); stmt_info_for_cost *si; 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 = si->stmt ? vinfo_for_stmt (si->stmt) : NULL; @@ -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, &peel_iters_epilogue, - &scalar_cost_vec, + &LOOP_VINFO_SCALAR_ITERATION_COST + (loop_vinfo), &prologue_cost_vec, &epilogue_cost_vec); diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h index b7ce9416a38..d3e788b8785 100644 --- a/gcc/tree-vectorizer.h +++ b/gcc/tree-vectorizer.h @@ -328,6 +328,12 @@ typedef struct _loop_vec_info { /* Hash table used to choose the best peeling option. */ hash_table *peeling_htab; + /* Cost vector for a single scalar iteration. */ + vec scalar_cost_vec; + + /* Cost of a single scalar iteration. */ + int single_scalar_iteration_cost; + /* Cost data used by the target cost model. */ void *target_cost_data; @@ -406,6 +412,8 @@ typedef struct _loop_vec_info { #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_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) \ ((L)->may_misalign_stmts.length () > 0) @@ -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 *); -extern int vect_get_single_scalar_iteration_cost (loop_vec_info, - stmt_vector_for_cost *); /* In tree-vect-slp.c. */ extern void vect_free_slp_instance (slp_instance); -- 2.30.2