diff options
Diffstat (limited to 'gcc/tree-vect-loop.c')
-rw-r--r-- | gcc/tree-vect-loop.c | 119 |
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); + } } |