[PATCH][1/n] Re-organize -fvect-cost-model, enable basic vectorization at -O2

Richard Biener rguenther@suse.de
Tue May 7 12:55:00 GMT 2013


The following patch is a first step towards being able to enable
vectorizing of a subset of all vectorizable functions at -O2 by
default.  Analysis of Polyhedron (loop heavy code) shows that
the cost of doing vectorizer analysis is in the noise but compile-time
(and binary size) grows only with the number of loops we emit
vectorized code for (because we generate up to 3 extra loops for
each vectorizable loop that we have to move down the pass pipeline).

This very first patch makes sure that a runtime cost model check
comes first - and not after alias or alignment versioning checks.
That part of the patch would be a no-op without the rest because
currently peeling for alignment and versioning cannot coexist
(well - they could not, before I introduced
STMT_VINFO_LOOP_PHI_EVOLUTION_PART a few releases ago ...).  Thus
the patch enables doing both which may eventually speedup things.

Sofar tested on the testsuite and polyhedron, full bootstrap and
regtest is underway.

Patches in this series will transform -fvect-cost-model to get
an additional parameter (not sure how that will end up looking like)
to be able to control vectorization in the following 'steps'

 1 vectorize loops that do not require a runtime cost check to be
   profitable and that do not require versioning (to be enabled at -O2)
 2 vectorize loops like we do now
 3 vectorize loops like we do now but assume the runtime cost check
   will always succeed (thus, omit it)  [-fno-vect-cost-model]

I'm not sure yet if restricting the versioning makes sense
(it's supposed to reduce code bloat and compile-time of course),
esp. considering that peeling for alignment could be disabled as well
(but then HW without unaligned accesses will likely vectorize nothing).
Thus the complication seems to be the code size considerations
(the cost model is currently set up to compare runtime cost only).

Richard.

2013-05-07  Richard Biener  <rguenther@suse.de>

	* tree-vect-data-refs.c (vect_enhance_data_refs_alignment): Do not
	disable peeling when we version for aliasing.
	* tree-vect-loop-manip.c (vect_can_advance_ivs_p): Use
	STMT_VINFO_LOOP_PHI_EVOLUTION_PART instead of recomputing it.
	* tree-vect-loop.c (vect_transform_loop): First apply versioning,
	then peeling to arrange for the cost-model check to come first.

Index: gcc/tree-vect-data-refs.c
===================================================================
*** gcc/tree-vect-data-refs.c	(revision 198676)
--- gcc/tree-vect-data-refs.c	(working copy)
*************** vect_enhance_data_refs_alignment (loop_v
*** 1323,1329 ****
    bool stat;
    gimple stmt;
    stmt_vec_info stmt_info;
-   int vect_versioning_for_alias_required;
    unsigned int npeel = 0;
    bool all_misalignments_unknown = true;
    unsigned int vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
--- 1323,1328 ----
*************** vect_enhance_data_refs_alignment (loop_v
*** 1510,1524 ****
          }
      }
  
!   vect_versioning_for_alias_required
!     = LOOP_REQUIRES_VERSIONING_FOR_ALIAS (loop_vinfo);
! 
!   /* Temporarily, if versioning for alias is required, we disable peeling
!      until we support peeling and versioning.  Often peeling for alignment
!      will require peeling for loop-bound, which in turn requires that we
!      know how to adjust the loop ivs after the loop.  */
!   if (vect_versioning_for_alias_required
!       || !vect_can_advance_ivs_p (loop_vinfo)
        || !slpeel_can_duplicate_loop_p (loop, single_exit (loop)))
      do_peeling = false;
  
--- 1509,1516 ----
          }
      }
  
!   /* Check if we can possibly peel the loop.  */
!   if (!vect_can_advance_ivs_p (loop_vinfo)
        || !slpeel_can_duplicate_loop_p (loop, single_exit (loop)))
      do_peeling = false;
  
Index: gcc/tree-vect-loop-manip.c
===================================================================
*** gcc/tree-vect-loop-manip.c	(revision 198676)
--- gcc/tree-vect-loop-manip.c	(working copy)
*************** vect_can_advance_ivs_p (loop_vec_info lo
*** 1588,1618 ****
  
        /* Analyze the evolution function.  */
  
!       access_fn = instantiate_parameters
! 	(loop, analyze_scalar_evolution (loop, PHI_RESULT (phi)));
! 
!       if (!access_fn)
! 	{
! 	  if (dump_enabled_p ())
! 	    dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
!                              "No Access function.");
! 	  return false;
! 	}
! 
!       STRIP_NOPS (access_fn);
!       if (dump_enabled_p ())
!         {
! 	  dump_printf_loc (MSG_NOTE, vect_location,
!                            "Access function of PHI: ");
! 	  dump_generic_expr (MSG_NOTE, TDF_SLIM, access_fn);
!         }
! 
!       evolution_part = evolution_part_in_loop_num (access_fn, loop->num);
! 
        if (evolution_part == NULL_TREE)
          {
  	  if (dump_enabled_p ())
! 	    dump_printf (MSG_MISSED_OPTIMIZATION, "No evolution.");
  	  return false;
          }
  
--- 1588,1600 ----
  
        /* Analyze the evolution function.  */
  
!       evolution_part
! 	= STMT_VINFO_LOOP_PHI_EVOLUTION_PART (vinfo_for_stmt (phi));
        if (evolution_part == NULL_TREE)
          {
  	  if (dump_enabled_p ())
! 	    dump_printf (MSG_MISSED_OPTIMIZATION,
! 			 "No access function or evolution.");
  	  return false;
          }
  
Index: gcc/tree-vect-loop.c
===================================================================
*** gcc/tree-vect-loop.c	(revision 198676)
--- gcc/tree-vect-loop.c	(working copy)
*************** vect_transform_loop (loop_vec_info loop_
*** 5499,5517 ****
        check_profitability = true;
      }
  
!   /* Peel the loop if there are data refs with unknown alignment.
!      Only one data ref with unknown store is allowed.  */
  
!   if (LOOP_PEELING_FOR_ALIGNMENT (loop_vinfo))
      {
!       vect_do_peeling_for_alignment (loop_vinfo, th, check_profitability);
        check_profitability = false;
      }
  
!   if (LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT (loop_vinfo)
!       || LOOP_REQUIRES_VERSIONING_FOR_ALIAS (loop_vinfo))
      {
!       vect_loop_versioning (loop_vinfo, th, check_profitability);
        check_profitability = false;
      }
  
--- 5499,5520 ----
        check_profitability = true;
      }
  
!   /* Version the loop first, if required, so the profitability check
!      comes first.  */
  
!   if (LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT (loop_vinfo)
!       || LOOP_REQUIRES_VERSIONING_FOR_ALIAS (loop_vinfo))
      {
!       vect_loop_versioning (loop_vinfo, th, check_profitability);
        check_profitability = false;
      }
  
!   /* Peel the loop if there are data refs with unknown alignment.
!      Only one data ref with unknown store is allowed.  */
! 
!   if (LOOP_PEELING_FOR_ALIGNMENT (loop_vinfo))
      {
!       vect_do_peeling_for_alignment (loop_vinfo, th, check_profitability);
        check_profitability = false;
      }
  



More information about the Gcc-patches mailing list