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