OSDN Git Service

* doc/passes.texi (Tree-SSA passes): Document SLP pass.
[pf3gnuchains/gcc-fork.git] / gcc / tree-vect-loop.c
1 /* Loop Vectorization
2    Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software
3    Foundation, Inc.
4    Contributed by Dorit Naishlos <dorit@il.ibm.com> and 
5    Ira Rosen <irar@il.ibm.com>
6
7 This file is part of GCC.
8
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
12 version.
13
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17 for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3.  If not see
21 <http://www.gnu.org/licenses/>.  */
22
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tm.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 "cfgloop.h"
34 #include "cfglayout.h"
35 #include "expr.h"
36 #include "recog.h"
37 #include "optabs.h"
38 #include "params.h"
39 #include "toplev.h"
40 #include "tree-chrec.h"
41 #include "tree-scalar-evolution.h"
42 #include "tree-vectorizer.h"
43
44 /* Loop Vectorization Pass.
45
46    This pass tries to vectorize loops. 
47
48    For example, the vectorizer transforms the following simple loop:
49
50         short a[N]; short b[N]; short c[N]; int i;
51
52         for (i=0; i<N; i++){
53           a[i] = b[i] + c[i];
54         }
55
56    as if it was manually vectorized by rewriting the source code into:
57
58         typedef int __attribute__((mode(V8HI))) v8hi;
59         short a[N];  short b[N]; short c[N];   int i;
60         v8hi *pa = (v8hi*)a, *pb = (v8hi*)b, *pc = (v8hi*)c;
61         v8hi va, vb, vc;
62
63         for (i=0; i<N/8; i++){
64           vb = pb[i];
65           vc = pc[i];
66           va = vb + vc;
67           pa[i] = va;
68         }
69
70         The main entry to this pass is vectorize_loops(), in which
71    the vectorizer applies a set of analyses on a given set of loops,
72    followed by the actual vectorization transformation for the loops that
73    had successfully passed the analysis phase.
74         Throughout this pass we make a distinction between two types of
75    data: scalars (which are represented by SSA_NAMES), and memory references
76    ("data-refs"). These two types of data require different handling both
77    during analysis and transformation. The types of data-refs that the
78    vectorizer currently supports are ARRAY_REFS which base is an array DECL
79    (not a pointer), and INDIRECT_REFS through pointers; both array and pointer
80    accesses are required to have a simple (consecutive) access pattern.
81
82    Analysis phase:
83    ===============
84         The driver for the analysis phase is vect_analyze_loop().
85    It applies a set of analyses, some of which rely on the scalar evolution
86    analyzer (scev) developed by Sebastian Pop.
87
88         During the analysis phase the vectorizer records some information
89    per stmt in a "stmt_vec_info" struct which is attached to each stmt in the
90    loop, as well as general information about the loop as a whole, which is
91    recorded in a "loop_vec_info" struct attached to each loop.
92
93    Transformation phase:
94    =====================
95         The loop transformation phase scans all the stmts in the loop, and
96    creates a vector stmt (or a sequence of stmts) for each scalar stmt S in
97    the loop that needs to be vectorized. It inserts the vector code sequence
98    just before the scalar stmt S, and records a pointer to the vector code
99    in STMT_VINFO_VEC_STMT (stmt_info) (stmt_info is the stmt_vec_info struct
100    attached to S). This pointer will be used for the vectorization of following
101    stmts which use the def of stmt S. Stmt S is removed if it writes to memory;
102    otherwise, we rely on dead code elimination for removing it.
103
104         For example, say stmt S1 was vectorized into stmt VS1:
105
106    VS1: vb = px[i];
107    S1:  b = x[i];    STMT_VINFO_VEC_STMT (stmt_info (S1)) = VS1
108    S2:  a = b;
109
110    To vectorize stmt S2, the vectorizer first finds the stmt that defines
111    the operand 'b' (S1), and gets the relevant vector def 'vb' from the
112    vector stmt VS1 pointed to by STMT_VINFO_VEC_STMT (stmt_info (S1)). The
113    resulting sequence would be:
114
115    VS1: vb = px[i];
116    S1:  b = x[i];       STMT_VINFO_VEC_STMT (stmt_info (S1)) = VS1
117    VS2: va = vb;
118    S2:  a = b;          STMT_VINFO_VEC_STMT (stmt_info (S2)) = VS2
119
120         Operands that are not SSA_NAMEs, are data-refs that appear in
121    load/store operations (like 'x[i]' in S1), and are handled differently.
122
123    Target modeling:
124    =================
125         Currently the only target specific information that is used is the
126    size of the vector (in bytes) - "UNITS_PER_SIMD_WORD". Targets that can
127    support different sizes of vectors, for now will need to specify one value
128    for "UNITS_PER_SIMD_WORD". More flexibility will be added in the future.
129
130         Since we only vectorize operations which vector form can be
131    expressed using existing tree codes, to verify that an operation is
132    supported, the vectorizer checks the relevant optab at the relevant
133    machine_mode (e.g, optab_handler (add_optab, V8HImode)->insn_code). If
134    the value found is CODE_FOR_nothing, then there's no target support, and
135    we can't vectorize the stmt.
136
137    For additional information on this project see:
138    http://gcc.gnu.org/projects/tree-ssa/vectorization.html
139 */
140
141 /* Function vect_determine_vectorization_factor
142
143    Determine the vectorization factor (VF). VF is the number of data elements
144    that are operated upon in parallel in a single iteration of the vectorized
145    loop. For example, when vectorizing a loop that operates on 4byte elements,
146    on a target with vector size (VS) 16byte, the VF is set to 4, since 4
147    elements can fit in a single vector register.
148
149    We currently support vectorization of loops in which all types operated upon
150    are of the same size. Therefore this function currently sets VF according to
151    the size of the types operated upon, and fails if there are multiple sizes
152    in the loop.
153
154    VF is also the factor by which the loop iterations are strip-mined, e.g.:
155    original loop:
156         for (i=0; i<N; i++){
157           a[i] = b[i] + c[i];
158         }
159
160    vectorized loop:
161         for (i=0; i<N; i+=VF){
162           a[i:VF] = b[i:VF] + c[i:VF];
163         }
164 */
165
166 static bool
167 vect_determine_vectorization_factor (loop_vec_info loop_vinfo)
168 {
169   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
170   basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
171   int nbbs = loop->num_nodes;
172   gimple_stmt_iterator si;
173   unsigned int vectorization_factor = 0;
174   tree scalar_type;
175   gimple phi;
176   tree vectype;
177   unsigned int nunits;
178   stmt_vec_info stmt_info;
179   int i;
180   HOST_WIDE_INT dummy;
181
182   if (vect_print_dump_info (REPORT_DETAILS))
183     fprintf (vect_dump, "=== vect_determine_vectorization_factor ===");
184
185   for (i = 0; i < nbbs; i++)
186     {
187       basic_block bb = bbs[i];
188
189       for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
190         {
191           phi = gsi_stmt (si);
192           stmt_info = vinfo_for_stmt (phi);
193           if (vect_print_dump_info (REPORT_DETAILS))
194             {
195               fprintf (vect_dump, "==> examining phi: ");
196               print_gimple_stmt (vect_dump, phi, 0, TDF_SLIM);
197             }
198
199           gcc_assert (stmt_info);
200
201           if (STMT_VINFO_RELEVANT_P (stmt_info))
202             {
203               gcc_assert (!STMT_VINFO_VECTYPE (stmt_info));
204               scalar_type = TREE_TYPE (PHI_RESULT (phi));
205
206               if (vect_print_dump_info (REPORT_DETAILS))
207                 {
208                   fprintf (vect_dump, "get vectype for scalar type:  ");
209                   print_generic_expr (vect_dump, scalar_type, TDF_SLIM);
210                 }
211
212               vectype = get_vectype_for_scalar_type (scalar_type);
213               if (!vectype)
214                 {
215                   if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
216                     {
217                       fprintf (vect_dump,
218                                "not vectorized: unsupported data-type ");
219                       print_generic_expr (vect_dump, scalar_type, TDF_SLIM);
220                     }
221                   return false;
222                 }
223               STMT_VINFO_VECTYPE (stmt_info) = vectype;
224
225               if (vect_print_dump_info (REPORT_DETAILS))
226                 {
227                   fprintf (vect_dump, "vectype: ");
228                   print_generic_expr (vect_dump, vectype, TDF_SLIM);
229                 }
230
231               nunits = TYPE_VECTOR_SUBPARTS (vectype);
232               if (vect_print_dump_info (REPORT_DETAILS))
233                 fprintf (vect_dump, "nunits = %d", nunits);
234
235               if (!vectorization_factor
236                   || (nunits > vectorization_factor))
237                 vectorization_factor = nunits;
238             }
239         }
240
241       for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
242         {
243           gimple stmt = gsi_stmt (si);
244           stmt_info = vinfo_for_stmt (stmt);
245
246           if (vect_print_dump_info (REPORT_DETAILS))
247             {
248               fprintf (vect_dump, "==> examining statement: ");
249               print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
250             }
251
252           gcc_assert (stmt_info);
253
254           /* skip stmts which do not need to be vectorized.  */
255           if (!STMT_VINFO_RELEVANT_P (stmt_info)
256               && !STMT_VINFO_LIVE_P (stmt_info))
257             {
258               if (vect_print_dump_info (REPORT_DETAILS))
259                 fprintf (vect_dump, "skip.");
260               continue;
261             }
262
263           if (gimple_get_lhs (stmt) == NULL_TREE)
264             {
265               if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
266                 {
267                   fprintf (vect_dump, "not vectorized: irregular stmt.");
268                   print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
269                 }
270               return false;
271             }
272
273           if (VECTOR_MODE_P (TYPE_MODE (gimple_expr_type (stmt))))
274             {
275               if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
276                 {
277                   fprintf (vect_dump, "not vectorized: vector stmt in loop:");
278                   print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
279                 }
280               return false;
281             }
282
283           if (STMT_VINFO_VECTYPE (stmt_info))
284             {
285               /* The only case when a vectype had been already set is for stmts 
286                  that contain a dataref, or for "pattern-stmts" (stmts generated
287                  by the vectorizer to represent/replace a certain idiom).  */
288               gcc_assert (STMT_VINFO_DATA_REF (stmt_info) 
289                           || is_pattern_stmt_p (stmt_info));
290               vectype = STMT_VINFO_VECTYPE (stmt_info);
291             }
292           else
293             {
294
295               gcc_assert (! STMT_VINFO_DATA_REF (stmt_info)
296                           && !is_pattern_stmt_p (stmt_info));
297
298               scalar_type = vect_get_smallest_scalar_type (stmt, &dummy, 
299                                                            &dummy);
300               if (vect_print_dump_info (REPORT_DETAILS))
301                 {
302                   fprintf (vect_dump, "get vectype for scalar type:  ");
303                   print_generic_expr (vect_dump, scalar_type, TDF_SLIM);
304                 }
305
306               vectype = get_vectype_for_scalar_type (scalar_type);
307               if (!vectype)
308                 {
309                   if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
310                     {
311                       fprintf (vect_dump, 
312                                "not vectorized: unsupported data-type ");
313                       print_generic_expr (vect_dump, scalar_type, TDF_SLIM);
314                     }
315                   return false;
316                 }
317               STMT_VINFO_VECTYPE (stmt_info) = vectype;
318             }
319
320           if (vect_print_dump_info (REPORT_DETAILS))
321             {
322               fprintf (vect_dump, "vectype: ");
323               print_generic_expr (vect_dump, vectype, TDF_SLIM);
324             }
325
326           nunits = TYPE_VECTOR_SUBPARTS (vectype);
327           if (vect_print_dump_info (REPORT_DETAILS))
328             fprintf (vect_dump, "nunits = %d", nunits);
329
330           if (!vectorization_factor
331               || (nunits > vectorization_factor))
332             vectorization_factor = nunits;
333
334         }
335     }
336
337   /* TODO: Analyze cost. Decide if worth while to vectorize.  */
338   if (vect_print_dump_info (REPORT_DETAILS))
339     fprintf (vect_dump, "vectorization factor = %d", vectorization_factor);
340   if (vectorization_factor <= 1)
341     {
342       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
343         fprintf (vect_dump, "not vectorized: unsupported data-type");
344       return false;
345     }
346   LOOP_VINFO_VECT_FACTOR (loop_vinfo) = vectorization_factor;
347
348   return true;
349 }
350
351
352 /* Function vect_is_simple_iv_evolution.
353
354    FORNOW: A simple evolution of an induction variables in the loop is
355    considered a polynomial evolution with constant step.  */
356
357 static bool
358 vect_is_simple_iv_evolution (unsigned loop_nb, tree access_fn, tree * init,
359                              tree * step)
360 {
361   tree init_expr;
362   tree step_expr;
363   tree evolution_part = evolution_part_in_loop_num (access_fn, loop_nb);
364
365   /* When there is no evolution in this loop, the evolution function
366      is not "simple".  */
367   if (evolution_part == NULL_TREE)
368     return false;
369
370   /* When the evolution is a polynomial of degree >= 2
371      the evolution function is not "simple".  */
372   if (tree_is_chrec (evolution_part))
373     return false;
374
375   step_expr = evolution_part;
376   init_expr = unshare_expr (initial_condition_in_loop_num (access_fn, loop_nb));
377
378   if (vect_print_dump_info (REPORT_DETAILS))
379     {
380       fprintf (vect_dump, "step: ");
381       print_generic_expr (vect_dump, step_expr, TDF_SLIM);
382       fprintf (vect_dump, ",  init: ");
383       print_generic_expr (vect_dump, init_expr, TDF_SLIM);
384     }
385
386   *init = init_expr;
387   *step = step_expr;
388
389   if (TREE_CODE (step_expr) != INTEGER_CST)
390     {
391       if (vect_print_dump_info (REPORT_DETAILS))
392         fprintf (vect_dump, "step unknown.");
393       return false;
394     }
395
396   return true;
397 }
398
399 /* Function vect_analyze_scalar_cycles_1.
400
401    Examine the cross iteration def-use cycles of scalar variables
402    in LOOP. LOOP_VINFO represents the loop that is now being
403    considered for vectorization (can be LOOP, or an outer-loop
404    enclosing LOOP).  */
405
406 static void
407 vect_analyze_scalar_cycles_1 (loop_vec_info loop_vinfo, struct loop *loop)
408 {
409   basic_block bb = loop->header;
410   tree dumy;
411   VEC(gimple,heap) *worklist = VEC_alloc (gimple, heap, 64);
412   gimple_stmt_iterator gsi;
413
414   if (vect_print_dump_info (REPORT_DETAILS))
415     fprintf (vect_dump, "=== vect_analyze_scalar_cycles ===");
416
417   /* First - identify all inductions.  */
418   for (gsi = gsi_start_phis  (bb); !gsi_end_p (gsi); gsi_next (&gsi))
419     {
420       gimple phi = gsi_stmt (gsi);
421       tree access_fn = NULL;
422       tree def = PHI_RESULT (phi);
423       stmt_vec_info stmt_vinfo = vinfo_for_stmt (phi);
424
425       if (vect_print_dump_info (REPORT_DETAILS))
426         {
427           fprintf (vect_dump, "Analyze phi: ");
428           print_gimple_stmt (vect_dump, phi, 0, TDF_SLIM);
429         }
430
431       /* Skip virtual phi's. The data dependences that are associated with
432          virtual defs/uses (i.e., memory accesses) are analyzed elsewhere.  */
433       if (!is_gimple_reg (SSA_NAME_VAR (def)))
434         continue;
435
436       STMT_VINFO_DEF_TYPE (stmt_vinfo) = vect_unknown_def_type;
437
438       /* Analyze the evolution function.  */
439       access_fn = analyze_scalar_evolution (loop, def);
440       if (access_fn && vect_print_dump_info (REPORT_DETAILS))
441         {
442           fprintf (vect_dump, "Access function of PHI: ");
443           print_generic_expr (vect_dump, access_fn, TDF_SLIM);
444         }
445
446       if (!access_fn
447           || !vect_is_simple_iv_evolution (loop->num, access_fn, &dumy, &dumy)) 
448         {
449           VEC_safe_push (gimple, heap, worklist, phi);    
450           continue;
451         }
452
453       if (vect_print_dump_info (REPORT_DETAILS))
454         fprintf (vect_dump, "Detected induction.");
455       STMT_VINFO_DEF_TYPE (stmt_vinfo) = vect_induction_def;
456     }
457
458
459   /* Second - identify all reductions.  */
460   while (VEC_length (gimple, worklist) > 0)
461     {
462       gimple phi = VEC_pop (gimple, worklist);
463       tree def = PHI_RESULT (phi);
464       stmt_vec_info stmt_vinfo = vinfo_for_stmt (phi);
465       gimple reduc_stmt;
466
467       if (vect_print_dump_info (REPORT_DETAILS))
468         { 
469           fprintf (vect_dump, "Analyze phi: ");
470           print_gimple_stmt (vect_dump, phi, 0, TDF_SLIM);
471         }
472
473       gcc_assert (is_gimple_reg (SSA_NAME_VAR (def)));
474       gcc_assert (STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_unknown_def_type);
475
476       reduc_stmt = vect_is_simple_reduction (loop_vinfo, phi);
477       if (reduc_stmt)
478         {
479           if (vect_print_dump_info (REPORT_DETAILS))
480             fprintf (vect_dump, "Detected reduction.");
481           STMT_VINFO_DEF_TYPE (stmt_vinfo) = vect_reduction_def;
482           STMT_VINFO_DEF_TYPE (vinfo_for_stmt (reduc_stmt)) =
483                                                         vect_reduction_def;
484         }
485       else
486         if (vect_print_dump_info (REPORT_DETAILS))
487           fprintf (vect_dump, "Unknown def-use cycle pattern.");
488     }
489
490   VEC_free (gimple, heap, worklist);
491   return;
492 }
493
494
495 /* Function vect_analyze_scalar_cycles.
496
497    Examine the cross iteration def-use cycles of scalar variables, by
498    analyzing the loop-header PHIs of scalar variables; Classify each 
499    cycle as one of the following: invariant, induction, reduction, unknown.
500    We do that for the loop represented by LOOP_VINFO, and also to its
501    inner-loop, if exists.
502    Examples for scalar cycles:
503
504    Example1: reduction:
505
506               loop1:
507               for (i=0; i<N; i++)
508                  sum += a[i];
509
510    Example2: induction:
511
512               loop2:
513               for (i=0; i<N; i++)
514                  a[i] = i;  */
515
516 static void
517 vect_analyze_scalar_cycles (loop_vec_info loop_vinfo)
518 {
519   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
520
521   vect_analyze_scalar_cycles_1 (loop_vinfo, loop);
522
523   /* When vectorizing an outer-loop, the inner-loop is executed sequentially.
524      Reductions in such inner-loop therefore have different properties than
525      the reductions in the nest that gets vectorized:
526      1. When vectorized, they are executed in the same order as in the original
527         scalar loop, so we can't change the order of computation when
528         vectorizing them.
529      2. FIXME: Inner-loop reductions can be used in the inner-loop, so the 
530         current checks are too strict.  */
531
532   if (loop->inner)
533     vect_analyze_scalar_cycles_1 (loop_vinfo, loop->inner);
534 }
535
536 /* Function vect_get_loop_niters.
537
538    Determine how many iterations the loop is executed.
539    If an expression that represents the number of iterations
540    can be constructed, place it in NUMBER_OF_ITERATIONS.
541    Return the loop exit condition.  */
542
543 static gimple
544 vect_get_loop_niters (struct loop *loop, tree *number_of_iterations)
545 {
546   tree niters;
547
548   if (vect_print_dump_info (REPORT_DETAILS))
549     fprintf (vect_dump, "=== get_loop_niters ===");
550
551   niters = number_of_exit_cond_executions (loop);
552
553   if (niters != NULL_TREE
554       && niters != chrec_dont_know)
555     {
556       *number_of_iterations = niters;
557
558       if (vect_print_dump_info (REPORT_DETAILS))
559         {
560           fprintf (vect_dump, "==> get_loop_niters:" );
561           print_generic_expr (vect_dump, *number_of_iterations, TDF_SLIM);
562         }
563     }
564
565   return get_loop_exit_condition (loop);
566 }
567
568
569 /* Function bb_in_loop_p
570
571    Used as predicate for dfs order traversal of the loop bbs.  */
572
573 static bool
574 bb_in_loop_p (const_basic_block bb, const void *data)
575 {
576   const struct loop *const loop = (const struct loop *)data;
577   if (flow_bb_inside_loop_p (loop, bb))
578     return true;
579   return false;
580 }
581
582
583 /* Function new_loop_vec_info.
584
585    Create and initialize a new loop_vec_info struct for LOOP, as well as
586    stmt_vec_info structs for all the stmts in LOOP.  */
587
588 static loop_vec_info
589 new_loop_vec_info (struct loop *loop)
590 {
591   loop_vec_info res;
592   basic_block *bbs;
593   gimple_stmt_iterator si;
594   unsigned int i, nbbs;
595
596   res = (loop_vec_info) xcalloc (1, sizeof (struct _loop_vec_info));
597   LOOP_VINFO_LOOP (res) = loop;
598
599   bbs = get_loop_body (loop);
600
601   /* Create/Update stmt_info for all stmts in the loop.  */
602   for (i = 0; i < loop->num_nodes; i++)
603     {
604       basic_block bb = bbs[i];
605
606       /* BBs in a nested inner-loop will have been already processed (because
607          we will have called vect_analyze_loop_form for any nested inner-loop).
608          Therefore, for stmts in an inner-loop we just want to update the
609          STMT_VINFO_LOOP_VINFO field of their stmt_info to point to the new
610          loop_info of the outer-loop we are currently considering to vectorize
611          (instead of the loop_info of the inner-loop).
612          For stmts in other BBs we need to create a stmt_info from scratch.  */
613       if (bb->loop_father != loop)
614         {
615           /* Inner-loop bb.  */
616           gcc_assert (loop->inner && bb->loop_father == loop->inner);
617           for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
618             {
619               gimple phi = gsi_stmt (si);
620               stmt_vec_info stmt_info = vinfo_for_stmt (phi);
621               loop_vec_info inner_loop_vinfo =
622                 STMT_VINFO_LOOP_VINFO (stmt_info);
623               gcc_assert (loop->inner == LOOP_VINFO_LOOP (inner_loop_vinfo));
624               STMT_VINFO_LOOP_VINFO (stmt_info) = res;
625             }
626           for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
627            {
628               gimple stmt = gsi_stmt (si);
629               stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
630               loop_vec_info inner_loop_vinfo =
631                  STMT_VINFO_LOOP_VINFO (stmt_info);
632               gcc_assert (loop->inner == LOOP_VINFO_LOOP (inner_loop_vinfo));
633               STMT_VINFO_LOOP_VINFO (stmt_info) = res;
634            }
635         }
636       else
637         {
638           /* bb in current nest.  */
639           for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
640             {
641               gimple phi = gsi_stmt (si);
642               gimple_set_uid (phi, 0);
643               set_vinfo_for_stmt (phi, new_stmt_vec_info (phi, res, NULL));
644             }
645
646           for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
647             {
648               gimple stmt = gsi_stmt (si);
649               gimple_set_uid (stmt, 0);
650               set_vinfo_for_stmt (stmt, new_stmt_vec_info (stmt, res, NULL));
651             }
652         }
653     }
654
655   /* CHECKME: We want to visit all BBs before their successors (except for
656      latch blocks, for which this assertion wouldn't hold).  In the simple
657      case of the loop forms we allow, a dfs order of the BBs would the same
658      as reversed postorder traversal, so we are safe.  */
659
660    free (bbs);
661    bbs = XCNEWVEC (basic_block, loop->num_nodes);
662    nbbs = dfs_enumerate_from (loop->header, 0, bb_in_loop_p,
663                               bbs, loop->num_nodes, loop);
664    gcc_assert (nbbs == loop->num_nodes);
665
666   LOOP_VINFO_BBS (res) = bbs;
667   LOOP_VINFO_NITERS (res) = NULL;
668   LOOP_VINFO_NITERS_UNCHANGED (res) = NULL;
669   LOOP_VINFO_COST_MODEL_MIN_ITERS (res) = 0;
670   LOOP_VINFO_VECTORIZABLE_P (res) = 0;
671   LOOP_PEELING_FOR_ALIGNMENT (res) = 0;
672   LOOP_VINFO_VECT_FACTOR (res) = 0;
673   LOOP_VINFO_DATAREFS (res) = VEC_alloc (data_reference_p, heap, 10);
674   LOOP_VINFO_DDRS (res) = VEC_alloc (ddr_p, heap, 10 * 10);
675   LOOP_VINFO_UNALIGNED_DR (res) = NULL;
676   LOOP_VINFO_MAY_MISALIGN_STMTS (res) =
677     VEC_alloc (gimple, heap,
678                PARAM_VALUE (PARAM_VECT_MAX_VERSION_FOR_ALIGNMENT_CHECKS));
679   LOOP_VINFO_MAY_ALIAS_DDRS (res) =
680     VEC_alloc (ddr_p, heap,
681                PARAM_VALUE (PARAM_VECT_MAX_VERSION_FOR_ALIAS_CHECKS));
682   LOOP_VINFO_STRIDED_STORES (res) = VEC_alloc (gimple, heap, 10);
683   LOOP_VINFO_SLP_INSTANCES (res) = VEC_alloc (slp_instance, heap, 10);
684   LOOP_VINFO_SLP_UNROLLING_FACTOR (res) = 1;
685
686   return res;
687 }
688
689
690 /* Function destroy_loop_vec_info.
691
692    Free LOOP_VINFO struct, as well as all the stmt_vec_info structs of all the
693    stmts in the loop.  */
694
695 void
696 destroy_loop_vec_info (loop_vec_info loop_vinfo, bool clean_stmts)
697 {
698   struct loop *loop;
699   basic_block *bbs;
700   int nbbs;
701   gimple_stmt_iterator si;
702   int j;
703   VEC (slp_instance, heap) *slp_instances;
704   slp_instance instance;
705
706   if (!loop_vinfo)
707     return;
708
709   loop = LOOP_VINFO_LOOP (loop_vinfo);
710
711   bbs = LOOP_VINFO_BBS (loop_vinfo);
712   nbbs = loop->num_nodes;
713
714   if (!clean_stmts)
715     {
716       free (LOOP_VINFO_BBS (loop_vinfo));
717       free_data_refs (LOOP_VINFO_DATAREFS (loop_vinfo));
718       free_dependence_relations (LOOP_VINFO_DDRS (loop_vinfo));
719       VEC_free (gimple, heap, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo));
720
721       free (loop_vinfo);
722       loop->aux = NULL;
723       return;
724     }
725
726   for (j = 0; j < nbbs; j++)
727     {
728       basic_block bb = bbs[j];
729       for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
730         free_stmt_vec_info (gsi_stmt (si));
731
732       for (si = gsi_start_bb (bb); !gsi_end_p (si); )
733         {
734           gimple stmt = gsi_stmt (si);
735           stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
736
737           if (stmt_info)
738             {
739               /* Check if this is a "pattern stmt" (introduced by the
740                  vectorizer during the pattern recognition pass).  */
741               bool remove_stmt_p = false;
742               gimple orig_stmt = STMT_VINFO_RELATED_STMT (stmt_info);
743               if (orig_stmt)
744                 {
745                   stmt_vec_info orig_stmt_info = vinfo_for_stmt (orig_stmt);
746                   if (orig_stmt_info
747                       && STMT_VINFO_IN_PATTERN_P (orig_stmt_info))
748                     remove_stmt_p = true;
749                 }
750
751               /* Free stmt_vec_info.  */
752               free_stmt_vec_info (stmt);
753
754               /* Remove dead "pattern stmts".  */
755               if (remove_stmt_p)
756                 gsi_remove (&si, true);
757             }
758           gsi_next (&si);
759         }
760     }
761
762   free (LOOP_VINFO_BBS (loop_vinfo));
763   free_data_refs (LOOP_VINFO_DATAREFS (loop_vinfo));
764   free_dependence_relations (LOOP_VINFO_DDRS (loop_vinfo));
765   VEC_free (gimple, heap, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo));
766   VEC_free (ddr_p, heap, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo));
767   slp_instances = LOOP_VINFO_SLP_INSTANCES (loop_vinfo);
768   for (j = 0; VEC_iterate (slp_instance, slp_instances, j, instance); j++)
769     vect_free_slp_instance (instance);
770
771   VEC_free (slp_instance, heap, LOOP_VINFO_SLP_INSTANCES (loop_vinfo));
772   VEC_free (gimple, heap, LOOP_VINFO_STRIDED_STORES (loop_vinfo));
773
774   free (loop_vinfo);
775   loop->aux = NULL;
776 }
777
778
779 /* Function vect_analyze_loop_1.
780
781    Apply a set of analyses on LOOP, and create a loop_vec_info struct
782    for it. The different analyses will record information in the
783    loop_vec_info struct.  This is a subset of the analyses applied in
784    vect_analyze_loop, to be applied on an inner-loop nested in the loop
785    that is now considered for (outer-loop) vectorization.  */
786
787 static loop_vec_info
788 vect_analyze_loop_1 (struct loop *loop)
789 {
790   loop_vec_info loop_vinfo;
791
792   if (vect_print_dump_info (REPORT_DETAILS))
793     fprintf (vect_dump, "===== analyze_loop_nest_1 =====");
794
795   /* Check the CFG characteristics of the loop (nesting, entry/exit, etc.  */
796
797   loop_vinfo = vect_analyze_loop_form (loop);
798   if (!loop_vinfo)
799     {
800       if (vect_print_dump_info (REPORT_DETAILS))
801         fprintf (vect_dump, "bad inner-loop form.");
802       return NULL;
803     }
804
805   return loop_vinfo;
806 }
807
808
809 /* Function vect_analyze_loop_form.
810
811    Verify that certain CFG restrictions hold, including:
812    - the loop has a pre-header
813    - the loop has a single entry and exit
814    - the loop exit condition is simple enough, and the number of iterations
815      can be analyzed (a countable loop).  */
816
817 loop_vec_info
818 vect_analyze_loop_form (struct loop *loop)
819 {
820   loop_vec_info loop_vinfo;
821   gimple loop_cond;
822   tree number_of_iterations = NULL;
823   loop_vec_info inner_loop_vinfo = NULL;
824
825   if (vect_print_dump_info (REPORT_DETAILS))
826     fprintf (vect_dump, "=== vect_analyze_loop_form ===");
827
828   /* Different restrictions apply when we are considering an inner-most loop,
829      vs. an outer (nested) loop.  
830      (FORNOW. May want to relax some of these restrictions in the future).  */
831
832   if (!loop->inner)
833     {
834       /* Inner-most loop.  We currently require that the number of BBs is 
835          exactly 2 (the header and latch).  Vectorizable inner-most loops 
836          look like this:
837
838                         (pre-header)
839                            |
840                           header <--------+
841                            | |            |
842                            | +--> latch --+
843                            |
844                         (exit-bb)  */
845
846       if (loop->num_nodes != 2)
847         {
848           if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
849             fprintf (vect_dump, "not vectorized: too many BBs in loop.");
850           return NULL;
851         }
852
853       if (empty_block_p (loop->header))
854     {
855           if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
856             fprintf (vect_dump, "not vectorized: empty loop.");
857       return NULL;
858     }
859     }
860   else
861     {
862       struct loop *innerloop = loop->inner;
863       edge backedge, entryedge;
864
865       /* Nested loop. We currently require that the loop is doubly-nested,
866          contains a single inner loop, and the number of BBs is exactly 5. 
867          Vectorizable outer-loops look like this:
868
869                         (pre-header)
870                            |
871                           header <---+
872                            |         |
873                           inner-loop |
874                            |         |
875                           tail ------+
876                            | 
877                         (exit-bb)
878
879          The inner-loop has the properties expected of inner-most loops
880          as described above.  */
881
882       if ((loop->inner)->inner || (loop->inner)->next)
883         {
884           if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
885             fprintf (vect_dump, "not vectorized: multiple nested loops.");
886           return NULL;
887         }
888
889       /* Analyze the inner-loop.  */
890       inner_loop_vinfo = vect_analyze_loop_1 (loop->inner);
891       if (!inner_loop_vinfo)
892         {
893           if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
894             fprintf (vect_dump, "not vectorized: Bad inner loop.");
895           return NULL;
896         }
897
898       if (!expr_invariant_in_loop_p (loop,
899                                         LOOP_VINFO_NITERS (inner_loop_vinfo)))
900         {
901           if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
902             fprintf (vect_dump,
903                      "not vectorized: inner-loop count not invariant.");
904           destroy_loop_vec_info (inner_loop_vinfo, true);
905           return NULL;
906         }
907
908       if (loop->num_nodes != 5) 
909         {
910           if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
911             fprintf (vect_dump, "not vectorized: too many BBs in loop.");
912           destroy_loop_vec_info (inner_loop_vinfo, true);
913           return NULL;
914         }
915
916       gcc_assert (EDGE_COUNT (innerloop->header->preds) == 2);
917       backedge = EDGE_PRED (innerloop->header, 1);        
918       entryedge = EDGE_PRED (innerloop->header, 0);
919       if (EDGE_PRED (innerloop->header, 0)->src == innerloop->latch)
920         {
921           backedge = EDGE_PRED (innerloop->header, 0);
922           entryedge = EDGE_PRED (innerloop->header, 1); 
923         }
924         
925       if (entryedge->src != loop->header
926           || !single_exit (innerloop)
927           || single_exit (innerloop)->dest !=  EDGE_PRED (loop->latch, 0)->src)
928         {
929           if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
930             fprintf (vect_dump, "not vectorized: unsupported outerloop form.");
931           destroy_loop_vec_info (inner_loop_vinfo, true);
932           return NULL;
933         }
934
935       if (vect_print_dump_info (REPORT_DETAILS))
936         fprintf (vect_dump, "Considering outer-loop vectorization.");
937     }
938   
939   if (!single_exit (loop) 
940       || EDGE_COUNT (loop->header->preds) != 2)
941     {
942       if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
943         {
944           if (!single_exit (loop))
945             fprintf (vect_dump, "not vectorized: multiple exits.");
946           else if (EDGE_COUNT (loop->header->preds) != 2)
947             fprintf (vect_dump, "not vectorized: too many incoming edges.");
948         }
949       if (inner_loop_vinfo)
950         destroy_loop_vec_info (inner_loop_vinfo, true);
951       return NULL;
952     }
953
954   /* We assume that the loop exit condition is at the end of the loop. i.e,
955      that the loop is represented as a do-while (with a proper if-guard
956      before the loop if needed), where the loop header contains all the
957      executable statements, and the latch is empty.  */
958   if (!empty_block_p (loop->latch)
959         || phi_nodes (loop->latch))
960     {
961       if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
962         fprintf (vect_dump, "not vectorized: unexpected loop form.");
963       if (inner_loop_vinfo)
964         destroy_loop_vec_info (inner_loop_vinfo, true);
965       return NULL;
966     }
967
968   /* Make sure there exists a single-predecessor exit bb:  */
969   if (!single_pred_p (single_exit (loop)->dest))
970     {
971       edge e = single_exit (loop);
972       if (!(e->flags & EDGE_ABNORMAL))
973         {
974           split_loop_exit_edge (e);
975           if (vect_print_dump_info (REPORT_DETAILS))
976             fprintf (vect_dump, "split exit edge.");
977         }
978       else
979         {
980           if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
981             fprintf (vect_dump, "not vectorized: abnormal loop exit edge.");
982           if (inner_loop_vinfo)
983             destroy_loop_vec_info (inner_loop_vinfo, true);
984           return NULL;
985         }
986     }
987
988   loop_cond = vect_get_loop_niters (loop, &number_of_iterations);
989   if (!loop_cond)
990     {
991       if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
992         fprintf (vect_dump, "not vectorized: complicated exit condition.");
993       if (inner_loop_vinfo)
994         destroy_loop_vec_info (inner_loop_vinfo, true);
995       return NULL;
996     }
997   
998   if (!number_of_iterations) 
999     {
1000       if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
1001         fprintf (vect_dump, 
1002                  "not vectorized: number of iterations cannot be computed.");
1003       if (inner_loop_vinfo)
1004         destroy_loop_vec_info (inner_loop_vinfo, true);
1005       return NULL;
1006     }
1007
1008   if (chrec_contains_undetermined (number_of_iterations))
1009     {
1010       if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
1011         fprintf (vect_dump, "Infinite number of iterations.");
1012       if (inner_loop_vinfo)
1013         destroy_loop_vec_info (inner_loop_vinfo, true);
1014       return NULL;
1015     }
1016
1017   if (!NITERS_KNOWN_P (number_of_iterations))
1018     {
1019       if (vect_print_dump_info (REPORT_DETAILS))
1020         {
1021           fprintf (vect_dump, "Symbolic number of iterations is ");
1022           print_generic_expr (vect_dump, number_of_iterations, TDF_DETAILS);
1023         }
1024     }
1025   else if (TREE_INT_CST_LOW (number_of_iterations) == 0)
1026     {
1027       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
1028         fprintf (vect_dump, "not vectorized: number of iterations = 0.");
1029       if (inner_loop_vinfo)
1030         destroy_loop_vec_info (inner_loop_vinfo, false);
1031       return NULL;
1032     }
1033
1034   loop_vinfo = new_loop_vec_info (loop);
1035   LOOP_VINFO_NITERS (loop_vinfo) = number_of_iterations;
1036   LOOP_VINFO_NITERS_UNCHANGED (loop_vinfo) = number_of_iterations;
1037
1038   STMT_VINFO_TYPE (vinfo_for_stmt (loop_cond)) = loop_exit_ctrl_vec_info_type;
1039
1040   /* CHECKME: May want to keep it around it in the future.  */
1041   if (inner_loop_vinfo)
1042     destroy_loop_vec_info (inner_loop_vinfo, false);
1043
1044   gcc_assert (!loop->aux);
1045   loop->aux = loop_vinfo;
1046   return loop_vinfo;
1047 }
1048
1049
1050 /* Function vect_analyze_loop_operations.
1051
1052    Scan the loop stmts and make sure they are all vectorizable.  */
1053
1054 static bool
1055 vect_analyze_loop_operations (loop_vec_info loop_vinfo)
1056 {
1057   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
1058   basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
1059   int nbbs = loop->num_nodes;
1060   gimple_stmt_iterator si;
1061   unsigned int vectorization_factor = 0;
1062   int i;
1063   gimple phi;
1064   stmt_vec_info stmt_info;
1065   bool need_to_vectorize = false;
1066   int min_profitable_iters;
1067   int min_scalar_loop_bound;
1068   unsigned int th;
1069   bool only_slp_in_loop = true, ok;
1070
1071   if (vect_print_dump_info (REPORT_DETAILS))
1072     fprintf (vect_dump, "=== vect_analyze_loop_operations ===");
1073
1074   gcc_assert (LOOP_VINFO_VECT_FACTOR (loop_vinfo));
1075   vectorization_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
1076
1077   for (i = 0; i < nbbs; i++)
1078     {
1079       basic_block bb = bbs[i];
1080
1081       for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
1082         {
1083           phi = gsi_stmt (si);
1084           ok = true;
1085
1086           stmt_info = vinfo_for_stmt (phi);
1087           if (vect_print_dump_info (REPORT_DETAILS))
1088             {
1089               fprintf (vect_dump, "examining phi: ");
1090               print_gimple_stmt (vect_dump, phi, 0, TDF_SLIM);
1091             }
1092
1093           if (! is_loop_header_bb_p (bb))
1094             {
1095               /* inner-loop loop-closed exit phi in outer-loop vectorization
1096                  (i.e. a phi in the tail of the outer-loop).
1097                  FORNOW: we currently don't support the case that these phis
1098                  are not used in the outerloop, cause this case requires
1099                  to actually do something here.  */
1100               if (!STMT_VINFO_RELEVANT_P (stmt_info)
1101                   || STMT_VINFO_LIVE_P (stmt_info))
1102                 {
1103                   if (vect_print_dump_info (REPORT_DETAILS))
1104                     fprintf (vect_dump,
1105                              "Unsupported loop-closed phi in outer-loop.");
1106                   return false;
1107                 }
1108               continue;
1109             }
1110
1111           gcc_assert (stmt_info);
1112
1113           if (STMT_VINFO_LIVE_P (stmt_info))
1114             {
1115               /* FORNOW: not yet supported.  */
1116               if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
1117                 fprintf (vect_dump, "not vectorized: value used after loop.");
1118               return false;
1119             }
1120
1121           if (STMT_VINFO_RELEVANT (stmt_info) == vect_used_in_scope
1122               && STMT_VINFO_DEF_TYPE (stmt_info) != vect_induction_def)
1123             {
1124               /* A scalar-dependence cycle that we don't support.  */
1125               if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
1126                 fprintf (vect_dump, "not vectorized: scalar dependence cycle.");
1127               return false;
1128             }
1129
1130           if (STMT_VINFO_RELEVANT_P (stmt_info))
1131             {
1132               need_to_vectorize = true;
1133               if (STMT_VINFO_DEF_TYPE (stmt_info) == vect_induction_def)
1134                 ok = vectorizable_induction (phi, NULL, NULL);
1135             }
1136
1137           if (!ok)
1138             {
1139               if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
1140                 {
1141                   fprintf (vect_dump,
1142                            "not vectorized: relevant phi not supported: ");
1143                   print_gimple_stmt (vect_dump, phi, 0, TDF_SLIM);
1144                 }
1145               return false;
1146             }
1147         }
1148
1149       for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
1150         {
1151           gimple stmt = gsi_stmt (si);
1152           stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
1153
1154           gcc_assert (stmt_info);
1155
1156           if (!vect_analyze_stmt (stmt, &need_to_vectorize, NULL))
1157             return false;
1158
1159           if (STMT_VINFO_RELEVANT_P (stmt_info) && !PURE_SLP_STMT (stmt_info))
1160             /* STMT needs both SLP and loop-based vectorization.  */
1161             only_slp_in_loop = false;
1162         } 
1163     } /* bbs */
1164
1165   /* All operations in the loop are either irrelevant (deal with loop
1166      control, or dead), or only used outside the loop and can be moved
1167      out of the loop (e.g. invariants, inductions).  The loop can be
1168      optimized away by scalar optimizations.  We're better off not
1169      touching this loop.  */
1170   if (!need_to_vectorize)
1171     {
1172       if (vect_print_dump_info (REPORT_DETAILS))
1173         fprintf (vect_dump,
1174                  "All the computation can be taken out of the loop.");
1175       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
1176         fprintf (vect_dump,
1177                  "not vectorized: redundant loop. no profit to vectorize.");
1178       return false;
1179     }
1180
1181   /* If all the stmts in the loop can be SLPed, we perform only SLP, and
1182      vectorization factor of the loop is the unrolling factor required by the
1183      SLP instances.  If that unrolling factor is 1, we say, that we perform
1184      pure SLP on loop - cross iteration parallelism is not exploited.  */
1185   if (only_slp_in_loop)
1186     vectorization_factor = LOOP_VINFO_SLP_UNROLLING_FACTOR (loop_vinfo);
1187   else
1188     vectorization_factor = least_common_multiple (vectorization_factor,
1189                                 LOOP_VINFO_SLP_UNROLLING_FACTOR (loop_vinfo));
1190
1191   LOOP_VINFO_VECT_FACTOR (loop_vinfo) = vectorization_factor;
1192
1193   if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
1194       && vect_print_dump_info (REPORT_DETAILS))
1195     fprintf (vect_dump,
1196         "vectorization_factor = %d, niters = " HOST_WIDE_INT_PRINT_DEC,
1197         vectorization_factor, LOOP_VINFO_INT_NITERS (loop_vinfo));
1198
1199   if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
1200       && (LOOP_VINFO_INT_NITERS (loop_vinfo) < vectorization_factor))
1201     {
1202       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
1203         fprintf (vect_dump, "not vectorized: iteration count too small.");
1204       if (vect_print_dump_info (REPORT_DETAILS))
1205         fprintf (vect_dump,"not vectorized: iteration count smaller than "
1206                  "vectorization factor.");
1207       return false;
1208     }
1209
1210   /* Analyze cost. Decide if worth while to vectorize.  */
1211
1212   /* Once VF is set, SLP costs should be updated since the number of created
1213      vector stmts depends on VF.  */
1214   vect_update_slp_costs_according_to_vf (loop_vinfo);
1215
1216   min_profitable_iters = vect_estimate_min_profitable_iters (loop_vinfo);
1217   LOOP_VINFO_COST_MODEL_MIN_ITERS (loop_vinfo) = min_profitable_iters;
1218
1219   if (min_profitable_iters < 0)
1220     {
1221       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
1222         fprintf (vect_dump, "not vectorized: vectorization not profitable.");
1223       if (vect_print_dump_info (REPORT_DETAILS))
1224         fprintf (vect_dump, "not vectorized: vector version will never be "
1225                  "profitable.");
1226       return false;
1227     }
1228
1229   min_scalar_loop_bound = ((PARAM_VALUE (PARAM_MIN_VECT_LOOP_BOUND)
1230                             * vectorization_factor) - 1);
1231
1232   /* Use the cost model only if it is more conservative than user specified
1233      threshold.  */
1234
1235   th = (unsigned) min_scalar_loop_bound;
1236   if (min_profitable_iters
1237       && (!min_scalar_loop_bound
1238           || min_profitable_iters > min_scalar_loop_bound))
1239     th = (unsigned) min_profitable_iters;
1240
1241   if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
1242       && LOOP_VINFO_INT_NITERS (loop_vinfo) <= th)
1243     {
1244       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
1245         fprintf (vect_dump, "not vectorized: vectorization not "
1246                  "profitable.");
1247       if (vect_print_dump_info (REPORT_DETAILS))
1248         fprintf (vect_dump, "not vectorized: iteration count smaller than "
1249                  "user specified loop bound parameter or minimum "
1250                  "profitable iterations (whichever is more conservative).");
1251       return false;
1252     }
1253
1254   if (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
1255       || LOOP_VINFO_INT_NITERS (loop_vinfo) % vectorization_factor != 0
1256       || LOOP_PEELING_FOR_ALIGNMENT (loop_vinfo))
1257     {
1258       if (vect_print_dump_info (REPORT_DETAILS))
1259         fprintf (vect_dump, "epilog loop required.");
1260       if (!vect_can_advance_ivs_p (loop_vinfo))
1261         {
1262           if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
1263             fprintf (vect_dump,
1264                      "not vectorized: can't create epilog loop 1.");
1265           return false;
1266         }
1267       if (!slpeel_can_duplicate_loop_p (loop, single_exit (loop)))
1268         {
1269           if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
1270             fprintf (vect_dump,
1271                      "not vectorized: can't create epilog loop 2.");
1272           return false;
1273         }
1274     }
1275
1276   return true;
1277 }
1278
1279
1280 /* Function vect_analyze_loop.
1281
1282    Apply a set of analyses on LOOP, and create a loop_vec_info struct
1283    for it. The different analyses will record information in the
1284    loop_vec_info struct.  */
1285 loop_vec_info
1286 vect_analyze_loop (struct loop *loop)
1287 {
1288   bool ok;
1289   loop_vec_info loop_vinfo;
1290
1291   if (vect_print_dump_info (REPORT_DETAILS))
1292     fprintf (vect_dump, "===== analyze_loop_nest =====");
1293
1294   if (loop_outer (loop) 
1295       && loop_vec_info_for_loop (loop_outer (loop))
1296       && LOOP_VINFO_VECTORIZABLE_P (loop_vec_info_for_loop (loop_outer (loop))))
1297     {
1298       if (vect_print_dump_info (REPORT_DETAILS))
1299         fprintf (vect_dump, "outer-loop already vectorized.");
1300       return NULL;
1301     }
1302
1303   /* Check the CFG characteristics of the loop (nesting, entry/exit, etc.  */
1304
1305   loop_vinfo = vect_analyze_loop_form (loop);
1306   if (!loop_vinfo)
1307     {
1308       if (vect_print_dump_info (REPORT_DETAILS))
1309         fprintf (vect_dump, "bad loop form.");
1310       return NULL;
1311     }
1312
1313   /* Find all data references in the loop (which correspond to vdefs/vuses)
1314      and analyze their evolution in the loop.
1315
1316      FORNOW: Handle only simple, array references, which
1317      alignment can be forced, and aligned pointer-references.  */
1318
1319   ok = vect_analyze_data_refs (loop_vinfo, NULL);
1320   if (!ok)
1321     {
1322       if (vect_print_dump_info (REPORT_DETAILS))
1323         fprintf (vect_dump, "bad data references.");
1324       destroy_loop_vec_info (loop_vinfo, true);
1325       return NULL;
1326     }
1327
1328   /* Classify all cross-iteration scalar data-flow cycles.
1329      Cross-iteration cycles caused by virtual phis are analyzed separately.  */
1330
1331   vect_analyze_scalar_cycles (loop_vinfo);
1332
1333   vect_pattern_recog (loop_vinfo);
1334
1335   /* Data-flow analysis to detect stmts that do not need to be vectorized.  */
1336
1337   ok = vect_mark_stmts_to_be_vectorized (loop_vinfo);
1338   if (!ok)
1339     {
1340       if (vect_print_dump_info (REPORT_DETAILS))
1341         fprintf (vect_dump, "unexpected pattern.");
1342       destroy_loop_vec_info (loop_vinfo, true);
1343       return NULL;
1344     }
1345
1346   /* Analyze the alignment of the data-refs in the loop.
1347      Fail if a data reference is found that cannot be vectorized.  */
1348
1349   ok = vect_analyze_data_refs_alignment (loop_vinfo, NULL);
1350   if (!ok)
1351     {
1352       if (vect_print_dump_info (REPORT_DETAILS))
1353         fprintf (vect_dump, "bad data alignment.");
1354       destroy_loop_vec_info (loop_vinfo, true);
1355       return NULL;
1356     }
1357
1358   ok = vect_determine_vectorization_factor (loop_vinfo);
1359   if (!ok)
1360     {
1361       if (vect_print_dump_info (REPORT_DETAILS))
1362         fprintf (vect_dump, "can't determine vectorization factor.");
1363       destroy_loop_vec_info (loop_vinfo, true);
1364       return NULL;
1365     }
1366
1367   /* Analyze data dependences between the data-refs in the loop. 
1368      FORNOW: fail at the first data dependence that we encounter.  */
1369
1370   ok = vect_analyze_data_ref_dependences (loop_vinfo, NULL);
1371   if (!ok)
1372     {
1373       if (vect_print_dump_info (REPORT_DETAILS))
1374         fprintf (vect_dump, "bad data dependence.");
1375       destroy_loop_vec_info (loop_vinfo, true);
1376       return NULL;
1377     }
1378
1379   /* Analyze the access patterns of the data-refs in the loop (consecutive,
1380      complex, etc.). FORNOW: Only handle consecutive access pattern.  */
1381
1382   ok = vect_analyze_data_ref_accesses (loop_vinfo, NULL);
1383   if (!ok)
1384     {
1385       if (vect_print_dump_info (REPORT_DETAILS))
1386         fprintf (vect_dump, "bad data access.");
1387       destroy_loop_vec_info (loop_vinfo, true);
1388       return NULL;
1389     }
1390
1391   /* Prune the list of ddrs to be tested at run-time by versioning for alias.
1392      It is important to call pruning after vect_analyze_data_ref_accesses,
1393      since we use grouping information gathered by interleaving analysis.  */
1394   ok = vect_prune_runtime_alias_test_list (loop_vinfo);
1395   if (!ok)
1396     {
1397       if (vect_print_dump_info (REPORT_DETAILS))
1398         fprintf (vect_dump, "too long list of versioning for alias "
1399                             "run-time tests.");
1400       destroy_loop_vec_info (loop_vinfo, true);
1401       return NULL;
1402     }
1403
1404   /* Check the SLP opportunities in the loop, analyze and build SLP trees.  */
1405   ok = vect_analyze_slp (loop_vinfo, NULL);
1406   if (ok)
1407     {
1408       /* Decide which possible SLP instances to SLP.  */
1409       vect_make_slp_decision (loop_vinfo);
1410
1411       /* Find stmts that need to be both vectorized and SLPed.  */
1412       vect_detect_hybrid_slp (loop_vinfo);
1413     }
1414
1415   /* This pass will decide on using loop versioning and/or loop peeling in
1416      order to enhance the alignment of data references in the loop.  */
1417
1418   ok = vect_enhance_data_refs_alignment (loop_vinfo);
1419   if (!ok)
1420     {
1421       if (vect_print_dump_info (REPORT_DETAILS))
1422         fprintf (vect_dump, "bad data alignment.");
1423       destroy_loop_vec_info (loop_vinfo, true);
1424       return NULL;
1425     }
1426
1427   /* Scan all the operations in the loop and make sure they are
1428      vectorizable.  */
1429
1430   ok = vect_analyze_loop_operations (loop_vinfo);
1431   if (!ok)
1432     {
1433       if (vect_print_dump_info (REPORT_DETAILS))
1434         fprintf (vect_dump, "bad operation or unsupported loop bound.");
1435       destroy_loop_vec_info (loop_vinfo, true);
1436       return NULL;
1437     }
1438
1439   LOOP_VINFO_VECTORIZABLE_P (loop_vinfo) = 1;
1440
1441   return loop_vinfo;
1442 }
1443
1444
1445 /* Function reduction_code_for_scalar_code
1446
1447    Input:
1448    CODE - tree_code of a reduction operations.
1449
1450    Output:
1451    REDUC_CODE - the corresponding tree-code to be used to reduce the
1452       vector of partial results into a single scalar result (which
1453       will also reside in a vector).
1454
1455    Return TRUE if a corresponding REDUC_CODE was found, FALSE otherwise.  */
1456
1457 static bool
1458 reduction_code_for_scalar_code (enum tree_code code,
1459                                 enum tree_code *reduc_code)
1460 {
1461   switch (code)
1462   {
1463   case MAX_EXPR:
1464     *reduc_code = REDUC_MAX_EXPR;
1465     return true;
1466
1467   case MIN_EXPR:
1468     *reduc_code = REDUC_MIN_EXPR;
1469     return true;
1470
1471   case PLUS_EXPR:
1472     *reduc_code = REDUC_PLUS_EXPR;
1473     return true;
1474
1475   default:
1476     return false;
1477   }
1478 }
1479
1480
1481 /* Error reporting helper for vect_is_simple_reduction below. GIMPLE statement
1482    STMT is printed with a message MSG. */
1483
1484 static void
1485 report_vect_op (gimple stmt, const char *msg)
1486 {
1487   fprintf (vect_dump, "%s", msg);
1488   print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
1489 }
1490
1491
1492 /* Function vect_is_simple_reduction
1493
1494    Detect a cross-iteration def-use cycle that represents a simple
1495    reduction computation. We look for the following pattern:
1496
1497    loop_header:
1498      a1 = phi < a0, a2 >
1499      a3 = ...
1500      a2 = operation (a3, a1)
1501   
1502    such that:
1503    1. operation is commutative and associative and it is safe to 
1504       change the order of the computation.
1505    2. no uses for a2 in the loop (a2 is used out of the loop)
1506    3. no uses of a1 in the loop besides the reduction operation.
1507
1508    Condition 1 is tested here.
1509    Conditions 2,3 are tested in vect_mark_stmts_to_be_vectorized.  */
1510
1511 gimple
1512 vect_is_simple_reduction (loop_vec_info loop_info, gimple phi)
1513 {
1514   struct loop *loop = (gimple_bb (phi))->loop_father;
1515   struct loop *vect_loop = LOOP_VINFO_LOOP (loop_info);
1516   edge latch_e = loop_latch_edge (loop);
1517   tree loop_arg = PHI_ARG_DEF_FROM_EDGE (phi, latch_e);
1518   gimple def_stmt, def1, def2;
1519   enum tree_code code;
1520   tree op1, op2;
1521   tree type;
1522   int nloop_uses;
1523   tree name;
1524   imm_use_iterator imm_iter;
1525   use_operand_p use_p;
1526
1527   gcc_assert (loop == vect_loop || flow_loop_nested_p (vect_loop, loop));
1528
1529   name = PHI_RESULT (phi);
1530   nloop_uses = 0;
1531   FOR_EACH_IMM_USE_FAST (use_p, imm_iter, name)
1532     {
1533       gimple use_stmt = USE_STMT (use_p);
1534       if (flow_bb_inside_loop_p (loop, gimple_bb (use_stmt))
1535           && vinfo_for_stmt (use_stmt)
1536           && !is_pattern_stmt_p (vinfo_for_stmt (use_stmt)))
1537         nloop_uses++;
1538       if (nloop_uses > 1)
1539         {
1540           if (vect_print_dump_info (REPORT_DETAILS))
1541             fprintf (vect_dump, "reduction used in loop.");
1542           return NULL;
1543         }
1544     }
1545
1546   if (TREE_CODE (loop_arg) != SSA_NAME)
1547     {
1548       if (vect_print_dump_info (REPORT_DETAILS))
1549         {
1550           fprintf (vect_dump, "reduction: not ssa_name: ");
1551           print_generic_expr (vect_dump, loop_arg, TDF_SLIM);
1552         }
1553       return NULL;
1554     }
1555
1556   def_stmt = SSA_NAME_DEF_STMT (loop_arg);
1557   if (!def_stmt)
1558     {
1559       if (vect_print_dump_info (REPORT_DETAILS))
1560         fprintf (vect_dump, "reduction: no def_stmt.");
1561       return NULL;
1562     }
1563
1564   if (!is_gimple_assign (def_stmt))
1565     {
1566       if (vect_print_dump_info (REPORT_DETAILS))
1567         print_gimple_stmt (vect_dump, def_stmt, 0, TDF_SLIM);
1568       return NULL;
1569     }
1570
1571   name = gimple_assign_lhs (def_stmt);
1572   nloop_uses = 0;
1573   FOR_EACH_IMM_USE_FAST (use_p, imm_iter, name)
1574     {
1575       gimple use_stmt = USE_STMT (use_p);
1576       if (flow_bb_inside_loop_p (loop, gimple_bb (use_stmt))
1577           && vinfo_for_stmt (use_stmt)
1578           && !is_pattern_stmt_p (vinfo_for_stmt (use_stmt)))
1579         nloop_uses++;
1580       if (nloop_uses > 1)
1581         {
1582           if (vect_print_dump_info (REPORT_DETAILS))
1583             fprintf (vect_dump, "reduction used in loop.");
1584           return NULL;
1585         }
1586     }
1587
1588   code = gimple_assign_rhs_code (def_stmt);
1589
1590   if (!commutative_tree_code (code) || !associative_tree_code (code))
1591     {
1592       if (vect_print_dump_info (REPORT_DETAILS))
1593         report_vect_op (def_stmt, "reduction: not commutative/associative: ");
1594       return NULL;
1595     }
1596
1597   if (get_gimple_rhs_class (code) != GIMPLE_BINARY_RHS)
1598     {
1599       if (vect_print_dump_info (REPORT_DETAILS))
1600         report_vect_op (def_stmt, "reduction: not binary operation: ");
1601       return NULL;
1602     }
1603
1604   op1 = gimple_assign_rhs1 (def_stmt);
1605   op2 = gimple_assign_rhs2 (def_stmt);
1606   if (TREE_CODE (op1) != SSA_NAME || TREE_CODE (op2) != SSA_NAME)
1607     {
1608       if (vect_print_dump_info (REPORT_DETAILS))
1609         report_vect_op (def_stmt, "reduction: uses not ssa_names: ");
1610       return NULL;
1611     }
1612
1613   /* Check that it's ok to change the order of the computation.  */
1614   type = TREE_TYPE (gimple_assign_lhs (def_stmt));
1615   if (TYPE_MAIN_VARIANT (type) != TYPE_MAIN_VARIANT (TREE_TYPE (op1))
1616       || TYPE_MAIN_VARIANT (type) != TYPE_MAIN_VARIANT (TREE_TYPE (op2)))
1617     {
1618       if (vect_print_dump_info (REPORT_DETAILS))
1619         {
1620           fprintf (vect_dump, "reduction: multiple types: operation type: ");
1621           print_generic_expr (vect_dump, type, TDF_SLIM);
1622           fprintf (vect_dump, ", operands types: ");
1623           print_generic_expr (vect_dump, TREE_TYPE (op1), TDF_SLIM);
1624           fprintf (vect_dump, ",");
1625           print_generic_expr (vect_dump, TREE_TYPE (op2), TDF_SLIM);
1626         }
1627       return NULL;
1628     }
1629
1630   /* Generally, when vectorizing a reduction we change the order of the
1631      computation.  This may change the behavior of the program in some
1632      cases, so we need to check that this is ok.  One exception is when 
1633      vectorizing an outer-loop: the inner-loop is executed sequentially,
1634      and therefore vectorizing reductions in the inner-loop during
1635      outer-loop vectorization is safe.  */
1636
1637   /* CHECKME: check for !flag_finite_math_only too?  */
1638   if (SCALAR_FLOAT_TYPE_P (type) && !flag_associative_math
1639       && !nested_in_vect_loop_p (vect_loop, def_stmt)) 
1640     {
1641       /* Changing the order of operations changes the semantics.  */
1642       if (vect_print_dump_info (REPORT_DETAILS))
1643         report_vect_op (def_stmt, "reduction: unsafe fp math optimization: ");
1644       return NULL;
1645     }
1646   else if (INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_TRAPS (type)
1647            && !nested_in_vect_loop_p (vect_loop, def_stmt))
1648     {
1649       /* Changing the order of operations changes the semantics.  */
1650       if (vect_print_dump_info (REPORT_DETAILS))
1651         report_vect_op (def_stmt, "reduction: unsafe int math optimization: ");
1652       return NULL;
1653     }
1654   else if (SAT_FIXED_POINT_TYPE_P (type))
1655     {
1656       /* Changing the order of operations changes the semantics.  */
1657       if (vect_print_dump_info (REPORT_DETAILS))
1658         report_vect_op (def_stmt, 
1659                         "reduction: unsafe fixed-point math optimization: ");
1660       return NULL;
1661     }
1662
1663   /* reduction is safe. we're dealing with one of the following:
1664      1) integer arithmetic and no trapv
1665      2) floating point arithmetic, and special flags permit this optimization.
1666    */
1667   def1 = SSA_NAME_DEF_STMT (op1);
1668   def2 = SSA_NAME_DEF_STMT (op2);
1669   if (!def1 || !def2 || gimple_nop_p (def1) || gimple_nop_p (def2))
1670     {
1671       if (vect_print_dump_info (REPORT_DETAILS))
1672         report_vect_op (def_stmt, "reduction: no defs for operands: ");
1673       return NULL;
1674     }
1675
1676
1677   /* Check that one def is the reduction def, defined by PHI,
1678      the other def is either defined in the loop ("vect_internal_def"),
1679      or it's an induction (defined by a loop-header phi-node).  */
1680
1681   if (def2 == phi
1682       && flow_bb_inside_loop_p (loop, gimple_bb (def1))
1683       && (is_gimple_assign (def1)
1684           || STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def1)) == vect_induction_def
1685           || (gimple_code (def1) == GIMPLE_PHI
1686               && STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def1)) == vect_internal_def
1687               && !is_loop_header_bb_p (gimple_bb (def1)))))
1688     {
1689       if (vect_print_dump_info (REPORT_DETAILS))
1690         report_vect_op (def_stmt, "detected reduction:");
1691       return def_stmt;
1692     }
1693   else if (def1 == phi
1694            && flow_bb_inside_loop_p (loop, gimple_bb (def2))
1695            && (is_gimple_assign (def2)
1696                || STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def2)) == vect_induction_def
1697                || (gimple_code (def2) == GIMPLE_PHI
1698                    && STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def2)) == vect_internal_def
1699                    && !is_loop_header_bb_p (gimple_bb (def2)))))
1700     {
1701       /* Swap operands (just for simplicity - so that the rest of the code
1702          can assume that the reduction variable is always the last (second)
1703          argument).  */
1704       if (vect_print_dump_info (REPORT_DETAILS))
1705         report_vect_op (def_stmt ,
1706                         "detected reduction: need to swap operands:");
1707       swap_tree_operands (def_stmt, gimple_assign_rhs1_ptr (def_stmt),
1708                           gimple_assign_rhs2_ptr (def_stmt));
1709       return def_stmt;
1710     }
1711   else
1712     {
1713       if (vect_print_dump_info (REPORT_DETAILS))
1714         report_vect_op (def_stmt, "reduction: unknown pattern.");
1715       return NULL;
1716     }
1717 }
1718
1719
1720 /* Function vect_estimate_min_profitable_iters
1721
1722    Return the number of iterations required for the vector version of the
1723    loop to be profitable relative to the cost of the scalar version of the
1724    loop.
1725
1726    TODO: Take profile info into account before making vectorization
1727    decisions, if available.  */
1728
1729 int
1730 vect_estimate_min_profitable_iters (loop_vec_info loop_vinfo)
1731 {
1732   int i;
1733   int min_profitable_iters;
1734   int peel_iters_prologue;
1735   int peel_iters_epilogue;
1736   int vec_inside_cost = 0;
1737   int vec_outside_cost = 0;
1738   int scalar_single_iter_cost = 0;
1739   int scalar_outside_cost = 0;
1740   int vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
1741   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
1742   basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
1743   int nbbs = loop->num_nodes;
1744   int byte_misalign = LOOP_PEELING_FOR_ALIGNMENT (loop_vinfo);
1745   int peel_guard_costs = 0;
1746   int innerloop_iters = 0, factor;
1747   VEC (slp_instance, heap) *slp_instances;
1748   slp_instance instance;
1749
1750   /* Cost model disabled.  */
1751   if (!flag_vect_cost_model)
1752     {
1753       if (vect_print_dump_info (REPORT_COST))
1754         fprintf (vect_dump, "cost model disabled.");      
1755       return 0;
1756     }
1757
1758   /* Requires loop versioning tests to handle misalignment.  */
1759   if (VEC_length (gimple, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo)))
1760     {
1761       /*  FIXME: Make cost depend on complexity of individual check.  */
1762       vec_outside_cost +=
1763         VEC_length (gimple, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo));
1764       if (vect_print_dump_info (REPORT_COST))
1765         fprintf (vect_dump, "cost model: Adding cost of checks for loop "
1766                  "versioning to treat misalignment.\n");
1767     }
1768
1769   if (VEC_length (ddr_p, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo)))
1770     {
1771       /*  FIXME: Make cost depend on complexity of individual check.  */
1772       vec_outside_cost +=
1773         VEC_length (ddr_p, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo));
1774       if (vect_print_dump_info (REPORT_COST))
1775         fprintf (vect_dump, "cost model: Adding cost of checks for loop "
1776                  "versioning aliasing.\n");
1777     }
1778
1779   if (VEC_length (gimple, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo))
1780       || VEC_length (ddr_p, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo)))
1781     {
1782       vec_outside_cost += TARG_COND_TAKEN_BRANCH_COST;
1783     }
1784
1785   /* Count statements in scalar loop.  Using this as scalar cost for a single
1786      iteration for now.
1787
1788      TODO: Add outer loop support.
1789
1790      TODO: Consider assigning different costs to different scalar
1791      statements.  */
1792
1793   /* FORNOW.  */
1794   if (loop->inner)
1795     innerloop_iters = 50; /* FIXME */
1796
1797   for (i = 0; i < nbbs; i++)
1798     {
1799       gimple_stmt_iterator si;
1800       basic_block bb = bbs[i];
1801
1802       if (bb->loop_father == loop->inner)
1803         factor = innerloop_iters;
1804       else
1805         factor = 1;
1806
1807       for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
1808         {
1809           gimple stmt = gsi_stmt (si);
1810           stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
1811           /* Skip stmts that are not vectorized inside the loop.  */
1812           if (!STMT_VINFO_RELEVANT_P (stmt_info)
1813               && (!STMT_VINFO_LIVE_P (stmt_info)
1814                   || STMT_VINFO_DEF_TYPE (stmt_info) != vect_reduction_def))
1815             continue;
1816           scalar_single_iter_cost += cost_for_stmt (stmt) * factor;
1817           vec_inside_cost += STMT_VINFO_INSIDE_OF_LOOP_COST (stmt_info) * factor;
1818           /* FIXME: for stmts in the inner-loop in outer-loop vectorization,
1819              some of the "outside" costs are generated inside the outer-loop.  */
1820           vec_outside_cost += STMT_VINFO_OUTSIDE_OF_LOOP_COST (stmt_info);
1821         }
1822     }
1823
1824   /* Add additional cost for the peeled instructions in prologue and epilogue
1825      loop.
1826
1827      FORNOW: If we don't know the value of peel_iters for prologue or epilogue
1828      at compile-time - we assume it's vf/2 (the worst would be vf-1).
1829
1830      TODO: Build an expression that represents peel_iters for prologue and
1831      epilogue to be used in a run-time test.  */
1832
1833   if (byte_misalign < 0)
1834     {
1835       peel_iters_prologue = vf/2;
1836       if (vect_print_dump_info (REPORT_COST))
1837         fprintf (vect_dump, "cost model: "
1838                  "prologue peel iters set to vf/2.");
1839
1840       /* If peeling for alignment is unknown, loop bound of main loop becomes
1841          unknown.  */
1842       peel_iters_epilogue = vf/2;
1843       if (vect_print_dump_info (REPORT_COST))
1844         fprintf (vect_dump, "cost model: "
1845                  "epilogue peel iters set to vf/2 because "
1846                  "peeling for alignment is unknown .");
1847
1848       /* If peeled iterations are unknown, count a taken branch and a not taken
1849          branch per peeled loop. Even if scalar loop iterations are known,
1850          vector iterations are not known since peeled prologue iterations are
1851          not known. Hence guards remain the same.  */
1852       peel_guard_costs +=  2 * (TARG_COND_TAKEN_BRANCH_COST
1853                               + TARG_COND_NOT_TAKEN_BRANCH_COST);
1854     }
1855   else 
1856     {
1857       if (byte_misalign)
1858         {
1859           struct data_reference *dr = LOOP_VINFO_UNALIGNED_DR (loop_vinfo);
1860           int element_size = GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (DR_REF (dr))));
1861           tree vectype = STMT_VINFO_VECTYPE (vinfo_for_stmt (DR_STMT (dr)));
1862           int nelements = TYPE_VECTOR_SUBPARTS (vectype);
1863
1864           peel_iters_prologue = nelements - (byte_misalign / element_size);
1865         }
1866       else
1867         peel_iters_prologue = 0;
1868
1869       if (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo))
1870         {
1871           peel_iters_epilogue = vf/2;
1872           if (vect_print_dump_info (REPORT_COST))
1873             fprintf (vect_dump, "cost model: "
1874                      "epilogue peel iters set to vf/2 because "
1875                      "loop iterations are unknown .");
1876
1877           /* If peeled iterations are known but number of scalar loop
1878              iterations are unknown, count a taken branch per peeled loop.  */
1879           peel_guard_costs +=  2 * TARG_COND_TAKEN_BRANCH_COST;
1880
1881         }
1882       else      
1883         {
1884           int niters = LOOP_VINFO_INT_NITERS (loop_vinfo);
1885           peel_iters_prologue = niters < peel_iters_prologue ? 
1886                                         niters : peel_iters_prologue;
1887           peel_iters_epilogue = (niters - peel_iters_prologue) % vf;
1888         }
1889     }
1890
1891   vec_outside_cost += (peel_iters_prologue * scalar_single_iter_cost)
1892                       + (peel_iters_epilogue * scalar_single_iter_cost)
1893                       + peel_guard_costs;
1894
1895   /* FORNOW: The scalar outside cost is incremented in one of the
1896      following ways:
1897
1898      1. The vectorizer checks for alignment and aliasing and generates
1899      a condition that allows dynamic vectorization.  A cost model
1900      check is ANDED with the versioning condition.  Hence scalar code
1901      path now has the added cost of the versioning check.
1902
1903        if (cost > th & versioning_check)
1904          jmp to vector code
1905
1906      Hence run-time scalar is incremented by not-taken branch cost.
1907
1908      2. The vectorizer then checks if a prologue is required.  If the
1909      cost model check was not done before during versioning, it has to
1910      be done before the prologue check.
1911
1912        if (cost <= th)
1913          prologue = scalar_iters
1914        if (prologue == 0)
1915          jmp to vector code
1916        else
1917          execute prologue
1918        if (prologue == num_iters)
1919          go to exit
1920
1921      Hence the run-time scalar cost is incremented by a taken branch,
1922      plus a not-taken branch, plus a taken branch cost.
1923
1924      3. The vectorizer then checks if an epilogue is required.  If the
1925      cost model check was not done before during prologue check, it
1926      has to be done with the epilogue check.
1927
1928        if (prologue == 0)
1929          jmp to vector code
1930        else
1931          execute prologue
1932        if (prologue == num_iters)
1933          go to exit
1934        vector code:
1935          if ((cost <= th) | (scalar_iters-prologue-epilogue == 0))
1936            jmp to epilogue
1937
1938      Hence the run-time scalar cost should be incremented by 2 taken
1939      branches.
1940
1941      TODO: The back end may reorder the BBS's differently and reverse
1942      conditions/branch directions.  Change the estimates below to
1943      something more reasonable.  */
1944
1945   /* If the number of iterations is known and we do not do versioning, we can
1946      decide whether to vectorize at compile time. Hence the scalar version
1947      do not carry cost model guard costs.  */
1948   if (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
1949       || VEC_length (gimple, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo))
1950       || VEC_length (ddr_p, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo)))
1951     {
1952       /* Cost model check occurs at versioning.  */
1953       if (VEC_length (gimple, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo))
1954           || VEC_length (ddr_p, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo)))
1955         scalar_outside_cost += TARG_COND_NOT_TAKEN_BRANCH_COST;
1956       else
1957         {
1958           /* Cost model check occurs at prologue generation.  */
1959           if (LOOP_PEELING_FOR_ALIGNMENT (loop_vinfo) < 0)
1960             scalar_outside_cost += 2 * TARG_COND_TAKEN_BRANCH_COST
1961               + TARG_COND_NOT_TAKEN_BRANCH_COST;
1962           /* Cost model check occurs at epilogue generation.  */
1963           else
1964             scalar_outside_cost += 2 * TARG_COND_TAKEN_BRANCH_COST;
1965         }
1966     }
1967
1968   /* Add SLP costs.  */
1969   slp_instances = LOOP_VINFO_SLP_INSTANCES (loop_vinfo);
1970   for (i = 0; VEC_iterate (slp_instance, slp_instances, i, instance); i++)
1971     {
1972       vec_outside_cost += SLP_INSTANCE_OUTSIDE_OF_LOOP_COST (instance);
1973       vec_inside_cost += SLP_INSTANCE_INSIDE_OF_LOOP_COST (instance);
1974     }
1975
1976   /* Calculate number of iterations required to make the vector version 
1977      profitable, relative to the loop bodies only. The following condition
1978      must hold true: 
1979      SIC * niters + SOC > VIC * ((niters-PL_ITERS-EP_ITERS)/VF) + VOC
1980      where
1981      SIC = scalar iteration cost, VIC = vector iteration cost,
1982      VOC = vector outside cost, VF = vectorization factor,
1983      PL_ITERS = prologue iterations, EP_ITERS= epilogue iterations
1984      SOC = scalar outside cost for run time cost model check.  */
1985
1986   if ((scalar_single_iter_cost * vf) > vec_inside_cost)
1987     {
1988       if (vec_outside_cost <= 0)
1989         min_profitable_iters = 1;
1990       else
1991         {
1992           min_profitable_iters = ((vec_outside_cost - scalar_outside_cost) * vf
1993                                   - vec_inside_cost * peel_iters_prologue
1994                                   - vec_inside_cost * peel_iters_epilogue)
1995                                  / ((scalar_single_iter_cost * vf)
1996                                     - vec_inside_cost);
1997
1998           if ((scalar_single_iter_cost * vf * min_profitable_iters)
1999               <= ((vec_inside_cost * min_profitable_iters)
2000                   + ((vec_outside_cost - scalar_outside_cost) * vf)))
2001             min_profitable_iters++;
2002         }
2003     }
2004   /* vector version will never be profitable.  */
2005   else
2006     {
2007       if (vect_print_dump_info (REPORT_COST))
2008         fprintf (vect_dump, "cost model: vector iteration cost = %d "
2009                  "is divisible by scalar iteration cost = %d by a factor "
2010                  "greater than or equal to the vectorization factor = %d .",
2011                  vec_inside_cost, scalar_single_iter_cost, vf);
2012       return -1;
2013     }
2014
2015   if (vect_print_dump_info (REPORT_COST))
2016     {
2017       fprintf (vect_dump, "Cost model analysis: \n");
2018       fprintf (vect_dump, "  Vector inside of loop cost: %d\n",
2019                vec_inside_cost);
2020       fprintf (vect_dump, "  Vector outside of loop cost: %d\n",
2021                vec_outside_cost);
2022       fprintf (vect_dump, "  Scalar iteration cost: %d\n",
2023                scalar_single_iter_cost);
2024       fprintf (vect_dump, "  Scalar outside cost: %d\n", scalar_outside_cost);
2025       fprintf (vect_dump, "  prologue iterations: %d\n",
2026                peel_iters_prologue);
2027       fprintf (vect_dump, "  epilogue iterations: %d\n",
2028                peel_iters_epilogue);
2029       fprintf (vect_dump, "  Calculated minimum iters for profitability: %d\n",
2030                min_profitable_iters);
2031     }
2032
2033   min_profitable_iters = 
2034         min_profitable_iters < vf ? vf : min_profitable_iters;
2035
2036   /* Because the condition we create is:
2037      if (niters <= min_profitable_iters)
2038        then skip the vectorized loop.  */
2039   min_profitable_iters--;
2040
2041   if (vect_print_dump_info (REPORT_COST))
2042     fprintf (vect_dump, "  Profitability threshold = %d\n",
2043              min_profitable_iters);
2044     
2045   return min_profitable_iters;
2046 }
2047
2048
2049 /* TODO: Close dependency between vect_model_*_cost and vectorizable_* 
2050    functions. Design better to avoid maintenance issues.  */
2051     
2052 /* Function vect_model_reduction_cost.  
2053
2054    Models cost for a reduction operation, including the vector ops 
2055    generated within the strip-mine loop, the initial definition before
2056    the loop, and the epilogue code that must be generated.  */
2057
2058 static bool 
2059 vect_model_reduction_cost (stmt_vec_info stmt_info, enum tree_code reduc_code,
2060                            int ncopies)
2061 {
2062   int outer_cost = 0;
2063   enum tree_code code;
2064   optab optab;
2065   tree vectype;
2066   gimple stmt, orig_stmt;
2067   tree reduction_op;
2068   enum machine_mode mode;
2069   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
2070   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
2071
2072
2073   /* Cost of reduction op inside loop.  */
2074   STMT_VINFO_INSIDE_OF_LOOP_COST (stmt_info) += ncopies * TARG_VEC_STMT_COST;
2075
2076   stmt = STMT_VINFO_STMT (stmt_info);
2077
2078   switch (get_gimple_rhs_class (gimple_assign_rhs_code (stmt)))
2079     {
2080     case GIMPLE_SINGLE_RHS:
2081       gcc_assert (TREE_OPERAND_LENGTH (gimple_assign_rhs1 (stmt)) == ternary_op);
2082       reduction_op = TREE_OPERAND (gimple_assign_rhs1 (stmt), 2);
2083       break;
2084     case GIMPLE_UNARY_RHS:
2085       reduction_op = gimple_assign_rhs1 (stmt);
2086       break;
2087     case GIMPLE_BINARY_RHS:
2088       reduction_op = gimple_assign_rhs2 (stmt);
2089       break;
2090     default:
2091       gcc_unreachable ();
2092     }
2093
2094   vectype = get_vectype_for_scalar_type (TREE_TYPE (reduction_op));
2095   if (!vectype)
2096     {
2097       if (vect_print_dump_info (REPORT_COST))
2098         {
2099           fprintf (vect_dump, "unsupported data-type ");
2100           print_generic_expr (vect_dump, TREE_TYPE (reduction_op), TDF_SLIM);
2101         }
2102       return false;
2103    }
2104   
2105   mode = TYPE_MODE (vectype);
2106   orig_stmt = STMT_VINFO_RELATED_STMT (stmt_info);
2107
2108   if (!orig_stmt) 
2109     orig_stmt = STMT_VINFO_STMT (stmt_info);
2110
2111   code = gimple_assign_rhs_code (orig_stmt);
2112
2113   /* Add in cost for initial definition.  */
2114   outer_cost += TARG_SCALAR_TO_VEC_COST;
2115
2116   /* Determine cost of epilogue code.
2117
2118      We have a reduction operator that will reduce the vector in one statement.
2119      Also requires scalar extract.  */
2120
2121   if (!nested_in_vect_loop_p (loop, orig_stmt))
2122     {
2123       if (reduc_code != ERROR_MARK)
2124         outer_cost += TARG_VEC_STMT_COST + TARG_VEC_TO_SCALAR_COST;
2125       else 
2126         {
2127           int vec_size_in_bits = tree_low_cst (TYPE_SIZE (vectype), 1);
2128           tree bitsize =
2129             TYPE_SIZE (TREE_TYPE (gimple_assign_lhs (orig_stmt)));
2130           int element_bitsize = tree_low_cst (bitsize, 1);
2131           int nelements = vec_size_in_bits / element_bitsize;
2132
2133           optab = optab_for_tree_code (code, vectype, optab_default);
2134
2135           /* We have a whole vector shift available.  */
2136           if (VECTOR_MODE_P (mode)
2137               && optab_handler (optab, mode)->insn_code != CODE_FOR_nothing
2138               && optab_handler (vec_shr_optab, mode)->insn_code != CODE_FOR_nothing)
2139             /* Final reduction via vector shifts and the reduction operator. Also
2140                requires scalar extract.  */
2141             outer_cost += ((exact_log2(nelements) * 2) * TARG_VEC_STMT_COST
2142                                 + TARG_VEC_TO_SCALAR_COST); 
2143           else
2144             /* Use extracts and reduction op for final reduction.  For N elements,
2145                we have N extracts and N-1 reduction ops.  */
2146             outer_cost += ((nelements + nelements - 1) * TARG_VEC_STMT_COST);
2147         }
2148     }
2149
2150   STMT_VINFO_OUTSIDE_OF_LOOP_COST (stmt_info) = outer_cost;
2151
2152   if (vect_print_dump_info (REPORT_COST))
2153     fprintf (vect_dump, "vect_model_reduction_cost: inside_cost = %d, "
2154              "outside_cost = %d .", STMT_VINFO_INSIDE_OF_LOOP_COST (stmt_info),
2155              STMT_VINFO_OUTSIDE_OF_LOOP_COST (stmt_info));
2156
2157   return true;
2158 }
2159
2160
2161 /* Function vect_model_induction_cost.
2162
2163    Models cost for induction operations.  */
2164
2165 static void
2166 vect_model_induction_cost (stmt_vec_info stmt_info, int ncopies)
2167 {
2168   /* loop cost for vec_loop.  */
2169   STMT_VINFO_INSIDE_OF_LOOP_COST (stmt_info) = ncopies * TARG_VEC_STMT_COST;
2170   /* prologue cost for vec_init and vec_step.  */
2171   STMT_VINFO_OUTSIDE_OF_LOOP_COST (stmt_info) = 2 * TARG_SCALAR_TO_VEC_COST;
2172   
2173   if (vect_print_dump_info (REPORT_COST))
2174     fprintf (vect_dump, "vect_model_induction_cost: inside_cost = %d, "
2175              "outside_cost = %d .", STMT_VINFO_INSIDE_OF_LOOP_COST (stmt_info),
2176              STMT_VINFO_OUTSIDE_OF_LOOP_COST (stmt_info));
2177 }
2178
2179
2180 /* Function get_initial_def_for_induction
2181
2182    Input:
2183    STMT - a stmt that performs an induction operation in the loop.
2184    IV_PHI - the initial value of the induction variable
2185
2186    Output:
2187    Return a vector variable, initialized with the first VF values of
2188    the induction variable. E.g., for an iv with IV_PHI='X' and
2189    evolution S, for a vector of 4 units, we want to return: 
2190    [X, X + S, X + 2*S, X + 3*S].  */
2191
2192 static tree
2193 get_initial_def_for_induction (gimple iv_phi)
2194 {
2195   stmt_vec_info stmt_vinfo = vinfo_for_stmt (iv_phi);
2196   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
2197   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
2198   tree scalar_type = TREE_TYPE (gimple_phi_result (iv_phi));
2199   tree vectype; 
2200   int nunits;
2201   edge pe = loop_preheader_edge (loop);
2202   struct loop *iv_loop;
2203   basic_block new_bb;
2204   tree vec, vec_init, vec_step, t;
2205   tree access_fn;
2206   tree new_var;
2207   tree new_name;
2208   gimple init_stmt, induction_phi, new_stmt;
2209   tree induc_def, vec_def, vec_dest;
2210   tree init_expr, step_expr;
2211   int vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
2212   int i;
2213   bool ok;
2214   int ncopies;
2215   tree expr;
2216   stmt_vec_info phi_info = vinfo_for_stmt (iv_phi);
2217   bool nested_in_vect_loop = false;
2218   gimple_seq stmts = NULL;
2219   imm_use_iterator imm_iter;
2220   use_operand_p use_p;
2221   gimple exit_phi;
2222   edge latch_e;
2223   tree loop_arg;
2224   gimple_stmt_iterator si;
2225   basic_block bb = gimple_bb (iv_phi);
2226   tree stepvectype;
2227
2228   vectype = get_vectype_for_scalar_type (scalar_type);
2229   gcc_assert (vectype);
2230   nunits = TYPE_VECTOR_SUBPARTS (vectype);
2231   ncopies = vf / nunits;
2232
2233   gcc_assert (phi_info);
2234   gcc_assert (ncopies >= 1);
2235
2236   /* Find the first insertion point in the BB.  */
2237   si = gsi_after_labels (bb);
2238
2239   if (INTEGRAL_TYPE_P (scalar_type))
2240     step_expr = build_int_cst (scalar_type, 0);
2241   else if (POINTER_TYPE_P (scalar_type))
2242     step_expr = build_int_cst (sizetype, 0);
2243   else
2244     step_expr = build_real (scalar_type, dconst0);
2245
2246   /* Is phi in an inner-loop, while vectorizing an enclosing outer-loop?  */
2247   if (nested_in_vect_loop_p (loop, iv_phi))
2248     {
2249       nested_in_vect_loop = true;
2250       iv_loop = loop->inner;
2251     }
2252   else
2253     iv_loop = loop;
2254   gcc_assert (iv_loop == (gimple_bb (iv_phi))->loop_father);
2255
2256   latch_e = loop_latch_edge (iv_loop);
2257   loop_arg = PHI_ARG_DEF_FROM_EDGE (iv_phi, latch_e);
2258
2259   access_fn = analyze_scalar_evolution (iv_loop, PHI_RESULT (iv_phi));
2260   gcc_assert (access_fn);
2261   ok = vect_is_simple_iv_evolution (iv_loop->num, access_fn,
2262                                   &init_expr, &step_expr);
2263   gcc_assert (ok);
2264   pe = loop_preheader_edge (iv_loop);
2265
2266   /* Create the vector that holds the initial_value of the induction.  */
2267   if (nested_in_vect_loop)
2268     {
2269       /* iv_loop is nested in the loop to be vectorized.  init_expr had already
2270          been created during vectorization of previous stmts; We obtain it from
2271          the STMT_VINFO_VEC_STMT of the defining stmt. */
2272       tree iv_def = PHI_ARG_DEF_FROM_EDGE (iv_phi, loop_preheader_edge (iv_loop));
2273       vec_init = vect_get_vec_def_for_operand (iv_def, iv_phi, NULL);
2274     }
2275   else
2276     {
2277       /* iv_loop is the loop to be vectorized. Create:
2278          vec_init = [X, X+S, X+2*S, X+3*S] (S = step_expr, X = init_expr)  */
2279       new_var = vect_get_new_vect_var (scalar_type, vect_scalar_var, "var_");
2280       add_referenced_var (new_var);
2281
2282       new_name = force_gimple_operand (init_expr, &stmts, false, new_var);
2283       if (stmts)
2284         {
2285           new_bb = gsi_insert_seq_on_edge_immediate (pe, stmts);
2286           gcc_assert (!new_bb);
2287         }
2288
2289       t = NULL_TREE;
2290       t = tree_cons (NULL_TREE, init_expr, t);
2291       for (i = 1; i < nunits; i++)
2292         {
2293           /* Create: new_name_i = new_name + step_expr  */
2294           enum tree_code code = POINTER_TYPE_P (scalar_type)
2295                                 ? POINTER_PLUS_EXPR : PLUS_EXPR;
2296           init_stmt = gimple_build_assign_with_ops (code, new_var,
2297                                                     new_name, step_expr);
2298           new_name = make_ssa_name (new_var, init_stmt);
2299           gimple_assign_set_lhs (init_stmt, new_name);
2300
2301           new_bb = gsi_insert_on_edge_immediate (pe, init_stmt);
2302           gcc_assert (!new_bb);
2303
2304           if (vect_print_dump_info (REPORT_DETAILS))
2305             {
2306               fprintf (vect_dump, "created new init_stmt: ");
2307               print_gimple_stmt (vect_dump, init_stmt, 0, TDF_SLIM);
2308             }
2309           t = tree_cons (NULL_TREE, new_name, t);
2310         }
2311       /* Create a vector from [new_name_0, new_name_1, ..., new_name_nunits-1]  */
2312       vec = build_constructor_from_list (vectype, nreverse (t));
2313       vec_init = vect_init_vector (iv_phi, vec, vectype, NULL);
2314     }
2315
2316
2317   /* Create the vector that holds the step of the induction.  */
2318   if (nested_in_vect_loop)
2319     /* iv_loop is nested in the loop to be vectorized. Generate:
2320        vec_step = [S, S, S, S]  */
2321     new_name = step_expr;
2322   else
2323     {
2324       /* iv_loop is the loop to be vectorized. Generate:
2325           vec_step = [VF*S, VF*S, VF*S, VF*S]  */
2326       expr = build_int_cst (TREE_TYPE (step_expr), vf);
2327       new_name = fold_build2 (MULT_EXPR, TREE_TYPE (step_expr),
2328                               expr, step_expr);
2329     }
2330
2331   t = NULL_TREE;
2332   for (i = 0; i < nunits; i++)
2333     t = tree_cons (NULL_TREE, unshare_expr (new_name), t);
2334   gcc_assert (CONSTANT_CLASS_P (new_name));
2335   stepvectype = get_vectype_for_scalar_type (TREE_TYPE (new_name));
2336   gcc_assert (stepvectype);
2337   vec = build_vector (stepvectype, t);
2338   vec_step = vect_init_vector (iv_phi, vec, stepvectype, NULL);
2339
2340
2341   /* Create the following def-use cycle:
2342      loop prolog:
2343          vec_init = ...
2344          vec_step = ...
2345      loop:
2346          vec_iv = PHI <vec_init, vec_loop>
2347          ...
2348          STMT
2349          ...
2350          vec_loop = vec_iv + vec_step;  */
2351
2352   /* Create the induction-phi that defines the induction-operand.  */
2353   vec_dest = vect_get_new_vect_var (vectype, vect_simple_var, "vec_iv_");
2354   add_referenced_var (vec_dest);
2355   induction_phi = create_phi_node (vec_dest, iv_loop->header);
2356   set_vinfo_for_stmt (induction_phi,
2357                       new_stmt_vec_info (induction_phi, loop_vinfo, NULL));
2358   induc_def = PHI_RESULT (induction_phi);
2359
2360   /* Create the iv update inside the loop  */
2361   new_stmt = gimple_build_assign_with_ops (PLUS_EXPR, vec_dest,
2362                                            induc_def, vec_step);
2363   vec_def = make_ssa_name (vec_dest, new_stmt);
2364   gimple_assign_set_lhs (new_stmt, vec_def);
2365   gsi_insert_before (&si, new_stmt, GSI_SAME_STMT);
2366   set_vinfo_for_stmt (new_stmt, new_stmt_vec_info (new_stmt, loop_vinfo, 
2367                                                    NULL));
2368
2369   /* Set the arguments of the phi node:  */
2370   add_phi_arg (induction_phi, vec_init, pe);
2371   add_phi_arg (induction_phi, vec_def, loop_latch_edge (iv_loop));
2372
2373
2374   /* In case that vectorization factor (VF) is bigger than the number
2375      of elements that we can fit in a vectype (nunits), we have to generate
2376      more than one vector stmt - i.e - we need to "unroll" the
2377      vector stmt by a factor VF/nunits.  For more details see documentation
2378      in vectorizable_operation.  */
2379   
2380   if (ncopies > 1)
2381     {
2382       stmt_vec_info prev_stmt_vinfo;
2383       /* FORNOW. This restriction should be relaxed.  */
2384       gcc_assert (!nested_in_vect_loop);
2385
2386       /* Create the vector that holds the step of the induction.  */
2387       expr = build_int_cst (TREE_TYPE (step_expr), nunits);
2388       new_name = fold_build2 (MULT_EXPR, TREE_TYPE (step_expr),
2389                               expr, step_expr);
2390       t = NULL_TREE;
2391       for (i = 0; i < nunits; i++)
2392         t = tree_cons (NULL_TREE, unshare_expr (new_name), t);
2393       gcc_assert (CONSTANT_CLASS_P (new_name));
2394       vec = build_vector (stepvectype, t);
2395       vec_step = vect_init_vector (iv_phi, vec, stepvectype, NULL);
2396
2397       vec_def = induc_def;
2398       prev_stmt_vinfo = vinfo_for_stmt (induction_phi);
2399       for (i = 1; i < ncopies; i++)
2400         {
2401           /* vec_i = vec_prev + vec_step  */
2402           new_stmt = gimple_build_assign_with_ops (PLUS_EXPR, vec_dest,
2403                                                    vec_def, vec_step);
2404           vec_def = make_ssa_name (vec_dest, new_stmt);
2405           gimple_assign_set_lhs (new_stmt, vec_def);
2406
2407           gsi_insert_before (&si, new_stmt, GSI_SAME_STMT);
2408           set_vinfo_for_stmt (new_stmt,
2409                               new_stmt_vec_info (new_stmt, loop_vinfo, NULL));
2410           STMT_VINFO_RELATED_STMT (prev_stmt_vinfo) = new_stmt;
2411           prev_stmt_vinfo = vinfo_for_stmt (new_stmt); 
2412         }
2413     }
2414
2415   if (nested_in_vect_loop)
2416     {
2417       /* Find the loop-closed exit-phi of the induction, and record
2418          the final vector of induction results:  */
2419       exit_phi = NULL;
2420       FOR_EACH_IMM_USE_FAST (use_p, imm_iter, loop_arg)
2421         {
2422           if (!flow_bb_inside_loop_p (iv_loop, gimple_bb (USE_STMT (use_p))))
2423             {
2424               exit_phi = USE_STMT (use_p);
2425               break;
2426             }
2427         }
2428       if (exit_phi) 
2429         {
2430           stmt_vec_info stmt_vinfo = vinfo_for_stmt (exit_phi);
2431           /* FORNOW. Currently not supporting the case that an inner-loop induction
2432              is not used in the outer-loop (i.e. only outside the outer-loop).  */
2433           gcc_assert (STMT_VINFO_RELEVANT_P (stmt_vinfo)
2434                       && !STMT_VINFO_LIVE_P (stmt_vinfo));
2435
2436           STMT_VINFO_VEC_STMT (stmt_vinfo) = new_stmt;
2437           if (vect_print_dump_info (REPORT_DETAILS))
2438             {
2439               fprintf (vect_dump, "vector of inductions after inner-loop:");
2440               print_gimple_stmt (vect_dump, new_stmt, 0, TDF_SLIM);
2441             }
2442         }
2443     }
2444
2445
2446   if (vect_print_dump_info (REPORT_DETAILS))
2447     {
2448       fprintf (vect_dump, "transform induction: created def-use cycle: ");
2449       print_gimple_stmt (vect_dump, induction_phi, 0, TDF_SLIM);
2450       fprintf (vect_dump, "\n");
2451       print_gimple_stmt (vect_dump, SSA_NAME_DEF_STMT (vec_def), 0, TDF_SLIM);
2452     }
2453
2454   STMT_VINFO_VEC_STMT (phi_info) = induction_phi;
2455   return induc_def;
2456 }
2457
2458
2459 /* Function get_initial_def_for_reduction
2460
2461    Input:
2462    STMT - a stmt that performs a reduction operation in the loop.
2463    INIT_VAL - the initial value of the reduction variable
2464
2465    Output:
2466    ADJUSTMENT_DEF - a tree that holds a value to be added to the final result
2467         of the reduction (used for adjusting the epilog - see below).
2468    Return a vector variable, initialized according to the operation that STMT
2469         performs. This vector will be used as the initial value of the
2470         vector of partial results.
2471
2472    Option1 (adjust in epilog): Initialize the vector as follows:
2473      add:         [0,0,...,0,0]
2474      mult:        [1,1,...,1,1]
2475      min/max:     [init_val,init_val,..,init_val,init_val]
2476      bit and/or:  [init_val,init_val,..,init_val,init_val]
2477    and when necessary (e.g. add/mult case) let the caller know
2478    that it needs to adjust the result by init_val.
2479
2480    Option2: Initialize the vector as follows:
2481      add:         [0,0,...,0,init_val]
2482      mult:        [1,1,...,1,init_val]
2483      min/max:     [init_val,init_val,...,init_val]
2484      bit and/or:  [init_val,init_val,...,init_val]
2485    and no adjustments are needed.
2486
2487    For example, for the following code:
2488
2489    s = init_val;
2490    for (i=0;i<n;i++)
2491      s = s + a[i];
2492
2493    STMT is 's = s + a[i]', and the reduction variable is 's'.
2494    For a vector of 4 units, we want to return either [0,0,0,init_val],
2495    or [0,0,0,0] and let the caller know that it needs to adjust
2496    the result at the end by 'init_val'.
2497
2498    FORNOW, we are using the 'adjust in epilog' scheme, because this way the
2499    initialization vector is simpler (same element in all entries).
2500    A cost model should help decide between these two schemes.  */
2501
2502 tree
2503 get_initial_def_for_reduction (gimple stmt, tree init_val, tree *adjustment_def)
2504 {
2505   stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt);
2506   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
2507   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
2508   tree scalar_type = TREE_TYPE (init_val);
2509   tree vectype = get_vectype_for_scalar_type (scalar_type);
2510   int nunits;
2511   enum tree_code code = gimple_assign_rhs_code (stmt);
2512   tree def_for_init;
2513   tree init_def;
2514   tree t = NULL_TREE;
2515   int i;
2516   bool nested_in_vect_loop = false; 
2517
2518   gcc_assert (vectype);
2519   nunits = TYPE_VECTOR_SUBPARTS (vectype);
2520
2521   gcc_assert (POINTER_TYPE_P (scalar_type) || INTEGRAL_TYPE_P (scalar_type)
2522               || SCALAR_FLOAT_TYPE_P (scalar_type));
2523   if (nested_in_vect_loop_p (loop, stmt))
2524     nested_in_vect_loop = true;
2525   else
2526     gcc_assert (loop == (gimple_bb (stmt))->loop_father);
2527
2528   switch (code)
2529   {
2530   case WIDEN_SUM_EXPR:
2531   case DOT_PROD_EXPR:
2532   case PLUS_EXPR:
2533     if (nested_in_vect_loop)
2534       *adjustment_def = vect_get_vec_def_for_operand (init_val, stmt, NULL);
2535     else
2536       *adjustment_def = init_val;
2537     /* Create a vector of zeros for init_def.  */
2538     if (SCALAR_FLOAT_TYPE_P (scalar_type))
2539       def_for_init = build_real (scalar_type, dconst0);
2540     else
2541       def_for_init = build_int_cst (scalar_type, 0);
2542       
2543     for (i = nunits - 1; i >= 0; --i)
2544       t = tree_cons (NULL_TREE, def_for_init, t);
2545     init_def = build_vector (vectype, t);
2546     break;
2547
2548   case MIN_EXPR:
2549   case MAX_EXPR:
2550     *adjustment_def = NULL_TREE;
2551     init_def = vect_get_vec_def_for_operand (init_val, stmt, NULL);
2552     break;
2553
2554   default:
2555     gcc_unreachable ();
2556   }
2557
2558   return init_def;
2559 }
2560
2561
2562 /* Function vect_create_epilog_for_reduction
2563     
2564    Create code at the loop-epilog to finalize the result of a reduction
2565    computation. 
2566   
2567    VECT_DEF is a vector of partial results. 
2568    REDUC_CODE is the tree-code for the epilog reduction.
2569    NCOPIES is > 1 in case the vectorization factor (VF) is bigger than the
2570      number of elements that we can fit in a vectype (nunits). In this case
2571      we have to generate more than one vector stmt - i.e - we need to "unroll"
2572      the vector stmt by a factor VF/nunits.  For more details see documentation
2573      in vectorizable_operation.
2574    STMT is the scalar reduction stmt that is being vectorized.
2575    REDUCTION_PHI is the phi-node that carries the reduction computation.
2576
2577    This function:
2578    1. Creates the reduction def-use cycle: sets the arguments for 
2579       REDUCTION_PHI:
2580       The loop-entry argument is the vectorized initial-value of the reduction.
2581       The loop-latch argument is VECT_DEF - the vector of partial sums.
2582    2. "Reduces" the vector of partial results VECT_DEF into a single result,
2583       by applying the operation specified by REDUC_CODE if available, or by 
2584       other means (whole-vector shifts or a scalar loop).
2585       The function also creates a new phi node at the loop exit to preserve 
2586       loop-closed form, as illustrated below.
2587   
2588      The flow at the entry to this function:
2589     
2590         loop:
2591           vec_def = phi <null, null>            # REDUCTION_PHI
2592           VECT_DEF = vector_stmt                # vectorized form of STMT
2593           s_loop = scalar_stmt                  # (scalar) STMT
2594         loop_exit:
2595           s_out0 = phi <s_loop>                 # (scalar) EXIT_PHI
2596           use <s_out0>
2597           use <s_out0>
2598
2599      The above is transformed by this function into:
2600
2601         loop:
2602           vec_def = phi <vec_init, VECT_DEF>    # REDUCTION_PHI
2603           VECT_DEF = vector_stmt                # vectorized form of STMT
2604           s_loop = scalar_stmt                  # (scalar) STMT 
2605         loop_exit:
2606           s_out0 = phi <s_loop>                 # (scalar) EXIT_PHI
2607           v_out1 = phi <VECT_DEF>               # NEW_EXIT_PHI
2608           v_out2 = reduce <v_out1>
2609           s_out3 = extract_field <v_out2, 0>
2610           s_out4 = adjust_result <s_out3>
2611           use <s_out4>
2612           use <s_out4>
2613 */
2614
2615 static void
2616 vect_create_epilog_for_reduction (tree vect_def, gimple stmt,
2617                                   int ncopies,
2618                                   enum tree_code reduc_code,
2619                                   gimple reduction_phi)
2620 {
2621   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
2622   stmt_vec_info prev_phi_info;
2623   tree vectype;
2624   enum machine_mode mode;
2625   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
2626   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
2627   basic_block exit_bb;
2628   tree scalar_dest;
2629   tree scalar_type;
2630   gimple new_phi = NULL, phi;
2631   gimple_stmt_iterator exit_gsi;
2632   tree vec_dest;
2633   tree new_temp = NULL_TREE;
2634   tree new_name;
2635   gimple epilog_stmt = NULL;
2636   tree new_scalar_dest, new_dest;
2637   gimple exit_phi;
2638   tree bitsize, bitpos, bytesize; 
2639   enum tree_code code = gimple_assign_rhs_code (stmt);
2640   tree adjustment_def;
2641   tree vec_initial_def, def;
2642   tree orig_name;
2643   imm_use_iterator imm_iter;
2644   use_operand_p use_p;
2645   bool extract_scalar_result = false;
2646   tree reduction_op, expr;
2647   gimple orig_stmt;
2648   gimple use_stmt;
2649   bool nested_in_vect_loop = false;
2650   VEC(gimple,heap) *phis = NULL;
2651   enum vect_def_type dt = vect_unknown_def_type;
2652   int j, i;
2653   
2654   if (nested_in_vect_loop_p (loop, stmt))
2655     {
2656       loop = loop->inner;
2657       nested_in_vect_loop = true;
2658     }
2659   
2660   switch (get_gimple_rhs_class (gimple_assign_rhs_code (stmt)))
2661     {
2662     case GIMPLE_SINGLE_RHS:
2663       gcc_assert (TREE_OPERAND_LENGTH (gimple_assign_rhs1 (stmt)) == ternary_op);
2664       reduction_op = TREE_OPERAND (gimple_assign_rhs1 (stmt), 2);
2665       break;
2666     case GIMPLE_UNARY_RHS:
2667       reduction_op = gimple_assign_rhs1 (stmt);
2668       break;
2669     case GIMPLE_BINARY_RHS:
2670       reduction_op = gimple_assign_rhs2 (stmt);
2671       break;
2672     default:
2673       gcc_unreachable ();
2674     }
2675
2676   vectype = get_vectype_for_scalar_type (TREE_TYPE (reduction_op));
2677   gcc_assert (vectype);
2678   mode = TYPE_MODE (vectype);
2679
2680   /*** 1. Create the reduction def-use cycle  ***/
2681   
2682   /* For the case of reduction, vect_get_vec_def_for_operand returns
2683      the scalar def before the loop, that defines the initial value
2684      of the reduction variable.  */
2685   vec_initial_def = vect_get_vec_def_for_operand (reduction_op, stmt,
2686                                                   &adjustment_def);
2687
2688   phi = reduction_phi;
2689   def = vect_def;
2690   for (j = 0; j < ncopies; j++)
2691     {
2692       /* 1.1 set the loop-entry arg of the reduction-phi:  */
2693       add_phi_arg (phi, vec_initial_def, loop_preheader_edge (loop));
2694
2695       /* 1.2 set the loop-latch arg for the reduction-phi:  */
2696       if (j > 0)
2697         def = vect_get_vec_def_for_stmt_copy (dt, def);
2698       add_phi_arg (phi, def, loop_latch_edge (loop));
2699
2700       if (vect_print_dump_info (REPORT_DETAILS))
2701         {
2702           fprintf (vect_dump, "transform reduction: created def-use cycle: ");
2703           print_gimple_stmt (vect_dump, phi, 0, TDF_SLIM);
2704           fprintf (vect_dump, "\n");
2705           print_gimple_stmt (vect_dump, SSA_NAME_DEF_STMT (def), 0, TDF_SLIM);
2706         }
2707
2708       phi = STMT_VINFO_RELATED_STMT (vinfo_for_stmt (phi));
2709     }
2710
2711   /*** 2. Create epilog code
2712           The reduction epilog code operates across the elements of the vector
2713           of partial results computed by the vectorized loop.
2714           The reduction epilog code consists of:
2715           step 1: compute the scalar result in a vector (v_out2)
2716           step 2: extract the scalar result (s_out3) from the vector (v_out2)
2717           step 3: adjust the scalar result (s_out3) if needed.
2718
2719           Step 1 can be accomplished using one the following three schemes:
2720           (scheme 1) using reduc_code, if available.
2721           (scheme 2) using whole-vector shifts, if available.
2722           (scheme 3) using a scalar loop. In this case steps 1+2 above are 
2723                      combined.
2724                 
2725           The overall epilog code looks like this:
2726
2727           s_out0 = phi <s_loop>         # original EXIT_PHI
2728           v_out1 = phi <VECT_DEF>       # NEW_EXIT_PHI
2729           v_out2 = reduce <v_out1>              # step 1
2730           s_out3 = extract_field <v_out2, 0>    # step 2
2731           s_out4 = adjust_result <s_out3>       # step 3
2732
2733           (step 3 is optional, and steps 1 and 2 may be combined).
2734           Lastly, the uses of s_out0 are replaced by s_out4.
2735
2736           ***/
2737
2738   /* 2.1 Create new loop-exit-phi to preserve loop-closed form:
2739         v_out1 = phi <v_loop>  */
2740
2741   exit_bb = single_exit (loop)->dest;
2742   def = vect_def;
2743   prev_phi_info = NULL;
2744   for (j = 0; j < ncopies; j++)
2745     {
2746       phi = create_phi_node (SSA_NAME_VAR (vect_def), exit_bb);
2747       set_vinfo_for_stmt (phi, new_stmt_vec_info (phi, loop_vinfo, NULL));
2748       if (j == 0)
2749         new_phi = phi;
2750       else
2751         {
2752           def = vect_get_vec_def_for_stmt_copy (dt, def);
2753           STMT_VINFO_RELATED_STMT (prev_phi_info) = phi;
2754         }
2755       SET_PHI_ARG_DEF (phi, single_exit (loop)->dest_idx, def);
2756       prev_phi_info = vinfo_for_stmt (phi);
2757     }
2758   exit_gsi = gsi_after_labels (exit_bb);
2759
2760   /* 2.2 Get the relevant tree-code to use in the epilog for schemes 2,3 
2761          (i.e. when reduc_code is not available) and in the final adjustment
2762          code (if needed).  Also get the original scalar reduction variable as
2763          defined in the loop.  In case STMT is a "pattern-stmt" (i.e. - it 
2764          represents a reduction pattern), the tree-code and scalar-def are 
2765          taken from the original stmt that the pattern-stmt (STMT) replaces.  
2766          Otherwise (it is a regular reduction) - the tree-code and scalar-def
2767          are taken from STMT.  */ 
2768
2769   orig_stmt = STMT_VINFO_RELATED_STMT (stmt_info);
2770   if (!orig_stmt)
2771     {
2772       /* Regular reduction  */
2773       orig_stmt = stmt;
2774     }
2775   else
2776     {
2777       /* Reduction pattern  */
2778       stmt_vec_info stmt_vinfo = vinfo_for_stmt (orig_stmt);
2779       gcc_assert (STMT_VINFO_IN_PATTERN_P (stmt_vinfo));
2780       gcc_assert (STMT_VINFO_RELATED_STMT (stmt_vinfo) == stmt);
2781     }
2782   code = gimple_assign_rhs_code (orig_stmt);
2783   scalar_dest = gimple_assign_lhs (orig_stmt);
2784   scalar_type = TREE_TYPE (scalar_dest);
2785   new_scalar_dest = vect_create_destination_var (scalar_dest, NULL);
2786   bitsize = TYPE_SIZE (scalar_type);
2787   bytesize = TYPE_SIZE_UNIT (scalar_type);
2788
2789
2790   /* In case this is a reduction in an inner-loop while vectorizing an outer
2791      loop - we don't need to extract a single scalar result at the end of the
2792      inner-loop.  The final vector of partial results will be used in the
2793      vectorized outer-loop, or reduced to a scalar result at the end of the
2794      outer-loop.  */
2795   if (nested_in_vect_loop)
2796     goto vect_finalize_reduction;
2797
2798   /* FORNOW */
2799   gcc_assert (ncopies == 1);
2800
2801   /* 2.3 Create the reduction code, using one of the three schemes described
2802          above.  */
2803
2804   if (reduc_code != ERROR_MARK)
2805     {
2806       tree tmp;
2807
2808       /*** Case 1:  Create:
2809            v_out2 = reduc_expr <v_out1>  */
2810
2811       if (vect_print_dump_info (REPORT_DETAILS))
2812         fprintf (vect_dump, "Reduce using direct vector reduction.");
2813
2814       vec_dest = vect_create_destination_var (scalar_dest, vectype);
2815       tmp = build1 (reduc_code, vectype,  PHI_RESULT (new_phi));
2816       epilog_stmt = gimple_build_assign (vec_dest, tmp);
2817       new_temp = make_ssa_name (vec_dest, epilog_stmt);
2818       gimple_assign_set_lhs (epilog_stmt, new_temp);
2819       gsi_insert_before (&exit_gsi, epilog_stmt, GSI_SAME_STMT);
2820
2821       extract_scalar_result = true;
2822     }
2823   else
2824     {
2825       enum tree_code shift_code = ERROR_MARK;
2826       bool have_whole_vector_shift = true;
2827       int bit_offset;
2828       int element_bitsize = tree_low_cst (bitsize, 1);
2829       int vec_size_in_bits = tree_low_cst (TYPE_SIZE (vectype), 1);
2830       tree vec_temp;
2831
2832       if (optab_handler (vec_shr_optab, mode)->insn_code != CODE_FOR_nothing)
2833         shift_code = VEC_RSHIFT_EXPR;
2834       else
2835         have_whole_vector_shift = false;
2836
2837       /* Regardless of whether we have a whole vector shift, if we're
2838          emulating the operation via tree-vect-generic, we don't want
2839          to use it.  Only the first round of the reduction is likely
2840          to still be profitable via emulation.  */
2841       /* ??? It might be better to emit a reduction tree code here, so that
2842          tree-vect-generic can expand the first round via bit tricks.  */
2843       if (!VECTOR_MODE_P (mode))
2844         have_whole_vector_shift = false;
2845       else
2846         {
2847           optab optab = optab_for_tree_code (code, vectype, optab_default);
2848           if (optab_handler (optab, mode)->insn_code == CODE_FOR_nothing)
2849             have_whole_vector_shift = false;
2850         }
2851
2852       if (have_whole_vector_shift)
2853         {
2854           /*** Case 2: Create:
2855              for (offset = VS/2; offset >= element_size; offset/=2)
2856                 {
2857                   Create:  va' = vec_shift <va, offset>
2858                   Create:  va = vop <va, va'>
2859                 }  */
2860
2861           if (vect_print_dump_info (REPORT_DETAILS))
2862             fprintf (vect_dump, "Reduce using vector shifts");
2863
2864           vec_dest = vect_create_destination_var (scalar_dest, vectype);
2865           new_temp = PHI_RESULT (new_phi);
2866
2867           for (bit_offset = vec_size_in_bits/2;
2868                bit_offset >= element_bitsize;
2869                bit_offset /= 2)
2870             {
2871               tree bitpos = size_int (bit_offset);
2872               epilog_stmt = gimple_build_assign_with_ops (shift_code, vec_dest,
2873                                                           new_temp, bitpos);
2874               new_name = make_ssa_name (vec_dest, epilog_stmt);
2875               gimple_assign_set_lhs (epilog_stmt, new_name);
2876               gsi_insert_before (&exit_gsi, epilog_stmt, GSI_SAME_STMT);
2877
2878               epilog_stmt = gimple_build_assign_with_ops (code, vec_dest,
2879                                                           new_name, new_temp);
2880               new_temp = make_ssa_name (vec_dest, epilog_stmt);
2881               gimple_assign_set_lhs (epilog_stmt, new_temp);
2882               gsi_insert_before (&exit_gsi, epilog_stmt, GSI_SAME_STMT);
2883             }
2884
2885           extract_scalar_result = true;
2886         }
2887       else
2888         {
2889           tree rhs;
2890
2891           /*** Case 3: Create:  
2892              s = extract_field <v_out2, 0>
2893              for (offset = element_size; 
2894                   offset < vector_size; 
2895                   offset += element_size;)
2896                {
2897                  Create:  s' = extract_field <v_out2, offset>
2898                  Create:  s = op <s, s'>
2899                }  */
2900
2901           if (vect_print_dump_info (REPORT_DETAILS))
2902             fprintf (vect_dump, "Reduce using scalar code. ");
2903
2904           vec_temp = PHI_RESULT (new_phi);
2905           vec_size_in_bits = tree_low_cst (TYPE_SIZE (vectype), 1);
2906           rhs = build3 (BIT_FIELD_REF, scalar_type, vec_temp, bitsize,
2907                          bitsize_zero_node);
2908           epilog_stmt = gimple_build_assign (new_scalar_dest, rhs);
2909           new_temp = make_ssa_name (new_scalar_dest, epilog_stmt);
2910           gimple_assign_set_lhs (epilog_stmt, new_temp);
2911           gsi_insert_before (&exit_gsi, epilog_stmt, GSI_SAME_STMT);
2912               
2913           for (bit_offset = element_bitsize;
2914                bit_offset < vec_size_in_bits;
2915                bit_offset += element_bitsize)
2916             { 
2917               tree bitpos = bitsize_int (bit_offset);
2918               tree rhs = build3 (BIT_FIELD_REF, scalar_type, vec_temp, bitsize,
2919                                  bitpos);
2920                 
2921               epilog_stmt = gimple_build_assign (new_scalar_dest, rhs);
2922               new_name = make_ssa_name (new_scalar_dest, epilog_stmt);
2923               gimple_assign_set_lhs (epilog_stmt, new_name);
2924               gsi_insert_before (&exit_gsi, epilog_stmt, GSI_SAME_STMT);
2925
2926               epilog_stmt = gimple_build_assign_with_ops (code,
2927                                                           new_scalar_dest,
2928                                                           new_name, new_temp);
2929               new_temp = make_ssa_name (new_scalar_dest, epilog_stmt);
2930               gimple_assign_set_lhs (epilog_stmt, new_temp);
2931               gsi_insert_before (&exit_gsi, epilog_stmt, GSI_SAME_STMT);
2932             }
2933
2934           extract_scalar_result = false;
2935         }
2936     }
2937
2938   /* 2.4  Extract the final scalar result.  Create:
2939          s_out3 = extract_field <v_out2, bitpos>  */
2940   
2941   if (extract_scalar_result)
2942     {
2943       tree rhs;
2944
2945       gcc_assert (!nested_in_vect_loop);
2946       if (vect_print_dump_info (REPORT_DETAILS))
2947         fprintf (vect_dump, "extract scalar result");
2948
2949       if (BYTES_BIG_ENDIAN)
2950         bitpos = size_binop (MULT_EXPR,
2951                        bitsize_int (TYPE_VECTOR_SUBPARTS (vectype) - 1),
2952                        TYPE_SIZE (scalar_type));
2953       else
2954         bitpos = bitsize_zero_node;
2955
2956       rhs = build3 (BIT_FIELD_REF, scalar_type, new_temp, bitsize, bitpos);
2957       epilog_stmt = gimple_build_assign (new_scalar_dest, rhs);
2958       new_temp = make_ssa_name (new_scalar_dest, epilog_stmt);
2959       gimple_assign_set_lhs (epilog_stmt, new_temp);
2960       gsi_insert_before (&exit_gsi, epilog_stmt, GSI_SAME_STMT);
2961     }
2962
2963 vect_finalize_reduction:
2964
2965   /* 2.5 Adjust the final result by the initial value of the reduction
2966          variable. (When such adjustment is not needed, then
2967          'adjustment_def' is zero).  For example, if code is PLUS we create:
2968          new_temp = loop_exit_def + adjustment_def  */
2969
2970   if (adjustment_def)
2971     {
2972       if (nested_in_vect_loop)
2973         {
2974           gcc_assert (TREE_CODE (TREE_TYPE (adjustment_def)) == VECTOR_TYPE);
2975           expr = build2 (code, vectype, PHI_RESULT (new_phi), adjustment_def);
2976           new_dest = vect_create_destination_var (scalar_dest, vectype);
2977         }
2978       else
2979         {
2980           gcc_assert (TREE_CODE (TREE_TYPE (adjustment_def)) != VECTOR_TYPE);
2981           expr = build2 (code, scalar_type, new_temp, adjustment_def);
2982           new_dest = vect_create_destination_var (scalar_dest, scalar_type);
2983         }
2984       epilog_stmt = gimple_build_assign (new_dest, expr);
2985       new_temp = make_ssa_name (new_dest, epilog_stmt);
2986       gimple_assign_set_lhs (epilog_stmt, new_temp);
2987       SSA_NAME_DEF_STMT (new_temp) = epilog_stmt;
2988       gsi_insert_before (&exit_gsi, epilog_stmt, GSI_SAME_STMT);
2989     }
2990
2991
2992   /* 2.6  Handle the loop-exit phi  */
2993
2994   /* Replace uses of s_out0 with uses of s_out3:
2995      Find the loop-closed-use at the loop exit of the original scalar result.
2996      (The reduction result is expected to have two immediate uses - one at the 
2997      latch block, and one at the loop exit).  */
2998   phis = VEC_alloc (gimple, heap, 10);
2999   FOR_EACH_IMM_USE_FAST (use_p, imm_iter, scalar_dest)
3000     {
3001       if (!flow_bb_inside_loop_p (loop, gimple_bb (USE_STMT (use_p))))
3002         {
3003           exit_phi = USE_STMT (use_p);
3004           VEC_quick_push (gimple, phis, exit_phi);
3005         }
3006     }
3007   /* We expect to have found an exit_phi because of loop-closed-ssa form.  */
3008   gcc_assert (!VEC_empty (gimple, phis));
3009
3010   for (i = 0; VEC_iterate (gimple, phis, i, exit_phi); i++)
3011     {
3012       if (nested_in_vect_loop)
3013         {
3014           stmt_vec_info stmt_vinfo = vinfo_for_stmt (exit_phi);
3015
3016           /* FORNOW. Currently not supporting the case that an inner-loop
3017              reduction is not used in the outer-loop (but only outside the
3018              outer-loop).  */
3019           gcc_assert (STMT_VINFO_RELEVANT_P (stmt_vinfo) 
3020                       && !STMT_VINFO_LIVE_P (stmt_vinfo));
3021
3022           epilog_stmt = adjustment_def ? epilog_stmt : new_phi;
3023           STMT_VINFO_VEC_STMT (stmt_vinfo) = epilog_stmt;
3024           set_vinfo_for_stmt (epilog_stmt, 
3025                               new_stmt_vec_info (epilog_stmt, loop_vinfo, 
3026                                                  NULL));
3027           if (adjustment_def)
3028             STMT_VINFO_RELATED_STMT (vinfo_for_stmt (epilog_stmt)) =
3029                 STMT_VINFO_RELATED_STMT (vinfo_for_stmt (new_phi));
3030           continue;
3031         }
3032
3033       /* Replace the uses:  */
3034       orig_name = PHI_RESULT (exit_phi);
3035       FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, orig_name)
3036         FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
3037           SET_USE (use_p, new_temp);
3038     }
3039   VEC_free (gimple, heap, phis);
3040
3041
3042
3043 /* Function vectorizable_reduction.
3044
3045    Check if STMT performs a reduction operation that can be vectorized.
3046    If VEC_STMT is also passed, vectorize the STMT: create a vectorized
3047    stmt to replace it, put it in VEC_STMT, and insert it at BSI.
3048    Return FALSE if not a vectorizable STMT, TRUE otherwise.
3049
3050    This function also handles reduction idioms (patterns) that have been 
3051    recognized in advance during vect_pattern_recog. In this case, STMT may be
3052    of this form:
3053      X = pattern_expr (arg0, arg1, ..., X)
3054    and it's STMT_VINFO_RELATED_STMT points to the last stmt in the original
3055    sequence that had been detected and replaced by the pattern-stmt (STMT).
3056   
3057    In some cases of reduction patterns, the type of the reduction variable X is
3058    different than the type of the other arguments of STMT.
3059    In such cases, the vectype that is used when transforming STMT into a vector
3060    stmt is different than the vectype that is used to determine the
3061    vectorization factor, because it consists of a different number of elements 
3062    than the actual number of elements that are being operated upon in parallel.
3063
3064    For example, consider an accumulation of shorts into an int accumulator.
3065    On some targets it's possible to vectorize this pattern operating on 8
3066    shorts at a time (hence, the vectype for purposes of determining the
3067    vectorization factor should be V8HI); on the other hand, the vectype that
3068    is used to create the vector form is actually V4SI (the type of the result).
3069
3070    Upon entry to this function, STMT_VINFO_VECTYPE records the vectype that
3071    indicates what is the actual level of parallelism (V8HI in the example), so
3072    that the right vectorization factor would be derived. This vectype
3073    corresponds to the type of arguments to the reduction stmt, and should *NOT*
3074    be used to create the vectorized stmt. The right vectype for the vectorized
3075    stmt is obtained from the type of the result X:
3076         get_vectype_for_scalar_type (TREE_TYPE (X))
3077
3078    This means that, contrary to "regular" reductions (or "regular" stmts in
3079    general), the following equation:
3080       STMT_VINFO_VECTYPE == get_vectype_for_scalar_type (TREE_TYPE (X))
3081    does *NOT* necessarily hold for reduction patterns.  */
3082
3083 bool
3084 vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi,
3085                         gimple *vec_stmt)
3086 {
3087   tree vec_dest;
3088   tree scalar_dest;
3089   tree loop_vec_def0 = NULL_TREE, loop_vec_def1 = NULL_TREE;
3090   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
3091   tree vectype = STMT_VINFO_VECTYPE (stmt_info);
3092   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
3093   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
3094   enum tree_code code, orig_code, epilog_reduc_code;
3095   enum machine_mode vec_mode;
3096   int op_type;
3097   optab optab, reduc_optab;
3098   tree new_temp = NULL_TREE;
3099   tree def;
3100   gimple def_stmt;
3101   enum vect_def_type dt;
3102   gimple new_phi = NULL;
3103   tree scalar_type;
3104   bool is_simple_use;
3105   gimple orig_stmt;
3106   stmt_vec_info orig_stmt_info;
3107   tree expr = NULL_TREE;
3108   int i;
3109   int nunits = TYPE_VECTOR_SUBPARTS (vectype);
3110   int ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits;
3111   int epilog_copies;
3112   stmt_vec_info prev_stmt_info, prev_phi_info;
3113   gimple first_phi = NULL;
3114   bool single_defuse_cycle = false;
3115   tree reduc_def;
3116   gimple new_stmt = NULL;
3117   int j;
3118   tree ops[3];
3119
3120   if (nested_in_vect_loop_p (loop, stmt))
3121     loop = loop->inner;
3122
3123   gcc_assert (ncopies >= 1);
3124
3125   /* FORNOW: SLP not supported.  */
3126   if (STMT_SLP_TYPE (stmt_info))
3127     return false;
3128
3129   /* 1. Is vectorizable reduction?  */
3130
3131   /* Not supportable if the reduction variable is used in the loop.  */
3132   if (STMT_VINFO_RELEVANT (stmt_info) > vect_used_in_outer)
3133     return false;
3134
3135   /* Reductions that are not used even in an enclosing outer-loop,
3136      are expected to be "live" (used out of the loop).  */
3137   if (STMT_VINFO_RELEVANT (stmt_info) == vect_unused_in_scope
3138       && !STMT_VINFO_LIVE_P (stmt_info))
3139     return false;
3140
3141   /* Make sure it was already recognized as a reduction computation.  */
3142   if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_reduction_def)
3143     return false;
3144
3145   /* 2. Has this been recognized as a reduction pattern? 
3146
3147      Check if STMT represents a pattern that has been recognized
3148      in earlier analysis stages.  For stmts that represent a pattern,
3149      the STMT_VINFO_RELATED_STMT field records the last stmt in
3150      the original sequence that constitutes the pattern.  */
3151
3152   orig_stmt = STMT_VINFO_RELATED_STMT (stmt_info);
3153   if (orig_stmt)
3154     {
3155       orig_stmt_info = vinfo_for_stmt (orig_stmt);
3156       gcc_assert (STMT_VINFO_RELATED_STMT (orig_stmt_info) == stmt);
3157       gcc_assert (STMT_VINFO_IN_PATTERN_P (orig_stmt_info));
3158       gcc_assert (!STMT_VINFO_IN_PATTERN_P (stmt_info));
3159     }
3160  
3161   /* 3. Check the operands of the operation. The first operands are defined
3162         inside the loop body. The last operand is the reduction variable,
3163         which is defined by the loop-header-phi.  */
3164
3165   gcc_assert (is_gimple_assign (stmt));
3166
3167   /* Flatten RHS */
3168   switch (get_gimple_rhs_class (gimple_assign_rhs_code (stmt)))
3169     {
3170     case GIMPLE_SINGLE_RHS:
3171       op_type = TREE_OPERAND_LENGTH (gimple_assign_rhs1 (stmt));
3172       if (op_type == ternary_op)
3173         {
3174           tree rhs = gimple_assign_rhs1 (stmt);
3175           ops[0] = TREE_OPERAND (rhs, 0);
3176           ops[1] = TREE_OPERAND (rhs, 1);
3177           ops[2] = TREE_OPERAND (rhs, 2);
3178           code = TREE_CODE (rhs);
3179         }
3180       else
3181         return false;
3182       break;
3183
3184     case GIMPLE_BINARY_RHS:
3185       code = gimple_assign_rhs_code (stmt);
3186       op_type = TREE_CODE_LENGTH (code);
3187       gcc_assert (op_type == binary_op);
3188       ops[0] = gimple_assign_rhs1 (stmt);
3189       ops[1] = gimple_assign_rhs2 (stmt);
3190       break;
3191
3192     case GIMPLE_UNARY_RHS:
3193       return false;
3194
3195     default:
3196       gcc_unreachable ();
3197     }
3198
3199   scalar_dest = gimple_assign_lhs (stmt);
3200   scalar_type = TREE_TYPE (scalar_dest);
3201   if (!POINTER_TYPE_P (scalar_type) && !INTEGRAL_TYPE_P (scalar_type) 
3202       && !SCALAR_FLOAT_TYPE_P (scalar_type))
3203     return false;
3204
3205   /* All uses but the last are expected to be defined in the loop.
3206      The last use is the reduction variable.  */
3207   for (i = 0; i < op_type-1; i++)
3208     {
3209       is_simple_use = vect_is_simple_use (ops[i], loop_vinfo, NULL, &def_stmt,
3210                                           &def, &dt);
3211       gcc_assert (is_simple_use);
3212       if (dt != vect_internal_def
3213           && dt != vect_external_def
3214           && dt != vect_constant_def
3215           && dt != vect_induction_def)
3216         return false;
3217     }
3218
3219   is_simple_use = vect_is_simple_use (ops[i], loop_vinfo, NULL, &def_stmt, 
3220                                       &def, &dt);
3221   gcc_assert (is_simple_use);
3222   gcc_assert (dt == vect_reduction_def);
3223   gcc_assert (gimple_code (def_stmt) == GIMPLE_PHI);
3224   if (orig_stmt) 
3225     gcc_assert (orig_stmt == vect_is_simple_reduction (loop_vinfo, def_stmt));
3226   else
3227     gcc_assert (stmt == vect_is_simple_reduction (loop_vinfo, def_stmt));
3228   
3229   if (STMT_VINFO_LIVE_P (vinfo_for_stmt (def_stmt)))
3230     return false;
3231
3232   /* 4. Supportable by target?  */
3233
3234   /* 4.1. check support for the operation in the loop  */
3235   optab = optab_for_tree_code (code, vectype, optab_default);
3236   if (!optab)
3237     {
3238       if (vect_print_dump_info (REPORT_DETAILS))
3239         fprintf (vect_dump, "no optab.");
3240       return false;
3241     }
3242   vec_mode = TYPE_MODE (vectype);
3243   if (optab_handler (optab, vec_mode)->insn_code == CODE_FOR_nothing)
3244     {
3245       if (vect_print_dump_info (REPORT_DETAILS))
3246         fprintf (vect_dump, "op not supported by target.");
3247       if (GET_MODE_SIZE (vec_mode) != UNITS_PER_WORD
3248           || LOOP_VINFO_VECT_FACTOR (loop_vinfo)
3249              < vect_min_worthwhile_factor (code))
3250         return false;
3251       if (vect_print_dump_info (REPORT_DETAILS))
3252         fprintf (vect_dump, "proceeding using word mode.");
3253     }
3254
3255   /* Worthwhile without SIMD support?  */
3256   if (!VECTOR_MODE_P (TYPE_MODE (vectype))
3257       && LOOP_VINFO_VECT_FACTOR (loop_vinfo)
3258          < vect_min_worthwhile_factor (code))
3259     {
3260       if (vect_print_dump_info (REPORT_DETAILS))
3261         fprintf (vect_dump, "not worthwhile without SIMD support.");
3262       return false;
3263     }
3264
3265   /* 4.2. Check support for the epilog operation.
3266
3267           If STMT represents a reduction pattern, then the type of the
3268           reduction variable may be different than the type of the rest
3269           of the arguments.  For example, consider the case of accumulation
3270           of shorts into an int accumulator; The original code:
3271                         S1: int_a = (int) short_a;
3272           orig_stmt->   S2: int_acc = plus <int_a ,int_acc>;
3273
3274           was replaced with:
3275                         STMT: int_acc = widen_sum <short_a, int_acc>
3276
3277           This means that:
3278           1. The tree-code that is used to create the vector operation in the 
3279              epilog code (that reduces the partial results) is not the 
3280              tree-code of STMT, but is rather the tree-code of the original 
3281              stmt from the pattern that STMT is replacing. I.e, in the example 
3282              above we want to use 'widen_sum' in the loop, but 'plus' in the 
3283              epilog.
3284           2. The type (mode) we use to check available target support
3285              for the vector operation to be created in the *epilog*, is 
3286              determined by the type of the reduction variable (in the example 
3287              above we'd check this: plus_optab[vect_int_mode]).
3288              However the type (mode) we use to check available target support
3289              for the vector operation to be created *inside the loop*, is
3290              determined by the type of the other arguments to STMT (in the
3291              example we'd check this: widen_sum_optab[vect_short_mode]).
3292   
3293           This is contrary to "regular" reductions, in which the types of all 
3294           the arguments are the same as the type of the reduction variable. 
3295           For "regular" reductions we can therefore use the same vector type 
3296           (and also the same tree-code) when generating the epilog code and
3297           when generating the code inside the loop.  */
3298
3299   if (orig_stmt)
3300     {
3301       /* This is a reduction pattern: get the vectype from the type of the
3302          reduction variable, and get the tree-code from orig_stmt.  */
3303       orig_code = gimple_assign_rhs_code (orig_stmt);
3304       vectype = get_vectype_for_scalar_type (TREE_TYPE (def));
3305       if (!vectype)
3306         {
3307           if (vect_print_dump_info (REPORT_DETAILS))
3308             {
3309               fprintf (vect_dump, "unsupported data-type ");
3310               print_generic_expr (vect_dump, TREE_TYPE (def), TDF_SLIM);
3311             }
3312           return false;
3313         }
3314
3315       vec_mode = TYPE_MODE (vectype);
3316     }
3317   else
3318     {
3319       /* Regular reduction: use the same vectype and tree-code as used for
3320          the vector code inside the loop can be used for the epilog code. */
3321       orig_code = code;
3322     }
3323
3324   if (!reduction_code_for_scalar_code (orig_code, &epilog_reduc_code))
3325     return false;
3326   reduc_optab = optab_for_tree_code (epilog_reduc_code, vectype, optab_default);
3327   if (!reduc_optab)
3328     {
3329       if (vect_print_dump_info (REPORT_DETAILS))
3330         fprintf (vect_dump, "no optab for reduction.");
3331       epilog_reduc_code = ERROR_MARK;
3332     }
3333   if (optab_handler (reduc_optab, vec_mode)->insn_code == CODE_FOR_nothing)
3334     {
3335       if (vect_print_dump_info (REPORT_DETAILS))
3336         fprintf (vect_dump, "reduc op not supported by target.");
3337       epilog_reduc_code = ERROR_MARK;
3338     }
3339  
3340   if (!vec_stmt) /* transformation not required.  */
3341     {
3342       STMT_VINFO_TYPE (stmt_info) = reduc_vec_info_type;
3343       if (!vect_model_reduction_cost (stmt_info, epilog_reduc_code, ncopies))
3344         return false;
3345       return true;
3346     }
3347
3348   /** Transform.  **/
3349
3350   if (vect_print_dump_info (REPORT_DETAILS))
3351     fprintf (vect_dump, "transform reduction.");
3352
3353   /* Create the destination vector  */
3354   vec_dest = vect_create_destination_var (scalar_dest, vectype);
3355
3356   /* In case the vectorization factor (VF) is bigger than the number
3357      of elements that we can fit in a vectype (nunits), we have to generate
3358      more than one vector stmt - i.e - we need to "unroll" the
3359      vector stmt by a factor VF/nunits.  For more details see documentation
3360      in vectorizable_operation.  */
3361
3362   /* If the reduction is used in an outer loop we need to generate
3363      VF intermediate results, like so (e.g. for ncopies=2):
3364         r0 = phi (init, r0)
3365         r1 = phi (init, r1)
3366         r0 = x0 + r0;
3367         r1 = x1 + r1;
3368     (i.e. we generate VF results in 2 registers).
3369     In this case we have a separate def-use cycle for each copy, and therefore
3370     for each copy we get the vector def for the reduction variable from the
3371     respective phi node created for this copy.
3372
3373     Otherwise (the reduction is unused in the loop nest), we can combine
3374     together intermediate results, like so (e.g. for ncopies=2):
3375         r = phi (init, r)
3376         r = x0 + r;
3377         r = x1 + r;
3378    (i.e. we generate VF/2 results in a single register).
3379    In this case for each copy we get the vector def for the reduction variable
3380    from the vectorized reduction operation generated in the previous iteration.
3381   */
3382
3383   if (STMT_VINFO_RELEVANT (stmt_info) == vect_unused_in_scope)
3384     {
3385       single_defuse_cycle = true;
3386       epilog_copies = 1;
3387     }
3388   else
3389     epilog_copies = ncopies;
3390
3391   prev_stmt_info = NULL;
3392   prev_phi_info = NULL;
3393   for (j = 0; j < ncopies; j++)
3394     {
3395       if (j == 0 || !single_defuse_cycle)
3396         {
3397           /* Create the reduction-phi that defines the reduction-operand.  */
3398           new_phi = create_phi_node (vec_dest, loop->header);
3399           set_vinfo_for_stmt (new_phi, new_stmt_vec_info (new_phi, loop_vinfo, 
3400                                                           NULL));
3401         }
3402
3403       /* Handle uses.  */
3404       if (j == 0)
3405         {
3406           loop_vec_def0 = vect_get_vec_def_for_operand (ops[0], stmt, NULL);
3407           if (op_type == ternary_op)
3408             {
3409               loop_vec_def1 = vect_get_vec_def_for_operand (ops[1], stmt, NULL);
3410             }
3411
3412           /* Get the vector def for the reduction variable from the phi node */
3413           reduc_def = PHI_RESULT (new_phi);
3414           first_phi = new_phi;
3415         }
3416       else
3417         {
3418           enum vect_def_type dt = vect_unknown_def_type; /* Dummy */
3419           loop_vec_def0 = vect_get_vec_def_for_stmt_copy (dt, loop_vec_def0);
3420           if (op_type == ternary_op)
3421             loop_vec_def1 = vect_get_vec_def_for_stmt_copy (dt, loop_vec_def1);
3422
3423           if (single_defuse_cycle)
3424             reduc_def = gimple_assign_lhs (new_stmt);
3425           else
3426             reduc_def = PHI_RESULT (new_phi);
3427
3428           STMT_VINFO_RELATED_STMT (prev_phi_info) = new_phi;
3429         }
3430
3431       /* Arguments are ready. create the new vector stmt.  */
3432       if (op_type == binary_op)
3433         expr = build2 (code, vectype, loop_vec_def0, reduc_def);
3434       else
3435         expr = build3 (code, vectype, loop_vec_def0, loop_vec_def1, 
3436                        reduc_def);
3437       new_stmt = gimple_build_assign (vec_dest, expr);
3438       new_temp = make_ssa_name (vec_dest, new_stmt);
3439       gimple_assign_set_lhs (new_stmt, new_temp);
3440       vect_finish_stmt_generation (stmt, new_stmt, gsi);
3441
3442       if (j == 0)
3443         STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt;
3444       else
3445         STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt;
3446       prev_stmt_info = vinfo_for_stmt (new_stmt);
3447       prev_phi_info = vinfo_for_stmt (new_phi);
3448     }
3449
3450   /* Finalize the reduction-phi (set its arguments) and create the
3451      epilog reduction code.  */
3452   if (!single_defuse_cycle)
3453     new_temp = gimple_assign_lhs (*vec_stmt);
3454   vect_create_epilog_for_reduction (new_temp, stmt, epilog_copies,
3455                                     epilog_reduc_code, first_phi);
3456   return true;
3457 }
3458
3459 /* Function vect_min_worthwhile_factor.
3460
3461    For a loop where we could vectorize the operation indicated by CODE,
3462    return the minimum vectorization factor that makes it worthwhile
3463    to use generic vectors.  */
3464 int
3465 vect_min_worthwhile_factor (enum tree_code code)
3466 {
3467   switch (code)
3468     {
3469     case PLUS_EXPR:
3470     case MINUS_EXPR:
3471     case NEGATE_EXPR:
3472       return 4;
3473
3474     case BIT_AND_EXPR:
3475     case BIT_IOR_EXPR:
3476     case BIT_XOR_EXPR:
3477     case BIT_NOT_EXPR:
3478       return 2;
3479
3480     default:
3481       return INT_MAX;
3482     }
3483 }
3484
3485
3486 /* Function vectorizable_induction
3487
3488    Check if PHI performs an induction computation that can be vectorized.
3489    If VEC_STMT is also passed, vectorize the induction PHI: create a vectorized
3490    phi to replace it, put it in VEC_STMT, and add it to the same basic block.
3491    Return FALSE if not a vectorizable STMT, TRUE otherwise.  */
3492
3493 bool
3494 vectorizable_induction (gimple phi, gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED,
3495                         gimple *vec_stmt)
3496 {
3497   stmt_vec_info stmt_info = vinfo_for_stmt (phi);
3498   tree vectype = STMT_VINFO_VECTYPE (stmt_info);
3499   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
3500   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
3501   int nunits = TYPE_VECTOR_SUBPARTS (vectype);
3502   int ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits;
3503   tree vec_def;
3504
3505   gcc_assert (ncopies >= 1);
3506   /* FORNOW. This restriction should be relaxed.  */
3507   if (nested_in_vect_loop_p (loop, phi) && ncopies > 1)
3508     {
3509       if (vect_print_dump_info (REPORT_DETAILS))
3510         fprintf (vect_dump, "multiple types in nested loop.");
3511       return false;
3512     }
3513
3514   if (!STMT_VINFO_RELEVANT_P (stmt_info))
3515     return false;
3516
3517   /* FORNOW: SLP not supported.  */
3518   if (STMT_SLP_TYPE (stmt_info))
3519     return false;
3520
3521   gcc_assert (STMT_VINFO_DEF_TYPE (stmt_info) == vect_induction_def);
3522
3523   if (gimple_code (phi) != GIMPLE_PHI)
3524     return false;
3525
3526   if (!vec_stmt) /* transformation not required.  */
3527     {
3528       STMT_VINFO_TYPE (stmt_info) = induc_vec_info_type;
3529       if (vect_print_dump_info (REPORT_DETAILS))
3530         fprintf (vect_dump, "=== vectorizable_induction ===");
3531       vect_model_induction_cost (stmt_info, ncopies);
3532       return true;
3533     }
3534
3535   /** Transform.  **/
3536
3537   if (vect_print_dump_info (REPORT_DETAILS))
3538     fprintf (vect_dump, "transform induction phi.");
3539
3540   vec_def = get_initial_def_for_induction (phi);
3541   *vec_stmt = SSA_NAME_DEF_STMT (vec_def);
3542   return true;
3543 }
3544
3545 /* Function vectorizable_live_operation.
3546
3547    STMT computes a value that is used outside the loop. Check if 
3548    it can be supported.  */
3549
3550 bool
3551 vectorizable_live_operation (gimple stmt,
3552                              gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED,
3553                              gimple *vec_stmt ATTRIBUTE_UNUSED)
3554 {
3555   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
3556   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
3557   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
3558   int i;
3559   int op_type;
3560   tree op;
3561   tree def;
3562   gimple def_stmt;
3563   enum vect_def_type dt; 
3564   enum tree_code code;
3565   enum gimple_rhs_class rhs_class;
3566
3567   gcc_assert (STMT_VINFO_LIVE_P (stmt_info));
3568
3569   if (STMT_VINFO_DEF_TYPE (stmt_info) == vect_reduction_def)
3570     return false;
3571
3572   if (!is_gimple_assign (stmt))
3573     return false;
3574
3575   if (TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
3576     return false;
3577
3578   /* FORNOW. CHECKME. */
3579   if (nested_in_vect_loop_p (loop, stmt))
3580     return false;
3581
3582   code = gimple_assign_rhs_code (stmt);
3583   op_type = TREE_CODE_LENGTH (code);
3584   rhs_class = get_gimple_rhs_class (code);
3585   gcc_assert (rhs_class != GIMPLE_UNARY_RHS || op_type == unary_op);
3586   gcc_assert (rhs_class != GIMPLE_BINARY_RHS || op_type == binary_op);
3587
3588   /* FORNOW: support only if all uses are invariant. This means
3589      that the scalar operations can remain in place, unvectorized.
3590      The original last scalar value that they compute will be used.  */
3591
3592   for (i = 0; i < op_type; i++)
3593     {
3594       if (rhs_class == GIMPLE_SINGLE_RHS)
3595         op = TREE_OPERAND (gimple_op (stmt, 1), i);
3596       else
3597         op = gimple_op (stmt, i + 1);
3598       if (op
3599           && !vect_is_simple_use (op, loop_vinfo, NULL, &def_stmt, &def, &dt))
3600         {
3601           if (vect_print_dump_info (REPORT_DETAILS))
3602             fprintf (vect_dump, "use not simple.");
3603           return false;
3604         }
3605
3606       if (dt != vect_external_def && dt != vect_constant_def)
3607         return false;
3608     }
3609
3610   /* No transformation is required for the cases we currently support.  */
3611   return true;
3612 }
3613
3614 /* Function vect_transform_loop.
3615
3616    The analysis phase has determined that the loop is vectorizable.
3617    Vectorize the loop - created vectorized stmts to replace the scalar
3618    stmts in the loop, and update the loop exit condition.  */
3619
3620 void
3621 vect_transform_loop (loop_vec_info loop_vinfo)
3622 {
3623   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
3624   basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
3625   int nbbs = loop->num_nodes;
3626   gimple_stmt_iterator si;
3627   int i;
3628   tree ratio = NULL;
3629   int vectorization_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
3630   bool strided_store;
3631   bool slp_scheduled = false;
3632   unsigned int nunits;
3633   tree cond_expr = NULL_TREE;
3634   gimple_seq cond_expr_stmt_list = NULL;
3635   bool do_peeling_for_loop_bound;
3636
3637   if (vect_print_dump_info (REPORT_DETAILS))
3638     fprintf (vect_dump, "=== vec_transform_loop ===");
3639
3640   /* Peel the loop if there are data refs with unknown alignment.
3641      Only one data ref with unknown store is allowed.  */
3642
3643   if (LOOP_PEELING_FOR_ALIGNMENT (loop_vinfo))
3644     vect_do_peeling_for_alignment (loop_vinfo);
3645
3646   do_peeling_for_loop_bound
3647     = (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
3648        || (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
3649            && LOOP_VINFO_INT_NITERS (loop_vinfo) % vectorization_factor != 0));
3650
3651   if (VEC_length (gimple, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo))
3652       || VEC_length (ddr_p, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo)))
3653     vect_loop_versioning (loop_vinfo,
3654                           !do_peeling_for_loop_bound,
3655                           &cond_expr, &cond_expr_stmt_list);
3656
3657   /* CHECKME: we wouldn't need this if we called update_ssa once
3658      for all loops.  */
3659   bitmap_zero (vect_memsyms_to_rename);
3660   
3661   /* If the loop has a symbolic number of iterations 'n' (i.e. it's not a
3662      compile time constant), or it is a constant that doesn't divide by the
3663      vectorization factor, then an epilog loop needs to be created.
3664      We therefore duplicate the loop: the original loop will be vectorized,
3665      and will compute the first (n/VF) iterations. The second copy of the loop
3666      will remain scalar and will compute the remaining (n%VF) iterations.
3667      (VF is the vectorization factor).  */
3668
3669   if (do_peeling_for_loop_bound)
3670     vect_do_peeling_for_loop_bound (loop_vinfo, &ratio,
3671                                     cond_expr, cond_expr_stmt_list);
3672   else
3673     ratio = build_int_cst (TREE_TYPE (LOOP_VINFO_NITERS (loop_vinfo)),
3674                 LOOP_VINFO_INT_NITERS (loop_vinfo) / vectorization_factor);
3675
3676   /* 1) Make sure the loop header has exactly two entries
3677      2) Make sure we have a preheader basic block.  */
3678
3679   gcc_assert (EDGE_COUNT (loop->header->preds) == 2);
3680
3681   split_edge (loop_preheader_edge (loop));
3682
3683   /* FORNOW: the vectorizer supports only loops which body consist
3684      of one basic block (header + empty latch). When the vectorizer will 
3685      support more involved loop forms, the order by which the BBs are 
3686      traversed need to be reconsidered.  */
3687
3688   for (i = 0; i < nbbs; i++)
3689     {
3690       basic_block bb = bbs[i];
3691       stmt_vec_info stmt_info;
3692       gimple phi;
3693
3694       for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
3695         {
3696           phi = gsi_stmt (si);
3697           if (vect_print_dump_info (REPORT_DETAILS))
3698             {
3699               fprintf (vect_dump, "------>vectorizing phi: ");
3700               print_gimple_stmt (vect_dump, phi, 0, TDF_SLIM);
3701             }
3702           stmt_info = vinfo_for_stmt (phi);
3703           if (!stmt_info)
3704             continue;
3705
3706           if (!STMT_VINFO_RELEVANT_P (stmt_info)
3707               && !STMT_VINFO_LIVE_P (stmt_info))
3708             continue;
3709
3710           if ((TYPE_VECTOR_SUBPARTS (STMT_VINFO_VECTYPE (stmt_info))
3711                 != (unsigned HOST_WIDE_INT) vectorization_factor)
3712               && vect_print_dump_info (REPORT_DETAILS))
3713             fprintf (vect_dump, "multiple-types.");
3714
3715           if (STMT_VINFO_DEF_TYPE (stmt_info) == vect_induction_def)
3716             {
3717               if (vect_print_dump_info (REPORT_DETAILS))
3718                 fprintf (vect_dump, "transform phi.");
3719               vect_transform_stmt (phi, NULL, NULL, NULL, NULL);
3720             }
3721         }
3722
3723       for (si = gsi_start_bb (bb); !gsi_end_p (si);)
3724         {
3725           gimple stmt = gsi_stmt (si);
3726           bool is_store;
3727
3728           if (vect_print_dump_info (REPORT_DETAILS))
3729             {
3730               fprintf (vect_dump, "------>vectorizing statement: ");
3731               print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
3732             }   
3733
3734           stmt_info = vinfo_for_stmt (stmt);
3735
3736           /* vector stmts created in the outer-loop during vectorization of
3737              stmts in an inner-loop may not have a stmt_info, and do not
3738              need to be vectorized.  */
3739           if (!stmt_info)
3740             {
3741               gsi_next (&si);
3742               continue;
3743             }
3744
3745           if (!STMT_VINFO_RELEVANT_P (stmt_info)
3746               && !STMT_VINFO_LIVE_P (stmt_info))
3747             {
3748               gsi_next (&si);
3749               continue;
3750             }
3751
3752           gcc_assert (STMT_VINFO_VECTYPE (stmt_info));
3753           nunits =
3754             (unsigned int) TYPE_VECTOR_SUBPARTS (STMT_VINFO_VECTYPE (stmt_info));
3755           if (!STMT_SLP_TYPE (stmt_info)
3756               && nunits != (unsigned int) vectorization_factor
3757               && vect_print_dump_info (REPORT_DETAILS))
3758             /* For SLP VF is set according to unrolling factor, and not to
3759                vector size, hence for SLP this print is not valid.  */
3760             fprintf (vect_dump, "multiple-types.");
3761
3762           /* SLP. Schedule all the SLP instances when the first SLP stmt is
3763              reached.  */
3764           if (STMT_SLP_TYPE (stmt_info))
3765             {
3766               if (!slp_scheduled)
3767                 {
3768                   slp_scheduled = true;
3769
3770                   if (vect_print_dump_info (REPORT_DETAILS))
3771                     fprintf (vect_dump, "=== scheduling SLP instances ===");
3772
3773                   vect_schedule_slp (loop_vinfo, NULL);
3774                 }
3775
3776               /* Hybrid SLP stmts must be vectorized in addition to SLP.  */
3777               if (!vinfo_for_stmt (stmt) || PURE_SLP_STMT (stmt_info))
3778                 {
3779                   gsi_next (&si);
3780                   continue;
3781                 }
3782             }
3783           
3784           /* -------- vectorize statement ------------ */
3785           if (vect_print_dump_info (REPORT_DETAILS))
3786             fprintf (vect_dump, "transform statement.");
3787
3788           strided_store = false;
3789           is_store = vect_transform_stmt (stmt, &si, &strided_store, NULL, NULL);
3790           if (is_store)
3791             {
3792               if (STMT_VINFO_STRIDED_ACCESS (stmt_info))
3793                 {
3794                   /* Interleaving. If IS_STORE is TRUE, the vectorization of the
3795                      interleaving chain was completed - free all the stores in
3796                      the chain.  */
3797                   vect_remove_stores (DR_GROUP_FIRST_DR (stmt_info));
3798                   gsi_remove (&si, true);
3799                   continue;
3800                 }
3801               else
3802                 {
3803                   /* Free the attached stmt_vec_info and remove the stmt.  */
3804                   free_stmt_vec_info (stmt);
3805                   gsi_remove (&si, true);
3806                   continue;
3807                 }
3808             }
3809           gsi_next (&si);
3810         }                       /* stmts in BB */
3811     }                           /* BBs in loop */
3812
3813   slpeel_make_loop_iterate_ntimes (loop, ratio);
3814
3815   mark_set_for_renaming (vect_memsyms_to_rename);
3816
3817   /* The memory tags and pointers in vectorized statements need to
3818      have their SSA forms updated.  FIXME, why can't this be delayed
3819      until all the loops have been transformed?  */
3820   update_ssa (TODO_update_ssa);
3821
3822   if (vect_print_dump_info (REPORT_VECTORIZED_LOCATIONS))
3823     fprintf (vect_dump, "LOOP VECTORIZED.");
3824   if (loop->inner && vect_print_dump_info (REPORT_VECTORIZED_LOCATIONS))
3825     fprintf (vect_dump, "OUTER LOOP VECTORIZED.");
3826 }