From: Richard Biener Date: Fri, 29 May 2020 10:00:00 +0000 (+0200) Subject: tree-optimization/95272 - add SLP_TREE_REPRESENTATIVE X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c735929a2503a7d03ac4739bba5b25336bf954c3;p=gcc.git tree-optimization/95272 - add SLP_TREE_REPRESENTATIVE This adds SLP_TREE_REPRESENTATIVE - a representative stmt-info that is used by SLP analysis and code generation. This avoids the need for the hack in vect_slp_rearrange_stmts which previously avoided to re-arrange stmts that might not have been isomorphic because of operand swapping. It also plays nice with future directions of SLP and for the forseeable future is easier than replicating more and more info in the SLP node as long as non-SLP is in-tree. 2020-05-29 Richard Biener PR tree-optimization/95272 * tree-vectorizer.h (_slp_tree::representative): Add. (SLP_TREE_REPRESENTATIVE): Likewise. * tree-vect-loop.c (vectorizable_reduction): Adjust SLP node gathering. (vectorizable_live_operation): Use the representative to attach the reduction info to. * tree-vect-slp.c (_slp_tree::_slp_tree): Initialize SLP_TREE_REPRESENTATIVE. (vect_create_new_slp_node): Likewise. (slp_copy_subtree): Copy it. (vect_slp_rearrange_stmts): Re-arrange even COND_EXPR stmts. (vect_slp_analyze_node_operations_1): Pass the representative to vect_analyze_stmt. (vect_schedule_slp_instance): Pass the representative to vect_transform_stmt. * gcc.dg/vect/pr95272.c: New testcase. --- diff --git a/gcc/testsuite/gcc.dg/vect/pr95272.c b/gcc/testsuite/gcc.dg/vect/pr95272.c new file mode 100644 index 00000000000..47698ff3e56 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr95272.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ + +enum { a = 5, b }; +typedef struct { + int c[b]; +} d; +extern d e[]; +int f; +int g[6]; +void h() { + int i; + for (; f; f++) { + i = 0; + for (; i < b; i++) + if (e[f].c[i]) + g[i] = e[f].c[i]; + } +} diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c index 4f94b4baad9..3c5c0ea9ebc 100644 --- a/gcc/tree-vect-loop.c +++ b/gcc/tree-vect-loop.c @@ -6192,9 +6192,9 @@ vectorizable_reduction (loop_vec_info loop_vinfo, { slp_for_stmt_info = slp_node_instance->root; /* And then there's reduction chain with a conversion ... */ - if (SLP_TREE_SCALAR_STMTS (slp_for_stmt_info)[0] != stmt_info) + if (SLP_TREE_REPRESENTATIVE (slp_for_stmt_info) != stmt_info) slp_for_stmt_info = SLP_TREE_CHILDREN (slp_for_stmt_info)[0]; - gcc_assert (SLP_TREE_SCALAR_STMTS (slp_for_stmt_info)[0] == stmt_info); + gcc_assert (SLP_TREE_REPRESENTATIVE (slp_for_stmt_info) == stmt_info); } slp_tree *slp_op = XALLOCAVEC (slp_tree, op_type); for (i = 0; i < op_type; i++) @@ -7952,6 +7952,10 @@ vectorizable_live_operation (loop_vec_info loop_vinfo, all involved stmts together. */ else if (slp_index != 0) return true; + else + /* For SLP reductions the meta-info is attached to + the representative. */ + stmt_info = SLP_TREE_REPRESENTATIVE (slp_node); } stmt_vec_info reduc_info = info_for_reduction (loop_vinfo, stmt_info); gcc_assert (reduc_info->is_reduc_info); diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c index 5976e91cf62..836defce990 100644 --- a/gcc/tree-vect-slp.c +++ b/gcc/tree-vect-slp.c @@ -61,6 +61,7 @@ _slp_tree::_slp_tree () SLP_TREE_TWO_OPERATORS (this) = false; SLP_TREE_DEF_TYPE (this) = vect_uninitialized_def; SLP_TREE_VECTYPE (this) = NULL_TREE; + SLP_TREE_REPRESENTATIVE (this) = NULL; this->refcnt = 1; this->max_nunits = 1; } @@ -132,6 +133,7 @@ vect_create_new_slp_node (vec scalar_stmts, unsigned nops) SLP_TREE_SCALAR_STMTS (node) = scalar_stmts; SLP_TREE_CHILDREN (node).create (nops); SLP_TREE_DEF_TYPE (node) = vect_internal_def; + SLP_TREE_REPRESENTATIVE (node) = scalar_stmts[0]; unsigned i; stmt_vec_info stmt_info; @@ -1741,6 +1743,7 @@ slp_copy_subtree (slp_tree node, hash_map &map) slp_tree copy = copy_ref; SLP_TREE_DEF_TYPE (copy) = SLP_TREE_DEF_TYPE (node); SLP_TREE_VECTYPE (copy) = SLP_TREE_VECTYPE (node); + SLP_TREE_REPRESENTATIVE (copy) = SLP_TREE_REPRESENTATIVE (node); copy->max_nunits = node->max_nunits; copy->refcnt = 0; if (SLP_TREE_SCALAR_STMTS (node).exists ()) @@ -1786,14 +1789,6 @@ vect_slp_rearrange_stmts (slp_tree node, unsigned int group_size, if (SLP_TREE_SCALAR_STMTS (node).exists ()) { gcc_assert (group_size == SLP_TREE_SCALAR_STMTS (node).length ()); - /* ??? Computation nodes are isomorphic and need no rearrangement. - This is a quick hack to cover those where rearrangement breaks - semantics because only the first stmt is guaranteed to have the - correct operation code due to others being swapped or inverted. */ - stmt_vec_info first = SLP_TREE_SCALAR_STMTS (node)[0]; - if (is_gimple_assign (first->stmt) - && gimple_assign_rhs_code (first->stmt) == COND_EXPR) - return; vec tmp_stmts; tmp_stmts.create (group_size); tmp_stmts.quick_grow (group_size); @@ -2664,7 +2659,7 @@ vect_slp_analyze_node_operations_1 (vec_info *vinfo, slp_tree node, slp_instance node_instance, stmt_vector_for_cost *cost_vec) { - stmt_vec_info stmt_info = SLP_TREE_SCALAR_STMTS (node)[0]; + stmt_vec_info stmt_info = SLP_TREE_REPRESENTATIVE (node); gcc_assert (STMT_SLP_TYPE (stmt_info) != loop_vect); /* Calculate the number of vector statements to be created for the @@ -4079,7 +4074,7 @@ vect_schedule_slp_instance (vec_info *vinfo, STMT_VINFO_DEF_TYPE (child_stmt_info) = SLP_TREE_DEF_TYPE (child); } - stmt_vec_info stmt_info = SLP_TREE_SCALAR_STMTS (node)[0]; + stmt_vec_info stmt_info = SLP_TREE_REPRESENTATIVE (node); /* VECTYPE is the type of the destination. */ tree vectype = STMT_VINFO_VECTYPE (stmt_info); diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h index 2bde71760e5..5a5648b3784 100644 --- a/gcc/tree-vectorizer.h +++ b/gcc/tree-vectorizer.h @@ -128,6 +128,9 @@ struct _slp_tree { vec stmts; /* A group of scalar operands to be vectorized together. */ vec ops; + /* The representative that should be used for analysis and + code generation. */ + stmt_vec_info representative; /* Load permutation relative to the stores, NULL if there is no permutation. */ @@ -193,6 +196,7 @@ public: #define SLP_TREE_TWO_OPERATORS(S) (S)->two_operators #define SLP_TREE_DEF_TYPE(S) (S)->def_type #define SLP_TREE_VECTYPE(S) (S)->vectype +#define SLP_TREE_REPRESENTATIVE(S) (S)->representative /* Key for map that records association between scalar conditions and corresponding loop mask, and