aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2016-08-23 13:58:19 +0000
committerRichard Biener <rguenther@suse.de>2016-08-23 13:58:19 +0000
commit8646a2b4ba86716c9373ee0f6e4632f1ca4ae077 (patch)
tree6396360f350e48e4f33a1ca55abda5edb7097000
parentdf85b752c97c86348bf03b2fb36c3432e0ddaac7 (diff)
2016-08-23 Richard Biener <rguenther@suse.de>
PR tree-optimization/77286 * tree-vect-loop.c (vect_analyze_loop_form_1): Do not modify the CFG here. (vect_transform_loop): Split exit edges of loop and scalar loop if required and at the appropriate time. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@239700 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/tree-vect-loop.c49
2 files changed, 41 insertions, 16 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 23cf5bc33cf..5cf4158a628 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2016-08-23 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/77286
+ * tree-vect-loop.c (vect_analyze_loop_form_1): Do not modify
+ the CFG here.
+ (vect_transform_loop): Split exit edges of loop and scalar
+ loop if required and at the appropriate time.
+
2016-08-23 Dominik Vogt <vogt@linux.vnet.ibm.com>
* explow.c (get_dynamic_stack_size): Take known alignment of stack
diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
index c9ba5810e70..fa06505d1f2 100644
--- a/gcc/tree-vect-loop.c
+++ b/gcc/tree-vect-loop.c
@@ -1486,23 +1486,14 @@ vect_analyze_loop_form_1 (struct loop *loop, gcond **loop_cond,
return false;
}
- /* Make sure there exists a single-predecessor exit bb: */
- if (!single_pred_p (single_exit (loop)->dest))
+ /* Make sure the exit is not abnormal. */
+ edge e = single_exit (loop);
+ if (e->flags & EDGE_ABNORMAL)
{
- edge e = single_exit (loop);
- if (!(e->flags & EDGE_ABNORMAL))
- {
- split_loop_exit_edge (e);
- if (dump_enabled_p ())
- dump_printf (MSG_NOTE, "split exit edge.\n");
- }
- else
- {
- if (dump_enabled_p ())
- dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
- "not vectorized: abnormal loop exit edge.\n");
- return false;
- }
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: abnormal loop exit edge.\n");
+ return false;
}
*loop_cond = vect_get_loop_niters (loop, assumptions, number_of_iterations,
@@ -6759,6 +6750,16 @@ vect_transform_loop (loop_vec_info loop_vinfo)
check_profitability = true;
}
+ /* Make sure there exists a single-predecessor exit bb. Do this before
+ versioning. */
+ edge e = single_exit (loop);
+ if (! single_pred_p (e->dest))
+ {
+ split_loop_exit_edge (e);
+ if (dump_enabled_p ())
+ dump_printf (MSG_NOTE, "split exit edge\n");
+ }
+
/* Version the loop first, if required, so the profitability check
comes first. */
@@ -6768,6 +6769,22 @@ vect_transform_loop (loop_vec_info loop_vinfo)
check_profitability = false;
}
+ /* Make sure there exists a single-predecessor exit bb also on the
+ scalar loop copy. Do this after versioning but before peeling
+ so CFG structure is fine for both scalar and if-converted loop
+ to make slpeel_duplicate_current_defs_from_edges face matched
+ loop closed PHI nodes on the exit. */
+ if (LOOP_VINFO_SCALAR_LOOP (loop_vinfo))
+ {
+ e = single_exit (LOOP_VINFO_SCALAR_LOOP (loop_vinfo));
+ if (! single_pred_p (e->dest))
+ {
+ split_loop_exit_edge (e);
+ if (dump_enabled_p ())
+ dump_printf (MSG_NOTE, "split exit edge of scalar loop\n");
+ }
+ }
+
tree ni_name = vect_build_loop_niters (loop_vinfo);
LOOP_VINFO_NITERS_UNCHANGED (loop_vinfo) = ni_name;