OSDN Git Service

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