SLP_TREE_LANE_PERMUTATION (this).release ();
}
-/* Recursively free the memory allocated for the SLP tree rooted at NODE.
- FINAL_P is true if we have vectorized the instance or if we have
- made a final decision not to vectorize the statements in any way. */
+/* Recursively free the memory allocated for the SLP tree rooted at NODE. */
static void
-vect_free_slp_tree (slp_tree node, bool final_p)
+vect_free_slp_tree (slp_tree node)
{
int i;
slp_tree child;
return;
FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
- vect_free_slp_tree (child, final_p);
-
- /* Don't update STMT_VINFO_NUM_SLP_USES if it isn't relevant.
- Some statements might no longer exist, after having been
- removed by vect_transform_stmt. Updating the remaining
- statements would be redundant. */
- if (!final_p)
- {
- stmt_vec_info stmt_info;
- FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (node), i, stmt_info)
- {
- gcc_assert (STMT_VINFO_NUM_SLP_USES (stmt_info) > 0);
- STMT_VINFO_NUM_SLP_USES (stmt_info)--;
- }
- }
+ vect_free_slp_tree (child);
delete node;
}
}
-/* Free the memory allocated for the SLP instance. FINAL_P is true if we
- have vectorized the instance or if we have made a final decision not
- to vectorize the statements in any way. */
+/* Free the memory allocated for the SLP instance. */
void
-vect_free_slp_instance (slp_instance instance, bool final_p)
+vect_free_slp_instance (slp_instance instance)
{
- vect_free_slp_tree (SLP_INSTANCE_TREE (instance), final_p);
+ vect_free_slp_tree (SLP_INSTANCE_TREE (instance));
SLP_INSTANCE_LOADS (instance).release ();
instance->subgraph_entries.release ();
instance->cost_vec.release ();
SLP_TREE_DEF_TYPE (node) = vect_internal_def;
SLP_TREE_REPRESENTATIVE (node) = scalar_stmts[0];
SLP_TREE_LANES (node) = scalar_stmts.length ();
-
- unsigned i;
- stmt_vec_info stmt_info;
- FOR_EACH_VEC_ELT (scalar_stmts, i, stmt_info)
- STMT_VINFO_NUM_SLP_USES (stmt_info)++;
-
return node;
}
Return true if we can, meaning that this choice doesn't conflict with
existing SLP nodes that use STMT_INFO. */
-static bool
+bool
vect_update_shared_vectype (stmt_vec_info stmt_info, tree vectype)
{
tree old_vectype = STMT_VINFO_VECTYPE (stmt_info);
- if (old_vectype && useless_type_conversion_p (vectype, old_vectype))
- return true;
+ if (old_vectype)
+ return useless_type_conversion_p (vectype, old_vectype);
- if (STMT_VINFO_GROUPED_ACCESS (stmt_info)
- && DR_IS_READ (STMT_VINFO_DATA_REF (stmt_info)))
+ if (STMT_VINFO_GROUPED_ACCESS (stmt_info))
{
/* We maintain the invariant that if any statement in the group is
used, all other members of the group have the same vector type. */
stmt_vec_info first_info = DR_GROUP_FIRST_ELEMENT (stmt_info);
stmt_vec_info member_info = first_info;
for (; member_info; member_info = DR_GROUP_NEXT_ELEMENT (member_info))
- if (STMT_VINFO_NUM_SLP_USES (member_info) > 0
- || is_pattern_stmt_p (member_info))
+ if (is_pattern_stmt_p (member_info)
+ && !useless_type_conversion_p (vectype,
+ STMT_VINFO_VECTYPE (member_info)))
break;
if (!member_info)
return true;
}
}
- else if (STMT_VINFO_NUM_SLP_USES (stmt_info) == 0
- && !is_pattern_stmt_p (stmt_info))
+ else if (!is_pattern_stmt_p (stmt_info))
{
STMT_VINFO_VECTYPE (stmt_info) = vectype;
return true;
gcc_assert (vectype);
- if (is_a <bb_vec_info> (vinfo)
- && !vect_update_shared_vectype (stmt_info, vectype))
- continue;
-
gcall *call_stmt = dyn_cast <gcall *> (stmt);
if (call_stmt)
{
gcc_assert (child == NULL);
FOR_EACH_VEC_ELT (children, j, child)
- vect_free_slp_tree (child, false);
+ vect_free_slp_tree (child);
vect_free_oprnd_info (oprnds_info);
return NULL;
}
/* Roll back. */
matches[0] = false;
FOR_EACH_VEC_ELT (children, j, child)
- vect_free_slp_tree (child, false);
+ vect_free_slp_tree (child);
if (dump_enabled_p ())
dump_printf_loc (MSG_NOTE, vect_location,
copy->max_nunits = node->max_nunits;
copy->refcnt = 0;
if (SLP_TREE_SCALAR_STMTS (node).exists ())
- {
- SLP_TREE_SCALAR_STMTS (copy) = SLP_TREE_SCALAR_STMTS (node).copy ();
- stmt_vec_info stmt_info;
- FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (node), i, stmt_info)
- STMT_VINFO_NUM_SLP_USES (stmt_info)++;
- }
+ SLP_TREE_SCALAR_STMTS (copy) = SLP_TREE_SCALAR_STMTS (node).copy ();
if (SLP_TREE_SCALAR_OPS (node).exists ())
SLP_TREE_SCALAR_OPS (copy) = SLP_TREE_SCALAR_OPS (node).copy ();
if (SLP_TREE_LOAD_PERMUTATION (node).exists ())
/* We have to unshare the SLP tree we modify. */
hash_map<slp_tree, slp_tree> map;
slp_tree unshared = slp_copy_subtree (SLP_INSTANCE_TREE (slp_instn), map);
- vect_free_slp_tree (SLP_INSTANCE_TREE (slp_instn), false);
+ vect_free_slp_tree (SLP_INSTANCE_TREE (slp_instn));
unshared->refcnt++;
SLP_INSTANCE_TREE (slp_instn) = unshared;
FOR_EACH_VEC_ELT (SLP_INSTANCE_LOADS (slp_instn), i, node)
"Build SLP failed: store group "
"size not a multiple of the vector size "
"in basic block SLP\n");
- vect_free_slp_tree (node, false);
+ vect_free_slp_tree (node);
return false;
}
/* Fatal mismatch. */
"splitting\n");
matches[0] = true;
matches[group_size / const_max_nunits * const_max_nunits] = false;
- vect_free_slp_tree (node, false);
+ vect_free_slp_tree (node);
}
else
{
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
"Built SLP cancelled: can use "
"load/store-lanes\n");
- vect_free_slp_instance (new_instance, false);
+ vect_free_slp_instance (new_instance);
return false;
}
}
for (scalar_stmts_to_slp_tree_map_t::iterator it = bst_map->begin ();
it != bst_map->end (); ++it)
if ((*it).second)
- vect_free_slp_tree ((*it).second, false);
+ vect_free_slp_tree ((*it).second);
delete bst_map;
/* Optimize permutations in SLP reductions. */
if (SLP_TREE_CODE (node) == VEC_PERM_EXPR)
return vectorizable_slp_permutation (vinfo, NULL, node, cost_vec);
+ if (is_a <bb_vec_info> (vinfo)
+ && !vect_update_shared_vectype (stmt_info, SLP_TREE_VECTYPE (node)))
+ return false;
+
bool dummy;
return vect_analyze_stmt (vinfo, stmt_info, &dummy,
node, node_instance, cost_vec);
dump_printf_loc (MSG_NOTE, vect_location,
"removing SLP instance operations starting from: %G",
stmt_info->stmt);
- vect_free_slp_instance (instance, false);
+ vect_free_slp_instance (instance);
vinfo->slp_instances.ordered_remove (i);
cost_vec.release ();
}
dump_printf_loc (MSG_NOTE, vect_location,
"removing SLP instance operations starting from: %G",
stmt_info->stmt);
- vect_free_slp_instance (instance, false);
+ vect_free_slp_instance (instance);
BB_VINFO_SLP_INSTANCES (bb_vinfo).ordered_remove (i);
continue;
}
/* Whether on this stmt reduction meta is recorded. */
bool is_reduc_info;
- /* The number of scalar stmt references from active SLP instances. */
- unsigned int num_slp_uses;
-
/* If nonzero, the lhs of the statement could be truncated to this
many bits without affecting any users of the result. */
unsigned int min_output_precision;
#define STMT_VINFO_LOOP_PHI_EVOLUTION_BASE_UNCHANGED(S) (S)->loop_phi_evolution_base_unchanged
#define STMT_VINFO_LOOP_PHI_EVOLUTION_PART(S) (S)->loop_phi_evolution_part
#define STMT_VINFO_MIN_NEG_DIST(S) (S)->min_neg_dist
-#define STMT_VINFO_NUM_SLP_USES(S) (S)->num_slp_uses
#define STMT_VINFO_REDUC_TYPE(S) (S)->reduc_type
#define STMT_VINFO_REDUC_CODE(S) (S)->reduc_code
#define STMT_VINFO_REDUC_FN(S) (S)->reduc_fn
extern tree cse_and_gimplify_to_preheader (loop_vec_info, tree);
/* In tree-vect-slp.c. */
-extern void vect_free_slp_instance (slp_instance, bool);
+extern void vect_free_slp_instance (slp_instance);
extern bool vect_transform_slp_perm_load (vec_info *, slp_tree, vec<tree>,
gimple_stmt_iterator *, poly_uint64,
bool, unsigned *);
extern void duplicate_and_interleave (vec_info *, gimple_seq *, tree,
vec<tree>, unsigned int, vec<tree> &);
extern int vect_get_place_in_interleaving_chain (stmt_vec_info, stmt_vec_info);
+extern bool vect_update_shared_vectype (stmt_vec_info, tree);
/* In tree-vect-patterns.c. */
/* Pattern recognition functions.