diff options
author | dorit <dorit@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-12-18 08:46:30 +0000 |
---|---|---|
committer | dorit <dorit@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-12-18 08:46:30 +0000 |
commit | cc8ac6b5ceb97b9f85ed75766c0f7315b6a77462 (patch) | |
tree | 0a126b82fdcf5cdc667dce21f12dcbd5adecbb17 /gcc/tree-vect-transform.c | |
parent | 5b8b451749fb4fa7d1c7afe08c6565f1d86a57a7 (diff) | |
download | gcc-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.c | 32 |
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); |