Hi,

As described in PR 51269, the vectorizer adjusts number of prologue loop
iterations according to cost model, but never uses the result. This happens
because the result is not returned from the function that computes it, and
is, therefore, ignored.

Bootstrapped and tested on powerpc64-suse-linux.
I am going to commit it shortly.

Ira

ChangeLog:

        PR tree-optimization/51269
        * tree-vect-loop-manip.c (set_prologue_iterations): Make
first_niters
        a pointer.
        (slpeel_tree_peel_loop_to_edge): Likewise.
        (vect_do_peeling_for_loop_bound): Update call to
        slpeel_tree_peel_loop_to_edge.
        (vect_gen_niters_for_prolog_loop): Don't compute wide_prolog_niters
        here.  Remove it from the parameters list.
        (vect_do_peeling_for_alignment): Update calls and compute
        wide_prolog_niters.

Index: tree-vect-loop-manip.c
===================================================================
--- tree-vect-loop-manip.c      (revision 182833)
+++ tree-vect-loop-manip.c      (working copy)
@@ -1037,7 +1037,7 @@ slpeel_verify_cfg_after_peeling (struct loop *firs

 static void
 set_prologue_iterations (basic_block bb_before_first_loop,
-                        tree first_niters,
+                        tree *first_niters,
                         struct loop *loop,
                         unsigned int th)
 {
@@ -1100,9 +1100,9 @@ set_prologue_iterations (basic_block bb_before_fir
   newphi = create_phi_node (var, bb_before_first_loop);
   add_phi_arg (newphi, prologue_after_cost_adjust_name, e_fallthru,
               UNKNOWN_LOCATION);
-  add_phi_arg (newphi, first_niters, e_false, UNKNOWN_LOCATION);
+  add_phi_arg (newphi, *first_niters, e_false, UNKNOWN_LOCATION);

-  first_niters = PHI_RESULT (newphi);
+  *first_niters = PHI_RESULT (newphi);
 }

 /* Function slpeel_tree_peel_loop_to_edge.
@@ -1158,7 +1158,7 @@ set_prologue_iterations (basic_block bb_before_fir

 static struct loop*
 slpeel_tree_peel_loop_to_edge (struct loop *loop,
-                              edge e, tree first_niters,
+                              edge e, tree *first_niters,
                               tree niters, bool update_first_loop_count,
                               unsigned int th, bool check_profitability,
                               tree cond_expr, gimple_seq
cond_expr_stmt_list)
@@ -1328,8 +1328,8 @@ slpeel_tree_peel_loop_to_edge (struct loop *loop,
   if (!update_first_loop_count)
     {
       pre_condition =
-       fold_build2 (LE_EXPR, boolean_type_node, first_niters,
-                    build_int_cst (TREE_TYPE (first_niters), 0));
+       fold_build2 (LE_EXPR, boolean_type_node, *first_niters,
+                    build_int_cst (TREE_TYPE (*first_niters), 0));
       if (check_profitability)
        {
          tree scalar_loop_iters
@@ -1360,8 +1360,8 @@ slpeel_tree_peel_loop_to_edge (struct loop *loop,
                                 loop, th);

       pre_condition =
-       fold_build2 (LE_EXPR, boolean_type_node, first_niters,
-                    build_int_cst (TREE_TYPE (first_niters), 0));
+       fold_build2 (LE_EXPR, boolean_type_node, *first_niters,
+                    build_int_cst (TREE_TYPE (*first_niters), 0));
     }

   skip_e = slpeel_add_loop_guard (bb_before_first_loop, pre_condition,
@@ -1402,7 +1402,7 @@ slpeel_tree_peel_loop_to_edge (struct loop *loop,
   bb_after_second_loop = split_edge (single_exit (second_loop));

   pre_condition =
-       fold_build2 (EQ_EXPR, boolean_type_node, first_niters, niters);
+       fold_build2 (EQ_EXPR, boolean_type_node, *first_niters, niters);
   skip_e = slpeel_add_loop_guard (bb_between_loops, pre_condition, NULL,
                                   bb_after_second_loop,
bb_before_first_loop);
   slpeel_update_phi_nodes_for_guard2 (skip_e, second_loop,
@@ -1411,7 +1411,7 @@ slpeel_tree_peel_loop_to_edge (struct loop *loop,
   /* 4. Make first-loop iterate FIRST_NITERS times, if requested.
    */
   if (update_first_loop_count)
-    slpeel_make_loop_iterate_ntimes (first_loop, first_niters);
+    slpeel_make_loop_iterate_ntimes (first_loop, *first_niters);

   BITMAP_FREE (definitions);
   delete_update_ssa ();
@@ -1925,7 +1925,7 @@ vect_do_peeling_for_loop_bound (loop_vec_info loop
     }

   new_loop = slpeel_tree_peel_loop_to_edge (loop, single_exit (loop),
-                                            ratio_mult_vf_name, ni_name,
false,
+                                            &ratio_mult_vf_name, ni_name,
false,
                                             th, check_profitability,
                                            cond_expr,
cond_expr_stmt_list);
   gcc_assert (new_loop);
@@ -1988,8 +1988,7 @@ vect_do_peeling_for_loop_bound (loop_vec_info loop
    use TYPE_VECTOR_SUBPARTS.  */

 static tree
-vect_gen_niters_for_prolog_loop (loop_vec_info loop_vinfo, tree
loop_niters,
-                                tree *wide_prolog_niters)
+vect_gen_niters_for_prolog_loop (loop_vec_info loop_vinfo, tree
loop_niters)
 {
   struct data_reference *dr = LOOP_VINFO_UNALIGNED_DR (loop_vinfo);
   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
@@ -2073,19 +2072,6 @@ static tree
   add_referenced_var (var);
   stmts = NULL;
   iters_name = force_gimple_operand (iters, &stmts, false, var);
-  if (types_compatible_p (sizetype, niters_type))
-    *wide_prolog_niters = iters_name;
-  else
-    {
-      gimple_seq seq = NULL;
-      tree wide_iters = fold_convert (sizetype, iters);
-      var = create_tmp_var (sizetype, "prolog_loop_niters");
-      add_referenced_var (var);
-      *wide_prolog_niters = force_gimple_operand (wide_iters, &seq, false,
-                                                 var);
-      if (seq)
-       gimple_seq_add_seq (&stmts, seq);
-    }

   /* Insert stmt on loop preheader edge.  */
   if (stmts)
@@ -2167,10 +2153,9 @@ vect_do_peeling_for_alignment (loop_vec_info loop_
   initialize_original_copy_tables ();

   ni_name = vect_build_loop_niters (loop_vinfo, NULL);
-  niters_of_prolog_loop = vect_gen_niters_for_prolog_loop (loop_vinfo,
ni_name,
-
&wide_prolog_niters);
+  niters_of_prolog_loop = vect_gen_niters_for_prolog_loop (loop_vinfo,
+                                                          ni_name);

-
   /* Get profitability threshold for vectorized loop.  */
   min_profitable_iters = LOOP_VINFO_COST_MODEL_MIN_ITERS (loop_vinfo);
   th = conservative_cost_threshold (loop_vinfo,
@@ -2179,7 +2164,7 @@ vect_do_peeling_for_alignment (loop_vec_info loop_
   /* Peel the prolog loop and iterate it niters_of_prolog_loop.  */
   new_loop =
     slpeel_tree_peel_loop_to_edge (loop, loop_preheader_edge (loop),
-                                  niters_of_prolog_loop, ni_name, true,
+                                  &niters_of_prolog_loop, ni_name, true,
                                   th, true, NULL_TREE, NULL);

   gcc_assert (new_loop);
@@ -2192,6 +2177,25 @@ vect_do_peeling_for_alignment (loop_vec_info loop_
   LOOP_VINFO_NITERS (loop_vinfo) = fold_build2 (MINUS_EXPR,
                TREE_TYPE (n_iters), n_iters, niters_of_prolog_loop);

+  if (types_compatible_p (sizetype, TREE_TYPE (niters_of_prolog_loop)))
+    wide_prolog_niters = niters_of_prolog_loop;
+  else
+    {
+      gimple_seq seq = NULL;
+      edge pe = loop_preheader_edge (loop);
+      tree wide_iters = fold_convert (sizetype, niters_of_prolog_loop);
+      tree var = create_tmp_var (sizetype, "prolog_loop_adjusted_niters");
+      add_referenced_var (var);
+      wide_prolog_niters = force_gimple_operand (wide_iters, &seq, false,
+                                                 var);
+      if (seq)
+       {
+         /* Insert stmt on loop preheader edge.  */
+          basic_block new_bb = gsi_insert_seq_on_edge_immediate (pe, seq);
+          gcc_assert (!new_bb);
+        }
+    }
+
   /* Update the init conditions of the access functions of all data refs.
*/
   vect_update_inits_of_drs (loop_vinfo, wide_prolog_niters);

Reply via email to