STMT 5 (be vectorized) -- point 2
...
*/
-static void
-compute_local_program_points (
+void
+costs::compute_local_program_points (
vec_info *vinfo,
hash_map<basic_block, vec<stmt_point>> &program_points_per_bb)
{
/* Return true if the variable should be counted into liveness. */
static bool
-variable_vectorized_p (class loop *loop, stmt_vec_info stmt_info, tree var,
- bool lhs_p)
+variable_vectorized_p (class loop *loop, stmt_vec_info stmt_info,
+ slp_tree node ATTRIBUTE_UNUSED, tree var, bool lhs_p)
{
if (!var)
return false;
gimple *stmt = STMT_VINFO_STMT (stmt_info);
- enum stmt_vec_info_type type
- = STMT_VINFO_TYPE (vect_stmt_to_vectorize (stmt_info));
+ stmt_info = vect_stmt_to_vectorize (stmt_info);
+ enum stmt_vec_info_type type = STMT_VINFO_TYPE (stmt_info);
if (is_gimple_call (stmt) && gimple_call_internal_p (stmt))
{
if (gimple_call_internal_fn (stmt) == IFN_MASK_STORE
The live range of SSA 1 is [1, 3] in bb 2.
The live range of SSA 2 is [0, 4] in bb 3. */
-static machine_mode
-compute_local_live_ranges (
+machine_mode
+costs::compute_local_live_ranges (
loop_vec_info loop_vinfo,
const hash_map<basic_block, vec<stmt_point>> &program_points_per_bb,
hash_map<basic_block, hash_map<tree, pair>> &live_ranges_per_bb)
unsigned int point = program_point.point;
gimple *stmt = program_point.stmt;
tree lhs = gimple_get_lhs (stmt);
- if (variable_vectorized_p (loop, program_point.stmt_info, lhs,
- true))
+ slp_tree *node = vinfo_slp_map.get (program_point.stmt_info);
+ if (!node)
+ continue;
+ if (variable_vectorized_p (loop, program_point.stmt_info,
+ *node, lhs, true))
{
biggest_mode = get_biggest_mode (biggest_mode,
TYPE_MODE (TREE_TYPE (lhs)));
for (i = 0; i < gimple_num_args (stmt); i++)
{
tree var = gimple_arg (stmt, i);
- if (variable_vectorized_p (loop, program_point.stmt_info, var,
- false))
+ if (variable_vectorized_p (loop, program_point.stmt_info,
+ *node, var, false))
{
biggest_mode
= get_biggest_mode (biggest_mode,
}
/* Return true if additional vector vars needed. */
-static bool
-need_additional_vector_vars_p (stmt_vec_info stmt_info)
+bool
+costs::need_additional_vector_vars_p (stmt_vec_info stmt_info,
+ slp_tree node ATTRIBUTE_UNUSED)
{
- enum stmt_vec_info_type type
- = STMT_VINFO_TYPE (vect_stmt_to_vectorize (stmt_info));
+ enum stmt_vec_info_type type = STMT_VINFO_TYPE (stmt_info);
if (type == load_vec_info_type || type == store_vec_info_type)
{
if (STMT_VINFO_GATHER_SCATTER_P (stmt_info)
Then, after this function, we update SSA 1 live range in bb 2
into [2, 4] since SSA 1 is live out into bb 3. */
-static void
-update_local_live_ranges (
+void
+costs::update_local_live_ranges (
vec_info *vinfo,
hash_map<basic_block, vec<stmt_point>> &program_points_per_bb,
hash_map<basic_block, hash_map<tree, pair>> &live_ranges_per_bb,
{
gphi *phi = psi.phi ();
stmt_vec_info stmt_info = vinfo->lookup_stmt (phi);
- if (STMT_VINFO_TYPE (vect_stmt_to_vectorize (stmt_info))
- == undef_vec_info_type)
+ stmt_info = vect_stmt_to_vectorize (stmt_info);
+ slp_tree *node = vinfo_slp_map.get (stmt_info);
+
+ if (!node)
+ continue;
+
+ if (STMT_VINFO_TYPE (stmt_info) == undef_vec_info_type)
continue;
for (j = 0; j < gimple_phi_num_args (phi); j++)
if (!is_gimple_assign_or_call (gsi_stmt (si)))
continue;
stmt_vec_info stmt_info = vinfo->lookup_stmt (gsi_stmt (si));
- enum stmt_vec_info_type type
- = STMT_VINFO_TYPE (vect_stmt_to_vectorize (stmt_info));
- if (need_additional_vector_vars_p (stmt_info))
+ stmt_info = vect_stmt_to_vectorize (stmt_info);
+ slp_tree *node = vinfo_slp_map.get (stmt_info);
+ if (!node)
+ continue;
+ enum stmt_vec_info_type type = STMT_VINFO_TYPE (stmt_info);
+ if (need_additional_vector_vars_p (stmt_info, *node))
{
/* For non-adjacent load/store STMT, we will potentially
convert it into:
}
/* Compute the maximum live V_REGS. */
-static bool
-has_unexpected_spills_p (loop_vec_info loop_vinfo)
+bool
+costs::has_unexpected_spills_p (loop_vec_info loop_vinfo)
{
/* Compute local program points.
It's a fast and effective computation. */
/* Detect whether we're vectorizing for VLA and should apply the unrolling
heuristic described above m_unrolled_vls_niters. */
record_potential_vls_unrolling (loop_vinfo);
+}
+void
+costs::record_lmul_spills (loop_vec_info loop_vinfo)
+{
/* Detect whether the LOOP has unexpected spills. */
record_potential_unexpected_spills (loop_vinfo);
}
int stmt_cost
= targetm.vectorize.builtin_vectorization_cost (kind, vectype, misalign);
+ if (stmt_info && node)
+ vinfo_slp_map.put (stmt_info, node);
+
/* Do one-time initialization based on the vinfo. */
loop_vec_info loop_vinfo = dyn_cast<loop_vec_info> (m_vinfo);
+
if (!m_analyzed_vinfo)
{
if (loop_vinfo)
{
if (loop_vec_info loop_vinfo = dyn_cast<loop_vec_info> (m_vinfo))
{
+ record_lmul_spills (loop_vinfo);
+
adjust_vect_cost_per_loop (loop_vinfo);
}
vector_costs::finish_cost (scalar_costs);
typedef pair_hash <tree_operand_hash, tree_operand_hash> tree_pair_hash;
hash_set <tree_pair_hash> memrefs;
+ hash_map <stmt_vec_info, slp_tree> vinfo_slp_map;
+
void analyze_loop_vinfo (loop_vec_info);
+ void record_lmul_spills (loop_vec_info loop_vinfo);
void record_potential_vls_unrolling (loop_vec_info);
bool prefer_unrolled_loop () const;
bool m_has_unexpected_spills_p = false;
void record_potential_unexpected_spills (loop_vec_info);
+ void compute_local_program_points (vec_info *,
+ hash_map<basic_block, vec<stmt_point>> &);
+ void update_local_live_ranges (vec_info *,
+ hash_map<basic_block, vec<stmt_point>> &,
+ hash_map<basic_block, hash_map<tree, pair>> &,
+ machine_mode *);
+ machine_mode compute_local_live_ranges
+ (loop_vec_info, const hash_map<basic_block, vec<stmt_point>> &,
+ hash_map<basic_block, hash_map<tree, pair>> &);
+
+ bool has_unexpected_spills_p (loop_vec_info);
+ bool need_additional_vector_vars_p (stmt_vec_info, slp_tree);
+
void adjust_vect_cost_per_loop (loop_vec_info);
unsigned adjust_stmt_cost (enum vect_cost_for_stmt kind,
loop_vec_info,