OSDN Git Service

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