OSDN Git Service

* tree-vectorizer.c (slpeel_make_loop_iterate_ntimes): Last two
authordorit <dorit@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 19 Nov 2004 19:08:03 +0000 (19:08 +0000)
committerdorit <dorit@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 19 Nov 2004 19:08:03 +0000 (19:08 +0000)
        arguments removed.
        (slpeel_tree_peel_loop_to_edge): Call slpeel_make_loop_iterate_ntimes
        without last two arguments. Update single_exit of loops.
        (vect_update_niters_after_peeling): Removed. Its functionality was
        moved to vect_do_peeling_for_alignment.
        (vect_do_peeling_for_loop_bound): New name for function previously
        called vect_transform_for_unknown_loop_bound.
        (vect_transform_loop_bound): Call slpeel_make_loop_iterate_ntimes
        instead of code that duplicates the same functionality.
        (vect_do_peeling_for_alignment): Functionality of
        vect_update_niters_after_peeling moved here.
        (vect_transform_loop): Unify call to vect_do_peeling_for_loop_bound -
        previously named vect_transform_for_unknown_loop_bound - for both known
        and unknown loop bound cases.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@90931 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/tree-vectorizer.c

index de6cbda..cf8c73b 100644 (file)
@@ -1,5 +1,23 @@
 2004-11-19  Dorit Naishlos  <dorit@il.ibm.com>
 
+       * tree-vectorizer.c (slpeel_make_loop_iterate_ntimes): Last two
+       arguments removed.
+       (slpeel_tree_peel_loop_to_edge): Call slpeel_make_loop_iterate_ntimes
+       without last two arguments. Update single_exit of loops.
+       (vect_update_niters_after_peeling): Removed. Its functionality was
+       moved to vect_do_peeling_for_alignment. 
+       (vect_do_peeling_for_loop_bound): New name for function previously
+       called vect_transform_for_unknown_loop_bound.
+       (vect_transform_loop_bound): Call slpeel_make_loop_iterate_ntimes
+       instead of code that duplicates the same functionality.
+       (vect_do_peeling_for_alignment): Functionality of   
+       vect_update_niters_after_peeling moved here.
+       (vect_transform_loop): Unify call to vect_do_peeling_for_loop_bound -
+       previously named vect_transform_for_unknown_loop_bound - for both known
+       and unknown loop bound cases.
+
+2004-11-19  Dorit Naishlos  <dorit@il.ibm.com>
+
        * tree-vectorizer.c (slpeel_can_duplicate_loop_p): New name for function
        previously called verify_loop_for_duplication. All conditions compacted
        into one compound condition. Removed debug dumps.
index 0b3796f..a7cc59b 100644 (file)
@@ -165,7 +165,7 @@ static struct loop *slpeel_tree_duplicate_loop_to_edge_cfg
 static void slpeel_update_phis_for_duplicate_loop 
   (struct loop *, struct loop *, bool after);
 static void slpeel_update_phi_nodes_for_guard (edge, struct loop *);
-static void slpeel_make_loop_iterate_ntimes (struct loop *, tree, tree, tree);
+static void slpeel_make_loop_iterate_ntimes (struct loop *, tree);
 static edge slpeel_add_loop_guard (basic_block, tree, basic_block);
 static bool slpeel_can_duplicate_loop_p (struct loop *, edge);
 static void allocate_new_names (bitmap);
@@ -251,12 +251,11 @@ static void vect_generate_tmps_on_preheader
 static tree vect_build_loop_niters (loop_vec_info);
 static void vect_update_ivs_after_vectorizer (struct loop *, tree); 
 static tree vect_gen_niters_for_prolog_loop (loop_vec_info, tree);
-static void vect_update_niters_after_peeling (loop_vec_info, tree);
 static void vect_update_inits_of_dr 
   (struct data_reference *, struct loop *, tree niters);
 static void vect_update_inits_of_drs (loop_vec_info, tree);
 static void vect_do_peeling_for_alignment (loop_vec_info, struct loops *);
-static void vect_transform_for_unknown_loop_bound 
+static void vect_do_peeling_for_loop_bound 
   (loop_vec_info, tree *, struct loops *);
 
 /* Utilities for creation and deletion of vec_info structs.  */
@@ -605,16 +604,19 @@ slpeel_update_phi_nodes_for_guard (edge guard_true_edge, struct loop * loop)
 
 
 /* Make the LOOP iterate NITERS times. This is done by adding a new IV
-   that starts at zero, increases by one and its limit is NITERS.  */
+   that starts at zero, increases by one and its limit is NITERS.
+
+   Assumption: the exit-condition of LOOP is the last stmt in the loop.  */
 
 static void
-slpeel_make_loop_iterate_ntimes (struct loop *loop, tree niters,
-                                tree begin_label, tree exit_label)
+slpeel_make_loop_iterate_ntimes (struct loop *loop, tree niters)
 {
   tree indx_before_incr, indx_after_incr, cond_stmt, cond;
   tree orig_cond;
   edge exit_edge = loop->exit_edges[0];
   block_stmt_iterator loop_exit_bsi = bsi_last (exit_edge->src);
+  tree begin_label = tree_block_label (loop->latch);
+  tree exit_label = tree_block_label (loop->single_exit->dest);
 
   /* Flow loop scan does not update loop->single_exit field.  */
   loop->single_exit = loop->exit_edges[0];
@@ -948,17 +950,13 @@ slpeel_tree_peel_loop_to_edge (struct loop *loop, struct loops *loops,
      and second loop preheader edge.  */
   flow_loop_scan (first_loop, LOOP_ALL);
   flow_loop_scan (second_loop, LOOP_ALL);  
+  /* Flow loop scan does not update loop->single_exit field.  */
+  first_loop->single_exit = first_loop->exit_edges[0];
+  second_loop->single_exit = second_loop->exit_edges[0];
 
   /* 3. Make first loop iterate FIRST_NITERS times, if needed.  */
   if (!update_first_loop_count)
-    {
-      tree first_loop_latch_lbl = tree_block_label (first_loop->latch);
-      tree first_loop_exit_lbl = tree_block_label (first_exit_bb);
-
-      slpeel_make_loop_iterate_ntimes (first_loop, first_niters,
-                               first_loop_latch_lbl,
-                               first_loop_exit_lbl);
-    }
+    slpeel_make_loop_iterate_ntimes (first_loop, first_niters);
   
   /* 4. Add the guard before first loop:
 
@@ -2791,16 +2789,11 @@ static void
 vect_transform_loop_bound (loop_vec_info loop_vinfo, tree niters)
 {
   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
-  edge exit_edge = loop->single_exit;
-  block_stmt_iterator loop_exit_bsi = bsi_last (exit_edge->src);
-  tree indx_before_incr, indx_after_incr;
   tree orig_cond_expr;
   HOST_WIDE_INT old_N = 0;
   int vf;
-  tree cond_stmt;
   tree new_loop_bound;
   bool symbol_niters;
-  tree cond;
   tree lb_type;
 
   symbol_niters = !LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo);
@@ -2814,45 +2807,16 @@ vect_transform_loop_bound (loop_vec_info loop_vinfo, tree niters)
 #ifdef ENABLE_CHECKING
   gcc_assert (orig_cond_expr);
 #endif
-  gcc_assert (orig_cond_expr == bsi_stmt (loop_exit_bsi));
-
-  create_iv (integer_zero_node, integer_one_node, NULL_TREE, loop, 
-            &loop_exit_bsi, false, &indx_before_incr, &indx_after_incr);
-
-  /* bsi_insert is using BSI_NEW_STMT. We need to bump it back 
-     to point to the exit condition.  */
-  bsi_next (&loop_exit_bsi);
-  gcc_assert (bsi_stmt (loop_exit_bsi) == orig_cond_expr);
 
   /* new loop exit test:  */
   lb_type = TREE_TYPE (TREE_OPERAND (COND_EXPR_COND (orig_cond_expr), 1));
   if (!symbol_niters)
-    new_loop_bound = fold_convert (lb_type, 
-                                  build_int_cst (unsigned_type_node, 
-                                                 old_N/vf));
+    new_loop_bound = 
+       fold_convert (lb_type, build_int_cst (unsigned_type_node, old_N/vf));
   else
     new_loop_bound = niters;
 
-  if (exit_edge->flags & EDGE_TRUE_VALUE) /* 'then' edge exits the loop.  */
-    cond = build2 (GE_EXPR, boolean_type_node, 
-                  indx_after_incr, new_loop_bound);
-  else /* 'then' edge loops back.  */
-    cond = build2 (LT_EXPR, boolean_type_node, 
-                  indx_after_incr, new_loop_bound);
-
-  cond_stmt = build3 (COND_EXPR, TREE_TYPE (orig_cond_expr), cond,
-                     COND_EXPR_THEN (orig_cond_expr),
-                     COND_EXPR_ELSE (orig_cond_expr));
-
-  bsi_insert_before (&loop_exit_bsi, cond_stmt, BSI_SAME_STMT);   
-
-  /* remove old loop exit test:  */
-  bsi_remove (&loop_exit_bsi);
-
-  if (vect_debug_details (NULL))
-    print_generic_expr (dump_file, cond_stmt, TDF_SLIM);
-
-  loop->nb_iterations = new_loop_bound;
+  slpeel_make_loop_iterate_ntimes (loop, new_loop_bound);
 }
 
 
@@ -2978,8 +2942,8 @@ vect_update_ivs_after_vectorizer (struct loop *loop, tree niters)
    unknown loop bound.  */
 
 static void 
-vect_transform_for_unknown_loop_bound (loop_vec_info loop_vinfo, tree * ratio,
-                                      struct loops *loops)
+vect_do_peeling_for_loop_bound (loop_vec_info loop_vinfo, tree * ratio,
+                               struct loops *loops)
 {
 
   tree ni_name, ratio_mult_vf_name;
@@ -3095,21 +3059,6 @@ vect_gen_niters_for_prolog_loop (loop_vec_info loop_vinfo, tree niters)
 }
 
 
-/* Function vect_update_niters_after_peeling
-
-   NITERS iterations were peeled from the loop represented by LOOP_VINFO. 
-   The new number of iterations is therefore original_niters - NITERS.
-   Record the new number of iterations in LOOP_VINFO.  */
-
-static void
-vect_update_niters_after_peeling (loop_vec_info loop_vinfo, tree niters)
-{
-  tree n_iters = LOOP_VINFO_NITERS (loop_vinfo);
-  LOOP_VINFO_NITERS (loop_vinfo) = 
-    build (MINUS_EXPR, integer_type_node, n_iters, niters);      
-}
-
-
 /* Function vect_update_inits_of_dr
 
    NITERS iterations were peeled from LOOP.  DR represents a data reference
@@ -3183,6 +3132,7 @@ vect_do_peeling_for_alignment (loop_vec_info loop_vinfo, struct loops *loops)
 {
   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
   tree niters_of_prolog_loop, ni_name;
+  tree n_iters;
 
   if (vect_debug_details (NULL))
     fprintf (dump_file, "\n<<vect_do_peeling_for_alignment>>\n");
@@ -3196,7 +3146,9 @@ vect_do_peeling_for_alignment (loop_vec_info loop_vinfo, struct loops *loops)
                                 niters_of_prolog_loop, ni_name, false); 
 
   /* Update number of times loop executes.  */
-  vect_update_niters_after_peeling (loop_vinfo, niters_of_prolog_loop);
+  n_iters = LOOP_VINFO_NITERS (loop_vinfo);
+  LOOP_VINFO_NITERS (loop_vinfo) =
+    build (MINUS_EXPR, integer_type_node, n_iters, niters_of_prolog_loop);
 
   /* Update all inits of access functions of all data refs.  */
   vect_update_inits_of_drs (loop_vinfo, niters_of_prolog_loop);
@@ -3233,32 +3185,21 @@ vect_transform_loop (loop_vec_info loop_vinfo,
   /* Peel the loop if there are data refs with unknown alignment.
      Only one data ref with unknown store is allowed.  */
 
-  
   if (LOOP_DO_PEELING_FOR_ALIGNMENT (loop_vinfo))
     vect_do_peeling_for_alignment (loop_vinfo, loops);
   
-  /* If the loop has a symbolic number of iterations 'n' 
-     (i.e. it's not a compile time constant), 
-     then an epilog loop needs to be created. We therefore duplicate 
-     the initial loop. The original loop will be vectorized, and will compute
-     the first (n/VF) iterations. The second copy of the loop will remain 
-     serial and will compute the remaining (n%VF) iterations.
+  /* If the loop has a symbolic number of iterations 'n' (i.e. it's not a
+     compile time constant), or it is a constant that doesn't divide by the
+     vectorization factor, then an epilog loop needs to be created.
+     We therefore duplicate the loop: the original loop will be vectorized,
+     and will compute the first (n/VF) iterations. The second copy of the loop
+     will remain scalar and will compute the remaining (n%VF) iterations.
      (VF is the vectorization factor).  */
 
-  if (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo))
-    vect_transform_for_unknown_loop_bound (loop_vinfo, &ratio, loops);
-
-  /* FORNOW: we'll treat the case where niters is constant and 
-     
-                        niters % vf != 0
-
-     in the way similar to one with symbolic niters. 
-     For this we'll generate variable which value is equal to niters.  */
-
-  if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo) 
-      && (LOOP_VINFO_INT_NITERS (loop_vinfo) % vectorization_factor != 0))
-    vect_transform_for_unknown_loop_bound (loop_vinfo, &ratio, loops);
-
+  if (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
+      || (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
+          && LOOP_VINFO_INT_NITERS (loop_vinfo) % vectorization_factor != 0))
+    vect_do_peeling_for_loop_bound (loop_vinfo, &ratio, loops);
 
   /* 1) Make sure the loop header has exactly two entries
      2) Make sure we have a preheader basic block.  */