diff options
author | Jakub Jelinek <jakub@redhat.com> | 2017-01-09 21:10:23 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2017-01-09 21:10:23 +0100 |
commit | cb330ba582c9b175bb0c2debaba075a8af8d0b95 (patch) | |
tree | 6dd4df32ad5eb0ca2c76ee47cb1d2ae5a80687ef /gcc/tree-if-conv.c | |
parent | 47d5beb478d39937b8068410101241ae806adc25 (diff) | |
download | gcc-cb330ba582c9b175bb0c2debaba075a8af8d0b95.zip gcc-cb330ba582c9b175bb0c2debaba075a8af8d0b95.tar.gz gcc-cb330ba582c9b175bb0c2debaba075a8af8d0b95.tar.bz2 |
re PR tree-optimization/78899 (Vestorized loop with optmized mask stores motion is completely deleted after r242520.)
PR tree-optimization/78899
* tree-if-conv.c (version_loop_for_if_conversion): Instead of
returning bool return struct loop *, NULL for failure and the new
loop on success.
(versionable_outer_loop_p): Don't version outer loop if it has
dont_vectorized bit set.
(tree_if_conversion): When versioning outer loop, ensure
tree_if_conversion is performed also on the inner loop of the
non-vectorizable outer loop copy.
* tree-vectorizer.c (set_uid_loop_bbs): Formatting fix. Fold
LOOP_VECTORIZED in inner loop of the scalar outer loop and
prevent vectorization of it.
(vectorize_loops): For outer + inner LOOP_VECTORIZED, ensure
the outer loop vectorization of the non-scalar version is attempted
before vectorization of the inner loop in scalar version. If
outer LOOP_VECTORIZED guarded loop is not vectorized, prevent
vectorization of its inner loop.
* tree-vect-loop-manip.c (rename_variables_in_bb): If outer_loop
has 2 inner loops, rename also on edges from bb whose single pred
is outer_loop->header. Fix typo in function comment.
* gcc.target/i386/pr78899.c: New test.
* gcc.dg/pr71077.c: New test.
From-SVN: r244238
Diffstat (limited to 'gcc/tree-if-conv.c')
-rw-r--r-- | gcc/tree-if-conv.c | 42 |
1 files changed, 37 insertions, 5 deletions
diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index 032182c..c12987e 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -2535,7 +2535,7 @@ combine_blocks (struct loop *loop) loop to execute. The vectorizer pass will fold this internal call into either true or false. */ -static bool +static struct loop * version_loop_for_if_conversion (struct loop *loop) { basic_block cond_bb; @@ -2566,7 +2566,7 @@ version_loop_for_if_conversion (struct loop *loop) ifc_bbs[i]->aux = saved_preds[i]; if (new_loop == NULL) - return false; + return NULL; new_loop->dont_vectorize = true; new_loop->force_vectorize = false; @@ -2574,7 +2574,7 @@ version_loop_for_if_conversion (struct loop *loop) gimple_call_set_arg (g, 1, build_int_cst (integer_type_node, new_loop->num)); gsi_insert_before (&gsi, g, GSI_SAME_STMT); update_ssa (TODO_update_ssa); - return true; + return new_loop; } /* Return true when LOOP satisfies the follow conditions that will @@ -2594,6 +2594,7 @@ static bool versionable_outer_loop_p (struct loop *loop) { if (!loop_outer (loop) + || loop->dont_vectorize || !loop->inner || loop->inner->next || !single_exit (loop) @@ -2602,7 +2603,7 @@ versionable_outer_loop_p (struct loop *loop) || !single_pred_p (loop->latch) || !single_pred_p (loop->inner->latch)) return false; - + basic_block outer_exit = single_pred (loop->latch); basic_block inner_exit = single_pred (loop->inner->latch); @@ -2789,7 +2790,10 @@ tree_if_conversion (struct loop *loop) { unsigned int todo = 0; bool aggressive_if_conv; + struct loop *rloop; + again: + rloop = NULL; ifc_bbs = NULL; any_pred_load_store = false; any_complicated_phi = false; @@ -2829,8 +2833,31 @@ tree_if_conversion (struct loop *loop) struct loop *vloop = (versionable_outer_loop_p (loop_outer (loop)) ? loop_outer (loop) : loop); - if (!version_loop_for_if_conversion (vloop)) + struct loop *nloop = version_loop_for_if_conversion (vloop); + if (nloop == NULL) goto cleanup; + if (vloop != loop) + { + /* If versionable_outer_loop_p decided to version the + outer loop, version also the inner loop of the non-vectorized + loop copy. So we transform: + loop1 + loop2 + into: + if (LOOP_VECTORIZED (1, 3)) + { + loop1 + loop2 + } + else + loop3 (copy of loop1) + if (LOOP_VECTORIZED (4, 5)) + loop4 (copy of loop2) + else + loop5 (copy of loop4) */ + gcc_assert (nloop->inner && nloop->inner->next == NULL); + rloop = nloop->inner; + } } /* Now all statements are if-convertible. Combine all the basic @@ -2854,6 +2881,11 @@ tree_if_conversion (struct loop *loop) free (ifc_bbs); ifc_bbs = NULL; } + if (rloop != NULL) + { + loop = rloop; + goto again; + } return todo; } |