aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-vect-loop.c
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2010-10-07 14:36:38 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2010-10-07 14:36:38 +0000
commitbb67d9c7cef80c80e817cafdd9ee2001cb29c9f7 (patch)
tree2b9ac40e2ddfd76e458ab91dc73fbb371682b0f1 /gcc/tree-vect-loop.c
parent767f865fb828fba54459911661d15289e1a42930 (diff)
downloadgcc-bb67d9c7cef80c80e817cafdd9ee2001cb29c9f7.zip
gcc-bb67d9c7cef80c80e817cafdd9ee2001cb29c9f7.tar.gz
gcc-bb67d9c7cef80c80e817cafdd9ee2001cb29c9f7.tar.bz2
machmode.h (mode_for_vector): Declare.
2010-10-07 Richard Guenther <rguenther@suse.de> * machmode.h (mode_for_vector): Declare. * stor-layout.c (mode_for_vector): New function, split out from ... (layout_type): ... here. * tree-vectorizer.h (current_vector_size): Declare. * tree-vect-stmts.c (perm_mask_for_reverse): Check if the mask vector type is available. (get_vectype_for_scalar_type): Rename to ... (get_vectype_for_scalar_type_and_size): ... this. Get a vector size argument. (get_vectype_for_scalar_type): New wrapper around get_vectype_for_scalar_type_and_size using current_vector_size. (get_same_sized_vectype): Use get_vectype_for_scalar_type_and_size. * tree-vect-loop.c (vect_analyze_loop_2): Split out core part of vect_analyze_loop here. (vect_analyze_loop): Loop over vector sizes calling vect_analyze_loop_3. * tree-vect-slp.c (vect_slp_analyze_bb): Set current_vector_size to autodetect. * config/i386/i386.c (ix86_vectorize_builtin_conversion): Fix V8SF to V8SI conversion builtin. From-SVN: r165116
Diffstat (limited to 'gcc/tree-vect-loop.c')
-rw-r--r--gcc/tree-vect-loop.c119
1 files changed, 72 insertions, 47 deletions
diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
index 95b36f7..d7a864a 100644
--- a/gcc/tree-vect-loop.c
+++ b/gcc/tree-vect-loop.c
@@ -1371,41 +1371,18 @@ vect_analyze_loop_operations (loop_vec_info loop_vinfo)
}
-/* Function vect_analyze_loop.
+/* 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. */
-loop_vec_info
-vect_analyze_loop (struct loop *loop)
+static bool
+vect_analyze_loop_2 (loop_vec_info loop_vinfo)
{
bool ok, dummy;
- 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
vectorization factor according to the loads and stores.
@@ -1418,8 +1395,7 @@ vect_analyze_loop (struct loop *loop)
{
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "bad data references.");
- destroy_loop_vec_info (loop_vinfo, true);
- return NULL;
+ return false;
}
/* Classify all cross-iteration scalar data-flow cycles.
@@ -1436,8 +1412,7 @@ vect_analyze_loop (struct loop *loop)
{
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "unexpected pattern.");
- destroy_loop_vec_info (loop_vinfo, true);
- return NULL;
+ return false;
}
/* Analyze data dependences between the data-refs in the loop
@@ -1451,8 +1426,7 @@ vect_analyze_loop (struct loop *loop)
{
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "bad data dependence.");
- destroy_loop_vec_info (loop_vinfo, true);
- return NULL;
+ return false;
}
ok = vect_determine_vectorization_factor (loop_vinfo);
@@ -1460,15 +1434,13 @@ vect_analyze_loop (struct loop *loop)
{
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "can't determine vectorization factor.");
- destroy_loop_vec_info (loop_vinfo, true);
- return NULL;
+ return false;
}
if (max_vf < LOOP_VINFO_VECT_FACTOR (loop_vinfo))
{
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "bad data dependence.");
- destroy_loop_vec_info (loop_vinfo, true);
- return NULL;
+ return false;
}
/* Analyze the alignment of the data-refs in the loop.
@@ -1479,8 +1451,7 @@ vect_analyze_loop (struct loop *loop)
{
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "bad data alignment.");
- destroy_loop_vec_info (loop_vinfo, true);
- return NULL;
+ return false;
}
/* Analyze the access patterns of the data-refs in the loop (consecutive,
@@ -1491,8 +1462,7 @@ vect_analyze_loop (struct loop *loop)
{
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "bad data access.");
- destroy_loop_vec_info (loop_vinfo, true);
- return NULL;
+ return false;
}
/* Prune the list of ddrs to be tested at run-time by versioning for alias.
@@ -1504,8 +1474,7 @@ vect_analyze_loop (struct loop *loop)
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;
+ return false;
}
/* This pass will decide on using loop versioning and/or loop peeling in
@@ -1516,8 +1485,7 @@ vect_analyze_loop (struct loop *loop)
{
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "bad data alignment.");
- destroy_loop_vec_info (loop_vinfo, true);
- return NULL;
+ return false;
}
/* Check the SLP opportunities in the loop, analyze and build SLP trees. */
@@ -1539,13 +1507,70 @@ vect_analyze_loop (struct loop *loop)
{
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "bad operation or unsupported loop bound.");
- destroy_loop_vec_info (loop_vinfo, true);
+ 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;
+ unsigned int vector_sizes;
+
+ /* Autodetect first vector size we try. */
+ current_vector_size = 0;
+ vector_sizes = targetm.vectorize.autovectorize_vector_sizes ();
+
+ 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;
}
- LOOP_VINFO_VECTORIZABLE_P (loop_vinfo) = 1;
+ while (1)
+ {
+ /* Check the CFG characteristics of the loop (nesting, entry/exit). */
+ 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;
+ }
- return loop_vinfo;
+ if (vect_analyze_loop_2 (loop_vinfo))
+ {
+ LOOP_VINFO_VECTORIZABLE_P (loop_vinfo) = 1;
+
+ return loop_vinfo;
+ }
+
+ destroy_loop_vec_info (loop_vinfo, true);
+
+ vector_sizes &= ~current_vector_size;
+ if (vector_sizes == 0
+ || current_vector_size == 0)
+ return NULL;
+
+ /* Try the next biggest vector size. */
+ current_vector_size = 1 << floor_log2 (vector_sizes);
+ if (vect_print_dump_info (REPORT_DETAILS))
+ fprintf (vect_dump, "***** Re-trying analysis with "
+ "vector size %d\n", current_vector_size);
+ }
}