OSDN Git Service

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