OSDN Git Service

* stor-layout.c (mode_for_size_tree): Remove restiction on type
[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
42 /* Main analysis functions.  */
43 static loop_vec_info vect_analyze_loop_form (struct loop *);
44 static bool vect_analyze_data_refs (loop_vec_info);
45 static bool vect_mark_stmts_to_be_vectorized (loop_vec_info);
46 static void vect_analyze_scalar_cycles (loop_vec_info);
47 static bool vect_analyze_data_ref_accesses (loop_vec_info);
48 static bool vect_analyze_data_ref_dependences (loop_vec_info);
49 static bool vect_analyze_data_refs_alignment (loop_vec_info);
50 static bool vect_compute_data_refs_alignment (loop_vec_info);
51 static bool vect_enhance_data_refs_alignment (loop_vec_info);
52 static bool vect_analyze_operations (loop_vec_info);
53 static bool vect_determine_vectorization_factor (loop_vec_info);
54
55 /* Utility functions for the analyses.  */
56 static bool exist_non_indexing_operands_for_use_p (tree, tree);
57 static void vect_mark_relevant (VEC(tree,heap) **, tree, bool, bool);
58 static bool vect_stmt_relevant_p (tree, loop_vec_info, bool *, bool *);
59 static tree vect_get_loop_niters (struct loop *, tree *);
60 static bool vect_analyze_data_ref_dependence
61   (struct data_dependence_relation *, loop_vec_info);
62 static bool vect_compute_data_ref_alignment (struct data_reference *); 
63 static bool vect_analyze_data_ref_access (struct data_reference *);
64 static bool vect_can_advance_ivs_p (loop_vec_info);
65 static void vect_update_misalignment_for_peel
66   (struct data_reference *, struct data_reference *, int npeel);
67  
68
69 /* Function vect_determine_vectorization_factor
70
71    Determine the vectorization factor (VF). VF is the number of data elements
72    that are operated upon in parallel in a single iteration of the vectorized
73    loop. For example, when vectorizing a loop that operates on 4byte elements,
74    on a target with vector size (VS) 16byte, the VF is set to 4, since 4
75    elements can fit in a single vector register.
76
77    We currently support vectorization of loops in which all types operated upon
78    are of the same size. Therefore this function currently sets VF according to
79    the size of the types operated upon, and fails if there are multiple sizes
80    in the loop.
81
82    VF is also the factor by which the loop iterations are strip-mined, e.g.:
83    original loop:
84         for (i=0; i<N; i++){
85           a[i] = b[i] + c[i];
86         }
87
88    vectorized loop:
89         for (i=0; i<N; i+=VF){
90           a[i:VF] = b[i:VF] + c[i:VF];
91         }
92 */
93
94 static bool
95 vect_determine_vectorization_factor (loop_vec_info loop_vinfo)
96 {
97   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
98   basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
99   int nbbs = loop->num_nodes;
100   block_stmt_iterator si;
101   unsigned int vectorization_factor = 0;
102   int i;
103   tree scalar_type;
104
105   if (vect_print_dump_info (REPORT_DETAILS))
106     fprintf (vect_dump, "=== vect_determine_vectorization_factor ===");
107
108   for (i = 0; i < nbbs; i++)
109     {
110       basic_block bb = bbs[i];
111
112       for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
113         {
114           tree stmt = bsi_stmt (si);
115           unsigned int nunits;
116           stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
117           tree vectype;
118
119           if (vect_print_dump_info (REPORT_DETAILS))
120             {
121               fprintf (vect_dump, "==> examining statement: ");
122               print_generic_expr (vect_dump, stmt, TDF_SLIM);
123             }
124
125           gcc_assert (stmt_info);
126           /* skip stmts which do not need to be vectorized.  */
127           if (!STMT_VINFO_RELEVANT_P (stmt_info)
128               && !STMT_VINFO_LIVE_P (stmt_info))
129             {
130               if (vect_print_dump_info (REPORT_DETAILS))
131                 fprintf (vect_dump, "skip.");
132               continue;
133             }
134
135           if (VECTOR_MODE_P (TYPE_MODE (TREE_TYPE (stmt))))
136             {
137               if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
138                 {
139                   fprintf (vect_dump, "not vectorized: vector stmt in loop:");
140                   print_generic_expr (vect_dump, stmt, TDF_SLIM);
141                 }
142               return false;
143             }
144
145           if (STMT_VINFO_VECTYPE (stmt_info))
146             {
147               vectype = STMT_VINFO_VECTYPE (stmt_info);
148               scalar_type = TREE_TYPE (vectype);
149             }
150           else
151             {
152               if (STMT_VINFO_DATA_REF (stmt_info))
153                 scalar_type = 
154                         TREE_TYPE (DR_REF (STMT_VINFO_DATA_REF (stmt_info)));
155               else if (TREE_CODE (stmt) == MODIFY_EXPR)
156                 scalar_type = TREE_TYPE (TREE_OPERAND (stmt, 0));
157               else
158                 scalar_type = TREE_TYPE (stmt);
159
160               if (vect_print_dump_info (REPORT_DETAILS))
161                 {
162                   fprintf (vect_dump, "get vectype for scalar type:  ");
163                   print_generic_expr (vect_dump, scalar_type, TDF_SLIM);
164                 }
165
166               vectype = get_vectype_for_scalar_type (scalar_type);
167               if (!vectype)
168                 {
169                   if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
170                     {
171                       fprintf (vect_dump, 
172                                "not vectorized: unsupported data-type ");
173                       print_generic_expr (vect_dump, scalar_type, TDF_SLIM);
174                     }
175                   return false;
176                 }
177               STMT_VINFO_VECTYPE (stmt_info) = vectype;
178             }
179
180           if (vect_print_dump_info (REPORT_DETAILS))
181             {
182               fprintf (vect_dump, "vectype: ");
183               print_generic_expr (vect_dump, vectype, TDF_SLIM);
184             }
185
186           nunits = TYPE_VECTOR_SUBPARTS (vectype);
187           if (vect_print_dump_info (REPORT_DETAILS))
188             fprintf (vect_dump, "nunits = %d", nunits);
189
190           if (vectorization_factor)
191             {
192               /* FORNOW: don't allow mixed units. 
193                  This restriction will be relaxed in the future.  */
194               if (nunits != vectorization_factor) 
195                 {
196                   if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
197                     fprintf (vect_dump, "not vectorized: mixed data-types");
198                   return false;
199                 }
200             }
201           else
202             vectorization_factor = nunits;
203
204           gcc_assert (GET_MODE_SIZE (TYPE_MODE (scalar_type))
205                         * vectorization_factor == UNITS_PER_SIMD_WORD);
206         }
207     }
208
209   /* TODO: Analyze cost. Decide if worth while to vectorize.  */
210
211   if (vectorization_factor <= 1)
212     {
213       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
214         fprintf (vect_dump, "not vectorized: unsupported data-type");
215       return false;
216     }
217   LOOP_VINFO_VECT_FACTOR (loop_vinfo) = vectorization_factor;
218
219   return true;
220 }
221
222
223 /* Function vect_analyze_operations.
224
225    Scan the loop stmts and make sure they are all vectorizable.  */
226
227 static bool
228 vect_analyze_operations (loop_vec_info loop_vinfo)
229 {
230   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
231   basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
232   int nbbs = loop->num_nodes;
233   block_stmt_iterator si;
234   unsigned int vectorization_factor = 0;
235   int i;
236   bool ok;
237   tree phi;
238   stmt_vec_info stmt_info;
239   bool need_to_vectorize = false;
240
241   if (vect_print_dump_info (REPORT_DETAILS))
242     fprintf (vect_dump, "=== vect_analyze_operations ===");
243
244   gcc_assert (LOOP_VINFO_VECT_FACTOR (loop_vinfo));
245   vectorization_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
246
247   for (i = 0; i < nbbs; i++)
248     {
249       basic_block bb = bbs[i];
250
251       for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
252         {
253           stmt_info = vinfo_for_stmt (phi);
254           if (vect_print_dump_info (REPORT_DETAILS))
255             {
256               fprintf (vect_dump, "examining phi: ");
257               print_generic_expr (vect_dump, phi, TDF_SLIM);
258             }
259
260           gcc_assert (stmt_info);
261
262           if (STMT_VINFO_LIVE_P (stmt_info))
263             {
264               /* FORNOW: not yet supported.  */
265               if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
266                 fprintf (vect_dump, "not vectorized: value used after loop.");
267             return false;
268           }
269
270           if (STMT_VINFO_RELEVANT_P (stmt_info))
271             {
272               /* Most likely a reduction-like computation that is used
273                  in the loop.  */
274               if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
275                 fprintf (vect_dump, "not vectorized: unsupported pattern.");
276              return false;
277             }
278         }
279
280       for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
281         {
282           tree stmt = bsi_stmt (si);
283           stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
284
285           if (vect_print_dump_info (REPORT_DETAILS))
286             {
287               fprintf (vect_dump, "==> examining statement: ");
288               print_generic_expr (vect_dump, stmt, TDF_SLIM);
289             }
290
291           gcc_assert (stmt_info);
292
293           /* skip stmts which do not need to be vectorized.
294              this is expected to include:
295              - the COND_EXPR which is the loop exit condition
296              - any LABEL_EXPRs in the loop
297              - computations that are used only for array indexing or loop
298              control  */
299
300           if (!STMT_VINFO_RELEVANT_P (stmt_info)
301               && !STMT_VINFO_LIVE_P (stmt_info))
302             {
303               if (vect_print_dump_info (REPORT_DETAILS))
304                 fprintf (vect_dump, "irrelevant.");
305               continue;
306             }
307
308           if (STMT_VINFO_RELEVANT_P (stmt_info))
309             {
310               gcc_assert (!VECTOR_MODE_P (TYPE_MODE (TREE_TYPE (stmt))));
311               gcc_assert (STMT_VINFO_VECTYPE (stmt_info));
312
313               ok = (vectorizable_operation (stmt, NULL, NULL)
314                     || vectorizable_assignment (stmt, NULL, NULL)
315                     || vectorizable_load (stmt, NULL, NULL)
316                     || vectorizable_store (stmt, NULL, NULL)
317                     || vectorizable_condition (stmt, NULL, NULL));
318
319               if (!ok)
320                 {
321                   if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
322                     {
323                       fprintf (vect_dump, 
324                                "not vectorized: relevant stmt not supported: ");
325                       print_generic_expr (vect_dump, stmt, TDF_SLIM);
326                     }
327                   return false;
328                 }       
329               need_to_vectorize = true;
330             }
331
332           if (STMT_VINFO_LIVE_P (stmt_info))
333             {
334               ok = vectorizable_reduction (stmt, NULL, NULL);
335
336               if (ok)
337                 need_to_vectorize = true;
338               else
339                 ok = vectorizable_live_operation (stmt, NULL, NULL);
340
341               if (!ok)
342                 {
343                   if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
344                     {
345                       fprintf (vect_dump, 
346                                "not vectorized: live stmt not supported: ");
347                       print_generic_expr (vect_dump, stmt, TDF_SLIM);
348                     }
349                   return false;
350                 }
351             }
352         } /* stmts in bb */
353     } /* bbs */
354
355   /* TODO: Analyze cost. Decide if worth while to vectorize.  */
356
357   /* All operations in the loop are either irrelevant (deal with loop
358      control, or dead), or only used outside the loop and can be moved
359      out of the loop (e.g. invariants, inductions).  The loop can be 
360      optimized away by scalar optimizations.  We're better off not 
361      touching this loop.  */
362   if (!need_to_vectorize)
363     {
364       if (vect_print_dump_info (REPORT_DETAILS))
365         fprintf (vect_dump, 
366                  "All the computation can be taken out of the loop.");
367       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
368         fprintf (vect_dump, 
369                  "not vectorized: redundant loop. no profit to vectorize.");
370       return false;
371     }
372
373   if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
374       && vect_print_dump_info (REPORT_DETAILS))
375     fprintf (vect_dump,
376         "vectorization_factor = %d, niters = " HOST_WIDE_INT_PRINT_DEC,
377         vectorization_factor, LOOP_VINFO_INT_NITERS (loop_vinfo));
378
379   if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
380       && LOOP_VINFO_INT_NITERS (loop_vinfo) < vectorization_factor)
381     {
382       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
383         fprintf (vect_dump, "not vectorized: iteration count too small.");
384       return false;
385     }
386
387   if (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
388       || LOOP_VINFO_INT_NITERS (loop_vinfo) % vectorization_factor != 0
389       || LOOP_PEELING_FOR_ALIGNMENT (loop_vinfo))
390     {
391       if (vect_print_dump_info (REPORT_DETAILS))
392         fprintf (vect_dump, "epilog loop required.");
393       if (!vect_can_advance_ivs_p (loop_vinfo))
394         {
395           if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
396             fprintf (vect_dump,
397                      "not vectorized: can't create epilog loop 1.");
398           return false;
399         }
400       if (!slpeel_can_duplicate_loop_p (loop, loop->single_exit))
401         {
402           if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
403             fprintf (vect_dump,
404                      "not vectorized: can't create epilog loop 2.");
405           return false;
406         }
407     }
408
409   return true;
410 }
411
412
413 /* Function exist_non_indexing_operands_for_use_p 
414
415    USE is one of the uses attached to STMT. Check if USE is 
416    used in STMT for anything other than indexing an array.  */
417
418 static bool
419 exist_non_indexing_operands_for_use_p (tree use, tree stmt)
420 {
421   tree operand;
422   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
423  
424   /* USE corresponds to some operand in STMT. If there is no data
425      reference in STMT, then any operand that corresponds to USE
426      is not indexing an array.  */
427   if (!STMT_VINFO_DATA_REF (stmt_info))
428     return true;
429  
430   /* STMT has a data_ref. FORNOW this means that its of one of
431      the following forms:
432      -1- ARRAY_REF = var
433      -2- var = ARRAY_REF
434      (This should have been verified in analyze_data_refs).
435
436      'var' in the second case corresponds to a def, not a use,
437      so USE cannot correspond to any operands that are not used 
438      for array indexing.
439
440      Therefore, all we need to check is if STMT falls into the
441      first case, and whether var corresponds to USE.  */
442  
443   if (TREE_CODE (TREE_OPERAND (stmt, 0)) == SSA_NAME)
444     return false;
445
446   operand = TREE_OPERAND (stmt, 1);
447
448   if (TREE_CODE (operand) != SSA_NAME)
449     return false;
450
451   if (operand == use)
452     return true;
453
454   return false;
455 }
456
457
458 /* Function vect_analyze_scalar_cycles.
459
460    Examine the cross iteration def-use cycles of scalar variables, by
461    analyzing the loop (scalar) PHIs; Classify each cycle as one of the
462    following: invariant, induction, reduction, unknown.
463    
464    Some forms of scalar cycles are not yet supported.
465
466    Example1: reduction: (unsupported yet)
467
468               loop1:
469               for (i=0; i<N; i++)
470                  sum += a[i];
471
472    Example2: induction: (unsupported yet)
473
474               loop2:
475               for (i=0; i<N; i++)
476                  a[i] = i;
477
478    Note: the following loop *is* vectorizable:
479
480               loop3:
481               for (i=0; i<N; i++)
482                  a[i] = b[i];
483
484          even though it has a def-use cycle caused by the induction variable i:
485
486               loop: i_2 = PHI (i_0, i_1)
487                     a[i_2] = ...;
488                     i_1 = i_2 + 1;
489                     GOTO loop;
490
491          because the def-use cycle in loop3 is considered "not relevant" - i.e.,
492          it does not need to be vectorized because it is only used for array
493          indexing (see 'mark_stmts_to_be_vectorized'). The def-use cycle in
494          loop2 on the other hand is relevant (it is being written to memory).
495 */
496
497 static void
498 vect_analyze_scalar_cycles (loop_vec_info loop_vinfo)
499 {
500   tree phi;
501   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
502   basic_block bb = loop->header;
503   tree dummy;
504
505   if (vect_print_dump_info (REPORT_DETAILS))
506     fprintf (vect_dump, "=== vect_analyze_scalar_cycles ===");
507
508   for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
509     {
510       tree access_fn = NULL;
511       tree def = PHI_RESULT (phi);
512       stmt_vec_info stmt_vinfo = vinfo_for_stmt (phi);
513       tree reduc_stmt;
514
515       if (vect_print_dump_info (REPORT_DETAILS))
516         {
517           fprintf (vect_dump, "Analyze phi: ");
518           print_generic_expr (vect_dump, phi, TDF_SLIM);
519         }
520
521       /* Skip virtual phi's. The data dependences that are associated with
522          virtual defs/uses (i.e., memory accesses) are analyzed elsewhere.  */
523
524       if (!is_gimple_reg (SSA_NAME_VAR (def)))
525         {
526           if (vect_print_dump_info (REPORT_DETAILS))
527             fprintf (vect_dump, "virtual phi. skip.");
528           continue;
529         }
530
531       STMT_VINFO_DEF_TYPE (stmt_vinfo) = vect_unknown_def_type;
532
533       /* Analyze the evolution function.  */
534
535       access_fn = analyze_scalar_evolution (loop, def);
536
537       if (!access_fn)
538         continue;
539
540       if (vect_print_dump_info (REPORT_DETAILS))
541         {
542            fprintf (vect_dump, "Access function of PHI: ");
543            print_generic_expr (vect_dump, access_fn, TDF_SLIM);
544         }
545
546       if (vect_is_simple_iv_evolution (loop->num, access_fn, &dummy, &dummy))
547         {
548           if (vect_print_dump_info (REPORT_DETAILS))
549             fprintf (vect_dump, "Detected induction.");
550           STMT_VINFO_DEF_TYPE (stmt_vinfo) = vect_induction_def;
551           continue;
552         }
553
554       /* TODO: handle invariant phis  */
555
556       reduc_stmt = vect_is_simple_reduction (loop, phi);
557       if (reduc_stmt)
558         {
559           if (vect_print_dump_info (REPORT_DETAILS))
560             fprintf (vect_dump, "Detected reduction.");
561           STMT_VINFO_DEF_TYPE (stmt_vinfo) = vect_reduction_def;
562           STMT_VINFO_DEF_TYPE (vinfo_for_stmt (reduc_stmt)) =
563                                                         vect_reduction_def;
564         }
565       else
566         if (vect_print_dump_info (REPORT_DETAILS))
567           fprintf (vect_dump, "Unknown def-use cycle pattern.");
568
569     }
570
571   return;
572 }
573
574
575 /* Function vect_analyze_data_ref_dependence.
576
577    Return TRUE if there (might) exist a dependence between a memory-reference
578    DRA and a memory-reference DRB.  */
579       
580 static bool
581 vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
582                                   loop_vec_info loop_vinfo)
583 {
584   unsigned int i;
585   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
586   int vectorization_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
587   struct data_reference *dra = DDR_A (ddr);
588   struct data_reference *drb = DDR_B (ddr);
589   stmt_vec_info stmtinfo_a = vinfo_for_stmt (DR_STMT (dra)); 
590   stmt_vec_info stmtinfo_b = vinfo_for_stmt (DR_STMT (drb));
591   lambda_vector dist_v;
592   unsigned int loop_depth;
593          
594   if (DDR_ARE_DEPENDENT (ddr) == chrec_known)
595     return false;
596   
597   if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know)
598     {
599       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
600         {
601           fprintf (vect_dump,
602                    "not vectorized: can't determine dependence between ");
603           print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
604           fprintf (vect_dump, " and ");
605           print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
606         }
607       return true;
608     }
609
610   if (DDR_NUM_DIST_VECTS (ddr) == 0)
611     {
612       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
613         {
614           fprintf (vect_dump, "not vectorized: bad dist vector for ");
615           print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
616           fprintf (vect_dump, " and ");
617           print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
618         }
619       return true;
620     }    
621
622   loop_depth = index_in_loop_nest (loop->num, DDR_LOOP_NEST (ddr));
623   for (i = 0; VEC_iterate (lambda_vector, DDR_DIST_VECTS (ddr), i, dist_v); i++)
624     {
625       int dist = dist_v[loop_depth];
626
627       if (vect_print_dump_info (REPORT_DR_DETAILS))
628         fprintf (vect_dump, "dependence distance  = %d.", dist);
629
630       /* Same loop iteration.  */
631       if (dist % vectorization_factor == 0)
632         {
633           /* Two references with distance zero have the same alignment.  */
634           VEC_safe_push (dr_p, heap, STMT_VINFO_SAME_ALIGN_REFS (stmtinfo_a), drb);
635           VEC_safe_push (dr_p, heap, STMT_VINFO_SAME_ALIGN_REFS (stmtinfo_b), dra);
636           if (vect_print_dump_info (REPORT_ALIGNMENT))
637             fprintf (vect_dump, "accesses have the same alignment.");
638           if (vect_print_dump_info (REPORT_DR_DETAILS))
639             {
640               fprintf (vect_dump, "dependence distance modulo vf == 0 between ");
641               print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
642               fprintf (vect_dump, " and ");
643               print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
644             }
645           continue;
646         }
647
648       if (abs (dist) >= vectorization_factor)
649         {
650           /* Dependence distance does not create dependence, as far as vectorization
651              is concerned, in this case.  */
652           if (vect_print_dump_info (REPORT_DR_DETAILS))
653             fprintf (vect_dump, "dependence distance >= VF.");
654           continue;
655         }
656
657       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
658         {
659           fprintf (vect_dump,
660                    "not vectorized: possible dependence between data-refs ");
661           print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
662           fprintf (vect_dump, " and ");
663           print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
664         }
665
666       return true;
667     }
668
669   return false;
670 }
671
672
673 /* Function vect_analyze_data_ref_dependences.
674           
675    Examine all the data references in the loop, and make sure there do not
676    exist any data dependences between them.  */
677          
678 static bool
679 vect_analyze_data_ref_dependences (loop_vec_info loop_vinfo)
680 {
681   unsigned int i;
682   VEC (ddr_p, heap) *ddrs = LOOP_VINFO_DDRS (loop_vinfo);
683   struct data_dependence_relation *ddr;
684
685   if (vect_print_dump_info (REPORT_DETAILS)) 
686     fprintf (vect_dump, "=== vect_analyze_dependences ===");
687      
688   for (i = 0; VEC_iterate (ddr_p, ddrs, i, ddr); i++)
689     if (vect_analyze_data_ref_dependence (ddr, loop_vinfo))
690       return false;
691
692   return true;
693 }
694
695
696 /* Function vect_compute_data_ref_alignment
697
698    Compute the misalignment of the data reference DR.
699
700    Output:
701    1. If during the misalignment computation it is found that the data reference
702       cannot be vectorized then false is returned.
703    2. DR_MISALIGNMENT (DR) is defined.
704
705    FOR NOW: No analysis is actually performed. Misalignment is calculated
706    only for trivial cases. TODO.  */
707
708 static bool
709 vect_compute_data_ref_alignment (struct data_reference *dr)
710 {
711   tree stmt = DR_STMT (dr);
712   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);  
713   tree ref = DR_REF (dr);
714   tree vectype;
715   tree base, base_addr;
716   bool base_aligned;
717   tree misalign;
718   tree aligned_to, alignment;
719    
720   if (vect_print_dump_info (REPORT_DETAILS))
721     fprintf (vect_dump, "vect_compute_data_ref_alignment:");
722
723   /* Initialize misalignment to unknown.  */
724   DR_MISALIGNMENT (dr) = -1;
725
726   misalign = DR_OFFSET_MISALIGNMENT (dr);
727   aligned_to = DR_ALIGNED_TO (dr);
728   base_addr = DR_BASE_ADDRESS (dr);
729   base = build_fold_indirect_ref (base_addr);
730   vectype = STMT_VINFO_VECTYPE (stmt_info);
731   alignment = ssize_int (TYPE_ALIGN (vectype)/BITS_PER_UNIT);
732
733   if ((aligned_to && tree_int_cst_compare (aligned_to, alignment) < 0)
734       || !misalign)
735     {
736       if (vect_print_dump_info (REPORT_DETAILS))
737         {
738           fprintf (vect_dump, "Unknown alignment for access: ");
739           print_generic_expr (vect_dump, base, TDF_SLIM);
740         }
741       return true;
742     }
743
744   if ((DECL_P (base) 
745        && tree_int_cst_compare (ssize_int (DECL_ALIGN_UNIT (base)),
746                                 alignment) >= 0)
747       || (TREE_CODE (base_addr) == SSA_NAME
748           && tree_int_cst_compare (ssize_int (TYPE_ALIGN_UNIT (TREE_TYPE (
749                                                       TREE_TYPE (base_addr)))),
750                                    alignment) >= 0))
751     base_aligned = true;
752   else
753     base_aligned = false;   
754
755   if (!base_aligned) 
756     {
757       if (!vect_can_force_dr_alignment_p (base, TYPE_ALIGN (vectype)))
758         {
759           if (vect_print_dump_info (REPORT_DETAILS))
760             {
761               fprintf (vect_dump, "can't force alignment of ref: ");
762               print_generic_expr (vect_dump, ref, TDF_SLIM);
763             }
764           return true;
765         }
766       
767       /* Force the alignment of the decl.
768          NOTE: This is the only change to the code we make during
769          the analysis phase, before deciding to vectorize the loop.  */
770       if (vect_print_dump_info (REPORT_DETAILS))
771         fprintf (vect_dump, "force alignment");
772       DECL_ALIGN (base) = TYPE_ALIGN (vectype);
773       DECL_USER_ALIGN (base) = 1;
774     }
775
776   /* At this point we assume that the base is aligned.  */
777   gcc_assert (base_aligned
778               || (TREE_CODE (base) == VAR_DECL 
779                   && DECL_ALIGN (base) >= TYPE_ALIGN (vectype)));
780
781   /* Modulo alignment.  */
782   misalign = size_binop (TRUNC_MOD_EXPR, misalign, alignment);
783
784   if (!host_integerp (misalign, 1))
785     {
786       /* Negative or overflowed misalignment value.  */
787       if (vect_print_dump_info (REPORT_DETAILS))
788         fprintf (vect_dump, "unexpected misalign value");
789       return false;
790     }
791
792   DR_MISALIGNMENT (dr) = TREE_INT_CST_LOW (misalign);
793
794   if (vect_print_dump_info (REPORT_DETAILS))
795     {
796       fprintf (vect_dump, "misalign = %d bytes of ref ", DR_MISALIGNMENT (dr));
797       print_generic_expr (vect_dump, ref, TDF_SLIM);
798     }
799
800   return true;
801 }
802
803
804 /* Function vect_compute_data_refs_alignment
805
806    Compute the misalignment of data references in the loop.
807    Return FALSE if a data reference is found that cannot be vectorized.  */
808
809 static bool
810 vect_compute_data_refs_alignment (loop_vec_info loop_vinfo)
811 {
812   VEC (data_reference_p, heap) *datarefs = LOOP_VINFO_DATAREFS (loop_vinfo);
813   struct data_reference *dr;
814   unsigned int i;
815
816   for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++)
817     if (!vect_compute_data_ref_alignment (dr))
818       return false;
819
820   return true;
821 }
822
823
824 /* Function vect_update_misalignment_for_peel
825
826    DR - the data reference whose misalignment is to be adjusted.
827    DR_PEEL - the data reference whose misalignment is being made
828              zero in the vector loop by the peel.
829    NPEEL - the number of iterations in the peel loop if the misalignment
830            of DR_PEEL is known at compile time.  */
831
832 static void
833 vect_update_misalignment_for_peel (struct data_reference *dr,
834                                    struct data_reference *dr_peel, int npeel)
835 {
836   unsigned int i;
837   int drsize;
838   VEC(dr_p,heap) *same_align_drs;
839   struct data_reference *current_dr;
840
841   if (known_alignment_for_access_p (dr)
842       && DR_MISALIGNMENT (dr) == DR_MISALIGNMENT (dr_peel))
843     {
844       DR_MISALIGNMENT (dr) = 0;
845       return;
846     }
847
848   /* It can be assumed that the data refs with the same alignment as dr_peel
849      are aligned in the vector loop.  */
850   same_align_drs
851     = STMT_VINFO_SAME_ALIGN_REFS (vinfo_for_stmt (DR_STMT (dr_peel)));
852   for (i = 0; VEC_iterate (dr_p, same_align_drs, i, current_dr); i++)
853     {
854       if (current_dr != dr)
855         continue;
856       gcc_assert (DR_MISALIGNMENT (dr) == DR_MISALIGNMENT (dr_peel));
857       DR_MISALIGNMENT (dr) = 0;
858       return;
859     }
860
861   if (known_alignment_for_access_p (dr)
862       && known_alignment_for_access_p (dr_peel))
863     {  
864       drsize = GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (DR_REF (dr))));
865       DR_MISALIGNMENT (dr) += npeel * drsize;
866       DR_MISALIGNMENT (dr) %= UNITS_PER_SIMD_WORD;
867       return;
868     }
869
870   DR_MISALIGNMENT (dr) = -1;
871 }
872
873
874 /* Function vect_verify_datarefs_alignment
875
876    Return TRUE if all data references in the loop can be
877    handled with respect to alignment.  */
878
879 static bool
880 vect_verify_datarefs_alignment (loop_vec_info loop_vinfo)
881 {
882   VEC (data_reference_p, heap) *datarefs = LOOP_VINFO_DATAREFS (loop_vinfo);
883   struct data_reference *dr;
884   enum dr_alignment_support supportable_dr_alignment;
885   unsigned int i;
886
887   for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++)
888     {
889       supportable_dr_alignment = vect_supportable_dr_alignment (dr);
890       if (!supportable_dr_alignment)
891         {
892           if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
893             {
894               if (DR_IS_READ (dr))
895                 fprintf (vect_dump, 
896                          "not vectorized: unsupported unaligned load.");
897               else
898                 fprintf (vect_dump, 
899                          "not vectorized: unsupported unaligned store.");
900             }
901           return false;
902         }
903       if (supportable_dr_alignment != dr_aligned
904           && vect_print_dump_info (REPORT_ALIGNMENT))
905         fprintf (vect_dump, "Vectorizing an unaligned access.");
906     }
907   return true;
908 }
909
910
911 /* Function vect_enhance_data_refs_alignment
912
913    This pass will use loop versioning and loop peeling in order to enhance
914    the alignment of data references in the loop.
915
916    FOR NOW: we assume that whatever versioning/peeling takes place, only the
917    original loop is to be vectorized; Any other loops that are created by
918    the transformations performed in this pass - are not supposed to be
919    vectorized. This restriction will be relaxed.
920
921    This pass will require a cost model to guide it whether to apply peeling
922    or versioning or a combination of the two. For example, the scheme that
923    intel uses when given a loop with several memory accesses, is as follows:
924    choose one memory access ('p') which alignment you want to force by doing
925    peeling. Then, either (1) generate a loop in which 'p' is aligned and all
926    other accesses are not necessarily aligned, or (2) use loop versioning to
927    generate one loop in which all accesses are aligned, and another loop in
928    which only 'p' is necessarily aligned.
929
930    ("Automatic Intra-Register Vectorization for the Intel Architecture",
931    Aart J.C. Bik, Milind Girkar, Paul M. Grey and Ximmin Tian, International
932    Journal of Parallel Programming, Vol. 30, No. 2, April 2002.)
933
934    Devising a cost model is the most critical aspect of this work. It will
935    guide us on which access to peel for, whether to use loop versioning, how
936    many versions to create, etc. The cost model will probably consist of
937    generic considerations as well as target specific considerations (on
938    powerpc for example, misaligned stores are more painful than misaligned
939    loads).
940
941    Here are the general steps involved in alignment enhancements:
942
943      -- original loop, before alignment analysis:
944         for (i=0; i<N; i++){
945           x = q[i];                     # DR_MISALIGNMENT(q) = unknown
946           p[i] = y;                     # DR_MISALIGNMENT(p) = unknown
947         }
948
949      -- After vect_compute_data_refs_alignment:
950         for (i=0; i<N; i++){
951           x = q[i];                     # DR_MISALIGNMENT(q) = 3
952           p[i] = y;                     # DR_MISALIGNMENT(p) = unknown
953         }
954
955      -- Possibility 1: we do loop versioning:
956      if (p is aligned) {
957         for (i=0; i<N; i++){    # loop 1A
958           x = q[i];                     # DR_MISALIGNMENT(q) = 3
959           p[i] = y;                     # DR_MISALIGNMENT(p) = 0
960         }
961      }
962      else {
963         for (i=0; i<N; i++){    # loop 1B
964           x = q[i];                     # DR_MISALIGNMENT(q) = 3
965           p[i] = y;                     # DR_MISALIGNMENT(p) = unaligned
966         }
967      }
968
969      -- Possibility 2: we do loop peeling:
970      for (i = 0; i < 3; i++){   # (scalar loop, not to be vectorized).
971         x = q[i];
972         p[i] = y;
973      }
974      for (i = 3; i < N; i++){   # loop 2A
975         x = q[i];                       # DR_MISALIGNMENT(q) = 0
976         p[i] = y;                       # DR_MISALIGNMENT(p) = unknown
977      }
978
979      -- Possibility 3: combination of loop peeling and versioning:
980      for (i = 0; i < 3; i++){   # (scalar loop, not to be vectorized).
981         x = q[i];
982         p[i] = y;
983      }
984      if (p is aligned) {
985         for (i = 3; i<N; i++){  # loop 3A
986           x = q[i];                     # DR_MISALIGNMENT(q) = 0
987           p[i] = y;                     # DR_MISALIGNMENT(p) = 0
988         }
989      }
990      else {
991         for (i = 3; i<N; i++){  # loop 3B
992           x = q[i];                     # DR_MISALIGNMENT(q) = 0
993           p[i] = y;                     # DR_MISALIGNMENT(p) = unaligned
994         }
995      }
996
997      These loops are later passed to loop_transform to be vectorized. The
998      vectorizer will use the alignment information to guide the transformation
999      (whether to generate regular loads/stores, or with special handling for
1000      misalignment).  */
1001
1002 static bool
1003 vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
1004 {
1005   VEC (data_reference_p, heap) *datarefs = LOOP_VINFO_DATAREFS (loop_vinfo);
1006   enum dr_alignment_support supportable_dr_alignment;
1007   struct data_reference *dr0 = NULL;
1008   struct data_reference *dr;
1009   unsigned int i;
1010   bool do_peeling = false;
1011   bool do_versioning = false;
1012   bool stat;
1013
1014   /* While cost model enhancements are expected in the future, the high level
1015      view of the code at this time is as follows:
1016
1017      A) If there is a misaligned write then see if peeling to align this write
1018         can make all data references satisfy vect_supportable_dr_alignment.
1019         If so, update data structures as needed and return true.  Note that
1020         at this time vect_supportable_dr_alignment is known to return false
1021         for a a misaligned write.
1022
1023      B) If peeling wasn't possible and there is a data reference with an
1024         unknown misalignment that does not satisfy vect_supportable_dr_alignment
1025         then see if loop versioning checks can be used to make all data
1026         references satisfy vect_supportable_dr_alignment.  If so, update
1027         data structures as needed and return true.
1028
1029      C) If neither peeling nor versioning were successful then return false if
1030         any data reference does not satisfy vect_supportable_dr_alignment.
1031
1032      D) Return true (all data references satisfy vect_supportable_dr_alignment).
1033
1034      Note, Possibility 3 above (which is peeling and versioning together) is not
1035      being done at this time.  */
1036
1037   /* (1) Peeling to force alignment.  */
1038
1039   /* (1.1) Decide whether to perform peeling, and how many iterations to peel:
1040      Considerations:
1041      + How many accesses will become aligned due to the peeling
1042      - How many accesses will become unaligned due to the peeling,
1043        and the cost of misaligned accesses.
1044      - The cost of peeling (the extra runtime checks, the increase 
1045        in code size).
1046
1047      The scheme we use FORNOW: peel to force the alignment of the first
1048      misaligned store in the loop.
1049      Rationale: misaligned stores are not yet supported.
1050
1051      TODO: Use a cost model.  */
1052
1053   for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++)
1054     if (!DR_IS_READ (dr) && !aligned_access_p (dr))
1055       {
1056         dr0 = dr;
1057         do_peeling = true;
1058         break;
1059       }
1060
1061   /* Often peeling for alignment will require peeling for loop-bound, which in 
1062      turn requires that we know how to adjust the loop ivs after the loop.  */
1063   if (!vect_can_advance_ivs_p (loop_vinfo))
1064     do_peeling = false;
1065
1066   if (do_peeling)
1067     {
1068       int mis;
1069       int npeel = 0;
1070
1071       if (known_alignment_for_access_p (dr0))
1072         {
1073           /* Since it's known at compile time, compute the number of iterations
1074              in the peeled loop (the peeling factor) for use in updating
1075              DR_MISALIGNMENT values.  The peeling factor is the vectorization
1076              factor minus the misalignment as an element count.  */
1077           mis = DR_MISALIGNMENT (dr0);
1078           mis /= GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (DR_REF (dr0))));
1079           npeel = LOOP_VINFO_VECT_FACTOR (loop_vinfo) - mis;
1080         }
1081
1082       /* Ensure that all data refs can be vectorized after the peel.  */
1083       for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++)
1084         {
1085           int save_misalignment;
1086
1087           if (dr == dr0)
1088             continue;
1089
1090           save_misalignment = DR_MISALIGNMENT (dr);
1091           vect_update_misalignment_for_peel (dr, dr0, npeel);
1092           supportable_dr_alignment = vect_supportable_dr_alignment (dr);
1093           DR_MISALIGNMENT (dr) = save_misalignment;
1094           
1095           if (!supportable_dr_alignment)
1096             {
1097               do_peeling = false;
1098               break;
1099             }
1100         }
1101
1102       if (do_peeling)
1103         {
1104           /* (1.2) Update the DR_MISALIGNMENT of each data reference DR_i.
1105              If the misalignment of DR_i is identical to that of dr0 then set
1106              DR_MISALIGNMENT (DR_i) to zero.  If the misalignment of DR_i and
1107              dr0 are known at compile time then increment DR_MISALIGNMENT (DR_i)
1108              by the peeling factor times the element size of DR_i (MOD the
1109              vectorization factor times the size).  Otherwise, the
1110              misalignment of DR_i must be set to unknown.  */
1111           for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++)
1112             if (dr != dr0)
1113               vect_update_misalignment_for_peel (dr, dr0, npeel);
1114
1115           LOOP_VINFO_UNALIGNED_DR (loop_vinfo) = dr0;
1116           LOOP_PEELING_FOR_ALIGNMENT (loop_vinfo) = DR_MISALIGNMENT (dr0);
1117           DR_MISALIGNMENT (dr0) = 0;
1118           if (vect_print_dump_info (REPORT_ALIGNMENT))
1119             fprintf (vect_dump, "Alignment of access forced using peeling.");
1120
1121           if (vect_print_dump_info (REPORT_DETAILS))
1122             fprintf (vect_dump, "Peeling for alignment will be applied.");
1123
1124           stat = vect_verify_datarefs_alignment (loop_vinfo);
1125           gcc_assert (stat);
1126           return stat;
1127         }
1128     }
1129
1130
1131   /* (2) Versioning to force alignment.  */
1132
1133   /* Try versioning if:
1134      1) flag_tree_vect_loop_version is TRUE
1135      2) optimize_size is FALSE
1136      3) there is at least one unsupported misaligned data ref with an unknown
1137         misalignment, and
1138      4) all misaligned data refs with a known misalignment are supported, and
1139      5) the number of runtime alignment checks is within reason.  */
1140
1141   do_versioning = flag_tree_vect_loop_version && (!optimize_size);
1142
1143   if (do_versioning)
1144     {
1145       for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++)
1146         {
1147           if (aligned_access_p (dr))
1148             continue;
1149
1150           supportable_dr_alignment = vect_supportable_dr_alignment (dr);
1151
1152           if (!supportable_dr_alignment)
1153             {
1154               tree stmt;
1155               int mask;
1156               tree vectype;
1157
1158               if (known_alignment_for_access_p (dr)
1159                   || VEC_length (tree,
1160                                  LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo))
1161                      >= (unsigned) PARAM_VALUE (PARAM_VECT_MAX_VERSION_CHECKS))
1162                 {
1163                   do_versioning = false;
1164                   break;
1165                 }
1166
1167               stmt = DR_STMT (dr);
1168               vectype = STMT_VINFO_VECTYPE (vinfo_for_stmt (stmt));
1169               gcc_assert (vectype);
1170   
1171               /* The rightmost bits of an aligned address must be zeros.
1172                  Construct the mask needed for this test.  For example,
1173                  GET_MODE_SIZE for the vector mode V4SI is 16 bytes so the
1174                  mask must be 15 = 0xf. */
1175               mask = GET_MODE_SIZE (TYPE_MODE (vectype)) - 1;
1176
1177               /* FORNOW: use the same mask to test all potentially unaligned
1178                  references in the loop.  The vectorizer currently supports
1179                  a single vector size, see the reference to
1180                  GET_MODE_NUNITS (TYPE_MODE (vectype)) where the
1181                  vectorization factor is computed.  */
1182               gcc_assert (!LOOP_VINFO_PTR_MASK (loop_vinfo)
1183                           || LOOP_VINFO_PTR_MASK (loop_vinfo) == mask);
1184               LOOP_VINFO_PTR_MASK (loop_vinfo) = mask;
1185               VEC_safe_push (tree, heap,
1186                              LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo),
1187                              DR_STMT (dr));
1188             }
1189         }
1190       
1191       /* Versioning requires at least one misaligned data reference.  */
1192       if (VEC_length (tree, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo)) == 0)
1193         do_versioning = false;
1194       else if (!do_versioning)
1195         VEC_truncate (tree, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo), 0);
1196     }
1197
1198   if (do_versioning)
1199     {
1200       VEC(tree,heap) *may_misalign_stmts
1201         = LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo);
1202       tree stmt;
1203
1204       /* It can now be assumed that the data references in the statements
1205          in LOOP_VINFO_MAY_MISALIGN_STMTS will be aligned in the version
1206          of the loop being vectorized.  */
1207       for (i = 0; VEC_iterate (tree, may_misalign_stmts, i, stmt); i++)
1208         {
1209           stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
1210           dr = STMT_VINFO_DATA_REF (stmt_info);
1211           DR_MISALIGNMENT (dr) = 0;
1212           if (vect_print_dump_info (REPORT_ALIGNMENT))
1213             fprintf (vect_dump, "Alignment of access forced using versioning.");
1214         }
1215
1216       if (vect_print_dump_info (REPORT_DETAILS))
1217         fprintf (vect_dump, "Versioning for alignment will be applied.");
1218
1219       /* Peeling and versioning can't be done together at this time.  */
1220       gcc_assert (! (do_peeling && do_versioning));
1221
1222       stat = vect_verify_datarefs_alignment (loop_vinfo);
1223       gcc_assert (stat);
1224       return stat;
1225     }
1226
1227   /* This point is reached if neither peeling nor versioning is being done.  */
1228   gcc_assert (! (do_peeling || do_versioning));
1229
1230   stat = vect_verify_datarefs_alignment (loop_vinfo);
1231   return stat;
1232 }
1233
1234
1235 /* Function vect_analyze_data_refs_alignment
1236
1237    Analyze the alignment of the data-references in the loop.
1238    Return FALSE if a data reference is found that cannot be vectorized.  */
1239
1240 static bool
1241 vect_analyze_data_refs_alignment (loop_vec_info loop_vinfo)
1242 {
1243   if (vect_print_dump_info (REPORT_DETAILS))
1244     fprintf (vect_dump, "=== vect_analyze_data_refs_alignment ===");
1245
1246   if (!vect_compute_data_refs_alignment (loop_vinfo))
1247     {
1248       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
1249         fprintf (vect_dump, 
1250                  "not vectorized: can't calculate alignment for data ref.");
1251       return false;
1252     }
1253
1254   return true;
1255 }
1256
1257
1258 /* Function vect_analyze_data_ref_access.
1259
1260    Analyze the access pattern of the data-reference DR. For now, a data access
1261    has to be consecutive to be considered vectorizable.  */
1262
1263 static bool
1264 vect_analyze_data_ref_access (struct data_reference *dr)
1265 {
1266   tree step = DR_STEP (dr);
1267   tree scalar_type = TREE_TYPE (DR_REF (dr));
1268
1269   if (!step || tree_int_cst_compare (step, TYPE_SIZE_UNIT (scalar_type)))
1270     {
1271       if (vect_print_dump_info (REPORT_DETAILS))
1272         fprintf (vect_dump, "not consecutive access");
1273       return false;
1274     }
1275   return true;
1276 }
1277
1278
1279 /* Function vect_analyze_data_ref_accesses.
1280
1281    Analyze the access pattern of all the data references in the loop.
1282
1283    FORNOW: the only access pattern that is considered vectorizable is a
1284            simple step 1 (consecutive) access.
1285
1286    FORNOW: handle only arrays and pointer accesses.  */
1287
1288 static bool
1289 vect_analyze_data_ref_accesses (loop_vec_info loop_vinfo)
1290 {
1291   unsigned int i;
1292   VEC (data_reference_p, heap) *datarefs = LOOP_VINFO_DATAREFS (loop_vinfo);
1293   struct data_reference *dr;
1294
1295   if (vect_print_dump_info (REPORT_DETAILS))
1296     fprintf (vect_dump, "=== vect_analyze_data_ref_accesses ===");
1297
1298   for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++)
1299     if (!vect_analyze_data_ref_access (dr))
1300       {
1301         if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
1302           fprintf (vect_dump, "not vectorized: complicated access pattern.");
1303         return false;
1304       }
1305
1306   return true;
1307 }
1308
1309
1310 /* Function vect_analyze_data_refs.
1311
1312   Find all the data references in the loop.
1313
1314    The general structure of the analysis of data refs in the vectorizer is as
1315    follows:
1316    1- vect_analyze_data_refs(loop): call compute_data_dependences_for_loop to
1317       find and analyze all data-refs in the loop and their dependences.
1318    2- vect_analyze_dependences(): apply dependence testing using ddrs.
1319    3- vect_analyze_drs_alignment(): check that ref_stmt.alignment is ok.
1320    4- vect_analyze_drs_access(): check that ref_stmt.step is ok.
1321
1322 */
1323
1324 static bool
1325 vect_analyze_data_refs (loop_vec_info loop_vinfo)  
1326 {
1327   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
1328   unsigned int i;
1329   VEC (data_reference_p, heap) *datarefs;
1330   struct data_reference *dr;
1331   tree scalar_type;
1332
1333   if (vect_print_dump_info (REPORT_DETAILS))
1334     fprintf (vect_dump, "=== vect_analyze_data_refs ===");
1335
1336   compute_data_dependences_for_loop (loop, false,
1337                                      &LOOP_VINFO_DATAREFS (loop_vinfo),
1338                                      &LOOP_VINFO_DDRS (loop_vinfo));
1339
1340   /* Go through the data-refs, check that the analysis succeeded. Update pointer
1341      from stmt_vec_info struct to DR and vectype.  */
1342   datarefs = LOOP_VINFO_DATAREFS (loop_vinfo);
1343
1344   for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++)
1345     {
1346       tree stmt;
1347       stmt_vec_info stmt_info;
1348    
1349       if (!dr || !DR_REF (dr))
1350         {
1351           if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
1352             fprintf (vect_dump, "not vectorized: unhandled data-ref ");
1353           return false;
1354         }
1355  
1356       /* Update DR field in stmt_vec_info struct.  */
1357       stmt = DR_STMT (dr);
1358       stmt_info = vinfo_for_stmt (stmt);
1359   
1360       if (STMT_VINFO_DATA_REF (stmt_info))
1361         {
1362           if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
1363             {
1364               fprintf (vect_dump,
1365                        "not vectorized: more than one data ref in stmt: ");
1366               print_generic_expr (vect_dump, stmt, TDF_SLIM);
1367             }
1368           return false;
1369         }
1370       STMT_VINFO_DATA_REF (stmt_info) = dr;
1371      
1372       /* Check that analysis of the data-ref succeeded.  */
1373       if (!DR_BASE_ADDRESS (dr) || !DR_OFFSET (dr) || !DR_INIT (dr)
1374           || !DR_STEP (dr))   
1375         {
1376           if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
1377             {
1378               fprintf (vect_dump, "not vectorized: data ref analysis failed ");
1379               print_generic_expr (vect_dump, stmt, TDF_SLIM);
1380             }
1381           return false;
1382         }
1383       if (!DR_MEMTAG (dr))
1384         {
1385           if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
1386             {
1387               fprintf (vect_dump, "not vectorized: no memory tag for ");
1388               print_generic_expr (vect_dump, DR_REF (dr), TDF_SLIM);
1389             }
1390           return false;
1391         }
1392                        
1393       /* Set vectype for STMT.  */
1394       scalar_type = TREE_TYPE (DR_REF (dr));
1395       STMT_VINFO_VECTYPE (stmt_info) =
1396                 get_vectype_for_scalar_type (scalar_type);
1397       if (!STMT_VINFO_VECTYPE (stmt_info)) 
1398         {
1399           if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
1400             {
1401               fprintf (vect_dump,
1402                        "not vectorized: no vectype for stmt: ");
1403               print_generic_expr (vect_dump, stmt, TDF_SLIM);
1404               fprintf (vect_dump, " scalar_type: ");
1405               print_generic_expr (vect_dump, scalar_type, TDF_DETAILS);
1406             }
1407           return false;
1408         }
1409     }
1410       
1411   return true;
1412 }
1413
1414
1415 /* Utility functions used by vect_mark_stmts_to_be_vectorized.  */
1416
1417 /* Function vect_mark_relevant.
1418
1419    Mark STMT as "relevant for vectorization" and add it to WORKLIST.  */
1420
1421 static void
1422 vect_mark_relevant (VEC(tree,heap) **worklist, tree stmt,
1423                     bool relevant_p, bool live_p)
1424 {
1425   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
1426   bool save_relevant_p = STMT_VINFO_RELEVANT_P (stmt_info);
1427   bool save_live_p = STMT_VINFO_LIVE_P (stmt_info);
1428
1429   if (vect_print_dump_info (REPORT_DETAILS))
1430     fprintf (vect_dump, "mark relevant %d, live %d.",relevant_p, live_p);
1431
1432   if (STMT_VINFO_IN_PATTERN_P (stmt_info))
1433     {
1434       tree pattern_stmt;
1435
1436       /* This is the last stmt in a sequence that was detected as a 
1437          pattern that can potentially be vectorized.  Don't mark the stmt
1438          as relevant/live because it's not going to vectorized.
1439          Instead mark the pattern-stmt that replaces it.  */
1440       if (vect_print_dump_info (REPORT_DETAILS))
1441         fprintf (vect_dump, "last stmt in pattern. don't mark relevant/live.");
1442       pattern_stmt = STMT_VINFO_RELATED_STMT (stmt_info);
1443       stmt_info = vinfo_for_stmt (pattern_stmt);
1444       gcc_assert (STMT_VINFO_RELATED_STMT (stmt_info) == stmt);
1445       save_relevant_p = STMT_VINFO_RELEVANT_P (stmt_info);
1446       save_live_p = STMT_VINFO_LIVE_P (stmt_info);
1447       stmt = pattern_stmt;
1448     }
1449
1450   STMT_VINFO_LIVE_P (stmt_info) |= live_p;
1451   STMT_VINFO_RELEVANT_P (stmt_info) |= relevant_p;
1452
1453   if (TREE_CODE (stmt) == PHI_NODE)
1454     /* Don't put phi-nodes in the worklist. Phis that are marked relevant
1455        or live will fail vectorization later on.  */
1456     return;
1457
1458   if (STMT_VINFO_RELEVANT_P (stmt_info) == save_relevant_p
1459       && STMT_VINFO_LIVE_P (stmt_info) == save_live_p)
1460     {
1461       if (vect_print_dump_info (REPORT_DETAILS))
1462         fprintf (vect_dump, "already marked relevant/live.");
1463       return;
1464     }
1465
1466   VEC_safe_push (tree, heap, *worklist, stmt);
1467 }
1468
1469
1470 /* Function vect_stmt_relevant_p.
1471
1472    Return true if STMT in loop that is represented by LOOP_VINFO is
1473    "relevant for vectorization".
1474
1475    A stmt is considered "relevant for vectorization" if:
1476    - it has uses outside the loop.
1477    - it has vdefs (it alters memory).
1478    - control stmts in the loop (except for the exit condition).
1479
1480    CHECKME: what other side effects would the vectorizer allow?  */
1481
1482 static bool
1483 vect_stmt_relevant_p (tree stmt, loop_vec_info loop_vinfo,
1484                       bool *relevant_p, bool *live_p)
1485 {
1486   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
1487   ssa_op_iter op_iter;
1488   imm_use_iterator imm_iter;
1489   use_operand_p use_p;
1490   def_operand_p def_p;
1491
1492   *relevant_p = false;
1493   *live_p = false;
1494
1495   /* cond stmt other than loop exit cond.  */
1496   if (is_ctrl_stmt (stmt) && (stmt != LOOP_VINFO_EXIT_COND (loop_vinfo)))
1497     *relevant_p = true;
1498
1499   /* changing memory.  */
1500   if (TREE_CODE (stmt) != PHI_NODE)
1501     if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_VIRTUAL_DEFS))
1502       {
1503         if (vect_print_dump_info (REPORT_DETAILS))
1504           fprintf (vect_dump, "vec_stmt_relevant_p: stmt has vdefs.");
1505         *relevant_p = true;
1506       }
1507
1508   /* uses outside the loop.  */
1509   FOR_EACH_PHI_OR_STMT_DEF (def_p, stmt, op_iter, SSA_OP_DEF)
1510     {
1511       FOR_EACH_IMM_USE_FAST (use_p, imm_iter, DEF_FROM_PTR (def_p))
1512         {
1513           basic_block bb = bb_for_stmt (USE_STMT (use_p));
1514           if (!flow_bb_inside_loop_p (loop, bb))
1515             {
1516               if (vect_print_dump_info (REPORT_DETAILS))
1517                 fprintf (vect_dump, "vec_stmt_relevant_p: used out of loop.");
1518
1519               /* We expect all such uses to be in the loop exit phis
1520                  (because of loop closed form)   */
1521               gcc_assert (TREE_CODE (USE_STMT (use_p)) == PHI_NODE);
1522               gcc_assert (bb == loop->single_exit->dest);
1523
1524               *live_p = true;
1525             }
1526         }
1527     }
1528
1529   return (*live_p || *relevant_p);
1530 }
1531
1532
1533 /* Function vect_mark_stmts_to_be_vectorized.
1534
1535    Not all stmts in the loop need to be vectorized. For example:
1536
1537      for i...
1538        for j...
1539    1.    T0 = i + j
1540    2.    T1 = a[T0]
1541
1542    3.    j = j + 1
1543
1544    Stmt 1 and 3 do not need to be vectorized, because loop control and
1545    addressing of vectorized data-refs are handled differently.
1546
1547    This pass detects such stmts.  */
1548
1549 static bool
1550 vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo)
1551 {
1552   VEC(tree,heap) *worklist;
1553   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
1554   basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
1555   unsigned int nbbs = loop->num_nodes;
1556   block_stmt_iterator si;
1557   tree stmt, use;
1558   stmt_ann_t ann;
1559   ssa_op_iter iter;
1560   unsigned int i;
1561   stmt_vec_info stmt_vinfo;
1562   basic_block bb;
1563   tree phi;
1564   bool relevant_p, live_p;
1565   tree def, def_stmt;
1566   enum vect_def_type dt;
1567
1568   if (vect_print_dump_info (REPORT_DETAILS))
1569     fprintf (vect_dump, "=== vect_mark_stmts_to_be_vectorized ===");
1570
1571   worklist = VEC_alloc (tree, heap, 64);
1572
1573   /* 1. Init worklist.  */
1574
1575   bb = loop->header;
1576   for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
1577     {
1578       if (vect_print_dump_info (REPORT_DETAILS))
1579         {
1580           fprintf (vect_dump, "init: phi relevant? ");
1581           print_generic_expr (vect_dump, phi, TDF_SLIM);
1582         }
1583
1584       if (vect_stmt_relevant_p (phi, loop_vinfo, &relevant_p, &live_p))
1585         vect_mark_relevant (&worklist, phi, relevant_p, live_p);
1586     }
1587
1588   for (i = 0; i < nbbs; i++)
1589     {
1590       bb = bbs[i];
1591       for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
1592         {
1593           stmt = bsi_stmt (si);
1594
1595           if (vect_print_dump_info (REPORT_DETAILS))
1596             {
1597               fprintf (vect_dump, "init: stmt relevant? ");
1598               print_generic_expr (vect_dump, stmt, TDF_SLIM);
1599             } 
1600
1601           if (vect_stmt_relevant_p (stmt, loop_vinfo, &relevant_p, &live_p))
1602             vect_mark_relevant (&worklist, stmt, relevant_p, live_p);
1603         }
1604     }
1605
1606
1607   /* 2. Process_worklist */
1608
1609   while (VEC_length (tree, worklist) > 0)
1610     {
1611       stmt = VEC_pop (tree, worklist);
1612
1613       if (vect_print_dump_info (REPORT_DETAILS))
1614         {
1615           fprintf (vect_dump, "worklist: examine stmt: ");
1616           print_generic_expr (vect_dump, stmt, TDF_SLIM);
1617         }
1618
1619       /* Examine the USEs of STMT. For each ssa-name USE thta is defined
1620          in the loop, mark the stmt that defines it (DEF_STMT) as
1621          relevant/irrelevant and live/dead according to the liveness and
1622          relevance properties of STMT.
1623        */
1624
1625       gcc_assert (TREE_CODE (stmt) != PHI_NODE);
1626
1627       ann = stmt_ann (stmt);
1628       stmt_vinfo = vinfo_for_stmt (stmt);
1629
1630       relevant_p = STMT_VINFO_RELEVANT_P (stmt_vinfo);
1631       live_p = STMT_VINFO_LIVE_P (stmt_vinfo);
1632
1633       /* Generally, the liveness and relevance properties of STMT are
1634          propagated to the DEF_STMTs of its USEs:
1635              STMT_VINFO_LIVE_P (DEF_STMT_info) <-- live_p
1636              STMT_VINFO_RELEVANT_P (DEF_STMT_info) <-- relevant_p
1637
1638          Exceptions:
1639
1640          (case 1)
1641            If USE is used only for address computations (e.g. array indexing),
1642            which does not need to be directly vectorized, then the
1643            liveness/relevance of the respective DEF_STMT is left unchanged.
1644
1645          (case 2)
1646            If STMT has been identified as defining a reduction variable, then
1647            we have two cases:
1648            (case 2.1)
1649              The last use of STMT is the reduction-variable, which is defined
1650              by a loop-header-phi. We don't want to mark the phi as live or
1651              relevant (because it does not need to be vectorized, it is handled
1652              as part of the vectorization of the reduction), so in this case we
1653              skip the call to vect_mark_relevant.
1654            (case 2.2)
1655              The rest of the uses of STMT are defined in the loop body. For
1656              the def_stmt of these uses we want to set liveness/relevance
1657              as follows:
1658                STMT_VINFO_LIVE_P (DEF_STMT_info) <-- false
1659                STMT_VINFO_RELEVANT_P (DEF_STMT_info) <-- true
1660              because even though STMT is classified as live (since it defines a
1661              value that is used across loop iterations) and irrelevant (since it
1662              is not used inside the loop), it will be vectorized, and therefore
1663              the corresponding DEF_STMTs need to marked as relevant.
1664        */
1665
1666       /* case 2.2:  */
1667       if (STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_reduction_def)
1668         {
1669           gcc_assert (!relevant_p && live_p);
1670           relevant_p = true;
1671           live_p = false;
1672         }
1673
1674       FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
1675         {
1676           /* case 1: we are only interested in uses that need to be vectorized. 
1677              Uses that are used for address computation are not considered 
1678              relevant.
1679            */
1680           if (!exist_non_indexing_operands_for_use_p (use, stmt))
1681             continue;
1682
1683           if (!vect_is_simple_use (use, loop_vinfo, &def_stmt, &def, &dt))
1684             {
1685               if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
1686                 fprintf (vect_dump, "not vectorized: unsupported use in stmt.");
1687               VEC_free (tree, heap, worklist);
1688               return false;
1689             }
1690
1691           if (!def_stmt || IS_EMPTY_STMT (def_stmt))
1692             continue;
1693
1694           if (vect_print_dump_info (REPORT_DETAILS))
1695             {
1696               fprintf (vect_dump, "worklist: examine use %d: ", i);
1697               print_generic_expr (vect_dump, use, TDF_SLIM);
1698             }
1699
1700           bb = bb_for_stmt (def_stmt);
1701           if (!flow_bb_inside_loop_p (loop, bb))
1702             continue;
1703
1704           /* case 2.1: the reduction-use does not mark the defining-phi
1705              as relevant.  */
1706           if (STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_reduction_def
1707               && TREE_CODE (def_stmt) == PHI_NODE)
1708             continue;
1709
1710           vect_mark_relevant (&worklist, def_stmt, relevant_p, live_p);
1711         }
1712     }                           /* while worklist */
1713
1714   VEC_free (tree, heap, worklist);
1715   return true;
1716 }
1717
1718
1719 /* Function vect_can_advance_ivs_p
1720
1721    In case the number of iterations that LOOP iterates is unknown at compile 
1722    time, an epilog loop will be generated, and the loop induction variables 
1723    (IVs) will be "advanced" to the value they are supposed to take just before 
1724    the epilog loop.  Here we check that the access function of the loop IVs
1725    and the expression that represents the loop bound are simple enough.
1726    These restrictions will be relaxed in the future.  */
1727
1728 static bool 
1729 vect_can_advance_ivs_p (loop_vec_info loop_vinfo)
1730 {
1731   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
1732   basic_block bb = loop->header;
1733   tree phi;
1734
1735   /* Analyze phi functions of the loop header.  */
1736
1737   if (vect_print_dump_info (REPORT_DETAILS))
1738     fprintf (vect_dump, "=== vect_can_advance_ivs_p ===");
1739
1740   for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
1741     {
1742       tree access_fn = NULL;
1743       tree evolution_part;
1744
1745       if (vect_print_dump_info (REPORT_DETAILS))
1746         {
1747           fprintf (vect_dump, "Analyze phi: ");
1748           print_generic_expr (vect_dump, phi, TDF_SLIM);
1749         }
1750
1751       /* Skip virtual phi's. The data dependences that are associated with
1752          virtual defs/uses (i.e., memory accesses) are analyzed elsewhere.  */
1753
1754       if (!is_gimple_reg (SSA_NAME_VAR (PHI_RESULT (phi))))
1755         {
1756           if (vect_print_dump_info (REPORT_DETAILS))
1757             fprintf (vect_dump, "virtual phi. skip.");
1758           continue;
1759         }
1760
1761       /* Skip reduction phis.  */
1762
1763       if (STMT_VINFO_DEF_TYPE (vinfo_for_stmt (phi)) == vect_reduction_def)
1764         {
1765           if (vect_print_dump_info (REPORT_DETAILS))
1766             fprintf (vect_dump, "reduc phi. skip.");
1767           continue;
1768         }
1769
1770       /* Analyze the evolution function.  */
1771
1772       access_fn = instantiate_parameters
1773         (loop, analyze_scalar_evolution (loop, PHI_RESULT (phi)));
1774
1775       if (!access_fn)
1776         {
1777           if (vect_print_dump_info (REPORT_DETAILS))
1778             fprintf (vect_dump, "No Access function.");
1779           return false;
1780         }
1781
1782       if (vect_print_dump_info (REPORT_DETAILS))
1783         {
1784           fprintf (vect_dump, "Access function of PHI: ");
1785           print_generic_expr (vect_dump, access_fn, TDF_SLIM);
1786         }
1787
1788       evolution_part = evolution_part_in_loop_num (access_fn, loop->num);
1789       
1790       if (evolution_part == NULL_TREE)
1791         {
1792           if (vect_print_dump_info (REPORT_DETAILS))
1793             fprintf (vect_dump, "No evolution.");
1794           return false;
1795         }
1796   
1797       /* FORNOW: We do not transform initial conditions of IVs 
1798          which evolution functions are a polynomial of degree >= 2.  */
1799
1800       if (tree_is_chrec (evolution_part))
1801         return false;  
1802     }
1803
1804   return true;
1805 }
1806
1807
1808 /* Function vect_get_loop_niters.
1809
1810    Determine how many iterations the loop is executed.
1811    If an expression that represents the number of iterations
1812    can be constructed, place it in NUMBER_OF_ITERATIONS.
1813    Return the loop exit condition.  */
1814
1815 static tree
1816 vect_get_loop_niters (struct loop *loop, tree *number_of_iterations)
1817 {
1818   tree niters;
1819
1820   if (vect_print_dump_info (REPORT_DETAILS))
1821     fprintf (vect_dump, "=== get_loop_niters ===");
1822
1823   niters = number_of_iterations_in_loop (loop);
1824
1825   if (niters != NULL_TREE
1826       && niters != chrec_dont_know)
1827     {
1828       *number_of_iterations = niters;
1829
1830       if (vect_print_dump_info (REPORT_DETAILS))
1831         {
1832           fprintf (vect_dump, "==> get_loop_niters:" );
1833           print_generic_expr (vect_dump, *number_of_iterations, TDF_SLIM);
1834         }
1835     }
1836
1837   return get_loop_exit_condition (loop);
1838 }
1839
1840
1841 /* Function vect_analyze_loop_form.
1842
1843    Verify the following restrictions (some may be relaxed in the future):
1844    - it's an inner-most loop
1845    - number of BBs = 2 (which are the loop header and the latch)
1846    - the loop has a pre-header
1847    - the loop has a single entry and exit
1848    - the loop exit condition is simple enough, and the number of iterations
1849      can be analyzed (a countable loop).  */
1850
1851 static loop_vec_info
1852 vect_analyze_loop_form (struct loop *loop)
1853 {
1854   loop_vec_info loop_vinfo;
1855   tree loop_cond;
1856   tree number_of_iterations = NULL;
1857
1858   if (vect_print_dump_info (REPORT_DETAILS))
1859     fprintf (vect_dump, "=== vect_analyze_loop_form ===");
1860
1861   if (loop->inner)
1862     {
1863       if (vect_print_dump_info (REPORT_OUTER_LOOPS))
1864         fprintf (vect_dump, "not vectorized: nested loop.");
1865       return NULL;
1866     }
1867   
1868   if (!loop->single_exit 
1869       || loop->num_nodes != 2
1870       || EDGE_COUNT (loop->header->preds) != 2)
1871     {
1872       if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
1873         {
1874           if (!loop->single_exit)
1875             fprintf (vect_dump, "not vectorized: multiple exits.");
1876           else if (loop->num_nodes != 2)
1877             fprintf (vect_dump, "not vectorized: too many BBs in loop.");
1878           else if (EDGE_COUNT (loop->header->preds) != 2)
1879             fprintf (vect_dump, "not vectorized: too many incoming edges.");
1880         }
1881
1882       return NULL;
1883     }
1884
1885   /* We assume that the loop exit condition is at the end of the loop. i.e,
1886      that the loop is represented as a do-while (with a proper if-guard
1887      before the loop if needed), where the loop header contains all the
1888      executable statements, and the latch is empty.  */
1889   if (!empty_block_p (loop->latch))
1890     {
1891       if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
1892         fprintf (vect_dump, "not vectorized: unexpected loop form.");
1893       return NULL;
1894     }
1895
1896   /* Make sure there exists a single-predecessor exit bb:  */
1897   if (!single_pred_p (loop->single_exit->dest))
1898     {
1899       edge e = loop->single_exit;
1900       if (!(e->flags & EDGE_ABNORMAL))
1901         {
1902           split_loop_exit_edge (e);
1903           if (vect_print_dump_info (REPORT_DETAILS))
1904             fprintf (vect_dump, "split exit edge.");
1905         }
1906       else
1907         {
1908           if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
1909             fprintf (vect_dump, "not vectorized: abnormal loop exit edge.");
1910           return NULL;
1911         }
1912     }
1913
1914   if (empty_block_p (loop->header))
1915     {
1916       if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
1917         fprintf (vect_dump, "not vectorized: empty loop.");
1918       return NULL;
1919     }
1920
1921   loop_cond = vect_get_loop_niters (loop, &number_of_iterations);
1922   if (!loop_cond)
1923     {
1924       if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
1925         fprintf (vect_dump, "not vectorized: complicated exit condition.");
1926       return NULL;
1927     }
1928   
1929   if (!number_of_iterations) 
1930     {
1931       if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
1932         fprintf (vect_dump, 
1933                  "not vectorized: number of iterations cannot be computed.");
1934       return NULL;
1935     }
1936
1937   if (chrec_contains_undetermined (number_of_iterations))
1938     {
1939       if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
1940         fprintf (vect_dump, "Infinite number of iterations.");
1941       return false;
1942     }
1943
1944   loop_vinfo = new_loop_vec_info (loop);
1945   LOOP_VINFO_NITERS (loop_vinfo) = number_of_iterations;
1946
1947   if (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo))
1948     {
1949       if (vect_print_dump_info (REPORT_DETAILS))
1950         {
1951           fprintf (vect_dump, "Symbolic number of iterations is ");
1952           print_generic_expr (vect_dump, number_of_iterations, TDF_DETAILS);
1953         }
1954     }
1955   else
1956   if (LOOP_VINFO_INT_NITERS (loop_vinfo) == 0)
1957     {
1958       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
1959         fprintf (vect_dump, "not vectorized: number of iterations = 0.");
1960       return NULL;
1961     }
1962
1963   LOOP_VINFO_EXIT_COND (loop_vinfo) = loop_cond;
1964
1965   return loop_vinfo;
1966 }
1967
1968
1969 /* Function vect_analyze_loop.
1970
1971    Apply a set of analyses on LOOP, and create a loop_vec_info struct
1972    for it. The different analyses will record information in the
1973    loop_vec_info struct.  */
1974 loop_vec_info
1975 vect_analyze_loop (struct loop *loop)
1976 {
1977   bool ok;
1978   loop_vec_info loop_vinfo;
1979
1980   if (vect_print_dump_info (REPORT_DETAILS))
1981     fprintf (vect_dump, "===== analyze_loop_nest =====");
1982
1983   /* Check the CFG characteristics of the loop (nesting, entry/exit, etc.  */
1984
1985   loop_vinfo = vect_analyze_loop_form (loop);
1986   if (!loop_vinfo)
1987     {
1988       if (vect_print_dump_info (REPORT_DETAILS))
1989         fprintf (vect_dump, "bad loop form.");
1990       return NULL;
1991     }
1992
1993   /* Find all data references in the loop (which correspond to vdefs/vuses)
1994      and analyze their evolution in the loop.
1995
1996      FORNOW: Handle only simple, array references, which
1997      alignment can be forced, and aligned pointer-references.  */
1998
1999   ok = vect_analyze_data_refs (loop_vinfo);
2000   if (!ok)
2001     {
2002       if (vect_print_dump_info (REPORT_DETAILS))
2003         fprintf (vect_dump, "bad data references.");
2004       destroy_loop_vec_info (loop_vinfo);
2005       return NULL;
2006     }
2007
2008   /* Classify all cross-iteration scalar data-flow cycles.
2009      Cross-iteration cycles caused by virtual phis are analyzed separately.  */
2010
2011   vect_analyze_scalar_cycles (loop_vinfo);
2012
2013   vect_pattern_recog (loop_vinfo);
2014
2015   /* Data-flow analysis to detect stmts that do not need to be vectorized.  */
2016
2017   ok = vect_mark_stmts_to_be_vectorized (loop_vinfo);
2018   if (!ok)
2019     {
2020       if (vect_print_dump_info (REPORT_DETAILS))
2021         fprintf (vect_dump, "unexpected pattern.");
2022       destroy_loop_vec_info (loop_vinfo);
2023       return NULL;
2024     }
2025
2026   /* Analyze the alignment of the data-refs in the loop.
2027      Fail if a data reference is found that cannot be vectorized.  */
2028
2029   ok = vect_analyze_data_refs_alignment (loop_vinfo);
2030   if (!ok)
2031     {
2032       if (vect_print_dump_info (REPORT_DETAILS))
2033         fprintf (vect_dump, "bad data alignment.");
2034       destroy_loop_vec_info (loop_vinfo);
2035       return NULL;
2036     }
2037
2038   ok = vect_determine_vectorization_factor (loop_vinfo);
2039   if (!ok)
2040     {
2041       if (vect_print_dump_info (REPORT_DETAILS))
2042         fprintf (vect_dump, "can't determine vectorization factor.");
2043       destroy_loop_vec_info (loop_vinfo);
2044       return NULL;
2045     }
2046
2047   /* Analyze data dependences between the data-refs in the loop. 
2048      FORNOW: fail at the first data dependence that we encounter.  */
2049
2050   ok = vect_analyze_data_ref_dependences (loop_vinfo);
2051   if (!ok)
2052     {
2053       if (vect_print_dump_info (REPORT_DETAILS))
2054         fprintf (vect_dump, "bad data dependence.");
2055       destroy_loop_vec_info (loop_vinfo);
2056       return NULL;
2057     }
2058
2059   /* Analyze the access patterns of the data-refs in the loop (consecutive,
2060      complex, etc.). FORNOW: Only handle consecutive access pattern.  */
2061
2062   ok = vect_analyze_data_ref_accesses (loop_vinfo);
2063   if (!ok)
2064     {
2065       if (vect_print_dump_info (REPORT_DETAILS))
2066         fprintf (vect_dump, "bad data access.");
2067       destroy_loop_vec_info (loop_vinfo);
2068       return NULL;
2069     }
2070
2071   /* This pass will decide on using loop versioning and/or loop peeling in
2072      order to enhance the alignment of data references in the loop.  */
2073
2074   ok = vect_enhance_data_refs_alignment (loop_vinfo);
2075   if (!ok)
2076     {
2077       if (vect_print_dump_info (REPORT_DETAILS))
2078         fprintf (vect_dump, "bad data alignment.");
2079       destroy_loop_vec_info (loop_vinfo);
2080       return NULL;
2081     }
2082
2083   /* Scan all the operations in the loop and make sure they are
2084      vectorizable.  */
2085
2086   ok = vect_analyze_operations (loop_vinfo);
2087   if (!ok)
2088     {
2089       if (vect_print_dump_info (REPORT_DETAILS))
2090         fprintf (vect_dump, "bad operation or unsupported loop bound.");
2091       destroy_loop_vec_info (loop_vinfo);
2092       return NULL;
2093     }
2094
2095   LOOP_VINFO_VECTORIZABLE_P (loop_vinfo) = 1;
2096
2097   return loop_vinfo;
2098 }