aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-if-conv.c
diff options
context:
space:
mode:
authorBill Schmidt <wschmidt@linux.vnet.ibm.com>2016-11-16 22:17:10 +0000
committerWilliam Schmidt <wschmidt@gcc.gnu.org>2016-11-16 22:17:10 +0000
commit9e16e6568110b66016b082cf4143b7a8ee3077c8 (patch)
treee8c01e70870d5bac27f8136579d9ce56fa4d30f6 /gcc/tree-if-conv.c
parenta2ea37fb4c8084421784c80bfd1a4e065980314c (diff)
downloadgcc-9e16e6568110b66016b082cf4143b7a8ee3077c8.zip
gcc-9e16e6568110b66016b082cf4143b7a8ee3077c8.tar.gz
gcc-9e16e6568110b66016b082cf4143b7a8ee3077c8.tar.bz2
re PR tree-optimization/77848 (Gimple if-conversion results in redundant comparisons)
2016-11-16 Bill Schmidt <wschmidt@linux.vnet.ibm.com> PR tree-optimization/77848 * tree-if-conv.c (version_loop_for_if_conversion): When versioning an outer loop, only save basic block aux information for the inner loop. (versionable_outer_loop_p): New function. (tree_if_conversion): Version the outer loop instead of the inner one if the pattern will be recognized for outer-loop vectorization. From-SVN: r242520
Diffstat (limited to 'gcc/tree-if-conv.c')
-rw-r--r--gcc/tree-if-conv.c52
1 files changed, 48 insertions, 4 deletions
diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c
index 0b86ffe..e173fab 100644
--- a/gcc/tree-if-conv.c
+++ b/gcc/tree-if-conv.c
@@ -2533,6 +2533,7 @@ version_loop_for_if_conversion (struct loop *loop)
struct loop *new_loop;
gimple *g;
gimple_stmt_iterator gsi;
+ unsigned int save_length;
g = gimple_build_call_internal (IFN_LOOP_VECTORIZED, 2,
build_int_cst (integer_type_node, loop->num),
@@ -2540,8 +2541,9 @@ version_loop_for_if_conversion (struct loop *loop)
gimple_call_set_lhs (g, cond);
/* Save BB->aux around loop_version as that uses the same field. */
- void **saved_preds = XALLOCAVEC (void *, loop->num_nodes);
- for (unsigned i = 0; i < loop->num_nodes; i++)
+ save_length = loop->inner ? loop->inner->num_nodes : loop->num_nodes;
+ void **saved_preds = XALLOCAVEC (void *, save_length);
+ for (unsigned i = 0; i < save_length; i++)
saved_preds[i] = ifc_bbs[i]->aux;
initialize_original_copy_tables ();
@@ -2550,7 +2552,7 @@ version_loop_for_if_conversion (struct loop *loop)
REG_BR_PROB_BASE, true);
free_original_copy_tables ();
- for (unsigned i = 0; i < loop->num_nodes; i++)
+ for (unsigned i = 0; i < save_length; i++)
ifc_bbs[i]->aux = saved_preds[i];
if (new_loop == NULL)
@@ -2565,6 +2567,40 @@ version_loop_for_if_conversion (struct loop *loop)
return true;
}
+/* Return true when LOOP satisfies the follow conditions that will
+ allow it to be recognized by the vectorizer for outer-loop
+ vectorization:
+ - The loop is not the root node of the loop tree.
+ - The loop has exactly one inner loop.
+ - The loop has a single exit.
+ - The loop header has a single successor, which is the inner
+ loop header.
+ - The loop exit block has a single predecessor, which is the
+ inner loop's exit block. */
+
+static bool
+versionable_outer_loop_p (struct loop *loop)
+{
+ if (!loop_outer (loop)
+ || !loop->inner
+ || loop->inner->next
+ || !single_exit (loop)
+ || !single_succ_p (loop->header)
+ || single_succ (loop->header) != loop->inner->header)
+ return false;
+
+ basic_block outer_exit = single_pred (loop->latch);
+ basic_block inner_exit = single_pred (loop->inner->latch);
+
+ if (!single_pred_p (outer_exit) || single_pred (outer_exit) != inner_exit)
+ return false;
+
+ if (dump_file)
+ fprintf (dump_file, "Found vectorizable outer loop for versioning\n");
+
+ return true;
+}
+
/* Performs splitting of critical edges. Skip splitting and return false
if LOOP will not be converted because:
@@ -2767,8 +2803,16 @@ tree_if_conversion (struct loop *loop)
|| loop->dont_vectorize))
goto cleanup;
+ /* Since we have no cost model, always version loops if vectorization
+ is enabled. Either version this loop, or if the pattern is right
+ for outer-loop vectorization, version the outer loop. In the
+ latter case we will still if-convert the original inner loop. */
+ /* FIXME: When SLP vectorization can handle if-conversion on its own,
+ predicate all of if-conversion on flag_tree_loop_vectorize. */
if ((any_pred_load_store || any_complicated_phi)
- && !version_loop_for_if_conversion (loop))
+ && !version_loop_for_if_conversion
+ (versionable_outer_loop_p (loop_outer (loop))
+ ? loop_outer (loop) : loop))
goto cleanup;
/* Now all statements are if-convertible. Combine all the basic