diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/tree-vect-loop.c | 61 |
1 files changed, 58 insertions, 3 deletions
diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c index 2985bfe..830531f 100644 --- a/gcc/tree-vect-loop.c +++ b/gcc/tree-vect-loop.c @@ -2850,6 +2850,45 @@ vect_joust_loop_vinfos (loop_vec_info new_loop_vinfo, return true; } +/* If LOOP_VINFO is already a main loop, return it unmodified. Otherwise + try to reanalyze it as a main loop. Return the loop_vinfo on success + and null on failure. */ + +static loop_vec_info +vect_reanalyze_as_main_loop (loop_vec_info loop_vinfo, unsigned int *n_stmts) +{ + if (!LOOP_VINFO_EPILOGUE_P (loop_vinfo)) + return loop_vinfo; + + if (dump_enabled_p ()) + dump_printf_loc (MSG_NOTE, vect_location, + "***** Reanalyzing as a main loop with vector mode %s\n", + GET_MODE_NAME (loop_vinfo->vector_mode)); + + struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo); + vec_info_shared *shared = loop_vinfo->shared; + opt_loop_vec_info main_loop_vinfo = vect_analyze_loop_form (loop, shared); + gcc_assert (main_loop_vinfo); + + main_loop_vinfo->vector_mode = loop_vinfo->vector_mode; + + bool fatal = false; + bool res = vect_analyze_loop_2 (main_loop_vinfo, fatal, n_stmts); + loop->aux = NULL; + if (!res) + { + if (dump_enabled_p ()) + dump_printf_loc (MSG_NOTE, vect_location, + "***** Failed to analyze main loop with vector" + " mode %s\n", + GET_MODE_NAME (loop_vinfo->vector_mode)); + delete main_loop_vinfo; + return NULL; + } + LOOP_VINFO_VECTORIZABLE_P (main_loop_vinfo) = 1; + return main_loop_vinfo; +} + /* Function vect_analyze_loop. Apply a set of analyses on LOOP, and create a loop_vec_info struct @@ -2997,9 +3036,25 @@ vect_analyze_loop (class loop *loop, vec_info_shared *shared) if (vinfos.is_empty () && vect_joust_loop_vinfos (loop_vinfo, first_loop_vinfo)) { - delete first_loop_vinfo; - first_loop_vinfo = opt_loop_vec_info::success (NULL); - LOOP_VINFO_ORIG_LOOP_INFO (loop_vinfo) = NULL; + loop_vec_info main_loop_vinfo + = vect_reanalyze_as_main_loop (loop_vinfo, &n_stmts); + if (main_loop_vinfo == loop_vinfo) + { + delete first_loop_vinfo; + first_loop_vinfo = opt_loop_vec_info::success (NULL); + } + else if (main_loop_vinfo + && vect_joust_loop_vinfos (main_loop_vinfo, + first_loop_vinfo)) + { + delete first_loop_vinfo; + first_loop_vinfo = opt_loop_vec_info::success (NULL); + delete loop_vinfo; + loop_vinfo + = opt_loop_vec_info::success (main_loop_vinfo); + } + else + delete main_loop_vinfo; } } |