summaryrefslogtreecommitdiff
path: root/gcc/tree-vect-transform.c
diff options
context:
space:
mode:
authordorit <dorit@138bc75d-0d04-0410-961f-82ee72b054a4>2005-12-18 08:46:30 +0000
committerdorit <dorit@138bc75d-0d04-0410-961f-82ee72b054a4>2005-12-18 08:46:30 +0000
commitcc8ac6b5ceb97b9f85ed75766c0f7315b6a77462 (patch)
tree0a126b82fdcf5cdc667dce21f12dcbd5adecbb17 /gcc/tree-vect-transform.c
parent5b8b451749fb4fa7d1c7afe08c6565f1d86a57a7 (diff)
downloadgcc-cc8ac6b5ceb97b9f85ed75766c0f7315b6a77462.tar.gz
PR tree-optimization/24378
* tree-vect-transform.c (vect_transform_loop): Create single-predecessor basic-block after loop-versioning. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@108746 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-vect-transform.c')
-rw-r--r--gcc/tree-vect-transform.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/gcc/tree-vect-transform.c b/gcc/tree-vect-transform.c
index 0d56efb50f5..13bca53da43 100644
--- a/gcc/tree-vect-transform.c
+++ b/gcc/tree-vect-transform.c
@@ -2822,12 +2822,44 @@ vect_transform_loop (loop_vec_info loop_vinfo,
tree cond_expr_stmt_list = NULL_TREE;
basic_block condition_bb;
block_stmt_iterator cond_exp_bsi;
+ basic_block merge_bb;
+ basic_block new_exit_bb;
+ edge new_exit_e, e;
+ tree orig_phi, new_phi, arg;
cond_expr = vect_create_cond_for_align_checks (loop_vinfo,
&cond_expr_stmt_list);
initialize_original_copy_tables ();
nloop = loop_version (loops, loop, cond_expr, &condition_bb, true);
free_original_copy_tables();
+
+ /** Loop versioning violates an assumption we try to maintain during
+ vectorization - that the loop exit block has a single predecessor.
+ After versioning, the exit block of both loop versions is the same
+ basic block (i.e. it has two predecessors). Just in order to simplify
+ following transformations in the vectorizer, we fix this situation
+ here by adding a new (empty) block on the exit-edge of the loop,
+ with the proper loop-exit phis to maintain loop-closed-form. **/
+
+ merge_bb = loop->single_exit->dest;
+ gcc_assert (EDGE_COUNT (merge_bb->preds) == 2);
+ new_exit_bb = split_edge (loop->single_exit);
+ add_bb_to_loop (new_exit_bb, loop->outer);
+ new_exit_e = loop->single_exit;
+ e = EDGE_SUCC (new_exit_bb, 0);
+
+ for (orig_phi = phi_nodes (merge_bb); orig_phi;
+ orig_phi = PHI_CHAIN (orig_phi))
+ {
+ new_phi = create_phi_node (SSA_NAME_VAR (PHI_RESULT (orig_phi)),
+ new_exit_bb);
+ arg = PHI_ARG_DEF_FROM_EDGE (orig_phi, e);
+ add_phi_arg (new_phi, arg, new_exit_e);
+ SET_PHI_ARG_DEF (orig_phi, e->dest_idx, PHI_RESULT (new_phi));
+ }
+
+ /** end loop-exit-fixes after versioning **/
+
update_ssa (TODO_update_ssa);
cond_exp_bsi = bsi_last (condition_bb);
bsi_insert_before (&cond_exp_bsi, cond_expr_stmt_list, BSI_SAME_STMT);