[PATCH] Handle mixed constant / invariant ops in SLP

Richard Biener rguenther@suse.de
Wed Apr 10 10:43:00 GMT 2013


This makes us handle mixed constant / invariant ops in SLP
(constant ops are a subset of invariant ops).  This allows us
to vectorize both foo and bar (the vect_get_constant_vectors
adjustment is only necessary for foo).

The patch also simplifies type checking (which in the end I think
is not required ...) as the type of the operand is the same as
it's def operand of its definition (well, they are the same ...).

Bootstrap and regtest running on x86_64-unknown-linux-gnu.

Richard.

2013-04-10  Richard Biener  <rguenther@suse.de>

	* tree-vectorizer.h (struct _slp_oprnd_info): Remove
	first_const_oprnd field, rename first_def_type to first_op_type.
	* tree-vect-slp.c (vect_create_oprnd_info): Adjust.
	(vect_get_and_check_slp_defs): Always use the type of the
	operand.  Allow mixed vect_external_def, vect_constant_def types.
	(vect_get_constant_vectors): Handle mixed vect_external_def,
	vect_constant_def types.

	* gcc.dg/vect/slp-39.c: New testcase.

Index: gcc/tree-vectorizer.h
===================================================================
*** gcc/tree-vectorizer.h	(revision 197665)
--- gcc/tree-vectorizer.h	(working copy)
*************** typedef struct _slp_oprnd_info
*** 169,176 ****
       operand itself in case it's constant, and an indication if it's a pattern
       stmt.  */
    enum vect_def_type first_dt;
!   tree first_def_type;
!   tree first_const_oprnd;
    bool first_pattern;
  } *slp_oprnd_info;
  
--- 169,175 ----
       operand itself in case it's constant, and an indication if it's a pattern
       stmt.  */
    enum vect_def_type first_dt;
!   tree first_op_type;
    bool first_pattern;
  } *slp_oprnd_info;
  
Index: gcc/tree-vect-slp.c
===================================================================
*** gcc/tree-vect-slp.c	(revision 197665)
--- gcc/tree-vect-slp.c	(working copy)
*************** vect_create_oprnd_info (int nops, int gr
*** 140,147 ****
        oprnd_info = XNEW (struct _slp_oprnd_info);
        oprnd_info->def_stmts.create (group_size);
        oprnd_info->first_dt = vect_uninitialized_def;
!       oprnd_info->first_def_type = NULL_TREE;
!       oprnd_info->first_const_oprnd = NULL_TREE;
        oprnd_info->first_pattern = false;
        oprnds_info.quick_push (oprnd_info);
      }
--- 140,146 ----
        oprnd_info = XNEW (struct _slp_oprnd_info);
        oprnd_info->def_stmts.create (group_size);
        oprnd_info->first_dt = vect_uninitialized_def;
!       oprnd_info->first_op_type = NULL_TREE;
        oprnd_info->first_pattern = false;
        oprnds_info.quick_push (oprnd_info);
      }
*************** vect_get_and_check_slp_defs (loop_vec_in
*** 321,336 ****
  	{
  	  oprnd_info->first_dt = dt;
  	  oprnd_info->first_pattern = pattern;
! 	  if (def)
! 	    {
! 	      oprnd_info->first_def_type = TREE_TYPE (def);
! 	      oprnd_info->first_const_oprnd = NULL_TREE;
! 	    }
! 	  else
!             {
!               oprnd_info->first_def_type = NULL_TREE;
!               oprnd_info->first_const_oprnd = oprnd;
!             }
  	}
        else
  	{
--- 320,326 ----
  	{
  	  oprnd_info->first_dt = dt;
  	  oprnd_info->first_pattern = pattern;
! 	  oprnd_info->first_op_type = TREE_TYPE (oprnd);
  	}
        else
  	{
*************** vect_get_and_check_slp_defs (loop_vec_in
*** 341,354 ****
  	     vect_internal_def.  */
  	  if (((oprnd_info->first_dt != dt
                  && !(oprnd_info->first_dt == vect_reduction_def
!                      && dt == vect_internal_def))
!                || (oprnd_info->first_def_type != NULL_TREE
! 		   && def
! 		   && !types_compatible_p (oprnd_info->first_def_type,
! 					   TREE_TYPE (def))))
! 	       || (!def
! 		   && !types_compatible_p (TREE_TYPE (oprnd_info->first_const_oprnd),
! 					   TREE_TYPE (oprnd))))
  	    {
  	      if (dump_enabled_p ())
  		dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
--- 331,343 ----
  	     vect_internal_def.  */
  	  if (((oprnd_info->first_dt != dt
                  && !(oprnd_info->first_dt == vect_reduction_def
!                      && dt == vect_internal_def)
! 		&& !((oprnd_info->first_dt == vect_external_def
! 		      || oprnd_info->first_dt == vect_constant_def)
! 		     && (dt == vect_external_def
! 			 || dt == vect_constant_def)))
!                || !types_compatible_p (oprnd_info->first_op_type,
! 				       TREE_TYPE (oprnd))))
  	    {
  	      if (dump_enabled_p ())
  		dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
*************** vect_get_constant_vectors (tree op, slp_
*** 2471,2477 ****
  		       the lhs, so make sure the scalar is the right type if
  		       we are dealing with vectors of
  		       long long/long/short/char.  */
! 		    if (op_num == 1 && constant_p)
  		      op = fold_convert (TREE_TYPE (vector_type), op);
  		    break;
  
--- 2460,2466 ----
  		       the lhs, so make sure the scalar is the right type if
  		       we are dealing with vectors of
  		       long long/long/short/char.  */
! 		    if (op_num == 1 && TREE_CODE (op) == INTEGER_CST)
  		      op = fold_convert (TREE_TYPE (vector_type), op);
  		    break;
  
*************** vect_get_constant_vectors (tree op, slp_
*** 2504,2510 ****
            number_of_places_left_in_vector--;
  	  if (!types_compatible_p (TREE_TYPE (vector_type), TREE_TYPE (op)))
  	    {
! 	      if (constant_p)
  		{
  		  op = fold_unary (VIEW_CONVERT_EXPR,
  				   TREE_TYPE (vector_type), op);
--- 2493,2499 ----
            number_of_places_left_in_vector--;
  	  if (!types_compatible_p (TREE_TYPE (vector_type), TREE_TYPE (op)))
  	    {
! 	      if (CONSTANT_CLASS_P (op))
  		{
  		  op = fold_unary (VIEW_CONVERT_EXPR,
  				   TREE_TYPE (vector_type), op);
*************** vect_get_constant_vectors (tree op, slp_
*** 2525,2530 ****
--- 2514,2521 ----
  		}
  	    }
  	  elts[number_of_places_left_in_vector] = op;
+ 	  if (!CONSTANT_CLASS_P (op))
+ 	    constant_p = false;
  
            if (number_of_places_left_in_vector == 0)
              {
Index: gcc/testsuite/gcc.dg/vect/slp-39.c
===================================================================
*** gcc/testsuite/gcc.dg/vect/slp-39.c	(revision 0)
--- gcc/testsuite/gcc.dg/vect/slp-39.c	(working copy)
***************
*** 0 ****
--- 1,25 ----
+ /* { dg-do compile } */
+ /* { dg-require-effective-target vect_double } */
+ 
+ double x[1024], y[1024], z[1024];
+ void foo (double w)
+ {
+   int i;
+   for (i = 0; i < 1023; i+=2)
+     {
+       z[i] = x[i] + 1;
+       z[i+1] = x[i+1] + w;
+     }
+ }
+ void bar (double w)
+ {
+   int i;
+   for (i = 0; i < 1023; i+=2)
+     {
+       z[i] = x[i] + w;
+       z[i+1] = x[i+1] + 1;
+     }
+ }
+ 
+ /* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" } } */
+ /* { dg-final { cleanup-tree-dump "vect" } } */

Property changes on: gcc/testsuite/gcc.dg/vect/slp-39.c
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property



More information about the Gcc-patches mailing list