OSDN Git Service

* tree-vectorizer.c (slpeel_make_loop_iterate_ntimes): Last two
[pf3gnuchains/gcc-fork.git] / gcc / tree-vectorizer.c
1 /* Loop Vectorization
2    Copyright (C) 2003, 2004 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 /* Loop Vectorization Pass.
23
24    This pass tries to vectorize loops. This first implementation focuses on
25    simple inner-most loops, with no conditional control flow, and a set of
26    simple operations which vector form can be expressed using existing
27    tree codes (PLUS, MULT etc).
28
29    For example, the vectorizer transforms the following simple loop:
30
31         short a[N]; short b[N]; short c[N]; int i;
32
33         for (i=0; i<N; i++){
34           a[i] = b[i] + c[i];
35         }
36
37    as if it was manually vectorized by rewriting the source code into:
38
39         typedef int __attribute__((mode(V8HI))) v8hi;
40         short a[N];  short b[N]; short c[N];   int i;
41         v8hi *pa = (v8hi*)a, *pb = (v8hi*)b, *pc = (v8hi*)c;
42         v8hi va, vb, vc;
43
44         for (i=0; i<N/8; i++){
45           vb = pb[i];
46           vc = pc[i];
47           va = vb + vc;
48           pa[i] = va;
49         }
50
51         The main entry to this pass is vectorize_loops(), in which
52    the vectorizer applies a set of analyses on a given set of loops,
53    followed by the actual vectorization transformation for the loops that
54    had successfully passed the analysis phase.
55
56         Throughout this pass we make a distinction between two types of
57    data: scalars (which are represented by SSA_NAMES), and memory references
58    ("data-refs"). These two types of data require different handling both 
59    during analysis and transformation. The types of data-refs that the 
60    vectorizer currently supports are ARRAY_REFS which base is an array DECL 
61    (not a pointer), and INDIRECT_REFS through pointers; both array and pointer
62    accesses are required to have a  simple (consecutive) access pattern.
63
64    Analysis phase:
65    ===============
66         The driver for the analysis phase is vect_analyze_loop_nest().
67    It applies a set of analyses, some of which rely on the scalar evolution 
68    analyzer (scev) developed by Sebastian Pop.
69
70         During the analysis phase the vectorizer records some information
71    per stmt in a "stmt_vec_info" struct which is attached to each stmt in the 
72    loop, as well as general information about the loop as a whole, which is
73    recorded in a "loop_vec_info" struct attached to each loop.
74
75    Transformation phase:
76    =====================
77         The loop transformation phase scans all the stmts in the loop, and
78    creates a vector stmt (or a sequence of stmts) for each scalar stmt S in
79    the loop that needs to be vectorized. It insert the vector code sequence
80    just before the scalar stmt S, and records a pointer to the vector code
81    in STMT_VINFO_VEC_STMT (stmt_info) (stmt_info is the stmt_vec_info struct 
82    attached to S). This pointer will be used for the vectorization of following
83    stmts which use the def of stmt S. Stmt S is removed if it writes to memory;
84    otherwise, we rely on dead code elimination for removing it.
85
86         For example, say stmt S1 was vectorized into stmt VS1:
87
88    VS1: vb = px[i];
89    S1:  b = x[i];    STMT_VINFO_VEC_STMT (stmt_info (S1)) = VS1
90    S2:  a = b;
91
92    To vectorize stmt S2, the vectorizer first finds the stmt that defines
93    the operand 'b' (S1), and gets the relevant vector def 'vb' from the
94    vector stmt VS1 pointed by STMT_VINFO_VEC_STMT (stmt_info (S1)). The
95    resulting sequence would be:
96
97    VS1: vb = px[i];
98    S1:  b = x[i];       STMT_VINFO_VEC_STMT (stmt_info (S1)) = VS1
99    VS2: va = vb;
100    S2:  a = b;          STMT_VINFO_VEC_STMT (stmt_info (S2)) = VS2
101
102         Operands that are not SSA_NAMEs, are data-refs that appear in 
103    load/store operations (like 'x[i]' in S1), and are handled differently.
104
105    Target modeling:
106    =================
107         Currently the only target specific information that is used is the
108    size of the vector (in bytes) - "UNITS_PER_SIMD_WORD". Targets that can 
109    support different sizes of vectors, for now will need to specify one value 
110    for "UNITS_PER_SIMD_WORD". More flexibility will be added in the future.
111
112         Since we only vectorize operations which vector form can be
113    expressed using existing tree codes, to verify that an operation is
114    supported, the vectorizer checks the relevant optab at the relevant
115    machine_mode (e.g, add_optab->handlers[(int) V8HImode].insn_code). If
116    the value found is CODE_FOR_nothing, then there's no target support, and
117    we can't vectorize the stmt.
118
119    For additional information on this project see:
120    http://gcc.gnu.org/projects/tree-ssa/vectorization.html
121 */
122
123 #include "config.h"
124 #include "system.h"
125 #include "coretypes.h"
126 #include "tm.h"
127 #include "errors.h"
128 #include "ggc.h"
129 #include "tree.h"
130 #include "target.h"
131
132 #include "rtl.h"
133 #include "basic-block.h"
134 #include "diagnostic.h"
135 #include "tree-flow.h"
136 #include "tree-dump.h"
137 #include "timevar.h"
138 #include "cfgloop.h"
139 #include "cfglayout.h"
140 #include "expr.h"
141 #include "optabs.h"
142 #include "toplev.h"
143 #include "tree-chrec.h"
144 #include "tree-data-ref.h"
145 #include "tree-scalar-evolution.h"
146 #include "tree-vectorizer.h"
147 #include "tree-pass.h"
148
149
150 /*************************************************************************
151   Simple Loop Peeling Utilities
152  *************************************************************************/
153    
154 /* Entry point for peeling of simple loops.
155    Peel the first/last iterations of a loop.
156    It can be used outside of the vectorizer for loops that are simple enough
157    (see function documentation).  In the vectorizer it is used to peel the
158    last few iterations when the loop bound is unknown or does not evenly
159    divide by the vectorization factor, and to peel the first few iterations
160    to force the alignment of data references in the loop.  */
161 struct loop *slpeel_tree_peel_loop_to_edge 
162   (struct loop *, struct loops *, edge, tree, tree, bool);
163 static struct loop *slpeel_tree_duplicate_loop_to_edge_cfg 
164   (struct loop *, struct loops *, edge);
165 static void slpeel_update_phis_for_duplicate_loop 
166   (struct loop *, struct loop *, bool after);
167 static void slpeel_update_phi_nodes_for_guard (edge, struct loop *);
168 static void slpeel_make_loop_iterate_ntimes (struct loop *, tree);
169 static edge slpeel_add_loop_guard (basic_block, tree, basic_block);
170 static bool slpeel_can_duplicate_loop_p (struct loop *, edge);
171 static void allocate_new_names (bitmap);
172 static void rename_use_op (use_operand_p);
173 static void rename_def_op (def_operand_p, tree);
174 static void rename_variables_in_bb (basic_block);
175 static void free_new_names (bitmap);
176 static void rename_variables_in_loop (struct loop *);
177
178
179 /*************************************************************************
180   Vectorization Utilities. 
181  *************************************************************************/
182
183 /* Main analysis functions.  */
184 static loop_vec_info vect_analyze_loop (struct loop *);
185 static loop_vec_info vect_analyze_loop_form (struct loop *);
186 static bool vect_analyze_data_refs (loop_vec_info);
187 static bool vect_mark_stmts_to_be_vectorized (loop_vec_info);
188 static bool vect_analyze_scalar_cycles (loop_vec_info);
189 static bool vect_analyze_data_ref_accesses (loop_vec_info);
190 static bool vect_analyze_data_refs_alignment (loop_vec_info);
191 static bool vect_compute_data_refs_alignment (loop_vec_info);
192 static bool vect_analyze_operations (loop_vec_info);
193
194 /* Main code transformation functions.  */
195 static void vect_transform_loop (loop_vec_info, struct loops *);
196 static void vect_transform_loop_bound (loop_vec_info, tree niters);
197 static bool vect_transform_stmt (tree, block_stmt_iterator *);
198 static bool vectorizable_load (tree, block_stmt_iterator *, tree *);
199 static bool vectorizable_store (tree, block_stmt_iterator *, tree *);
200 static bool vectorizable_operation (tree, block_stmt_iterator *, tree *);
201 static bool vectorizable_assignment (tree, block_stmt_iterator *, tree *);
202 static enum dr_alignment_support vect_supportable_dr_alignment
203   (struct data_reference *);
204 static void vect_align_data_ref (tree);
205 static void vect_enhance_data_refs_alignment (loop_vec_info);
206
207 /* Utility functions for the analyses.  */
208 static bool vect_is_simple_use (tree , struct loop *, tree *);
209 static bool exist_non_indexing_operands_for_use_p (tree, tree);
210 static bool vect_is_simple_iv_evolution (unsigned, tree, tree *, tree *, bool);
211 static void vect_mark_relevant (varray_type, tree);
212 static bool vect_stmt_relevant_p (tree, loop_vec_info);
213 static tree vect_get_loop_niters (struct loop *, tree *);
214 static bool vect_compute_data_ref_alignment 
215   (struct data_reference *, loop_vec_info);
216 static bool vect_analyze_data_ref_access (struct data_reference *);
217 static bool vect_get_first_index (tree, tree *);
218 static bool vect_can_force_dr_alignment_p (tree, unsigned int);
219 static struct data_reference * vect_analyze_pointer_ref_access 
220   (tree, tree, bool);
221 static bool vect_can_advance_ivs_p (struct loop *);
222 static tree vect_get_base_and_bit_offset
223   (struct data_reference *, tree, tree, loop_vec_info, tree *, bool*);
224 static struct data_reference * vect_analyze_pointer_ref_access
225   (tree, tree, bool);
226 static tree vect_compute_array_base_alignment (tree, tree, tree *, tree *);
227 static tree vect_compute_array_ref_alignment
228   (struct data_reference *, loop_vec_info, tree, tree *);
229 static tree vect_get_ptr_offset (tree, tree, tree *);
230 static tree vect_get_symbl_and_dr
231   (tree, tree, bool, loop_vec_info, struct data_reference **);
232
233 /* Utility functions for the code transformation.  */
234 static tree vect_create_destination_var (tree, tree);
235 static tree vect_create_data_ref_ptr 
236   (tree, block_stmt_iterator *, tree, tree *, bool); 
237 static tree vect_create_index_for_vector_ref 
238   (struct loop *, block_stmt_iterator *);
239 static tree vect_create_addr_base_for_vector_ref (tree, tree *, tree);
240 static tree get_vectype_for_scalar_type (tree);
241 static tree vect_get_new_vect_var (tree, enum vect_var_kind, const char *);
242 static tree vect_get_vec_def_for_operand (tree, tree);
243 static tree vect_init_vector (tree, tree);
244 static tree vect_build_symbol_bound (tree, int, struct loop *);
245 static void vect_finish_stmt_generation 
246   (tree stmt, tree vec_stmt, block_stmt_iterator *bsi);
247
248 /* Utility function dealing with loop peeling (not peeling itself).  */
249 static void vect_generate_tmps_on_preheader 
250   (loop_vec_info, tree *, tree *, tree *);
251 static tree vect_build_loop_niters (loop_vec_info);
252 static void vect_update_ivs_after_vectorizer (struct loop *, tree); 
253 static tree vect_gen_niters_for_prolog_loop (loop_vec_info, tree);
254 static void vect_update_inits_of_dr 
255   (struct data_reference *, struct loop *, tree niters);
256 static void vect_update_inits_of_drs (loop_vec_info, tree);
257 static void vect_do_peeling_for_alignment (loop_vec_info, struct loops *);
258 static void vect_do_peeling_for_loop_bound 
259   (loop_vec_info, tree *, struct loops *);
260
261 /* Utilities for creation and deletion of vec_info structs.  */
262 loop_vec_info new_loop_vec_info (struct loop *loop);
263 void destroy_loop_vec_info (loop_vec_info);
264 stmt_vec_info new_stmt_vec_info (tree stmt, struct loop *loop);
265
266 static bool vect_debug_stats (struct loop *loop);
267 static bool vect_debug_details (struct loop *loop);
268
269 \f
270 /*************************************************************************
271   Simple Loop Peeling Utilities
272
273   Utilities to support loop peeling for vectorization purposes.
274  *************************************************************************/
275
276
277 /* For each definition in DEFINITIONS this function allocates 
278    new ssa name.  */
279
280 static void
281 allocate_new_names (bitmap definitions)
282 {
283   unsigned ver;
284   bitmap_iterator bi;
285
286   EXECUTE_IF_SET_IN_BITMAP (definitions, 0, ver, bi)
287     {
288       tree def = ssa_name (ver);
289       tree *new_name_ptr = xmalloc (sizeof (tree));
290
291       bool abnormal = SSA_NAME_OCCURS_IN_ABNORMAL_PHI (def);
292
293       *new_name_ptr = duplicate_ssa_name (def, SSA_NAME_DEF_STMT (def));
294       SSA_NAME_OCCURS_IN_ABNORMAL_PHI (*new_name_ptr) = abnormal;
295
296       SSA_NAME_AUX (def) = new_name_ptr;
297     }
298 }
299
300
301 /* Renames the use *OP_P.  */
302
303 static void
304 rename_use_op (use_operand_p op_p)
305 {
306   tree *new_name_ptr;
307
308   if (TREE_CODE (USE_FROM_PTR (op_p)) != SSA_NAME)
309     return;
310
311   new_name_ptr = SSA_NAME_AUX (USE_FROM_PTR (op_p));
312
313   /* Something defined outside of the loop.  */
314   if (!new_name_ptr)
315     return;
316
317   /* An ordinary ssa name defined in the loop.  */
318
319   SET_USE (op_p, *new_name_ptr);
320 }
321
322
323 /* Renames the def *OP_P in statement STMT.  */
324
325 static void
326 rename_def_op (def_operand_p op_p, tree stmt)
327 {
328   tree *new_name_ptr;
329
330   if (TREE_CODE (DEF_FROM_PTR (op_p)) != SSA_NAME)
331     return;
332
333   new_name_ptr = SSA_NAME_AUX (DEF_FROM_PTR (op_p));
334
335   /* Something defined outside of the loop.  */
336   if (!new_name_ptr)
337     return;
338
339   /* An ordinary ssa name defined in the loop.  */
340
341   SET_DEF (op_p, *new_name_ptr);
342   SSA_NAME_DEF_STMT (DEF_FROM_PTR (op_p)) = stmt;
343 }
344
345
346 /* Renames the variables in basic block BB.  */
347
348 static void
349 rename_variables_in_bb (basic_block bb)
350 {
351   tree phi;
352   block_stmt_iterator bsi;
353   tree stmt;
354   stmt_ann_t ann;
355   use_optype uses;
356   vuse_optype vuses;
357   def_optype defs;
358   v_may_def_optype v_may_defs;
359   v_must_def_optype v_must_defs;
360   unsigned i;
361   edge e;
362   edge_iterator ei;
363
364   for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
365     rename_def_op (PHI_RESULT_PTR (phi), phi);
366
367   for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
368     {
369       stmt = bsi_stmt (bsi);
370       get_stmt_operands (stmt);
371       ann = stmt_ann (stmt);
372
373       uses = USE_OPS (ann);
374       for (i = 0; i < NUM_USES (uses); i++)
375         rename_use_op (USE_OP_PTR (uses, i));
376
377       defs = DEF_OPS (ann);
378       for (i = 0; i < NUM_DEFS (defs); i++)
379         rename_def_op (DEF_OP_PTR (defs, i), stmt);
380
381       vuses = VUSE_OPS (ann);
382       for (i = 0; i < NUM_VUSES (vuses); i++)
383         rename_use_op (VUSE_OP_PTR (vuses, i));
384
385       v_may_defs = V_MAY_DEF_OPS (ann);
386       for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
387         {
388           rename_use_op (V_MAY_DEF_OP_PTR (v_may_defs, i));
389           rename_def_op (V_MAY_DEF_RESULT_PTR (v_may_defs, i), stmt);
390         }
391
392       v_must_defs = V_MUST_DEF_OPS (ann);
393       for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
394         {
395           rename_use_op (V_MUST_DEF_KILL_PTR (v_must_defs, i));
396           rename_def_op (V_MUST_DEF_RESULT_PTR (v_must_defs, i), stmt);
397         }
398     }
399
400   FOR_EACH_EDGE (e, ei, bb->succs)
401     for (phi = phi_nodes (e->dest); phi; phi = PHI_CHAIN (phi))
402       rename_use_op (PHI_ARG_DEF_PTR_FROM_EDGE (phi, e));
403 }
404
405
406 /* Releases the structures holding the new ssa names.  */
407
408 static void
409 free_new_names (bitmap definitions)
410 {
411   unsigned ver;
412   bitmap_iterator bi;
413
414   EXECUTE_IF_SET_IN_BITMAP (definitions, 0, ver, bi)
415     {
416       tree def = ssa_name (ver);
417
418       if (SSA_NAME_AUX (def))
419         {
420           free (SSA_NAME_AUX (def));
421           SSA_NAME_AUX (def) = NULL;
422         }
423     }
424 }
425
426
427 /* Renames variables in new generated LOOP.  */
428
429 static void
430 rename_variables_in_loop (struct loop *loop)
431 {
432   unsigned i;
433   basic_block *bbs;
434
435   bbs = get_loop_body (loop);
436
437   for (i = 0; i < loop->num_nodes; i++)
438     rename_variables_in_bb (bbs[i]);
439
440   free (bbs);
441 }
442
443
444 /* This function copies phis from LOOP header to
445    NEW_LOOP header. AFTER is as
446    in update_phis_for_duplicate_loop function.  */
447
448 static void
449 copy_phi_nodes (struct loop *loop, struct loop *new_loop,
450                       bool after)
451 {
452   tree phi, new_phi, def;
453   edge new_e;
454   edge e = (after ? loop_latch_edge (loop) : loop_preheader_edge (loop));
455
456   /* Second add arguments to newly created phi nodes.  */
457   for (phi = phi_nodes (loop->header),
458          new_phi = phi_nodes (new_loop->header);
459        phi;
460        phi = PHI_CHAIN (phi),
461          new_phi = PHI_CHAIN (new_phi))
462     {
463       new_e = loop_preheader_edge (new_loop);
464       def = PHI_ARG_DEF_FROM_EDGE (phi, e);
465       add_phi_arg (&new_phi, def, new_e);
466     }
467 }
468
469
470 /* Update the PHI nodes of the NEW_LOOP. AFTER is true if the NEW_LOOP
471    executes after LOOP, and false if it executes before it.  */
472
473 static void
474 slpeel_update_phis_for_duplicate_loop (struct loop *loop,
475                                        struct loop *new_loop, bool after)
476 {
477   edge old_latch;
478   tree *new_name_ptr, new_ssa_name;
479   tree phi_new, phi_old, def;
480   edge orig_entry_e = loop_preheader_edge (loop);
481
482   /* Copy phis from loop->header to new_loop->header.  */
483   copy_phi_nodes (loop, new_loop, after);
484
485   old_latch = loop_latch_edge (loop);
486
487   /* Update PHI args for the new loop latch edge, and
488      the old loop preheader edge, we know that the PHI nodes
489      are ordered appropriately in copy_phi_nodes.  */
490   for (phi_new = phi_nodes (new_loop->header),
491        phi_old = phi_nodes (loop->header);
492        phi_new && phi_old;
493        phi_new = PHI_CHAIN (phi_new), phi_old = PHI_CHAIN (phi_old))
494     {
495       def = PHI_ARG_DEF_FROM_EDGE (phi_old, old_latch);
496
497       if (TREE_CODE (def) != SSA_NAME)
498         continue;
499
500       new_name_ptr = SSA_NAME_AUX (def);
501
502       /* Something defined outside of the loop.  */
503       if (!new_name_ptr)
504         continue;
505
506       /* An ordinary ssa name defined in the loop.  */
507       new_ssa_name = *new_name_ptr;
508
509       add_phi_arg (&phi_new, new_ssa_name, loop_latch_edge(new_loop));
510
511       /* Update PHI args for the original loop pre-header edge.  */
512       if (! after)
513         SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi_old, orig_entry_e),
514                  new_ssa_name);
515     }
516 }
517
518
519 /* Update PHI nodes for a guard of the LOOP.
520
521    LOOP is supposed to have a preheader bb at which a guard condition is 
522    located.  The true edge of this condition skips the LOOP and ends
523    at the destination of the (unique) LOOP exit.  The loop exit bb is supposed 
524    to be an empty bb (created by this transformation) with one successor.
525
526    This function creates phi nodes at the LOOP exit bb.  These phis need to be
527    created as a result of adding true edge coming from guard.
528
529    FORNOW: Only phis which have corresponding phi nodes at the header of the
530    LOOP are created.  Here we use the assumption that after the LOOP there
531    are no uses of defs generated in LOOP.
532
533    After the phis creation, the function updates the values of phi nodes at
534    the LOOP exit successor bb:
535
536    Original loop:
537
538    bb0: loop preheader
539         goto bb1
540    bb1: loop header
541         if (exit_cond) goto bb3 else goto bb2
542    bb2: loop latch
543         goto bb1
544    bb3:
545
546
547    After guard creation (the loop before this function):
548
549    bb0: loop preheader
550         if (guard_condition) goto bb4 else goto bb1
551    bb1: loop header
552         if (exit_cond) goto bb4 else goto bb2
553    bb2: loop latch
554         goto bb1
555    bb4: loop exit       
556         (new empty bb)
557         goto bb3
558    bb3:
559
560    This function updates the phi nodes in bb4 and in bb3, to account for the 
561    new edge from bb0 to bb4.  */
562
563 static void
564 slpeel_update_phi_nodes_for_guard (edge guard_true_edge, struct loop * loop)
565 {
566   tree phi, phi1;
567   basic_block bb = loop->exit_edges[0]->dest;
568
569   for (phi = phi_nodes (loop->header); phi; phi = PHI_CHAIN (phi))
570       {
571         tree new_phi;
572         tree phi_arg;
573
574         /* Generate new phi node.  */
575         new_phi = create_phi_node (SSA_NAME_VAR (PHI_RESULT (phi)), bb);
576
577         /* Add argument coming from guard true edge.  */
578         phi_arg = PHI_ARG_DEF_FROM_EDGE (phi, loop->entry_edges[0]);
579         add_phi_arg (&new_phi, phi_arg, guard_true_edge);
580
581         /* Add argument coming from loop exit edge.  */
582         phi_arg = PHI_ARG_DEF_FROM_EDGE (phi, EDGE_SUCC (loop->latch, 0));                                 
583         add_phi_arg (&new_phi, phi_arg, loop->exit_edges[0]);
584       
585         /* Update all phi nodes at the loop exit successor.  */
586         for (phi1 = phi_nodes (EDGE_SUCC (bb, 0)->dest); 
587              phi1; 
588              phi1 = PHI_CHAIN (phi1))
589           {
590             tree old_arg = PHI_ARG_DEF_FROM_EDGE (phi1, EDGE_SUCC (bb, 0));
591             if (old_arg == phi_arg)
592               { 
593                 edge e = EDGE_SUCC (bb, 0);
594
595                 SET_PHI_ARG_DEF (phi1, 
596                                  phi_arg_from_edge (phi1, e),
597                                  PHI_RESULT (new_phi)); 
598               }
599           }
600       }       
601
602   set_phi_nodes (bb, phi_reverse (phi_nodes (bb)));
603 }
604
605
606 /* Make the LOOP iterate NITERS times. This is done by adding a new IV
607    that starts at zero, increases by one and its limit is NITERS.
608
609    Assumption: the exit-condition of LOOP is the last stmt in the loop.  */
610
611 static void
612 slpeel_make_loop_iterate_ntimes (struct loop *loop, tree niters)
613 {
614   tree indx_before_incr, indx_after_incr, cond_stmt, cond;
615   tree orig_cond;
616   edge exit_edge = loop->exit_edges[0];
617   block_stmt_iterator loop_exit_bsi = bsi_last (exit_edge->src);
618   tree begin_label = tree_block_label (loop->latch);
619   tree exit_label = tree_block_label (loop->single_exit->dest);
620
621   /* Flow loop scan does not update loop->single_exit field.  */
622   loop->single_exit = loop->exit_edges[0];
623   orig_cond = get_loop_exit_condition (loop);
624   gcc_assert (orig_cond);
625   create_iv (integer_zero_node, integer_one_node, NULL_TREE, loop,
626              &loop_exit_bsi, false, &indx_before_incr, &indx_after_incr);
627   
628   /* CREATE_IV uses BSI_INSERT with TSI_NEW_STMT, so we want to get
629      back to the exit condition statement.  */
630   bsi_next (&loop_exit_bsi);
631   gcc_assert (bsi_stmt (loop_exit_bsi) == orig_cond);
632
633
634   if (exit_edge->flags & EDGE_TRUE_VALUE) /* 'then' edge exits the loop.  */
635     cond = build2 (GE_EXPR, boolean_type_node, indx_after_incr, niters);
636   else /* 'then' edge loops back.  */
637     cond = build2 (LT_EXPR, boolean_type_node, indx_after_incr, niters);
638
639   begin_label = build1 (GOTO_EXPR, void_type_node, begin_label);
640   exit_label = build1 (GOTO_EXPR, void_type_node, exit_label);
641   cond_stmt = build (COND_EXPR, TREE_TYPE (orig_cond), cond,
642                      begin_label, exit_label);
643   bsi_insert_before (&loop_exit_bsi, cond_stmt, BSI_SAME_STMT);
644
645   /* Remove old loop exit test:  */
646   bsi_remove (&loop_exit_bsi);
647
648   if (vect_debug_stats (loop) || vect_debug_details (loop))
649     print_generic_expr (dump_file, cond_stmt, TDF_SLIM);
650
651   loop->nb_iterations = niters;
652 }
653
654
655 /* Given LOOP this function generates a new copy of it and puts it 
656    on E which is either the entry or exit of LOOP.  */
657
658 static struct loop *
659 slpeel_tree_duplicate_loop_to_edge_cfg (struct loop *loop, struct loops *loops, 
660                                         edge e)
661 {
662   struct loop *new_loop;
663   basic_block *new_bbs, *bbs;
664   bool at_exit;
665   bool was_imm_dom;
666   basic_block exit_dest; 
667   tree phi, phi_arg;
668
669   at_exit = (e == loop->exit_edges[0]); 
670   if (!at_exit && e != loop_preheader_edge (loop))
671     {
672       if (dump_file && (dump_flags & TDF_DETAILS))
673           fprintf (dump_file,
674                    "Edge is not an entry nor an exit edge.\n");
675       return NULL;
676     }
677
678   bbs = get_loop_body (loop);
679
680   /* Check whether duplication is possible.  */
681   if (!can_copy_bbs_p (bbs, loop->num_nodes))
682     {
683       if (vect_debug_stats (loop) || vect_debug_details (loop)) 
684           fprintf (dump_file,
685                    "Cannot copy basic blocks.\n");
686       free (bbs);
687       return NULL;
688     }
689
690   /* Generate new loop structure.  */
691   new_loop = duplicate_loop (loops, loop, loop->outer);
692   if (!new_loop)
693     {
694       if (vect_debug_stats (loop) || vect_debug_details (loop)) 
695           fprintf (dump_file,
696                    "The duplicate_loop returns NULL.\n");
697       free (bbs);
698       return NULL;
699     }
700
701   exit_dest = loop->exit_edges[0]->dest;
702   was_imm_dom = (get_immediate_dominator (CDI_DOMINATORS, 
703                                           exit_dest) == loop->header ? 
704                  true : false);
705
706   new_bbs = xmalloc (sizeof (basic_block) * loop->num_nodes);
707
708   copy_bbs (bbs, loop->num_nodes, new_bbs, NULL, 0, NULL, NULL);
709
710   /* Duplicating phi args at exit bbs as coming 
711      also from exit of duplicated loop.  */
712   for (phi = phi_nodes (exit_dest); phi; phi = PHI_CHAIN (phi))
713     {
714       phi_arg = PHI_ARG_DEF_FROM_EDGE (phi, loop->exit_edges[0]);
715       if (phi_arg)
716         {
717           edge new_loop_exit_edge;
718
719           if (EDGE_SUCC (new_loop->header, 0)->dest == new_loop->latch)
720             new_loop_exit_edge = EDGE_SUCC (new_loop->header, 1);
721           else
722             new_loop_exit_edge = EDGE_SUCC (new_loop->header, 0);
723   
724           add_phi_arg (&phi, phi_arg, new_loop_exit_edge);      
725         }
726     }    
727    
728   if (at_exit) /* Add the loop copy at exit.  */
729     {
730       redirect_edge_and_branch_force (e, new_loop->header);
731       set_immediate_dominator (CDI_DOMINATORS, new_loop->header, e->src);
732       if (was_imm_dom)
733         set_immediate_dominator (CDI_DOMINATORS, exit_dest, new_loop->header);
734     }
735   else /* Add the copy at entry.  */
736     {
737       edge new_exit_e;
738       edge entry_e = loop_preheader_edge (loop);
739       basic_block preheader = entry_e->src;
740            
741       if (!flow_bb_inside_loop_p (new_loop, 
742                                   EDGE_SUCC (new_loop->header, 0)->dest))
743         new_exit_e = EDGE_SUCC (new_loop->header, 0);
744       else
745         new_exit_e = EDGE_SUCC (new_loop->header, 1); 
746
747       redirect_edge_and_branch_force (new_exit_e, loop->header);
748       set_immediate_dominator (CDI_DOMINATORS, loop->header,
749                                new_exit_e->src);
750
751       /* We have to add phi args to the loop->header here as coming 
752          from new_exit_e edge.  */
753       for (phi = phi_nodes (loop->header); phi; phi = PHI_CHAIN (phi))
754         {
755           phi_arg = PHI_ARG_DEF_FROM_EDGE (phi, entry_e);
756           if (phi_arg)
757             add_phi_arg (&phi, phi_arg, new_exit_e);    
758         }    
759
760       redirect_edge_and_branch_force (entry_e, new_loop->header);
761       set_immediate_dominator (CDI_DOMINATORS, new_loop->header, preheader);
762     }
763
764   flow_loop_scan (new_loop, LOOP_ALL);
765   flow_loop_scan (loop, LOOP_ALL);  
766   free (new_bbs);
767   free (bbs);
768
769   return new_loop;
770 }
771
772
773 /* Given the condition statement COND, put it as the last statement
774    of GUARD_BB; EXIT_BB is the basic block to skip the loop;
775    Assumes that this is the single exit of the guarded loop.  
776    Returns the skip edge.  */
777
778 static edge
779 slpeel_add_loop_guard (basic_block guard_bb, tree cond, basic_block exit_bb)
780 {
781   block_stmt_iterator bsi;
782   edge new_e, enter_e;
783   tree cond_stmt, then_label, else_label;
784
785   enter_e = EDGE_SUCC (guard_bb, 0);
786   enter_e->flags &= ~EDGE_FALLTHRU;
787   enter_e->flags |= EDGE_FALSE_VALUE;
788   bsi = bsi_last (guard_bb);
789
790   then_label = build1 (GOTO_EXPR, void_type_node,
791                        tree_block_label (exit_bb));
792   else_label = build1 (GOTO_EXPR, void_type_node,
793                        tree_block_label (enter_e->dest));
794   cond_stmt = build (COND_EXPR, void_type_node, cond,
795                      then_label, else_label);
796   bsi_insert_after (&bsi, cond_stmt, BSI_NEW_STMT);
797   /* Add new edge to connect entry block to the second loop.  */
798   new_e = make_edge (guard_bb, exit_bb, EDGE_TRUE_VALUE);
799   set_immediate_dominator (CDI_DOMINATORS, exit_bb, guard_bb);
800   return new_e;
801 }
802
803
804 /* This function verifies that the following restrictions apply to LOOP:
805    (1) it is innermost
806    (2) it consists of exactly 2 basic blocks - header, and an empty latch.
807    (3) it is single entry, single exit
808    (4) its exit condition is the last stmt in the header
809    (5) E is the entry/exit edge of LOOP.
810  */
811
812 static bool
813 slpeel_can_duplicate_loop_p (struct loop *loop, edge e)
814 {
815   edge exit_e = loop->exit_edges [0];
816   edge entry_e = loop_preheader_edge (loop);
817   tree orig_cond = get_loop_exit_condition (loop);
818   block_stmt_iterator loop_exit_bsi = bsi_last (exit_e->src);
819
820   if (any_marked_for_rewrite_p ())
821     return false;
822
823   if (loop->inner
824       /* All loops have an outer scope; the only case loop->outer is NULL is for
825          the function itself.  */
826       || !loop->outer
827       || loop->num_nodes != 2
828       || !empty_block_p (loop->latch)
829       || loop->num_exits != 1
830       || loop->num_entries != 1
831       /* Verify that new loop exit condition can be trivially modified.  */
832       || (!orig_cond || orig_cond != bsi_stmt (loop_exit_bsi))
833       || (e != exit_e && e != entry_e))
834     return false;
835
836   return true;
837 }
838
839
840 /* Given LOOP this function duplicates it to the edge E. 
841
842    This transformation takes place before the loop is vectorized. 
843    For now, there are two main cases when it's used 
844    by the vectorizer: to support loops with unknown loop bounds 
845    (or loop bounds indivisible by vectorization factor) and to force the 
846    alignment of data references in the loop. In the first case, LOOP is 
847    duplicated to the exit edge, producing epilog loop. In the second case, LOOP 
848    is duplicated to the preheader edge thus generating prolog loop. In both 
849    cases, the original loop will be vectorized after the transformation. 
850
851    The edge E is supposed to be either preheader edge of the LOOP or  
852    its exit edge. If preheader edge is specified, the LOOP copy 
853    will precede the original one. Otherwise the copy will be located 
854    at the exit of the LOOP.
855    
856    FIRST_NITERS (SSA_NAME) parameter specifies how many times to iterate 
857    the first loop. If UPDATE_FIRST_LOOP_COUNT parameter is false, the first 
858    loop will be iterated FIRST_NITERS times by introducing additional 
859    induction variable and replacing loop exit condition. If 
860    UPDATE_FIRST_LOOP_COUNT is true no change to the first loop is made and 
861    the caller to tree_duplicate_loop_to_edge is responsible for updating 
862    the first loop count.
863    
864    NITERS (also SSA_NAME) parameter defines the number of iteration the
865    original loop iterated. The function generates two if-then guards: 
866    one prior to the first loop and the other prior to the second loop. 
867    The first guard will be:
868
869    if (FIRST_NITERS == 0) then skip the first loop
870    
871    The second guard will be:
872
873    if (FIRST_NITERS == NITERS) then skip the second loop
874
875    Thus the equivalence to the original code is guaranteed by correct values 
876    of NITERS and FIRST_NITERS and generation of if-then loop guards.
877
878    For now this function supports only loop forms that are candidate for 
879    vectorization. Such types are the following: 
880
881    (1) only innermost loops 
882    (2) loops built from 2 basic blocks 
883    (3) loops with one entry and one exit
884    (4) loops without function calls
885    (5) loops without defs that are used after the loop 
886
887    (1), (3) are checked in this function; (2) - in function 
888    vect_analyze_loop_form; (4) - in function vect_analyze_data_refs;
889    (5) is checked as part of the function vect_mark_stmts_to_be_vectorized, 
890    when excluding induction/reduction support.   
891
892    The function returns NULL in case one of these checks or 
893    transformations failed.  */
894    
895 struct loop*
896 slpeel_tree_peel_loop_to_edge (struct loop *loop, struct loops *loops, 
897                                edge e, tree first_niters, 
898                                tree niters, bool update_first_loop_count)
899 {
900   struct loop *new_loop = NULL, *first_loop, *second_loop;
901   edge skip_e;
902   tree pre_condition;
903   bitmap definitions;
904   basic_block first_exit_bb, second_exit_bb;
905   basic_block pre_header_bb;
906   edge exit_e = loop->exit_edges [0];
907
908   if (!slpeel_can_duplicate_loop_p (loop, e))
909     return NULL;
910
911   /* We have to initialize cfg_hooks. Then, when calling 
912    cfg_hooks->split_edge, the function tree_split_edge 
913    is actually called and, when calling cfg_hooks->duplicate_block, 
914    the function tree_duplicate_bb is called.  */
915   tree_register_cfg_hooks ();
916
917   /* 1. Generate a copy of LOOP and put it on E (entry or exit).  */
918   if (!(new_loop = slpeel_tree_duplicate_loop_to_edge_cfg (loop, loops, e)))
919     {
920       if (vect_debug_stats (loop) || vect_debug_details (loop)) 
921         fprintf (dump_file,
922                  "The tree_duplicate_loop_to_edge_cfg failed.\n");
923       return NULL;
924     }
925
926   definitions = marked_ssa_names ();
927   allocate_new_names (definitions);
928   slpeel_update_phis_for_duplicate_loop (loop, new_loop, e == exit_e);
929   /* Here, using assumption (5), we do not propagate new names further 
930      than on phis of the exit from the second loop.  */
931   rename_variables_in_loop (new_loop);
932   free_new_names (definitions);
933
934   if (e == exit_e)
935     {
936       first_loop = loop;
937       second_loop = new_loop;
938     }
939   else 
940     {
941       first_loop = new_loop;
942       second_loop = loop;
943     }
944
945   /* 2. Generate bb between the loops.  */
946   first_exit_bb = split_edge (first_loop->exit_edges[0]);
947   add_bb_to_loop (first_exit_bb, first_loop->outer);
948
949   /* We need to update here first loop exit edge 
950      and second loop preheader edge.  */
951   flow_loop_scan (first_loop, LOOP_ALL);
952   flow_loop_scan (second_loop, LOOP_ALL);  
953   /* Flow loop scan does not update loop->single_exit field.  */
954   first_loop->single_exit = first_loop->exit_edges[0];
955   second_loop->single_exit = second_loop->exit_edges[0];
956
957   /* 3. Make first loop iterate FIRST_NITERS times, if needed.  */
958   if (!update_first_loop_count)
959     slpeel_make_loop_iterate_ntimes (first_loop, first_niters);
960   
961   /* 4. Add the guard before first loop:
962
963      if FIRST_NITERS == 0 
964        skip first loop
965      else 
966        enter first loop  */
967
968   /* 4a. Generate bb before first loop.  */
969   pre_header_bb = split_edge (loop_preheader_edge (first_loop));
970   add_bb_to_loop (pre_header_bb, first_loop->outer);
971
972   /* First loop preheader edge is changed.  */
973   flow_loop_scan (first_loop, LOOP_ALL);
974
975   /* 4b. Generate guard condition.  */
976   pre_condition = build (LE_EXPR, boolean_type_node,
977                            first_niters, integer_zero_node);
978
979   /* 4c. Add condition at the end of preheader bb.  */
980   skip_e = slpeel_add_loop_guard (pre_header_bb, pre_condition, first_exit_bb);
981
982   /* 4d. Update phis at first loop exit and propagate changes 
983      to the phis of second loop.  */
984   slpeel_update_phi_nodes_for_guard (skip_e, first_loop);
985
986   /* 5. Add the guard before second loop:
987
988      if FIRST_NITERS == NITERS SKIP
989        skip second loop
990      else 
991        enter second loop  */
992
993   /* 5a. Generate empty bb at the exit from the second loop.  */
994   second_exit_bb = split_edge (second_loop->exit_edges[0]);
995   add_bb_to_loop (second_exit_bb, second_loop->outer);
996
997   /* Second loop preheader edge is changed.  */
998   flow_loop_scan (second_loop, LOOP_ALL);
999
1000   /* 5b. Generate guard condition.  */
1001   pre_condition = build (EQ_EXPR, boolean_type_node,
1002                            first_niters, niters);
1003
1004   /* 5c. Add condition at the end of preheader bb.  */
1005   skip_e = slpeel_add_loop_guard (first_exit_bb, pre_condition, second_exit_bb);
1006   slpeel_update_phi_nodes_for_guard (skip_e, second_loop);
1007
1008   BITMAP_XFREE (definitions);
1009   unmark_all_for_rewrite ();
1010   
1011   return new_loop;
1012 }
1013
1014
1015 \f
1016 /* Here the proper Vectorizer starts.  */
1017
1018 /*************************************************************************
1019   Vectorization Utilities.
1020  *************************************************************************/
1021
1022 /* Function new_stmt_vec_info.
1023
1024    Create and initialize a new stmt_vec_info struct for STMT.  */
1025
1026 stmt_vec_info
1027 new_stmt_vec_info (tree stmt, struct loop *loop)
1028 {
1029   stmt_vec_info res;
1030   res = (stmt_vec_info) xcalloc (1, sizeof (struct _stmt_vec_info));
1031
1032   STMT_VINFO_TYPE (res) = undef_vec_info_type;
1033   STMT_VINFO_STMT (res) = stmt;
1034   STMT_VINFO_LOOP (res) = loop;
1035   STMT_VINFO_RELEVANT_P (res) = 0;
1036   STMT_VINFO_VECTYPE (res) = NULL;
1037   STMT_VINFO_VEC_STMT (res) = NULL;
1038   STMT_VINFO_DATA_REF (res) = NULL;
1039   STMT_VINFO_MEMTAG (res) = NULL;
1040   STMT_VINFO_VECT_DR_BASE (res) = NULL;
1041
1042   return res;
1043 }
1044
1045
1046 /* Function new_loop_vec_info.
1047
1048    Create and initialize a new loop_vec_info struct for LOOP, as well as
1049    stmt_vec_info structs for all the stmts in LOOP.  */
1050
1051 loop_vec_info
1052 new_loop_vec_info (struct loop *loop)
1053 {
1054   loop_vec_info res;
1055   basic_block *bbs;
1056   block_stmt_iterator si;
1057   unsigned int i;
1058
1059   res = (loop_vec_info) xcalloc (1, sizeof (struct _loop_vec_info));
1060
1061   bbs = get_loop_body (loop);
1062
1063   /* Create stmt_info for all stmts in the loop.  */
1064   for (i = 0; i < loop->num_nodes; i++)
1065     {
1066       basic_block bb = bbs[i];
1067       for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
1068         {
1069           tree stmt = bsi_stmt (si);
1070           stmt_ann_t ann;
1071
1072           get_stmt_operands (stmt);
1073           ann = stmt_ann (stmt);
1074           set_stmt_info (ann, new_stmt_vec_info (stmt, loop));
1075         }
1076     }
1077
1078   LOOP_VINFO_LOOP (res) = loop;
1079   LOOP_VINFO_BBS (res) = bbs;
1080   LOOP_VINFO_EXIT_COND (res) = NULL;
1081   LOOP_VINFO_NITERS (res) = NULL;
1082   LOOP_VINFO_VECTORIZABLE_P (res) = 0;
1083   LOOP_DO_PEELING_FOR_ALIGNMENT (res) = false;
1084   LOOP_VINFO_VECT_FACTOR (res) = 0;
1085   VARRAY_GENERIC_PTR_INIT (LOOP_VINFO_DATAREF_WRITES (res), 20,
1086                            "loop_write_datarefs");
1087   VARRAY_GENERIC_PTR_INIT (LOOP_VINFO_DATAREF_READS (res), 20,
1088                            "loop_read_datarefs");
1089   LOOP_VINFO_UNALIGNED_DR (res) = NULL;
1090
1091   return res;
1092 }
1093
1094
1095 /* Function destroy_loop_vec_info.
1096  
1097    Free LOOP_VINFO struct, as well as all the stmt_vec_info structs of all the 
1098    stmts in the loop.  */
1099
1100 void
1101 destroy_loop_vec_info (loop_vec_info loop_vinfo)
1102 {
1103   struct loop *loop;
1104   basic_block *bbs;
1105   int nbbs;
1106   block_stmt_iterator si;
1107   int j;
1108
1109   if (!loop_vinfo)
1110     return;
1111
1112   loop = LOOP_VINFO_LOOP (loop_vinfo);
1113
1114   bbs = LOOP_VINFO_BBS (loop_vinfo);
1115   nbbs = loop->num_nodes;
1116
1117   for (j = 0; j < nbbs; j++)
1118     {
1119       basic_block bb = bbs[j];
1120       for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
1121         {
1122           tree stmt = bsi_stmt (si);
1123           stmt_ann_t ann = stmt_ann (stmt);
1124           stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
1125           free (stmt_info);
1126           set_stmt_info (ann, NULL);
1127         }
1128     }
1129
1130   free (LOOP_VINFO_BBS (loop_vinfo));
1131   varray_clear (LOOP_VINFO_DATAREF_WRITES (loop_vinfo));
1132   varray_clear (LOOP_VINFO_DATAREF_READS (loop_vinfo));
1133
1134   free (loop_vinfo);
1135 }
1136
1137
1138 /* Function debug_loop_stats.
1139
1140    For vectorization statistics dumps.  */
1141
1142 static bool
1143 vect_debug_stats (struct loop *loop)
1144 {
1145   basic_block bb;
1146   block_stmt_iterator si;
1147   tree node = NULL_TREE;
1148
1149   if (!dump_file || !(dump_flags & TDF_STATS))
1150     return false;
1151
1152   if (!loop)
1153     {
1154       fprintf (dump_file, "\n");
1155       return true;
1156     }
1157
1158   if (!loop->header)
1159     return false;
1160
1161   bb = loop->header;
1162
1163   for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
1164     {
1165       node = bsi_stmt (si);
1166       if (node && EXPR_P (node) && EXPR_LOCUS (node))
1167         break;
1168     }
1169
1170   if (node && EXPR_P (node) && EXPR_LOCUS (node) 
1171       && EXPR_FILENAME (node) && EXPR_LINENO (node))
1172     {
1173       fprintf (dump_file, "\nloop at %s:%d: ", 
1174         EXPR_FILENAME (node), EXPR_LINENO (node));
1175       return true;
1176     }
1177
1178   return false;
1179 }
1180
1181
1182 /* Function debug_loop_details.
1183
1184    For vectorization debug dumps.  */
1185
1186 static bool
1187 vect_debug_details (struct loop *loop)
1188 {
1189    basic_block bb;
1190    block_stmt_iterator si;
1191    tree node = NULL_TREE;
1192
1193   if (!dump_file || !(dump_flags & TDF_DETAILS))
1194     return false;
1195
1196   if (!loop)
1197     {
1198       fprintf (dump_file, "\n");
1199       return true;
1200     }
1201
1202   if (!loop->header)
1203     return false;
1204
1205   bb = loop->header;
1206
1207   for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
1208     {
1209       node = bsi_stmt (si);
1210       if (node && EXPR_P (node) && EXPR_LOCUS (node))
1211         break;
1212     }
1213
1214   if (node && EXPR_P (node) && EXPR_LOCUS (node)
1215       && EXPR_FILENAME (node) && EXPR_LINENO (node))
1216     {
1217       fprintf (dump_file, "\nloop at %s:%d: ", 
1218                EXPR_FILENAME (node), EXPR_LINENO (node));
1219       return true;
1220     }
1221
1222   return false;
1223 }
1224
1225
1226 /* Function vect_get_ptr_offset
1227
1228    Compute the OFFSET modulo vector-type alignment of pointer REF in bits.  */
1229
1230 static tree 
1231 vect_get_ptr_offset (tree ref ATTRIBUTE_UNUSED, 
1232                      tree vectype ATTRIBUTE_UNUSED, 
1233                      tree *offset ATTRIBUTE_UNUSED)
1234 {
1235   /* TODO: Use alignment information.  */
1236   return NULL_TREE; 
1237 }
1238
1239
1240 /* Function vect_get_base_and_bit_offset
1241
1242    Return the BASE of the data reference EXPR.
1243    If VECTYPE is given, also compute the OFFSET from BASE in bits.
1244    E.g., for EXPR a.b[i] + 4B, BASE is a, and OFFSET is the overall offset in 
1245    bits of 'a.b[i] + 4B' from a.
1246
1247    Input:
1248    EXPR - the memory reference that is being analyzed
1249    DR - the data_reference struct of the _original_ memory reference
1250         (Note: DR_REF (DR) is not necessarily EXPR)
1251    VECTYPE - the type that defines the alignment (i.e, we compute
1252              alignment relative to TYPE_ALIGN(VECTYPE))
1253    
1254    Output:
1255    BASE (returned value) - the base of the data reference EXPR.
1256                            E.g, if EXPR is a.b[k].c[i][j] the returned
1257                            base is a.
1258    OFFSET - offset of EXPR from BASE in bits
1259    BASE_ALIGNED_P - indicates if BASE is aligned
1260  
1261    If something unexpected is encountered (an unsupported form of data-ref),
1262    or if VECTYPE is given but OFFSET cannot be determined:
1263    then NULL_TREE is returned.  */
1264
1265 static tree 
1266 vect_get_base_and_bit_offset (struct data_reference *dr, 
1267                               tree expr, 
1268                               tree vectype, 
1269                               loop_vec_info loop_vinfo,
1270                               tree *offset,
1271                               bool *base_aligned_p)
1272 {
1273   tree this_offset = size_zero_node;
1274   tree base = NULL_TREE;
1275   tree next_ref;
1276   tree oprnd0, oprnd1;
1277   struct data_reference *array_dr;
1278   enum tree_code code = TREE_CODE (expr);
1279
1280   *base_aligned_p = false;
1281
1282   switch (code)
1283     {
1284     /* These cases end the recursion:  */
1285     case VAR_DECL:
1286       *offset = size_zero_node;
1287       if (vectype && DECL_ALIGN (expr) >= TYPE_ALIGN (vectype))
1288         *base_aligned_p = true;
1289       return expr;
1290
1291     case SSA_NAME:
1292       if (!vectype)
1293         return expr;
1294
1295       if (TREE_CODE (TREE_TYPE (expr)) != POINTER_TYPE)
1296         return NULL_TREE;
1297       
1298       if (TYPE_ALIGN (TREE_TYPE (TREE_TYPE (expr))) < TYPE_ALIGN (vectype)) 
1299         {
1300           base = vect_get_ptr_offset (expr, vectype, offset);
1301           if (base)
1302             *base_aligned_p = true;
1303         }
1304       else
1305         {         
1306           *base_aligned_p = true;
1307           *offset = size_zero_node;
1308           base = expr;
1309         }
1310       return base;
1311       
1312     case INTEGER_CST:      
1313       *offset = int_const_binop (MULT_EXPR, expr,     
1314                                  build_int_cst (NULL_TREE, BITS_PER_UNIT), 1);
1315       return expr;
1316
1317     /* These cases continue the recursion:  */
1318     case COMPONENT_REF:
1319       oprnd0 = TREE_OPERAND (expr, 0);
1320       oprnd1 = TREE_OPERAND (expr, 1);
1321
1322       this_offset = bit_position (oprnd1);
1323       if (vectype && !host_integerp (this_offset, 1))
1324         return NULL_TREE;
1325       next_ref = oprnd0;
1326       break;
1327
1328     case ADDR_EXPR:
1329       oprnd0 = TREE_OPERAND (expr, 0);
1330       next_ref = oprnd0;
1331       break;
1332
1333     case INDIRECT_REF:
1334       oprnd0 = TREE_OPERAND (expr, 0);
1335       next_ref = oprnd0;
1336       break;
1337     
1338     case ARRAY_REF:
1339       if (DR_REF (dr) != expr)
1340         /* Build array data_reference struct if the existing DR_REF 
1341            doesn't match EXPR. This happens, for example, when the 
1342            EXPR is *T and T is initialized to &arr[indx]. The DR struct
1343            contains information on the access of T, not of arr. In order
1344            to continue  the analysis, we create a new DR struct that
1345            describes the access of arr.  
1346         */
1347         array_dr = analyze_array (DR_STMT (dr), expr, DR_IS_READ (dr));
1348       else
1349         array_dr = dr;
1350           
1351       next_ref = vect_compute_array_ref_alignment (array_dr, loop_vinfo,  
1352                                                    vectype, &this_offset);
1353       if (!next_ref)
1354         return NULL_TREE;
1355
1356       if (vectype &&
1357           TYPE_ALIGN (TREE_TYPE (TREE_TYPE (next_ref))) >= TYPE_ALIGN (vectype))
1358         {
1359           *offset = this_offset;
1360           *base_aligned_p = true;
1361           return next_ref;
1362         }
1363       break;
1364
1365     case PLUS_EXPR:
1366     case MINUS_EXPR:
1367       /* In case we have a PLUS_EXPR of the form
1368          (oprnd0 + oprnd1), we assume that only oprnd0 determines the base. 
1369          This is verified in  vect_get_symbl_and_dr.  */ 
1370       oprnd0 = TREE_OPERAND (expr, 0);
1371       oprnd1 = TREE_OPERAND (expr, 1);
1372
1373       base = vect_get_base_and_bit_offset 
1374         (dr, oprnd1, vectype, loop_vinfo, &this_offset, base_aligned_p);  
1375       if (vectype && !base) 
1376         return NULL_TREE;
1377
1378       next_ref = oprnd0;
1379       break;
1380
1381     default:
1382       return NULL_TREE;
1383     }
1384
1385   base = vect_get_base_and_bit_offset (dr, next_ref, vectype, 
1386                                        loop_vinfo, offset, base_aligned_p);  
1387
1388   if (vectype && base)
1389     {
1390       *offset = int_const_binop (PLUS_EXPR, *offset, this_offset, 1);
1391       if (!host_integerp (*offset, 1) || TREE_OVERFLOW (*offset))
1392         return NULL_TREE;
1393
1394       if (vect_debug_details (NULL))
1395         {
1396           print_generic_expr (dump_file, expr, TDF_SLIM);
1397           fprintf (dump_file, " --> total offset for ref: ");
1398           print_generic_expr (dump_file, *offset, TDF_SLIM);
1399         }
1400     }    
1401   return base;
1402 }
1403
1404
1405 /* Function vect_force_dr_alignment_p.
1406
1407    Returns whether the alignment of a DECL can be forced to be aligned
1408    on ALIGNMENT bit boundary.  */
1409
1410 static bool 
1411 vect_can_force_dr_alignment_p (tree decl, unsigned int alignment)
1412 {
1413   if (TREE_CODE (decl) != VAR_DECL)
1414     return false;
1415
1416   if (DECL_EXTERNAL (decl))
1417     return false;
1418
1419   if (TREE_STATIC (decl))
1420     return (alignment <= MAX_OFILE_ALIGNMENT);
1421   else
1422     /* This is not 100% correct.  The absolute correct stack alignment
1423        is STACK_BOUNDARY.  We're supposed to hope, but not assume, that
1424        PREFERRED_STACK_BOUNDARY is honored by all translation units.
1425        However, until someone implements forced stack alignment, SSE
1426        isn't really usable without this.  */  
1427     return (alignment <= PREFERRED_STACK_BOUNDARY); 
1428 }
1429
1430
1431 /* Function vect_get_new_vect_var.
1432
1433    Returns a name for a new variable. The current naming scheme appends the 
1434    prefix "vect_" or "vect_p" (depending on the value of VAR_KIND) to 
1435    the name of vectorizer generated variables, and appends that to NAME if 
1436    provided.  */
1437
1438 static tree
1439 vect_get_new_vect_var (tree type, enum vect_var_kind var_kind, const char *name)
1440 {
1441   const char *prefix;
1442   int prefix_len;
1443   tree new_vect_var;
1444
1445   if (var_kind == vect_simple_var)
1446     prefix = "vect_"; 
1447   else
1448     prefix = "vect_p";
1449
1450   prefix_len = strlen (prefix);
1451
1452   if (name)
1453     new_vect_var = create_tmp_var (type, concat (prefix, name, NULL));
1454   else
1455     new_vect_var = create_tmp_var (type, prefix);
1456
1457   return new_vect_var;
1458 }
1459
1460
1461 /* Function vect_create_index_for_vector_ref.
1462
1463    Create (and return) an index variable, along with it's update chain in the
1464    loop. This variable will be used to access a memory location in a vector
1465    operation.
1466
1467    Input:
1468    LOOP: The loop being vectorized.
1469    BSI: The block_stmt_iterator where STMT is. Any new stmts created by this
1470         function can be added here, or in the loop pre-header.
1471
1472    Output:
1473    Return an index that will be used to index a vector array.  It is expected
1474    that a pointer to the first vector will be used as the base address for the
1475    indexed reference.
1476
1477    FORNOW: we are not trying to be efficient, just creating a new index each
1478    time from scratch.  At this time all vector references could use the same
1479    index.
1480
1481    TODO: create only one index to be used by all vector references.  Record
1482    the index in the LOOP_VINFO the first time this procedure is called and
1483    return it on subsequent calls.  The increment of this index must be placed
1484    just before the conditional expression that ends the single block loop.  */
1485
1486 static tree
1487 vect_create_index_for_vector_ref (struct loop *loop, block_stmt_iterator *bsi)
1488 {
1489   tree init, step;
1490   tree indx_before_incr, indx_after_incr;
1491
1492   /* It is assumed that the base pointer used for vectorized access contains
1493      the address of the first vector.  Therefore the index used for vectorized
1494      access must be initialized to zero and incremented by 1.  */
1495
1496   init = integer_zero_node;
1497   step = integer_one_node;
1498
1499   /* Assuming that bsi_insert is used with BSI_NEW_STMT  */
1500   create_iv (init, step, NULL_TREE, loop, bsi, false,
1501         &indx_before_incr, &indx_after_incr);
1502
1503   return indx_before_incr;
1504 }
1505
1506
1507 /* Function vect_create_addr_base_for_vector_ref.
1508
1509    Create an expression that computes the address of the first memory location
1510    that will be accessed for a data reference.
1511
1512    Input:
1513    STMT: The statement containing the data reference.
1514    NEW_STMT_LIST: Must be initialized to NULL_TREE or a statement list.
1515    OFFSET: Optional. If supplied, it is be added to the initial address.
1516
1517    Output:
1518    1. Return an SSA_NAME whose value is the address of the memory location of 
1519       the first vector of the data reference.
1520    2. If new_stmt_list is not NULL_TREE after return then the caller must insert
1521       these statement(s) which define the returned SSA_NAME.
1522
1523    FORNOW: We are only handling array accesses with step 1.  */
1524
1525 static tree
1526 vect_create_addr_base_for_vector_ref (tree stmt,
1527                                       tree *new_stmt_list,
1528                                       tree offset)
1529 {
1530   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
1531   struct loop *loop = STMT_VINFO_LOOP (stmt_info);
1532   struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
1533   tree data_ref_base = unshare_expr (STMT_VINFO_VECT_DR_BASE (stmt_info));
1534   tree base_name = unshare_expr (DR_BASE_NAME (dr));
1535   tree ref = DR_REF (dr);
1536   tree data_ref_base_type = TREE_TYPE (data_ref_base);
1537   tree scalar_type = TREE_TYPE (ref);
1538   tree scalar_ptr_type = build_pointer_type (scalar_type);
1539   tree access_fn;
1540   tree init_val, step, init_oval;
1541   bool ok;
1542   bool is_ptr_ref, is_array_ref, is_addr_expr;
1543   tree array_base;
1544   tree vec_stmt;
1545   tree new_temp;
1546   tree array_ref;
1547   tree addr_base, addr_expr;
1548   tree dest, new_stmt;
1549
1550   /* Only the access function of the last index is relevant (i_n in
1551      a[i_1][i_2]...[i_n]), the others correspond to loop invariants.  */
1552   access_fn = DR_ACCESS_FN (dr, 0);
1553   ok = vect_is_simple_iv_evolution (loop->num, access_fn, &init_oval, &step, 
1554                                     true);
1555   if (!ok)
1556     init_oval = integer_zero_node;
1557
1558   is_ptr_ref = TREE_CODE (data_ref_base_type) == POINTER_TYPE
1559                && TREE_CODE (data_ref_base) == SSA_NAME;
1560   is_array_ref = TREE_CODE (data_ref_base_type) == ARRAY_TYPE;
1561   is_addr_expr = TREE_CODE (data_ref_base) == ADDR_EXPR
1562                  || TREE_CODE (data_ref_base) == PLUS_EXPR
1563                  || TREE_CODE (data_ref_base) == MINUS_EXPR;
1564   gcc_assert (is_ptr_ref || is_array_ref || is_addr_expr);
1565
1566   /** Create: &(base[init_val])
1567
1568       if data_ref_base is an ARRAY_TYPE:
1569          base = data_ref_base
1570
1571       if data_ref_base is the SSA_NAME of a POINTER_TYPE:
1572          base = *((scalar_array *) data_ref_base)
1573    **/
1574
1575   if (is_array_ref)
1576     array_base = data_ref_base;
1577   else /* is_ptr_ref  or is_addr_expr */
1578     {
1579       /* array_ptr = (scalar_array_ptr_type *) data_ref_base;  */
1580       tree scalar_array_type = build_array_type (scalar_type, 0);
1581       tree scalar_array_ptr_type = build_pointer_type (scalar_array_type);
1582       tree array_ptr = create_tmp_var (scalar_array_ptr_type, "array_ptr");
1583       add_referenced_tmp_var (array_ptr);
1584
1585       dest = create_tmp_var (TREE_TYPE (data_ref_base), "dataref");
1586       add_referenced_tmp_var (dest);
1587       data_ref_base = 
1588         force_gimple_operand (data_ref_base, &new_stmt, false, dest);  
1589       append_to_statement_list_force (new_stmt, new_stmt_list);
1590
1591       vec_stmt = fold_convert (scalar_array_ptr_type, data_ref_base);
1592       vec_stmt = build2 (MODIFY_EXPR, void_type_node, array_ptr, vec_stmt);
1593       new_temp = make_ssa_name (array_ptr, vec_stmt);
1594       TREE_OPERAND (vec_stmt, 0) = new_temp;
1595       append_to_statement_list_force (vec_stmt, new_stmt_list);
1596
1597       /* (*array_ptr)  */
1598       array_base = build_fold_indirect_ref (new_temp);
1599     }
1600
1601   dest = create_tmp_var (TREE_TYPE (init_oval), "newinit");
1602   add_referenced_tmp_var (dest);
1603   init_val = force_gimple_operand (init_oval, &new_stmt, false, dest);  
1604   append_to_statement_list_force (new_stmt, new_stmt_list);
1605
1606   if (offset)
1607     {
1608       tree tmp = create_tmp_var (TREE_TYPE (init_val), "offset");
1609       add_referenced_tmp_var (tmp);
1610       vec_stmt = build2 (PLUS_EXPR, TREE_TYPE (init_val), init_val, offset);
1611       vec_stmt = build2 (MODIFY_EXPR, TREE_TYPE (init_val), tmp, vec_stmt);
1612       init_val = make_ssa_name (tmp, vec_stmt);
1613       TREE_OPERAND (vec_stmt, 0) = init_val;
1614       append_to_statement_list_force (vec_stmt, new_stmt_list);
1615     }
1616
1617   array_ref = build4 (ARRAY_REF, scalar_type, array_base, init_val, 
1618                       NULL_TREE, NULL_TREE);
1619   addr_base = build_fold_addr_expr (array_ref);
1620
1621   /* addr_expr = addr_base */
1622   addr_expr = vect_get_new_vect_var (scalar_ptr_type, vect_pointer_var,
1623                                      get_name (base_name));
1624   add_referenced_tmp_var (addr_expr);
1625   vec_stmt = build2 (MODIFY_EXPR, void_type_node, addr_expr, addr_base);
1626   new_temp = make_ssa_name (addr_expr, vec_stmt);
1627   TREE_OPERAND (vec_stmt, 0) = new_temp;
1628   append_to_statement_list_force (vec_stmt, new_stmt_list);
1629
1630   return new_temp;
1631 }
1632
1633
1634 /* Function get_vectype_for_scalar_type.
1635
1636    Returns the vector type corresponding to SCALAR_TYPE as supported
1637    by the target.  */
1638
1639 static tree
1640 get_vectype_for_scalar_type (tree scalar_type)
1641 {
1642   enum machine_mode inner_mode = TYPE_MODE (scalar_type);
1643   int nbytes = GET_MODE_SIZE (inner_mode);
1644   int nunits;
1645   tree vectype;
1646
1647   if (nbytes == 0)
1648     return NULL_TREE;
1649
1650   /* FORNOW: Only a single vector size per target (UNITS_PER_SIMD_WORD)
1651      is expected.  */
1652   nunits = UNITS_PER_SIMD_WORD / nbytes;
1653
1654   vectype = build_vector_type (scalar_type, nunits);
1655   if (vect_debug_details (NULL))
1656     {
1657       fprintf (dump_file, "get vectype with %d units of type ", nunits);
1658       print_generic_expr (dump_file, scalar_type, TDF_SLIM);
1659     }
1660
1661   if (!vectype)
1662     return NULL_TREE;
1663
1664   if (vect_debug_details (NULL))
1665     {
1666       fprintf (dump_file, "vectype: ");
1667       print_generic_expr (dump_file, vectype, TDF_SLIM);
1668     }
1669
1670   if (!VECTOR_MODE_P (TYPE_MODE (vectype)))
1671     {
1672       /* TODO: tree-complex.c sometimes can parallelize operations
1673          on generic vectors.  We can vectorize the loop in that case,
1674          but then we should re-run the lowering pass.  */
1675       if (vect_debug_details (NULL))
1676         fprintf (dump_file, "mode not supported by target.");
1677       return NULL_TREE;
1678     }
1679
1680   return vectype;
1681 }
1682
1683
1684 /* Function vect_align_data_ref.
1685
1686    Handle mislignment of a memory accesses.
1687
1688    FORNOW: Can't handle misaligned accesses. 
1689    Make sure that the dataref is aligned.  */
1690
1691 static void
1692 vect_align_data_ref (tree stmt)
1693 {
1694   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
1695   struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
1696
1697   /* FORNOW: can't handle misaligned accesses; 
1698              all accesses expected to be aligned.  */
1699   gcc_assert (aligned_access_p (dr));
1700 }
1701
1702
1703 /* Function vect_create_data_ref_ptr.
1704
1705    Create a memory reference expression for vector access, to be used in a
1706    vector load/store stmt. The reference is based on a new pointer to vector
1707    type (vp).
1708
1709    Input:
1710    1. STMT: a stmt that references memory. Expected to be of the form
1711          MODIFY_EXPR <name, data-ref> or MODIFY_EXPR <data-ref, name>.
1712    2. BSI: block_stmt_iterator where new stmts can be added.
1713    3. OFFSET (optional): an offset to be added to the initial address accessed
1714         by the data-ref in STMT.
1715    4. ONLY_INIT: indicate if vp is to be updated in the loop, or remain
1716         pointing to the initial address.
1717
1718    Output:
1719    1. Declare a new ptr to vector_type, and have it point to the base of the
1720       data reference (initial addressed accessed by the data reference).
1721       For example, for vector of type V8HI, the following code is generated:
1722
1723       v8hi *vp;
1724       vp = (v8hi *)initial_address;
1725
1726       if OFFSET is not supplied:
1727          initial_address = &a[init];
1728       if OFFSET is supplied:
1729          initial_address = &a[init + OFFSET];
1730
1731       Return the initial_address in INITIAL_ADDRESS.
1732
1733    2. Create a data-reference in the loop based on the new vector pointer vp,
1734       and using a new index variable 'idx' as follows:
1735
1736       vp' = vp + update
1737
1738       where if ONLY_INIT is true:
1739          update = zero
1740       and otherwise
1741          update = idx + vector_type_size
1742
1743       Return the pointer vp'.
1744
1745
1746    FORNOW: handle only aligned and consecutive accesses.  */
1747
1748 static tree
1749 vect_create_data_ref_ptr (tree stmt, block_stmt_iterator *bsi, tree offset,
1750                           tree *initial_address, bool only_init)
1751 {
1752   tree base_name;
1753   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
1754   struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
1755   struct loop *loop = STMT_VINFO_LOOP (stmt_info);
1756   tree vectype = STMT_VINFO_VECTYPE (stmt_info);
1757   tree vect_ptr_type;
1758   tree vect_ptr;
1759   tree tag;
1760   v_may_def_optype v_may_defs = STMT_V_MAY_DEF_OPS (stmt);
1761   v_must_def_optype v_must_defs = STMT_V_MUST_DEF_OPS (stmt);
1762   vuse_optype vuses = STMT_VUSE_OPS (stmt);
1763   int nvuses, nv_may_defs, nv_must_defs;
1764   int i;
1765   tree new_temp;
1766   tree vec_stmt;
1767   tree new_stmt_list = NULL_TREE;
1768   tree idx;
1769   edge pe = loop_preheader_edge (loop);
1770   basic_block new_bb;
1771   tree vect_ptr_init;
1772   tree vectype_size;
1773   tree ptr_update;
1774   tree data_ref_ptr;
1775
1776   base_name = unshare_expr (DR_BASE_NAME (dr));
1777   if (vect_debug_details (NULL))
1778     {
1779       tree data_ref_base = base_name;
1780       fprintf (dump_file, "create array_ref of type: ");
1781       print_generic_expr (dump_file, vectype, TDF_SLIM);
1782       if (TREE_CODE (data_ref_base) == VAR_DECL)
1783         fprintf (dump_file, "vectorizing a one dimensional array ref: ");
1784       else if (TREE_CODE (data_ref_base) == ARRAY_REF)
1785         fprintf (dump_file, "vectorizing a multidimensional array ref: ");
1786       else if (TREE_CODE (data_ref_base) == COMPONENT_REF)
1787         fprintf (dump_file, "vectorizing a record based array ref: ");
1788       else if (TREE_CODE (data_ref_base) == SSA_NAME)
1789         fprintf (dump_file, "vectorizing a pointer ref: ");
1790       print_generic_expr (dump_file, base_name, TDF_SLIM);
1791     }
1792
1793   /** (1) Create the new vector-pointer variable:  **/
1794
1795   vect_ptr_type = build_pointer_type (vectype);
1796   vect_ptr = vect_get_new_vect_var (vect_ptr_type, vect_pointer_var,
1797                                     get_name (base_name));
1798   add_referenced_tmp_var (vect_ptr);
1799   
1800   
1801   /** (2) Handle aliasing information of the new vector-pointer:  **/
1802   
1803   tag = STMT_VINFO_MEMTAG (stmt_info);
1804   gcc_assert (tag);
1805   get_var_ann (vect_ptr)->type_mem_tag = tag;
1806   
1807   /* Mark for renaming all aliased variables
1808      (i.e, the may-aliases of the type-mem-tag).  */
1809   nvuses = NUM_VUSES (vuses);
1810   nv_may_defs = NUM_V_MAY_DEFS (v_may_defs);
1811   nv_must_defs = NUM_V_MUST_DEFS (v_must_defs);
1812   for (i = 0; i < nvuses; i++)
1813     {
1814       tree use = VUSE_OP (vuses, i);
1815       if (TREE_CODE (use) == SSA_NAME)
1816         bitmap_set_bit (vars_to_rename, var_ann (SSA_NAME_VAR (use))->uid);
1817     }
1818   for (i = 0; i < nv_may_defs; i++)
1819     {
1820       tree def = V_MAY_DEF_RESULT (v_may_defs, i);
1821       if (TREE_CODE (def) == SSA_NAME)
1822         bitmap_set_bit (vars_to_rename, var_ann (SSA_NAME_VAR (def))->uid);
1823     }
1824   for (i = 0; i < nv_must_defs; i++)
1825     {
1826       tree def = V_MUST_DEF_RESULT (v_must_defs, i);
1827       if (TREE_CODE (def) == SSA_NAME)
1828         bitmap_set_bit (vars_to_rename, var_ann (SSA_NAME_VAR (def))->uid);
1829     }
1830
1831
1832   /** (3) Calculate the initial address the vector-pointer, and set
1833           the vector-pointer to point to it before the loop:  **/
1834
1835   /* Create: (&(base[init_val+offset]) in the loop preheader.  */
1836   new_temp = vect_create_addr_base_for_vector_ref (stmt, &new_stmt_list,
1837                                                    offset);
1838   pe = loop_preheader_edge (loop);
1839   new_bb = bsi_insert_on_edge_immediate (pe, new_stmt_list);
1840   gcc_assert (!new_bb);
1841   *initial_address = new_temp;
1842
1843   /* Create: p = (vectype *) initial_base  */
1844   vec_stmt = fold_convert (vect_ptr_type, new_temp);
1845   vec_stmt = build2 (MODIFY_EXPR, void_type_node, vect_ptr, vec_stmt);
1846   new_temp = make_ssa_name (vect_ptr, vec_stmt);
1847   TREE_OPERAND (vec_stmt, 0) = new_temp;
1848   new_bb = bsi_insert_on_edge_immediate (pe, vec_stmt);
1849   gcc_assert (!new_bb);
1850   vect_ptr_init = TREE_OPERAND (vec_stmt, 0);
1851
1852
1853   /** (4) Handle the updating of the vector-pointer inside the loop: **/
1854
1855   if (only_init) /* No update in loop is required.  */
1856     return vect_ptr_init;
1857
1858   idx = vect_create_index_for_vector_ref (loop, bsi);
1859
1860   /* Create: update = idx * vectype_size  */
1861   ptr_update = create_tmp_var (integer_type_node, "update");
1862   add_referenced_tmp_var (ptr_update);
1863   vectype_size = build_int_cst (integer_type_node,
1864                                 GET_MODE_SIZE (TYPE_MODE (vectype)));
1865   vec_stmt = build2 (MULT_EXPR, integer_type_node, idx, vectype_size);
1866   vec_stmt = build2 (MODIFY_EXPR, void_type_node, ptr_update, vec_stmt);
1867   new_temp = make_ssa_name (ptr_update, vec_stmt);
1868   TREE_OPERAND (vec_stmt, 0) = new_temp;
1869   bsi_insert_before (bsi, vec_stmt, BSI_SAME_STMT);
1870
1871   /* Create: data_ref_ptr = vect_ptr_init + update  */
1872   vec_stmt = build2 (PLUS_EXPR, vect_ptr_type, vect_ptr_init, new_temp);
1873   vec_stmt = build2 (MODIFY_EXPR, void_type_node, vect_ptr, vec_stmt);
1874   new_temp = make_ssa_name (vect_ptr, vec_stmt);
1875   TREE_OPERAND (vec_stmt, 0) = new_temp;
1876   bsi_insert_before (bsi, vec_stmt, BSI_SAME_STMT);
1877   data_ref_ptr = TREE_OPERAND (vec_stmt, 0);
1878
1879   return data_ref_ptr;
1880 }
1881
1882
1883 /* Function vect_create_destination_var.
1884
1885    Create a new temporary of type VECTYPE.  */
1886
1887 static tree
1888 vect_create_destination_var (tree scalar_dest, tree vectype)
1889 {
1890   tree vec_dest;
1891   const char *new_name;
1892
1893   gcc_assert (TREE_CODE (scalar_dest) == SSA_NAME);
1894
1895   new_name = get_name (scalar_dest);
1896   if (!new_name)
1897     new_name = "var_";
1898   vec_dest = vect_get_new_vect_var (vectype, vect_simple_var, new_name);
1899   add_referenced_tmp_var (vec_dest);
1900
1901   return vec_dest;
1902 }
1903
1904
1905 /* Function vect_init_vector.
1906
1907    Insert a new stmt (INIT_STMT) that initializes a new vector variable with
1908    the vector elements of VECTOR_VAR. Return the DEF of INIT_STMT. It will be
1909    used in the vectorization of STMT.  */
1910
1911 static tree
1912 vect_init_vector (tree stmt, tree vector_var)
1913 {
1914   stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt);
1915   struct loop *loop = STMT_VINFO_LOOP (stmt_vinfo);
1916   tree new_var;
1917   tree init_stmt;
1918   tree vectype = STMT_VINFO_VECTYPE (stmt_vinfo); 
1919   tree vec_oprnd;
1920   edge pe;
1921   tree new_temp;
1922   basic_block new_bb;
1923  
1924   new_var = vect_get_new_vect_var (vectype, vect_simple_var, "cst_");
1925   add_referenced_tmp_var (new_var); 
1926  
1927   init_stmt = build2 (MODIFY_EXPR, vectype, new_var, vector_var);
1928   new_temp = make_ssa_name (new_var, init_stmt);
1929   TREE_OPERAND (init_stmt, 0) = new_temp;
1930
1931   pe = loop_preheader_edge (loop);
1932   new_bb = bsi_insert_on_edge_immediate (pe, init_stmt);
1933   gcc_assert (!new_bb);
1934
1935   if (vect_debug_details (NULL))
1936     {
1937       fprintf (dump_file, "created new init_stmt: ");
1938       print_generic_expr (dump_file, init_stmt, TDF_SLIM);
1939     }
1940
1941   vec_oprnd = TREE_OPERAND (init_stmt, 0);
1942   return vec_oprnd;
1943 }
1944
1945
1946 /* Function vect_get_vec_def_for_operand.
1947
1948    OP is an operand in STMT. This function returns a (vector) def that will be
1949    used in the vectorized stmt for STMT.
1950
1951    In the case that OP is an SSA_NAME which is defined in the loop, then
1952    STMT_VINFO_VEC_STMT of the defining stmt holds the relevant def.
1953
1954    In case OP is an invariant or constant, a new stmt that creates a vector def
1955    needs to be introduced.  */
1956
1957 static tree
1958 vect_get_vec_def_for_operand (tree op, tree stmt)
1959 {
1960   tree vec_oprnd;
1961   tree vec_stmt;
1962   tree def_stmt;
1963   stmt_vec_info def_stmt_info = NULL;
1964   stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt);
1965   tree vectype = STMT_VINFO_VECTYPE (stmt_vinfo);
1966   int nunits = GET_MODE_NUNITS (TYPE_MODE (vectype));
1967   struct loop *loop = STMT_VINFO_LOOP (stmt_vinfo);
1968   basic_block bb;
1969   tree vec_inv;
1970   tree t = NULL_TREE;
1971   tree def;
1972   int i;
1973
1974   if (vect_debug_details (NULL))
1975     {
1976       fprintf (dump_file, "vect_get_vec_def_for_operand: ");
1977       print_generic_expr (dump_file, op, TDF_SLIM);
1978     }
1979
1980   /** ===> Case 1: operand is a constant.  **/
1981
1982   if (TREE_CODE (op) == INTEGER_CST || TREE_CODE (op) == REAL_CST)
1983     {
1984       /* Create 'vect_cst_ = {cst,cst,...,cst}'  */
1985
1986       tree vec_cst;
1987
1988       /* Build a tree with vector elements.  */
1989       if (vect_debug_details (NULL))
1990         fprintf (dump_file, "Create vector_cst. nunits = %d", nunits);
1991
1992       for (i = nunits - 1; i >= 0; --i)
1993         {
1994           t = tree_cons (NULL_TREE, op, t);
1995         }
1996       vec_cst = build_vector (vectype, t);
1997       return vect_init_vector (stmt, vec_cst);
1998     }
1999
2000   gcc_assert (TREE_CODE (op) == SSA_NAME);
2001  
2002   /** ===> Case 2: operand is an SSA_NAME - find the stmt that defines it.  **/
2003
2004   def_stmt = SSA_NAME_DEF_STMT (op);
2005   def_stmt_info = vinfo_for_stmt (def_stmt);
2006
2007   if (vect_debug_details (NULL))
2008     {
2009       fprintf (dump_file, "vect_get_vec_def_for_operand: def_stmt: ");
2010       print_generic_expr (dump_file, def_stmt, TDF_SLIM);
2011     }
2012
2013
2014   /** ==> Case 2.1: operand is defined inside the loop.  **/
2015
2016   if (def_stmt_info)
2017     {
2018       /* Get the def from the vectorized stmt.  */
2019
2020       vec_stmt = STMT_VINFO_VEC_STMT (def_stmt_info);
2021       gcc_assert (vec_stmt);
2022       vec_oprnd = TREE_OPERAND (vec_stmt, 0);
2023       return vec_oprnd;
2024     }
2025
2026
2027   /** ==> Case 2.2: operand is defined by the loop-header phi-node - 
2028                     it is a reduction/induction.  **/
2029
2030   bb = bb_for_stmt (def_stmt);
2031   if (TREE_CODE (def_stmt) == PHI_NODE && flow_bb_inside_loop_p (loop, bb))
2032     {
2033       if (vect_debug_details (NULL))
2034         fprintf (dump_file, "reduction/induction - unsupported.");
2035       internal_error ("no support for reduction/induction"); /* FORNOW */
2036     }
2037
2038
2039   /** ==> Case 2.3: operand is defined outside the loop - 
2040                     it is a loop invariant.  */
2041
2042   switch (TREE_CODE (def_stmt))
2043     {
2044     case PHI_NODE:
2045       def = PHI_RESULT (def_stmt);
2046       break;
2047     case MODIFY_EXPR:
2048       def = TREE_OPERAND (def_stmt, 0);
2049       break;
2050     case NOP_EXPR:
2051       def = TREE_OPERAND (def_stmt, 0);
2052       gcc_assert (IS_EMPTY_STMT (def_stmt));
2053       def = op;
2054       break;
2055     default:
2056       if (vect_debug_details (NULL))
2057         {
2058           fprintf (dump_file, "unsupported defining stmt: ");
2059           print_generic_expr (dump_file, def_stmt, TDF_SLIM);
2060         }
2061       internal_error ("unsupported defining stmt");
2062     }
2063
2064   /* Build a tree with vector elements. Create 'vec_inv = {inv,inv,..,inv}'  */
2065
2066   if (vect_debug_details (NULL))
2067     fprintf (dump_file, "Create vector_inv.");
2068
2069   for (i = nunits - 1; i >= 0; --i)
2070     {
2071       t = tree_cons (NULL_TREE, def, t);
2072     }
2073
2074   vec_inv = build_constructor (vectype, t);
2075   return vect_init_vector (stmt, vec_inv);
2076 }
2077
2078
2079 /* Function vect_finish_stmt_generation.
2080
2081    Insert a new stmt.  */
2082
2083 static void
2084 vect_finish_stmt_generation (tree stmt, tree vec_stmt, block_stmt_iterator *bsi)
2085 {
2086   bsi_insert_before (bsi, vec_stmt, BSI_SAME_STMT);
2087
2088   if (vect_debug_details (NULL))
2089     {
2090       fprintf (dump_file, "add new stmt: ");
2091       print_generic_expr (dump_file, vec_stmt, TDF_SLIM);
2092     }
2093
2094   /* Make sure bsi points to the stmt that is being vectorized.  */
2095
2096   /* Assumption: any stmts created for the vectorization of stmt S were
2097      inserted before S. BSI is expected to point to S or some new stmt before S.  */
2098
2099   while (stmt != bsi_stmt (*bsi) && !bsi_end_p (*bsi))
2100     bsi_next (bsi);
2101   gcc_assert (stmt == bsi_stmt (*bsi));
2102 }
2103
2104
2105 /* Function vectorizable_assignment.
2106
2107    Check if STMT performs an assignment (copy) that can be vectorized. 
2108    If VEC_STMT is also passed, vectorize the STMT: create a vectorized 
2109    stmt to replace it, put it in VEC_STMT, and insert it at BSI.
2110    Return FALSE if not a vectorizable STMT, TRUE otherwise.  */
2111
2112 static bool
2113 vectorizable_assignment (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
2114 {
2115   tree vec_dest;
2116   tree scalar_dest;
2117   tree op;
2118   tree vec_oprnd;
2119   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
2120   tree vectype = STMT_VINFO_VECTYPE (stmt_info);
2121   struct loop *loop = STMT_VINFO_LOOP (stmt_info);
2122   tree new_temp;
2123
2124   /* Is vectorizable assignment?  */
2125
2126   if (TREE_CODE (stmt) != MODIFY_EXPR)
2127     return false;
2128
2129   scalar_dest = TREE_OPERAND (stmt, 0);
2130   if (TREE_CODE (scalar_dest) != SSA_NAME)
2131     return false;
2132
2133   op = TREE_OPERAND (stmt, 1);
2134   if (!vect_is_simple_use (op, loop, NULL))
2135     {
2136       if (vect_debug_details (NULL))
2137         fprintf (dump_file, "use not simple.");
2138       return false;
2139     }
2140
2141   if (!vec_stmt) /* transformation not required.  */
2142     {
2143       STMT_VINFO_TYPE (stmt_info) = assignment_vec_info_type;
2144       return true;
2145     }
2146
2147   /** Trasform.  **/
2148   if (vect_debug_details (NULL))
2149     fprintf (dump_file, "transform assignment.");
2150
2151   /* Handle def.  */
2152   vec_dest = vect_create_destination_var (scalar_dest, vectype);
2153
2154   /* Handle use.  */
2155   op = TREE_OPERAND (stmt, 1);
2156   vec_oprnd = vect_get_vec_def_for_operand (op, stmt);
2157
2158   /* Arguments are ready. create the new vector stmt.  */
2159   *vec_stmt = build2 (MODIFY_EXPR, vectype, vec_dest, vec_oprnd);
2160   new_temp = make_ssa_name (vec_dest, *vec_stmt);
2161   TREE_OPERAND (*vec_stmt, 0) = new_temp;
2162   vect_finish_stmt_generation (stmt, *vec_stmt, bsi);
2163   
2164   return true;
2165 }
2166
2167
2168 /* Function vectorizable_operation.
2169
2170    Check if STMT performs a binary or unary operation that can be vectorized. 
2171    If VEC_STMT is also passed, vectorize the STMT: create a vectorized 
2172    stmt to replace it, put it in VEC_STMT, and insert it at BSI.
2173    Return FALSE if not a vectorizable STMT, TRUE otherwise.  */
2174
2175 static bool
2176 vectorizable_operation (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
2177 {
2178   tree vec_dest;
2179   tree scalar_dest;
2180   tree operation;
2181   tree op0, op1 = NULL;
2182   tree vec_oprnd0, vec_oprnd1=NULL;
2183   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
2184   tree vectype = STMT_VINFO_VECTYPE (stmt_info);
2185   struct loop *loop = STMT_VINFO_LOOP (stmt_info);
2186   int i;
2187   enum tree_code code;
2188   enum machine_mode vec_mode;
2189   tree new_temp;
2190   int op_type;
2191   tree op;
2192   optab optab;
2193
2194   /* Is STMT a vectorizable binary/unary operation?   */
2195   if (TREE_CODE (stmt) != MODIFY_EXPR)
2196     return false;
2197
2198   if (TREE_CODE (TREE_OPERAND (stmt, 0)) != SSA_NAME)
2199     return false;
2200
2201   operation = TREE_OPERAND (stmt, 1);
2202   code = TREE_CODE (operation);
2203   optab = optab_for_tree_code (code, vectype);
2204
2205   /* Support only unary or binary operations.  */
2206   op_type = TREE_CODE_LENGTH (code);
2207   if (op_type != unary_op && op_type != binary_op)
2208     {
2209       if (vect_debug_details (NULL))
2210         fprintf (dump_file, "num. args = %d (not unary/binary op).", op_type);
2211       return false;
2212     }
2213
2214   for (i = 0; i < op_type; i++)
2215     {
2216       op = TREE_OPERAND (operation, i);
2217       if (!vect_is_simple_use (op, loop, NULL))
2218         {
2219           if (vect_debug_details (NULL))
2220             fprintf (dump_file, "use not simple.");
2221           return false;
2222         }       
2223     } 
2224
2225   /* Supportable by target?  */
2226   if (!optab)
2227     {
2228       if (vect_debug_details (NULL))
2229         fprintf (dump_file, "no optab.");
2230       return false;
2231     }
2232   vec_mode = TYPE_MODE (vectype);
2233   if (optab->handlers[(int) vec_mode].insn_code == CODE_FOR_nothing)
2234     {
2235       if (vect_debug_details (NULL))
2236         fprintf (dump_file, "op not supported by target.");
2237       return false;
2238     }
2239
2240   if (!vec_stmt) /* transformation not required.  */
2241     {
2242       STMT_VINFO_TYPE (stmt_info) = op_vec_info_type;
2243       return true;
2244     }
2245
2246   /** Transform.  **/
2247
2248   if (vect_debug_details (NULL))
2249     fprintf (dump_file, "transform binary/unary operation.");
2250
2251   /* Handle def.  */
2252   scalar_dest = TREE_OPERAND (stmt, 0);
2253   vec_dest = vect_create_destination_var (scalar_dest, vectype);
2254
2255   /* Handle uses.  */
2256   op0 = TREE_OPERAND (operation, 0);
2257   vec_oprnd0 = vect_get_vec_def_for_operand (op0, stmt);
2258
2259   if (op_type == binary_op)
2260     {
2261       op1 = TREE_OPERAND (operation, 1);
2262       vec_oprnd1 = vect_get_vec_def_for_operand (op1, stmt); 
2263     }
2264
2265   /* Arguments are ready. create the new vector stmt.  */
2266
2267   if (op_type == binary_op)
2268     *vec_stmt = build2 (MODIFY_EXPR, vectype, vec_dest,
2269                 build2 (code, vectype, vec_oprnd0, vec_oprnd1));
2270   else
2271     *vec_stmt = build2 (MODIFY_EXPR, vectype, vec_dest,
2272                 build1 (code, vectype, vec_oprnd0));
2273   new_temp = make_ssa_name (vec_dest, *vec_stmt);
2274   TREE_OPERAND (*vec_stmt, 0) = new_temp;
2275   vect_finish_stmt_generation (stmt, *vec_stmt, bsi);
2276
2277   return true;
2278 }
2279
2280
2281 /* Function vectorizable_store.
2282
2283    Check if STMT defines a non scalar data-ref (array/pointer/structure) that 
2284    can be vectorized. 
2285    If VEC_STMT is also passed, vectorize the STMT: create a vectorized 
2286    stmt to replace it, put it in VEC_STMT, and insert it at BSI.
2287    Return FALSE if not a vectorizable STMT, TRUE otherwise.  */
2288
2289 static bool
2290 vectorizable_store (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
2291 {
2292   tree scalar_dest;
2293   tree data_ref;
2294   tree op;
2295   tree vec_oprnd1;
2296   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
2297   struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
2298   tree vectype = STMT_VINFO_VECTYPE (stmt_info);
2299   struct loop *loop = STMT_VINFO_LOOP (stmt_info);
2300   enum machine_mode vec_mode;
2301   tree dummy;
2302   enum dr_alignment_support alignment_support_cheme;
2303
2304   /* Is vectorizable store? */
2305
2306   if (TREE_CODE (stmt) != MODIFY_EXPR)
2307     return false;
2308
2309   scalar_dest = TREE_OPERAND (stmt, 0);
2310   if (TREE_CODE (scalar_dest) != ARRAY_REF
2311       && TREE_CODE (scalar_dest) != INDIRECT_REF)
2312     return false;
2313
2314   op = TREE_OPERAND (stmt, 1);
2315   if (!vect_is_simple_use (op, loop, NULL))
2316     {
2317       if (vect_debug_details (NULL))
2318         fprintf (dump_file, "use not simple.");
2319       return false;
2320     }
2321
2322   vec_mode = TYPE_MODE (vectype);
2323   /* FORNOW. In some cases can vectorize even if data-type not supported
2324      (e.g. - array initialization with 0).  */
2325   if (mov_optab->handlers[(int)vec_mode].insn_code == CODE_FOR_nothing)
2326     return false;
2327
2328   if (!STMT_VINFO_DATA_REF (stmt_info))
2329     return false;
2330
2331
2332   if (!vec_stmt) /* transformation not required.  */
2333     {
2334       STMT_VINFO_TYPE (stmt_info) = store_vec_info_type;
2335       return true;
2336     }
2337
2338   /** Trasform.  **/
2339
2340   if (vect_debug_details (NULL))
2341     fprintf (dump_file, "transform store");
2342
2343   alignment_support_cheme = vect_supportable_dr_alignment (dr);
2344   gcc_assert (alignment_support_cheme);
2345   gcc_assert (alignment_support_cheme = dr_aligned);  /* FORNOW */
2346
2347   /* Handle use - get the vectorized def from the defining stmt.  */
2348   vec_oprnd1 = vect_get_vec_def_for_operand (op, stmt);
2349
2350   /* Handle def.  */
2351   /* FORNOW: make sure the data reference is aligned.  */
2352   vect_align_data_ref (stmt);
2353   data_ref = vect_create_data_ref_ptr (stmt, bsi, NULL_TREE, &dummy, false);
2354   data_ref = build_fold_indirect_ref (data_ref);
2355
2356   /* Arguments are ready. create the new vector stmt.  */
2357   *vec_stmt = build2 (MODIFY_EXPR, vectype, data_ref, vec_oprnd1);
2358   vect_finish_stmt_generation (stmt, *vec_stmt, bsi);
2359
2360   return true;
2361 }
2362
2363
2364 /* vectorizable_load.
2365
2366    Check if STMT reads a non scalar data-ref (array/pointer/structure) that 
2367    can be vectorized. 
2368    If VEC_STMT is also passed, vectorize the STMT: create a vectorized 
2369    stmt to replace it, put it in VEC_STMT, and insert it at BSI.
2370    Return FALSE if not a vectorizable STMT, TRUE otherwise.  */
2371
2372 static bool
2373 vectorizable_load (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
2374 {
2375   tree scalar_dest;
2376   tree vec_dest = NULL;
2377   tree data_ref = NULL;
2378   tree op;
2379   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
2380   struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
2381   tree vectype = STMT_VINFO_VECTYPE (stmt_info);
2382   tree new_temp;
2383   int mode;
2384   tree init_addr;
2385   tree new_stmt;
2386   tree dummy;
2387   basic_block new_bb;
2388   struct loop *loop = STMT_VINFO_LOOP (stmt_info);
2389   edge pe = loop_preheader_edge (loop);
2390   enum dr_alignment_support alignment_support_cheme;
2391
2392   /* Is vectorizable load? */
2393
2394   if (TREE_CODE (stmt) != MODIFY_EXPR)
2395     return false;
2396
2397   scalar_dest = TREE_OPERAND (stmt, 0);
2398   if (TREE_CODE (scalar_dest) != SSA_NAME)
2399     return false;
2400
2401   op = TREE_OPERAND (stmt, 1);
2402   if (TREE_CODE (op) != ARRAY_REF && TREE_CODE (op) != INDIRECT_REF)
2403     return false;
2404
2405   if (!STMT_VINFO_DATA_REF (stmt_info))
2406     return false;
2407
2408   mode = (int) TYPE_MODE (vectype);
2409
2410   /* FORNOW. In some cases can vectorize even if data-type not supported
2411     (e.g. - data copies).  */
2412   if (mov_optab->handlers[mode].insn_code == CODE_FOR_nothing)
2413     {
2414       if (vect_debug_details (loop))
2415         fprintf (dump_file, "Aligned load, but unsupported type.");
2416       return false;
2417     }
2418
2419   if (!vec_stmt) /* transformation not required.  */
2420     {
2421       STMT_VINFO_TYPE (stmt_info) = load_vec_info_type;
2422       return true;
2423     }
2424
2425   /** Trasform.  **/
2426
2427   if (vect_debug_details (NULL))
2428     fprintf (dump_file, "transform load.");
2429
2430   alignment_support_cheme = vect_supportable_dr_alignment (dr);
2431   gcc_assert (alignment_support_cheme);
2432
2433   if (alignment_support_cheme == dr_aligned
2434       || alignment_support_cheme == dr_unaligned_supported)
2435     {
2436       /* Create:
2437          p = initial_addr;
2438          indx = 0;
2439          loop {
2440            vec_dest = *(p);
2441            indx = indx + 1;
2442          }
2443       */
2444
2445       vec_dest = vect_create_destination_var (scalar_dest, vectype);
2446       data_ref = vect_create_data_ref_ptr (stmt, bsi, NULL_TREE, &dummy, false);
2447       if (aligned_access_p (dr))
2448         data_ref = build_fold_indirect_ref (data_ref);
2449       else
2450         {
2451           int mis = DR_MISALIGNMENT (dr);
2452           tree tmis = (mis == -1 ?
2453                        integer_zero_node : 
2454                        build_int_cst (integer_type_node, mis));
2455           tmis = int_const_binop (MULT_EXPR, tmis, 
2456                         build_int_cst (integer_type_node, BITS_PER_UNIT), 1);
2457           data_ref = build2 (MISALIGNED_INDIRECT_REF, vectype, data_ref, tmis);
2458         }
2459       new_stmt = build2 (MODIFY_EXPR, vectype, vec_dest, data_ref);
2460       new_temp = make_ssa_name (vec_dest, new_stmt);
2461       TREE_OPERAND (new_stmt, 0) = new_temp;
2462       vect_finish_stmt_generation (stmt, new_stmt, bsi);
2463     }
2464   else if (alignment_support_cheme == dr_unaligned_software_pipeline)
2465     {
2466       /* Create:
2467          p1 = initial_addr;
2468          msq_init = *(floor(p1))
2469          p2 = initial_addr + VS - 1;
2470          magic = have_builtin ? builtin_result : initial_address;
2471          indx = 0;
2472          loop {
2473            p2' = p2 + indx * vectype_size
2474            lsq = *(floor(p2'))
2475            vec_dest = realign_load (msq, lsq, magic)
2476            indx = indx + 1;
2477            msq = lsq;
2478          }
2479       */
2480
2481       tree offset;
2482       tree magic;
2483       tree phi_stmt;
2484       tree msq_init;
2485       tree msq, lsq;
2486       tree dataref_ptr;
2487       tree params;
2488
2489       /* <1> Create msq_init = *(floor(p1)) in the loop preheader  */
2490       vec_dest = vect_create_destination_var (scalar_dest, vectype);
2491       data_ref = vect_create_data_ref_ptr (stmt, bsi, NULL_TREE, 
2492                                            &init_addr, true);
2493       data_ref = build1 (ALIGN_INDIRECT_REF, vectype, data_ref);
2494       new_stmt = build2 (MODIFY_EXPR, vectype, vec_dest, data_ref);
2495       new_temp = make_ssa_name (vec_dest, new_stmt);
2496       TREE_OPERAND (new_stmt, 0) = new_temp;
2497       new_bb = bsi_insert_on_edge_immediate (pe, new_stmt);
2498       gcc_assert (!new_bb);
2499       msq_init = TREE_OPERAND (new_stmt, 0);
2500
2501
2502       /* <2> Create lsq = *(floor(p2')) in the loop  */ 
2503       offset = build_int_cst (integer_type_node, 
2504                               GET_MODE_NUNITS (TYPE_MODE (vectype)));
2505       offset = int_const_binop (MINUS_EXPR, offset, integer_one_node, 1);
2506       vec_dest = vect_create_destination_var (scalar_dest, vectype);
2507       dataref_ptr = vect_create_data_ref_ptr (stmt, bsi, offset, &dummy, false);
2508       data_ref = build1 (ALIGN_INDIRECT_REF, vectype, dataref_ptr);
2509       new_stmt = build2 (MODIFY_EXPR, vectype, vec_dest, data_ref);
2510       new_temp = make_ssa_name (vec_dest, new_stmt);
2511       TREE_OPERAND (new_stmt, 0) = new_temp;
2512       vect_finish_stmt_generation (stmt, new_stmt, bsi);
2513       lsq = TREE_OPERAND (new_stmt, 0);
2514
2515
2516       /* <3> */
2517       if (targetm.vectorize.builtin_mask_for_load)
2518         {
2519           /* Create permutation mask, if required, in loop preheader.  */
2520           tree builtin_decl;
2521           params = build_tree_list (NULL_TREE, init_addr);
2522           vec_dest = vect_create_destination_var (scalar_dest, vectype);
2523           builtin_decl = targetm.vectorize.builtin_mask_for_load ();
2524           new_stmt = build_function_call_expr (builtin_decl, params);
2525           new_stmt = build2 (MODIFY_EXPR, vectype, vec_dest, new_stmt);
2526           new_temp = make_ssa_name (vec_dest, new_stmt);
2527           TREE_OPERAND (new_stmt, 0) = new_temp;
2528           new_bb = bsi_insert_on_edge_immediate (pe, new_stmt);
2529           gcc_assert (!new_bb);
2530           magic = TREE_OPERAND (new_stmt, 0);
2531         }
2532       else
2533         {
2534           /* Use current address instead of init_addr for reduced reg pressure.
2535            */
2536           magic = dataref_ptr;
2537         }
2538
2539
2540       /* <4> Create msq = phi <msq_init, lsq> in loop  */ 
2541       vec_dest = vect_create_destination_var (scalar_dest, vectype);
2542       msq = make_ssa_name (vec_dest, NULL_TREE);
2543       phi_stmt = create_phi_node (msq, loop->header); /* CHECKME */
2544       SSA_NAME_DEF_STMT (msq) = phi_stmt;
2545       add_phi_arg (&phi_stmt, msq_init, loop_preheader_edge (loop));
2546       add_phi_arg (&phi_stmt, lsq, loop_latch_edge (loop));
2547
2548
2549       /* <5> Create <vec_dest = realign_load (msq, lsq, magic)> in loop  */
2550       vec_dest = vect_create_destination_var (scalar_dest, vectype);
2551       new_stmt = build3 (REALIGN_LOAD_EXPR, vectype, msq, lsq, magic);
2552       new_stmt = build2 (MODIFY_EXPR, vectype, vec_dest, new_stmt);
2553       new_temp = make_ssa_name (vec_dest, new_stmt); 
2554       TREE_OPERAND (new_stmt, 0) = new_temp;
2555       vect_finish_stmt_generation (stmt, new_stmt, bsi);
2556     }
2557   else
2558     gcc_unreachable ();
2559
2560   *vec_stmt = new_stmt;
2561   return true;
2562 }
2563
2564
2565 /* Function vect_supportable_dr_alignment
2566
2567    Return whether the data reference DR is supported with respect to its
2568    alignment.  */
2569
2570 static enum dr_alignment_support
2571 vect_supportable_dr_alignment (struct data_reference *dr)
2572 {
2573   tree vectype = STMT_VINFO_VECTYPE (vinfo_for_stmt (DR_STMT (dr)));
2574   enum machine_mode mode = (int) TYPE_MODE (vectype);
2575
2576   if (aligned_access_p (dr))
2577     return dr_aligned;
2578
2579   /* Possibly unaligned access.  */
2580   
2581   if (DR_IS_READ (dr))
2582     {
2583       if (vec_realign_load_optab->handlers[mode].insn_code != CODE_FOR_nothing
2584           && (!targetm.vectorize.builtin_mask_for_load
2585               || targetm.vectorize.builtin_mask_for_load ()))
2586         return dr_unaligned_software_pipeline;
2587
2588       if (targetm.vectorize.misaligned_mem_ok (mode))
2589         /* Can't software pipeline the loads.  */
2590         return dr_unaligned_supported;
2591     }
2592
2593   /* Unsupported.  */
2594   return dr_unaligned_unsupported;
2595 }
2596
2597
2598 /* Function vect_transform_stmt.
2599
2600    Create a vectorized stmt to replace STMT, and insert it at BSI.  */
2601
2602 static bool
2603 vect_transform_stmt (tree stmt, block_stmt_iterator *bsi)
2604 {
2605   bool is_store = false;
2606   tree vec_stmt = NULL_TREE;
2607   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
2608   bool done;
2609
2610   switch (STMT_VINFO_TYPE (stmt_info))
2611     {
2612     case op_vec_info_type:
2613       done = vectorizable_operation (stmt, bsi, &vec_stmt);
2614       gcc_assert (done);
2615       break;
2616
2617     case assignment_vec_info_type:
2618       done = vectorizable_assignment (stmt, bsi, &vec_stmt);
2619       gcc_assert (done);
2620       break;
2621
2622     case load_vec_info_type:
2623       done = vectorizable_load (stmt, bsi, &vec_stmt);
2624       gcc_assert (done);
2625       break;
2626
2627     case store_vec_info_type:
2628       done = vectorizable_store (stmt, bsi, &vec_stmt);
2629       gcc_assert (done);
2630       is_store = true;
2631       break;
2632     default:
2633       if (vect_debug_details (NULL))
2634         fprintf (dump_file, "stmt not supported.");
2635       gcc_unreachable ();
2636     }
2637
2638   STMT_VINFO_VEC_STMT (stmt_info) = vec_stmt;
2639
2640   return is_store;
2641 }
2642
2643
2644 /* This function builds ni_name = number of iterations loop executes
2645    on the loop preheader.  */
2646
2647 static tree
2648 vect_build_loop_niters (loop_vec_info loop_vinfo)
2649 {
2650   tree ni_name, stmt, var;
2651   edge pe;
2652   basic_block new_bb = NULL;
2653   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
2654   tree ni = unshare_expr (LOOP_VINFO_NITERS(loop_vinfo));
2655
2656   var = create_tmp_var (TREE_TYPE (ni), "niters");
2657   add_referenced_tmp_var (var);
2658   if (TREE_CODE (ni) == INTEGER_CST)
2659     {
2660       /* This case is generated when treating a known loop bound 
2661          indivisible by VF. Here we cannot use force_gimple_operand.  */
2662       stmt = build (MODIFY_EXPR, void_type_node, var, ni);
2663       ni_name = make_ssa_name (var, stmt);
2664       TREE_OPERAND (stmt, 0) = ni_name;
2665     }
2666   else
2667     ni_name = force_gimple_operand (ni, &stmt, false, var);
2668
2669   pe = loop_preheader_edge (loop);
2670   if (stmt)
2671     new_bb = bsi_insert_on_edge_immediate (pe, stmt);
2672   if (new_bb)
2673     add_bb_to_loop (new_bb, EDGE_PRED (new_bb, 0)->src->loop_father);
2674       
2675   return ni_name;
2676 }
2677
2678
2679 /* This function generates the following statements:
2680
2681  ni_name = number of iterations loop executes
2682  ratio = ni_name / vf
2683  ratio_mult_vf_name = ratio * vf
2684
2685  and places them at the loop preheader edge.  */
2686
2687 static void 
2688 vect_generate_tmps_on_preheader (loop_vec_info loop_vinfo, tree *ni_name_p,
2689                                  tree *ratio_mult_vf_name_p, tree *ratio_p)
2690 {
2691
2692   edge pe;
2693   basic_block new_bb;
2694   tree stmt, ni_name;
2695   tree ratio;
2696   tree ratio_mult_vf_name, ratio_mult_vf;
2697   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
2698   tree ni = LOOP_VINFO_NITERS(loop_vinfo);
2699   
2700   int vf, i;
2701
2702   /* Generate temporary variable that contains 
2703      number of iterations loop executes.  */
2704
2705   ni_name = vect_build_loop_niters (loop_vinfo);
2706
2707   /* ratio = ni / vf.
2708      vf is power of 2; then if ratio =  = n >> log2 (vf).  */
2709   vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
2710   ratio = vect_build_symbol_bound (ni_name, vf, loop);
2711        
2712   /* Update initial conditions of loop copy.  */
2713        
2714   /* ratio_mult_vf = ratio * vf;  
2715      then if ratio_mult_vf = ratio << log2 (vf).  */
2716
2717   i = exact_log2 (vf);
2718   ratio_mult_vf = create_tmp_var (TREE_TYPE (ni), "ratio_mult_vf");
2719   add_referenced_tmp_var (ratio_mult_vf);
2720
2721   ratio_mult_vf_name = make_ssa_name (ratio_mult_vf, NULL_TREE);
2722
2723   stmt = build2 (MODIFY_EXPR, void_type_node, ratio_mult_vf_name,
2724                 build2 (LSHIFT_EXPR, TREE_TYPE (ratio),
2725                        ratio, build_int_cst (unsigned_type_node,
2726                                              i)));
2727
2728   SSA_NAME_DEF_STMT (ratio_mult_vf_name) = stmt;
2729
2730   pe = loop_preheader_edge (loop);
2731   new_bb = bsi_insert_on_edge_immediate (pe, stmt);
2732   if (new_bb)
2733     add_bb_to_loop (new_bb, EDGE_PRED (new_bb, 0)->src->loop_father);
2734
2735   *ni_name_p = ni_name;
2736   *ratio_mult_vf_name_p = ratio_mult_vf_name;
2737   *ratio_p = ratio;
2738     
2739   return;  
2740 }
2741
2742
2743 /* This function generates stmt 
2744    
2745    tmp = n / vf;
2746
2747    and attaches it to preheader of LOOP.  */
2748
2749 static tree 
2750 vect_build_symbol_bound (tree n, int vf, struct loop * loop)
2751 {
2752   tree var, stmt, var_name;
2753   edge pe;
2754   basic_block new_bb;
2755   int i;
2756
2757   /* create temporary variable */
2758   var = create_tmp_var (TREE_TYPE (n), "bnd");
2759   add_referenced_tmp_var (var);
2760
2761   var_name = make_ssa_name (var, NULL_TREE);
2762
2763   /* vf is power of 2; then n/vf = n >> log2 (vf).  */
2764
2765   i = exact_log2 (vf);
2766   stmt = build2 (MODIFY_EXPR, void_type_node, var_name,
2767                 build2 (RSHIFT_EXPR, TREE_TYPE (n),
2768                        n, build_int_cst (unsigned_type_node,i)));
2769
2770   SSA_NAME_DEF_STMT (var_name) = stmt;
2771
2772   pe = loop_preheader_edge (loop);
2773   new_bb = bsi_insert_on_edge_immediate (pe, stmt);
2774   if (new_bb)
2775     add_bb_to_loop (new_bb, EDGE_PRED (new_bb, 0)->src->loop_father);
2776   else  
2777     if (vect_debug_details (NULL))
2778       fprintf (dump_file, "New bb on preheader edge was not generated.");
2779
2780   return var_name;
2781 }
2782
2783
2784 /* Function vect_transform_loop_bound.
2785
2786    Create a new exit condition for the loop.  */
2787
2788 static void
2789 vect_transform_loop_bound (loop_vec_info loop_vinfo, tree niters)
2790 {
2791   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
2792   tree orig_cond_expr;
2793   HOST_WIDE_INT old_N = 0;
2794   int vf;
2795   tree new_loop_bound;
2796   bool symbol_niters;
2797   tree lb_type;
2798
2799   symbol_niters = !LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo);
2800
2801   if (!symbol_niters)
2802     old_N = LOOP_VINFO_INT_NITERS (loop_vinfo);
2803
2804   vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
2805
2806   orig_cond_expr = LOOP_VINFO_EXIT_COND (loop_vinfo);
2807 #ifdef ENABLE_CHECKING
2808   gcc_assert (orig_cond_expr);
2809 #endif
2810
2811   /* new loop exit test:  */
2812   lb_type = TREE_TYPE (TREE_OPERAND (COND_EXPR_COND (orig_cond_expr), 1));
2813   if (!symbol_niters)
2814     new_loop_bound = 
2815         fold_convert (lb_type, build_int_cst (unsigned_type_node, old_N/vf));
2816   else
2817     new_loop_bound = niters;
2818
2819   slpeel_make_loop_iterate_ntimes (loop, new_loop_bound);
2820 }
2821
2822
2823 /*   Function vect_update_ivs_after_vectorizer.
2824
2825      "Advance" the induction variables of LOOP to the value they should take
2826      after the execution of LOOP.  This is currently necessary because the
2827      vectorizer does not handle induction variables that are used after the
2828      loop.  Such a situation occurs when the last iterations of LOOP are
2829      peeled, because:
2830      1. We introduced new uses after LOOP for IVs that were not originally used
2831         after LOOP: the IVs of LOOP are now used by an epilog loop.
2832      2. LOOP is going to be vectorized; this means that it will iterate N/VF
2833         times, whereas the loop IVs should be bumped N times.
2834
2835      Input:
2836      - LOOP - a loop that is going to be vectorized. The last few iterations
2837               of LOOP were peeled.
2838      - NITERS - the number of iterations that LOOP executes (before it is
2839                 vectorized). i.e, the number of times the ivs should be bumped.
2840
2841      We have:
2842
2843         bb_before_loop:
2844           if (guard-cond) GOTO bb_before_epilog_loop
2845           else            GOTO loop
2846
2847         loop:
2848           do {
2849           } while ...
2850
2851         bb_before_epilog_loop:
2852
2853      bb_before_epilog_loop has edges coming in form the loop exit and
2854      from bb_before_loop.  New definitions for ivs will be placed on the edge
2855      from loop->exit to bb_before_epilog_loop.  This also requires that we update
2856      the phis in bb_before_epilog_loop. (In the code this bb is denoted 
2857      "update_bb").
2858
2859      Assumption 1: Like the rest of the vectorizer, this function assumes
2860      a single loop exit that has a single predecessor.
2861
2862      Assumption 2: The phi nodes in the LOOP header and in update_bb are
2863      organized in the same order.
2864
2865      Assumption 3: The access function of the ivs is simple enough (see
2866      vect_can_advance_ivs_p).  This assumption will be relaxed in the future.
2867  */
2868
2869 static void
2870 vect_update_ivs_after_vectorizer (struct loop *loop, tree niters)
2871 {
2872   edge exit = loop->exit_edges[0];
2873   tree phi, phi1;
2874   basic_block update_bb = exit->dest;
2875   edge update_e;
2876
2877   /* Generate basic block at the exit from the loop.  */
2878   basic_block new_bb = split_edge (exit);
2879
2880   add_bb_to_loop (new_bb, EDGE_SUCC (new_bb, 0)->dest->loop_father);
2881   loop->exit_edges[0] = EDGE_PRED (new_bb, 0);
2882   update_e = EDGE_SUCC (new_bb, 0);
2883   
2884   for (phi = phi_nodes (loop->header), phi1 = phi_nodes (update_bb); 
2885        phi && phi1; 
2886        phi = PHI_CHAIN (phi), phi1 = PHI_CHAIN (phi1))
2887     {
2888       tree access_fn = NULL;
2889       tree evolution_part;
2890       tree init_expr;
2891       tree step_expr;
2892       tree var, stmt, ni, ni_name;
2893       block_stmt_iterator last_bsi;
2894
2895       /* Skip virtual phi's. The data dependences that are associated with
2896          virtual defs/uses (i.e., memory accesses) are analyzed elsewhere.  */
2897
2898       if (!is_gimple_reg (SSA_NAME_VAR (PHI_RESULT (phi))))
2899         {
2900           if (vect_debug_details (NULL))
2901             fprintf (dump_file, "virtual phi. skip.");
2902           continue;
2903         }
2904
2905       access_fn = analyze_scalar_evolution (loop, PHI_RESULT (phi)); 
2906       gcc_assert (access_fn);
2907       evolution_part =
2908          unshare_expr (evolution_part_in_loop_num (access_fn, loop->num));
2909       
2910       /* FORNOW: We do not transform initial conditions of IVs 
2911          which evolution functions are a polynomial of degree >= 2 or
2912          exponential.  */
2913       gcc_assert (!tree_is_chrec (evolution_part));
2914
2915       step_expr = evolution_part;
2916       init_expr = unshare_expr (initial_condition (access_fn));
2917
2918       ni = build2 (PLUS_EXPR, TREE_TYPE (init_expr),
2919                   build2 (MULT_EXPR, TREE_TYPE (niters),
2920                        niters, step_expr), init_expr);
2921
2922       var = create_tmp_var (TREE_TYPE (init_expr), "tmp");
2923       add_referenced_tmp_var (var);
2924
2925       ni_name = force_gimple_operand (ni, &stmt, false, var);
2926       
2927       /* Insert stmt into new_bb.  */
2928       last_bsi = bsi_last (new_bb);
2929       if (stmt)
2930         bsi_insert_after (&last_bsi, stmt, BSI_NEW_STMT);   
2931
2932       /* Fix phi expressions in duplicated loop.  */
2933       gcc_assert (PHI_ARG_DEF_FROM_EDGE (phi1, update_e) ==
2934                   PHI_ARG_DEF_FROM_EDGE (phi, EDGE_SUCC (loop->latch, 0)));
2935       SET_PHI_ARG_DEF (phi1, phi_arg_from_edge (phi1, update_e), ni_name);
2936     }
2937 }
2938
2939
2940 /* This function is the main driver of transformation 
2941    to be done for loop before vectorizing it in case of 
2942    unknown loop bound.  */
2943
2944 static void 
2945 vect_do_peeling_for_loop_bound (loop_vec_info loop_vinfo, tree * ratio,
2946                                 struct loops *loops)
2947 {
2948
2949   tree ni_name, ratio_mult_vf_name;
2950 #ifdef ENABLE_CHECKING
2951   int loop_num;
2952 #endif
2953   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
2954   struct loop *new_loop;
2955
2956   if (vect_debug_details (NULL))
2957     fprintf (dump_file, "\n<<vect_transtorm_for_unknown_loop_bound>>\n");
2958
2959   /* Generate the following variables on the preheader of original loop:
2960          
2961      ni_name = number of iteration the original loop executes
2962      ratio = ni_name / vf
2963      ratio_mult_vf_name = ratio * vf  */
2964   vect_generate_tmps_on_preheader (loop_vinfo, &ni_name,
2965                                    &ratio_mult_vf_name, ratio);
2966
2967   /* Update loop info.  */
2968   loop->pre_header = loop_preheader_edge (loop)->src;
2969   loop->pre_header_edges[0] = loop_preheader_edge (loop);
2970
2971 #ifdef ENABLE_CHECKING
2972   loop_num  = loop->num; 
2973 #endif
2974   new_loop = slpeel_tree_peel_loop_to_edge (loop, loops, loop->exit_edges[0],
2975                                             ratio_mult_vf_name, ni_name, true); 
2976 #ifdef ENABLE_CHECKING
2977   gcc_assert (new_loop);
2978   gcc_assert (loop_num == loop->num);
2979 #endif
2980
2981   /* Update IVs of original loop as if they were advanced 
2982      by ratio_mult_vf_name steps.  */
2983
2984 #ifdef ENABLE_CHECKING
2985   /* Check existence of intermediate bb.  */
2986   gcc_assert (loop->exit_edges[0]->dest == new_loop->pre_header);
2987 #endif
2988   vect_update_ivs_after_vectorizer (loop, ratio_mult_vf_name); 
2989
2990   return;
2991
2992 }
2993
2994
2995 /* Function vect_gen_niters_for_prolog_loop
2996
2997    Set the number of iterations for the loop represented by LOOP_VINFO
2998    to the minimum between NITERS (the original iteration count of the loop)
2999    and the misalignment of DR - the first data reference recorded in
3000    LOOP_VINFO_UNALIGNED_DR (LOOP_VINFO).  As a result, after the execution of 
3001    this loop, the data reference DR will refer to an aligned location.  */
3002
3003 static tree 
3004 vect_gen_niters_for_prolog_loop (loop_vec_info loop_vinfo, tree niters)
3005 {
3006   struct data_reference *dr = LOOP_VINFO_UNALIGNED_DR (loop_vinfo);
3007   int vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
3008   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
3009   tree var, stmt;
3010   tree iters, iters_name;
3011   edge pe;
3012   basic_block new_bb;
3013   tree dr_stmt = DR_STMT (dr);
3014   stmt_vec_info stmt_info = vinfo_for_stmt (dr_stmt);
3015   tree start_addr, byte_miss_align, elem_miss_align;
3016   int vec_type_align = 
3017     GET_MODE_ALIGNMENT (TYPE_MODE (STMT_VINFO_VECTYPE (stmt_info))) 
3018                                                         / BITS_PER_UNIT;
3019   tree tmp1, tmp2;
3020   tree new_stmt_list = NULL_TREE;
3021
3022   start_addr = vect_create_addr_base_for_vector_ref (dr_stmt,
3023                                                      &new_stmt_list, NULL_TREE);
3024
3025   pe = loop_preheader_edge (loop); 
3026   new_bb = bsi_insert_on_edge_immediate (pe, new_stmt_list); 
3027   if (new_bb)
3028     add_bb_to_loop (new_bb, EDGE_PRED (new_bb, 0)->src->loop_father);
3029
3030   byte_miss_align = 
3031         build (BIT_AND_EXPR, integer_type_node, start_addr, 
3032                   build (MINUS_EXPR, integer_type_node, 
3033                          build_int_cst (unsigned_type_node,
3034                                         vec_type_align), integer_one_node));
3035   tmp1 = build_int_cst (unsigned_type_node, vec_type_align/vf);
3036   elem_miss_align = build (FLOOR_DIV_EXPR, integer_type_node, 
3037                            byte_miss_align, tmp1); 
3038   
3039   tmp2 = 
3040         build (BIT_AND_EXPR, integer_type_node,
3041           build (MINUS_EXPR, integer_type_node, 
3042                 build_int_cst (unsigned_type_node, vf), elem_miss_align),
3043           build (MINUS_EXPR, integer_type_node, 
3044                 build_int_cst (unsigned_type_node, vf), integer_one_node)); 
3045
3046   iters = build2 (MIN_EXPR, TREE_TYPE (tmp2), tmp2, niters);
3047   var = create_tmp_var (TREE_TYPE (iters), "iters");
3048   add_referenced_tmp_var (var);
3049   iters_name = force_gimple_operand (iters, &stmt, false, var);
3050
3051   /* Insert stmt on loop preheader edge.  */
3052   pe = loop_preheader_edge (loop);
3053   if (stmt)
3054     new_bb = bsi_insert_on_edge_immediate (pe, stmt);
3055   if (new_bb)
3056     add_bb_to_loop (new_bb, EDGE_PRED (new_bb, 0)->src->loop_father);
3057
3058   return iters_name; 
3059 }
3060
3061
3062 /* Function vect_update_inits_of_dr
3063
3064    NITERS iterations were peeled from LOOP.  DR represents a data reference
3065    in LOOP.  This function updates the information recorded in DR to
3066    account for the fact that the first NITERS iterations had already been 
3067    executed.  Specifically, it updates the initial_condition of the 
3068    access_function of DR.  */
3069
3070 static void
3071 vect_update_inits_of_dr (struct data_reference *dr, struct loop *loop, 
3072                          tree niters)
3073 {
3074   tree access_fn = DR_ACCESS_FN (dr, 0);
3075   tree init, init_new, step;
3076       
3077   step = evolution_part_in_loop_num (access_fn, loop->num);
3078   init = initial_condition (access_fn);
3079       
3080   init_new = build (PLUS_EXPR, TREE_TYPE (init),
3081                   build (MULT_EXPR, TREE_TYPE (niters),
3082                          niters, step), init);
3083   DR_ACCESS_FN (dr, 0) = chrec_replace_initial_condition (access_fn, init_new);
3084   
3085   return;
3086 }
3087
3088
3089 /* Function vect_update_inits_of_drs
3090
3091    NITERS iterations were peeled from the loop represented by LOOP_VINFO.  
3092    This function updates the information recorded for the data references in 
3093    the loop to account for the fact that the first NITERS iterations had 
3094    already been executed.  Specifically, it updates the initial_condition of the
3095    access_function of all the data_references in the loop.  */
3096
3097 static void
3098 vect_update_inits_of_drs (loop_vec_info loop_vinfo, tree niters)
3099 {
3100   unsigned int i;
3101   varray_type loop_write_datarefs = LOOP_VINFO_DATAREF_WRITES (loop_vinfo);
3102   varray_type loop_read_datarefs = LOOP_VINFO_DATAREF_READS (loop_vinfo);
3103   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
3104
3105   if (dump_file && (dump_flags & TDF_DETAILS))
3106     fprintf (dump_file, "\n<<vect_update_inits_of_dr>>\n");
3107
3108   for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_write_datarefs); i++)
3109     {
3110       struct data_reference *dr = VARRAY_GENERIC_PTR (loop_write_datarefs, i);
3111       vect_update_inits_of_dr (dr, loop, niters);
3112     }
3113
3114   for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_read_datarefs); i++)
3115     {
3116       struct data_reference *dr = VARRAY_GENERIC_PTR (loop_read_datarefs, i);
3117       vect_update_inits_of_dr (dr, loop, niters);
3118     }
3119 }
3120
3121
3122 /* Function vect_do_peeling_for_alignment
3123
3124    Peel the first 'niters' iterations of the loop represented by LOOP_VINFO.
3125    'niters' is set to the misalignment of one of the data references in the
3126    loop, thereby forcing it to refer to an aligned location at the beginning
3127    of the execution of this loop.  The data reference for which we are
3128    peeling is recorded in LOOP_VINFO_UNALIGNED_DR.  */
3129
3130 static void
3131 vect_do_peeling_for_alignment (loop_vec_info loop_vinfo, struct loops *loops)
3132 {
3133   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
3134   tree niters_of_prolog_loop, ni_name;
3135   tree n_iters;
3136
3137   if (vect_debug_details (NULL))
3138     fprintf (dump_file, "\n<<vect_do_peeling_for_alignment>>\n");
3139
3140   ni_name = vect_build_loop_niters (loop_vinfo);
3141   niters_of_prolog_loop = vect_gen_niters_for_prolog_loop (loop_vinfo, ni_name);
3142   
3143
3144   /* Peel the prolog loop and iterate it niters_of_prolog_loop.  */
3145   slpeel_tree_peel_loop_to_edge (loop, loops, loop_preheader_edge(loop), 
3146                                  niters_of_prolog_loop, ni_name, false); 
3147
3148   /* Update number of times loop executes.  */
3149   n_iters = LOOP_VINFO_NITERS (loop_vinfo);
3150   LOOP_VINFO_NITERS (loop_vinfo) =
3151     build (MINUS_EXPR, integer_type_node, n_iters, niters_of_prolog_loop);
3152
3153   /* Update all inits of access functions of all data refs.  */
3154   vect_update_inits_of_drs (loop_vinfo, niters_of_prolog_loop);
3155
3156   /* After peeling we have to reset scalar evolution analyzer.  */
3157   scev_reset ();
3158
3159   return;
3160 }
3161
3162
3163 /* Function vect_transform_loop.
3164
3165    The analysis phase has determined that the loop is vectorizable.
3166    Vectorize the loop - created vectorized stmts to replace the scalar
3167    stmts in the loop, and update the loop exit condition.  */
3168
3169 static void
3170 vect_transform_loop (loop_vec_info loop_vinfo, 
3171                      struct loops *loops ATTRIBUTE_UNUSED)
3172 {
3173   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
3174   basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
3175   int nbbs = loop->num_nodes;
3176   block_stmt_iterator si;
3177   int i;
3178   tree ratio = NULL;
3179   int vectorization_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
3180
3181   if (vect_debug_details (NULL))
3182     fprintf (dump_file, "\n<<vec_transform_loop>>\n");
3183
3184   
3185   /* Peel the loop if there are data refs with unknown alignment.
3186      Only one data ref with unknown store is allowed.  */
3187
3188   if (LOOP_DO_PEELING_FOR_ALIGNMENT (loop_vinfo))
3189     vect_do_peeling_for_alignment (loop_vinfo, loops);
3190   
3191   /* If the loop has a symbolic number of iterations 'n' (i.e. it's not a
3192      compile time constant), or it is a constant that doesn't divide by the
3193      vectorization factor, then an epilog loop needs to be created.
3194      We therefore duplicate the loop: the original loop will be vectorized,
3195      and will compute the first (n/VF) iterations. The second copy of the loop
3196      will remain scalar and will compute the remaining (n%VF) iterations.
3197      (VF is the vectorization factor).  */
3198
3199   if (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
3200       || (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
3201           && LOOP_VINFO_INT_NITERS (loop_vinfo) % vectorization_factor != 0))
3202     vect_do_peeling_for_loop_bound (loop_vinfo, &ratio, loops);
3203
3204   /* 1) Make sure the loop header has exactly two entries
3205      2) Make sure we have a preheader basic block.  */
3206
3207   gcc_assert (EDGE_COUNT (loop->header->preds) == 2);
3208
3209   loop_split_edge_with (loop_preheader_edge (loop), NULL);
3210
3211
3212   /* FORNOW: the vectorizer supports only loops which body consist
3213      of one basic block (header + empty latch). When the vectorizer will 
3214      support more involved loop forms, the order by which the BBs are 
3215      traversed need to be reconsidered.  */
3216
3217   for (i = 0; i < nbbs; i++)
3218     {
3219       basic_block bb = bbs[i];
3220
3221       for (si = bsi_start (bb); !bsi_end_p (si);)
3222         {
3223           tree stmt = bsi_stmt (si);
3224           stmt_vec_info stmt_info;
3225           bool is_store;
3226
3227           if (vect_debug_details (NULL))
3228             {
3229               fprintf (dump_file, "------>vectorizing statement: ");
3230               print_generic_expr (dump_file, stmt, TDF_SLIM);
3231             }   
3232           stmt_info = vinfo_for_stmt (stmt);
3233           gcc_assert (stmt_info);
3234           if (!STMT_VINFO_RELEVANT_P (stmt_info))
3235             {
3236               bsi_next (&si);
3237               continue;
3238             }
3239 #ifdef ENABLE_CHECKING
3240           /* FORNOW: Verify that all stmts operate on the same number of
3241                      units and no inner unrolling is necessary.  */
3242           gcc_assert 
3243                 (GET_MODE_NUNITS (TYPE_MODE (STMT_VINFO_VECTYPE (stmt_info)))
3244                  == vectorization_factor);
3245 #endif
3246           /* -------- vectorize statement ------------ */
3247           if (vect_debug_details (NULL))
3248             fprintf (dump_file, "transform statement.");
3249
3250           is_store = vect_transform_stmt (stmt, &si);
3251           if (is_store)
3252             {
3253               /* free the attached stmt_vec_info and remove the stmt.  */
3254               stmt_ann_t ann = stmt_ann (stmt);
3255               free (stmt_info);
3256               set_stmt_info (ann, NULL);
3257               bsi_remove (&si);
3258               continue;
3259             }
3260
3261           bsi_next (&si);
3262         }                       /* stmts in BB */
3263     }                           /* BBs in loop */
3264
3265   vect_transform_loop_bound (loop_vinfo, ratio);
3266
3267   if (vect_debug_details (loop))
3268     fprintf (dump_file,"Success! loop vectorized.");
3269   if (vect_debug_stats (loop))
3270     fprintf (dump_file, "LOOP VECTORIZED.");
3271 }
3272
3273
3274 /* Function vect_is_simple_use.
3275
3276    Input:
3277    LOOP - the loop that is being vectorized.
3278    OPERAND - operand of a stmt in LOOP.
3279    DEF - the defining stmt in case OPERAND is an SSA_NAME.
3280
3281    Returns whether a stmt with OPERAND can be vectorized.
3282    Supportable operands are constants, loop invariants, and operands that are
3283    defined by the current iteration of the loop. Unsupportable operands are 
3284    those that are defined by a previous iteration of the loop (as is the case
3285    in reduction/induction computations).  */
3286
3287 static bool
3288 vect_is_simple_use (tree operand, struct loop *loop, tree *def)
3289
3290   tree def_stmt;
3291   basic_block bb;
3292
3293   if (def)
3294     *def = NULL_TREE;
3295
3296   if (TREE_CODE (operand) == INTEGER_CST || TREE_CODE (operand) == REAL_CST)
3297     return true;
3298
3299   if (TREE_CODE (operand) != SSA_NAME)
3300     return false;
3301
3302   def_stmt = SSA_NAME_DEF_STMT (operand);
3303   if (def_stmt == NULL_TREE )
3304     {
3305       if (vect_debug_details (NULL))
3306         fprintf (dump_file, "no def_stmt.");
3307       return false;
3308     }
3309
3310   /* empty stmt is expected only in case of a function argument.
3311      (Otherwise - we expect a phi_node or a modify_expr).  */
3312   if (IS_EMPTY_STMT (def_stmt))
3313     {
3314       tree arg = TREE_OPERAND (def_stmt, 0);
3315       if (TREE_CODE (arg) == INTEGER_CST || TREE_CODE (arg) == REAL_CST)
3316         return true;
3317       if (vect_debug_details (NULL))
3318         {
3319           fprintf (dump_file, "Unexpected empty stmt: ");
3320           print_generic_expr (dump_file, def_stmt, TDF_SLIM);
3321         }
3322       return false;  
3323     }
3324
3325   /* phi_node inside the loop indicates an induction/reduction pattern.
3326      This is not supported yet.  */
3327   bb = bb_for_stmt (def_stmt);
3328   if (TREE_CODE (def_stmt) == PHI_NODE && flow_bb_inside_loop_p (loop, bb))
3329     {
3330       if (vect_debug_details (NULL))
3331         fprintf (dump_file, "reduction/induction - unsupported.");
3332       return false; /* FORNOW: not supported yet.  */
3333     }
3334
3335   /* Expecting a modify_expr or a phi_node.  */
3336   if (TREE_CODE (def_stmt) == MODIFY_EXPR
3337       || TREE_CODE (def_stmt) == PHI_NODE)
3338     {
3339       if (def)
3340         *def = def_stmt;        
3341       return true;
3342     }
3343
3344   return false;
3345 }
3346
3347
3348 /* Function vect_analyze_operations.
3349
3350    Scan the loop stmts and make sure they are all vectorizable.  */
3351
3352 static bool
3353 vect_analyze_operations (loop_vec_info loop_vinfo)
3354 {
3355   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
3356   basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
3357   int nbbs = loop->num_nodes;
3358   block_stmt_iterator si;
3359   int vectorization_factor = 0;
3360   int i;
3361   bool ok;
3362   tree scalar_type;
3363
3364   if (vect_debug_details (NULL))
3365     fprintf (dump_file, "\n<<vect_analyze_operations>>\n");
3366
3367   for (i = 0; i < nbbs; i++)
3368     {
3369       basic_block bb = bbs[i];
3370
3371       for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
3372         {
3373           tree stmt = bsi_stmt (si);
3374           int nunits;
3375           stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
3376           tree vectype;
3377
3378           if (vect_debug_details (NULL))
3379             {
3380               fprintf (dump_file, "==> examining statement: ");
3381               print_generic_expr (dump_file, stmt, TDF_SLIM);
3382             }
3383
3384           gcc_assert (stmt_info);
3385
3386           /* skip stmts which do not need to be vectorized.
3387              this is expected to include:
3388              - the COND_EXPR which is the loop exit condition
3389              - any LABEL_EXPRs in the loop
3390              - computations that are used only for array indexing or loop
3391              control  */
3392
3393           if (!STMT_VINFO_RELEVANT_P (stmt_info))
3394             {
3395               if (vect_debug_details (NULL))
3396                 fprintf (dump_file, "irrelevant.");
3397               continue;
3398             }
3399
3400           if (VECTOR_MODE_P (TYPE_MODE (TREE_TYPE (stmt))))
3401             {
3402               if (vect_debug_stats (loop) || vect_debug_details (loop))
3403                 {
3404                   fprintf (dump_file, "not vectorized: vector stmt in loop:");
3405                   print_generic_expr (dump_file, stmt, TDF_SLIM);
3406                 }
3407               return false;
3408             }
3409
3410           if (STMT_VINFO_DATA_REF (stmt_info))
3411             scalar_type = TREE_TYPE (DR_REF (STMT_VINFO_DATA_REF (stmt_info)));    
3412           else if (TREE_CODE (stmt) == MODIFY_EXPR)
3413             scalar_type = TREE_TYPE (TREE_OPERAND (stmt, 0));
3414           else
3415             scalar_type = TREE_TYPE (stmt);
3416
3417           if (vect_debug_details (NULL))
3418             {
3419               fprintf (dump_file, "get vectype for scalar type:  ");
3420               print_generic_expr (dump_file, scalar_type, TDF_SLIM);
3421             }
3422
3423           vectype = get_vectype_for_scalar_type (scalar_type);
3424           if (!vectype)
3425             {
3426               if (vect_debug_stats (loop) || vect_debug_details (loop))
3427                 {
3428                   fprintf (dump_file, "not vectorized: unsupported data-type ");
3429                   print_generic_expr (dump_file, scalar_type, TDF_SLIM);
3430                 }
3431               return false;
3432             }
3433
3434           if (vect_debug_details (NULL))
3435             {
3436               fprintf (dump_file, "vectype: ");
3437               print_generic_expr (dump_file, vectype, TDF_SLIM);
3438             }
3439           STMT_VINFO_VECTYPE (stmt_info) = vectype;
3440
3441           ok = (vectorizable_operation (stmt, NULL, NULL)
3442                 || vectorizable_assignment (stmt, NULL, NULL)
3443                 || vectorizable_load (stmt, NULL, NULL)
3444                 || vectorizable_store (stmt, NULL, NULL));
3445
3446           if (!ok)
3447             {
3448               if (vect_debug_stats (loop) || vect_debug_details (loop))
3449                 {
3450                   fprintf (dump_file, "not vectorized: stmt not supported: ");
3451                   print_generic_expr (dump_file, stmt, TDF_SLIM);
3452                 }
3453               return false;
3454             }
3455
3456           nunits = GET_MODE_NUNITS (TYPE_MODE (vectype));
3457           if (vect_debug_details (NULL))
3458             fprintf (dump_file, "nunits = %d", nunits);
3459
3460           if (vectorization_factor)
3461             {
3462               /* FORNOW: don't allow mixed units.
3463                  This restriction will be relaxed in the future.  */
3464               if (nunits != vectorization_factor)
3465                 {
3466                   if (vect_debug_stats (loop) || vect_debug_details (loop))
3467                     fprintf (dump_file, "not vectorized: mixed data-types");
3468                   return false;
3469                 }
3470             }
3471           else
3472             vectorization_factor = nunits;
3473
3474 #ifdef ENABLE_CHECKING
3475           gcc_assert (GET_MODE_SIZE (TYPE_MODE (scalar_type))
3476                         * vectorization_factor == UNITS_PER_SIMD_WORD);
3477 #endif
3478         }
3479     }
3480
3481   /* TODO: Analyze cost. Decide if worth while to vectorize.  */
3482
3483   if (vectorization_factor <= 1)
3484     {
3485       if (vect_debug_stats (loop) || vect_debug_details (loop))
3486         fprintf (dump_file, "not vectorized: unsupported data-type");
3487       return false;
3488     }
3489   LOOP_VINFO_VECT_FACTOR (loop_vinfo) = vectorization_factor;
3490
3491   if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo) && vect_debug_details (NULL))
3492     fprintf (dump_file,
3493         "vectorization_factor = %d, niters = " HOST_WIDE_INT_PRINT_DEC,
3494         vectorization_factor, LOOP_VINFO_INT_NITERS (loop_vinfo));
3495
3496   if (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
3497       || LOOP_VINFO_INT_NITERS (loop_vinfo) % vectorization_factor != 0)
3498     {
3499       if (vect_debug_stats (loop) || vect_debug_details (loop))
3500         fprintf (dump_file, "epilog loop required.");
3501       if (!vect_can_advance_ivs_p (loop))
3502         {
3503           if (vect_debug_stats (loop) || vect_debug_details (loop))
3504             fprintf (dump_file, "not vectorized: can't create epilog loop 1.");
3505           return false;
3506         }
3507       if (!slpeel_can_duplicate_loop_p (loop, loop->exit_edges[0]))
3508         {
3509           if (vect_debug_stats (loop) || vect_debug_details (loop))
3510             fprintf (dump_file, "not vectorized: can't create epilog loop 2.");
3511           return false;
3512         }
3513     }
3514
3515   return true;
3516 }
3517
3518
3519 /* Function exist_non_indexing_operands_for_use_p 
3520
3521    USE is one of the uses attached to STMT. Check if USE is 
3522    used in STMT for anything other than indexing an array.  */
3523
3524 static bool
3525 exist_non_indexing_operands_for_use_p (tree use, tree stmt)
3526 {
3527   tree operand;
3528   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
3529  
3530   /* USE corresponds to some operand in STMT. If there is no data
3531      reference in STMT, then any operand that corresponds to USE
3532      is not indexing an array.  */
3533   if (!STMT_VINFO_DATA_REF (stmt_info))
3534     return true;
3535  
3536   /* STMT has a data_ref. FORNOW this means that its of one of
3537      the following forms:
3538      -1- ARRAY_REF = var
3539      -2- var = ARRAY_REF
3540      (This should have been verified in analyze_data_refs).
3541
3542      'var' in the second case corresponds to a def, not a use,
3543      so USE cannot correspond to any operands that are not used 
3544      for array indexing.
3545
3546      Therefore, all we need to check is if STMT falls into the
3547      first case, and whether var corresponds to USE.  */
3548  
3549   if (TREE_CODE (TREE_OPERAND (stmt, 0)) == SSA_NAME)
3550     return false;
3551
3552   operand = TREE_OPERAND (stmt, 1);
3553
3554   if (TREE_CODE (operand) != SSA_NAME)
3555     return false;
3556
3557   if (operand == use)
3558     return true;
3559
3560   return false;
3561 }
3562
3563
3564 /* Function vect_is_simple_iv_evolution.
3565
3566    FORNOW: A simple evolution of an induction variables in the loop is
3567    considered a polynomial evolution with constant step.  */
3568
3569 static bool
3570 vect_is_simple_iv_evolution (unsigned loop_nb, tree access_fn, tree * init, 
3571                                 tree * step, bool strict)
3572 {
3573   tree init_expr;
3574   tree step_expr;
3575   
3576   tree evolution_part = evolution_part_in_loop_num (access_fn, loop_nb);
3577
3578   /* When there is no evolution in this loop, the evolution function
3579      is not "simple".  */  
3580   if (evolution_part == NULL_TREE)
3581     return false;
3582   
3583   /* When the evolution is a polynomial of degree >= 2
3584      the evolution function is not "simple".  */
3585   if (tree_is_chrec (evolution_part))
3586     return false;
3587   
3588   step_expr = evolution_part;
3589   init_expr = unshare_expr (initial_condition (access_fn));
3590
3591   if (vect_debug_details (NULL))
3592     {
3593       fprintf (dump_file, "step: ");
3594       print_generic_expr (dump_file, step_expr, TDF_SLIM);
3595       fprintf (dump_file, ",  init: ");
3596       print_generic_expr (dump_file, init_expr, TDF_SLIM);
3597     }
3598
3599   *init = init_expr;
3600   *step = step_expr;
3601
3602   if (TREE_CODE (step_expr) != INTEGER_CST)
3603     {
3604       if (vect_debug_details (NULL))
3605         fprintf (dump_file, "step unknown.");
3606       return false;
3607     }
3608
3609   if (strict)
3610     if (!integer_onep (step_expr))
3611       {
3612         if (vect_debug_details (NULL))
3613           print_generic_expr (dump_file, step_expr, TDF_SLIM);
3614         return false;
3615       }
3616
3617   return true;
3618 }
3619
3620
3621 /* Function vect_analyze_scalar_cycles.
3622
3623    Examine the cross iteration def-use cycles of scalar variables, by
3624    analyzing the loop (scalar) PHIs; verify that the cross iteration def-use
3625    cycles that they represent do not impede vectorization.
3626
3627    FORNOW: Reduction as in the following loop, is not supported yet:
3628               loop1:
3629               for (i=0; i<N; i++)
3630                  sum += a[i];
3631            The cross-iteration cycle corresponding to variable 'sum' will be
3632            considered too complicated and will impede vectorization.
3633
3634    FORNOW: Induction as in the following loop, is not supported yet:
3635               loop2:
3636               for (i=0; i<N; i++)
3637                  a[i] = i;
3638
3639            However, the following loop *is* vectorizable:
3640               loop3:
3641               for (i=0; i<N; i++)
3642                  a[i] = b[i];
3643
3644            In both loops there exists a def-use cycle for the variable i:
3645               loop: i_2 = PHI (i_0, i_1)
3646                     a[i_2] = ...;
3647                     i_1 = i_2 + 1;
3648                     GOTO loop;
3649
3650            The evolution of the above cycle is considered simple enough,
3651            however, we also check that the cycle does not need to be
3652            vectorized, i.e - we check that the variable that this cycle
3653            defines is only used for array indexing or in stmts that do not
3654            need to be vectorized. This is not the case in loop2, but it
3655            *is* the case in loop3.  */
3656
3657 static bool
3658 vect_analyze_scalar_cycles (loop_vec_info loop_vinfo)
3659 {
3660   tree phi;
3661   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
3662   basic_block bb = loop->header;
3663   tree dummy;
3664
3665   if (vect_debug_details (NULL))
3666     fprintf (dump_file, "\n<<vect_analyze_scalar_cycles>>\n");
3667
3668   for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
3669     {
3670       tree access_fn = NULL;
3671
3672       if (vect_debug_details (NULL))
3673         {
3674           fprintf (dump_file, "Analyze phi: ");
3675           print_generic_expr (dump_file, phi, TDF_SLIM);
3676         }
3677
3678       /* Skip virtual phi's. The data dependences that are associated with
3679          virtual defs/uses (i.e., memory accesses) are analyzed elsewhere.  */
3680
3681       if (!is_gimple_reg (SSA_NAME_VAR (PHI_RESULT (phi))))
3682         {
3683           if (vect_debug_details (NULL))
3684             fprintf (dump_file, "virtual phi. skip.");
3685           continue;
3686         }
3687
3688       /* Analyze the evolution function.  */
3689
3690       /* FORNOW: The only scalar cross-iteration cycles that we allow are
3691          those of loop induction variables; This property is verified here.
3692
3693          Furthermore, if that induction variable is used in an operation
3694          that needs to be vectorized (i.e, is not solely used to index
3695          arrays and check the exit condition) - we do not support its
3696          vectorization yet. This property is verified in vect_is_simple_use,
3697          during vect_analyze_operations.  */
3698
3699       access_fn = /* instantiate_parameters
3700                      (loop,*/
3701          analyze_scalar_evolution (loop, PHI_RESULT (phi));
3702
3703       if (!access_fn)
3704         {
3705           if (vect_debug_stats (loop) || vect_debug_details (loop))
3706             fprintf (dump_file, "not vectorized: unsupported scalar cycle.");
3707           return false;
3708         }
3709
3710       if (vect_debug_details (NULL))
3711         {
3712            fprintf (dump_file, "Access function of PHI: ");
3713            print_generic_expr (dump_file, access_fn, TDF_SLIM);
3714         }
3715
3716       if (!vect_is_simple_iv_evolution (loop->num, access_fn, &dummy, 
3717                                         &dummy, false))
3718         {
3719           if (vect_debug_stats (loop) || vect_debug_details (loop))
3720             fprintf (dump_file, "not vectorized: unsupported scalar cycle.");
3721           return false;
3722         }
3723     }
3724
3725   return true;
3726 }
3727
3728
3729 /* Function vect_analyze_data_ref_dependence.
3730
3731    Return TRUE if there (might) exist a dependence between a memory-reference
3732    DRA and a memory-reference DRB.  */
3733
3734 static bool
3735 vect_analyze_data_ref_dependence (struct data_reference *dra,
3736                                   struct data_reference *drb, 
3737                                   struct loop *loop)
3738 {
3739   bool differ_p; 
3740   struct data_dependence_relation *ddr;
3741   
3742   if (!array_base_name_differ_p (dra, drb, &differ_p))
3743     {
3744       if (vect_debug_stats (loop) || vect_debug_details (loop))   
3745         {
3746           fprintf (dump_file,
3747                 "not vectorized: can't determine dependence between: ");
3748           print_generic_expr (dump_file, DR_REF (dra), TDF_SLIM);
3749           fprintf (dump_file, " and ");
3750           print_generic_expr (dump_file, DR_REF (drb), TDF_SLIM);
3751         }
3752       return true;
3753     }
3754
3755   if (differ_p)
3756     return false;
3757
3758   ddr = initialize_data_dependence_relation (dra, drb);
3759   compute_affine_dependence (ddr);
3760
3761   if (DDR_ARE_DEPENDENT (ddr) == chrec_known)
3762     return false;
3763   
3764   if (vect_debug_stats (loop) || vect_debug_details (loop))
3765     {
3766       fprintf (dump_file,
3767         "not vectorized: possible dependence between data-refs ");
3768       print_generic_expr (dump_file, DR_REF (dra), TDF_SLIM);
3769       fprintf (dump_file, " and ");
3770       print_generic_expr (dump_file, DR_REF (drb), TDF_SLIM);
3771     }
3772
3773   return true;
3774 }
3775
3776
3777 /* Function vect_analyze_data_ref_dependences.
3778
3779    Examine all the data references in the loop, and make sure there do not
3780    exist any data dependences between them.
3781
3782    TODO: dependences which distance is greater than the vectorization factor
3783          can be ignored.  */
3784
3785 static bool
3786 vect_analyze_data_ref_dependences (loop_vec_info loop_vinfo)
3787 {
3788   unsigned int i, j;
3789   varray_type loop_write_refs = LOOP_VINFO_DATAREF_WRITES (loop_vinfo);
3790   varray_type loop_read_refs = LOOP_VINFO_DATAREF_READS (loop_vinfo);
3791   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
3792
3793   /* Examine store-store (output) dependences.  */
3794
3795   if (vect_debug_details (NULL))
3796     fprintf (dump_file, "\n<<vect_analyze_dependences>>\n");
3797
3798   if (vect_debug_details (NULL))
3799     fprintf (dump_file, "compare all store-store pairs.");
3800
3801   for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_write_refs); i++)
3802     {
3803       for (j = i + 1; j < VARRAY_ACTIVE_SIZE (loop_write_refs); j++)
3804         {
3805           struct data_reference *dra =
3806             VARRAY_GENERIC_PTR (loop_write_refs, i);
3807           struct data_reference *drb =
3808             VARRAY_GENERIC_PTR (loop_write_refs, j);
3809           if (vect_analyze_data_ref_dependence (dra, drb, loop))
3810             return false;
3811         }
3812     }
3813
3814   /* Examine load-store (true/anti) dependences.  */
3815
3816   if (vect_debug_details (NULL))
3817     fprintf (dump_file, "compare all load-store pairs.");
3818
3819   for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_read_refs); i++)
3820     {
3821       for (j = 0; j < VARRAY_ACTIVE_SIZE (loop_write_refs); j++)
3822         {
3823           struct data_reference *dra = VARRAY_GENERIC_PTR (loop_read_refs, i);
3824           struct data_reference *drb =
3825             VARRAY_GENERIC_PTR (loop_write_refs, j);
3826           if (vect_analyze_data_ref_dependence (dra, drb, loop))
3827             return false;
3828         }
3829     }
3830
3831   return true;
3832 }
3833
3834
3835 /* Function vect_get_first_index.
3836
3837    REF is a data reference.  
3838    If it is an ARRAY_REF: if its lower bound is simple enough, 
3839    put it in ARRAY_FIRST_INDEX and return TRUE; otherwise - return FALSE.
3840    If it is not an ARRAY_REF: REF has no "first index";
3841    ARRAY_FIRST_INDEX in zero, and the function returns TRUE.  */
3842
3843 static bool
3844 vect_get_first_index (tree ref, tree *array_first_index)
3845 {
3846   tree array_start;
3847
3848   if (TREE_CODE (ref) != ARRAY_REF)
3849     *array_first_index = size_zero_node;
3850   else
3851     {
3852       array_start = array_ref_low_bound (ref);
3853       if (!host_integerp (array_start,0))
3854         {
3855           if (vect_debug_details (NULL))
3856             {
3857               fprintf (dump_file, "array min val not simple integer cst.");
3858               print_generic_expr (dump_file, array_start, TDF_DETAILS);
3859             }
3860           return false;
3861         }
3862       *array_first_index = array_start;
3863     }
3864
3865   return true;
3866 }
3867
3868
3869 /* Function vect_compute_array_base_alignment.
3870    A utility function of vect_compute_array_ref_alignment.
3871
3872    Compute the misalignment of ARRAY in bits.
3873
3874    Input:
3875    ARRAY - an array_ref (possibly multidimensional) of type ARRAY_TYPE.
3876    VECTYPE - we are interested in the misalignment modulo the size of vectype.
3877              if NULL: don't compute misalignment, just return the base of ARRAY.
3878    PREV_DIMENSIONS - initialized to one.
3879    MISALIGNMENT - the computed misalignment in bits.
3880
3881    Output:
3882    If VECTYPE is not NULL:
3883      Return NULL_TREE if the misalignment cannot be computed. Otherwise, return 
3884      the base of the array, and put the computed misalignment in MISALIGNMENT. 
3885    If VECTYPE is NULL:
3886      Return the base of the array.
3887
3888    For a[idx_N]...[idx_2][idx_1][idx_0], the address of 
3889    a[idx_N]...[idx_2][idx_1] is 
3890    {&a + idx_1 * dim_0 + idx_2 * dim_0 * dim_1 + ...  
3891     ... + idx_N * dim_0 * ... * dim_N-1}. 
3892    (The misalignment of &a is not checked here).
3893    Note, that every term contains dim_0, therefore, if dim_0 is a 
3894    multiple of NUNITS, the whole sum is a multiple of NUNITS.
3895    Otherwise, if idx_1 is constant, and dim_1 is a multiple of
3896    NUINTS, we can say that the misalignment of the sum is equal to
3897    the misalignment of {idx_1 * dim_0}.  If idx_1 is not constant,
3898    we can't determine this array misalignment, and we return
3899    false. 
3900    We proceed recursively in this manner, accumulating total misalignment
3901    and the multiplication of previous dimensions for correct misalignment
3902    calculation.  */
3903
3904 static tree
3905 vect_compute_array_base_alignment (tree array,
3906                                    tree vectype,
3907                                    tree *prev_dimensions,
3908                                    tree *misalignment)
3909 {
3910   tree index;
3911   tree domain;
3912   tree dimension_size;
3913   tree mis;
3914   tree bits_per_vectype;
3915   tree bits_per_vectype_unit;
3916
3917   /* The 'stop condition' of the recursion.  */
3918   if (TREE_CODE (array) != ARRAY_REF)
3919     return array;
3920   
3921   if (!vectype)
3922     /* Just get the base decl.  */
3923     return vect_compute_array_base_alignment 
3924                 (TREE_OPERAND (array, 0), NULL, NULL, NULL);
3925
3926   if (!host_integerp (*misalignment, 1) || TREE_OVERFLOW (*misalignment) || 
3927       !host_integerp (*prev_dimensions, 1) || TREE_OVERFLOW (*prev_dimensions))
3928     return NULL_TREE;
3929
3930   domain = TYPE_DOMAIN (TREE_TYPE (array));
3931   dimension_size = 
3932         int_const_binop (PLUS_EXPR,
3933                 int_const_binop (MINUS_EXPR, TYPE_MAX_VALUE (domain), 
3934                                              TYPE_MIN_VALUE (domain), 1),
3935                 size_one_node, 1);
3936
3937   /* Check if the dimension size is a multiple of NUNITS, the remaining sum
3938      is a multiple of NUNITS: 
3939
3940      dimension_size % GET_MODE_NUNITS (TYPE_MODE (vectype)) == 0 ?
3941    */
3942   mis = int_const_binop (TRUNC_MOD_EXPR, dimension_size,
3943          build_int_cst (NULL_TREE, GET_MODE_NUNITS (TYPE_MODE (vectype))), 1);
3944   if (integer_zerop (mis))
3945     /* This array is aligned. Continue just in order to get the base decl.  */
3946     return vect_compute_array_base_alignment 
3947                 (TREE_OPERAND (array, 0), NULL, NULL, NULL);
3948
3949   index = TREE_OPERAND (array, 1);
3950   if (!host_integerp (index, 1))
3951     /* The current index is not constant.  */
3952     return NULL_TREE;
3953    
3954   index = int_const_binop (MINUS_EXPR, index, TYPE_MIN_VALUE (domain), 0);
3955
3956   bits_per_vectype = fold_convert (unsigned_type_node, 
3957     build_int_cst (NULL_TREE, BITS_PER_UNIT * 
3958                  GET_MODE_SIZE (TYPE_MODE (vectype))));
3959   bits_per_vectype_unit =  fold_convert (unsigned_type_node,
3960     build_int_cst (NULL_TREE, BITS_PER_UNIT * 
3961                  GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (vectype)))));
3962   
3963   /* Add {idx_i * dim_i-1 * ... * dim_0 } to the misalignment computed
3964      earlier:
3965
3966      *misalignment = 
3967        (*misalignment + index_val * dimension_size * *prev_dimensions) 
3968                                                         % vectype_nunits;
3969    */
3970
3971   mis = int_const_binop (MULT_EXPR, index, dimension_size, 1);
3972   mis = int_const_binop (MULT_EXPR, mis, *prev_dimensions, 1);
3973   mis = int_const_binop (MULT_EXPR, mis, bits_per_vectype_unit, 1);
3974   mis = int_const_binop (PLUS_EXPR, *misalignment, mis, 1);
3975   *misalignment = int_const_binop (TRUNC_MOD_EXPR, mis, bits_per_vectype, 1);
3976
3977
3978   *prev_dimensions = int_const_binop (MULT_EXPR, 
3979                                 *prev_dimensions, dimension_size, 1);
3980
3981   return vect_compute_array_base_alignment (TREE_OPERAND (array, 0), vectype,
3982                                             prev_dimensions,
3983                                             misalignment);
3984 }
3985
3986  
3987 /* Function vect_compute_data_ref_alignment
3988
3989    Compute the misalignment of the data reference DR.
3990
3991    Output:
3992    1. If during the misalignment computation it is found that the data reference
3993       cannot be vectorized then false is returned.
3994    2. DR_MISALIGNMENT (DR) is defined.
3995
3996    FOR NOW: No analysis is actually performed. Misalignment is calculated
3997    only for trivial cases. TODO.  */
3998
3999 static bool
4000 vect_compute_data_ref_alignment (struct data_reference *dr, 
4001                                  loop_vec_info loop_vinfo)
4002 {
4003   tree stmt = DR_STMT (dr);
4004   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);  
4005   tree ref = DR_REF (dr);
4006   tree vectype;
4007   tree scalar_type;
4008   tree offset = size_zero_node;
4009   tree base, bit_offset, alignment;
4010   tree unit_bits = fold_convert (unsigned_type_node, 
4011                                  build_int_cst (NULL_TREE, BITS_PER_UNIT));
4012   tree dr_base;
4013   bool base_aligned_p;
4014    
4015   if (vect_debug_details (NULL))
4016     fprintf (dump_file, "vect_compute_data_ref_alignment:");
4017
4018   /* Initialize misalignment to unknown.  */
4019   DR_MISALIGNMENT (dr) = -1;
4020
4021   scalar_type = TREE_TYPE (ref);
4022   vectype = get_vectype_for_scalar_type (scalar_type);
4023   if (!vectype)
4024     {
4025       if (vect_debug_details (NULL))
4026         {
4027           fprintf (dump_file, "no vectype for stmt: ");
4028           print_generic_expr (dump_file, stmt, TDF_SLIM);
4029           fprintf (dump_file, " scalar_type: ");
4030           print_generic_expr (dump_file, scalar_type, TDF_DETAILS);
4031         }
4032       /* It is not possible to vectorize this data reference.  */
4033       return false;
4034     }
4035   STMT_VINFO_VECTYPE (stmt_info) = vectype;
4036   gcc_assert (TREE_CODE (ref) == ARRAY_REF || TREE_CODE (ref) == INDIRECT_REF);
4037   
4038   if (TREE_CODE (ref) == ARRAY_REF)
4039     dr_base = ref;
4040   else
4041     dr_base = STMT_VINFO_VECT_DR_BASE (stmt_info);
4042
4043   base = vect_get_base_and_bit_offset (dr, dr_base, vectype, 
4044                           loop_vinfo, &bit_offset, &base_aligned_p);
4045   if (!base)
4046     {
4047       if (vect_debug_details (NULL)) 
4048         {
4049           fprintf (dump_file, "Unknown alignment for access: ");
4050           print_generic_expr (dump_file, 
4051                               STMT_VINFO_VECT_DR_BASE (stmt_info), TDF_SLIM);
4052         }
4053       return true;
4054     }
4055
4056   if (!base_aligned_p) 
4057     {
4058       if (!vect_can_force_dr_alignment_p (base, TYPE_ALIGN (vectype)))
4059         {
4060           if (vect_debug_details (NULL))
4061             {
4062               fprintf (dump_file, "can't force alignment of ref: ");
4063               print_generic_expr (dump_file, ref, TDF_SLIM);
4064             }
4065           return true;
4066         }
4067       
4068       /* Force the alignment of the decl.
4069          NOTE: This is the only change to the code we make during
4070          the analysis phase, before deciding to vectorize the loop.  */
4071       if (vect_debug_details (NULL))
4072         fprintf (dump_file, "force alignment");
4073       DECL_ALIGN (base) = TYPE_ALIGN (vectype);
4074       DECL_USER_ALIGN (base) = TYPE_ALIGN (vectype);
4075     }
4076
4077   /* At this point we assume that the base is aligned, and the offset from it
4078      (including index, if relevant) has been computed and is in BIT_OFFSET.  */
4079   gcc_assert (base_aligned_p 
4080               || (TREE_CODE (base) == VAR_DECL 
4081                   && DECL_ALIGN (base) >= TYPE_ALIGN (vectype)));
4082
4083   /* Convert into bytes.  */
4084   offset = int_const_binop (TRUNC_DIV_EXPR, bit_offset, unit_bits, 1);
4085   /* Check that there is no remainder in bits.  */
4086   bit_offset = int_const_binop (TRUNC_MOD_EXPR, bit_offset, unit_bits, 1);
4087   if (!integer_zerop (bit_offset))
4088     {
4089       if (vect_debug_details (NULL))
4090         {
4091           fprintf (dump_file, "bit offset alignment: ");
4092           print_generic_expr (dump_file, bit_offset, TDF_SLIM);
4093         }
4094       return false;
4095     }
4096   
4097   /* Alignment required, in bytes:  */
4098   alignment = fold_convert (unsigned_type_node,
4099             build_int_cst (NULL_TREE, TYPE_ALIGN (vectype)/BITS_PER_UNIT));
4100
4101   /* Modulo alignment.  */
4102   offset = int_const_binop (TRUNC_MOD_EXPR, offset, alignment, 0);
4103   if (!host_integerp (offset, 1) || TREE_OVERFLOW (offset))
4104     {
4105       if (vect_debug_details (NULL))
4106         fprintf (dump_file, "unexpected misalign value");
4107       return false;
4108     }
4109
4110   DR_MISALIGNMENT (dr) = tree_low_cst (offset, 1);
4111
4112   if (vect_debug_details (NULL))
4113     fprintf (dump_file, "misalign = %d", DR_MISALIGNMENT (dr));
4114
4115   return true;
4116 }
4117
4118
4119 /* Function vect_compute_array_ref_alignment
4120
4121    Compute the alignment of an array-ref.
4122    The alignment we compute here is relative to 
4123    TYPE_ALIGN(VECTYPE) boundary.  
4124
4125    Output:
4126    OFFSET - the alignment in bits
4127    Return value - the base of the array-ref. E.g, 
4128                   if the array-ref is a.b[k].c[i][j] the returned
4129                   base is a.b[k].c
4130 */
4131
4132 static tree
4133 vect_compute_array_ref_alignment (struct data_reference *dr,
4134                                   loop_vec_info loop_vinfo,
4135                                   tree vectype,
4136                                   tree *offset)
4137 {
4138   tree array_first_index = size_zero_node;
4139   tree init;
4140   tree ref = DR_REF (dr);
4141   tree scalar_type = TREE_TYPE (ref);
4142   tree oprnd0 = TREE_OPERAND (ref, 0);
4143   tree dims = size_one_node;  
4144   tree misalign = size_zero_node;
4145   tree next_ref, this_offset = size_zero_node;
4146   tree nunits;
4147   tree nbits;
4148
4149   if (TREE_CODE (TREE_TYPE (ref)) == ARRAY_TYPE)
4150     /* The reference is an array without its last index.  */
4151     next_ref = vect_compute_array_base_alignment (ref, vectype, &dims, 
4152                                                   &misalign);
4153   else
4154     next_ref = vect_compute_array_base_alignment (oprnd0, vectype, &dims, 
4155                                                   &misalign);
4156   if (!vectype)
4157     /* Alignment is not requested. Just return the base.  */
4158     return next_ref;
4159
4160   /* Compute alignment.  */
4161   if (!host_integerp (misalign, 1) || TREE_OVERFLOW (misalign) || !next_ref)
4162     return NULL_TREE;
4163   this_offset = misalign;
4164
4165   /* Check the first index accessed.  */
4166   if (!vect_get_first_index (ref, &array_first_index))
4167     {
4168       if (vect_debug_details (NULL))
4169         fprintf (dump_file, "no first_index for array.");
4170       return NULL_TREE;
4171     }
4172
4173   /* Check the index of the array_ref.  */
4174   init = initial_condition_in_loop_num (DR_ACCESS_FN (dr, 0), 
4175                                         LOOP_VINFO_LOOP (loop_vinfo)->num);
4176
4177   /* FORNOW: In order to simplify the handling of alignment, we make sure
4178      that the first location at which the array is accessed ('init') is on an
4179      'NUNITS' boundary, since we are assuming here that 'array base' is aligned. 
4180      This is too conservative, since we require that
4181      both {'array_base' is a multiple of NUNITS} && {'init' is a multiple of
4182      NUNITS}, instead of just {('array_base' + 'init') is a multiple of NUNITS}.
4183      This should be relaxed in the future.  */
4184
4185   if (!init || !host_integerp (init, 0))
4186     {
4187       if (vect_debug_details (NULL))
4188         fprintf (dump_file, "non constant init. ");
4189       return NULL_TREE;
4190     }
4191
4192   /* bytes per scalar element: */
4193   nunits = fold_convert (unsigned_type_node,
4194         build_int_cst (NULL_TREE, GET_MODE_SIZE (TYPE_MODE (scalar_type))));
4195   nbits = int_const_binop (MULT_EXPR, nunits,     
4196                            build_int_cst (NULL_TREE, BITS_PER_UNIT), 1);
4197
4198   /* misalign = offset + (init-array_first_index)*nunits*bits_in_byte */
4199   misalign = int_const_binop (MINUS_EXPR, init, array_first_index, 0);
4200   misalign = int_const_binop (MULT_EXPR, misalign, nbits, 0);
4201   misalign = int_const_binop (PLUS_EXPR, misalign, this_offset, 0);
4202
4203   /* TODO: allow negative misalign values.  */
4204   if (!host_integerp (misalign, 1) || TREE_OVERFLOW (misalign))
4205     {
4206       if (vect_debug_details (NULL))
4207         fprintf (dump_file, "unexpected misalign value");
4208       return NULL_TREE;
4209     }
4210   *offset = misalign;
4211   return next_ref;
4212 }
4213
4214
4215 /* Function vect_compute_data_refs_alignment
4216
4217    Compute the misalignment of data references in the loop.
4218    This pass may take place at function granularity instead of at loop
4219    granularity.
4220
4221    FOR NOW: No analysis is actually performed. Misalignment is calculated
4222    only for trivial cases. TODO.  */
4223
4224 static bool
4225 vect_compute_data_refs_alignment (loop_vec_info loop_vinfo)
4226 {
4227   varray_type loop_write_datarefs = LOOP_VINFO_DATAREF_WRITES (loop_vinfo);
4228   varray_type loop_read_datarefs = LOOP_VINFO_DATAREF_READS (loop_vinfo);
4229   unsigned int i;
4230
4231   for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_write_datarefs); i++)
4232     {
4233       struct data_reference *dr = VARRAY_GENERIC_PTR (loop_write_datarefs, i);
4234       if (!vect_compute_data_ref_alignment (dr, loop_vinfo))
4235         return false;
4236     }
4237
4238   for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_read_datarefs); i++)
4239     {
4240       struct data_reference *dr = VARRAY_GENERIC_PTR (loop_read_datarefs, i);
4241       if (!vect_compute_data_ref_alignment (dr, loop_vinfo))
4242         return false;
4243     }
4244
4245   return true;
4246 }
4247
4248
4249 /* Function vect_enhance_data_refs_alignment
4250
4251    This pass will use loop versioning and loop peeling in order to enhance
4252    the alignment of data references in the loop.
4253
4254    FOR NOW: we assume that whatever versioning/peeling takes place, only the
4255    original loop is to be vectorized; Any other loops that are created by
4256    the transformations performed in this pass - are not supposed to be
4257    vectorized. This restriction will be relaxed.  */
4258
4259 static void
4260 vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
4261 {
4262   varray_type loop_read_datarefs = LOOP_VINFO_DATAREF_READS (loop_vinfo);
4263   varray_type loop_write_datarefs = LOOP_VINFO_DATAREF_WRITES (loop_vinfo);
4264   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
4265   unsigned int i;
4266
4267   /*
4268      This pass will require a cost model to guide it whether to apply peeling 
4269      or versioning or a combination of the two. For example, the scheme that
4270      intel uses when given a loop with several memory accesses, is as follows:
4271      choose one memory access ('p') which alignment you want to force by doing 
4272      peeling. Then, either (1) generate a loop in which 'p' is aligned and all 
4273      other accesses are not necessarily aligned, or (2) use loop versioning to 
4274      generate one loop in which all accesses are aligned, and another loop in 
4275      which only 'p' is necessarily aligned. 
4276
4277      ("Automatic Intra-Register Vectorization for the Intel Architecture",
4278       Aart J.C. Bik, Milind Girkar, Paul M. Grey and Ximmin Tian, International
4279       Journal of Parallel Programming, Vol. 30, No. 2, April 2002.)     
4280
4281      Devising a cost model is the most critical aspect of this work. It will 
4282      guide us on which access to peel for, whether to use loop versioning, how 
4283      many versions to create, etc. The cost model will probably consist of 
4284      generic considerations as well as target specific considerations (on 
4285      powerpc for example, misaligned stores are more painful than misaligned 
4286      loads). 
4287
4288      Here is the general steps involved in alignment enhancements:
4289     
4290      -- original loop, before alignment analysis:
4291         for (i=0; i<N; i++){
4292           x = q[i];                     # DR_MISALIGNMENT(q) = unknown
4293           p[i] = y;                     # DR_MISALIGNMENT(p) = unknown
4294         }
4295
4296      -- After vect_compute_data_refs_alignment:
4297         for (i=0; i<N; i++){
4298           x = q[i];                     # DR_MISALIGNMENT(q) = 3
4299           p[i] = y;                     # DR_MISALIGNMENT(p) = unknown
4300         }
4301
4302      -- Possibility 1: we do loop versioning:
4303      if (p is aligned) {
4304         for (i=0; i<N; i++){    # loop 1A
4305           x = q[i];                     # DR_MISALIGNMENT(q) = 3
4306           p[i] = y;                     # DR_MISALIGNMENT(p) = 0
4307         }
4308      } 
4309      else {
4310         for (i=0; i<N; i++){    # loop 1B
4311           x = q[i];                     # DR_MISALIGNMENT(q) = 3
4312           p[i] = y;                     # DR_MISALIGNMENT(p) = unaligned
4313         }
4314      }
4315    
4316      -- Possibility 2: we do loop peeling:
4317      for (i = 0; i < 3; i++){   # (scalar loop, not to be vectorized).
4318         x = q[i];
4319         p[i] = y;
4320      }
4321      for (i = 3; i < N; i++){   # loop 2A
4322         x = q[i];                       # DR_MISALIGNMENT(q) = 0
4323         p[i] = y;                       # DR_MISALIGNMENT(p) = unknown
4324      }
4325
4326      -- Possibility 3: combination of loop peeling and versioning:
4327      for (i = 0; i < 3; i++){   # (scalar loop, not to be vectorized).
4328         x = q[i];
4329         p[i] = y;
4330      }
4331      if (p is aligned) {
4332         for (i = 3; i<N; i++){  # loop 3A
4333           x = q[i];                     # DR_MISALIGNMENT(q) = 0
4334           p[i] = y;                     # DR_MISALIGNMENT(p) = 0
4335         }
4336      } 
4337      else {
4338         for (i = 3; i<N; i++){  # loop 3B
4339           x = q[i];                     # DR_MISALIGNMENT(q) = 0
4340           p[i] = y;                     # DR_MISALIGNMENT(p) = unaligned
4341         }
4342      }
4343
4344      These loops are later passed to loop_transform to be vectorized. The 
4345      vectorizer will use the alignment information to guide the transformation 
4346      (whether to generate regular loads/stores, or with special handling for 
4347      misalignment). 
4348    */
4349
4350   /* (1) Peeling to force alignment.  */
4351
4352   /* (1.1) Decide whether to perform peeling, and how many iterations to peel:
4353      Considerations:
4354      + How many accesses will become aligned due to the peeling
4355      - How many accesses will become unaligned due to the peeling,
4356        and the cost of misaligned accesses.
4357      - The cost of peeling (the extra runtime checks, the increase 
4358        in code size).
4359
4360      The scheme we use FORNOW: peel to force the alignment of the first
4361      misaligned store in the loop.
4362      Rationale: misaligned stores are not yet supported.
4363
4364      TODO: Use a better cost model.  */
4365
4366   for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_write_datarefs); i++)
4367     {
4368       struct data_reference *dr = VARRAY_GENERIC_PTR (loop_write_datarefs, i);
4369       if (!aligned_access_p (dr))
4370         {
4371           LOOP_VINFO_UNALIGNED_DR (loop_vinfo) = dr;
4372           LOOP_DO_PEELING_FOR_ALIGNMENT (loop_vinfo) = true;
4373           break;
4374         }
4375     }
4376
4377   if (!LOOP_VINFO_UNALIGNED_DR (loop_vinfo))
4378     {
4379       if (vect_debug_details (loop))
4380         fprintf (dump_file, "Peeling for alignment will not be applied.");
4381       return;
4382     }
4383   else
4384     if (vect_debug_details (loop))
4385       fprintf (dump_file, "Peeling for alignment will be applied.");
4386
4387
4388   /* (1.2) Update the alignment info according to the peeling factor.
4389            If the misalignment of the DR we peel for is M, then the
4390            peeling factor is VF - M, and the misalignment of each access DR_i
4391            in the loop is DR_MISALIGNMENT (DR_i) + VF - M.
4392            If the misalignment of the DR we peel for is unknown, then the 
4393            misalignment of each access DR_i in the loop is also unknown.
4394
4395            FORNOW: set the misalignment of the accesses to unknown even
4396                    if the peeling factor is known at compile time.
4397
4398            TODO: - if the peeling factor is known at compile time, use that
4399                    when updating the misalignment info of the loop DRs.
4400                  - consider accesses that are known to have the same 
4401                    alignment, even if that alignment is unknown.  */
4402    
4403   for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_write_datarefs); i++)
4404     {
4405       struct data_reference *dr = VARRAY_GENERIC_PTR (loop_write_datarefs, i);
4406       if (dr == LOOP_VINFO_UNALIGNED_DR (loop_vinfo))
4407         DR_MISALIGNMENT (dr) = 0;
4408       else
4409         DR_MISALIGNMENT (dr) = -1;
4410     }
4411   for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_read_datarefs); i++)
4412     {
4413       struct data_reference *dr = VARRAY_GENERIC_PTR (loop_read_datarefs, i);
4414       if (dr == LOOP_VINFO_UNALIGNED_DR (loop_vinfo))
4415         DR_MISALIGNMENT (dr) = 0;
4416       else
4417         DR_MISALIGNMENT (dr) = -1;
4418     }
4419 }
4420
4421
4422 /* Function vect_analyze_data_refs_alignment
4423
4424    Analyze the alignment of the data-references in the loop.
4425    FOR NOW: Until support for misliagned accesses is in place, only if all
4426    accesses are aligned can the loop be vectorized. This restriction will be 
4427    relaxed.  */ 
4428
4429 static bool
4430 vect_analyze_data_refs_alignment (loop_vec_info loop_vinfo)
4431 {
4432   varray_type loop_read_datarefs = LOOP_VINFO_DATAREF_READS (loop_vinfo);
4433   varray_type loop_write_datarefs = LOOP_VINFO_DATAREF_WRITES (loop_vinfo);
4434   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
4435   enum dr_alignment_support supportable_dr_alignment;
4436   unsigned int i;
4437
4438   if (vect_debug_details (NULL))
4439     fprintf (dump_file, "\n<<vect_analyze_data_refs_alignment>>\n");
4440
4441
4442   /* This pass may take place at function granularity instead of at loop
4443      granularity.  */
4444
4445   if (!vect_compute_data_refs_alignment (loop_vinfo))
4446     {
4447       if (vect_debug_details (loop) || vect_debug_stats (loop))
4448         fprintf (dump_file, 
4449                  "not vectorized: can't calculate alignment for data ref.");
4450       return false;
4451     }
4452
4453
4454   /* This pass will decide on using loop versioning and/or loop peeling in 
4455      order to enhance the alignment of data references in the loop.  */
4456
4457   vect_enhance_data_refs_alignment (loop_vinfo);
4458
4459
4460   /* Finally, check that all the data references in the loop can be
4461      handled with respect to their alignment.  */
4462
4463   for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_read_datarefs); i++)
4464     {
4465       struct data_reference *dr = VARRAY_GENERIC_PTR (loop_read_datarefs, i);
4466       supportable_dr_alignment = vect_supportable_dr_alignment (dr);
4467       if (!supportable_dr_alignment)
4468         {
4469           if (vect_debug_details (loop) || vect_debug_stats (loop))
4470             fprintf (dump_file, "not vectorized: unsupported unaligned load.");
4471           return false;
4472         }
4473     }
4474   for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_write_datarefs); i++)
4475     {
4476       struct data_reference *dr = VARRAY_GENERIC_PTR (loop_write_datarefs, i);
4477       supportable_dr_alignment = vect_supportable_dr_alignment (dr);
4478       if (!supportable_dr_alignment)
4479         {
4480           if (vect_debug_details (loop) || vect_debug_stats (loop))
4481             fprintf (dump_file, "not vectorized: unsupported unaligned store.");
4482           return false;
4483         }
4484     }
4485
4486   return true;
4487 }
4488
4489
4490 /* Function vect_analyze_data_ref_access.
4491
4492    Analyze the access pattern of the data-reference DR. For now, a data access
4493    has to consecutive and aligned to be considered vectorizable.  */
4494
4495 static bool
4496 vect_analyze_data_ref_access (struct data_reference *dr)
4497 {
4498   varray_type access_fns = DR_ACCESS_FNS (dr);
4499   tree access_fn;
4500   tree init, step;
4501   unsigned int dimensions, i;
4502
4503   /* Check that in case of multidimensional array ref A[i1][i2]..[iN],
4504      i1, i2, ..., iN-1 are loop invariant (to make sure that the memory
4505      access is contiguous).  */
4506   dimensions = VARRAY_ACTIVE_SIZE (access_fns);
4507
4508   for (i = 1; i < dimensions; i++) /* Not including the last dimension.  */
4509     {
4510       access_fn = DR_ACCESS_FN (dr, i);
4511
4512       if (evolution_part_in_loop_num (access_fn, 
4513                                       loop_containing_stmt (DR_STMT (dr))->num))
4514         {
4515           /* Evolution part is not NULL in this loop (it is neither constant 
4516              nor invariant).  */
4517           if (vect_debug_details (NULL))
4518             {
4519               fprintf (dump_file, 
4520                        "not vectorized: complicated multidim. array access.");
4521               print_generic_expr (dump_file, access_fn, TDF_SLIM);
4522             }
4523           return false;
4524         }
4525     }
4526   
4527   access_fn = DR_ACCESS_FN (dr, 0); /*  The last dimension access function.  */
4528   if (!evolution_function_is_constant_p (access_fn)
4529       && !vect_is_simple_iv_evolution (loop_containing_stmt (DR_STMT (dr))->num,
4530                                        access_fn, &init, &step, true))
4531     {
4532       if (vect_debug_details (NULL))
4533         {
4534           fprintf (dump_file, "not vectorized: complicated access function.");
4535           print_generic_expr (dump_file, access_fn, TDF_SLIM);
4536         }
4537       return false;
4538     }
4539   
4540   return true;
4541 }
4542
4543
4544 /* Function vect_analyze_data_ref_accesses.
4545
4546    Analyze the access pattern of all the data references in the loop.
4547
4548    FORNOW: the only access pattern that is considered vectorizable is a
4549            simple step 1 (consecutive) access.
4550
4551    FORNOW: handle only arrays and pointer accesses.  */
4552
4553 static bool
4554 vect_analyze_data_ref_accesses (loop_vec_info loop_vinfo)
4555 {
4556   unsigned int i;
4557   varray_type loop_write_datarefs = LOOP_VINFO_DATAREF_WRITES (loop_vinfo);
4558   varray_type loop_read_datarefs = LOOP_VINFO_DATAREF_READS (loop_vinfo);
4559
4560   if (vect_debug_details (NULL))
4561     fprintf (dump_file, "\n<<vect_analyze_data_ref_accesses>>\n");
4562
4563   for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_write_datarefs); i++)
4564     {
4565       struct data_reference *dr = VARRAY_GENERIC_PTR (loop_write_datarefs, i);
4566       bool ok = vect_analyze_data_ref_access (dr);
4567       if (!ok)
4568         {
4569           if (vect_debug_stats (LOOP_VINFO_LOOP (loop_vinfo))
4570               || vect_debug_details (LOOP_VINFO_LOOP (loop_vinfo)))
4571             fprintf (dump_file, "not vectorized: complicated access pattern.");
4572           return false;
4573         }
4574     }
4575
4576   for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_read_datarefs); i++)
4577     {
4578       struct data_reference *dr = VARRAY_GENERIC_PTR (loop_read_datarefs, i);
4579       bool ok = vect_analyze_data_ref_access (dr);
4580       if (!ok)
4581         {
4582           if (vect_debug_stats (LOOP_VINFO_LOOP (loop_vinfo))
4583               || vect_debug_details (LOOP_VINFO_LOOP (loop_vinfo))) 
4584             fprintf (dump_file, "not vectorized: complicated access pattern.");
4585           return false;
4586         }
4587     }
4588
4589   return true;
4590 }
4591
4592
4593 /* Function vect_analyze_pointer_ref_access.
4594
4595    Input:
4596    STMT - a stmt that contains a data-ref
4597    MEMREF - a data-ref in STMT, which is an INDIRECT_REF.
4598
4599    If the data-ref access is vectorizable, return a data_reference structure
4600    that represents it (DR). Otherwise - return NULL.  */
4601
4602 static struct data_reference *
4603 vect_analyze_pointer_ref_access (tree memref, tree stmt, bool is_read)
4604 {
4605   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
4606   struct loop *loop = STMT_VINFO_LOOP (stmt_info);
4607   tree access_fn = analyze_scalar_evolution (loop, TREE_OPERAND (memref, 0));
4608   tree init, step;      
4609   int step_val;
4610   tree reftype, innertype;
4611   enum machine_mode innermode;
4612   tree indx_access_fn; 
4613   int loopnum = loop->num;
4614   struct data_reference *dr;
4615
4616   if (!access_fn)
4617     {
4618       if (vect_debug_stats (loop) || vect_debug_details (loop))
4619         fprintf (dump_file, "not vectorized: complicated pointer access.");     
4620       return NULL;
4621     }
4622
4623   if (vect_debug_details (NULL))
4624     {
4625       fprintf (dump_file, "Access function of ptr: ");
4626       print_generic_expr (dump_file, access_fn, TDF_SLIM);
4627     }
4628
4629   if (!vect_is_simple_iv_evolution (loopnum, access_fn, &init, &step, false))
4630     {
4631       if (vect_debug_stats (loop) || vect_debug_details (loop)) 
4632         fprintf (dump_file, "not vectorized: pointer access is not simple.");   
4633       return NULL;
4634     }
4635                 
4636   STRIP_NOPS (init);
4637
4638   if (!host_integerp (step,0))
4639     {
4640       if (vect_debug_stats (loop) || vect_debug_details (loop)) 
4641         fprintf (dump_file, 
4642                 "not vectorized: non constant step for pointer access.");       
4643       return NULL;
4644     }
4645
4646   step_val = TREE_INT_CST_LOW (step);
4647
4648   reftype = TREE_TYPE (TREE_OPERAND (memref, 0));
4649   if (TREE_CODE (reftype) != POINTER_TYPE) 
4650     {
4651       if (vect_debug_stats (loop) || vect_debug_details (loop))
4652         fprintf (dump_file, "not vectorized: unexpected pointer access form."); 
4653       return NULL;
4654     }
4655
4656   reftype = TREE_TYPE (init);
4657   if (TREE_CODE (reftype) != POINTER_TYPE) 
4658     {
4659       if (vect_debug_stats (loop) || vect_debug_details (loop)) 
4660         fprintf (dump_file, "not vectorized: unexpected pointer access form.");
4661       return NULL;
4662     }
4663
4664   innertype = TREE_TYPE (reftype);
4665   innermode = TYPE_MODE (innertype);
4666   if (GET_MODE_SIZE (innermode) != step_val) 
4667     {
4668       /* FORNOW: support only consecutive access */
4669       if (vect_debug_stats (loop) || vect_debug_details (loop)) 
4670         fprintf (dump_file, "not vectorized: non consecutive access."); 
4671       return NULL;
4672     }
4673
4674   indx_access_fn = 
4675         build_polynomial_chrec (loopnum, integer_zero_node, integer_one_node);
4676   if (vect_debug_details (NULL)) 
4677     {
4678       fprintf (dump_file, "Access function of ptr indx: ");
4679       print_generic_expr (dump_file, indx_access_fn, TDF_SLIM);
4680     }
4681   dr = init_data_ref (stmt, memref, init, indx_access_fn, is_read);
4682   return dr;
4683 }
4684
4685
4686 /* Function vect_get_symbl_and_dr.  
4687
4688    The function returns SYMBL - the relevant variable for
4689    memory tag (for aliasing purposes). 
4690    Also data reference structure DR is created.  
4691
4692    Input:
4693    MEMREF - data reference in STMT
4694    IS_READ - TRUE if STMT reads from MEMREF, FALSE if writes to MEMREF
4695    
4696    Output:
4697    DR - data_reference struct for MEMREF
4698    return value - the relevant variable for memory tag (for aliasing purposes).
4699
4700 */ 
4701
4702 static tree
4703 vect_get_symbl_and_dr (tree memref, tree stmt, bool is_read, 
4704                        loop_vec_info loop_vinfo, struct data_reference **dr)
4705 {
4706   tree symbl, oprnd0, oprnd1;
4707   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
4708   tree offset;
4709   tree array_base, base;
4710   struct data_reference *new_dr;
4711   bool base_aligned_p;
4712
4713   *dr = NULL;
4714   switch (TREE_CODE (memref))
4715     {
4716     case INDIRECT_REF:
4717       new_dr = vect_analyze_pointer_ref_access (memref, stmt, is_read);
4718       if (! new_dr)
4719         return NULL_TREE; 
4720       *dr = new_dr;
4721       symbl = DR_BASE_NAME (new_dr);
4722       STMT_VINFO_VECT_DR_BASE (stmt_info) = symbl;
4723
4724       switch (TREE_CODE (symbl))
4725         {
4726         case PLUS_EXPR:
4727         case MINUS_EXPR:
4728           oprnd0 = TREE_OPERAND (symbl, 0);
4729           oprnd1 = TREE_OPERAND (symbl, 1);
4730
4731           STRIP_NOPS(oprnd1);
4732           /* Only {address_base + offset} expressions are supported,  
4733              where address_base can be POINTER_TYPE or ARRAY_TYPE and 
4734              offset can be anything but POINTER_TYPE or ARRAY_TYPE.  
4735              TODO: swap operands if {offset + address_base}.  */
4736           if ((TREE_CODE (TREE_TYPE (oprnd1)) == POINTER_TYPE 
4737                && TREE_CODE (oprnd1) != INTEGER_CST)
4738               || TREE_CODE (TREE_TYPE (oprnd1)) == ARRAY_TYPE)
4739             return NULL_TREE;
4740
4741           if (TREE_CODE (TREE_TYPE (oprnd0)) == POINTER_TYPE)
4742             symbl = oprnd0;
4743           else
4744             symbl = vect_get_symbl_and_dr (oprnd0, stmt, is_read, 
4745                                            loop_vinfo, &new_dr); 
4746
4747         case SSA_NAME:
4748         case ADDR_EXPR:
4749           /* symbl remains unchanged.  */
4750           break;
4751
4752         default:
4753           if (vect_debug_details (NULL))
4754             {
4755               fprintf (dump_file, "unhandled data ref: ");
4756               print_generic_expr (dump_file, memref, TDF_SLIM);
4757               fprintf (dump_file, " (symbl ");
4758               print_generic_expr (dump_file, symbl, TDF_SLIM);
4759               fprintf (dump_file, ") in stmt  ");
4760               print_generic_expr (dump_file, stmt, TDF_SLIM);
4761             }
4762           return NULL_TREE;     
4763         }
4764       break;
4765
4766     case ARRAY_REF:
4767       offset = size_zero_node;
4768
4769       /* Store the array base in the stmt info. 
4770          For one dimensional array ref a[i], the base is a,
4771          for multidimensional a[i1][i2]..[iN], the base is 
4772          a[i1][i2]..[iN-1].  */
4773       array_base = TREE_OPERAND (memref, 0);
4774       STMT_VINFO_VECT_DR_BASE (stmt_info) = array_base;      
4775
4776       new_dr = analyze_array (stmt, memref, is_read);
4777       *dr = new_dr;
4778
4779       /* Find the relevant symbol for aliasing purposes.  */    
4780       base = DR_BASE_NAME (new_dr);
4781       switch (TREE_CODE (base)) 
4782         {
4783         case VAR_DECL:
4784           symbl = base;
4785           break;
4786
4787         case INDIRECT_REF:
4788           symbl = TREE_OPERAND (base, 0); 
4789           break;
4790
4791         case COMPONENT_REF:
4792           /* Could have recorded more accurate information - 
4793              i.e, the actual FIELD_DECL that is being referenced -
4794              but later passes expect VAR_DECL as the nmt.  */   
4795           symbl = vect_get_base_and_bit_offset (new_dr, base, NULL_TREE, 
4796                                         loop_vinfo, &offset, &base_aligned_p);
4797           if (symbl)
4798             break;
4799           /* fall through */    
4800         default:
4801           if (vect_debug_details (NULL))
4802             {
4803               fprintf (dump_file, "unhandled struct/class field access ");
4804               print_generic_expr (dump_file, stmt, TDF_SLIM);
4805             }
4806           return NULL_TREE;
4807         }
4808       break;
4809
4810     default:
4811       if (vect_debug_details (NULL))
4812         {
4813           fprintf (dump_file, "unhandled data ref: ");
4814           print_generic_expr (dump_file, memref, TDF_SLIM);
4815           fprintf (dump_file, " in stmt  ");
4816           print_generic_expr (dump_file, stmt, TDF_SLIM);
4817         }
4818       return NULL_TREE;
4819     }
4820   return symbl;
4821 }
4822
4823
4824 /* Function vect_analyze_data_refs.
4825
4826    Find all the data references in the loop.
4827
4828    FORNOW: Handle aligned INDIRECT_REFs and ARRAY_REFs 
4829            which base is really an array (not a pointer) and which alignment 
4830            can be forced. This restriction will be relaxed.  */
4831
4832 static bool
4833 vect_analyze_data_refs (loop_vec_info loop_vinfo)
4834 {
4835   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
4836   basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
4837   int nbbs = loop->num_nodes;
4838   block_stmt_iterator si;
4839   int j;
4840   struct data_reference *dr;
4841   tree tag;
4842   tree address_base;
4843   bool base_aligned_p;
4844   tree offset;
4845
4846   if (vect_debug_details (NULL))
4847     fprintf (dump_file, "\n<<vect_analyze_data_refs>>\n");
4848
4849   for (j = 0; j < nbbs; j++)
4850     {
4851       basic_block bb = bbs[j];
4852       for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
4853         {
4854           bool is_read = false;
4855           tree stmt = bsi_stmt (si);
4856           stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
4857           v_may_def_optype v_may_defs = STMT_V_MAY_DEF_OPS (stmt);
4858           v_must_def_optype v_must_defs = STMT_V_MUST_DEF_OPS (stmt);
4859           vuse_optype vuses = STMT_VUSE_OPS (stmt);
4860           varray_type *datarefs = NULL;
4861           int nvuses, nv_may_defs, nv_must_defs;
4862           tree memref = NULL;
4863           tree symbl;
4864
4865           /* Assumption: there exists a data-ref in stmt, if and only if 
4866              it has vuses/vdefs.  */
4867
4868           if (!vuses && !v_may_defs && !v_must_defs)
4869             continue;
4870
4871           nvuses = NUM_VUSES (vuses);
4872           nv_may_defs = NUM_V_MAY_DEFS (v_may_defs);
4873           nv_must_defs = NUM_V_MUST_DEFS (v_must_defs);
4874
4875           if (nvuses && (nv_may_defs || nv_must_defs))
4876             {
4877               if (vect_debug_details (NULL))
4878                 {
4879                   fprintf (dump_file, "unexpected vdefs and vuses in stmt: ");
4880                   print_generic_expr (dump_file, stmt, TDF_SLIM);
4881                 }
4882               return false;
4883             }
4884
4885           if (TREE_CODE (stmt) != MODIFY_EXPR)
4886             {
4887               if (vect_debug_details (NULL))
4888                 {
4889                   fprintf (dump_file, "unexpected vops in stmt: ");
4890                   print_generic_expr (dump_file, stmt, TDF_SLIM);
4891                 }
4892               return false;
4893             }
4894
4895           if (vuses)
4896             {
4897               memref = TREE_OPERAND (stmt, 1);
4898               datarefs = &(LOOP_VINFO_DATAREF_READS (loop_vinfo));
4899               is_read = true;
4900             } 
4901           else /* vdefs */
4902             {
4903               memref = TREE_OPERAND (stmt, 0);
4904               datarefs = &(LOOP_VINFO_DATAREF_WRITES (loop_vinfo));
4905               is_read = false;
4906             }
4907
4908           /* Analyze MEMREF. If it is of a supported form, build data_reference
4909              struct for it (DR) and find the relevant symbol for aliasing 
4910              purposes.  */
4911           symbl = vect_get_symbl_and_dr (memref, stmt, is_read, loop_vinfo, 
4912                                          &dr);
4913           if (!symbl)
4914             {
4915               if (vect_debug_stats (loop) || vect_debug_details (loop))
4916                 {
4917                   fprintf (dump_file, "not vectorized: unhandled data ref: "); 
4918                   print_generic_expr (dump_file, stmt, TDF_SLIM);
4919                 }
4920               return false;
4921             }
4922
4923           /* Find and record the memtag assigned to this data-ref.  */
4924            switch (TREE_CODE (symbl))
4925             {
4926             case VAR_DECL:
4927               STMT_VINFO_MEMTAG (stmt_info) = symbl;
4928               break;
4929               
4930             case SSA_NAME:
4931               symbl = SSA_NAME_VAR (symbl);
4932               tag = get_var_ann (symbl)->type_mem_tag;
4933               if (!tag)
4934                 {
4935                   tree ptr = TREE_OPERAND (memref, 0);
4936                   if (TREE_CODE (ptr) == SSA_NAME)
4937                     tag = get_var_ann (SSA_NAME_VAR (ptr))->type_mem_tag;
4938                 }
4939               if (!tag)
4940                 {
4941                   if (vect_debug_stats (loop) || vect_debug_details (loop))
4942                     fprintf (dump_file, "not vectorized: no memtag for ref.");
4943                   return false;
4944                 }
4945               STMT_VINFO_MEMTAG (stmt_info) = tag;
4946               break;
4947
4948             case ADDR_EXPR:
4949               address_base = TREE_OPERAND (symbl, 0);
4950
4951               switch (TREE_CODE (address_base))
4952                 {
4953                 case ARRAY_REF:
4954                   dr = analyze_array (stmt, TREE_OPERAND (symbl, 0), 
4955                                       DR_IS_READ(dr));
4956                   STMT_VINFO_MEMTAG (stmt_info) = 
4957                      vect_get_base_and_bit_offset (dr, DR_BASE_NAME (dr), NULL_TREE,
4958                                                    loop_vinfo, &offset, 
4959                                                    &base_aligned_p);
4960                   break;
4961                   
4962                 case VAR_DECL: 
4963                   STMT_VINFO_MEMTAG (stmt_info) = address_base;
4964                   break;
4965
4966                 default:
4967                   if (vect_debug_stats (loop) || vect_debug_details (loop))
4968                     {
4969                       fprintf (dump_file, 
4970                                "not vectorized: unhandled address expr: ");
4971                       print_generic_expr (dump_file, stmt, TDF_SLIM);
4972                     }
4973                   return false;
4974                 }
4975               break;
4976               
4977             default:
4978               if (vect_debug_stats (loop) || vect_debug_details (loop))
4979                 {
4980                   fprintf (dump_file, "not vectorized: unsupported data-ref: ");
4981                   print_generic_expr (dump_file, memref, TDF_SLIM);
4982                 }
4983               return false;
4984             }
4985
4986           VARRAY_PUSH_GENERIC_PTR (*datarefs, dr);
4987           STMT_VINFO_DATA_REF (stmt_info) = dr;
4988         }
4989     }
4990
4991   return true;
4992 }
4993
4994
4995 /* Utility functions used by vect_mark_stmts_to_be_vectorized.  */
4996
4997 /* Function vect_mark_relevant.
4998
4999    Mark STMT as "relevant for vectorization" and add it to WORKLIST.  */
5000
5001 static void
5002 vect_mark_relevant (varray_type worklist, tree stmt)
5003 {
5004   stmt_vec_info stmt_info;
5005
5006   if (vect_debug_details (NULL))
5007     fprintf (dump_file, "mark relevant.");
5008
5009   if (TREE_CODE (stmt) == PHI_NODE)
5010     {
5011       VARRAY_PUSH_TREE (worklist, stmt);
5012       return;
5013     }
5014
5015   stmt_info = vinfo_for_stmt (stmt);
5016
5017   if (!stmt_info)
5018     {
5019       if (vect_debug_details (NULL))
5020         {
5021           fprintf (dump_file, "mark relevant: no stmt info!!.");
5022           print_generic_expr (dump_file, stmt, TDF_SLIM);
5023         }
5024       return;
5025     }
5026
5027   if (STMT_VINFO_RELEVANT_P (stmt_info))
5028     {
5029       if (vect_debug_details (NULL))
5030         fprintf (dump_file, "already marked relevant.");
5031       return;
5032     }
5033
5034   STMT_VINFO_RELEVANT_P (stmt_info) = 1;
5035   VARRAY_PUSH_TREE (worklist, stmt);
5036 }
5037
5038
5039 /* Function vect_stmt_relevant_p.
5040
5041    Return true if STMT in loop that is represented by LOOP_VINFO is
5042    "relevant for vectorization".
5043
5044    A stmt is considered "relevant for vectorization" if:
5045    - it has uses outside the loop.
5046    - it has vdefs (it alters memory).
5047    - control stmts in the loop (except for the exit condition).
5048
5049    CHECKME: what other side effects would the vectorizer allow?  */
5050
5051 static bool
5052 vect_stmt_relevant_p (tree stmt, loop_vec_info loop_vinfo)
5053 {
5054   v_may_def_optype v_may_defs;
5055   v_must_def_optype v_must_defs;
5056   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
5057   int i;
5058   dataflow_t df;
5059   int num_uses;
5060
5061   /* cond stmt other than loop exit cond.  */
5062   if (is_ctrl_stmt (stmt) && (stmt != LOOP_VINFO_EXIT_COND (loop_vinfo)))
5063     return true;
5064
5065   /* changing memory.  */
5066   v_may_defs = STMT_V_MAY_DEF_OPS (stmt);
5067   v_must_defs = STMT_V_MUST_DEF_OPS (stmt);
5068   if (v_may_defs || v_must_defs)
5069     {
5070       if (vect_debug_details (NULL))
5071         fprintf (dump_file, "vec_stmt_relevant_p: stmt has vdefs.");
5072       return true;
5073     }
5074
5075   /* uses outside the loop.  */
5076   df = get_immediate_uses (stmt);
5077   num_uses = num_immediate_uses (df);
5078   for (i = 0; i < num_uses; i++)
5079     {
5080       tree use = immediate_use (df, i);
5081       basic_block bb = bb_for_stmt (use);
5082       if (!flow_bb_inside_loop_p (loop, bb))
5083         {
5084           if (vect_debug_details (NULL))
5085             fprintf (dump_file, "vec_stmt_relevant_p: used out of loop.");
5086           return true;
5087         }
5088     }
5089
5090   return false;
5091 }
5092
5093
5094 /* Function vect_mark_stmts_to_be_vectorized.
5095
5096    Not all stmts in the loop need to be vectorized. For example:
5097
5098      for i...
5099        for j...
5100    1.    T0 = i + j
5101    2.    T1 = a[T0]
5102
5103    3.    j = j + 1
5104
5105    Stmt 1 and 3 do not need to be vectorized, because loop control and
5106    addressing of vectorized data-refs are handled differently.
5107
5108    This pass detects such stmts.  */
5109
5110 static bool
5111 vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo)
5112 {
5113   varray_type worklist;
5114   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
5115   basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
5116   unsigned int nbbs = loop->num_nodes;
5117   block_stmt_iterator si;
5118   tree stmt;
5119   stmt_ann_t ann;
5120   unsigned int i;
5121   int j;
5122   use_optype use_ops;
5123   stmt_vec_info stmt_info;
5124
5125   if (vect_debug_details (NULL))
5126     fprintf (dump_file, "\n<<vect_mark_stmts_to_be_vectorized>>\n");
5127
5128   VARRAY_TREE_INIT (worklist, 64, "work list");
5129
5130   /* 1. Init worklist.  */
5131
5132   for (i = 0; i < nbbs; i++)
5133     {
5134       basic_block bb = bbs[i];
5135       for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
5136         {
5137           stmt = bsi_stmt (si);
5138
5139           if (vect_debug_details (NULL))
5140             {
5141               fprintf (dump_file, "init: stmt relevant? ");
5142               print_generic_expr (dump_file, stmt, TDF_SLIM);
5143             } 
5144
5145           stmt_info = vinfo_for_stmt (stmt);
5146           STMT_VINFO_RELEVANT_P (stmt_info) = 0;
5147
5148           if (vect_stmt_relevant_p (stmt, loop_vinfo))
5149             vect_mark_relevant (worklist, stmt);
5150         }
5151     }
5152
5153
5154   /* 2. Process_worklist */
5155
5156   while (VARRAY_ACTIVE_SIZE (worklist) > 0)
5157     {
5158       stmt = VARRAY_TOP_TREE (worklist);
5159       VARRAY_POP (worklist);
5160
5161       if (vect_debug_details (NULL))
5162         {
5163           fprintf (dump_file, "worklist: examine stmt: ");
5164           print_generic_expr (dump_file, stmt, TDF_SLIM);
5165         }
5166
5167       /* Examine the USES in this statement. Mark all the statements which
5168          feed this statement's uses as "relevant", unless the USE is used as
5169          an array index.  */
5170
5171       if (TREE_CODE (stmt) == PHI_NODE)
5172         {
5173           /* follow the def-use chain inside the loop.  */
5174           for (j = 0; j < PHI_NUM_ARGS (stmt); j++)
5175             {
5176               tree arg = PHI_ARG_DEF (stmt, j);
5177               tree def_stmt = NULL_TREE;
5178               basic_block bb;
5179               if (!vect_is_simple_use (arg, loop, &def_stmt))
5180                 {
5181                   if (vect_debug_details (NULL))        
5182                     fprintf (dump_file, "worklist: unsupported use.");
5183                   varray_clear (worklist);
5184                   return false;
5185                 }
5186               if (!def_stmt)
5187                 continue;
5188
5189               if (vect_debug_details (NULL))
5190                 {
5191                   fprintf (dump_file, "worklist: def_stmt: ");
5192                   print_generic_expr (dump_file, def_stmt, TDF_SLIM);
5193                 }
5194
5195               bb = bb_for_stmt (def_stmt);
5196               if (flow_bb_inside_loop_p (loop, bb))
5197                 vect_mark_relevant (worklist, def_stmt);
5198             }
5199         } 
5200
5201       ann = stmt_ann (stmt);
5202       use_ops = USE_OPS (ann);
5203
5204       for (i = 0; i < NUM_USES (use_ops); i++)
5205         {
5206           tree use = USE_OP (use_ops, i);
5207
5208           /* We are only interested in uses that need to be vectorized. Uses 
5209              that are used for address computation are not considered relevant.
5210            */
5211           if (exist_non_indexing_operands_for_use_p (use, stmt))
5212             {
5213               tree def_stmt = NULL_TREE;
5214               basic_block bb;
5215               if (!vect_is_simple_use (use, loop, &def_stmt))
5216                 {
5217                   if (vect_debug_details (NULL))        
5218                     fprintf (dump_file, "worklist: unsupported use.");
5219                   varray_clear (worklist);
5220                   return false;
5221                 }
5222
5223               if (!def_stmt)
5224                 continue;
5225
5226               if (vect_debug_details (NULL))
5227                 {
5228                   fprintf (dump_file, "worklist: examine use %d: ", i);
5229                   print_generic_expr (dump_file, use, TDF_SLIM);
5230                 }
5231
5232               bb = bb_for_stmt (def_stmt);
5233               if (flow_bb_inside_loop_p (loop, bb))
5234                 vect_mark_relevant (worklist, def_stmt);
5235             }
5236         }
5237     }                           /* while worklist */
5238
5239   varray_clear (worklist);
5240   return true;
5241 }
5242
5243
5244 /* Function vect_can_advance_ivs_p
5245
5246    In case the number of iterations that LOOP iterates in unknown at compile 
5247    time, an epilog loop will be generated, and the loop induction variables 
5248    (IVs) will be "advanced" to the value they are supposed to take just before 
5249    the epilog loop.  Here we check that the access function of the loop IVs
5250    and the expression that represents the loop bound are simple enough.
5251    These restrictions will be relaxed in the future.  */
5252
5253 static bool 
5254 vect_can_advance_ivs_p (struct loop *loop)
5255 {
5256   basic_block bb = loop->header;
5257   tree phi;
5258
5259   /* Analyze phi functions of the loop header.  */
5260
5261   for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
5262     {
5263       tree access_fn = NULL;
5264       tree evolution_part;
5265
5266       if (vect_debug_details (NULL))
5267         {
5268           fprintf (dump_file, "Analyze phi: ");
5269           print_generic_expr (dump_file, phi, TDF_SLIM);
5270         }
5271
5272       /* Skip virtual phi's. The data dependences that are associated with
5273          virtual defs/uses (i.e., memory accesses) are analyzed elsewhere.  */
5274
5275       if (!is_gimple_reg (SSA_NAME_VAR (PHI_RESULT (phi))))
5276         {
5277           if (vect_debug_details (NULL))
5278             fprintf (dump_file, "virtual phi. skip.");
5279           continue;
5280         }
5281
5282       /* Analyze the evolution function.  */
5283
5284       access_fn = instantiate_parameters
5285         (loop, analyze_scalar_evolution (loop, PHI_RESULT (phi)));
5286
5287       if (!access_fn)
5288         {
5289           if (vect_debug_details (NULL))
5290             fprintf (dump_file, "No Access function.");
5291           return false;
5292         }
5293
5294       if (vect_debug_details (NULL))
5295         {
5296           fprintf (dump_file, "Access function of PHI: ");
5297           print_generic_expr (dump_file, access_fn, TDF_SLIM);
5298         }
5299
5300       evolution_part = evolution_part_in_loop_num (access_fn, loop->num);
5301       
5302       if (evolution_part == NULL_TREE)
5303         return false;
5304   
5305       /* FORNOW: We do not transform initial conditions of IVs 
5306          which evolution functions are a polynomial of degree >= 2.  */
5307
5308       if (tree_is_chrec (evolution_part))
5309         return false;  
5310     }
5311
5312   return true;
5313 }
5314
5315
5316 /* Function vect_get_loop_niters.
5317
5318    Determine how many iterations the loop is executed.
5319    If an expression that represents the number of iterations
5320    can be constructed, place it in NUMBER_OF_ITERATIONS.
5321    Return the loop exit condition.  */
5322
5323 static tree
5324 vect_get_loop_niters (struct loop *loop, tree *number_of_iterations)
5325 {
5326   tree niters;
5327
5328   if (vect_debug_details (NULL))
5329     fprintf (dump_file, "\n<<get_loop_niters>>\n");
5330
5331   niters = number_of_iterations_in_loop (loop);
5332
5333   if (niters != NULL_TREE
5334       && niters != chrec_dont_know)
5335     {
5336       *number_of_iterations = niters;
5337
5338       if (vect_debug_details (NULL))
5339         {
5340           fprintf (dump_file, "==> get_loop_niters:" );
5341           print_generic_expr (dump_file, *number_of_iterations, TDF_SLIM);
5342         }
5343     }
5344
5345   return get_loop_exit_condition (loop);
5346 }
5347
5348
5349 /* Function vect_analyze_loop_form.
5350
5351    Verify the following restrictions (some may be relaxed in the future):
5352    - it's an inner-most loop
5353    - number of BBs = 2 (which are the loop header and the latch)
5354    - the loop has a pre-header
5355    - the loop has a single entry and exit
5356    - the loop exit condition is simple enough, and the number of iterations
5357      can be analyzed (a countable loop).  */
5358
5359 static loop_vec_info
5360 vect_analyze_loop_form (struct loop *loop)
5361 {
5362   loop_vec_info loop_vinfo;
5363   tree loop_cond;
5364   tree number_of_iterations = NULL;
5365   bool rescan = false;
5366
5367   if (vect_debug_details (loop))
5368     fprintf (dump_file, "\n<<vect_analyze_loop_form>>\n");
5369
5370   if (loop->inner
5371       || !loop->single_exit
5372       || loop->num_nodes != 2
5373       || EDGE_COUNT (loop->header->preds) != 2
5374       || loop->num_entries != 1)
5375     {
5376       if (vect_debug_stats (loop) || vect_debug_details (loop)) 
5377         {
5378           fprintf (dump_file, "not vectorized: bad loop form. ");
5379           if (loop->inner)
5380             fprintf (dump_file, "nested loop.");
5381           else if (!loop->single_exit)
5382             fprintf (dump_file, "multiple exits.");
5383           else if (loop->num_nodes != 2)
5384             fprintf (dump_file, "too many BBs in loop.");
5385           else if (EDGE_COUNT (loop->header->preds) != 2)
5386             fprintf (dump_file, "too many incoming edges.");
5387           else if (loop->num_entries != 1)
5388             fprintf (dump_file, "too many entries.");
5389         }
5390
5391       return NULL;
5392     }
5393
5394   /* We assume that the loop exit condition is at the end of the loop. i.e,
5395      that the loop is represented as a do-while (with a proper if-guard
5396      before the loop if needed), where the loop header contains all the
5397      executable statements, and the latch is empty.  */
5398   if (!empty_block_p (loop->latch))
5399     {
5400       if (vect_debug_stats (loop) || vect_debug_details (loop))
5401         fprintf (dump_file, "not vectorized: unexpectd loop form.");
5402       return NULL;
5403     }
5404
5405   /* Make sure we have a preheader basic block.  */
5406   if (!loop->pre_header)
5407     {
5408       rescan = true;
5409       loop_split_edge_with (loop_preheader_edge (loop), NULL);
5410     }
5411     
5412   /* Make sure there exists a single-predecessor exit bb:  */
5413   if (EDGE_COUNT (loop->exit_edges[0]->dest->preds) != 1)
5414     {
5415       rescan = true;
5416       loop_split_edge_with (loop->exit_edges[0], NULL);
5417     }
5418     
5419   if (rescan)
5420     {
5421       flow_loop_scan (loop, LOOP_ALL);
5422       /* Flow loop scan does not update loop->single_exit field.  */
5423       loop->single_exit = loop->exit_edges[0];
5424     }
5425
5426   if (empty_block_p (loop->header))
5427     {
5428       if (vect_debug_stats (loop) || vect_debug_details (loop))
5429         fprintf (dump_file, "not vectorized: empty loop.");
5430       return NULL;
5431     }
5432
5433   loop_cond = vect_get_loop_niters (loop, &number_of_iterations);
5434   if (!loop_cond)
5435     {
5436       if (vect_debug_stats (loop) || vect_debug_details (loop))
5437         fprintf (dump_file, "not vectorized: complicated exit condition.");
5438       return NULL;
5439     }
5440   
5441   if (!number_of_iterations) 
5442     {
5443       if (vect_debug_stats (loop) || vect_debug_details (loop))
5444         fprintf (dump_file, 
5445                  "not vectorized: number of iterations cannot be computed.");
5446       return NULL;
5447     }
5448
5449   if (chrec_contains_undetermined (number_of_iterations))
5450     {
5451       if (vect_debug_details (NULL))
5452         fprintf (dump_file, "Infinite number of iterations.");
5453       return false;
5454     }
5455
5456   loop_vinfo = new_loop_vec_info (loop);
5457   LOOP_VINFO_NITERS (loop_vinfo) = number_of_iterations;
5458
5459   if (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo))
5460     {
5461       if (vect_debug_details (loop))
5462         {
5463           fprintf (dump_file, "loop bound unknown.\n");
5464           fprintf (dump_file, "Symbolic number of iterations is ");
5465           print_generic_expr (dump_file, number_of_iterations, TDF_DETAILS);
5466         }
5467     }
5468   else
5469   if (LOOP_VINFO_INT_NITERS (loop_vinfo) == 0)
5470     {
5471       if (vect_debug_stats (loop) || vect_debug_details (loop))
5472         fprintf (dump_file, "not vectorized: number of iterations = 0.");
5473       return NULL;
5474     }
5475
5476   LOOP_VINFO_EXIT_COND (loop_vinfo) = loop_cond;
5477
5478   return loop_vinfo;
5479 }
5480
5481
5482 /* Function vect_analyze_loop.
5483
5484    Apply a set of analyses on LOOP, and create a loop_vec_info struct
5485    for it. The different analyses will record information in the
5486    loop_vec_info struct.  */
5487
5488 static loop_vec_info
5489 vect_analyze_loop (struct loop *loop)
5490 {
5491   bool ok;
5492   loop_vec_info loop_vinfo;
5493
5494   if (vect_debug_details (NULL))
5495     fprintf (dump_file, "\n<<<<<<< analyze_loop_nest >>>>>>>\n");
5496
5497   /* Check the CFG characteristics of the loop (nesting, entry/exit, etc.  */
5498
5499   loop_vinfo = vect_analyze_loop_form (loop);
5500   if (!loop_vinfo)
5501     {
5502       if (vect_debug_details (loop))
5503         fprintf (dump_file, "bad loop form.");
5504       return NULL;
5505     }
5506
5507   /* Find all data references in the loop (which correspond to vdefs/vuses)
5508      and analyze their evolution in the loop.
5509
5510      FORNOW: Handle only simple, array references, which
5511      alignment can be forced, and aligned pointer-references.  */
5512
5513   ok = vect_analyze_data_refs (loop_vinfo);
5514   if (!ok)
5515     {
5516       if (vect_debug_details (loop))
5517         fprintf (dump_file, "bad data references.");
5518       destroy_loop_vec_info (loop_vinfo);
5519       return NULL;
5520     }
5521
5522   /* Data-flow analysis to detect stmts that do not need to be vectorized.  */
5523
5524   ok = vect_mark_stmts_to_be_vectorized (loop_vinfo);
5525   if (!ok)
5526     {
5527       if (vect_debug_details (loop))
5528         fprintf (dump_file, "unexpected pattern.");
5529       if (vect_debug_details (loop))
5530         fprintf (dump_file, "not vectorized: unexpected pattern.");
5531       destroy_loop_vec_info (loop_vinfo);
5532       return NULL;
5533     }
5534
5535   /* Check that all cross-iteration scalar data-flow cycles are OK.
5536      Cross-iteration cycles caused by virtual phis are analyzed separately.  */
5537
5538   ok = vect_analyze_scalar_cycles (loop_vinfo);
5539   if (!ok)
5540     {
5541       if (vect_debug_details (loop))
5542         fprintf (dump_file, "bad scalar cycle.");
5543       destroy_loop_vec_info (loop_vinfo);
5544       return NULL;
5545     }
5546
5547   /* Analyze data dependences between the data-refs in the loop. 
5548      FORNOW: fail at the first data dependence that we encounter.  */
5549
5550   ok = vect_analyze_data_ref_dependences (loop_vinfo);
5551   if (!ok)
5552     {
5553       if (vect_debug_details (loop))
5554         fprintf (dump_file, "bad data dependence.");
5555       destroy_loop_vec_info (loop_vinfo);
5556       return NULL;
5557     }
5558
5559   /* Analyze the access patterns of the data-refs in the loop (consecutive,
5560      complex, etc.). FORNOW: Only handle consecutive access pattern.  */
5561
5562   ok = vect_analyze_data_ref_accesses (loop_vinfo);
5563   if (!ok)
5564     {
5565       if (vect_debug_details (loop))
5566         fprintf (dump_file, "bad data access.");
5567       destroy_loop_vec_info (loop_vinfo);
5568       return NULL;
5569     }
5570
5571   /* Analyze the alignment of the data-refs in the loop.
5572      FORNOW: Only aligned accesses are handled.  */
5573
5574   ok = vect_analyze_data_refs_alignment (loop_vinfo);
5575   if (!ok)
5576     {
5577       if (vect_debug_details (loop))
5578         fprintf (dump_file, "bad data alignment.");
5579       destroy_loop_vec_info (loop_vinfo);
5580       return NULL;
5581     }
5582
5583   /* Scan all the operations in the loop and make sure they are
5584      vectorizable.  */
5585
5586   ok = vect_analyze_operations (loop_vinfo);
5587   if (!ok)
5588     {
5589       if (vect_debug_details (loop))
5590         fprintf (dump_file, "bad operation or unsupported loop bound.");
5591       destroy_loop_vec_info (loop_vinfo);
5592       return NULL;
5593     }
5594
5595   LOOP_VINFO_VECTORIZABLE_P (loop_vinfo) = 1;
5596
5597   return loop_vinfo;
5598 }
5599
5600
5601 /* Function need_imm_uses_for.
5602
5603    Return whether we ought to include information for 'var'
5604    when calculating immediate uses.  For this pass we only want use
5605    information for non-virtual variables.  */
5606
5607 static bool
5608 need_imm_uses_for (tree var)
5609 {
5610   return is_gimple_reg (var);
5611 }
5612
5613
5614 /* Function vectorize_loops.
5615    
5616    Entry Point to loop vectorization phase.  */
5617
5618 void
5619 vectorize_loops (struct loops *loops)
5620 {
5621   unsigned int i, loops_num;
5622   unsigned int num_vectorized_loops = 0;
5623
5624   /* Does the target support SIMD?  */
5625   /* FORNOW: until more sophisticated machine modelling is in place.  */
5626   if (!UNITS_PER_SIMD_WORD)
5627     {
5628       if (vect_debug_details (NULL))
5629         fprintf (dump_file, "vectorizer: target vector size is not defined.");
5630       return;
5631     }
5632
5633 #ifdef ENABLE_CHECKING
5634   verify_loop_closed_ssa ();
5635 #endif
5636
5637   compute_immediate_uses (TDFA_USE_OPS, need_imm_uses_for);
5638
5639   /*  ----------- Analyze loops. -----------  */
5640
5641   /* If some loop was duplicated, it gets bigger number 
5642      than all previously defined loops. This fact allows us to run 
5643      only over initial loops skipping newly generated ones.  */
5644   loops_num = loops->num;
5645   for (i = 1; i < loops_num; i++)
5646     {
5647       loop_vec_info loop_vinfo;
5648       struct loop *loop = loops->parray[i];
5649
5650       if (!loop)
5651         continue;
5652
5653       loop_vinfo = vect_analyze_loop (loop);
5654       loop->aux = loop_vinfo;
5655
5656       if (!loop_vinfo || !LOOP_VINFO_VECTORIZABLE_P (loop_vinfo))
5657         continue;
5658
5659       vect_transform_loop (loop_vinfo, loops); 
5660       num_vectorized_loops++;
5661     }
5662
5663   if (vect_debug_stats (NULL) || vect_debug_details (NULL))
5664     fprintf (dump_file, "\nvectorized %u loops in function.\n",
5665              num_vectorized_loops);
5666
5667   /*  ----------- Finalize. -----------  */
5668
5669   free_df ();
5670   for (i = 1; i < loops_num; i++)
5671     {
5672       struct loop *loop = loops->parray[i];
5673       loop_vec_info loop_vinfo;
5674
5675       if (!loop)
5676         continue;
5677       loop_vinfo = loop->aux;
5678       destroy_loop_vec_info (loop_vinfo);
5679       loop->aux = NULL;
5680     }
5681
5682   rewrite_into_ssa (false);
5683   rewrite_into_loop_closed_ssa (); /* FORNOW */
5684   bitmap_clear (vars_to_rename);
5685 }