aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-vectorizer.h
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-vectorizer.h')
-rw-r--r--gcc/tree-vectorizer.h141
1 files changed, 116 insertions, 25 deletions
diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
index 73347ce..76e22ee 100644
--- a/gcc/tree-vectorizer.h
+++ b/gcc/tree-vectorizer.h
@@ -368,7 +368,7 @@ public:
typedef hash_set<int_hash<machine_mode, E_VOIDmode, E_BLKmode> > mode_set;
enum vec_kind { bb, loop };
- vec_info (vec_kind, void *, vec_info_shared *);
+ vec_info (vec_kind, vec_info_shared *);
~vec_info ();
stmt_vec_info add_stmt (gimple *);
@@ -406,7 +406,7 @@ public:
auto_vec<stmt_vec_info> grouped_stores;
/* Cost data used by the target cost model. */
- void *target_cost_data;
+ class vector_costs *target_cost_data;
/* The set of vector modes used in the vectorized region. */
mode_set used_vector_modes;
@@ -1395,6 +1395,103 @@ struct gather_scatter_info {
#define PURE_SLP_STMT(S) ((S)->slp_type == pure_slp)
#define STMT_SLP_TYPE(S) (S)->slp_type
+/* Contains the scalar or vector costs for a vec_info. */
+class vector_costs
+{
+public:
+ vector_costs (vec_info *, bool);
+ virtual ~vector_costs () {}
+
+ /* Update the costs in response to adding COUNT copies of a statement.
+
+ - WHERE specifies whether the cost occurs in the loop prologue,
+ the loop body, or the loop epilogue.
+ - KIND is the kind of statement, which is always meaningful.
+ - STMT_INFO, if nonnull, describes the statement that will be
+ vectorized.
+ - VECTYPE, if nonnull, is the vector type that the vectorized
+ statement will operate on. Note that this should be used in
+ preference to STMT_VINFO_VECTYPE (STMT_INFO) since the latter
+ is not correct for SLP.
+ - for unaligned_load and unaligned_store statements, MISALIGN is
+ the byte misalignment of the load or store relative to the target's
+ preferred alignment for VECTYPE, or DR_MISALIGNMENT_UNKNOWN
+ if the misalignment is not known.
+
+ Return the calculated cost as well as recording it. The return
+ value is used for dumping purposes. */
+ virtual unsigned int add_stmt_cost (int count, vect_cost_for_stmt kind,
+ stmt_vec_info stmt_info, tree vectype,
+ int misalign,
+ vect_cost_model_location where);
+
+ /* Finish calculating the cost of the code. The results can be
+ read back using the functions below. */
+ virtual void finish_cost ();
+
+ unsigned int prologue_cost () const;
+ unsigned int body_cost () const;
+ unsigned int epilogue_cost () const;
+
+protected:
+ unsigned int record_stmt_cost (stmt_vec_info, vect_cost_model_location,
+ unsigned int);
+ unsigned int adjust_cost_for_freq (stmt_vec_info, vect_cost_model_location,
+ unsigned int);
+
+ /* The region of code that we're considering vectorizing. */
+ vec_info *m_vinfo;
+
+ /* True if we're costing the scalar code, false if we're costing
+ the vector code. */
+ bool m_costing_for_scalar;
+
+ /* The costs of the three regions, indexed by vect_cost_model_location. */
+ unsigned int m_costs[3];
+
+ /* True if finish_cost has been called. */
+ bool m_finished;
+};
+
+/* Create costs for VINFO. COSTING_FOR_SCALAR is true if the costs
+ are for scalar code, false if they are for vector code. */
+
+inline
+vector_costs::vector_costs (vec_info *vinfo, bool costing_for_scalar)
+ : m_vinfo (vinfo),
+ m_costing_for_scalar (costing_for_scalar),
+ m_costs (),
+ m_finished (false)
+{
+}
+
+/* Return the cost of the prologue code (in abstract units). */
+
+inline unsigned int
+vector_costs::prologue_cost () const
+{
+ gcc_checking_assert (m_finished);
+ return m_costs[vect_prologue];
+}
+
+/* Return the cost of the body code (in abstract units). */
+
+inline unsigned int
+vector_costs::body_cost () const
+{
+ gcc_checking_assert (m_finished);
+ return m_costs[vect_body];
+}
+
+/* Return the cost of the epilogue code (in abstract units). */
+
+inline unsigned int
+vector_costs::epilogue_cost () const
+{
+ gcc_checking_assert (m_finished);
+ return m_costs[vect_epilogue];
+}
+
#define VECT_MAX_COST 1000
/* The maximum number of intermediate steps required in multi-step type
@@ -1531,29 +1628,28 @@ 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, bool costing_for_scalar)
+static inline vector_costs *
+init_cost (vec_info *vinfo, bool costing_for_scalar)
{
- return targetm.vectorize.init_cost (loop_info, costing_for_scalar);
+ return targetm.vectorize.create_costs (vinfo, costing_for_scalar);
}
-extern void dump_stmt_cost (FILE *, void *, int, enum vect_cost_for_stmt,
+extern void dump_stmt_cost (FILE *, int, enum vect_cost_for_stmt,
stmt_vec_info, tree, int, unsigned,
enum vect_cost_model_location);
/* Alias targetm.vectorize.add_stmt_cost. */
static inline unsigned
-add_stmt_cost (vec_info *vinfo, void *data, int count,
+add_stmt_cost (vector_costs *costs, int count,
enum vect_cost_for_stmt kind,
stmt_vec_info stmt_info, tree vectype, int misalign,
enum vect_cost_model_location where)
{
- unsigned cost = targetm.vectorize.add_stmt_cost (vinfo, data, count, kind,
- stmt_info, vectype,
- misalign, where);
+ unsigned cost = costs->add_stmt_cost (count, kind, stmt_info, vectype,
+ misalign, where);
if (dump_file && (dump_flags & TDF_DETAILS))
- dump_stmt_cost (dump_file, data, count, kind, stmt_info, vectype, misalign,
+ dump_stmt_cost (dump_file, count, kind, stmt_info, vectype, misalign,
cost, where);
return cost;
}
@@ -1561,36 +1657,31 @@ add_stmt_cost (vec_info *vinfo, void *data, int count,
/* Alias targetm.vectorize.add_stmt_cost. */
static inline unsigned
-add_stmt_cost (vec_info *vinfo, void *data, stmt_info_for_cost *i)
+add_stmt_cost (vector_costs *costs, stmt_info_for_cost *i)
{
- return add_stmt_cost (vinfo, data, i->count, i->kind, i->stmt_info,
+ return add_stmt_cost (costs, i->count, i->kind, i->stmt_info,
i->vectype, i->misalign, i->where);
}
/* Alias targetm.vectorize.finish_cost. */
static inline void
-finish_cost (void *data, unsigned *prologue_cost,
+finish_cost (vector_costs *costs, unsigned *prologue_cost,
unsigned *body_cost, unsigned *epilogue_cost)
{
- targetm.vectorize.finish_cost (data, prologue_cost, body_cost, epilogue_cost);
-}
-
-/* Alias targetm.vectorize.destroy_cost_data. */
-
-static inline void
-destroy_cost_data (void *data)
-{
- targetm.vectorize.destroy_cost_data (data);
+ costs->finish_cost ();
+ *prologue_cost = costs->prologue_cost ();
+ *body_cost = costs->body_cost ();
+ *epilogue_cost = costs->epilogue_cost ();
}
inline void
-add_stmt_costs (vec_info *vinfo, void *data, stmt_vector_for_cost *cost_vec)
+add_stmt_costs (vector_costs *costs, stmt_vector_for_cost *cost_vec)
{
stmt_info_for_cost *cost;
unsigned i;
FOR_EACH_VEC_ELT (*cost_vec, i, cost)
- add_stmt_cost (vinfo, data, cost->count, cost->kind, cost->stmt_info,
+ add_stmt_cost (costs, cost->count, cost->kind, cost->stmt_info,
cost->vectype, cost->misalign, cost->where);
}