This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH][vect256] Iterate vectorizer analysis phase


This makes us consider a different vectorization factor if the first
choosen failed.  It removes most of the intfloat conversion FAILs
but gets us some spurious new ones because we dump things twice
now.  It also shows that basing the vectorization type choice on
the vectorization factor might be not the best approach (but
maybe we should re-write things to instead iterate over available
vector sizes).  If you look at gcc.dg/vect/vect-intfloat-conversion-2.c
the char store forces a vectorization factor of at least 16,
so we always get v8sf for the float access - but we can't support
the conversion from int as we do not allow v8si vectors (even
though the HW could do that conversion - another generic issue).

Thus we could either back-up and make things simpler by iterating
over available vector size (not allowing v4si -> v4df conversions
for example).  Or we need to switch to a real greedy search for
a vectorization solution.  Which of course would require more
major surgery on the structure of the vectorization analysis
(thus, move more of the data reference analysis to the front,
best not decide on vector types based on data reference analysis
at all and simply use the vectorizable_* functions to decide
on the stmt vector types).

Well.

Bootstrapped and tested on x86_64-unknown-linux-gnu, not applied
(it has some non -mavx fails as well).

As I said my initial vectorizer patches were preliminary anyway.

Richard.

2010-05-17  Richard Guenther  <rguenther@suse.de>

	* tree-vect-loop.c (vect_analyze_loop): Split ...
	(vect_analyze_loop_2): ... into repeatable part and prologue/epilogue.
	(vect_analyze_loop): Repeat analysis with different vectorization
	factor constaints if it failed.

Index: gcc/tree-vect-loop.c
===================================================================
*** gcc/tree-vect-loop.c	(revision 159480)
--- gcc/tree-vect-loop.c	(working copy)
*************** vect_analyze_loop_operations (loop_vec_i
*** 1499,1538 ****
  }
  
  
! /* Function vect_analyze_loop.
  
     Apply a set of analyses on LOOP, and create a loop_vec_info struct
     for it. The different analyses will record information in the
     loop_vec_info struct.  */
! loop_vec_info
! vect_analyze_loop (struct loop *loop)
  {
    bool ok;
-   loop_vec_info loop_vinfo;
-   int max_vf = MAX_VECTORIZATION_FACTOR;
-   int min_vf = 2;
- 
-   if (vect_print_dump_info (REPORT_DETAILS))
-     fprintf (vect_dump, "===== analyze_loop_nest =====");
- 
-   if (loop_outer (loop)
-       && loop_vec_info_for_loop (loop_outer (loop))
-       && LOOP_VINFO_VECTORIZABLE_P (loop_vec_info_for_loop (loop_outer (loop))))
-     {
-       if (vect_print_dump_info (REPORT_DETAILS))
- 	fprintf (vect_dump, "outer-loop already vectorized.");
-       return NULL;
-     }
- 
-   /* Check the CFG characteristics of the loop (nesting, entry/exit, etc.  */
- 
-   loop_vinfo = vect_analyze_loop_form (loop);
-   if (!loop_vinfo)
-     {
-       if (vect_print_dump_info (REPORT_DETAILS))
- 	fprintf (vect_dump, "bad loop form.");
-       return NULL;
-     }
  
    /* Find all data references in the loop (which correspond to vdefs/vuses)
       and analyze their evolution in the loop.  Also adjust the minimal
--- 1499,1513 ----
  }
  
  
! /* Function vect_analyze_loop_2.
  
     Apply a set of analyses on LOOP, and create a loop_vec_info struct
     for it. The different analyses will record information in the
     loop_vec_info struct.  */
! static bool
! vect_analyze_loop_2 (loop_vec_info loop_vinfo, int *min_vf, int *max_vf)
  {
    bool ok;
  
    /* Find all data references in the loop (which correspond to vdefs/vuses)
       and analyze their evolution in the loop.  Also adjust the minimal
*************** vect_analyze_loop (struct loop *loop)
*** 1541,1556 ****
       FORNOW: Handle only simple, array references, which
       alignment can be forced, and aligned pointer-references.  */
  
!   ok = vect_analyze_data_refs (loop_vinfo, NULL, &min_vf);
    if (!ok)
      {
        if (vect_print_dump_info (REPORT_DETAILS))
  	fprintf (vect_dump, "bad data references.");
!       destroy_loop_vec_info (loop_vinfo, true);
!       return NULL;
      }
    if (vect_print_dump_info (REPORT_DETAILS))
!     fprintf (vect_dump, "minimum vectorization factor %i.", min_vf);
  
    /* Classify all cross-iteration scalar data-flow cycles.
       Cross-iteration cycles caused by virtual phis are analyzed separately.  */
--- 1516,1530 ----
       FORNOW: Handle only simple, array references, which
       alignment can be forced, and aligned pointer-references.  */
  
!   ok = vect_analyze_data_refs (loop_vinfo, NULL, min_vf);
    if (!ok)
      {
        if (vect_print_dump_info (REPORT_DETAILS))
  	fprintf (vect_dump, "bad data references.");
!       return false;
      }
    if (vect_print_dump_info (REPORT_DETAILS))
!     fprintf (vect_dump, "minimum vectorization factor %i.", *min_vf);
  
    /* Classify all cross-iteration scalar data-flow cycles.
       Cross-iteration cycles caused by virtual phis are analyzed separately.  */
*************** vect_analyze_loop (struct loop *loop)
*** 1560,1566 ****
    /* Pattern recognition requires vectory types and thus knowledge
       of the vectorization factor.  Use the minimal required vector size
       according to data-ref analysis.  */
!   vect_pattern_recog (loop_vinfo, min_vf);
  
    /* Data-flow analysis to detect stmts that do not need to be vectorized.  */
  
--- 1534,1540 ----
    /* Pattern recognition requires vectory types and thus knowledge
       of the vectorization factor.  Use the minimal required vector size
       according to data-ref analysis.  */
!   vect_pattern_recog (loop_vinfo, *min_vf);
  
    /* Data-flow analysis to detect stmts that do not need to be vectorized.  */
  
*************** vect_analyze_loop (struct loop *loop)
*** 1569,1576 ****
      {
        if (vect_print_dump_info (REPORT_DETAILS))
  	fprintf (vect_dump, "unexpected pattern.");
!       destroy_loop_vec_info (loop_vinfo, true);
!       return NULL;
      }
  
    /* Analyze data dependences between the data-refs in the loop
--- 1543,1549 ----
      {
        if (vect_print_dump_info (REPORT_DETAILS))
  	fprintf (vect_dump, "unexpected pattern.");
!       return false;
      }
  
    /* Analyze data dependences between the data-refs in the loop
*************** vect_analyze_loop (struct loop *loop)
*** 1578,1603 ****
       the dependences.
       FORNOW: fail at the first data dependence that we encounter.  */
  
!   ok = vect_analyze_data_ref_dependences (loop_vinfo, NULL, &max_vf);
    if (!ok
!       || max_vf < min_vf)
      {
        if (vect_print_dump_info (REPORT_DETAILS))
  	fprintf (vect_dump, "bad data dependence.");
!       destroy_loop_vec_info (loop_vinfo, true);
!       return NULL;
      }
    if (vect_print_dump_info (REPORT_DETAILS))
!     fprintf (vect_dump, "maximum vectorization factor %i.", max_vf);
  
    /* Determine the vectorization factor.  */
!   ok = vect_determine_vectorization_factor (loop_vinfo, &min_vf, &max_vf);
    if (!ok)
      {
        if (vect_print_dump_info (REPORT_DETAILS))
          fprintf (vect_dump, "can't determine vectorization factor.");
!       destroy_loop_vec_info (loop_vinfo, true);
!       return NULL;
      }
  
    /* Set the vector type on all statements according to the vector
--- 1551,1574 ----
       the dependences.
       FORNOW: fail at the first data dependence that we encounter.  */
  
!   ok = vect_analyze_data_ref_dependences (loop_vinfo, NULL, max_vf);
    if (!ok
!       || *max_vf < *min_vf)
      {
        if (vect_print_dump_info (REPORT_DETAILS))
  	fprintf (vect_dump, "bad data dependence.");
!       return false;
      }
    if (vect_print_dump_info (REPORT_DETAILS))
!     fprintf (vect_dump, "maximum vectorization factor %i.", *max_vf);
  
    /* Determine the vectorization factor.  */
!   ok = vect_determine_vectorization_factor (loop_vinfo, min_vf, max_vf);
    if (!ok)
      {
        if (vect_print_dump_info (REPORT_DETAILS))
          fprintf (vect_dump, "can't determine vectorization factor.");
!       return false;
      }
  
    /* Set the vector type on all statements according to the vector
*************** vect_analyze_loop (struct loop *loop)
*** 1608,1625 ****
      {
        if (vect_print_dump_info (REPORT_DETAILS))
  	fprintf (vect_dump, "unsupported data-types.");
!       destroy_loop_vec_info (loop_vinfo, true);
!       return NULL;
      }
  
    /* Set the vector type on all data-reference statements according to
       the vector size.  */
    if (!vect_set_data_ref_stmt_vectypes (loop_vinfo, NULL,
  					LOOP_VINFO_VECT_FACTOR (loop_vinfo)))
!     {
!       destroy_loop_vec_info (loop_vinfo, true);
!       return NULL;
!     }
  
    /* Analyze the alignment of the data-refs in the loop.
       Fail if a data reference is found that cannot be vectorized.  */
--- 1579,1592 ----
      {
        if (vect_print_dump_info (REPORT_DETAILS))
  	fprintf (vect_dump, "unsupported data-types.");
!       return false;
      }
  
    /* Set the vector type on all data-reference statements according to
       the vector size.  */
    if (!vect_set_data_ref_stmt_vectypes (loop_vinfo, NULL,
  					LOOP_VINFO_VECT_FACTOR (loop_vinfo)))
!     return false;
  
    /* Analyze the alignment of the data-refs in the loop.
       Fail if a data reference is found that cannot be vectorized.  */
*************** vect_analyze_loop (struct loop *loop)
*** 1629,1636 ****
      {
        if (vect_print_dump_info (REPORT_DETAILS))
  	fprintf (vect_dump, "bad data alignment.");
!       destroy_loop_vec_info (loop_vinfo, true);
!       return NULL;
      }
  
    /* Analyze the access patterns of the data-refs in the loop (consecutive,
--- 1596,1602 ----
      {
        if (vect_print_dump_info (REPORT_DETAILS))
  	fprintf (vect_dump, "bad data alignment.");
!       return false;
      }
  
    /* Analyze the access patterns of the data-refs in the loop (consecutive,
*************** vect_analyze_loop (struct loop *loop)
*** 1641,1648 ****
      {
        if (vect_print_dump_info (REPORT_DETAILS))
  	fprintf (vect_dump, "bad data access.");
!       destroy_loop_vec_info (loop_vinfo, true);
!       return NULL;
      }
  
    /* Prune the list of ddrs to be tested at run-time by versioning for alias.
--- 1607,1613 ----
      {
        if (vect_print_dump_info (REPORT_DETAILS))
  	fprintf (vect_dump, "bad data access.");
!       return false;
      }
  
    /* Prune the list of ddrs to be tested at run-time by versioning for alias.
*************** vect_analyze_loop (struct loop *loop)
*** 1654,1661 ****
        if (vect_print_dump_info (REPORT_DETAILS))
  	fprintf (vect_dump, "too long list of versioning for alias "
  			    "run-time tests.");
!       destroy_loop_vec_info (loop_vinfo, true);
!       return NULL;
      }
  
    /* Check the SLP opportunities in the loop, analyze and build SLP trees.  */
--- 1619,1625 ----
        if (vect_print_dump_info (REPORT_DETAILS))
  	fprintf (vect_dump, "too long list of versioning for alias "
  			    "run-time tests.");
!       return false;
      }
  
    /* Check the SLP opportunities in the loop, analyze and build SLP trees.  */
*************** vect_analyze_loop (struct loop *loop)
*** 1677,1684 ****
      {
        if (vect_print_dump_info (REPORT_DETAILS))
  	fprintf (vect_dump, "bad data alignment.");
!       destroy_loop_vec_info (loop_vinfo, true);
!       return NULL;
      }
  
    /* Scan all the operations in the loop and make sure they are
--- 1641,1647 ----
      {
        if (vect_print_dump_info (REPORT_DETAILS))
  	fprintf (vect_dump, "bad data alignment.");
!       return false;
      }
  
    /* Scan all the operations in the loop and make sure they are
*************** vect_analyze_loop (struct loop *loop)
*** 1689,1694 ****
--- 1652,1712 ----
      {
        if (vect_print_dump_info (REPORT_DETAILS))
  	fprintf (vect_dump, "bad operation or unsupported loop bound.");
+       return false;
+     }
+ 
+   return true;
+ }
+ 
+ /* Function vect_analyze_loop.
+ 
+    Apply a set of analyses on LOOP, and create a loop_vec_info struct
+    for it. The different analyses will record information in the
+    loop_vec_info struct.  */
+ loop_vec_info
+ vect_analyze_loop (struct loop *loop)
+ {
+   loop_vec_info loop_vinfo;
+   int max_vf = MAX_VECTORIZATION_FACTOR;
+   int min_vf = 2;
+ 
+   if (vect_print_dump_info (REPORT_DETAILS))
+     fprintf (vect_dump, "===== analyze_loop_nest =====");
+ 
+   if (loop_outer (loop)
+       && loop_vec_info_for_loop (loop_outer (loop))
+       && LOOP_VINFO_VECTORIZABLE_P (loop_vec_info_for_loop (loop_outer (loop))))
+     {
+       if (vect_print_dump_info (REPORT_DETAILS))
+ 	fprintf (vect_dump, "outer-loop already vectorized.");
+       return NULL;
+     }
+ 
+ try_again:
+   /* Check the CFG characteristics of the loop (nesting, entry/exit, etc.  */
+   loop_vinfo = vect_analyze_loop_form (loop);
+   if (!loop_vinfo)
+     {
+       if (vect_print_dump_info (REPORT_DETAILS))
+ 	fprintf (vect_dump, "bad loop form.");
+       return NULL;
+     }
+ 
+   if (!vect_analyze_loop_2 (loop_vinfo, &min_vf, &max_vf))
+     {
+       int vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
+       if (vf != 0
+ 	  && min_vf < max_vf)
+ 	{
+ 	  if (vf == min_vf)
+ 	    min_vf = min_vf * 2;
+ 	  else
+ 	    max_vf = vf / 2;
+ 	  destroy_loop_vec_info (loop_vinfo, true);
+ 	  if (vect_print_dump_info (REPORT_DETAILS))
+ 	    fprintf (vect_dump, "***** Re-trying analysis with different VF\n");
+ 	  goto try_again;
+ 	}
        destroy_loop_vec_info (loop_vinfo, true);
        return NULL;
      }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]