OSDN Git Service

PR tree-optimization/20501
[pf3gnuchains/gcc-fork.git] / gcc / tree-vect-analyze.c
1 /* Analysis Utilities for Loop Vectorization.
2    Copyright (C) 2003,2004,2005 Free Software Foundation, Inc.
3    Contributed by Dorit Naishlos <dorit@il.ibm.com>
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING.  If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA.  */
21
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "errors.h"
27 #include "ggc.h"
28 #include "tree.h"
29 #include "basic-block.h"
30 #include "diagnostic.h"
31 #include "tree-flow.h"
32 #include "tree-dump.h"
33 #include "timevar.h"
34 #include "cfgloop.h"
35 #include "expr.h"
36 #include "optabs.h"
37 #include "tree-chrec.h"
38 #include "tree-data-ref.h"
39 #include "tree-scalar-evolution.h"
40 #include "tree-vectorizer.h"
41
42 /* Main analysis functions.  */
43 static loop_vec_info vect_analyze_loop_form (struct loop *);
44 static bool vect_analyze_data_refs (loop_vec_info);
45 static bool vect_mark_stmts_to_be_vectorized (loop_vec_info);
46 static bool vect_analyze_scalar_cycles (loop_vec_info);
47 static bool vect_analyze_data_ref_accesses (loop_vec_info);
48 static bool vect_analyze_data_ref_dependences (loop_vec_info);
49 static bool vect_analyze_data_refs_alignment (loop_vec_info);
50 static bool vect_compute_data_refs_alignment (loop_vec_info);
51 static void vect_enhance_data_refs_alignment (loop_vec_info);
52 static bool vect_analyze_operations (loop_vec_info);
53 static bool vect_determine_vectorization_factor (loop_vec_info);
54
55 /* Utility functions for the analyses.  */
56 static bool exist_non_indexing_operands_for_use_p (tree, tree);
57 static void vect_mark_relevant (varray_type *, tree);
58 static bool vect_stmt_relevant_p (tree, loop_vec_info);
59 static tree vect_get_loop_niters (struct loop *, tree *);
60 static bool vect_analyze_data_ref_dependence
61   (struct data_reference *, struct data_reference *, 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 struct data_reference * vect_analyze_pointer_ref_access 
65   (tree, tree, bool, tree, tree *, tree *);
66 static bool vect_can_advance_ivs_p (loop_vec_info);
67 static tree vect_get_ptr_offset (tree, tree, tree *);
68 static bool vect_analyze_offset_expr (tree, struct loop *, tree, tree *, 
69                                       tree *, tree *);
70 static bool vect_base_addr_differ_p (struct data_reference *,
71                                      struct data_reference *drb, bool *);
72 static tree vect_object_analysis (tree, tree, bool, tree, 
73                                   struct data_reference **, tree *, tree *, 
74                                   tree *, bool *, tree *, subvar_t *);
75 static tree vect_address_analysis (tree, tree, bool, tree, 
76                                    struct data_reference *, tree *, tree *, 
77                                    tree *, bool *);
78
79
80 /* Function vect_get_ptr_offset
81
82    Compute the OFFSET modulo vector-type alignment of pointer REF in bits.  */
83
84 static tree 
85 vect_get_ptr_offset (tree ref ATTRIBUTE_UNUSED, 
86                      tree vectype ATTRIBUTE_UNUSED, 
87                      tree *offset ATTRIBUTE_UNUSED)
88 {
89   /* TODO: Use alignment information.  */
90   return NULL_TREE; 
91 }
92
93
94 /* Function vect_analyze_offset_expr
95
96    Given an offset expression EXPR received from get_inner_reference, analyze
97    it and create an expression for INITIAL_OFFSET by substituting the variables 
98    of EXPR with initial_condition of the corresponding access_fn in the loop. 
99    E.g., 
100       for i
101          for (j = 3; j < N; j++)
102             a[j].b[i][j] = 0;
103          
104    For a[j].b[i][j], EXPR will be 'i * C_i + j * C_j + C'. 'i' cannot be 
105    substituted, since its access_fn in the inner loop is i. 'j' will be 
106    substituted with 3. An INITIAL_OFFSET will be 'i * C_i + C`', where
107    C` =  3 * C_j + C.
108
109    Compute MISALIGN (the misalignment of the data reference initial access from
110    its base) if possible. Misalignment can be calculated only if all the
111    variables can be substituted with constants, or if a variable is multiplied
112    by a multiple of VECTYPE_ALIGNMENT. In the above example, since 'i' cannot
113    be substituted, MISALIGN will be NULL_TREE in case that C_i is not a multiple
114    of VECTYPE_ALIGNMENT, and C` otherwise. (We perform MISALIGN modulo 
115    VECTYPE_ALIGNMENT computation in the caller of this function).
116
117    STEP is an evolution of the data reference in this loop in bytes.
118    In the above example, STEP is C_j.
119
120    Return FALSE, if the analysis fails, e.g., there is no access_fn for a 
121    variable. In this case, all the outputs (INITIAL_OFFSET, MISALIGN and STEP) 
122    are NULL_TREEs. Otherwise, return TRUE.
123
124 */
125
126 static bool
127 vect_analyze_offset_expr (tree expr, 
128                           struct loop *loop, 
129                           tree vectype_alignment,
130                           tree *initial_offset,
131                           tree *misalign,
132                           tree *step)
133 {
134   tree oprnd0;
135   tree oprnd1;
136   tree left_offset = ssize_int (0);
137   tree right_offset = ssize_int (0);
138   tree left_misalign = ssize_int (0);
139   tree right_misalign = ssize_int (0);
140   tree left_step = ssize_int (0);
141   tree right_step = ssize_int (0);
142   enum tree_code code;
143   tree init, evolution;
144
145   *step = NULL_TREE;
146   *misalign = NULL_TREE;
147   *initial_offset = NULL_TREE;
148
149   /* Strip conversions that don't narrow the mode.  */
150   expr = vect_strip_conversion (expr);
151   if (!expr)
152     return false;
153
154   /* Stop conditions:
155      1. Constant.  */
156   if (TREE_CODE (expr) == INTEGER_CST)
157     {
158       *initial_offset = fold_convert (ssizetype, expr);
159       *misalign = fold_convert (ssizetype, expr);      
160       *step = ssize_int (0);
161       return true;
162     }
163
164   /* 2. Variable. Try to substitute with initial_condition of the corresponding
165      access_fn in the current loop.  */
166   if (SSA_VAR_P (expr))
167     {
168       tree access_fn = analyze_scalar_evolution (loop, expr);
169
170       if (access_fn == chrec_dont_know)
171         /* No access_fn.  */
172         return false;
173
174       init = initial_condition_in_loop_num (access_fn, loop->num);
175       if (init == expr && !expr_invariant_in_loop_p (loop, init))
176         /* Not enough information: may be not loop invariant.  
177            E.g., for a[b[i]], we get a[D], where D=b[i]. EXPR is D, its 
178            initial_condition is D, but it depends on i - loop's induction
179            variable.  */          
180         return false;
181
182       evolution = evolution_part_in_loop_num (access_fn, loop->num);
183       if (evolution && TREE_CODE (evolution) != INTEGER_CST)
184         /* Evolution is not constant.  */
185         return false;
186
187       if (TREE_CODE (init) == INTEGER_CST)
188         *misalign = fold_convert (ssizetype, init);
189       else
190         /* Not constant, misalignment cannot be calculated.  */
191         *misalign = NULL_TREE;
192
193       *initial_offset = fold_convert (ssizetype, init); 
194
195       *step = evolution ? fold_convert (ssizetype, evolution) : ssize_int (0);
196       return true;      
197     }
198
199   /* Recursive computation.  */
200   if (!BINARY_CLASS_P (expr))
201     {
202       /* We expect to get binary expressions (PLUS/MINUS and MULT).  */
203       if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
204         {
205           fprintf (vect_dump, "Not binary expression ");
206           print_generic_expr (vect_dump, expr, TDF_SLIM);
207         }
208       return false;
209     }
210   oprnd0 = TREE_OPERAND (expr, 0);
211   oprnd1 = TREE_OPERAND (expr, 1);
212
213   if (!vect_analyze_offset_expr (oprnd0, loop, vectype_alignment, &left_offset, 
214                                 &left_misalign, &left_step)
215       || !vect_analyze_offset_expr (oprnd1, loop, vectype_alignment, 
216                                    &right_offset, &right_misalign, &right_step))
217     return false;
218
219   /* The type of the operation: plus, minus or mult.  */
220   code = TREE_CODE (expr);
221   switch (code)
222     {
223     case MULT_EXPR:
224       if (TREE_CODE (right_offset) != INTEGER_CST)
225         /* RIGHT_OFFSET can be not constant. For example, for arrays of variable 
226            sized types. 
227            FORNOW: We don't support such cases.  */
228         return false;
229
230       /* Strip conversions that don't narrow the mode.  */
231       left_offset = vect_strip_conversion (left_offset);      
232       if (!left_offset)
233         return false;      
234       /* Misalignment computation.  */
235       if (SSA_VAR_P (left_offset))
236         {
237           /* If the left side contains variables that can't be substituted with 
238              constants, we check if the right side is a multiple of ALIGNMENT.
239            */
240           if (integer_zerop (size_binop (TRUNC_MOD_EXPR, right_offset, 
241                                   fold_convert (ssizetype, vectype_alignment))))
242             *misalign = ssize_int (0);
243           else
244             /* If the remainder is not zero or the right side isn't constant,
245                we can't compute  misalignment.  */
246             *misalign = NULL_TREE;
247         }
248       else 
249         {
250           /* The left operand was successfully substituted with constant.  */     
251           if (left_misalign)
252             /* In case of EXPR '(i * C1 + j) * C2', LEFT_MISALIGN is 
253                NULL_TREE.  */
254             *misalign  = size_binop (code, left_misalign, right_misalign);
255           else
256             *misalign = NULL_TREE; 
257         }
258
259       /* Step calculation.  */
260       /* Multiply the step by the right operand.  */
261       *step  = size_binop (MULT_EXPR, left_step, right_offset);
262       break;
263    
264     case PLUS_EXPR:
265     case MINUS_EXPR:
266       /* Combine the recursive calculations for step and misalignment.  */
267       *step = size_binop (code, left_step, right_step);
268    
269       if (left_misalign && right_misalign)
270         *misalign  = size_binop (code, left_misalign, right_misalign);
271       else
272         *misalign = NULL_TREE;
273     
274       break;
275
276     default:
277       gcc_unreachable ();
278     }
279
280   /* Compute offset.  */
281   *initial_offset = fold_convert (ssizetype, 
282                                   fold (build2 (code, TREE_TYPE (left_offset), 
283                                                 left_offset, 
284                                                 right_offset)));
285   return true;
286 }
287
288
289 /* Function vect_determine_vectorization_factor
290
291    Determine the vectorization factor (VF). VF is the number of data elements
292    that are operated upon in parallel in a single iteration of the vectorized
293    loop. For example, when vectorizing a loop that operates on 4byte elements,
294    on a target with vector size (VS) 16byte, the VF is set to 4, since 4
295    elements can fit in a single vector register.
296
297    We currently support vectorization of loops in which all types operated upon
298    are of the same size. Therefore this function currently sets VF according to
299    the size of the types operated upon, and fails if there are multiple sizes
300    in the loop.
301
302    VF is also the factor by which the loop iterations are strip-mined, e.g.:
303    original loop:
304         for (i=0; i<N; i++){
305           a[i] = b[i] + c[i];
306         }
307
308    vectorized loop:
309         for (i=0; i<N; i+=VF){
310           a[i:VF] = b[i:VF] + c[i:VF];
311         }
312 */
313
314 static bool
315 vect_determine_vectorization_factor (loop_vec_info loop_vinfo)
316 {
317   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
318   basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
319   int nbbs = loop->num_nodes;
320   block_stmt_iterator si;
321   unsigned int vectorization_factor = 0;
322   int i;
323   tree scalar_type;
324
325   if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
326     fprintf (vect_dump, "=== vect_determine_vectorization_factor ===");
327
328   for (i = 0; i < nbbs; i++)
329     {
330       basic_block bb = bbs[i];
331
332       for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
333         {
334           tree stmt = bsi_stmt (si);
335           unsigned int nunits;
336           stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
337           tree vectype;
338
339           if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
340             {
341               fprintf (vect_dump, "==> examining statement: ");
342               print_generic_expr (vect_dump, stmt, TDF_SLIM);
343             }
344
345           gcc_assert (stmt_info);
346           /* skip stmts which do not need to be vectorized.  */
347           if (!STMT_VINFO_RELEVANT_P (stmt_info))
348             continue;
349
350           if (VECTOR_MODE_P (TYPE_MODE (TREE_TYPE (stmt))))
351             {
352               if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
353                                         LOOP_LOC (loop_vinfo)))
354                 {
355                   fprintf (vect_dump, "not vectorized: vector stmt in loop:");
356                   print_generic_expr (vect_dump, stmt, TDF_SLIM);
357                 }
358               return false;
359             }
360
361           if (STMT_VINFO_DATA_REF (stmt_info))
362             scalar_type = TREE_TYPE (DR_REF (STMT_VINFO_DATA_REF (stmt_info)));
363           else if (TREE_CODE (stmt) == MODIFY_EXPR)
364             scalar_type = TREE_TYPE (TREE_OPERAND (stmt, 0));
365           else
366             scalar_type = TREE_TYPE (stmt);
367
368           if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
369             {
370               fprintf (vect_dump, "get vectype for scalar type:  ");
371               print_generic_expr (vect_dump, scalar_type, TDF_SLIM);
372             }
373
374           vectype = get_vectype_for_scalar_type (scalar_type);
375           if (!vectype)
376             {
377               if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
378                                         LOOP_LOC (loop_vinfo)))
379                 {
380                   fprintf (vect_dump, "not vectorized: unsupported data-type ");
381                   print_generic_expr (vect_dump, scalar_type, TDF_SLIM);
382                 }
383               return false;
384             }
385           if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
386             {
387               fprintf (vect_dump, "vectype: ");
388               print_generic_expr (vect_dump, vectype, TDF_SLIM);
389             }
390           STMT_VINFO_VECTYPE (stmt_info) = vectype;
391
392           nunits = GET_MODE_NUNITS (TYPE_MODE (vectype));
393           if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
394             fprintf (vect_dump, "nunits = %d", nunits);
395
396           if (vectorization_factor)
397             {
398               /* FORNOW: don't allow mixed units. 
399                  This restriction will be relaxed in the future.  */
400               if (nunits != vectorization_factor) 
401                 {
402                   if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
403                                             LOOP_LOC (loop_vinfo)))
404                     fprintf (vect_dump, "not vectorized: mixed data-types");
405                   return false;
406                 }
407             }
408           else
409             vectorization_factor = nunits;
410
411 #ifdef ENABLE_CHECKING
412           gcc_assert (GET_MODE_SIZE (TYPE_MODE (scalar_type))
413                         * vectorization_factor == UNITS_PER_SIMD_WORD);
414 #endif
415         }
416     }
417
418   /* TODO: Analyze cost. Decide if worth while to vectorize.  */
419
420   if (vectorization_factor <= 1)
421     {
422       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
423                                 LOOP_LOC (loop_vinfo)))
424         fprintf (vect_dump, "not vectorized: unsupported data-type");
425       return false;
426     }
427   LOOP_VINFO_VECT_FACTOR (loop_vinfo) = vectorization_factor;
428
429   return true;
430 }
431
432
433 /* Function vect_analyze_operations.
434
435    Scan the loop stmts and make sure they are all vectorizable.  */
436
437 static bool
438 vect_analyze_operations (loop_vec_info loop_vinfo)
439 {
440   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
441   basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
442   int nbbs = loop->num_nodes;
443   block_stmt_iterator si;
444   unsigned int vectorization_factor = 0;
445   int i;
446   bool ok;
447
448   if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
449     fprintf (vect_dump, "=== vect_analyze_operations ===");
450
451   gcc_assert (LOOP_VINFO_VECT_FACTOR (loop_vinfo));
452   vectorization_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
453
454   for (i = 0; i < nbbs; i++)
455     {
456       basic_block bb = bbs[i];
457
458       for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
459         {
460           tree stmt = bsi_stmt (si);
461           stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
462
463           if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
464             {
465               fprintf (vect_dump, "==> examining statement: ");
466               print_generic_expr (vect_dump, stmt, TDF_SLIM);
467             }
468
469           gcc_assert (stmt_info);
470
471           /* skip stmts which do not need to be vectorized.
472              this is expected to include:
473              - the COND_EXPR which is the loop exit condition
474              - any LABEL_EXPRs in the loop
475              - computations that are used only for array indexing or loop
476              control  */
477
478           if (!STMT_VINFO_RELEVANT_P (stmt_info))
479             {
480               if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
481                 fprintf (vect_dump, "irrelevant.");
482               continue;
483             }
484
485 #ifdef ENABLE_CHECKING
486           if (STMT_VINFO_RELEVANT_P (stmt_info))
487             {
488               gcc_assert (!VECTOR_MODE_P (TYPE_MODE (TREE_TYPE (stmt))));
489               gcc_assert (STMT_VINFO_VECTYPE (stmt_info));
490             }
491 #endif
492
493           ok = (vectorizable_operation (stmt, NULL, NULL)
494                 || vectorizable_assignment (stmt, NULL, NULL)
495                 || vectorizable_load (stmt, NULL, NULL)
496                 || vectorizable_store (stmt, NULL, NULL));
497
498           if (!ok)
499             {
500               if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
501                                          LOOP_LOC (loop_vinfo)))
502                 {
503                   fprintf (vect_dump, "not vectorized: stmt not supported: ");
504                   print_generic_expr (vect_dump, stmt, TDF_SLIM);
505                 }
506               return false;
507             }
508         }
509     }
510
511   /* TODO: Analyze cost. Decide if worth while to vectorize.  */
512
513   if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
514       && vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
515     fprintf (vect_dump,
516         "vectorization_factor = %d, niters = " HOST_WIDE_INT_PRINT_DEC,
517         vectorization_factor, LOOP_VINFO_INT_NITERS (loop_vinfo));
518
519   if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
520       && LOOP_VINFO_INT_NITERS (loop_vinfo) < vectorization_factor)
521     {
522       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
523                                  LOOP_LOC (loop_vinfo)))
524         fprintf (vect_dump, "not vectorized: iteration count too small.");
525       return false;
526     }
527
528   if (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
529       || LOOP_VINFO_INT_NITERS (loop_vinfo) % vectorization_factor != 0)
530     {
531       if (vect_print_dump_info (REPORT_DETAILS, LOOP_LOC (loop_vinfo)))
532         fprintf (vect_dump, "epilog loop required.");
533       if (!vect_can_advance_ivs_p (loop_vinfo))
534         {
535           if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
536                                      LOOP_LOC (loop_vinfo)))
537             fprintf (vect_dump,
538                      "not vectorized: can't create epilog loop 1.");
539           return false;
540         }
541       if (!slpeel_can_duplicate_loop_p (loop, loop->single_exit))
542         {
543           if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
544                                      LOOP_LOC (loop_vinfo)))
545             fprintf (vect_dump,
546                      "not vectorized: can't create epilog loop 2.");
547           return false;
548         }
549     }
550
551   return true;
552 }
553
554
555 /* Function exist_non_indexing_operands_for_use_p 
556
557    USE is one of the uses attached to STMT. Check if USE is 
558    used in STMT for anything other than indexing an array.  */
559
560 static bool
561 exist_non_indexing_operands_for_use_p (tree use, tree stmt)
562 {
563   tree operand;
564   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
565  
566   /* USE corresponds to some operand in STMT. If there is no data
567      reference in STMT, then any operand that corresponds to USE
568      is not indexing an array.  */
569   if (!STMT_VINFO_DATA_REF (stmt_info))
570     return true;
571  
572   /* STMT has a data_ref. FORNOW this means that its of one of
573      the following forms:
574      -1- ARRAY_REF = var
575      -2- var = ARRAY_REF
576      (This should have been verified in analyze_data_refs).
577
578      'var' in the second case corresponds to a def, not a use,
579      so USE cannot correspond to any operands that are not used 
580      for array indexing.
581
582      Therefore, all we need to check is if STMT falls into the
583      first case, and whether var corresponds to USE.  */
584  
585   if (TREE_CODE (TREE_OPERAND (stmt, 0)) == SSA_NAME)
586     return false;
587
588   operand = TREE_OPERAND (stmt, 1);
589
590   if (TREE_CODE (operand) != SSA_NAME)
591     return false;
592
593   if (operand == use)
594     return true;
595
596   return false;
597 }
598
599
600 /* Function vect_analyze_scalar_cycles.
601
602    Examine the cross iteration def-use cycles of scalar variables, by
603    analyzing the loop (scalar) PHIs; verify that the cross iteration def-use
604    cycles that they represent do not impede vectorization.
605
606    FORNOW: Reduction as in the following loop, is not supported yet:
607               loop1:
608               for (i=0; i<N; i++)
609                  sum += a[i];
610            The cross-iteration cycle corresponding to variable 'sum' will be
611            considered too complicated and will impede vectorization.
612
613    FORNOW: Induction as in the following loop, is not supported yet:
614               loop2:
615               for (i=0; i<N; i++)
616                  a[i] = i;
617
618            However, the following loop *is* vectorizable:
619               loop3:
620               for (i=0; i<N; i++)
621                  a[i] = b[i];
622
623            In both loops there exists a def-use cycle for the variable i:
624               loop: i_2 = PHI (i_0, i_1)
625                     a[i_2] = ...;
626                     i_1 = i_2 + 1;
627                     GOTO loop;
628
629            The evolution of the above cycle is considered simple enough,
630            however, we also check that the cycle does not need to be
631            vectorized, i.e - we check that the variable that this cycle
632            defines is only used for array indexing or in stmts that do not
633            need to be vectorized. This is not the case in loop2, but it
634            *is* the case in loop3.  */
635
636 static bool
637 vect_analyze_scalar_cycles (loop_vec_info loop_vinfo)
638 {
639   tree phi;
640   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
641   basic_block bb = loop->header;
642   tree dummy;
643
644   if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
645     fprintf (vect_dump, "=== vect_analyze_scalar_cycles ===");
646
647   for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
648     {
649       tree access_fn = NULL;
650
651       if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
652         {
653           fprintf (vect_dump, "Analyze phi: ");
654           print_generic_expr (vect_dump, phi, TDF_SLIM);
655         }
656
657       /* Skip virtual phi's. The data dependences that are associated with
658          virtual defs/uses (i.e., memory accesses) are analyzed elsewhere.  */
659
660       if (!is_gimple_reg (SSA_NAME_VAR (PHI_RESULT (phi))))
661         {
662           if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
663             fprintf (vect_dump, "virtual phi. skip.");
664           continue;
665         }
666
667       /* Analyze the evolution function.  */
668
669       /* FORNOW: The only scalar cross-iteration cycles that we allow are
670          those of loop induction variables; This property is verified here.
671
672          Furthermore, if that induction variable is used in an operation
673          that needs to be vectorized (i.e, is not solely used to index
674          arrays and check the exit condition) - we do not support its
675          vectorization yet. This property is verified in vect_is_simple_use,
676          during vect_analyze_operations.  */
677
678       access_fn = /* instantiate_parameters
679                      (loop,*/
680          analyze_scalar_evolution (loop, PHI_RESULT (phi));
681
682       if (!access_fn)
683         {
684           if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
685                                     LOOP_LOC (loop_vinfo)))
686             fprintf (vect_dump, "not vectorized: unsupported scalar cycle.");
687           return false;
688         }
689
690       if (vect_print_dump_info (REPORT_DETAILS,
691                                 LOOP_LOC (loop_vinfo)))
692         {
693            fprintf (vect_dump, "Access function of PHI: ");
694            print_generic_expr (vect_dump, access_fn, TDF_SLIM);
695         }
696
697       if (!vect_is_simple_iv_evolution (loop->num, access_fn, &dummy, &dummy))
698         {
699           if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
700                                     LOOP_LOC (loop_vinfo)))
701             fprintf (vect_dump, "not vectorized: unsupported scalar cycle.");
702           return false;
703         }
704     }
705
706   return true;
707 }
708
709
710 /* Function vect_base_addr_differ_p.
711
712    This is the simplest data dependence test: determines whether the
713    data references A and B access the same array/region.  Returns
714    false when the property is not computable at compile time.
715    Otherwise return true, and DIFFER_P will record the result. This
716    utility will not be necessary when alias_sets_conflict_p will be
717    less conservative.  */
718
719 static bool
720 vect_base_addr_differ_p (struct data_reference *dra,
721                          struct data_reference *drb,
722                          bool *differ_p)
723 {
724   tree stmt_a = DR_STMT (dra);
725   stmt_vec_info stmt_info_a = vinfo_for_stmt (stmt_a);   
726   tree stmt_b = DR_STMT (drb);
727   stmt_vec_info stmt_info_b = vinfo_for_stmt (stmt_b);   
728   tree addr_a = STMT_VINFO_VECT_DR_BASE_ADDRESS (stmt_info_a);
729   tree addr_b = STMT_VINFO_VECT_DR_BASE_ADDRESS (stmt_info_b);
730   tree type_a = TREE_TYPE (addr_a);
731   tree type_b = TREE_TYPE (addr_b);
732   HOST_WIDE_INT alias_set_a, alias_set_b;
733
734   gcc_assert (POINTER_TYPE_P (type_a) &&  POINTER_TYPE_P (type_b));
735   
736   /* Both references are ADDR_EXPR, i.e., we have the objects.  */
737   if (TREE_CODE (addr_a) == ADDR_EXPR && TREE_CODE (addr_b) == ADDR_EXPR)
738     return array_base_name_differ_p (dra, drb, differ_p);  
739
740   alias_set_a = (TREE_CODE (addr_a) == ADDR_EXPR) ? 
741     get_alias_set (TREE_OPERAND (addr_a, 0)) : get_alias_set (addr_a);
742   alias_set_b = (TREE_CODE (addr_b) == ADDR_EXPR) ? 
743     get_alias_set (TREE_OPERAND (addr_b, 0)) : get_alias_set (addr_b);
744
745   if (!alias_sets_conflict_p (alias_set_a, alias_set_b))
746     {
747       *differ_p = true;
748       return true;
749     }
750   
751   /* An instruction writing through a restricted pointer is "independent" of any 
752      instruction reading or writing through a different pointer, in the same 
753      block/scope.  */
754   else if ((TYPE_RESTRICT (type_a) && !DR_IS_READ (dra))
755       || (TYPE_RESTRICT (type_b) && !DR_IS_READ (drb)))
756     {
757       *differ_p = true;
758       return true;
759     }
760   return false;
761 }
762
763
764 /* Function vect_analyze_data_ref_dependence.
765
766    Return TRUE if there (might) exist a dependence between a memory-reference
767    DRA and a memory-reference DRB.  */
768
769 static bool
770 vect_analyze_data_ref_dependence (struct data_reference *dra,
771                                   struct data_reference *drb, 
772                                   loop_vec_info loop_vinfo)
773 {
774   bool differ_p; 
775   struct data_dependence_relation *ddr;
776   
777   if (!vect_base_addr_differ_p (dra, drb, &differ_p))
778     {
779       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
780                                 LOOP_LOC (loop_vinfo)))
781         {
782           fprintf (vect_dump,
783                 "not vectorized: can't determine dependence between: ");
784           print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
785           fprintf (vect_dump, " and ");
786           print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
787         }
788       return true;
789     }
790
791   if (differ_p)
792     return false;
793
794   ddr = initialize_data_dependence_relation (dra, drb);
795   compute_affine_dependence (ddr);
796
797   if (DDR_ARE_DEPENDENT (ddr) == chrec_known)
798     return false;
799   
800   if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
801                             LOOP_LOC (loop_vinfo)))
802     {
803       fprintf (vect_dump,
804         "not vectorized: possible dependence between data-refs ");
805       print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
806       fprintf (vect_dump, " and ");
807       print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
808     }
809
810   return true;
811 }
812
813
814 /* Function vect_analyze_data_ref_dependences.
815
816    Examine all the data references in the loop, and make sure there do not
817    exist any data dependences between them.
818
819    TODO: dependences which distance is greater than the vectorization factor
820          can be ignored.  */
821
822 static bool
823 vect_analyze_data_ref_dependences (loop_vec_info loop_vinfo)
824 {
825   unsigned int i, j;
826   varray_type loop_write_refs = LOOP_VINFO_DATAREF_WRITES (loop_vinfo);
827   varray_type loop_read_refs = LOOP_VINFO_DATAREF_READS (loop_vinfo);
828
829   /* Examine store-store (output) dependences.  */
830
831   if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
832     fprintf (vect_dump, "=== vect_analyze_dependences ===");
833
834   if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
835     fprintf (vect_dump, "compare all store-store pairs.");
836
837   for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_write_refs); i++)
838     {
839       for (j = i + 1; j < VARRAY_ACTIVE_SIZE (loop_write_refs); j++)
840         {
841           struct data_reference *dra =
842             VARRAY_GENERIC_PTR (loop_write_refs, i);
843           struct data_reference *drb =
844             VARRAY_GENERIC_PTR (loop_write_refs, j);
845           if (vect_analyze_data_ref_dependence (dra, drb, loop_vinfo))
846             return false;
847         }
848     }
849
850   /* Examine load-store (true/anti) dependences.  */
851
852   if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
853     fprintf (vect_dump, "compare all load-store pairs.");
854
855   for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_read_refs); i++)
856     {
857       for (j = 0; j < VARRAY_ACTIVE_SIZE (loop_write_refs); j++)
858         {
859           struct data_reference *dra = VARRAY_GENERIC_PTR (loop_read_refs, i);
860           struct data_reference *drb =
861             VARRAY_GENERIC_PTR (loop_write_refs, j);
862           if (vect_analyze_data_ref_dependence (dra, drb, loop_vinfo))
863             return false;
864         }
865     }
866
867   return true;
868 }
869
870
871 /* Function vect_compute_data_ref_alignment
872
873    Compute the misalignment of the data reference DR.
874
875    Output:
876    1. If during the misalignment computation it is found that the data reference
877       cannot be vectorized then false is returned.
878    2. DR_MISALIGNMENT (DR) is defined.
879
880    FOR NOW: No analysis is actually performed. Misalignment is calculated
881    only for trivial cases. TODO.  */
882
883 static bool
884 vect_compute_data_ref_alignment (struct data_reference *dr)
885 {
886   tree stmt = DR_STMT (dr);
887   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);  
888   tree ref = DR_REF (dr);
889   tree vectype;
890   tree base, alignment;
891   bool base_aligned_p;
892   tree misalign;
893    
894   if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
895     fprintf (vect_dump, "vect_compute_data_ref_alignment:");
896
897   /* Initialize misalignment to unknown.  */
898   DR_MISALIGNMENT (dr) = -1;
899
900   misalign = STMT_VINFO_VECT_MISALIGNMENT (stmt_info);
901   base_aligned_p = STMT_VINFO_VECT_BASE_ALIGNED_P (stmt_info);
902   base = build_fold_indirect_ref (STMT_VINFO_VECT_DR_BASE_ADDRESS (stmt_info));
903   vectype = STMT_VINFO_VECTYPE (stmt_info);
904
905   if (!misalign)
906     {
907       if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC)) 
908         {
909           fprintf (vect_dump, "Unknown alignment for access: ");
910           print_generic_expr (vect_dump, base, TDF_SLIM);
911         }
912       return true;
913     }
914
915   if (!base_aligned_p) 
916     {
917       if (!vect_can_force_dr_alignment_p (base, TYPE_ALIGN (vectype)))
918         {
919           if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
920             {
921               fprintf (vect_dump, "can't force alignment of ref: ");
922               print_generic_expr (vect_dump, ref, TDF_SLIM);
923             }
924           return true;
925         }
926       
927       /* Force the alignment of the decl.
928          NOTE: This is the only change to the code we make during
929          the analysis phase, before deciding to vectorize the loop.  */
930       if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
931         fprintf (vect_dump, "force alignment");
932       DECL_ALIGN (base) = TYPE_ALIGN (vectype);
933       DECL_USER_ALIGN (base) = 1;
934     }
935
936   /* At this point we assume that the base is aligned.  */
937   gcc_assert (base_aligned_p 
938               || (TREE_CODE (base) == VAR_DECL 
939                   && DECL_ALIGN (base) >= TYPE_ALIGN (vectype)));
940
941   /* Alignment required, in bytes:  */
942   alignment = ssize_int (TYPE_ALIGN (vectype)/BITS_PER_UNIT);
943
944   /* Modulo alignment.  */
945   misalign = size_binop (TRUNC_MOD_EXPR, misalign, alignment);
946   if (tree_int_cst_sgn (misalign) < 0)
947     {
948       /* Negative misalignment value.  */
949       if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
950         fprintf (vect_dump, "unexpected misalign value");
951       return false;
952     }
953
954   DR_MISALIGNMENT (dr) = tree_low_cst (misalign, 1);
955
956   if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
957     fprintf (vect_dump, "misalign = %d bytes", DR_MISALIGNMENT (dr));
958
959   return true;
960 }
961
962
963 /* Function vect_compute_data_refs_alignment
964
965    Compute the misalignment of data references in the loop.
966    This pass may take place at function granularity instead of at loop
967    granularity.
968
969    FOR NOW: No analysis is actually performed. Misalignment is calculated
970    only for trivial cases. TODO.  */
971
972 static bool
973 vect_compute_data_refs_alignment (loop_vec_info loop_vinfo)
974 {
975   varray_type loop_write_datarefs = LOOP_VINFO_DATAREF_WRITES (loop_vinfo);
976   varray_type loop_read_datarefs = LOOP_VINFO_DATAREF_READS (loop_vinfo);
977   unsigned int i;
978
979   for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_write_datarefs); i++)
980     {
981       struct data_reference *dr = VARRAY_GENERIC_PTR (loop_write_datarefs, i);
982       if (!vect_compute_data_ref_alignment (dr))
983         return false;
984     }
985
986   for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_read_datarefs); i++)
987     {
988       struct data_reference *dr = VARRAY_GENERIC_PTR (loop_read_datarefs, i);
989       if (!vect_compute_data_ref_alignment (dr))
990         return false;
991     }
992
993   return true;
994 }
995
996
997 /* Function vect_enhance_data_refs_alignment
998
999    This pass will use loop versioning and loop peeling in order to enhance
1000    the alignment of data references in the loop.
1001
1002    FOR NOW: we assume that whatever versioning/peeling takes place, only the
1003    original loop is to be vectorized; Any other loops that are created by
1004    the transformations performed in this pass - are not supposed to be
1005    vectorized. This restriction will be relaxed.  */
1006
1007 static void
1008 vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
1009 {
1010   varray_type loop_read_datarefs = LOOP_VINFO_DATAREF_READS (loop_vinfo);
1011   varray_type loop_write_datarefs = LOOP_VINFO_DATAREF_WRITES (loop_vinfo);
1012   varray_type datarefs;
1013   struct data_reference *dr0 = NULL;
1014   unsigned int i, j;
1015
1016   /* Sigh, a hack to make targets that do not define UNITS_PER_SIMD_WORD
1017      bootstrap.  Copy UNITS_PER_SIMD_WORD to a local variable to avoid a
1018      "division by zero" error.  This error would be issued because we
1019      we do "... % UNITS_PER_SIMD_WORD" below, and UNITS_PER_SIMD_WORD
1020      defaults to 0 if it is not defined by the target.  */
1021   int units_per_simd_word = UNITS_PER_SIMD_WORD;
1022
1023   /*
1024      This pass will require a cost model to guide it whether to apply peeling 
1025      or versioning or a combination of the two. For example, the scheme that
1026      intel uses when given a loop with several memory accesses, is as follows:
1027      choose one memory access ('p') which alignment you want to force by doing 
1028      peeling. Then, either (1) generate a loop in which 'p' is aligned and all 
1029      other accesses are not necessarily aligned, or (2) use loop versioning to 
1030      generate one loop in which all accesses are aligned, and another loop in 
1031      which only 'p' is necessarily aligned. 
1032
1033      ("Automatic Intra-Register Vectorization for the Intel Architecture",
1034       Aart J.C. Bik, Milind Girkar, Paul M. Grey and Ximmin Tian, International
1035       Journal of Parallel Programming, Vol. 30, No. 2, April 2002.)     
1036
1037      Devising a cost model is the most critical aspect of this work. It will 
1038      guide us on which access to peel for, whether to use loop versioning, how 
1039      many versions to create, etc. The cost model will probably consist of 
1040      generic considerations as well as target specific considerations (on 
1041      powerpc for example, misaligned stores are more painful than misaligned 
1042      loads). 
1043
1044      Here is the general steps involved in alignment enhancements:
1045     
1046      -- original loop, before alignment analysis:
1047         for (i=0; i<N; i++){
1048           x = q[i];                     # DR_MISALIGNMENT(q) = unknown
1049           p[i] = y;                     # DR_MISALIGNMENT(p) = unknown
1050         }
1051
1052      -- After vect_compute_data_refs_alignment:
1053         for (i=0; i<N; i++){
1054           x = q[i];                     # DR_MISALIGNMENT(q) = 3
1055           p[i] = y;                     # DR_MISALIGNMENT(p) = unknown
1056         }
1057
1058      -- Possibility 1: we do loop versioning:
1059      if (p is aligned) {
1060         for (i=0; i<N; i++){    # loop 1A
1061           x = q[i];                     # DR_MISALIGNMENT(q) = 3
1062           p[i] = y;                     # DR_MISALIGNMENT(p) = 0
1063         }
1064      } 
1065      else {
1066         for (i=0; i<N; i++){    # loop 1B
1067           x = q[i];                     # DR_MISALIGNMENT(q) = 3
1068           p[i] = y;                     # DR_MISALIGNMENT(p) = unaligned
1069         }
1070      }
1071    
1072      -- Possibility 2: we do loop peeling:
1073      for (i = 0; i < 3; i++){   # (scalar loop, not to be vectorized).
1074         x = q[i];
1075         p[i] = y;
1076      }
1077      for (i = 3; i < N; i++){   # loop 2A
1078         x = q[i];                       # DR_MISALIGNMENT(q) = 0
1079         p[i] = y;                       # DR_MISALIGNMENT(p) = unknown
1080      }
1081
1082      -- Possibility 3: combination of loop peeling and versioning:
1083      for (i = 0; i < 3; i++){   # (scalar loop, not to be vectorized).
1084         x = q[i];
1085         p[i] = y;
1086      }
1087      if (p is aligned) {
1088         for (i = 3; i<N; i++){  # loop 3A
1089           x = q[i];                     # DR_MISALIGNMENT(q) = 0
1090           p[i] = y;                     # DR_MISALIGNMENT(p) = 0
1091         }
1092      } 
1093      else {
1094         for (i = 3; i<N; i++){  # loop 3B
1095           x = q[i];                     # DR_MISALIGNMENT(q) = 0
1096           p[i] = y;                     # DR_MISALIGNMENT(p) = unaligned
1097         }
1098      }
1099
1100      These loops are later passed to loop_transform to be vectorized. The 
1101      vectorizer will use the alignment information to guide the transformation 
1102      (whether to generate regular loads/stores, or with special handling for 
1103      misalignment). 
1104    */
1105
1106   /* (1) Peeling to force alignment.  */
1107
1108   /* (1.1) Decide whether to perform peeling, and how many iterations to peel:
1109      Considerations:
1110      + How many accesses will become aligned due to the peeling
1111      - How many accesses will become unaligned due to the peeling,
1112        and the cost of misaligned accesses.
1113      - The cost of peeling (the extra runtime checks, the increase 
1114        in code size).
1115
1116      The scheme we use FORNOW: peel to force the alignment of the first
1117      misaligned store in the loop.
1118      Rationale: misaligned stores are not yet supported.
1119
1120      TODO: Use a better cost model.  */
1121
1122   for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_write_datarefs); i++)
1123     {
1124       dr0 = VARRAY_GENERIC_PTR (loop_write_datarefs, i);
1125       if (!aligned_access_p (dr0))
1126         {
1127           LOOP_VINFO_UNALIGNED_DR (loop_vinfo) = dr0;
1128           LOOP_PEELING_FOR_ALIGNMENT (loop_vinfo) = DR_MISALIGNMENT (dr0);
1129           break;
1130         }
1131     }
1132
1133   /* (1.2) Update the alignment info according to the peeling factor.
1134            If the misalignment of the DR we peel for is M, then the
1135            peeling factor is VF - M, and the misalignment of each access DR_i
1136            in the loop is DR_MISALIGNMENT (DR_i) + VF - M.
1137            If the misalignment of the DR we peel for is unknown, then the 
1138            misalignment of each access DR_i in the loop is also unknown.
1139
1140            TODO: - consider accesses that are known to have the same
1141                    alignment, even if that alignment is unknown.  */
1142
1143   if (LOOP_PEELING_FOR_ALIGNMENT (loop_vinfo))
1144     {
1145       int mis;
1146       int npeel = 0;
1147
1148       if (known_alignment_for_access_p (dr0))
1149         {
1150           /* Since it's known at compile time, compute the number of iterations
1151              in the peeled loop (the peeling factor) for use in updating
1152              DR_MISALIGNMENT values.  The peeling factor is the vectorization
1153              factor minus the misalignment as an element count.  */
1154           mis = DR_MISALIGNMENT (dr0);
1155           mis /= GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (DR_REF (dr0))));
1156           npeel = LOOP_VINFO_VECT_FACTOR (loop_vinfo) - mis;
1157         }
1158
1159       datarefs = loop_write_datarefs;
1160       for (j = 0; j < 2; j++)
1161         {
1162           for (i = 0; i < VARRAY_ACTIVE_SIZE (datarefs); i++)
1163             {
1164               struct data_reference *dr = VARRAY_GENERIC_PTR (datarefs, i);
1165
1166               if (dr == dr0)
1167                 continue;
1168               if (known_alignment_for_access_p (dr)
1169                   && DR_MISALIGNMENT (dr) == DR_MISALIGNMENT (dr0))
1170                 DR_MISALIGNMENT (dr) = 0;
1171               else if (known_alignment_for_access_p (dr)
1172                        && known_alignment_for_access_p (dr0))
1173                 {
1174                   int drsize = GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (DR_REF (dr))));
1175
1176                   DR_MISALIGNMENT (dr) += npeel * drsize;
1177                   DR_MISALIGNMENT (dr) %= units_per_simd_word;
1178                 }
1179               else
1180                 DR_MISALIGNMENT (dr) = -1;
1181             }
1182           datarefs = loop_read_datarefs;
1183         }
1184
1185       DR_MISALIGNMENT (dr0) = 0;
1186     }
1187 }
1188
1189
1190 /* Function vect_analyze_data_refs_alignment
1191
1192    Analyze the alignment of the data-references in the loop.
1193    FOR NOW: Until support for misliagned accesses is in place, only if all
1194    accesses are aligned can the loop be vectorized. This restriction will be 
1195    relaxed.  */ 
1196
1197 static bool
1198 vect_analyze_data_refs_alignment (loop_vec_info loop_vinfo)
1199 {
1200   varray_type loop_read_datarefs = LOOP_VINFO_DATAREF_READS (loop_vinfo);
1201   varray_type loop_write_datarefs = LOOP_VINFO_DATAREF_WRITES (loop_vinfo);
1202   enum dr_alignment_support supportable_dr_alignment;
1203   unsigned int i;
1204
1205   if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
1206     fprintf (vect_dump, "=== vect_analyze_data_refs_alignment ===");
1207
1208
1209   /* This pass may take place at function granularity instead of at loop
1210      granularity.  */
1211
1212   if (!vect_compute_data_refs_alignment (loop_vinfo))
1213     {
1214       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
1215                                 LOOP_LOC (loop_vinfo)))
1216         fprintf (vect_dump, 
1217                  "not vectorized: can't calculate alignment for data ref.");
1218       return false;
1219     }
1220
1221
1222   /* This pass will decide on using loop versioning and/or loop peeling in 
1223      order to enhance the alignment of data references in the loop.  */
1224
1225   vect_enhance_data_refs_alignment (loop_vinfo);
1226
1227
1228   /* Finally, check that all the data references in the loop can be
1229      handled with respect to their alignment.  */
1230
1231   for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_read_datarefs); i++)
1232     {
1233       struct data_reference *dr = VARRAY_GENERIC_PTR (loop_read_datarefs, i);
1234       supportable_dr_alignment = vect_supportable_dr_alignment (dr);
1235       if (!supportable_dr_alignment)
1236         {
1237           if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
1238                                     LOOP_LOC (loop_vinfo)))
1239             fprintf (vect_dump, "not vectorized: unsupported unaligned load.");
1240           return false;
1241         }
1242       if (supportable_dr_alignment != dr_aligned 
1243           && (vect_print_dump_info (REPORT_ALIGNMENT, LOOP_LOC (loop_vinfo))))
1244         fprintf (vect_dump, "Vectorizing an unaligned access.");
1245     }
1246   for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_write_datarefs); i++)
1247     {
1248       struct data_reference *dr = VARRAY_GENERIC_PTR (loop_write_datarefs, i);
1249       supportable_dr_alignment = vect_supportable_dr_alignment (dr);
1250       if (!supportable_dr_alignment)
1251         {
1252           if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
1253                                     LOOP_LOC (loop_vinfo)))
1254             fprintf (vect_dump, "not vectorized: unsupported unaligned store.");
1255           return false;
1256         }
1257       if (supportable_dr_alignment != dr_aligned 
1258           && (vect_print_dump_info (REPORT_ALIGNMENT, LOOP_LOC (loop_vinfo))))
1259         fprintf (vect_dump, "Vectorizing an unaligned access.");
1260     }
1261   if (LOOP_VINFO_UNALIGNED_DR (loop_vinfo)
1262       && vect_print_dump_info (REPORT_ALIGNMENT, LOOP_LOC (loop_vinfo)))
1263     fprintf (vect_dump, "Alignment of access forced using peeling.");
1264
1265   return true;
1266 }
1267
1268
1269 /* Function vect_analyze_data_ref_access.
1270
1271    Analyze the access pattern of the data-reference DR. For now, a data access
1272    has to consecutive to be considered vectorizable.  */
1273
1274 static bool
1275 vect_analyze_data_ref_access (struct data_reference *dr)
1276 {
1277   tree stmt = DR_STMT (dr);
1278   stmt_vec_info stmt_info = vinfo_for_stmt (stmt); 
1279   tree step = STMT_VINFO_VECT_STEP (stmt_info);
1280   tree scalar_type = TREE_TYPE (DR_REF (dr));
1281
1282   if (!step || tree_int_cst_compare (step, TYPE_SIZE_UNIT (scalar_type)))
1283     {
1284       if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
1285         fprintf (vect_dump, "not consecutive access");
1286       return false;
1287     }
1288   return true;
1289 }
1290
1291
1292 /* Function vect_analyze_data_ref_accesses.
1293
1294    Analyze the access pattern of all the data references in the loop.
1295
1296    FORNOW: the only access pattern that is considered vectorizable is a
1297            simple step 1 (consecutive) access.
1298
1299    FORNOW: handle only arrays and pointer accesses.  */
1300
1301 static bool
1302 vect_analyze_data_ref_accesses (loop_vec_info loop_vinfo)
1303 {
1304   unsigned int i;
1305   varray_type loop_write_datarefs = LOOP_VINFO_DATAREF_WRITES (loop_vinfo);
1306   varray_type loop_read_datarefs = LOOP_VINFO_DATAREF_READS (loop_vinfo);
1307
1308   if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
1309     fprintf (vect_dump, "=== vect_analyze_data_ref_accesses ===");
1310
1311   for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_write_datarefs); i++)
1312     {
1313       struct data_reference *dr = VARRAY_GENERIC_PTR (loop_write_datarefs, i);
1314       bool ok = vect_analyze_data_ref_access (dr);
1315       if (!ok)
1316         {
1317           if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
1318                                       LOOP_LOC (loop_vinfo)))
1319             fprintf (vect_dump, "not vectorized: complicated access pattern.");
1320           return false;
1321         }
1322     }
1323
1324   for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_read_datarefs); i++)
1325     {
1326       struct data_reference *dr = VARRAY_GENERIC_PTR (loop_read_datarefs, i);
1327       bool ok = vect_analyze_data_ref_access (dr);
1328       if (!ok)
1329         {
1330           if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
1331                                     LOOP_LOC (loop_vinfo)))
1332             fprintf (vect_dump, "not vectorized: complicated access pattern.");
1333           return false;
1334         }
1335     }
1336
1337   return true;
1338 }
1339
1340
1341 /* Function vect_analyze_pointer_ref_access.
1342
1343    Input:
1344    STMT - a stmt that contains a data-ref.
1345    MEMREF - a data-ref in STMT, which is an INDIRECT_REF.
1346    ACCESS_FN - the access function of MEMREF.
1347
1348    Output:
1349    If the data-ref access is vectorizable, return a data_reference structure
1350    that represents it (DR). Otherwise - return NULL.  
1351    STEP - the stride of MEMREF in the loop.
1352    INIT - the initial condition of MEMREF in the loop.
1353 */
1354
1355 static struct data_reference *
1356 vect_analyze_pointer_ref_access (tree memref, tree stmt, bool is_read, 
1357                                  tree access_fn, tree *ptr_init, tree *ptr_step)
1358 {
1359   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
1360   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
1361   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
1362   tree step, init;      
1363   tree reftype, innertype;
1364   tree indx_access_fn; 
1365   int loopnum = loop->num;
1366   struct data_reference *dr;
1367
1368   if (!vect_is_simple_iv_evolution (loopnum, access_fn, &init, &step))
1369     {
1370       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS, 
1371                                 LOOP_LOC (loop_vinfo))) 
1372         fprintf (vect_dump, "not vectorized: pointer access is not simple.");   
1373       return NULL;
1374     }
1375
1376   STRIP_NOPS (init);
1377
1378   if (!expr_invariant_in_loop_p (loop, init))
1379     {
1380       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
1381                                 LOOP_LOC (loop_vinfo))) 
1382         fprintf (vect_dump, 
1383                  "not vectorized: initial condition is not loop invariant.");   
1384       return NULL;
1385     }
1386
1387   if (TREE_CODE (step) != INTEGER_CST)
1388     {
1389       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
1390                                 LOOP_LOC (loop_vinfo))) 
1391         fprintf (vect_dump, 
1392                 "not vectorized: non constant step for pointer access.");       
1393       return NULL;
1394     }
1395
1396   reftype = TREE_TYPE (TREE_OPERAND (memref, 0));
1397   if (!POINTER_TYPE_P (reftype)) 
1398     {
1399       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
1400                                 LOOP_LOC (loop_vinfo)))
1401         fprintf (vect_dump, "not vectorized: unexpected pointer access form."); 
1402       return NULL;
1403     }
1404
1405   if (!POINTER_TYPE_P (TREE_TYPE (init))) 
1406     {
1407       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
1408                                 LOOP_LOC (loop_vinfo))) 
1409         fprintf (vect_dump, "not vectorized: unexpected pointer access form.");
1410       return NULL;
1411     }
1412
1413   *ptr_step = fold_convert (ssizetype, step);
1414   innertype = TREE_TYPE (reftype);
1415   if (!COMPLETE_TYPE_P (innertype))
1416     {
1417       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
1418                               LOOP_LOC (loop_vinfo)))
1419       fprintf (vect_dump, "not vectorized: pointer to incomplete type.");
1420       return NULL;
1421     }
1422    
1423   /* Check that STEP is a multiple of type size.  */
1424   if (!integer_zerop (size_binop (TRUNC_MOD_EXPR, *ptr_step, 
1425                         fold_convert (ssizetype, TYPE_SIZE_UNIT (innertype)))))
1426     {
1427       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
1428                                 LOOP_LOC (loop_vinfo))) 
1429         fprintf (vect_dump, "not vectorized: non consecutive access."); 
1430       return NULL;
1431     }
1432    
1433   indx_access_fn = 
1434         build_polynomial_chrec (loopnum, integer_zero_node, integer_one_node);
1435   if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
1436     {
1437       fprintf (vect_dump, "Access function of ptr indx: ");
1438       print_generic_expr (vect_dump, indx_access_fn, TDF_SLIM);
1439     }
1440   dr = init_data_ref (stmt, memref, NULL_TREE, indx_access_fn, is_read);
1441   *ptr_init = init;
1442   return dr;
1443 }
1444
1445
1446 /* Function vect_address_analysis
1447
1448    Return the BASE of the address expression EXPR.
1449    Also compute the INITIAL_OFFSET from BASE, MISALIGN and STEP.
1450
1451    Input:
1452    EXPR - the address expression that is being analyzed
1453    STMT - the statement that contains EXPR or its original memory reference
1454    IS_READ - TRUE if STMT reads from EXPR, FALSE if writes to EXPR
1455    VECTYPE - the type that defines the alignment (i.e, we compute
1456              alignment relative to TYPE_ALIGN(VECTYPE))
1457    DR - data_reference struct for the original memory reference
1458
1459    Output:
1460    BASE (returned value) - the base of the data reference EXPR.
1461    INITIAL_OFFSET - initial offset of EXPR from BASE (an expression)
1462    MISALIGN - offset of EXPR from BASE in bytes (a constant) or NULL_TREE if the
1463               computation is impossible
1464    STEP - evolution of EXPR in the loop
1465    BASE_ALIGNED - indicates if BASE is aligned
1466  
1467    If something unexpected is encountered (an unsupported form of data-ref),
1468    then NULL_TREE is returned.  
1469  */
1470
1471 static tree
1472 vect_address_analysis (tree expr, tree stmt, bool is_read, tree vectype, 
1473                        struct data_reference *dr, tree *offset, tree *misalign,
1474                        tree *step, bool *base_aligned)
1475 {
1476   tree oprnd0, oprnd1, base_address, offset_expr, base_addr0, base_addr1;
1477   tree address_offset = ssize_int (0), address_misalign = ssize_int (0);
1478   tree dummy;
1479   subvar_t dummy2;
1480
1481   switch (TREE_CODE (expr))
1482     {
1483     case PLUS_EXPR:
1484     case MINUS_EXPR:
1485       /* EXPR is of form {base +/- offset} (or {offset +/- base}).  */
1486       oprnd0 = TREE_OPERAND (expr, 0);
1487       oprnd1 = TREE_OPERAND (expr, 1);
1488
1489       STRIP_NOPS (oprnd0);
1490       STRIP_NOPS (oprnd1);
1491       
1492       /* Recursively try to find the base of the address contained in EXPR.
1493          For offset, the returned base will be NULL.  */
1494       base_addr0 = vect_address_analysis (oprnd0, stmt, is_read, vectype, dr, 
1495                                      &address_offset, &address_misalign, step, 
1496                                      base_aligned);
1497
1498       base_addr1 = vect_address_analysis (oprnd1, stmt, is_read, vectype, dr, 
1499                                      &address_offset, &address_misalign, step, 
1500                                      base_aligned);
1501
1502       /* We support cases where only one of the operands contains an 
1503          address.  */
1504       if ((base_addr0 && base_addr1) || (!base_addr0 && !base_addr1))
1505         return NULL_TREE;
1506
1507       /* To revert STRIP_NOPS.  */
1508       oprnd0 = TREE_OPERAND (expr, 0);
1509       oprnd1 = TREE_OPERAND (expr, 1);
1510       
1511       offset_expr = base_addr0 ? 
1512         fold_convert (ssizetype, oprnd1) : fold_convert (ssizetype, oprnd0);
1513
1514       /* EXPR is of form {base +/- offset} (or {offset +/- base}). If offset is 
1515          a number, we can add it to the misalignment value calculated for base,
1516          otherwise, misalignment is NULL.  */
1517       if (TREE_CODE (offset_expr) == INTEGER_CST && address_misalign)
1518         *misalign = size_binop (TREE_CODE (expr), address_misalign, 
1519                                 offset_expr);
1520       else
1521         *misalign = NULL_TREE;
1522
1523       /* Combine offset (from EXPR {base + offset}) with the offset calculated
1524          for base.  */
1525       *offset = size_binop (TREE_CODE (expr), address_offset, offset_expr);
1526       return base_addr0 ? base_addr0 : base_addr1;
1527
1528     case ADDR_EXPR:
1529       base_address = vect_object_analysis (TREE_OPERAND (expr, 0), stmt,
1530                                            is_read, vectype, &dr, offset, 
1531                                            misalign, step, base_aligned, 
1532                                            &dummy, &dummy2);
1533       return base_address;
1534
1535     case SSA_NAME:
1536       if (!POINTER_TYPE_P (TREE_TYPE (expr)))
1537         return NULL_TREE;
1538
1539       if (TYPE_ALIGN (TREE_TYPE (TREE_TYPE (expr))) < TYPE_ALIGN (vectype)) 
1540         {
1541           if (vect_get_ptr_offset (expr, vectype, misalign))
1542             *base_aligned = true;         
1543           else
1544             *base_aligned = false;
1545         }
1546       else
1547         {         
1548           *base_aligned = true;
1549           *misalign = ssize_int (0);
1550         }
1551       *offset = ssize_int (0);
1552       *step = ssize_int (0);
1553       return expr;
1554       
1555     default:
1556       return NULL_TREE;
1557     }
1558 }
1559
1560
1561 /* Function vect_object_analysis
1562
1563    Return the BASE of the data reference MEMREF.
1564    Also compute the INITIAL_OFFSET from BASE, MISALIGN and STEP.
1565    E.g., for EXPR a.b[i] + 4B, BASE is a, and OFFSET is the overall offset  
1566    'a.b[i] + 4B' from a (can be an expression), MISALIGN is an OFFSET 
1567    instantiated with initial_conditions of access_functions of variables, 
1568    modulo alignment, and STEP is the evolution of the DR_REF in this loop.
1569
1570    Function get_inner_reference is used for the above in case of ARRAY_REF and
1571    COMPONENT_REF.
1572
1573    The structure of the function is as follows:
1574    Part 1:
1575    Case 1. For handled_component_p refs 
1576           1.1 call get_inner_reference
1577             1.1.1 analyze offset expr received from get_inner_reference
1578           1.2. build data-reference structure for MEMREF
1579         (fall through with BASE)
1580    Case 2. For declarations 
1581           2.1 check alignment
1582           2.2 update DR_BASE_NAME if necessary for alias
1583    Case 3. For INDIRECT_REFs 
1584           3.1 get the access function
1585           3.2 analyze evolution of MEMREF
1586           3.3 set data-reference structure for MEMREF
1587           3.4 call vect_address_analysis to analyze INIT of the access function
1588
1589    Part 2:
1590    Combine the results of object and address analysis to calculate 
1591    INITIAL_OFFSET, STEP and misalignment info.   
1592
1593    Input:
1594    MEMREF - the memory reference that is being analyzed
1595    STMT - the statement that contains MEMREF
1596    IS_READ - TRUE if STMT reads from MEMREF, FALSE if writes to MEMREF
1597    VECTYPE - the type that defines the alignment (i.e, we compute
1598              alignment relative to TYPE_ALIGN(VECTYPE))
1599    
1600    Output:
1601    BASE_ADDRESS (returned value) - the base address of the data reference MEMREF
1602                                    E.g, if MEMREF is a.b[k].c[i][j] the returned
1603                                    base is &a.
1604    DR - data_reference struct for MEMREF
1605    INITIAL_OFFSET - initial offset of MEMREF from BASE (an expression)
1606    MISALIGN - offset of MEMREF from BASE in bytes (a constant) or NULL_TREE if 
1607               the computation is impossible
1608    STEP - evolution of the DR_REF in the loop
1609    BASE_ALIGNED - indicates if BASE is aligned
1610    MEMTAG - memory tag for aliasing purposes
1611    SUBVAR - Sub-variables of the variable
1612  
1613    If something unexpected is encountered (an unsupported form of data-ref),
1614    then NULL_TREE is returned.  */
1615
1616 static tree
1617 vect_object_analysis (tree memref, tree stmt, bool is_read,
1618                       tree vectype, struct data_reference **dr,
1619                       tree *offset, tree *misalign, tree *step,
1620                       bool *base_aligned, tree *memtag,
1621                       subvar_t *subvars)
1622 {
1623   tree base = NULL_TREE, base_address = NULL_TREE;
1624   tree object_offset = ssize_int (0), object_misalign = ssize_int (0);
1625   tree object_step = ssize_int (0), address_step = ssize_int (0);
1626   bool object_base_aligned = true, address_base_aligned = true;
1627   tree address_offset = ssize_int (0), address_misalign = ssize_int (0);
1628   HOST_WIDE_INT pbitsize, pbitpos;
1629   tree poffset, bit_pos_in_bytes;
1630   enum machine_mode pmode;
1631   int punsignedp, pvolatilep;
1632   tree ptr_step = ssize_int (0), ptr_init = NULL_TREE;
1633   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
1634   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
1635   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
1636   struct data_reference *ptr_dr = NULL;
1637   tree access_fn, evolution_part, address_to_analyze;
1638    
1639   /* Part 1: */
1640   /* Case 1. handled_component_p refs.  */
1641   if (handled_component_p (memref))
1642     {
1643       /* 1.1 call get_inner_reference.  */
1644       /* Find the base and the offset from it.  */
1645       base = get_inner_reference (memref, &pbitsize, &pbitpos, &poffset,
1646                                   &pmode, &punsignedp, &pvolatilep, false);
1647       if (!base)
1648         return NULL_TREE;
1649
1650       /* 1.1.1 analyze offset expr received from get_inner_reference.  */
1651       if (poffset 
1652           && !vect_analyze_offset_expr (poffset, loop, TYPE_SIZE_UNIT (vectype), 
1653                                 &object_offset, &object_misalign, &object_step))
1654         {
1655           if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
1656             {
1657               fprintf (vect_dump, "failed to compute offset or step for ");
1658               print_generic_expr (vect_dump, memref, TDF_SLIM);
1659             }
1660           return NULL_TREE;
1661         }
1662
1663       /* Add bit position to OFFSET and MISALIGN.  */
1664
1665       bit_pos_in_bytes = ssize_int (pbitpos/BITS_PER_UNIT);
1666       /* Check that there is no remainder in bits.  */
1667       if (pbitpos%BITS_PER_UNIT)
1668         {
1669           if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
1670             fprintf (vect_dump, "bit offset alignment.");
1671           return NULL_TREE;
1672         }
1673       object_offset = size_binop (PLUS_EXPR, bit_pos_in_bytes, object_offset);     
1674       if (object_misalign) 
1675         object_misalign = size_binop (PLUS_EXPR, object_misalign, 
1676                                       bit_pos_in_bytes); 
1677
1678       /* Create data-reference for MEMREF. TODO: handle COMPONENT_REFs.  */
1679       if (!(*dr))
1680         { 
1681           if (TREE_CODE (memref) == ARRAY_REF)
1682             *dr = analyze_array (stmt, memref, is_read);
1683           else
1684             /* FORNOW.  */
1685             return NULL_TREE;
1686         }
1687       memref = base; /* To continue analysis of BASE.  */
1688       /* fall through  */
1689     }
1690   
1691   /*  Part 1: Case 2. Declarations.  */ 
1692   if (DECL_P (memref))
1693     {
1694       /* We expect to get a decl only if we already have a DR.  */
1695       if (!(*dr))
1696         {
1697           if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
1698             {
1699               fprintf (vect_dump, "unhandled decl ");
1700               print_generic_expr (vect_dump, memref, TDF_SLIM);
1701             }
1702           return NULL_TREE;
1703         }
1704
1705       /* 2.1 check the alignment.  */
1706       if (DECL_ALIGN (memref) >= TYPE_ALIGN (vectype))
1707         object_base_aligned = true;
1708       else
1709         object_base_aligned = false;
1710
1711       /* 2.2 update DR_BASE_NAME if necessary.  */
1712       if (!DR_BASE_NAME ((*dr)))
1713         /* For alias analysis.  In case the analysis of INDIRECT_REF brought 
1714            us to object.  */
1715         DR_BASE_NAME ((*dr)) = memref;
1716
1717       if (SSA_VAR_P (memref) && var_can_have_subvars (memref))  
1718         *subvars = get_subvars_for_var (memref);
1719       base_address = build_fold_addr_expr (memref);
1720       *memtag = memref;
1721     }
1722
1723   /* Part 1:  Case 3. INDIRECT_REFs.  */
1724   else if (TREE_CODE (memref) == INDIRECT_REF)
1725     {      
1726       /* 3.1 get the access function.  */
1727       access_fn = analyze_scalar_evolution (loop, TREE_OPERAND (memref, 0));
1728       if (!access_fn)
1729         {
1730           if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
1731                                     LOOP_LOC (loop_vinfo)))
1732             fprintf (vect_dump, "not vectorized: complicated pointer access."); 
1733           return NULL_TREE;
1734         }
1735       if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
1736         {
1737           fprintf (vect_dump, "Access function of ptr: ");
1738           print_generic_expr (vect_dump, access_fn, TDF_SLIM);
1739         }
1740
1741       /* 3.2 analyze evolution of MEMREF.  */
1742       evolution_part = evolution_part_in_loop_num (access_fn, loop->num);
1743       if (evolution_part)
1744         {
1745           ptr_dr = vect_analyze_pointer_ref_access (memref, stmt, is_read, 
1746                                          access_fn, &ptr_init, &ptr_step);
1747           if (!(ptr_dr))
1748             return NULL_TREE; 
1749           
1750           object_step = size_binop (PLUS_EXPR, object_step, ptr_step);
1751           address_to_analyze = ptr_init;
1752         }
1753       else
1754         {
1755           if (!(*dr))
1756             {
1757               if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
1758                                         LOOP_LOC (loop_vinfo))) 
1759                 fprintf (vect_dump, "not vectorized: ptr is loop invariant.");  
1760               return NULL_TREE;
1761             }
1762           /* Since there exists DR for MEMREF, we are analyzing the init of 
1763              the access function, which not necessary has evolution in the 
1764              loop.  */
1765           address_to_analyze = initial_condition_in_loop_num (access_fn,
1766                                                               loop->num);
1767         }
1768       
1769       /* 3.3 set data-reference structure for MEMREF.  */
1770       *dr = (*dr) ? *dr : ptr_dr;
1771
1772       /* 3.4 call vect_address_analysis to analyze INIT of the access 
1773          function.  */
1774       base_address = vect_address_analysis (address_to_analyze, stmt, is_read, 
1775                                vectype, *dr, &address_offset, &address_misalign, 
1776                                &address_step, &address_base_aligned);
1777       if (!base_address)
1778         return NULL_TREE;
1779
1780       switch (TREE_CODE (base_address))
1781         {
1782         case SSA_NAME:
1783           *memtag = get_var_ann (SSA_NAME_VAR (base_address))->type_mem_tag;
1784           if (!(*memtag) && TREE_CODE (TREE_OPERAND (memref, 0)) == SSA_NAME)
1785             *memtag = get_var_ann (
1786                       SSA_NAME_VAR (TREE_OPERAND (memref, 0)))->type_mem_tag;
1787           break;
1788         case ADDR_EXPR:
1789           *memtag = TREE_OPERAND (base_address, 0);
1790           break;
1791         default:
1792           if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
1793                                     LOOP_LOC (loop_vinfo)))
1794             {
1795               fprintf (vect_dump, "not vectorized: no memtag ref: "); 
1796               print_generic_expr (vect_dump, memref, TDF_SLIM);
1797             }
1798           return NULL_TREE;
1799         }
1800     }
1801             
1802   if (!base_address)
1803     /* MEMREF cannot be analyzed.  */
1804     return NULL_TREE;
1805
1806   if (SSA_VAR_P (*memtag) && var_can_have_subvars (*memtag))
1807     *subvars = get_subvars_for_var (*memtag);
1808
1809   /* Part 2: Combine the results of object and address analysis to calculate 
1810      INITIAL_OFFSET, STEP and misalignment info.  */
1811   *offset = size_binop (PLUS_EXPR, object_offset, address_offset);
1812   if (object_misalign && address_misalign)
1813     *misalign = size_binop (PLUS_EXPR, object_misalign, address_misalign);
1814   else
1815     *misalign = NULL_TREE;
1816   *step = size_binop (PLUS_EXPR, object_step, address_step); 
1817   *base_aligned = object_base_aligned && address_base_aligned;
1818
1819   if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
1820     {
1821       fprintf (vect_dump, "Results of object analysis for: ");
1822       print_generic_expr (vect_dump, memref, TDF_SLIM);
1823       fprintf (vect_dump, "\n\tbase_address: ");
1824       print_generic_expr (vect_dump, base_address, TDF_SLIM);
1825       fprintf (vect_dump, "\n\toffset: ");
1826       print_generic_expr (vect_dump, *offset, TDF_SLIM);
1827       fprintf (vect_dump, "\n\tstep: ");
1828       print_generic_expr (vect_dump, *step, TDF_SLIM);
1829       fprintf (vect_dump, "\n\tbase aligned %d\n\tmisalign: ", *base_aligned);
1830       print_generic_expr (vect_dump, *misalign, TDF_SLIM);
1831     }
1832   return base_address;
1833 }
1834
1835
1836 /* Function vect_analyze_data_refs.
1837
1838    Find all the data references in the loop.
1839
1840    The general structure of the analysis of data refs in the vectorizer is as 
1841    follows:
1842    1- vect_analyze_data_refs(loop): 
1843       Find and analyze all data-refs in the loop:
1844           foreach ref
1845              base_address = vect_object_analysis(ref)
1846       1.1- vect_object_analysis(ref): 
1847            Analyze ref, and build a DR (data_referece struct) for it;
1848            compute base, initial_offset, step and alignment. 
1849            Call get_inner_reference for refs handled in this function.
1850            Call vect_addr_analysis(addr) to analyze pointer type expressions.
1851       Set ref_stmt.base, ref_stmt.initial_offset, ref_stmt.alignment,  
1852       ref_stmt.memtag and ref_stmt.step accordingly. 
1853    2- vect_analyze_dependences(): apply dependence testing using ref_stmt.DR
1854    3- vect_analyze_drs_alignment(): check that ref_stmt.alignment is ok.
1855    4- vect_analyze_drs_access(): check that ref_stmt.step is ok.
1856
1857    FORNOW: Handle aligned INDIRECT_REFs and ARRAY_REFs 
1858            which base is really an array (not a pointer) and which alignment 
1859            can be forced. This restriction will be relaxed.  */
1860
1861 static bool
1862 vect_analyze_data_refs (loop_vec_info loop_vinfo)
1863 {
1864   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
1865   basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
1866   int nbbs = loop->num_nodes;
1867   block_stmt_iterator si;
1868   int j;
1869   struct data_reference *dr;
1870
1871   if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
1872     fprintf (vect_dump, "=== vect_analyze_data_refs ===");
1873
1874   for (j = 0; j < nbbs; j++)
1875     {
1876       basic_block bb = bbs[j];
1877       for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
1878         {
1879           bool is_read = false;
1880           tree stmt = bsi_stmt (si);
1881           stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
1882           v_may_def_optype v_may_defs = STMT_V_MAY_DEF_OPS (stmt);
1883           v_must_def_optype v_must_defs = STMT_V_MUST_DEF_OPS (stmt);
1884           vuse_optype vuses = STMT_VUSE_OPS (stmt);
1885           varray_type *datarefs = NULL;
1886           int nvuses, nv_may_defs, nv_must_defs;
1887           tree memref = NULL;
1888           tree scalar_type, vectype;      
1889           tree base, offset, misalign, step, tag;
1890           bool base_aligned;
1891           subvar_t subvars = NULL;
1892
1893           /* Assumption: there exists a data-ref in stmt, if and only if 
1894              it has vuses/vdefs.  */
1895
1896           if (!vuses && !v_may_defs && !v_must_defs)
1897             continue;
1898
1899           nvuses = NUM_VUSES (vuses);
1900           nv_may_defs = NUM_V_MAY_DEFS (v_may_defs);
1901           nv_must_defs = NUM_V_MUST_DEFS (v_must_defs);
1902
1903           if (nvuses && (nv_may_defs || nv_must_defs))
1904             {
1905               if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
1906                 {
1907                   fprintf (vect_dump, "unexpected vdefs and vuses in stmt: ");
1908                   print_generic_expr (vect_dump, stmt, TDF_SLIM);
1909                 }
1910               return false;
1911             }
1912
1913           if (TREE_CODE (stmt) != MODIFY_EXPR)
1914             {
1915               if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
1916                 {
1917                   fprintf (vect_dump, "unexpected vops in stmt: ");
1918                   print_generic_expr (vect_dump, stmt, TDF_SLIM);
1919                 }
1920               return false;
1921             }
1922
1923           if (vuses)
1924             {
1925               memref = TREE_OPERAND (stmt, 1);
1926               datarefs = &(LOOP_VINFO_DATAREF_READS (loop_vinfo));
1927               is_read = true;
1928             } 
1929           else /* vdefs */
1930             {
1931               memref = TREE_OPERAND (stmt, 0);
1932               datarefs = &(LOOP_VINFO_DATAREF_WRITES (loop_vinfo));
1933               is_read = false;
1934             }
1935           
1936           scalar_type = TREE_TYPE (memref);
1937           vectype = get_vectype_for_scalar_type (scalar_type);
1938           if (!vectype)
1939             {
1940               if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
1941                 {
1942                   fprintf (vect_dump, "no vectype for stmt: ");
1943                   print_generic_expr (vect_dump, stmt, TDF_SLIM);
1944                   fprintf (vect_dump, " scalar_type: ");
1945                   print_generic_expr (vect_dump, scalar_type, TDF_DETAILS);
1946                 }
1947               /* It is not possible to vectorize this data reference.  */
1948               return false;
1949             }
1950          /* Analyze MEMREF. If it is of a supported form, build data_reference
1951              struct for it (DR).  */
1952           dr = NULL; 
1953           base = vect_object_analysis (memref, stmt, is_read, vectype, &dr, 
1954                                        &offset, &misalign, &step, 
1955                                        &base_aligned, &tag, &subvars);
1956           if (!base)
1957             {
1958               if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
1959                                         LOOP_LOC (loop_vinfo)))
1960                 {
1961                   fprintf (vect_dump, "not vectorized: unhandled data ref: "); 
1962                   print_generic_expr (vect_dump, stmt, TDF_SLIM);
1963                 }
1964               return false;
1965             }
1966           STMT_VINFO_VECT_DR_BASE_ADDRESS (stmt_info) = base;
1967           STMT_VINFO_VECT_INIT_OFFSET (stmt_info) = offset;
1968           STMT_VINFO_VECT_STEP (stmt_info) = step;
1969           STMT_VINFO_VECT_MISALIGNMENT (stmt_info) = misalign;
1970           STMT_VINFO_VECT_BASE_ALIGNED_P (stmt_info) = base_aligned;
1971           STMT_VINFO_MEMTAG (stmt_info) = tag;
1972           STMT_VINFO_SUBVARS (stmt_info) = subvars;
1973           STMT_VINFO_VECTYPE (stmt_info) = vectype;
1974           VARRAY_PUSH_GENERIC_PTR (*datarefs, dr);
1975           STMT_VINFO_DATA_REF (stmt_info) = dr;
1976         }
1977     }
1978
1979   return true;
1980 }
1981
1982
1983 /* Utility functions used by vect_mark_stmts_to_be_vectorized.  */
1984
1985 /* Function vect_mark_relevant.
1986
1987    Mark STMT as "relevant for vectorization" and add it to WORKLIST.  */
1988
1989 static void
1990 vect_mark_relevant (varray_type *worklist, tree stmt)
1991 {
1992   stmt_vec_info stmt_info;
1993
1994   if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
1995     fprintf (vect_dump, "mark relevant.");
1996
1997   if (TREE_CODE (stmt) == PHI_NODE)
1998     {
1999       VARRAY_PUSH_TREE (*worklist, stmt);
2000       return;
2001     }
2002
2003   stmt_info = vinfo_for_stmt (stmt);
2004
2005   if (!stmt_info)
2006     {
2007       if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
2008         {
2009           fprintf (vect_dump, "mark relevant: no stmt info!!.");
2010           print_generic_expr (vect_dump, stmt, TDF_SLIM);
2011         }
2012       return;
2013     }
2014
2015   if (STMT_VINFO_RELEVANT_P (stmt_info))
2016     {
2017       if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
2018         fprintf (vect_dump, "already marked relevant.");
2019       return;
2020     }
2021
2022   STMT_VINFO_RELEVANT_P (stmt_info) = 1;
2023   VARRAY_PUSH_TREE (*worklist, stmt);
2024 }
2025
2026
2027 /* Function vect_stmt_relevant_p.
2028
2029    Return true if STMT in loop that is represented by LOOP_VINFO is
2030    "relevant for vectorization".
2031
2032    A stmt is considered "relevant for vectorization" if:
2033    - it has uses outside the loop.
2034    - it has vdefs (it alters memory).
2035    - control stmts in the loop (except for the exit condition).
2036
2037    CHECKME: what other side effects would the vectorizer allow?  */
2038
2039 static bool
2040 vect_stmt_relevant_p (tree stmt, loop_vec_info loop_vinfo)
2041 {
2042   v_may_def_optype v_may_defs;
2043   v_must_def_optype v_must_defs;
2044   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
2045   int i;
2046   dataflow_t df;
2047   int num_uses;
2048
2049   /* cond stmt other than loop exit cond.  */
2050   if (is_ctrl_stmt (stmt) && (stmt != LOOP_VINFO_EXIT_COND (loop_vinfo)))
2051     return true;
2052
2053   /* changing memory.  */
2054   if (TREE_CODE (stmt) != PHI_NODE)
2055     {
2056       v_may_defs = STMT_V_MAY_DEF_OPS (stmt);
2057       v_must_defs = STMT_V_MUST_DEF_OPS (stmt);
2058       if (v_may_defs || v_must_defs)
2059         {
2060           if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
2061             fprintf (vect_dump, "vec_stmt_relevant_p: stmt has vdefs.");
2062           return true;
2063         }
2064     }
2065
2066   /* uses outside the loop.  */
2067   df = get_immediate_uses (stmt);
2068   num_uses = num_immediate_uses (df);
2069   for (i = 0; i < num_uses; i++)
2070     {
2071       tree use = immediate_use (df, i);
2072       basic_block bb = bb_for_stmt (use);
2073       if (!flow_bb_inside_loop_p (loop, bb))
2074         {
2075           if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
2076             fprintf (vect_dump, "vec_stmt_relevant_p: used out of loop.");
2077           return true;
2078         }
2079     }
2080
2081   return false;
2082 }
2083
2084
2085 /* Function vect_mark_stmts_to_be_vectorized.
2086
2087    Not all stmts in the loop need to be vectorized. For example:
2088
2089      for i...
2090        for j...
2091    1.    T0 = i + j
2092    2.    T1 = a[T0]
2093
2094    3.    j = j + 1
2095
2096    Stmt 1 and 3 do not need to be vectorized, because loop control and
2097    addressing of vectorized data-refs are handled differently.
2098
2099    This pass detects such stmts.  */
2100
2101 static bool
2102 vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo)
2103 {
2104   varray_type worklist;
2105   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
2106   basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
2107   unsigned int nbbs = loop->num_nodes;
2108   block_stmt_iterator si;
2109   tree stmt;
2110   stmt_ann_t ann;
2111   unsigned int i;
2112   int j;
2113   use_optype use_ops;
2114   stmt_vec_info stmt_info;
2115   basic_block bb;
2116   tree phi;
2117
2118   if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
2119     fprintf (vect_dump, "=== vect_mark_stmts_to_be_vectorized ===");
2120
2121   bb = loop->header;
2122   for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
2123     {
2124       if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
2125         {
2126           fprintf (vect_dump, "init: phi relevant? ");
2127           print_generic_expr (vect_dump, phi, TDF_SLIM);
2128         }
2129
2130       if (vect_stmt_relevant_p (phi, loop_vinfo))
2131         {
2132           if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
2133                                     LOOP_LOC (loop_vinfo)))
2134             fprintf (vect_dump, "unsupported reduction/induction.");
2135           return false;
2136         }
2137     }
2138
2139   VARRAY_TREE_INIT (worklist, 64, "work list");
2140
2141   /* 1. Init worklist.  */
2142
2143   for (i = 0; i < nbbs; i++)
2144     {
2145       bb = bbs[i];
2146       for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
2147         {
2148           stmt = bsi_stmt (si);
2149
2150           if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
2151             {
2152               fprintf (vect_dump, "init: stmt relevant? ");
2153               print_generic_expr (vect_dump, stmt, TDF_SLIM);
2154             } 
2155
2156           stmt_info = vinfo_for_stmt (stmt);
2157           STMT_VINFO_RELEVANT_P (stmt_info) = 0;
2158
2159           if (vect_stmt_relevant_p (stmt, loop_vinfo))
2160             vect_mark_relevant (&worklist, stmt);
2161         }
2162     }
2163
2164
2165   /* 2. Process_worklist */
2166
2167   while (VARRAY_ACTIVE_SIZE (worklist) > 0)
2168     {
2169       stmt = VARRAY_TOP_TREE (worklist);
2170       VARRAY_POP (worklist);
2171
2172       if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
2173         {
2174           fprintf (vect_dump, "worklist: examine stmt: ");
2175           print_generic_expr (vect_dump, stmt, TDF_SLIM);
2176         }
2177
2178       /* Examine the USES in this statement. Mark all the statements which
2179          feed this statement's uses as "relevant", unless the USE is used as
2180          an array index.  */
2181
2182       if (TREE_CODE (stmt) == PHI_NODE)
2183         {
2184           /* follow the def-use chain inside the loop.  */
2185           for (j = 0; j < PHI_NUM_ARGS (stmt); j++)
2186             {
2187               tree arg = PHI_ARG_DEF (stmt, j);
2188               tree def_stmt = NULL_TREE;
2189               basic_block bb;
2190               if (!vect_is_simple_use (arg, loop_vinfo, &def_stmt))
2191                 {
2192                   if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
2193                                             LOOP_LOC (loop_vinfo)))
2194                     fprintf (vect_dump, "not vectorized: unsupported use in stmt.");
2195                   varray_clear (worklist);
2196                   return false;
2197                 }
2198               if (!def_stmt)
2199                 continue;
2200
2201               if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
2202                 {
2203                   fprintf (vect_dump, "worklist: def_stmt: ");
2204                   print_generic_expr (vect_dump, def_stmt, TDF_SLIM);
2205                 }
2206
2207               bb = bb_for_stmt (def_stmt);
2208               if (flow_bb_inside_loop_p (loop, bb))
2209                 vect_mark_relevant (&worklist, def_stmt);
2210             }
2211         } 
2212
2213       ann = stmt_ann (stmt);
2214       use_ops = USE_OPS (ann);
2215
2216       for (i = 0; i < NUM_USES (use_ops); i++)
2217         {
2218           tree use = USE_OP (use_ops, i);
2219
2220           /* We are only interested in uses that need to be vectorized. Uses 
2221              that are used for address computation are not considered relevant.
2222            */
2223           if (exist_non_indexing_operands_for_use_p (use, stmt))
2224             {
2225               tree def_stmt = NULL_TREE;
2226               basic_block bb;
2227               if (!vect_is_simple_use (use, loop_vinfo, &def_stmt))
2228                 {
2229                   if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
2230                                             LOOP_LOC (loop_vinfo)))
2231                     fprintf (vect_dump, "not vectorized: unsupported use in stmt.");
2232                   varray_clear (worklist);
2233                   return false;
2234                 }
2235
2236               if (!def_stmt)
2237                 continue;
2238
2239               if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
2240                 {
2241                   fprintf (vect_dump, "worklist: examine use %d: ", i);
2242                   print_generic_expr (vect_dump, use, TDF_SLIM);
2243                 }
2244
2245               bb = bb_for_stmt (def_stmt);
2246               if (flow_bb_inside_loop_p (loop, bb))
2247                 vect_mark_relevant (&worklist, def_stmt);
2248             }
2249         }
2250     }                           /* while worklist */
2251
2252   varray_clear (worklist);
2253   return true;
2254 }
2255
2256
2257 /* Function vect_can_advance_ivs_p
2258
2259    In case the number of iterations that LOOP iterates in unknown at compile 
2260    time, an epilog loop will be generated, and the loop induction variables 
2261    (IVs) will be "advanced" to the value they are supposed to take just before 
2262    the epilog loop.  Here we check that the access function of the loop IVs
2263    and the expression that represents the loop bound are simple enough.
2264    These restrictions will be relaxed in the future.  */
2265
2266 static bool 
2267 vect_can_advance_ivs_p (loop_vec_info loop_vinfo)
2268 {
2269   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
2270   basic_block bb = loop->header;
2271   tree phi;
2272
2273   /* Analyze phi functions of the loop header.  */
2274
2275   for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
2276     {
2277       tree access_fn = NULL;
2278       tree evolution_part;
2279
2280       if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
2281         {
2282           fprintf (vect_dump, "Analyze phi: ");
2283           print_generic_expr (vect_dump, phi, TDF_SLIM);
2284         }
2285
2286       /* Skip virtual phi's. The data dependences that are associated with
2287          virtual defs/uses (i.e., memory accesses) are analyzed elsewhere.  */
2288
2289       if (!is_gimple_reg (SSA_NAME_VAR (PHI_RESULT (phi))))
2290         {
2291           if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
2292             fprintf (vect_dump, "virtual phi. skip.");
2293           continue;
2294         }
2295
2296       /* Analyze the evolution function.  */
2297
2298       access_fn = instantiate_parameters
2299         (loop, analyze_scalar_evolution (loop, PHI_RESULT (phi)));
2300
2301       if (!access_fn)
2302         {
2303           if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
2304             fprintf (vect_dump, "No Access function.");
2305           return false;
2306         }
2307
2308       if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
2309         {
2310           fprintf (vect_dump, "Access function of PHI: ");
2311           print_generic_expr (vect_dump, access_fn, TDF_SLIM);
2312         }
2313
2314       evolution_part = evolution_part_in_loop_num (access_fn, loop->num);
2315       
2316       if (evolution_part == NULL_TREE)
2317         return false;
2318   
2319       /* FORNOW: We do not transform initial conditions of IVs 
2320          which evolution functions are a polynomial of degree >= 2.  */
2321
2322       if (tree_is_chrec (evolution_part))
2323         return false;  
2324     }
2325
2326   return true;
2327 }
2328
2329
2330 /* Function vect_get_loop_niters.
2331
2332    Determine how many iterations the loop is executed.
2333    If an expression that represents the number of iterations
2334    can be constructed, place it in NUMBER_OF_ITERATIONS.
2335    Return the loop exit condition.  */
2336
2337 static tree
2338 vect_get_loop_niters (struct loop *loop, tree *number_of_iterations)
2339 {
2340   tree niters;
2341
2342   if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
2343     fprintf (vect_dump, "=== get_loop_niters ===");
2344
2345   niters = number_of_iterations_in_loop (loop);
2346
2347   if (niters != NULL_TREE
2348       && niters != chrec_dont_know)
2349     {
2350       *number_of_iterations = niters;
2351
2352       if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
2353         {
2354           fprintf (vect_dump, "==> get_loop_niters:" );
2355           print_generic_expr (vect_dump, *number_of_iterations, TDF_SLIM);
2356         }
2357     }
2358
2359   return get_loop_exit_condition (loop);
2360 }
2361
2362
2363 /* Function vect_analyze_loop_form.
2364
2365    Verify the following restrictions (some may be relaxed in the future):
2366    - it's an inner-most loop
2367    - number of BBs = 2 (which are the loop header and the latch)
2368    - the loop has a pre-header
2369    - the loop has a single entry and exit
2370    - the loop exit condition is simple enough, and the number of iterations
2371      can be analyzed (a countable loop).  */
2372
2373 static loop_vec_info
2374 vect_analyze_loop_form (struct loop *loop)
2375 {
2376   loop_vec_info loop_vinfo;
2377   tree loop_cond;
2378   tree number_of_iterations = NULL;
2379   LOC loop_loc;
2380
2381   loop_loc = find_loop_location (loop);
2382
2383   if (vect_print_dump_info (REPORT_DETAILS, loop_loc))
2384     fprintf (vect_dump, "=== vect_analyze_loop_form ===");
2385
2386   if (loop->inner)
2387     {
2388       if (vect_print_dump_info (REPORT_OUTER_LOOPS, loop_loc))
2389         fprintf (vect_dump, "not vectorized: nested loop.");
2390       return NULL;
2391     }
2392   
2393   if (!loop->single_exit 
2394       || loop->num_nodes != 2
2395       || EDGE_COUNT (loop->header->preds) != 2)
2396     {
2397       if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS, loop_loc))
2398         {
2399           if (!loop->single_exit)
2400             fprintf (vect_dump, "not vectorized: multiple exits.");
2401           else if (loop->num_nodes != 2)
2402             fprintf (vect_dump, "not vectorized: too many BBs in loop.");
2403           else if (EDGE_COUNT (loop->header->preds) != 2)
2404             fprintf (vect_dump, "not vectorized: too many incoming edges.");
2405         }
2406
2407       return NULL;
2408     }
2409
2410   /* We assume that the loop exit condition is at the end of the loop. i.e,
2411      that the loop is represented as a do-while (with a proper if-guard
2412      before the loop if needed), where the loop header contains all the
2413      executable statements, and the latch is empty.  */
2414   if (!empty_block_p (loop->latch))
2415     {
2416       if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS, loop_loc))
2417         fprintf (vect_dump, "not vectorized: unexpectd loop form.");
2418       return NULL;
2419     }
2420
2421   /* Make sure there exists a single-predecessor exit bb:  */
2422   if (!single_pred_p (loop->single_exit->dest))
2423     {
2424       edge e = loop->single_exit;
2425       if (!(e->flags & EDGE_ABNORMAL))
2426         {
2427           loop_split_edge_with (e, NULL);
2428           if (vect_print_dump_info (REPORT_DETAILS, loop_loc))
2429             fprintf (vect_dump, "split exit edge.");
2430         }
2431       else
2432         {
2433           if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS, loop_loc))
2434             fprintf (vect_dump, "not vectorized: abnormal loop exit edge.");
2435           return NULL;
2436         }
2437     }
2438
2439   if (empty_block_p (loop->header))
2440     {
2441       if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS, loop_loc))
2442         fprintf (vect_dump, "not vectorized: empty loop.");
2443       return NULL;
2444     }
2445
2446   loop_cond = vect_get_loop_niters (loop, &number_of_iterations);
2447   if (!loop_cond)
2448     {
2449       if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS, loop_loc))
2450         fprintf (vect_dump, "not vectorized: complicated exit condition.");
2451       return NULL;
2452     }
2453   
2454   if (!number_of_iterations) 
2455     {
2456       if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS, loop_loc))
2457         fprintf (vect_dump, 
2458                  "not vectorized: number of iterations cannot be computed.");
2459       return NULL;
2460     }
2461
2462   if (chrec_contains_undetermined (number_of_iterations))
2463     {
2464       if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS, loop_loc))
2465         fprintf (vect_dump, "Infinite number of iterations.");
2466       return false;
2467     }
2468
2469   loop_vinfo = new_loop_vec_info (loop);
2470   LOOP_VINFO_NITERS (loop_vinfo) = number_of_iterations;
2471
2472   if (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo))
2473     {
2474       if (vect_print_dump_info (REPORT_DETAILS, loop_loc))
2475         {
2476           fprintf (vect_dump, "Symbolic number of iterations is ");
2477           print_generic_expr (vect_dump, number_of_iterations, TDF_DETAILS);
2478         }
2479     }
2480   else
2481   if (LOOP_VINFO_INT_NITERS (loop_vinfo) == 0)
2482     {
2483       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS, loop_loc))
2484         fprintf (vect_dump, "not vectorized: number of iterations = 0.");
2485       return NULL;
2486     }
2487
2488   LOOP_VINFO_EXIT_COND (loop_vinfo) = loop_cond;
2489   LOOP_VINFO_LOC (loop_vinfo) = loop_loc;
2490
2491   return loop_vinfo;
2492 }
2493
2494
2495 /* Function vect_analyze_loop.
2496
2497    Apply a set of analyses on LOOP, and create a loop_vec_info struct
2498    for it. The different analyses will record information in the
2499    loop_vec_info struct.  */
2500 loop_vec_info
2501 vect_analyze_loop (struct loop *loop)
2502 {
2503   bool ok;
2504   loop_vec_info loop_vinfo;
2505
2506   if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
2507     fprintf (vect_dump, "===== analyze_loop_nest =====");
2508
2509   /* Check the CFG characteristics of the loop (nesting, entry/exit, etc.  */
2510
2511   loop_vinfo = vect_analyze_loop_form (loop);
2512   if (!loop_vinfo)
2513     {
2514       if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
2515         fprintf (vect_dump, "bad loop form.");
2516       return NULL;
2517     }
2518
2519   /* Find all data references in the loop (which correspond to vdefs/vuses)
2520      and analyze their evolution in the loop.
2521
2522      FORNOW: Handle only simple, array references, which
2523      alignment can be forced, and aligned pointer-references.  */
2524
2525   ok = vect_analyze_data_refs (loop_vinfo);
2526   if (!ok)
2527     {
2528       if (vect_print_dump_info (REPORT_DETAILS, LOOP_LOC (loop_vinfo)))
2529         fprintf (vect_dump, "bad data references.");
2530       destroy_loop_vec_info (loop_vinfo);
2531       return NULL;
2532     }
2533
2534   /* Data-flow analysis to detect stmts that do not need to be vectorized.  */
2535
2536   ok = vect_mark_stmts_to_be_vectorized (loop_vinfo);
2537   if (!ok)
2538     {
2539       if (vect_print_dump_info (REPORT_DETAILS, LOOP_LOC (loop_vinfo)))
2540         fprintf (vect_dump, "unexpected pattern.");
2541       destroy_loop_vec_info (loop_vinfo);
2542       return NULL;
2543     }
2544
2545   /* Check that all cross-iteration scalar data-flow cycles are OK.
2546      Cross-iteration cycles caused by virtual phis are analyzed separately.  */
2547
2548   ok = vect_analyze_scalar_cycles (loop_vinfo);
2549   if (!ok)
2550     {
2551       if (vect_print_dump_info (REPORT_DETAILS, LOOP_LOC (loop_vinfo)))
2552         fprintf (vect_dump, "bad scalar cycle.");
2553       destroy_loop_vec_info (loop_vinfo);
2554       return NULL;
2555     }
2556
2557   /* Analyze data dependences between the data-refs in the loop. 
2558      FORNOW: fail at the first data dependence that we encounter.  */
2559
2560   ok = vect_analyze_data_ref_dependences (loop_vinfo);
2561   if (!ok)
2562     {
2563       if (vect_print_dump_info (REPORT_DETAILS, LOOP_LOC (loop_vinfo)))
2564         fprintf (vect_dump, "bad data dependence.");
2565       destroy_loop_vec_info (loop_vinfo);
2566       return NULL;
2567     }
2568
2569   /* Analyze the access patterns of the data-refs in the loop (consecutive,
2570      complex, etc.). FORNOW: Only handle consecutive access pattern.  */
2571
2572   ok = vect_analyze_data_ref_accesses (loop_vinfo);
2573   if (!ok)
2574     {
2575       if (vect_print_dump_info (REPORT_DETAILS, LOOP_LOC (loop_vinfo)))
2576         fprintf (vect_dump, "bad data access.");
2577       destroy_loop_vec_info (loop_vinfo);
2578       return NULL;
2579     }
2580
2581   ok = vect_determine_vectorization_factor (loop_vinfo);
2582   if (!ok)
2583     {
2584       if (vect_print_dump_info (REPORT_DETAILS, LOOP_LOC (loop_vinfo)))
2585         fprintf (vect_dump, "can't determine vectorization factor.");
2586       destroy_loop_vec_info (loop_vinfo);
2587       return NULL;
2588     }
2589
2590   /* Analyze the alignment of the data-refs in the loop.
2591      FORNOW: Only aligned accesses are handled.  */
2592
2593   ok = vect_analyze_data_refs_alignment (loop_vinfo);
2594   if (!ok)
2595     {
2596       if (vect_print_dump_info (REPORT_DETAILS, LOOP_LOC (loop_vinfo)))
2597         fprintf (vect_dump, "bad data alignment.");
2598       destroy_loop_vec_info (loop_vinfo);
2599       return NULL;
2600     }
2601
2602   /* Scan all the operations in the loop and make sure they are
2603      vectorizable.  */
2604
2605   ok = vect_analyze_operations (loop_vinfo);
2606   if (!ok)
2607     {
2608       if (vect_print_dump_info (REPORT_DETAILS, LOOP_LOC (loop_vinfo)))
2609         fprintf (vect_dump, "bad operation or unsupported loop bound.");
2610       destroy_loop_vec_info (loop_vinfo);
2611       return NULL;
2612     }
2613
2614   LOOP_VINFO_VECTORIZABLE_P (loop_vinfo) = 1;
2615
2616   return loop_vinfo;
2617 }