OSDN Git Service

PR tree-optimization/33373
[pf3gnuchains/gcc-fork.git] / gcc / tree-vect-analyze.c
1 /* Analysis Utilities for Loop Vectorization.
2    Copyright (C) 2003, 2004, 2005, 2006, 2007 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 3, 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 COPYING3.  If not see
19 <http://www.gnu.org/licenses/>.  */
20
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "ggc.h"
26 #include "tree.h"
27 #include "target.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 #include "recog.h"
43
44 /* Main analysis functions.  */
45 static loop_vec_info vect_analyze_loop_form (struct loop *);
46 static bool vect_analyze_data_refs (loop_vec_info);
47 static bool vect_mark_stmts_to_be_vectorized (loop_vec_info);
48 static void vect_analyze_scalar_cycles (loop_vec_info);
49 static bool vect_analyze_data_ref_accesses (loop_vec_info);
50 static bool vect_analyze_data_ref_dependences (loop_vec_info);
51 static bool vect_analyze_data_refs_alignment (loop_vec_info);
52 static bool vect_compute_data_refs_alignment (loop_vec_info);
53 static bool vect_enhance_data_refs_alignment (loop_vec_info);
54 static bool vect_analyze_operations (loop_vec_info);
55 static bool vect_determine_vectorization_factor (loop_vec_info);
56
57 /* Utility functions for the analyses.  */
58 static bool exist_non_indexing_operands_for_use_p (tree, tree);
59 static tree vect_get_loop_niters (struct loop *, tree *);
60 static bool vect_analyze_data_ref_dependence
61   (struct data_dependence_relation *, loop_vec_info);
62 static bool vect_compute_data_ref_alignment (struct data_reference *); 
63 static bool vect_analyze_data_ref_access (struct data_reference *);
64 static bool vect_can_advance_ivs_p (loop_vec_info);
65 static void vect_update_misalignment_for_peel
66   (struct data_reference *, struct data_reference *, int npeel);
67
68 /* Function vect_determine_vectorization_factor
69
70    Determine the vectorization factor (VF). VF is the number of data elements
71    that are operated upon in parallel in a single iteration of the vectorized
72    loop. For example, when vectorizing a loop that operates on 4byte elements,
73    on a target with vector size (VS) 16byte, the VF is set to 4, since 4
74    elements can fit in a single vector register.
75
76    We currently support vectorization of loops in which all types operated upon
77    are of the same size. Therefore this function currently sets VF according to
78    the size of the types operated upon, and fails if there are multiple sizes
79    in the loop.
80
81    VF is also the factor by which the loop iterations are strip-mined, e.g.:
82    original loop:
83         for (i=0; i<N; i++){
84           a[i] = b[i] + c[i];
85         }
86
87    vectorized loop:
88         for (i=0; i<N; i+=VF){
89           a[i:VF] = b[i:VF] + c[i:VF];
90         }
91 */
92
93 static bool
94 vect_determine_vectorization_factor (loop_vec_info loop_vinfo)
95 {
96   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
97   basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
98   int nbbs = loop->num_nodes;
99   block_stmt_iterator si;
100   unsigned int vectorization_factor = 0;
101   tree scalar_type;
102   tree phi;
103   tree vectype;
104   unsigned int nunits;
105   stmt_vec_info stmt_info;
106   int i;
107
108   if (vect_print_dump_info (REPORT_DETAILS))
109     fprintf (vect_dump, "=== vect_determine_vectorization_factor ===");
110
111   for (i = 0; i < nbbs; i++)
112     {
113       basic_block bb = bbs[i];
114
115       for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
116         {
117           stmt_info = vinfo_for_stmt (phi);
118           if (vect_print_dump_info (REPORT_DETAILS))
119             {
120               fprintf (vect_dump, "==> examining phi: ");
121               print_generic_expr (vect_dump, phi, TDF_SLIM);
122             }
123
124           gcc_assert (stmt_info);
125
126           if (STMT_VINFO_RELEVANT_P (stmt_info))
127             {
128               gcc_assert (!STMT_VINFO_VECTYPE (stmt_info));
129               scalar_type = TREE_TYPE (PHI_RESULT (phi));
130
131               if (vect_print_dump_info (REPORT_DETAILS))
132                 {
133                   fprintf (vect_dump, "get vectype for scalar type:  ");
134                   print_generic_expr (vect_dump, scalar_type, TDF_SLIM);
135                 }
136
137               vectype = get_vectype_for_scalar_type (scalar_type);
138               if (!vectype)
139                 {
140                   if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
141                     {
142                       fprintf (vect_dump,
143                                "not vectorized: unsupported data-type ");
144                       print_generic_expr (vect_dump, scalar_type, TDF_SLIM);
145                     }
146                   return false;
147                 }
148               STMT_VINFO_VECTYPE (stmt_info) = vectype;
149
150               if (vect_print_dump_info (REPORT_DETAILS))
151                 {
152                   fprintf (vect_dump, "vectype: ");
153                   print_generic_expr (vect_dump, vectype, TDF_SLIM);
154                 }
155
156               nunits = TYPE_VECTOR_SUBPARTS (vectype);
157               if (vect_print_dump_info (REPORT_DETAILS))
158                 fprintf (vect_dump, "nunits = %d", nunits);
159
160               if (!vectorization_factor
161                   || (nunits > vectorization_factor))
162                 vectorization_factor = nunits;
163             }
164         }
165
166       for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
167         {
168           tree stmt = bsi_stmt (si);
169           stmt_info = vinfo_for_stmt (stmt);
170
171           if (vect_print_dump_info (REPORT_DETAILS))
172             {
173               fprintf (vect_dump, "==> examining statement: ");
174               print_generic_expr (vect_dump, stmt, TDF_SLIM);
175             }
176
177           gcc_assert (stmt_info);
178
179           /* skip stmts which do not need to be vectorized.  */
180           if (!STMT_VINFO_RELEVANT_P (stmt_info)
181               && !STMT_VINFO_LIVE_P (stmt_info))
182             {
183               if (vect_print_dump_info (REPORT_DETAILS))
184                 fprintf (vect_dump, "skip.");
185               continue;
186             }
187
188           if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
189             {
190               if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
191                 {
192                   fprintf (vect_dump, "not vectorized: irregular stmt.");
193                   print_generic_expr (vect_dump, stmt, TDF_SLIM);
194                 }
195               return false;
196             }
197
198           if (!GIMPLE_STMT_P (stmt)
199               && VECTOR_MODE_P (TYPE_MODE (TREE_TYPE (stmt))))
200             {
201               if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
202                 {
203                   fprintf (vect_dump, "not vectorized: vector stmt in loop:");
204                   print_generic_expr (vect_dump, stmt, TDF_SLIM);
205                 }
206               return false;
207             }
208
209           if (STMT_VINFO_VECTYPE (stmt_info))
210             {
211               /* The only case when a vectype had been already set is for stmts 
212                  that contain a dataref, or for "pattern-stmts" (stmts generated
213                  by the vectorizer to represent/replace a certain idiom).  */
214               gcc_assert (STMT_VINFO_DATA_REF (stmt_info) 
215                           || is_pattern_stmt_p (stmt_info));
216               vectype = STMT_VINFO_VECTYPE (stmt_info);
217             }
218           else
219             {
220               tree operation;
221
222               gcc_assert (! STMT_VINFO_DATA_REF (stmt_info)
223                           && !is_pattern_stmt_p (stmt_info));
224
225               /* We generally set the vectype according to the type of the 
226                  result (lhs).
227                  For stmts whose result-type is different than the type of the
228                  arguments (e.g. demotion, promotion), vectype will be reset 
229                  appropriately (later).  Note that we have to visit the smallest 
230                  datatype in this function, because that determines the VF.  
231                  If the smallest datatype in the loop is present only as the 
232                  rhs of a promotion operation - we'd miss it here.
233                  Such a case, where a variable of this datatype does not appear 
234                  in the lhs anywhere in the loop, can only occur if it's an
235                  invariant: e.g.: 'int_x = (int) short_inv', which we'd expect
236                  to have been optimized away by invariant motion. However, we 
237                  cannot rely on invariant motion to always take invariants out
238                  of the loop, and so in the case of promotion we also have to 
239                  check the rhs.  */
240               scalar_type = TREE_TYPE (GIMPLE_STMT_OPERAND (stmt, 0));
241
242               operation = GIMPLE_STMT_OPERAND (stmt, 1);
243               if (TREE_CODE (operation) == NOP_EXPR
244                   || TREE_CODE (operation) == CONVERT_EXPR
245                   || TREE_CODE (operation) == WIDEN_MULT_EXPR)
246                 {
247                   tree rhs_type = TREE_TYPE (TREE_OPERAND (operation, 0));
248                   if (TREE_INT_CST_LOW (TYPE_SIZE_UNIT (rhs_type)) < 
249                       TREE_INT_CST_LOW (TYPE_SIZE_UNIT (scalar_type)))
250                     scalar_type = rhs_type;
251                 }
252
253               if (vect_print_dump_info (REPORT_DETAILS))
254                 {
255                   fprintf (vect_dump, "get vectype for scalar type:  ");
256                   print_generic_expr (vect_dump, scalar_type, TDF_SLIM);
257                 }
258
259               vectype = get_vectype_for_scalar_type (scalar_type);
260               if (!vectype)
261                 {
262                   if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
263                     {
264                       fprintf (vect_dump, 
265                                "not vectorized: unsupported data-type ");
266                       print_generic_expr (vect_dump, scalar_type, TDF_SLIM);
267                     }
268                   return false;
269                 }
270               STMT_VINFO_VECTYPE (stmt_info) = vectype;
271             }
272
273           if (vect_print_dump_info (REPORT_DETAILS))
274             {
275               fprintf (vect_dump, "vectype: ");
276               print_generic_expr (vect_dump, vectype, TDF_SLIM);
277             }
278
279           nunits = TYPE_VECTOR_SUBPARTS (vectype);
280           if (vect_print_dump_info (REPORT_DETAILS))
281             fprintf (vect_dump, "nunits = %d", nunits);
282
283           if (!vectorization_factor
284               || (nunits > vectorization_factor))
285             vectorization_factor = nunits;
286
287         }
288     }
289
290   /* TODO: Analyze cost. Decide if worth while to vectorize.  */
291   if (vect_print_dump_info (REPORT_DETAILS))
292     fprintf (vect_dump, "vectorization factor = %d", vectorization_factor);
293   if (vectorization_factor <= 1)
294     {
295       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
296         fprintf (vect_dump, "not vectorized: unsupported data-type");
297       return false;
298     }
299   LOOP_VINFO_VECT_FACTOR (loop_vinfo) = vectorization_factor;
300
301   return true;
302 }
303
304
305 /* SLP costs are calculated according to SLP instance unrolling factor (i.e., 
306    the number of created vector stmts depends on the unrolling factor). However,
307    the actual number of vector stmts for every SLP node depends on VF which is
308    set later in vect_analyze_operations(). Hence, SLP costs should be updated.
309    In this function we assume that the inside costs calculated in 
310    vect_model_xxx_cost are linear in ncopies.  */
311
312 static void
313 vect_update_slp_costs_according_to_vf (loop_vec_info loop_vinfo)
314 {
315   unsigned int i, vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
316   VEC (slp_instance, heap) *slp_instances = LOOP_VINFO_SLP_INSTANCES (loop_vinfo);
317   slp_instance instance;
318
319   if (vect_print_dump_info (REPORT_SLP))
320     fprintf (vect_dump, "=== vect_update_slp_costs_according_to_vf ===");
321
322   for (i = 0; VEC_iterate (slp_instance, slp_instances, i, instance); i++)
323     /* We assume that costs are linear in ncopies.  */
324     SLP_INSTANCE_INSIDE_OF_LOOP_COST (instance) *= vf 
325       / SLP_INSTANCE_UNROLLING_FACTOR (instance);         
326 }
327
328
329 /* Function vect_analyze_operations.
330
331    Scan the loop stmts and make sure they are all vectorizable.  */
332
333 static bool
334 vect_analyze_operations (loop_vec_info loop_vinfo)
335 {
336   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
337   basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
338   int nbbs = loop->num_nodes;
339   block_stmt_iterator si;
340   unsigned int vectorization_factor = 0;
341   int i;
342   bool ok;
343   tree phi;
344   stmt_vec_info stmt_info;
345   bool need_to_vectorize = false;
346   int min_profitable_iters;
347   int min_scalar_loop_bound;
348   unsigned int th;
349   bool only_slp_in_loop = true;
350
351   if (vect_print_dump_info (REPORT_DETAILS))
352     fprintf (vect_dump, "=== vect_analyze_operations ===");
353
354   gcc_assert (LOOP_VINFO_VECT_FACTOR (loop_vinfo));
355   vectorization_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
356
357   for (i = 0; i < nbbs; i++)
358     {
359       basic_block bb = bbs[i];
360
361       for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
362         {
363           ok = true;
364
365           stmt_info = vinfo_for_stmt (phi);
366           if (vect_print_dump_info (REPORT_DETAILS))
367             {
368               fprintf (vect_dump, "examining phi: ");
369               print_generic_expr (vect_dump, phi, TDF_SLIM);
370             }
371
372           if (! is_loop_header_bb_p (bb))
373             {
374               /* inner-loop loop-closed exit phi in outer-loop vectorization
375                  (i.e. a phi in the tail of the outer-loop). 
376                  FORNOW: we currently don't support the case that these phis
377                  are not used in the outerloop, cause this case requires
378                  to actually do something here.  */
379               if (!STMT_VINFO_RELEVANT_P (stmt_info) 
380                   || STMT_VINFO_LIVE_P (stmt_info))
381                 {
382                   if (vect_print_dump_info (REPORT_DETAILS))
383                     fprintf (vect_dump, 
384                              "Unsupported loop-closed phi in outer-loop.");
385                   return false;
386                 }
387               continue;
388             }
389
390           gcc_assert (stmt_info);
391
392           if (STMT_VINFO_LIVE_P (stmt_info))
393             {
394               /* FORNOW: not yet supported.  */
395               if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
396                 fprintf (vect_dump, "not vectorized: value used after loop.");
397               return false;
398             }
399
400           if (STMT_VINFO_RELEVANT (stmt_info) == vect_used_in_loop
401               && STMT_VINFO_DEF_TYPE (stmt_info) != vect_induction_def)
402             {
403               /* A scalar-dependence cycle that we don't support.  */
404               if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
405                 fprintf (vect_dump, "not vectorized: scalar dependence cycle.");
406               return false;
407             }
408
409           if (STMT_VINFO_RELEVANT_P (stmt_info))
410             {
411               need_to_vectorize = true;
412               if (STMT_VINFO_DEF_TYPE (stmt_info) == vect_induction_def)
413                 ok = vectorizable_induction (phi, NULL, NULL);
414             }
415
416           if (!ok)
417             {
418               if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
419                 {
420                   fprintf (vect_dump,
421                            "not vectorized: relevant phi not supported: ");
422                   print_generic_expr (vect_dump, phi, TDF_SLIM);
423                 }
424               return false;
425             }
426         }
427
428       for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
429         {
430           tree stmt = bsi_stmt (si);
431           stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
432           enum vect_def_type relevance = STMT_VINFO_RELEVANT (stmt_info);
433
434           if (vect_print_dump_info (REPORT_DETAILS))
435             {
436               fprintf (vect_dump, "==> examining statement: ");
437               print_generic_expr (vect_dump, stmt, TDF_SLIM);
438             }
439
440           gcc_assert (stmt_info);
441
442           /* skip stmts which do not need to be vectorized.
443              this is expected to include:
444              - the COND_EXPR which is the loop exit condition
445              - any LABEL_EXPRs in the loop
446              - computations that are used only for array indexing or loop
447              control  */
448
449           if (!STMT_VINFO_RELEVANT_P (stmt_info)
450               && !STMT_VINFO_LIVE_P (stmt_info))
451             {
452               if (vect_print_dump_info (REPORT_DETAILS))
453                 fprintf (vect_dump, "irrelevant.");
454               continue;
455             }
456
457           switch (STMT_VINFO_DEF_TYPE (stmt_info))
458             {
459             case vect_loop_def:
460               break;
461         
462             case vect_reduction_def:
463               gcc_assert (relevance == vect_used_in_outer
464                           || relevance == vect_used_in_outer_by_reduction
465                           || relevance == vect_unused_in_loop);
466               break;    
467
468             case vect_induction_def:
469             case vect_constant_def:
470             case vect_invariant_def:
471             case vect_unknown_def_type:
472             default:
473               gcc_unreachable ();       
474             }
475
476           if (STMT_VINFO_RELEVANT_P (stmt_info))
477             {
478               gcc_assert (GIMPLE_STMT_P (stmt)
479                           || !VECTOR_MODE_P (TYPE_MODE (TREE_TYPE (stmt))));
480               gcc_assert (STMT_VINFO_VECTYPE (stmt_info));
481               need_to_vectorize = true;
482             }
483
484           ok = (vectorizable_type_promotion (stmt, NULL, NULL)
485                 || vectorizable_type_demotion (stmt, NULL, NULL)
486                 || vectorizable_conversion (stmt, NULL, NULL, NULL)
487                 || vectorizable_operation (stmt, NULL, NULL, NULL)
488                 || vectorizable_assignment (stmt, NULL, NULL, NULL)
489                 || vectorizable_load (stmt, NULL, NULL, NULL)
490                 || vectorizable_call (stmt, NULL, NULL)
491                 || vectorizable_store (stmt, NULL, NULL, NULL)
492                 || vectorizable_condition (stmt, NULL, NULL)
493                 || vectorizable_reduction (stmt, NULL, NULL));
494
495           /* Stmts that are (also) "live" (i.e. - that are used out of the loop)
496              need extra handling, except for vectorizable reductions.  */
497           if (STMT_VINFO_LIVE_P (stmt_info)
498               && STMT_VINFO_TYPE (stmt_info) != reduc_vec_info_type) 
499             ok |= vectorizable_live_operation (stmt, NULL, NULL);
500
501           if (!ok)
502             {
503               if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
504                 {
505                   fprintf (vect_dump, "not vectorized: stmt not supported: ");
506                   print_generic_expr (vect_dump, stmt, TDF_SLIM);
507                 }
508               return false;
509             }   
510
511           if (!PURE_SLP_STMT (stmt_info))
512             {
513               /* STMT needs loop-based vectorization.  */
514               only_slp_in_loop = false;
515
516               /* Groups of strided accesses whose size is not a power of 2 are 
517                  not vectorizable yet using loop-vectorization. Therefore, if 
518                  this stmt feeds non-SLP-able stmts (i.e., this stmt has to be 
519                  both SLPed and loop-based vectorzed), the loop cannot be 
520                  vectorized.  */
521               if (STMT_VINFO_STRIDED_ACCESS (stmt_info)
522                   && exact_log2 (DR_GROUP_SIZE (vinfo_for_stmt (
523                                   DR_GROUP_FIRST_DR (stmt_info)))) == -1)
524                 {
525                   if (vect_print_dump_info (REPORT_DETAILS))
526                     {
527                       fprintf (vect_dump, "not vectorized: the size of group "
528                                "of strided accesses is not a power of 2");
529                       print_generic_expr (vect_dump, stmt, TDF_SLIM);
530                     }
531                   return false;
532                 }
533             }
534         } /* stmts in bb */
535     } /* bbs */
536
537   /* All operations in the loop are either irrelevant (deal with loop
538      control, or dead), or only used outside the loop and can be moved
539      out of the loop (e.g. invariants, inductions).  The loop can be 
540      optimized away by scalar optimizations.  We're better off not 
541      touching this loop.  */
542   if (!need_to_vectorize)
543     {
544       if (vect_print_dump_info (REPORT_DETAILS))
545         fprintf (vect_dump, 
546                  "All the computation can be taken out of the loop.");
547       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
548         fprintf (vect_dump, 
549                  "not vectorized: redundant loop. no profit to vectorize.");
550       return false;
551     }
552
553   /* If all the stmts in the loop can be SLPed, we perform only SLP, and
554      vectorization factor of the loop is the unrolling factor required by the
555      SLP instances.  If that unrolling factor is 1, we say, that we perform
556      pure SLP on loop - cross iteration parallelism is not exploited.  */
557   if (only_slp_in_loop)
558     vectorization_factor = LOOP_VINFO_SLP_UNROLLING_FACTOR (loop_vinfo);
559   else
560     vectorization_factor = least_common_multiple (vectorization_factor,
561                                 LOOP_VINFO_SLP_UNROLLING_FACTOR (loop_vinfo));
562   
563   LOOP_VINFO_VECT_FACTOR (loop_vinfo) = vectorization_factor;
564
565   if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
566       && vect_print_dump_info (REPORT_DETAILS))
567     fprintf (vect_dump,
568         "vectorization_factor = %d, niters = " HOST_WIDE_INT_PRINT_DEC,
569         vectorization_factor, LOOP_VINFO_INT_NITERS (loop_vinfo));
570
571   if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
572       && (LOOP_VINFO_INT_NITERS (loop_vinfo) < vectorization_factor))
573     {
574       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
575         fprintf (vect_dump, "not vectorized: iteration count too small.");
576       if (vect_print_dump_info (REPORT_DETAILS))
577         fprintf (vect_dump,"not vectorized: iteration count smaller than "
578                  "vectorization factor.");
579       return false;
580     }
581
582   /* Analyze cost. Decide if worth while to vectorize.  */
583
584   /* Once VF is set, SLP costs should be updated since the number of created
585      vector stmts depends on VF.  */
586   vect_update_slp_costs_according_to_vf (loop_vinfo);
587
588   min_profitable_iters = vect_estimate_min_profitable_iters (loop_vinfo);
589   LOOP_VINFO_COST_MODEL_MIN_ITERS (loop_vinfo) = min_profitable_iters;
590   if (min_profitable_iters < 0)
591     {
592       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
593         fprintf (vect_dump, "not vectorized: vectorization not profitable.");
594       if (vect_print_dump_info (REPORT_DETAILS))
595         fprintf (vect_dump, "not vectorized: vector version will never be "
596                  "profitable.");
597       return false;
598     }
599
600   min_scalar_loop_bound = ((PARAM_VALUE (PARAM_MIN_VECT_LOOP_BOUND)
601                             * vectorization_factor) - 1);
602
603   /* Use the cost model only if it is more conservative than user specified
604      threshold.  */
605
606   th = (unsigned) min_scalar_loop_bound;
607   if (min_profitable_iters 
608       && (!min_scalar_loop_bound
609           || min_profitable_iters > min_scalar_loop_bound))
610     th = (unsigned) min_profitable_iters;
611
612   if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
613       && LOOP_VINFO_INT_NITERS (loop_vinfo) <= th)
614     {
615       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))           
616         fprintf (vect_dump, "not vectorized: vectorization not "
617                  "profitable.");
618       if (vect_print_dump_info (REPORT_DETAILS))              
619         fprintf (vect_dump, "not vectorized: iteration count smaller than "
620                  "user specified loop bound parameter or minimum "
621                  "profitable iterations (whichever is more conservative).");
622       return false;
623     }  
624
625   if (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
626       || LOOP_VINFO_INT_NITERS (loop_vinfo) % vectorization_factor != 0
627       || LOOP_PEELING_FOR_ALIGNMENT (loop_vinfo))
628     {
629       if (vect_print_dump_info (REPORT_DETAILS))
630         fprintf (vect_dump, "epilog loop required.");
631       if (!vect_can_advance_ivs_p (loop_vinfo))
632         {
633           if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
634             fprintf (vect_dump,
635                      "not vectorized: can't create epilog loop 1.");
636           return false;
637         }
638       if (!slpeel_can_duplicate_loop_p (loop, single_exit (loop)))
639         {
640           if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
641             fprintf (vect_dump,
642                      "not vectorized: can't create epilog loop 2.");
643           return false;
644         }
645     }
646
647   return true;
648 }
649
650
651 /* Function exist_non_indexing_operands_for_use_p 
652
653    USE is one of the uses attached to STMT. Check if USE is 
654    used in STMT for anything other than indexing an array.  */
655
656 static bool
657 exist_non_indexing_operands_for_use_p (tree use, tree stmt)
658 {
659   tree operand;
660   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
661  
662   /* USE corresponds to some operand in STMT. If there is no data
663      reference in STMT, then any operand that corresponds to USE
664      is not indexing an array.  */
665   if (!STMT_VINFO_DATA_REF (stmt_info))
666     return true;
667  
668   /* STMT has a data_ref. FORNOW this means that its of one of
669      the following forms:
670      -1- ARRAY_REF = var
671      -2- var = ARRAY_REF
672      (This should have been verified in analyze_data_refs).
673
674      'var' in the second case corresponds to a def, not a use,
675      so USE cannot correspond to any operands that are not used 
676      for array indexing.
677
678      Therefore, all we need to check is if STMT falls into the
679      first case, and whether var corresponds to USE.  */
680  
681   if (TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) == SSA_NAME)
682     return false;
683
684   operand = GIMPLE_STMT_OPERAND (stmt, 1);
685
686   if (TREE_CODE (operand) != SSA_NAME)
687     return false;
688
689   if (operand == use)
690     return true;
691
692   return false;
693 }
694
695
696 /* Function vect_analyze_scalar_cycles_1.
697
698    Examine the cross iteration def-use cycles of scalar variables
699    in LOOP. LOOP_VINFO represents the loop that is noe being
700    considered for vectorization (can be LOOP, or an outer-loop
701    enclosing LOOP).  */
702
703 static void
704 vect_analyze_scalar_cycles_1 (loop_vec_info loop_vinfo, struct loop *loop)
705 {
706   tree phi;
707   basic_block bb = loop->header;
708   tree dumy;
709   VEC(tree,heap) *worklist = VEC_alloc (tree, heap, 64);
710
711   if (vect_print_dump_info (REPORT_DETAILS))
712     fprintf (vect_dump, "=== vect_analyze_scalar_cycles ===");
713
714   /* First - identify all inductions.  */
715   for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
716     {
717       tree access_fn = NULL;
718       tree def = PHI_RESULT (phi);
719       stmt_vec_info stmt_vinfo = vinfo_for_stmt (phi);
720
721       if (vect_print_dump_info (REPORT_DETAILS))
722         {
723           fprintf (vect_dump, "Analyze phi: ");
724           print_generic_expr (vect_dump, phi, TDF_SLIM);
725         }
726
727       /* Skip virtual phi's. The data dependences that are associated with
728          virtual defs/uses (i.e., memory accesses) are analyzed elsewhere.  */
729       if (!is_gimple_reg (SSA_NAME_VAR (def)))
730         continue;
731
732       STMT_VINFO_DEF_TYPE (stmt_vinfo) = vect_unknown_def_type;
733
734       /* Analyze the evolution function.  */
735       access_fn = analyze_scalar_evolution (loop, def);
736       if (access_fn && vect_print_dump_info (REPORT_DETAILS))
737         {
738           fprintf (vect_dump, "Access function of PHI: ");
739           print_generic_expr (vect_dump, access_fn, TDF_SLIM);
740         }
741
742       if (!access_fn
743           || !vect_is_simple_iv_evolution (loop->num, access_fn, &dumy, &dumy)) 
744         {
745           VEC_safe_push (tree, heap, worklist, phi);      
746           continue;
747         }
748
749       if (vect_print_dump_info (REPORT_DETAILS))
750         fprintf (vect_dump, "Detected induction.");
751       STMT_VINFO_DEF_TYPE (stmt_vinfo) = vect_induction_def;
752     }
753
754
755   /* Second - identify all reductions.  */
756   while (VEC_length (tree, worklist) > 0)
757     {
758       tree phi = VEC_pop (tree, worklist);
759       tree def = PHI_RESULT (phi);
760       stmt_vec_info stmt_vinfo = vinfo_for_stmt (phi);
761       tree reduc_stmt;
762
763       if (vect_print_dump_info (REPORT_DETAILS))
764         { 
765           fprintf (vect_dump, "Analyze phi: ");
766           print_generic_expr (vect_dump, phi, TDF_SLIM);
767         }
768
769       gcc_assert (is_gimple_reg (SSA_NAME_VAR (def)));
770       gcc_assert (STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_unknown_def_type);
771
772       reduc_stmt = vect_is_simple_reduction (loop_vinfo, phi);
773       if (reduc_stmt)
774         {
775           if (vect_print_dump_info (REPORT_DETAILS))
776             fprintf (vect_dump, "Detected reduction.");
777           STMT_VINFO_DEF_TYPE (stmt_vinfo) = vect_reduction_def;
778           STMT_VINFO_DEF_TYPE (vinfo_for_stmt (reduc_stmt)) =
779                                                         vect_reduction_def;
780         }
781       else
782         if (vect_print_dump_info (REPORT_DETAILS))
783           fprintf (vect_dump, "Unknown def-use cycle pattern.");
784     }
785
786   VEC_free (tree, heap, worklist);
787   return;
788 }
789
790
791 /* Function vect_analyze_scalar_cycles.
792
793    Examine the cross iteration def-use cycles of scalar variables, by
794    analyzing the loop-header PHIs of scalar variables; Classify each 
795    cycle as one of the following: invariant, induction, reduction, unknown.
796    We do that for the loop represented by LOOP_VINFO, and also to its
797    inner-loop, if exists.
798    Examples for scalar cycles:
799
800    Example1: reduction:
801
802               loop1:
803               for (i=0; i<N; i++)
804                  sum += a[i];
805
806    Example2: induction:
807
808               loop2:
809               for (i=0; i<N; i++)
810                  a[i] = i;  */
811
812 static void
813 vect_analyze_scalar_cycles (loop_vec_info loop_vinfo)
814 {
815   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
816
817   vect_analyze_scalar_cycles_1 (loop_vinfo, loop);
818
819   /* When vectorizing an outer-loop, the inner-loop is executed sequentially.
820      Reductions in such inner-loop therefore have different properties than
821      the reductions in the nest that gets vectorized:
822      1. When vectorized, they are executed in the same order as in the original
823         scalar loop, so we can't change the order of computation when
824         vectorizing them.
825      2. FIXME: Inner-loop reductions can be used in the inner-loop, so the 
826         current checks are too strict.  */
827
828   if (loop->inner)
829     vect_analyze_scalar_cycles_1 (loop_vinfo, loop->inner);
830 }
831
832
833 /* Function vect_insert_into_interleaving_chain.
834
835    Insert DRA into the interleaving chain of DRB according to DRA's INIT.  */
836
837 static void
838 vect_insert_into_interleaving_chain (struct data_reference *dra,
839                                      struct data_reference *drb)
840 {
841   tree prev, next, next_init;
842   stmt_vec_info stmtinfo_a = vinfo_for_stmt (DR_STMT (dra)); 
843   stmt_vec_info stmtinfo_b = vinfo_for_stmt (DR_STMT (drb));
844
845   prev = DR_GROUP_FIRST_DR (stmtinfo_b);
846   next = DR_GROUP_NEXT_DR (vinfo_for_stmt (prev));                
847   while (next)
848     {
849       next_init = DR_INIT (STMT_VINFO_DATA_REF (vinfo_for_stmt (next)));
850       if (tree_int_cst_compare (next_init, DR_INIT (dra)) > 0)
851         {
852           /* Insert here.  */
853           DR_GROUP_NEXT_DR (vinfo_for_stmt (prev)) = DR_STMT (dra);
854           DR_GROUP_NEXT_DR (stmtinfo_a) = next;
855           return;
856         }
857       prev = next;
858       next = DR_GROUP_NEXT_DR (vinfo_for_stmt (prev));
859     }
860
861   /* We got to the end of the list. Insert here.  */
862   DR_GROUP_NEXT_DR (vinfo_for_stmt (prev)) = DR_STMT (dra);
863   DR_GROUP_NEXT_DR (stmtinfo_a) = NULL_TREE;
864 }
865
866
867 /* Function vect_update_interleaving_chain.
868    
869    For two data-refs DRA and DRB that are a part of a chain interleaved data 
870    accesses, update the interleaving chain. DRB's INIT is smaller than DRA's.
871
872    There are four possible cases:
873    1. New stmts - both DRA and DRB are not a part of any chain:
874       FIRST_DR = DRB
875       NEXT_DR (DRB) = DRA
876    2. DRB is a part of a chain and DRA is not:
877       no need to update FIRST_DR
878       no need to insert DRB
879       insert DRA according to init
880    3. DRA is a part of a chain and DRB is not:
881       if (init of FIRST_DR > init of DRB)
882           FIRST_DR = DRB
883           NEXT(FIRST_DR) = previous FIRST_DR
884       else
885           insert DRB according to its init
886    4. both DRA and DRB are in some interleaving chains:
887       choose the chain with the smallest init of FIRST_DR
888       insert the nodes of the second chain into the first one.  */
889
890 static void
891 vect_update_interleaving_chain (struct data_reference *drb,
892                                 struct data_reference *dra)
893 {
894   stmt_vec_info stmtinfo_a = vinfo_for_stmt (DR_STMT (dra)); 
895   stmt_vec_info stmtinfo_b = vinfo_for_stmt (DR_STMT (drb));
896   tree next_init, init_dra_chain, init_drb_chain, first_a, first_b;
897   tree node, prev, next, node_init, first_stmt;
898
899   /* 1. New stmts - both DRA and DRB are not a part of any chain.   */
900   if (!DR_GROUP_FIRST_DR (stmtinfo_a) && !DR_GROUP_FIRST_DR (stmtinfo_b))
901     {
902       DR_GROUP_FIRST_DR (stmtinfo_a) = DR_STMT (drb);
903       DR_GROUP_FIRST_DR (stmtinfo_b) = DR_STMT (drb);
904       DR_GROUP_NEXT_DR (stmtinfo_b) = DR_STMT (dra);
905       return;
906     }
907
908   /* 2. DRB is a part of a chain and DRA is not.  */
909   if (!DR_GROUP_FIRST_DR (stmtinfo_a) && DR_GROUP_FIRST_DR (stmtinfo_b))
910     {
911       DR_GROUP_FIRST_DR (stmtinfo_a) = DR_GROUP_FIRST_DR (stmtinfo_b);
912       /* Insert DRA into the chain of DRB.  */
913       vect_insert_into_interleaving_chain (dra, drb);
914       return;
915     }
916
917   /* 3. DRA is a part of a chain and DRB is not.  */  
918   if (DR_GROUP_FIRST_DR (stmtinfo_a) && !DR_GROUP_FIRST_DR (stmtinfo_b))
919     {
920       tree old_first_stmt = DR_GROUP_FIRST_DR (stmtinfo_a);
921       tree init_old = DR_INIT (STMT_VINFO_DATA_REF (vinfo_for_stmt (
922                                                               old_first_stmt)));
923       tree tmp;
924
925       if (tree_int_cst_compare (init_old, DR_INIT (drb)) > 0)
926         {
927           /* DRB's init is smaller than the init of the stmt previously marked 
928              as the first stmt of the interleaving chain of DRA. Therefore, we 
929              update FIRST_STMT and put DRB in the head of the list.  */
930           DR_GROUP_FIRST_DR (stmtinfo_b) = DR_STMT (drb);
931           DR_GROUP_NEXT_DR (stmtinfo_b) = old_first_stmt;
932                 
933           /* Update all the stmts in the list to point to the new FIRST_STMT.  */
934           tmp = old_first_stmt;
935           while (tmp)
936             {
937               DR_GROUP_FIRST_DR (vinfo_for_stmt (tmp)) = DR_STMT (drb);
938               tmp = DR_GROUP_NEXT_DR (vinfo_for_stmt (tmp));
939             }
940         }
941       else
942         {
943           /* Insert DRB in the list of DRA.  */
944           vect_insert_into_interleaving_chain (drb, dra);
945           DR_GROUP_FIRST_DR (stmtinfo_b) = DR_GROUP_FIRST_DR (stmtinfo_a);            
946         }
947       return;
948     }
949   
950   /* 4. both DRA and DRB are in some interleaving chains.  */
951   first_a = DR_GROUP_FIRST_DR (stmtinfo_a);
952   first_b = DR_GROUP_FIRST_DR (stmtinfo_b);
953   if (first_a == first_b)
954     return;
955   init_dra_chain = DR_INIT (STMT_VINFO_DATA_REF (vinfo_for_stmt (first_a)));
956   init_drb_chain = DR_INIT (STMT_VINFO_DATA_REF (vinfo_for_stmt (first_b)));
957
958   if (tree_int_cst_compare (init_dra_chain, init_drb_chain) > 0)
959     {
960       /* Insert the nodes of DRA chain into the DRB chain.  
961          After inserting a node, continue from this node of the DRB chain (don't
962          start from the beginning.  */
963       node = DR_GROUP_FIRST_DR (stmtinfo_a);
964       prev = DR_GROUP_FIRST_DR (stmtinfo_b);      
965       first_stmt = first_b;
966     }
967   else
968     {
969       /* Insert the nodes of DRB chain into the DRA chain.  
970          After inserting a node, continue from this node of the DRA chain (don't
971          start from the beginning.  */
972       node = DR_GROUP_FIRST_DR (stmtinfo_b);
973       prev = DR_GROUP_FIRST_DR (stmtinfo_a);      
974       first_stmt = first_a;
975     }
976   
977   while (node)
978     {
979       node_init = DR_INIT (STMT_VINFO_DATA_REF (vinfo_for_stmt (node)));
980       next = DR_GROUP_NEXT_DR (vinfo_for_stmt (prev));            
981       while (next)
982         {         
983           next_init = DR_INIT (STMT_VINFO_DATA_REF (vinfo_for_stmt (next)));
984           if (tree_int_cst_compare (next_init, node_init) > 0)
985             {
986               /* Insert here.  */
987               DR_GROUP_NEXT_DR (vinfo_for_stmt (prev)) = node;
988               DR_GROUP_NEXT_DR (vinfo_for_stmt (node)) = next;
989               prev = node;
990               break;
991             }
992           prev = next;
993           next = DR_GROUP_NEXT_DR (vinfo_for_stmt (prev));
994         }
995       if (!next)
996         {
997           /* We got to the end of the list. Insert here.  */
998           DR_GROUP_NEXT_DR (vinfo_for_stmt (prev)) = node;
999           DR_GROUP_NEXT_DR (vinfo_for_stmt (node)) = NULL_TREE;
1000           prev = node;
1001         }                       
1002       DR_GROUP_FIRST_DR (vinfo_for_stmt (node)) = first_stmt;
1003       node = DR_GROUP_NEXT_DR (vinfo_for_stmt (node));         
1004     }
1005 }
1006
1007
1008 /* Function vect_equal_offsets.
1009
1010    Check if OFFSET1 and OFFSET2 are identical expressions.  */
1011
1012 static bool
1013 vect_equal_offsets (tree offset1, tree offset2)
1014 {
1015   bool res0, res1;
1016
1017   STRIP_NOPS (offset1);
1018   STRIP_NOPS (offset2);
1019
1020   if (offset1 == offset2)
1021     return true;
1022
1023   if (TREE_CODE (offset1) != TREE_CODE (offset2)
1024       || !BINARY_CLASS_P (offset1)
1025       || !BINARY_CLASS_P (offset2))    
1026     return false;
1027   
1028   res0 = vect_equal_offsets (TREE_OPERAND (offset1, 0), 
1029                              TREE_OPERAND (offset2, 0));
1030   res1 = vect_equal_offsets (TREE_OPERAND (offset1, 1), 
1031                              TREE_OPERAND (offset2, 1));
1032
1033   return (res0 && res1);
1034 }
1035
1036
1037 /* Function vect_check_interleaving.
1038
1039    Check if DRA and DRB are a part of interleaving. In case they are, insert
1040    DRA and DRB in an interleaving chain.  */
1041
1042 static void
1043 vect_check_interleaving (struct data_reference *dra,
1044                          struct data_reference *drb)
1045 {
1046   HOST_WIDE_INT type_size_a, type_size_b, diff_mod_size, step, init_a, init_b;
1047
1048   /* Check that the data-refs have same first location (except init) and they
1049      are both either store or load (not load and store).  */
1050   if ((DR_BASE_ADDRESS (dra) != DR_BASE_ADDRESS (drb)
1051        && (TREE_CODE (DR_BASE_ADDRESS (dra)) != ADDR_EXPR 
1052            || TREE_CODE (DR_BASE_ADDRESS (drb)) != ADDR_EXPR
1053            || TREE_OPERAND (DR_BASE_ADDRESS (dra), 0) 
1054            != TREE_OPERAND (DR_BASE_ADDRESS (drb),0)))
1055       || !vect_equal_offsets (DR_OFFSET (dra), DR_OFFSET (drb))
1056       || !tree_int_cst_compare (DR_INIT (dra), DR_INIT (drb)) 
1057       || DR_IS_READ (dra) != DR_IS_READ (drb))
1058     return;
1059
1060   /* Check:
1061      1. data-refs are of the same type
1062      2. their steps are equal
1063      3. the step is greater than the difference between data-refs' inits  */
1064   type_size_a = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (dra))));
1065   type_size_b = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (drb))));
1066
1067   if (type_size_a != type_size_b
1068       || tree_int_cst_compare (DR_STEP (dra), DR_STEP (drb)))
1069     return;
1070
1071   init_a = TREE_INT_CST_LOW (DR_INIT (dra));
1072   init_b = TREE_INT_CST_LOW (DR_INIT (drb));
1073   step = TREE_INT_CST_LOW (DR_STEP (dra));
1074
1075   if (init_a > init_b)
1076     {
1077       /* If init_a == init_b + the size of the type * k, we have an interleaving, 
1078          and DRB is accessed before DRA.  */
1079       diff_mod_size = (init_a - init_b) % type_size_a;
1080
1081       if ((init_a - init_b) > step)
1082          return; 
1083
1084       if (diff_mod_size == 0)
1085         {
1086           vect_update_interleaving_chain (drb, dra);      
1087           if (vect_print_dump_info (REPORT_DR_DETAILS))
1088             {
1089               fprintf (vect_dump, "Detected interleaving ");
1090               print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
1091               fprintf (vect_dump, " and ");
1092               print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
1093             }
1094           return;
1095         } 
1096     }
1097   else 
1098     {
1099       /* If init_b == init_a + the size of the type * k, we have an 
1100          interleaving, and DRA is accessed before DRB.  */
1101       diff_mod_size = (init_b - init_a) % type_size_a;
1102
1103       if ((init_b - init_a) > step)
1104          return;
1105
1106       if (diff_mod_size == 0)
1107         {
1108           vect_update_interleaving_chain (dra, drb);      
1109           if (vect_print_dump_info (REPORT_DR_DETAILS))
1110             {
1111               fprintf (vect_dump, "Detected interleaving ");
1112               print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
1113               fprintf (vect_dump, " and ");
1114               print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
1115             }
1116           return;
1117         } 
1118     }
1119 }
1120
1121
1122 /* Function vect_analyze_data_ref_dependence.
1123
1124    Return TRUE if there (might) exist a dependence between a memory-reference
1125    DRA and a memory-reference DRB.  */
1126       
1127 static bool
1128 vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
1129                                   loop_vec_info loop_vinfo)
1130 {
1131   unsigned int i;
1132   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
1133   int vectorization_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
1134   struct data_reference *dra = DDR_A (ddr);
1135   struct data_reference *drb = DDR_B (ddr);
1136   stmt_vec_info stmtinfo_a = vinfo_for_stmt (DR_STMT (dra)); 
1137   stmt_vec_info stmtinfo_b = vinfo_for_stmt (DR_STMT (drb));
1138   int dra_size = GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (DR_REF (dra))));
1139   int drb_size = GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (DR_REF (drb))));
1140   lambda_vector dist_v;
1141   unsigned int loop_depth;
1142          
1143   if (DDR_ARE_DEPENDENT (ddr) == chrec_known)
1144     {
1145       /* Independent data accesses.  */
1146       vect_check_interleaving (dra, drb);
1147       return false;
1148     }
1149
1150   if ((DR_IS_READ (dra) && DR_IS_READ (drb)) || dra == drb)
1151     return false;
1152   
1153   if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know)
1154     {
1155       if (vect_print_dump_info (REPORT_DR_DETAILS))
1156         {
1157           fprintf (vect_dump,
1158                    "versioning for alias required: can't determine dependence between ");
1159           print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
1160           fprintf (vect_dump, " and ");
1161           print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
1162         }
1163       return true;
1164     }
1165
1166   if (DDR_NUM_DIST_VECTS (ddr) == 0)
1167     {
1168       if (vect_print_dump_info (REPORT_DR_DETAILS))
1169         {
1170           fprintf (vect_dump, "versioning for alias required: bad dist vector for ");
1171           print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
1172           fprintf (vect_dump, " and ");
1173           print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
1174         }
1175       return true;
1176     }    
1177
1178   loop_depth = index_in_loop_nest (loop->num, DDR_LOOP_NEST (ddr));
1179   for (i = 0; VEC_iterate (lambda_vector, DDR_DIST_VECTS (ddr), i, dist_v); i++)
1180     {
1181       int dist = dist_v[loop_depth];
1182
1183       if (vect_print_dump_info (REPORT_DR_DETAILS))
1184         fprintf (vect_dump, "dependence distance  = %d.", dist);
1185
1186       /* Same loop iteration.  */
1187       if (dist % vectorization_factor == 0 && dra_size == drb_size)
1188         {
1189           /* Two references with distance zero have the same alignment.  */
1190           VEC_safe_push (dr_p, heap, STMT_VINFO_SAME_ALIGN_REFS (stmtinfo_a), drb);
1191           VEC_safe_push (dr_p, heap, STMT_VINFO_SAME_ALIGN_REFS (stmtinfo_b), dra);
1192           if (vect_print_dump_info (REPORT_ALIGNMENT))
1193             fprintf (vect_dump, "accesses have the same alignment.");
1194           if (vect_print_dump_info (REPORT_DR_DETAILS))
1195             {
1196               fprintf (vect_dump, "dependence distance modulo vf == 0 between ");
1197               print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
1198               fprintf (vect_dump, " and ");
1199               print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
1200             }
1201
1202           /* For interleaving, mark that there is a read-write dependency if
1203              necessary. We check before that one of the data-refs is store.  */ 
1204           if (DR_IS_READ (dra))
1205             DR_GROUP_READ_WRITE_DEPENDENCE (stmtinfo_a) = true;
1206           else
1207             {
1208               if (DR_IS_READ (drb))
1209                 DR_GROUP_READ_WRITE_DEPENDENCE (stmtinfo_b) = true;
1210             }
1211           
1212           continue;
1213         }
1214
1215       if (abs (dist) >= vectorization_factor)
1216         {
1217           /* Dependence distance does not create dependence, as far as vectorization
1218              is concerned, in this case.  */
1219           if (vect_print_dump_info (REPORT_DR_DETAILS))
1220             fprintf (vect_dump, "dependence distance >= VF.");
1221           continue;
1222         }
1223
1224       if (vect_print_dump_info (REPORT_DR_DETAILS))
1225         {
1226           fprintf (vect_dump,
1227                    "versioning for alias required: possible dependence "
1228                    "between data-refs ");
1229           print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
1230           fprintf (vect_dump, " and ");
1231           print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
1232         }
1233
1234       return true;
1235     }
1236
1237   return false;
1238 }
1239
1240 /* Return TRUE if DDR_NEW is already found in MAY_ALIAS_DDRS list.  */
1241
1242 static bool
1243 vect_is_duplicate_ddr (VEC (ddr_p, heap) * may_alias_ddrs, ddr_p ddr_new)
1244 {
1245   unsigned i;
1246   ddr_p ddr;
1247
1248   for (i = 0; VEC_iterate (ddr_p, may_alias_ddrs, i, ddr); i++)
1249     {
1250       tree dref_A_i, dref_B_i, dref_A_j, dref_B_j;
1251
1252       dref_A_i = DR_REF (DDR_A (ddr));
1253       dref_B_i = DR_REF (DDR_B (ddr));
1254       dref_A_j = DR_REF (DDR_A (ddr_new));
1255       dref_B_j = DR_REF (DDR_B (ddr_new));
1256
1257       if ((operand_equal_p (dref_A_i, dref_A_j, 0)
1258            && operand_equal_p (dref_B_i, dref_B_j, 0))
1259           || (operand_equal_p (dref_A_i, dref_B_j, 0)
1260               && operand_equal_p (dref_B_i, dref_A_j, 0)))
1261         {
1262           if (vect_print_dump_info (REPORT_DR_DETAILS))
1263             {
1264               fprintf (vect_dump, "found same pair of data references ");
1265               print_generic_expr (vect_dump, dref_A_i, TDF_SLIM);
1266               fprintf (vect_dump, " and ");
1267               print_generic_expr (vect_dump, dref_B_i, TDF_SLIM);
1268             }
1269           return true;
1270         }
1271     }
1272   return false;
1273 }
1274
1275 /* Save DDR in LOOP_VINFO list of ddrs that may alias and need to be
1276    tested at run-time.  Returns false if number of run-time checks
1277    inserted by vectorizer is greater than maximum defined by
1278    PARAM_VECT_MAX_VERSION_FOR_ALIAS_CHECKS.  */
1279 static bool
1280 vect_mark_for_runtime_alias_test (ddr_p ddr, loop_vec_info loop_vinfo)
1281 {
1282   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
1283
1284   if (vect_print_dump_info (REPORT_DR_DETAILS))
1285     {
1286       fprintf (vect_dump, "mark for run-time aliasing test between ");
1287       print_generic_expr (vect_dump, DR_REF (DDR_A (ddr)), TDF_SLIM);
1288       fprintf (vect_dump, " and ");
1289       print_generic_expr (vect_dump, DR_REF (DDR_B (ddr)), TDF_SLIM);
1290     }
1291
1292   /* FORNOW: We don't support versioning with outer-loop vectorization.  */
1293   if (loop->inner)
1294     {
1295       if (vect_print_dump_info (REPORT_DR_DETAILS))
1296         fprintf (vect_dump, "versioning not yet supported for outer-loops.");
1297       return false;
1298     }
1299
1300   /* Do not add to the list duplicate ddrs.  */
1301   if (vect_is_duplicate_ddr (LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo), ddr))
1302     return true;
1303
1304   if (VEC_length (ddr_p, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo))
1305       >= (unsigned) PARAM_VALUE (PARAM_VECT_MAX_VERSION_FOR_ALIAS_CHECKS))
1306     {
1307       if (vect_print_dump_info (REPORT_DR_DETAILS))
1308         {
1309           fprintf (vect_dump,
1310                    "disable versioning for alias - max number of generated "
1311                    "checks exceeded.");
1312         }
1313
1314       VEC_truncate (ddr_p, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo), 0);
1315
1316       return false;
1317     }
1318   VEC_safe_push (ddr_p, heap, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo), ddr);
1319   return true;
1320 }
1321
1322 /* Function vect_analyze_data_ref_dependences.
1323           
1324    Examine all the data references in the loop, and make sure there do not
1325    exist any data dependences between them.  */
1326          
1327 static bool
1328 vect_analyze_data_ref_dependences (loop_vec_info loop_vinfo)
1329 {
1330   unsigned int i;
1331   VEC (ddr_p, heap) * ddrs = LOOP_VINFO_DDRS (loop_vinfo);
1332   struct data_dependence_relation *ddr;
1333
1334   if (vect_print_dump_info (REPORT_DETAILS)) 
1335     fprintf (vect_dump, "=== vect_analyze_dependences ===");
1336      
1337   for (i = 0; VEC_iterate (ddr_p, ddrs, i, ddr); i++)
1338     if (vect_analyze_data_ref_dependence (ddr, loop_vinfo))
1339       {
1340         /* Add to list of ddrs that need to be tested at run-time.  */
1341         if (!vect_mark_for_runtime_alias_test (ddr, loop_vinfo))
1342       return false;
1343       }
1344
1345   return true;
1346 }
1347
1348
1349 /* Function vect_compute_data_ref_alignment
1350
1351    Compute the misalignment of the data reference DR.
1352
1353    Output:
1354    1. If during the misalignment computation it is found that the data reference
1355       cannot be vectorized then false is returned.
1356    2. DR_MISALIGNMENT (DR) is defined.
1357
1358    FOR NOW: No analysis is actually performed. Misalignment is calculated
1359    only for trivial cases. TODO.  */
1360
1361 static bool
1362 vect_compute_data_ref_alignment (struct data_reference *dr)
1363 {
1364   tree stmt = DR_STMT (dr);
1365   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);  
1366   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
1367   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
1368   tree ref = DR_REF (dr);
1369   tree vectype;
1370   tree base, base_addr;
1371   bool base_aligned;
1372   tree misalign;
1373   tree aligned_to, alignment;
1374    
1375   if (vect_print_dump_info (REPORT_DETAILS))
1376     fprintf (vect_dump, "vect_compute_data_ref_alignment:");
1377
1378   /* Initialize misalignment to unknown.  */
1379   SET_DR_MISALIGNMENT (dr, -1);
1380
1381   misalign = DR_INIT (dr);
1382   aligned_to = DR_ALIGNED_TO (dr);
1383   base_addr = DR_BASE_ADDRESS (dr);
1384
1385   /* In case the dataref is in an inner-loop of the loop that is being
1386      vectorized (LOOP), we use the base and misalignment information
1387      relative to the outer-loop (LOOP). This is ok only if the misalignment
1388      stays the same throughout the execution of the inner-loop, which is why
1389      we have to check that the stride of the dataref in the inner-loop evenly
1390      divides by the vector size.  */
1391   if (nested_in_vect_loop_p (loop, stmt))
1392     {
1393       tree step = DR_STEP (dr);
1394       HOST_WIDE_INT dr_step = TREE_INT_CST_LOW (step);
1395     
1396       if (dr_step % UNITS_PER_SIMD_WORD == 0)
1397         {
1398           if (vect_print_dump_info (REPORT_ALIGNMENT))
1399             fprintf (vect_dump, "inner step divides the vector-size.");
1400           misalign = STMT_VINFO_DR_INIT (stmt_info);
1401           aligned_to = STMT_VINFO_DR_ALIGNED_TO (stmt_info);
1402           base_addr = STMT_VINFO_DR_BASE_ADDRESS (stmt_info);
1403         }
1404       else
1405         {
1406           if (vect_print_dump_info (REPORT_ALIGNMENT))
1407             fprintf (vect_dump, "inner step doesn't divide the vector-size.");
1408           misalign = NULL_TREE;
1409         }
1410     }
1411
1412   base = build_fold_indirect_ref (base_addr);
1413   vectype = STMT_VINFO_VECTYPE (stmt_info);
1414   alignment = ssize_int (TYPE_ALIGN (vectype)/BITS_PER_UNIT);
1415
1416   if ((aligned_to && tree_int_cst_compare (aligned_to, alignment) < 0)
1417       || !misalign)
1418     {
1419       if (vect_print_dump_info (REPORT_ALIGNMENT))
1420         {
1421           fprintf (vect_dump, "Unknown alignment for access: ");
1422           print_generic_expr (vect_dump, base, TDF_SLIM);
1423         }
1424       return true;
1425     }
1426
1427   if ((DECL_P (base) 
1428        && tree_int_cst_compare (ssize_int (DECL_ALIGN_UNIT (base)),
1429                                 alignment) >= 0)
1430       || (TREE_CODE (base_addr) == SSA_NAME
1431           && tree_int_cst_compare (ssize_int (TYPE_ALIGN_UNIT (TREE_TYPE (
1432                                                       TREE_TYPE (base_addr)))),
1433                                    alignment) >= 0))
1434     base_aligned = true;
1435   else
1436     base_aligned = false;   
1437
1438   if (!base_aligned) 
1439     {
1440       /* Do not change the alignment of global variables if 
1441          flag_section_anchors is enabled.  */
1442       if (!vect_can_force_dr_alignment_p (base, TYPE_ALIGN (vectype))
1443           || (TREE_STATIC (base) && flag_section_anchors))
1444         {
1445           if (vect_print_dump_info (REPORT_DETAILS))
1446             {
1447               fprintf (vect_dump, "can't force alignment of ref: ");
1448               print_generic_expr (vect_dump, ref, TDF_SLIM);
1449             }
1450           return true;
1451         }
1452       
1453       /* Force the alignment of the decl.
1454          NOTE: This is the only change to the code we make during
1455          the analysis phase, before deciding to vectorize the loop.  */
1456       if (vect_print_dump_info (REPORT_DETAILS))
1457         fprintf (vect_dump, "force alignment");
1458       DECL_ALIGN (base) = TYPE_ALIGN (vectype);
1459       DECL_USER_ALIGN (base) = 1;
1460     }
1461
1462   /* At this point we assume that the base is aligned.  */
1463   gcc_assert (base_aligned
1464               || (TREE_CODE (base) == VAR_DECL 
1465                   && DECL_ALIGN (base) >= TYPE_ALIGN (vectype)));
1466
1467   /* Modulo alignment.  */
1468   misalign = size_binop (TRUNC_MOD_EXPR, misalign, alignment);
1469
1470   if (!host_integerp (misalign, 1))
1471     {
1472       /* Negative or overflowed misalignment value.  */
1473       if (vect_print_dump_info (REPORT_DETAILS))
1474         fprintf (vect_dump, "unexpected misalign value");
1475       return false;
1476     }
1477
1478   SET_DR_MISALIGNMENT (dr, TREE_INT_CST_LOW (misalign));
1479
1480   if (vect_print_dump_info (REPORT_DETAILS))
1481     {
1482       fprintf (vect_dump, "misalign = %d bytes of ref ", DR_MISALIGNMENT (dr));
1483       print_generic_expr (vect_dump, ref, TDF_SLIM);
1484     }
1485
1486   return true;
1487 }
1488
1489
1490 /* Function vect_compute_data_refs_alignment
1491
1492    Compute the misalignment of data references in the loop.
1493    Return FALSE if a data reference is found that cannot be vectorized.  */
1494
1495 static bool
1496 vect_compute_data_refs_alignment (loop_vec_info loop_vinfo)
1497 {
1498   VEC (data_reference_p, heap) *datarefs = LOOP_VINFO_DATAREFS (loop_vinfo);
1499   struct data_reference *dr;
1500   unsigned int i;
1501
1502   for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++)
1503     if (!vect_compute_data_ref_alignment (dr))
1504       return false;
1505
1506   return true;
1507 }
1508
1509
1510 /* Function vect_update_misalignment_for_peel
1511
1512    DR - the data reference whose misalignment is to be adjusted.
1513    DR_PEEL - the data reference whose misalignment is being made
1514              zero in the vector loop by the peel.
1515    NPEEL - the number of iterations in the peel loop if the misalignment
1516            of DR_PEEL is known at compile time.  */
1517
1518 static void
1519 vect_update_misalignment_for_peel (struct data_reference *dr,
1520                                    struct data_reference *dr_peel, int npeel)
1521 {
1522   unsigned int i;
1523   VEC(dr_p,heap) *same_align_drs;
1524   struct data_reference *current_dr;
1525   int dr_size = GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (DR_REF (dr))));
1526   int dr_peel_size = GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (DR_REF (dr_peel))));
1527   stmt_vec_info stmt_info = vinfo_for_stmt (DR_STMT (dr));
1528   stmt_vec_info peel_stmt_info = vinfo_for_stmt (DR_STMT (dr_peel));
1529
1530  /* For interleaved data accesses the step in the loop must be multiplied by
1531      the size of the interleaving group.  */
1532   if (STMT_VINFO_STRIDED_ACCESS (stmt_info))
1533     dr_size *= DR_GROUP_SIZE (vinfo_for_stmt (DR_GROUP_FIRST_DR (stmt_info)));
1534   if (STMT_VINFO_STRIDED_ACCESS (peel_stmt_info))
1535     dr_peel_size *= DR_GROUP_SIZE (peel_stmt_info);
1536
1537   /* It can be assumed that the data refs with the same alignment as dr_peel
1538      are aligned in the vector loop.  */
1539   same_align_drs
1540     = STMT_VINFO_SAME_ALIGN_REFS (vinfo_for_stmt (DR_STMT (dr_peel)));
1541   for (i = 0; VEC_iterate (dr_p, same_align_drs, i, current_dr); i++)
1542     {
1543       if (current_dr != dr)
1544         continue;
1545       gcc_assert (DR_MISALIGNMENT (dr) / dr_size ==
1546                   DR_MISALIGNMENT (dr_peel) / dr_peel_size);
1547       SET_DR_MISALIGNMENT (dr, 0);
1548       return;
1549     }
1550
1551   if (known_alignment_for_access_p (dr)
1552       && known_alignment_for_access_p (dr_peel))
1553     {
1554       int misal = DR_MISALIGNMENT (dr);
1555       misal += npeel * dr_size;
1556       misal %= UNITS_PER_SIMD_WORD;
1557       SET_DR_MISALIGNMENT (dr, misal);
1558       return;
1559     }
1560
1561   if (vect_print_dump_info (REPORT_DETAILS))
1562     fprintf (vect_dump, "Setting misalignment to -1.");
1563   SET_DR_MISALIGNMENT (dr, -1);
1564 }
1565
1566
1567 /* Function vect_verify_datarefs_alignment
1568
1569    Return TRUE if all data references in the loop can be
1570    handled with respect to alignment.  */
1571
1572 static bool
1573 vect_verify_datarefs_alignment (loop_vec_info loop_vinfo)
1574 {
1575   VEC (data_reference_p, heap) *datarefs = LOOP_VINFO_DATAREFS (loop_vinfo);
1576   struct data_reference *dr;
1577   enum dr_alignment_support supportable_dr_alignment;
1578   unsigned int i;
1579
1580   for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++)
1581     {
1582       tree stmt = DR_STMT (dr);
1583       stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
1584
1585       /* For interleaving, only the alignment of the first access matters.  */
1586       if (STMT_VINFO_STRIDED_ACCESS (stmt_info)
1587           && DR_GROUP_FIRST_DR (stmt_info) != stmt)
1588         continue;
1589
1590       supportable_dr_alignment = vect_supportable_dr_alignment (dr);
1591       if (!supportable_dr_alignment)
1592         {
1593           if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
1594             {
1595               if (DR_IS_READ (dr))
1596                 fprintf (vect_dump, 
1597                          "not vectorized: unsupported unaligned load.");
1598               else
1599                 fprintf (vect_dump, 
1600                          "not vectorized: unsupported unaligned store.");
1601             }
1602           return false;
1603         }
1604       if (supportable_dr_alignment != dr_aligned
1605           && vect_print_dump_info (REPORT_ALIGNMENT))
1606         fprintf (vect_dump, "Vectorizing an unaligned access.");
1607     }
1608   return true;
1609 }
1610
1611
1612 /* Function vector_alignment_reachable_p
1613
1614    Return true if vector alignment for DR is reachable by peeling
1615    a few loop iterations.  Return false otherwise.  */
1616
1617 static bool
1618 vector_alignment_reachable_p (struct data_reference *dr)
1619 {
1620   tree stmt = DR_STMT (dr);
1621   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
1622   tree vectype = STMT_VINFO_VECTYPE (stmt_info);
1623
1624   if (STMT_VINFO_STRIDED_ACCESS (stmt_info))
1625     {
1626       /* For interleaved access we peel only if number of iterations in
1627          the prolog loop ({VF - misalignment}), is a multiple of the
1628          number of the interleaved accesses.  */
1629       int elem_size, mis_in_elements;
1630       int nelements = TYPE_VECTOR_SUBPARTS (vectype);
1631
1632       /* FORNOW: handle only known alignment.  */
1633       if (!known_alignment_for_access_p (dr))
1634         return false;
1635
1636       elem_size = UNITS_PER_SIMD_WORD / nelements;
1637       mis_in_elements = DR_MISALIGNMENT (dr) / elem_size;
1638
1639       if ((nelements - mis_in_elements) % DR_GROUP_SIZE (stmt_info))
1640         return false;
1641     }
1642
1643   /* If misalignment is known at the compile time then allow peeling
1644      only if natural alignment is reachable through peeling.  */
1645   if (known_alignment_for_access_p (dr) && !aligned_access_p (dr))
1646     {
1647       HOST_WIDE_INT elmsize = 
1648                 int_cst_value (TYPE_SIZE_UNIT (TREE_TYPE (vectype)));
1649       if (vect_print_dump_info (REPORT_DETAILS))
1650         {
1651           fprintf (vect_dump, "data size =" HOST_WIDE_INT_PRINT_DEC, elmsize);
1652           fprintf (vect_dump, ". misalignment = %d. ", DR_MISALIGNMENT (dr));
1653         }
1654       if (DR_MISALIGNMENT (dr) % elmsize)
1655         {
1656           if (vect_print_dump_info (REPORT_DETAILS))
1657             fprintf (vect_dump, "data size does not divide the misalignment.\n");
1658           return false;
1659         }
1660     }
1661
1662   if (!known_alignment_for_access_p (dr))
1663     {
1664       tree type = (TREE_TYPE (DR_REF (dr)));
1665       tree ba = DR_BASE_OBJECT (dr);
1666       bool is_packed = false;
1667
1668       if (ba)
1669         is_packed = contains_packed_reference (ba);
1670
1671       if (vect_print_dump_info (REPORT_DETAILS))
1672         fprintf (vect_dump, "Unknown misalignment, is_packed = %d",is_packed);
1673       if (targetm.vectorize.vector_alignment_reachable (type, is_packed))
1674         return true;
1675       else
1676         return false;
1677     }
1678
1679   return true;
1680 }
1681
1682 /* Function vect_enhance_data_refs_alignment
1683
1684    This pass will use loop versioning and loop peeling in order to enhance
1685    the alignment of data references in the loop.
1686
1687    FOR NOW: we assume that whatever versioning/peeling takes place, only the
1688    original loop is to be vectorized; Any other loops that are created by
1689    the transformations performed in this pass - are not supposed to be
1690    vectorized. This restriction will be relaxed.
1691
1692    This pass will require a cost model to guide it whether to apply peeling
1693    or versioning or a combination of the two. For example, the scheme that
1694    intel uses when given a loop with several memory accesses, is as follows:
1695    choose one memory access ('p') which alignment you want to force by doing
1696    peeling. Then, either (1) generate a loop in which 'p' is aligned and all
1697    other accesses are not necessarily aligned, or (2) use loop versioning to
1698    generate one loop in which all accesses are aligned, and another loop in
1699    which only 'p' is necessarily aligned.
1700
1701    ("Automatic Intra-Register Vectorization for the Intel Architecture",
1702    Aart J.C. Bik, Milind Girkar, Paul M. Grey and Ximmin Tian, International
1703    Journal of Parallel Programming, Vol. 30, No. 2, April 2002.)
1704
1705    Devising a cost model is the most critical aspect of this work. It will
1706    guide us on which access to peel for, whether to use loop versioning, how
1707    many versions to create, etc. The cost model will probably consist of
1708    generic considerations as well as target specific considerations (on
1709    powerpc for example, misaligned stores are more painful than misaligned
1710    loads).
1711
1712    Here are the general steps involved in alignment enhancements:
1713
1714      -- original loop, before alignment analysis:
1715         for (i=0; i<N; i++){
1716           x = q[i];                     # DR_MISALIGNMENT(q) = unknown
1717           p[i] = y;                     # DR_MISALIGNMENT(p) = unknown
1718         }
1719
1720      -- After vect_compute_data_refs_alignment:
1721         for (i=0; i<N; i++){
1722           x = q[i];                     # DR_MISALIGNMENT(q) = 3
1723           p[i] = y;                     # DR_MISALIGNMENT(p) = unknown
1724         }
1725
1726      -- Possibility 1: we do loop versioning:
1727      if (p is aligned) {
1728         for (i=0; i<N; i++){    # loop 1A
1729           x = q[i];                     # DR_MISALIGNMENT(q) = 3
1730           p[i] = y;                     # DR_MISALIGNMENT(p) = 0
1731         }
1732      }
1733      else {
1734         for (i=0; i<N; i++){    # loop 1B
1735           x = q[i];                     # DR_MISALIGNMENT(q) = 3
1736           p[i] = y;                     # DR_MISALIGNMENT(p) = unaligned
1737         }
1738      }
1739
1740      -- Possibility 2: we do loop peeling:
1741      for (i = 0; i < 3; i++){   # (scalar loop, not to be vectorized).
1742         x = q[i];
1743         p[i] = y;
1744      }
1745      for (i = 3; i < N; i++){   # loop 2A
1746         x = q[i];                       # DR_MISALIGNMENT(q) = 0
1747         p[i] = y;                       # DR_MISALIGNMENT(p) = unknown
1748      }
1749
1750      -- Possibility 3: combination of loop peeling and versioning:
1751      for (i = 0; i < 3; i++){   # (scalar loop, not to be vectorized).
1752         x = q[i];
1753         p[i] = y;
1754      }
1755      if (p is aligned) {
1756         for (i = 3; i<N; i++){  # loop 3A
1757           x = q[i];                     # DR_MISALIGNMENT(q) = 0
1758           p[i] = y;                     # DR_MISALIGNMENT(p) = 0
1759         }
1760      }
1761      else {
1762         for (i = 3; i<N; i++){  # loop 3B
1763           x = q[i];                     # DR_MISALIGNMENT(q) = 0
1764           p[i] = y;                     # DR_MISALIGNMENT(p) = unaligned
1765         }
1766      }
1767
1768      These loops are later passed to loop_transform to be vectorized. The
1769      vectorizer will use the alignment information to guide the transformation
1770      (whether to generate regular loads/stores, or with special handling for
1771      misalignment).  */
1772
1773 static bool
1774 vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
1775 {
1776   VEC (data_reference_p, heap) *datarefs = LOOP_VINFO_DATAREFS (loop_vinfo);
1777   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
1778   enum dr_alignment_support supportable_dr_alignment;
1779   struct data_reference *dr0 = NULL;
1780   struct data_reference *dr;
1781   unsigned int i;
1782   bool do_peeling = false;
1783   bool do_versioning = false;
1784   bool stat;
1785   tree stmt;
1786   stmt_vec_info stmt_info;
1787   int vect_versioning_for_alias_required;
1788
1789   if (vect_print_dump_info (REPORT_DETAILS))
1790     fprintf (vect_dump, "=== vect_enhance_data_refs_alignment ===");
1791
1792   /* While cost model enhancements are expected in the future, the high level
1793      view of the code at this time is as follows:
1794
1795      A) If there is a misaligned write then see if peeling to align this write
1796         can make all data references satisfy vect_supportable_dr_alignment.
1797         If so, update data structures as needed and return true.  Note that
1798         at this time vect_supportable_dr_alignment is known to return false
1799         for a misaligned write.
1800
1801      B) If peeling wasn't possible and there is a data reference with an
1802         unknown misalignment that does not satisfy vect_supportable_dr_alignment
1803         then see if loop versioning checks can be used to make all data
1804         references satisfy vect_supportable_dr_alignment.  If so, update
1805         data structures as needed and return true.
1806
1807      C) If neither peeling nor versioning were successful then return false if
1808         any data reference does not satisfy vect_supportable_dr_alignment.
1809
1810      D) Return true (all data references satisfy vect_supportable_dr_alignment).
1811
1812      Note, Possibility 3 above (which is peeling and versioning together) is not
1813      being done at this time.  */
1814
1815   /* (1) Peeling to force alignment.  */
1816
1817   /* (1.1) Decide whether to perform peeling, and how many iterations to peel:
1818      Considerations:
1819      + How many accesses will become aligned due to the peeling
1820      - How many accesses will become unaligned due to the peeling,
1821        and the cost of misaligned accesses.
1822      - The cost of peeling (the extra runtime checks, the increase 
1823        in code size).
1824
1825      The scheme we use FORNOW: peel to force the alignment of the first
1826      misaligned store in the loop.
1827      Rationale: misaligned stores are not yet supported.
1828
1829      TODO: Use a cost model.  */
1830
1831   for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++)
1832     {
1833       stmt = DR_STMT (dr);
1834       stmt_info = vinfo_for_stmt (stmt);
1835
1836       /* For interleaving, only the alignment of the first access
1837          matters.  */
1838       if (STMT_VINFO_STRIDED_ACCESS (stmt_info)
1839           && DR_GROUP_FIRST_DR (stmt_info) != stmt)
1840         continue;
1841
1842       if (!DR_IS_READ (dr) && !aligned_access_p (dr))
1843         {
1844           do_peeling = vector_alignment_reachable_p (dr);
1845           if (do_peeling)
1846             dr0 = dr;
1847           if (!do_peeling && vect_print_dump_info (REPORT_DETAILS))
1848             fprintf (vect_dump, "vector alignment may not be reachable");
1849           break;
1850         }
1851     }
1852
1853   vect_versioning_for_alias_required =
1854     (VEC_length (ddr_p, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo)) > 0);
1855
1856   /* Temporarily, if versioning for alias is required, we disable peeling
1857      until we support peeling and versioning.  Often peeling for alignment
1858      will require peeling for loop-bound, which in turn requires that we
1859      know how to adjust the loop ivs after the loop.  */
1860   if (vect_versioning_for_alias_required
1861        || !vect_can_advance_ivs_p (loop_vinfo)
1862       || !slpeel_can_duplicate_loop_p (loop, single_exit (loop)))
1863     do_peeling = false;
1864
1865   if (do_peeling)
1866     {
1867       int mis;
1868       int npeel = 0;
1869       tree stmt = DR_STMT (dr0);
1870       stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
1871       tree vectype = STMT_VINFO_VECTYPE (stmt_info);
1872       int nelements = TYPE_VECTOR_SUBPARTS (vectype);
1873
1874       if (known_alignment_for_access_p (dr0))
1875         {
1876           /* Since it's known at compile time, compute the number of iterations
1877              in the peeled loop (the peeling factor) for use in updating
1878              DR_MISALIGNMENT values.  The peeling factor is the vectorization
1879              factor minus the misalignment as an element count.  */
1880           mis = DR_MISALIGNMENT (dr0);
1881           mis /= GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (DR_REF (dr0))));
1882           npeel = nelements - mis;
1883
1884           /* For interleaved data access every iteration accesses all the 
1885              members of the group, therefore we divide the number of iterations
1886              by the group size.  */
1887           stmt_info = vinfo_for_stmt (DR_STMT (dr0));     
1888           if (STMT_VINFO_STRIDED_ACCESS (stmt_info))
1889             npeel /= DR_GROUP_SIZE (stmt_info);
1890
1891           if (vect_print_dump_info (REPORT_DETAILS))
1892             fprintf (vect_dump, "Try peeling by %d", npeel);
1893         }
1894
1895       /* Ensure that all data refs can be vectorized after the peel.  */
1896       for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++)
1897         {
1898           int save_misalignment;
1899
1900           if (dr == dr0)
1901             continue;
1902
1903           stmt = DR_STMT (dr);
1904           stmt_info = vinfo_for_stmt (stmt);
1905           /* For interleaving, only the alignment of the first access
1906             matters.  */
1907           if (STMT_VINFO_STRIDED_ACCESS (stmt_info)
1908               && DR_GROUP_FIRST_DR (stmt_info) != stmt)
1909             continue;
1910
1911           save_misalignment = DR_MISALIGNMENT (dr);
1912           vect_update_misalignment_for_peel (dr, dr0, npeel);
1913           supportable_dr_alignment = vect_supportable_dr_alignment (dr);
1914           SET_DR_MISALIGNMENT (dr, save_misalignment);
1915           
1916           if (!supportable_dr_alignment)
1917             {
1918               do_peeling = false;
1919               break;
1920             }
1921         }
1922
1923       if (do_peeling)
1924         {
1925           /* (1.2) Update the DR_MISALIGNMENT of each data reference DR_i.
1926              If the misalignment of DR_i is identical to that of dr0 then set
1927              DR_MISALIGNMENT (DR_i) to zero.  If the misalignment of DR_i and
1928              dr0 are known at compile time then increment DR_MISALIGNMENT (DR_i)
1929              by the peeling factor times the element size of DR_i (MOD the
1930              vectorization factor times the size).  Otherwise, the
1931              misalignment of DR_i must be set to unknown.  */
1932           for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++)
1933             if (dr != dr0)
1934               vect_update_misalignment_for_peel (dr, dr0, npeel);
1935
1936           LOOP_VINFO_UNALIGNED_DR (loop_vinfo) = dr0;
1937           LOOP_PEELING_FOR_ALIGNMENT (loop_vinfo) = DR_MISALIGNMENT (dr0);
1938           SET_DR_MISALIGNMENT (dr0, 0);
1939           if (vect_print_dump_info (REPORT_ALIGNMENT))
1940             fprintf (vect_dump, "Alignment of access forced using peeling.");
1941
1942           if (vect_print_dump_info (REPORT_DETAILS))
1943             fprintf (vect_dump, "Peeling for alignment will be applied.");
1944
1945           stat = vect_verify_datarefs_alignment (loop_vinfo);
1946           gcc_assert (stat);
1947           return stat;
1948         }
1949     }
1950
1951
1952   /* (2) Versioning to force alignment.  */
1953
1954   /* Try versioning if:
1955      1) flag_tree_vect_loop_version is TRUE
1956      2) optimize_size is FALSE
1957      3) there is at least one unsupported misaligned data ref with an unknown
1958         misalignment, and
1959      4) all misaligned data refs with a known misalignment are supported, and
1960      5) the number of runtime alignment checks is within reason.  */
1961
1962   do_versioning = 
1963         flag_tree_vect_loop_version 
1964         && (!optimize_size)
1965         && (!loop->inner); /* FORNOW */
1966
1967   if (do_versioning)
1968     {
1969       for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++)
1970         {
1971           stmt = DR_STMT (dr);
1972           stmt_info = vinfo_for_stmt (stmt);
1973
1974           /* For interleaving, only the alignment of the first access
1975              matters.  */
1976           if (aligned_access_p (dr)
1977               || (STMT_VINFO_STRIDED_ACCESS (stmt_info)
1978                   && DR_GROUP_FIRST_DR (stmt_info) != stmt))
1979             continue;
1980
1981           supportable_dr_alignment = vect_supportable_dr_alignment (dr);
1982
1983           if (!supportable_dr_alignment)
1984             {
1985               tree stmt;
1986               int mask;
1987               tree vectype;
1988
1989               if (known_alignment_for_access_p (dr)
1990                   || VEC_length (tree,
1991                                  LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo))
1992                      >= (unsigned) PARAM_VALUE (PARAM_VECT_MAX_VERSION_FOR_ALIGNMENT_CHECKS))
1993                 {
1994                   do_versioning = false;
1995                   break;
1996                 }
1997
1998               stmt = DR_STMT (dr);
1999               vectype = STMT_VINFO_VECTYPE (vinfo_for_stmt (stmt));
2000               gcc_assert (vectype);
2001   
2002               /* The rightmost bits of an aligned address must be zeros.
2003                  Construct the mask needed for this test.  For example,
2004                  GET_MODE_SIZE for the vector mode V4SI is 16 bytes so the
2005                  mask must be 15 = 0xf. */
2006               mask = GET_MODE_SIZE (TYPE_MODE (vectype)) - 1;
2007
2008               /* FORNOW: use the same mask to test all potentially unaligned
2009                  references in the loop.  The vectorizer currently supports
2010                  a single vector size, see the reference to
2011                  GET_MODE_NUNITS (TYPE_MODE (vectype)) where the
2012                  vectorization factor is computed.  */
2013               gcc_assert (!LOOP_VINFO_PTR_MASK (loop_vinfo)
2014                           || LOOP_VINFO_PTR_MASK (loop_vinfo) == mask);
2015               LOOP_VINFO_PTR_MASK (loop_vinfo) = mask;
2016               VEC_safe_push (tree, heap,
2017                              LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo),
2018                              DR_STMT (dr));
2019             }
2020         }
2021       
2022       /* Versioning requires at least one misaligned data reference.  */
2023       if (VEC_length (tree, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo)) == 0)
2024         do_versioning = false;
2025       else if (!do_versioning)
2026         VEC_truncate (tree, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo), 0);
2027     }
2028
2029   if (do_versioning)
2030     {
2031       VEC(tree,heap) *may_misalign_stmts
2032         = LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo);
2033       tree stmt;
2034
2035       /* It can now be assumed that the data references in the statements
2036          in LOOP_VINFO_MAY_MISALIGN_STMTS will be aligned in the version
2037          of the loop being vectorized.  */
2038       for (i = 0; VEC_iterate (tree, may_misalign_stmts, i, stmt); i++)
2039         {
2040           stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
2041           dr = STMT_VINFO_DATA_REF (stmt_info);
2042           SET_DR_MISALIGNMENT (dr, 0);
2043           if (vect_print_dump_info (REPORT_ALIGNMENT))
2044             fprintf (vect_dump, "Alignment of access forced using versioning.");
2045         }
2046
2047       if (vect_print_dump_info (REPORT_DETAILS))
2048         fprintf (vect_dump, "Versioning for alignment will be applied.");
2049
2050       /* Peeling and versioning can't be done together at this time.  */
2051       gcc_assert (! (do_peeling && do_versioning));
2052
2053       stat = vect_verify_datarefs_alignment (loop_vinfo);
2054       gcc_assert (stat);
2055       return stat;
2056     }
2057
2058   /* This point is reached if neither peeling nor versioning is being done.  */
2059   gcc_assert (! (do_peeling || do_versioning));
2060
2061   stat = vect_verify_datarefs_alignment (loop_vinfo);
2062   return stat;
2063 }
2064
2065
2066 /* Function vect_analyze_data_refs_alignment
2067
2068    Analyze the alignment of the data-references in the loop.
2069    Return FALSE if a data reference is found that cannot be vectorized.  */
2070
2071 static bool
2072 vect_analyze_data_refs_alignment (loop_vec_info loop_vinfo)
2073 {
2074   if (vect_print_dump_info (REPORT_DETAILS))
2075     fprintf (vect_dump, "=== vect_analyze_data_refs_alignment ===");
2076
2077   if (!vect_compute_data_refs_alignment (loop_vinfo))
2078     {
2079       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
2080         fprintf (vect_dump, 
2081                  "not vectorized: can't calculate alignment for data ref.");
2082       return false;
2083     }
2084
2085   return true;
2086 }
2087
2088
2089 /* Analyze groups of strided accesses: check that DR belongs to a group of
2090    strided accesses of legal size, step, etc. Detect gaps, single element
2091    interleaving, and other special cases. Set strided access info.
2092    Collect groups of strided stores for further use in SLP analysis.  */
2093
2094 static bool
2095 vect_analyze_group_access (struct data_reference *dr)
2096 {
2097   tree step = DR_STEP (dr);
2098   tree scalar_type = TREE_TYPE (DR_REF (dr));
2099   HOST_WIDE_INT type_size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (scalar_type));
2100   tree stmt = DR_STMT (dr);
2101   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
2102   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
2103   HOST_WIDE_INT dr_step = TREE_INT_CST_LOW (step);
2104   HOST_WIDE_INT stride;
2105   bool slp_impossible = false;
2106
2107   /* For interleaving, STRIDE is STEP counted in elements, i.e., the size of the 
2108      interleaving group (including gaps).  */
2109   stride = dr_step / type_size; 
2110
2111   /* Not consecutive access is possible only if it is a part of interleaving.  */
2112   if (!DR_GROUP_FIRST_DR (vinfo_for_stmt (stmt)))
2113     {
2114       /* Check if it this DR is a part of interleaving, and is a single
2115          element of the group that is accessed in the loop.  */
2116       
2117       /* Gaps are supported only for loads. STEP must be a multiple of the type
2118          size.  The size of the group must be a power of 2.  */
2119       if (DR_IS_READ (dr)
2120           && (dr_step % type_size) == 0
2121           && stride > 0
2122           && exact_log2 (stride) != -1)
2123         {
2124           DR_GROUP_FIRST_DR (vinfo_for_stmt (stmt)) = stmt;
2125           DR_GROUP_SIZE (vinfo_for_stmt (stmt)) = stride;
2126           if (vect_print_dump_info (REPORT_DR_DETAILS))
2127             {
2128               fprintf (vect_dump, "Detected single element interleaving %d ",
2129                        DR_GROUP_SIZE (vinfo_for_stmt (stmt)));
2130               print_generic_expr (vect_dump, DR_REF (dr), TDF_SLIM);
2131               fprintf (vect_dump, " step ");
2132               print_generic_expr (vect_dump, step, TDF_SLIM);
2133             }
2134           return true;
2135         }
2136       if (vect_print_dump_info (REPORT_DETAILS))
2137         fprintf (vect_dump, "not consecutive access");
2138       return false;
2139     }
2140
2141   if (DR_GROUP_FIRST_DR (vinfo_for_stmt (stmt)) == stmt)
2142     {
2143       /* First stmt in the interleaving chain. Check the chain.  */
2144       tree next = DR_GROUP_NEXT_DR (vinfo_for_stmt (stmt));
2145       struct data_reference *data_ref = dr;
2146       unsigned int count = 1;
2147       tree next_step;
2148       tree prev_init = DR_INIT (data_ref);
2149       tree prev = stmt;
2150       HOST_WIDE_INT diff, count_in_bytes;
2151
2152       while (next)
2153         {
2154           /* Skip same data-refs. In case that two or more stmts share data-ref
2155              (supported only for loads), we vectorize only the first stmt, and
2156              the rest get their vectorized loads from the first one.  */
2157           if (!tree_int_cst_compare (DR_INIT (data_ref),
2158                                      DR_INIT (STMT_VINFO_DATA_REF (
2159                                                    vinfo_for_stmt (next)))))
2160             {
2161               if (!DR_IS_READ (data_ref))
2162                 {
2163                   if (vect_print_dump_info (REPORT_DETAILS))
2164                     fprintf (vect_dump, "Two store stmts share the same dr.");
2165                   return false;
2166                 }
2167
2168               /* Check that there is no load-store dependencies for this loads
2169                  to prevent a case of load-store-load to the same location.  */
2170               if (DR_GROUP_READ_WRITE_DEPENDENCE (vinfo_for_stmt (next))
2171                   || DR_GROUP_READ_WRITE_DEPENDENCE (vinfo_for_stmt (prev)))
2172                 {
2173                   if (vect_print_dump_info (REPORT_DETAILS))
2174                     fprintf (vect_dump,
2175                              "READ_WRITE dependence in interleaving.");
2176                   return false;
2177                 }
2178
2179               /* For load use the same data-ref load.  */
2180               DR_GROUP_SAME_DR_STMT (vinfo_for_stmt (next)) = prev;
2181
2182               prev = next;
2183               next = DR_GROUP_NEXT_DR (vinfo_for_stmt (next));
2184               continue;
2185             }
2186           prev = next;
2187
2188           /* Check that all the accesses have the same STEP.  */
2189           next_step = DR_STEP (STMT_VINFO_DATA_REF (vinfo_for_stmt (next)));
2190           if (tree_int_cst_compare (step, next_step))
2191             {
2192               if (vect_print_dump_info (REPORT_DETAILS))
2193                 fprintf (vect_dump, "not consecutive access in interleaving");
2194               return false;
2195             }
2196
2197           data_ref = STMT_VINFO_DATA_REF (vinfo_for_stmt (next));
2198           /* Check that the distance between two accesses is equal to the type
2199              size. Otherwise, we have gaps.  */
2200           diff = (TREE_INT_CST_LOW (DR_INIT (data_ref))
2201                   - TREE_INT_CST_LOW (prev_init)) / type_size;
2202           if (diff != 1)
2203             {
2204               /* FORNOW: SLP of accesses with gaps is not supported.  */
2205               slp_impossible = true;
2206               if (!DR_IS_READ (data_ref))
2207                 {
2208                   if (vect_print_dump_info (REPORT_DETAILS))
2209                     fprintf (vect_dump, "interleaved store with gaps");
2210                   return false;
2211                 }
2212             }
2213
2214           /* Store the gap from the previous member of the group. If there is no
2215              gap in the access, DR_GROUP_GAP is always 1.  */
2216           DR_GROUP_GAP (vinfo_for_stmt (next)) = diff;
2217
2218           prev_init = DR_INIT (data_ref);
2219           next = DR_GROUP_NEXT_DR (vinfo_for_stmt (next));
2220           /* Count the number of data-refs in the chain.  */
2221           count++;
2222         }
2223
2224       /* COUNT is the number of accesses found, we multiply it by the size of
2225          the type to get COUNT_IN_BYTES.  */
2226       count_in_bytes = type_size * count;
2227
2228       /* Check that the size of the interleaving is not greater than STEP.  */
2229       if (dr_step < count_in_bytes)
2230         {
2231           if (vect_print_dump_info (REPORT_DETAILS))
2232             {
2233               fprintf (vect_dump, "interleaving size is greater than step for ");
2234               print_generic_expr (vect_dump, DR_REF (dr), TDF_SLIM);
2235             }
2236           return false;
2237         }
2238
2239       /* Check that the size of the interleaving is equal to STEP for stores,
2240          i.e., that there are no gaps.  */
2241       if (!DR_IS_READ (dr) && dr_step != count_in_bytes)
2242         {
2243           if (vect_print_dump_info (REPORT_DETAILS))
2244             fprintf (vect_dump, "interleaved store with gaps");
2245           return false;
2246         }
2247
2248       /* Check that STEP is a multiple of type size.  */
2249       if ((dr_step % type_size) != 0)
2250         {
2251           if (vect_print_dump_info (REPORT_DETAILS))
2252             {
2253               fprintf (vect_dump, "step is not a multiple of type size: step ");
2254               print_generic_expr (vect_dump, step, TDF_SLIM);
2255               fprintf (vect_dump, " size ");
2256               print_generic_expr (vect_dump, TYPE_SIZE_UNIT (scalar_type),
2257                                   TDF_SLIM);
2258             }
2259           return false;
2260         }
2261
2262       /* FORNOW: we handle only interleaving that is a power of 2.  
2263          We don't fail here if it may be still possible to vectorize the
2264          group using SLP. If not, the size of the group will be checked in
2265          vect_analyze_operations, and the vectorization will fail.  */
2266       if (exact_log2 (stride) == -1)
2267         {
2268           if (vect_print_dump_info (REPORT_DETAILS))
2269             fprintf (vect_dump, "interleaving is not a power of 2");
2270
2271           if (slp_impossible)
2272             return false;
2273         }
2274       DR_GROUP_SIZE (vinfo_for_stmt (stmt)) = stride;
2275       if (vect_print_dump_info (REPORT_DETAILS))
2276         fprintf (vect_dump, "Detected interleaving of size %d", (int)stride);
2277
2278       /* SLP: create an SLP data structure for every interleaving group of 
2279          stores for further analysis in vect_analyse_slp.  */
2280       if (!DR_IS_READ (dr) && !slp_impossible)
2281         VEC_safe_push (tree, heap, LOOP_VINFO_STRIDED_STORES (loop_vinfo), stmt);
2282     }
2283
2284   return true;
2285 }
2286
2287
2288 /* Analyze the access pattern of the data-reference DR.
2289    In case of non-consecutive accesse call vect_analyze_group_access() to
2290    analyze groups of strided accesses.  */
2291
2292 static bool
2293 vect_analyze_data_ref_access (struct data_reference *dr)
2294 {
2295   tree step = DR_STEP (dr);
2296   tree scalar_type = TREE_TYPE (DR_REF (dr));
2297   tree stmt = DR_STMT (dr);
2298   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
2299   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
2300   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
2301   HOST_WIDE_INT dr_step = TREE_INT_CST_LOW (step);
2302
2303   if (!step)
2304     {
2305       if (vect_print_dump_info (REPORT_DETAILS))
2306         fprintf (vect_dump, "bad data-ref access");
2307       return false;
2308     }
2309
2310   /* Don't allow invariant accesses.  */
2311   if (dr_step == 0)
2312     return false; 
2313
2314   if (nested_in_vect_loop_p (loop, stmt))
2315     {
2316       /* For the rest of the analysis we use the outer-loop step.  */
2317       step = STMT_VINFO_DR_STEP (stmt_info);
2318       dr_step = TREE_INT_CST_LOW (step);
2319       
2320       if (dr_step == 0)
2321         {
2322           if (vect_print_dump_info (REPORT_ALIGNMENT))
2323             fprintf (vect_dump, "zero step in outer loop.");
2324           if (DR_IS_READ (dr))
2325             return true; 
2326           else
2327             return false;
2328         }
2329     }
2330
2331   /* Consecutive?  */
2332   if (!tree_int_cst_compare (step, TYPE_SIZE_UNIT (scalar_type)))
2333     {
2334       /* Mark that it is not interleaving.  */
2335       DR_GROUP_FIRST_DR (vinfo_for_stmt (stmt)) = NULL_TREE;
2336       return true;
2337     }
2338
2339   if (nested_in_vect_loop_p (loop, stmt))
2340     {
2341       if (vect_print_dump_info (REPORT_ALIGNMENT))
2342         fprintf (vect_dump, "strided access in outer loop.");
2343       return false;
2344     }
2345
2346   /* Not consecutive access - check if it's a part of interleaving group.  */
2347   return vect_analyze_group_access (dr);
2348 }
2349
2350
2351 /* Function vect_analyze_data_ref_accesses.
2352
2353    Analyze the access pattern of all the data references in the loop.
2354
2355    FORNOW: the only access pattern that is considered vectorizable is a
2356            simple step 1 (consecutive) access.
2357
2358    FORNOW: handle only arrays and pointer accesses.  */
2359
2360 static bool
2361 vect_analyze_data_ref_accesses (loop_vec_info loop_vinfo)
2362 {
2363   unsigned int i;
2364   VEC (data_reference_p, heap) *datarefs = LOOP_VINFO_DATAREFS (loop_vinfo);
2365   struct data_reference *dr;
2366
2367   if (vect_print_dump_info (REPORT_DETAILS))
2368     fprintf (vect_dump, "=== vect_analyze_data_ref_accesses ===");
2369
2370   for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++)
2371     if (!vect_analyze_data_ref_access (dr))
2372       {
2373         if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
2374           fprintf (vect_dump, "not vectorized: complicated access pattern.");
2375         return false;
2376       }
2377
2378   return true;
2379 }
2380
2381
2382 /* Recursively free the memory allocated for the SLP tree rooted at NODE.  */
2383
2384 void
2385 vect_free_slp_tree (slp_tree node)
2386 {
2387   if (!node)
2388     return;
2389
2390   if (SLP_TREE_LEFT (node))
2391     vect_free_slp_tree (SLP_TREE_LEFT (node));
2392    
2393   if (SLP_TREE_RIGHT (node))
2394     vect_free_slp_tree (SLP_TREE_RIGHT (node));
2395    
2396   VEC_free (tree, heap, SLP_TREE_SCALAR_STMTS (node));
2397   
2398   if (SLP_TREE_VEC_STMTS (node))
2399     VEC_free (tree, heap, SLP_TREE_VEC_STMTS (node));
2400
2401   free (node);
2402 }
2403
2404
2405 /* Get the defs for the RHS (collect them in DEF_STMTS0/1), check that they are 
2406    of a legal type and that they match the defs of the first stmt of the SLP 
2407    group (stored in FIRST_STMT_...).  */
2408
2409 static bool
2410 vect_get_and_check_slp_defs (loop_vec_info loop_vinfo, slp_tree slp_node,
2411                              tree rhs, VEC (tree, heap) **def_stmts0,
2412                              VEC (tree, heap) **def_stmts1,
2413                              enum vect_def_type *first_stmt_dt0,
2414                              enum vect_def_type *first_stmt_dt1,
2415                              tree *first_stmt_def0_type, 
2416                              tree *first_stmt_def1_type,
2417                              tree *first_stmt_const_oprnd,
2418                              int ncopies_for_cost)
2419 {
2420   tree oprnd;
2421   enum operation_type op_type = TREE_OPERAND_LENGTH (rhs);
2422   unsigned int i, number_of_oprnds = op_type;
2423   tree def, def_stmt;
2424   enum vect_def_type dt[2] = {vect_unknown_def_type, vect_unknown_def_type};
2425   stmt_vec_info stmt_info = 
2426     vinfo_for_stmt (VEC_index (tree, SLP_TREE_SCALAR_STMTS (slp_node), 0));
2427
2428   /* Store.  */
2429   if (!op_type)
2430     number_of_oprnds = 1;
2431   else
2432     gcc_assert (op_type == unary_op || op_type == binary_op);
2433
2434   for (i = 0; i < number_of_oprnds; i++)
2435     {
2436       if (op_type)
2437         oprnd = TREE_OPERAND (rhs, i);
2438       else
2439         oprnd = rhs;
2440
2441       if (!vect_is_simple_use (oprnd, loop_vinfo, &def_stmt, &def, &dt[i])
2442           || (!def_stmt && dt[i] != vect_constant_def))
2443         {
2444           if (vect_print_dump_info (REPORT_SLP)) 
2445             {
2446               fprintf (vect_dump, "Build SLP failed: can't find def for ");
2447               print_generic_expr (vect_dump, oprnd, TDF_SLIM);
2448             }
2449
2450           return false;
2451         }
2452
2453       if (!*first_stmt_dt0)
2454         {
2455           /* op0 of the first stmt of the group - store its info.  */
2456           *first_stmt_dt0 = dt[i];
2457           if (def)
2458             *first_stmt_def0_type = TREE_TYPE (def);
2459           else
2460             *first_stmt_const_oprnd = oprnd;
2461
2462           /* Analyze costs (for the first stmt of the group only).  */
2463           if (op_type)
2464             /* Not memory operation (we don't call this functions for loads).  */
2465             vect_model_simple_cost (stmt_info, ncopies_for_cost, dt, slp_node);
2466           else
2467             /* Store.  */
2468             vect_model_store_cost (stmt_info, ncopies_for_cost, dt[0], slp_node);
2469         }
2470       
2471       else
2472         {
2473           if (!*first_stmt_dt1 && i == 1)
2474             {
2475               /* op1 of the first stmt of the group - store its info.  */
2476               *first_stmt_dt1 = dt[i];
2477               if (def)
2478                 *first_stmt_def1_type = TREE_TYPE (def);
2479               else
2480                 {
2481                   /* We assume that the stmt contains only one constant 
2482                      operand. We fail otherwise, to be on the safe side.  */
2483                   if (*first_stmt_const_oprnd)
2484                     {
2485                       if (vect_print_dump_info (REPORT_SLP)) 
2486                         fprintf (vect_dump, "Build SLP failed: two constant "
2487                                  "oprnds in stmt");                 
2488                       return false;
2489                     }
2490                   *first_stmt_const_oprnd = oprnd;
2491                 }
2492             }
2493           else
2494             {
2495               /* Not first stmt of the group, check that the def-stmt/s match 
2496                  the def-stmt/s of the first stmt.  */
2497               if ((i == 0 
2498                    && (*first_stmt_dt0 != dt[i]
2499                        || (*first_stmt_def0_type && def
2500                            && *first_stmt_def0_type != TREE_TYPE (def))))
2501                   || (i == 1 
2502                       && (*first_stmt_dt1 != dt[i]
2503                           || (*first_stmt_def1_type && def
2504                               && *first_stmt_def1_type != TREE_TYPE (def))))              
2505                   || (!def 
2506                       && TREE_TYPE (*first_stmt_const_oprnd) 
2507                       != TREE_TYPE (oprnd)))
2508                 { 
2509                   if (vect_print_dump_info (REPORT_SLP)) 
2510                     fprintf (vect_dump, "Build SLP failed: different types ");
2511                   
2512                   return false;
2513                 }
2514             }
2515         }
2516
2517       /* Check the types of the definitions.  */
2518       switch (dt[i])
2519         {
2520         case vect_constant_def:
2521         case vect_invariant_def:
2522           break;
2523           
2524         case vect_loop_def:
2525           if (i == 0)
2526             VEC_safe_push (tree, heap, *def_stmts0, def_stmt);
2527           else
2528             VEC_safe_push (tree, heap, *def_stmts1, def_stmt);
2529           break;
2530
2531         default:
2532           /* FORNOW: Not supported.  */
2533           if (vect_print_dump_info (REPORT_SLP)) 
2534             {
2535               fprintf (vect_dump, "Build SLP failed: illegal type of def ");
2536               print_generic_expr (vect_dump, def, TDF_SLIM);
2537             }
2538
2539           return false;
2540         }
2541     }
2542
2543   return true;
2544 }
2545
2546
2547 /* Recursively build an SLP tree starting from NODE.
2548    Fail (and return FALSE) if def-stmts are not isomorphic, require data 
2549    permutation or are of unsupported types of operation. Otherwise, return 
2550    TRUE.
2551    SLP_IMPOSSIBLE is TRUE if it is impossible to SLP in the loop, for example
2552    in the case of multiple types for now.  */
2553
2554 static bool
2555 vect_build_slp_tree (loop_vec_info loop_vinfo, slp_tree *node, 
2556                      unsigned int group_size, bool *slp_impossible,
2557                      int *inside_cost, int *outside_cost,
2558                      int ncopies_for_cost)
2559 {
2560   VEC (tree, heap) *def_stmts0 = VEC_alloc (tree, heap, group_size);
2561   VEC (tree, heap) *def_stmts1 =  VEC_alloc (tree, heap, group_size);
2562   unsigned int i;
2563   VEC (tree, heap) *stmts = SLP_TREE_SCALAR_STMTS (*node);
2564   tree stmt = VEC_index (tree, stmts, 0);
2565   enum vect_def_type first_stmt_dt0 = 0, first_stmt_dt1 = 0;
2566   enum tree_code first_stmt_code = 0;
2567   tree first_stmt_def1_type = NULL_TREE, first_stmt_def0_type = NULL_TREE;
2568   tree lhs, rhs, prev_stmt = NULL_TREE;
2569   bool stop_recursion = false, need_same_oprnds = false;
2570   tree vectype, scalar_type, first_op1 = NULL_TREE;
2571   unsigned int vectorization_factor = 0, ncopies;
2572   optab optab;
2573   int icode;
2574   enum machine_mode optab_op2_mode;
2575   enum machine_mode vec_mode;
2576   tree first_stmt_const_oprnd = NULL_TREE;
2577   struct data_reference *first_dr;
2578  
2579   /* For every stmt in NODE find its def stmt/s.  */
2580   for (i = 0; VEC_iterate (tree, stmts, i, stmt); i++)
2581     {
2582       if (vect_print_dump_info (REPORT_SLP)) 
2583         {
2584           fprintf (vect_dump, "Build SLP for ");
2585           print_generic_expr (vect_dump, stmt, TDF_SLIM);
2586         }
2587
2588       if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
2589         {
2590           if (vect_print_dump_info (REPORT_SLP)) 
2591             {
2592               fprintf (vect_dump, "Build SLP failed: not MODIFY_STMT ");
2593               print_generic_expr (vect_dump, stmt, TDF_SLIM);
2594             }
2595           
2596           return false;
2597         }
2598
2599       scalar_type = TREE_TYPE (GIMPLE_STMT_OPERAND (stmt, 0));
2600       vectype = get_vectype_for_scalar_type (scalar_type);
2601       gcc_assert (LOOP_VINFO_VECT_FACTOR (loop_vinfo));
2602       vectorization_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
2603       ncopies = vectorization_factor / TYPE_VECTOR_SUBPARTS (vectype);
2604       if (ncopies > 1)
2605         {
2606           /* FORNOW.  */
2607           if (vect_print_dump_info (REPORT_SLP)) 
2608             fprintf (vect_dump, "SLP failed - multiple types ");
2609           
2610           *slp_impossible = true;
2611           return false;
2612         }
2613
2614       lhs = GIMPLE_STMT_OPERAND (stmt, 0);
2615       rhs = GIMPLE_STMT_OPERAND (stmt, 1);
2616
2617       /* Check the operation.  */
2618       if (i == 0)
2619         {
2620           first_stmt_code = TREE_CODE (rhs);
2621
2622           /* Shift arguments should be equal in all the packed stmts for a 
2623              vector shift with scalar shift operand.  */
2624           if (TREE_CODE (rhs) == LSHIFT_EXPR || TREE_CODE (rhs) == RSHIFT_EXPR)
2625             {
2626               vec_mode = TYPE_MODE (vectype);
2627               optab = optab_for_tree_code (TREE_CODE (rhs), vectype);
2628               if (!optab)
2629                 {
2630                   if (vect_print_dump_info (REPORT_SLP))
2631                     fprintf (vect_dump, "Build SLP failed: no optab.");
2632                   return false;
2633                 }
2634               icode = (int) optab->handlers[(int) vec_mode].insn_code;
2635               optab_op2_mode = insn_data[icode].operand[2].mode;
2636               if (!VECTOR_MODE_P (optab_op2_mode))
2637                 {
2638                   need_same_oprnds = true;
2639                   first_op1 = TREE_OPERAND (rhs, 1);
2640                 }
2641             }
2642         }
2643       else
2644         {
2645           if (first_stmt_code != TREE_CODE (rhs))
2646             {
2647               if (vect_print_dump_info (REPORT_SLP)) 
2648                 {
2649                   fprintf (vect_dump, 
2650                            "Build SLP failed: different operation in stmt ");
2651                   print_generic_expr (vect_dump, stmt, TDF_SLIM);
2652                 }
2653               
2654               return false;
2655             }
2656           
2657           if (need_same_oprnds 
2658               && !operand_equal_p (first_op1, TREE_OPERAND (rhs, 1), 0))
2659             {
2660               if (vect_print_dump_info (REPORT_SLP)) 
2661                 {
2662                   fprintf (vect_dump, 
2663                            "Build SLP failed: different shift arguments in ");
2664                   print_generic_expr (vect_dump, stmt, TDF_SLIM);
2665                 }
2666               
2667               return false;
2668             }
2669         }
2670
2671       /* Strided store or load.  */
2672       if (STMT_VINFO_STRIDED_ACCESS (vinfo_for_stmt (stmt)))
2673         {
2674           if (REFERENCE_CLASS_P (lhs))
2675             {
2676               /* Store.  */
2677               if (!vect_get_and_check_slp_defs (loop_vinfo, *node, rhs, 
2678                                                 &def_stmts0, &def_stmts1, 
2679                                                 &first_stmt_dt0, 
2680                                                 &first_stmt_dt1, 
2681                                                 &first_stmt_def0_type, 
2682                                                 &first_stmt_def1_type,
2683                                                 &first_stmt_const_oprnd,
2684                                                 ncopies_for_cost))
2685                 return false;
2686             }
2687             else
2688               {
2689                 /* Load.  */
2690                 if (i == 0)
2691                   {
2692                     /* First stmt of the SLP group should be the first load of 
2693                        the interleaving loop if data permutation is not 
2694                        allowed.  */
2695                     if  (DR_GROUP_FIRST_DR (vinfo_for_stmt (stmt)) != stmt) 
2696                       {
2697                         /* FORNOW: data permutations are not supported.  */
2698                         if (vect_print_dump_info (REPORT_SLP)) 
2699                           {
2700                             fprintf (vect_dump, "Build SLP failed: strided "
2701                                      " loads need permutation ");
2702                             print_generic_expr (vect_dump, stmt, TDF_SLIM);
2703                           }
2704
2705                         return false;
2706                       }
2707
2708                     first_dr = STMT_VINFO_DATA_REF (vinfo_for_stmt (stmt));
2709                     if (vect_supportable_dr_alignment (first_dr)
2710                         == dr_unaligned_unsupported)
2711                       {
2712                         if (vect_print_dump_info (REPORT_SLP)) 
2713                           {
2714                             fprintf (vect_dump, "Build SLP failed: unsupported "
2715                                      " unaligned load ");
2716                             print_generic_expr (vect_dump, stmt, TDF_SLIM);
2717                           }
2718
2719                         return false;
2720                       }
2721
2722                     /* Analyze costs (for the first stmt in the group).  */
2723                     vect_model_load_cost (vinfo_for_stmt (stmt), 
2724                                           ncopies_for_cost, *node);
2725                   }
2726                 else
2727                   {
2728                     if (DR_GROUP_NEXT_DR (vinfo_for_stmt (prev_stmt)) != stmt)
2729                       {
2730                         /* FORNOW: data permutations are not supported.  */
2731                         if (vect_print_dump_info (REPORT_SLP)) 
2732                           {
2733                             fprintf (vect_dump, "Build SLP failed: strided "
2734                                      " loads need permutation ");
2735                             print_generic_expr (vect_dump, stmt, TDF_SLIM);
2736                           }
2737                         return false;
2738                       }
2739                   }
2740
2741                 prev_stmt = stmt;
2742
2743                 /* We stop the tree when we reach a group of loads.  */
2744                 stop_recursion = true;
2745                 continue;
2746               }
2747         } /* Strided access.  */
2748       else
2749         {
2750           if (REFERENCE_CLASS_P (rhs))
2751             {
2752               /* Not strided load. */
2753               if (vect_print_dump_info (REPORT_SLP)) 
2754                 {
2755                   fprintf (vect_dump, "Build SLP failed: not strided load ");
2756                   print_generic_expr (vect_dump, stmt, TDF_SLIM);
2757                 }
2758
2759               /* FORNOW: Not strided loads are not supported.  */
2760               return false;
2761             }
2762
2763           /* Not memory operation.  */
2764           if (!BINARY_CLASS_P (rhs) && !UNARY_CLASS_P (rhs))
2765             {
2766               if (vect_print_dump_info (REPORT_SLP)) 
2767                 {
2768                   fprintf (vect_dump, "Build SLP failed: operation");
2769                   fprintf (vect_dump, " unsupported ");
2770                   print_generic_expr (vect_dump, stmt, TDF_SLIM);
2771                 }
2772
2773               return false;
2774             }
2775
2776           /* Find the def-stmts.  */ 
2777           if (!vect_get_and_check_slp_defs (loop_vinfo, *node, rhs, &def_stmts0, 
2778                                             &def_stmts1, &first_stmt_dt0, 
2779                                             &first_stmt_dt1, 
2780                                             &first_stmt_def0_type, 
2781                                             &first_stmt_def1_type,
2782                                             &first_stmt_const_oprnd,
2783                                             ncopies_for_cost))
2784             return false;
2785         }
2786     }
2787
2788   /* Add the costs of the node to the overall instance costs.  */
2789   *inside_cost += SLP_TREE_INSIDE_OF_LOOP_COST (*node); 
2790   *outside_cost += SLP_TREE_OUTSIDE_OF_LOOP_COST (*node);
2791
2792   /* Strided loads were reached - stop the recursion.  */
2793   if (stop_recursion)
2794     return true;
2795
2796   /* Create SLP_TREE nodes for the definition node/s.  */ 
2797   if (first_stmt_dt0 == vect_loop_def)
2798     {
2799       slp_tree left_node = XNEW (struct _slp_tree);
2800       SLP_TREE_SCALAR_STMTS (left_node) = def_stmts0;
2801       SLP_TREE_VEC_STMTS (left_node) = NULL;
2802       SLP_TREE_LEFT (left_node) = NULL;
2803       SLP_TREE_RIGHT (left_node) = NULL;
2804       SLP_TREE_OUTSIDE_OF_LOOP_COST (left_node) = 0;
2805       SLP_TREE_INSIDE_OF_LOOP_COST (left_node) = 0;
2806       if (!vect_build_slp_tree (loop_vinfo, &left_node, group_size, 
2807                                 slp_impossible, inside_cost, outside_cost,
2808                                 ncopies_for_cost))
2809         return false;
2810       
2811       SLP_TREE_LEFT (*node) = left_node;
2812     }
2813
2814   if (first_stmt_dt1 == vect_loop_def)
2815     {
2816       slp_tree right_node = XNEW (struct _slp_tree);
2817       SLP_TREE_SCALAR_STMTS (right_node) = def_stmts1;
2818       SLP_TREE_VEC_STMTS (right_node) = NULL;
2819       SLP_TREE_LEFT (right_node) = NULL;
2820       SLP_TREE_RIGHT (right_node) = NULL;
2821       SLP_TREE_OUTSIDE_OF_LOOP_COST (right_node) = 0;
2822       SLP_TREE_INSIDE_OF_LOOP_COST (right_node) = 0;
2823       if (!vect_build_slp_tree (loop_vinfo, &right_node, group_size,
2824                                 slp_impossible, inside_cost, outside_cost,
2825                                 ncopies_for_cost))
2826         return false;
2827       
2828       SLP_TREE_RIGHT (*node) = right_node;
2829     }
2830
2831   return true;
2832 }
2833
2834
2835 static void
2836 vect_print_slp_tree (slp_tree node)
2837 {
2838   int i;
2839   tree stmt;
2840
2841   if (!node)
2842     return;
2843
2844   fprintf (vect_dump, "node ");
2845   for (i = 0; VEC_iterate (tree, SLP_TREE_SCALAR_STMTS (node), i, stmt); i++)
2846     {
2847       fprintf (vect_dump, "\n\tstmt %d ", i);
2848       print_generic_expr (vect_dump, stmt, TDF_SLIM);  
2849     }
2850   fprintf (vect_dump, "\n");
2851
2852   vect_print_slp_tree (SLP_TREE_LEFT (node));
2853   vect_print_slp_tree (SLP_TREE_RIGHT (node));
2854 }
2855
2856
2857 /* Mark the tree rooted at NODE with MARK (PURE_SLP or HYBRID). 
2858    If MARK is HYBRID, it refers to a specific stmt in NODE (the stmt at index 
2859    J). Otherwise, MARK is PURE_SLP and J is -1, which indicates that all the 
2860    stmts in NODE are to be marked.  */
2861
2862 static void
2863 vect_mark_slp_stmts (slp_tree node, enum slp_vect_type mark, int j)
2864 {
2865   int i;
2866   tree stmt;
2867
2868   if (!node)
2869     return;
2870
2871   for (i = 0; VEC_iterate (tree, SLP_TREE_SCALAR_STMTS (node), i, stmt); i++)
2872     if (j < 0 || i == j)
2873       STMT_SLP_TYPE (vinfo_for_stmt (stmt)) = mark;
2874
2875   vect_mark_slp_stmts (SLP_TREE_LEFT (node), mark, j);
2876   vect_mark_slp_stmts (SLP_TREE_RIGHT (node), mark, j);
2877 }
2878
2879
2880 /* Analyze an SLP instance starting from a group of strided stores. Call
2881    vect_build_slp_tree to build a tree of packed stmts if possible. 
2882    Return FALSE if it's impossible to SLP any stmt in the loop.  */
2883
2884 static bool
2885 vect_analyze_slp_instance (loop_vec_info loop_vinfo, tree stmt)
2886 {
2887   slp_instance new_instance;
2888   slp_tree node = XNEW (struct _slp_tree);
2889   unsigned int group_size = DR_GROUP_SIZE (vinfo_for_stmt (stmt));
2890   unsigned int unrolling_factor = 1, nunits;
2891   tree vectype, scalar_type, next;
2892   unsigned int vectorization_factor = 0, ncopies;
2893   bool slp_impossible = false; 
2894   int inside_cost = 0, outside_cost = 0, ncopies_for_cost;
2895
2896   /* FORNOW: multiple types are not supported.  */
2897   scalar_type = TREE_TYPE (DR_REF (STMT_VINFO_DATA_REF (vinfo_for_stmt (stmt))));
2898   vectype = get_vectype_for_scalar_type (scalar_type);
2899   nunits = TYPE_VECTOR_SUBPARTS (vectype);
2900   vectorization_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
2901   ncopies = vectorization_factor / nunits;
2902   if (ncopies > 1)
2903     {
2904       if (vect_print_dump_info (REPORT_SLP)) 
2905           fprintf (vect_dump, "SLP failed - multiple types ");
2906
2907       return false;
2908     }
2909
2910   /* Create a node (a root of the SLP tree) for the packed strided stores.  */ 
2911   SLP_TREE_SCALAR_STMTS (node) = VEC_alloc (tree, heap, group_size);
2912   next = stmt;
2913   /* Collect the stores and store them in SLP_TREE_SCALAR_STMTS.  */
2914   while (next)
2915     {
2916       VEC_safe_push (tree, heap, SLP_TREE_SCALAR_STMTS (node), next);
2917       next = DR_GROUP_NEXT_DR (vinfo_for_stmt (next));
2918     }
2919
2920   SLP_TREE_VEC_STMTS (node) = NULL;
2921   SLP_TREE_NUMBER_OF_VEC_STMTS (node) = 0;
2922   SLP_TREE_LEFT (node) = NULL;
2923   SLP_TREE_RIGHT (node) = NULL;
2924   SLP_TREE_OUTSIDE_OF_LOOP_COST (node) = 0;
2925   SLP_TREE_INSIDE_OF_LOOP_COST (node) = 0;
2926
2927   /* Calculate the unrolling factor.  */
2928   unrolling_factor = least_common_multiple (nunits, group_size) / group_size;
2929         
2930   /* Calculate the number of vector stmts to create based on the unrolling
2931      factor (number of vectors is 1 if NUNITS >= GROUP_SIZE, and is
2932      GROUP_SIZE / NUNITS otherwise.  */
2933   ncopies_for_cost = unrolling_factor * group_size / nunits;
2934
2935   /* Build the tree for the SLP instance.  */
2936   if (vect_build_slp_tree (loop_vinfo, &node, group_size, &slp_impossible,
2937                            &inside_cost, &outside_cost, ncopies_for_cost))
2938     {
2939       /* Create a new SLP instance.  */  
2940       new_instance = XNEW (struct _slp_instance);
2941       SLP_INSTANCE_TREE (new_instance) = node;
2942       SLP_INSTANCE_GROUP_SIZE (new_instance) = group_size;
2943       SLP_INSTANCE_UNROLLING_FACTOR (new_instance) = unrolling_factor;
2944       SLP_INSTANCE_OUTSIDE_OF_LOOP_COST (new_instance) = outside_cost;
2945       SLP_INSTANCE_INSIDE_OF_LOOP_COST (new_instance) = inside_cost;
2946       VEC_safe_push (slp_instance, heap, LOOP_VINFO_SLP_INSTANCES (loop_vinfo), 
2947                      new_instance);
2948       if (vect_print_dump_info (REPORT_SLP))
2949         vect_print_slp_tree (node);
2950
2951       return true;
2952     }
2953
2954   /* Failed to SLP.  */
2955   /* Free the allocated memory.  */
2956   vect_free_slp_tree (node);
2957
2958   if (slp_impossible)
2959     return false;
2960
2961   /* SLP failed for this instance, but it is still possible to SLP other stmts 
2962      in the loop.  */
2963   return true;
2964 }
2965
2966
2967 /* Check if there are stmts in the loop can be vectorized using SLP. Build SLP
2968    trees of packed scalar stmts if SLP is possible.  */
2969
2970 static bool
2971 vect_analyze_slp (loop_vec_info loop_vinfo)
2972 {
2973   unsigned int i;
2974   VEC (tree, heap) *strided_stores = LOOP_VINFO_STRIDED_STORES (loop_vinfo);
2975   tree store;
2976
2977   if (vect_print_dump_info (REPORT_SLP))
2978     fprintf (vect_dump, "=== vect_analyze_slp ===");
2979
2980   for (i = 0; VEC_iterate (tree, strided_stores, i, store); i++)
2981     if (!vect_analyze_slp_instance (loop_vinfo, store))
2982       {
2983         /* SLP failed. No instance can be SLPed in the loop.  */
2984         if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))   
2985           fprintf (vect_dump, "SLP failed.");
2986
2987         return false;
2988       }
2989
2990   return true;
2991 }
2992
2993
2994 /* For each possible SLP instance decide whether to SLP it and calculate overall
2995    unrolling factor needed to SLP the loop.  */
2996
2997 static void
2998 vect_make_slp_decision (loop_vec_info loop_vinfo)
2999 {
3000   unsigned int i, unrolling_factor = 1;
3001   VEC (slp_instance, heap) *slp_instances = LOOP_VINFO_SLP_INSTANCES (loop_vinfo);
3002   slp_instance instance;
3003   int decided_to_slp = 0;
3004
3005   if (vect_print_dump_info (REPORT_SLP))
3006     fprintf (vect_dump, "=== vect_make_slp_decision ===");
3007
3008   for (i = 0; VEC_iterate (slp_instance, slp_instances, i, instance); i++)
3009     {
3010       /* FORNOW: SLP if you can.  */
3011       if (unrolling_factor < SLP_INSTANCE_UNROLLING_FACTOR (instance))
3012         unrolling_factor = SLP_INSTANCE_UNROLLING_FACTOR (instance);
3013
3014       /* Mark all the stmts that belong to INSTANCE as PURE_SLP stmts. Later we 
3015          call vect_detect_hybrid_slp () to find stmts that need hybrid SLP and 
3016          loop-based vectorization. Such stmts will be marked as HYBRID.  */
3017       vect_mark_slp_stmts (SLP_INSTANCE_TREE (instance), pure_slp, -1);
3018       decided_to_slp++;
3019     }
3020
3021   LOOP_VINFO_SLP_UNROLLING_FACTOR (loop_vinfo) = unrolling_factor;
3022
3023   if (decided_to_slp && vect_print_dump_info (REPORT_SLP)) 
3024     fprintf (vect_dump, "Decided to SLP %d instances. Unrolling factor %d", 
3025              decided_to_slp, unrolling_factor);
3026 }
3027
3028
3029 /* Find stmts that must be both vectorized and SLPed (since they feed stmts that
3030    can't be SLPed) in the tree rooted at NODE. Mark such stmts as HYBRID.  */
3031
3032 static void
3033 vect_detect_hybrid_slp_stmts (slp_tree node)
3034 {
3035   int i;
3036   tree stmt;
3037   imm_use_iterator imm_iter;
3038   tree use_stmt;
3039
3040   if (!node)
3041     return;
3042
3043   for (i = 0; VEC_iterate (tree, SLP_TREE_SCALAR_STMTS (node), i, stmt); i++)
3044     if (PURE_SLP_STMT (vinfo_for_stmt (stmt))
3045         && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) == SSA_NAME)
3046       FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, GIMPLE_STMT_OPERAND (stmt, 0))
3047         if (vinfo_for_stmt (use_stmt)
3048             && !STMT_SLP_TYPE (vinfo_for_stmt (use_stmt)))
3049           vect_mark_slp_stmts (node, hybrid, i);
3050
3051   vect_detect_hybrid_slp_stmts (SLP_TREE_LEFT (node));
3052   vect_detect_hybrid_slp_stmts (SLP_TREE_RIGHT (node));
3053 }
3054
3055
3056 /* Find stmts that must be both vectorized and SLPed.  */
3057
3058 static void
3059 vect_detect_hybrid_slp (loop_vec_info loop_vinfo)
3060 {
3061   unsigned int i;
3062   VEC (slp_instance, heap) *slp_instances = LOOP_VINFO_SLP_INSTANCES (loop_vinfo);
3063   slp_instance instance;
3064
3065   if (vect_print_dump_info (REPORT_SLP))
3066     fprintf (vect_dump, "=== vect_detect_hybrid_slp ===");
3067
3068   for (i = 0; VEC_iterate (slp_instance, slp_instances, i, instance); i++)
3069     vect_detect_hybrid_slp_stmts (SLP_INSTANCE_TREE (instance));
3070 }
3071
3072
3073 /* Function vect_analyze_data_refs.
3074
3075   Find all the data references in the loop.
3076
3077    The general structure of the analysis of data refs in the vectorizer is as
3078    follows:
3079    1- vect_analyze_data_refs(loop): call compute_data_dependences_for_loop to
3080       find and analyze all data-refs in the loop and their dependences.
3081    2- vect_analyze_dependences(): apply dependence testing using ddrs.
3082    3- vect_analyze_drs_alignment(): check that ref_stmt.alignment is ok.
3083    4- vect_analyze_drs_access(): check that ref_stmt.step is ok.
3084
3085 */
3086
3087 static bool
3088 vect_analyze_data_refs (loop_vec_info loop_vinfo)  
3089 {
3090   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
3091   unsigned int i;
3092   VEC (data_reference_p, heap) *datarefs;
3093   struct data_reference *dr;
3094   tree scalar_type;
3095
3096   if (vect_print_dump_info (REPORT_DETAILS))
3097     fprintf (vect_dump, "=== vect_analyze_data_refs ===\n");
3098
3099   compute_data_dependences_for_loop (loop, true,
3100                                      &LOOP_VINFO_DATAREFS (loop_vinfo),
3101                                      &LOOP_VINFO_DDRS (loop_vinfo));
3102
3103   /* Go through the data-refs, check that the analysis succeeded. Update pointer
3104      from stmt_vec_info struct to DR and vectype.  */
3105   datarefs = LOOP_VINFO_DATAREFS (loop_vinfo);
3106
3107   for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++)
3108     {
3109       tree stmt;
3110       stmt_vec_info stmt_info;
3111       basic_block bb;
3112       tree base, offset, init;  
3113    
3114       if (!dr || !DR_REF (dr))
3115         {
3116           if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
3117             fprintf (vect_dump, "not vectorized: unhandled data-ref ");
3118           return false;
3119         }
3120
3121       stmt = DR_STMT (dr);
3122       stmt_info = vinfo_for_stmt (stmt);
3123
3124       /* Check that analysis of the data-ref succeeded.  */
3125       if (!DR_BASE_ADDRESS (dr) || !DR_OFFSET (dr) || !DR_INIT (dr)
3126           || !DR_STEP (dr))
3127         {
3128           if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
3129             {
3130               fprintf (vect_dump, "not vectorized: data ref analysis failed ");
3131               print_generic_expr (vect_dump, stmt, TDF_SLIM);
3132             }
3133           return false;
3134         }
3135
3136       if (TREE_CODE (DR_BASE_ADDRESS (dr)) == INTEGER_CST)
3137         {
3138           if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
3139             fprintf (vect_dump, "not vectorized: base addr of dr is a "
3140                      "constant");
3141           return false;
3142         }
3143
3144       if (!DR_SYMBOL_TAG (dr))
3145         {
3146           if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
3147             {
3148               fprintf (vect_dump, "not vectorized: no memory tag for ");
3149               print_generic_expr (vect_dump, DR_REF (dr), TDF_SLIM);
3150             }
3151           return false;
3152         }
3153
3154       base = unshare_expr (DR_BASE_ADDRESS (dr));
3155       offset = unshare_expr (DR_OFFSET (dr));
3156       init = unshare_expr (DR_INIT (dr));
3157         
3158       /* Update DR field in stmt_vec_info struct.  */
3159       bb = bb_for_stmt (stmt);
3160
3161       /* If the dataref is in an inner-loop of the loop that is considered for
3162          for vectorization, we also want to analyze the access relative to
3163          the outer-loop (DR contains information only relative to the 
3164          inner-most enclosing loop).  We do that by building a reference to the
3165          first location accessed by the inner-loop, and analyze it relative to
3166          the outer-loop.  */    
3167       if (nested_in_vect_loop_p (loop, stmt)) 
3168         {
3169           tree outer_step, outer_base, outer_init;
3170           HOST_WIDE_INT pbitsize, pbitpos;
3171           tree poffset;
3172           enum machine_mode pmode;
3173           int punsignedp, pvolatilep;
3174           affine_iv base_iv, offset_iv;
3175           tree dinit;
3176
3177           /* Build a reference to the first location accessed by the 
3178              inner-loop: *(BASE+INIT). (The first location is actually
3179              BASE+INIT+OFFSET, but we add OFFSET separately later.  */
3180           tree inner_base = build_fold_indirect_ref 
3181                                 (fold_build2 (PLUS_EXPR, TREE_TYPE (base), base, init));
3182
3183           if (vect_print_dump_info (REPORT_DETAILS))
3184             {
3185               fprintf (dump_file, "analyze in outer-loop: ");
3186               print_generic_expr (dump_file, inner_base, TDF_SLIM);
3187             }
3188
3189           outer_base = get_inner_reference (inner_base, &pbitsize, &pbitpos, 
3190                           &poffset, &pmode, &punsignedp, &pvolatilep, false);
3191           gcc_assert (outer_base != NULL_TREE);
3192
3193           if (pbitpos % BITS_PER_UNIT != 0)
3194             {
3195               if (vect_print_dump_info (REPORT_DETAILS))
3196                 fprintf (dump_file, "failed: bit offset alignment.\n");
3197               return false;
3198             }
3199
3200           outer_base = build_fold_addr_expr (outer_base);
3201           if (!simple_iv (loop, stmt, outer_base, &base_iv, false))
3202             {
3203               if (vect_print_dump_info (REPORT_DETAILS))
3204                 fprintf (dump_file, "failed: evolution of base is not affine.\n");
3205               return false;
3206             }
3207
3208           if (offset)
3209             {
3210               if (poffset)
3211                 poffset = fold_build2 (PLUS_EXPR, TREE_TYPE (offset), offset, poffset);
3212               else
3213                 poffset = offset;
3214             }
3215
3216           if (!poffset)
3217             {
3218               offset_iv.base = ssize_int (0);
3219               offset_iv.step = ssize_int (0);
3220             }
3221           else if (!simple_iv (loop, stmt, poffset, &offset_iv, false))
3222             {
3223               if (vect_print_dump_info (REPORT_DETAILS))
3224                 fprintf (dump_file, "evolution of offset is not affine.\n");
3225               return false;
3226             }
3227
3228           outer_init = ssize_int (pbitpos / BITS_PER_UNIT);
3229           split_constant_offset (base_iv.base, &base_iv.base, &dinit);
3230           outer_init =  size_binop (PLUS_EXPR, outer_init, dinit);
3231           split_constant_offset (offset_iv.base, &offset_iv.base, &dinit);
3232           outer_init =  size_binop (PLUS_EXPR, outer_init, dinit);
3233
3234           outer_step = size_binop (PLUS_EXPR,
3235                                 fold_convert (ssizetype, base_iv.step),
3236                                 fold_convert (ssizetype, offset_iv.step));
3237
3238           STMT_VINFO_DR_STEP (stmt_info) = outer_step;
3239           /* FIXME: Use canonicalize_base_object_address (base_iv.base); */
3240           STMT_VINFO_DR_BASE_ADDRESS (stmt_info) = base_iv.base; 
3241           STMT_VINFO_DR_INIT (stmt_info) = outer_init;
3242           STMT_VINFO_DR_OFFSET (stmt_info) = 
3243                                 fold_convert (ssizetype, offset_iv.base);
3244           STMT_VINFO_DR_ALIGNED_TO (stmt_info) = 
3245                                 size_int (highest_pow2_factor (offset_iv.base));
3246
3247           if (dump_file && (dump_flags & TDF_DETAILS))
3248             {
3249               fprintf (dump_file, "\touter base_address: ");
3250               print_generic_expr (dump_file, STMT_VINFO_DR_BASE_ADDRESS (stmt_info), TDF_SLIM);
3251               fprintf (dump_file, "\n\touter offset from base address: ");
3252               print_generic_expr (dump_file, STMT_VINFO_DR_OFFSET (stmt_info), TDF_SLIM);
3253               fprintf (dump_file, "\n\touter constant offset from base address: ");
3254               print_generic_expr (dump_file, STMT_VINFO_DR_INIT (stmt_info), TDF_SLIM);
3255               fprintf (dump_file, "\n\touter step: ");
3256               print_generic_expr (dump_file, STMT_VINFO_DR_STEP (stmt_info), TDF_SLIM);
3257               fprintf (dump_file, "\n\touter aligned to: ");
3258               print_generic_expr (dump_file, STMT_VINFO_DR_ALIGNED_TO (stmt_info), TDF_SLIM);
3259             }
3260         }
3261
3262       if (STMT_VINFO_DATA_REF (stmt_info))
3263         {
3264           if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
3265             {
3266               fprintf (vect_dump,
3267                        "not vectorized: more than one data ref in stmt: ");
3268               print_generic_expr (vect_dump, stmt, TDF_SLIM);
3269             }
3270           return false;
3271         }
3272       STMT_VINFO_DATA_REF (stmt_info) = dr;
3273      
3274       /* Set vectype for STMT.  */
3275       scalar_type = TREE_TYPE (DR_REF (dr));
3276       STMT_VINFO_VECTYPE (stmt_info) =
3277                 get_vectype_for_scalar_type (scalar_type);
3278       if (!STMT_VINFO_VECTYPE (stmt_info)) 
3279         {
3280           if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
3281             {
3282               fprintf (vect_dump,
3283                        "not vectorized: no vectype for stmt: ");
3284               print_generic_expr (vect_dump, stmt, TDF_SLIM);
3285               fprintf (vect_dump, " scalar_type: ");
3286               print_generic_expr (vect_dump, scalar_type, TDF_DETAILS);
3287             }
3288           return false;
3289         }
3290     }
3291       
3292   return true;
3293 }
3294
3295
3296 /* Utility functions used by vect_mark_stmts_to_be_vectorized.  */
3297
3298 /* Function vect_mark_relevant.
3299
3300    Mark STMT as "relevant for vectorization" and add it to WORKLIST.  */
3301
3302 static void
3303 vect_mark_relevant (VEC(tree,heap) **worklist, tree stmt,
3304                     enum vect_relevant relevant, bool live_p)
3305 {
3306   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
3307   enum vect_relevant save_relevant = STMT_VINFO_RELEVANT (stmt_info);
3308   bool save_live_p = STMT_VINFO_LIVE_P (stmt_info);
3309
3310   if (vect_print_dump_info (REPORT_DETAILS))
3311     fprintf (vect_dump, "mark relevant %d, live %d.", relevant, live_p);
3312
3313   if (STMT_VINFO_IN_PATTERN_P (stmt_info))
3314     {
3315       tree pattern_stmt;
3316
3317       /* This is the last stmt in a sequence that was detected as a 
3318          pattern that can potentially be vectorized.  Don't mark the stmt
3319          as relevant/live because it's not going to be vectorized.
3320          Instead mark the pattern-stmt that replaces it.  */
3321
3322       pattern_stmt = STMT_VINFO_RELATED_STMT (stmt_info);
3323
3324       if (vect_print_dump_info (REPORT_DETAILS))
3325         fprintf (vect_dump, "last stmt in pattern. don't mark relevant/live.");
3326       stmt_info = vinfo_for_stmt (pattern_stmt);
3327       gcc_assert (STMT_VINFO_RELATED_STMT (stmt_info) == stmt);
3328       save_relevant = STMT_VINFO_RELEVANT (stmt_info);
3329       save_live_p = STMT_VINFO_LIVE_P (stmt_info);
3330       stmt = pattern_stmt;
3331     }
3332
3333   STMT_VINFO_LIVE_P (stmt_info) |= live_p;
3334   if (relevant > STMT_VINFO_RELEVANT (stmt_info))
3335     STMT_VINFO_RELEVANT (stmt_info) = relevant;
3336
3337   if (STMT_VINFO_RELEVANT (stmt_info) == save_relevant
3338       && STMT_VINFO_LIVE_P (stmt_info) == save_live_p)
3339     {
3340       if (vect_print_dump_info (REPORT_DETAILS))
3341         fprintf (vect_dump, "already marked relevant/live.");
3342       return;
3343     }
3344
3345   VEC_safe_push (tree, heap, *worklist, stmt);
3346 }
3347
3348
3349 /* Function vect_stmt_relevant_p.
3350
3351    Return true if STMT in loop that is represented by LOOP_VINFO is
3352    "relevant for vectorization".
3353
3354    A stmt is considered "relevant for vectorization" if:
3355    - it has uses outside the loop.
3356    - it has vdefs (it alters memory).
3357    - control stmts in the loop (except for the exit condition).
3358
3359    CHECKME: what other side effects would the vectorizer allow?  */
3360
3361 static bool
3362 vect_stmt_relevant_p (tree stmt, loop_vec_info loop_vinfo,
3363                       enum vect_relevant *relevant, bool *live_p)
3364 {
3365   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
3366   ssa_op_iter op_iter;
3367   imm_use_iterator imm_iter;
3368   use_operand_p use_p;
3369   def_operand_p def_p;
3370
3371   *relevant = vect_unused_in_loop;
3372   *live_p = false;
3373
3374   /* cond stmt other than loop exit cond.  */
3375   if (is_ctrl_stmt (stmt) 
3376       && STMT_VINFO_TYPE (vinfo_for_stmt (stmt)) != loop_exit_ctrl_vec_info_type) 
3377     *relevant = vect_used_in_loop;
3378
3379   /* changing memory.  */
3380   if (TREE_CODE (stmt) != PHI_NODE)
3381     if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_VIRTUAL_DEFS))
3382       {
3383         if (vect_print_dump_info (REPORT_DETAILS))
3384           fprintf (vect_dump, "vec_stmt_relevant_p: stmt has vdefs.");
3385         *relevant = vect_used_in_loop;
3386       }
3387
3388   /* uses outside the loop.  */
3389   FOR_EACH_PHI_OR_STMT_DEF (def_p, stmt, op_iter, SSA_OP_DEF)
3390     {
3391       FOR_EACH_IMM_USE_FAST (use_p, imm_iter, DEF_FROM_PTR (def_p))
3392         {
3393           basic_block bb = bb_for_stmt (USE_STMT (use_p));
3394           if (!flow_bb_inside_loop_p (loop, bb))
3395             {
3396               if (vect_print_dump_info (REPORT_DETAILS))
3397                 fprintf (vect_dump, "vec_stmt_relevant_p: used out of loop.");
3398
3399               /* We expect all such uses to be in the loop exit phis
3400                  (because of loop closed form)   */
3401               gcc_assert (TREE_CODE (USE_STMT (use_p)) == PHI_NODE);
3402               gcc_assert (bb == single_exit (loop)->dest);
3403
3404               *live_p = true;
3405             }
3406         }
3407     }
3408
3409   return (*live_p || *relevant);
3410 }
3411
3412
3413 /* 
3414    Function process_use.
3415
3416    Inputs:
3417    - a USE in STMT in a loop represented by LOOP_VINFO
3418    - LIVE_P, RELEVANT - enum values to be set in the STMT_VINFO of the stmt 
3419      that defined USE. This is dont by calling mark_relevant and passing it
3420      the WORKLIST (to add DEF_STMT to the WORKlist in case itis relevant). 
3421
3422    Outputs:
3423    Generally, LIVE_P and RELEVANT are used to define the liveness and
3424    relevance info of the DEF_STMT of this USE:
3425        STMT_VINFO_LIVE_P (DEF_STMT_info) <-- live_p
3426        STMT_VINFO_RELEVANT (DEF_STMT_info) <-- relevant
3427    Exceptions:
3428    - case 1: If USE is used only for address computations (e.g. array indexing),
3429    which does not need to be directly vectorized, then the liveness/relevance 
3430    of the respective DEF_STMT is left unchanged.
3431    - case 2: If STMT is a reduction phi and DEF_STMT is a reduction stmt, we 
3432    skip DEF_STMT cause it had already been processed.  
3433    - case 3: If DEF_STMT and STMT are in different nests, then  "relevant" will
3434    be modified accordingly.
3435
3436    Return true if everything is as expected. Return false otherwise.  */
3437
3438 static bool
3439 process_use (tree stmt, tree use, loop_vec_info loop_vinfo, bool live_p, 
3440              enum vect_relevant relevant, VEC(tree,heap) **worklist)
3441 {
3442   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
3443   stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt);
3444   stmt_vec_info dstmt_vinfo;
3445   basic_block bb, def_bb;
3446   tree def, def_stmt;
3447   enum vect_def_type dt;
3448
3449   /* case 1: we are only interested in uses that need to be vectorized.  Uses 
3450      that are used for address computation are not considered relevant.  */
3451   if (!exist_non_indexing_operands_for_use_p (use, stmt))
3452      return true;
3453
3454   if (!vect_is_simple_use (use, loop_vinfo, &def_stmt, &def, &dt))
3455     { 
3456       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
3457         fprintf (vect_dump, "not vectorized: unsupported use in stmt.");
3458       return false;
3459     }
3460
3461   if (!def_stmt || IS_EMPTY_STMT (def_stmt))
3462     return true;
3463
3464   def_bb = bb_for_stmt (def_stmt);
3465   if (!flow_bb_inside_loop_p (loop, def_bb))
3466     {
3467       if (vect_print_dump_info (REPORT_DETAILS))
3468         fprintf (vect_dump, "def_stmt is out of loop.");
3469       return true;
3470     }
3471
3472   /* case 2: A reduction phi (STMT) defined by a reduction stmt (DEF_STMT). 
3473      DEF_STMT must have already been processed, because this should be the 
3474      only way that STMT, which is a reduction-phi, was put in the worklist, 
3475      as there should be no other uses for DEF_STMT in the loop.  So we just 
3476      check that everything is as expected, and we are done.  */
3477   dstmt_vinfo = vinfo_for_stmt (def_stmt);
3478   bb = bb_for_stmt (stmt);
3479   if (TREE_CODE (stmt) == PHI_NODE
3480       && STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_reduction_def
3481       && TREE_CODE (def_stmt) != PHI_NODE
3482       && STMT_VINFO_DEF_TYPE (dstmt_vinfo) == vect_reduction_def
3483       && bb->loop_father == def_bb->loop_father)
3484     {
3485       if (vect_print_dump_info (REPORT_DETAILS))
3486         fprintf (vect_dump, "reduc-stmt defining reduc-phi in the same nest.");
3487       if (STMT_VINFO_IN_PATTERN_P (dstmt_vinfo))
3488         dstmt_vinfo = vinfo_for_stmt (STMT_VINFO_RELATED_STMT (dstmt_vinfo));
3489       gcc_assert (STMT_VINFO_RELEVANT (dstmt_vinfo) < vect_used_by_reduction);
3490       gcc_assert (STMT_VINFO_LIVE_P (dstmt_vinfo) 
3491                   || STMT_VINFO_RELEVANT (dstmt_vinfo) > vect_unused_in_loop);
3492       return true;
3493     }
3494
3495   /* case 3a: outer-loop stmt defining an inner-loop stmt:
3496         outer-loop-header-bb:
3497                 d = def_stmt
3498         inner-loop:
3499                 stmt # use (d)
3500         outer-loop-tail-bb:
3501                 ...               */
3502   if (flow_loop_nested_p (def_bb->loop_father, bb->loop_father))
3503     {
3504       if (vect_print_dump_info (REPORT_DETAILS))
3505         fprintf (vect_dump, "outer-loop def-stmt defining inner-loop stmt.");
3506       switch (relevant)
3507         {
3508         case vect_unused_in_loop:
3509           relevant = (STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_reduction_def) ?
3510                         vect_used_by_reduction : vect_unused_in_loop;
3511           break;
3512         case vect_used_in_outer_by_reduction:
3513           relevant = vect_used_by_reduction;
3514           break;
3515         case vect_used_in_outer:
3516           relevant = vect_used_in_loop;
3517           break;
3518         case vect_used_by_reduction: 
3519         case vect_used_in_loop:
3520           break;
3521
3522         default:
3523           gcc_unreachable ();
3524         }   
3525     }
3526
3527   /* case 3b: inner-loop stmt defining an outer-loop stmt:
3528         outer-loop-header-bb:
3529                 ...
3530         inner-loop:
3531                 d = def_stmt
3532         outer-loop-tail-bb:
3533                 stmt # use (d)          */
3534   else if (flow_loop_nested_p (bb->loop_father, def_bb->loop_father))
3535     {
3536       if (vect_print_dump_info (REPORT_DETAILS))
3537         fprintf (vect_dump, "inner-loop def-stmt defining outer-loop stmt.");
3538       switch (relevant)
3539         {
3540         case vect_unused_in_loop:
3541           relevant = (STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_reduction_def) ?
3542                         vect_used_in_outer_by_reduction : vect_unused_in_loop;
3543           break;
3544
3545         case vect_used_in_outer_by_reduction:
3546         case vect_used_in_outer:
3547           break;
3548
3549         case vect_used_by_reduction:
3550           relevant = vect_used_in_outer_by_reduction;
3551           break;
3552
3553         case vect_used_in_loop:
3554           relevant = vect_used_in_outer;
3555           break;
3556
3557         default:
3558           gcc_unreachable ();
3559         }
3560     }
3561
3562   vect_mark_relevant (worklist, def_stmt, relevant, live_p);
3563   return true;
3564 }
3565
3566
3567 /* Function vect_mark_stmts_to_be_vectorized.
3568
3569    Not all stmts in the loop need to be vectorized. For example:
3570
3571      for i...
3572        for j...
3573    1.    T0 = i + j
3574    2.    T1 = a[T0]
3575
3576    3.    j = j + 1
3577
3578    Stmt 1 and 3 do not need to be vectorized, because loop control and
3579    addressing of vectorized data-refs are handled differently.
3580
3581    This pass detects such stmts.  */
3582
3583 static bool
3584 vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo)
3585 {
3586   VEC(tree,heap) *worklist;
3587   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
3588   basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
3589   unsigned int nbbs = loop->num_nodes;
3590   block_stmt_iterator si;
3591   tree stmt;
3592   stmt_ann_t ann;
3593   unsigned int i;
3594   stmt_vec_info stmt_vinfo;
3595   basic_block bb;
3596   tree phi;
3597   bool live_p;
3598   enum vect_relevant relevant;
3599
3600   if (vect_print_dump_info (REPORT_DETAILS))
3601     fprintf (vect_dump, "=== vect_mark_stmts_to_be_vectorized ===");
3602
3603   worklist = VEC_alloc (tree, heap, 64);
3604
3605   /* 1. Init worklist.  */
3606   for (i = 0; i < nbbs; i++)
3607     {
3608       bb = bbs[i];
3609       for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
3610         { 
3611           if (vect_print_dump_info (REPORT_DETAILS))
3612             {
3613               fprintf (vect_dump, "init: phi relevant? ");
3614               print_generic_expr (vect_dump, phi, TDF_SLIM);
3615             }
3616
3617           if (vect_stmt_relevant_p (phi, loop_vinfo, &relevant, &live_p))
3618             vect_mark_relevant (&worklist, phi, relevant, live_p);
3619         }
3620       for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
3621         {
3622           stmt = bsi_stmt (si);
3623           if (vect_print_dump_info (REPORT_DETAILS))
3624             {
3625               fprintf (vect_dump, "init: stmt relevant? ");
3626               print_generic_expr (vect_dump, stmt, TDF_SLIM);
3627             } 
3628
3629           if (vect_stmt_relevant_p (stmt, loop_vinfo, &relevant, &live_p))
3630             vect_mark_relevant (&worklist, stmt, relevant, live_p);
3631         }
3632     }
3633
3634   /* 2. Process_worklist */
3635   while (VEC_length (tree, worklist) > 0)
3636     {
3637       use_operand_p use_p;
3638       ssa_op_iter iter;
3639
3640       stmt = VEC_pop (tree, worklist);
3641       if (vect_print_dump_info (REPORT_DETAILS))
3642         {
3643           fprintf (vect_dump, "worklist: examine stmt: ");
3644           print_generic_expr (vect_dump, stmt, TDF_SLIM);
3645         }
3646
3647       /* Examine the USEs of STMT. For each USE, mark the stmt that defines it 
3648          (DEF_STMT) as relevant/irrelevant and live/dead according to the 
3649          liveness and relevance properties of STMT.  */
3650       ann = stmt_ann (stmt);
3651       stmt_vinfo = vinfo_for_stmt (stmt);
3652       relevant = STMT_VINFO_RELEVANT (stmt_vinfo);
3653       live_p = STMT_VINFO_LIVE_P (stmt_vinfo);
3654
3655       /* Generally, the liveness and relevance properties of STMT are
3656          propagated as is to the DEF_STMTs of its USEs:
3657           live_p <-- STMT_VINFO_LIVE_P (STMT_VINFO)
3658           relevant <-- STMT_VINFO_RELEVANT (STMT_VINFO)
3659
3660          One exception is when STMT has been identified as defining a reduction
3661          variable; in this case we set the liveness/relevance as follows:
3662            live_p = false
3663            relevant = vect_used_by_reduction
3664          This is because we distinguish between two kinds of relevant stmts -
3665          those that are used by a reduction computation, and those that are 
3666          (also) used by a regular computation. This allows us later on to 
3667          identify stmts that are used solely by a reduction, and therefore the 
3668          order of the results that they produce does not have to be kept.
3669
3670          Reduction phis are expected to be used by a reduction stmt, or by
3671          in an outer loop;  Other reduction stmts are expected to be
3672          in the loop, and possibly used by a stmt in an outer loop. 
3673          Here are the expected values of "relevant" for reduction phis/stmts:
3674
3675          relevance:                             phi     stmt
3676          vect_unused_in_loop                            ok
3677          vect_used_in_outer_by_reduction        ok      ok
3678          vect_used_in_outer                     ok      ok
3679          vect_used_by_reduction                 ok
3680          vect_used_in_loop                                                */
3681
3682       if (STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_reduction_def)
3683         {
3684           enum vect_relevant tmp_relevant = relevant;
3685           switch (tmp_relevant)
3686             {
3687             case vect_unused_in_loop:
3688               gcc_assert (TREE_CODE (stmt) != PHI_NODE);
3689               relevant = vect_used_by_reduction;
3690               break;
3691
3692             case vect_used_in_outer_by_reduction:
3693             case vect_used_in_outer:
3694               gcc_assert (TREE_CODE (stmt) != WIDEN_SUM_EXPR
3695                           && TREE_CODE (stmt) != DOT_PROD_EXPR);
3696               break;
3697
3698             case vect_used_by_reduction:
3699               if (TREE_CODE (stmt) == PHI_NODE)
3700                 break;
3701               /* fall through */
3702             case vect_used_in_loop:
3703             default:
3704               if (vect_print_dump_info (REPORT_DETAILS))
3705                 fprintf (vect_dump, "unsupported use of reduction.");
3706               VEC_free (tree, heap, worklist);
3707               return false;
3708             }
3709           live_p = false;       
3710         }
3711
3712       FOR_EACH_PHI_OR_STMT_USE (use_p, stmt, iter, SSA_OP_USE)
3713         {
3714           tree op = USE_FROM_PTR (use_p);
3715           if (!process_use (stmt, op, loop_vinfo, live_p, relevant, &worklist))
3716             {
3717               VEC_free (tree, heap, worklist);
3718               return false;
3719             }
3720         }
3721     } /* while worklist */
3722
3723   VEC_free (tree, heap, worklist);
3724   return true;
3725 }
3726
3727
3728 /* Function vect_can_advance_ivs_p
3729
3730    In case the number of iterations that LOOP iterates is unknown at compile 
3731    time, an epilog loop will be generated, and the loop induction variables 
3732    (IVs) will be "advanced" to the value they are supposed to take just before 
3733    the epilog loop.  Here we check that the access function of the loop IVs
3734    and the expression that represents the loop bound are simple enough.
3735    These restrictions will be relaxed in the future.  */
3736
3737 static bool 
3738 vect_can_advance_ivs_p (loop_vec_info loop_vinfo)
3739 {
3740   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
3741   basic_block bb = loop->header;
3742   tree phi;
3743
3744   /* Analyze phi functions of the loop header.  */
3745
3746   if (vect_print_dump_info (REPORT_DETAILS))
3747     fprintf (vect_dump, "vect_can_advance_ivs_p:");
3748
3749   for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
3750     {
3751       tree access_fn = NULL;
3752       tree evolution_part;
3753
3754       if (vect_print_dump_info (REPORT_DETAILS))
3755         {
3756           fprintf (vect_dump, "Analyze phi: ");
3757           print_generic_expr (vect_dump, phi, TDF_SLIM);
3758         }
3759
3760       /* Skip virtual phi's. The data dependences that are associated with
3761          virtual defs/uses (i.e., memory accesses) are analyzed elsewhere.  */
3762
3763       if (!is_gimple_reg (SSA_NAME_VAR (PHI_RESULT (phi))))
3764         {
3765           if (vect_print_dump_info (REPORT_DETAILS))
3766             fprintf (vect_dump, "virtual phi. skip.");
3767           continue;
3768         }
3769
3770       /* Skip reduction phis.  */
3771
3772       if (STMT_VINFO_DEF_TYPE (vinfo_for_stmt (phi)) == vect_reduction_def)
3773         {
3774           if (vect_print_dump_info (REPORT_DETAILS))
3775             fprintf (vect_dump, "reduc phi. skip.");
3776           continue;
3777         }
3778
3779       /* Analyze the evolution function.  */
3780
3781       access_fn = instantiate_parameters
3782         (loop, analyze_scalar_evolution (loop, PHI_RESULT (phi)));
3783
3784       if (!access_fn)
3785         {
3786           if (vect_print_dump_info (REPORT_DETAILS))
3787             fprintf (vect_dump, "No Access function.");
3788           return false;
3789         }
3790
3791       if (vect_print_dump_info (REPORT_DETAILS))
3792         {
3793           fprintf (vect_dump, "Access function of PHI: ");
3794           print_generic_expr (vect_dump, access_fn, TDF_SLIM);
3795         }
3796
3797       evolution_part = evolution_part_in_loop_num (access_fn, loop->num);
3798       
3799       if (evolution_part == NULL_TREE)
3800         {
3801           if (vect_print_dump_info (REPORT_DETAILS))
3802             fprintf (vect_dump, "No evolution.");
3803           return false;
3804         }
3805   
3806       /* FORNOW: We do not transform initial conditions of IVs 
3807          which evolution functions are a polynomial of degree >= 2.  */
3808
3809       if (tree_is_chrec (evolution_part))
3810         return false;  
3811     }
3812
3813   return true;
3814 }
3815
3816
3817 /* Function vect_get_loop_niters.
3818
3819    Determine how many iterations the loop is executed.
3820    If an expression that represents the number of iterations
3821    can be constructed, place it in NUMBER_OF_ITERATIONS.
3822    Return the loop exit condition.  */
3823
3824 static tree
3825 vect_get_loop_niters (struct loop *loop, tree *number_of_iterations)
3826 {
3827   tree niters;
3828
3829   if (vect_print_dump_info (REPORT_DETAILS))
3830     fprintf (vect_dump, "=== get_loop_niters ===");
3831
3832   niters = number_of_exit_cond_executions (loop);
3833
3834   if (niters != NULL_TREE
3835       && niters != chrec_dont_know)
3836     {
3837       *number_of_iterations = niters;
3838
3839       if (vect_print_dump_info (REPORT_DETAILS))
3840         {
3841           fprintf (vect_dump, "==> get_loop_niters:" );
3842           print_generic_expr (vect_dump, *number_of_iterations, TDF_SLIM);
3843         }
3844     }
3845
3846   return get_loop_exit_condition (loop);
3847 }
3848
3849
3850 /* Function vect_analyze_loop_1.
3851
3852    Apply a set of analyses on LOOP, and create a loop_vec_info struct
3853    for it. The different analyses will record information in the
3854    loop_vec_info struct.  This is a subset of the analyses applied in
3855    vect_analyze_loop, to be applied on an inner-loop nested in the loop
3856    that is now considered for (outer-loop) vectorization.  */
3857
3858 static loop_vec_info
3859 vect_analyze_loop_1 (struct loop *loop)
3860 {
3861   loop_vec_info loop_vinfo;
3862
3863   if (vect_print_dump_info (REPORT_DETAILS))
3864     fprintf (vect_dump, "===== analyze_loop_nest_1 =====");
3865
3866   /* Check the CFG characteristics of the loop (nesting, entry/exit, etc.  */
3867
3868   loop_vinfo = vect_analyze_loop_form (loop);
3869   if (!loop_vinfo)
3870     {
3871       if (vect_print_dump_info (REPORT_DETAILS))
3872         fprintf (vect_dump, "bad inner-loop form.");
3873       return NULL;
3874     }
3875
3876   return loop_vinfo;
3877 }
3878
3879
3880 /* Function vect_analyze_loop_form.
3881
3882    Verify that certain CFG restrictions hold, including:
3883    - the loop has a pre-header
3884    - the loop has a single entry and exit
3885    - the loop exit condition is simple enough, and the number of iterations
3886      can be analyzed (a countable loop).  */
3887
3888 static loop_vec_info
3889 vect_analyze_loop_form (struct loop *loop)
3890 {
3891   loop_vec_info loop_vinfo;
3892   tree loop_cond;
3893   tree number_of_iterations = NULL;
3894   loop_vec_info inner_loop_vinfo = NULL;
3895
3896   if (vect_print_dump_info (REPORT_DETAILS))
3897     fprintf (vect_dump, "=== vect_analyze_loop_form ===");
3898
3899   /* Different restrictions apply when we are considering an inner-most loop,
3900      vs. an outer (nested) loop.  
3901      (FORNOW. May want to relax some of these restrictions in the future).  */
3902
3903   if (!loop->inner)
3904     {
3905       /* Inner-most loop.  We currently require that the number of BBs is 
3906          exactly 2 (the header and latch).  Vectorizable inner-most loops 
3907          look like this:
3908
3909                         (pre-header)
3910                            |
3911                           header <--------+
3912                            | |            |
3913                            | +--> latch --+
3914                            |
3915                         (exit-bb)  */
3916
3917       if (loop->num_nodes != 2)
3918         {
3919           if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
3920             fprintf (vect_dump, "not vectorized: too many BBs in loop.");
3921           return NULL;
3922         }
3923
3924       if (empty_block_p (loop->header))
3925     {
3926           if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
3927             fprintf (vect_dump, "not vectorized: empty loop.");
3928       return NULL;
3929     }
3930     }
3931   else
3932     {
3933       struct loop *innerloop = loop->inner;
3934       edge backedge, entryedge;
3935
3936       /* Nested loop. We currently require that the loop is doubly-nested,
3937          contains a single inner loop, and the number of BBs is exactly 5. 
3938          Vectorizable outer-loops look like this:
3939
3940                         (pre-header)
3941                            |
3942                           header <---+
3943                            |         |
3944                           inner-loop |
3945                            |         |
3946                           tail ------+
3947                            | 
3948                         (exit-bb)
3949
3950          The inner-loop has the properties expected of inner-most loops
3951          as described above.  */
3952
3953       if ((loop->inner)->inner || (loop->inner)->next)
3954         {
3955           if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
3956             fprintf (vect_dump, "not vectorized: multiple nested loops.");
3957           return NULL;
3958         }
3959
3960       /* Analyze the inner-loop.  */
3961       inner_loop_vinfo = vect_analyze_loop_1 (loop->inner);
3962       if (!inner_loop_vinfo)
3963         {
3964           if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
3965             fprintf (vect_dump, "not vectorized: Bad inner loop.");
3966           return NULL;
3967         }
3968
3969       if (!expr_invariant_in_loop_p (loop,
3970                                         LOOP_VINFO_NITERS (inner_loop_vinfo)))
3971         {
3972           if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
3973             fprintf (vect_dump,
3974                      "not vectorized: inner-loop count not invariant.");
3975           destroy_loop_vec_info (inner_loop_vinfo, true);
3976           return NULL;
3977         }
3978
3979       if (loop->num_nodes != 5) 
3980         {
3981           if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
3982             fprintf (vect_dump, "not vectorized: too many BBs in loop.");
3983           destroy_loop_vec_info (inner_loop_vinfo, true);
3984           return NULL;
3985         }
3986
3987       gcc_assert (EDGE_COUNT (innerloop->header->preds) == 2);
3988       backedge = EDGE_PRED (innerloop->header, 1);        
3989       entryedge = EDGE_PRED (innerloop->header, 0);
3990       if (EDGE_PRED (innerloop->header, 0)->src == innerloop->latch)
3991         {
3992           backedge = EDGE_PRED (innerloop->header, 0);
3993           entryedge = EDGE_PRED (innerloop->header, 1); 
3994         }
3995         
3996       if (entryedge->src != loop->header
3997           || !single_exit (innerloop)
3998           || single_exit (innerloop)->dest !=  EDGE_PRED (loop->latch, 0)->src)
3999         {
4000           if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
4001             fprintf (vect_dump, "not vectorized: unsupported outerloop form.");
4002           destroy_loop_vec_info (inner_loop_vinfo, true);
4003           return NULL;
4004         }
4005
4006       if (vect_print_dump_info (REPORT_DETAILS))
4007         fprintf (vect_dump, "Considering outer-loop vectorization.");
4008     }
4009   
4010   if (!single_exit (loop) 
4011       || EDGE_COUNT (loop->header->preds) != 2)
4012     {
4013       if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
4014         {
4015           if (!single_exit (loop))
4016             fprintf (vect_dump, "not vectorized: multiple exits.");
4017           else if (EDGE_COUNT (loop->header->preds) != 2)
4018             fprintf (vect_dump, "not vectorized: too many incoming edges.");
4019         }
4020       if (inner_loop_vinfo)
4021         destroy_loop_vec_info (inner_loop_vinfo, true);
4022       return NULL;
4023     }
4024
4025   /* We assume that the loop exit condition is at the end of the loop. i.e,
4026      that the loop is represented as a do-while (with a proper if-guard
4027      before the loop if needed), where the loop header contains all the
4028      executable statements, and the latch is empty.  */
4029   if (!empty_block_p (loop->latch)
4030         || phi_nodes (loop->latch))
4031     {
4032       if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
4033         fprintf (vect_dump, "not vectorized: unexpected loop form.");
4034       if (inner_loop_vinfo)
4035         destroy_loop_vec_info (inner_loop_vinfo, true);
4036       return NULL;
4037     }
4038
4039   /* Make sure there exists a single-predecessor exit bb:  */
4040   if (!single_pred_p (single_exit (loop)->dest))
4041     {
4042       edge e = single_exit (loop);
4043       if (!(e->flags & EDGE_ABNORMAL))
4044         {
4045           split_loop_exit_edge (e);
4046           if (vect_print_dump_info (REPORT_DETAILS))
4047             fprintf (vect_dump, "split exit edge.");
4048         }
4049       else
4050         {
4051           if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
4052             fprintf (vect_dump, "not vectorized: abnormal loop exit edge.");
4053           if (inner_loop_vinfo)
4054             destroy_loop_vec_info (inner_loop_vinfo, true);
4055           return NULL;
4056         }
4057     }
4058
4059   loop_cond = vect_get_loop_niters (loop, &number_of_iterations);
4060   if (!loop_cond)
4061     {
4062       if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
4063         fprintf (vect_dump, "not vectorized: complicated exit condition.");
4064       if (inner_loop_vinfo)
4065         destroy_loop_vec_info (inner_loop_vinfo, true);
4066       return NULL;
4067     }
4068   
4069   if (!number_of_iterations) 
4070     {
4071       if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
4072         fprintf (vect_dump, 
4073                  "not vectorized: number of iterations cannot be computed.");
4074       if (inner_loop_vinfo)
4075         destroy_loop_vec_info (inner_loop_vinfo, true);
4076       return NULL;
4077     }
4078
4079   if (chrec_contains_undetermined (number_of_iterations))
4080     {
4081       if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
4082         fprintf (vect_dump, "Infinite number of iterations.");
4083       if (inner_loop_vinfo)
4084         destroy_loop_vec_info (inner_loop_vinfo, true);
4085       return NULL;
4086     }
4087
4088   if (!NITERS_KNOWN_P (number_of_iterations))
4089     {
4090       if (vect_print_dump_info (REPORT_DETAILS))
4091         {
4092           fprintf (vect_dump, "Symbolic number of iterations is ");
4093           print_generic_expr (vect_dump, number_of_iterations, TDF_DETAILS);
4094         }
4095     }
4096   else if (TREE_INT_CST_LOW (number_of_iterations) == 0)
4097     {
4098       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
4099         fprintf (vect_dump, "not vectorized: number of iterations = 0.");
4100       if (inner_loop_vinfo)
4101         destroy_loop_vec_info (inner_loop_vinfo, false);
4102       return NULL;
4103     }
4104
4105   loop_vinfo = new_loop_vec_info (loop);
4106   LOOP_VINFO_NITERS (loop_vinfo) = number_of_iterations;
4107
4108   STMT_VINFO_TYPE (vinfo_for_stmt (loop_cond)) = loop_exit_ctrl_vec_info_type;
4109
4110   /* CHECKME: May want to keep it around it in the future.  */
4111   if (inner_loop_vinfo)
4112     destroy_loop_vec_info (inner_loop_vinfo, false);
4113
4114   gcc_assert (!loop->aux);
4115   loop->aux = loop_vinfo;
4116   return loop_vinfo;
4117 }
4118
4119
4120 /* Function vect_analyze_loop.
4121
4122    Apply a set of analyses on LOOP, and create a loop_vec_info struct
4123    for it. The different analyses will record information in the
4124    loop_vec_info struct.  */
4125 loop_vec_info
4126 vect_analyze_loop (struct loop *loop)
4127 {
4128   bool ok;
4129   loop_vec_info loop_vinfo;
4130
4131   if (vect_print_dump_info (REPORT_DETAILS))
4132     fprintf (vect_dump, "===== analyze_loop_nest =====");
4133
4134   if (loop_outer (loop) 
4135       && loop_vec_info_for_loop (loop_outer (loop))
4136       && LOOP_VINFO_VECTORIZABLE_P (loop_vec_info_for_loop (loop_outer (loop))))
4137     {
4138       if (vect_print_dump_info (REPORT_DETAILS))
4139         fprintf (vect_dump, "outer-loop already vectorized.");
4140       return NULL;
4141     }
4142
4143   /* Check the CFG characteristics of the loop (nesting, entry/exit, etc.  */
4144
4145   loop_vinfo = vect_analyze_loop_form (loop);
4146   if (!loop_vinfo)
4147     {
4148       if (vect_print_dump_info (REPORT_DETAILS))
4149         fprintf (vect_dump, "bad loop form.");
4150       return NULL;
4151     }
4152
4153   /* Find all data references in the loop (which correspond to vdefs/vuses)
4154      and analyze their evolution in the loop.
4155
4156      FORNOW: Handle only simple, array references, which
4157      alignment can be forced, and aligned pointer-references.  */
4158
4159   ok = vect_analyze_data_refs (loop_vinfo);
4160   if (!ok)
4161     {
4162       if (vect_print_dump_info (REPORT_DETAILS))
4163         fprintf (vect_dump, "bad data references.");
4164       destroy_loop_vec_info (loop_vinfo, true);
4165       return NULL;
4166     }
4167
4168   /* Classify all cross-iteration scalar data-flow cycles.
4169      Cross-iteration cycles caused by virtual phis are analyzed separately.  */
4170
4171   vect_analyze_scalar_cycles (loop_vinfo);
4172
4173   vect_pattern_recog (loop_vinfo);
4174
4175   /* Data-flow analysis to detect stmts that do not need to be vectorized.  */
4176
4177   ok = vect_mark_stmts_to_be_vectorized (loop_vinfo);
4178   if (!ok)
4179     {
4180       if (vect_print_dump_info (REPORT_DETAILS))
4181         fprintf (vect_dump, "unexpected pattern.");
4182       destroy_loop_vec_info (loop_vinfo, true);
4183       return NULL;
4184     }
4185
4186   /* Analyze the alignment of the data-refs in the loop.
4187      Fail if a data reference is found that cannot be vectorized.  */
4188
4189   ok = vect_analyze_data_refs_alignment (loop_vinfo);
4190   if (!ok)
4191     {
4192       if (vect_print_dump_info (REPORT_DETAILS))
4193         fprintf (vect_dump, "bad data alignment.");
4194       destroy_loop_vec_info (loop_vinfo, true);
4195       return NULL;
4196     }
4197
4198   ok = vect_determine_vectorization_factor (loop_vinfo);
4199   if (!ok)
4200     {
4201       if (vect_print_dump_info (REPORT_DETAILS))
4202         fprintf (vect_dump, "can't determine vectorization factor.");
4203       destroy_loop_vec_info (loop_vinfo, true);
4204       return NULL;
4205     }
4206
4207   /* Analyze data dependences between the data-refs in the loop. 
4208      FORNOW: fail at the first data dependence that we encounter.  */
4209
4210   ok = vect_analyze_data_ref_dependences (loop_vinfo);
4211   if (!ok)
4212     {
4213       if (vect_print_dump_info (REPORT_DETAILS))
4214         fprintf (vect_dump, "bad data dependence.");
4215       destroy_loop_vec_info (loop_vinfo, true);
4216       return NULL;
4217     }
4218
4219   /* Analyze the access patterns of the data-refs in the loop (consecutive,
4220      complex, etc.). FORNOW: Only handle consecutive access pattern.  */
4221
4222   ok = vect_analyze_data_ref_accesses (loop_vinfo);
4223   if (!ok)
4224     {
4225       if (vect_print_dump_info (REPORT_DETAILS))
4226         fprintf (vect_dump, "bad data access.");
4227       destroy_loop_vec_info (loop_vinfo, true);
4228       return NULL;
4229     }
4230
4231   /* Check the SLP opportunities in the loop, analyze and build SLP trees.  */
4232   ok = vect_analyze_slp (loop_vinfo);
4233   if (ok)
4234     {
4235       /* Decide which possible SLP instances to SLP.  */
4236       vect_make_slp_decision (loop_vinfo);
4237
4238       /* Find stmts that need to be both vectorized and SLPed.  */
4239       vect_detect_hybrid_slp (loop_vinfo);
4240     }
4241
4242   /* This pass will decide on using loop versioning and/or loop peeling in
4243      order to enhance the alignment of data references in the loop.  */
4244
4245   ok = vect_enhance_data_refs_alignment (loop_vinfo);
4246   if (!ok)
4247     {
4248       if (vect_print_dump_info (REPORT_DETAILS))
4249         fprintf (vect_dump, "bad data alignment.");
4250       destroy_loop_vec_info (loop_vinfo, true);
4251       return NULL;
4252     }
4253
4254   /* Scan all the operations in the loop and make sure they are
4255      vectorizable.  */
4256
4257   ok = vect_analyze_operations (loop_vinfo);
4258   if (!ok)
4259     {
4260       if (vect_print_dump_info (REPORT_DETAILS))
4261         fprintf (vect_dump, "bad operation or unsupported loop bound.");
4262       destroy_loop_vec_info (loop_vinfo, true);
4263       return NULL;
4264     }
4265
4266   LOOP_VINFO_VECTORIZABLE_P (loop_vinfo) = 1;
4267
4268   return loop_vinfo;
4269 }