diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index 04855cbd576..85fd80e29bb 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -14388,7 +14388,7 @@ struct aarch64_vector_costs /* Implement TARGET_VECTORIZE_INIT_COST. */ void * -aarch64_init_cost (class loop *) +aarch64_init_cost (class loop *, bool) { return new aarch64_vector_costs; } diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index ecc15358efe..915f89f571a 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -22289,7 +22289,7 @@ ix86_noce_conversion_profitable_p (rtx_insn *seq, struct noce_if_info *if_info) /* Implement targetm.vectorize.init_cost. */ static void * -ix86_init_cost (class loop *) +ix86_init_cost (class loop *, bool) { unsigned *cost = XNEWVEC (unsigned, 3); cost[vect_prologue] = cost[vect_body] = cost[vect_epilogue] = 0; diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 96d0166d833..1ef5149ad2e 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -5296,7 +5296,7 @@ rs6000_density_test (rs6000_cost_data *data) /* Implement targetm.vectorize.init_cost. */ static void * -rs6000_init_cost (struct loop *loop_info) +rs6000_init_cost (struct loop *loop_info, bool) { rs6000_cost_data *data = XNEW (struct _rs6000_cost_data); data->loop_info = loop_info; diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 5f273097169..85ea9395560 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -6120,8 +6120,8 @@ type @code{internal_fn}) should be considered expensive when the mask is all zeros. GCC can then try to branch around the instruction instead. @end deftypefn -@deftypefn {Target Hook} {void *} TARGET_VECTORIZE_INIT_COST (class loop *@var{loop_info}) -This hook should initialize target-specific data structures in preparation for modeling the costs of vectorizing a loop or basic block. The default allocates three unsigned integers for accumulating costs for the prologue, body, and epilogue of the loop or basic block. If @var{loop_info} is non-NULL, it identifies the loop being vectorized; otherwise a single block is being vectorized. +@deftypefn {Target Hook} {void *} TARGET_VECTORIZE_INIT_COST (class loop *@var{loop_info}, bool @var{costing_for_scalar}) +This hook should initialize target-specific data structures in preparation for modeling the costs of vectorizing a loop or basic block. The default allocates three unsigned integers for accumulating costs for the prologue, body, and epilogue of the loop or basic block. If @var{loop_info} is non-NULL, it identifies the loop being vectorized; otherwise a single block is being vectorized. If @var{costing_for_scalar} is true, it indicates the current cost model is for the scalar version of a loop or block; otherwise it is for the vector version. @end deftypefn @deftypefn {Target Hook} unsigned TARGET_VECTORIZE_ADD_STMT_COST (class vec_info *@var{}, void *@var{data}, int @var{count}, enum vect_cost_for_stmt @var{kind}, class _stmt_vec_info *@var{stmt_info}, tree @var{vectype}, int @var{misalign}, enum vect_cost_model_location @var{where}) diff --git a/gcc/target.def b/gcc/target.def index a902a50755b..bbaf6b4f3a0 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -2004,9 +2004,11 @@ DEFHOOK "allocates three unsigned integers for accumulating costs for the prologue, " "body, and epilogue of the loop or basic block. If @var{loop_info} is " "non-NULL, it identifies the loop being vectorized; otherwise a single block " - "is being vectorized.", + "is being vectorized. If @var{costing_for_scalar} is true, it indicates the " + "current cost model is for the scalar version of a loop or block; otherwise " + "it is for the vector version.", void *, - (class loop *loop_info), + (class loop *loop_info, bool costing_for_scalar), default_init_cost) /* Target function to record N statements of the given kind using the diff --git a/gcc/targhooks.c b/gcc/targhooks.c index 952fad422eb..2e0fdb797e0 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -1373,7 +1373,8 @@ default_empty_mask_is_expensive (unsigned ifn) array of three unsigned ints, set it to zero, and return its address. */ void * -default_init_cost (class loop *loop_info ATTRIBUTE_UNUSED) +default_init_cost (class loop *loop_info ATTRIBUTE_UNUSED, + bool costing_for_scalar ATTRIBUTE_UNUSED) { unsigned *cost = XNEWVEC (unsigned, 3); cost[vect_prologue] = cost[vect_body] = cost[vect_epilogue] = 0; diff --git a/gcc/targhooks.h b/gcc/targhooks.h index 9928d064abd..b537038c0aa 100644 --- a/gcc/targhooks.h +++ b/gcc/targhooks.h @@ -117,7 +117,7 @@ extern opt_machine_mode default_vectorize_related_mode (machine_mode, poly_uint64); extern opt_machine_mode default_get_mask_mode (machine_mode); extern bool default_empty_mask_is_expensive (unsigned); -extern void *default_init_cost (class loop *); +extern void *default_init_cost (class loop *, bool); extern unsigned default_add_stmt_cost (class vec_info *, void *, int, enum vect_cost_for_stmt, class _stmt_vec_info *, tree, int, diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c index 2aba503fef7..f10e66a2465 100644 --- a/gcc/tree-vect-loop.c +++ b/gcc/tree-vect-loop.c @@ -813,7 +813,7 @@ bb_in_loop_p (const_basic_block bb, const void *data) stmt_vec_info structs for all the stmts in LOOP_IN. */ _loop_vec_info::_loop_vec_info (class loop *loop_in, vec_info_shared *shared) - : vec_info (vec_info::loop, init_cost (loop_in), shared), + : vec_info (vec_info::loop, init_cost (loop_in, false), shared), loop (loop_in), bbs (XCNEWVEC (basic_block, loop->num_nodes)), num_itersm1 (NULL_TREE), @@ -1284,7 +1284,7 @@ vect_compute_single_scalar_iteration_cost (loop_vec_info loop_vinfo) } /* Now accumulate cost. */ - void *target_cost_data = init_cost (loop); + void *target_cost_data = init_cost (loop, true); stmt_info_for_cost *si; int j; FOR_EACH_VEC_ELT (LOOP_VINFO_SCALAR_ITERATION_COST (loop_vinfo), @@ -2723,7 +2723,7 @@ again: /* Reset target cost data. */ destroy_cost_data (LOOP_VINFO_TARGET_COST_DATA (loop_vinfo)); LOOP_VINFO_TARGET_COST_DATA (loop_vinfo) - = init_cost (LOOP_VINFO_LOOP (loop_vinfo)); + = init_cost (LOOP_VINFO_LOOP (loop_vinfo), false); /* Reset accumulated rgroup information. */ release_vec_loop_controls (&LOOP_VINFO_MASKS (loop_vinfo)); release_vec_loop_controls (&LOOP_VINFO_LENS (loop_vinfo)); diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c index 1c5b7ae84e2..0ec92b0f0ca 100644 --- a/gcc/tree-vect-slp.c +++ b/gcc/tree-vect-slp.c @@ -3690,7 +3690,9 @@ vect_detect_hybrid_slp (loop_vec_info loop_vinfo) /* Initialize a bb_vec_info struct for the statements in BBS basic blocks. */ _bb_vec_info::_bb_vec_info (vec _bbs, vec_info_shared *shared) - : vec_info (vec_info::bb, init_cost (NULL), shared), bbs (_bbs), roots (vNULL) + : vec_info (vec_info::bb, init_cost (NULL, false), shared), + bbs (_bbs), + roots (vNULL) { for (unsigned i = 0; i < bbs.length (); ++i) { @@ -4530,7 +4532,7 @@ vect_bb_vectorization_profitable_p (bb_vec_info bb_vinfo, continue; } - void *scalar_target_cost_data = init_cost (NULL); + void *scalar_target_cost_data = init_cost (NULL, true); do { add_stmt_cost (bb_vinfo, scalar_target_cost_data, @@ -4544,7 +4546,7 @@ vect_bb_vectorization_profitable_p (bb_vec_info bb_vinfo, destroy_cost_data (scalar_target_cost_data); /* Complete the target-specific vector cost calculation. */ - void *vect_target_cost_data = init_cost (NULL); + void *vect_target_cost_data = init_cost (NULL, false); do { add_stmt_cost (bb_vinfo, vect_target_cost_data, diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h index 9861d9e8810..8d1ffafdbf0 100644 --- a/gcc/tree-vectorizer.h +++ b/gcc/tree-vectorizer.h @@ -1455,9 +1455,9 @@ int vect_get_stmt_cost (enum vect_cost_for_stmt type_of_cost) /* Alias targetm.vectorize.init_cost. */ static inline void * -init_cost (class loop *loop_info) +init_cost (class loop *loop_info, bool costing_for_scalar) { - return targetm.vectorize.init_cost (loop_info); + return targetm.vectorize.init_cost (loop_info, costing_for_scalar); } extern void dump_stmt_cost (FILE *, void *, int, enum vect_cost_for_stmt,