if (result != CMPLX_NONE && ops != NULL)
{
- ops->create (2);
- ops->quick_push (node1);
- ops->quick_push (node2);
+ ops->safe_push (node1);
+ ops->safe_push (node2);
}
return result;
}
{
slp_tree node;
unsigned i;
+ slp_tree newnode
+ = vect_build_combine_node (this->m_ops[0], this->m_ops[1], *this->m_node);
+ SLP_TREE_REF_COUNT (this->m_ops[2])++;
+
FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (*this->m_node), i, node)
vect_free_slp_tree (node);
/* First re-arrange the children. */
SLP_TREE_CHILDREN (*this->m_node).reserve_exact (2);
SLP_TREE_CHILDREN (*this->m_node)[0] = this->m_ops[2];
- SLP_TREE_CHILDREN (*this->m_node)[1] =
- vect_build_combine_node (this->m_ops[0], this->m_ops[1], *this->m_node);
- SLP_TREE_REF_COUNT (this->m_ops[2])++;
+ SLP_TREE_CHILDREN (*this->m_node)[1] = newnode;
/* And then rewrite the node itself. */
complex_pattern::build (vinfo);
}
};
-/* Helper function to "reset" a previously matched node and undo the changes
- made enough so that the node is treated as an irrelevant node. */
-
-static inline void
-vect_slp_reset_pattern (slp_tree node)
-{
- stmt_vec_info stmt_info = vect_orig_stmt (SLP_TREE_REPRESENTATIVE (node));
- STMT_VINFO_IN_PATTERN_P (stmt_info) = false;
- STMT_SLP_TYPE (stmt_info) = pure_slp;
- SLP_TREE_REPRESENTATIVE (node) = stmt_info;
-}
-
/* Pattern matcher for trying to match complex multiply and accumulate
and multiply and subtract patterns in SLP tree.
If the operation matches then IFN is set to the operation it matched and
if (!vect_pattern_validate_optab (ifn, vnode))
return IFN_LAST;
- /* FMA matched ADD + CMUL. During the matching of CMUL the
- stmt that starts the pattern is marked as being in a pattern,
- namely the CMUL. When replacing this with a CFMA we have to
- unmark this statement as being in a pattern. This is because
- vect_mark_pattern_stmts will only mark the current stmt as being
- in a pattern. Later on when the scalar stmts are examined the
- old statement which is supposed to be irrelevant will point to
- CMUL unless we undo the pattern relationship here. */
- vect_slp_reset_pattern (node);
ops->truncate (0);
ops->create (3);
void
complex_fma_pattern::build (vec_info *vinfo)
{
+ slp_tree node = SLP_TREE_CHILDREN (*this->m_node)[1];
+
SLP_TREE_CHILDREN (*this->m_node).release ();
SLP_TREE_CHILDREN (*this->m_node).create (3);
SLP_TREE_CHILDREN (*this->m_node).safe_splice (this->m_ops);
+ SLP_TREE_REF_COUNT (this->m_ops[1])++;
+ SLP_TREE_REF_COUNT (this->m_ops[2])++;
+
+ vect_free_slp_tree (node);
+
complex_pattern::build (vinfo);
}
{
slp_tree node;
unsigned i;
+ slp_tree newnode =
+ vect_build_combine_node (this->m_ops[2], this->m_ops[3], *this->m_node);
+ SLP_TREE_REF_COUNT (this->m_ops[0])++;
+ SLP_TREE_REF_COUNT (this->m_ops[1])++;
+
FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (*this->m_node), i, node)
vect_free_slp_tree (node);
/* First re-arrange the children. */
SLP_TREE_CHILDREN (*this->m_node).quick_push (this->m_ops[0]);
SLP_TREE_CHILDREN (*this->m_node).quick_push (this->m_ops[1]);
- SLP_TREE_CHILDREN (*this->m_node).quick_push (
- vect_build_combine_node (this->m_ops[2], this->m_ops[3], *this->m_node));
- SLP_TREE_REF_COUNT (this->m_ops[0])++;
- SLP_TREE_REF_COUNT (this->m_ops[1])++;
+ SLP_TREE_CHILDREN (*this->m_node).quick_push (newnode);
/* And then rewrite the node itself. */
complex_pattern::build (vinfo);
if (child)
vect_free_slp_tree (child);
+ /* If the node defines any SLP only patterns then those patterns are no
+ longer valid and should be removed. */
+ stmt_vec_info rep_stmt_info = SLP_TREE_REPRESENTATIVE (node);
+ if (rep_stmt_info && STMT_VINFO_SLP_VECT_ONLY_PATTERN (rep_stmt_info))
+ {
+ stmt_vec_info stmt_info = vect_orig_stmt (rep_stmt_info);
+ STMT_VINFO_IN_PATTERN_P (stmt_info) = false;
+ STMT_SLP_TYPE (stmt_info) = STMT_SLP_TYPE (rep_stmt_info);
+ }
+
delete node;
}
slp_tree node = *ref_node;
bool found_p = false;
if (!node || visited->add (node))
- return false;
+ return node
+ && SLP_TREE_REPRESENTATIVE (node)
+ && STMT_VINFO_SLP_VECT_ONLY_PATTERN (SLP_TREE_REPRESENTATIVE (node));
slp_tree child;
FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
store_info = vect_orig_stmt (store_info);
/* Free the attached stmt_vec_info and remove the stmt. */
vinfo->remove_stmt (store_info);
+
+ /* Invalidate SLP_TREE_REPRESENTATIVE in case we released it
+ to not crash in vect_free_slp_tree later. */
+ if (SLP_TREE_REPRESENTATIVE (root) == store_info)
+ SLP_TREE_REPRESENTATIVE (root) = NULL;
}
}
}