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