OSDN Git Service

Merge from tree-cleanup-branch: VRP, store CCP, store
[pf3gnuchains/gcc-fork.git] / gcc / tree-vect-transform.c
1 /* Transformation Utilities for Loop Vectorization.
2    Copyright (C) 2003,2004,2005 Free Software Foundation, Inc.
3    Contributed by Dorit Naishlos <dorit@il.ibm.com>
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING.  If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA.  */
21
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "errors.h"
27 #include "ggc.h"
28 #include "tree.h"
29 #include "target.h"
30 #include "rtl.h"
31 #include "basic-block.h"
32 #include "diagnostic.h"
33 #include "tree-flow.h"
34 #include "tree-dump.h"
35 #include "timevar.h"
36 #include "cfgloop.h"
37 #include "expr.h"
38 #include "optabs.h"
39 #include "tree-data-ref.h"
40 #include "tree-chrec.h"
41 #include "tree-scalar-evolution.h"
42 #include "tree-vectorizer.h"
43 #include "langhooks.h"
44 #include "tree-pass.h"
45 #include "toplev.h"
46
47 /* Utility functions for the code transformation.  */
48 static bool vect_transform_stmt (tree, block_stmt_iterator *);
49 static void vect_align_data_ref (tree);
50 static tree vect_create_destination_var (tree, tree);
51 static tree vect_create_data_ref_ptr 
52   (tree, block_stmt_iterator *, tree, tree *, bool); 
53 static tree vect_create_index_for_vector_ref (loop_vec_info);
54 static tree vect_create_addr_base_for_vector_ref (tree, tree *, tree);
55 static tree vect_get_new_vect_var (tree, enum vect_var_kind, const char *);
56 static tree vect_get_vec_def_for_operand (tree, tree);
57 static tree vect_init_vector (tree, tree);
58 static void vect_finish_stmt_generation 
59   (tree stmt, tree vec_stmt, block_stmt_iterator *bsi);
60 static void update_vuses_to_preheader (tree, struct loop*);
61
62 /* Utility function dealing with loop peeling (not peeling itself).  */
63 static void vect_generate_tmps_on_preheader 
64   (loop_vec_info, tree *, tree *, tree *);
65 static tree vect_build_loop_niters (loop_vec_info);
66 static void vect_update_ivs_after_vectorizer (loop_vec_info, tree, edge); 
67 static tree vect_gen_niters_for_prolog_loop (loop_vec_info, tree);
68 static void vect_update_init_of_dr (struct data_reference *, tree niters);
69 static void vect_update_inits_of_drs (loop_vec_info, tree);
70 static void vect_do_peeling_for_alignment (loop_vec_info, struct loops *);
71 static void vect_do_peeling_for_loop_bound 
72   (loop_vec_info, tree *, struct loops *);
73
74
75 /* Function vect_get_new_vect_var.
76
77    Returns a name for a new variable. The current naming scheme appends the 
78    prefix "vect_" or "vect_p" (depending on the value of VAR_KIND) to 
79    the name of vectorizer generated variables, and appends that to NAME if 
80    provided.  */
81
82 static tree
83 vect_get_new_vect_var (tree type, enum vect_var_kind var_kind, const char *name)
84 {
85   const char *prefix;
86   tree new_vect_var;
87
88   if (var_kind == vect_simple_var)
89     prefix = "vect_"; 
90   else
91     prefix = "vect_p";
92
93   if (name)
94     new_vect_var = create_tmp_var (type, concat (prefix, name, NULL));
95   else
96     new_vect_var = create_tmp_var (type, prefix);
97
98   return new_vect_var;
99 }
100
101
102 /* Function vect_create_index_for_vector_ref.
103
104    Create (and return) an index variable, along with it's update chain in the
105    loop. This variable will be used to access a memory location in a vector
106    operation.
107
108    Input:
109    LOOP: The loop being vectorized.
110    BSI: The block_stmt_iterator where STMT is. Any new stmts created by this
111         function can be added here, or in the loop pre-header.
112
113    Output:
114    Return an index that will be used to index a vector array.  It is expected
115    that a pointer to the first vector will be used as the base address for the
116    indexed reference.
117
118    FORNOW: we are not trying to be efficient, just creating a new index each
119    time from scratch.  At this time all vector references could use the same
120    index.
121
122    TODO: create only one index to be used by all vector references.  Record
123    the index in the LOOP_VINFO the first time this procedure is called and
124    return it on subsequent calls.  The increment of this index must be placed
125    just before the conditional expression that ends the single block loop.  */
126
127 static tree
128 vect_create_index_for_vector_ref (loop_vec_info loop_vinfo)
129 {
130   tree init, step;
131   block_stmt_iterator incr_bsi;
132   bool insert_after;
133   tree indx_before_incr, indx_after_incr;
134   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
135   tree incr;
136
137   /* It is assumed that the base pointer used for vectorized access contains
138      the address of the first vector.  Therefore the index used for vectorized
139      access must be initialized to zero and incremented by 1.  */
140
141   init = integer_zero_node;
142   step = integer_one_node;
143
144   standard_iv_increment_position (loop, &incr_bsi, &insert_after);
145   create_iv (init, step, NULL_TREE, loop, &incr_bsi, insert_after,
146         &indx_before_incr, &indx_after_incr);
147   incr = bsi_stmt (incr_bsi);
148   get_stmt_operands (incr);
149   set_stmt_info (stmt_ann (incr), new_stmt_vec_info (incr, loop_vinfo));
150
151   return indx_before_incr;
152 }
153
154
155 /* Function vect_create_addr_base_for_vector_ref.
156
157    Create an expression that computes the address of the first memory location
158    that will be accessed for a data reference.
159
160    Input:
161    STMT: The statement containing the data reference.
162    NEW_STMT_LIST: Must be initialized to NULL_TREE or a statement list.
163    OFFSET: Optional. If supplied, it is be added to the initial address.
164
165    Output:
166    1. Return an SSA_NAME whose value is the address of the memory location of 
167       the first vector of the data reference.
168    2. If new_stmt_list is not NULL_TREE after return then the caller must insert
169       these statement(s) which define the returned SSA_NAME.
170
171    FORNOW: We are only handling array accesses with step 1.  */
172
173 static tree
174 vect_create_addr_base_for_vector_ref (tree stmt,
175                                       tree *new_stmt_list,
176                                       tree offset)
177 {
178   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
179   struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
180   tree data_ref_base = 
181     unshare_expr (STMT_VINFO_VECT_DR_BASE_ADDRESS (stmt_info));
182   tree base_name = build_fold_indirect_ref (data_ref_base);
183   tree ref = DR_REF (dr);
184   tree scalar_type = TREE_TYPE (ref);
185   tree scalar_ptr_type = build_pointer_type (scalar_type);
186   tree vec_stmt;
187   tree new_temp;
188   tree addr_base, addr_expr;
189   tree dest, new_stmt;
190   tree base_offset = unshare_expr (STMT_VINFO_VECT_INIT_OFFSET (stmt_info));
191
192   /* Create base_offset */
193   dest = create_tmp_var (TREE_TYPE (base_offset), "base_off");
194   add_referenced_tmp_var (dest);
195   base_offset = force_gimple_operand (base_offset, &new_stmt, false, dest);  
196   append_to_statement_list_force (new_stmt, new_stmt_list);
197
198   if (offset)
199     {
200       tree tmp = create_tmp_var (TREE_TYPE (base_offset), "offset");
201       add_referenced_tmp_var (tmp);
202       offset = fold (build2 (MULT_EXPR, TREE_TYPE (offset), offset, 
203                              STMT_VINFO_VECT_STEP (stmt_info)));
204       base_offset = fold (build2 (PLUS_EXPR, TREE_TYPE (base_offset), 
205                                   base_offset, offset));
206       base_offset = force_gimple_operand (base_offset, &new_stmt, false, tmp);  
207       append_to_statement_list_force (new_stmt, new_stmt_list);
208     }
209   
210   /* base + base_offset */
211   addr_base = fold (build2 (PLUS_EXPR, TREE_TYPE (data_ref_base), data_ref_base, 
212                             base_offset));
213
214   /* addr_expr = addr_base */
215   addr_expr = vect_get_new_vect_var (scalar_ptr_type, vect_pointer_var,
216                                      get_name (base_name));
217   add_referenced_tmp_var (addr_expr);
218   vec_stmt = build2 (MODIFY_EXPR, void_type_node, addr_expr, addr_base);
219   new_temp = make_ssa_name (addr_expr, vec_stmt);
220   TREE_OPERAND (vec_stmt, 0) = new_temp;
221   append_to_statement_list_force (vec_stmt, new_stmt_list);
222
223   if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
224     {
225       fprintf (vect_dump, "created ");
226       print_generic_expr (vect_dump, vec_stmt, TDF_SLIM);
227     }
228   return new_temp;
229 }
230
231
232 /* Function vect_align_data_ref.
233
234    Handle mislignment of a memory accesses.
235
236    FORNOW: Can't handle misaligned accesses. 
237    Make sure that the dataref is aligned.  */
238
239 static void
240 vect_align_data_ref (tree stmt)
241 {
242   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
243   struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
244
245   /* FORNOW: can't handle misaligned accesses; 
246              all accesses expected to be aligned.  */
247   gcc_assert (aligned_access_p (dr));
248 }
249
250
251 /* Function vect_create_data_ref_ptr.
252
253    Create a memory reference expression for vector access, to be used in a
254    vector load/store stmt. The reference is based on a new pointer to vector
255    type (vp).
256
257    Input:
258    1. STMT: a stmt that references memory. Expected to be of the form
259          MODIFY_EXPR <name, data-ref> or MODIFY_EXPR <data-ref, name>.
260    2. BSI: block_stmt_iterator where new stmts can be added.
261    3. OFFSET (optional): an offset to be added to the initial address accessed
262         by the data-ref in STMT.
263    4. ONLY_INIT: indicate if vp is to be updated in the loop, or remain
264         pointing to the initial address.
265
266    Output:
267    1. Declare a new ptr to vector_type, and have it point to the base of the
268       data reference (initial addressed accessed by the data reference).
269       For example, for vector of type V8HI, the following code is generated:
270
271       v8hi *vp;
272       vp = (v8hi *)initial_address;
273
274       if OFFSET is not supplied:
275          initial_address = &a[init];
276       if OFFSET is supplied:
277          initial_address = &a[init + OFFSET];
278
279       Return the initial_address in INITIAL_ADDRESS.
280
281    2. Create a data-reference in the loop based on the new vector pointer vp,
282       and using a new index variable 'idx' as follows:
283
284       vp' = vp + update
285
286       where if ONLY_INIT is true:
287          update = zero
288       and otherwise
289          update = idx + vector_type_size
290
291       Return the pointer vp'.
292
293
294    FORNOW: handle only aligned and consecutive accesses.  */
295
296 static tree
297 vect_create_data_ref_ptr (tree stmt, block_stmt_iterator *bsi, tree offset,
298                           tree *initial_address, bool only_init)
299 {
300   tree base_name;
301   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
302   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
303   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
304   tree vectype = STMT_VINFO_VECTYPE (stmt_info);
305   tree vect_ptr_type;
306   tree vect_ptr;
307   tree tag;
308   tree new_temp;
309   tree vec_stmt;
310   tree new_stmt_list = NULL_TREE;
311   tree idx;
312   edge pe = loop_preheader_edge (loop);
313   basic_block new_bb;
314   tree vect_ptr_init;
315   tree vectype_size;
316   tree ptr_update;
317   tree data_ref_ptr;
318   tree type, tmp, size;
319
320   base_name =  build_fold_indirect_ref (unshare_expr (
321                       STMT_VINFO_VECT_DR_BASE_ADDRESS (stmt_info)));
322
323   if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
324     {
325       tree data_ref_base = base_name;
326       fprintf (vect_dump, "create array_ref of type: ");
327       print_generic_expr (vect_dump, vectype, TDF_SLIM);
328       if (TREE_CODE (data_ref_base) == VAR_DECL)
329         fprintf (vect_dump, "  vectorizing a one dimensional array ref: ");
330       else if (TREE_CODE (data_ref_base) == ARRAY_REF)
331         fprintf (vect_dump, "  vectorizing a multidimensional array ref: ");
332       else if (TREE_CODE (data_ref_base) == COMPONENT_REF)
333         fprintf (vect_dump, "  vectorizing a record based array ref: ");
334       else if (TREE_CODE (data_ref_base) == SSA_NAME)
335         fprintf (vect_dump, "  vectorizing a pointer ref: ");
336       print_generic_expr (vect_dump, base_name, TDF_SLIM);
337     }
338
339   /** (1) Create the new vector-pointer variable:  **/
340
341   vect_ptr_type = build_pointer_type (vectype);
342   vect_ptr = vect_get_new_vect_var (vect_ptr_type, vect_pointer_var,
343                                     get_name (base_name));
344   add_referenced_tmp_var (vect_ptr);
345   
346   
347   /** (2) Add aliasing information to the new vector-pointer:
348           (The points-to info (SSA_NAME_PTR_INFO) may be defined later.)  **/
349   
350   tag = STMT_VINFO_MEMTAG (stmt_info);
351   gcc_assert (tag);
352
353   /* If the memory tag of the original reference was not a type tag or
354      if the pointed-to type of VECT_PTR has an alias set number
355      different than TAG's, then we need to create a new type tag for
356      VECT_PTR and add TAG to its alias set.  */
357   if (var_ann (tag)->mem_tag_kind == NOT_A_TAG
358       || get_alias_set (tag) != get_alias_set (TREE_TYPE (vect_ptr_type)))
359     add_type_alias (vect_ptr, tag);
360   else
361     var_ann (vect_ptr)->type_mem_tag = tag;
362   
363   var_ann (vect_ptr)->subvars = STMT_VINFO_SUBVARS (stmt_info);
364
365   /** (3) Calculate the initial address the vector-pointer, and set
366           the vector-pointer to point to it before the loop:  **/
367
368   /* Create: (&(base[init_val+offset]) in the loop preheader.  */
369   new_temp = vect_create_addr_base_for_vector_ref (stmt, &new_stmt_list,
370                                                    offset);
371   pe = loop_preheader_edge (loop);
372   new_bb = bsi_insert_on_edge_immediate (pe, new_stmt_list);
373   gcc_assert (!new_bb);
374   *initial_address = new_temp;
375
376   /* Create: p = (vectype *) initial_base  */
377   vec_stmt = fold_convert (vect_ptr_type, new_temp);
378   vec_stmt = build2 (MODIFY_EXPR, void_type_node, vect_ptr, vec_stmt);
379   new_temp = make_ssa_name (vect_ptr, vec_stmt);
380   TREE_OPERAND (vec_stmt, 0) = new_temp;
381   new_bb = bsi_insert_on_edge_immediate (pe, vec_stmt);
382   gcc_assert (!new_bb);
383   vect_ptr_init = TREE_OPERAND (vec_stmt, 0);
384
385
386   /** (4) Handle the updating of the vector-pointer inside the loop: **/
387
388   if (only_init) /* No update in loop is required.  */
389     {
390       /* Copy the points-to information if it exists. */
391       if (STMT_VINFO_PTR_INFO (stmt_info))
392         duplicate_ssa_name_ptr_info (vect_ptr_init,
393                                      STMT_VINFO_PTR_INFO (stmt_info));
394       return vect_ptr_init;
395     }
396
397   idx = vect_create_index_for_vector_ref (loop_vinfo);
398
399   /* Create: update = idx * vectype_size  */
400   tmp = create_tmp_var (integer_type_node, "update");
401   add_referenced_tmp_var (tmp);
402   size = TYPE_SIZE (vect_ptr_type); 
403   type = lang_hooks.types.type_for_size (tree_low_cst (size, 1), 1);
404   ptr_update = create_tmp_var (type, "update");
405   add_referenced_tmp_var (ptr_update);
406   vectype_size = TYPE_SIZE_UNIT (vectype);
407   vec_stmt = build2 (MULT_EXPR, integer_type_node, idx, vectype_size);
408   vec_stmt = build2 (MODIFY_EXPR, void_type_node, tmp, vec_stmt);
409   new_temp = make_ssa_name (tmp, vec_stmt);
410   TREE_OPERAND (vec_stmt, 0) = new_temp;
411   bsi_insert_before (bsi, vec_stmt, BSI_SAME_STMT);
412   vec_stmt = fold_convert (type, new_temp);
413   vec_stmt = build2 (MODIFY_EXPR, void_type_node, ptr_update, vec_stmt);
414   new_temp = make_ssa_name (ptr_update, vec_stmt);
415   TREE_OPERAND (vec_stmt, 0) = new_temp;
416   bsi_insert_before (bsi, vec_stmt, BSI_SAME_STMT);
417
418   /* Create: data_ref_ptr = vect_ptr_init + update  */
419   vec_stmt = build2 (PLUS_EXPR, vect_ptr_type, vect_ptr_init, new_temp);
420   vec_stmt = build2 (MODIFY_EXPR, void_type_node, vect_ptr, vec_stmt);
421   new_temp = make_ssa_name (vect_ptr, vec_stmt);
422   TREE_OPERAND (vec_stmt, 0) = new_temp;
423   bsi_insert_before (bsi, vec_stmt, BSI_SAME_STMT);
424   data_ref_ptr = TREE_OPERAND (vec_stmt, 0);
425
426   /* Copy the points-to information if it exists. */
427   if (STMT_VINFO_PTR_INFO (stmt_info))
428     duplicate_ssa_name_ptr_info (data_ref_ptr, STMT_VINFO_PTR_INFO (stmt_info));
429   return data_ref_ptr;
430 }
431
432
433 /* Function vect_create_destination_var.
434
435    Create a new temporary of type VECTYPE.  */
436
437 static tree
438 vect_create_destination_var (tree scalar_dest, tree vectype)
439 {
440   tree vec_dest;
441   const char *new_name;
442
443   gcc_assert (TREE_CODE (scalar_dest) == SSA_NAME);
444
445   new_name = get_name (scalar_dest);
446   if (!new_name)
447     new_name = "var_";
448   vec_dest = vect_get_new_vect_var (vectype, vect_simple_var, new_name);
449   add_referenced_tmp_var (vec_dest);
450
451   return vec_dest;
452 }
453
454
455 /* Function vect_init_vector.
456
457    Insert a new stmt (INIT_STMT) that initializes a new vector variable with
458    the vector elements of VECTOR_VAR. Return the DEF of INIT_STMT. It will be
459    used in the vectorization of STMT.  */
460
461 static tree
462 vect_init_vector (tree stmt, tree vector_var)
463 {
464   stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt);
465   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
466   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
467   tree new_var;
468   tree init_stmt;
469   tree vectype = STMT_VINFO_VECTYPE (stmt_vinfo); 
470   tree vec_oprnd;
471   edge pe;
472   tree new_temp;
473   basic_block new_bb;
474  
475   new_var = vect_get_new_vect_var (vectype, vect_simple_var, "cst_");
476   add_referenced_tmp_var (new_var); 
477  
478   init_stmt = build2 (MODIFY_EXPR, vectype, new_var, vector_var);
479   new_temp = make_ssa_name (new_var, init_stmt);
480   TREE_OPERAND (init_stmt, 0) = new_temp;
481
482   pe = loop_preheader_edge (loop);
483   new_bb = bsi_insert_on_edge_immediate (pe, init_stmt);
484   gcc_assert (!new_bb);
485
486   if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
487     {
488       fprintf (vect_dump, "created new init_stmt: ");
489       print_generic_expr (vect_dump, init_stmt, TDF_SLIM);
490     }
491
492   vec_oprnd = TREE_OPERAND (init_stmt, 0);
493   return vec_oprnd;
494 }
495
496
497 /* Function vect_get_vec_def_for_operand.
498
499    OP is an operand in STMT. This function returns a (vector) def that will be
500    used in the vectorized stmt for STMT.
501
502    In the case that OP is an SSA_NAME which is defined in the loop, then
503    STMT_VINFO_VEC_STMT of the defining stmt holds the relevant def.
504
505    In case OP is an invariant or constant, a new stmt that creates a vector def
506    needs to be introduced.  */
507
508 static tree
509 vect_get_vec_def_for_operand (tree op, tree stmt)
510 {
511   tree vec_oprnd;
512   tree vec_stmt;
513   tree def_stmt;
514   stmt_vec_info def_stmt_info = NULL;
515   stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt);
516   tree vectype = STMT_VINFO_VECTYPE (stmt_vinfo);
517   int nunits = GET_MODE_NUNITS (TYPE_MODE (vectype));
518   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
519   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
520   basic_block bb;
521   tree vec_inv;
522   tree t = NULL_TREE;
523   tree def;
524   int i;
525
526   if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
527     {
528       fprintf (vect_dump, "vect_get_vec_def_for_operand: ");
529       print_generic_expr (vect_dump, op, TDF_SLIM);
530     }
531
532   /** ===> Case 1: operand is a constant.  **/
533
534   if (TREE_CODE (op) == INTEGER_CST || TREE_CODE (op) == REAL_CST)
535     {
536       /* Create 'vect_cst_ = {cst,cst,...,cst}'  */
537
538       tree vec_cst;
539
540       /* Build a tree with vector elements.  */
541       if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
542         fprintf (vect_dump, "Create vector_cst. nunits = %d", nunits);
543
544       for (i = nunits - 1; i >= 0; --i)
545         {
546           t = tree_cons (NULL_TREE, op, t);
547         }
548       vec_cst = build_vector (vectype, t);
549       return vect_init_vector (stmt, vec_cst);
550     }
551
552   gcc_assert (TREE_CODE (op) == SSA_NAME);
553  
554   /** ===> Case 2: operand is an SSA_NAME - find the stmt that defines it.  **/
555
556   def_stmt = SSA_NAME_DEF_STMT (op);
557   def_stmt_info = vinfo_for_stmt (def_stmt);
558
559   if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
560     {
561       fprintf (vect_dump, "vect_get_vec_def_for_operand: def_stmt: ");
562       print_generic_expr (vect_dump, def_stmt, TDF_SLIM);
563     }
564
565
566   /** ==> Case 2.1: operand is defined inside the loop.  **/
567
568   if (def_stmt_info)
569     {
570       /* Get the def from the vectorized stmt.  */
571
572       vec_stmt = STMT_VINFO_VEC_STMT (def_stmt_info);
573       gcc_assert (vec_stmt);
574       vec_oprnd = TREE_OPERAND (vec_stmt, 0);
575       return vec_oprnd;
576     }
577
578
579   /** ==> Case 2.2: operand is defined by the loop-header phi-node - 
580                     it is a reduction/induction.  **/
581
582   bb = bb_for_stmt (def_stmt);
583   if (TREE_CODE (def_stmt) == PHI_NODE && flow_bb_inside_loop_p (loop, bb))
584     {
585       if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
586         fprintf (vect_dump, "reduction/induction - unsupported.");
587       internal_error ("no support for reduction/induction"); /* FORNOW */
588     }
589
590
591   /** ==> Case 2.3: operand is defined outside the loop - 
592                     it is a loop invariant.  */
593
594   switch (TREE_CODE (def_stmt))
595     {
596     case PHI_NODE:
597       def = PHI_RESULT (def_stmt);
598       break;
599     case MODIFY_EXPR:
600       def = TREE_OPERAND (def_stmt, 0);
601       break;
602     case NOP_EXPR:
603       def = TREE_OPERAND (def_stmt, 0);
604       gcc_assert (IS_EMPTY_STMT (def_stmt));
605       def = op;
606       break;
607     default:
608       if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
609         {
610           fprintf (vect_dump, "unsupported defining stmt: ");
611           print_generic_expr (vect_dump, def_stmt, TDF_SLIM);
612         }
613       internal_error ("unsupported defining stmt");
614     }
615
616   /* Build a tree with vector elements.
617      Create 'vec_inv = {inv,inv,..,inv}'  */
618
619   if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
620     fprintf (vect_dump, "Create vector_inv.");
621
622   for (i = nunits - 1; i >= 0; --i)
623     {
624       t = tree_cons (NULL_TREE, def, t);
625     }
626
627   vec_inv = build_constructor (vectype, t);
628   return vect_init_vector (stmt, vec_inv);
629 }
630
631
632 /* Function vect_finish_stmt_generation.
633
634    Insert a new stmt.  */
635
636 static void
637 vect_finish_stmt_generation (tree stmt, tree vec_stmt, block_stmt_iterator *bsi)
638 {
639   bsi_insert_before (bsi, vec_stmt, BSI_SAME_STMT);
640
641   if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
642     {
643       fprintf (vect_dump, "add new stmt: ");
644       print_generic_expr (vect_dump, vec_stmt, TDF_SLIM);
645     }
646
647 #ifdef ENABLE_CHECKING
648   /* Make sure bsi points to the stmt that is being vectorized.  */
649   gcc_assert (stmt == bsi_stmt (*bsi));
650 #endif
651
652 #ifdef USE_MAPPED_LOCATION
653   SET_EXPR_LOCATION (vec_stmt, EXPR_LOCATION (stmt));
654 #else
655   SET_EXPR_LOCUS (vec_stmt, EXPR_LOCUS (stmt));
656 #endif
657 }
658
659
660 /* Function vectorizable_assignment.
661
662    Check if STMT performs an assignment (copy) that can be vectorized. 
663    If VEC_STMT is also passed, vectorize the STMT: create a vectorized 
664    stmt to replace it, put it in VEC_STMT, and insert it at BSI.
665    Return FALSE if not a vectorizable STMT, TRUE otherwise.  */
666
667 bool
668 vectorizable_assignment (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
669 {
670   tree vec_dest;
671   tree scalar_dest;
672   tree op;
673   tree vec_oprnd;
674   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
675   tree vectype = STMT_VINFO_VECTYPE (stmt_info);
676   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
677   tree new_temp;
678
679   /* Is vectorizable assignment?  */
680
681   if (TREE_CODE (stmt) != MODIFY_EXPR)
682     return false;
683
684   scalar_dest = TREE_OPERAND (stmt, 0);
685   if (TREE_CODE (scalar_dest) != SSA_NAME)
686     return false;
687
688   op = TREE_OPERAND (stmt, 1);
689   if (!vect_is_simple_use (op, loop_vinfo, NULL))
690     {
691       if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
692         fprintf (vect_dump, "use not simple.");
693       return false;
694     }
695
696   if (!vec_stmt) /* transformation not required.  */
697     {
698       STMT_VINFO_TYPE (stmt_info) = assignment_vec_info_type;
699       return true;
700     }
701
702   /** Transform.  **/
703   if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
704     fprintf (vect_dump, "transform assignment.");
705
706   /* Handle def.  */
707   vec_dest = vect_create_destination_var (scalar_dest, vectype);
708
709   /* Handle use.  */
710   op = TREE_OPERAND (stmt, 1);
711   vec_oprnd = vect_get_vec_def_for_operand (op, stmt);
712
713   /* Arguments are ready. create the new vector stmt.  */
714   *vec_stmt = build2 (MODIFY_EXPR, vectype, vec_dest, vec_oprnd);
715   new_temp = make_ssa_name (vec_dest, *vec_stmt);
716   TREE_OPERAND (*vec_stmt, 0) = new_temp;
717   vect_finish_stmt_generation (stmt, *vec_stmt, bsi);
718   
719   return true;
720 }
721
722
723 /* Function vectorizable_operation.
724
725    Check if STMT performs a binary or unary operation that can be vectorized. 
726    If VEC_STMT is also passed, vectorize the STMT: create a vectorized 
727    stmt to replace it, put it in VEC_STMT, and insert it at BSI.
728    Return FALSE if not a vectorizable STMT, TRUE otherwise.  */
729
730 bool
731 vectorizable_operation (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
732 {
733   tree vec_dest;
734   tree scalar_dest;
735   tree operation;
736   tree op0, op1 = NULL;
737   tree vec_oprnd0, vec_oprnd1=NULL;
738   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
739   tree vectype = STMT_VINFO_VECTYPE (stmt_info);
740   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
741   int i;
742   enum tree_code code;
743   enum machine_mode vec_mode;
744   tree new_temp;
745   int op_type;
746   tree op;
747   optab optab;
748
749   /* Is STMT a vectorizable binary/unary operation?   */
750   if (TREE_CODE (stmt) != MODIFY_EXPR)
751     return false;
752
753   if (TREE_CODE (TREE_OPERAND (stmt, 0)) != SSA_NAME)
754     return false;
755
756   operation = TREE_OPERAND (stmt, 1);
757   code = TREE_CODE (operation);
758   optab = optab_for_tree_code (code, vectype);
759
760   /* Support only unary or binary operations.  */
761   op_type = TREE_CODE_LENGTH (code);
762   if (op_type != unary_op && op_type != binary_op)
763     {
764       if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
765         fprintf (vect_dump, "num. args = %d (not unary/binary op).", op_type);
766       return false;
767     }
768
769   for (i = 0; i < op_type; i++)
770     {
771       op = TREE_OPERAND (operation, i);
772       if (!vect_is_simple_use (op, loop_vinfo, NULL))
773         {
774           if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
775             fprintf (vect_dump, "use not simple.");
776           return false;
777         }       
778     } 
779
780   /* Supportable by target?  */
781   if (!optab)
782     {
783       if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
784         fprintf (vect_dump, "no optab.");
785       return false;
786     }
787   vec_mode = TYPE_MODE (vectype);
788   if (optab->handlers[(int) vec_mode].insn_code == CODE_FOR_nothing)
789     {
790       if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
791         fprintf (vect_dump, "op not supported by target.");
792       return false;
793     }
794
795   if (!vec_stmt) /* transformation not required.  */
796     {
797       STMT_VINFO_TYPE (stmt_info) = op_vec_info_type;
798       return true;
799     }
800
801   /** Transform.  **/
802
803   if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
804     fprintf (vect_dump, "transform binary/unary operation.");
805
806   /* Handle def.  */
807   scalar_dest = TREE_OPERAND (stmt, 0);
808   vec_dest = vect_create_destination_var (scalar_dest, vectype);
809
810   /* Handle uses.  */
811   op0 = TREE_OPERAND (operation, 0);
812   vec_oprnd0 = vect_get_vec_def_for_operand (op0, stmt);
813
814   if (op_type == binary_op)
815     {
816       op1 = TREE_OPERAND (operation, 1);
817       vec_oprnd1 = vect_get_vec_def_for_operand (op1, stmt); 
818     }
819
820   /* Arguments are ready. create the new vector stmt.  */
821
822   if (op_type == binary_op)
823     *vec_stmt = build2 (MODIFY_EXPR, vectype, vec_dest,
824                 build2 (code, vectype, vec_oprnd0, vec_oprnd1));
825   else
826     *vec_stmt = build2 (MODIFY_EXPR, vectype, vec_dest,
827                 build1 (code, vectype, vec_oprnd0));
828   new_temp = make_ssa_name (vec_dest, *vec_stmt);
829   TREE_OPERAND (*vec_stmt, 0) = new_temp;
830   vect_finish_stmt_generation (stmt, *vec_stmt, bsi);
831
832   return true;
833 }
834
835
836 /* Function vectorizable_store.
837
838    Check if STMT defines a non scalar data-ref (array/pointer/structure) that 
839    can be vectorized. 
840    If VEC_STMT is also passed, vectorize the STMT: create a vectorized 
841    stmt to replace it, put it in VEC_STMT, and insert it at BSI.
842    Return FALSE if not a vectorizable STMT, TRUE otherwise.  */
843
844 bool
845 vectorizable_store (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
846 {
847   tree scalar_dest;
848   tree data_ref;
849   tree op;
850   tree vec_oprnd1;
851   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
852   struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
853   tree vectype = STMT_VINFO_VECTYPE (stmt_info);
854   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
855   enum machine_mode vec_mode;
856   tree dummy;
857   enum dr_alignment_support alignment_support_cheme;
858   v_may_def_optype v_may_defs;
859   int nv_may_defs, i;
860
861   /* Is vectorizable store? */
862
863   if (TREE_CODE (stmt) != MODIFY_EXPR)
864     return false;
865
866   scalar_dest = TREE_OPERAND (stmt, 0);
867   if (TREE_CODE (scalar_dest) != ARRAY_REF
868       && TREE_CODE (scalar_dest) != INDIRECT_REF)
869     return false;
870
871   op = TREE_OPERAND (stmt, 1);
872   if (!vect_is_simple_use (op, loop_vinfo, NULL))
873     {
874       if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
875         fprintf (vect_dump, "use not simple.");
876       return false;
877     }
878
879   vec_mode = TYPE_MODE (vectype);
880   /* FORNOW. In some cases can vectorize even if data-type not supported
881      (e.g. - array initialization with 0).  */
882   if (mov_optab->handlers[(int)vec_mode].insn_code == CODE_FOR_nothing)
883     return false;
884
885   if (!STMT_VINFO_DATA_REF (stmt_info))
886     return false;
887
888
889   if (!vec_stmt) /* transformation not required.  */
890     {
891       STMT_VINFO_TYPE (stmt_info) = store_vec_info_type;
892       return true;
893     }
894
895   /** Transform.  **/
896
897   if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
898     fprintf (vect_dump, "transform store");
899
900   alignment_support_cheme = vect_supportable_dr_alignment (dr);
901   gcc_assert (alignment_support_cheme);
902   gcc_assert (alignment_support_cheme == dr_aligned);  /* FORNOW */
903
904   /* Handle use - get the vectorized def from the defining stmt.  */
905   vec_oprnd1 = vect_get_vec_def_for_operand (op, stmt);
906
907   /* Handle def.  */
908   /* FORNOW: make sure the data reference is aligned.  */
909   vect_align_data_ref (stmt);
910   data_ref = vect_create_data_ref_ptr (stmt, bsi, NULL_TREE, &dummy, false);
911   data_ref = build_fold_indirect_ref (data_ref);
912
913   /* Arguments are ready. create the new vector stmt.  */
914   *vec_stmt = build2 (MODIFY_EXPR, vectype, data_ref, vec_oprnd1);
915   vect_finish_stmt_generation (stmt, *vec_stmt, bsi);
916
917   /* Copy the V_MAY_DEFS representing the aliasing of the original array
918      element's definition to the vector's definition then update the
919      defining statement.  The original is being deleted so the same
920      SSA_NAMEs can be used.  */
921   copy_virtual_operands (*vec_stmt, stmt);
922   v_may_defs = STMT_V_MAY_DEF_OPS (*vec_stmt);
923   nv_may_defs = NUM_V_MAY_DEFS (v_may_defs);
924             
925   for (i = 0; i < nv_may_defs; i++)
926     {
927       tree ssa_name = V_MAY_DEF_RESULT (v_may_defs, i);
928       SSA_NAME_DEF_STMT (ssa_name) = *vec_stmt;
929     }
930
931   return true;
932 }
933
934
935 /* vectorizable_load.
936
937    Check if STMT reads a non scalar data-ref (array/pointer/structure) that 
938    can be vectorized. 
939    If VEC_STMT is also passed, vectorize the STMT: create a vectorized 
940    stmt to replace it, put it in VEC_STMT, and insert it at BSI.
941    Return FALSE if not a vectorizable STMT, TRUE otherwise.  */
942
943 bool
944 vectorizable_load (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
945 {
946   tree scalar_dest;
947   tree vec_dest = NULL;
948   tree data_ref = NULL;
949   tree op;
950   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
951   struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
952   tree vectype = STMT_VINFO_VECTYPE (stmt_info);
953   tree new_temp;
954   int mode;
955   tree init_addr;
956   tree new_stmt;
957   tree dummy;
958   basic_block new_bb;
959   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
960   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
961   edge pe = loop_preheader_edge (loop);
962   enum dr_alignment_support alignment_support_cheme;
963
964   /* Is vectorizable load? */
965
966   if (TREE_CODE (stmt) != MODIFY_EXPR)
967     return false;
968
969   scalar_dest = TREE_OPERAND (stmt, 0);
970   if (TREE_CODE (scalar_dest) != SSA_NAME)
971     return false;
972
973   op = TREE_OPERAND (stmt, 1);
974   if (TREE_CODE (op) != ARRAY_REF && TREE_CODE (op) != INDIRECT_REF)
975     return false;
976
977   if (!STMT_VINFO_DATA_REF (stmt_info))
978     return false;
979
980   mode = (int) TYPE_MODE (vectype);
981
982   /* FORNOW. In some cases can vectorize even if data-type not supported
983     (e.g. - data copies).  */
984   if (mov_optab->handlers[mode].insn_code == CODE_FOR_nothing)
985     {
986       if (vect_print_dump_info (REPORT_DETAILS, LOOP_LOC (loop_vinfo)))
987         fprintf (vect_dump, "Aligned load, but unsupported type.");
988       return false;
989     }
990
991   if (!vec_stmt) /* transformation not required.  */
992     {
993       STMT_VINFO_TYPE (stmt_info) = load_vec_info_type;
994       return true;
995     }
996
997   /** Transform.  **/
998
999   if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
1000     fprintf (vect_dump, "transform load.");
1001
1002   alignment_support_cheme = vect_supportable_dr_alignment (dr);
1003   gcc_assert (alignment_support_cheme);
1004
1005   if (alignment_support_cheme == dr_aligned
1006       || alignment_support_cheme == dr_unaligned_supported)
1007     {
1008       /* Create:
1009          p = initial_addr;
1010          indx = 0;
1011          loop {
1012            vec_dest = *(p);
1013            indx = indx + 1;
1014          }
1015       */
1016
1017       vec_dest = vect_create_destination_var (scalar_dest, vectype);
1018       data_ref = vect_create_data_ref_ptr (stmt, bsi, NULL_TREE, &dummy, false);
1019       if (aligned_access_p (dr))
1020         data_ref = build_fold_indirect_ref (data_ref);
1021       else
1022         {
1023           int mis = DR_MISALIGNMENT (dr);
1024           tree tmis = (mis == -1 ? size_zero_node : size_int (mis));
1025           tmis = size_binop (MULT_EXPR, tmis, size_int(BITS_PER_UNIT));
1026           data_ref = build2 (MISALIGNED_INDIRECT_REF, vectype, data_ref, tmis);
1027         }
1028       new_stmt = build2 (MODIFY_EXPR, vectype, vec_dest, data_ref);
1029       new_temp = make_ssa_name (vec_dest, new_stmt);
1030       TREE_OPERAND (new_stmt, 0) = new_temp;
1031       vect_finish_stmt_generation (stmt, new_stmt, bsi);
1032       copy_virtual_operands (new_stmt, stmt);
1033     }
1034   else if (alignment_support_cheme == dr_unaligned_software_pipeline)
1035     {
1036       /* Create:
1037          p1 = initial_addr;
1038          msq_init = *(floor(p1))
1039          p2 = initial_addr + VS - 1;
1040          magic = have_builtin ? builtin_result : initial_address;
1041          indx = 0;
1042          loop {
1043            p2' = p2 + indx * vectype_size
1044            lsq = *(floor(p2'))
1045            vec_dest = realign_load (msq, lsq, magic)
1046            indx = indx + 1;
1047            msq = lsq;
1048          }
1049       */
1050
1051       tree offset;
1052       tree magic;
1053       tree phi_stmt;
1054       tree msq_init;
1055       tree msq, lsq;
1056       tree dataref_ptr;
1057       tree params;
1058
1059       /* <1> Create msq_init = *(floor(p1)) in the loop preheader  */
1060       vec_dest = vect_create_destination_var (scalar_dest, vectype);
1061       data_ref = vect_create_data_ref_ptr (stmt, bsi, NULL_TREE, 
1062                                            &init_addr, true);
1063       data_ref = build1 (ALIGN_INDIRECT_REF, vectype, data_ref);
1064       new_stmt = build2 (MODIFY_EXPR, vectype, vec_dest, data_ref);
1065       new_temp = make_ssa_name (vec_dest, new_stmt);
1066       TREE_OPERAND (new_stmt, 0) = new_temp;
1067       new_bb = bsi_insert_on_edge_immediate (pe, new_stmt);
1068       gcc_assert (!new_bb);
1069       msq_init = TREE_OPERAND (new_stmt, 0);
1070       copy_virtual_operands (new_stmt, stmt);
1071       update_vuses_to_preheader (new_stmt, loop);
1072
1073
1074       /* <2> Create lsq = *(floor(p2')) in the loop  */ 
1075       offset = build_int_cst (integer_type_node, 
1076                               GET_MODE_NUNITS (TYPE_MODE (vectype)));
1077       offset = int_const_binop (MINUS_EXPR, offset, integer_one_node, 1);
1078       vec_dest = vect_create_destination_var (scalar_dest, vectype);
1079       dataref_ptr = vect_create_data_ref_ptr (stmt, bsi, offset, &dummy, false);
1080       data_ref = build1 (ALIGN_INDIRECT_REF, vectype, dataref_ptr);
1081       new_stmt = build2 (MODIFY_EXPR, vectype, vec_dest, data_ref);
1082       new_temp = make_ssa_name (vec_dest, new_stmt);
1083       TREE_OPERAND (new_stmt, 0) = new_temp;
1084       vect_finish_stmt_generation (stmt, new_stmt, bsi);
1085       lsq = TREE_OPERAND (new_stmt, 0);
1086       copy_virtual_operands (new_stmt, stmt);
1087
1088
1089       /* <3> */
1090       if (targetm.vectorize.builtin_mask_for_load)
1091         {
1092           /* Create permutation mask, if required, in loop preheader.  */
1093           tree builtin_decl;
1094           params = build_tree_list (NULL_TREE, init_addr);
1095           vec_dest = vect_create_destination_var (scalar_dest, vectype);
1096           builtin_decl = targetm.vectorize.builtin_mask_for_load ();
1097           new_stmt = build_function_call_expr (builtin_decl, params);
1098           new_stmt = build2 (MODIFY_EXPR, vectype, vec_dest, new_stmt);
1099           new_temp = make_ssa_name (vec_dest, new_stmt);
1100           TREE_OPERAND (new_stmt, 0) = new_temp;
1101           new_bb = bsi_insert_on_edge_immediate (pe, new_stmt);
1102           gcc_assert (!new_bb);
1103           magic = TREE_OPERAND (new_stmt, 0);
1104
1105           /* The result of the CALL_EXPR to this builtin is determined from
1106              the value of the parameter and no global variables are touched
1107              which makes the builtin a "const" function.  Requiring the
1108              builtin to have the "const" attribute makes it unnecessary
1109              to call mark_call_clobbered_vars_to_rename.  */
1110           gcc_assert (TREE_READONLY (builtin_decl));
1111         }
1112       else
1113         {
1114           /* Use current address instead of init_addr for reduced reg pressure.
1115            */
1116           magic = dataref_ptr;
1117         }
1118
1119
1120       /* <4> Create msq = phi <msq_init, lsq> in loop  */ 
1121       vec_dest = vect_create_destination_var (scalar_dest, vectype);
1122       msq = make_ssa_name (vec_dest, NULL_TREE);
1123       phi_stmt = create_phi_node (msq, loop->header); /* CHECKME */
1124       SSA_NAME_DEF_STMT (msq) = phi_stmt;
1125       add_phi_arg (phi_stmt, msq_init, loop_preheader_edge (loop));
1126       add_phi_arg (phi_stmt, lsq, loop_latch_edge (loop));
1127
1128
1129       /* <5> Create <vec_dest = realign_load (msq, lsq, magic)> in loop  */
1130       vec_dest = vect_create_destination_var (scalar_dest, vectype);
1131       new_stmt = build3 (REALIGN_LOAD_EXPR, vectype, msq, lsq, magic);
1132       new_stmt = build2 (MODIFY_EXPR, vectype, vec_dest, new_stmt);
1133       new_temp = make_ssa_name (vec_dest, new_stmt); 
1134       TREE_OPERAND (new_stmt, 0) = new_temp;
1135       vect_finish_stmt_generation (stmt, new_stmt, bsi);
1136     }
1137   else
1138     gcc_unreachable ();
1139
1140   *vec_stmt = new_stmt;
1141   return true;
1142 }
1143
1144
1145 /* Function vect_transform_stmt.
1146
1147    Create a vectorized stmt to replace STMT, and insert it at BSI.  */
1148
1149 bool
1150 vect_transform_stmt (tree stmt, block_stmt_iterator *bsi)
1151 {
1152   bool is_store = false;
1153   tree vec_stmt = NULL_TREE;
1154   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
1155   bool done;
1156
1157   switch (STMT_VINFO_TYPE (stmt_info))
1158     {
1159     case op_vec_info_type:
1160       done = vectorizable_operation (stmt, bsi, &vec_stmt);
1161       gcc_assert (done);
1162       break;
1163
1164     case assignment_vec_info_type:
1165       done = vectorizable_assignment (stmt, bsi, &vec_stmt);
1166       gcc_assert (done);
1167       break;
1168
1169     case load_vec_info_type:
1170       done = vectorizable_load (stmt, bsi, &vec_stmt);
1171       gcc_assert (done);
1172       break;
1173
1174     case store_vec_info_type:
1175       done = vectorizable_store (stmt, bsi, &vec_stmt);
1176       gcc_assert (done);
1177       is_store = true;
1178       break;
1179     default:
1180       if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
1181         fprintf (vect_dump, "stmt not supported.");
1182       gcc_unreachable ();
1183     }
1184
1185   STMT_VINFO_VEC_STMT (stmt_info) = vec_stmt;
1186
1187   return is_store;
1188 }
1189
1190
1191 /* This function builds ni_name = number of iterations loop executes
1192    on the loop preheader.  */
1193
1194 static tree
1195 vect_build_loop_niters (loop_vec_info loop_vinfo)
1196 {
1197   tree ni_name, stmt, var;
1198   edge pe;
1199   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
1200   tree ni = unshare_expr (LOOP_VINFO_NITERS (loop_vinfo));
1201
1202   var = create_tmp_var (TREE_TYPE (ni), "niters");
1203   add_referenced_tmp_var (var);
1204   ni_name = force_gimple_operand (ni, &stmt, false, var);
1205
1206   pe = loop_preheader_edge (loop);
1207   if (stmt)
1208     {
1209       basic_block new_bb = bsi_insert_on_edge_immediate (pe, stmt);
1210       gcc_assert (!new_bb);
1211     }
1212       
1213   return ni_name;
1214 }
1215
1216
1217 /* This function generates the following statements:
1218
1219  ni_name = number of iterations loop executes
1220  ratio = ni_name / vf
1221  ratio_mult_vf_name = ratio * vf
1222
1223  and places them at the loop preheader edge.  */
1224
1225 static void 
1226 vect_generate_tmps_on_preheader (loop_vec_info loop_vinfo, 
1227                                  tree *ni_name_ptr,
1228                                  tree *ratio_mult_vf_name_ptr, 
1229                                  tree *ratio_name_ptr)
1230 {
1231
1232   edge pe;
1233   basic_block new_bb;
1234   tree stmt, ni_name;
1235   tree var;
1236   tree ratio_name;
1237   tree ratio_mult_vf_name;
1238   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
1239   tree ni = LOOP_VINFO_NITERS (loop_vinfo);
1240   int vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
1241   tree log_vf = build_int_cst (unsigned_type_node, exact_log2 (vf));
1242
1243   pe = loop_preheader_edge (loop);
1244
1245   /* Generate temporary variable that contains 
1246      number of iterations loop executes.  */
1247
1248   ni_name = vect_build_loop_niters (loop_vinfo);
1249
1250   /* Create: ratio = ni >> log2(vf) */
1251
1252   var = create_tmp_var (TREE_TYPE (ni), "bnd");
1253   add_referenced_tmp_var (var);
1254   ratio_name = make_ssa_name (var, NULL_TREE);
1255   stmt = build2 (MODIFY_EXPR, void_type_node, ratio_name,
1256            build2 (RSHIFT_EXPR, TREE_TYPE (ni_name), ni_name, log_vf));
1257   SSA_NAME_DEF_STMT (ratio_name) = stmt;
1258
1259   pe = loop_preheader_edge (loop);
1260   new_bb = bsi_insert_on_edge_immediate (pe, stmt);
1261   gcc_assert (!new_bb);
1262        
1263   /* Create: ratio_mult_vf = ratio << log2 (vf).  */
1264
1265   var = create_tmp_var (TREE_TYPE (ni), "ratio_mult_vf");
1266   add_referenced_tmp_var (var);
1267   ratio_mult_vf_name = make_ssa_name (var, NULL_TREE);
1268   stmt = build2 (MODIFY_EXPR, void_type_node, ratio_mult_vf_name,
1269            build2 (LSHIFT_EXPR, TREE_TYPE (ratio_name), ratio_name, log_vf));
1270   SSA_NAME_DEF_STMT (ratio_mult_vf_name) = stmt;
1271
1272   pe = loop_preheader_edge (loop);
1273   new_bb = bsi_insert_on_edge_immediate (pe, stmt);
1274   gcc_assert (!new_bb);
1275
1276   *ni_name_ptr = ni_name;
1277   *ratio_mult_vf_name_ptr = ratio_mult_vf_name;
1278   *ratio_name_ptr = ratio_name;
1279     
1280   return;  
1281 }
1282
1283
1284 /* Function update_vuses_to_preheader.
1285
1286    Input:
1287    STMT - a statement with potential VUSEs.
1288    LOOP - the loop whose preheader will contain STMT.
1289
1290    It's possible to vectorize a loop even though an SSA_NAME from a VUSE
1291    appears to be defined in a V_MAY_DEF in another statement in a loop.
1292    One such case is when the VUSE is at the dereference of a __restricted__
1293    pointer in a load and the V_MAY_DEF is at the dereference of a different
1294    __restricted__ pointer in a store.  Vectorization may result in
1295    copy_virtual_uses being called to copy the problematic VUSE to a new
1296    statement that is being inserted in the loop preheader.  This procedure
1297    is called to change the SSA_NAME in the new statement's VUSE from the
1298    SSA_NAME updated in the loop to the related SSA_NAME available on the
1299    path entering the loop.
1300
1301    When this function is called, we have the following situation:
1302
1303         # vuse <name1>
1304         S1: vload
1305     do {
1306         # name1 = phi < name0 , name2>
1307
1308         # vuse <name1>
1309         S2: vload
1310
1311         # name2 = vdef <name1>
1312         S3: vstore
1313
1314     }while...
1315
1316    Stmt S1 was created in the loop preheader block as part of misaligned-load
1317    handling. This function fixes the name of the vuse of S1 from 'name1' to
1318    'name0'.  */
1319
1320 static void
1321 update_vuses_to_preheader (tree stmt, struct loop *loop)
1322 {
1323   basic_block header_bb = loop->header;
1324   edge preheader_e = loop_preheader_edge (loop);
1325   vuse_optype vuses = STMT_VUSE_OPS (stmt);
1326   int nvuses = NUM_VUSES (vuses);
1327   int i;
1328
1329   for (i = 0; i < nvuses; i++)
1330     {
1331       tree ssa_name = VUSE_OP (vuses, i);
1332       tree def_stmt = SSA_NAME_DEF_STMT (ssa_name);
1333       tree name_var = SSA_NAME_VAR (ssa_name);
1334       basic_block bb = bb_for_stmt (def_stmt);
1335
1336       /* For a use before any definitions, def_stmt is a NOP_EXPR.  */
1337       if (!IS_EMPTY_STMT (def_stmt)
1338           && flow_bb_inside_loop_p (loop, bb))
1339         {
1340           /* If the block containing the statement defining the SSA_NAME
1341              is in the loop then it's necessary to find the definition
1342              outside the loop using the PHI nodes of the header.  */
1343           tree phi;
1344           bool updated = false;
1345
1346           for (phi = phi_nodes (header_bb); phi; phi = TREE_CHAIN (phi))
1347             {
1348               if (SSA_NAME_VAR (PHI_RESULT (phi)) == name_var)
1349                 {
1350                   SET_VUSE_OP (vuses, i, 
1351                                PHI_ARG_DEF (phi, preheader_e->dest_idx));
1352                   updated = true;
1353                   break;
1354                 }
1355             }
1356           gcc_assert (updated);
1357         }
1358     }
1359 }
1360
1361
1362 /*   Function vect_update_ivs_after_vectorizer.
1363
1364      "Advance" the induction variables of LOOP to the value they should take
1365      after the execution of LOOP.  This is currently necessary because the
1366      vectorizer does not handle induction variables that are used after the
1367      loop.  Such a situation occurs when the last iterations of LOOP are
1368      peeled, because:
1369      1. We introduced new uses after LOOP for IVs that were not originally used
1370         after LOOP: the IVs of LOOP are now used by an epilog loop.
1371      2. LOOP is going to be vectorized; this means that it will iterate N/VF
1372         times, whereas the loop IVs should be bumped N times.
1373
1374      Input:
1375      - LOOP - a loop that is going to be vectorized. The last few iterations
1376               of LOOP were peeled.
1377      - NITERS - the number of iterations that LOOP executes (before it is
1378                 vectorized). i.e, the number of times the ivs should be bumped.
1379      - UPDATE_E - a successor edge of LOOP->exit that is on the (only) path
1380                   coming out from LOOP on which there are uses of the LOOP ivs
1381                   (this is the path from LOOP->exit to epilog_loop->preheader).
1382
1383                   The new definitions of the ivs are placed in LOOP->exit.
1384                   The phi args associated with the edge UPDATE_E in the bb
1385                   UPDATE_E->dest are updated accordingly.
1386
1387      Assumption 1: Like the rest of the vectorizer, this function assumes
1388      a single loop exit that has a single predecessor.
1389
1390      Assumption 2: The phi nodes in the LOOP header and in update_bb are
1391      organized in the same order.
1392
1393      Assumption 3: The access function of the ivs is simple enough (see
1394      vect_can_advance_ivs_p).  This assumption will be relaxed in the future.
1395
1396      Assumption 4: Exactly one of the successors of LOOP exit-bb is on a path
1397      coming out of LOOP on which the ivs of LOOP are used (this is the path 
1398      that leads to the epilog loop; other paths skip the epilog loop).  This
1399      path starts with the edge UPDATE_E, and its destination (denoted update_bb)
1400      needs to have its phis updated.
1401  */
1402
1403 static void
1404 vect_update_ivs_after_vectorizer (loop_vec_info loop_vinfo, tree niters, 
1405                                   edge update_e)
1406 {
1407   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
1408   basic_block exit_bb = loop->single_exit->dest;
1409   tree phi, phi1;
1410   basic_block update_bb = update_e->dest;
1411
1412   /* gcc_assert (vect_can_advance_ivs_p (loop_vinfo)); */
1413
1414   /* Make sure there exists a single-predecessor exit bb:  */
1415   gcc_assert (single_pred_p (exit_bb));
1416
1417   for (phi = phi_nodes (loop->header), phi1 = phi_nodes (update_bb); 
1418        phi && phi1; 
1419        phi = PHI_CHAIN (phi), phi1 = PHI_CHAIN (phi1))
1420     {
1421       tree access_fn = NULL;
1422       tree evolution_part;
1423       tree init_expr;
1424       tree step_expr;
1425       tree var, stmt, ni, ni_name;
1426       block_stmt_iterator last_bsi;
1427
1428       /* Skip virtual phi's.  */
1429       if (!is_gimple_reg (SSA_NAME_VAR (PHI_RESULT (phi))))
1430         {
1431           if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
1432             fprintf (vect_dump, "virtual phi. skip.");
1433           continue;
1434         }
1435
1436       access_fn = analyze_scalar_evolution (loop, PHI_RESULT (phi)); 
1437       gcc_assert (access_fn);
1438       evolution_part =
1439          unshare_expr (evolution_part_in_loop_num (access_fn, loop->num));
1440       gcc_assert (evolution_part != NULL_TREE);
1441       
1442       /* FORNOW: We do not support IVs whose evolution function is a polynomial
1443          of degree >= 2 or exponential.  */
1444       gcc_assert (!tree_is_chrec (evolution_part));
1445
1446       step_expr = evolution_part;
1447       init_expr = unshare_expr (initial_condition_in_loop_num (access_fn, 
1448                                                                loop->num));
1449
1450       ni = build2 (PLUS_EXPR, TREE_TYPE (init_expr),
1451                   build2 (MULT_EXPR, TREE_TYPE (niters),
1452                        niters, step_expr), init_expr);
1453
1454       var = create_tmp_var (TREE_TYPE (init_expr), "tmp");
1455       add_referenced_tmp_var (var);
1456
1457       ni_name = force_gimple_operand (ni, &stmt, false, var);
1458       
1459       /* Insert stmt into exit_bb.  */
1460       last_bsi = bsi_last (exit_bb);
1461       if (stmt)
1462         bsi_insert_before (&last_bsi, stmt, BSI_SAME_STMT);   
1463
1464       /* Fix phi expressions in the successor bb.  */
1465       SET_PHI_ARG_DEF (phi1, update_e->dest_idx, ni_name);
1466     }
1467 }
1468
1469
1470 /* Function vect_do_peeling_for_loop_bound
1471
1472    Peel the last iterations of the loop represented by LOOP_VINFO.
1473    The peeled iterations form a new epilog loop.  Given that the loop now 
1474    iterates NITERS times, the new epilog loop iterates
1475    NITERS % VECTORIZATION_FACTOR times.
1476    
1477    The original loop will later be made to iterate 
1478    NITERS / VECTORIZATION_FACTOR times (this value is placed into RATIO).  */
1479
1480 static void 
1481 vect_do_peeling_for_loop_bound (loop_vec_info loop_vinfo, tree *ratio,
1482                                 struct loops *loops)
1483 {
1484
1485   tree ni_name, ratio_mult_vf_name;
1486   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
1487   struct loop *new_loop;
1488   edge update_e;
1489   basic_block preheader;
1490 #ifdef ENABLE_CHECKING
1491   int loop_num;
1492 #endif
1493
1494   if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
1495     fprintf (vect_dump, "=== vect_transtorm_for_unknown_loop_bound ===");
1496
1497   /* Generate the following variables on the preheader of original loop:
1498          
1499      ni_name = number of iteration the original loop executes
1500      ratio = ni_name / vf
1501      ratio_mult_vf_name = ratio * vf  */
1502   vect_generate_tmps_on_preheader (loop_vinfo, &ni_name,
1503                                    &ratio_mult_vf_name, ratio);
1504
1505 #ifdef ENABLE_CHECKING
1506   loop_num  = loop->num; 
1507 #endif
1508   new_loop = slpeel_tree_peel_loop_to_edge (loop, loops, loop->single_exit,
1509                                             ratio_mult_vf_name, ni_name, false);
1510 #ifdef ENABLE_CHECKING
1511   gcc_assert (new_loop);
1512   gcc_assert (loop_num == loop->num);
1513   slpeel_verify_cfg_after_peeling (loop, new_loop);
1514 #endif
1515
1516   /* A guard that controls whether the new_loop is to be executed or skipped
1517      is placed in LOOP->exit.  LOOP->exit therefore has two successors - one
1518      is the preheader of NEW_LOOP, where the IVs from LOOP are used.  The other
1519      is a bb after NEW_LOOP, where these IVs are not used.  Find the edge that
1520      is on the path where the LOOP IVs are used and need to be updated.  */
1521
1522   preheader = loop_preheader_edge (new_loop)->src;
1523   if (EDGE_PRED (preheader, 0)->src == loop->single_exit->dest)
1524     update_e = EDGE_PRED (preheader, 0);
1525   else
1526     update_e = EDGE_PRED (preheader, 1);
1527
1528   /* Update IVs of original loop as if they were advanced 
1529      by ratio_mult_vf_name steps.  */
1530   vect_update_ivs_after_vectorizer (loop_vinfo, ratio_mult_vf_name, update_e); 
1531
1532   /* After peeling we have to reset scalar evolution analyzer.  */
1533   scev_reset ();
1534
1535   return;
1536 }
1537
1538
1539 /* Function vect_gen_niters_for_prolog_loop
1540
1541    Set the number of iterations for the loop represented by LOOP_VINFO
1542    to the minimum between LOOP_NITERS (the original iteration count of the loop)
1543    and the misalignment of DR - the data reference recorded in
1544    LOOP_VINFO_UNALIGNED_DR (LOOP_VINFO).  As a result, after the execution of 
1545    this loop, the data reference DR will refer to an aligned location.
1546
1547    The following computation is generated:
1548
1549    If the misalignment of DR is known at compile time:
1550      addr_mis = int mis = DR_MISALIGNMENT (dr);
1551    Else, compute address misalignment in bytes:
1552      addr_mis = addr & (vectype_size - 1)
1553
1554    prolog_niters = min ( LOOP_NITERS , (VF - addr_mis/elem_size)&(VF-1) )
1555    
1556    (elem_size = element type size; an element is the scalar element 
1557         whose type is the inner type of the vectype)  */
1558
1559 static tree 
1560 vect_gen_niters_for_prolog_loop (loop_vec_info loop_vinfo, tree loop_niters)
1561 {
1562   struct data_reference *dr = LOOP_VINFO_UNALIGNED_DR (loop_vinfo);
1563   int vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
1564   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
1565   tree var, stmt;
1566   tree iters, iters_name;
1567   edge pe;
1568   basic_block new_bb;
1569   tree dr_stmt = DR_STMT (dr);
1570   stmt_vec_info stmt_info = vinfo_for_stmt (dr_stmt);
1571   tree vectype = STMT_VINFO_VECTYPE (stmt_info);
1572   int vectype_align = TYPE_ALIGN (vectype) / BITS_PER_UNIT;
1573   tree vf_minus_1 = build_int_cst (unsigned_type_node, vf - 1);
1574   tree niters_type = TREE_TYPE (loop_niters);
1575
1576   pe = loop_preheader_edge (loop); 
1577
1578   if (LOOP_PEELING_FOR_ALIGNMENT (loop_vinfo) > 0)
1579     {
1580       int byte_misalign = LOOP_PEELING_FOR_ALIGNMENT (loop_vinfo);
1581       int element_size = vectype_align/vf;
1582       int elem_misalign = byte_misalign / element_size;
1583
1584       if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
1585         fprintf (vect_dump, "known alignment = %d.", byte_misalign);
1586       iters = build_int_cst (niters_type, (vf - elem_misalign)&(vf-1));
1587     }
1588   else
1589     {
1590       tree new_stmts = NULL_TREE;
1591       tree start_addr =
1592         vect_create_addr_base_for_vector_ref (dr_stmt, &new_stmts, NULL_TREE);
1593       tree ptr_type = TREE_TYPE (start_addr);
1594       tree size = TYPE_SIZE (ptr_type);
1595       tree type = lang_hooks.types.type_for_size (tree_low_cst (size, 1), 1);
1596       tree vectype_size_minus_1 = build_int_cst (type, vectype_align - 1);
1597       tree elem_size_log =
1598         build_int_cst (unsigned_type_node, exact_log2 (vectype_align/vf));
1599       tree vf_tree = build_int_cst (unsigned_type_node, vf);
1600       tree byte_misalign;
1601       tree elem_misalign;
1602
1603       new_bb = bsi_insert_on_edge_immediate (pe, new_stmts);
1604       gcc_assert (!new_bb);
1605   
1606       /* Create:  byte_misalign = addr & (vectype_size - 1)  */
1607       byte_misalign = 
1608         build2 (BIT_AND_EXPR, type, start_addr, vectype_size_minus_1);
1609   
1610       /* Create:  elem_misalign = byte_misalign / element_size  */
1611       elem_misalign =
1612         build2 (RSHIFT_EXPR, unsigned_type_node, byte_misalign, elem_size_log);
1613
1614       /* Create:  (niters_type) (VF - elem_misalign)&(VF - 1)  */
1615       iters = build2 (MINUS_EXPR, unsigned_type_node, vf_tree, elem_misalign);
1616       iters = build2 (BIT_AND_EXPR, unsigned_type_node, iters, vf_minus_1);
1617       iters = fold_convert (niters_type, iters);
1618     }
1619
1620   /* Create:  prolog_loop_niters = min (iters, loop_niters) */
1621   /* If the loop bound is known at compile time we already verified that it is
1622      greater than vf; since the misalignment ('iters') is at most vf, there's
1623      no need to generate the MIN_EXPR in this case.  */
1624   if (TREE_CODE (loop_niters) != INTEGER_CST)
1625     iters = build2 (MIN_EXPR, niters_type, iters, loop_niters);
1626
1627   if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
1628     {
1629       fprintf (vect_dump, "niters for prolog loop: ");
1630       print_generic_expr (vect_dump, iters, TDF_SLIM);
1631     }
1632
1633   var = create_tmp_var (niters_type, "prolog_loop_niters");
1634   add_referenced_tmp_var (var);
1635   iters_name = force_gimple_operand (iters, &stmt, false, var);
1636
1637   /* Insert stmt on loop preheader edge.  */
1638   if (stmt)
1639     {
1640       basic_block new_bb = bsi_insert_on_edge_immediate (pe, stmt);
1641       gcc_assert (!new_bb);
1642     }
1643
1644   return iters_name; 
1645 }
1646
1647
1648 /* Function vect_update_init_of_dr
1649
1650    NITERS iterations were peeled from LOOP.  DR represents a data reference
1651    in LOOP.  This function updates the information recorded in DR to
1652    account for the fact that the first NITERS iterations had already been 
1653    executed.  Specifically, it updates the OFFSET field of stmt_info.  */
1654
1655 static void
1656 vect_update_init_of_dr (struct data_reference *dr, tree niters)
1657 {
1658   stmt_vec_info stmt_info = vinfo_for_stmt (DR_STMT (dr));
1659   tree offset = STMT_VINFO_VECT_INIT_OFFSET (stmt_info);
1660       
1661   niters = fold (build2 (MULT_EXPR, TREE_TYPE (niters), niters, 
1662                          STMT_VINFO_VECT_STEP (stmt_info)));
1663   offset = fold (build2 (PLUS_EXPR, TREE_TYPE (offset), offset, niters));
1664   STMT_VINFO_VECT_INIT_OFFSET (stmt_info) = offset;
1665 }
1666
1667
1668 /* Function vect_update_inits_of_drs
1669
1670    NITERS iterations were peeled from the loop represented by LOOP_VINFO.  
1671    This function updates the information recorded for the data references in 
1672    the loop to account for the fact that the first NITERS iterations had 
1673    already been executed.  Specifically, it updates the initial_condition of the
1674    access_function of all the data_references in the loop.  */
1675
1676 static void
1677 vect_update_inits_of_drs (loop_vec_info loop_vinfo, tree niters)
1678 {
1679   unsigned int i;
1680   varray_type loop_write_datarefs = LOOP_VINFO_DATAREF_WRITES (loop_vinfo);
1681   varray_type loop_read_datarefs = LOOP_VINFO_DATAREF_READS (loop_vinfo);
1682
1683   if (vect_dump && (dump_flags & TDF_DETAILS))
1684     fprintf (vect_dump, "=== vect_update_inits_of_dr ===");
1685
1686   for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_write_datarefs); i++)
1687     {
1688       struct data_reference *dr = VARRAY_GENERIC_PTR (loop_write_datarefs, i);
1689       vect_update_init_of_dr (dr, niters);
1690     }
1691
1692   for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_read_datarefs); i++)
1693     {
1694       struct data_reference *dr = VARRAY_GENERIC_PTR (loop_read_datarefs, i);
1695       vect_update_init_of_dr (dr, niters);
1696     }
1697 }
1698
1699
1700 /* Function vect_do_peeling_for_alignment
1701
1702    Peel the first 'niters' iterations of the loop represented by LOOP_VINFO.
1703    'niters' is set to the misalignment of one of the data references in the
1704    loop, thereby forcing it to refer to an aligned location at the beginning
1705    of the execution of this loop.  The data reference for which we are
1706    peeling is recorded in LOOP_VINFO_UNALIGNED_DR.  */
1707
1708 static void
1709 vect_do_peeling_for_alignment (loop_vec_info loop_vinfo, struct loops *loops)
1710 {
1711   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
1712   tree niters_of_prolog_loop, ni_name;
1713   tree n_iters;
1714   struct loop *new_loop;
1715
1716   if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
1717     fprintf (vect_dump, "=== vect_do_peeling_for_alignment ===");
1718
1719   ni_name = vect_build_loop_niters (loop_vinfo);
1720   niters_of_prolog_loop = vect_gen_niters_for_prolog_loop (loop_vinfo, ni_name);
1721   
1722   /* Peel the prolog loop and iterate it niters_of_prolog_loop.  */
1723   new_loop = 
1724         slpeel_tree_peel_loop_to_edge (loop, loops, loop_preheader_edge (loop), 
1725                                        niters_of_prolog_loop, ni_name, true); 
1726 #ifdef ENABLE_CHECKING
1727   gcc_assert (new_loop);
1728   slpeel_verify_cfg_after_peeling (new_loop, loop);
1729 #endif
1730
1731   /* Update number of times loop executes.  */
1732   n_iters = LOOP_VINFO_NITERS (loop_vinfo);
1733   LOOP_VINFO_NITERS (loop_vinfo) = fold (build2 (MINUS_EXPR,
1734                 TREE_TYPE (n_iters), n_iters, niters_of_prolog_loop));
1735
1736   /* Update the init conditions of the access functions of all data refs.  */
1737   vect_update_inits_of_drs (loop_vinfo, niters_of_prolog_loop);
1738
1739   /* After peeling we have to reset scalar evolution analyzer.  */
1740   scev_reset ();
1741
1742   return;
1743 }
1744
1745
1746 /* Function vect_transform_loop.
1747
1748    The analysis phase has determined that the loop is vectorizable.
1749    Vectorize the loop - created vectorized stmts to replace the scalar
1750    stmts in the loop, and update the loop exit condition.  */
1751
1752 void
1753 vect_transform_loop (loop_vec_info loop_vinfo, 
1754                      struct loops *loops ATTRIBUTE_UNUSED)
1755 {
1756   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
1757   basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
1758   int nbbs = loop->num_nodes;
1759   block_stmt_iterator si;
1760   int i;
1761   tree ratio = NULL;
1762   int vectorization_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
1763
1764   if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
1765     fprintf (vect_dump, "=== vec_transform_loop ===");
1766
1767   
1768   /* Peel the loop if there are data refs with unknown alignment.
1769      Only one data ref with unknown store is allowed.  */
1770
1771   if (LOOP_PEELING_FOR_ALIGNMENT (loop_vinfo))
1772     vect_do_peeling_for_alignment (loop_vinfo, loops);
1773   
1774   /* If the loop has a symbolic number of iterations 'n' (i.e. it's not a
1775      compile time constant), or it is a constant that doesn't divide by the
1776      vectorization factor, then an epilog loop needs to be created.
1777      We therefore duplicate the loop: the original loop will be vectorized,
1778      and will compute the first (n/VF) iterations. The second copy of the loop
1779      will remain scalar and will compute the remaining (n%VF) iterations.
1780      (VF is the vectorization factor).  */
1781
1782   if (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
1783       || (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
1784           && LOOP_VINFO_INT_NITERS (loop_vinfo) % vectorization_factor != 0))
1785     vect_do_peeling_for_loop_bound (loop_vinfo, &ratio, loops);
1786   else
1787     ratio = build_int_cst (TREE_TYPE (LOOP_VINFO_NITERS (loop_vinfo)),
1788                 LOOP_VINFO_INT_NITERS (loop_vinfo) / vectorization_factor);
1789
1790   /* 1) Make sure the loop header has exactly two entries
1791      2) Make sure we have a preheader basic block.  */
1792
1793   gcc_assert (EDGE_COUNT (loop->header->preds) == 2);
1794
1795   loop_split_edge_with (loop_preheader_edge (loop), NULL);
1796
1797
1798   /* FORNOW: the vectorizer supports only loops which body consist
1799      of one basic block (header + empty latch). When the vectorizer will 
1800      support more involved loop forms, the order by which the BBs are 
1801      traversed need to be reconsidered.  */
1802
1803   for (i = 0; i < nbbs; i++)
1804     {
1805       basic_block bb = bbs[i];
1806
1807       for (si = bsi_start (bb); !bsi_end_p (si);)
1808         {
1809           tree stmt = bsi_stmt (si);
1810           stmt_vec_info stmt_info;
1811           bool is_store;
1812
1813           if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
1814             {
1815               fprintf (vect_dump, "------>vectorizing statement: ");
1816               print_generic_expr (vect_dump, stmt, TDF_SLIM);
1817             }   
1818           stmt_info = vinfo_for_stmt (stmt);
1819           gcc_assert (stmt_info);
1820           if (!STMT_VINFO_RELEVANT_P (stmt_info))
1821             {
1822               bsi_next (&si);
1823               continue;
1824             }
1825 #ifdef ENABLE_CHECKING
1826           /* FORNOW: Verify that all stmts operate on the same number of
1827                      units and no inner unrolling is necessary.  */
1828           gcc_assert 
1829                 (GET_MODE_NUNITS (TYPE_MODE (STMT_VINFO_VECTYPE (stmt_info)))
1830                  == vectorization_factor);
1831 #endif
1832           /* -------- vectorize statement ------------ */
1833           if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
1834             fprintf (vect_dump, "transform statement.");
1835
1836           is_store = vect_transform_stmt (stmt, &si);
1837           if (is_store)
1838             {
1839               /* free the attached stmt_vec_info and remove the stmt.  */
1840               stmt_ann_t ann = stmt_ann (stmt);
1841               free (stmt_info);
1842               set_stmt_info (ann, NULL);
1843               bsi_remove (&si);
1844               continue;
1845             }
1846
1847           bsi_next (&si);
1848         }                       /* stmts in BB */
1849     }                           /* BBs in loop */
1850
1851   slpeel_make_loop_iterate_ntimes (loop, ratio);
1852
1853   if (vect_print_dump_info (REPORT_VECTORIZED_LOOPS, LOOP_LOC (loop_vinfo)))
1854     fprintf (vect_dump, "LOOP VECTORIZED.");
1855 }