OSDN Git Service

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