[gcc(refs/vendors/vrull/heads/slp-improvements)] tree-optimization: use fewer lanes on VEC_PERM_EXPR for two operators

Philipp Tomsich ptomsich@gcc.gnu.org
Wed Jan 17 19:14:10 GMT 2024


https://gcc.gnu.org/g:eb4b8050767b12680a96ef4d215a3440b5950957

commit eb4b8050767b12680a96ef4d215a3440b5950957
Author: Manolis Tsamis <manolis.tsamis@vrull.eu>
Date:   Fri Nov 17 17:42:30 2023 +0100

    tree-optimization: use fewer lanes on VEC_PERM_EXPR for two operators
    
    Currently when SLP nodes are built with "two_operators == true" the
    VEC_PERM_EXPR that merges the result selects a lane only based on the
    operator found. In the case that the input nodes have duplicate
    elements there may be more than one ways to chose. This commit OBtries
    to use an existing lane if possible, which can free up lanes that can
    be used in other optimizations.
    
    For example, given two vectors with duplicates:
      A = {a1, a1, a2, a2}
      B = {b1, b1, b2, b2}
    a two_operator node with operators +, -, +, - can be built as:
      RES = VEC_PERM_EXPR<A, B>(0, 4, 2, 6)
    and use 2 lanes with this commit.
    
    The existing implementation would have built a (0, 5, 2, 7)
    permutation and have used 4 lanes.
    
    This commit adds a case that if the current element can be found in
    another lane that has been used previously then that lane will be
    reused.  This can happen when the ONE and TWO contain duplicate
    elements and reduces the number of 'active' lanes.

Diff:
---
 gcc/tree-vect-slp.cc | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc
index 4c56e8d1395..8d4fdc4f836 100644
--- a/gcc/tree-vect-slp.cc
+++ b/gcc/tree-vect-slp.cc
@@ -2859,7 +2859,25 @@ fail:
 	  gassign *ostmt = as_a <gassign *> (ostmt_info->stmt);
 	  if (gimple_assign_rhs_code (ostmt) != code0)
 	    {
-	      SLP_TREE_LANE_PERMUTATION (node).safe_push (std::make_pair (1, i));
+	      /* If the current element can be found in another lane that has
+		 been used previously then use that one instead.  This can
+		 happen when the ONE and TWO contain duplicate elements and
+		 reduces the number of 'active' lanes.  */
+	      int idx = i;
+	      for (int alt_idx = (int) i - 1; alt_idx >= 0; alt_idx--)
+		{
+		  gassign *alt_stmt = as_a <gassign *> (stmts[alt_idx]->stmt);
+		  if (gimple_assign_rhs_code (alt_stmt) == code0
+		      && gimple_assign_rhs1 (ostmt)
+			== gimple_assign_rhs1 (alt_stmt)
+		      && gimple_assign_rhs2 (ostmt)
+			== gimple_assign_rhs2 (alt_stmt))
+		    {
+		      idx = alt_idx;
+		      break;
+		    }
+		}
+	      SLP_TREE_LANE_PERMUTATION (node).safe_push (std::make_pair (1, idx));
 	      ocode = gimple_assign_rhs_code (ostmt);
 	      j = i;
 	    }


More information about the Gcc-cvs mailing list