OSDN Git Service

* gcc.dg/dfp/func-array.c: Support -DDBG to report individual failures.
[pf3gnuchains/gcc-fork.git] / gcc / tree-vect-analyze.c
1 /* Analysis Utilities for Loop Vectorization.
2    Copyright (C) 2003,2004,2005,2006 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, 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301, USA.  */
21
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "ggc.h"
27 #include "tree.h"
28 #include "basic-block.h"
29 #include "diagnostic.h"
30 #include "tree-flow.h"
31 #include "tree-dump.h"
32 #include "timevar.h"
33 #include "cfgloop.h"
34 #include "expr.h"
35 #include "optabs.h"
36 #include "params.h"
37 #include "tree-chrec.h"
38 #include "tree-data-ref.h"
39 #include "tree-scalar-evolution.h"
40 #include "tree-vectorizer.h"
41 #include "toplev.h"
42
43 /* Main analysis functions.  */
44 static loop_vec_info vect_analyze_loop_form (struct loop *);
45 static bool vect_analyze_data_refs (loop_vec_info);
46 static bool vect_mark_stmts_to_be_vectorized (loop_vec_info);
47 static void vect_analyze_scalar_cycles (loop_vec_info);
48 static bool vect_analyze_data_ref_accesses (loop_vec_info);
49 static bool vect_analyze_data_ref_dependences (loop_vec_info);
50 static bool vect_analyze_data_refs_alignment (loop_vec_info);
51 static bool vect_compute_data_refs_alignment (loop_vec_info);
52 static bool vect_enhance_data_refs_alignment (loop_vec_info);
53 static bool vect_analyze_operations (loop_vec_info);
54 static bool vect_determine_vectorization_factor (loop_vec_info);
55
56 /* Utility functions for the analyses.  */
57 static bool exist_non_indexing_operands_for_use_p (tree, tree);
58 static tree vect_get_loop_niters (struct loop *, tree *);
59 static bool vect_analyze_data_ref_dependence
60   (struct data_dependence_relation *, loop_vec_info);
61 static bool vect_compute_data_ref_alignment (struct data_reference *); 
62 static bool vect_analyze_data_ref_access (struct data_reference *);
63 static bool vect_can_advance_ivs_p (loop_vec_info);
64 static void vect_update_misalignment_for_peel
65   (struct data_reference *, struct data_reference *, int npeel);
66
67 /* Function vect_determine_vectorization_factor
68
69    Determine the vectorization factor (VF). VF is the number of data elements
70    that are operated upon in parallel in a single iteration of the vectorized
71    loop. For example, when vectorizing a loop that operates on 4byte elements,
72    on a target with vector size (VS) 16byte, the VF is set to 4, since 4
73    elements can fit in a single vector register.
74
75    We currently support vectorization of loops in which all types operated upon
76    are of the same size. Therefore this function currently sets VF according to
77    the size of the types operated upon, and fails if there are multiple sizes
78    in the loop.
79
80    VF is also the factor by which the loop iterations are strip-mined, e.g.:
81    original loop:
82         for (i=0; i<N; i++){
83           a[i] = b[i] + c[i];
84         }
85
86    vectorized loop:
87         for (i=0; i<N; i+=VF){
88           a[i:VF] = b[i:VF] + c[i:VF];
89         }
90 */
91
92 static bool
93 vect_determine_vectorization_factor (loop_vec_info loop_vinfo)
94 {
95   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
96   basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
97   int nbbs = loop->num_nodes;
98   block_stmt_iterator si;
99   unsigned int vectorization_factor = 0;
100   tree scalar_type;
101   tree phi;
102   tree vectype;
103   unsigned int nunits;
104   stmt_vec_info stmt_info;
105   int i;
106
107   if (vect_print_dump_info (REPORT_DETAILS))
108     fprintf (vect_dump, "=== vect_determine_vectorization_factor ===");
109
110   for (i = 0; i < nbbs; i++)
111     {
112       basic_block bb = bbs[i];
113
114       for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
115         {
116           stmt_info = vinfo_for_stmt (phi);
117           if (vect_print_dump_info (REPORT_DETAILS))
118             {
119               fprintf (vect_dump, "==> examining phi: ");
120               print_generic_expr (vect_dump, phi, TDF_SLIM);
121             }
122
123           gcc_assert (stmt_info);
124
125           if (STMT_VINFO_RELEVANT_P (stmt_info))
126             {
127               gcc_assert (!STMT_VINFO_VECTYPE (stmt_info));
128               scalar_type = TREE_TYPE (PHI_RESULT (phi));
129
130               if (vect_print_dump_info (REPORT_DETAILS))
131                 {
132                   fprintf (vect_dump, "get vectype for scalar type:  ");
133                   print_generic_expr (vect_dump, scalar_type, TDF_SLIM);
134                 }
135
136               vectype = get_vectype_for_scalar_type (scalar_type);
137               if (!vectype)
138                 {
139                   if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
140                     {
141                       fprintf (vect_dump,
142                                "not vectorized: unsupported data-type ");
143                       print_generic_expr (vect_dump, scalar_type, TDF_SLIM);
144                     }
145                   return false;
146                 }
147               STMT_VINFO_VECTYPE (stmt_info) = vectype;
148
149               if (vect_print_dump_info (REPORT_DETAILS))
150                 {
151                   fprintf (vect_dump, "vectype: ");
152                   print_generic_expr (vect_dump, vectype, TDF_SLIM);
153                 }
154
155               nunits = TYPE_VECTOR_SUBPARTS (vectype);
156               if (vect_print_dump_info (REPORT_DETAILS))
157                 fprintf (vect_dump, "nunits = %d", nunits);
158
159               if (!vectorization_factor
160                   || (nunits > vectorization_factor))
161                 vectorization_factor = nunits;
162             }
163         }
164
165       for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
166         {
167           tree stmt = bsi_stmt (si);
168           stmt_info = vinfo_for_stmt (stmt);
169
170           if (vect_print_dump_info (REPORT_DETAILS))
171             {
172               fprintf (vect_dump, "==> examining statement: ");
173               print_generic_expr (vect_dump, stmt, TDF_SLIM);
174             }
175
176           if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
177             continue;
178
179           gcc_assert (stmt_info);
180
181           /* skip stmts which do not need to be vectorized.  */
182           if (!STMT_VINFO_RELEVANT_P (stmt_info)
183               && !STMT_VINFO_LIVE_P (stmt_info))
184             {
185               if (vect_print_dump_info (REPORT_DETAILS))
186                 fprintf (vect_dump, "skip.");
187               continue;
188             }
189
190           if (!GIMPLE_STMT_P (stmt)
191               && VECTOR_MODE_P (TYPE_MODE (TREE_TYPE (stmt))))
192             {
193               if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
194                 {
195                   fprintf (vect_dump, "not vectorized: vector stmt in loop:");
196                   print_generic_expr (vect_dump, stmt, TDF_SLIM);
197                 }
198               return false;
199             }
200
201           if (STMT_VINFO_VECTYPE (stmt_info))
202             {
203               /* The only case when a vectype had been already set is for stmts 
204                  that contain a dataref, or for "pattern-stmts" (stmts generated
205                  by the vectorizer to represent/replace a certain idiom).  */
206               gcc_assert (STMT_VINFO_DATA_REF (stmt_info) 
207                           || is_pattern_stmt_p (stmt_info));
208               vectype = STMT_VINFO_VECTYPE (stmt_info);
209             }
210           else
211             {
212               gcc_assert (! STMT_VINFO_DATA_REF (stmt_info)
213                           && !is_pattern_stmt_p (stmt_info));
214
215               /* We set the vectype according to the type of the result (lhs).
216                  For stmts whose result-type is different than the type of the
217                  arguments (e.g. demotion, promotion), vectype will be reset 
218                  appropriately (later).  Note that we have to visit the smallest 
219                  datatype in this function, because that determines the VF.  
220                  If the smallest datatype in the loop is present only as the 
221                  rhs of a promotion operation - we'd miss it here.
222                  However, in such a case, that a variable of this datatype
223                  does not appear in the lhs anywhere in the loop, it shouldn't
224                  affect the vectorization factor.   */
225               scalar_type = TREE_TYPE (GIMPLE_STMT_OPERAND (stmt, 0));
226
227               if (vect_print_dump_info (REPORT_DETAILS))
228                 {
229                   fprintf (vect_dump, "get vectype for scalar type:  ");
230                   print_generic_expr (vect_dump, scalar_type, TDF_SLIM);
231                 }
232
233               vectype = get_vectype_for_scalar_type (scalar_type);
234               if (!vectype)
235                 {
236                   if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
237                     {
238                       fprintf (vect_dump, 
239                                "not vectorized: unsupported data-type ");
240                       print_generic_expr (vect_dump, scalar_type, TDF_SLIM);
241                     }
242                   return false;
243                 }
244               STMT_VINFO_VECTYPE (stmt_info) = vectype;
245             }
246
247           if (vect_print_dump_info (REPORT_DETAILS))
248             {
249               fprintf (vect_dump, "vectype: ");
250               print_generic_expr (vect_dump, vectype, TDF_SLIM);
251             }
252
253           nunits = TYPE_VECTOR_SUBPARTS (vectype);
254           if (vect_print_dump_info (REPORT_DETAILS))
255             fprintf (vect_dump, "nunits = %d", nunits);
256
257           if (!vectorization_factor
258               || (nunits > vectorization_factor))
259             vectorization_factor = nunits;
260
261         }
262     }
263
264   /* TODO: Analyze cost. Decide if worth while to vectorize.  */
265   if (vect_print_dump_info (REPORT_DETAILS))
266     fprintf (vect_dump, "vectorization factor = %d", vectorization_factor);
267   if (vectorization_factor <= 1)
268     {
269       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
270         fprintf (vect_dump, "not vectorized: unsupported data-type");
271       return false;
272     }
273   LOOP_VINFO_VECT_FACTOR (loop_vinfo) = vectorization_factor;
274
275   return true;
276 }
277
278
279 /* Function vect_analyze_operations.
280
281    Scan the loop stmts and make sure they are all vectorizable.  */
282
283 static bool
284 vect_analyze_operations (loop_vec_info loop_vinfo)
285 {
286   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
287   basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
288   int nbbs = loop->num_nodes;
289   block_stmt_iterator si;
290   unsigned int vectorization_factor = 0;
291   int i;
292   bool ok;
293   tree phi;
294   stmt_vec_info stmt_info;
295   bool need_to_vectorize = false;
296
297   if (vect_print_dump_info (REPORT_DETAILS))
298     fprintf (vect_dump, "=== vect_analyze_operations ===");
299
300   gcc_assert (LOOP_VINFO_VECT_FACTOR (loop_vinfo));
301   vectorization_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
302
303   for (i = 0; i < nbbs; i++)
304     {
305       basic_block bb = bbs[i];
306
307       for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
308         {
309           ok = true;
310
311           stmt_info = vinfo_for_stmt (phi);
312           if (vect_print_dump_info (REPORT_DETAILS))
313             {
314               fprintf (vect_dump, "examining phi: ");
315               print_generic_expr (vect_dump, phi, TDF_SLIM);
316             }
317
318           gcc_assert (stmt_info);
319
320           if (STMT_VINFO_LIVE_P (stmt_info))
321             {
322               /* FORNOW: not yet supported.  */
323               if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
324                 fprintf (vect_dump, "not vectorized: value used after loop.");
325               return false;
326             }
327
328           if (STMT_VINFO_RELEVANT (stmt_info) == vect_used_in_loop
329               && STMT_VINFO_DEF_TYPE (stmt_info) != vect_induction_def)
330             {
331               /* A scalar-dependence cycle that we don't support.  */
332               if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
333                 fprintf (vect_dump, "not vectorized: scalar dependence cycle.");
334               return false;
335             }
336
337           if (STMT_VINFO_RELEVANT_P (stmt_info))
338             {
339               need_to_vectorize = true;
340               if (STMT_VINFO_DEF_TYPE (stmt_info) == vect_induction_def)
341                 ok = vectorizable_induction (phi, NULL, NULL);
342             }
343
344           if (!ok)
345             {
346               if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
347                 {
348                   fprintf (vect_dump,
349                            "not vectorized: relevant phi not supported: ");
350                   print_generic_expr (vect_dump, phi, TDF_SLIM);
351                 }
352               return false;
353             }
354         }
355
356       for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
357         {
358           tree stmt = bsi_stmt (si);
359           stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
360           enum vect_def_type relevance = STMT_VINFO_RELEVANT (stmt_info);
361
362           if (vect_print_dump_info (REPORT_DETAILS))
363             {
364               fprintf (vect_dump, "==> examining statement: ");
365               print_generic_expr (vect_dump, stmt, TDF_SLIM);
366             }
367
368           gcc_assert (stmt_info);
369
370           /* skip stmts which do not need to be vectorized.
371              this is expected to include:
372              - the COND_EXPR which is the loop exit condition
373              - any LABEL_EXPRs in the loop
374              - computations that are used only for array indexing or loop
375              control  */
376
377           if (!STMT_VINFO_RELEVANT_P (stmt_info)
378               && !STMT_VINFO_LIVE_P (stmt_info))
379             {
380               if (vect_print_dump_info (REPORT_DETAILS))
381                 fprintf (vect_dump, "irrelevant.");
382               continue;
383             }
384
385           switch (STMT_VINFO_DEF_TYPE (stmt_info))
386             {
387             case vect_loop_def:
388               break;
389         
390             case vect_reduction_def:
391               gcc_assert (relevance == vect_unused_in_loop);
392               break;    
393
394             case vect_induction_def:
395             case vect_constant_def:
396             case vect_invariant_def:
397             case vect_unknown_def_type:
398             default:
399               gcc_unreachable ();       
400             }
401
402           if (STMT_VINFO_RELEVANT_P (stmt_info))
403             {
404               gcc_assert (GIMPLE_STMT_P (stmt)
405                           || !VECTOR_MODE_P (TYPE_MODE (TREE_TYPE (stmt))));
406               gcc_assert (STMT_VINFO_VECTYPE (stmt_info));
407               need_to_vectorize = true;
408             }
409
410           ok = (vectorizable_type_promotion (stmt, NULL, NULL)
411                 || vectorizable_type_demotion (stmt, NULL, NULL)
412                 || vectorizable_conversion (stmt, NULL, NULL)
413                 || vectorizable_operation (stmt, NULL, NULL)
414                 || vectorizable_assignment (stmt, NULL, NULL)
415                 || vectorizable_load (stmt, NULL, NULL)
416                 || vectorizable_call (stmt, NULL, NULL)
417                 || vectorizable_store (stmt, NULL, NULL)
418                 || vectorizable_condition (stmt, NULL, NULL)
419                 || vectorizable_reduction (stmt, NULL, NULL));
420
421           /* Stmts that are (also) "live" (i.e. - that are used out of the loop)
422              need extra handling, except for vectorizable reductions.  */
423           if (STMT_VINFO_LIVE_P (stmt_info)
424               && STMT_VINFO_TYPE (stmt_info) != reduc_vec_info_type) 
425             ok |= vectorizable_live_operation (stmt, NULL, NULL);
426
427           if (!ok)
428             {
429               if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
430                 {
431                   fprintf (vect_dump, "not vectorized: stmt not supported: ");
432                   print_generic_expr (vect_dump, stmt, TDF_SLIM);
433                 }
434               return false;
435             }   
436         } /* stmts in bb */
437     } /* bbs */
438
439   /* TODO: Analyze cost. Decide if worth while to vectorize.  */
440
441   /* All operations in the loop are either irrelevant (deal with loop
442      control, or dead), or only used outside the loop and can be moved
443      out of the loop (e.g. invariants, inductions).  The loop can be 
444      optimized away by scalar optimizations.  We're better off not 
445      touching this loop.  */
446   if (!need_to_vectorize)
447     {
448       if (vect_print_dump_info (REPORT_DETAILS))
449         fprintf (vect_dump, 
450                  "All the computation can be taken out of the loop.");
451       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
452         fprintf (vect_dump, 
453                  "not vectorized: redundant loop. no profit to vectorize.");
454       return false;
455     }
456
457   if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
458       && vect_print_dump_info (REPORT_DETAILS))
459     fprintf (vect_dump,
460         "vectorization_factor = %d, niters = " HOST_WIDE_INT_PRINT_DEC,
461         vectorization_factor, LOOP_VINFO_INT_NITERS (loop_vinfo));
462
463   if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
464       && ((LOOP_VINFO_INT_NITERS (loop_vinfo) < vectorization_factor)
465           || (LOOP_VINFO_INT_NITERS (loop_vinfo) <=
466                 ((unsigned) (PARAM_VALUE (PARAM_MIN_VECT_LOOP_BOUND)) 
467                                            * vectorization_factor))))
468     {
469       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
470         fprintf (vect_dump, "not vectorized: iteration count too small.");
471       return false;
472     }
473
474   if (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
475       || LOOP_VINFO_INT_NITERS (loop_vinfo) % vectorization_factor != 0
476       || LOOP_PEELING_FOR_ALIGNMENT (loop_vinfo))
477     {
478       if (vect_print_dump_info (REPORT_DETAILS))
479         fprintf (vect_dump, "epilog loop required.");
480       if (!vect_can_advance_ivs_p (loop_vinfo))
481         {
482           if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
483             fprintf (vect_dump,
484                      "not vectorized: can't create epilog loop 1.");
485           return false;
486         }
487       if (!slpeel_can_duplicate_loop_p (loop, single_exit (loop)))
488         {
489           if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
490             fprintf (vect_dump,
491                      "not vectorized: can't create epilog loop 2.");
492           return false;
493         }
494     }
495
496   return true;
497 }
498
499
500 /* Function exist_non_indexing_operands_for_use_p 
501
502    USE is one of the uses attached to STMT. Check if USE is 
503    used in STMT for anything other than indexing an array.  */
504
505 static bool
506 exist_non_indexing_operands_for_use_p (tree use, tree stmt)
507 {
508   tree operand;
509   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
510  
511   /* USE corresponds to some operand in STMT. If there is no data
512      reference in STMT, then any operand that corresponds to USE
513      is not indexing an array.  */
514   if (!STMT_VINFO_DATA_REF (stmt_info))
515     return true;
516  
517   /* STMT has a data_ref. FORNOW this means that its of one of
518      the following forms:
519      -1- ARRAY_REF = var
520      -2- var = ARRAY_REF
521      (This should have been verified in analyze_data_refs).
522
523      'var' in the second case corresponds to a def, not a use,
524      so USE cannot correspond to any operands that are not used 
525      for array indexing.
526
527      Therefore, all we need to check is if STMT falls into the
528      first case, and whether var corresponds to USE.  */
529  
530   if (TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) == SSA_NAME)
531     return false;
532
533   operand = GIMPLE_STMT_OPERAND (stmt, 1);
534
535   if (TREE_CODE (operand) != SSA_NAME)
536     return false;
537
538   if (operand == use)
539     return true;
540
541   return false;
542 }
543
544
545 /* Function vect_analyze_scalar_cycles.
546
547    Examine the cross iteration def-use cycles of scalar variables, by
548    analyzing the loop (scalar) PHIs; Classify each cycle as one of the
549    following: invariant, induction, reduction, unknown.
550    
551    Some forms of scalar cycles are not yet supported.
552
553    Example1: reduction: (unsupported yet)
554
555               loop1:
556               for (i=0; i<N; i++)
557                  sum += a[i];
558
559    Example2: induction: (unsupported yet)
560
561               loop2:
562               for (i=0; i<N; i++)
563                  a[i] = i;
564
565    Note: the following loop *is* vectorizable:
566
567               loop3:
568               for (i=0; i<N; i++)
569                  a[i] = b[i];
570
571          even though it has a def-use cycle caused by the induction variable i:
572
573               loop: i_2 = PHI (i_0, i_1)
574                     a[i_2] = ...;
575                     i_1 = i_2 + 1;
576                     GOTO loop;
577
578          because the def-use cycle in loop3 is considered "not relevant" - i.e.,
579          it does not need to be vectorized because it is only used for array
580          indexing (see 'mark_stmts_to_be_vectorized'). The def-use cycle in
581          loop2 on the other hand is relevant (it is being written to memory).
582 */
583
584 static void
585 vect_analyze_scalar_cycles (loop_vec_info loop_vinfo)
586 {
587   tree phi;
588   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
589   basic_block bb = loop->header;
590   tree dumy;
591   VEC(tree,heap) *worklist = VEC_alloc (tree, heap, 64);
592
593   if (vect_print_dump_info (REPORT_DETAILS))
594     fprintf (vect_dump, "=== vect_analyze_scalar_cycles ===");
595
596   /* First - identify all inductions.  */
597   for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
598     {
599       tree access_fn = NULL;
600       tree def = PHI_RESULT (phi);
601       stmt_vec_info stmt_vinfo = vinfo_for_stmt (phi);
602
603       if (vect_print_dump_info (REPORT_DETAILS))
604         {
605           fprintf (vect_dump, "Analyze phi: ");
606           print_generic_expr (vect_dump, phi, TDF_SLIM);
607         }
608
609       /* Skip virtual phi's. The data dependences that are associated with
610          virtual defs/uses (i.e., memory accesses) are analyzed elsewhere.  */
611       if (!is_gimple_reg (SSA_NAME_VAR (def)))
612         continue;
613
614       STMT_VINFO_DEF_TYPE (stmt_vinfo) = vect_unknown_def_type;
615
616       /* Analyze the evolution function.  */
617       access_fn = analyze_scalar_evolution (loop, def);
618       if (access_fn && vect_print_dump_info (REPORT_DETAILS))
619         {
620           fprintf (vect_dump, "Access function of PHI: ");
621           print_generic_expr (vect_dump, access_fn, TDF_SLIM);
622         }
623
624       if (!access_fn
625           || !vect_is_simple_iv_evolution (loop->num, access_fn, &dumy, &dumy)) 
626         {
627           VEC_safe_push (tree, heap, worklist, phi);      
628           continue;
629         }
630
631       if (vect_print_dump_info (REPORT_DETAILS))
632         fprintf (vect_dump, "Detected induction.");
633       STMT_VINFO_DEF_TYPE (stmt_vinfo) = vect_induction_def;
634     }
635
636
637   /* Second - identify all reductions.  */
638   while (VEC_length (tree, worklist) > 0)
639     {
640       tree phi = VEC_pop (tree, worklist);
641       tree def = PHI_RESULT (phi);
642       stmt_vec_info stmt_vinfo = vinfo_for_stmt (phi);
643       tree reduc_stmt;
644
645       if (vect_print_dump_info (REPORT_DETAILS))
646         { 
647           fprintf (vect_dump, "Analyze phi: ");
648           print_generic_expr (vect_dump, phi, TDF_SLIM);
649         }
650
651       gcc_assert (is_gimple_reg (SSA_NAME_VAR (def)));
652       gcc_assert (STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_unknown_def_type);
653
654       reduc_stmt = vect_is_simple_reduction (loop, phi);
655       if (reduc_stmt)
656         {
657           if (vect_print_dump_info (REPORT_DETAILS))
658             fprintf (vect_dump, "Detected reduction.");
659           STMT_VINFO_DEF_TYPE (stmt_vinfo) = vect_reduction_def;
660           STMT_VINFO_DEF_TYPE (vinfo_for_stmt (reduc_stmt)) =
661                                                         vect_reduction_def;
662         }
663       else
664         if (vect_print_dump_info (REPORT_DETAILS))
665           fprintf (vect_dump, "Unknown def-use cycle pattern.");
666     }
667
668   VEC_free (tree, heap, worklist);
669   return;
670 }
671
672
673 /* Function vect_insert_into_interleaving_chain.
674
675    Insert DRA into the interleaving chain of DRB according to DRA's INIT.  */
676
677 static void
678 vect_insert_into_interleaving_chain (struct data_reference *dra,
679                                      struct data_reference *drb)
680 {
681   tree prev, next, next_init;
682   stmt_vec_info stmtinfo_a = vinfo_for_stmt (DR_STMT (dra)); 
683   stmt_vec_info stmtinfo_b = vinfo_for_stmt (DR_STMT (drb));
684
685   prev = DR_GROUP_FIRST_DR (stmtinfo_b);
686   next = DR_GROUP_NEXT_DR (vinfo_for_stmt (prev));                
687   while (next)
688     {
689       next_init = DR_INIT (STMT_VINFO_DATA_REF (vinfo_for_stmt (next)));
690       if (tree_int_cst_compare (next_init, DR_INIT (dra)) > 0)
691         {
692           /* Insert here.  */
693           DR_GROUP_NEXT_DR (vinfo_for_stmt (prev)) = DR_STMT (dra);
694           DR_GROUP_NEXT_DR (stmtinfo_a) = next;
695           return;
696         }
697       prev = next;
698       next = DR_GROUP_NEXT_DR (vinfo_for_stmt (prev));
699     }
700
701   /* We got to the end of the list. Insert here.  */
702   DR_GROUP_NEXT_DR (vinfo_for_stmt (prev)) = DR_STMT (dra);
703   DR_GROUP_NEXT_DR (stmtinfo_a) = NULL_TREE;
704 }
705
706
707 /* Function vect_update_interleaving_chain.
708    
709    For two data-refs DRA and DRB that are a part of a chain interleaved data 
710    accesses, update the interleaving chain. DRB's INIT is smaller than DRA's.
711
712    There are four possible cases:
713    1. New stmts - both DRA and DRB are not a part of any chain:
714       FIRST_DR = DRB
715       NEXT_DR (DRB) = DRA
716    2. DRB is a part of a chain and DRA is not:
717       no need to update FIRST_DR
718       no need to insert DRB
719       insert DRA according to init
720    3. DRA is a part of a chain and DRB is not:
721       if (init of FIRST_DR > init of DRB)
722           FIRST_DR = DRB
723           NEXT(FIRST_DR) = previous FIRST_DR
724       else
725           insert DRB according to its init
726    4. both DRA and DRB are in some interleaving chains:
727       choose the chain with the smallest init of FIRST_DR
728       insert the nodes of the second chain into the first one.  */
729
730 static void
731 vect_update_interleaving_chain (struct data_reference *drb,
732                                 struct data_reference *dra)
733 {
734   stmt_vec_info stmtinfo_a = vinfo_for_stmt (DR_STMT (dra)); 
735   stmt_vec_info stmtinfo_b = vinfo_for_stmt (DR_STMT (drb));
736   tree next_init, init_dra_chain, init_drb_chain, first_a, first_b;
737   tree node, prev, next, node_init, first_stmt;
738
739   /* 1. New stmts - both DRA and DRB are not a part of any chain.   */
740   if (!DR_GROUP_FIRST_DR (stmtinfo_a) && !DR_GROUP_FIRST_DR (stmtinfo_b))
741     {
742       DR_GROUP_FIRST_DR (stmtinfo_a) = DR_STMT (drb);
743       DR_GROUP_FIRST_DR (stmtinfo_b) = DR_STMT (drb);
744       DR_GROUP_NEXT_DR (stmtinfo_b) = DR_STMT (dra);
745       return;
746     }
747
748   /* 2. DRB is a part of a chain and DRA is not.  */
749   if (!DR_GROUP_FIRST_DR (stmtinfo_a) && DR_GROUP_FIRST_DR (stmtinfo_b))
750     {
751       DR_GROUP_FIRST_DR (stmtinfo_a) = DR_GROUP_FIRST_DR (stmtinfo_b);
752       /* Insert DRA into the chain of DRB.  */
753       vect_insert_into_interleaving_chain (dra, drb);
754       return;
755     }
756
757   /* 3. DRA is a part of a chain and DRB is not.  */  
758   if (DR_GROUP_FIRST_DR (stmtinfo_a) && !DR_GROUP_FIRST_DR (stmtinfo_b))
759     {
760       tree old_first_stmt = DR_GROUP_FIRST_DR (stmtinfo_a);
761       tree init_old = DR_INIT (STMT_VINFO_DATA_REF (vinfo_for_stmt (
762                                                               old_first_stmt)));
763       tree tmp;
764
765       if (tree_int_cst_compare (init_old, DR_INIT (drb)) > 0)
766         {
767           /* DRB's init is smaller than the init of the stmt previously marked 
768              as the first stmt of the interleaving chain of DRA. Therefore, we 
769              update FIRST_STMT and put DRB in the head of the list.  */
770           DR_GROUP_FIRST_DR (stmtinfo_b) = DR_STMT (drb);
771           DR_GROUP_NEXT_DR (stmtinfo_b) = old_first_stmt;
772                 
773           /* Update all the stmts in the list to point to the new FIRST_STMT.  */
774           tmp = old_first_stmt;
775           while (tmp)
776             {
777               DR_GROUP_FIRST_DR (vinfo_for_stmt (tmp)) = DR_STMT (drb);
778               tmp = DR_GROUP_NEXT_DR (vinfo_for_stmt (tmp));
779             }
780         }
781       else
782         {
783           /* Insert DRB in the list of DRA.  */
784           vect_insert_into_interleaving_chain (drb, dra);
785           DR_GROUP_FIRST_DR (stmtinfo_b) = DR_GROUP_FIRST_DR (stmtinfo_a);            
786         }
787       return;
788     }
789   
790   /* 4. both DRA and DRB are in some interleaving chains.  */
791   first_a = DR_GROUP_FIRST_DR (stmtinfo_a);
792   first_b = DR_GROUP_FIRST_DR (stmtinfo_b);
793   if (first_a == first_b)
794     return;
795   init_dra_chain = DR_INIT (STMT_VINFO_DATA_REF (vinfo_for_stmt (first_a)));
796   init_drb_chain = DR_INIT (STMT_VINFO_DATA_REF (vinfo_for_stmt (first_b)));
797
798   if (tree_int_cst_compare (init_dra_chain, init_drb_chain) > 0)
799     {
800       /* Insert the nodes of DRA chain into the DRB chain.  
801          After inserting a node, continue from this node of the DRB chain (don't
802          start from the beginning.  */
803       node = DR_GROUP_FIRST_DR (stmtinfo_a);
804       prev = DR_GROUP_FIRST_DR (stmtinfo_b);      
805       first_stmt = first_b;
806     }
807   else
808     {
809       /* Insert the nodes of DRB chain into the DRA chain.  
810          After inserting a node, continue from this node of the DRA chain (don't
811          start from the beginning.  */
812       node = DR_GROUP_FIRST_DR (stmtinfo_b);
813       prev = DR_GROUP_FIRST_DR (stmtinfo_a);      
814       first_stmt = first_a;
815     }
816   
817   while (node)
818     {
819       node_init = DR_INIT (STMT_VINFO_DATA_REF (vinfo_for_stmt (node)));
820       next = DR_GROUP_NEXT_DR (vinfo_for_stmt (prev));            
821       while (next)
822         {         
823           next_init = DR_INIT (STMT_VINFO_DATA_REF (vinfo_for_stmt (next)));
824           if (tree_int_cst_compare (next_init, node_init) > 0)
825             {
826               /* Insert here.  */
827               DR_GROUP_NEXT_DR (vinfo_for_stmt (prev)) = node;
828               DR_GROUP_NEXT_DR (vinfo_for_stmt (node)) = next;
829               prev = node;
830               break;
831             }
832           prev = next;
833           next = DR_GROUP_NEXT_DR (vinfo_for_stmt (prev));
834         }
835       if (!next)
836         {
837           /* We got to the end of the list. Insert here.  */
838           DR_GROUP_NEXT_DR (vinfo_for_stmt (prev)) = node;
839           DR_GROUP_NEXT_DR (vinfo_for_stmt (node)) = NULL_TREE;
840           prev = node;
841         }                       
842       DR_GROUP_FIRST_DR (vinfo_for_stmt (node)) = first_stmt;
843       node = DR_GROUP_NEXT_DR (vinfo_for_stmt (node));         
844     }
845 }
846
847
848 /* Function vect_equal_offsets.
849
850    Check if OFFSET1 and OFFSET2 are identical expressions.  */
851
852 static bool
853 vect_equal_offsets (tree offset1, tree offset2)
854 {
855   bool res0, res1;
856
857   STRIP_NOPS (offset1);
858   STRIP_NOPS (offset2);
859
860   if (offset1 == offset2)
861     return true;
862
863   if (TREE_CODE (offset1) != TREE_CODE (offset2)
864       || !BINARY_CLASS_P (offset1)
865       || !BINARY_CLASS_P (offset2))    
866     return false;
867   
868   res0 = vect_equal_offsets (TREE_OPERAND (offset1, 0), 
869                              TREE_OPERAND (offset2, 0));
870   res1 = vect_equal_offsets (TREE_OPERAND (offset1, 1), 
871                              TREE_OPERAND (offset2, 1));
872
873   return (res0 && res1);
874 }
875
876
877 /* Function vect_check_interleaving.
878
879    Check if DRA and DRB are a part of interleaving. In case they are, insert
880    DRA and DRB in an interleaving chain.  */
881
882 static void
883 vect_check_interleaving (struct data_reference *dra,
884                          struct data_reference *drb)
885 {
886   HOST_WIDE_INT type_size_a, type_size_b, diff_mod_size, step, init_a, init_b;
887
888   /* Check that the data-refs have same first location (except init) and they
889      are both either store or load (not load and store).  */
890   if ((DR_BASE_ADDRESS (dra) != DR_BASE_ADDRESS (drb)
891        && (TREE_CODE (DR_BASE_ADDRESS (dra)) != ADDR_EXPR 
892            || TREE_CODE (DR_BASE_ADDRESS (drb)) != ADDR_EXPR
893            || TREE_OPERAND (DR_BASE_ADDRESS (dra), 0) 
894            != TREE_OPERAND (DR_BASE_ADDRESS (drb),0)))
895       || !vect_equal_offsets (DR_OFFSET (dra), DR_OFFSET (drb))
896       || !tree_int_cst_compare (DR_INIT (dra), DR_INIT (drb)) 
897       || DR_IS_READ (dra) != DR_IS_READ (drb))
898     return;
899
900   /* Check:
901      1. data-refs are of the same type
902      2. their steps are equal
903      3. the step is greater than the difference between data-refs' inits  */
904   type_size_a = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (dra))));
905   type_size_b = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (drb))));
906
907   if (type_size_a != type_size_b
908       || tree_int_cst_compare (DR_STEP (dra), DR_STEP (drb)))
909     return;
910
911   init_a = TREE_INT_CST_LOW (DR_INIT (dra));
912   init_b = TREE_INT_CST_LOW (DR_INIT (drb));
913   step = TREE_INT_CST_LOW (DR_STEP (dra));
914
915   if (init_a > init_b)
916     {
917       /* If init_a == init_b + the size of the type * k, we have an interleaving, 
918          and DRB is accessed before DRA.  */
919       diff_mod_size = (init_a - init_b) % type_size_a;
920
921       if ((init_a - init_b) > step)
922          return; 
923
924       if (diff_mod_size == 0)
925         {
926           vect_update_interleaving_chain (drb, dra);      
927           if (vect_print_dump_info (REPORT_DR_DETAILS))
928             {
929               fprintf (vect_dump, "Detected interleaving ");
930               print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
931               fprintf (vect_dump, " and ");
932               print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
933             }
934           return;
935         } 
936     }
937   else 
938     {
939       /* If init_b == init_a + the size of the type * k, we have an 
940          interleaving, and DRA is accessed before DRB.  */
941       diff_mod_size = (init_b - init_a) % type_size_a;
942
943       if ((init_b - init_a) > step)
944          return;
945
946       if (diff_mod_size == 0)
947         {
948           vect_update_interleaving_chain (dra, drb);      
949           if (vect_print_dump_info (REPORT_DR_DETAILS))
950             {
951               fprintf (vect_dump, "Detected interleaving ");
952               print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
953               fprintf (vect_dump, " and ");
954               print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
955             }
956           return;
957         } 
958     }
959 }
960
961
962 /* Function vect_analyze_data_ref_dependence.
963
964    Return TRUE if there (might) exist a dependence between a memory-reference
965    DRA and a memory-reference DRB.  */
966       
967 static bool
968 vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
969                                   loop_vec_info loop_vinfo)
970 {
971   unsigned int i;
972   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
973   int vectorization_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
974   struct data_reference *dra = DDR_A (ddr);
975   struct data_reference *drb = DDR_B (ddr);
976   stmt_vec_info stmtinfo_a = vinfo_for_stmt (DR_STMT (dra)); 
977   stmt_vec_info stmtinfo_b = vinfo_for_stmt (DR_STMT (drb));
978   int dra_size = GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (DR_REF (dra))));
979   int drb_size = GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (DR_REF (drb))));
980   lambda_vector dist_v;
981   unsigned int loop_depth;
982          
983   if (DDR_ARE_DEPENDENT (ddr) == chrec_known)
984     {
985       /* Independent data accesses.  */
986       vect_check_interleaving (dra, drb);
987       return false;
988     }
989
990   if ((DR_IS_READ (dra) && DR_IS_READ (drb)) || dra == drb)
991     return false;
992   
993   if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know)
994     {
995       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
996         {
997           fprintf (vect_dump,
998                    "not vectorized: can't determine dependence between ");
999           print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
1000           fprintf (vect_dump, " and ");
1001           print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
1002         }
1003       return true;
1004     }
1005
1006   if (DDR_NUM_DIST_VECTS (ddr) == 0)
1007     {
1008       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
1009         {
1010           fprintf (vect_dump, "not vectorized: bad dist vector for ");
1011           print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
1012           fprintf (vect_dump, " and ");
1013           print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
1014         }
1015       return true;
1016     }    
1017
1018   loop_depth = index_in_loop_nest (loop->num, DDR_LOOP_NEST (ddr));
1019   for (i = 0; VEC_iterate (lambda_vector, DDR_DIST_VECTS (ddr), i, dist_v); i++)
1020     {
1021       int dist = dist_v[loop_depth];
1022
1023       if (vect_print_dump_info (REPORT_DR_DETAILS))
1024         fprintf (vect_dump, "dependence distance  = %d.", dist);
1025
1026       /* Same loop iteration.  */
1027       if (dist % vectorization_factor == 0 && dra_size == drb_size)
1028         {
1029           /* Two references with distance zero have the same alignment.  */
1030           VEC_safe_push (dr_p, heap, STMT_VINFO_SAME_ALIGN_REFS (stmtinfo_a), drb);
1031           VEC_safe_push (dr_p, heap, STMT_VINFO_SAME_ALIGN_REFS (stmtinfo_b), dra);
1032           if (vect_print_dump_info (REPORT_ALIGNMENT))
1033             fprintf (vect_dump, "accesses have the same alignment.");
1034           if (vect_print_dump_info (REPORT_DR_DETAILS))
1035             {
1036               fprintf (vect_dump, "dependence distance modulo vf == 0 between ");
1037               print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
1038               fprintf (vect_dump, " and ");
1039               print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
1040             }
1041
1042           /* For interleaving, mark that there is a read-write dependency if
1043              necessary. We check before that one of the data-refs is store.  */ 
1044           if (DR_IS_READ (dra))
1045             DR_GROUP_READ_WRITE_DEPENDENCE (stmtinfo_a) = true;
1046           else
1047             {
1048               if (DR_IS_READ (drb))
1049                 DR_GROUP_READ_WRITE_DEPENDENCE (stmtinfo_b) = true;
1050             }
1051           
1052           continue;
1053         }
1054
1055       if (abs (dist) >= vectorization_factor)
1056         {
1057           /* Dependence distance does not create dependence, as far as vectorization
1058              is concerned, in this case.  */
1059           if (vect_print_dump_info (REPORT_DR_DETAILS))
1060             fprintf (vect_dump, "dependence distance >= VF.");
1061           continue;
1062         }
1063
1064       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
1065         {
1066           fprintf (vect_dump,
1067                    "not vectorized: possible dependence between data-refs ");
1068           print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
1069           fprintf (vect_dump, " and ");
1070           print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
1071         }
1072
1073       return true;
1074     }
1075
1076   return false;
1077 }
1078
1079
1080 /* Function vect_analyze_data_ref_dependences.
1081           
1082    Examine all the data references in the loop, and make sure there do not
1083    exist any data dependences between them.  */
1084          
1085 static bool
1086 vect_analyze_data_ref_dependences (loop_vec_info loop_vinfo)
1087 {
1088   unsigned int i;
1089   VEC (ddr_p, heap) *ddrs = LOOP_VINFO_DDRS (loop_vinfo);
1090   struct data_dependence_relation *ddr;
1091
1092   if (vect_print_dump_info (REPORT_DETAILS)) 
1093     fprintf (vect_dump, "=== vect_analyze_dependences ===");
1094      
1095   for (i = 0; VEC_iterate (ddr_p, ddrs, i, ddr); i++)
1096     if (vect_analyze_data_ref_dependence (ddr, loop_vinfo))
1097       return false;
1098
1099   return true;
1100 }
1101
1102
1103 /* Function vect_compute_data_ref_alignment
1104
1105    Compute the misalignment of the data reference DR.
1106
1107    Output:
1108    1. If during the misalignment computation it is found that the data reference
1109       cannot be vectorized then false is returned.
1110    2. DR_MISALIGNMENT (DR) is defined.
1111
1112    FOR NOW: No analysis is actually performed. Misalignment is calculated
1113    only for trivial cases. TODO.  */
1114
1115 static bool
1116 vect_compute_data_ref_alignment (struct data_reference *dr)
1117 {
1118   tree stmt = DR_STMT (dr);
1119   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);  
1120   tree ref = DR_REF (dr);
1121   tree vectype;
1122   tree base, base_addr;
1123   bool base_aligned;
1124   tree misalign;
1125   tree aligned_to, alignment;
1126    
1127   if (vect_print_dump_info (REPORT_DETAILS))
1128     fprintf (vect_dump, "vect_compute_data_ref_alignment:");
1129
1130   /* Initialize misalignment to unknown.  */
1131   DR_MISALIGNMENT (dr) = -1;
1132
1133   misalign = DR_INIT (dr);
1134   aligned_to = DR_ALIGNED_TO (dr);
1135   base_addr = DR_BASE_ADDRESS (dr);
1136   base = build_fold_indirect_ref (base_addr);
1137   vectype = STMT_VINFO_VECTYPE (stmt_info);
1138   alignment = ssize_int (TYPE_ALIGN (vectype)/BITS_PER_UNIT);
1139
1140   if (tree_int_cst_compare (aligned_to, alignment) < 0)
1141     {
1142       if (vect_print_dump_info (REPORT_DETAILS))
1143         {
1144           fprintf (vect_dump, "Unknown alignment for access: ");
1145           print_generic_expr (vect_dump, base, TDF_SLIM);
1146         }
1147       return true;
1148     }
1149
1150   if ((DECL_P (base) 
1151        && tree_int_cst_compare (ssize_int (DECL_ALIGN_UNIT (base)),
1152                                 alignment) >= 0)
1153       || (TREE_CODE (base_addr) == SSA_NAME
1154           && tree_int_cst_compare (ssize_int (TYPE_ALIGN_UNIT (TREE_TYPE (
1155                                                       TREE_TYPE (base_addr)))),
1156                                    alignment) >= 0))
1157     base_aligned = true;
1158   else
1159     base_aligned = false;   
1160
1161   if (!base_aligned) 
1162     {
1163       /* Do not change the alignment of global variables if 
1164          flag_section_anchors is enabled.  */
1165       if (!vect_can_force_dr_alignment_p (base, TYPE_ALIGN (vectype))
1166           || (TREE_STATIC (base) && flag_section_anchors))
1167         {
1168           if (vect_print_dump_info (REPORT_DETAILS))
1169             {
1170               fprintf (vect_dump, "can't force alignment of ref: ");
1171               print_generic_expr (vect_dump, ref, TDF_SLIM);
1172             }
1173           return true;
1174         }
1175       
1176       /* Force the alignment of the decl.
1177          NOTE: This is the only change to the code we make during
1178          the analysis phase, before deciding to vectorize the loop.  */
1179       if (vect_print_dump_info (REPORT_DETAILS))
1180         fprintf (vect_dump, "force alignment");
1181       DECL_ALIGN (base) = TYPE_ALIGN (vectype);
1182       DECL_USER_ALIGN (base) = 1;
1183     }
1184
1185   /* At this point we assume that the base is aligned.  */
1186   gcc_assert (base_aligned
1187               || (TREE_CODE (base) == VAR_DECL 
1188                   && DECL_ALIGN (base) >= TYPE_ALIGN (vectype)));
1189
1190   /* Modulo alignment.  */
1191   misalign = size_binop (TRUNC_MOD_EXPR, misalign, alignment);
1192
1193   if (!host_integerp (misalign, 1))
1194     {
1195       /* Negative or overflowed misalignment value.  */
1196       if (vect_print_dump_info (REPORT_DETAILS))
1197         fprintf (vect_dump, "unexpected misalign value");
1198       return false;
1199     }
1200
1201   DR_MISALIGNMENT (dr) = TREE_INT_CST_LOW (misalign);
1202
1203   if (vect_print_dump_info (REPORT_DETAILS))
1204     {
1205       fprintf (vect_dump, "misalign = %d bytes of ref ", DR_MISALIGNMENT (dr));
1206       print_generic_expr (vect_dump, ref, TDF_SLIM);
1207     }
1208
1209   return true;
1210 }
1211
1212
1213 /* Function vect_compute_data_refs_alignment
1214
1215    Compute the misalignment of data references in the loop.
1216    Return FALSE if a data reference is found that cannot be vectorized.  */
1217
1218 static bool
1219 vect_compute_data_refs_alignment (loop_vec_info loop_vinfo)
1220 {
1221   VEC (data_reference_p, heap) *datarefs = LOOP_VINFO_DATAREFS (loop_vinfo);
1222   struct data_reference *dr;
1223   unsigned int i;
1224
1225   for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++)
1226     if (!vect_compute_data_ref_alignment (dr))
1227       return false;
1228
1229   return true;
1230 }
1231
1232
1233 /* Function vect_update_misalignment_for_peel
1234
1235    DR - the data reference whose misalignment is to be adjusted.
1236    DR_PEEL - the data reference whose misalignment is being made
1237              zero in the vector loop by the peel.
1238    NPEEL - the number of iterations in the peel loop if the misalignment
1239            of DR_PEEL is known at compile time.  */
1240
1241 static void
1242 vect_update_misalignment_for_peel (struct data_reference *dr,
1243                                    struct data_reference *dr_peel, int npeel)
1244 {
1245   unsigned int i;
1246   VEC(dr_p,heap) *same_align_drs;
1247   struct data_reference *current_dr;
1248   int dr_size = GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (DR_REF (dr))));
1249   int dr_peel_size = GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (DR_REF (dr_peel))));
1250   stmt_vec_info stmt_info = vinfo_for_stmt (DR_STMT (dr));
1251   stmt_vec_info peel_stmt_info = vinfo_for_stmt (DR_STMT (dr_peel));
1252
1253  /* For interleaved data accesses the step in the loop must be multiplied by
1254      the size of the interleaving group.  */
1255   if (DR_GROUP_FIRST_DR (stmt_info))
1256     dr_size *= DR_GROUP_SIZE (vinfo_for_stmt (DR_GROUP_FIRST_DR (stmt_info)));
1257   if (DR_GROUP_FIRST_DR (peel_stmt_info))
1258     dr_peel_size *= DR_GROUP_SIZE (peel_stmt_info);
1259
1260   /* It can be assumed that the data refs with the same alignment as dr_peel
1261      are aligned in the vector loop.  */
1262   same_align_drs
1263     = STMT_VINFO_SAME_ALIGN_REFS (vinfo_for_stmt (DR_STMT (dr_peel)));
1264   for (i = 0; VEC_iterate (dr_p, same_align_drs, i, current_dr); i++)
1265     {
1266       if (current_dr != dr)
1267         continue;
1268       gcc_assert (DR_MISALIGNMENT (dr) / dr_size ==
1269                   DR_MISALIGNMENT (dr_peel) / dr_peel_size);
1270       DR_MISALIGNMENT (dr) = 0;
1271       return;
1272     }
1273
1274   if (known_alignment_for_access_p (dr)
1275       && known_alignment_for_access_p (dr_peel))
1276     {
1277       DR_MISALIGNMENT (dr) += npeel * dr_size;
1278       DR_MISALIGNMENT (dr) %= UNITS_PER_SIMD_WORD;
1279       return;
1280     }
1281
1282   if (vect_print_dump_info (REPORT_DETAILS))
1283     fprintf (vect_dump, "Setting misalignment to -1.");
1284   DR_MISALIGNMENT (dr) = -1;
1285 }
1286
1287
1288 /* Function vect_verify_datarefs_alignment
1289
1290    Return TRUE if all data references in the loop can be
1291    handled with respect to alignment.  */
1292
1293 static bool
1294 vect_verify_datarefs_alignment (loop_vec_info loop_vinfo)
1295 {
1296   VEC (data_reference_p, heap) *datarefs = LOOP_VINFO_DATAREFS (loop_vinfo);
1297   struct data_reference *dr;
1298   enum dr_alignment_support supportable_dr_alignment;
1299   unsigned int i;
1300
1301   for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++)
1302     {
1303       tree stmt = DR_STMT (dr);
1304       stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
1305
1306       /* For interleaving, only the alignment of the first access matters.  */
1307       if (DR_GROUP_FIRST_DR (stmt_info)
1308           && DR_GROUP_FIRST_DR (stmt_info) != stmt)
1309         continue;
1310
1311       supportable_dr_alignment = vect_supportable_dr_alignment (dr);
1312       if (!supportable_dr_alignment)
1313         {
1314           if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
1315             {
1316               if (DR_IS_READ (dr))
1317                 fprintf (vect_dump, 
1318                          "not vectorized: unsupported unaligned load.");
1319               else
1320                 fprintf (vect_dump, 
1321                          "not vectorized: unsupported unaligned store.");
1322             }
1323           return false;
1324         }
1325       if (supportable_dr_alignment != dr_aligned
1326           && vect_print_dump_info (REPORT_ALIGNMENT))
1327         fprintf (vect_dump, "Vectorizing an unaligned access.");
1328     }
1329   return true;
1330 }
1331
1332
1333 /* Function vect_enhance_data_refs_alignment
1334
1335    This pass will use loop versioning and loop peeling in order to enhance
1336    the alignment of data references in the loop.
1337
1338    FOR NOW: we assume that whatever versioning/peeling takes place, only the
1339    original loop is to be vectorized; Any other loops that are created by
1340    the transformations performed in this pass - are not supposed to be
1341    vectorized. This restriction will be relaxed.
1342
1343    This pass will require a cost model to guide it whether to apply peeling
1344    or versioning or a combination of the two. For example, the scheme that
1345    intel uses when given a loop with several memory accesses, is as follows:
1346    choose one memory access ('p') which alignment you want to force by doing
1347    peeling. Then, either (1) generate a loop in which 'p' is aligned and all
1348    other accesses are not necessarily aligned, or (2) use loop versioning to
1349    generate one loop in which all accesses are aligned, and another loop in
1350    which only 'p' is necessarily aligned.
1351
1352    ("Automatic Intra-Register Vectorization for the Intel Architecture",
1353    Aart J.C. Bik, Milind Girkar, Paul M. Grey and Ximmin Tian, International
1354    Journal of Parallel Programming, Vol. 30, No. 2, April 2002.)
1355
1356    Devising a cost model is the most critical aspect of this work. It will
1357    guide us on which access to peel for, whether to use loop versioning, how
1358    many versions to create, etc. The cost model will probably consist of
1359    generic considerations as well as target specific considerations (on
1360    powerpc for example, misaligned stores are more painful than misaligned
1361    loads).
1362
1363    Here are the general steps involved in alignment enhancements:
1364
1365      -- original loop, before alignment analysis:
1366         for (i=0; i<N; i++){
1367           x = q[i];                     # DR_MISALIGNMENT(q) = unknown
1368           p[i] = y;                     # DR_MISALIGNMENT(p) = unknown
1369         }
1370
1371      -- After vect_compute_data_refs_alignment:
1372         for (i=0; i<N; i++){
1373           x = q[i];                     # DR_MISALIGNMENT(q) = 3
1374           p[i] = y;                     # DR_MISALIGNMENT(p) = unknown
1375         }
1376
1377      -- Possibility 1: we do loop versioning:
1378      if (p is aligned) {
1379         for (i=0; i<N; i++){    # loop 1A
1380           x = q[i];                     # DR_MISALIGNMENT(q) = 3
1381           p[i] = y;                     # DR_MISALIGNMENT(p) = 0
1382         }
1383      }
1384      else {
1385         for (i=0; i<N; i++){    # loop 1B
1386           x = q[i];                     # DR_MISALIGNMENT(q) = 3
1387           p[i] = y;                     # DR_MISALIGNMENT(p) = unaligned
1388         }
1389      }
1390
1391      -- Possibility 2: we do loop peeling:
1392      for (i = 0; i < 3; i++){   # (scalar loop, not to be vectorized).
1393         x = q[i];
1394         p[i] = y;
1395      }
1396      for (i = 3; i < N; i++){   # loop 2A
1397         x = q[i];                       # DR_MISALIGNMENT(q) = 0
1398         p[i] = y;                       # DR_MISALIGNMENT(p) = unknown
1399      }
1400
1401      -- Possibility 3: combination of loop peeling and versioning:
1402      for (i = 0; i < 3; i++){   # (scalar loop, not to be vectorized).
1403         x = q[i];
1404         p[i] = y;
1405      }
1406      if (p is aligned) {
1407         for (i = 3; i<N; i++){  # loop 3A
1408           x = q[i];                     # DR_MISALIGNMENT(q) = 0
1409           p[i] = y;                     # DR_MISALIGNMENT(p) = 0
1410         }
1411      }
1412      else {
1413         for (i = 3; i<N; i++){  # loop 3B
1414           x = q[i];                     # DR_MISALIGNMENT(q) = 0
1415           p[i] = y;                     # DR_MISALIGNMENT(p) = unaligned
1416         }
1417      }
1418
1419      These loops are later passed to loop_transform to be vectorized. The
1420      vectorizer will use the alignment information to guide the transformation
1421      (whether to generate regular loads/stores, or with special handling for
1422      misalignment).  */
1423
1424 static bool
1425 vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
1426 {
1427   VEC (data_reference_p, heap) *datarefs = LOOP_VINFO_DATAREFS (loop_vinfo);
1428   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
1429   enum dr_alignment_support supportable_dr_alignment;
1430   struct data_reference *dr0 = NULL;
1431   struct data_reference *dr;
1432   unsigned int i;
1433   bool do_peeling = false;
1434   bool do_versioning = false;
1435   bool stat;
1436   tree stmt;
1437   stmt_vec_info stmt_info;
1438
1439   if (vect_print_dump_info (REPORT_DETAILS))
1440     fprintf (vect_dump, "=== vect_enhance_data_refs_alignment ===");
1441
1442   /* While cost model enhancements are expected in the future, the high level
1443      view of the code at this time is as follows:
1444
1445      A) If there is a misaligned write then see if peeling to align this write
1446         can make all data references satisfy vect_supportable_dr_alignment.
1447         If so, update data structures as needed and return true.  Note that
1448         at this time vect_supportable_dr_alignment is known to return false
1449         for a misaligned write.
1450
1451      B) If peeling wasn't possible and there is a data reference with an
1452         unknown misalignment that does not satisfy vect_supportable_dr_alignment
1453         then see if loop versioning checks can be used to make all data
1454         references satisfy vect_supportable_dr_alignment.  If so, update
1455         data structures as needed and return true.
1456
1457      C) If neither peeling nor versioning were successful then return false if
1458         any data reference does not satisfy vect_supportable_dr_alignment.
1459
1460      D) Return true (all data references satisfy vect_supportable_dr_alignment).
1461
1462      Note, Possibility 3 above (which is peeling and versioning together) is not
1463      being done at this time.  */
1464
1465   /* (1) Peeling to force alignment.  */
1466
1467   /* (1.1) Decide whether to perform peeling, and how many iterations to peel:
1468      Considerations:
1469      + How many accesses will become aligned due to the peeling
1470      - How many accesses will become unaligned due to the peeling,
1471        and the cost of misaligned accesses.
1472      - The cost of peeling (the extra runtime checks, the increase 
1473        in code size).
1474
1475      The scheme we use FORNOW: peel to force the alignment of the first
1476      misaligned store in the loop.
1477      Rationale: misaligned stores are not yet supported.
1478
1479      TODO: Use a cost model.  */
1480
1481   for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++)
1482     {
1483       stmt = DR_STMT (dr);
1484       stmt_info = vinfo_for_stmt (stmt);
1485
1486       /* For interleaving, only the alignment of the first access
1487          matters.  */
1488       if (DR_GROUP_FIRST_DR (stmt_info)
1489           && DR_GROUP_FIRST_DR (stmt_info) != stmt)
1490         continue;
1491
1492       if (!DR_IS_READ (dr) && !aligned_access_p (dr))
1493         {
1494           if (DR_GROUP_FIRST_DR (stmt_info))
1495             {
1496               /* For interleaved access we peel only if number of iterations in
1497                  the prolog loop ({VF - misalignment}), is a multiple of the
1498                  number of the interleaved accesses.  */
1499               int elem_size, mis_in_elements;
1500               tree vectype = STMT_VINFO_VECTYPE (stmt_info);
1501               int nelements = TYPE_VECTOR_SUBPARTS (vectype);
1502
1503               /* FORNOW: handle only known alignment.  */
1504               if (!known_alignment_for_access_p (dr))
1505                 {
1506                   do_peeling = false;
1507                   break;
1508                 }
1509
1510               elem_size = UNITS_PER_SIMD_WORD / nelements;
1511               mis_in_elements = DR_MISALIGNMENT (dr) / elem_size;
1512
1513               if ((nelements - mis_in_elements) % DR_GROUP_SIZE (stmt_info))
1514                 {
1515                   do_peeling = false;
1516                   break;
1517                 }
1518             }
1519           dr0 = dr;
1520           do_peeling = true;
1521           break;
1522         }
1523     }
1524
1525   /* Often peeling for alignment will require peeling for loop-bound, which in 
1526      turn requires that we know how to adjust the loop ivs after the loop.  */
1527   if (!vect_can_advance_ivs_p (loop_vinfo)
1528       || !slpeel_can_duplicate_loop_p (loop, single_exit (loop)))
1529     do_peeling = false;
1530
1531   if (do_peeling)
1532     {
1533       int mis;
1534       int npeel = 0;
1535       tree stmt = DR_STMT (dr0);
1536       stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
1537       tree vectype = STMT_VINFO_VECTYPE (stmt_info);
1538       int nelements = TYPE_VECTOR_SUBPARTS (vectype);
1539
1540       if (known_alignment_for_access_p (dr0))
1541         {
1542           /* Since it's known at compile time, compute the number of iterations
1543              in the peeled loop (the peeling factor) for use in updating
1544              DR_MISALIGNMENT values.  The peeling factor is the vectorization
1545              factor minus the misalignment as an element count.  */
1546           mis = DR_MISALIGNMENT (dr0);
1547           mis /= GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (DR_REF (dr0))));
1548           npeel = nelements - mis;
1549
1550           /* For interleaved data access every iteration accesses all the 
1551              members of the group, therefore we divide the number of iterations
1552              by the group size.  */
1553           stmt_info = vinfo_for_stmt (DR_STMT (dr0));     
1554           if (DR_GROUP_FIRST_DR (stmt_info))
1555             npeel /= DR_GROUP_SIZE (stmt_info);
1556
1557           if (vect_print_dump_info (REPORT_DETAILS))
1558             fprintf (vect_dump, "Try peeling by %d", npeel);
1559         }
1560
1561       /* Ensure that all data refs can be vectorized after the peel.  */
1562       for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++)
1563         {
1564           int save_misalignment;
1565
1566           if (dr == dr0)
1567             continue;
1568
1569           stmt = DR_STMT (dr);
1570           stmt_info = vinfo_for_stmt (stmt);
1571           /* For interleaving, only the alignment of the first access
1572             matters.  */
1573           if (DR_GROUP_FIRST_DR (stmt_info)
1574               && DR_GROUP_FIRST_DR (stmt_info) != stmt)
1575             continue;
1576
1577           save_misalignment = DR_MISALIGNMENT (dr);
1578           vect_update_misalignment_for_peel (dr, dr0, npeel);
1579           supportable_dr_alignment = vect_supportable_dr_alignment (dr);
1580           DR_MISALIGNMENT (dr) = save_misalignment;
1581           
1582           if (!supportable_dr_alignment)
1583             {
1584               do_peeling = false;
1585               break;
1586             }
1587         }
1588
1589       if (do_peeling)
1590         {
1591           /* (1.2) Update the DR_MISALIGNMENT of each data reference DR_i.
1592              If the misalignment of DR_i is identical to that of dr0 then set
1593              DR_MISALIGNMENT (DR_i) to zero.  If the misalignment of DR_i and
1594              dr0 are known at compile time then increment DR_MISALIGNMENT (DR_i)
1595              by the peeling factor times the element size of DR_i (MOD the
1596              vectorization factor times the size).  Otherwise, the
1597              misalignment of DR_i must be set to unknown.  */
1598           for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++)
1599             if (dr != dr0)
1600               vect_update_misalignment_for_peel (dr, dr0, npeel);
1601
1602           LOOP_VINFO_UNALIGNED_DR (loop_vinfo) = dr0;
1603           LOOP_PEELING_FOR_ALIGNMENT (loop_vinfo) = DR_MISALIGNMENT (dr0);
1604           DR_MISALIGNMENT (dr0) = 0;
1605           if (vect_print_dump_info (REPORT_ALIGNMENT))
1606             fprintf (vect_dump, "Alignment of access forced using peeling.");
1607
1608           if (vect_print_dump_info (REPORT_DETAILS))
1609             fprintf (vect_dump, "Peeling for alignment will be applied.");
1610
1611           stat = vect_verify_datarefs_alignment (loop_vinfo);
1612           gcc_assert (stat);
1613           return stat;
1614         }
1615     }
1616
1617
1618   /* (2) Versioning to force alignment.  */
1619
1620   /* Try versioning if:
1621      1) flag_tree_vect_loop_version is TRUE
1622      2) optimize_size is FALSE
1623      3) there is at least one unsupported misaligned data ref with an unknown
1624         misalignment, and
1625      4) all misaligned data refs with a known misalignment are supported, and
1626      5) the number of runtime alignment checks is within reason.  */
1627
1628   do_versioning = flag_tree_vect_loop_version && (!optimize_size);
1629
1630   if (do_versioning)
1631     {
1632       for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++)
1633         {
1634           stmt = DR_STMT (dr);
1635           stmt_info = vinfo_for_stmt (stmt);
1636
1637           /* For interleaving, only the alignment of the first access
1638              matters.  */
1639           if (aligned_access_p (dr)
1640               || (DR_GROUP_FIRST_DR (stmt_info)
1641                   && DR_GROUP_FIRST_DR (stmt_info) != stmt))
1642             continue;
1643
1644           supportable_dr_alignment = vect_supportable_dr_alignment (dr);
1645
1646           if (!supportable_dr_alignment)
1647             {
1648               tree stmt;
1649               int mask;
1650               tree vectype;
1651
1652               if (known_alignment_for_access_p (dr)
1653                   || VEC_length (tree,
1654                                  LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo))
1655                      >= (unsigned) PARAM_VALUE (PARAM_VECT_MAX_VERSION_CHECKS))
1656                 {
1657                   do_versioning = false;
1658                   break;
1659                 }
1660
1661               stmt = DR_STMT (dr);
1662               vectype = STMT_VINFO_VECTYPE (vinfo_for_stmt (stmt));
1663               gcc_assert (vectype);
1664   
1665               /* The rightmost bits of an aligned address must be zeros.
1666                  Construct the mask needed for this test.  For example,
1667                  GET_MODE_SIZE for the vector mode V4SI is 16 bytes so the
1668                  mask must be 15 = 0xf. */
1669               mask = GET_MODE_SIZE (TYPE_MODE (vectype)) - 1;
1670
1671               /* FORNOW: use the same mask to test all potentially unaligned
1672                  references in the loop.  The vectorizer currently supports
1673                  a single vector size, see the reference to
1674                  GET_MODE_NUNITS (TYPE_MODE (vectype)) where the
1675                  vectorization factor is computed.  */
1676               gcc_assert (!LOOP_VINFO_PTR_MASK (loop_vinfo)
1677                           || LOOP_VINFO_PTR_MASK (loop_vinfo) == mask);
1678               LOOP_VINFO_PTR_MASK (loop_vinfo) = mask;
1679               VEC_safe_push (tree, heap,
1680                              LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo),
1681                              DR_STMT (dr));
1682             }
1683         }
1684       
1685       /* Versioning requires at least one misaligned data reference.  */
1686       if (VEC_length (tree, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo)) == 0)
1687         do_versioning = false;
1688       else if (!do_versioning)
1689         VEC_truncate (tree, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo), 0);
1690     }
1691
1692   if (do_versioning)
1693     {
1694       VEC(tree,heap) *may_misalign_stmts
1695         = LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo);
1696       tree stmt;
1697
1698       /* It can now be assumed that the data references in the statements
1699          in LOOP_VINFO_MAY_MISALIGN_STMTS will be aligned in the version
1700          of the loop being vectorized.  */
1701       for (i = 0; VEC_iterate (tree, may_misalign_stmts, i, stmt); i++)
1702         {
1703           stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
1704           dr = STMT_VINFO_DATA_REF (stmt_info);
1705           DR_MISALIGNMENT (dr) = 0;
1706           if (vect_print_dump_info (REPORT_ALIGNMENT))
1707             fprintf (vect_dump, "Alignment of access forced using versioning.");
1708         }
1709
1710       if (vect_print_dump_info (REPORT_DETAILS))
1711         fprintf (vect_dump, "Versioning for alignment will be applied.");
1712
1713       /* Peeling and versioning can't be done together at this time.  */
1714       gcc_assert (! (do_peeling && do_versioning));
1715
1716       stat = vect_verify_datarefs_alignment (loop_vinfo);
1717       gcc_assert (stat);
1718       return stat;
1719     }
1720
1721   /* This point is reached if neither peeling nor versioning is being done.  */
1722   gcc_assert (! (do_peeling || do_versioning));
1723
1724   stat = vect_verify_datarefs_alignment (loop_vinfo);
1725   return stat;
1726 }
1727
1728
1729 /* Function vect_analyze_data_refs_alignment
1730
1731    Analyze the alignment of the data-references in the loop.
1732    Return FALSE if a data reference is found that cannot be vectorized.  */
1733
1734 static bool
1735 vect_analyze_data_refs_alignment (loop_vec_info loop_vinfo)
1736 {
1737   if (vect_print_dump_info (REPORT_DETAILS))
1738     fprintf (vect_dump, "=== vect_analyze_data_refs_alignment ===");
1739
1740   if (!vect_compute_data_refs_alignment (loop_vinfo))
1741     {
1742       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
1743         fprintf (vect_dump, 
1744                  "not vectorized: can't calculate alignment for data ref.");
1745       return false;
1746     }
1747
1748   return true;
1749 }
1750
1751
1752 /* Function vect_analyze_data_ref_access.
1753
1754    Analyze the access pattern of the data-reference DR. For now, a data access
1755    has to be consecutive to be considered vectorizable.  */
1756
1757 static bool
1758 vect_analyze_data_ref_access (struct data_reference *dr)
1759 {
1760   tree step = DR_STEP (dr);
1761   HOST_WIDE_INT dr_step = TREE_INT_CST_LOW (step);
1762   tree scalar_type = TREE_TYPE (DR_REF (dr));
1763   HOST_WIDE_INT type_size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (scalar_type));
1764   tree stmt = DR_STMT (dr);
1765   /* For interleaving, STRIDE is STEP counted in elements, i.e., the size of the 
1766      interleaving group (including gaps).  */
1767   HOST_WIDE_INT stride = dr_step / type_size;
1768
1769   if (!step)
1770     {
1771       if (vect_print_dump_info (REPORT_DETAILS))
1772         fprintf (vect_dump, "bad data-ref access");
1773       return false;
1774     }
1775
1776   /* Consecutive?  */
1777   if (!tree_int_cst_compare (step, TYPE_SIZE_UNIT (scalar_type)))
1778     {
1779       /* Mark that it is not interleaving.  */
1780       DR_GROUP_FIRST_DR (vinfo_for_stmt (stmt)) = NULL_TREE;
1781       return true;
1782     }
1783
1784   /* Not consecutive access is possible only if it is a part of interleaving.  */
1785   if (!DR_GROUP_FIRST_DR (vinfo_for_stmt (stmt)))
1786     {
1787       /* Check if it this DR is a part of interleaving, and is a single
1788          element of the group that is accessed in the loop.  */
1789       
1790       /* Gaps are supported only for loads. STEP must be a multiple of the type
1791          size.  The size of the group must be a power of 2.  */
1792       if (DR_IS_READ (dr)
1793           && (dr_step % type_size) == 0
1794           && stride > 0
1795           && exact_log2 (stride) != -1)
1796         {
1797           DR_GROUP_FIRST_DR (vinfo_for_stmt (stmt)) = stmt;
1798           DR_GROUP_SIZE (vinfo_for_stmt (stmt)) = stride;
1799           if (vect_print_dump_info (REPORT_DR_DETAILS))
1800             {
1801               fprintf (vect_dump, "Detected single element interleaving %d ",
1802                        DR_GROUP_SIZE (vinfo_for_stmt (stmt)));
1803               print_generic_expr (vect_dump, DR_REF (dr), TDF_SLIM);
1804               fprintf (vect_dump, " step ");
1805               print_generic_expr (vect_dump, step, TDF_SLIM);
1806             }
1807           return true;
1808         }
1809       if (vect_print_dump_info (REPORT_DETAILS))
1810         fprintf (vect_dump, "not consecutive access");
1811       return false;
1812     }
1813
1814   if (DR_GROUP_FIRST_DR (vinfo_for_stmt (stmt)) == stmt)
1815     {
1816       /* First stmt in the interleaving chain. Check the chain.  */
1817       tree next = DR_GROUP_NEXT_DR (vinfo_for_stmt (stmt));
1818       struct data_reference *data_ref = dr;
1819       unsigned int count = 1;
1820       tree next_step;
1821       tree prev_init = DR_INIT (data_ref);
1822       tree prev = stmt;
1823       HOST_WIDE_INT diff, count_in_bytes;
1824
1825       while (next)
1826         {
1827           /* Skip same data-refs. In case that two or more stmts share data-ref
1828              (supported only for loads), we vectorize only the first stmt, and
1829              the rest get their vectorized loads from the first one.  */
1830           if (!tree_int_cst_compare (DR_INIT (data_ref),
1831                                      DR_INIT (STMT_VINFO_DATA_REF (
1832                                                       vinfo_for_stmt (next)))))
1833             {
1834               if (!DR_IS_READ (data_ref))
1835                 { 
1836                   if (vect_print_dump_info (REPORT_DETAILS))
1837                     fprintf (vect_dump, "Two store stmts share the same dr.");
1838                   return false; 
1839                 }
1840
1841               /* Check that there is no load-store dependencies for this loads 
1842                  to prevent a case of load-store-load to the same location.  */
1843               if (DR_GROUP_READ_WRITE_DEPENDENCE (vinfo_for_stmt (next))
1844                   || DR_GROUP_READ_WRITE_DEPENDENCE (vinfo_for_stmt (prev)))
1845                 {
1846                   if (vect_print_dump_info (REPORT_DETAILS))
1847                     fprintf (vect_dump, 
1848                              "READ_WRITE dependence in interleaving.");
1849                   return false;
1850                 }
1851
1852               /* For load use the same data-ref load.  */
1853               DR_GROUP_SAME_DR_STMT (vinfo_for_stmt (next)) = prev;
1854
1855               prev = next;
1856               next = DR_GROUP_NEXT_DR (vinfo_for_stmt (next));
1857               continue;
1858             }
1859           prev = next;
1860
1861           /* Check that all the accesses have the same STEP.  */
1862           next_step = DR_STEP (STMT_VINFO_DATA_REF (vinfo_for_stmt (next)));
1863           if (tree_int_cst_compare (step, next_step))
1864             {
1865               if (vect_print_dump_info (REPORT_DETAILS))
1866                 fprintf (vect_dump, "not consecutive access in interleaving");
1867               return false;
1868             }
1869
1870           data_ref = STMT_VINFO_DATA_REF (vinfo_for_stmt (next));
1871           /* Check that the distance between two accesses is equal to the type
1872              size. Otherwise, we have gaps.  */
1873           diff = (TREE_INT_CST_LOW (DR_INIT (data_ref)) 
1874                   - TREE_INT_CST_LOW (prev_init)) / type_size;
1875           if (!DR_IS_READ (data_ref) && diff != 1)
1876             {
1877               if (vect_print_dump_info (REPORT_DETAILS))
1878                 fprintf (vect_dump, "interleaved store with gaps");
1879               return false;
1880             }
1881           /* Store the gap from the previous member of the group. If there is no
1882              gap in the access, DR_GROUP_GAP is always 1.  */
1883           DR_GROUP_GAP (vinfo_for_stmt (next)) = diff;
1884
1885           prev_init = DR_INIT (data_ref);
1886           next = DR_GROUP_NEXT_DR (vinfo_for_stmt (next));
1887           /* Count the number of data-refs in the chain.  */
1888           count++;
1889         }
1890
1891       /* COUNT is the number of accesses found, we multiply it by the size of 
1892          the type to get COUNT_IN_BYTES.  */
1893       count_in_bytes = type_size * count;
1894
1895       /* Check that the size of the interleaving is not greater than STEP.  */
1896       if (dr_step < count_in_bytes) 
1897         {
1898           if (vect_print_dump_info (REPORT_DETAILS))
1899             {
1900               fprintf (vect_dump, "interleaving size is greater than step for ");
1901               print_generic_expr (vect_dump, DR_REF (dr), TDF_SLIM); 
1902             }
1903           return false;
1904         }
1905
1906       /* Check that the size of the interleaving is equal to STEP for stores, 
1907          i.e., that there are no gaps.  */ 
1908       if (!DR_IS_READ (dr) && dr_step != count_in_bytes) 
1909         {
1910           if (vect_print_dump_info (REPORT_DETAILS))
1911             fprintf (vect_dump, "interleaved store with gaps");
1912           return false;
1913         }
1914
1915       /* Check that STEP is a multiple of type size.  */
1916       if ((dr_step % type_size) != 0)
1917         {
1918           if (vect_print_dump_info (REPORT_DETAILS)) 
1919             {
1920               fprintf (vect_dump, "step is not a multiple of type size: step ");
1921               print_generic_expr (vect_dump, step, TDF_SLIM);
1922               fprintf (vect_dump, " size ");
1923               print_generic_expr (vect_dump, TYPE_SIZE_UNIT (scalar_type),
1924                                   TDF_SLIM);
1925             }
1926           return false;
1927         }
1928
1929       /* FORNOW: we handle only interleaving that is a power of 2.  */
1930       if (exact_log2 (stride) == -1)
1931         {
1932           if (vect_print_dump_info (REPORT_DETAILS))
1933             fprintf (vect_dump, "interleaving is not a power of 2");
1934           return false;
1935         }
1936       DR_GROUP_SIZE (vinfo_for_stmt (stmt)) = stride;
1937     }
1938   return true;
1939 }
1940
1941
1942 /* Function vect_analyze_data_ref_accesses.
1943
1944    Analyze the access pattern of all the data references in the loop.
1945
1946    FORNOW: the only access pattern that is considered vectorizable is a
1947            simple step 1 (consecutive) access.
1948
1949    FORNOW: handle only arrays and pointer accesses.  */
1950
1951 static bool
1952 vect_analyze_data_ref_accesses (loop_vec_info loop_vinfo)
1953 {
1954   unsigned int i;
1955   VEC (data_reference_p, heap) *datarefs = LOOP_VINFO_DATAREFS (loop_vinfo);
1956   struct data_reference *dr;
1957
1958   if (vect_print_dump_info (REPORT_DETAILS))
1959     fprintf (vect_dump, "=== vect_analyze_data_ref_accesses ===");
1960
1961   for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++)
1962     if (!vect_analyze_data_ref_access (dr))
1963       {
1964         if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
1965           fprintf (vect_dump, "not vectorized: complicated access pattern.");
1966         return false;
1967       }
1968
1969   return true;
1970 }
1971
1972
1973 /* Function vect_analyze_data_refs.
1974
1975   Find all the data references in the loop.
1976
1977    The general structure of the analysis of data refs in the vectorizer is as
1978    follows:
1979    1- vect_analyze_data_refs(loop): call compute_data_dependences_for_loop to
1980       find and analyze all data-refs in the loop and their dependences.
1981    2- vect_analyze_dependences(): apply dependence testing using ddrs.
1982    3- vect_analyze_drs_alignment(): check that ref_stmt.alignment is ok.
1983    4- vect_analyze_drs_access(): check that ref_stmt.step is ok.
1984
1985 */
1986
1987 static bool
1988 vect_analyze_data_refs (loop_vec_info loop_vinfo)  
1989 {
1990   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
1991   unsigned int i;
1992   VEC (data_reference_p, heap) *datarefs;
1993   struct data_reference *dr;
1994   tree scalar_type;
1995
1996   if (vect_print_dump_info (REPORT_DETAILS))
1997     fprintf (vect_dump, "=== vect_analyze_data_refs ===\n");
1998
1999   compute_data_dependences_for_loop (loop, true,
2000                                      &LOOP_VINFO_DATAREFS (loop_vinfo),
2001                                      &LOOP_VINFO_DDRS (loop_vinfo));
2002
2003   /* Go through the data-refs, check that the analysis succeeded. Update pointer
2004      from stmt_vec_info struct to DR and vectype.  */
2005   datarefs = LOOP_VINFO_DATAREFS (loop_vinfo);
2006
2007   for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++)
2008     {
2009       tree stmt;
2010       stmt_vec_info stmt_info;
2011    
2012       if (!dr || !DR_REF (dr))
2013         {
2014           if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
2015             fprintf (vect_dump, "not vectorized: unhandled data-ref ");
2016           return false;
2017         }
2018  
2019       /* Update DR field in stmt_vec_info struct.  */
2020       stmt = DR_STMT (dr);
2021       stmt_info = vinfo_for_stmt (stmt);
2022
2023       if (STMT_VINFO_DATA_REF (stmt_info))
2024         {
2025           if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
2026             {
2027               fprintf (vect_dump,
2028                        "not vectorized: more than one data ref in stmt: ");
2029               print_generic_expr (vect_dump, stmt, TDF_SLIM);
2030             }
2031           return false;
2032         }
2033       STMT_VINFO_DATA_REF (stmt_info) = dr;
2034      
2035       /* Check that analysis of the data-ref succeeded.  */
2036       if (!DR_BASE_ADDRESS (dr) || !DR_OFFSET (dr) || !DR_INIT (dr)
2037           || !DR_STEP (dr))   
2038         {
2039           if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
2040             {
2041               fprintf (vect_dump, "not vectorized: data ref analysis failed ");
2042               print_generic_expr (vect_dump, stmt, TDF_SLIM);
2043             }
2044           return false;
2045         }
2046       if (!DR_SYMBOL_TAG (dr))
2047         {
2048           if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
2049             {
2050               fprintf (vect_dump, "not vectorized: no memory tag for ");
2051               print_generic_expr (vect_dump, DR_REF (dr), TDF_SLIM);
2052             }
2053           return false;
2054         }
2055                        
2056       /* Set vectype for STMT.  */
2057       scalar_type = TREE_TYPE (DR_REF (dr));
2058       STMT_VINFO_VECTYPE (stmt_info) =
2059                 get_vectype_for_scalar_type (scalar_type);
2060       if (!STMT_VINFO_VECTYPE (stmt_info)) 
2061         {
2062           if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
2063             {
2064               fprintf (vect_dump,
2065                        "not vectorized: no vectype for stmt: ");
2066               print_generic_expr (vect_dump, stmt, TDF_SLIM);
2067               fprintf (vect_dump, " scalar_type: ");
2068               print_generic_expr (vect_dump, scalar_type, TDF_DETAILS);
2069             }
2070           return false;
2071         }
2072     }
2073       
2074   return true;
2075 }
2076
2077
2078 /* Utility functions used by vect_mark_stmts_to_be_vectorized.  */
2079
2080 /* Function vect_mark_relevant.
2081
2082    Mark STMT as "relevant for vectorization" and add it to WORKLIST.  */
2083
2084 static void
2085 vect_mark_relevant (VEC(tree,heap) **worklist, tree stmt,
2086                     enum vect_relevant relevant, bool live_p)
2087 {
2088   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
2089   enum vect_relevant save_relevant = STMT_VINFO_RELEVANT (stmt_info);
2090   bool save_live_p = STMT_VINFO_LIVE_P (stmt_info);
2091
2092   if (vect_print_dump_info (REPORT_DETAILS))
2093     fprintf (vect_dump, "mark relevant %d, live %d.", relevant, live_p);
2094
2095   if (STMT_VINFO_IN_PATTERN_P (stmt_info))
2096     {
2097       tree pattern_stmt;
2098
2099       /* This is the last stmt in a sequence that was detected as a 
2100          pattern that can potentially be vectorized.  Don't mark the stmt
2101          as relevant/live because it's not going to vectorized.
2102          Instead mark the pattern-stmt that replaces it.  */
2103       if (vect_print_dump_info (REPORT_DETAILS))
2104         fprintf (vect_dump, "last stmt in pattern. don't mark relevant/live.");
2105       pattern_stmt = STMT_VINFO_RELATED_STMT (stmt_info);
2106       stmt_info = vinfo_for_stmt (pattern_stmt);
2107       gcc_assert (STMT_VINFO_RELATED_STMT (stmt_info) == stmt);
2108       save_relevant = STMT_VINFO_RELEVANT (stmt_info);
2109       save_live_p = STMT_VINFO_LIVE_P (stmt_info);
2110       stmt = pattern_stmt;
2111     }
2112
2113   STMT_VINFO_LIVE_P (stmt_info) |= live_p;
2114   if (relevant > STMT_VINFO_RELEVANT (stmt_info))
2115     STMT_VINFO_RELEVANT (stmt_info) = relevant;
2116
2117   if (STMT_VINFO_RELEVANT (stmt_info) == save_relevant
2118       && STMT_VINFO_LIVE_P (stmt_info) == save_live_p)
2119     {
2120       if (vect_print_dump_info (REPORT_DETAILS))
2121         fprintf (vect_dump, "already marked relevant/live.");
2122       return;
2123     }
2124
2125   VEC_safe_push (tree, heap, *worklist, stmt);
2126 }
2127
2128
2129 /* Function vect_stmt_relevant_p.
2130
2131    Return true if STMT in loop that is represented by LOOP_VINFO is
2132    "relevant for vectorization".
2133
2134    A stmt is considered "relevant for vectorization" if:
2135    - it has uses outside the loop.
2136    - it has vdefs (it alters memory).
2137    - control stmts in the loop (except for the exit condition).
2138
2139    CHECKME: what other side effects would the vectorizer allow?  */
2140
2141 static bool
2142 vect_stmt_relevant_p (tree stmt, loop_vec_info loop_vinfo,
2143                       enum vect_relevant *relevant, bool *live_p)
2144 {
2145   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
2146   ssa_op_iter op_iter;
2147   imm_use_iterator imm_iter;
2148   use_operand_p use_p;
2149   def_operand_p def_p;
2150
2151   *relevant = vect_unused_in_loop;
2152   *live_p = false;
2153
2154   /* cond stmt other than loop exit cond.  */
2155   if (is_ctrl_stmt (stmt) && (stmt != LOOP_VINFO_EXIT_COND (loop_vinfo)))
2156     *relevant = vect_used_in_loop;
2157
2158   /* changing memory.  */
2159   if (TREE_CODE (stmt) != PHI_NODE)
2160     if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_VIRTUAL_DEFS))
2161       {
2162         if (vect_print_dump_info (REPORT_DETAILS))
2163           fprintf (vect_dump, "vec_stmt_relevant_p: stmt has vdefs.");
2164         *relevant = vect_used_in_loop;
2165       }
2166
2167   /* uses outside the loop.  */
2168   FOR_EACH_PHI_OR_STMT_DEF (def_p, stmt, op_iter, SSA_OP_DEF)
2169     {
2170       FOR_EACH_IMM_USE_FAST (use_p, imm_iter, DEF_FROM_PTR (def_p))
2171         {
2172           basic_block bb = bb_for_stmt (USE_STMT (use_p));
2173           if (!flow_bb_inside_loop_p (loop, bb))
2174             {
2175               if (vect_print_dump_info (REPORT_DETAILS))
2176                 fprintf (vect_dump, "vec_stmt_relevant_p: used out of loop.");
2177
2178               /* We expect all such uses to be in the loop exit phis
2179                  (because of loop closed form)   */
2180               gcc_assert (TREE_CODE (USE_STMT (use_p)) == PHI_NODE);
2181               gcc_assert (bb == single_exit (loop)->dest);
2182
2183               *live_p = true;
2184             }
2185         }
2186     }
2187
2188   return (*live_p || *relevant);
2189 }
2190
2191
2192 /* 
2193    Function process_use.
2194
2195    Inputs:
2196    - a USE in STMT in a loop represented by LOOP_VINFO
2197    - LIVE_P, RELEVANT - enum values to be set in the STMT_VINFO of the stmt 
2198      that defined USE. This is dont by calling mark_relevant and passing it
2199      the WORKLIST (to add DEF_STMT to the WORKlist in case itis relevant). 
2200
2201    Outputs:
2202    Generally, LIVE_P and RELEVANT are used to define the liveness and
2203    relevance info of the DEF_STMT of this USE:
2204        STMT_VINFO_LIVE_P (DEF_STMT_info) <-- live_p
2205        STMT_VINFO_RELEVANT (DEF_STMT_info) <-- relevant
2206    Exceptions:
2207    - case 1: If USE is used only for address computations (e.g. array indexing),
2208    which does not need to be directly vectorized, then the liveness/relevance 
2209    of the respective DEF_STMT is left unchanged.
2210    - case 2: If STMT is a reduction phi and DEF_STMT is a reduction stmt, we 
2211    skip DEF_STMT cause it had already been processed.  
2212
2213    Return true if everyting is as expected. Return false otherwise.  */
2214
2215 static bool
2216 process_use (tree stmt, tree use, loop_vec_info loop_vinfo, bool live_p, 
2217              enum vect_relevant relevant, VEC(tree,heap) **worklist)
2218 {
2219   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
2220   stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt);
2221   stmt_vec_info dstmt_vinfo;
2222   basic_block def_bb;
2223   tree def, def_stmt;
2224   enum vect_def_type dt;
2225
2226   /* case 1: we are only interested in uses that need to be vectorized.  Uses 
2227      that are used for address computation are not considered relevant.  */
2228   if (!exist_non_indexing_operands_for_use_p (use, stmt))
2229      return true;
2230
2231   if (!vect_is_simple_use (use, loop_vinfo, &def_stmt, &def, &dt))
2232     { 
2233       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
2234         fprintf (vect_dump, "not vectorized: unsupported use in stmt.");
2235       return false;
2236     }
2237
2238   if (!def_stmt || IS_EMPTY_STMT (def_stmt))
2239     return true;
2240
2241   def_bb = bb_for_stmt (def_stmt);
2242   if (!flow_bb_inside_loop_p (loop, def_bb))
2243     return true;
2244
2245   /* case 2: A reduction phi defining a reduction stmt (DEF_STMT). DEF_STMT 
2246      must have already been processed, so we just check that everything is as 
2247      expected, and we are done.  */
2248   dstmt_vinfo = vinfo_for_stmt (def_stmt);
2249   if (TREE_CODE (stmt) == PHI_NODE
2250       && STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_reduction_def
2251       && TREE_CODE (def_stmt) != PHI_NODE
2252       && STMT_VINFO_DEF_TYPE (dstmt_vinfo) == vect_reduction_def)
2253     {
2254       if (STMT_VINFO_IN_PATTERN_P (dstmt_vinfo))
2255         dstmt_vinfo = vinfo_for_stmt (STMT_VINFO_RELATED_STMT (dstmt_vinfo));
2256       gcc_assert (STMT_VINFO_RELEVANT (dstmt_vinfo) < vect_used_by_reduction);
2257       gcc_assert (STMT_VINFO_LIVE_P (dstmt_vinfo) 
2258                   || STMT_VINFO_RELEVANT (dstmt_vinfo) > vect_unused_in_loop);
2259       return true;
2260     }
2261
2262   vect_mark_relevant (worklist, def_stmt, relevant, live_p);
2263   return true;
2264 }
2265
2266
2267 /* Function vect_mark_stmts_to_be_vectorized.
2268
2269    Not all stmts in the loop need to be vectorized. For example:
2270
2271      for i...
2272        for j...
2273    1.    T0 = i + j
2274    2.    T1 = a[T0]
2275
2276    3.    j = j + 1
2277
2278    Stmt 1 and 3 do not need to be vectorized, because loop control and
2279    addressing of vectorized data-refs are handled differently.
2280
2281    This pass detects such stmts.  */
2282
2283 static bool
2284 vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo)
2285 {
2286   VEC(tree,heap) *worklist;
2287   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
2288   basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
2289   unsigned int nbbs = loop->num_nodes;
2290   block_stmt_iterator si;
2291   tree stmt;
2292   stmt_ann_t ann;
2293   unsigned int i;
2294   stmt_vec_info stmt_vinfo;
2295   basic_block bb;
2296   tree phi;
2297   bool live_p;
2298   enum vect_relevant relevant;
2299
2300   if (vect_print_dump_info (REPORT_DETAILS))
2301     fprintf (vect_dump, "=== vect_mark_stmts_to_be_vectorized ===");
2302
2303   worklist = VEC_alloc (tree, heap, 64);
2304
2305   /* 1. Init worklist.  */
2306   for (i = 0; i < nbbs; i++)
2307     {
2308       bb = bbs[i];
2309       for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
2310         { 
2311           if (vect_print_dump_info (REPORT_DETAILS))
2312             {
2313               fprintf (vect_dump, "init: phi relevant? ");
2314               print_generic_expr (vect_dump, phi, TDF_SLIM);
2315             }
2316
2317           if (vect_stmt_relevant_p (phi, loop_vinfo, &relevant, &live_p))
2318             vect_mark_relevant (&worklist, phi, relevant, live_p);
2319         }
2320       for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
2321         {
2322           stmt = bsi_stmt (si);
2323           if (vect_print_dump_info (REPORT_DETAILS))
2324             {
2325               fprintf (vect_dump, "init: stmt relevant? ");
2326               print_generic_expr (vect_dump, stmt, TDF_SLIM);
2327             } 
2328
2329           if (vect_stmt_relevant_p (stmt, loop_vinfo, &relevant, &live_p))
2330             vect_mark_relevant (&worklist, stmt, relevant, live_p);
2331         }
2332     }
2333
2334   /* 2. Process_worklist */
2335   while (VEC_length (tree, worklist) > 0)
2336     {
2337       use_operand_p use_p;
2338       ssa_op_iter iter;
2339
2340       stmt = VEC_pop (tree, worklist);
2341       if (vect_print_dump_info (REPORT_DETAILS))
2342         {
2343           fprintf (vect_dump, "worklist: examine stmt: ");
2344           print_generic_expr (vect_dump, stmt, TDF_SLIM);
2345         }
2346
2347       /* Examine the USEs of STMT. For each USE, mark the stmt that defines it 
2348          (DEF_STMT) as relevant/irrelevant and live/dead according to the 
2349          liveness and relevance properties of STMT.  */
2350       ann = stmt_ann (stmt);
2351       stmt_vinfo = vinfo_for_stmt (stmt);
2352       relevant = STMT_VINFO_RELEVANT (stmt_vinfo);
2353       live_p = STMT_VINFO_LIVE_P (stmt_vinfo);
2354
2355       /* Generally, the liveness and relevance properties of STMT are
2356          propagated as is to the DEF_STMTs of its USEs:
2357           live_p <-- STMT_VINFO_LIVE_P (STMT_VINFO)
2358           relevant <-- STMT_VINFO_RELEVANT (STMT_VINFO)
2359
2360          One exception is when STMT has been identified as defining a reduction
2361          variable; in this case we set the liveness/relevance as follows:
2362            live_p = false
2363            relevant = vect_used_by_reduction
2364          This is because we distinguish between two kinds of relevant stmts -
2365          those that are used by a reduction computation, and those that are 
2366          (also) used by a regular computation. This allows us later on to 
2367          identify stmts that are used solely by a reduction, and therefore the 
2368          order of the results that they produce does not have to be kept.
2369
2370          Reduction phis are expected to be used by a reduction stmt;  Other 
2371          reduction stmts are expected to be unused in the loop.  These are the 
2372          expected values of "relevant" for reduction phis/stmts in the loop:
2373
2374          relevance:                             phi     stmt
2375          vect_unused_in_loop                            ok
2376          vect_used_by_reduction                 ok
2377          vect_used_in_loop                                                */
2378
2379       if (STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_reduction_def)
2380         {
2381           switch (relevant)
2382             {
2383             case vect_unused_in_loop:
2384               gcc_assert (TREE_CODE (stmt) != PHI_NODE);
2385               break;
2386             case vect_used_by_reduction:
2387               if (TREE_CODE (stmt) == PHI_NODE)
2388                 break;
2389             case vect_used_in_loop:
2390             default:
2391               if (vect_print_dump_info (REPORT_DETAILS))
2392                 fprintf (vect_dump, "unsupported use of reduction.");
2393               VEC_free (tree, heap, worklist);
2394               return false;
2395             }
2396           relevant = vect_used_by_reduction;
2397           live_p = false;       
2398         }
2399
2400       FOR_EACH_PHI_OR_STMT_USE (use_p, stmt, iter, SSA_OP_USE)
2401         {
2402           tree op = USE_FROM_PTR (use_p);
2403           if (!process_use (stmt, op, loop_vinfo, live_p, relevant, &worklist))
2404             {
2405               VEC_free (tree, heap, worklist);
2406               return false;
2407             }
2408         }
2409     } /* while worklist */
2410
2411   VEC_free (tree, heap, worklist);
2412   return true;
2413 }
2414
2415
2416 /* Function vect_can_advance_ivs_p
2417
2418    In case the number of iterations that LOOP iterates is unknown at compile 
2419    time, an epilog loop will be generated, and the loop induction variables 
2420    (IVs) will be "advanced" to the value they are supposed to take just before 
2421    the epilog loop.  Here we check that the access function of the loop IVs
2422    and the expression that represents the loop bound are simple enough.
2423    These restrictions will be relaxed in the future.  */
2424
2425 static bool 
2426 vect_can_advance_ivs_p (loop_vec_info loop_vinfo)
2427 {
2428   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
2429   basic_block bb = loop->header;
2430   tree phi;
2431
2432   /* Analyze phi functions of the loop header.  */
2433
2434   if (vect_print_dump_info (REPORT_DETAILS))
2435     fprintf (vect_dump, "vect_can_advance_ivs_p:");
2436
2437   for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
2438     {
2439       tree access_fn = NULL;
2440       tree evolution_part;
2441
2442       if (vect_print_dump_info (REPORT_DETAILS))
2443         {
2444           fprintf (vect_dump, "Analyze phi: ");
2445           print_generic_expr (vect_dump, phi, TDF_SLIM);
2446         }
2447
2448       /* Skip virtual phi's. The data dependences that are associated with
2449          virtual defs/uses (i.e., memory accesses) are analyzed elsewhere.  */
2450
2451       if (!is_gimple_reg (SSA_NAME_VAR (PHI_RESULT (phi))))
2452         {
2453           if (vect_print_dump_info (REPORT_DETAILS))
2454             fprintf (vect_dump, "virtual phi. skip.");
2455           continue;
2456         }
2457
2458       /* Skip reduction phis.  */
2459
2460       if (STMT_VINFO_DEF_TYPE (vinfo_for_stmt (phi)) == vect_reduction_def)
2461         {
2462           if (vect_print_dump_info (REPORT_DETAILS))
2463             fprintf (vect_dump, "reduc phi. skip.");
2464           continue;
2465         }
2466
2467       /* Analyze the evolution function.  */
2468
2469       access_fn = instantiate_parameters
2470         (loop, analyze_scalar_evolution (loop, PHI_RESULT (phi)));
2471
2472       if (!access_fn)
2473         {
2474           if (vect_print_dump_info (REPORT_DETAILS))
2475             fprintf (vect_dump, "No Access function.");
2476           return false;
2477         }
2478
2479       if (vect_print_dump_info (REPORT_DETAILS))
2480         {
2481           fprintf (vect_dump, "Access function of PHI: ");
2482           print_generic_expr (vect_dump, access_fn, TDF_SLIM);
2483         }
2484
2485       evolution_part = evolution_part_in_loop_num (access_fn, loop->num);
2486       
2487       if (evolution_part == NULL_TREE)
2488         {
2489           if (vect_print_dump_info (REPORT_DETAILS))
2490             fprintf (vect_dump, "No evolution.");
2491           return false;
2492         }
2493   
2494       /* FORNOW: We do not transform initial conditions of IVs 
2495          which evolution functions are a polynomial of degree >= 2.  */
2496
2497       if (tree_is_chrec (evolution_part))
2498         return false;  
2499     }
2500
2501   return true;
2502 }
2503
2504
2505 /* Function vect_get_loop_niters.
2506
2507    Determine how many iterations the loop is executed.
2508    If an expression that represents the number of iterations
2509    can be constructed, place it in NUMBER_OF_ITERATIONS.
2510    Return the loop exit condition.  */
2511
2512 static tree
2513 vect_get_loop_niters (struct loop *loop, tree *number_of_iterations)
2514 {
2515   tree niters;
2516
2517   if (vect_print_dump_info (REPORT_DETAILS))
2518     fprintf (vect_dump, "=== get_loop_niters ===");
2519
2520   niters = number_of_exit_cond_executions (loop);
2521
2522   if (niters != NULL_TREE
2523       && niters != chrec_dont_know)
2524     {
2525       *number_of_iterations = niters;
2526
2527       if (vect_print_dump_info (REPORT_DETAILS))
2528         {
2529           fprintf (vect_dump, "==> get_loop_niters:" );
2530           print_generic_expr (vect_dump, *number_of_iterations, TDF_SLIM);
2531         }
2532     }
2533
2534   return get_loop_exit_condition (loop);
2535 }
2536
2537
2538 /* Function vect_analyze_loop_form.
2539
2540    Verify the following restrictions (some may be relaxed in the future):
2541    - it's an inner-most loop
2542    - number of BBs = 2 (which are the loop header and the latch)
2543    - the loop has a pre-header
2544    - the loop has a single entry and exit
2545    - the loop exit condition is simple enough, and the number of iterations
2546      can be analyzed (a countable loop).  */
2547
2548 static loop_vec_info
2549 vect_analyze_loop_form (struct loop *loop)
2550 {
2551   loop_vec_info loop_vinfo;
2552   tree loop_cond;
2553   tree number_of_iterations = NULL;
2554
2555   if (vect_print_dump_info (REPORT_DETAILS))
2556     fprintf (vect_dump, "=== vect_analyze_loop_form ===");
2557
2558   if (loop->inner)
2559     {
2560       if (vect_print_dump_info (REPORT_OUTER_LOOPS))
2561         fprintf (vect_dump, "not vectorized: nested loop.");
2562       return NULL;
2563     }
2564   
2565   if (!single_exit (loop) 
2566       || loop->num_nodes != 2
2567       || EDGE_COUNT (loop->header->preds) != 2)
2568     {
2569       if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
2570         {
2571           if (!single_exit (loop))
2572             fprintf (vect_dump, "not vectorized: multiple exits.");
2573           else if (loop->num_nodes != 2)
2574             fprintf (vect_dump, "not vectorized: too many BBs in loop.");
2575           else if (EDGE_COUNT (loop->header->preds) != 2)
2576             fprintf (vect_dump, "not vectorized: too many incoming edges.");
2577         }
2578
2579       return NULL;
2580     }
2581
2582   /* We assume that the loop exit condition is at the end of the loop. i.e,
2583      that the loop is represented as a do-while (with a proper if-guard
2584      before the loop if needed), where the loop header contains all the
2585      executable statements, and the latch is empty.  */
2586   if (!empty_block_p (loop->latch)
2587         || phi_nodes (loop->latch))
2588     {
2589       if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
2590         fprintf (vect_dump, "not vectorized: unexpected loop form.");
2591       return NULL;
2592     }
2593
2594   /* Make sure there exists a single-predecessor exit bb:  */
2595   if (!single_pred_p (single_exit (loop)->dest))
2596     {
2597       edge e = single_exit (loop);
2598       if (!(e->flags & EDGE_ABNORMAL))
2599         {
2600           split_loop_exit_edge (e);
2601           if (vect_print_dump_info (REPORT_DETAILS))
2602             fprintf (vect_dump, "split exit edge.");
2603         }
2604       else
2605         {
2606           if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
2607             fprintf (vect_dump, "not vectorized: abnormal loop exit edge.");
2608           return NULL;
2609         }
2610     }
2611
2612   if (empty_block_p (loop->header))
2613     {
2614       if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
2615         fprintf (vect_dump, "not vectorized: empty loop.");
2616       return NULL;
2617     }
2618
2619   loop_cond = vect_get_loop_niters (loop, &number_of_iterations);
2620   if (!loop_cond)
2621     {
2622       if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
2623         fprintf (vect_dump, "not vectorized: complicated exit condition.");
2624       return NULL;
2625     }
2626   
2627   if (!number_of_iterations) 
2628     {
2629       if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
2630         fprintf (vect_dump, 
2631                  "not vectorized: number of iterations cannot be computed.");
2632       return NULL;
2633     }
2634
2635   if (chrec_contains_undetermined (number_of_iterations))
2636     {
2637       if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
2638         fprintf (vect_dump, "Infinite number of iterations.");
2639       return false;
2640     }
2641
2642   if (!NITERS_KNOWN_P (number_of_iterations))
2643     {
2644       if (vect_print_dump_info (REPORT_DETAILS))
2645         {
2646           fprintf (vect_dump, "Symbolic number of iterations is ");
2647           print_generic_expr (vect_dump, number_of_iterations, TDF_DETAILS);
2648         }
2649     }
2650   else if (TREE_INT_CST_LOW (number_of_iterations) == 0)
2651     {
2652       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
2653         fprintf (vect_dump, "not vectorized: number of iterations = 0.");
2654       return NULL;
2655     }
2656
2657   loop_vinfo = new_loop_vec_info (loop);
2658   LOOP_VINFO_NITERS (loop_vinfo) = number_of_iterations;
2659   LOOP_VINFO_EXIT_COND (loop_vinfo) = loop_cond;
2660
2661   gcc_assert (!loop->aux);
2662   loop->aux = loop_vinfo;
2663   return loop_vinfo;
2664 }
2665
2666
2667 /* Function vect_analyze_loop.
2668
2669    Apply a set of analyses on LOOP, and create a loop_vec_info struct
2670    for it. The different analyses will record information in the
2671    loop_vec_info struct.  */
2672 loop_vec_info
2673 vect_analyze_loop (struct loop *loop)
2674 {
2675   bool ok;
2676   loop_vec_info loop_vinfo;
2677
2678   if (vect_print_dump_info (REPORT_DETAILS))
2679     fprintf (vect_dump, "===== analyze_loop_nest =====");
2680
2681   /* Check the CFG characteristics of the loop (nesting, entry/exit, etc.  */
2682
2683   loop_vinfo = vect_analyze_loop_form (loop);
2684   if (!loop_vinfo)
2685     {
2686       if (vect_print_dump_info (REPORT_DETAILS))
2687         fprintf (vect_dump, "bad loop form.");
2688       return NULL;
2689     }
2690
2691   /* Find all data references in the loop (which correspond to vdefs/vuses)
2692      and analyze their evolution in the loop.
2693
2694      FORNOW: Handle only simple, array references, which
2695      alignment can be forced, and aligned pointer-references.  */
2696
2697   ok = vect_analyze_data_refs (loop_vinfo);
2698   if (!ok)
2699     {
2700       if (vect_print_dump_info (REPORT_DETAILS))
2701         fprintf (vect_dump, "bad data references.");
2702       destroy_loop_vec_info (loop_vinfo);
2703       return NULL;
2704     }
2705
2706   /* Classify all cross-iteration scalar data-flow cycles.
2707      Cross-iteration cycles caused by virtual phis are analyzed separately.  */
2708
2709   vect_analyze_scalar_cycles (loop_vinfo);
2710
2711   vect_pattern_recog (loop_vinfo);
2712
2713   /* Data-flow analysis to detect stmts that do not need to be vectorized.  */
2714
2715   ok = vect_mark_stmts_to_be_vectorized (loop_vinfo);
2716   if (!ok)
2717     {
2718       if (vect_print_dump_info (REPORT_DETAILS))
2719         fprintf (vect_dump, "unexpected pattern.");
2720       destroy_loop_vec_info (loop_vinfo);
2721       return NULL;
2722     }
2723
2724   /* Analyze the alignment of the data-refs in the loop.
2725      Fail if a data reference is found that cannot be vectorized.  */
2726
2727   ok = vect_analyze_data_refs_alignment (loop_vinfo);
2728   if (!ok)
2729     {
2730       if (vect_print_dump_info (REPORT_DETAILS))
2731         fprintf (vect_dump, "bad data alignment.");
2732       destroy_loop_vec_info (loop_vinfo);
2733       return NULL;
2734     }
2735
2736   ok = vect_determine_vectorization_factor (loop_vinfo);
2737   if (!ok)
2738     {
2739       if (vect_print_dump_info (REPORT_DETAILS))
2740         fprintf (vect_dump, "can't determine vectorization factor.");
2741       destroy_loop_vec_info (loop_vinfo);
2742       return NULL;
2743     }
2744
2745   /* Analyze data dependences between the data-refs in the loop. 
2746      FORNOW: fail at the first data dependence that we encounter.  */
2747
2748   ok = vect_analyze_data_ref_dependences (loop_vinfo);
2749   if (!ok)
2750     {
2751       if (vect_print_dump_info (REPORT_DETAILS))
2752         fprintf (vect_dump, "bad data dependence.");
2753       destroy_loop_vec_info (loop_vinfo);
2754       return NULL;
2755     }
2756
2757   /* Analyze the access patterns of the data-refs in the loop (consecutive,
2758      complex, etc.). FORNOW: Only handle consecutive access pattern.  */
2759
2760   ok = vect_analyze_data_ref_accesses (loop_vinfo);
2761   if (!ok)
2762     {
2763       if (vect_print_dump_info (REPORT_DETAILS))
2764         fprintf (vect_dump, "bad data access.");
2765       destroy_loop_vec_info (loop_vinfo);
2766       return NULL;
2767     }
2768
2769   /* This pass will decide on using loop versioning and/or loop peeling in
2770      order to enhance the alignment of data references in the loop.  */
2771
2772   ok = vect_enhance_data_refs_alignment (loop_vinfo);
2773   if (!ok)
2774     {
2775       if (vect_print_dump_info (REPORT_DETAILS))
2776         fprintf (vect_dump, "bad data alignment.");
2777       destroy_loop_vec_info (loop_vinfo);
2778       return NULL;
2779     }
2780
2781   /* Scan all the operations in the loop and make sure they are
2782      vectorizable.  */
2783
2784   ok = vect_analyze_operations (loop_vinfo);
2785   if (!ok)
2786     {
2787       if (vect_print_dump_info (REPORT_DETAILS))
2788         fprintf (vect_dump, "bad operation or unsupported loop bound.");
2789       destroy_loop_vec_info (loop_vinfo);
2790       return NULL;
2791     }
2792
2793   LOOP_VINFO_VECTORIZABLE_P (loop_vinfo) = 1;
2794
2795   return loop_vinfo;
2796 }