OSDN Git Service

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