OSDN Git Service

2011-07-01 Jonathan Wakely <jwakely.gcc@gmail.com>
[pf3gnuchains/gcc-fork.git] / gcc / tree-vect-loop.c
1 /* Loop Vectorization
2    Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
3    Free Software 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 "tree-pretty-print.h"
31 #include "gimple-pretty-print.h"
32 #include "tree-flow.h"
33 #include "tree-dump.h"
34 #include "cfgloop.h"
35 #include "cfglayout.h"
36 #include "expr.h"
37 #include "recog.h"
38 #include "optabs.h"
39 #include "params.h"
40 #include "diagnostic-core.h"
41 #include "tree-chrec.h"
42 #include "tree-scalar-evolution.h"
43 #include "tree-vectorizer.h"
44 #include "target.h"
45
46 /* Loop Vectorization Pass.
47
48    This pass tries to vectorize loops.
49
50    For example, the vectorizer transforms the following simple loop:
51
52         short a[N]; short b[N]; short c[N]; int i;
53
54         for (i=0; i<N; i++){
55           a[i] = b[i] + c[i];
56         }
57
58    as if it was manually vectorized by rewriting the source code into:
59
60         typedef int __attribute__((mode(V8HI))) v8hi;
61         short a[N];  short b[N]; short c[N];   int i;
62         v8hi *pa = (v8hi*)a, *pb = (v8hi*)b, *pc = (v8hi*)c;
63         v8hi va, vb, vc;
64
65         for (i=0; i<N/8; i++){
66           vb = pb[i];
67           vc = pc[i];
68           va = vb + vc;
69           pa[i] = va;
70         }
71
72         The main entry to this pass is vectorize_loops(), in which
73    the vectorizer applies a set of analyses on a given set of loops,
74    followed by the actual vectorization transformation for the loops that
75    had successfully passed the analysis phase.
76         Throughout this pass we make a distinction between two types of
77    data: scalars (which are represented by SSA_NAMES), and memory references
78    ("data-refs").  These two types of data require different handling both
79    during analysis and transformation. The types of data-refs that the
80    vectorizer currently supports are ARRAY_REFS which base is an array DECL
81    (not a pointer), and INDIRECT_REFS through pointers; both array and pointer
82    accesses are required to have a simple (consecutive) access pattern.
83
84    Analysis phase:
85    ===============
86         The driver for the analysis phase is vect_analyze_loop().
87    It applies a set of analyses, some of which rely on the scalar evolution
88    analyzer (scev) developed by Sebastian Pop.
89
90         During the analysis phase the vectorizer records some information
91    per stmt in a "stmt_vec_info" struct which is attached to each stmt in the
92    loop, as well as general information about the loop as a whole, which is
93    recorded in a "loop_vec_info" struct attached to each loop.
94
95    Transformation phase:
96    =====================
97         The loop transformation phase scans all the stmts in the loop, and
98    creates a vector stmt (or a sequence of stmts) for each scalar stmt S in
99    the loop that needs to be vectorized.  It inserts the vector code sequence
100    just before the scalar stmt S, and records a pointer to the vector code
101    in STMT_VINFO_VEC_STMT (stmt_info) (stmt_info is the stmt_vec_info struct
102    attached to S).  This pointer will be used for the vectorization of following
103    stmts which use the def of stmt S. Stmt S is removed if it writes to memory;
104    otherwise, we rely on dead code elimination for removing it.
105
106         For example, say stmt S1 was vectorized into stmt VS1:
107
108    VS1: vb = px[i];
109    S1:  b = x[i];    STMT_VINFO_VEC_STMT (stmt_info (S1)) = VS1
110    S2:  a = b;
111
112    To vectorize stmt S2, the vectorizer first finds the stmt that defines
113    the operand 'b' (S1), and gets the relevant vector def 'vb' from the
114    vector stmt VS1 pointed to by STMT_VINFO_VEC_STMT (stmt_info (S1)).  The
115    resulting sequence would be:
116
117    VS1: vb = px[i];
118    S1:  b = x[i];       STMT_VINFO_VEC_STMT (stmt_info (S1)) = VS1
119    VS2: va = vb;
120    S2:  a = b;          STMT_VINFO_VEC_STMT (stmt_info (S2)) = VS2
121
122         Operands that are not SSA_NAMEs, are data-refs that appear in
123    load/store operations (like 'x[i]' in S1), and are handled differently.
124
125    Target modeling:
126    =================
127         Currently the only target specific information that is used is the
128    size of the vector (in bytes) - "TARGET_VECTORIZE_UNITS_PER_SIMD_WORD".
129    Targets that can support different sizes of vectors, for now will need
130    to specify one value for "TARGET_VECTORIZE_UNITS_PER_SIMD_WORD".  More
131    flexibility will be added in the future.
132
133         Since we only vectorize operations which vector form can be
134    expressed using existing tree codes, to verify that an operation is
135    supported, the vectorizer checks the relevant optab at the relevant
136    machine_mode (e.g, optab_handler (add_optab, V8HImode)).  If
137    the value found is CODE_FOR_nothing, then there's no target support, and
138    we can't vectorize the stmt.
139
140    For additional information on this project see:
141    http://gcc.gnu.org/projects/tree-ssa/vectorization.html
142 */
143
144 /* Function vect_determine_vectorization_factor
145
146    Determine the vectorization factor (VF).  VF is the number of data elements
147    that are operated upon in parallel in a single iteration of the vectorized
148    loop.  For example, when vectorizing a loop that operates on 4byte elements,
149    on a target with vector size (VS) 16byte, the VF is set to 4, since 4
150    elements can fit in a single vector register.
151
152    We currently support vectorization of loops in which all types operated upon
153    are of the same size.  Therefore this function currently sets VF according to
154    the size of the types operated upon, and fails if there are multiple sizes
155    in the loop.
156
157    VF is also the factor by which the loop iterations are strip-mined, e.g.:
158    original loop:
159         for (i=0; i<N; i++){
160           a[i] = b[i] + c[i];
161         }
162
163    vectorized loop:
164         for (i=0; i<N; i+=VF){
165           a[i:VF] = b[i:VF] + c[i:VF];
166         }
167 */
168
169 static bool
170 vect_determine_vectorization_factor (loop_vec_info loop_vinfo)
171 {
172   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
173   basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
174   int nbbs = loop->num_nodes;
175   gimple_stmt_iterator si;
176   unsigned int vectorization_factor = 0;
177   tree scalar_type;
178   gimple phi;
179   tree vectype;
180   unsigned int nunits;
181   stmt_vec_info stmt_info;
182   int i;
183   HOST_WIDE_INT dummy;
184   gimple stmt, pattern_stmt = NULL;
185   bool analyze_pattern_stmt = false;
186
187   if (vect_print_dump_info (REPORT_DETAILS))
188     fprintf (vect_dump, "=== vect_determine_vectorization_factor ===");
189
190   for (i = 0; i < nbbs; i++)
191     {
192       basic_block bb = bbs[i];
193
194       for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
195         {
196           phi = gsi_stmt (si);
197           stmt_info = vinfo_for_stmt (phi);
198           if (vect_print_dump_info (REPORT_DETAILS))
199             {
200               fprintf (vect_dump, "==> examining phi: ");
201               print_gimple_stmt (vect_dump, phi, 0, TDF_SLIM);
202             }
203
204           gcc_assert (stmt_info);
205
206           if (STMT_VINFO_RELEVANT_P (stmt_info))
207             {
208               gcc_assert (!STMT_VINFO_VECTYPE (stmt_info));
209               scalar_type = TREE_TYPE (PHI_RESULT (phi));
210
211               if (vect_print_dump_info (REPORT_DETAILS))
212                 {
213                   fprintf (vect_dump, "get vectype for scalar type:  ");
214                   print_generic_expr (vect_dump, scalar_type, TDF_SLIM);
215                 }
216
217               vectype = get_vectype_for_scalar_type (scalar_type);
218               if (!vectype)
219                 {
220                   if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
221                     {
222                       fprintf (vect_dump,
223                                "not vectorized: unsupported data-type ");
224                       print_generic_expr (vect_dump, scalar_type, TDF_SLIM);
225                     }
226                   return false;
227                 }
228               STMT_VINFO_VECTYPE (stmt_info) = vectype;
229
230               if (vect_print_dump_info (REPORT_DETAILS))
231                 {
232                   fprintf (vect_dump, "vectype: ");
233                   print_generic_expr (vect_dump, vectype, TDF_SLIM);
234                 }
235
236               nunits = TYPE_VECTOR_SUBPARTS (vectype);
237               if (vect_print_dump_info (REPORT_DETAILS))
238                 fprintf (vect_dump, "nunits = %d", nunits);
239
240               if (!vectorization_factor
241                   || (nunits > vectorization_factor))
242                 vectorization_factor = nunits;
243             }
244         }
245
246       for (si = gsi_start_bb (bb); !gsi_end_p (si) || analyze_pattern_stmt;)
247         {
248           tree vf_vectype;
249
250           if (analyze_pattern_stmt)
251             {
252               stmt = pattern_stmt;
253               analyze_pattern_stmt = false;
254             }
255           else
256             stmt = gsi_stmt (si);
257
258           stmt_info = vinfo_for_stmt (stmt);
259
260           if (vect_print_dump_info (REPORT_DETAILS))
261             {
262               fprintf (vect_dump, "==> examining statement: ");
263               print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
264             }
265
266           gcc_assert (stmt_info);
267
268           /* Skip stmts which do not need to be vectorized.  */
269           if (!STMT_VINFO_RELEVANT_P (stmt_info)
270               && !STMT_VINFO_LIVE_P (stmt_info))
271             {
272               if (STMT_VINFO_IN_PATTERN_P (stmt_info)
273                   && (pattern_stmt = STMT_VINFO_RELATED_STMT (stmt_info))
274                   && (STMT_VINFO_RELEVANT_P (vinfo_for_stmt (pattern_stmt))
275                       || STMT_VINFO_LIVE_P (vinfo_for_stmt (pattern_stmt))))
276                 {
277                   stmt = pattern_stmt;
278                   stmt_info = vinfo_for_stmt (pattern_stmt);
279                   if (vect_print_dump_info (REPORT_DETAILS))
280                     {
281                       fprintf (vect_dump, "==> examining pattern statement: ");
282                       print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
283                     }
284                 }
285               else
286                 {
287                   if (vect_print_dump_info (REPORT_DETAILS))
288                     fprintf (vect_dump, "skip.");
289                   gsi_next (&si);
290                   continue;
291                 }
292             }
293           else if (STMT_VINFO_IN_PATTERN_P (stmt_info)
294                    && (pattern_stmt = STMT_VINFO_RELATED_STMT (stmt_info))
295                    && (STMT_VINFO_RELEVANT_P (vinfo_for_stmt (pattern_stmt))
296                        || STMT_VINFO_LIVE_P (vinfo_for_stmt (pattern_stmt))))
297             analyze_pattern_stmt = true;
298
299           if (gimple_get_lhs (stmt) == NULL_TREE)
300             {
301               if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
302                 {
303                   fprintf (vect_dump, "not vectorized: irregular stmt.");
304                   print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
305                 }
306               return false;
307             }
308
309           if (VECTOR_MODE_P (TYPE_MODE (gimple_expr_type (stmt))))
310             {
311               if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
312                 {
313                   fprintf (vect_dump, "not vectorized: vector stmt in loop:");
314                   print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
315                 }
316               return false;
317             }
318
319           if (STMT_VINFO_VECTYPE (stmt_info))
320             {
321               /* The only case when a vectype had been already set is for stmts
322                  that contain a dataref, or for "pattern-stmts" (stmts generated
323                  by the vectorizer to represent/replace a certain idiom).  */
324               gcc_assert (STMT_VINFO_DATA_REF (stmt_info)
325                           || is_pattern_stmt_p (stmt_info));
326               vectype = STMT_VINFO_VECTYPE (stmt_info);
327             }
328           else
329             {
330               gcc_assert (!STMT_VINFO_DATA_REF (stmt_info));
331               scalar_type = TREE_TYPE (gimple_get_lhs (stmt));
332               if (vect_print_dump_info (REPORT_DETAILS))
333                 {
334                   fprintf (vect_dump, "get vectype for scalar type:  ");
335                   print_generic_expr (vect_dump, scalar_type, TDF_SLIM);
336                 }
337               vectype = get_vectype_for_scalar_type (scalar_type);
338               if (!vectype)
339                 {
340                   if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
341                     {
342                       fprintf (vect_dump,
343                                "not vectorized: unsupported data-type ");
344                       print_generic_expr (vect_dump, scalar_type, TDF_SLIM);
345                     }
346                   return false;
347                 }
348
349               STMT_VINFO_VECTYPE (stmt_info) = vectype;
350             }
351
352           /* The vectorization factor is according to the smallest
353              scalar type (or the largest vector size, but we only
354              support one vector size per loop).  */
355           scalar_type = vect_get_smallest_scalar_type (stmt, &dummy,
356                                                        &dummy);
357           if (vect_print_dump_info (REPORT_DETAILS))
358             {
359               fprintf (vect_dump, "get vectype for scalar type:  ");
360               print_generic_expr (vect_dump, scalar_type, TDF_SLIM);
361             }
362           vf_vectype = get_vectype_for_scalar_type (scalar_type);
363           if (!vf_vectype)
364             {
365               if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
366                 {
367                   fprintf (vect_dump,
368                            "not vectorized: unsupported data-type ");
369                   print_generic_expr (vect_dump, scalar_type, TDF_SLIM);
370                 }
371               return false;
372             }
373
374           if ((GET_MODE_SIZE (TYPE_MODE (vectype))
375                != GET_MODE_SIZE (TYPE_MODE (vf_vectype))))
376             {
377               if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
378                 {
379                   fprintf (vect_dump,
380                            "not vectorized: different sized vector "
381                            "types in statement, ");
382                   print_generic_expr (vect_dump, vectype, TDF_SLIM);
383                   fprintf (vect_dump, " and ");
384                   print_generic_expr (vect_dump, vf_vectype, TDF_SLIM);
385                 }
386               return false;
387             }
388
389           if (vect_print_dump_info (REPORT_DETAILS))
390             {
391               fprintf (vect_dump, "vectype: ");
392               print_generic_expr (vect_dump, vf_vectype, TDF_SLIM);
393             }
394
395           nunits = TYPE_VECTOR_SUBPARTS (vf_vectype);
396           if (vect_print_dump_info (REPORT_DETAILS))
397             fprintf (vect_dump, "nunits = %d", nunits);
398
399           if (!vectorization_factor
400               || (nunits > vectorization_factor))
401             vectorization_factor = nunits;
402
403           if (!analyze_pattern_stmt)
404             gsi_next (&si);
405         }
406     }
407
408   /* TODO: Analyze cost. Decide if worth while to vectorize.  */
409   if (vect_print_dump_info (REPORT_DETAILS))
410     fprintf (vect_dump, "vectorization factor = %d", vectorization_factor);
411   if (vectorization_factor <= 1)
412     {
413       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
414         fprintf (vect_dump, "not vectorized: unsupported data-type");
415       return false;
416     }
417   LOOP_VINFO_VECT_FACTOR (loop_vinfo) = vectorization_factor;
418
419   return true;
420 }
421
422
423 /* Function vect_is_simple_iv_evolution.
424
425    FORNOW: A simple evolution of an induction variables in the loop is
426    considered a polynomial evolution with constant step.  */
427
428 static bool
429 vect_is_simple_iv_evolution (unsigned loop_nb, tree access_fn, tree * init,
430                              tree * step)
431 {
432   tree init_expr;
433   tree step_expr;
434   tree evolution_part = evolution_part_in_loop_num (access_fn, loop_nb);
435
436   /* When there is no evolution in this loop, the evolution function
437      is not "simple".  */
438   if (evolution_part == NULL_TREE)
439     return false;
440
441   /* When the evolution is a polynomial of degree >= 2
442      the evolution function is not "simple".  */
443   if (tree_is_chrec (evolution_part))
444     return false;
445
446   step_expr = evolution_part;
447   init_expr = unshare_expr (initial_condition_in_loop_num (access_fn, loop_nb));
448
449   if (vect_print_dump_info (REPORT_DETAILS))
450     {
451       fprintf (vect_dump, "step: ");
452       print_generic_expr (vect_dump, step_expr, TDF_SLIM);
453       fprintf (vect_dump, ",  init: ");
454       print_generic_expr (vect_dump, init_expr, TDF_SLIM);
455     }
456
457   *init = init_expr;
458   *step = step_expr;
459
460   if (TREE_CODE (step_expr) != INTEGER_CST)
461     {
462       if (vect_print_dump_info (REPORT_DETAILS))
463         fprintf (vect_dump, "step unknown.");
464       return false;
465     }
466
467   return true;
468 }
469
470 /* Function vect_analyze_scalar_cycles_1.
471
472    Examine the cross iteration def-use cycles of scalar variables
473    in LOOP.  LOOP_VINFO represents the loop that is now being
474    considered for vectorization (can be LOOP, or an outer-loop
475    enclosing LOOP).  */
476
477 static void
478 vect_analyze_scalar_cycles_1 (loop_vec_info loop_vinfo, struct loop *loop)
479 {
480   basic_block bb = loop->header;
481   tree dumy;
482   VEC(gimple,heap) *worklist = VEC_alloc (gimple, heap, 64);
483   gimple_stmt_iterator gsi;
484   bool double_reduc;
485
486   if (vect_print_dump_info (REPORT_DETAILS))
487     fprintf (vect_dump, "=== vect_analyze_scalar_cycles ===");
488
489   /* First - identify all inductions.  Reduction detection assumes that all the
490      inductions have been identified, therefore, this order must not be
491      changed.  */
492   for (gsi = gsi_start_phis  (bb); !gsi_end_p (gsi); gsi_next (&gsi))
493     {
494       gimple phi = gsi_stmt (gsi);
495       tree access_fn = NULL;
496       tree def = PHI_RESULT (phi);
497       stmt_vec_info stmt_vinfo = vinfo_for_stmt (phi);
498
499       if (vect_print_dump_info (REPORT_DETAILS))
500         {
501           fprintf (vect_dump, "Analyze phi: ");
502           print_gimple_stmt (vect_dump, phi, 0, TDF_SLIM);
503         }
504
505       /* Skip virtual phi's.  The data dependences that are associated with
506          virtual defs/uses (i.e., memory accesses) are analyzed elsewhere.  */
507       if (!is_gimple_reg (SSA_NAME_VAR (def)))
508         continue;
509
510       STMT_VINFO_DEF_TYPE (stmt_vinfo) = vect_unknown_def_type;
511
512       /* Analyze the evolution function.  */
513       access_fn = analyze_scalar_evolution (loop, def);
514       if (access_fn)
515         STRIP_NOPS (access_fn);
516       if (access_fn && vect_print_dump_info (REPORT_DETAILS))
517         {
518           fprintf (vect_dump, "Access function of PHI: ");
519           print_generic_expr (vect_dump, access_fn, TDF_SLIM);
520         }
521
522       if (!access_fn
523           || !vect_is_simple_iv_evolution (loop->num, access_fn, &dumy, &dumy))
524         {
525           VEC_safe_push (gimple, heap, worklist, phi);
526           continue;
527         }
528
529       if (vect_print_dump_info (REPORT_DETAILS))
530         fprintf (vect_dump, "Detected induction.");
531       STMT_VINFO_DEF_TYPE (stmt_vinfo) = vect_induction_def;
532     }
533
534
535   /* Second - identify all reductions and nested cycles.  */
536   while (VEC_length (gimple, worklist) > 0)
537     {
538       gimple phi = VEC_pop (gimple, worklist);
539       tree def = PHI_RESULT (phi);
540       stmt_vec_info stmt_vinfo = vinfo_for_stmt (phi);
541       gimple reduc_stmt;
542       bool nested_cycle;
543
544       if (vect_print_dump_info (REPORT_DETAILS))
545         {
546           fprintf (vect_dump, "Analyze phi: ");
547           print_gimple_stmt (vect_dump, phi, 0, TDF_SLIM);
548         }
549
550       gcc_assert (is_gimple_reg (SSA_NAME_VAR (def)));
551       gcc_assert (STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_unknown_def_type);
552
553       nested_cycle = (loop != LOOP_VINFO_LOOP (loop_vinfo));
554       reduc_stmt = vect_force_simple_reduction (loop_vinfo, phi, !nested_cycle,
555                                                 &double_reduc);
556       if (reduc_stmt)
557         {
558           if (double_reduc)
559             {
560               if (vect_print_dump_info (REPORT_DETAILS))
561                 fprintf (vect_dump, "Detected double reduction.");
562
563               STMT_VINFO_DEF_TYPE (stmt_vinfo) = vect_double_reduction_def;
564               STMT_VINFO_DEF_TYPE (vinfo_for_stmt (reduc_stmt)) =
565                                                     vect_double_reduction_def;
566             }
567           else
568             {
569               if (nested_cycle)
570                 {
571                   if (vect_print_dump_info (REPORT_DETAILS))
572                     fprintf (vect_dump, "Detected vectorizable nested cycle.");
573
574                   STMT_VINFO_DEF_TYPE (stmt_vinfo) = vect_nested_cycle;
575                   STMT_VINFO_DEF_TYPE (vinfo_for_stmt (reduc_stmt)) =
576                                                              vect_nested_cycle;
577                 }
578               else
579                 {
580                   if (vect_print_dump_info (REPORT_DETAILS))
581                     fprintf (vect_dump, "Detected reduction.");
582
583                   STMT_VINFO_DEF_TYPE (stmt_vinfo) = vect_reduction_def;
584                   STMT_VINFO_DEF_TYPE (vinfo_for_stmt (reduc_stmt)) =
585                                                            vect_reduction_def;
586                   /* Store the reduction cycles for possible vectorization in
587                      loop-aware SLP.  */
588                   VEC_safe_push (gimple, heap,
589                                  LOOP_VINFO_REDUCTIONS (loop_vinfo),
590                                  reduc_stmt);
591                 }
592             }
593         }
594       else
595         if (vect_print_dump_info (REPORT_DETAILS))
596           fprintf (vect_dump, "Unknown def-use cycle pattern.");
597     }
598
599   VEC_free (gimple, heap, worklist);
600 }
601
602
603 /* Function vect_analyze_scalar_cycles.
604
605    Examine the cross iteration def-use cycles of scalar variables, by
606    analyzing the loop-header PHIs of scalar variables.  Classify each
607    cycle as one of the following: invariant, induction, reduction, unknown.
608    We do that for the loop represented by LOOP_VINFO, and also to its
609    inner-loop, if exists.
610    Examples for scalar cycles:
611
612    Example1: reduction:
613
614               loop1:
615               for (i=0; i<N; i++)
616                  sum += a[i];
617
618    Example2: induction:
619
620               loop2:
621               for (i=0; i<N; i++)
622                  a[i] = i;  */
623
624 static void
625 vect_analyze_scalar_cycles (loop_vec_info loop_vinfo)
626 {
627   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
628
629   vect_analyze_scalar_cycles_1 (loop_vinfo, loop);
630
631   /* When vectorizing an outer-loop, the inner-loop is executed sequentially.
632      Reductions in such inner-loop therefore have different properties than
633      the reductions in the nest that gets vectorized:
634      1. When vectorized, they are executed in the same order as in the original
635         scalar loop, so we can't change the order of computation when
636         vectorizing them.
637      2. FIXME: Inner-loop reductions can be used in the inner-loop, so the
638         current checks are too strict.  */
639
640   if (loop->inner)
641     vect_analyze_scalar_cycles_1 (loop_vinfo, loop->inner);
642 }
643
644 /* Function vect_get_loop_niters.
645
646    Determine how many iterations the loop is executed.
647    If an expression that represents the number of iterations
648    can be constructed, place it in NUMBER_OF_ITERATIONS.
649    Return the loop exit condition.  */
650
651 static gimple
652 vect_get_loop_niters (struct loop *loop, tree *number_of_iterations)
653 {
654   tree niters;
655
656   if (vect_print_dump_info (REPORT_DETAILS))
657     fprintf (vect_dump, "=== get_loop_niters ===");
658
659   niters = number_of_exit_cond_executions (loop);
660
661   if (niters != NULL_TREE
662       && niters != chrec_dont_know)
663     {
664       *number_of_iterations = niters;
665
666       if (vect_print_dump_info (REPORT_DETAILS))
667         {
668           fprintf (vect_dump, "==> get_loop_niters:" );
669           print_generic_expr (vect_dump, *number_of_iterations, TDF_SLIM);
670         }
671     }
672
673   return get_loop_exit_condition (loop);
674 }
675
676
677 /* Function bb_in_loop_p
678
679    Used as predicate for dfs order traversal of the loop bbs.  */
680
681 static bool
682 bb_in_loop_p (const_basic_block bb, const void *data)
683 {
684   const struct loop *const loop = (const struct loop *)data;
685   if (flow_bb_inside_loop_p (loop, bb))
686     return true;
687   return false;
688 }
689
690
691 /* Function new_loop_vec_info.
692
693    Create and initialize a new loop_vec_info struct for LOOP, as well as
694    stmt_vec_info structs for all the stmts in LOOP.  */
695
696 static loop_vec_info
697 new_loop_vec_info (struct loop *loop)
698 {
699   loop_vec_info res;
700   basic_block *bbs;
701   gimple_stmt_iterator si;
702   unsigned int i, nbbs;
703
704   res = (loop_vec_info) xcalloc (1, sizeof (struct _loop_vec_info));
705   LOOP_VINFO_LOOP (res) = loop;
706
707   bbs = get_loop_body (loop);
708
709   /* Create/Update stmt_info for all stmts in the loop.  */
710   for (i = 0; i < loop->num_nodes; i++)
711     {
712       basic_block bb = bbs[i];
713
714       /* BBs in a nested inner-loop will have been already processed (because
715          we will have called vect_analyze_loop_form for any nested inner-loop).
716          Therefore, for stmts in an inner-loop we just want to update the
717          STMT_VINFO_LOOP_VINFO field of their stmt_info to point to the new
718          loop_info of the outer-loop we are currently considering to vectorize
719          (instead of the loop_info of the inner-loop).
720          For stmts in other BBs we need to create a stmt_info from scratch.  */
721       if (bb->loop_father != loop)
722         {
723           /* Inner-loop bb.  */
724           gcc_assert (loop->inner && bb->loop_father == loop->inner);
725           for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
726             {
727               gimple phi = gsi_stmt (si);
728               stmt_vec_info stmt_info = vinfo_for_stmt (phi);
729               loop_vec_info inner_loop_vinfo =
730                 STMT_VINFO_LOOP_VINFO (stmt_info);
731               gcc_assert (loop->inner == LOOP_VINFO_LOOP (inner_loop_vinfo));
732               STMT_VINFO_LOOP_VINFO (stmt_info) = res;
733             }
734           for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
735            {
736               gimple stmt = gsi_stmt (si);
737               stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
738               loop_vec_info inner_loop_vinfo =
739                  STMT_VINFO_LOOP_VINFO (stmt_info);
740               gcc_assert (loop->inner == LOOP_VINFO_LOOP (inner_loop_vinfo));
741               STMT_VINFO_LOOP_VINFO (stmt_info) = res;
742            }
743         }
744       else
745         {
746           /* bb in current nest.  */
747           for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
748             {
749               gimple phi = gsi_stmt (si);
750               gimple_set_uid (phi, 0);
751               set_vinfo_for_stmt (phi, new_stmt_vec_info (phi, res, NULL));
752             }
753
754           for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
755             {
756               gimple stmt = gsi_stmt (si);
757               gimple_set_uid (stmt, 0);
758               set_vinfo_for_stmt (stmt, new_stmt_vec_info (stmt, res, NULL));
759             }
760         }
761     }
762
763   /* CHECKME: We want to visit all BBs before their successors (except for
764      latch blocks, for which this assertion wouldn't hold).  In the simple
765      case of the loop forms we allow, a dfs order of the BBs would the same
766      as reversed postorder traversal, so we are safe.  */
767
768    free (bbs);
769    bbs = XCNEWVEC (basic_block, loop->num_nodes);
770    nbbs = dfs_enumerate_from (loop->header, 0, bb_in_loop_p,
771                               bbs, loop->num_nodes, loop);
772    gcc_assert (nbbs == loop->num_nodes);
773
774   LOOP_VINFO_BBS (res) = bbs;
775   LOOP_VINFO_NITERS (res) = NULL;
776   LOOP_VINFO_NITERS_UNCHANGED (res) = NULL;
777   LOOP_VINFO_COST_MODEL_MIN_ITERS (res) = 0;
778   LOOP_VINFO_VECTORIZABLE_P (res) = 0;
779   LOOP_PEELING_FOR_ALIGNMENT (res) = 0;
780   LOOP_VINFO_VECT_FACTOR (res) = 0;
781   LOOP_VINFO_LOOP_NEST (res) = VEC_alloc (loop_p, heap, 3);
782   LOOP_VINFO_DATAREFS (res) = VEC_alloc (data_reference_p, heap, 10);
783   LOOP_VINFO_DDRS (res) = VEC_alloc (ddr_p, heap, 10 * 10);
784   LOOP_VINFO_UNALIGNED_DR (res) = NULL;
785   LOOP_VINFO_MAY_MISALIGN_STMTS (res) =
786     VEC_alloc (gimple, heap,
787                PARAM_VALUE (PARAM_VECT_MAX_VERSION_FOR_ALIGNMENT_CHECKS));
788   LOOP_VINFO_MAY_ALIAS_DDRS (res) =
789     VEC_alloc (ddr_p, heap,
790                PARAM_VALUE (PARAM_VECT_MAX_VERSION_FOR_ALIAS_CHECKS));
791   LOOP_VINFO_STRIDED_STORES (res) = VEC_alloc (gimple, heap, 10);
792   LOOP_VINFO_REDUCTIONS (res) = VEC_alloc (gimple, heap, 10);
793   LOOP_VINFO_REDUCTION_CHAINS (res) = VEC_alloc (gimple, heap, 10);
794   LOOP_VINFO_SLP_INSTANCES (res) = VEC_alloc (slp_instance, heap, 10);
795   LOOP_VINFO_SLP_UNROLLING_FACTOR (res) = 1;
796   LOOP_VINFO_PEELING_HTAB (res) = NULL;
797   LOOP_VINFO_PEELING_FOR_GAPS (res) = false;
798
799   return res;
800 }
801
802
803 /* Function destroy_loop_vec_info.
804
805    Free LOOP_VINFO struct, as well as all the stmt_vec_info structs of all the
806    stmts in the loop.  */
807
808 void
809 destroy_loop_vec_info (loop_vec_info loop_vinfo, bool clean_stmts)
810 {
811   struct loop *loop;
812   basic_block *bbs;
813   int nbbs;
814   gimple_stmt_iterator si;
815   int j;
816   VEC (slp_instance, heap) *slp_instances;
817   slp_instance instance;
818
819   if (!loop_vinfo)
820     return;
821
822   loop = LOOP_VINFO_LOOP (loop_vinfo);
823
824   bbs = LOOP_VINFO_BBS (loop_vinfo);
825   nbbs = loop->num_nodes;
826
827   if (!clean_stmts)
828     {
829       free (LOOP_VINFO_BBS (loop_vinfo));
830       free_data_refs (LOOP_VINFO_DATAREFS (loop_vinfo));
831       free_dependence_relations (LOOP_VINFO_DDRS (loop_vinfo));
832       VEC_free (loop_p, heap, LOOP_VINFO_LOOP_NEST (loop_vinfo));
833       VEC_free (gimple, heap, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo));
834       VEC_free (ddr_p, heap, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo));
835
836       free (loop_vinfo);
837       loop->aux = NULL;
838       return;
839     }
840
841   for (j = 0; j < nbbs; j++)
842     {
843       basic_block bb = bbs[j];
844       for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
845         free_stmt_vec_info (gsi_stmt (si));
846
847       for (si = gsi_start_bb (bb); !gsi_end_p (si); )
848         {
849           gimple stmt = gsi_stmt (si);
850           stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
851
852           if (stmt_info)
853             {
854               /* Check if this statement has a related "pattern stmt"
855                  (introduced by the vectorizer during the pattern recognition
856                  pass).  Free pattern's stmt_vec_info.  */
857               if (STMT_VINFO_IN_PATTERN_P (stmt_info)
858                   && vinfo_for_stmt (STMT_VINFO_RELATED_STMT (stmt_info)))
859                 free_stmt_vec_info (STMT_VINFO_RELATED_STMT (stmt_info));
860
861               /* Free stmt_vec_info.  */
862               free_stmt_vec_info (stmt);
863             }
864
865           gsi_next (&si);
866         }
867     }
868
869   free (LOOP_VINFO_BBS (loop_vinfo));
870   free_data_refs (LOOP_VINFO_DATAREFS (loop_vinfo));
871   free_dependence_relations (LOOP_VINFO_DDRS (loop_vinfo));
872   VEC_free (loop_p, heap, LOOP_VINFO_LOOP_NEST (loop_vinfo));
873   VEC_free (gimple, heap, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo));
874   VEC_free (ddr_p, heap, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo));
875   slp_instances = LOOP_VINFO_SLP_INSTANCES (loop_vinfo);
876   FOR_EACH_VEC_ELT (slp_instance, slp_instances, j, instance)
877     vect_free_slp_instance (instance);
878
879   VEC_free (slp_instance, heap, LOOP_VINFO_SLP_INSTANCES (loop_vinfo));
880   VEC_free (gimple, heap, LOOP_VINFO_STRIDED_STORES (loop_vinfo));
881   VEC_free (gimple, heap, LOOP_VINFO_REDUCTIONS (loop_vinfo));
882   VEC_free (gimple, heap, LOOP_VINFO_REDUCTION_CHAINS (loop_vinfo));
883
884   if (LOOP_VINFO_PEELING_HTAB (loop_vinfo))
885     htab_delete (LOOP_VINFO_PEELING_HTAB (loop_vinfo));
886
887   free (loop_vinfo);
888   loop->aux = NULL;
889 }
890
891
892 /* Function vect_analyze_loop_1.
893
894    Apply a set of analyses on LOOP, and create a loop_vec_info struct
895    for it. The different analyses will record information in the
896    loop_vec_info struct.  This is a subset of the analyses applied in
897    vect_analyze_loop, to be applied on an inner-loop nested in the loop
898    that is now considered for (outer-loop) vectorization.  */
899
900 static loop_vec_info
901 vect_analyze_loop_1 (struct loop *loop)
902 {
903   loop_vec_info loop_vinfo;
904
905   if (vect_print_dump_info (REPORT_DETAILS))
906     fprintf (vect_dump, "===== analyze_loop_nest_1 =====");
907
908   /* Check the CFG characteristics of the loop (nesting, entry/exit, etc.  */
909
910   loop_vinfo = vect_analyze_loop_form (loop);
911   if (!loop_vinfo)
912     {
913       if (vect_print_dump_info (REPORT_DETAILS))
914         fprintf (vect_dump, "bad inner-loop form.");
915       return NULL;
916     }
917
918   return loop_vinfo;
919 }
920
921
922 /* Function vect_analyze_loop_form.
923
924    Verify that certain CFG restrictions hold, including:
925    - the loop has a pre-header
926    - the loop has a single entry and exit
927    - the loop exit condition is simple enough, and the number of iterations
928      can be analyzed (a countable loop).  */
929
930 loop_vec_info
931 vect_analyze_loop_form (struct loop *loop)
932 {
933   loop_vec_info loop_vinfo;
934   gimple loop_cond;
935   tree number_of_iterations = NULL;
936   loop_vec_info inner_loop_vinfo = NULL;
937
938   if (vect_print_dump_info (REPORT_DETAILS))
939     fprintf (vect_dump, "=== vect_analyze_loop_form ===");
940
941   /* Different restrictions apply when we are considering an inner-most loop,
942      vs. an outer (nested) loop.
943      (FORNOW. May want to relax some of these restrictions in the future).  */
944
945   if (!loop->inner)
946     {
947       /* Inner-most loop.  We currently require that the number of BBs is
948          exactly 2 (the header and latch).  Vectorizable inner-most loops
949          look like this:
950
951                         (pre-header)
952                            |
953                           header <--------+
954                            | |            |
955                            | +--> latch --+
956                            |
957                         (exit-bb)  */
958
959       if (loop->num_nodes != 2)
960         {
961           if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
962             fprintf (vect_dump, "not vectorized: control flow in loop.");
963           return NULL;
964         }
965
966       if (empty_block_p (loop->header))
967     {
968           if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
969             fprintf (vect_dump, "not vectorized: empty loop.");
970       return NULL;
971     }
972     }
973   else
974     {
975       struct loop *innerloop = loop->inner;
976       edge entryedge;
977
978       /* Nested loop. We currently require that the loop is doubly-nested,
979          contains a single inner loop, and the number of BBs is exactly 5.
980          Vectorizable outer-loops look like this:
981
982                         (pre-header)
983                            |
984                           header <---+
985                            |         |
986                           inner-loop |
987                            |         |
988                           tail ------+
989                            |
990                         (exit-bb)
991
992          The inner-loop has the properties expected of inner-most loops
993          as described above.  */
994
995       if ((loop->inner)->inner || (loop->inner)->next)
996         {
997           if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
998             fprintf (vect_dump, "not vectorized: multiple nested loops.");
999           return NULL;
1000         }
1001
1002       /* Analyze the inner-loop.  */
1003       inner_loop_vinfo = vect_analyze_loop_1 (loop->inner);
1004       if (!inner_loop_vinfo)
1005         {
1006           if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
1007             fprintf (vect_dump, "not vectorized: Bad inner loop.");
1008           return NULL;
1009         }
1010
1011       if (!expr_invariant_in_loop_p (loop,
1012                                         LOOP_VINFO_NITERS (inner_loop_vinfo)))
1013         {
1014           if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
1015             fprintf (vect_dump,
1016                      "not vectorized: inner-loop count not invariant.");
1017           destroy_loop_vec_info (inner_loop_vinfo, true);
1018           return NULL;
1019         }
1020
1021       if (loop->num_nodes != 5)
1022         {
1023           if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
1024             fprintf (vect_dump, "not vectorized: control flow in loop.");
1025           destroy_loop_vec_info (inner_loop_vinfo, true);
1026           return NULL;
1027         }
1028
1029       gcc_assert (EDGE_COUNT (innerloop->header->preds) == 2);
1030       entryedge = EDGE_PRED (innerloop->header, 0);
1031       if (EDGE_PRED (innerloop->header, 0)->src == innerloop->latch)
1032         entryedge = EDGE_PRED (innerloop->header, 1);
1033
1034       if (entryedge->src != loop->header
1035           || !single_exit (innerloop)
1036           || single_exit (innerloop)->dest !=  EDGE_PRED (loop->latch, 0)->src)
1037         {
1038           if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
1039             fprintf (vect_dump, "not vectorized: unsupported outerloop form.");
1040           destroy_loop_vec_info (inner_loop_vinfo, true);
1041           return NULL;
1042         }
1043
1044       if (vect_print_dump_info (REPORT_DETAILS))
1045         fprintf (vect_dump, "Considering outer-loop vectorization.");
1046     }
1047
1048   if (!single_exit (loop)
1049       || EDGE_COUNT (loop->header->preds) != 2)
1050     {
1051       if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
1052         {
1053           if (!single_exit (loop))
1054             fprintf (vect_dump, "not vectorized: multiple exits.");
1055           else if (EDGE_COUNT (loop->header->preds) != 2)
1056             fprintf (vect_dump, "not vectorized: too many incoming edges.");
1057         }
1058       if (inner_loop_vinfo)
1059         destroy_loop_vec_info (inner_loop_vinfo, true);
1060       return NULL;
1061     }
1062
1063   /* We assume that the loop exit condition is at the end of the loop. i.e,
1064      that the loop is represented as a do-while (with a proper if-guard
1065      before the loop if needed), where the loop header contains all the
1066      executable statements, and the latch is empty.  */
1067   if (!empty_block_p (loop->latch)
1068         || !gimple_seq_empty_p (phi_nodes (loop->latch)))
1069     {
1070       if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
1071         fprintf (vect_dump, "not vectorized: unexpected loop form.");
1072       if (inner_loop_vinfo)
1073         destroy_loop_vec_info (inner_loop_vinfo, true);
1074       return NULL;
1075     }
1076
1077   /* Make sure there exists a single-predecessor exit bb:  */
1078   if (!single_pred_p (single_exit (loop)->dest))
1079     {
1080       edge e = single_exit (loop);
1081       if (!(e->flags & EDGE_ABNORMAL))
1082         {
1083           split_loop_exit_edge (e);
1084           if (vect_print_dump_info (REPORT_DETAILS))
1085             fprintf (vect_dump, "split exit edge.");
1086         }
1087       else
1088         {
1089           if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
1090             fprintf (vect_dump, "not vectorized: abnormal loop exit edge.");
1091           if (inner_loop_vinfo)
1092             destroy_loop_vec_info (inner_loop_vinfo, true);
1093           return NULL;
1094         }
1095     }
1096
1097   loop_cond = vect_get_loop_niters (loop, &number_of_iterations);
1098   if (!loop_cond)
1099     {
1100       if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
1101         fprintf (vect_dump, "not vectorized: complicated exit condition.");
1102       if (inner_loop_vinfo)
1103         destroy_loop_vec_info (inner_loop_vinfo, true);
1104       return NULL;
1105     }
1106
1107   if (!number_of_iterations)
1108     {
1109       if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
1110         fprintf (vect_dump,
1111                  "not vectorized: number of iterations cannot be computed.");
1112       if (inner_loop_vinfo)
1113         destroy_loop_vec_info (inner_loop_vinfo, true);
1114       return NULL;
1115     }
1116
1117   if (chrec_contains_undetermined (number_of_iterations))
1118     {
1119       if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
1120         fprintf (vect_dump, "Infinite number of iterations.");
1121       if (inner_loop_vinfo)
1122         destroy_loop_vec_info (inner_loop_vinfo, true);
1123       return NULL;
1124     }
1125
1126   if (!NITERS_KNOWN_P (number_of_iterations))
1127     {
1128       if (vect_print_dump_info (REPORT_DETAILS))
1129         {
1130           fprintf (vect_dump, "Symbolic number of iterations is ");
1131           print_generic_expr (vect_dump, number_of_iterations, TDF_DETAILS);
1132         }
1133     }
1134   else if (TREE_INT_CST_LOW (number_of_iterations) == 0)
1135     {
1136       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
1137         fprintf (vect_dump, "not vectorized: number of iterations = 0.");
1138       if (inner_loop_vinfo)
1139         destroy_loop_vec_info (inner_loop_vinfo, false);
1140       return NULL;
1141     }
1142
1143   loop_vinfo = new_loop_vec_info (loop);
1144   LOOP_VINFO_NITERS (loop_vinfo) = number_of_iterations;
1145   LOOP_VINFO_NITERS_UNCHANGED (loop_vinfo) = number_of_iterations;
1146
1147   STMT_VINFO_TYPE (vinfo_for_stmt (loop_cond)) = loop_exit_ctrl_vec_info_type;
1148
1149   /* CHECKME: May want to keep it around it in the future.  */
1150   if (inner_loop_vinfo)
1151     destroy_loop_vec_info (inner_loop_vinfo, false);
1152
1153   gcc_assert (!loop->aux);
1154   loop->aux = loop_vinfo;
1155   return loop_vinfo;
1156 }
1157
1158
1159 /* Get cost by calling cost target builtin.  */
1160
1161 static inline int
1162 vect_get_cost (enum vect_cost_for_stmt type_of_cost)
1163 {
1164   tree dummy_type = NULL;
1165   int dummy = 0;
1166
1167   return targetm.vectorize.builtin_vectorization_cost (type_of_cost,
1168                                                        dummy_type, dummy);
1169 }
1170
1171  
1172 /* Function vect_analyze_loop_operations.
1173
1174    Scan the loop stmts and make sure they are all vectorizable.  */
1175
1176 static bool
1177 vect_analyze_loop_operations (loop_vec_info loop_vinfo, bool slp)
1178 {
1179   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
1180   basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
1181   int nbbs = loop->num_nodes;
1182   gimple_stmt_iterator si;
1183   unsigned int vectorization_factor = 0;
1184   int i;
1185   gimple phi;
1186   stmt_vec_info stmt_info;
1187   bool need_to_vectorize = false;
1188   int min_profitable_iters;
1189   int min_scalar_loop_bound;
1190   unsigned int th;
1191   bool only_slp_in_loop = true, ok;
1192
1193   if (vect_print_dump_info (REPORT_DETAILS))
1194     fprintf (vect_dump, "=== vect_analyze_loop_operations ===");
1195
1196   gcc_assert (LOOP_VINFO_VECT_FACTOR (loop_vinfo));
1197   vectorization_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
1198   if (slp)
1199     {
1200       /* If all the stmts in the loop can be SLPed, we perform only SLP, and
1201          vectorization factor of the loop is the unrolling factor required by
1202          the SLP instances.  If that unrolling factor is 1, we say, that we
1203          perform pure SLP on loop - cross iteration parallelism is not
1204          exploited.  */
1205       for (i = 0; i < nbbs; i++)
1206         {
1207           basic_block bb = bbs[i];
1208           for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
1209             {
1210               gimple stmt = gsi_stmt (si);
1211               stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
1212               gcc_assert (stmt_info);
1213               if ((STMT_VINFO_RELEVANT_P (stmt_info)
1214                    || VECTORIZABLE_CYCLE_DEF (STMT_VINFO_DEF_TYPE (stmt_info)))
1215                   && !PURE_SLP_STMT (stmt_info))
1216                 /* STMT needs both SLP and loop-based vectorization.  */
1217                 only_slp_in_loop = false;
1218             }
1219         }
1220
1221       if (only_slp_in_loop)
1222         vectorization_factor = LOOP_VINFO_SLP_UNROLLING_FACTOR (loop_vinfo);
1223       else
1224         vectorization_factor = least_common_multiple (vectorization_factor,
1225                                 LOOP_VINFO_SLP_UNROLLING_FACTOR (loop_vinfo));
1226
1227       LOOP_VINFO_VECT_FACTOR (loop_vinfo) = vectorization_factor;
1228       if (vect_print_dump_info (REPORT_DETAILS))
1229         fprintf (vect_dump, "Updating vectorization factor to %d ",
1230                             vectorization_factor);
1231     }
1232
1233   for (i = 0; i < nbbs; i++)
1234     {
1235       basic_block bb = bbs[i];
1236
1237       for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
1238         {
1239           phi = gsi_stmt (si);
1240           ok = true;
1241
1242           stmt_info = vinfo_for_stmt (phi);
1243           if (vect_print_dump_info (REPORT_DETAILS))
1244             {
1245               fprintf (vect_dump, "examining phi: ");
1246               print_gimple_stmt (vect_dump, phi, 0, TDF_SLIM);
1247             }
1248
1249           /* Inner-loop loop-closed exit phi in outer-loop vectorization
1250              (i.e., a phi in the tail of the outer-loop).  */
1251           if (! is_loop_header_bb_p (bb))
1252             {
1253               /* FORNOW: we currently don't support the case that these phis
1254                  are not used in the outerloop (unless it is double reduction,
1255                  i.e., this phi is vect_reduction_def), cause this case
1256                  requires to actually do something here.  */
1257               if ((!STMT_VINFO_RELEVANT_P (stmt_info)
1258                    || STMT_VINFO_LIVE_P (stmt_info))
1259                   && STMT_VINFO_DEF_TYPE (stmt_info)
1260                      != vect_double_reduction_def)
1261                 {
1262                   if (vect_print_dump_info (REPORT_DETAILS))
1263                     fprintf (vect_dump,
1264                              "Unsupported loop-closed phi in outer-loop.");
1265                   return false;
1266                 }
1267
1268               /* If PHI is used in the outer loop, we check that its operand
1269                  is defined in the inner loop.  */
1270               if (STMT_VINFO_RELEVANT_P (stmt_info))
1271                 {
1272                   tree phi_op;
1273                   gimple op_def_stmt;
1274
1275                   if (gimple_phi_num_args (phi) != 1)
1276                     return false;
1277
1278                   phi_op = PHI_ARG_DEF (phi, 0);
1279                   if (TREE_CODE (phi_op) != SSA_NAME)
1280                     return false;
1281
1282                   op_def_stmt = SSA_NAME_DEF_STMT (phi_op);
1283                   if (!op_def_stmt || !vinfo_for_stmt (op_def_stmt))
1284                     return false;
1285
1286                   if (STMT_VINFO_RELEVANT (vinfo_for_stmt (op_def_stmt))
1287                         != vect_used_in_outer
1288                       && STMT_VINFO_RELEVANT (vinfo_for_stmt (op_def_stmt))
1289                            != vect_used_in_outer_by_reduction)
1290                     return false;
1291                 }
1292
1293               continue;
1294             }
1295
1296           gcc_assert (stmt_info);
1297
1298           if (STMT_VINFO_LIVE_P (stmt_info))
1299             {
1300               /* FORNOW: not yet supported.  */
1301               if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
1302                 fprintf (vect_dump, "not vectorized: value used after loop.");
1303               return false;
1304             }
1305
1306           if (STMT_VINFO_RELEVANT (stmt_info) == vect_used_in_scope
1307               && STMT_VINFO_DEF_TYPE (stmt_info) != vect_induction_def)
1308             {
1309               /* A scalar-dependence cycle that we don't support.  */
1310               if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
1311                 fprintf (vect_dump, "not vectorized: scalar dependence cycle.");
1312               return false;
1313             }
1314
1315           if (STMT_VINFO_RELEVANT_P (stmt_info))
1316             {
1317               need_to_vectorize = true;
1318               if (STMT_VINFO_DEF_TYPE (stmt_info) == vect_induction_def)
1319                 ok = vectorizable_induction (phi, NULL, NULL);
1320             }
1321
1322           if (!ok)
1323             {
1324               if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
1325                 {
1326                   fprintf (vect_dump,
1327                            "not vectorized: relevant phi not supported: ");
1328                   print_gimple_stmt (vect_dump, phi, 0, TDF_SLIM);
1329                 }
1330               return false;
1331             }
1332         }
1333
1334       for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
1335         {
1336           gimple stmt = gsi_stmt (si);
1337           if (!vect_analyze_stmt (stmt, &need_to_vectorize, NULL))
1338             return false;
1339         }
1340     } /* bbs */
1341
1342   /* All operations in the loop are either irrelevant (deal with loop
1343      control, or dead), or only used outside the loop and can be moved
1344      out of the loop (e.g. invariants, inductions).  The loop can be
1345      optimized away by scalar optimizations.  We're better off not
1346      touching this loop.  */
1347   if (!need_to_vectorize)
1348     {
1349       if (vect_print_dump_info (REPORT_DETAILS))
1350         fprintf (vect_dump,
1351                  "All the computation can be taken out of the loop.");
1352       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
1353         fprintf (vect_dump,
1354                  "not vectorized: redundant loop. no profit to vectorize.");
1355       return false;
1356     }
1357
1358   if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
1359       && vect_print_dump_info (REPORT_DETAILS))
1360     fprintf (vect_dump,
1361         "vectorization_factor = %d, niters = " HOST_WIDE_INT_PRINT_DEC,
1362         vectorization_factor, LOOP_VINFO_INT_NITERS (loop_vinfo));
1363
1364   if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
1365       && (LOOP_VINFO_INT_NITERS (loop_vinfo) < vectorization_factor))
1366     {
1367       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
1368         fprintf (vect_dump, "not vectorized: iteration count too small.");
1369       if (vect_print_dump_info (REPORT_DETAILS))
1370         fprintf (vect_dump,"not vectorized: iteration count smaller than "
1371                  "vectorization factor.");
1372       return false;
1373     }
1374
1375   /* Analyze cost.  Decide if worth while to vectorize.  */
1376
1377   /* Once VF is set, SLP costs should be updated since the number of created
1378      vector stmts depends on VF.  */
1379   vect_update_slp_costs_according_to_vf (loop_vinfo);
1380
1381   min_profitable_iters = vect_estimate_min_profitable_iters (loop_vinfo);
1382   LOOP_VINFO_COST_MODEL_MIN_ITERS (loop_vinfo) = min_profitable_iters;
1383
1384   if (min_profitable_iters < 0)
1385     {
1386       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
1387         fprintf (vect_dump, "not vectorized: vectorization not profitable.");
1388       if (vect_print_dump_info (REPORT_DETAILS))
1389         fprintf (vect_dump, "not vectorized: vector version will never be "
1390                  "profitable.");
1391       return false;
1392     }
1393
1394   min_scalar_loop_bound = ((PARAM_VALUE (PARAM_MIN_VECT_LOOP_BOUND)
1395                             * vectorization_factor) - 1);
1396
1397   /* Use the cost model only if it is more conservative than user specified
1398      threshold.  */
1399
1400   th = (unsigned) min_scalar_loop_bound;
1401   if (min_profitable_iters
1402       && (!min_scalar_loop_bound
1403           || min_profitable_iters > min_scalar_loop_bound))
1404     th = (unsigned) min_profitable_iters;
1405
1406   if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
1407       && LOOP_VINFO_INT_NITERS (loop_vinfo) <= th)
1408     {
1409       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
1410         fprintf (vect_dump, "not vectorized: vectorization not "
1411                  "profitable.");
1412       if (vect_print_dump_info (REPORT_DETAILS))
1413         fprintf (vect_dump, "not vectorized: iteration count smaller than "
1414                  "user specified loop bound parameter or minimum "
1415                  "profitable iterations (whichever is more conservative).");
1416       return false;
1417     }
1418
1419   if (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
1420       || LOOP_VINFO_INT_NITERS (loop_vinfo) % vectorization_factor != 0
1421       || LOOP_PEELING_FOR_ALIGNMENT (loop_vinfo))
1422     {
1423       if (vect_print_dump_info (REPORT_DETAILS))
1424         fprintf (vect_dump, "epilog loop required.");
1425       if (!vect_can_advance_ivs_p (loop_vinfo))
1426         {
1427           if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
1428             fprintf (vect_dump,
1429                      "not vectorized: can't create epilog loop 1.");
1430           return false;
1431         }
1432       if (!slpeel_can_duplicate_loop_p (loop, single_exit (loop)))
1433         {
1434           if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
1435             fprintf (vect_dump,
1436                      "not vectorized: can't create epilog loop 2.");
1437           return false;
1438         }
1439     }
1440
1441   return true;
1442 }
1443
1444
1445 /* Function vect_analyze_loop_2.
1446
1447    Apply a set of analyses on LOOP, and create a loop_vec_info struct
1448    for it.  The different analyses will record information in the
1449    loop_vec_info struct.  */
1450 static bool
1451 vect_analyze_loop_2 (loop_vec_info loop_vinfo)
1452 {
1453   bool ok, dummy, slp = false;
1454   int max_vf = MAX_VECTORIZATION_FACTOR;
1455   int min_vf = 2;
1456
1457   /* Find all data references in the loop (which correspond to vdefs/vuses)
1458      and analyze their evolution in the loop.  Also adjust the minimal
1459      vectorization factor according to the loads and stores.
1460
1461      FORNOW: Handle only simple, array references, which
1462      alignment can be forced, and aligned pointer-references.  */
1463
1464   ok = vect_analyze_data_refs (loop_vinfo, NULL, &min_vf);
1465   if (!ok)
1466     {
1467       if (vect_print_dump_info (REPORT_DETAILS))
1468         fprintf (vect_dump, "bad data references.");
1469       return false;
1470     }
1471
1472   /* Classify all cross-iteration scalar data-flow cycles.
1473      Cross-iteration cycles caused by virtual phis are analyzed separately.  */
1474
1475   vect_analyze_scalar_cycles (loop_vinfo);
1476
1477   vect_pattern_recog (loop_vinfo);
1478
1479   /* Data-flow analysis to detect stmts that do not need to be vectorized.  */
1480
1481   ok = vect_mark_stmts_to_be_vectorized (loop_vinfo);
1482   if (!ok)
1483     {
1484       if (vect_print_dump_info (REPORT_DETAILS))
1485         fprintf (vect_dump, "unexpected pattern.");
1486       return false;
1487     }
1488
1489   /* Analyze data dependences between the data-refs in the loop
1490      and adjust the maximum vectorization factor according to
1491      the dependences.
1492      FORNOW: fail at the first data dependence that we encounter.  */
1493
1494   ok = vect_analyze_data_ref_dependences (loop_vinfo, NULL, &max_vf, &dummy);
1495   if (!ok
1496       || max_vf < min_vf)
1497     {
1498       if (vect_print_dump_info (REPORT_DETAILS))
1499         fprintf (vect_dump, "bad data dependence.");
1500       return false;
1501     }
1502
1503   ok = vect_determine_vectorization_factor (loop_vinfo);
1504   if (!ok)
1505     {
1506       if (vect_print_dump_info (REPORT_DETAILS))
1507         fprintf (vect_dump, "can't determine vectorization factor.");
1508       return false;
1509     }
1510   if (max_vf < LOOP_VINFO_VECT_FACTOR (loop_vinfo))
1511     {
1512       if (vect_print_dump_info (REPORT_DETAILS))
1513         fprintf (vect_dump, "bad data dependence.");
1514       return false;
1515     }
1516
1517   /* Analyze the alignment of the data-refs in the loop.
1518      Fail if a data reference is found that cannot be vectorized.  */
1519
1520   ok = vect_analyze_data_refs_alignment (loop_vinfo, NULL);
1521   if (!ok)
1522     {
1523       if (vect_print_dump_info (REPORT_DETAILS))
1524         fprintf (vect_dump, "bad data alignment.");
1525       return false;
1526     }
1527
1528   /* Analyze the access patterns of the data-refs in the loop (consecutive,
1529      complex, etc.). FORNOW: Only handle consecutive access pattern.  */
1530
1531   ok = vect_analyze_data_ref_accesses (loop_vinfo, NULL);
1532   if (!ok)
1533     {
1534       if (vect_print_dump_info (REPORT_DETAILS))
1535         fprintf (vect_dump, "bad data access.");
1536       return false;
1537     }
1538
1539   /* Prune the list of ddrs to be tested at run-time by versioning for alias.
1540      It is important to call pruning after vect_analyze_data_ref_accesses,
1541      since we use grouping information gathered by interleaving analysis.  */
1542   ok = vect_prune_runtime_alias_test_list (loop_vinfo);
1543   if (!ok)
1544     {
1545       if (vect_print_dump_info (REPORT_DETAILS))
1546         fprintf (vect_dump, "too long list of versioning for alias "
1547                             "run-time tests.");
1548       return false;
1549     }
1550
1551   /* This pass will decide on using loop versioning and/or loop peeling in
1552      order to enhance the alignment of data references in the loop.  */
1553
1554   ok = vect_enhance_data_refs_alignment (loop_vinfo);
1555   if (!ok)
1556     {
1557       if (vect_print_dump_info (REPORT_DETAILS))
1558         fprintf (vect_dump, "bad data alignment.");
1559       return false;
1560     }
1561
1562   /* Check the SLP opportunities in the loop, analyze and build SLP trees.  */
1563   ok = vect_analyze_slp (loop_vinfo, NULL);
1564   if (ok)
1565     {
1566       /* Decide which possible SLP instances to SLP.  */
1567       slp = vect_make_slp_decision (loop_vinfo);
1568
1569       /* Find stmts that need to be both vectorized and SLPed.  */
1570       vect_detect_hybrid_slp (loop_vinfo);
1571     }
1572   else
1573     return false;
1574
1575   /* Scan all the operations in the loop and make sure they are
1576      vectorizable.  */
1577
1578   ok = vect_analyze_loop_operations (loop_vinfo, slp);
1579   if (!ok)
1580     {
1581       if (vect_print_dump_info (REPORT_DETAILS))
1582         fprintf (vect_dump, "bad operation or unsupported loop bound.");
1583       return false;
1584     }
1585
1586   return true;
1587 }
1588
1589 /* Function vect_analyze_loop.
1590
1591    Apply a set of analyses on LOOP, and create a loop_vec_info struct
1592    for it.  The different analyses will record information in the
1593    loop_vec_info struct.  */
1594 loop_vec_info
1595 vect_analyze_loop (struct loop *loop)
1596 {
1597   loop_vec_info loop_vinfo;
1598   unsigned int vector_sizes;
1599
1600   /* Autodetect first vector size we try.  */
1601   current_vector_size = 0;
1602   vector_sizes = targetm.vectorize.autovectorize_vector_sizes ();
1603
1604   if (vect_print_dump_info (REPORT_DETAILS))
1605     fprintf (vect_dump, "===== analyze_loop_nest =====");
1606
1607   if (loop_outer (loop)
1608       && loop_vec_info_for_loop (loop_outer (loop))
1609       && LOOP_VINFO_VECTORIZABLE_P (loop_vec_info_for_loop (loop_outer (loop))))
1610     {
1611       if (vect_print_dump_info (REPORT_DETAILS))
1612         fprintf (vect_dump, "outer-loop already vectorized.");
1613       return NULL;
1614     }
1615
1616   while (1)
1617     {
1618       /* Check the CFG characteristics of the loop (nesting, entry/exit).  */
1619       loop_vinfo = vect_analyze_loop_form (loop);
1620       if (!loop_vinfo)
1621         {
1622           if (vect_print_dump_info (REPORT_DETAILS))
1623             fprintf (vect_dump, "bad loop form.");
1624           return NULL;
1625         }
1626
1627       if (vect_analyze_loop_2 (loop_vinfo))
1628         {
1629           LOOP_VINFO_VECTORIZABLE_P (loop_vinfo) = 1;
1630
1631           return loop_vinfo;
1632         }
1633
1634       destroy_loop_vec_info (loop_vinfo, true);
1635
1636       vector_sizes &= ~current_vector_size;
1637       if (vector_sizes == 0
1638           || current_vector_size == 0)
1639         return NULL;
1640
1641       /* Try the next biggest vector size.  */
1642       current_vector_size = 1 << floor_log2 (vector_sizes);
1643       if (vect_print_dump_info (REPORT_DETAILS))
1644         fprintf (vect_dump, "***** Re-trying analysis with "
1645                  "vector size %d\n", current_vector_size);
1646     }
1647 }
1648
1649
1650 /* Function reduction_code_for_scalar_code
1651
1652    Input:
1653    CODE - tree_code of a reduction operations.
1654
1655    Output:
1656    REDUC_CODE - the corresponding tree-code to be used to reduce the
1657       vector of partial results into a single scalar result (which
1658       will also reside in a vector) or ERROR_MARK if the operation is
1659       a supported reduction operation, but does not have such tree-code.
1660
1661    Return FALSE if CODE currently cannot be vectorized as reduction.  */
1662
1663 static bool
1664 reduction_code_for_scalar_code (enum tree_code code,
1665                                 enum tree_code *reduc_code)
1666 {
1667   switch (code)
1668     {
1669       case MAX_EXPR:
1670         *reduc_code = REDUC_MAX_EXPR;
1671         return true;
1672
1673       case MIN_EXPR:
1674         *reduc_code = REDUC_MIN_EXPR;
1675         return true;
1676
1677       case PLUS_EXPR:
1678         *reduc_code = REDUC_PLUS_EXPR;
1679         return true;
1680
1681       case MULT_EXPR:
1682       case MINUS_EXPR:
1683       case BIT_IOR_EXPR:
1684       case BIT_XOR_EXPR:
1685       case BIT_AND_EXPR:
1686         *reduc_code = ERROR_MARK;
1687         return true;
1688
1689       default:
1690        return false;
1691     }
1692 }
1693
1694
1695 /* Error reporting helper for vect_is_simple_reduction below.  GIMPLE statement
1696    STMT is printed with a message MSG. */
1697
1698 static void
1699 report_vect_op (gimple stmt, const char *msg)
1700 {
1701   fprintf (vect_dump, "%s", msg);
1702   print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
1703 }
1704
1705
1706 /* Detect SLP reduction of the form:
1707
1708    #a1 = phi <a5, a0>
1709    a2 = operation (a1)
1710    a3 = operation (a2)
1711    a4 = operation (a3)
1712    a5 = operation (a4)
1713
1714    #a = phi <a5>
1715
1716    PHI is the reduction phi node (#a1 = phi <a5, a0> above)
1717    FIRST_STMT is the first reduction stmt in the chain
1718    (a2 = operation (a1)).
1719
1720    Return TRUE if a reduction chain was detected.  */
1721
1722 static bool
1723 vect_is_slp_reduction (loop_vec_info loop_info, gimple phi, gimple first_stmt)
1724 {
1725   struct loop *loop = (gimple_bb (phi))->loop_father;
1726   struct loop *vect_loop = LOOP_VINFO_LOOP (loop_info);
1727   enum tree_code code;
1728   gimple current_stmt = NULL, loop_use_stmt = NULL, first, next_stmt;
1729   stmt_vec_info use_stmt_info, current_stmt_info;
1730   tree lhs;
1731   imm_use_iterator imm_iter;
1732   use_operand_p use_p;
1733   int nloop_uses, size = 0;
1734   bool found = false;
1735
1736   if (loop != vect_loop)
1737     return false;
1738
1739   lhs = PHI_RESULT (phi);
1740   code = gimple_assign_rhs_code (first_stmt);
1741   while (1)
1742     {
1743       nloop_uses = 0;
1744       FOR_EACH_IMM_USE_FAST (use_p, imm_iter, lhs)
1745         {
1746           gimple use_stmt = USE_STMT (use_p);
1747           if (is_gimple_debug (use_stmt))
1748             continue;
1749
1750           use_stmt = USE_STMT (use_p);
1751
1752           /* Check if we got back to the reduction phi.  */
1753           if (use_stmt == phi)
1754             {
1755               loop_use_stmt = use_stmt;
1756               found = true;
1757               break;
1758             }
1759
1760           if (flow_bb_inside_loop_p (loop, gimple_bb (use_stmt))
1761               && vinfo_for_stmt (use_stmt)
1762               && !STMT_VINFO_IN_PATTERN_P (vinfo_for_stmt (use_stmt)))
1763             {
1764               loop_use_stmt = use_stmt;
1765               nloop_uses++;
1766             }
1767
1768           if (nloop_uses > 1)
1769             return false;
1770         }
1771
1772       if (found)
1773         break;
1774
1775       /* We reached a statement with no loop uses.  */
1776       if (nloop_uses == 0)
1777         return false;
1778
1779       /* This is a loop exit phi, and we haven't reached the reduction phi.  */
1780       if (gimple_code (loop_use_stmt) == GIMPLE_PHI)
1781         return false;
1782
1783       if (!is_gimple_assign (loop_use_stmt)
1784           || code != gimple_assign_rhs_code (loop_use_stmt)
1785           || !flow_bb_inside_loop_p (loop, gimple_bb (loop_use_stmt)))
1786         return false;
1787
1788       /* Insert USE_STMT into reduction chain.  */
1789       use_stmt_info = vinfo_for_stmt (loop_use_stmt);
1790       if (current_stmt)
1791         {
1792           current_stmt_info = vinfo_for_stmt (current_stmt);
1793           GROUP_NEXT_ELEMENT (current_stmt_info) = loop_use_stmt;
1794           GROUP_FIRST_ELEMENT (use_stmt_info)
1795             = GROUP_FIRST_ELEMENT (current_stmt_info);
1796         }
1797       else
1798         GROUP_FIRST_ELEMENT (use_stmt_info) = loop_use_stmt;
1799
1800       lhs = gimple_assign_lhs (loop_use_stmt);
1801       current_stmt = loop_use_stmt;
1802       size++;
1803    }
1804
1805   if (!found || loop_use_stmt != phi || size < 2)
1806     return false;
1807
1808   /* Swap the operands, if needed, to make the reduction operand be the second
1809      operand.  */
1810   lhs = PHI_RESULT (phi);
1811   next_stmt = GROUP_FIRST_ELEMENT (vinfo_for_stmt (current_stmt));
1812   while (next_stmt)
1813     {
1814       if (gimple_assign_rhs2 (next_stmt) == lhs)
1815         {
1816           tree op = gimple_assign_rhs1 (next_stmt);
1817           gimple def_stmt = NULL;
1818
1819           if (TREE_CODE (op) == SSA_NAME)
1820             def_stmt = SSA_NAME_DEF_STMT (op);
1821
1822           /* Check that the other def is either defined in the loop
1823              ("vect_internal_def"), or it's an induction (defined by a
1824              loop-header phi-node).  */
1825           if (def_stmt
1826               && flow_bb_inside_loop_p (loop, gimple_bb (def_stmt))
1827               && (is_gimple_assign (def_stmt)
1828                   || is_gimple_call (def_stmt)
1829                   || STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def_stmt))
1830                            == vect_induction_def
1831                   || (gimple_code (def_stmt) == GIMPLE_PHI
1832                       && STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def_stmt))
1833                                   == vect_internal_def
1834                       && !is_loop_header_bb_p (gimple_bb (def_stmt)))))
1835             {
1836               lhs = gimple_assign_lhs (next_stmt);
1837               next_stmt = GROUP_NEXT_ELEMENT (vinfo_for_stmt (next_stmt));
1838               continue;
1839             }
1840
1841           return false;
1842         }
1843       else
1844         {
1845           tree op = gimple_assign_rhs2 (next_stmt);
1846           gimple def_stmt = NULL;
1847
1848           if (TREE_CODE (op) == SSA_NAME)
1849             def_stmt = SSA_NAME_DEF_STMT (op);
1850
1851           /* Check that the other def is either defined in the loop
1852             ("vect_internal_def"), or it's an induction (defined by a
1853             loop-header phi-node).  */
1854           if (def_stmt
1855               && flow_bb_inside_loop_p (loop, gimple_bb (def_stmt))
1856               && (is_gimple_assign (def_stmt)
1857                   || is_gimple_call (def_stmt)
1858                   || STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def_stmt))
1859                               == vect_induction_def
1860                   || (gimple_code (def_stmt) == GIMPLE_PHI
1861                       && STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def_stmt))
1862                                   == vect_internal_def
1863                       && !is_loop_header_bb_p (gimple_bb (def_stmt)))))
1864             {
1865               if (vect_print_dump_info (REPORT_DETAILS))
1866                 {
1867                   fprintf (vect_dump, "swapping oprnds: ");
1868                   print_gimple_stmt (vect_dump, next_stmt, 0, TDF_SLIM);
1869                 }
1870
1871               swap_tree_operands (next_stmt,
1872                                   gimple_assign_rhs1_ptr (next_stmt),
1873                                   gimple_assign_rhs2_ptr (next_stmt));
1874               mark_symbols_for_renaming (next_stmt);
1875             }
1876           else
1877             return false;
1878         }
1879
1880       lhs = gimple_assign_lhs (next_stmt);
1881       next_stmt = GROUP_NEXT_ELEMENT (vinfo_for_stmt (next_stmt));
1882     }
1883
1884   /* Save the chain for further analysis in SLP detection.  */
1885   first = GROUP_FIRST_ELEMENT (vinfo_for_stmt (current_stmt));
1886   VEC_safe_push (gimple, heap, LOOP_VINFO_REDUCTION_CHAINS (loop_info), first);
1887   GROUP_SIZE (vinfo_for_stmt (first)) = size;
1888
1889   return true;
1890 }
1891
1892
1893 /* Function vect_is_simple_reduction_1
1894
1895    (1) Detect a cross-iteration def-use cycle that represents a simple
1896    reduction computation.  We look for the following pattern:
1897
1898    loop_header:
1899      a1 = phi < a0, a2 >
1900      a3 = ...
1901      a2 = operation (a3, a1)
1902
1903    such that:
1904    1. operation is commutative and associative and it is safe to
1905       change the order of the computation (if CHECK_REDUCTION is true)
1906    2. no uses for a2 in the loop (a2 is used out of the loop)
1907    3. no uses of a1 in the loop besides the reduction operation
1908    4. no uses of a1 outside the loop.
1909
1910    Conditions 1,4 are tested here.
1911    Conditions 2,3 are tested in vect_mark_stmts_to_be_vectorized.
1912
1913    (2) Detect a cross-iteration def-use cycle in nested loops, i.e.,
1914    nested cycles, if CHECK_REDUCTION is false.
1915
1916    (3) Detect cycles of phi nodes in outer-loop vectorization, i.e., double
1917    reductions:
1918
1919      a1 = phi < a0, a2 >
1920      inner loop (def of a3)
1921      a2 = phi < a3 >
1922
1923    If MODIFY is true it tries also to rework the code in-place to enable
1924    detection of more reduction patterns.  For the time being we rewrite
1925    "res -= RHS" into "rhs += -RHS" when it seems worthwhile.
1926 */
1927
1928 static gimple
1929 vect_is_simple_reduction_1 (loop_vec_info loop_info, gimple phi,
1930                             bool check_reduction, bool *double_reduc,
1931                             bool modify)
1932 {
1933   struct loop *loop = (gimple_bb (phi))->loop_father;
1934   struct loop *vect_loop = LOOP_VINFO_LOOP (loop_info);
1935   edge latch_e = loop_latch_edge (loop);
1936   tree loop_arg = PHI_ARG_DEF_FROM_EDGE (phi, latch_e);
1937   gimple def_stmt, def1 = NULL, def2 = NULL;
1938   enum tree_code orig_code, code;
1939   tree op1, op2, op3 = NULL_TREE, op4 = NULL_TREE;
1940   tree type;
1941   int nloop_uses;
1942   tree name;
1943   imm_use_iterator imm_iter;
1944   use_operand_p use_p;
1945   bool phi_def;
1946
1947   *double_reduc = false;
1948
1949   /* If CHECK_REDUCTION is true, we assume inner-most loop vectorization,
1950      otherwise, we assume outer loop vectorization.  */
1951   gcc_assert ((check_reduction && loop == vect_loop)
1952               || (!check_reduction && flow_loop_nested_p (vect_loop, loop)));
1953
1954   name = PHI_RESULT (phi);
1955   nloop_uses = 0;
1956   FOR_EACH_IMM_USE_FAST (use_p, imm_iter, name)
1957     {
1958       gimple use_stmt = USE_STMT (use_p);
1959       if (is_gimple_debug (use_stmt))
1960         continue;
1961
1962       if (!flow_bb_inside_loop_p (loop, gimple_bb (use_stmt)))
1963         {
1964           if (vect_print_dump_info (REPORT_DETAILS))
1965             fprintf (vect_dump, "intermediate value used outside loop.");
1966
1967           return NULL;
1968         }
1969
1970       if (vinfo_for_stmt (use_stmt)
1971           && !is_pattern_stmt_p (vinfo_for_stmt (use_stmt)))
1972         nloop_uses++;
1973       if (nloop_uses > 1)
1974         {
1975           if (vect_print_dump_info (REPORT_DETAILS))
1976             fprintf (vect_dump, "reduction used in loop.");
1977           return NULL;
1978         }
1979     }
1980
1981   if (TREE_CODE (loop_arg) != SSA_NAME)
1982     {
1983       if (vect_print_dump_info (REPORT_DETAILS))
1984         {
1985           fprintf (vect_dump, "reduction: not ssa_name: ");
1986           print_generic_expr (vect_dump, loop_arg, TDF_SLIM);
1987         }
1988       return NULL;
1989     }
1990
1991   def_stmt = SSA_NAME_DEF_STMT (loop_arg);
1992   if (!def_stmt)
1993     {
1994       if (vect_print_dump_info (REPORT_DETAILS))
1995         fprintf (vect_dump, "reduction: no def_stmt.");
1996       return NULL;
1997     }
1998
1999   if (!is_gimple_assign (def_stmt) && gimple_code (def_stmt) != GIMPLE_PHI)
2000     {
2001       if (vect_print_dump_info (REPORT_DETAILS))
2002         print_gimple_stmt (vect_dump, def_stmt, 0, TDF_SLIM);
2003       return NULL;
2004     }
2005
2006   if (is_gimple_assign (def_stmt))
2007     {
2008       name = gimple_assign_lhs (def_stmt);
2009       phi_def = false;
2010     }
2011   else
2012     {
2013       name = PHI_RESULT (def_stmt);
2014       phi_def = true;
2015     }
2016
2017   nloop_uses = 0;
2018   FOR_EACH_IMM_USE_FAST (use_p, imm_iter, name)
2019     {
2020       gimple use_stmt = USE_STMT (use_p);
2021       if (is_gimple_debug (use_stmt))
2022         continue;
2023       if (flow_bb_inside_loop_p (loop, gimple_bb (use_stmt))
2024           && vinfo_for_stmt (use_stmt)
2025           && !is_pattern_stmt_p (vinfo_for_stmt (use_stmt)))
2026         nloop_uses++;
2027       if (nloop_uses > 1)
2028         {
2029           if (vect_print_dump_info (REPORT_DETAILS))
2030             fprintf (vect_dump, "reduction used in loop.");
2031           return NULL;
2032         }
2033     }
2034
2035   /* If DEF_STMT is a phi node itself, we expect it to have a single argument
2036      defined in the inner loop.  */
2037   if (phi_def)
2038     {
2039       op1 = PHI_ARG_DEF (def_stmt, 0);
2040
2041       if (gimple_phi_num_args (def_stmt) != 1
2042           || TREE_CODE (op1) != SSA_NAME)
2043         {
2044           if (vect_print_dump_info (REPORT_DETAILS))
2045             fprintf (vect_dump, "unsupported phi node definition.");
2046
2047           return NULL;
2048         }
2049
2050       def1 = SSA_NAME_DEF_STMT (op1);
2051       if (flow_bb_inside_loop_p (loop, gimple_bb (def_stmt))
2052           && loop->inner
2053           && flow_bb_inside_loop_p (loop->inner, gimple_bb (def1))
2054           && is_gimple_assign (def1))
2055         {
2056           if (vect_print_dump_info (REPORT_DETAILS))
2057             report_vect_op (def_stmt, "detected double reduction: ");
2058
2059           *double_reduc = true;
2060           return def_stmt;
2061         }
2062
2063       return NULL;
2064     }
2065
2066   code = orig_code = gimple_assign_rhs_code (def_stmt);
2067
2068   /* We can handle "res -= x[i]", which is non-associative by
2069      simply rewriting this into "res += -x[i]".  Avoid changing
2070      gimple instruction for the first simple tests and only do this
2071      if we're allowed to change code at all.  */
2072   if (code == MINUS_EXPR
2073       && modify
2074       && (op1 = gimple_assign_rhs1 (def_stmt))
2075       && TREE_CODE (op1) == SSA_NAME
2076       && SSA_NAME_DEF_STMT (op1) == phi)
2077     code = PLUS_EXPR;
2078
2079   if (check_reduction
2080       && (!commutative_tree_code (code) || !associative_tree_code (code)))
2081     {
2082       if (vect_print_dump_info (REPORT_DETAILS))
2083         report_vect_op (def_stmt, "reduction: not commutative/associative: ");
2084       return NULL;
2085     }
2086
2087   if (get_gimple_rhs_class (code) != GIMPLE_BINARY_RHS)
2088     {
2089       if (code != COND_EXPR)
2090         {
2091           if (vect_print_dump_info (REPORT_DETAILS))
2092             report_vect_op (def_stmt, "reduction: not binary operation: ");
2093
2094           return NULL;
2095         }
2096
2097       op3 = TREE_OPERAND (gimple_assign_rhs1 (def_stmt), 0);
2098       if (COMPARISON_CLASS_P (op3))
2099         {
2100           op4 = TREE_OPERAND (op3, 1);
2101           op3 = TREE_OPERAND (op3, 0);
2102         }
2103
2104       op1 = TREE_OPERAND (gimple_assign_rhs1 (def_stmt), 1);
2105       op2 = TREE_OPERAND (gimple_assign_rhs1 (def_stmt), 2);
2106
2107       if (TREE_CODE (op1) != SSA_NAME && TREE_CODE (op2) != SSA_NAME)
2108         {
2109           if (vect_print_dump_info (REPORT_DETAILS))
2110             report_vect_op (def_stmt, "reduction: uses not ssa_names: ");
2111
2112           return NULL;
2113         }
2114     }
2115   else
2116     {
2117       op1 = gimple_assign_rhs1 (def_stmt);
2118       op2 = gimple_assign_rhs2 (def_stmt);
2119
2120       if (TREE_CODE (op1) != SSA_NAME || TREE_CODE (op2) != SSA_NAME)
2121         {
2122           if (vect_print_dump_info (REPORT_DETAILS))
2123             report_vect_op (def_stmt, "reduction: uses not ssa_names: ");
2124
2125           return NULL;
2126         }
2127    }
2128
2129   type = TREE_TYPE (gimple_assign_lhs (def_stmt));
2130   if ((TREE_CODE (op1) == SSA_NAME
2131        && !types_compatible_p (type,TREE_TYPE (op1)))
2132       || (TREE_CODE (op2) == SSA_NAME
2133           && !types_compatible_p (type, TREE_TYPE (op2)))
2134       || (op3 && TREE_CODE (op3) == SSA_NAME
2135           && !types_compatible_p (type, TREE_TYPE (op3)))
2136       || (op4 && TREE_CODE (op4) == SSA_NAME
2137           && !types_compatible_p (type, TREE_TYPE (op4))))
2138     {
2139       if (vect_print_dump_info (REPORT_DETAILS))
2140         {
2141           fprintf (vect_dump, "reduction: multiple types: operation type: ");
2142           print_generic_expr (vect_dump, type, TDF_SLIM);
2143           fprintf (vect_dump, ", operands types: ");
2144           print_generic_expr (vect_dump, TREE_TYPE (op1), TDF_SLIM);
2145           fprintf (vect_dump, ",");
2146           print_generic_expr (vect_dump, TREE_TYPE (op2), TDF_SLIM);
2147           if (op3)
2148             {
2149               fprintf (vect_dump, ",");
2150               print_generic_expr (vect_dump, TREE_TYPE (op3), TDF_SLIM);
2151             }
2152
2153           if (op4)
2154             {
2155               fprintf (vect_dump, ",");
2156               print_generic_expr (vect_dump, TREE_TYPE (op4), TDF_SLIM);
2157             }
2158         }
2159
2160       return NULL;
2161     }
2162
2163   /* Check that it's ok to change the order of the computation.
2164      Generally, when vectorizing a reduction we change the order of the
2165      computation.  This may change the behavior of the program in some
2166      cases, so we need to check that this is ok.  One exception is when
2167      vectorizing an outer-loop: the inner-loop is executed sequentially,
2168      and therefore vectorizing reductions in the inner-loop during
2169      outer-loop vectorization is safe.  */
2170
2171   /* CHECKME: check for !flag_finite_math_only too?  */
2172   if (SCALAR_FLOAT_TYPE_P (type) && !flag_associative_math
2173       && check_reduction)
2174     {
2175       /* Changing the order of operations changes the semantics.  */
2176       if (vect_print_dump_info (REPORT_DETAILS))
2177         report_vect_op (def_stmt, "reduction: unsafe fp math optimization: ");
2178       return NULL;
2179     }
2180   else if (INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_TRAPS (type)
2181            && check_reduction)
2182     {
2183       /* Changing the order of operations changes the semantics.  */
2184       if (vect_print_dump_info (REPORT_DETAILS))
2185         report_vect_op (def_stmt, "reduction: unsafe int math optimization: ");
2186       return NULL;
2187     }
2188   else if (SAT_FIXED_POINT_TYPE_P (type) && check_reduction)
2189     {
2190       /* Changing the order of operations changes the semantics.  */
2191       if (vect_print_dump_info (REPORT_DETAILS))
2192         report_vect_op (def_stmt,
2193                         "reduction: unsafe fixed-point math optimization: ");
2194       return NULL;
2195     }
2196
2197   /* If we detected "res -= x[i]" earlier, rewrite it into
2198      "res += -x[i]" now.  If this turns out to be useless reassoc
2199      will clean it up again.  */
2200   if (orig_code == MINUS_EXPR)
2201     {
2202       tree rhs = gimple_assign_rhs2 (def_stmt);
2203       tree negrhs = make_ssa_name (SSA_NAME_VAR (rhs), NULL);
2204       gimple negate_stmt = gimple_build_assign_with_ops (NEGATE_EXPR, negrhs,
2205                                                          rhs, NULL);
2206       gimple_stmt_iterator gsi = gsi_for_stmt (def_stmt);
2207       set_vinfo_for_stmt (negate_stmt, new_stmt_vec_info (negate_stmt, 
2208                                                           loop_info, NULL));
2209       gsi_insert_before (&gsi, negate_stmt, GSI_NEW_STMT);
2210       gimple_assign_set_rhs2 (def_stmt, negrhs);
2211       gimple_assign_set_rhs_code (def_stmt, PLUS_EXPR);
2212       update_stmt (def_stmt);
2213     }
2214
2215   /* Reduction is safe. We're dealing with one of the following:
2216      1) integer arithmetic and no trapv
2217      2) floating point arithmetic, and special flags permit this optimization
2218      3) nested cycle (i.e., outer loop vectorization).  */
2219   if (TREE_CODE (op1) == SSA_NAME)
2220     def1 = SSA_NAME_DEF_STMT (op1);
2221
2222   if (TREE_CODE (op2) == SSA_NAME)
2223     def2 = SSA_NAME_DEF_STMT (op2);
2224
2225   if (code != COND_EXPR
2226       && (!def1 || !def2 || gimple_nop_p (def1) || gimple_nop_p (def2)))
2227     {
2228       if (vect_print_dump_info (REPORT_DETAILS))
2229         report_vect_op (def_stmt, "reduction: no defs for operands: ");
2230       return NULL;
2231     }
2232
2233   /* Check that one def is the reduction def, defined by PHI,
2234      the other def is either defined in the loop ("vect_internal_def"),
2235      or it's an induction (defined by a loop-header phi-node).  */
2236
2237   if (def2 && def2 == phi
2238       && (code == COND_EXPR
2239           || (def1 && flow_bb_inside_loop_p (loop, gimple_bb (def1))
2240               && (is_gimple_assign (def1)
2241                   || is_gimple_call (def1)
2242                   || STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def1))
2243                       == vect_induction_def
2244                   || (gimple_code (def1) == GIMPLE_PHI
2245                       && STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def1))
2246                           == vect_internal_def
2247                       && !is_loop_header_bb_p (gimple_bb (def1)))))))
2248     {
2249       if (vect_print_dump_info (REPORT_DETAILS))
2250         report_vect_op (def_stmt, "detected reduction: ");
2251       return def_stmt;
2252     }
2253
2254   if (def1 && def1 == phi
2255       && (code == COND_EXPR
2256           || (def2 && flow_bb_inside_loop_p (loop, gimple_bb (def2))
2257               && (is_gimple_assign (def2)
2258                   || is_gimple_call (def2)
2259                   || STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def2))
2260                       == vect_induction_def
2261                   || (gimple_code (def2) == GIMPLE_PHI
2262                       && STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def2))
2263                           == vect_internal_def
2264                       && !is_loop_header_bb_p (gimple_bb (def2)))))))
2265     {
2266       if (check_reduction)
2267         {
2268           /* Swap operands (just for simplicity - so that the rest of the code
2269              can assume that the reduction variable is always the last (second)
2270              argument).  */
2271           if (vect_print_dump_info (REPORT_DETAILS))
2272             report_vect_op (def_stmt,
2273                             "detected reduction: need to swap operands: ");
2274
2275           swap_tree_operands (def_stmt, gimple_assign_rhs1_ptr (def_stmt),
2276                               gimple_assign_rhs2_ptr (def_stmt));
2277         }
2278       else
2279         {
2280           if (vect_print_dump_info (REPORT_DETAILS))
2281             report_vect_op (def_stmt, "detected reduction: ");
2282         }
2283
2284       return def_stmt;
2285     }
2286
2287   /* Try to find SLP reduction chain.  */
2288   if (check_reduction && vect_is_slp_reduction (loop_info, phi, def_stmt))
2289     {
2290       if (vect_print_dump_info (REPORT_DETAILS))
2291         report_vect_op (def_stmt, "reduction: detected reduction chain: ");
2292
2293       return def_stmt;
2294     }
2295
2296   if (vect_print_dump_info (REPORT_DETAILS))
2297     report_vect_op (def_stmt, "reduction: unknown pattern: ");
2298        
2299   return NULL;
2300 }
2301
2302 /* Wrapper around vect_is_simple_reduction_1, that won't modify code
2303    in-place.  Arguments as there.  */
2304
2305 static gimple
2306 vect_is_simple_reduction (loop_vec_info loop_info, gimple phi,
2307                           bool check_reduction, bool *double_reduc)
2308 {
2309   return vect_is_simple_reduction_1 (loop_info, phi, check_reduction,
2310                                      double_reduc, false);
2311 }
2312
2313 /* Wrapper around vect_is_simple_reduction_1, which will modify code
2314    in-place if it enables detection of more reductions.  Arguments
2315    as there.  */
2316
2317 gimple
2318 vect_force_simple_reduction (loop_vec_info loop_info, gimple phi,
2319                           bool check_reduction, bool *double_reduc)
2320 {
2321   return vect_is_simple_reduction_1 (loop_info, phi, check_reduction,
2322                                      double_reduc, true);
2323 }
2324
2325 /* Calculate the cost of one scalar iteration of the loop.  */
2326 int
2327 vect_get_single_scalar_iteraion_cost (loop_vec_info loop_vinfo)
2328 {
2329   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
2330   basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
2331   int nbbs = loop->num_nodes, factor, scalar_single_iter_cost = 0;
2332   int innerloop_iters, i, stmt_cost;
2333
2334   /* Count statements in scalar loop.  Using this as scalar cost for a single
2335      iteration for now.
2336
2337      TODO: Add outer loop support.
2338
2339      TODO: Consider assigning different costs to different scalar
2340      statements.  */
2341
2342   /* FORNOW.  */
2343   innerloop_iters = 1;
2344   if (loop->inner)
2345     innerloop_iters = 50; /* FIXME */
2346
2347   for (i = 0; i < nbbs; i++)
2348     {
2349       gimple_stmt_iterator si;
2350       basic_block bb = bbs[i];
2351
2352       if (bb->loop_father == loop->inner)
2353         factor = innerloop_iters;
2354       else
2355         factor = 1;
2356
2357       for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
2358         {
2359           gimple stmt = gsi_stmt (si);
2360           stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
2361
2362           if (!is_gimple_assign (stmt) && !is_gimple_call (stmt))
2363             continue;
2364
2365           /* Skip stmts that are not vectorized inside the loop.  */
2366           if (stmt_info
2367               && !STMT_VINFO_RELEVANT_P (stmt_info)
2368               && (!STMT_VINFO_LIVE_P (stmt_info)
2369                   || STMT_VINFO_DEF_TYPE (stmt_info) != vect_reduction_def))
2370             continue;
2371
2372           if (STMT_VINFO_DATA_REF (vinfo_for_stmt (stmt)))
2373             {
2374               if (DR_IS_READ (STMT_VINFO_DATA_REF (vinfo_for_stmt (stmt))))
2375                stmt_cost = vect_get_cost (scalar_load);
2376              else
2377                stmt_cost = vect_get_cost (scalar_store);
2378             }
2379           else
2380             stmt_cost = vect_get_cost (scalar_stmt);
2381
2382           scalar_single_iter_cost += stmt_cost * factor;
2383         }
2384     }
2385   return scalar_single_iter_cost;
2386 }
2387
2388 /* Calculate cost of peeling the loop PEEL_ITERS_PROLOGUE times.  */
2389 int
2390 vect_get_known_peeling_cost (loop_vec_info loop_vinfo, int peel_iters_prologue,
2391                              int *peel_iters_epilogue,
2392                              int scalar_single_iter_cost)
2393 {
2394   int peel_guard_costs = 0;
2395   int vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
2396
2397   if (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo))
2398     {
2399       *peel_iters_epilogue = vf/2;
2400       if (vect_print_dump_info (REPORT_COST))
2401         fprintf (vect_dump, "cost model: "
2402                             "epilogue peel iters set to vf/2 because "
2403                             "loop iterations are unknown .");
2404
2405       /* If peeled iterations are known but number of scalar loop
2406          iterations are unknown, count a taken branch per peeled loop.  */
2407       peel_guard_costs =  2 * vect_get_cost (cond_branch_taken);
2408     }
2409   else
2410     {
2411       int niters = LOOP_VINFO_INT_NITERS (loop_vinfo);
2412       peel_iters_prologue = niters < peel_iters_prologue ?
2413                             niters : peel_iters_prologue;
2414       *peel_iters_epilogue = (niters - peel_iters_prologue) % vf;
2415       /* If we need to peel for gaps, but no peeling is required, we have to
2416          peel VF iterations.  */
2417       if (LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo) && !*peel_iters_epilogue)
2418         *peel_iters_epilogue = vf;
2419     }
2420
2421    return (peel_iters_prologue * scalar_single_iter_cost)
2422             + (*peel_iters_epilogue * scalar_single_iter_cost)
2423            + peel_guard_costs;
2424 }
2425
2426 /* Function vect_estimate_min_profitable_iters
2427
2428    Return the number of iterations required for the vector version of the
2429    loop to be profitable relative to the cost of the scalar version of the
2430    loop.
2431
2432    TODO: Take profile info into account before making vectorization
2433    decisions, if available.  */
2434
2435 int
2436 vect_estimate_min_profitable_iters (loop_vec_info loop_vinfo)
2437 {
2438   int i;
2439   int min_profitable_iters;
2440   int peel_iters_prologue;
2441   int peel_iters_epilogue;
2442   int vec_inside_cost = 0;
2443   int vec_outside_cost = 0;
2444   int scalar_single_iter_cost = 0;
2445   int scalar_outside_cost = 0;
2446   int vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
2447   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
2448   basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
2449   int nbbs = loop->num_nodes;
2450   int npeel = LOOP_PEELING_FOR_ALIGNMENT (loop_vinfo);
2451   int peel_guard_costs = 0;
2452   int innerloop_iters = 0, factor;
2453   VEC (slp_instance, heap) *slp_instances;
2454   slp_instance instance;
2455
2456   /* Cost model disabled.  */
2457   if (!flag_vect_cost_model)
2458     {
2459       if (vect_print_dump_info (REPORT_COST))
2460         fprintf (vect_dump, "cost model disabled.");
2461       return 0;
2462     }
2463
2464   /* Requires loop versioning tests to handle misalignment.  */
2465   if (LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT (loop_vinfo))
2466     {
2467       /*  FIXME: Make cost depend on complexity of individual check.  */
2468       vec_outside_cost +=
2469         VEC_length (gimple, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo));
2470       if (vect_print_dump_info (REPORT_COST))
2471         fprintf (vect_dump, "cost model: Adding cost of checks for loop "
2472                  "versioning to treat misalignment.\n");
2473     }
2474
2475   /* Requires loop versioning with alias checks.  */
2476   if (LOOP_REQUIRES_VERSIONING_FOR_ALIAS (loop_vinfo))
2477     {
2478       /*  FIXME: Make cost depend on complexity of individual check.  */
2479       vec_outside_cost +=
2480         VEC_length (ddr_p, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo));
2481       if (vect_print_dump_info (REPORT_COST))
2482         fprintf (vect_dump, "cost model: Adding cost of checks for loop "
2483                  "versioning aliasing.\n");
2484     }
2485
2486   if (LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT (loop_vinfo)
2487       || LOOP_REQUIRES_VERSIONING_FOR_ALIAS (loop_vinfo))
2488     vec_outside_cost += vect_get_cost (cond_branch_taken); 
2489
2490   /* Count statements in scalar loop.  Using this as scalar cost for a single
2491      iteration for now.
2492
2493      TODO: Add outer loop support.
2494
2495      TODO: Consider assigning different costs to different scalar
2496      statements.  */
2497
2498   /* FORNOW.  */
2499   if (loop->inner)
2500     innerloop_iters = 50; /* FIXME */
2501
2502   for (i = 0; i < nbbs; i++)
2503     {
2504       gimple_stmt_iterator si;
2505       basic_block bb = bbs[i];
2506
2507       if (bb->loop_father == loop->inner)
2508         factor = innerloop_iters;
2509       else
2510         factor = 1;
2511
2512       for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
2513         {
2514           gimple stmt = gsi_stmt (si);
2515           stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
2516           /* Skip stmts that are not vectorized inside the loop.  */
2517           if (!STMT_VINFO_RELEVANT_P (stmt_info)
2518               && (!STMT_VINFO_LIVE_P (stmt_info)
2519                   || STMT_VINFO_DEF_TYPE (stmt_info) != vect_reduction_def))
2520             continue;
2521           vec_inside_cost += STMT_VINFO_INSIDE_OF_LOOP_COST (stmt_info) * factor;
2522           /* FIXME: for stmts in the inner-loop in outer-loop vectorization,
2523              some of the "outside" costs are generated inside the outer-loop.  */
2524           vec_outside_cost += STMT_VINFO_OUTSIDE_OF_LOOP_COST (stmt_info);
2525         }
2526     }
2527
2528   scalar_single_iter_cost = vect_get_single_scalar_iteraion_cost (loop_vinfo);
2529
2530   /* Add additional cost for the peeled instructions in prologue and epilogue
2531      loop.
2532
2533      FORNOW: If we don't know the value of peel_iters for prologue or epilogue
2534      at compile-time - we assume it's vf/2 (the worst would be vf-1).
2535
2536      TODO: Build an expression that represents peel_iters for prologue and
2537      epilogue to be used in a run-time test.  */
2538
2539   if (npeel  < 0)
2540     {
2541       peel_iters_prologue = vf/2;
2542       if (vect_print_dump_info (REPORT_COST))
2543         fprintf (vect_dump, "cost model: "
2544                  "prologue peel iters set to vf/2.");
2545
2546       /* If peeling for alignment is unknown, loop bound of main loop becomes
2547          unknown.  */
2548       peel_iters_epilogue = vf/2;
2549       if (vect_print_dump_info (REPORT_COST))
2550         fprintf (vect_dump, "cost model: "
2551                  "epilogue peel iters set to vf/2 because "
2552                  "peeling for alignment is unknown .");
2553
2554       /* If peeled iterations are unknown, count a taken branch and a not taken
2555          branch per peeled loop. Even if scalar loop iterations are known,
2556          vector iterations are not known since peeled prologue iterations are
2557          not known. Hence guards remain the same.  */
2558       peel_guard_costs +=  2 * (vect_get_cost (cond_branch_taken)
2559                                 + vect_get_cost (cond_branch_not_taken));
2560       vec_outside_cost += (peel_iters_prologue * scalar_single_iter_cost)
2561                            + (peel_iters_epilogue * scalar_single_iter_cost)
2562                            + peel_guard_costs;
2563     }
2564   else
2565     {
2566       peel_iters_prologue = npeel;
2567       vec_outside_cost += vect_get_known_peeling_cost (loop_vinfo,
2568                                     peel_iters_prologue, &peel_iters_epilogue,
2569                                     scalar_single_iter_cost);
2570     }
2571
2572   /* FORNOW: The scalar outside cost is incremented in one of the
2573      following ways:
2574
2575      1. The vectorizer checks for alignment and aliasing and generates
2576      a condition that allows dynamic vectorization.  A cost model
2577      check is ANDED with the versioning condition.  Hence scalar code
2578      path now has the added cost of the versioning check.
2579
2580        if (cost > th & versioning_check)
2581          jmp to vector code
2582
2583      Hence run-time scalar is incremented by not-taken branch cost.
2584
2585      2. The vectorizer then checks if a prologue is required.  If the
2586      cost model check was not done before during versioning, it has to
2587      be done before the prologue check.
2588
2589        if (cost <= th)
2590          prologue = scalar_iters
2591        if (prologue == 0)
2592          jmp to vector code
2593        else
2594          execute prologue
2595        if (prologue == num_iters)
2596          go to exit
2597
2598      Hence the run-time scalar cost is incremented by a taken branch,
2599      plus a not-taken branch, plus a taken branch cost.
2600
2601      3. The vectorizer then checks if an epilogue is required.  If the
2602      cost model check was not done before during prologue check, it
2603      has to be done with the epilogue check.
2604
2605        if (prologue == 0)
2606          jmp to vector code
2607        else
2608          execute prologue
2609        if (prologue == num_iters)
2610          go to exit
2611        vector code:
2612          if ((cost <= th) | (scalar_iters-prologue-epilogue == 0))
2613            jmp to epilogue
2614
2615      Hence the run-time scalar cost should be incremented by 2 taken
2616      branches.
2617
2618      TODO: The back end may reorder the BBS's differently and reverse
2619      conditions/branch directions.  Change the estimates below to
2620      something more reasonable.  */
2621
2622   /* If the number of iterations is known and we do not do versioning, we can
2623      decide whether to vectorize at compile time.  Hence the scalar version
2624      do not carry cost model guard costs.  */
2625   if (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
2626       || LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT (loop_vinfo)
2627       || LOOP_REQUIRES_VERSIONING_FOR_ALIAS (loop_vinfo))
2628     {
2629       /* Cost model check occurs at versioning.  */
2630       if (LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT (loop_vinfo)
2631           || LOOP_REQUIRES_VERSIONING_FOR_ALIAS (loop_vinfo))
2632         scalar_outside_cost += vect_get_cost (cond_branch_not_taken);
2633       else
2634         {
2635           /* Cost model check occurs at prologue generation.  */
2636           if (LOOP_PEELING_FOR_ALIGNMENT (loop_vinfo) < 0)
2637             scalar_outside_cost += 2 * vect_get_cost (cond_branch_taken)
2638                                    + vect_get_cost (cond_branch_not_taken); 
2639           /* Cost model check occurs at epilogue generation.  */
2640           else
2641             scalar_outside_cost += 2 * vect_get_cost (cond_branch_taken); 
2642         }
2643     }
2644
2645   /* Add SLP costs.  */
2646   slp_instances = LOOP_VINFO_SLP_INSTANCES (loop_vinfo);
2647   FOR_EACH_VEC_ELT (slp_instance, slp_instances, i, instance)
2648     {
2649       vec_outside_cost += SLP_INSTANCE_OUTSIDE_OF_LOOP_COST (instance);
2650       vec_inside_cost += SLP_INSTANCE_INSIDE_OF_LOOP_COST (instance);
2651     }
2652
2653   /* Calculate number of iterations required to make the vector version
2654      profitable, relative to the loop bodies only.  The following condition
2655      must hold true:
2656      SIC * niters + SOC > VIC * ((niters-PL_ITERS-EP_ITERS)/VF) + VOC
2657      where
2658      SIC = scalar iteration cost, VIC = vector iteration cost,
2659      VOC = vector outside cost, VF = vectorization factor,
2660      PL_ITERS = prologue iterations, EP_ITERS= epilogue iterations
2661      SOC = scalar outside cost for run time cost model check.  */
2662
2663   if ((scalar_single_iter_cost * vf) > vec_inside_cost)
2664     {
2665       if (vec_outside_cost <= 0)
2666         min_profitable_iters = 1;
2667       else
2668         {
2669           min_profitable_iters = ((vec_outside_cost - scalar_outside_cost) * vf
2670                                   - vec_inside_cost * peel_iters_prologue
2671                                   - vec_inside_cost * peel_iters_epilogue)
2672                                  / ((scalar_single_iter_cost * vf)
2673                                     - vec_inside_cost);
2674
2675           if ((scalar_single_iter_cost * vf * min_profitable_iters)
2676               <= ((vec_inside_cost * min_profitable_iters)
2677                   + ((vec_outside_cost - scalar_outside_cost) * vf)))
2678             min_profitable_iters++;
2679         }
2680     }
2681   /* vector version will never be profitable.  */
2682   else
2683     {
2684       if (vect_print_dump_info (REPORT_COST))
2685         fprintf (vect_dump, "cost model: the vector iteration cost = %d "
2686                  "divided by the scalar iteration cost = %d "
2687                  "is greater or equal to the vectorization factor = %d.",
2688                  vec_inside_cost, scalar_single_iter_cost, vf);
2689       return -1;
2690     }
2691
2692   if (vect_print_dump_info (REPORT_COST))
2693     {
2694       fprintf (vect_dump, "Cost model analysis: \n");
2695       fprintf (vect_dump, "  Vector inside of loop cost: %d\n",
2696                vec_inside_cost);
2697       fprintf (vect_dump, "  Vector outside of loop cost: %d\n",
2698                vec_outside_cost);
2699       fprintf (vect_dump, "  Scalar iteration cost: %d\n",
2700                scalar_single_iter_cost);
2701       fprintf (vect_dump, "  Scalar outside cost: %d\n", scalar_outside_cost);
2702       fprintf (vect_dump, "  prologue iterations: %d\n",
2703                peel_iters_prologue);
2704       fprintf (vect_dump, "  epilogue iterations: %d\n",
2705                peel_iters_epilogue);
2706       fprintf (vect_dump, "  Calculated minimum iters for profitability: %d\n",
2707                min_profitable_iters);
2708     }
2709
2710   min_profitable_iters =
2711         min_profitable_iters < vf ? vf : min_profitable_iters;
2712
2713   /* Because the condition we create is:
2714      if (niters <= min_profitable_iters)
2715        then skip the vectorized loop.  */
2716   min_profitable_iters--;
2717
2718   if (vect_print_dump_info (REPORT_COST))
2719     fprintf (vect_dump, "  Profitability threshold = %d\n",
2720              min_profitable_iters);
2721
2722   return min_profitable_iters;
2723 }
2724
2725
2726 /* TODO: Close dependency between vect_model_*_cost and vectorizable_*
2727    functions. Design better to avoid maintenance issues.  */
2728
2729 /* Function vect_model_reduction_cost.
2730
2731    Models cost for a reduction operation, including the vector ops
2732    generated within the strip-mine loop, the initial definition before
2733    the loop, and the epilogue code that must be generated.  */
2734
2735 static bool
2736 vect_model_reduction_cost (stmt_vec_info stmt_info, enum tree_code reduc_code,
2737                            int ncopies)
2738 {
2739   int outer_cost = 0;
2740   enum tree_code code;
2741   optab optab;
2742   tree vectype;
2743   gimple stmt, orig_stmt;
2744   tree reduction_op;
2745   enum machine_mode mode;
2746   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
2747   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
2748
2749
2750   /* Cost of reduction op inside loop.  */
2751   STMT_VINFO_INSIDE_OF_LOOP_COST (stmt_info) 
2752     += ncopies * vect_get_cost (vector_stmt);
2753
2754   stmt = STMT_VINFO_STMT (stmt_info);
2755
2756   switch (get_gimple_rhs_class (gimple_assign_rhs_code (stmt)))
2757     {
2758     case GIMPLE_SINGLE_RHS:
2759       gcc_assert (TREE_OPERAND_LENGTH (gimple_assign_rhs1 (stmt)) == ternary_op);
2760       reduction_op = TREE_OPERAND (gimple_assign_rhs1 (stmt), 2);
2761       break;
2762     case GIMPLE_UNARY_RHS:
2763       reduction_op = gimple_assign_rhs1 (stmt);
2764       break;
2765     case GIMPLE_BINARY_RHS:
2766       reduction_op = gimple_assign_rhs2 (stmt);
2767       break;
2768     case GIMPLE_TERNARY_RHS:
2769       reduction_op = gimple_assign_rhs3 (stmt);
2770       break;
2771     default:
2772       gcc_unreachable ();
2773     }
2774
2775   vectype = get_vectype_for_scalar_type (TREE_TYPE (reduction_op));
2776   if (!vectype)
2777     {
2778       if (vect_print_dump_info (REPORT_COST))
2779         {
2780           fprintf (vect_dump, "unsupported data-type ");
2781           print_generic_expr (vect_dump, TREE_TYPE (reduction_op), TDF_SLIM);
2782         }
2783       return false;
2784    }
2785
2786   mode = TYPE_MODE (vectype);
2787   orig_stmt = STMT_VINFO_RELATED_STMT (stmt_info);
2788
2789   if (!orig_stmt)
2790     orig_stmt = STMT_VINFO_STMT (stmt_info);
2791
2792   code = gimple_assign_rhs_code (orig_stmt);
2793
2794   /* Add in cost for initial definition.  */
2795   outer_cost += vect_get_cost (scalar_to_vec);
2796
2797   /* Determine cost of epilogue code.
2798
2799      We have a reduction operator that will reduce the vector in one statement.
2800      Also requires scalar extract.  */
2801
2802   if (!nested_in_vect_loop_p (loop, orig_stmt))
2803     {
2804       if (reduc_code != ERROR_MARK)
2805         outer_cost += vect_get_cost (vector_stmt) 
2806                       + vect_get_cost (vec_to_scalar); 
2807       else
2808         {
2809           int vec_size_in_bits = tree_low_cst (TYPE_SIZE (vectype), 1);
2810           tree bitsize =
2811             TYPE_SIZE (TREE_TYPE (gimple_assign_lhs (orig_stmt)));
2812           int element_bitsize = tree_low_cst (bitsize, 1);
2813           int nelements = vec_size_in_bits / element_bitsize;
2814
2815           optab = optab_for_tree_code (code, vectype, optab_default);
2816
2817           /* We have a whole vector shift available.  */
2818           if (VECTOR_MODE_P (mode)
2819               && optab_handler (optab, mode) != CODE_FOR_nothing
2820               && optab_handler (vec_shr_optab, mode) != CODE_FOR_nothing)
2821             /* Final reduction via vector shifts and the reduction operator. Also
2822                requires scalar extract.  */
2823             outer_cost += ((exact_log2(nelements) * 2) 
2824               * vect_get_cost (vector_stmt) 
2825               + vect_get_cost (vec_to_scalar));
2826           else
2827             /* Use extracts and reduction op for final reduction.  For N elements,
2828                we have N extracts and N-1 reduction ops.  */
2829             outer_cost += ((nelements + nelements - 1) 
2830               * vect_get_cost (vector_stmt));
2831         }
2832     }
2833
2834   STMT_VINFO_OUTSIDE_OF_LOOP_COST (stmt_info) = outer_cost;
2835
2836   if (vect_print_dump_info (REPORT_COST))
2837     fprintf (vect_dump, "vect_model_reduction_cost: inside_cost = %d, "
2838              "outside_cost = %d .", STMT_VINFO_INSIDE_OF_LOOP_COST (stmt_info),
2839              STMT_VINFO_OUTSIDE_OF_LOOP_COST (stmt_info));
2840
2841   return true;
2842 }
2843
2844
2845 /* Function vect_model_induction_cost.
2846
2847    Models cost for induction operations.  */
2848
2849 static void
2850 vect_model_induction_cost (stmt_vec_info stmt_info, int ncopies)
2851 {
2852   /* loop cost for vec_loop.  */
2853   STMT_VINFO_INSIDE_OF_LOOP_COST (stmt_info) 
2854     = ncopies * vect_get_cost (vector_stmt);
2855   /* prologue cost for vec_init and vec_step.  */
2856   STMT_VINFO_OUTSIDE_OF_LOOP_COST (stmt_info)  
2857     = 2 * vect_get_cost (scalar_to_vec);
2858
2859   if (vect_print_dump_info (REPORT_COST))
2860     fprintf (vect_dump, "vect_model_induction_cost: inside_cost = %d, "
2861              "outside_cost = %d .", STMT_VINFO_INSIDE_OF_LOOP_COST (stmt_info),
2862              STMT_VINFO_OUTSIDE_OF_LOOP_COST (stmt_info));
2863 }
2864
2865
2866 /* Function get_initial_def_for_induction
2867
2868    Input:
2869    STMT - a stmt that performs an induction operation in the loop.
2870    IV_PHI - the initial value of the induction variable
2871
2872    Output:
2873    Return a vector variable, initialized with the first VF values of
2874    the induction variable.  E.g., for an iv with IV_PHI='X' and
2875    evolution S, for a vector of 4 units, we want to return:
2876    [X, X + S, X + 2*S, X + 3*S].  */
2877
2878 static tree
2879 get_initial_def_for_induction (gimple iv_phi)
2880 {
2881   stmt_vec_info stmt_vinfo = vinfo_for_stmt (iv_phi);
2882   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
2883   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
2884   tree scalar_type;
2885   tree vectype;
2886   int nunits;
2887   edge pe = loop_preheader_edge (loop);
2888   struct loop *iv_loop;
2889   basic_block new_bb;
2890   tree vec, vec_init, vec_step, t;
2891   tree access_fn;
2892   tree new_var;
2893   tree new_name;
2894   gimple init_stmt, induction_phi, new_stmt;
2895   tree induc_def, vec_def, vec_dest;
2896   tree init_expr, step_expr;
2897   int vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
2898   int i;
2899   bool ok;
2900   int ncopies;
2901   tree expr;
2902   stmt_vec_info phi_info = vinfo_for_stmt (iv_phi);
2903   bool nested_in_vect_loop = false;
2904   gimple_seq stmts = NULL;
2905   imm_use_iterator imm_iter;
2906   use_operand_p use_p;
2907   gimple exit_phi;
2908   edge latch_e;
2909   tree loop_arg;
2910   gimple_stmt_iterator si;
2911   basic_block bb = gimple_bb (iv_phi);
2912   tree stepvectype;
2913   tree resvectype;
2914
2915   /* Is phi in an inner-loop, while vectorizing an enclosing outer-loop?  */
2916   if (nested_in_vect_loop_p (loop, iv_phi))
2917     {
2918       nested_in_vect_loop = true;
2919       iv_loop = loop->inner;
2920     }
2921   else
2922     iv_loop = loop;
2923   gcc_assert (iv_loop == (gimple_bb (iv_phi))->loop_father);
2924
2925   latch_e = loop_latch_edge (iv_loop);
2926   loop_arg = PHI_ARG_DEF_FROM_EDGE (iv_phi, latch_e);
2927
2928   access_fn = analyze_scalar_evolution (iv_loop, PHI_RESULT (iv_phi));
2929   gcc_assert (access_fn);
2930   STRIP_NOPS (access_fn);
2931   ok = vect_is_simple_iv_evolution (iv_loop->num, access_fn,
2932                                     &init_expr, &step_expr);
2933   gcc_assert (ok);
2934   pe = loop_preheader_edge (iv_loop);
2935
2936   scalar_type = TREE_TYPE (init_expr);
2937   vectype = get_vectype_for_scalar_type (scalar_type);
2938   resvectype = get_vectype_for_scalar_type (TREE_TYPE (PHI_RESULT (iv_phi)));
2939   gcc_assert (vectype);
2940   nunits = TYPE_VECTOR_SUBPARTS (vectype);
2941   ncopies = vf / nunits;
2942
2943   gcc_assert (phi_info);
2944   gcc_assert (ncopies >= 1);
2945
2946   /* Find the first insertion point in the BB.  */
2947   si = gsi_after_labels (bb);
2948
2949   /* Create the vector that holds the initial_value of the induction.  */
2950   if (nested_in_vect_loop)
2951     {
2952       /* iv_loop is nested in the loop to be vectorized.  init_expr had already
2953          been created during vectorization of previous stmts.  We obtain it
2954          from the STMT_VINFO_VEC_STMT of the defining stmt.  */
2955       tree iv_def = PHI_ARG_DEF_FROM_EDGE (iv_phi,
2956                                            loop_preheader_edge (iv_loop));
2957       vec_init = vect_get_vec_def_for_operand (iv_def, iv_phi, NULL);
2958     }
2959   else
2960     {
2961       /* iv_loop is the loop to be vectorized. Create:
2962          vec_init = [X, X+S, X+2*S, X+3*S] (S = step_expr, X = init_expr)  */
2963       new_var = vect_get_new_vect_var (scalar_type, vect_scalar_var, "var_");
2964       add_referenced_var (new_var);
2965
2966       new_name = force_gimple_operand (init_expr, &stmts, false, new_var);
2967       if (stmts)
2968         {
2969           new_bb = gsi_insert_seq_on_edge_immediate (pe, stmts);
2970           gcc_assert (!new_bb);
2971         }
2972
2973       t = NULL_TREE;
2974       t = tree_cons (NULL_TREE, new_name, t);
2975       for (i = 1; i < nunits; i++)
2976         {
2977           /* Create: new_name_i = new_name + step_expr  */
2978           enum tree_code code = POINTER_TYPE_P (scalar_type)
2979                                 ? POINTER_PLUS_EXPR : PLUS_EXPR;
2980           init_stmt = gimple_build_assign_with_ops (code, new_var,
2981                                                     new_name, step_expr);
2982           new_name = make_ssa_name (new_var, init_stmt);
2983           gimple_assign_set_lhs (init_stmt, new_name);
2984
2985           new_bb = gsi_insert_on_edge_immediate (pe, init_stmt);
2986           gcc_assert (!new_bb);
2987
2988           if (vect_print_dump_info (REPORT_DETAILS))
2989             {
2990               fprintf (vect_dump, "created new init_stmt: ");
2991               print_gimple_stmt (vect_dump, init_stmt, 0, TDF_SLIM);
2992             }
2993           t = tree_cons (NULL_TREE, new_name, t);
2994         }
2995       /* Create a vector from [new_name_0, new_name_1, ..., new_name_nunits-1]  */
2996       vec = build_constructor_from_list (vectype, nreverse (t));
2997       vec_init = vect_init_vector (iv_phi, vec, vectype, NULL);
2998     }
2999
3000
3001   /* Create the vector that holds the step of the induction.  */
3002   if (nested_in_vect_loop)
3003     /* iv_loop is nested in the loop to be vectorized. Generate:
3004        vec_step = [S, S, S, S]  */
3005     new_name = step_expr;
3006   else
3007     {
3008       /* iv_loop is the loop to be vectorized. Generate:
3009           vec_step = [VF*S, VF*S, VF*S, VF*S]  */
3010       expr = build_int_cst (TREE_TYPE (step_expr), vf);
3011       new_name = fold_build2 (MULT_EXPR, TREE_TYPE (step_expr),
3012                               expr, step_expr);
3013     }
3014
3015   t = unshare_expr (new_name);
3016   gcc_assert (CONSTANT_CLASS_P (new_name));
3017   stepvectype = get_vectype_for_scalar_type (TREE_TYPE (new_name));
3018   gcc_assert (stepvectype);
3019   vec = build_vector_from_val (stepvectype, t);
3020   vec_step = vect_init_vector (iv_phi, vec, stepvectype, NULL);
3021
3022
3023   /* Create the following def-use cycle:
3024      loop prolog:
3025          vec_init = ...
3026          vec_step = ...
3027      loop:
3028          vec_iv = PHI <vec_init, vec_loop>
3029          ...
3030          STMT
3031          ...
3032          vec_loop = vec_iv + vec_step;  */
3033
3034   /* Create the induction-phi that defines the induction-operand.  */
3035   vec_dest = vect_get_new_vect_var (vectype, vect_simple_var, "vec_iv_");
3036   add_referenced_var (vec_dest);
3037   induction_phi = create_phi_node (vec_dest, iv_loop->header);
3038   set_vinfo_for_stmt (induction_phi,
3039                       new_stmt_vec_info (induction_phi, loop_vinfo, NULL));
3040   induc_def = PHI_RESULT (induction_phi);
3041
3042   /* Create the iv update inside the loop  */
3043   new_stmt = gimple_build_assign_with_ops (PLUS_EXPR, vec_dest,
3044                                            induc_def, vec_step);
3045   vec_def = make_ssa_name (vec_dest, new_stmt);
3046   gimple_assign_set_lhs (new_stmt, vec_def);
3047   gsi_insert_before (&si, new_stmt, GSI_SAME_STMT);
3048   set_vinfo_for_stmt (new_stmt, new_stmt_vec_info (new_stmt, loop_vinfo,
3049                                                    NULL));
3050
3051   /* Set the arguments of the phi node:  */
3052   add_phi_arg (induction_phi, vec_init, pe, UNKNOWN_LOCATION);
3053   add_phi_arg (induction_phi, vec_def, loop_latch_edge (iv_loop),
3054                UNKNOWN_LOCATION);
3055
3056
3057   /* In case that vectorization factor (VF) is bigger than the number
3058      of elements that we can fit in a vectype (nunits), we have to generate
3059      more than one vector stmt - i.e - we need to "unroll" the
3060      vector stmt by a factor VF/nunits.  For more details see documentation
3061      in vectorizable_operation.  */
3062
3063   if (ncopies > 1)
3064     {
3065       stmt_vec_info prev_stmt_vinfo;
3066       /* FORNOW. This restriction should be relaxed.  */
3067       gcc_assert (!nested_in_vect_loop);
3068
3069       /* Create the vector that holds the step of the induction.  */
3070       expr = build_int_cst (TREE_TYPE (step_expr), nunits);
3071       new_name = fold_build2 (MULT_EXPR, TREE_TYPE (step_expr),
3072                               expr, step_expr);
3073       t = unshare_expr (new_name);
3074       gcc_assert (CONSTANT_CLASS_P (new_name));
3075       vec = build_vector_from_val (stepvectype, t);
3076       vec_step = vect_init_vector (iv_phi, vec, stepvectype, NULL);
3077
3078       vec_def = induc_def;
3079       prev_stmt_vinfo = vinfo_for_stmt (induction_phi);
3080       for (i = 1; i < ncopies; i++)
3081         {
3082           /* vec_i = vec_prev + vec_step  */
3083           new_stmt = gimple_build_assign_with_ops (PLUS_EXPR, vec_dest,
3084                                                    vec_def, vec_step);
3085           vec_def = make_ssa_name (vec_dest, new_stmt);
3086           gimple_assign_set_lhs (new_stmt, vec_def);
3087  
3088           gsi_insert_before (&si, new_stmt, GSI_SAME_STMT);
3089           if (!useless_type_conversion_p (resvectype, vectype))
3090             {
3091               new_stmt = gimple_build_assign_with_ops
3092                   (VIEW_CONVERT_EXPR,
3093                    vect_get_new_vect_var (resvectype, vect_simple_var,
3094                                           "vec_iv_"),
3095                    build1 (VIEW_CONVERT_EXPR, resvectype,
3096                            gimple_assign_lhs (new_stmt)), NULL_TREE);
3097               gimple_assign_set_lhs (new_stmt,
3098                                      make_ssa_name
3099                                        (gimple_assign_lhs (new_stmt), new_stmt));
3100               gsi_insert_before (&si, new_stmt, GSI_SAME_STMT);
3101             }
3102           set_vinfo_for_stmt (new_stmt,
3103                               new_stmt_vec_info (new_stmt, loop_vinfo, NULL));
3104           STMT_VINFO_RELATED_STMT (prev_stmt_vinfo) = new_stmt;
3105           prev_stmt_vinfo = vinfo_for_stmt (new_stmt);
3106         }
3107     }
3108
3109   if (nested_in_vect_loop)
3110     {
3111       /* Find the loop-closed exit-phi of the induction, and record
3112          the final vector of induction results:  */
3113       exit_phi = NULL;
3114       FOR_EACH_IMM_USE_FAST (use_p, imm_iter, loop_arg)
3115         {
3116           if (!flow_bb_inside_loop_p (iv_loop, gimple_bb (USE_STMT (use_p))))
3117             {
3118               exit_phi = USE_STMT (use_p);
3119               break;
3120             }
3121         }
3122       if (exit_phi)
3123         {
3124           stmt_vec_info stmt_vinfo = vinfo_for_stmt (exit_phi);
3125           /* FORNOW. Currently not supporting the case that an inner-loop induction
3126              is not used in the outer-loop (i.e. only outside the outer-loop).  */
3127           gcc_assert (STMT_VINFO_RELEVANT_P (stmt_vinfo)
3128                       && !STMT_VINFO_LIVE_P (stmt_vinfo));
3129
3130           STMT_VINFO_VEC_STMT (stmt_vinfo) = new_stmt;
3131           if (vect_print_dump_info (REPORT_DETAILS))
3132             {
3133               fprintf (vect_dump, "vector of inductions after inner-loop:");
3134               print_gimple_stmt (vect_dump, new_stmt, 0, TDF_SLIM);
3135             }
3136         }
3137     }
3138
3139
3140   if (vect_print_dump_info (REPORT_DETAILS))
3141     {
3142       fprintf (vect_dump, "transform induction: created def-use cycle: ");
3143       print_gimple_stmt (vect_dump, induction_phi, 0, TDF_SLIM);
3144       fprintf (vect_dump, "\n");
3145       print_gimple_stmt (vect_dump, SSA_NAME_DEF_STMT (vec_def), 0, TDF_SLIM);
3146     }
3147
3148   STMT_VINFO_VEC_STMT (phi_info) = induction_phi;
3149   if (!useless_type_conversion_p (resvectype, vectype))
3150     {
3151       new_stmt = gimple_build_assign_with_ops
3152          (VIEW_CONVERT_EXPR,
3153           vect_get_new_vect_var (resvectype, vect_simple_var, "vec_iv_"),
3154           build1 (VIEW_CONVERT_EXPR, resvectype, induc_def), NULL_TREE);
3155       induc_def = make_ssa_name (gimple_assign_lhs (new_stmt), new_stmt);
3156       gimple_assign_set_lhs (new_stmt, induc_def);
3157       si = gsi_start_bb (bb);
3158       gsi_insert_before (&si, new_stmt, GSI_SAME_STMT);
3159       set_vinfo_for_stmt (new_stmt,
3160                           new_stmt_vec_info (new_stmt, loop_vinfo, NULL));
3161       STMT_VINFO_RELATED_STMT (vinfo_for_stmt (new_stmt))
3162         = STMT_VINFO_RELATED_STMT (vinfo_for_stmt (induction_phi));
3163     }
3164
3165   return induc_def;
3166 }
3167
3168
3169 /* Function get_initial_def_for_reduction
3170
3171    Input:
3172    STMT - a stmt that performs a reduction operation in the loop.
3173    INIT_VAL - the initial value of the reduction variable
3174
3175    Output:
3176    ADJUSTMENT_DEF - a tree that holds a value to be added to the final result
3177         of the reduction (used for adjusting the epilog - see below).
3178    Return a vector variable, initialized according to the operation that STMT
3179         performs. This vector will be used as the initial value of the
3180         vector of partial results.
3181
3182    Option1 (adjust in epilog): Initialize the vector as follows:
3183      add/bit or/xor:    [0,0,...,0,0]
3184      mult/bit and:      [1,1,...,1,1]
3185      min/max/cond_expr: [init_val,init_val,..,init_val,init_val]
3186    and when necessary (e.g. add/mult case) let the caller know
3187    that it needs to adjust the result by init_val.
3188
3189    Option2: Initialize the vector as follows:
3190      add/bit or/xor:    [init_val,0,0,...,0]
3191      mult/bit and:      [init_val,1,1,...,1]
3192      min/max/cond_expr: [init_val,init_val,...,init_val]
3193    and no adjustments are needed.
3194
3195    For example, for the following code:
3196
3197    s = init_val;
3198    for (i=0;i<n;i++)
3199      s = s + a[i];
3200
3201    STMT is 's = s + a[i]', and the reduction variable is 's'.
3202    For a vector of 4 units, we want to return either [0,0,0,init_val],
3203    or [0,0,0,0] and let the caller know that it needs to adjust
3204    the result at the end by 'init_val'.
3205
3206    FORNOW, we are using the 'adjust in epilog' scheme, because this way the
3207    initialization vector is simpler (same element in all entries), if
3208    ADJUSTMENT_DEF is not NULL, and Option2 otherwise.
3209
3210    A cost model should help decide between these two schemes.  */
3211
3212 tree
3213 get_initial_def_for_reduction (gimple stmt, tree init_val,
3214                                tree *adjustment_def)
3215 {
3216   stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt);
3217   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
3218   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
3219   tree scalar_type = TREE_TYPE (init_val);
3220   tree vectype = get_vectype_for_scalar_type (scalar_type);
3221   int nunits;
3222   enum tree_code code = gimple_assign_rhs_code (stmt);
3223   tree def_for_init;
3224   tree init_def;
3225   tree t = NULL_TREE;
3226   int i;
3227   bool nested_in_vect_loop = false;
3228   tree init_value;
3229   REAL_VALUE_TYPE real_init_val = dconst0;
3230   int int_init_val = 0;
3231   gimple def_stmt = NULL;
3232
3233   gcc_assert (vectype);
3234   nunits = TYPE_VECTOR_SUBPARTS (vectype);
3235
3236   gcc_assert (POINTER_TYPE_P (scalar_type) || INTEGRAL_TYPE_P (scalar_type)
3237               || SCALAR_FLOAT_TYPE_P (scalar_type));
3238
3239   if (nested_in_vect_loop_p (loop, stmt))
3240     nested_in_vect_loop = true;
3241   else
3242     gcc_assert (loop == (gimple_bb (stmt))->loop_father);
3243
3244   /* In case of double reduction we only create a vector variable to be put
3245      in the reduction phi node.  The actual statement creation is done in
3246      vect_create_epilog_for_reduction.  */
3247   if (adjustment_def && nested_in_vect_loop
3248       && TREE_CODE (init_val) == SSA_NAME
3249       && (def_stmt = SSA_NAME_DEF_STMT (init_val))
3250       && gimple_code (def_stmt) == GIMPLE_PHI
3251       && flow_bb_inside_loop_p (loop, gimple_bb (def_stmt))
3252       && vinfo_for_stmt (def_stmt)
3253       && STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def_stmt))
3254           == vect_double_reduction_def)
3255     {
3256       *adjustment_def = NULL;
3257       return vect_create_destination_var (init_val, vectype);
3258     }
3259
3260   if (TREE_CONSTANT (init_val))
3261     {
3262       if (SCALAR_FLOAT_TYPE_P (scalar_type))
3263         init_value = build_real (scalar_type, TREE_REAL_CST (init_val));
3264       else
3265         init_value = build_int_cst (scalar_type, TREE_INT_CST_LOW (init_val));
3266     }
3267   else
3268     init_value = init_val;
3269
3270   switch (code)
3271     {
3272       case WIDEN_SUM_EXPR:
3273       case DOT_PROD_EXPR:
3274       case PLUS_EXPR:
3275       case MINUS_EXPR:
3276       case BIT_IOR_EXPR:
3277       case BIT_XOR_EXPR:
3278       case MULT_EXPR:
3279       case BIT_AND_EXPR:
3280         /* ADJUSMENT_DEF is NULL when called from
3281            vect_create_epilog_for_reduction to vectorize double reduction.  */
3282         if (adjustment_def)
3283           {
3284             if (nested_in_vect_loop)
3285               *adjustment_def = vect_get_vec_def_for_operand (init_val, stmt,
3286                                                               NULL);
3287             else
3288               *adjustment_def = init_val;
3289           }
3290
3291         if (code == MULT_EXPR)
3292           {
3293             real_init_val = dconst1;
3294             int_init_val = 1;
3295           }
3296
3297         if (code == BIT_AND_EXPR)
3298           int_init_val = -1;
3299
3300         if (SCALAR_FLOAT_TYPE_P (scalar_type))
3301           def_for_init = build_real (scalar_type, real_init_val);
3302         else
3303           def_for_init = build_int_cst (scalar_type, int_init_val);
3304
3305         /* Create a vector of '0' or '1' except the first element.  */
3306         for (i = nunits - 2; i >= 0; --i)
3307           t = tree_cons (NULL_TREE, def_for_init, t);
3308
3309         /* Option1: the first element is '0' or '1' as well.  */
3310         if (adjustment_def)
3311           {
3312             t = tree_cons (NULL_TREE, def_for_init, t);
3313             init_def = build_vector (vectype, t);
3314             break;
3315           }
3316
3317         /* Option2: the first element is INIT_VAL.  */
3318         t = tree_cons (NULL_TREE, init_value, t);
3319         if (TREE_CONSTANT (init_val))
3320           init_def = build_vector (vectype, t);
3321         else
3322           init_def = build_constructor_from_list (vectype, t);
3323
3324         break;
3325
3326       case MIN_EXPR:
3327       case MAX_EXPR:
3328       case COND_EXPR:
3329         if (adjustment_def)
3330           {
3331             *adjustment_def = NULL_TREE;
3332             init_def = vect_get_vec_def_for_operand (init_val, stmt, NULL);
3333             break;
3334           }
3335
3336         init_def = build_vector_from_val (vectype, init_value);
3337         break;
3338
3339       default:
3340         gcc_unreachable ();
3341     }
3342
3343   return init_def;
3344 }
3345
3346
3347 /* Function vect_create_epilog_for_reduction
3348
3349    Create code at the loop-epilog to finalize the result of a reduction
3350    computation. 
3351   
3352    VECT_DEFS is list of vector of partial results, i.e., the lhs's of vector 
3353      reduction statements. 
3354    STMT is the scalar reduction stmt that is being vectorized.
3355    NCOPIES is > 1 in case the vectorization factor (VF) is bigger than the
3356      number of elements that we can fit in a vectype (nunits).  In this case
3357      we have to generate more than one vector stmt - i.e - we need to "unroll"
3358      the vector stmt by a factor VF/nunits.  For more details see documentation
3359      in vectorizable_operation.
3360    REDUC_CODE is the tree-code for the epilog reduction.
3361    REDUCTION_PHIS is a list of the phi-nodes that carry the reduction 
3362      computation.
3363    REDUC_INDEX is the index of the operand in the right hand side of the 
3364      statement that is defined by REDUCTION_PHI.
3365    DOUBLE_REDUC is TRUE if double reduction phi nodes should be handled.
3366    SLP_NODE is an SLP node containing a group of reduction statements. The 
3367      first one in this group is STMT.
3368
3369    This function:
3370    1. Creates the reduction def-use cycles: sets the arguments for 
3371       REDUCTION_PHIS:
3372       The loop-entry argument is the vectorized initial-value of the reduction.
3373       The loop-latch argument is taken from VECT_DEFS - the vector of partial 
3374       sums.
3375    2. "Reduces" each vector of partial results VECT_DEFS into a single result,
3376       by applying the operation specified by REDUC_CODE if available, or by 
3377       other means (whole-vector shifts or a scalar loop).
3378       The function also creates a new phi node at the loop exit to preserve
3379       loop-closed form, as illustrated below.
3380
3381      The flow at the entry to this function:
3382
3383         loop:
3384           vec_def = phi <null, null>            # REDUCTION_PHI
3385           VECT_DEF = vector_stmt                # vectorized form of STMT
3386           s_loop = scalar_stmt                  # (scalar) STMT
3387         loop_exit:
3388           s_out0 = phi <s_loop>                 # (scalar) EXIT_PHI
3389           use <s_out0>
3390           use <s_out0>
3391
3392      The above is transformed by this function into:
3393
3394         loop:
3395           vec_def = phi <vec_init, VECT_DEF>    # REDUCTION_PHI
3396           VECT_DEF = vector_stmt                # vectorized form of STMT
3397           s_loop = scalar_stmt                  # (scalar) STMT
3398         loop_exit:
3399           s_out0 = phi <s_loop>                 # (scalar) EXIT_PHI
3400           v_out1 = phi <VECT_DEF>               # NEW_EXIT_PHI
3401           v_out2 = reduce <v_out1>
3402           s_out3 = extract_field <v_out2, 0>
3403           s_out4 = adjust_result <s_out3>
3404           use <s_out4>
3405           use <s_out4>
3406 */
3407
3408 static void
3409 vect_create_epilog_for_reduction (VEC (tree, heap) *vect_defs, gimple stmt,
3410                                   int ncopies, enum tree_code reduc_code,
3411                                   VEC (gimple, heap) *reduction_phis,
3412                                   int reduc_index, bool double_reduc, 
3413                                   slp_tree slp_node)
3414 {
3415   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
3416   stmt_vec_info prev_phi_info;
3417   tree vectype;
3418   enum machine_mode mode;
3419   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
3420   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo), *outer_loop = NULL;
3421   basic_block exit_bb;
3422   tree scalar_dest;
3423   tree scalar_type;
3424   gimple new_phi = NULL, phi;
3425   gimple_stmt_iterator exit_gsi;
3426   tree vec_dest;
3427   tree new_temp = NULL_TREE, new_dest, new_name, new_scalar_dest;
3428   gimple epilog_stmt = NULL;
3429   enum tree_code code = gimple_assign_rhs_code (stmt);
3430   gimple exit_phi;
3431   tree bitsize, bitpos;
3432   tree adjustment_def = NULL;
3433   tree vec_initial_def = NULL;
3434   tree reduction_op, expr, def;
3435   tree orig_name, scalar_result;
3436   imm_use_iterator imm_iter, phi_imm_iter;
3437   use_operand_p use_p, phi_use_p;
3438   bool extract_scalar_result = false;
3439   gimple use_stmt, orig_stmt, reduction_phi = NULL;
3440   bool nested_in_vect_loop = false;
3441   VEC (gimple, heap) *new_phis = NULL;
3442   enum vect_def_type dt = vect_unknown_def_type;
3443   int j, i;
3444   VEC (tree, heap) *scalar_results = NULL;
3445   unsigned int group_size = 1, k, ratio;
3446   VEC (tree, heap) *vec_initial_defs = NULL;
3447   VEC (gimple, heap) *phis;
3448   bool slp_reduc = false;
3449   tree new_phi_result;
3450
3451   if (slp_node)
3452     group_size = VEC_length (gimple, SLP_TREE_SCALAR_STMTS (slp_node)); 
3453
3454   if (nested_in_vect_loop_p (loop, stmt))
3455     {
3456       outer_loop = loop;
3457       loop = loop->inner;
3458       nested_in_vect_loop = true;
3459       gcc_assert (!slp_node);
3460     }
3461
3462   switch (get_gimple_rhs_class (gimple_assign_rhs_code (stmt)))
3463     {
3464     case GIMPLE_SINGLE_RHS:
3465       gcc_assert (TREE_OPERAND_LENGTH (gimple_assign_rhs1 (stmt))
3466                   == ternary_op);
3467       reduction_op = TREE_OPERAND (gimple_assign_rhs1 (stmt), reduc_index);
3468       break;
3469     case GIMPLE_UNARY_RHS:
3470       reduction_op = gimple_assign_rhs1 (stmt);
3471       break;
3472     case GIMPLE_BINARY_RHS:
3473       reduction_op = reduc_index ?
3474                      gimple_assign_rhs2 (stmt) : gimple_assign_rhs1 (stmt);
3475       break;
3476     case GIMPLE_TERNARY_RHS:
3477       reduction_op = gimple_op (stmt, reduc_index + 1);
3478       break;
3479     default:
3480       gcc_unreachable ();
3481     }
3482
3483   vectype = get_vectype_for_scalar_type (TREE_TYPE (reduction_op));
3484   gcc_assert (vectype);
3485   mode = TYPE_MODE (vectype);
3486
3487   /* 1. Create the reduction def-use cycle:
3488      Set the arguments of REDUCTION_PHIS, i.e., transform
3489
3490         loop:
3491           vec_def = phi <null, null>            # REDUCTION_PHI
3492           VECT_DEF = vector_stmt                # vectorized form of STMT
3493           ...
3494
3495      into:
3496
3497         loop:
3498           vec_def = phi <vec_init, VECT_DEF>    # REDUCTION_PHI
3499           VECT_DEF = vector_stmt                # vectorized form of STMT
3500           ...
3501
3502      (in case of SLP, do it for all the phis). */
3503
3504   /* Get the loop-entry arguments.  */
3505   if (slp_node)
3506     vect_get_slp_defs (reduction_op, NULL_TREE, slp_node, &vec_initial_defs,
3507                        NULL, reduc_index);
3508   else
3509     {
3510       vec_initial_defs = VEC_alloc (tree, heap, 1);
3511      /* For the case of reduction, vect_get_vec_def_for_operand returns
3512         the scalar def before the loop, that defines the initial value
3513         of the reduction variable.  */
3514       vec_initial_def = vect_get_vec_def_for_operand (reduction_op, stmt,
3515                                                       &adjustment_def);
3516       VEC_quick_push (tree, vec_initial_defs, vec_initial_def);
3517     }
3518
3519   /* Set phi nodes arguments.  */
3520   FOR_EACH_VEC_ELT (gimple, reduction_phis, i, phi)
3521     {
3522       tree vec_init_def = VEC_index (tree, vec_initial_defs, i);
3523       tree def = VEC_index (tree, vect_defs, i);
3524       for (j = 0; j < ncopies; j++)
3525         {
3526           /* Set the loop-entry arg of the reduction-phi.  */
3527           add_phi_arg (phi, vec_init_def, loop_preheader_edge (loop),
3528                        UNKNOWN_LOCATION);
3529
3530           /* Set the loop-latch arg for the reduction-phi.  */
3531           if (j > 0)
3532             def = vect_get_vec_def_for_stmt_copy (vect_unknown_def_type, def);
3533
3534           add_phi_arg (phi, def, loop_latch_edge (loop), UNKNOWN_LOCATION);
3535
3536           if (vect_print_dump_info (REPORT_DETAILS))
3537             {
3538               fprintf (vect_dump, "transform reduction: created def-use"
3539                                   " cycle: ");
3540               print_gimple_stmt (vect_dump, phi, 0, TDF_SLIM);
3541               fprintf (vect_dump, "\n");
3542               print_gimple_stmt (vect_dump, SSA_NAME_DEF_STMT (def), 0,
3543                                  TDF_SLIM);
3544             }
3545
3546           phi = STMT_VINFO_RELATED_STMT (vinfo_for_stmt (phi));
3547         }
3548     }
3549
3550   VEC_free (tree, heap, vec_initial_defs);
3551
3552   /* 2. Create epilog code.
3553         The reduction epilog code operates across the elements of the vector
3554         of partial results computed by the vectorized loop.
3555         The reduction epilog code consists of:
3556
3557         step 1: compute the scalar result in a vector (v_out2)
3558         step 2: extract the scalar result (s_out3) from the vector (v_out2)
3559         step 3: adjust the scalar result (s_out3) if needed.
3560
3561         Step 1 can be accomplished using one the following three schemes:
3562           (scheme 1) using reduc_code, if available.
3563           (scheme 2) using whole-vector shifts, if available.
3564           (scheme 3) using a scalar loop. In this case steps 1+2 above are
3565                      combined.
3566
3567           The overall epilog code looks like this:
3568
3569           s_out0 = phi <s_loop>         # original EXIT_PHI
3570           v_out1 = phi <VECT_DEF>       # NEW_EXIT_PHI
3571           v_out2 = reduce <v_out1>              # step 1
3572           s_out3 = extract_field <v_out2, 0>    # step 2
3573           s_out4 = adjust_result <s_out3>       # step 3
3574
3575           (step 3 is optional, and steps 1 and 2 may be combined).
3576           Lastly, the uses of s_out0 are replaced by s_out4.  */
3577
3578
3579   /* 2.1 Create new loop-exit-phis to preserve loop-closed form:
3580          v_out1 = phi <VECT_DEF> 
3581          Store them in NEW_PHIS.  */
3582
3583   exit_bb = single_exit (loop)->dest;
3584   prev_phi_info = NULL;
3585   new_phis = VEC_alloc (gimple, heap, VEC_length (tree, vect_defs));
3586   FOR_EACH_VEC_ELT (tree, vect_defs, i, def)
3587     {
3588       for (j = 0; j < ncopies; j++)
3589         {
3590           phi = create_phi_node (SSA_NAME_VAR (def), exit_bb);
3591           set_vinfo_for_stmt (phi, new_stmt_vec_info (phi, loop_vinfo, NULL));
3592           if (j == 0)
3593             VEC_quick_push (gimple, new_phis, phi);
3594           else
3595             {
3596               def = vect_get_vec_def_for_stmt_copy (dt, def);
3597               STMT_VINFO_RELATED_STMT (prev_phi_info) = phi;
3598             }
3599
3600           SET_PHI_ARG_DEF (phi, single_exit (loop)->dest_idx, def);
3601           prev_phi_info = vinfo_for_stmt (phi);
3602         }
3603     }
3604
3605   /* The epilogue is created for the outer-loop, i.e., for the loop being
3606      vectorized.  */
3607   if (double_reduc)
3608     {
3609       loop = outer_loop;
3610       exit_bb = single_exit (loop)->dest;
3611     }
3612
3613   exit_gsi = gsi_after_labels (exit_bb);
3614
3615   /* 2.2 Get the relevant tree-code to use in the epilog for schemes 2,3
3616          (i.e. when reduc_code is not available) and in the final adjustment
3617          code (if needed).  Also get the original scalar reduction variable as
3618          defined in the loop.  In case STMT is a "pattern-stmt" (i.e. - it
3619          represents a reduction pattern), the tree-code and scalar-def are
3620          taken from the original stmt that the pattern-stmt (STMT) replaces.
3621          Otherwise (it is a regular reduction) - the tree-code and scalar-def
3622          are taken from STMT.  */
3623
3624   orig_stmt = STMT_VINFO_RELATED_STMT (stmt_info);
3625   if (!orig_stmt)
3626     {
3627       /* Regular reduction  */
3628       orig_stmt = stmt;
3629     }
3630   else
3631     {
3632       /* Reduction pattern  */
3633       stmt_vec_info stmt_vinfo = vinfo_for_stmt (orig_stmt);
3634       gcc_assert (STMT_VINFO_IN_PATTERN_P (stmt_vinfo));
3635       gcc_assert (STMT_VINFO_RELATED_STMT (stmt_vinfo) == stmt);
3636     }
3637
3638   code = gimple_assign_rhs_code (orig_stmt);
3639   /* For MINUS_EXPR the initial vector is [init_val,0,...,0], therefore,
3640      partial results are added and not subtracted.  */
3641   if (code == MINUS_EXPR) 
3642     code = PLUS_EXPR;
3643   
3644   scalar_dest = gimple_assign_lhs (orig_stmt);
3645   scalar_type = TREE_TYPE (scalar_dest);
3646   scalar_results = VEC_alloc (tree, heap, group_size); 
3647   new_scalar_dest = vect_create_destination_var (scalar_dest, NULL);
3648   bitsize = TYPE_SIZE (scalar_type);
3649
3650   /* In case this is a reduction in an inner-loop while vectorizing an outer
3651      loop - we don't need to extract a single scalar result at the end of the
3652      inner-loop (unless it is double reduction, i.e., the use of reduction is
3653      outside the outer-loop).  The final vector of partial results will be used
3654      in the vectorized outer-loop, or reduced to a scalar result at the end of
3655      the outer-loop.  */
3656   if (nested_in_vect_loop && !double_reduc)
3657     goto vect_finalize_reduction;
3658
3659   /* SLP reduction without reduction chain, e.g.,
3660      # a1 = phi <a2, a0>
3661      # b1 = phi <b2, b0>
3662      a2 = operation (a1)
3663      b2 = operation (b1)  */
3664   slp_reduc = (slp_node && !GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt)));
3665
3666   /* In case of reduction chain, e.g.,
3667      # a1 = phi <a3, a0>
3668      a2 = operation (a1)
3669      a3 = operation (a2),
3670
3671      we may end up with more than one vector result.  Here we reduce them to
3672      one vector.  */
3673   if (GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt)))
3674     {
3675       tree first_vect = PHI_RESULT (VEC_index (gimple, new_phis, 0));
3676       tree tmp;
3677
3678       vec_dest = vect_create_destination_var (scalar_dest, vectype);
3679       for (k = 1; k < VEC_length (gimple, new_phis); k++)
3680         {
3681           gimple next_phi = VEC_index (gimple, new_phis, k);
3682           tree second_vect = PHI_RESULT (next_phi);
3683           gimple new_vec_stmt;
3684
3685           tmp = build2 (code, vectype,  first_vect, second_vect);
3686           new_vec_stmt = gimple_build_assign (vec_dest, tmp);
3687           first_vect = make_ssa_name (vec_dest, new_vec_stmt);
3688           gimple_assign_set_lhs (new_vec_stmt, first_vect);
3689           gsi_insert_before (&exit_gsi, new_vec_stmt, GSI_SAME_STMT);
3690         }
3691
3692       new_phi_result = first_vect;
3693     }
3694   else
3695     new_phi_result = PHI_RESULT (VEC_index (gimple, new_phis, 0));
3696  
3697   /* 2.3 Create the reduction code, using one of the three schemes described
3698          above. In SLP we simply need to extract all the elements from the 
3699          vector (without reducing them), so we use scalar shifts.  */
3700   if (reduc_code != ERROR_MARK && !slp_reduc)
3701     {
3702       tree tmp;
3703
3704       /*** Case 1:  Create:
3705            v_out2 = reduc_expr <v_out1>  */
3706
3707       if (vect_print_dump_info (REPORT_DETAILS))
3708         fprintf (vect_dump, "Reduce using direct vector reduction.");
3709
3710       vec_dest = vect_create_destination_var (scalar_dest, vectype);
3711       tmp = build1 (reduc_code, vectype, new_phi_result);
3712       epilog_stmt = gimple_build_assign (vec_dest, tmp);
3713       new_temp = make_ssa_name (vec_dest, epilog_stmt);
3714       gimple_assign_set_lhs (epilog_stmt, new_temp);
3715       gsi_insert_before (&exit_gsi, epilog_stmt, GSI_SAME_STMT);
3716
3717       extract_scalar_result = true;
3718     }
3719   else
3720     {
3721       enum tree_code shift_code = ERROR_MARK;
3722       bool have_whole_vector_shift = true;
3723       int bit_offset;
3724       int element_bitsize = tree_low_cst (bitsize, 1);
3725       int vec_size_in_bits = tree_low_cst (TYPE_SIZE (vectype), 1);
3726       tree vec_temp;
3727
3728       if (optab_handler (vec_shr_optab, mode) != CODE_FOR_nothing)
3729         shift_code = VEC_RSHIFT_EXPR;
3730       else
3731         have_whole_vector_shift = false;
3732
3733       /* Regardless of whether we have a whole vector shift, if we're
3734          emulating the operation via tree-vect-generic, we don't want
3735          to use it.  Only the first round of the reduction is likely
3736          to still be profitable via emulation.  */
3737       /* ??? It might be better to emit a reduction tree code here, so that
3738          tree-vect-generic can expand the first round via bit tricks.  */
3739       if (!VECTOR_MODE_P (mode))
3740         have_whole_vector_shift = false;
3741       else
3742         {
3743           optab optab = optab_for_tree_code (code, vectype, optab_default);
3744           if (optab_handler (optab, mode) == CODE_FOR_nothing)
3745             have_whole_vector_shift = false;
3746         }
3747
3748       if (have_whole_vector_shift && !slp_reduc)
3749         {
3750           /*** Case 2: Create:
3751              for (offset = VS/2; offset >= element_size; offset/=2)
3752                 {
3753                   Create:  va' = vec_shift <va, offset>
3754                   Create:  va = vop <va, va'>
3755                 }  */
3756
3757           if (vect_print_dump_info (REPORT_DETAILS))
3758             fprintf (vect_dump, "Reduce using vector shifts");
3759
3760           vec_dest = vect_create_destination_var (scalar_dest, vectype);
3761           new_temp = new_phi_result;
3762           for (bit_offset = vec_size_in_bits/2;
3763                bit_offset >= element_bitsize;
3764                bit_offset /= 2)
3765             {
3766               tree bitpos = size_int (bit_offset);
3767
3768               epilog_stmt = gimple_build_assign_with_ops (shift_code,
3769                                                vec_dest, new_temp, bitpos);
3770               new_name = make_ssa_name (vec_dest, epilog_stmt);
3771               gimple_assign_set_lhs (epilog_stmt, new_name);
3772               gsi_insert_before (&exit_gsi, epilog_stmt, GSI_SAME_STMT);
3773
3774               epilog_stmt = gimple_build_assign_with_ops (code, vec_dest,
3775                                                           new_name, new_temp);
3776               new_temp = make_ssa_name (vec_dest, epilog_stmt);
3777               gimple_assign_set_lhs (epilog_stmt, new_temp);
3778               gsi_insert_before (&exit_gsi, epilog_stmt, GSI_SAME_STMT);
3779             }
3780
3781           extract_scalar_result = true;
3782         }
3783       else
3784         {
3785           tree rhs;
3786
3787           /*** Case 3: Create:
3788              s = extract_field <v_out2, 0>
3789              for (offset = element_size;
3790                   offset < vector_size;
3791                   offset += element_size;)
3792                {
3793                  Create:  s' = extract_field <v_out2, offset>
3794                  Create:  s = op <s, s'>  // For non SLP cases
3795                }  */
3796
3797           if (vect_print_dump_info (REPORT_DETAILS))
3798             fprintf (vect_dump, "Reduce using scalar code. ");
3799
3800           vec_size_in_bits = tree_low_cst (TYPE_SIZE (vectype), 1);
3801           FOR_EACH_VEC_ELT (gimple, new_phis, i, new_phi)
3802             {
3803               vec_temp = PHI_RESULT (new_phi);
3804               rhs = build3 (BIT_FIELD_REF, scalar_type, vec_temp, bitsize,
3805                             bitsize_zero_node);
3806               epilog_stmt = gimple_build_assign (new_scalar_dest, rhs);
3807               new_temp = make_ssa_name (new_scalar_dest, epilog_stmt);
3808               gimple_assign_set_lhs (epilog_stmt, new_temp);
3809               gsi_insert_before (&exit_gsi, epilog_stmt, GSI_SAME_STMT);
3810
3811               /* In SLP we don't need to apply reduction operation, so we just
3812                  collect s' values in SCALAR_RESULTS.  */
3813               if (slp_reduc)
3814                 VEC_safe_push (tree, heap, scalar_results, new_temp);
3815
3816               for (bit_offset = element_bitsize;
3817                    bit_offset < vec_size_in_bits;
3818                    bit_offset += element_bitsize)
3819                 {
3820                   tree bitpos = bitsize_int (bit_offset);
3821                   tree rhs = build3 (BIT_FIELD_REF, scalar_type, vec_temp,
3822                                      bitsize, bitpos);
3823
3824                   epilog_stmt = gimple_build_assign (new_scalar_dest, rhs);
3825                   new_name = make_ssa_name (new_scalar_dest, epilog_stmt);
3826                   gimple_assign_set_lhs (epilog_stmt, new_name);
3827                   gsi_insert_before (&exit_gsi, epilog_stmt, GSI_SAME_STMT);
3828
3829                   if (slp_reduc)
3830                     {
3831                       /* In SLP we don't need to apply reduction operation, so 
3832                          we just collect s' values in SCALAR_RESULTS.  */
3833                       new_temp = new_name;
3834                       VEC_safe_push (tree, heap, scalar_results, new_name);
3835                     }
3836                   else
3837                     {
3838                       epilog_stmt = gimple_build_assign_with_ops (code,
3839                                           new_scalar_dest, new_name, new_temp);
3840                       new_temp = make_ssa_name (new_scalar_dest, epilog_stmt);
3841                       gimple_assign_set_lhs (epilog_stmt, new_temp);
3842                       gsi_insert_before (&exit_gsi, epilog_stmt, GSI_SAME_STMT);
3843                     }
3844                 }
3845             }
3846
3847           /* The only case where we need to reduce scalar results in SLP, is
3848              unrolling.  If the size of SCALAR_RESULTS is greater than
3849              GROUP_SIZE, we reduce them combining elements modulo 
3850              GROUP_SIZE.  */
3851           if (slp_reduc)
3852             {
3853               tree res, first_res, new_res;
3854               gimple new_stmt;
3855             
3856               /* Reduce multiple scalar results in case of SLP unrolling.  */
3857               for (j = group_size; VEC_iterate (tree, scalar_results, j, res);
3858                    j++)
3859                 {
3860                   first_res = VEC_index (tree, scalar_results, j % group_size);
3861                   new_stmt = gimple_build_assign_with_ops (code,
3862                                               new_scalar_dest, first_res, res);
3863                   new_res = make_ssa_name (new_scalar_dest, new_stmt);
3864                   gimple_assign_set_lhs (new_stmt, new_res);
3865                   gsi_insert_before (&exit_gsi, new_stmt, GSI_SAME_STMT);
3866                   VEC_replace (tree, scalar_results, j % group_size, new_res);
3867                 }
3868             }
3869           else
3870             /* Not SLP - we have one scalar to keep in SCALAR_RESULTS.  */
3871             VEC_safe_push (tree, heap, scalar_results, new_temp);
3872
3873           extract_scalar_result = false;
3874         }
3875     }
3876
3877   /* 2.4  Extract the final scalar result.  Create:
3878           s_out3 = extract_field <v_out2, bitpos>  */
3879
3880   if (extract_scalar_result)
3881     {
3882       tree rhs;
3883
3884       if (vect_print_dump_info (REPORT_DETAILS))
3885         fprintf (vect_dump, "extract scalar result");
3886
3887       if (BYTES_BIG_ENDIAN)
3888         bitpos = size_binop (MULT_EXPR,
3889                              bitsize_int (TYPE_VECTOR_SUBPARTS (vectype) - 1),
3890                              TYPE_SIZE (scalar_type));
3891       else
3892         bitpos = bitsize_zero_node;
3893
3894       rhs = build3 (BIT_FIELD_REF, scalar_type, new_temp, bitsize, bitpos);
3895       epilog_stmt = gimple_build_assign (new_scalar_dest, rhs);
3896       new_temp = make_ssa_name (new_scalar_dest, epilog_stmt);
3897       gimple_assign_set_lhs (epilog_stmt, new_temp);
3898       gsi_insert_before (&exit_gsi, epilog_stmt, GSI_SAME_STMT);
3899       VEC_safe_push (tree, heap, scalar_results, new_temp);
3900     }
3901   
3902 vect_finalize_reduction:
3903
3904   if (double_reduc)
3905     loop = loop->inner;
3906
3907   /* 2.5 Adjust the final result by the initial value of the reduction
3908          variable. (When such adjustment is not needed, then
3909          'adjustment_def' is zero).  For example, if code is PLUS we create:
3910          new_temp = loop_exit_def + adjustment_def  */
3911
3912   if (adjustment_def)
3913     {
3914       gcc_assert (!slp_reduc);
3915       if (nested_in_vect_loop)
3916         {
3917           new_phi = VEC_index (gimple, new_phis, 0);
3918           gcc_assert (TREE_CODE (TREE_TYPE (adjustment_def)) == VECTOR_TYPE);
3919           expr = build2 (code, vectype, PHI_RESULT (new_phi), adjustment_def);
3920           new_dest = vect_create_destination_var (scalar_dest, vectype);
3921         }
3922       else
3923         {
3924           new_temp = VEC_index (tree, scalar_results, 0);
3925           gcc_assert (TREE_CODE (TREE_TYPE (adjustment_def)) != VECTOR_TYPE);
3926           expr = build2 (code, scalar_type, new_temp, adjustment_def);
3927           new_dest = vect_create_destination_var (scalar_dest, scalar_type);
3928         }
3929
3930       epilog_stmt = gimple_build_assign (new_dest, expr);
3931       new_temp = make_ssa_name (new_dest, epilog_stmt);
3932       gimple_assign_set_lhs (epilog_stmt, new_temp);
3933       SSA_NAME_DEF_STMT (new_temp) = epilog_stmt;
3934       gsi_insert_before (&exit_gsi, epilog_stmt, GSI_SAME_STMT);
3935       if (nested_in_vect_loop)
3936         {
3937           set_vinfo_for_stmt (epilog_stmt,
3938                               new_stmt_vec_info (epilog_stmt, loop_vinfo,
3939                                                  NULL));
3940           STMT_VINFO_RELATED_STMT (vinfo_for_stmt (epilog_stmt)) =
3941                 STMT_VINFO_RELATED_STMT (vinfo_for_stmt (new_phi));
3942
3943           if (!double_reduc)
3944             VEC_quick_push (tree, scalar_results, new_temp);
3945           else
3946             VEC_replace (tree, scalar_results, 0, new_temp);
3947         }
3948       else
3949         VEC_replace (tree, scalar_results, 0, new_temp);
3950
3951       VEC_replace (gimple, new_phis, 0, epilog_stmt);
3952     }
3953
3954   /* 2.6  Handle the loop-exit phis.  Replace the uses of scalar loop-exit
3955           phis with new adjusted scalar results, i.e., replace use <s_out0>
3956           with use <s_out4>.        
3957
3958      Transform:
3959         loop_exit:
3960           s_out0 = phi <s_loop>                 # (scalar) EXIT_PHI
3961           v_out1 = phi <VECT_DEF>               # NEW_EXIT_PHI
3962           v_out2 = reduce <v_out1>
3963           s_out3 = extract_field <v_out2, 0>
3964           s_out4 = adjust_result <s_out3>
3965           use <s_out0>
3966           use <s_out0>
3967
3968      into:
3969
3970         loop_exit:
3971           s_out0 = phi <s_loop>                 # (scalar) EXIT_PHI
3972           v_out1 = phi <VECT_DEF>               # NEW_EXIT_PHI
3973           v_out2 = reduce <v_out1>
3974           s_out3 = extract_field <v_out2, 0>
3975           s_out4 = adjust_result <s_out3>
3976           use <s_out4>  
3977           use <s_out4> */
3978
3979
3980   /* In SLP reduction chain we reduce vector results into one vector if
3981      necessary, hence we set here GROUP_SIZE to 1.  SCALAR_DEST is the LHS of
3982      the last stmt in the reduction chain, since we are looking for the loop
3983      exit phi node.  */
3984   if (GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt)))
3985     {
3986       scalar_dest = gimple_assign_lhs (VEC_index (gimple,
3987                                        SLP_TREE_SCALAR_STMTS (slp_node),
3988                                        group_size - 1));
3989       group_size = 1;
3990     }
3991
3992   /* In SLP we may have several statements in NEW_PHIS and REDUCTION_PHIS (in 
3993      case that GROUP_SIZE is greater than vectorization factor).  Therefore, we
3994      need to match SCALAR_RESULTS with corresponding statements.  The first
3995      (GROUP_SIZE / number of new vector stmts) scalar results correspond to
3996      the first vector stmt, etc.  
3997      (RATIO is equal to (GROUP_SIZE / number of new vector stmts)).  */ 
3998   if (group_size > VEC_length (gimple, new_phis))
3999     {
4000       ratio = group_size / VEC_length (gimple, new_phis);
4001       gcc_assert (!(group_size % VEC_length (gimple, new_phis)));
4002     }
4003   else
4004     ratio = 1;
4005
4006   for (k = 0; k < group_size; k++)
4007     {
4008       if (k % ratio == 0)
4009         {
4010           epilog_stmt = VEC_index (gimple, new_phis, k / ratio);
4011           reduction_phi = VEC_index (gimple, reduction_phis, k / ratio);
4012         }
4013
4014       if (slp_reduc)
4015         {
4016           gimple current_stmt = VEC_index (gimple,
4017                                        SLP_TREE_SCALAR_STMTS (slp_node), k);
4018
4019           orig_stmt = STMT_VINFO_RELATED_STMT (vinfo_for_stmt (current_stmt));
4020           /* SLP statements can't participate in patterns.  */
4021           gcc_assert (!orig_stmt);
4022           scalar_dest = gimple_assign_lhs (current_stmt);
4023         }
4024
4025       phis = VEC_alloc (gimple, heap, 3);
4026       /* Find the loop-closed-use at the loop exit of the original scalar
4027          result.  (The reduction result is expected to have two immediate uses -
4028          one at the latch block, and one at the loop exit).  */
4029       FOR_EACH_IMM_USE_FAST (use_p, imm_iter, scalar_dest)
4030         if (!flow_bb_inside_loop_p (loop, gimple_bb (USE_STMT (use_p))))
4031           VEC_safe_push (gimple, heap, phis, USE_STMT (use_p));
4032
4033       /* We expect to have found an exit_phi because of loop-closed-ssa
4034          form.  */
4035       gcc_assert (!VEC_empty (gimple, phis));
4036
4037       FOR_EACH_VEC_ELT (gimple, phis, i, exit_phi)
4038         {
4039           if (outer_loop)
4040             {
4041               stmt_vec_info exit_phi_vinfo = vinfo_for_stmt (exit_phi);
4042               gimple vect_phi;
4043
4044               /* FORNOW. Currently not supporting the case that an inner-loop
4045                  reduction is not used in the outer-loop (but only outside the
4046                  outer-loop), unless it is double reduction.  */
4047               gcc_assert ((STMT_VINFO_RELEVANT_P (exit_phi_vinfo)
4048                            && !STMT_VINFO_LIVE_P (exit_phi_vinfo))
4049                           || double_reduc);
4050
4051               STMT_VINFO_VEC_STMT (exit_phi_vinfo) = epilog_stmt;
4052               if (!double_reduc
4053                   || STMT_VINFO_DEF_TYPE (exit_phi_vinfo)
4054                       != vect_double_reduction_def)
4055                 continue;
4056
4057               /* Handle double reduction:
4058
4059                  stmt1: s1 = phi <s0, s2>  - double reduction phi (outer loop)
4060                  stmt2:   s3 = phi <s1, s4> - (regular) reduc phi (inner loop)
4061                  stmt3:   s4 = use (s3)     - (regular) reduc stmt (inner loop)
4062                  stmt4: s2 = phi <s4>      - double reduction stmt (outer loop)
4063
4064                  At that point the regular reduction (stmt2 and stmt3) is
4065                  already vectorized, as well as the exit phi node, stmt4.
4066                  Here we vectorize the phi node of double reduction, stmt1, and
4067                  update all relevant statements.  */
4068
4069               /* Go through all the uses of s2 to find double reduction phi
4070                  node, i.e., stmt1 above.  */
4071               orig_name = PHI_RESULT (exit_phi);
4072               FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, orig_name)
4073                 {
4074                   stmt_vec_info use_stmt_vinfo = vinfo_for_stmt (use_stmt);
4075                   stmt_vec_info new_phi_vinfo;
4076                   tree vect_phi_init, preheader_arg, vect_phi_res, init_def;
4077                   basic_block bb = gimple_bb (use_stmt);
4078                   gimple use;
4079
4080                   /* Check that USE_STMT is really double reduction phi
4081                      node.  */
4082                   if (gimple_code (use_stmt) != GIMPLE_PHI
4083                       || gimple_phi_num_args (use_stmt) != 2
4084                       || !use_stmt_vinfo
4085                       || STMT_VINFO_DEF_TYPE (use_stmt_vinfo)
4086                           != vect_double_reduction_def
4087                       || bb->loop_father != outer_loop)
4088                     continue;
4089
4090                   /* Create vector phi node for double reduction:
4091                      vs1 = phi <vs0, vs2>
4092                      vs1 was created previously in this function by a call to
4093                        vect_get_vec_def_for_operand and is stored in
4094                        vec_initial_def;
4095                      vs2 is defined by EPILOG_STMT, the vectorized EXIT_PHI;
4096                      vs0 is created here.  */
4097
4098                   /* Create vector phi node.  */
4099                   vect_phi = create_phi_node (vec_initial_def, bb);
4100                   new_phi_vinfo = new_stmt_vec_info (vect_phi,
4101                                     loop_vec_info_for_loop (outer_loop), NULL);
4102                   set_vinfo_for_stmt (vect_phi, new_phi_vinfo);
4103
4104                   /* Create vs0 - initial def of the double reduction phi.  */
4105                   preheader_arg = PHI_ARG_DEF_FROM_EDGE (use_stmt,
4106                                              loop_preheader_edge (outer_loop));
4107                   init_def = get_initial_def_for_reduction (stmt,
4108                                                           preheader_arg, NULL);
4109                   vect_phi_init = vect_init_vector (use_stmt, init_def,
4110                                                     vectype, NULL);
4111
4112                   /* Update phi node arguments with vs0 and vs2.  */
4113                   add_phi_arg (vect_phi, vect_phi_init,
4114                                loop_preheader_edge (outer_loop),
4115                                UNKNOWN_LOCATION);
4116                   add_phi_arg (vect_phi, PHI_RESULT (epilog_stmt),
4117                                loop_latch_edge (outer_loop), UNKNOWN_LOCATION);
4118                   if (vect_print_dump_info (REPORT_DETAILS))
4119                     {
4120                       fprintf (vect_dump, "created double reduction phi "
4121                                           "node: ");
4122                       print_gimple_stmt (vect_dump, vect_phi, 0, TDF_SLIM);
4123                     }
4124
4125                   vect_phi_res = PHI_RESULT (vect_phi);
4126
4127                   /* Replace the use, i.e., set the correct vs1 in the regular
4128                      reduction phi node.  FORNOW, NCOPIES is always 1, so the
4129                      loop is redundant.  */
4130                   use = reduction_phi;
4131                   for (j = 0; j < ncopies; j++)
4132                     {
4133                       edge pr_edge = loop_preheader_edge (loop);
4134                       SET_PHI_ARG_DEF (use, pr_edge->dest_idx, vect_phi_res);
4135                       use = STMT_VINFO_RELATED_STMT (vinfo_for_stmt (use));
4136                     }
4137                 }
4138             }
4139         }
4140
4141       VEC_free (gimple, heap, phis);
4142       if (nested_in_vect_loop)
4143         {
4144           if (double_reduc)
4145             loop = outer_loop;
4146           else
4147             continue;
4148         }
4149
4150       phis = VEC_alloc (gimple, heap, 3);
4151       /* Find the loop-closed-use at the loop exit of the original scalar
4152          result.  (The reduction result is expected to have two immediate uses,
4153          one at the latch block, and one at the loop exit).  For double
4154          reductions we are looking for exit phis of the outer loop.  */
4155       FOR_EACH_IMM_USE_FAST (use_p, imm_iter, scalar_dest)
4156         {
4157           if (!flow_bb_inside_loop_p (loop, gimple_bb (USE_STMT (use_p))))
4158             VEC_safe_push (gimple, heap, phis, USE_STMT (use_p));
4159           else
4160             {
4161               if (double_reduc && gimple_code (USE_STMT (use_p)) == GIMPLE_PHI)
4162                 {
4163                   tree phi_res = PHI_RESULT (USE_STMT (use_p));
4164
4165                   FOR_EACH_IMM_USE_FAST (phi_use_p, phi_imm_iter, phi_res)
4166                     {
4167                       if (!flow_bb_inside_loop_p (loop,
4168                                              gimple_bb (USE_STMT (phi_use_p))))
4169                         VEC_safe_push (gimple, heap, phis,
4170                                        USE_STMT (phi_use_p));
4171                     }
4172                 }
4173             }
4174         }
4175
4176       FOR_EACH_VEC_ELT (gimple, phis, i, exit_phi)
4177         {
4178           /* Replace the uses:  */
4179           orig_name = PHI_RESULT (exit_phi);
4180           scalar_result = VEC_index (tree, scalar_results, k);
4181           FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, orig_name)
4182             FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
4183               SET_USE (use_p, scalar_result);
4184         }
4185
4186       VEC_free (gimple, heap, phis);
4187     }
4188
4189   VEC_free (tree, heap, scalar_results);
4190   VEC_free (gimple, heap, new_phis);
4191
4192
4193
4194 /* Function vectorizable_reduction.
4195
4196    Check if STMT performs a reduction operation that can be vectorized.
4197    If VEC_STMT is also passed, vectorize the STMT: create a vectorized
4198    stmt to replace it, put it in VEC_STMT, and insert it at GSI.
4199    Return FALSE if not a vectorizable STMT, TRUE otherwise.
4200
4201    This function also handles reduction idioms (patterns) that have been
4202    recognized in advance during vect_pattern_recog.  In this case, STMT may be
4203    of this form:
4204      X = pattern_expr (arg0, arg1, ..., X)
4205    and it's STMT_VINFO_RELATED_STMT points to the last stmt in the original
4206    sequence that had been detected and replaced by the pattern-stmt (STMT).
4207
4208    In some cases of reduction patterns, the type of the reduction variable X is
4209    different than the type of the other arguments of STMT.
4210    In such cases, the vectype that is used when transforming STMT into a vector
4211    stmt is different than the vectype that is used to determine the
4212    vectorization factor, because it consists of a different number of elements
4213    than the actual number of elements that are being operated upon in parallel.
4214
4215    For example, consider an accumulation of shorts into an int accumulator.
4216    On some targets it's possible to vectorize this pattern operating on 8
4217    shorts at a time (hence, the vectype for purposes of determining the
4218    vectorization factor should be V8HI); on the other hand, the vectype that
4219    is used to create the vector form is actually V4SI (the type of the result).
4220
4221    Upon entry to this function, STMT_VINFO_VECTYPE records the vectype that
4222    indicates what is the actual level of parallelism (V8HI in the example), so
4223    that the right vectorization factor would be derived.  This vectype
4224    corresponds to the type of arguments to the reduction stmt, and should *NOT*
4225    be used to create the vectorized stmt.  The right vectype for the vectorized
4226    stmt is obtained from the type of the result X:
4227         get_vectype_for_scalar_type (TREE_TYPE (X))
4228
4229    This means that, contrary to "regular" reductions (or "regular" stmts in
4230    general), the following equation:
4231       STMT_VINFO_VECTYPE == get_vectype_for_scalar_type (TREE_TYPE (X))
4232    does *NOT* necessarily hold for reduction patterns.  */
4233
4234 bool
4235 vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi,
4236                         gimple *vec_stmt, slp_tree slp_node)
4237 {
4238   tree vec_dest;
4239   tree scalar_dest;
4240   tree loop_vec_def0 = NULL_TREE, loop_vec_def1 = NULL_TREE;
4241   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
4242   tree vectype_out = STMT_VINFO_VECTYPE (stmt_info);
4243   tree vectype_in = NULL_TREE;
4244   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
4245   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
4246   enum tree_code code, orig_code, epilog_reduc_code;
4247   enum machine_mode vec_mode;
4248   int op_type;
4249   optab optab, reduc_optab;
4250   tree new_temp = NULL_TREE;
4251   tree def;
4252   gimple def_stmt;
4253   enum vect_def_type dt;
4254   gimple new_phi = NULL;
4255   tree scalar_type;
4256   bool is_simple_use;
4257   gimple orig_stmt;
4258   stmt_vec_info orig_stmt_info;
4259   tree expr = NULL_TREE;
4260   int i;
4261   int ncopies;
4262   int epilog_copies;
4263   stmt_vec_info prev_stmt_info, prev_phi_info;
4264   bool single_defuse_cycle = false;
4265   tree reduc_def = NULL_TREE;
4266   gimple new_stmt = NULL;
4267   int j;
4268   tree ops[3];
4269   bool nested_cycle = false, found_nested_cycle_def = false;
4270   gimple reduc_def_stmt = NULL;
4271   /* The default is that the reduction variable is the last in statement.  */
4272   int reduc_index = 2;
4273   bool double_reduc = false, dummy;
4274   basic_block def_bb;
4275   struct loop * def_stmt_loop, *outer_loop = NULL;
4276   tree def_arg;
4277   gimple def_arg_stmt;
4278   VEC (tree, heap) *vec_oprnds0 = NULL, *vec_oprnds1 = NULL, *vect_defs = NULL;
4279   VEC (gimple, heap) *phis = NULL;
4280   int vec_num;
4281   tree def0, def1, tem;
4282
4283   /* In case of reduction chain we switch to the first stmt in the chain, but
4284      we don't update STMT_INFO, since only the last stmt is marked as reduction
4285      and has reduction properties.  */
4286   if (GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt)))
4287     stmt = GROUP_FIRST_ELEMENT (stmt_info);
4288
4289   if (nested_in_vect_loop_p (loop, stmt))
4290     {
4291       outer_loop = loop;
4292       loop = loop->inner;
4293       nested_cycle = true;
4294     }
4295
4296   /* 1. Is vectorizable reduction?  */
4297   /* Not supportable if the reduction variable is used in the loop, unless
4298      it's a reduction chain.  */
4299   if (STMT_VINFO_RELEVANT (stmt_info) > vect_used_in_outer
4300       && !GROUP_FIRST_ELEMENT (stmt_info))
4301     return false;
4302
4303   /* Reductions that are not used even in an enclosing outer-loop,
4304      are expected to be "live" (used out of the loop).  */
4305   if (STMT_VINFO_RELEVANT (stmt_info) == vect_unused_in_scope
4306       && !STMT_VINFO_LIVE_P (stmt_info))
4307     return false;
4308
4309   /* Make sure it was already recognized as a reduction computation.  */
4310   if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_reduction_def
4311       && STMT_VINFO_DEF_TYPE (stmt_info) != vect_nested_cycle)
4312     return false;
4313
4314   /* 2. Has this been recognized as a reduction pattern?
4315
4316      Check if STMT represents a pattern that has been recognized
4317      in earlier analysis stages.  For stmts that represent a pattern,
4318      the STMT_VINFO_RELATED_STMT field records the last stmt in
4319      the original sequence that constitutes the pattern.  */
4320
4321   orig_stmt = STMT_VINFO_RELATED_STMT (stmt_info);
4322   if (orig_stmt)
4323     {
4324       orig_stmt_info = vinfo_for_stmt (orig_stmt);
4325       gcc_assert (STMT_VINFO_RELATED_STMT (orig_stmt_info) == stmt);
4326       gcc_assert (STMT_VINFO_IN_PATTERN_P (orig_stmt_info));
4327       gcc_assert (!STMT_VINFO_IN_PATTERN_P (stmt_info));
4328     }
4329
4330   /* 3. Check the operands of the operation.  The first operands are defined
4331         inside the loop body. The last operand is the reduction variable,
4332         which is defined by the loop-header-phi.  */
4333
4334   gcc_assert (is_gimple_assign (stmt));
4335
4336   /* Flatten RHS.  */
4337   switch (get_gimple_rhs_class (gimple_assign_rhs_code (stmt)))
4338     {
4339     case GIMPLE_SINGLE_RHS:
4340       op_type = TREE_OPERAND_LENGTH (gimple_assign_rhs1 (stmt));
4341       if (op_type == ternary_op)
4342         {
4343           tree rhs = gimple_assign_rhs1 (stmt);
4344           ops[0] = TREE_OPERAND (rhs, 0);
4345           ops[1] = TREE_OPERAND (rhs, 1);
4346           ops[2] = TREE_OPERAND (rhs, 2);
4347           code = TREE_CODE (rhs);
4348         }
4349       else
4350         return false;
4351       break;
4352
4353     case GIMPLE_BINARY_RHS:
4354       code = gimple_assign_rhs_code (stmt);
4355       op_type = TREE_CODE_LENGTH (code);
4356       gcc_assert (op_type == binary_op);
4357       ops[0] = gimple_assign_rhs1 (stmt);
4358       ops[1] = gimple_assign_rhs2 (stmt);
4359       break;
4360
4361     case GIMPLE_TERNARY_RHS:
4362       code = gimple_assign_rhs_code (stmt);
4363       op_type = TREE_CODE_LENGTH (code);
4364       gcc_assert (op_type == ternary_op);
4365       ops[0] = gimple_assign_rhs1 (stmt);
4366       ops[1] = gimple_assign_rhs2 (stmt);
4367       ops[2] = gimple_assign_rhs3 (stmt);
4368       break;
4369
4370     case GIMPLE_UNARY_RHS:
4371       return false;
4372
4373     default:
4374       gcc_unreachable ();
4375     }
4376
4377   scalar_dest = gimple_assign_lhs (stmt);
4378   scalar_type = TREE_TYPE (scalar_dest);
4379   if (!POINTER_TYPE_P (scalar_type) && !INTEGRAL_TYPE_P (scalar_type)
4380       && !SCALAR_FLOAT_TYPE_P (scalar_type))
4381     return false;
4382
4383   /* All uses but the last are expected to be defined in the loop.
4384      The last use is the reduction variable.  In case of nested cycle this
4385      assumption is not true: we use reduc_index to record the index of the
4386      reduction variable.  */
4387   for (i = 0; i < op_type-1; i++)
4388     {
4389       /* The condition of COND_EXPR is checked in vectorizable_condition().  */
4390       if (i == 0 && code == COND_EXPR)
4391         continue;
4392
4393       is_simple_use = vect_is_simple_use_1 (ops[i], loop_vinfo, NULL,
4394                                             &def_stmt, &def, &dt, &tem);
4395       if (!vectype_in)
4396         vectype_in = tem;
4397       gcc_assert (is_simple_use);
4398
4399       if (dt != vect_internal_def
4400           && dt != vect_external_def
4401           && dt != vect_constant_def
4402           && dt != vect_induction_def
4403           && !(dt == vect_nested_cycle && nested_cycle))
4404         return false;
4405
4406       if (dt == vect_nested_cycle)
4407         {
4408           found_nested_cycle_def = true;
4409           reduc_def_stmt = def_stmt;
4410           reduc_index = i;
4411         }
4412     }
4413
4414   is_simple_use = vect_is_simple_use_1 (ops[i], loop_vinfo, NULL, &def_stmt,
4415                                         &def, &dt, &tem);
4416   if (!vectype_in)
4417     vectype_in = tem;
4418   gcc_assert (is_simple_use);
4419   gcc_assert (dt == vect_reduction_def
4420               || dt == vect_nested_cycle
4421               || ((dt == vect_internal_def || dt == vect_external_def
4422                    || dt == vect_constant_def || dt == vect_induction_def)
4423                    && nested_cycle && found_nested_cycle_def));
4424   if (!found_nested_cycle_def)
4425     reduc_def_stmt = def_stmt;
4426
4427   gcc_assert (gimple_code (reduc_def_stmt) == GIMPLE_PHI);
4428   if (orig_stmt)
4429     gcc_assert (orig_stmt == vect_is_simple_reduction (loop_vinfo,
4430                                                        reduc_def_stmt,
4431                                                        !nested_cycle,
4432                                                        &dummy));
4433   else
4434     {
4435       gimple tmp = vect_is_simple_reduction (loop_vinfo, reduc_def_stmt,
4436                                              !nested_cycle, &dummy);
4437       /* We changed STMT to be the first stmt in reduction chain, hence we
4438          check that in this case the first element in the chain is STMT.  */
4439       gcc_assert (stmt == tmp
4440                   || GROUP_FIRST_ELEMENT (vinfo_for_stmt (tmp)) == stmt);
4441     }
4442
4443   if (STMT_VINFO_LIVE_P (vinfo_for_stmt (reduc_def_stmt)))
4444     return false;
4445
4446   if (slp_node || PURE_SLP_STMT (stmt_info))
4447     ncopies = 1;
4448   else
4449     ncopies = (LOOP_VINFO_VECT_FACTOR (loop_vinfo)
4450                / TYPE_VECTOR_SUBPARTS (vectype_in));
4451
4452   gcc_assert (ncopies >= 1);
4453
4454   vec_mode = TYPE_MODE (vectype_in);
4455
4456   if (code == COND_EXPR)
4457     {
4458       if (!vectorizable_condition (stmt, gsi, NULL, ops[reduc_index], 0))
4459         {
4460           if (vect_print_dump_info (REPORT_DETAILS))
4461             fprintf (vect_dump, "unsupported condition in reduction");
4462
4463             return false;
4464         }
4465     }
4466   else
4467     {
4468       /* 4. Supportable by target?  */
4469
4470       /* 4.1. check support for the operation in the loop  */
4471       optab = optab_for_tree_code (code, vectype_in, optab_default);
4472       if (!optab)
4473         {
4474           if (vect_print_dump_info (REPORT_DETAILS))
4475             fprintf (vect_dump, "no optab.");
4476
4477           return false;
4478         }
4479
4480       if (optab_handler (optab, vec_mode) == CODE_FOR_nothing)
4481         {
4482           if (vect_print_dump_info (REPORT_DETAILS))
4483             fprintf (vect_dump, "op not supported by target.");
4484
4485           if (GET_MODE_SIZE (vec_mode) != UNITS_PER_WORD
4486               || LOOP_VINFO_VECT_FACTOR (loop_vinfo)
4487                   < vect_min_worthwhile_factor (code))
4488             return false;
4489
4490           if (vect_print_dump_info (REPORT_DETAILS))
4491             fprintf (vect_dump, "proceeding using word mode.");
4492         }
4493
4494       /* Worthwhile without SIMD support?  */
4495       if (!VECTOR_MODE_P (TYPE_MODE (vectype_in))
4496           && LOOP_VINFO_VECT_FACTOR (loop_vinfo)
4497              < vect_min_worthwhile_factor (code))
4498         {
4499           if (vect_print_dump_info (REPORT_DETAILS))
4500             fprintf (vect_dump, "not worthwhile without SIMD support.");
4501
4502           return false;
4503         }
4504     }
4505
4506   /* 4.2. Check support for the epilog operation.
4507
4508           If STMT represents a reduction pattern, then the type of the
4509           reduction variable may be different than the type of the rest
4510           of the arguments.  For example, consider the case of accumulation
4511           of shorts into an int accumulator; The original code:
4512                         S1: int_a = (int) short_a;
4513           orig_stmt->   S2: int_acc = plus <int_a ,int_acc>;
4514
4515           was replaced with:
4516                         STMT: int_acc = widen_sum <short_a, int_acc>
4517
4518           This means that:
4519           1. The tree-code that is used to create the vector operation in the
4520              epilog code (that reduces the partial results) is not the
4521              tree-code of STMT, but is rather the tree-code of the original
4522              stmt from the pattern that STMT is replacing.  I.e, in the example
4523              above we want to use 'widen_sum' in the loop, but 'plus' in the
4524              epilog.
4525           2. The type (mode) we use to check available target support
4526              for the vector operation to be created in the *epilog*, is
4527              determined by the type of the reduction variable (in the example
4528              above we'd check this: optab_handler (plus_optab, vect_int_mode])).
4529              However the type (mode) we use to check available target support
4530              for the vector operation to be created *inside the loop*, is
4531              determined by the type of the other arguments to STMT (in the
4532              example we'd check this: optab_handler (widen_sum_optab,
4533              vect_short_mode)).
4534
4535           This is contrary to "regular" reductions, in which the types of all
4536           the arguments are the same as the type of the reduction variable.
4537           For "regular" reductions we can therefore use the same vector type
4538           (and also the same tree-code) when generating the epilog code and
4539           when generating the code inside the loop.  */
4540
4541   if (orig_stmt)
4542     {
4543       /* This is a reduction pattern: get the vectype from the type of the
4544          reduction variable, and get the tree-code from orig_stmt.  */
4545       orig_code = gimple_assign_rhs_code (orig_stmt);
4546       gcc_assert (vectype_out);
4547       vec_mode = TYPE_MODE (vectype_out);
4548     }
4549   else
4550     {
4551       /* Regular reduction: use the same vectype and tree-code as used for
4552          the vector code inside the loop can be used for the epilog code. */
4553       orig_code = code;
4554     }
4555
4556   if (nested_cycle)
4557     {
4558       def_bb = gimple_bb (reduc_def_stmt);
4559       def_stmt_loop = def_bb->loop_father;
4560       def_arg = PHI_ARG_DEF_FROM_EDGE (reduc_def_stmt,
4561                                        loop_preheader_edge (def_stmt_loop));
4562       if (TREE_CODE (def_arg) == SSA_NAME
4563           && (def_arg_stmt = SSA_NAME_DEF_STMT (def_arg))
4564           && gimple_code (def_arg_stmt) == GIMPLE_PHI
4565           && flow_bb_inside_loop_p (outer_loop, gimple_bb (def_arg_stmt))
4566           && vinfo_for_stmt (def_arg_stmt)
4567           && STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def_arg_stmt))
4568               == vect_double_reduction_def)
4569         double_reduc = true;
4570     }
4571
4572   epilog_reduc_code = ERROR_MARK;
4573   if (reduction_code_for_scalar_code (orig_code, &epilog_reduc_code))
4574     {
4575       reduc_optab = optab_for_tree_code (epilog_reduc_code, vectype_out,
4576                                          optab_default);
4577       if (!reduc_optab)
4578         {
4579           if (vect_print_dump_info (REPORT_DETAILS))
4580             fprintf (vect_dump, "no optab for reduction.");
4581
4582           epilog_reduc_code = ERROR_MARK;
4583         }
4584
4585       if (reduc_optab
4586           && optab_handler (reduc_optab, vec_mode) == CODE_FOR_nothing)
4587         {
4588           if (vect_print_dump_info (REPORT_DETAILS))
4589             fprintf (vect_dump, "reduc op not supported by target.");
4590
4591           epilog_reduc_code = ERROR_MARK;
4592         }
4593     }
4594   else
4595     {
4596       if (!nested_cycle || double_reduc)
4597         {
4598           if (vect_print_dump_info (REPORT_DETAILS))
4599             fprintf (vect_dump, "no reduc code for scalar code.");
4600
4601           return false;
4602         }
4603     }
4604
4605   if (double_reduc && ncopies > 1)
4606     {
4607       if (vect_print_dump_info (REPORT_DETAILS))
4608         fprintf (vect_dump, "multiple types in double reduction");
4609
4610       return false;
4611     }
4612
4613   /* In case of widenning multiplication by a constant, we update the type
4614      of the constant to be the type of the other operand.  We check that the
4615      constant fits the type in the pattern recognition pass.  */
4616   if (code == DOT_PROD_EXPR
4617       && !types_compatible_p (TREE_TYPE (ops[0]), TREE_TYPE (ops[1])))
4618     {
4619       if (TREE_CODE (ops[0]) == INTEGER_CST)
4620         ops[0] = fold_convert (TREE_TYPE (ops[1]), ops[0]);
4621       else if (TREE_CODE (ops[1]) == INTEGER_CST)
4622         ops[1] = fold_convert (TREE_TYPE (ops[0]), ops[1]);
4623       else
4624         {
4625           if (vect_print_dump_info (REPORT_DETAILS))
4626             fprintf (vect_dump, "invalid types in dot-prod");
4627
4628           return false;
4629         }
4630     }
4631
4632   if (!vec_stmt) /* transformation not required.  */
4633     {
4634       if (!vect_model_reduction_cost (stmt_info, epilog_reduc_code, ncopies))
4635         return false;
4636       STMT_VINFO_TYPE (stmt_info) = reduc_vec_info_type;
4637       return true;
4638     }
4639
4640   /** Transform.  **/
4641
4642   if (vect_print_dump_info (REPORT_DETAILS))
4643     fprintf (vect_dump, "transform reduction.");
4644
4645   /* FORNOW: Multiple types are not supported for condition.  */
4646   if (code == COND_EXPR)
4647     gcc_assert (ncopies == 1);
4648
4649   /* Create the destination vector  */
4650   vec_dest = vect_create_destination_var (scalar_dest, vectype_out);
4651
4652   /* In case the vectorization factor (VF) is bigger than the number
4653      of elements that we can fit in a vectype (nunits), we have to generate
4654      more than one vector stmt - i.e - we need to "unroll" the
4655      vector stmt by a factor VF/nunits.  For more details see documentation
4656      in vectorizable_operation.  */
4657
4658   /* If the reduction is used in an outer loop we need to generate
4659      VF intermediate results, like so (e.g. for ncopies=2):
4660         r0 = phi (init, r0)
4661         r1 = phi (init, r1)
4662         r0 = x0 + r0;
4663         r1 = x1 + r1;
4664     (i.e. we generate VF results in 2 registers).
4665     In this case we have a separate def-use cycle for each copy, and therefore
4666     for each copy we get the vector def for the reduction variable from the
4667     respective phi node created for this copy.
4668
4669     Otherwise (the reduction is unused in the loop nest), we can combine
4670     together intermediate results, like so (e.g. for ncopies=2):
4671         r = phi (init, r)
4672         r = x0 + r;
4673         r = x1 + r;
4674    (i.e. we generate VF/2 results in a single register).
4675    In this case for each copy we get the vector def for the reduction variable
4676    from the vectorized reduction operation generated in the previous iteration.
4677   */
4678
4679   if (STMT_VINFO_RELEVANT (stmt_info) == vect_unused_in_scope)
4680     {
4681       single_defuse_cycle = true;
4682       epilog_copies = 1;
4683     }
4684   else
4685     epilog_copies = ncopies;
4686
4687   prev_stmt_info = NULL;
4688   prev_phi_info = NULL;
4689   if (slp_node)
4690     {
4691       vec_num = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node);
4692       gcc_assert (TYPE_VECTOR_SUBPARTS (vectype_out) 
4693                   == TYPE_VECTOR_SUBPARTS (vectype_in));
4694     }
4695   else
4696     {
4697       vec_num = 1;
4698       vec_oprnds0 = VEC_alloc (tree, heap, 1);
4699       if (op_type == ternary_op)
4700         vec_oprnds1 = VEC_alloc (tree, heap, 1);
4701     }
4702
4703   phis = VEC_alloc (gimple, heap, vec_num);
4704   vect_defs = VEC_alloc (tree, heap, vec_num);
4705   if (!slp_node)
4706     VEC_quick_push (tree, vect_defs, NULL_TREE);
4707
4708   for (j = 0; j < ncopies; j++)
4709     {
4710       if (j == 0 || !single_defuse_cycle)
4711         {
4712           for (i = 0; i < vec_num; i++)
4713             {
4714               /* Create the reduction-phi that defines the reduction
4715                  operand.  */
4716               new_phi = create_phi_node (vec_dest, loop->header);
4717               set_vinfo_for_stmt (new_phi,
4718                                   new_stmt_vec_info (new_phi, loop_vinfo,
4719                                                      NULL));
4720                if (j == 0 || slp_node)
4721                  VEC_quick_push (gimple, phis, new_phi);
4722             }
4723         }
4724
4725       if (code == COND_EXPR)
4726         {
4727           gcc_assert (!slp_node);
4728           vectorizable_condition (stmt, gsi, vec_stmt, 
4729                                   PHI_RESULT (VEC_index (gimple, phis, 0)), 
4730                                   reduc_index);
4731           /* Multiple types are not supported for condition.  */
4732           break;
4733         }
4734
4735       /* Handle uses.  */
4736       if (j == 0)
4737         {
4738           tree op0, op1 = NULL_TREE;
4739
4740           op0 = ops[!reduc_index];
4741           if (op_type == ternary_op)
4742             {
4743               if (reduc_index == 0)
4744                 op1 = ops[2];
4745               else
4746                 op1 = ops[1];
4747             }
4748
4749           if (slp_node)
4750             vect_get_slp_defs (op0, op1, slp_node, &vec_oprnds0, &vec_oprnds1,
4751                                -1);
4752           else
4753             {
4754               loop_vec_def0 = vect_get_vec_def_for_operand (ops[!reduc_index],
4755                                                             stmt, NULL);
4756               VEC_quick_push (tree, vec_oprnds0, loop_vec_def0);
4757               if (op_type == ternary_op)
4758                {
4759                  loop_vec_def1 = vect_get_vec_def_for_operand (op1, stmt,
4760                                                                NULL);
4761                  VEC_quick_push (tree, vec_oprnds1, loop_vec_def1);
4762                }
4763             }
4764         }
4765       else
4766         {
4767           if (!slp_node)
4768             {
4769               enum vect_def_type dt = vect_unknown_def_type; /* Dummy */
4770               loop_vec_def0 = vect_get_vec_def_for_stmt_copy (dt, loop_vec_def0);
4771               VEC_replace (tree, vec_oprnds0, 0, loop_vec_def0);
4772               if (op_type == ternary_op)
4773                 {
4774                   loop_vec_def1 = vect_get_vec_def_for_stmt_copy (dt,
4775                                                                 loop_vec_def1);
4776                   VEC_replace (tree, vec_oprnds1, 0, loop_vec_def1);
4777                 }
4778             }
4779
4780           if (single_defuse_cycle)
4781             reduc_def = gimple_assign_lhs (new_stmt);
4782
4783           STMT_VINFO_RELATED_STMT (prev_phi_info) = new_phi;
4784         }
4785
4786       FOR_EACH_VEC_ELT (tree, vec_oprnds0, i, def0)
4787         {
4788           if (slp_node)
4789             reduc_def = PHI_RESULT (VEC_index (gimple, phis, i));
4790           else
4791             {
4792               if (!single_defuse_cycle || j == 0)
4793                 reduc_def = PHI_RESULT (new_phi);
4794             }
4795
4796           def1 = ((op_type == ternary_op)
4797                   ? VEC_index (tree, vec_oprnds1, i) : NULL);
4798           if (op_type == binary_op)
4799             {
4800               if (reduc_index == 0)
4801                 expr = build2 (code, vectype_out, reduc_def, def0);
4802               else
4803                 expr = build2 (code, vectype_out, def0, reduc_def);
4804             }
4805           else
4806             {
4807               if (reduc_index == 0)
4808                 expr = build3 (code, vectype_out, reduc_def, def0, def1);
4809               else
4810                 {
4811                   if (reduc_index == 1)
4812                     expr = build3 (code, vectype_out, def0, reduc_def, def1);
4813                   else
4814                     expr = build3 (code, vectype_out, def0, def1, reduc_def);
4815                 }
4816             }
4817
4818           new_stmt = gimple_build_assign (vec_dest, expr);
4819           new_temp = make_ssa_name (vec_dest, new_stmt);
4820           gimple_assign_set_lhs (new_stmt, new_temp);
4821           vect_finish_stmt_generation (stmt, new_stmt, gsi);
4822
4823           if (slp_node)
4824             {
4825               VEC_quick_push (gimple, SLP_TREE_VEC_STMTS (slp_node), new_stmt);
4826               VEC_quick_push (tree, vect_defs, new_temp);
4827             }
4828           else
4829             VEC_replace (tree, vect_defs, 0, new_temp);
4830         }
4831
4832       if (slp_node)
4833         continue;
4834
4835       if (j == 0)
4836         STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt;
4837       else
4838         STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt;
4839
4840       prev_stmt_info = vinfo_for_stmt (new_stmt);
4841       prev_phi_info = vinfo_for_stmt (new_phi);
4842     }
4843
4844   /* Finalize the reduction-phi (set its arguments) and create the
4845      epilog reduction code.  */
4846   if ((!single_defuse_cycle || code == COND_EXPR) && !slp_node)
4847     {
4848       new_temp = gimple_assign_lhs (*vec_stmt);
4849       VEC_replace (tree, vect_defs, 0, new_temp);
4850     }
4851
4852   vect_create_epilog_for_reduction (vect_defs, stmt, epilog_copies,
4853                                     epilog_reduc_code, phis, reduc_index,
4854                                     double_reduc, slp_node);
4855
4856   VEC_free (gimple, heap, phis);
4857   VEC_free (tree, heap, vec_oprnds0);
4858   if (vec_oprnds1)
4859     VEC_free (tree, heap, vec_oprnds1);
4860
4861   return true;
4862 }
4863
4864 /* Function vect_min_worthwhile_factor.
4865
4866    For a loop where we could vectorize the operation indicated by CODE,
4867    return the minimum vectorization factor that makes it worthwhile
4868    to use generic vectors.  */
4869 int
4870 vect_min_worthwhile_factor (enum tree_code code)
4871 {
4872   switch (code)
4873     {
4874     case PLUS_EXPR:
4875     case MINUS_EXPR:
4876     case NEGATE_EXPR:
4877       return 4;
4878
4879     case BIT_AND_EXPR:
4880     case BIT_IOR_EXPR:
4881     case BIT_XOR_EXPR:
4882     case BIT_NOT_EXPR:
4883       return 2;
4884
4885     default:
4886       return INT_MAX;
4887     }
4888 }
4889
4890
4891 /* Function vectorizable_induction
4892
4893    Check if PHI performs an induction computation that can be vectorized.
4894    If VEC_STMT is also passed, vectorize the induction PHI: create a vectorized
4895    phi to replace it, put it in VEC_STMT, and add it to the same basic block.
4896    Return FALSE if not a vectorizable STMT, TRUE otherwise.  */
4897
4898 bool
4899 vectorizable_induction (gimple phi, gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED,
4900                         gimple *vec_stmt)
4901 {
4902   stmt_vec_info stmt_info = vinfo_for_stmt (phi);
4903   tree vectype = STMT_VINFO_VECTYPE (stmt_info);
4904   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
4905   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
4906   int nunits = TYPE_VECTOR_SUBPARTS (vectype);
4907   int ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits;
4908   tree vec_def;
4909
4910   gcc_assert (ncopies >= 1);
4911   /* FORNOW. This restriction should be relaxed.  */
4912   if (nested_in_vect_loop_p (loop, phi) && ncopies > 1)
4913     {
4914       if (vect_print_dump_info (REPORT_DETAILS))
4915         fprintf (vect_dump, "multiple types in nested loop.");
4916       return false;
4917     }
4918
4919   if (!STMT_VINFO_RELEVANT_P (stmt_info))
4920     return false;
4921
4922   /* FORNOW: SLP not supported.  */
4923   if (STMT_SLP_TYPE (stmt_info))
4924     return false;
4925
4926   gcc_assert (STMT_VINFO_DEF_TYPE (stmt_info) == vect_induction_def);
4927
4928   if (gimple_code (phi) != GIMPLE_PHI)
4929     return false;
4930
4931   if (!vec_stmt) /* transformation not required.  */
4932     {
4933       STMT_VINFO_TYPE (stmt_info) = induc_vec_info_type;
4934       if (vect_print_dump_info (REPORT_DETAILS))
4935         fprintf (vect_dump, "=== vectorizable_induction ===");
4936       vect_model_induction_cost (stmt_info, ncopies);
4937       return true;
4938     }
4939
4940   /** Transform.  **/
4941
4942   if (vect_print_dump_info (REPORT_DETAILS))
4943     fprintf (vect_dump, "transform induction phi.");
4944
4945   vec_def = get_initial_def_for_induction (phi);
4946   *vec_stmt = SSA_NAME_DEF_STMT (vec_def);
4947   return true;
4948 }
4949
4950 /* Function vectorizable_live_operation.
4951
4952    STMT computes a value that is used outside the loop.  Check if
4953    it can be supported.  */
4954
4955 bool
4956 vectorizable_live_operation (gimple stmt,
4957                              gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED,
4958                              gimple *vec_stmt ATTRIBUTE_UNUSED)
4959 {
4960   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
4961   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
4962   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
4963   int i;
4964   int op_type;
4965   tree op;
4966   tree def;
4967   gimple def_stmt;
4968   enum vect_def_type dt;
4969   enum tree_code code;
4970   enum gimple_rhs_class rhs_class;
4971
4972   gcc_assert (STMT_VINFO_LIVE_P (stmt_info));
4973
4974   if (STMT_VINFO_DEF_TYPE (stmt_info) == vect_reduction_def)
4975     return false;
4976
4977   if (!is_gimple_assign (stmt))
4978     return false;
4979
4980   if (TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
4981     return false;
4982
4983   /* FORNOW. CHECKME. */
4984   if (nested_in_vect_loop_p (loop, stmt))
4985     return false;
4986
4987   code = gimple_assign_rhs_code (stmt);
4988   op_type = TREE_CODE_LENGTH (code);
4989   rhs_class = get_gimple_rhs_class (code);
4990   gcc_assert (rhs_class != GIMPLE_UNARY_RHS || op_type == unary_op);
4991   gcc_assert (rhs_class != GIMPLE_BINARY_RHS || op_type == binary_op);
4992
4993   /* FORNOW: support only if all uses are invariant.  This means
4994      that the scalar operations can remain in place, unvectorized.
4995      The original last scalar value that they compute will be used.  */
4996
4997   for (i = 0; i < op_type; i++)
4998     {
4999       if (rhs_class == GIMPLE_SINGLE_RHS)
5000         op = TREE_OPERAND (gimple_op (stmt, 1), i);
5001       else
5002         op = gimple_op (stmt, i + 1);
5003       if (op
5004           && !vect_is_simple_use (op, loop_vinfo, NULL, &def_stmt, &def, &dt))
5005         {
5006           if (vect_print_dump_info (REPORT_DETAILS))
5007             fprintf (vect_dump, "use not simple.");
5008           return false;
5009         }
5010
5011       if (dt != vect_external_def && dt != vect_constant_def)
5012         return false;
5013     }
5014
5015   /* No transformation is required for the cases we currently support.  */
5016   return true;
5017 }
5018
5019 /* Kill any debug uses outside LOOP of SSA names defined in STMT.  */
5020
5021 static void
5022 vect_loop_kill_debug_uses (struct loop *loop, gimple stmt)
5023 {
5024   ssa_op_iter op_iter;
5025   imm_use_iterator imm_iter;
5026   def_operand_p def_p;
5027   gimple ustmt;
5028
5029   FOR_EACH_PHI_OR_STMT_DEF (def_p, stmt, op_iter, SSA_OP_DEF)
5030     {
5031       FOR_EACH_IMM_USE_STMT (ustmt, imm_iter, DEF_FROM_PTR (def_p))
5032         {
5033           basic_block bb;
5034
5035           if (!is_gimple_debug (ustmt))
5036             continue;
5037
5038           bb = gimple_bb (ustmt);
5039
5040           if (!flow_bb_inside_loop_p (loop, bb))
5041             {
5042               if (gimple_debug_bind_p (ustmt))
5043                 {
5044                   if (vect_print_dump_info (REPORT_DETAILS))
5045                     fprintf (vect_dump, "killing debug use");
5046
5047                   gimple_debug_bind_reset_value (ustmt);
5048                   update_stmt (ustmt);
5049                 }
5050               else
5051                 gcc_unreachable ();
5052             }
5053         }
5054     }
5055 }
5056
5057 /* Function vect_transform_loop.
5058
5059    The analysis phase has determined that the loop is vectorizable.
5060    Vectorize the loop - created vectorized stmts to replace the scalar
5061    stmts in the loop, and update the loop exit condition.  */
5062
5063 void
5064 vect_transform_loop (loop_vec_info loop_vinfo)
5065 {
5066   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
5067   basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
5068   int nbbs = loop->num_nodes;
5069   gimple_stmt_iterator si;
5070   int i;
5071   tree ratio = NULL;
5072   int vectorization_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
5073   bool strided_store;
5074   bool slp_scheduled = false;
5075   unsigned int nunits;
5076   tree cond_expr = NULL_TREE;
5077   gimple_seq cond_expr_stmt_list = NULL;
5078   bool do_peeling_for_loop_bound;
5079   gimple stmt, pattern_stmt;
5080   bool transform_pattern_stmt = false;
5081
5082   if (vect_print_dump_info (REPORT_DETAILS))
5083     fprintf (vect_dump, "=== vec_transform_loop ===");
5084
5085   /* Peel the loop if there are data refs with unknown alignment.
5086      Only one data ref with unknown store is allowed.  */
5087
5088   if (LOOP_PEELING_FOR_ALIGNMENT (loop_vinfo))
5089     vect_do_peeling_for_alignment (loop_vinfo);
5090
5091   do_peeling_for_loop_bound
5092     = (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
5093        || (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
5094            && LOOP_VINFO_INT_NITERS (loop_vinfo) % vectorization_factor != 0)
5095        || LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo));
5096
5097   if (LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT (loop_vinfo)
5098       || LOOP_REQUIRES_VERSIONING_FOR_ALIAS (loop_vinfo))
5099     vect_loop_versioning (loop_vinfo,
5100                           !do_peeling_for_loop_bound,
5101                           &cond_expr, &cond_expr_stmt_list);
5102
5103   /* If the loop has a symbolic number of iterations 'n' (i.e. it's not a
5104      compile time constant), or it is a constant that doesn't divide by the
5105      vectorization factor, then an epilog loop needs to be created.
5106      We therefore duplicate the loop: the original loop will be vectorized,
5107      and will compute the first (n/VF) iterations.  The second copy of the loop
5108      will remain scalar and will compute the remaining (n%VF) iterations.
5109      (VF is the vectorization factor).  */
5110
5111   if (do_peeling_for_loop_bound)
5112     vect_do_peeling_for_loop_bound (loop_vinfo, &ratio,
5113                                     cond_expr, cond_expr_stmt_list);
5114   else
5115     ratio = build_int_cst (TREE_TYPE (LOOP_VINFO_NITERS (loop_vinfo)),
5116                 LOOP_VINFO_INT_NITERS (loop_vinfo) / vectorization_factor);
5117
5118   /* 1) Make sure the loop header has exactly two entries
5119      2) Make sure we have a preheader basic block.  */
5120
5121   gcc_assert (EDGE_COUNT (loop->header->preds) == 2);
5122
5123   split_edge (loop_preheader_edge (loop));
5124
5125   /* FORNOW: the vectorizer supports only loops which body consist
5126      of one basic block (header + empty latch). When the vectorizer will
5127      support more involved loop forms, the order by which the BBs are
5128      traversed need to be reconsidered.  */
5129
5130   for (i = 0; i < nbbs; i++)
5131     {
5132       basic_block bb = bbs[i];
5133       stmt_vec_info stmt_info;
5134       gimple phi;
5135
5136       for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
5137         {
5138           phi = gsi_stmt (si);
5139           if (vect_print_dump_info (REPORT_DETAILS))
5140             {
5141               fprintf (vect_dump, "------>vectorizing phi: ");
5142               print_gimple_stmt (vect_dump, phi, 0, TDF_SLIM);
5143             }
5144           stmt_info = vinfo_for_stmt (phi);
5145           if (!stmt_info)
5146             continue;
5147
5148           if (MAY_HAVE_DEBUG_STMTS && !STMT_VINFO_LIVE_P (stmt_info))
5149             vect_loop_kill_debug_uses (loop, phi);
5150
5151           if (!STMT_VINFO_RELEVANT_P (stmt_info)
5152               && !STMT_VINFO_LIVE_P (stmt_info))
5153             continue;
5154
5155           if ((TYPE_VECTOR_SUBPARTS (STMT_VINFO_VECTYPE (stmt_info))
5156                 != (unsigned HOST_WIDE_INT) vectorization_factor)
5157               && vect_print_dump_info (REPORT_DETAILS))
5158             fprintf (vect_dump, "multiple-types.");
5159
5160           if (STMT_VINFO_DEF_TYPE (stmt_info) == vect_induction_def)
5161             {
5162               if (vect_print_dump_info (REPORT_DETAILS))
5163                 fprintf (vect_dump, "transform phi.");
5164               vect_transform_stmt (phi, NULL, NULL, NULL, NULL);
5165             }
5166         }
5167
5168       pattern_stmt = NULL;
5169       for (si = gsi_start_bb (bb); !gsi_end_p (si) || transform_pattern_stmt;)
5170         {
5171           bool is_store;
5172
5173           if (transform_pattern_stmt)
5174             {
5175               stmt = pattern_stmt;
5176               transform_pattern_stmt = false;
5177             }
5178           else
5179             stmt = gsi_stmt (si);
5180
5181           if (vect_print_dump_info (REPORT_DETAILS))
5182             {
5183               fprintf (vect_dump, "------>vectorizing statement: ");
5184               print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
5185             }
5186
5187           stmt_info = vinfo_for_stmt (stmt);
5188
5189           /* vector stmts created in the outer-loop during vectorization of
5190              stmts in an inner-loop may not have a stmt_info, and do not
5191              need to be vectorized.  */
5192           if (!stmt_info)
5193             {
5194               gsi_next (&si);
5195               continue;
5196             }
5197
5198           if (MAY_HAVE_DEBUG_STMTS && !STMT_VINFO_LIVE_P (stmt_info))
5199             vect_loop_kill_debug_uses (loop, stmt);
5200
5201           if (!STMT_VINFO_RELEVANT_P (stmt_info)
5202               && !STMT_VINFO_LIVE_P (stmt_info))
5203             {
5204               if (STMT_VINFO_IN_PATTERN_P (stmt_info)
5205                   && (pattern_stmt = STMT_VINFO_RELATED_STMT (stmt_info))
5206                   && (STMT_VINFO_RELEVANT_P (vinfo_for_stmt (pattern_stmt))
5207                       || STMT_VINFO_LIVE_P (vinfo_for_stmt (pattern_stmt))))
5208                 {
5209                   stmt = pattern_stmt;
5210                   stmt_info = vinfo_for_stmt (stmt);
5211                 }
5212               else
5213                 {
5214                   gsi_next (&si);
5215                   continue;
5216                 }
5217             }
5218           else if (STMT_VINFO_IN_PATTERN_P (stmt_info)
5219                    && (pattern_stmt = STMT_VINFO_RELATED_STMT (stmt_info))
5220                    && (STMT_VINFO_RELEVANT_P (vinfo_for_stmt (pattern_stmt))
5221                        || STMT_VINFO_LIVE_P (vinfo_for_stmt (pattern_stmt))))
5222             transform_pattern_stmt = true;
5223
5224           gcc_assert (STMT_VINFO_VECTYPE (stmt_info));
5225           nunits = (unsigned int) TYPE_VECTOR_SUBPARTS (
5226                                                STMT_VINFO_VECTYPE (stmt_info));
5227           if (!STMT_SLP_TYPE (stmt_info)
5228               && nunits != (unsigned int) vectorization_factor
5229               && vect_print_dump_info (REPORT_DETAILS))
5230             /* For SLP VF is set according to unrolling factor, and not to
5231                vector size, hence for SLP this print is not valid.  */
5232             fprintf (vect_dump, "multiple-types.");
5233
5234           /* SLP. Schedule all the SLP instances when the first SLP stmt is
5235              reached.  */
5236           if (STMT_SLP_TYPE (stmt_info))
5237             {
5238               if (!slp_scheduled)
5239                 {
5240                   slp_scheduled = true;
5241
5242                   if (vect_print_dump_info (REPORT_DETAILS))
5243                     fprintf (vect_dump, "=== scheduling SLP instances ===");
5244
5245                   vect_schedule_slp (loop_vinfo, NULL);
5246                 }
5247
5248               /* Hybrid SLP stmts must be vectorized in addition to SLP.  */
5249               if (!vinfo_for_stmt (stmt) || PURE_SLP_STMT (stmt_info))
5250                 {
5251                   if (!transform_pattern_stmt)
5252                     gsi_next (&si);
5253                   continue;
5254                 }
5255             }
5256
5257           /* -------- vectorize statement ------------ */
5258           if (vect_print_dump_info (REPORT_DETAILS))
5259             fprintf (vect_dump, "transform statement.");
5260
5261           strided_store = false;
5262           is_store = vect_transform_stmt (stmt, &si, &strided_store, NULL, NULL);
5263           if (is_store)
5264             {
5265               if (STMT_VINFO_STRIDED_ACCESS (stmt_info))
5266                 {
5267                   /* Interleaving. If IS_STORE is TRUE, the vectorization of the
5268                      interleaving chain was completed - free all the stores in
5269                      the chain.  */
5270                   vect_remove_stores (GROUP_FIRST_ELEMENT (stmt_info));
5271                   gsi_remove (&si, true);
5272                   continue;
5273                 }
5274               else
5275                 {
5276                   /* Free the attached stmt_vec_info and remove the stmt.  */
5277                   free_stmt_vec_info (stmt);
5278                   gsi_remove (&si, true);
5279                   continue;
5280                 }
5281             }
5282
5283           if (!transform_pattern_stmt)
5284             gsi_next (&si);
5285         }                       /* stmts in BB */
5286     }                           /* BBs in loop */
5287
5288   slpeel_make_loop_iterate_ntimes (loop, ratio);
5289
5290   /* The memory tags and pointers in vectorized statements need to
5291      have their SSA forms updated.  FIXME, why can't this be delayed
5292      until all the loops have been transformed?  */
5293   update_ssa (TODO_update_ssa);
5294
5295   if (vect_print_dump_info (REPORT_VECTORIZED_LOCATIONS))
5296     fprintf (vect_dump, "LOOP VECTORIZED.");
5297   if (loop->inner && vect_print_dump_info (REPORT_VECTORIZED_LOCATIONS))
5298     fprintf (vect_dump, "OUTER LOOP VECTORIZED.");
5299 }