OSDN Git Service

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