OSDN Git Service

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