OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / tree-vect-stmts.c
1 /* Statement Analysis and Transformation for Vectorization
2    Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
3    Free Software Foundation, Inc.
4    Contributed by Dorit Naishlos <dorit@il.ibm.com>
5    and Ira Rosen <irar@il.ibm.com>
6
7 This file is part of GCC.
8
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
12 version.
13
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17 for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3.  If not see
21 <http://www.gnu.org/licenses/>.  */
22
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tm.h"
27 #include "ggc.h"
28 #include "tree.h"
29 #include "target.h"
30 #include "basic-block.h"
31 #include "tree-pretty-print.h"
32 #include "gimple-pretty-print.h"
33 #include "tree-flow.h"
34 #include "tree-dump.h"
35 #include "cfgloop.h"
36 #include "cfglayout.h"
37 #include "expr.h"
38 #include "recog.h"
39 #include "optabs.h"
40 #include "diagnostic-core.h"
41 #include "tree-vectorizer.h"
42 #include "langhooks.h"
43
44
45 /* Utility functions used by vect_mark_stmts_to_be_vectorized.  */
46
47 /* Function vect_mark_relevant.
48
49    Mark STMT as "relevant for vectorization" and add it to WORKLIST.  */
50
51 static void
52 vect_mark_relevant (VEC(gimple,heap) **worklist, gimple stmt,
53                     enum vect_relevant relevant, bool live_p)
54 {
55   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
56   enum vect_relevant save_relevant = STMT_VINFO_RELEVANT (stmt_info);
57   bool save_live_p = STMT_VINFO_LIVE_P (stmt_info);
58
59   if (vect_print_dump_info (REPORT_DETAILS))
60     fprintf (vect_dump, "mark relevant %d, live %d.", relevant, live_p);
61
62   if (STMT_VINFO_IN_PATTERN_P (stmt_info))
63     {
64       gimple pattern_stmt;
65
66       /* This is the last stmt in a sequence that was detected as a
67          pattern that can potentially be vectorized.  Don't mark the stmt
68          as relevant/live because it's not going to be vectorized.
69          Instead mark the pattern-stmt that replaces it.  */
70
71       pattern_stmt = STMT_VINFO_RELATED_STMT (stmt_info);
72
73       if (vect_print_dump_info (REPORT_DETAILS))
74         fprintf (vect_dump, "last stmt in pattern. don't mark relevant/live.");
75       stmt_info = vinfo_for_stmt (pattern_stmt);
76       gcc_assert (STMT_VINFO_RELATED_STMT (stmt_info) == stmt);
77       save_relevant = STMT_VINFO_RELEVANT (stmt_info);
78       save_live_p = STMT_VINFO_LIVE_P (stmt_info);
79       stmt = pattern_stmt;
80     }
81
82   STMT_VINFO_LIVE_P (stmt_info) |= live_p;
83   if (relevant > STMT_VINFO_RELEVANT (stmt_info))
84     STMT_VINFO_RELEVANT (stmt_info) = relevant;
85
86   if (STMT_VINFO_RELEVANT (stmt_info) == save_relevant
87       && STMT_VINFO_LIVE_P (stmt_info) == save_live_p)
88     {
89       if (vect_print_dump_info (REPORT_DETAILS))
90         fprintf (vect_dump, "already marked relevant/live.");
91       return;
92     }
93
94   VEC_safe_push (gimple, heap, *worklist, stmt);
95 }
96
97
98 /* Function vect_stmt_relevant_p.
99
100    Return true if STMT in loop that is represented by LOOP_VINFO is
101    "relevant for vectorization".
102
103    A stmt is considered "relevant for vectorization" if:
104    - it has uses outside the loop.
105    - it has vdefs (it alters memory).
106    - control stmts in the loop (except for the exit condition).
107
108    CHECKME: what other side effects would the vectorizer allow?  */
109
110 static bool
111 vect_stmt_relevant_p (gimple stmt, loop_vec_info loop_vinfo,
112                       enum vect_relevant *relevant, bool *live_p)
113 {
114   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
115   ssa_op_iter op_iter;
116   imm_use_iterator imm_iter;
117   use_operand_p use_p;
118   def_operand_p def_p;
119
120   *relevant = vect_unused_in_scope;
121   *live_p = false;
122
123   /* cond stmt other than loop exit cond.  */
124   if (is_ctrl_stmt (stmt)
125       && STMT_VINFO_TYPE (vinfo_for_stmt (stmt))
126          != loop_exit_ctrl_vec_info_type)
127     *relevant = vect_used_in_scope;
128
129   /* changing memory.  */
130   if (gimple_code (stmt) != GIMPLE_PHI)
131     if (gimple_vdef (stmt))
132       {
133         if (vect_print_dump_info (REPORT_DETAILS))
134           fprintf (vect_dump, "vec_stmt_relevant_p: stmt has vdefs.");
135         *relevant = vect_used_in_scope;
136       }
137
138   /* uses outside the loop.  */
139   FOR_EACH_PHI_OR_STMT_DEF (def_p, stmt, op_iter, SSA_OP_DEF)
140     {
141       FOR_EACH_IMM_USE_FAST (use_p, imm_iter, DEF_FROM_PTR (def_p))
142         {
143           basic_block bb = gimple_bb (USE_STMT (use_p));
144           if (!flow_bb_inside_loop_p (loop, bb))
145             {
146               if (vect_print_dump_info (REPORT_DETAILS))
147                 fprintf (vect_dump, "vec_stmt_relevant_p: used out of loop.");
148
149               if (is_gimple_debug (USE_STMT (use_p)))
150                 continue;
151
152               /* We expect all such uses to be in the loop exit phis
153                  (because of loop closed form)   */
154               gcc_assert (gimple_code (USE_STMT (use_p)) == GIMPLE_PHI);
155               gcc_assert (bb == single_exit (loop)->dest);
156
157               *live_p = true;
158             }
159         }
160     }
161
162   return (*live_p || *relevant);
163 }
164
165
166 /* Function exist_non_indexing_operands_for_use_p
167
168    USE is one of the uses attached to STMT.  Check if USE is
169    used in STMT for anything other than indexing an array.  */
170
171 static bool
172 exist_non_indexing_operands_for_use_p (tree use, gimple stmt)
173 {
174   tree operand;
175   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
176
177   /* USE corresponds to some operand in STMT.  If there is no data
178      reference in STMT, then any operand that corresponds to USE
179      is not indexing an array.  */
180   if (!STMT_VINFO_DATA_REF (stmt_info))
181     return true;
182
183   /* STMT has a data_ref. FORNOW this means that its of one of
184      the following forms:
185      -1- ARRAY_REF = var
186      -2- var = ARRAY_REF
187      (This should have been verified in analyze_data_refs).
188
189      'var' in the second case corresponds to a def, not a use,
190      so USE cannot correspond to any operands that are not used
191      for array indexing.
192
193      Therefore, all we need to check is if STMT falls into the
194      first case, and whether var corresponds to USE.  */
195
196   if (!gimple_assign_copy_p (stmt))
197     return false;
198   if (TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME)
199     return false;
200   operand = gimple_assign_rhs1 (stmt);
201   if (TREE_CODE (operand) != SSA_NAME)
202     return false;
203
204   if (operand == use)
205     return true;
206
207   return false;
208 }
209
210
211 /*
212    Function process_use.
213
214    Inputs:
215    - a USE in STMT in a loop represented by LOOP_VINFO
216    - LIVE_P, RELEVANT - enum values to be set in the STMT_VINFO of the stmt
217      that defined USE.  This is done by calling mark_relevant and passing it
218      the WORKLIST (to add DEF_STMT to the WORKLIST in case it is relevant).
219
220    Outputs:
221    Generally, LIVE_P and RELEVANT are used to define the liveness and
222    relevance info of the DEF_STMT of this USE:
223        STMT_VINFO_LIVE_P (DEF_STMT_info) <-- live_p
224        STMT_VINFO_RELEVANT (DEF_STMT_info) <-- relevant
225    Exceptions:
226    - case 1: If USE is used only for address computations (e.g. array indexing),
227    which does not need to be directly vectorized, then the liveness/relevance
228    of the respective DEF_STMT is left unchanged.
229    - case 2: If STMT is a reduction phi and DEF_STMT is a reduction stmt, we
230    skip DEF_STMT cause it had already been processed.
231    - case 3: If DEF_STMT and STMT are in different nests, then  "relevant" will
232    be modified accordingly.
233
234    Return true if everything is as expected. Return false otherwise.  */
235
236 static bool
237 process_use (gimple stmt, tree use, loop_vec_info loop_vinfo, bool live_p,
238              enum vect_relevant relevant, VEC(gimple,heap) **worklist)
239 {
240   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
241   stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt);
242   stmt_vec_info dstmt_vinfo;
243   basic_block bb, def_bb;
244   tree def;
245   gimple def_stmt;
246   enum vect_def_type dt;
247
248   /* case 1: we are only interested in uses that need to be vectorized.  Uses
249      that are used for address computation are not considered relevant.  */
250   if (!exist_non_indexing_operands_for_use_p (use, stmt))
251      return true;
252
253   if (!vect_is_simple_use (use, loop_vinfo, NULL, &def_stmt, &def, &dt))
254     {
255       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
256         fprintf (vect_dump, "not vectorized: unsupported use in stmt.");
257       return false;
258     }
259
260   if (!def_stmt || gimple_nop_p (def_stmt))
261     return true;
262
263   def_bb = gimple_bb (def_stmt);
264   if (!flow_bb_inside_loop_p (loop, def_bb))
265     {
266       if (vect_print_dump_info (REPORT_DETAILS))
267         fprintf (vect_dump, "def_stmt is out of loop.");
268       return true;
269     }
270
271   /* case 2: A reduction phi (STMT) defined by a reduction stmt (DEF_STMT).
272      DEF_STMT must have already been processed, because this should be the
273      only way that STMT, which is a reduction-phi, was put in the worklist,
274      as there should be no other uses for DEF_STMT in the loop.  So we just
275      check that everything is as expected, and we are done.  */
276   dstmt_vinfo = vinfo_for_stmt (def_stmt);
277   bb = gimple_bb (stmt);
278   if (gimple_code (stmt) == GIMPLE_PHI
279       && STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_reduction_def
280       && gimple_code (def_stmt) != GIMPLE_PHI
281       && STMT_VINFO_DEF_TYPE (dstmt_vinfo) == vect_reduction_def
282       && bb->loop_father == def_bb->loop_father)
283     {
284       if (vect_print_dump_info (REPORT_DETAILS))
285         fprintf (vect_dump, "reduc-stmt defining reduc-phi in the same nest.");
286       if (STMT_VINFO_IN_PATTERN_P (dstmt_vinfo))
287         dstmt_vinfo = vinfo_for_stmt (STMT_VINFO_RELATED_STMT (dstmt_vinfo));
288       gcc_assert (STMT_VINFO_RELEVANT (dstmt_vinfo) < vect_used_by_reduction);
289       gcc_assert (STMT_VINFO_LIVE_P (dstmt_vinfo)
290                   || STMT_VINFO_RELEVANT (dstmt_vinfo) > vect_unused_in_scope);
291       return true;
292     }
293
294   /* case 3a: outer-loop stmt defining an inner-loop stmt:
295         outer-loop-header-bb:
296                 d = def_stmt
297         inner-loop:
298                 stmt # use (d)
299         outer-loop-tail-bb:
300                 ...               */
301   if (flow_loop_nested_p (def_bb->loop_father, bb->loop_father))
302     {
303       if (vect_print_dump_info (REPORT_DETAILS))
304         fprintf (vect_dump, "outer-loop def-stmt defining inner-loop stmt.");
305
306       switch (relevant)
307         {
308         case vect_unused_in_scope:
309           relevant = (STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_nested_cycle) ?
310                       vect_used_in_scope : vect_unused_in_scope;
311           break;
312
313         case vect_used_in_outer_by_reduction:
314           gcc_assert (STMT_VINFO_DEF_TYPE (stmt_vinfo) != vect_reduction_def);
315           relevant = vect_used_by_reduction;
316           break;
317
318         case vect_used_in_outer:
319           gcc_assert (STMT_VINFO_DEF_TYPE (stmt_vinfo) != vect_reduction_def);
320           relevant = vect_used_in_scope;
321           break;
322
323         case vect_used_in_scope:
324           break;
325
326         default:
327           gcc_unreachable ();
328         }
329     }
330
331   /* case 3b: inner-loop stmt defining an outer-loop stmt:
332         outer-loop-header-bb:
333                 ...
334         inner-loop:
335                 d = def_stmt
336         outer-loop-tail-bb (or outer-loop-exit-bb in double reduction):
337                 stmt # use (d)          */
338   else if (flow_loop_nested_p (bb->loop_father, def_bb->loop_father))
339     {
340       if (vect_print_dump_info (REPORT_DETAILS))
341         fprintf (vect_dump, "inner-loop def-stmt defining outer-loop stmt.");
342
343       switch (relevant)
344         {
345         case vect_unused_in_scope:
346           relevant = (STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_reduction_def
347             || STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_double_reduction_def) ?
348                       vect_used_in_outer_by_reduction : vect_unused_in_scope;
349           break;
350
351         case vect_used_by_reduction:
352           relevant = vect_used_in_outer_by_reduction;
353           break;
354
355         case vect_used_in_scope:
356           relevant = vect_used_in_outer;
357           break;
358
359         default:
360           gcc_unreachable ();
361         }
362     }
363
364   vect_mark_relevant (worklist, def_stmt, relevant, live_p);
365   return true;
366 }
367
368
369 /* Function vect_mark_stmts_to_be_vectorized.
370
371    Not all stmts in the loop need to be vectorized. For example:
372
373      for i...
374        for j...
375    1.    T0 = i + j
376    2.    T1 = a[T0]
377
378    3.    j = j + 1
379
380    Stmt 1 and 3 do not need to be vectorized, because loop control and
381    addressing of vectorized data-refs are handled differently.
382
383    This pass detects such stmts.  */
384
385 bool
386 vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo)
387 {
388   VEC(gimple,heap) *worklist;
389   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
390   basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
391   unsigned int nbbs = loop->num_nodes;
392   gimple_stmt_iterator si;
393   gimple stmt;
394   unsigned int i;
395   stmt_vec_info stmt_vinfo;
396   basic_block bb;
397   gimple phi;
398   bool live_p;
399   enum vect_relevant relevant, tmp_relevant;
400   enum vect_def_type def_type;
401
402   if (vect_print_dump_info (REPORT_DETAILS))
403     fprintf (vect_dump, "=== vect_mark_stmts_to_be_vectorized ===");
404
405   worklist = VEC_alloc (gimple, heap, 64);
406
407   /* 1. Init worklist.  */
408   for (i = 0; i < nbbs; i++)
409     {
410       bb = bbs[i];
411       for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
412         {
413           phi = gsi_stmt (si);
414           if (vect_print_dump_info (REPORT_DETAILS))
415             {
416               fprintf (vect_dump, "init: phi relevant? ");
417               print_gimple_stmt (vect_dump, phi, 0, TDF_SLIM);
418             }
419
420           if (vect_stmt_relevant_p (phi, loop_vinfo, &relevant, &live_p))
421             vect_mark_relevant (&worklist, phi, relevant, live_p);
422         }
423       for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
424         {
425           stmt = gsi_stmt (si);
426           if (vect_print_dump_info (REPORT_DETAILS))
427             {
428               fprintf (vect_dump, "init: stmt relevant? ");
429               print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
430             }
431
432           if (vect_stmt_relevant_p (stmt, loop_vinfo, &relevant, &live_p))
433             vect_mark_relevant (&worklist, stmt, relevant, live_p);
434         }
435     }
436
437   /* 2. Process_worklist */
438   while (VEC_length (gimple, worklist) > 0)
439     {
440       use_operand_p use_p;
441       ssa_op_iter iter;
442
443       stmt = VEC_pop (gimple, worklist);
444       if (vect_print_dump_info (REPORT_DETAILS))
445         {
446           fprintf (vect_dump, "worklist: examine stmt: ");
447           print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
448         }
449
450       /* Examine the USEs of STMT. For each USE, mark the stmt that defines it
451          (DEF_STMT) as relevant/irrelevant and live/dead according to the
452          liveness and relevance properties of STMT.  */
453       stmt_vinfo = vinfo_for_stmt (stmt);
454       relevant = STMT_VINFO_RELEVANT (stmt_vinfo);
455       live_p = STMT_VINFO_LIVE_P (stmt_vinfo);
456
457       /* Generally, the liveness and relevance properties of STMT are
458          propagated as is to the DEF_STMTs of its USEs:
459           live_p <-- STMT_VINFO_LIVE_P (STMT_VINFO)
460           relevant <-- STMT_VINFO_RELEVANT (STMT_VINFO)
461
462          One exception is when STMT has been identified as defining a reduction
463          variable; in this case we set the liveness/relevance as follows:
464            live_p = false
465            relevant = vect_used_by_reduction
466          This is because we distinguish between two kinds of relevant stmts -
467          those that are used by a reduction computation, and those that are
468          (also) used by a regular computation.  This allows us later on to
469          identify stmts that are used solely by a reduction, and therefore the
470          order of the results that they produce does not have to be kept.  */
471
472       def_type = STMT_VINFO_DEF_TYPE (stmt_vinfo);
473       tmp_relevant = relevant;
474       switch (def_type)
475         {
476           case vect_reduction_def:
477             switch (tmp_relevant)
478               {
479                 case vect_unused_in_scope:
480                   relevant = vect_used_by_reduction;
481                   break;
482
483                 case vect_used_by_reduction:
484                   if (gimple_code (stmt) == GIMPLE_PHI)
485                     break;
486                   /* fall through */
487
488                 default:
489                   if (vect_print_dump_info (REPORT_DETAILS))
490                     fprintf (vect_dump, "unsupported use of reduction.");
491
492                   VEC_free (gimple, heap, worklist);
493                   return false;
494               }
495
496             live_p = false;
497             break;
498
499           case vect_nested_cycle:
500             if (tmp_relevant != vect_unused_in_scope
501                 && tmp_relevant != vect_used_in_outer_by_reduction
502                 && tmp_relevant != vect_used_in_outer)
503               {
504                 if (vect_print_dump_info (REPORT_DETAILS))
505                   fprintf (vect_dump, "unsupported use of nested cycle.");
506
507                 VEC_free (gimple, heap, worklist);
508                 return false;
509               }
510
511             live_p = false;
512             break;
513
514           case vect_double_reduction_def:
515             if (tmp_relevant != vect_unused_in_scope
516                 && tmp_relevant != vect_used_by_reduction)
517               {
518                 if (vect_print_dump_info (REPORT_DETAILS))
519                   fprintf (vect_dump, "unsupported use of double reduction.");
520
521                 VEC_free (gimple, heap, worklist);
522                 return false;
523               }
524
525             live_p = false;
526             break;
527
528           default:
529             break;
530         }
531
532       FOR_EACH_PHI_OR_STMT_USE (use_p, stmt, iter, SSA_OP_USE)
533         {
534           tree op = USE_FROM_PTR (use_p);
535           if (!process_use (stmt, op, loop_vinfo, live_p, relevant, &worklist))
536             {
537               VEC_free (gimple, heap, worklist);
538               return false;
539             }
540         }
541     } /* while worklist */
542
543   VEC_free (gimple, heap, worklist);
544   return true;
545 }
546
547
548 /* Get cost by calling cost target builtin.  */
549
550 static inline
551 int vect_get_stmt_cost (enum vect_cost_for_stmt type_of_cost)
552 {
553   tree dummy_type = NULL;
554   int dummy = 0;
555
556   return targetm.vectorize.builtin_vectorization_cost (type_of_cost,
557                                                        dummy_type, dummy);
558 }
559
560
561 /* Get cost for STMT.  */
562
563 int
564 cost_for_stmt (gimple stmt)
565 {
566   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
567
568   switch (STMT_VINFO_TYPE (stmt_info))
569   {
570   case load_vec_info_type:
571     return vect_get_stmt_cost (scalar_load);
572   case store_vec_info_type:
573     return vect_get_stmt_cost (scalar_store);
574   case op_vec_info_type:
575   case condition_vec_info_type:
576   case assignment_vec_info_type:
577   case reduc_vec_info_type:
578   case induc_vec_info_type:
579   case type_promotion_vec_info_type:
580   case type_demotion_vec_info_type:
581   case type_conversion_vec_info_type:
582   case call_vec_info_type:
583     return vect_get_stmt_cost (scalar_stmt);
584   case undef_vec_info_type:
585   default:
586     gcc_unreachable ();
587   }
588 }
589
590 /* Function vect_model_simple_cost.
591
592    Models cost for simple operations, i.e. those that only emit ncopies of a
593    single op.  Right now, this does not account for multiple insns that could
594    be generated for the single vector op.  We will handle that shortly.  */
595
596 void
597 vect_model_simple_cost (stmt_vec_info stmt_info, int ncopies,
598                         enum vect_def_type *dt, slp_tree slp_node)
599 {
600   int i;
601   int inside_cost = 0, outside_cost = 0;
602
603   /* The SLP costs were already calculated during SLP tree build.  */
604   if (PURE_SLP_STMT (stmt_info))
605     return;
606
607   inside_cost = ncopies * vect_get_stmt_cost (vector_stmt); 
608
609   /* FORNOW: Assuming maximum 2 args per stmts.  */
610   for (i = 0; i < 2; i++)
611     {
612       if (dt[i] == vect_constant_def || dt[i] == vect_external_def)
613         outside_cost += vect_get_stmt_cost (vector_stmt); 
614     }
615
616   if (vect_print_dump_info (REPORT_COST))
617     fprintf (vect_dump, "vect_model_simple_cost: inside_cost = %d, "
618              "outside_cost = %d .", inside_cost, outside_cost);
619
620   /* Set the costs either in STMT_INFO or SLP_NODE (if exists).  */
621   stmt_vinfo_set_inside_of_loop_cost (stmt_info, slp_node, inside_cost);
622   stmt_vinfo_set_outside_of_loop_cost (stmt_info, slp_node, outside_cost);
623 }
624
625
626 /* Model cost for type demotion and promotion operations.  PWR is normally
627    zero for single-step promotions and demotions.  It will be one if 
628    two-step promotion/demotion is required, and so on.  Each additional
629    step doubles the number of instructions required.  */
630
631 static void
632 vect_model_promotion_demotion_cost (stmt_vec_info stmt_info,
633                                     enum vect_def_type *dt, int pwr)
634 {
635   int i, tmp;
636   int inside_cost = 0, outside_cost = 0, single_stmt_cost;
637
638   /* The SLP costs were already calculated during SLP tree build.  */
639   if (PURE_SLP_STMT (stmt_info))
640     return;
641
642   single_stmt_cost = vect_get_stmt_cost (vec_promote_demote);
643   for (i = 0; i < pwr + 1; i++)
644     {
645       tmp = (STMT_VINFO_TYPE (stmt_info) == type_promotion_vec_info_type) ?
646         (i + 1) : i;
647       inside_cost += vect_pow2 (tmp) * single_stmt_cost;
648     }
649
650   /* FORNOW: Assuming maximum 2 args per stmts.  */
651   for (i = 0; i < 2; i++)
652     {
653       if (dt[i] == vect_constant_def || dt[i] == vect_external_def)
654         outside_cost += vect_get_stmt_cost (vector_stmt);
655     }
656
657   if (vect_print_dump_info (REPORT_COST))
658     fprintf (vect_dump, "vect_model_promotion_demotion_cost: inside_cost = %d, "
659              "outside_cost = %d .", inside_cost, outside_cost);
660
661   /* Set the costs in STMT_INFO.  */
662   stmt_vinfo_set_inside_of_loop_cost (stmt_info, NULL, inside_cost);
663   stmt_vinfo_set_outside_of_loop_cost (stmt_info, NULL, outside_cost);
664 }
665
666 /* Function vect_cost_strided_group_size
667
668    For strided load or store, return the group_size only if it is the first
669    load or store of a group, else return 1.  This ensures that group size is
670    only returned once per group.  */
671
672 static int
673 vect_cost_strided_group_size (stmt_vec_info stmt_info)
674 {
675   gimple first_stmt = DR_GROUP_FIRST_DR (stmt_info);
676
677   if (first_stmt == STMT_VINFO_STMT (stmt_info))
678     return DR_GROUP_SIZE (stmt_info);
679
680   return 1;
681 }
682
683
684 /* Function vect_model_store_cost
685
686    Models cost for stores.  In the case of strided accesses, one access
687    has the overhead of the strided access attributed to it.  */
688
689 void
690 vect_model_store_cost (stmt_vec_info stmt_info, int ncopies,
691                        enum vect_def_type dt, slp_tree slp_node)
692 {
693   int group_size;
694   unsigned int inside_cost = 0, outside_cost = 0;
695   struct data_reference *first_dr;
696   gimple first_stmt;
697
698   /* The SLP costs were already calculated during SLP tree build.  */
699   if (PURE_SLP_STMT (stmt_info))
700     return;
701
702   if (dt == vect_constant_def || dt == vect_external_def)
703     outside_cost = vect_get_stmt_cost (scalar_to_vec); 
704
705   /* Strided access?  */
706   if (DR_GROUP_FIRST_DR (stmt_info))
707     {
708       if (slp_node)
709         {
710           first_stmt = VEC_index (gimple, SLP_TREE_SCALAR_STMTS (slp_node), 0);
711           group_size = 1;
712         }
713       else
714         {
715           first_stmt = DR_GROUP_FIRST_DR (stmt_info);
716           group_size = vect_cost_strided_group_size (stmt_info);
717         }
718
719       first_dr = STMT_VINFO_DATA_REF (vinfo_for_stmt (first_stmt));
720     }
721   /* Not a strided access.  */
722   else
723     {
724       group_size = 1;
725       first_dr = STMT_VINFO_DATA_REF (stmt_info);
726     }
727
728   /* Is this an access in a group of stores, which provide strided access?
729      If so, add in the cost of the permutes.  */
730   if (group_size > 1)
731     {
732       /* Uses a high and low interleave operation for each needed permute.  */
733       inside_cost = ncopies * exact_log2(group_size) * group_size
734         * vect_get_stmt_cost (vec_perm);
735
736       if (vect_print_dump_info (REPORT_COST))
737         fprintf (vect_dump, "vect_model_store_cost: strided group_size = %d .",
738                  group_size);
739
740     }
741
742   /* Costs of the stores.  */
743   vect_get_store_cost (first_dr, ncopies, &inside_cost);
744
745   if (vect_print_dump_info (REPORT_COST))
746     fprintf (vect_dump, "vect_model_store_cost: inside_cost = %d, "
747              "outside_cost = %d .", inside_cost, outside_cost);
748
749   /* Set the costs either in STMT_INFO or SLP_NODE (if exists).  */
750   stmt_vinfo_set_inside_of_loop_cost (stmt_info, slp_node, inside_cost);
751   stmt_vinfo_set_outside_of_loop_cost (stmt_info, slp_node, outside_cost);
752 }
753
754
755 /* Calculate cost of DR's memory access.  */
756 void
757 vect_get_store_cost (struct data_reference *dr, int ncopies,
758                      unsigned int *inside_cost)
759 {
760   int alignment_support_scheme = vect_supportable_dr_alignment (dr, false);
761
762   switch (alignment_support_scheme)
763     {
764     case dr_aligned:
765       {
766         *inside_cost += ncopies * vect_get_stmt_cost (vector_store);
767
768         if (vect_print_dump_info (REPORT_COST))
769           fprintf (vect_dump, "vect_model_store_cost: aligned.");
770
771         break;
772       }
773
774     case dr_unaligned_supported:
775       {
776         gimple stmt = DR_STMT (dr);
777         stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
778         tree vectype = STMT_VINFO_VECTYPE (stmt_info);
779
780         /* Here, we assign an additional cost for the unaligned store.  */
781         *inside_cost += ncopies
782           * targetm.vectorize.builtin_vectorization_cost (unaligned_store,
783                                  vectype, DR_MISALIGNMENT (dr));
784
785         if (vect_print_dump_info (REPORT_COST))
786           fprintf (vect_dump, "vect_model_store_cost: unaligned supported by "
787                    "hardware.");
788
789         break;
790       }
791
792     default:
793       gcc_unreachable ();
794     }
795 }
796
797
798 /* Function vect_model_load_cost
799
800    Models cost for loads.  In the case of strided accesses, the last access
801    has the overhead of the strided access attributed to it.  Since unaligned
802    accesses are supported for loads, we also account for the costs of the
803    access scheme chosen.  */
804
805 void
806 vect_model_load_cost (stmt_vec_info stmt_info, int ncopies, slp_tree slp_node)
807
808 {
809   int group_size;
810   gimple first_stmt;
811   struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info), *first_dr;
812   unsigned int inside_cost = 0, outside_cost = 0;
813
814   /* The SLP costs were already calculated during SLP tree build.  */
815   if (PURE_SLP_STMT (stmt_info))
816     return;
817
818   /* Strided accesses?  */
819   first_stmt = DR_GROUP_FIRST_DR (stmt_info);
820   if (first_stmt && !slp_node)
821     {
822       group_size = vect_cost_strided_group_size (stmt_info);
823       first_dr = STMT_VINFO_DATA_REF (vinfo_for_stmt (first_stmt));
824     }
825   /* Not a strided access.  */
826   else
827     {
828       group_size = 1;
829       first_dr = dr;
830     }
831
832   /* Is this an access in a group of loads providing strided access?
833      If so, add in the cost of the permutes.  */
834   if (group_size > 1)
835     {
836       /* Uses an even and odd extract operations for each needed permute.  */
837       inside_cost = ncopies * exact_log2(group_size) * group_size
838         * vect_get_stmt_cost (vec_perm);
839
840       if (vect_print_dump_info (REPORT_COST))
841         fprintf (vect_dump, "vect_model_load_cost: strided group_size = %d .",
842                  group_size);
843     }
844
845   /* The loads themselves.  */
846   vect_get_load_cost (first_dr, ncopies,
847          ((!DR_GROUP_FIRST_DR (stmt_info)) || group_size > 1 || slp_node),
848          &inside_cost, &outside_cost);
849
850   if (vect_print_dump_info (REPORT_COST))
851     fprintf (vect_dump, "vect_model_load_cost: inside_cost = %d, "
852              "outside_cost = %d .", inside_cost, outside_cost);
853
854   /* Set the costs either in STMT_INFO or SLP_NODE (if exists).  */
855   stmt_vinfo_set_inside_of_loop_cost (stmt_info, slp_node, inside_cost);
856   stmt_vinfo_set_outside_of_loop_cost (stmt_info, slp_node, outside_cost);
857 }
858
859
860 /* Calculate cost of DR's memory access.  */
861 void
862 vect_get_load_cost (struct data_reference *dr, int ncopies,
863                     bool add_realign_cost, unsigned int *inside_cost,
864                     unsigned int *outside_cost)
865 {
866   int alignment_support_scheme = vect_supportable_dr_alignment (dr, false);
867
868   switch (alignment_support_scheme)
869     {
870     case dr_aligned:
871       {
872         *inside_cost += ncopies * vect_get_stmt_cost (vector_load); 
873
874         if (vect_print_dump_info (REPORT_COST))
875           fprintf (vect_dump, "vect_model_load_cost: aligned.");
876
877         break;
878       }
879     case dr_unaligned_supported:
880       {
881         gimple stmt = DR_STMT (dr);
882         stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
883         tree vectype = STMT_VINFO_VECTYPE (stmt_info);
884
885         /* Here, we assign an additional cost for the unaligned load.  */
886         *inside_cost += ncopies
887           * targetm.vectorize.builtin_vectorization_cost (unaligned_load,
888                                            vectype, DR_MISALIGNMENT (dr));
889         if (vect_print_dump_info (REPORT_COST))
890           fprintf (vect_dump, "vect_model_load_cost: unaligned supported by "
891                    "hardware.");
892
893         break;
894       }
895     case dr_explicit_realign:
896       {
897         *inside_cost += ncopies * (2 * vect_get_stmt_cost (vector_load)
898                                    + vect_get_stmt_cost (vec_perm));
899
900         /* FIXME: If the misalignment remains fixed across the iterations of
901            the containing loop, the following cost should be added to the
902            outside costs.  */
903         if (targetm.vectorize.builtin_mask_for_load)
904           *inside_cost += vect_get_stmt_cost (vector_stmt);
905
906         if (vect_print_dump_info (REPORT_COST))
907           fprintf (vect_dump, "vect_model_load_cost: explicit realign");
908
909         break;
910       }
911     case dr_explicit_realign_optimized:
912       {
913         if (vect_print_dump_info (REPORT_COST))
914           fprintf (vect_dump, "vect_model_load_cost: unaligned software "
915                    "pipelined.");
916
917         /* Unaligned software pipeline has a load of an address, an initial
918            load, and possibly a mask operation to "prime" the loop.  However,
919            if this is an access in a group of loads, which provide strided
920            access, then the above cost should only be considered for one
921            access in the group.  Inside the loop, there is a load op
922            and a realignment op.  */
923
924         if (add_realign_cost)
925           {
926             *outside_cost = 2 * vect_get_stmt_cost (vector_stmt);
927             if (targetm.vectorize.builtin_mask_for_load)
928               *outside_cost += vect_get_stmt_cost (vector_stmt);
929           }
930
931         *inside_cost += ncopies * (vect_get_stmt_cost (vector_load)
932                                    + vect_get_stmt_cost (vec_perm));
933
934         if (vect_print_dump_info (REPORT_COST))
935           fprintf (vect_dump,
936                    "vect_model_load_cost: explicit realign optimized");
937
938         break;
939       }
940
941     default:
942       gcc_unreachable ();
943     }
944 }
945
946
947 /* Function vect_init_vector.
948
949    Insert a new stmt (INIT_STMT) that initializes a new vector variable with
950    the vector elements of VECTOR_VAR.  Place the initialization at BSI if it
951    is not NULL.  Otherwise, place the initialization at the loop preheader.
952    Return the DEF of INIT_STMT.
953    It will be used in the vectorization of STMT.  */
954
955 tree
956 vect_init_vector (gimple stmt, tree vector_var, tree vector_type,
957                   gimple_stmt_iterator *gsi)
958 {
959   stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt);
960   tree new_var;
961   gimple init_stmt;
962   tree vec_oprnd;
963   edge pe;
964   tree new_temp;
965   basic_block new_bb;
966
967   new_var = vect_get_new_vect_var (vector_type, vect_simple_var, "cst_");
968   add_referenced_var (new_var);
969   init_stmt = gimple_build_assign  (new_var, vector_var);
970   new_temp = make_ssa_name (new_var, init_stmt);
971   gimple_assign_set_lhs (init_stmt, new_temp);
972
973   if (gsi)
974     vect_finish_stmt_generation (stmt, init_stmt, gsi);
975   else
976     {
977       loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
978
979       if (loop_vinfo)
980         {
981           struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
982
983           if (nested_in_vect_loop_p (loop, stmt))
984             loop = loop->inner;
985
986           pe = loop_preheader_edge (loop);
987           new_bb = gsi_insert_on_edge_immediate (pe, init_stmt);
988           gcc_assert (!new_bb);
989         }
990       else
991        {
992           bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_vinfo);
993           basic_block bb;
994           gimple_stmt_iterator gsi_bb_start;
995
996           gcc_assert (bb_vinfo);
997           bb = BB_VINFO_BB (bb_vinfo);
998           gsi_bb_start = gsi_after_labels (bb);
999           gsi_insert_before (&gsi_bb_start, init_stmt, GSI_SAME_STMT);
1000        }
1001     }
1002
1003   if (vect_print_dump_info (REPORT_DETAILS))
1004     {
1005       fprintf (vect_dump, "created new init_stmt: ");
1006       print_gimple_stmt (vect_dump, init_stmt, 0, TDF_SLIM);
1007     }
1008
1009   vec_oprnd = gimple_assign_lhs (init_stmt);
1010   return vec_oprnd;
1011 }
1012
1013
1014 /* Function vect_get_vec_def_for_operand.
1015
1016    OP is an operand in STMT.  This function returns a (vector) def that will be
1017    used in the vectorized stmt for STMT.
1018
1019    In the case that OP is an SSA_NAME which is defined in the loop, then
1020    STMT_VINFO_VEC_STMT of the defining stmt holds the relevant def.
1021
1022    In case OP is an invariant or constant, a new stmt that creates a vector def
1023    needs to be introduced.  */
1024
1025 tree
1026 vect_get_vec_def_for_operand (tree op, gimple stmt, tree *scalar_def)
1027 {
1028   tree vec_oprnd;
1029   gimple vec_stmt;
1030   gimple def_stmt;
1031   stmt_vec_info def_stmt_info = NULL;
1032   stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt);
1033   unsigned int nunits;
1034   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
1035   tree vec_inv;
1036   tree vec_cst;
1037   tree t = NULL_TREE;
1038   tree def;
1039   int i;
1040   enum vect_def_type dt;
1041   bool is_simple_use;
1042   tree vector_type;
1043
1044   if (vect_print_dump_info (REPORT_DETAILS))
1045     {
1046       fprintf (vect_dump, "vect_get_vec_def_for_operand: ");
1047       print_generic_expr (vect_dump, op, TDF_SLIM);
1048     }
1049
1050   is_simple_use = vect_is_simple_use (op, loop_vinfo, NULL, &def_stmt, &def,
1051                                       &dt);
1052   gcc_assert (is_simple_use);
1053   if (vect_print_dump_info (REPORT_DETAILS))
1054     {
1055       if (def)
1056         {
1057           fprintf (vect_dump, "def =  ");
1058           print_generic_expr (vect_dump, def, TDF_SLIM);
1059         }
1060       if (def_stmt)
1061         {
1062           fprintf (vect_dump, "  def_stmt =  ");
1063           print_gimple_stmt (vect_dump, def_stmt, 0, TDF_SLIM);
1064         }
1065     }
1066
1067   switch (dt)
1068     {
1069     /* Case 1: operand is a constant.  */
1070     case vect_constant_def:
1071       {
1072         vector_type = get_vectype_for_scalar_type (TREE_TYPE (op));
1073         gcc_assert (vector_type);
1074         nunits = TYPE_VECTOR_SUBPARTS (vector_type);
1075
1076         if (scalar_def)
1077           *scalar_def = op;
1078
1079         /* Create 'vect_cst_ = {cst,cst,...,cst}'  */
1080         if (vect_print_dump_info (REPORT_DETAILS))
1081           fprintf (vect_dump, "Create vector_cst. nunits = %d", nunits);
1082
1083         vec_cst = build_vector_from_val (vector_type, op);
1084         return vect_init_vector (stmt, vec_cst, vector_type, NULL);
1085       }
1086
1087     /* Case 2: operand is defined outside the loop - loop invariant.  */
1088     case vect_external_def:
1089       {
1090         vector_type = get_vectype_for_scalar_type (TREE_TYPE (def));
1091         gcc_assert (vector_type);
1092         nunits = TYPE_VECTOR_SUBPARTS (vector_type);
1093
1094         if (scalar_def)
1095           *scalar_def = def;
1096
1097         /* Create 'vec_inv = {inv,inv,..,inv}'  */
1098         if (vect_print_dump_info (REPORT_DETAILS))
1099           fprintf (vect_dump, "Create vector_inv.");
1100
1101         for (i = nunits - 1; i >= 0; --i)
1102           {
1103             t = tree_cons (NULL_TREE, def, t);
1104           }
1105
1106         /* FIXME: use build_constructor directly.  */
1107         vec_inv = build_constructor_from_list (vector_type, t);
1108         return vect_init_vector (stmt, vec_inv, vector_type, NULL);
1109       }
1110
1111     /* Case 3: operand is defined inside the loop.  */
1112     case vect_internal_def:
1113       {
1114         if (scalar_def)
1115           *scalar_def = NULL/* FIXME tuples: def_stmt*/;
1116
1117         /* Get the def from the vectorized stmt.  */
1118         def_stmt_info = vinfo_for_stmt (def_stmt);
1119         vec_stmt = STMT_VINFO_VEC_STMT (def_stmt_info);
1120         gcc_assert (vec_stmt);
1121         if (gimple_code (vec_stmt) == GIMPLE_PHI)
1122           vec_oprnd = PHI_RESULT (vec_stmt);
1123         else if (is_gimple_call (vec_stmt))
1124           vec_oprnd = gimple_call_lhs (vec_stmt);
1125         else
1126           vec_oprnd = gimple_assign_lhs (vec_stmt);
1127         return vec_oprnd;
1128       }
1129
1130     /* Case 4: operand is defined by a loop header phi - reduction  */
1131     case vect_reduction_def:
1132     case vect_double_reduction_def:
1133     case vect_nested_cycle:
1134       {
1135         struct loop *loop;
1136
1137         gcc_assert (gimple_code (def_stmt) == GIMPLE_PHI);
1138         loop = (gimple_bb (def_stmt))->loop_father;
1139
1140         /* Get the def before the loop  */
1141         op = PHI_ARG_DEF_FROM_EDGE (def_stmt, loop_preheader_edge (loop));
1142         return get_initial_def_for_reduction (stmt, op, scalar_def);
1143      }
1144
1145     /* Case 5: operand is defined by loop-header phi - induction.  */
1146     case vect_induction_def:
1147       {
1148         gcc_assert (gimple_code (def_stmt) == GIMPLE_PHI);
1149
1150         /* Get the def from the vectorized stmt.  */
1151         def_stmt_info = vinfo_for_stmt (def_stmt);
1152         vec_stmt = STMT_VINFO_VEC_STMT (def_stmt_info);
1153         if (gimple_code (vec_stmt) == GIMPLE_PHI)
1154           vec_oprnd = PHI_RESULT (vec_stmt);
1155         else
1156           vec_oprnd = gimple_get_lhs (vec_stmt);
1157         return vec_oprnd;
1158       }
1159
1160     default:
1161       gcc_unreachable ();
1162     }
1163 }
1164
1165
1166 /* Function vect_get_vec_def_for_stmt_copy
1167
1168    Return a vector-def for an operand.  This function is used when the
1169    vectorized stmt to be created (by the caller to this function) is a "copy"
1170    created in case the vectorized result cannot fit in one vector, and several
1171    copies of the vector-stmt are required.  In this case the vector-def is
1172    retrieved from the vector stmt recorded in the STMT_VINFO_RELATED_STMT field
1173    of the stmt that defines VEC_OPRND.
1174    DT is the type of the vector def VEC_OPRND.
1175
1176    Context:
1177         In case the vectorization factor (VF) is bigger than the number
1178    of elements that can fit in a vectype (nunits), we have to generate
1179    more than one vector stmt to vectorize the scalar stmt.  This situation
1180    arises when there are multiple data-types operated upon in the loop; the
1181    smallest data-type determines the VF, and as a result, when vectorizing
1182    stmts operating on wider types we need to create 'VF/nunits' "copies" of the
1183    vector stmt (each computing a vector of 'nunits' results, and together
1184    computing 'VF' results in each iteration).  This function is called when
1185    vectorizing such a stmt (e.g. vectorizing S2 in the illustration below, in
1186    which VF=16 and nunits=4, so the number of copies required is 4):
1187
1188    scalar stmt:         vectorized into:        STMT_VINFO_RELATED_STMT
1189
1190    S1: x = load         VS1.0:  vx.0 = memref0      VS1.1
1191                         VS1.1:  vx.1 = memref1      VS1.2
1192                         VS1.2:  vx.2 = memref2      VS1.3
1193                         VS1.3:  vx.3 = memref3
1194
1195    S2: z = x + ...      VSnew.0:  vz0 = vx.0 + ...  VSnew.1
1196                         VSnew.1:  vz1 = vx.1 + ...  VSnew.2
1197                         VSnew.2:  vz2 = vx.2 + ...  VSnew.3
1198                         VSnew.3:  vz3 = vx.3 + ...
1199
1200    The vectorization of S1 is explained in vectorizable_load.
1201    The vectorization of S2:
1202         To create the first vector-stmt out of the 4 copies - VSnew.0 -
1203    the function 'vect_get_vec_def_for_operand' is called to
1204    get the relevant vector-def for each operand of S2.  For operand x it
1205    returns  the vector-def 'vx.0'.
1206
1207         To create the remaining copies of the vector-stmt (VSnew.j), this
1208    function is called to get the relevant vector-def for each operand.  It is
1209    obtained from the respective VS1.j stmt, which is recorded in the
1210    STMT_VINFO_RELATED_STMT field of the stmt that defines VEC_OPRND.
1211
1212         For example, to obtain the vector-def 'vx.1' in order to create the
1213    vector stmt 'VSnew.1', this function is called with VEC_OPRND='vx.0'.
1214    Given 'vx0' we obtain the stmt that defines it ('VS1.0'); from the
1215    STMT_VINFO_RELATED_STMT field of 'VS1.0' we obtain the next copy - 'VS1.1',
1216    and return its def ('vx.1').
1217    Overall, to create the above sequence this function will be called 3 times:
1218         vx.1 = vect_get_vec_def_for_stmt_copy (dt, vx.0);
1219         vx.2 = vect_get_vec_def_for_stmt_copy (dt, vx.1);
1220         vx.3 = vect_get_vec_def_for_stmt_copy (dt, vx.2);  */
1221
1222 tree
1223 vect_get_vec_def_for_stmt_copy (enum vect_def_type dt, tree vec_oprnd)
1224 {
1225   gimple vec_stmt_for_operand;
1226   stmt_vec_info def_stmt_info;
1227
1228   /* Do nothing; can reuse same def.  */
1229   if (dt == vect_external_def || dt == vect_constant_def )
1230     return vec_oprnd;
1231
1232   vec_stmt_for_operand = SSA_NAME_DEF_STMT (vec_oprnd);
1233   def_stmt_info = vinfo_for_stmt (vec_stmt_for_operand);
1234   gcc_assert (def_stmt_info);
1235   vec_stmt_for_operand = STMT_VINFO_RELATED_STMT (def_stmt_info);
1236   gcc_assert (vec_stmt_for_operand);
1237   vec_oprnd = gimple_get_lhs (vec_stmt_for_operand);
1238   if (gimple_code (vec_stmt_for_operand) == GIMPLE_PHI)
1239     vec_oprnd = PHI_RESULT (vec_stmt_for_operand);
1240   else
1241     vec_oprnd = gimple_get_lhs (vec_stmt_for_operand);
1242   return vec_oprnd;
1243 }
1244
1245
1246 /* Get vectorized definitions for the operands to create a copy of an original
1247    stmt.  See vect_get_vec_def_for_stmt_copy () for details.  */
1248
1249 static void
1250 vect_get_vec_defs_for_stmt_copy (enum vect_def_type *dt,
1251                                  VEC(tree,heap) **vec_oprnds0,
1252                                  VEC(tree,heap) **vec_oprnds1)
1253 {
1254   tree vec_oprnd = VEC_pop (tree, *vec_oprnds0);
1255
1256   vec_oprnd = vect_get_vec_def_for_stmt_copy (dt[0], vec_oprnd);
1257   VEC_quick_push (tree, *vec_oprnds0, vec_oprnd);
1258
1259   if (vec_oprnds1 && *vec_oprnds1)
1260     {
1261       vec_oprnd = VEC_pop (tree, *vec_oprnds1);
1262       vec_oprnd = vect_get_vec_def_for_stmt_copy (dt[1], vec_oprnd);
1263       VEC_quick_push (tree, *vec_oprnds1, vec_oprnd);
1264     }
1265 }
1266
1267
1268 /* Get vectorized definitions for OP0 and OP1, or SLP_NODE if it is not
1269    NULL.  */
1270
1271 static void
1272 vect_get_vec_defs (tree op0, tree op1, gimple stmt,
1273                    VEC(tree,heap) **vec_oprnds0, VEC(tree,heap) **vec_oprnds1,
1274                    slp_tree slp_node)
1275 {
1276   if (slp_node)
1277     vect_get_slp_defs (op0, op1, slp_node, vec_oprnds0, vec_oprnds1, -1);
1278   else
1279     {
1280       tree vec_oprnd;
1281
1282       *vec_oprnds0 = VEC_alloc (tree, heap, 1);
1283       vec_oprnd = vect_get_vec_def_for_operand (op0, stmt, NULL);
1284       VEC_quick_push (tree, *vec_oprnds0, vec_oprnd);
1285
1286       if (op1)
1287         {
1288           *vec_oprnds1 = VEC_alloc (tree, heap, 1);
1289           vec_oprnd = vect_get_vec_def_for_operand (op1, stmt, NULL);
1290           VEC_quick_push (tree, *vec_oprnds1, vec_oprnd);
1291         }
1292     }
1293 }
1294
1295
1296 /* Function vect_finish_stmt_generation.
1297
1298    Insert a new stmt.  */
1299
1300 void
1301 vect_finish_stmt_generation (gimple stmt, gimple vec_stmt,
1302                              gimple_stmt_iterator *gsi)
1303 {
1304   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
1305   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
1306   bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info);
1307
1308   gcc_assert (gimple_code (stmt) != GIMPLE_LABEL);
1309
1310   gsi_insert_before (gsi, vec_stmt, GSI_SAME_STMT);
1311
1312   set_vinfo_for_stmt (vec_stmt, new_stmt_vec_info (vec_stmt, loop_vinfo,
1313                                                    bb_vinfo));
1314
1315   if (vect_print_dump_info (REPORT_DETAILS))
1316     {
1317       fprintf (vect_dump, "add new stmt: ");
1318       print_gimple_stmt (vect_dump, vec_stmt, 0, TDF_SLIM);
1319     }
1320
1321   gimple_set_location (vec_stmt, gimple_location (gsi_stmt (*gsi)));
1322 }
1323
1324 /* Checks if CALL can be vectorized in type VECTYPE.  Returns
1325    a function declaration if the target has a vectorized version
1326    of the function, or NULL_TREE if the function cannot be vectorized.  */
1327
1328 tree
1329 vectorizable_function (gimple call, tree vectype_out, tree vectype_in)
1330 {
1331   tree fndecl = gimple_call_fndecl (call);
1332
1333   /* We only handle functions that do not read or clobber memory -- i.e.
1334      const or novops ones.  */
1335   if (!(gimple_call_flags (call) & (ECF_CONST | ECF_NOVOPS)))
1336     return NULL_TREE;
1337
1338   if (!fndecl
1339       || TREE_CODE (fndecl) != FUNCTION_DECL
1340       || !DECL_BUILT_IN (fndecl))
1341     return NULL_TREE;
1342
1343   return targetm.vectorize.builtin_vectorized_function (fndecl, vectype_out,
1344                                                         vectype_in);
1345 }
1346
1347 /* Function vectorizable_call.
1348
1349    Check if STMT performs a function call that can be vectorized.
1350    If VEC_STMT is also passed, vectorize the STMT: create a vectorized
1351    stmt to replace it, put it in VEC_STMT, and insert it at BSI.
1352    Return FALSE if not a vectorizable STMT, TRUE otherwise.  */
1353
1354 static bool
1355 vectorizable_call (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt)
1356 {
1357   tree vec_dest;
1358   tree scalar_dest;
1359   tree op, type;
1360   tree vec_oprnd0 = NULL_TREE, vec_oprnd1 = NULL_TREE;
1361   stmt_vec_info stmt_info = vinfo_for_stmt (stmt), prev_stmt_info;
1362   tree vectype_out, vectype_in;
1363   int nunits_in;
1364   int nunits_out;
1365   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
1366   tree fndecl, new_temp, def, rhs_type;
1367   gimple def_stmt;
1368   enum vect_def_type dt[3]
1369     = {vect_unknown_def_type, vect_unknown_def_type, vect_unknown_def_type};
1370   gimple new_stmt = NULL;
1371   int ncopies, j;
1372   VEC(tree, heap) *vargs = NULL;
1373   enum { NARROW, NONE, WIDEN } modifier;
1374   size_t i, nargs;
1375
1376   /* FORNOW: unsupported in basic block SLP.  */
1377   gcc_assert (loop_vinfo);
1378
1379   if (!STMT_VINFO_RELEVANT_P (stmt_info))
1380     return false;
1381
1382   if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def)
1383     return false;
1384
1385   /* FORNOW: SLP not supported.  */
1386   if (STMT_SLP_TYPE (stmt_info))
1387     return false;
1388
1389   /* Is STMT a vectorizable call?   */
1390   if (!is_gimple_call (stmt))
1391     return false;
1392
1393   if (TREE_CODE (gimple_call_lhs (stmt)) != SSA_NAME)
1394     return false;
1395
1396   if (stmt_can_throw_internal (stmt))
1397     return false;
1398
1399   vectype_out = STMT_VINFO_VECTYPE (stmt_info);
1400
1401   /* Process function arguments.  */
1402   rhs_type = NULL_TREE;
1403   vectype_in = NULL_TREE;
1404   nargs = gimple_call_num_args (stmt);
1405
1406   /* Bail out if the function has more than three arguments, we do not have
1407      interesting builtin functions to vectorize with more than two arguments
1408      except for fma.  No arguments is also not good.  */
1409   if (nargs == 0 || nargs > 3)
1410     return false;
1411
1412   for (i = 0; i < nargs; i++)
1413     {
1414       tree opvectype;
1415
1416       op = gimple_call_arg (stmt, i);
1417
1418       /* We can only handle calls with arguments of the same type.  */
1419       if (rhs_type
1420           && !types_compatible_p (rhs_type, TREE_TYPE (op)))
1421         {
1422           if (vect_print_dump_info (REPORT_DETAILS))
1423             fprintf (vect_dump, "argument types differ.");
1424           return false;
1425         }
1426       if (!rhs_type)
1427         rhs_type = TREE_TYPE (op);
1428
1429       if (!vect_is_simple_use_1 (op, loop_vinfo, NULL,
1430                                  &def_stmt, &def, &dt[i], &opvectype))
1431         {
1432           if (vect_print_dump_info (REPORT_DETAILS))
1433             fprintf (vect_dump, "use not simple.");
1434           return false;
1435         }
1436
1437       if (!vectype_in)
1438         vectype_in = opvectype;
1439       else if (opvectype
1440                && opvectype != vectype_in)
1441         {
1442           if (vect_print_dump_info (REPORT_DETAILS))
1443             fprintf (vect_dump, "argument vector types differ.");
1444           return false;
1445         }
1446     }
1447   /* If all arguments are external or constant defs use a vector type with
1448      the same size as the output vector type.  */
1449   if (!vectype_in)
1450     vectype_in = get_same_sized_vectype (rhs_type, vectype_out);
1451   if (vec_stmt)
1452     gcc_assert (vectype_in);
1453   if (!vectype_in)
1454     {
1455       if (vect_print_dump_info (REPORT_DETAILS))
1456         {
1457           fprintf (vect_dump, "no vectype for scalar type ");
1458           print_generic_expr (vect_dump, rhs_type, TDF_SLIM);
1459         }
1460
1461       return false;
1462     }
1463
1464   /* FORNOW */
1465   nunits_in = TYPE_VECTOR_SUBPARTS (vectype_in);
1466   nunits_out = TYPE_VECTOR_SUBPARTS (vectype_out);
1467   if (nunits_in == nunits_out / 2)
1468     modifier = NARROW;
1469   else if (nunits_out == nunits_in)
1470     modifier = NONE;
1471   else if (nunits_out == nunits_in / 2)
1472     modifier = WIDEN;
1473   else
1474     return false;
1475
1476   /* For now, we only vectorize functions if a target specific builtin
1477      is available.  TODO -- in some cases, it might be profitable to
1478      insert the calls for pieces of the vector, in order to be able
1479      to vectorize other operations in the loop.  */
1480   fndecl = vectorizable_function (stmt, vectype_out, vectype_in);
1481   if (fndecl == NULL_TREE)
1482     {
1483       if (vect_print_dump_info (REPORT_DETAILS))
1484         fprintf (vect_dump, "function is not vectorizable.");
1485
1486       return false;
1487     }
1488
1489   gcc_assert (!gimple_vuse (stmt));
1490
1491   if (modifier == NARROW)
1492     ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits_out;
1493   else
1494     ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits_in;
1495
1496   /* Sanity check: make sure that at least one copy of the vectorized stmt
1497      needs to be generated.  */
1498   gcc_assert (ncopies >= 1);
1499
1500   if (!vec_stmt) /* transformation not required.  */
1501     {
1502       STMT_VINFO_TYPE (stmt_info) = call_vec_info_type;
1503       if (vect_print_dump_info (REPORT_DETAILS))
1504         fprintf (vect_dump, "=== vectorizable_call ===");
1505       vect_model_simple_cost (stmt_info, ncopies, dt, NULL);
1506       return true;
1507     }
1508
1509   /** Transform.  **/
1510
1511   if (vect_print_dump_info (REPORT_DETAILS))
1512     fprintf (vect_dump, "transform operation.");
1513
1514   /* Handle def.  */
1515   scalar_dest = gimple_call_lhs (stmt);
1516   vec_dest = vect_create_destination_var (scalar_dest, vectype_out);
1517
1518   prev_stmt_info = NULL;
1519   switch (modifier)
1520     {
1521     case NONE:
1522       for (j = 0; j < ncopies; ++j)
1523         {
1524           /* Build argument list for the vectorized call.  */
1525           if (j == 0)
1526             vargs = VEC_alloc (tree, heap, nargs);
1527           else
1528             VEC_truncate (tree, vargs, 0);
1529
1530           for (i = 0; i < nargs; i++)
1531             {
1532               op = gimple_call_arg (stmt, i);
1533               if (j == 0)
1534                 vec_oprnd0
1535                   = vect_get_vec_def_for_operand (op, stmt, NULL);
1536               else
1537                 {
1538                   vec_oprnd0 = gimple_call_arg (new_stmt, i);
1539                   vec_oprnd0
1540                     = vect_get_vec_def_for_stmt_copy (dt[i], vec_oprnd0);
1541                 }
1542
1543               VEC_quick_push (tree, vargs, vec_oprnd0);
1544             }
1545
1546           new_stmt = gimple_build_call_vec (fndecl, vargs);
1547           new_temp = make_ssa_name (vec_dest, new_stmt);
1548           gimple_call_set_lhs (new_stmt, new_temp);
1549
1550           vect_finish_stmt_generation (stmt, new_stmt, gsi);
1551           mark_symbols_for_renaming (new_stmt);
1552
1553           if (j == 0)
1554             STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt;
1555           else
1556             STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt;
1557
1558           prev_stmt_info = vinfo_for_stmt (new_stmt);
1559         }
1560
1561       break;
1562
1563     case NARROW:
1564       for (j = 0; j < ncopies; ++j)
1565         {
1566           /* Build argument list for the vectorized call.  */
1567           if (j == 0)
1568             vargs = VEC_alloc (tree, heap, nargs * 2);
1569           else
1570             VEC_truncate (tree, vargs, 0);
1571
1572           for (i = 0; i < nargs; i++)
1573             {
1574               op = gimple_call_arg (stmt, i);
1575               if (j == 0)
1576                 {
1577                   vec_oprnd0
1578                     = vect_get_vec_def_for_operand (op, stmt, NULL);
1579                   vec_oprnd1
1580                     = vect_get_vec_def_for_stmt_copy (dt[i], vec_oprnd0);
1581                 }
1582               else
1583                 {
1584                   vec_oprnd1 = gimple_call_arg (new_stmt, 2*i + 1);
1585                   vec_oprnd0
1586                     = vect_get_vec_def_for_stmt_copy (dt[i], vec_oprnd1);
1587                   vec_oprnd1
1588                     = vect_get_vec_def_for_stmt_copy (dt[i], vec_oprnd0);
1589                 }
1590
1591               VEC_quick_push (tree, vargs, vec_oprnd0);
1592               VEC_quick_push (tree, vargs, vec_oprnd1);
1593             }
1594
1595           new_stmt = gimple_build_call_vec (fndecl, vargs);
1596           new_temp = make_ssa_name (vec_dest, new_stmt);
1597           gimple_call_set_lhs (new_stmt, new_temp);
1598
1599           vect_finish_stmt_generation (stmt, new_stmt, gsi);
1600           mark_symbols_for_renaming (new_stmt);
1601
1602           if (j == 0)
1603             STMT_VINFO_VEC_STMT (stmt_info) = new_stmt;
1604           else
1605             STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt;
1606
1607           prev_stmt_info = vinfo_for_stmt (new_stmt);
1608         }
1609
1610       *vec_stmt = STMT_VINFO_VEC_STMT (stmt_info);
1611
1612       break;
1613
1614     case WIDEN:
1615       /* No current target implements this case.  */
1616       return false;
1617     }
1618
1619   VEC_free (tree, heap, vargs);
1620
1621   /* Update the exception handling table with the vector stmt if necessary.  */
1622   if (maybe_clean_or_replace_eh_stmt (stmt, *vec_stmt))
1623     gimple_purge_dead_eh_edges (gimple_bb (stmt));
1624
1625   /* The call in STMT might prevent it from being removed in dce.
1626      We however cannot remove it here, due to the way the ssa name
1627      it defines is mapped to the new definition.  So just replace
1628      rhs of the statement with something harmless.  */
1629
1630   type = TREE_TYPE (scalar_dest);
1631   new_stmt = gimple_build_assign (gimple_call_lhs (stmt),
1632                                   build_zero_cst (type));
1633   set_vinfo_for_stmt (new_stmt, stmt_info);
1634   /* For pattern statements make the related statement to point to
1635      NEW_STMT in order to be able to retrieve the original statement
1636      information later.  */
1637   if (is_pattern_stmt_p (stmt_info))
1638     {
1639       gimple related = STMT_VINFO_RELATED_STMT (stmt_info);
1640       STMT_VINFO_RELATED_STMT (vinfo_for_stmt (related)) = new_stmt;
1641     }
1642   set_vinfo_for_stmt (stmt, NULL);
1643   STMT_VINFO_STMT (stmt_info) = new_stmt;
1644   gsi_replace (gsi, new_stmt, false);
1645   SSA_NAME_DEF_STMT (gimple_assign_lhs (new_stmt)) = new_stmt;
1646
1647   return true;
1648 }
1649
1650
1651 /* Function vect_gen_widened_results_half
1652
1653    Create a vector stmt whose code, type, number of arguments, and result
1654    variable are CODE, OP_TYPE, and VEC_DEST, and its arguments are
1655    VEC_OPRND0 and VEC_OPRND1.  The new vector stmt is to be inserted at BSI.
1656    In the case that CODE is a CALL_EXPR, this means that a call to DECL
1657    needs to be created (DECL is a function-decl of a target-builtin).
1658    STMT is the original scalar stmt that we are vectorizing.  */
1659
1660 static gimple
1661 vect_gen_widened_results_half (enum tree_code code,
1662                                tree decl,
1663                                tree vec_oprnd0, tree vec_oprnd1, int op_type,
1664                                tree vec_dest, gimple_stmt_iterator *gsi,
1665                                gimple stmt)
1666 {
1667   gimple new_stmt;
1668   tree new_temp;
1669
1670   /* Generate half of the widened result:  */
1671   if (code == CALL_EXPR)
1672     {
1673       /* Target specific support  */
1674       if (op_type == binary_op)
1675         new_stmt = gimple_build_call (decl, 2, vec_oprnd0, vec_oprnd1);
1676       else
1677         new_stmt = gimple_build_call (decl, 1, vec_oprnd0);
1678       new_temp = make_ssa_name (vec_dest, new_stmt);
1679       gimple_call_set_lhs (new_stmt, new_temp);
1680     }
1681   else
1682     {
1683       /* Generic support */
1684       gcc_assert (op_type == TREE_CODE_LENGTH (code));
1685       if (op_type != binary_op)
1686         vec_oprnd1 = NULL;
1687       new_stmt = gimple_build_assign_with_ops (code, vec_dest, vec_oprnd0,
1688                                                vec_oprnd1);
1689       new_temp = make_ssa_name (vec_dest, new_stmt);
1690       gimple_assign_set_lhs (new_stmt, new_temp);
1691     }
1692   vect_finish_stmt_generation (stmt, new_stmt, gsi);
1693
1694   return new_stmt;
1695 }
1696
1697
1698 /* Check if STMT performs a conversion operation, that can be vectorized.
1699    If VEC_STMT is also passed, vectorize the STMT: create a vectorized
1700    stmt to replace it, put it in VEC_STMT, and insert it at BSI.
1701    Return FALSE if not a vectorizable STMT, TRUE otherwise.  */
1702
1703 static bool
1704 vectorizable_conversion (gimple stmt, gimple_stmt_iterator *gsi,
1705                          gimple *vec_stmt, slp_tree slp_node)
1706 {
1707   tree vec_dest;
1708   tree scalar_dest;
1709   tree op0;
1710   tree vec_oprnd0 = NULL_TREE, vec_oprnd1 = NULL_TREE;
1711   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
1712   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
1713   enum tree_code code, code1 = ERROR_MARK, code2 = ERROR_MARK;
1714   tree decl1 = NULL_TREE, decl2 = NULL_TREE;
1715   tree new_temp;
1716   tree def;
1717   gimple def_stmt;
1718   enum vect_def_type dt[2] = {vect_unknown_def_type, vect_unknown_def_type};
1719   gimple new_stmt = NULL;
1720   stmt_vec_info prev_stmt_info;
1721   int nunits_in;
1722   int nunits_out;
1723   tree vectype_out, vectype_in;
1724   int ncopies, j;
1725   tree rhs_type;
1726   tree builtin_decl;
1727   enum { NARROW, NONE, WIDEN } modifier;
1728   int i;
1729   VEC(tree,heap) *vec_oprnds0 = NULL;
1730   tree vop0;
1731   VEC(tree,heap) *dummy = NULL;
1732   int dummy_int;
1733
1734   /* Is STMT a vectorizable conversion?   */
1735
1736   /* FORNOW: unsupported in basic block SLP.  */
1737   gcc_assert (loop_vinfo);
1738
1739   if (!STMT_VINFO_RELEVANT_P (stmt_info))
1740     return false;
1741
1742   if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def)
1743     return false;
1744
1745   if (!is_gimple_assign (stmt))
1746     return false;
1747
1748   if (TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
1749     return false;
1750
1751   code = gimple_assign_rhs_code (stmt);
1752   if (code != FIX_TRUNC_EXPR && code != FLOAT_EXPR)
1753     return false;
1754
1755   /* Check types of lhs and rhs.  */
1756   scalar_dest = gimple_assign_lhs (stmt);
1757   vectype_out = STMT_VINFO_VECTYPE (stmt_info);
1758
1759   op0 = gimple_assign_rhs1 (stmt);
1760   rhs_type = TREE_TYPE (op0);
1761   /* Check the operands of the operation.  */
1762   if (!vect_is_simple_use_1 (op0, loop_vinfo, NULL,
1763                              &def_stmt, &def, &dt[0], &vectype_in))
1764     {
1765       if (vect_print_dump_info (REPORT_DETAILS))
1766         fprintf (vect_dump, "use not simple.");
1767       return false;
1768     }
1769   /* If op0 is an external or constant defs use a vector type of
1770      the same size as the output vector type.  */
1771   if (!vectype_in)
1772     vectype_in = get_same_sized_vectype (rhs_type, vectype_out);
1773   if (vec_stmt)
1774     gcc_assert (vectype_in);
1775   if (!vectype_in)
1776     {
1777       if (vect_print_dump_info (REPORT_DETAILS))
1778         {
1779           fprintf (vect_dump, "no vectype for scalar type ");
1780           print_generic_expr (vect_dump, rhs_type, TDF_SLIM);
1781         }
1782
1783       return false;
1784     }
1785
1786   /* FORNOW */
1787   nunits_in = TYPE_VECTOR_SUBPARTS (vectype_in);
1788   nunits_out = TYPE_VECTOR_SUBPARTS (vectype_out);
1789   if (nunits_in == nunits_out / 2)
1790     modifier = NARROW;
1791   else if (nunits_out == nunits_in)
1792     modifier = NONE;
1793   else if (nunits_out == nunits_in / 2)
1794     modifier = WIDEN;
1795   else
1796     return false;
1797
1798   if (modifier == NARROW)
1799     ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits_out;
1800   else
1801     ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits_in;
1802
1803   /* Multiple types in SLP are handled by creating the appropriate number of
1804      vectorized stmts for each SLP node.  Hence, NCOPIES is always 1 in
1805      case of SLP.  */
1806   if (slp_node)
1807     ncopies = 1;
1808
1809   /* Sanity check: make sure that at least one copy of the vectorized stmt
1810      needs to be generated.  */
1811   gcc_assert (ncopies >= 1);
1812
1813   /* Supportable by target?  */
1814   if ((modifier == NONE
1815        && !targetm.vectorize.builtin_conversion (code, vectype_out, vectype_in))
1816       || (modifier == WIDEN
1817           && !supportable_widening_operation (code, stmt,
1818                                               vectype_out, vectype_in,
1819                                               &decl1, &decl2,
1820                                               &code1, &code2,
1821                                               &dummy_int, &dummy))
1822       || (modifier == NARROW
1823           && !supportable_narrowing_operation (code, vectype_out, vectype_in,
1824                                                &code1, &dummy_int, &dummy)))
1825     {
1826       if (vect_print_dump_info (REPORT_DETAILS))
1827         fprintf (vect_dump, "conversion not supported by target.");
1828       return false;
1829     }
1830
1831   if (modifier != NONE)
1832     {
1833       /* FORNOW: SLP not supported.  */
1834       if (STMT_SLP_TYPE (stmt_info))
1835         return false;
1836     }
1837
1838   if (!vec_stmt)                /* transformation not required.  */
1839     {
1840       STMT_VINFO_TYPE (stmt_info) = type_conversion_vec_info_type;
1841       return true;
1842     }
1843
1844   /** Transform.  **/
1845   if (vect_print_dump_info (REPORT_DETAILS))
1846     fprintf (vect_dump, "transform conversion.");
1847
1848   /* Handle def.  */
1849   vec_dest = vect_create_destination_var (scalar_dest, vectype_out);
1850
1851   if (modifier == NONE && !slp_node)
1852     vec_oprnds0 = VEC_alloc (tree, heap, 1);
1853
1854   prev_stmt_info = NULL;
1855   switch (modifier)
1856     {
1857     case NONE:
1858       for (j = 0; j < ncopies; j++)
1859         {
1860           if (j == 0)
1861             vect_get_vec_defs (op0, NULL, stmt, &vec_oprnds0, NULL, slp_node);
1862           else
1863             vect_get_vec_defs_for_stmt_copy (dt, &vec_oprnds0, NULL);
1864
1865           builtin_decl =
1866             targetm.vectorize.builtin_conversion (code,
1867                                                   vectype_out, vectype_in);
1868           FOR_EACH_VEC_ELT (tree, vec_oprnds0, i, vop0)
1869             {
1870               /* Arguments are ready. create the new vector stmt.  */
1871               new_stmt = gimple_build_call (builtin_decl, 1, vop0);
1872               new_temp = make_ssa_name (vec_dest, new_stmt);
1873               gimple_call_set_lhs (new_stmt, new_temp);
1874               vect_finish_stmt_generation (stmt, new_stmt, gsi);
1875               if (slp_node)
1876                 VEC_quick_push (gimple, SLP_TREE_VEC_STMTS (slp_node), new_stmt);
1877             }
1878
1879           if (j == 0)
1880             STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt;
1881           else
1882             STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt;
1883           prev_stmt_info = vinfo_for_stmt (new_stmt);
1884         }
1885       break;
1886
1887     case WIDEN:
1888       /* In case the vectorization factor (VF) is bigger than the number
1889          of elements that we can fit in a vectype (nunits), we have to
1890          generate more than one vector stmt - i.e - we need to "unroll"
1891          the vector stmt by a factor VF/nunits.  */
1892       for (j = 0; j < ncopies; j++)
1893         {
1894           if (j == 0)
1895             vec_oprnd0 = vect_get_vec_def_for_operand (op0, stmt, NULL);
1896           else
1897             vec_oprnd0 = vect_get_vec_def_for_stmt_copy (dt[0], vec_oprnd0);
1898
1899           /* Generate first half of the widened result:  */
1900           new_stmt
1901             = vect_gen_widened_results_half (code1, decl1,
1902                                              vec_oprnd0, vec_oprnd1,
1903                                              unary_op, vec_dest, gsi, stmt);
1904           if (j == 0)
1905             STMT_VINFO_VEC_STMT (stmt_info) = new_stmt;
1906           else
1907             STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt;
1908           prev_stmt_info = vinfo_for_stmt (new_stmt);
1909
1910           /* Generate second half of the widened result:  */
1911           new_stmt
1912             = vect_gen_widened_results_half (code2, decl2,
1913                                              vec_oprnd0, vec_oprnd1,
1914                                              unary_op, vec_dest, gsi, stmt);
1915           STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt;
1916           prev_stmt_info = vinfo_for_stmt (new_stmt);
1917         }
1918       break;
1919
1920     case NARROW:
1921       /* In case the vectorization factor (VF) is bigger than the number
1922          of elements that we can fit in a vectype (nunits), we have to
1923          generate more than one vector stmt - i.e - we need to "unroll"
1924          the vector stmt by a factor VF/nunits.  */
1925       for (j = 0; j < ncopies; j++)
1926         {
1927           /* Handle uses.  */
1928           if (j == 0)
1929             {
1930               vec_oprnd0 = vect_get_vec_def_for_operand (op0, stmt, NULL);
1931               vec_oprnd1 = vect_get_vec_def_for_stmt_copy (dt[0], vec_oprnd0);
1932             }
1933           else
1934             {
1935               vec_oprnd0 = vect_get_vec_def_for_stmt_copy (dt[0], vec_oprnd1);
1936               vec_oprnd1 = vect_get_vec_def_for_stmt_copy (dt[0], vec_oprnd0);
1937             }
1938
1939           /* Arguments are ready.  Create the new vector stmt.  */
1940           new_stmt = gimple_build_assign_with_ops (code1, vec_dest, vec_oprnd0,
1941                                                    vec_oprnd1);
1942           new_temp = make_ssa_name (vec_dest, new_stmt);
1943           gimple_assign_set_lhs (new_stmt, new_temp);
1944           vect_finish_stmt_generation (stmt, new_stmt, gsi);
1945
1946           if (j == 0)
1947             STMT_VINFO_VEC_STMT (stmt_info) = new_stmt;
1948           else
1949             STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt;
1950
1951           prev_stmt_info = vinfo_for_stmt (new_stmt);
1952         }
1953
1954       *vec_stmt = STMT_VINFO_VEC_STMT (stmt_info);
1955     }
1956
1957   if (vec_oprnds0)
1958     VEC_free (tree, heap, vec_oprnds0);
1959
1960   return true;
1961 }
1962
1963
1964 /* Function vectorizable_assignment.
1965
1966    Check if STMT performs an assignment (copy) that can be vectorized.
1967    If VEC_STMT is also passed, vectorize the STMT: create a vectorized
1968    stmt to replace it, put it in VEC_STMT, and insert it at BSI.
1969    Return FALSE if not a vectorizable STMT, TRUE otherwise.  */
1970
1971 static bool
1972 vectorizable_assignment (gimple stmt, gimple_stmt_iterator *gsi,
1973                          gimple *vec_stmt, slp_tree slp_node)
1974 {
1975   tree vec_dest;
1976   tree scalar_dest;
1977   tree op;
1978   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
1979   tree vectype = STMT_VINFO_VECTYPE (stmt_info);
1980   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
1981   tree new_temp;
1982   tree def;
1983   gimple def_stmt;
1984   enum vect_def_type dt[2] = {vect_unknown_def_type, vect_unknown_def_type};
1985   unsigned int nunits = TYPE_VECTOR_SUBPARTS (vectype);
1986   int ncopies;
1987   int i, j;
1988   VEC(tree,heap) *vec_oprnds = NULL;
1989   tree vop;
1990   bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info);
1991   gimple new_stmt = NULL;
1992   stmt_vec_info prev_stmt_info = NULL;
1993   enum tree_code code;
1994   tree vectype_in;
1995
1996   /* Multiple types in SLP are handled by creating the appropriate number of
1997      vectorized stmts for each SLP node. Hence, NCOPIES is always 1 in
1998      case of SLP.  */
1999   if (slp_node)
2000     ncopies = 1;
2001   else
2002     ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits;
2003
2004   gcc_assert (ncopies >= 1);
2005
2006   if (!STMT_VINFO_RELEVANT_P (stmt_info) && !bb_vinfo)
2007     return false;
2008
2009   if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def)
2010     return false;
2011
2012   /* Is vectorizable assignment?  */
2013   if (!is_gimple_assign (stmt))
2014     return false;
2015
2016   scalar_dest = gimple_assign_lhs (stmt);
2017   if (TREE_CODE (scalar_dest) != SSA_NAME)
2018     return false;
2019
2020   code = gimple_assign_rhs_code (stmt);
2021   if (gimple_assign_single_p (stmt)
2022       || code == PAREN_EXPR
2023       || CONVERT_EXPR_CODE_P (code))
2024     op = gimple_assign_rhs1 (stmt);
2025   else
2026     return false;
2027
2028   if (!vect_is_simple_use_1 (op, loop_vinfo, bb_vinfo,
2029                              &def_stmt, &def, &dt[0], &vectype_in))
2030     {
2031       if (vect_print_dump_info (REPORT_DETAILS))
2032         fprintf (vect_dump, "use not simple.");
2033       return false;
2034     }
2035
2036   /* We can handle NOP_EXPR conversions that do not change the number
2037      of elements or the vector size.  */
2038   if (CONVERT_EXPR_CODE_P (code)
2039       && (!vectype_in
2040           || TYPE_VECTOR_SUBPARTS (vectype_in) != nunits
2041           || (GET_MODE_SIZE (TYPE_MODE (vectype))
2042               != GET_MODE_SIZE (TYPE_MODE (vectype_in)))))
2043     return false;
2044
2045   if (!vec_stmt) /* transformation not required.  */
2046     {
2047       STMT_VINFO_TYPE (stmt_info) = assignment_vec_info_type;
2048       if (vect_print_dump_info (REPORT_DETAILS))
2049         fprintf (vect_dump, "=== vectorizable_assignment ===");
2050       vect_model_simple_cost (stmt_info, ncopies, dt, NULL);
2051       return true;
2052     }
2053
2054   /** Transform.  **/
2055   if (vect_print_dump_info (REPORT_DETAILS))
2056     fprintf (vect_dump, "transform assignment.");
2057
2058   /* Handle def.  */
2059   vec_dest = vect_create_destination_var (scalar_dest, vectype);
2060
2061   /* Handle use.  */
2062   for (j = 0; j < ncopies; j++)
2063     {
2064       /* Handle uses.  */
2065       if (j == 0)
2066         vect_get_vec_defs (op, NULL, stmt, &vec_oprnds, NULL, slp_node);
2067       else
2068         vect_get_vec_defs_for_stmt_copy (dt, &vec_oprnds, NULL);
2069
2070       /* Arguments are ready. create the new vector stmt.  */
2071       FOR_EACH_VEC_ELT (tree, vec_oprnds, i, vop)
2072        {
2073          if (CONVERT_EXPR_CODE_P (code))
2074            vop = build1 (VIEW_CONVERT_EXPR, vectype, vop);
2075          new_stmt = gimple_build_assign (vec_dest, vop);
2076          new_temp = make_ssa_name (vec_dest, new_stmt);
2077          gimple_assign_set_lhs (new_stmt, new_temp);
2078          vect_finish_stmt_generation (stmt, new_stmt, gsi);
2079          if (slp_node)
2080            VEC_quick_push (gimple, SLP_TREE_VEC_STMTS (slp_node), new_stmt);
2081        }
2082
2083       if (slp_node)
2084         continue;
2085
2086       if (j == 0)
2087         STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt;
2088       else
2089         STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt;
2090
2091       prev_stmt_info = vinfo_for_stmt (new_stmt);
2092     }
2093
2094   VEC_free (tree, heap, vec_oprnds);
2095   return true;
2096 }
2097
2098
2099 /* Function vectorizable_shift.
2100
2101    Check if STMT performs a shift operation that can be vectorized.
2102    If VEC_STMT is also passed, vectorize the STMT: create a vectorized
2103    stmt to replace it, put it in VEC_STMT, and insert it at BSI.
2104    Return FALSE if not a vectorizable STMT, TRUE otherwise.  */
2105
2106 static bool
2107 vectorizable_shift (gimple stmt, gimple_stmt_iterator *gsi,
2108                     gimple *vec_stmt, slp_tree slp_node)
2109 {
2110   tree vec_dest;
2111   tree scalar_dest;
2112   tree op0, op1 = NULL;
2113   tree vec_oprnd1 = NULL_TREE;
2114   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
2115   tree vectype;
2116   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
2117   enum tree_code code;
2118   enum machine_mode vec_mode;
2119   tree new_temp;
2120   optab optab;
2121   int icode;
2122   enum machine_mode optab_op2_mode;
2123   tree def;
2124   gimple def_stmt;
2125   enum vect_def_type dt[2] = {vect_unknown_def_type, vect_unknown_def_type};
2126   gimple new_stmt = NULL;
2127   stmt_vec_info prev_stmt_info;
2128   int nunits_in;
2129   int nunits_out;
2130   tree vectype_out;
2131   int ncopies;
2132   int j, i;
2133   VEC (tree, heap) *vec_oprnds0 = NULL, *vec_oprnds1 = NULL;
2134   tree vop0, vop1;
2135   unsigned int k;
2136   bool scalar_shift_arg = true;
2137   bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info);
2138   int vf;
2139
2140   if (!STMT_VINFO_RELEVANT_P (stmt_info) && !bb_vinfo)
2141     return false;
2142
2143   if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def)
2144     return false;
2145
2146   /* Is STMT a vectorizable binary/unary operation?   */
2147   if (!is_gimple_assign (stmt))
2148     return false;
2149
2150   if (TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
2151     return false;
2152
2153   code = gimple_assign_rhs_code (stmt);
2154
2155   if (!(code == LSHIFT_EXPR || code == RSHIFT_EXPR || code == LROTATE_EXPR
2156       || code == RROTATE_EXPR))
2157     return false;
2158
2159   scalar_dest = gimple_assign_lhs (stmt);
2160   vectype_out = STMT_VINFO_VECTYPE (stmt_info);
2161
2162   op0 = gimple_assign_rhs1 (stmt);
2163   if (!vect_is_simple_use_1 (op0, loop_vinfo, bb_vinfo,
2164                              &def_stmt, &def, &dt[0], &vectype))
2165     {
2166       if (vect_print_dump_info (REPORT_DETAILS))
2167         fprintf (vect_dump, "use not simple.");
2168       return false;
2169     }
2170   /* If op0 is an external or constant def use a vector type with
2171      the same size as the output vector type.  */
2172   if (!vectype)
2173     vectype = get_same_sized_vectype (TREE_TYPE (op0), vectype_out);
2174   if (vec_stmt)
2175     gcc_assert (vectype);
2176   if (!vectype)
2177     {
2178       if (vect_print_dump_info (REPORT_DETAILS))
2179         {
2180           fprintf (vect_dump, "no vectype for scalar type ");
2181           print_generic_expr (vect_dump, TREE_TYPE (op0), TDF_SLIM);
2182         }
2183
2184       return false;
2185     }
2186
2187   nunits_out = TYPE_VECTOR_SUBPARTS (vectype_out);
2188   nunits_in = TYPE_VECTOR_SUBPARTS (vectype);
2189   if (nunits_out != nunits_in)
2190     return false;
2191
2192   op1 = gimple_assign_rhs2 (stmt);
2193   if (!vect_is_simple_use (op1, loop_vinfo, bb_vinfo, &def_stmt, &def, &dt[1]))
2194     {
2195       if (vect_print_dump_info (REPORT_DETAILS))
2196         fprintf (vect_dump, "use not simple.");
2197       return false;
2198     }
2199
2200   if (loop_vinfo)
2201     vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
2202   else
2203     vf = 1;
2204
2205   /* Multiple types in SLP are handled by creating the appropriate number of
2206      vectorized stmts for each SLP node.  Hence, NCOPIES is always 1 in
2207      case of SLP.  */
2208   if (slp_node)
2209     ncopies = 1;
2210   else
2211     ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits_in;
2212
2213   gcc_assert (ncopies >= 1);
2214
2215   /* Determine whether the shift amount is a vector, or scalar.  If the
2216      shift/rotate amount is a vector, use the vector/vector shift optabs.  */
2217
2218   if (dt[1] == vect_internal_def && !slp_node)
2219     scalar_shift_arg = false;
2220   else if (dt[1] == vect_constant_def
2221            || dt[1] == vect_external_def
2222            || dt[1] == vect_internal_def)
2223     {
2224       /* In SLP, need to check whether the shift count is the same,
2225          in loops if it is a constant or invariant, it is always
2226          a scalar shift.  */
2227       if (slp_node)
2228         {
2229           VEC (gimple, heap) *stmts = SLP_TREE_SCALAR_STMTS (slp_node);
2230           gimple slpstmt;
2231
2232           FOR_EACH_VEC_ELT (gimple, stmts, k, slpstmt)
2233             if (!operand_equal_p (gimple_assign_rhs2 (slpstmt), op1, 0))
2234               scalar_shift_arg = false;
2235         }
2236     }
2237   else
2238     {
2239       if (vect_print_dump_info (REPORT_DETAILS))
2240         fprintf (vect_dump, "operand mode requires invariant argument.");
2241       return false;
2242     }
2243
2244   /* Vector shifted by vector.  */
2245   if (!scalar_shift_arg)
2246     {
2247       optab = optab_for_tree_code (code, vectype, optab_vector);
2248       if (vect_print_dump_info (REPORT_DETAILS))
2249         fprintf (vect_dump, "vector/vector shift/rotate found.");
2250     }
2251   /* See if the machine has a vector shifted by scalar insn and if not
2252      then see if it has a vector shifted by vector insn.  */
2253   else
2254     {
2255       optab = optab_for_tree_code (code, vectype, optab_scalar);
2256       if (optab
2257           && optab_handler (optab, TYPE_MODE (vectype)) != CODE_FOR_nothing)
2258         {
2259           if (vect_print_dump_info (REPORT_DETAILS))
2260             fprintf (vect_dump, "vector/scalar shift/rotate found.");
2261         }
2262       else
2263         {
2264           optab = optab_for_tree_code (code, vectype, optab_vector);
2265           if (optab
2266                && (optab_handler (optab, TYPE_MODE (vectype))
2267                       != CODE_FOR_nothing))
2268             {
2269               scalar_shift_arg = false;
2270
2271               if (vect_print_dump_info (REPORT_DETAILS))
2272                 fprintf (vect_dump, "vector/vector shift/rotate found.");
2273
2274               /* Unlike the other binary operators, shifts/rotates have
2275                  the rhs being int, instead of the same type as the lhs,
2276                  so make sure the scalar is the right type if we are
2277                  dealing with vectors of short/char.  */
2278               if (dt[1] == vect_constant_def)
2279                 op1 = fold_convert (TREE_TYPE (vectype), op1);
2280             }
2281         }
2282     }
2283
2284   /* Supportable by target?  */
2285   if (!optab)
2286     {
2287       if (vect_print_dump_info (REPORT_DETAILS))
2288         fprintf (vect_dump, "no optab.");
2289       return false;
2290     }
2291   vec_mode = TYPE_MODE (vectype);
2292   icode = (int) optab_handler (optab, vec_mode);
2293   if (icode == CODE_FOR_nothing)
2294     {
2295       if (vect_print_dump_info (REPORT_DETAILS))
2296         fprintf (vect_dump, "op not supported by target.");
2297       /* Check only during analysis.  */
2298       if (GET_MODE_SIZE (vec_mode) != UNITS_PER_WORD
2299           || (vf < vect_min_worthwhile_factor (code)
2300               && !vec_stmt))
2301         return false;
2302       if (vect_print_dump_info (REPORT_DETAILS))
2303         fprintf (vect_dump, "proceeding using word mode.");
2304     }
2305
2306   /* Worthwhile without SIMD support?  Check only during analysis.  */
2307   if (!VECTOR_MODE_P (TYPE_MODE (vectype))
2308       && vf < vect_min_worthwhile_factor (code)
2309       && !vec_stmt)
2310     {
2311       if (vect_print_dump_info (REPORT_DETAILS))
2312         fprintf (vect_dump, "not worthwhile without SIMD support.");
2313       return false;
2314     }
2315
2316   if (!vec_stmt) /* transformation not required.  */
2317     {
2318       STMT_VINFO_TYPE (stmt_info) = shift_vec_info_type;
2319       if (vect_print_dump_info (REPORT_DETAILS))
2320         fprintf (vect_dump, "=== vectorizable_shift ===");
2321       vect_model_simple_cost (stmt_info, ncopies, dt, NULL);
2322       return true;
2323     }
2324
2325   /** Transform.  **/
2326
2327   if (vect_print_dump_info (REPORT_DETAILS))
2328     fprintf (vect_dump, "transform binary/unary operation.");
2329
2330   /* Handle def.  */
2331   vec_dest = vect_create_destination_var (scalar_dest, vectype);
2332
2333   /* Allocate VECs for vector operands.  In case of SLP, vector operands are
2334      created in the previous stages of the recursion, so no allocation is
2335      needed, except for the case of shift with scalar shift argument.  In that
2336      case we store the scalar operand in VEC_OPRNDS1 for every vector stmt to
2337      be created to vectorize the SLP group, i.e., SLP_NODE->VEC_STMTS_SIZE.
2338      In case of loop-based vectorization we allocate VECs of size 1.  We
2339      allocate VEC_OPRNDS1 only in case of binary operation.  */
2340   if (!slp_node)
2341     {
2342       vec_oprnds0 = VEC_alloc (tree, heap, 1);
2343       vec_oprnds1 = VEC_alloc (tree, heap, 1);
2344     }
2345   else if (scalar_shift_arg)
2346     vec_oprnds1 = VEC_alloc (tree, heap, slp_node->vec_stmts_size);
2347
2348   prev_stmt_info = NULL;
2349   for (j = 0; j < ncopies; j++)
2350     {
2351       /* Handle uses.  */
2352       if (j == 0)
2353         {
2354           if (scalar_shift_arg)
2355             {
2356               /* Vector shl and shr insn patterns can be defined with scalar
2357                  operand 2 (shift operand).  In this case, use constant or loop
2358                  invariant op1 directly, without extending it to vector mode
2359                  first.  */
2360               optab_op2_mode = insn_data[icode].operand[2].mode;
2361               if (!VECTOR_MODE_P (optab_op2_mode))
2362                 {
2363                   if (vect_print_dump_info (REPORT_DETAILS))
2364                     fprintf (vect_dump, "operand 1 using scalar mode.");
2365                   vec_oprnd1 = op1;
2366                   VEC_quick_push (tree, vec_oprnds1, vec_oprnd1);
2367                   if (slp_node)
2368                     {
2369                       /* Store vec_oprnd1 for every vector stmt to be created
2370                          for SLP_NODE.  We check during the analysis that all
2371                          the shift arguments are the same.
2372                          TODO: Allow different constants for different vector
2373                          stmts generated for an SLP instance.  */
2374                       for (k = 0; k < slp_node->vec_stmts_size - 1; k++)
2375                         VEC_quick_push (tree, vec_oprnds1, vec_oprnd1);
2376                     }
2377                 }
2378             }
2379
2380           /* vec_oprnd1 is available if operand 1 should be of a scalar-type
2381              (a special case for certain kind of vector shifts); otherwise,
2382              operand 1 should be of a vector type (the usual case).  */
2383           if (vec_oprnd1)
2384             vect_get_vec_defs (op0, NULL_TREE, stmt, &vec_oprnds0, NULL,
2385                                slp_node);
2386           else
2387             vect_get_vec_defs (op0, op1, stmt, &vec_oprnds0, &vec_oprnds1,
2388                                slp_node);
2389         }
2390       else
2391         vect_get_vec_defs_for_stmt_copy (dt, &vec_oprnds0, &vec_oprnds1);
2392
2393       /* Arguments are ready.  Create the new vector stmt.  */
2394       FOR_EACH_VEC_ELT (tree, vec_oprnds0, i, vop0)
2395         {
2396           vop1 = VEC_index (tree, vec_oprnds1, i);
2397           new_stmt = gimple_build_assign_with_ops (code, vec_dest, vop0, vop1);
2398           new_temp = make_ssa_name (vec_dest, new_stmt);
2399           gimple_assign_set_lhs (new_stmt, new_temp);
2400           vect_finish_stmt_generation (stmt, new_stmt, gsi);
2401           if (slp_node)
2402             VEC_quick_push (gimple, SLP_TREE_VEC_STMTS (slp_node), new_stmt);
2403         }
2404
2405       if (slp_node)
2406         continue;
2407
2408       if (j == 0)
2409         STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt;
2410       else
2411         STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt;
2412       prev_stmt_info = vinfo_for_stmt (new_stmt);
2413     }
2414
2415   VEC_free (tree, heap, vec_oprnds0);
2416   VEC_free (tree, heap, vec_oprnds1);
2417
2418   return true;
2419 }
2420
2421
2422 /* Function vectorizable_operation.
2423
2424    Check if STMT performs a binary, unary or ternary operation that can
2425    be vectorized.
2426    If VEC_STMT is also passed, vectorize the STMT: create a vectorized
2427    stmt to replace it, put it in VEC_STMT, and insert it at BSI.
2428    Return FALSE if not a vectorizable STMT, TRUE otherwise.  */
2429
2430 static bool
2431 vectorizable_operation (gimple stmt, gimple_stmt_iterator *gsi,
2432                         gimple *vec_stmt, slp_tree slp_node)
2433 {
2434   tree vec_dest;
2435   tree scalar_dest;
2436   tree op0, op1 = NULL_TREE, op2 = NULL_TREE;
2437   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
2438   tree vectype;
2439   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
2440   enum tree_code code;
2441   enum machine_mode vec_mode;
2442   tree new_temp;
2443   int op_type;
2444   optab optab;
2445   int icode;
2446   tree def;
2447   gimple def_stmt;
2448   enum vect_def_type dt[3]
2449     = {vect_unknown_def_type, vect_unknown_def_type, vect_unknown_def_type};
2450   gimple new_stmt = NULL;
2451   stmt_vec_info prev_stmt_info;
2452   int nunits_in;
2453   int nunits_out;
2454   tree vectype_out;
2455   int ncopies;
2456   int j, i;
2457   VEC(tree,heap) *vec_oprnds0 = NULL, *vec_oprnds1 = NULL, *vec_oprnds2 = NULL;
2458   tree vop0, vop1, vop2;
2459   bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info);
2460   int vf;
2461
2462   if (!STMT_VINFO_RELEVANT_P (stmt_info) && !bb_vinfo)
2463     return false;
2464
2465   if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def)
2466     return false;
2467
2468   /* Is STMT a vectorizable binary/unary operation?   */
2469   if (!is_gimple_assign (stmt))
2470     return false;
2471
2472   if (TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
2473     return false;
2474
2475   code = gimple_assign_rhs_code (stmt);
2476
2477   /* For pointer addition, we should use the normal plus for
2478      the vector addition.  */
2479   if (code == POINTER_PLUS_EXPR)
2480     code = PLUS_EXPR;
2481
2482   /* Support only unary or binary operations.  */
2483   op_type = TREE_CODE_LENGTH (code);
2484   if (op_type != unary_op && op_type != binary_op && op_type != ternary_op)
2485     {
2486       if (vect_print_dump_info (REPORT_DETAILS))
2487         fprintf (vect_dump, "num. args = %d (not unary/binary/ternary op).",
2488                  op_type);
2489       return false;
2490     }
2491
2492   scalar_dest = gimple_assign_lhs (stmt);
2493   vectype_out = STMT_VINFO_VECTYPE (stmt_info);
2494
2495   op0 = gimple_assign_rhs1 (stmt);
2496   if (!vect_is_simple_use_1 (op0, loop_vinfo, bb_vinfo,
2497                              &def_stmt, &def, &dt[0], &vectype))
2498     {
2499       if (vect_print_dump_info (REPORT_DETAILS))
2500         fprintf (vect_dump, "use not simple.");
2501       return false;
2502     }
2503   /* If op0 is an external or constant def use a vector type with
2504      the same size as the output vector type.  */
2505   if (!vectype)
2506     vectype = get_same_sized_vectype (TREE_TYPE (op0), vectype_out);
2507   if (vec_stmt)
2508     gcc_assert (vectype);
2509   if (!vectype)
2510     {
2511       if (vect_print_dump_info (REPORT_DETAILS))
2512         {
2513           fprintf (vect_dump, "no vectype for scalar type ");
2514           print_generic_expr (vect_dump, TREE_TYPE (op0), TDF_SLIM);
2515         }
2516
2517       return false;
2518     }
2519
2520   nunits_out = TYPE_VECTOR_SUBPARTS (vectype_out);
2521   nunits_in = TYPE_VECTOR_SUBPARTS (vectype);
2522   if (nunits_out != nunits_in)
2523     return false;
2524
2525   if (op_type == binary_op || op_type == ternary_op)
2526     {
2527       op1 = gimple_assign_rhs2 (stmt);
2528       if (!vect_is_simple_use (op1, loop_vinfo, bb_vinfo, &def_stmt, &def,
2529                                &dt[1]))
2530         {
2531           if (vect_print_dump_info (REPORT_DETAILS))
2532             fprintf (vect_dump, "use not simple.");
2533           return false;
2534         }
2535     }
2536   if (op_type == ternary_op)
2537     {
2538       op2 = gimple_assign_rhs3 (stmt);
2539       if (!vect_is_simple_use (op2, loop_vinfo, bb_vinfo, &def_stmt, &def,
2540                                &dt[2]))
2541         {
2542           if (vect_print_dump_info (REPORT_DETAILS))
2543             fprintf (vect_dump, "use not simple.");
2544           return false;
2545         }
2546     }
2547
2548   if (loop_vinfo)
2549     vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
2550   else
2551     vf = 1;
2552
2553   /* Multiple types in SLP are handled by creating the appropriate number of
2554      vectorized stmts for each SLP node.  Hence, NCOPIES is always 1 in
2555      case of SLP.  */
2556   if (slp_node)
2557     ncopies = 1;
2558   else
2559     ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits_in;
2560
2561   gcc_assert (ncopies >= 1);
2562
2563   /* Shifts are handled in vectorizable_shift ().  */
2564   if (code == LSHIFT_EXPR || code == RSHIFT_EXPR || code == LROTATE_EXPR
2565       || code == RROTATE_EXPR)
2566    return false;
2567
2568   optab = optab_for_tree_code (code, vectype, optab_default);
2569
2570   /* Supportable by target?  */
2571   if (!optab)
2572     {
2573       if (vect_print_dump_info (REPORT_DETAILS))
2574         fprintf (vect_dump, "no optab.");
2575       return false;
2576     }
2577   vec_mode = TYPE_MODE (vectype);
2578   icode = (int) optab_handler (optab, vec_mode);
2579   if (icode == CODE_FOR_nothing)
2580     {
2581       if (vect_print_dump_info (REPORT_DETAILS))
2582         fprintf (vect_dump, "op not supported by target.");
2583       /* Check only during analysis.  */
2584       if (GET_MODE_SIZE (vec_mode) != UNITS_PER_WORD
2585           || (vf < vect_min_worthwhile_factor (code)
2586               && !vec_stmt))
2587         return false;
2588       if (vect_print_dump_info (REPORT_DETAILS))
2589         fprintf (vect_dump, "proceeding using word mode.");
2590     }
2591
2592   /* Worthwhile without SIMD support?  Check only during analysis.  */
2593   if (!VECTOR_MODE_P (TYPE_MODE (vectype))
2594       && vf < vect_min_worthwhile_factor (code)
2595       && !vec_stmt)
2596     {
2597       if (vect_print_dump_info (REPORT_DETAILS))
2598         fprintf (vect_dump, "not worthwhile without SIMD support.");
2599       return false;
2600     }
2601
2602   if (!vec_stmt) /* transformation not required.  */
2603     {
2604       STMT_VINFO_TYPE (stmt_info) = op_vec_info_type;
2605       if (vect_print_dump_info (REPORT_DETAILS))
2606         fprintf (vect_dump, "=== vectorizable_operation ===");
2607       vect_model_simple_cost (stmt_info, ncopies, dt, NULL);
2608       return true;
2609     }
2610
2611   /** Transform.  **/
2612
2613   if (vect_print_dump_info (REPORT_DETAILS))
2614     fprintf (vect_dump, "transform binary/unary operation.");
2615
2616   /* Handle def.  */
2617   vec_dest = vect_create_destination_var (scalar_dest, vectype);
2618
2619   /* Allocate VECs for vector operands.  In case of SLP, vector operands are
2620      created in the previous stages of the recursion, so no allocation is
2621      needed, except for the case of shift with scalar shift argument.  In that
2622      case we store the scalar operand in VEC_OPRNDS1 for every vector stmt to
2623      be created to vectorize the SLP group, i.e., SLP_NODE->VEC_STMTS_SIZE.
2624      In case of loop-based vectorization we allocate VECs of size 1.  We
2625      allocate VEC_OPRNDS1 only in case of binary operation.  */
2626   if (!slp_node)
2627     {
2628       vec_oprnds0 = VEC_alloc (tree, heap, 1);
2629       if (op_type == binary_op || op_type == ternary_op)
2630         vec_oprnds1 = VEC_alloc (tree, heap, 1);
2631       if (op_type == ternary_op)
2632         vec_oprnds2 = VEC_alloc (tree, heap, 1);
2633     }
2634
2635   /* In case the vectorization factor (VF) is bigger than the number
2636      of elements that we can fit in a vectype (nunits), we have to generate
2637      more than one vector stmt - i.e - we need to "unroll" the
2638      vector stmt by a factor VF/nunits.  In doing so, we record a pointer
2639      from one copy of the vector stmt to the next, in the field
2640      STMT_VINFO_RELATED_STMT.  This is necessary in order to allow following
2641      stages to find the correct vector defs to be used when vectorizing
2642      stmts that use the defs of the current stmt.  The example below
2643      illustrates the vectorization process when VF=16 and nunits=4 (i.e.,
2644      we need to create 4 vectorized stmts):
2645
2646      before vectorization:
2647                                 RELATED_STMT    VEC_STMT
2648         S1:     x = memref      -               -
2649         S2:     z = x + 1       -               -
2650
2651      step 1: vectorize stmt S1 (done in vectorizable_load. See more details
2652              there):
2653                                 RELATED_STMT    VEC_STMT
2654         VS1_0:  vx0 = memref0   VS1_1           -
2655         VS1_1:  vx1 = memref1   VS1_2           -
2656         VS1_2:  vx2 = memref2   VS1_3           -
2657         VS1_3:  vx3 = memref3   -               -
2658         S1:     x = load        -               VS1_0
2659         S2:     z = x + 1       -               -
2660
2661      step2: vectorize stmt S2 (done here):
2662         To vectorize stmt S2 we first need to find the relevant vector
2663         def for the first operand 'x'.  This is, as usual, obtained from
2664         the vector stmt recorded in the STMT_VINFO_VEC_STMT of the stmt
2665         that defines 'x' (S1).  This way we find the stmt VS1_0, and the
2666         relevant vector def 'vx0'.  Having found 'vx0' we can generate
2667         the vector stmt VS2_0, and as usual, record it in the
2668         STMT_VINFO_VEC_STMT of stmt S2.
2669         When creating the second copy (VS2_1), we obtain the relevant vector
2670         def from the vector stmt recorded in the STMT_VINFO_RELATED_STMT of
2671         stmt VS1_0.  This way we find the stmt VS1_1 and the relevant
2672         vector def 'vx1'.  Using 'vx1' we create stmt VS2_1 and record a
2673         pointer to it in the STMT_VINFO_RELATED_STMT of the vector stmt VS2_0.
2674         Similarly when creating stmts VS2_2 and VS2_3.  This is the resulting
2675         chain of stmts and pointers:
2676                                 RELATED_STMT    VEC_STMT
2677         VS1_0:  vx0 = memref0   VS1_1           -
2678         VS1_1:  vx1 = memref1   VS1_2           -
2679         VS1_2:  vx2 = memref2   VS1_3           -
2680         VS1_3:  vx3 = memref3   -               -
2681         S1:     x = load        -               VS1_0
2682         VS2_0:  vz0 = vx0 + v1  VS2_1           -
2683         VS2_1:  vz1 = vx1 + v1  VS2_2           -
2684         VS2_2:  vz2 = vx2 + v1  VS2_3           -
2685         VS2_3:  vz3 = vx3 + v1  -               -
2686         S2:     z = x + 1       -               VS2_0  */
2687
2688   prev_stmt_info = NULL;
2689   for (j = 0; j < ncopies; j++)
2690     {
2691       /* Handle uses.  */
2692       if (j == 0)
2693         {
2694           if (op_type == binary_op || op_type == ternary_op)
2695             vect_get_vec_defs (op0, op1, stmt, &vec_oprnds0, &vec_oprnds1,
2696                                slp_node);
2697           else
2698             vect_get_vec_defs (op0, NULL_TREE, stmt, &vec_oprnds0, NULL,
2699                                slp_node);
2700           if (op_type == ternary_op)
2701             {
2702               vec_oprnds2 = VEC_alloc (tree, heap, 1);
2703               VEC_quick_push (tree, vec_oprnds2,
2704                               vect_get_vec_def_for_operand (op2, stmt, NULL));
2705             }
2706         }
2707       else
2708         {
2709           vect_get_vec_defs_for_stmt_copy (dt, &vec_oprnds0, &vec_oprnds1);
2710           if (op_type == ternary_op)
2711             {
2712               tree vec_oprnd = VEC_pop (tree, vec_oprnds2);
2713               VEC_quick_push (tree, vec_oprnds2,
2714                               vect_get_vec_def_for_stmt_copy (dt[2],
2715                                                               vec_oprnd));
2716             }
2717         }
2718
2719       /* Arguments are ready.  Create the new vector stmt.  */
2720       FOR_EACH_VEC_ELT (tree, vec_oprnds0, i, vop0)
2721         {
2722           vop1 = ((op_type == binary_op || op_type == ternary_op)
2723                   ? VEC_index (tree, vec_oprnds1, i) : NULL_TREE);
2724           vop2 = ((op_type == ternary_op)
2725                   ? VEC_index (tree, vec_oprnds2, i) : NULL_TREE);
2726           new_stmt = gimple_build_assign_with_ops3 (code, vec_dest,
2727                                                     vop0, vop1, vop2);
2728           new_temp = make_ssa_name (vec_dest, new_stmt);
2729           gimple_assign_set_lhs (new_stmt, new_temp);
2730           vect_finish_stmt_generation (stmt, new_stmt, gsi);
2731           if (slp_node)
2732             VEC_quick_push (gimple, SLP_TREE_VEC_STMTS (slp_node), new_stmt);
2733         }
2734
2735       if (slp_node)
2736         continue;
2737
2738       if (j == 0)
2739         STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt;
2740       else
2741         STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt;
2742       prev_stmt_info = vinfo_for_stmt (new_stmt);
2743     }
2744
2745   VEC_free (tree, heap, vec_oprnds0);
2746   if (vec_oprnds1)
2747     VEC_free (tree, heap, vec_oprnds1);
2748   if (vec_oprnds2)
2749     VEC_free (tree, heap, vec_oprnds2);
2750
2751   return true;
2752 }
2753
2754
2755 /* Get vectorized definitions for loop-based vectorization.  For the first
2756    operand we call vect_get_vec_def_for_operand() (with OPRND containing
2757    scalar operand), and for the rest we get a copy with
2758    vect_get_vec_def_for_stmt_copy() using the previous vector definition
2759    (stored in OPRND). See vect_get_vec_def_for_stmt_copy() for details.
2760    The vectors are collected into VEC_OPRNDS.  */
2761
2762 static void
2763 vect_get_loop_based_defs (tree *oprnd, gimple stmt, enum vect_def_type dt,
2764                           VEC (tree, heap) **vec_oprnds, int multi_step_cvt)
2765 {
2766   tree vec_oprnd;
2767
2768   /* Get first vector operand.  */
2769   /* All the vector operands except the very first one (that is scalar oprnd)
2770      are stmt copies.  */
2771   if (TREE_CODE (TREE_TYPE (*oprnd)) != VECTOR_TYPE)
2772     vec_oprnd = vect_get_vec_def_for_operand (*oprnd, stmt, NULL);
2773   else
2774     vec_oprnd = vect_get_vec_def_for_stmt_copy (dt, *oprnd);
2775
2776   VEC_quick_push (tree, *vec_oprnds, vec_oprnd);
2777
2778   /* Get second vector operand.  */
2779   vec_oprnd = vect_get_vec_def_for_stmt_copy (dt, vec_oprnd);
2780   VEC_quick_push (tree, *vec_oprnds, vec_oprnd);
2781
2782   *oprnd = vec_oprnd;
2783
2784   /* For conversion in multiple steps, continue to get operands
2785      recursively.  */
2786   if (multi_step_cvt)
2787     vect_get_loop_based_defs (oprnd, stmt, dt, vec_oprnds,  multi_step_cvt - 1);
2788 }
2789
2790
2791 /* Create vectorized demotion statements for vector operands from VEC_OPRNDS.
2792    For multi-step conversions store the resulting vectors and call the function
2793    recursively.  */
2794
2795 static void
2796 vect_create_vectorized_demotion_stmts (VEC (tree, heap) **vec_oprnds,
2797                                        int multi_step_cvt, gimple stmt,
2798                                        VEC (tree, heap) *vec_dsts,
2799                                        gimple_stmt_iterator *gsi,
2800                                        slp_tree slp_node, enum tree_code code,
2801                                        stmt_vec_info *prev_stmt_info)
2802 {
2803   unsigned int i;
2804   tree vop0, vop1, new_tmp, vec_dest;
2805   gimple new_stmt;
2806   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
2807
2808   vec_dest = VEC_pop (tree, vec_dsts);
2809
2810   for (i = 0; i < VEC_length (tree, *vec_oprnds); i += 2)
2811     {
2812       /* Create demotion operation.  */
2813       vop0 = VEC_index (tree, *vec_oprnds, i);
2814       vop1 = VEC_index (tree, *vec_oprnds, i + 1);
2815       new_stmt = gimple_build_assign_with_ops (code, vec_dest, vop0, vop1);
2816       new_tmp = make_ssa_name (vec_dest, new_stmt);
2817       gimple_assign_set_lhs (new_stmt, new_tmp);
2818       vect_finish_stmt_generation (stmt, new_stmt, gsi);
2819
2820       if (multi_step_cvt)
2821         /* Store the resulting vector for next recursive call.  */
2822         VEC_replace (tree, *vec_oprnds, i/2, new_tmp);
2823       else
2824         {
2825           /* This is the last step of the conversion sequence. Store the
2826              vectors in SLP_NODE or in vector info of the scalar statement
2827              (or in STMT_VINFO_RELATED_STMT chain).  */
2828           if (slp_node)
2829             VEC_quick_push (gimple, SLP_TREE_VEC_STMTS (slp_node), new_stmt);
2830           else
2831             {
2832               if (!*prev_stmt_info)
2833                 STMT_VINFO_VEC_STMT (stmt_info) = new_stmt;
2834               else
2835                 STMT_VINFO_RELATED_STMT (*prev_stmt_info) = new_stmt;
2836
2837               *prev_stmt_info = vinfo_for_stmt (new_stmt);
2838             }
2839         }
2840     }
2841
2842   /* For multi-step demotion operations we first generate demotion operations
2843      from the source type to the intermediate types, and then combine the
2844      results (stored in VEC_OPRNDS) in demotion operation to the destination
2845      type.  */
2846   if (multi_step_cvt)
2847     {
2848       /* At each level of recursion we have have of the operands we had at the
2849          previous level.  */
2850       VEC_truncate (tree, *vec_oprnds, (i+1)/2);
2851       vect_create_vectorized_demotion_stmts (vec_oprnds, multi_step_cvt - 1,
2852                                              stmt, vec_dsts, gsi, slp_node,
2853                                              code, prev_stmt_info);
2854     }
2855 }
2856
2857
2858 /* Function vectorizable_type_demotion
2859
2860    Check if STMT performs a binary or unary operation that involves
2861    type demotion, and if it can be vectorized.
2862    If VEC_STMT is also passed, vectorize the STMT: create a vectorized
2863    stmt to replace it, put it in VEC_STMT, and insert it at BSI.
2864    Return FALSE if not a vectorizable STMT, TRUE otherwise.  */
2865
2866 static bool
2867 vectorizable_type_demotion (gimple stmt, gimple_stmt_iterator *gsi,
2868                             gimple *vec_stmt, slp_tree slp_node)
2869 {
2870   tree vec_dest;
2871   tree scalar_dest;
2872   tree op0;
2873   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
2874   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
2875   enum tree_code code, code1 = ERROR_MARK;
2876   tree def;
2877   gimple def_stmt;
2878   enum vect_def_type dt[2] = {vect_unknown_def_type, vect_unknown_def_type};
2879   stmt_vec_info prev_stmt_info;
2880   int nunits_in;
2881   int nunits_out;
2882   tree vectype_out;
2883   int ncopies;
2884   int j, i;
2885   tree vectype_in;
2886   int multi_step_cvt = 0;
2887   VEC (tree, heap) *vec_oprnds0 = NULL;
2888   VEC (tree, heap) *vec_dsts = NULL, *interm_types = NULL, *tmp_vec_dsts = NULL;
2889   tree last_oprnd, intermediate_type;
2890
2891   /* FORNOW: not supported by basic block SLP vectorization.  */
2892   gcc_assert (loop_vinfo);
2893
2894   if (!STMT_VINFO_RELEVANT_P (stmt_info))
2895     return false;
2896
2897   if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def)
2898     return false;
2899
2900   /* Is STMT a vectorizable type-demotion operation?  */
2901   if (!is_gimple_assign (stmt))
2902     return false;
2903
2904   if (TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
2905     return false;
2906
2907   code = gimple_assign_rhs_code (stmt);
2908   if (!CONVERT_EXPR_CODE_P (code))
2909     return false;
2910
2911   scalar_dest = gimple_assign_lhs (stmt);
2912   vectype_out = STMT_VINFO_VECTYPE (stmt_info);
2913
2914   /* Check the operands of the operation.  */
2915   op0 = gimple_assign_rhs1 (stmt);
2916   if (! ((INTEGRAL_TYPE_P (TREE_TYPE (scalar_dest))
2917           && INTEGRAL_TYPE_P (TREE_TYPE (op0)))
2918          || (SCALAR_FLOAT_TYPE_P (TREE_TYPE (scalar_dest))
2919              && SCALAR_FLOAT_TYPE_P (TREE_TYPE (op0))
2920              && CONVERT_EXPR_CODE_P (code))))
2921     return false;
2922   if (!vect_is_simple_use_1 (op0, loop_vinfo, NULL,
2923                              &def_stmt, &def, &dt[0], &vectype_in))
2924     {
2925       if (vect_print_dump_info (REPORT_DETAILS))
2926         fprintf (vect_dump, "use not simple.");
2927       return false;
2928     }
2929   /* If op0 is an external def use a vector type with the
2930      same size as the output vector type if possible.  */
2931   if (!vectype_in)
2932     vectype_in = get_same_sized_vectype (TREE_TYPE (op0), vectype_out);
2933   if (vec_stmt)
2934     gcc_assert (vectype_in);
2935   if (!vectype_in)
2936     {
2937       if (vect_print_dump_info (REPORT_DETAILS))
2938         {
2939           fprintf (vect_dump, "no vectype for scalar type ");
2940           print_generic_expr (vect_dump, TREE_TYPE (op0), TDF_SLIM);
2941         }
2942
2943       return false;
2944     }
2945
2946   nunits_in = TYPE_VECTOR_SUBPARTS (vectype_in);
2947   nunits_out = TYPE_VECTOR_SUBPARTS (vectype_out);
2948   if (nunits_in >= nunits_out)
2949     return false;
2950
2951   /* Multiple types in SLP are handled by creating the appropriate number of
2952      vectorized stmts for each SLP node.  Hence, NCOPIES is always 1 in
2953      case of SLP.  */
2954   if (slp_node)
2955     ncopies = 1;
2956   else
2957     ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits_out;
2958   gcc_assert (ncopies >= 1);
2959
2960   /* Supportable by target?  */
2961   if (!supportable_narrowing_operation (code, vectype_out, vectype_in,
2962                                         &code1, &multi_step_cvt, &interm_types))
2963     return false;
2964
2965   if (!vec_stmt) /* transformation not required.  */
2966     {
2967       STMT_VINFO_TYPE (stmt_info) = type_demotion_vec_info_type;
2968       if (vect_print_dump_info (REPORT_DETAILS))
2969         fprintf (vect_dump, "=== vectorizable_demotion ===");
2970       vect_model_promotion_demotion_cost (stmt_info, dt, multi_step_cvt);
2971       return true;
2972     }
2973
2974   /** Transform.  **/
2975   if (vect_print_dump_info (REPORT_DETAILS))
2976     fprintf (vect_dump, "transform type demotion operation. ncopies = %d.",
2977              ncopies);
2978
2979   /* In case of multi-step demotion, we first generate demotion operations to
2980      the intermediate types, and then from that types to the final one.
2981      We create vector destinations for the intermediate type (TYPES) received
2982      from supportable_narrowing_operation, and store them in the correct order
2983      for future use in vect_create_vectorized_demotion_stmts().  */
2984   if (multi_step_cvt)
2985     vec_dsts = VEC_alloc (tree, heap, multi_step_cvt + 1);
2986   else
2987     vec_dsts = VEC_alloc (tree, heap, 1);
2988
2989   vec_dest = vect_create_destination_var (scalar_dest, vectype_out);
2990   VEC_quick_push (tree, vec_dsts, vec_dest);
2991
2992   if (multi_step_cvt)
2993     {
2994       for (i = VEC_length (tree, interm_types) - 1;
2995            VEC_iterate (tree, interm_types, i, intermediate_type); i--)
2996         {
2997           vec_dest = vect_create_destination_var (scalar_dest,
2998                                                   intermediate_type);
2999           VEC_quick_push (tree, vec_dsts, vec_dest);
3000         }
3001     }
3002
3003   /* In case the vectorization factor (VF) is bigger than the number
3004      of elements that we can fit in a vectype (nunits), we have to generate
3005      more than one vector stmt - i.e - we need to "unroll" the
3006      vector stmt by a factor VF/nunits.   */
3007   last_oprnd = op0;
3008   prev_stmt_info = NULL;
3009   for (j = 0; j < ncopies; j++)
3010     {
3011       /* Handle uses.  */
3012       if (slp_node)
3013         vect_get_slp_defs (op0, NULL_TREE, slp_node, &vec_oprnds0, NULL, -1);
3014       else
3015         {
3016           VEC_free (tree, heap, vec_oprnds0);
3017           vec_oprnds0 = VEC_alloc (tree, heap,
3018                         (multi_step_cvt ? vect_pow2 (multi_step_cvt) * 2 : 2));
3019           vect_get_loop_based_defs (&last_oprnd, stmt, dt[0], &vec_oprnds0,
3020                                     vect_pow2 (multi_step_cvt) - 1);
3021         }
3022
3023       /* Arguments are ready.  Create the new vector stmts.  */
3024       tmp_vec_dsts = VEC_copy (tree, heap, vec_dsts);
3025       vect_create_vectorized_demotion_stmts (&vec_oprnds0,
3026                                              multi_step_cvt, stmt, tmp_vec_dsts,
3027                                              gsi, slp_node, code1,
3028                                              &prev_stmt_info);
3029     }
3030
3031   VEC_free (tree, heap, vec_oprnds0);
3032   VEC_free (tree, heap, vec_dsts);
3033   VEC_free (tree, heap, tmp_vec_dsts);
3034   VEC_free (tree, heap, interm_types);
3035
3036   *vec_stmt = STMT_VINFO_VEC_STMT (stmt_info);
3037   return true;
3038 }
3039
3040
3041 /* Create vectorized promotion statements for vector operands from VEC_OPRNDS0
3042    and VEC_OPRNDS1 (for binary operations).  For multi-step conversions store
3043    the resulting vectors and call the function recursively.  */
3044
3045 static void
3046 vect_create_vectorized_promotion_stmts (VEC (tree, heap) **vec_oprnds0,
3047                                         VEC (tree, heap) **vec_oprnds1,
3048                                         int multi_step_cvt, gimple stmt,
3049                                         VEC (tree, heap) *vec_dsts,
3050                                         gimple_stmt_iterator *gsi,
3051                                         slp_tree slp_node, enum tree_code code1,
3052                                         enum tree_code code2, tree decl1,
3053                                         tree decl2, int op_type,
3054                                         stmt_vec_info *prev_stmt_info)
3055 {
3056   int i;
3057   tree vop0, vop1, new_tmp1, new_tmp2, vec_dest;
3058   gimple new_stmt1, new_stmt2;
3059   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
3060   VEC (tree, heap) *vec_tmp;
3061
3062   vec_dest = VEC_pop (tree, vec_dsts);
3063   vec_tmp = VEC_alloc (tree, heap, VEC_length (tree, *vec_oprnds0) * 2);
3064
3065   FOR_EACH_VEC_ELT (tree, *vec_oprnds0, i, vop0)
3066     {
3067       if (op_type == binary_op)
3068         vop1 = VEC_index (tree, *vec_oprnds1, i);
3069       else
3070         vop1 = NULL_TREE;
3071
3072       /* Generate the two halves of promotion operation.  */
3073       new_stmt1 = vect_gen_widened_results_half (code1, decl1, vop0, vop1,
3074                                                  op_type, vec_dest, gsi, stmt);
3075       new_stmt2 = vect_gen_widened_results_half (code2, decl2, vop0, vop1,
3076                                                  op_type, vec_dest, gsi, stmt);
3077       if (is_gimple_call (new_stmt1))
3078         {
3079           new_tmp1 = gimple_call_lhs (new_stmt1);
3080           new_tmp2 = gimple_call_lhs (new_stmt2);
3081         }
3082       else
3083         {
3084           new_tmp1 = gimple_assign_lhs (new_stmt1);
3085           new_tmp2 = gimple_assign_lhs (new_stmt2);
3086         }
3087
3088       if (multi_step_cvt)
3089         {
3090           /* Store the results for the recursive call.  */
3091           VEC_quick_push (tree, vec_tmp, new_tmp1);
3092           VEC_quick_push (tree, vec_tmp, new_tmp2);
3093         }
3094       else
3095         {
3096           /* Last step of promotion sequience - store the results.  */
3097           if (slp_node)
3098             {
3099               VEC_quick_push (gimple, SLP_TREE_VEC_STMTS (slp_node), new_stmt1);
3100               VEC_quick_push (gimple, SLP_TREE_VEC_STMTS (slp_node), new_stmt2);
3101             }
3102           else
3103             {
3104               if (!*prev_stmt_info)
3105                 STMT_VINFO_VEC_STMT (stmt_info) = new_stmt1;
3106               else
3107                 STMT_VINFO_RELATED_STMT (*prev_stmt_info) = new_stmt1;
3108
3109               *prev_stmt_info = vinfo_for_stmt (new_stmt1);
3110               STMT_VINFO_RELATED_STMT (*prev_stmt_info) = new_stmt2;
3111               *prev_stmt_info = vinfo_for_stmt (new_stmt2);
3112             }
3113         }
3114     }
3115
3116   if (multi_step_cvt)
3117     {
3118       /* For multi-step promotion operation we first generate we call the
3119          function recurcively for every stage.  We start from the input type,
3120          create promotion operations to the intermediate types, and then
3121          create promotions to the output type.  */
3122       *vec_oprnds0 = VEC_copy (tree, heap, vec_tmp);
3123       vect_create_vectorized_promotion_stmts (vec_oprnds0, vec_oprnds1,
3124                                               multi_step_cvt - 1, stmt,
3125                                               vec_dsts, gsi, slp_node, code1,
3126                                               code2, decl2, decl2, op_type,
3127                                               prev_stmt_info);
3128     }
3129
3130   VEC_free (tree, heap, vec_tmp);
3131 }
3132
3133
3134 /* Function vectorizable_type_promotion
3135
3136    Check if STMT performs a binary or unary operation that involves
3137    type promotion, and if it can be vectorized.
3138    If VEC_STMT is also passed, vectorize the STMT: create a vectorized
3139    stmt to replace it, put it in VEC_STMT, and insert it at BSI.
3140    Return FALSE if not a vectorizable STMT, TRUE otherwise.  */
3141
3142 static bool
3143 vectorizable_type_promotion (gimple stmt, gimple_stmt_iterator *gsi,
3144                              gimple *vec_stmt, slp_tree slp_node)
3145 {
3146   tree vec_dest;
3147   tree scalar_dest;
3148   tree op0, op1 = NULL;
3149   tree vec_oprnd0=NULL, vec_oprnd1=NULL;
3150   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
3151   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
3152   enum tree_code code, code1 = ERROR_MARK, code2 = ERROR_MARK;
3153   tree decl1 = NULL_TREE, decl2 = NULL_TREE;
3154   int op_type;
3155   tree def;
3156   gimple def_stmt;
3157   enum vect_def_type dt[2] = {vect_unknown_def_type, vect_unknown_def_type};
3158   stmt_vec_info prev_stmt_info;
3159   int nunits_in;
3160   int nunits_out;
3161   tree vectype_out;
3162   int ncopies;
3163   int j, i;
3164   tree vectype_in;
3165   tree intermediate_type = NULL_TREE;
3166   int multi_step_cvt = 0;
3167   VEC (tree, heap) *vec_oprnds0 = NULL, *vec_oprnds1 = NULL;
3168   VEC (tree, heap) *vec_dsts = NULL, *interm_types = NULL, *tmp_vec_dsts = NULL;
3169
3170   /* FORNOW: not supported by basic block SLP vectorization.  */
3171   gcc_assert (loop_vinfo);
3172
3173   if (!STMT_VINFO_RELEVANT_P (stmt_info))
3174     return false;
3175
3176   if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def)
3177     return false;
3178
3179   /* Is STMT a vectorizable type-promotion operation?  */
3180   if (!is_gimple_assign (stmt))
3181     return false;
3182
3183   if (TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
3184     return false;
3185
3186   code = gimple_assign_rhs_code (stmt);
3187   if (!CONVERT_EXPR_CODE_P (code)
3188       && code != WIDEN_MULT_EXPR)
3189     return false;
3190
3191   scalar_dest = gimple_assign_lhs (stmt);
3192   vectype_out = STMT_VINFO_VECTYPE (stmt_info);
3193
3194   /* Check the operands of the operation.  */
3195   op0 = gimple_assign_rhs1 (stmt);
3196   if (! ((INTEGRAL_TYPE_P (TREE_TYPE (scalar_dest))
3197           && INTEGRAL_TYPE_P (TREE_TYPE (op0)))
3198          || (SCALAR_FLOAT_TYPE_P (TREE_TYPE (scalar_dest))
3199              && SCALAR_FLOAT_TYPE_P (TREE_TYPE (op0))
3200              && CONVERT_EXPR_CODE_P (code))))
3201     return false;
3202   if (!vect_is_simple_use_1 (op0, loop_vinfo, NULL,
3203                              &def_stmt, &def, &dt[0], &vectype_in))
3204     {
3205       if (vect_print_dump_info (REPORT_DETAILS))
3206         fprintf (vect_dump, "use not simple.");
3207       return false;
3208     }
3209   /* If op0 is an external or constant def use a vector type with
3210      the same size as the output vector type.  */
3211   if (!vectype_in)
3212     vectype_in = get_same_sized_vectype (TREE_TYPE (op0), vectype_out);
3213   if (vec_stmt)
3214     gcc_assert (vectype_in);
3215   if (!vectype_in)
3216     {
3217       if (vect_print_dump_info (REPORT_DETAILS))
3218         {
3219           fprintf (vect_dump, "no vectype for scalar type ");
3220           print_generic_expr (vect_dump, TREE_TYPE (op0), TDF_SLIM);
3221         }
3222
3223       return false;
3224     }
3225
3226   nunits_in = TYPE_VECTOR_SUBPARTS (vectype_in);
3227   nunits_out = TYPE_VECTOR_SUBPARTS (vectype_out);
3228   if (nunits_in <= nunits_out)
3229     return false;
3230
3231   /* Multiple types in SLP are handled by creating the appropriate number of
3232      vectorized stmts for each SLP node.  Hence, NCOPIES is always 1 in
3233      case of SLP.  */
3234   if (slp_node)
3235     ncopies = 1;
3236   else
3237     ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits_in;
3238
3239   gcc_assert (ncopies >= 1);
3240
3241   op_type = TREE_CODE_LENGTH (code);
3242   if (op_type == binary_op)
3243     {
3244       op1 = gimple_assign_rhs2 (stmt);
3245       if (!vect_is_simple_use (op1, loop_vinfo, NULL, &def_stmt, &def, &dt[1]))
3246         {
3247           if (vect_print_dump_info (REPORT_DETAILS))
3248             fprintf (vect_dump, "use not simple.");
3249           return false;
3250         }
3251     }
3252
3253   /* Supportable by target?  */
3254   if (!supportable_widening_operation (code, stmt, vectype_out, vectype_in,
3255                                        &decl1, &decl2, &code1, &code2,
3256                                        &multi_step_cvt, &interm_types))
3257     return false;
3258
3259   /* Binary widening operation can only be supported directly by the
3260      architecture.  */
3261   gcc_assert (!(multi_step_cvt && op_type == binary_op));
3262
3263   if (!vec_stmt) /* transformation not required.  */
3264     {
3265       STMT_VINFO_TYPE (stmt_info) = type_promotion_vec_info_type;
3266       if (vect_print_dump_info (REPORT_DETAILS))
3267         fprintf (vect_dump, "=== vectorizable_promotion ===");
3268       vect_model_promotion_demotion_cost (stmt_info, dt, multi_step_cvt);
3269       return true;
3270     }
3271
3272   /** Transform.  **/
3273
3274   if (vect_print_dump_info (REPORT_DETAILS))
3275     fprintf (vect_dump, "transform type promotion operation. ncopies = %d.",
3276                         ncopies);
3277
3278   /* Handle def.  */
3279   /* In case of multi-step promotion, we first generate promotion operations
3280      to the intermediate types, and then from that types to the final one.
3281      We store vector destination in VEC_DSTS in the correct order for
3282      recursive creation of promotion operations in
3283      vect_create_vectorized_promotion_stmts(). Vector destinations are created
3284      according to TYPES recieved from supportable_widening_operation().   */
3285   if (multi_step_cvt)
3286     vec_dsts = VEC_alloc (tree, heap, multi_step_cvt + 1);
3287   else
3288     vec_dsts = VEC_alloc (tree, heap, 1);
3289
3290   vec_dest = vect_create_destination_var (scalar_dest, vectype_out);
3291   VEC_quick_push (tree, vec_dsts, vec_dest);
3292
3293   if (multi_step_cvt)
3294     {
3295       for (i = VEC_length (tree, interm_types) - 1;
3296            VEC_iterate (tree, interm_types, i, intermediate_type); i--)
3297         {
3298           vec_dest = vect_create_destination_var (scalar_dest,
3299                                                   intermediate_type);
3300           VEC_quick_push (tree, vec_dsts, vec_dest);
3301         }
3302     }
3303
3304   if (!slp_node)
3305     {
3306       vec_oprnds0 = VEC_alloc (tree, heap,
3307                             (multi_step_cvt ? vect_pow2 (multi_step_cvt) : 1));
3308       if (op_type == binary_op)
3309         vec_oprnds1 = VEC_alloc (tree, heap, 1);
3310     }
3311
3312   /* In case the vectorization factor (VF) is bigger than the number
3313      of elements that we can fit in a vectype (nunits), we have to generate
3314      more than one vector stmt - i.e - we need to "unroll" the
3315      vector stmt by a factor VF/nunits.   */
3316
3317   prev_stmt_info = NULL;
3318   for (j = 0; j < ncopies; j++)
3319     {
3320       /* Handle uses.  */
3321       if (j == 0)
3322         {
3323           if (slp_node)
3324               vect_get_slp_defs (op0, op1, slp_node, &vec_oprnds0,
3325                                  &vec_oprnds1, -1);
3326           else
3327             {
3328               vec_oprnd0 = vect_get_vec_def_for_operand (op0, stmt, NULL);
3329               VEC_quick_push (tree, vec_oprnds0, vec_oprnd0);
3330               if (op_type == binary_op)
3331                 {
3332                   vec_oprnd1 = vect_get_vec_def_for_operand (op1, stmt, NULL);
3333                   VEC_quick_push (tree, vec_oprnds1, vec_oprnd1);
3334                 }
3335             }
3336         }
3337       else
3338         {
3339           vec_oprnd0 = vect_get_vec_def_for_stmt_copy (dt[0], vec_oprnd0);
3340           VEC_replace (tree, vec_oprnds0, 0, vec_oprnd0);
3341           if (op_type == binary_op)
3342             {
3343               vec_oprnd1 = vect_get_vec_def_for_stmt_copy (dt[1], vec_oprnd1);
3344               VEC_replace (tree, vec_oprnds1, 0, vec_oprnd1);
3345             }
3346         }
3347
3348       /* Arguments are ready.  Create the new vector stmts.  */
3349       tmp_vec_dsts = VEC_copy (tree, heap, vec_dsts);
3350       vect_create_vectorized_promotion_stmts (&vec_oprnds0, &vec_oprnds1,
3351                                               multi_step_cvt, stmt,
3352                                               tmp_vec_dsts,
3353                                               gsi, slp_node, code1, code2,
3354                                               decl1, decl2, op_type,
3355                                               &prev_stmt_info);
3356     }
3357
3358   VEC_free (tree, heap, vec_dsts);
3359   VEC_free (tree, heap, tmp_vec_dsts);
3360   VEC_free (tree, heap, interm_types);
3361   VEC_free (tree, heap, vec_oprnds0);
3362   VEC_free (tree, heap, vec_oprnds1);
3363
3364   *vec_stmt = STMT_VINFO_VEC_STMT (stmt_info);
3365   return true;
3366 }
3367
3368
3369 /* Function vectorizable_store.
3370
3371    Check if STMT defines a non scalar data-ref (array/pointer/structure) that
3372    can be vectorized.
3373    If VEC_STMT is also passed, vectorize the STMT: create a vectorized
3374    stmt to replace it, put it in VEC_STMT, and insert it at BSI.
3375    Return FALSE if not a vectorizable STMT, TRUE otherwise.  */
3376
3377 static bool
3378 vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
3379                     slp_tree slp_node)
3380 {
3381   tree scalar_dest;
3382   tree data_ref;
3383   tree op;
3384   tree vec_oprnd = NULL_TREE;
3385   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
3386   struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info), *first_dr = NULL;
3387   tree vectype = STMT_VINFO_VECTYPE (stmt_info);
3388   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
3389   struct loop *loop = NULL;
3390   enum machine_mode vec_mode;
3391   tree dummy;
3392   enum dr_alignment_support alignment_support_scheme;
3393   tree def;
3394   gimple def_stmt;
3395   enum vect_def_type dt;
3396   stmt_vec_info prev_stmt_info = NULL;
3397   tree dataref_ptr = NULL_TREE;
3398   int nunits = TYPE_VECTOR_SUBPARTS (vectype);
3399   int ncopies;
3400   int j;
3401   gimple next_stmt, first_stmt = NULL;
3402   bool strided_store = false;
3403   unsigned int group_size, i;
3404   VEC(tree,heap) *dr_chain = NULL, *oprnds = NULL, *result_chain = NULL;
3405   bool inv_p;
3406   VEC(tree,heap) *vec_oprnds = NULL;
3407   bool slp = (slp_node != NULL);
3408   unsigned int vec_num;
3409   bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info);
3410
3411   if (loop_vinfo)
3412     loop = LOOP_VINFO_LOOP (loop_vinfo);
3413
3414   /* Multiple types in SLP are handled by creating the appropriate number of
3415      vectorized stmts for each SLP node. Hence, NCOPIES is always 1 in
3416      case of SLP.  */
3417   if (slp)
3418     ncopies = 1;
3419   else
3420     ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits;
3421
3422   gcc_assert (ncopies >= 1);
3423
3424   /* FORNOW. This restriction should be relaxed.  */
3425   if (loop && nested_in_vect_loop_p (loop, stmt) && ncopies > 1)
3426     {
3427       if (vect_print_dump_info (REPORT_DETAILS))
3428         fprintf (vect_dump, "multiple types in nested loop.");
3429       return false;
3430     }
3431
3432   if (!STMT_VINFO_RELEVANT_P (stmt_info) && !bb_vinfo)
3433     return false;
3434
3435   if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def)
3436     return false;
3437
3438   /* Is vectorizable store? */
3439
3440   if (!is_gimple_assign (stmt))
3441     return false;
3442
3443   scalar_dest = gimple_assign_lhs (stmt);
3444   if (TREE_CODE (scalar_dest) != ARRAY_REF
3445       && TREE_CODE (scalar_dest) != INDIRECT_REF
3446       && TREE_CODE (scalar_dest) != COMPONENT_REF
3447       && TREE_CODE (scalar_dest) != IMAGPART_EXPR
3448       && TREE_CODE (scalar_dest) != REALPART_EXPR
3449       && TREE_CODE (scalar_dest) != MEM_REF)
3450     return false;
3451
3452   gcc_assert (gimple_assign_single_p (stmt));
3453   op = gimple_assign_rhs1 (stmt);
3454   if (!vect_is_simple_use (op, loop_vinfo, bb_vinfo, &def_stmt, &def, &dt))
3455     {
3456       if (vect_print_dump_info (REPORT_DETAILS))
3457         fprintf (vect_dump, "use not simple.");
3458       return false;
3459     }
3460
3461   /* The scalar rhs type needs to be trivially convertible to the vector
3462      component type.  This should always be the case.  */
3463   if (!useless_type_conversion_p (TREE_TYPE (vectype), TREE_TYPE (op)))
3464     {
3465       if (vect_print_dump_info (REPORT_DETAILS))
3466         fprintf (vect_dump, "???  operands of different types");
3467       return false;
3468     }
3469
3470   vec_mode = TYPE_MODE (vectype);
3471   /* FORNOW. In some cases can vectorize even if data-type not supported
3472      (e.g. - array initialization with 0).  */
3473   if (optab_handler (mov_optab, vec_mode) == CODE_FOR_nothing)
3474     return false;
3475
3476   if (!STMT_VINFO_DATA_REF (stmt_info))
3477     return false;
3478
3479   if (tree_int_cst_compare (DR_STEP (dr), size_zero_node) < 0)
3480     {
3481       if (vect_print_dump_info (REPORT_DETAILS))
3482         fprintf (vect_dump, "negative step for store.");
3483       return false;
3484     }
3485
3486   if (STMT_VINFO_STRIDED_ACCESS (stmt_info))
3487     {
3488       strided_store = true;
3489       first_stmt = DR_GROUP_FIRST_DR (stmt_info);
3490       if (!vect_strided_store_supported (vectype)
3491           && !PURE_SLP_STMT (stmt_info) && !slp)
3492         return false;
3493
3494       if (first_stmt == stmt)
3495         {
3496           /* STMT is the leader of the group. Check the operands of all the
3497              stmts of the group.  */
3498           next_stmt = DR_GROUP_NEXT_DR (stmt_info);
3499           while (next_stmt)
3500             {
3501               gcc_assert (gimple_assign_single_p (next_stmt));
3502               op = gimple_assign_rhs1 (next_stmt);
3503               if (!vect_is_simple_use (op, loop_vinfo, bb_vinfo, &def_stmt,
3504                                        &def, &dt))
3505                 {
3506                   if (vect_print_dump_info (REPORT_DETAILS))
3507                     fprintf (vect_dump, "use not simple.");
3508                   return false;
3509                 }
3510               next_stmt = DR_GROUP_NEXT_DR (vinfo_for_stmt (next_stmt));
3511             }
3512         }
3513     }
3514
3515   if (!vec_stmt) /* transformation not required.  */
3516     {
3517       STMT_VINFO_TYPE (stmt_info) = store_vec_info_type;
3518       vect_model_store_cost (stmt_info, ncopies, dt, NULL);
3519       return true;
3520     }
3521
3522   /** Transform.  **/
3523
3524   if (strided_store)
3525     {
3526       first_dr = STMT_VINFO_DATA_REF (vinfo_for_stmt (first_stmt));
3527       group_size = DR_GROUP_SIZE (vinfo_for_stmt (first_stmt));
3528
3529       DR_GROUP_STORE_COUNT (vinfo_for_stmt (first_stmt))++;
3530
3531       /* FORNOW */
3532       gcc_assert (!loop || !nested_in_vect_loop_p (loop, stmt));
3533
3534       /* We vectorize all the stmts of the interleaving group when we
3535          reach the last stmt in the group.  */
3536       if (DR_GROUP_STORE_COUNT (vinfo_for_stmt (first_stmt))
3537           < DR_GROUP_SIZE (vinfo_for_stmt (first_stmt))
3538           && !slp)
3539         {
3540           *vec_stmt = NULL;
3541           return true;
3542         }
3543
3544       if (slp)
3545         {
3546           strided_store = false;
3547           /* VEC_NUM is the number of vect stmts to be created for this 
3548              group.  */
3549           vec_num = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node);
3550           first_stmt = VEC_index (gimple, SLP_TREE_SCALAR_STMTS (slp_node), 0); 
3551           first_dr = STMT_VINFO_DATA_REF (vinfo_for_stmt (first_stmt));
3552         } 
3553       else
3554         /* VEC_NUM is the number of vect stmts to be created for this 
3555            group.  */
3556         vec_num = group_size;
3557     }
3558   else
3559     {
3560       first_stmt = stmt;
3561       first_dr = dr;
3562       group_size = vec_num = 1;
3563     }
3564
3565   if (vect_print_dump_info (REPORT_DETAILS))
3566     fprintf (vect_dump, "transform store. ncopies = %d",ncopies);
3567
3568   dr_chain = VEC_alloc (tree, heap, group_size);
3569   oprnds = VEC_alloc (tree, heap, group_size);
3570
3571   alignment_support_scheme = vect_supportable_dr_alignment (first_dr, false);
3572   gcc_assert (alignment_support_scheme);
3573
3574   /* In case the vectorization factor (VF) is bigger than the number
3575      of elements that we can fit in a vectype (nunits), we have to generate
3576      more than one vector stmt - i.e - we need to "unroll" the
3577      vector stmt by a factor VF/nunits.  For more details see documentation in
3578      vect_get_vec_def_for_copy_stmt.  */
3579
3580   /* In case of interleaving (non-unit strided access):
3581
3582         S1:  &base + 2 = x2
3583         S2:  &base = x0
3584         S3:  &base + 1 = x1
3585         S4:  &base + 3 = x3
3586
3587      We create vectorized stores starting from base address (the access of the
3588      first stmt in the chain (S2 in the above example), when the last store stmt
3589      of the chain (S4) is reached:
3590
3591         VS1: &base = vx2
3592         VS2: &base + vec_size*1 = vx0
3593         VS3: &base + vec_size*2 = vx1
3594         VS4: &base + vec_size*3 = vx3
3595
3596      Then permutation statements are generated:
3597
3598         VS5: vx5 = VEC_INTERLEAVE_HIGH_EXPR < vx0, vx3 >
3599         VS6: vx6 = VEC_INTERLEAVE_LOW_EXPR < vx0, vx3 >
3600         ...
3601
3602      And they are put in STMT_VINFO_VEC_STMT of the corresponding scalar stmts
3603      (the order of the data-refs in the output of vect_permute_store_chain
3604      corresponds to the order of scalar stmts in the interleaving chain - see
3605      the documentation of vect_permute_store_chain()).
3606
3607      In case of both multiple types and interleaving, above vector stores and
3608      permutation stmts are created for every copy.  The result vector stmts are
3609      put in STMT_VINFO_VEC_STMT for the first copy and in the corresponding
3610      STMT_VINFO_RELATED_STMT for the next copies.
3611   */
3612
3613   prev_stmt_info = NULL;
3614   for (j = 0; j < ncopies; j++)
3615     {
3616       gimple new_stmt;
3617       gimple ptr_incr;
3618
3619       if (j == 0)
3620         {
3621           if (slp)
3622             {
3623               /* Get vectorized arguments for SLP_NODE.  */
3624               vect_get_slp_defs (NULL_TREE, NULL_TREE, slp_node, &vec_oprnds,
3625                                  NULL, -1);
3626
3627               vec_oprnd = VEC_index (tree, vec_oprnds, 0);
3628             }
3629           else
3630             {
3631               /* For interleaved stores we collect vectorized defs for all the
3632                  stores in the group in DR_CHAIN and OPRNDS. DR_CHAIN is then
3633                  used as an input to vect_permute_store_chain(), and OPRNDS as
3634                  an input to vect_get_vec_def_for_stmt_copy() for the next copy.
3635
3636                  If the store is not strided, GROUP_SIZE is 1, and DR_CHAIN and
3637                  OPRNDS are of size 1.  */
3638               next_stmt = first_stmt;
3639               for (i = 0; i < group_size; i++)
3640                 {
3641                   /* Since gaps are not supported for interleaved stores,
3642                      GROUP_SIZE is the exact number of stmts in the chain.
3643                      Therefore, NEXT_STMT can't be NULL_TREE.  In case that
3644                      there is no interleaving, GROUP_SIZE is 1, and only one
3645                      iteration of the loop will be executed.  */
3646                   gcc_assert (next_stmt
3647                               && gimple_assign_single_p (next_stmt));
3648                   op = gimple_assign_rhs1 (next_stmt);
3649
3650                   vec_oprnd = vect_get_vec_def_for_operand (op, next_stmt,
3651                                                             NULL);
3652                   VEC_quick_push(tree, dr_chain, vec_oprnd);
3653                   VEC_quick_push(tree, oprnds, vec_oprnd);
3654                   next_stmt = DR_GROUP_NEXT_DR (vinfo_for_stmt (next_stmt));
3655                 }
3656             }
3657
3658           /* We should have catched mismatched types earlier.  */
3659           gcc_assert (useless_type_conversion_p (vectype,
3660                                                  TREE_TYPE (vec_oprnd)));
3661           dataref_ptr = vect_create_data_ref_ptr (first_stmt, NULL, NULL_TREE,
3662                                                   &dummy, &ptr_incr, false,
3663                                                   &inv_p);
3664           gcc_assert (bb_vinfo || !inv_p);
3665         }
3666       else
3667         {
3668           /* For interleaved stores we created vectorized defs for all the
3669              defs stored in OPRNDS in the previous iteration (previous copy).
3670              DR_CHAIN is then used as an input to vect_permute_store_chain(),
3671              and OPRNDS as an input to vect_get_vec_def_for_stmt_copy() for the
3672              next copy.
3673              If the store is not strided, GROUP_SIZE is 1, and DR_CHAIN and
3674              OPRNDS are of size 1.  */
3675           for (i = 0; i < group_size; i++)
3676             {
3677               op = VEC_index (tree, oprnds, i);
3678               vect_is_simple_use (op, loop_vinfo, bb_vinfo, &def_stmt, &def,
3679                                   &dt);
3680               vec_oprnd = vect_get_vec_def_for_stmt_copy (dt, op);
3681               VEC_replace(tree, dr_chain, i, vec_oprnd);
3682               VEC_replace(tree, oprnds, i, vec_oprnd);
3683             }
3684           dataref_ptr =
3685                 bump_vector_ptr (dataref_ptr, ptr_incr, gsi, stmt, NULL_TREE);
3686         }
3687
3688       if (strided_store)
3689         {
3690           result_chain = VEC_alloc (tree, heap, group_size);
3691           /* Permute.  */
3692           if (!vect_permute_store_chain (dr_chain, group_size, stmt, gsi,
3693                                          &result_chain))
3694             return false;
3695         }
3696
3697       next_stmt = first_stmt;
3698       for (i = 0; i < vec_num; i++)
3699         {
3700           struct ptr_info_def *pi;
3701
3702           if (i > 0)
3703             /* Bump the vector pointer.  */
3704             dataref_ptr = bump_vector_ptr (dataref_ptr, ptr_incr, gsi, stmt,
3705                                            NULL_TREE);
3706
3707           if (slp)
3708             vec_oprnd = VEC_index (tree, vec_oprnds, i);
3709           else if (strided_store)
3710             /* For strided stores vectorized defs are interleaved in
3711                vect_permute_store_chain().  */
3712             vec_oprnd = VEC_index (tree, result_chain, i);
3713
3714           data_ref = build2 (MEM_REF, TREE_TYPE (vec_oprnd), dataref_ptr,
3715                              build_int_cst (reference_alias_ptr_type
3716                                             (DR_REF (first_dr)), 0));
3717           pi = get_ptr_info (dataref_ptr);
3718           pi->align = TYPE_ALIGN_UNIT (vectype);
3719           if (aligned_access_p (first_dr))
3720             pi->misalign = 0;
3721           else if (DR_MISALIGNMENT (first_dr) == -1)
3722             {
3723               TREE_TYPE (data_ref)
3724                 = build_aligned_type (TREE_TYPE (data_ref),
3725                                       TYPE_ALIGN (TREE_TYPE (vectype)));
3726               pi->align = TYPE_ALIGN_UNIT (TREE_TYPE (vectype));
3727               pi->misalign = 0;
3728             }
3729           else
3730             {
3731               TREE_TYPE (data_ref)
3732                 = build_aligned_type (TREE_TYPE (data_ref),
3733                                       TYPE_ALIGN (TREE_TYPE (vectype)));
3734               pi->misalign = DR_MISALIGNMENT (first_dr);
3735             }
3736
3737           /* Arguments are ready.  Create the new vector stmt.  */
3738           new_stmt = gimple_build_assign (data_ref, vec_oprnd);
3739           vect_finish_stmt_generation (stmt, new_stmt, gsi);
3740           mark_symbols_for_renaming (new_stmt);
3741
3742           if (slp)
3743             continue;
3744
3745           if (j == 0)
3746             STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt =  new_stmt;
3747           else
3748             STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt;
3749
3750           prev_stmt_info = vinfo_for_stmt (new_stmt);
3751           next_stmt = DR_GROUP_NEXT_DR (vinfo_for_stmt (next_stmt));
3752           if (!next_stmt)
3753             break;
3754         }
3755     }
3756
3757   VEC_free (tree, heap, dr_chain);
3758   VEC_free (tree, heap, oprnds);
3759   if (result_chain)
3760     VEC_free (tree, heap, result_chain);
3761   if (vec_oprnds)
3762     VEC_free (tree, heap, vec_oprnds);
3763
3764   return true;
3765 }
3766
3767 /* Given a vector type VECTYPE returns a builtin DECL to be used
3768    for vector permutation and stores a mask into *MASK that implements
3769    reversal of the vector elements.  If that is impossible to do
3770    returns NULL (and *MASK is unchanged).  */
3771
3772 static tree
3773 perm_mask_for_reverse (tree vectype, tree *mask)
3774 {
3775   tree builtin_decl;
3776   tree mask_element_type, mask_type;
3777   tree mask_vec = NULL;
3778   int i;
3779   int nunits;
3780   if (!targetm.vectorize.builtin_vec_perm)
3781     return NULL;
3782
3783   builtin_decl = targetm.vectorize.builtin_vec_perm (vectype,
3784                                                      &mask_element_type);
3785   if (!builtin_decl || !mask_element_type)
3786     return NULL;
3787
3788   mask_type = get_vectype_for_scalar_type (mask_element_type);
3789   nunits = TYPE_VECTOR_SUBPARTS (vectype);
3790   if (!mask_type
3791       || TYPE_VECTOR_SUBPARTS (vectype) != TYPE_VECTOR_SUBPARTS (mask_type))
3792     return NULL;
3793
3794   for (i = 0; i < nunits; i++)
3795     mask_vec = tree_cons (NULL, build_int_cst (mask_element_type, i), mask_vec);
3796   mask_vec = build_vector (mask_type, mask_vec);
3797
3798   if (!targetm.vectorize.builtin_vec_perm_ok (vectype, mask_vec))
3799     return NULL;
3800   if (mask)
3801     *mask = mask_vec;
3802   return builtin_decl;
3803 }
3804
3805 /* Given a vector variable X, that was generated for the scalar LHS of
3806    STMT, generate instructions to reverse the vector elements of X,
3807    insert them a *GSI and return the permuted vector variable.  */
3808
3809 static tree
3810 reverse_vec_elements (tree x, gimple stmt, gimple_stmt_iterator *gsi)
3811 {
3812   tree vectype = TREE_TYPE (x);
3813   tree mask_vec, builtin_decl;
3814   tree perm_dest, data_ref;
3815   gimple perm_stmt;
3816
3817   builtin_decl = perm_mask_for_reverse (vectype, &mask_vec);
3818
3819   perm_dest = vect_create_destination_var (gimple_assign_lhs (stmt), vectype);
3820
3821   /* Generate the permute statement.  */
3822   perm_stmt = gimple_build_call (builtin_decl, 3, x, x, mask_vec);
3823   if (!useless_type_conversion_p (vectype,
3824                                   TREE_TYPE (TREE_TYPE (builtin_decl))))
3825     {
3826       tree tem = create_tmp_reg (TREE_TYPE (TREE_TYPE (builtin_decl)), NULL);
3827       tem = make_ssa_name (tem, perm_stmt);
3828       gimple_call_set_lhs (perm_stmt, tem);
3829       vect_finish_stmt_generation (stmt, perm_stmt, gsi);
3830       perm_stmt = gimple_build_assign (NULL_TREE,
3831                                        build1 (VIEW_CONVERT_EXPR,
3832                                                vectype, tem));
3833     }
3834   data_ref = make_ssa_name (perm_dest, perm_stmt);
3835   gimple_set_lhs (perm_stmt, data_ref);
3836   vect_finish_stmt_generation (stmt, perm_stmt, gsi);
3837
3838   return data_ref;
3839 }
3840
3841 /* vectorizable_load.
3842
3843    Check if STMT reads a non scalar data-ref (array/pointer/structure) that
3844    can be vectorized.
3845    If VEC_STMT is also passed, vectorize the STMT: create a vectorized
3846    stmt to replace it, put it in VEC_STMT, and insert it at BSI.
3847    Return FALSE if not a vectorizable STMT, TRUE otherwise.  */
3848
3849 static bool
3850 vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
3851                    slp_tree slp_node, slp_instance slp_node_instance)
3852 {
3853   tree scalar_dest;
3854   tree vec_dest = NULL;
3855   tree data_ref = NULL;
3856   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
3857   stmt_vec_info prev_stmt_info;
3858   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
3859   struct loop *loop = NULL;
3860   struct loop *containing_loop = (gimple_bb (stmt))->loop_father;
3861   bool nested_in_vect_loop = false;
3862   struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info), *first_dr;
3863   tree vectype = STMT_VINFO_VECTYPE (stmt_info);
3864   tree new_temp;
3865   enum machine_mode mode;
3866   gimple new_stmt = NULL;
3867   tree dummy;
3868   enum dr_alignment_support alignment_support_scheme;
3869   tree dataref_ptr = NULL_TREE;
3870   gimple ptr_incr;
3871   int nunits = TYPE_VECTOR_SUBPARTS (vectype);
3872   int ncopies;
3873   int i, j, group_size;
3874   tree msq = NULL_TREE, lsq;
3875   tree offset = NULL_TREE;
3876   tree realignment_token = NULL_TREE;
3877   gimple phi = NULL;
3878   VEC(tree,heap) *dr_chain = NULL;
3879   bool strided_load = false;
3880   gimple first_stmt;
3881   tree scalar_type;
3882   bool inv_p;
3883   bool negative;
3884   bool compute_in_loop = false;
3885   struct loop *at_loop;
3886   int vec_num;
3887   bool slp = (slp_node != NULL);
3888   bool slp_perm = false;
3889   enum tree_code code;
3890   bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info);
3891   int vf;
3892
3893   if (loop_vinfo)
3894     {
3895       loop = LOOP_VINFO_LOOP (loop_vinfo);
3896       nested_in_vect_loop = nested_in_vect_loop_p (loop, stmt);
3897       vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
3898     }
3899   else
3900     vf = 1;
3901
3902   /* Multiple types in SLP are handled by creating the appropriate number of
3903      vectorized stmts for each SLP node.  Hence, NCOPIES is always 1 in
3904      case of SLP.  */
3905   if (slp)
3906     ncopies = 1;
3907   else
3908     ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits;
3909
3910   gcc_assert (ncopies >= 1);
3911
3912   /* FORNOW. This restriction should be relaxed.  */
3913   if (nested_in_vect_loop && ncopies > 1)
3914     {
3915       if (vect_print_dump_info (REPORT_DETAILS))
3916         fprintf (vect_dump, "multiple types in nested loop.");
3917       return false;
3918     }
3919
3920   if (!STMT_VINFO_RELEVANT_P (stmt_info) && !bb_vinfo)
3921     return false;
3922
3923   if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def)
3924     return false;
3925
3926   /* Is vectorizable load? */
3927   if (!is_gimple_assign (stmt))
3928     return false;
3929
3930   scalar_dest = gimple_assign_lhs (stmt);
3931   if (TREE_CODE (scalar_dest) != SSA_NAME)
3932     return false;
3933
3934   code = gimple_assign_rhs_code (stmt);
3935   if (code != ARRAY_REF
3936       && code != INDIRECT_REF
3937       && code != COMPONENT_REF
3938       && code != IMAGPART_EXPR
3939       && code != REALPART_EXPR
3940       && code != MEM_REF)
3941     return false;
3942
3943   if (!STMT_VINFO_DATA_REF (stmt_info))
3944     return false;
3945
3946   negative = tree_int_cst_compare (DR_STEP (dr), size_zero_node) < 0;
3947   if (negative && ncopies > 1)
3948     {
3949       if (vect_print_dump_info (REPORT_DETAILS))
3950         fprintf (vect_dump, "multiple types with negative step.");
3951       return false;
3952     }
3953
3954   scalar_type = TREE_TYPE (DR_REF (dr));
3955   mode = TYPE_MODE (vectype);
3956
3957   /* FORNOW. In some cases can vectorize even if data-type not supported
3958     (e.g. - data copies).  */
3959   if (optab_handler (mov_optab, mode) == CODE_FOR_nothing)
3960     {
3961       if (vect_print_dump_info (REPORT_DETAILS))
3962         fprintf (vect_dump, "Aligned load, but unsupported type.");
3963       return false;
3964     }
3965
3966   /* The vector component type needs to be trivially convertible to the
3967      scalar lhs.  This should always be the case.  */
3968   if (!useless_type_conversion_p (TREE_TYPE (scalar_dest), TREE_TYPE (vectype)))
3969     {
3970       if (vect_print_dump_info (REPORT_DETAILS))
3971         fprintf (vect_dump, "???  operands of different types");
3972       return false;
3973     }
3974
3975   /* Check if the load is a part of an interleaving chain.  */
3976   if (STMT_VINFO_STRIDED_ACCESS (stmt_info))
3977     {
3978       strided_load = true;
3979       /* FORNOW */
3980       gcc_assert (! nested_in_vect_loop);
3981
3982       /* Check if interleaving is supported.  */
3983       if (!vect_strided_load_supported (vectype)
3984           && !PURE_SLP_STMT (stmt_info) && !slp)
3985         return false;
3986     }
3987
3988   if (negative)
3989     {
3990       gcc_assert (!strided_load);
3991       alignment_support_scheme = vect_supportable_dr_alignment (dr, false);
3992       if (alignment_support_scheme != dr_aligned
3993           && alignment_support_scheme != dr_unaligned_supported)
3994         {
3995           if (vect_print_dump_info (REPORT_DETAILS))
3996             fprintf (vect_dump, "negative step but alignment required.");
3997           return false;
3998         }
3999       if (!perm_mask_for_reverse (vectype, NULL))
4000         {
4001           if (vect_print_dump_info (REPORT_DETAILS))
4002             fprintf (vect_dump, "negative step and reversing not supported.");
4003           return false;
4004         }
4005     }
4006
4007   if (!vec_stmt) /* transformation not required.  */
4008     {
4009       STMT_VINFO_TYPE (stmt_info) = load_vec_info_type;
4010       vect_model_load_cost (stmt_info, ncopies, NULL);
4011       return true;
4012     }
4013
4014   if (vect_print_dump_info (REPORT_DETAILS))
4015     fprintf (vect_dump, "transform load.");
4016
4017   /** Transform.  **/
4018
4019   if (strided_load)
4020     {
4021       first_stmt = DR_GROUP_FIRST_DR (stmt_info);
4022       /* Check if the chain of loads is already vectorized.  */
4023       if (STMT_VINFO_VEC_STMT (vinfo_for_stmt (first_stmt)))
4024         {
4025           *vec_stmt = STMT_VINFO_VEC_STMT (stmt_info);
4026           return true;
4027         }
4028       first_dr = STMT_VINFO_DATA_REF (vinfo_for_stmt (first_stmt));
4029       group_size = DR_GROUP_SIZE (vinfo_for_stmt (first_stmt));
4030
4031       /* VEC_NUM is the number of vect stmts to be created for this group.  */
4032       if (slp)
4033         {
4034           strided_load = false;
4035           vec_num = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node);
4036           if (SLP_INSTANCE_LOAD_PERMUTATION (slp_node_instance))
4037             slp_perm = true;
4038         }
4039       else
4040         vec_num = group_size;
4041
4042       dr_chain = VEC_alloc (tree, heap, vec_num);
4043     }
4044   else
4045     {
4046       first_stmt = stmt;
4047       first_dr = dr;
4048       group_size = vec_num = 1;
4049     }
4050
4051   alignment_support_scheme = vect_supportable_dr_alignment (first_dr, false);
4052   gcc_assert (alignment_support_scheme);
4053
4054   /* In case the vectorization factor (VF) is bigger than the number
4055      of elements that we can fit in a vectype (nunits), we have to generate
4056      more than one vector stmt - i.e - we need to "unroll" the
4057      vector stmt by a factor VF/nunits.  In doing so, we record a pointer
4058      from one copy of the vector stmt to the next, in the field
4059      STMT_VINFO_RELATED_STMT.  This is necessary in order to allow following
4060      stages to find the correct vector defs to be used when vectorizing
4061      stmts that use the defs of the current stmt.  The example below
4062      illustrates the vectorization process when VF=16 and nunits=4 (i.e., we
4063      need to create 4 vectorized stmts):
4064
4065      before vectorization:
4066                                 RELATED_STMT    VEC_STMT
4067         S1:     x = memref      -               -
4068         S2:     z = x + 1       -               -
4069
4070      step 1: vectorize stmt S1:
4071         We first create the vector stmt VS1_0, and, as usual, record a
4072         pointer to it in the STMT_VINFO_VEC_STMT of the scalar stmt S1.
4073         Next, we create the vector stmt VS1_1, and record a pointer to
4074         it in the STMT_VINFO_RELATED_STMT of the vector stmt VS1_0.
4075         Similarly, for VS1_2 and VS1_3.  This is the resulting chain of
4076         stmts and pointers:
4077                                 RELATED_STMT    VEC_STMT
4078         VS1_0:  vx0 = memref0   VS1_1           -
4079         VS1_1:  vx1 = memref1   VS1_2           -
4080         VS1_2:  vx2 = memref2   VS1_3           -
4081         VS1_3:  vx3 = memref3   -               -
4082         S1:     x = load        -               VS1_0
4083         S2:     z = x + 1       -               -
4084
4085      See in documentation in vect_get_vec_def_for_stmt_copy for how the
4086      information we recorded in RELATED_STMT field is used to vectorize
4087      stmt S2.  */
4088
4089   /* In case of interleaving (non-unit strided access):
4090
4091      S1:  x2 = &base + 2
4092      S2:  x0 = &base
4093      S3:  x1 = &base + 1
4094      S4:  x3 = &base + 3
4095
4096      Vectorized loads are created in the order of memory accesses
4097      starting from the access of the first stmt of the chain:
4098
4099      VS1: vx0 = &base
4100      VS2: vx1 = &base + vec_size*1
4101      VS3: vx3 = &base + vec_size*2
4102      VS4: vx4 = &base + vec_size*3
4103
4104      Then permutation statements are generated:
4105
4106      VS5: vx5 = VEC_EXTRACT_EVEN_EXPR < vx0, vx1 >
4107      VS6: vx6 = VEC_EXTRACT_ODD_EXPR < vx0, vx1 >
4108        ...
4109
4110      And they are put in STMT_VINFO_VEC_STMT of the corresponding scalar stmts
4111      (the order of the data-refs in the output of vect_permute_load_chain
4112      corresponds to the order of scalar stmts in the interleaving chain - see
4113      the documentation of vect_permute_load_chain()).
4114      The generation of permutation stmts and recording them in
4115      STMT_VINFO_VEC_STMT is done in vect_transform_strided_load().
4116
4117      In case of both multiple types and interleaving, the vector loads and
4118      permutation stmts above are created for every copy.  The result vector
4119      stmts are put in STMT_VINFO_VEC_STMT for the first copy and in the
4120      corresponding STMT_VINFO_RELATED_STMT for the next copies.  */
4121
4122   /* If the data reference is aligned (dr_aligned) or potentially unaligned
4123      on a target that supports unaligned accesses (dr_unaligned_supported)
4124      we generate the following code:
4125          p = initial_addr;
4126          indx = 0;
4127          loop {
4128            p = p + indx * vectype_size;
4129            vec_dest = *(p);
4130            indx = indx + 1;
4131          }
4132
4133      Otherwise, the data reference is potentially unaligned on a target that
4134      does not support unaligned accesses (dr_explicit_realign_optimized) -
4135      then generate the following code, in which the data in each iteration is
4136      obtained by two vector loads, one from the previous iteration, and one
4137      from the current iteration:
4138          p1 = initial_addr;
4139          msq_init = *(floor(p1))
4140          p2 = initial_addr + VS - 1;
4141          realignment_token = call target_builtin;
4142          indx = 0;
4143          loop {
4144            p2 = p2 + indx * vectype_size
4145            lsq = *(floor(p2))
4146            vec_dest = realign_load (msq, lsq, realignment_token)
4147            indx = indx + 1;
4148            msq = lsq;
4149          }   */
4150
4151   /* If the misalignment remains the same throughout the execution of the
4152      loop, we can create the init_addr and permutation mask at the loop
4153      preheader.  Otherwise, it needs to be created inside the loop.
4154      This can only occur when vectorizing memory accesses in the inner-loop
4155      nested within an outer-loop that is being vectorized.  */
4156
4157   if (loop && nested_in_vect_loop_p (loop, stmt)
4158       && (TREE_INT_CST_LOW (DR_STEP (dr))
4159           % GET_MODE_SIZE (TYPE_MODE (vectype)) != 0))
4160     {
4161       gcc_assert (alignment_support_scheme != dr_explicit_realign_optimized);
4162       compute_in_loop = true;
4163     }
4164
4165   if ((alignment_support_scheme == dr_explicit_realign_optimized
4166        || alignment_support_scheme == dr_explicit_realign)
4167       && !compute_in_loop)
4168     {
4169       msq = vect_setup_realignment (first_stmt, gsi, &realignment_token,
4170                                     alignment_support_scheme, NULL_TREE,
4171                                     &at_loop);
4172       if (alignment_support_scheme == dr_explicit_realign_optimized)
4173         {
4174           phi = SSA_NAME_DEF_STMT (msq);
4175           offset = size_int (TYPE_VECTOR_SUBPARTS (vectype) - 1);
4176         }
4177     }
4178   else
4179     at_loop = loop;
4180
4181   if (negative)
4182     offset = size_int (-TYPE_VECTOR_SUBPARTS (vectype) + 1);
4183
4184   prev_stmt_info = NULL;
4185   for (j = 0; j < ncopies; j++)
4186     {
4187       /* 1. Create the vector pointer update chain.  */
4188       if (j == 0)
4189         dataref_ptr = vect_create_data_ref_ptr (first_stmt,
4190                                                 at_loop, offset,
4191                                                 &dummy, &ptr_incr, false,
4192                                                 &inv_p);
4193       else
4194         dataref_ptr =
4195                 bump_vector_ptr (dataref_ptr, ptr_incr, gsi, stmt, NULL_TREE);
4196
4197       for (i = 0; i < vec_num; i++)
4198         {
4199           if (i > 0)
4200             dataref_ptr = bump_vector_ptr (dataref_ptr, ptr_incr, gsi, stmt,
4201                                            NULL_TREE);
4202
4203           /* 2. Create the vector-load in the loop.  */
4204           switch (alignment_support_scheme)
4205             {
4206             case dr_aligned:
4207             case dr_unaligned_supported:
4208               {
4209                 struct ptr_info_def *pi;
4210                 data_ref
4211                   = build2 (MEM_REF, vectype, dataref_ptr,
4212                             build_int_cst (reference_alias_ptr_type
4213                                            (DR_REF (first_dr)), 0));
4214                 pi = get_ptr_info (dataref_ptr);
4215                 pi->align = TYPE_ALIGN_UNIT (vectype);
4216                 if (alignment_support_scheme == dr_aligned)
4217                   {
4218                     gcc_assert (aligned_access_p (first_dr));
4219                     pi->misalign = 0;
4220                   }
4221                 else if (DR_MISALIGNMENT (first_dr) == -1)
4222                   {
4223                     TREE_TYPE (data_ref)
4224                       = build_aligned_type (TREE_TYPE (data_ref),
4225                                             TYPE_ALIGN (TREE_TYPE (vectype)));
4226                     pi->align = TYPE_ALIGN_UNIT (TREE_TYPE (vectype));
4227                     pi->misalign = 0;
4228                   }
4229                 else
4230                   {
4231                     TREE_TYPE (data_ref)
4232                       = build_aligned_type (TREE_TYPE (data_ref),
4233                                             TYPE_ALIGN (TREE_TYPE (vectype)));
4234                     pi->misalign = DR_MISALIGNMENT (first_dr);
4235                   }
4236                 break;
4237               }
4238             case dr_explicit_realign:
4239               {
4240                 tree ptr, bump;
4241                 tree vs_minus_1 = size_int (TYPE_VECTOR_SUBPARTS (vectype) - 1);
4242
4243                 if (compute_in_loop)
4244                   msq = vect_setup_realignment (first_stmt, gsi,
4245                                                 &realignment_token,
4246                                                 dr_explicit_realign,
4247                                                 dataref_ptr, NULL);
4248
4249                 new_stmt = gimple_build_assign_with_ops
4250                              (BIT_AND_EXPR, NULL_TREE, dataref_ptr,
4251                               build_int_cst
4252                                 (TREE_TYPE (dataref_ptr),
4253                                  -(HOST_WIDE_INT)TYPE_ALIGN_UNIT (vectype)));
4254                 ptr = make_ssa_name (SSA_NAME_VAR (dataref_ptr), new_stmt);
4255                 gimple_assign_set_lhs (new_stmt, ptr);
4256                 vect_finish_stmt_generation (stmt, new_stmt, gsi);
4257                 data_ref
4258                   = build2 (MEM_REF, vectype, ptr,
4259                             build_int_cst (reference_alias_ptr_type
4260                                              (DR_REF (first_dr)), 0));
4261                 vec_dest = vect_create_destination_var (scalar_dest, vectype);
4262                 new_stmt = gimple_build_assign (vec_dest, data_ref);
4263                 new_temp = make_ssa_name (vec_dest, new_stmt);
4264                 gimple_assign_set_lhs (new_stmt, new_temp);
4265                 gimple_set_vdef (new_stmt, gimple_vdef (stmt));
4266                 gimple_set_vuse (new_stmt, gimple_vuse (stmt));
4267                 vect_finish_stmt_generation (stmt, new_stmt, gsi);
4268                 msq = new_temp;
4269
4270                 bump = size_binop (MULT_EXPR, vs_minus_1,
4271                                    TYPE_SIZE_UNIT (scalar_type));
4272                 ptr = bump_vector_ptr (dataref_ptr, NULL, gsi, stmt, bump);
4273                 new_stmt = gimple_build_assign_with_ops
4274                              (BIT_AND_EXPR, NULL_TREE, ptr,
4275                               build_int_cst
4276                                 (TREE_TYPE (ptr),
4277                                  -(HOST_WIDE_INT)TYPE_ALIGN_UNIT (vectype)));
4278                 ptr = make_ssa_name (SSA_NAME_VAR (dataref_ptr), new_stmt);
4279                 gimple_assign_set_lhs (new_stmt, ptr);
4280                 vect_finish_stmt_generation (stmt, new_stmt, gsi);
4281                 data_ref
4282                   = build2 (MEM_REF, vectype, ptr,
4283                             build_int_cst (reference_alias_ptr_type
4284                                              (DR_REF (first_dr)), 0));
4285                 break;
4286               }
4287             case dr_explicit_realign_optimized:
4288               new_stmt = gimple_build_assign_with_ops
4289                            (BIT_AND_EXPR, NULL_TREE, dataref_ptr,
4290                             build_int_cst
4291                               (TREE_TYPE (dataref_ptr),
4292                                -(HOST_WIDE_INT)TYPE_ALIGN_UNIT (vectype)));
4293               new_temp = make_ssa_name (SSA_NAME_VAR (dataref_ptr), new_stmt);
4294               gimple_assign_set_lhs (new_stmt, new_temp);
4295               vect_finish_stmt_generation (stmt, new_stmt, gsi);
4296               data_ref
4297                 = build2 (MEM_REF, vectype, new_temp,
4298                           build_int_cst (reference_alias_ptr_type
4299                                            (DR_REF (first_dr)), 0));
4300               break;
4301             default:
4302               gcc_unreachable ();
4303             }
4304           vec_dest = vect_create_destination_var (scalar_dest, vectype);
4305           new_stmt = gimple_build_assign (vec_dest, data_ref);
4306           new_temp = make_ssa_name (vec_dest, new_stmt);
4307           gimple_assign_set_lhs (new_stmt, new_temp);
4308           vect_finish_stmt_generation (stmt, new_stmt, gsi);
4309           mark_symbols_for_renaming (new_stmt);
4310
4311           /* 3. Handle explicit realignment if necessary/supported.  Create in
4312                 loop: vec_dest = realign_load (msq, lsq, realignment_token)  */
4313           if (alignment_support_scheme == dr_explicit_realign_optimized
4314               || alignment_support_scheme == dr_explicit_realign)
4315             {
4316               tree tmp;
4317
4318               lsq = gimple_assign_lhs (new_stmt);
4319               if (!realignment_token)
4320                 realignment_token = dataref_ptr;
4321               vec_dest = vect_create_destination_var (scalar_dest, vectype);
4322               tmp = build3 (REALIGN_LOAD_EXPR, vectype, msq, lsq,
4323                             realignment_token);
4324               new_stmt = gimple_build_assign (vec_dest, tmp);
4325               new_temp = make_ssa_name (vec_dest, new_stmt);
4326               gimple_assign_set_lhs (new_stmt, new_temp);
4327               vect_finish_stmt_generation (stmt, new_stmt, gsi);
4328
4329               if (alignment_support_scheme == dr_explicit_realign_optimized)
4330                 {
4331                   gcc_assert (phi);
4332                   if (i == vec_num - 1 && j == ncopies - 1)
4333                     add_phi_arg (phi, lsq, loop_latch_edge (containing_loop),
4334                                  UNKNOWN_LOCATION);
4335                   msq = lsq;
4336                 }
4337             }
4338
4339           /* 4. Handle invariant-load.  */
4340           if (inv_p && !bb_vinfo)
4341             {
4342               gcc_assert (!strided_load);
4343               gcc_assert (nested_in_vect_loop_p (loop, stmt));
4344               if (j == 0)
4345                 {
4346                   int k;
4347                   tree t = NULL_TREE;
4348                   tree vec_inv, bitpos, bitsize = TYPE_SIZE (scalar_type);
4349
4350                   /* CHECKME: bitpos depends on endianess?  */
4351                   bitpos = bitsize_zero_node;
4352                   vec_inv = build3 (BIT_FIELD_REF, scalar_type, new_temp,
4353                                     bitsize, bitpos);
4354                   vec_dest =
4355                         vect_create_destination_var (scalar_dest, NULL_TREE);
4356                   new_stmt = gimple_build_assign (vec_dest, vec_inv);
4357                   new_temp = make_ssa_name (vec_dest, new_stmt);
4358                   gimple_assign_set_lhs (new_stmt, new_temp);
4359                   vect_finish_stmt_generation (stmt, new_stmt, gsi);
4360
4361                   for (k = nunits - 1; k >= 0; --k)
4362                     t = tree_cons (NULL_TREE, new_temp, t);
4363                   /* FIXME: use build_constructor directly.  */
4364                   vec_inv = build_constructor_from_list (vectype, t);
4365                   new_temp = vect_init_vector (stmt, vec_inv, vectype, gsi);
4366                   new_stmt = SSA_NAME_DEF_STMT (new_temp);
4367                 }
4368               else
4369                 gcc_unreachable (); /* FORNOW. */
4370             }
4371
4372           if (negative)
4373             {
4374               new_temp = reverse_vec_elements (new_temp, stmt, gsi);
4375               new_stmt = SSA_NAME_DEF_STMT (new_temp);
4376             }
4377
4378           /* Collect vector loads and later create their permutation in
4379              vect_transform_strided_load ().  */
4380           if (strided_load || slp_perm)
4381             VEC_quick_push (tree, dr_chain, new_temp);
4382
4383          /* Store vector loads in the corresponding SLP_NODE.  */
4384           if (slp && !slp_perm)
4385             VEC_quick_push (gimple, SLP_TREE_VEC_STMTS (slp_node), new_stmt);
4386         }
4387
4388       if (slp && !slp_perm)
4389         continue;
4390
4391       if (slp_perm)
4392         {
4393           if (!vect_transform_slp_perm_load (stmt, dr_chain, gsi, vf,
4394                                              slp_node_instance, false))
4395             {
4396               VEC_free (tree, heap, dr_chain);
4397               return false;
4398             }
4399         }
4400       else
4401         {
4402           if (strided_load)
4403             {
4404               if (!vect_transform_strided_load (stmt, dr_chain, group_size, gsi))
4405                 return false;
4406
4407               *vec_stmt = STMT_VINFO_VEC_STMT (stmt_info);
4408               VEC_free (tree, heap, dr_chain);
4409               dr_chain = VEC_alloc (tree, heap, group_size);
4410             }
4411           else
4412             {
4413               if (j == 0)
4414                 STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt;
4415               else
4416                 STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt;
4417               prev_stmt_info = vinfo_for_stmt (new_stmt);
4418             }
4419         }
4420     }
4421
4422   if (dr_chain)
4423     VEC_free (tree, heap, dr_chain);
4424
4425   return true;
4426 }
4427
4428 /* Function vect_is_simple_cond.
4429
4430    Input:
4431    LOOP - the loop that is being vectorized.
4432    COND - Condition that is checked for simple use.
4433
4434    Returns whether a COND can be vectorized.  Checks whether
4435    condition operands are supportable using vec_is_simple_use.  */
4436
4437 static bool
4438 vect_is_simple_cond (tree cond, loop_vec_info loop_vinfo)
4439 {
4440   tree lhs, rhs;
4441   tree def;
4442   enum vect_def_type dt;
4443
4444   if (!COMPARISON_CLASS_P (cond))
4445     return false;
4446
4447   lhs = TREE_OPERAND (cond, 0);
4448   rhs = TREE_OPERAND (cond, 1);
4449
4450   if (TREE_CODE (lhs) == SSA_NAME)
4451     {
4452       gimple lhs_def_stmt = SSA_NAME_DEF_STMT (lhs);
4453       if (!vect_is_simple_use (lhs, loop_vinfo, NULL, &lhs_def_stmt, &def,
4454                                &dt))
4455         return false;
4456     }
4457   else if (TREE_CODE (lhs) != INTEGER_CST && TREE_CODE (lhs) != REAL_CST
4458            && TREE_CODE (lhs) != FIXED_CST)
4459     return false;
4460
4461   if (TREE_CODE (rhs) == SSA_NAME)
4462     {
4463       gimple rhs_def_stmt = SSA_NAME_DEF_STMT (rhs);
4464       if (!vect_is_simple_use (rhs, loop_vinfo, NULL, &rhs_def_stmt, &def,
4465                                &dt))
4466         return false;
4467     }
4468   else if (TREE_CODE (rhs) != INTEGER_CST  && TREE_CODE (rhs) != REAL_CST
4469            && TREE_CODE (rhs) != FIXED_CST)
4470     return false;
4471
4472   return true;
4473 }
4474
4475 /* vectorizable_condition.
4476
4477    Check if STMT is conditional modify expression that can be vectorized.
4478    If VEC_STMT is also passed, vectorize the STMT: create a vectorized
4479    stmt using VEC_COND_EXPR  to replace it, put it in VEC_STMT, and insert it
4480    at GSI.
4481
4482    When STMT is vectorized as nested cycle, REDUC_DEF is the vector variable
4483    to be used at REDUC_INDEX (in then clause if REDUC_INDEX is 1, and in
4484    else caluse if it is 2).
4485
4486    Return FALSE if not a vectorizable STMT, TRUE otherwise.  */
4487
4488 bool
4489 vectorizable_condition (gimple stmt, gimple_stmt_iterator *gsi,
4490                         gimple *vec_stmt, tree reduc_def, int reduc_index)
4491 {
4492   tree scalar_dest = NULL_TREE;
4493   tree vec_dest = NULL_TREE;
4494   tree op = NULL_TREE;
4495   tree cond_expr, then_clause, else_clause;
4496   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
4497   tree vectype = STMT_VINFO_VECTYPE (stmt_info);
4498   tree vec_cond_lhs = NULL_TREE, vec_cond_rhs = NULL_TREE;
4499   tree vec_then_clause = NULL_TREE, vec_else_clause = NULL_TREE;
4500   tree vec_compare, vec_cond_expr;
4501   tree new_temp;
4502   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
4503   enum machine_mode vec_mode;
4504   tree def;
4505   enum vect_def_type dt, dts[4];
4506   int nunits = TYPE_VECTOR_SUBPARTS (vectype);
4507   int ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits;
4508   enum tree_code code;
4509   stmt_vec_info prev_stmt_info = NULL;
4510   int j;
4511
4512   /* FORNOW: unsupported in basic block SLP.  */
4513   gcc_assert (loop_vinfo);
4514
4515   gcc_assert (ncopies >= 1);
4516   if (reduc_index && ncopies > 1)
4517     return false; /* FORNOW */
4518
4519   if (!STMT_VINFO_RELEVANT_P (stmt_info))
4520     return false;
4521
4522   if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def
4523       && !(STMT_VINFO_DEF_TYPE (stmt_info) == vect_nested_cycle
4524            && reduc_def))
4525     return false;
4526
4527   /* FORNOW: SLP not supported.  */
4528   if (STMT_SLP_TYPE (stmt_info))
4529     return false;
4530
4531   /* FORNOW: not yet supported.  */
4532   if (STMT_VINFO_LIVE_P (stmt_info))
4533     {
4534       if (vect_print_dump_info (REPORT_DETAILS))
4535         fprintf (vect_dump, "value used after loop.");
4536       return false;
4537     }
4538
4539   /* Is vectorizable conditional operation?  */
4540   if (!is_gimple_assign (stmt))
4541     return false;
4542
4543   code = gimple_assign_rhs_code (stmt);
4544
4545   if (code != COND_EXPR)
4546     return false;
4547
4548   gcc_assert (gimple_assign_single_p (stmt));
4549   op = gimple_assign_rhs1 (stmt);
4550   cond_expr = TREE_OPERAND (op, 0);
4551   then_clause = TREE_OPERAND (op, 1);
4552   else_clause = TREE_OPERAND (op, 2);
4553
4554   if (!vect_is_simple_cond (cond_expr, loop_vinfo))
4555     return false;
4556
4557   /* We do not handle two different vector types for the condition
4558      and the values.  */
4559   if (!types_compatible_p (TREE_TYPE (TREE_OPERAND (cond_expr, 0)),
4560                            TREE_TYPE (vectype)))
4561     return false;
4562
4563   if (TREE_CODE (then_clause) == SSA_NAME)
4564     {
4565       gimple then_def_stmt = SSA_NAME_DEF_STMT (then_clause);
4566       if (!vect_is_simple_use (then_clause, loop_vinfo, NULL,
4567                                &then_def_stmt, &def, &dt))
4568         return false;
4569     }
4570   else if (TREE_CODE (then_clause) != INTEGER_CST
4571            && TREE_CODE (then_clause) != REAL_CST
4572            && TREE_CODE (then_clause) != FIXED_CST)
4573     return false;
4574
4575   if (TREE_CODE (else_clause) == SSA_NAME)
4576     {
4577       gimple else_def_stmt = SSA_NAME_DEF_STMT (else_clause);
4578       if (!vect_is_simple_use (else_clause, loop_vinfo, NULL,
4579                                &else_def_stmt, &def, &dt))
4580         return false;
4581     }
4582   else if (TREE_CODE (else_clause) != INTEGER_CST
4583            && TREE_CODE (else_clause) != REAL_CST
4584            && TREE_CODE (else_clause) != FIXED_CST)
4585     return false;
4586
4587
4588   vec_mode = TYPE_MODE (vectype);
4589
4590   if (!vec_stmt)
4591     {
4592       STMT_VINFO_TYPE (stmt_info) = condition_vec_info_type;
4593       return expand_vec_cond_expr_p (TREE_TYPE (op), vec_mode);
4594     }
4595
4596   /* Transform */
4597
4598   /* Handle def.  */
4599   scalar_dest = gimple_assign_lhs (stmt);
4600   vec_dest = vect_create_destination_var (scalar_dest, vectype);
4601
4602   /* Handle cond expr.  */
4603   for (j = 0; j < ncopies; j++)
4604     {
4605       gimple new_stmt;
4606       if (j == 0)
4607         {
4608           gimple gtemp;
4609           vec_cond_lhs =
4610               vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 0),
4611                                             stmt, NULL);
4612           vect_is_simple_use (TREE_OPERAND (cond_expr, 0), loop_vinfo,
4613                               NULL, &gtemp, &def, &dts[0]);
4614           vec_cond_rhs =
4615               vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 1),
4616                                             stmt, NULL);
4617           vect_is_simple_use (TREE_OPERAND (cond_expr, 1), loop_vinfo,
4618                               NULL, &gtemp, &def, &dts[1]);
4619           if (reduc_index == 1)
4620             vec_then_clause = reduc_def;
4621           else
4622             {
4623               vec_then_clause = vect_get_vec_def_for_operand (then_clause,
4624                                                               stmt, NULL);
4625               vect_is_simple_use (then_clause, loop_vinfo,
4626                                   NULL, &gtemp, &def, &dts[2]);
4627             }
4628           if (reduc_index == 2)
4629             vec_else_clause = reduc_def;
4630           else
4631             {
4632               vec_else_clause = vect_get_vec_def_for_operand (else_clause,
4633                                                               stmt, NULL);
4634               vect_is_simple_use (else_clause, loop_vinfo,
4635                                   NULL, &gtemp, &def, &dts[3]);
4636             }
4637         }
4638       else
4639         {
4640           vec_cond_lhs = vect_get_vec_def_for_stmt_copy (dts[0], vec_cond_lhs);
4641           vec_cond_rhs = vect_get_vec_def_for_stmt_copy (dts[1], vec_cond_rhs);
4642           vec_then_clause = vect_get_vec_def_for_stmt_copy (dts[2],
4643                                                             vec_then_clause);
4644           vec_else_clause = vect_get_vec_def_for_stmt_copy (dts[3],
4645                                                             vec_else_clause);
4646         }
4647
4648       /* Arguments are ready.  Create the new vector stmt.  */
4649       vec_compare = build2 (TREE_CODE (cond_expr), vectype,
4650                             vec_cond_lhs, vec_cond_rhs);
4651       vec_cond_expr = build3 (VEC_COND_EXPR, vectype,
4652                               vec_compare, vec_then_clause, vec_else_clause);
4653
4654       new_stmt = gimple_build_assign (vec_dest, vec_cond_expr);
4655       new_temp = make_ssa_name (vec_dest, new_stmt);
4656       gimple_assign_set_lhs (new_stmt, new_temp);
4657       vect_finish_stmt_generation (stmt, new_stmt, gsi);
4658       if (j == 0)
4659         STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt;
4660       else
4661         STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt;
4662
4663       prev_stmt_info = vinfo_for_stmt (new_stmt);
4664     }
4665
4666   return true;
4667 }
4668
4669
4670 /* Make sure the statement is vectorizable.  */
4671
4672 bool
4673 vect_analyze_stmt (gimple stmt, bool *need_to_vectorize, slp_tree node)
4674 {
4675   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
4676   bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info);
4677   enum vect_relevant relevance = STMT_VINFO_RELEVANT (stmt_info);
4678   bool ok;
4679   tree scalar_type, vectype;
4680
4681   if (vect_print_dump_info (REPORT_DETAILS))
4682     {
4683       fprintf (vect_dump, "==> examining statement: ");
4684       print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
4685     }
4686
4687   if (gimple_has_volatile_ops (stmt))
4688     {
4689       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
4690         fprintf (vect_dump, "not vectorized: stmt has volatile operands");
4691
4692       return false;
4693     }
4694
4695   /* Skip stmts that do not need to be vectorized. In loops this is expected
4696      to include:
4697      - the COND_EXPR which is the loop exit condition
4698      - any LABEL_EXPRs in the loop
4699      - computations that are used only for array indexing or loop control.
4700      In basic blocks we only analyze statements that are a part of some SLP
4701      instance, therefore, all the statements are relevant.  */
4702
4703   if (!STMT_VINFO_RELEVANT_P (stmt_info)
4704       && !STMT_VINFO_LIVE_P (stmt_info))
4705     {
4706       if (vect_print_dump_info (REPORT_DETAILS))
4707         fprintf (vect_dump, "irrelevant.");
4708
4709       return true;
4710     }
4711
4712   switch (STMT_VINFO_DEF_TYPE (stmt_info))
4713     {
4714       case vect_internal_def:
4715         break;
4716
4717       case vect_reduction_def:
4718       case vect_nested_cycle:
4719          gcc_assert (!bb_vinfo && (relevance == vect_used_in_outer
4720                      || relevance == vect_used_in_outer_by_reduction
4721                      || relevance == vect_unused_in_scope));
4722          break;
4723
4724       case vect_induction_def:
4725       case vect_constant_def:
4726       case vect_external_def:
4727       case vect_unknown_def_type:
4728       default:
4729         gcc_unreachable ();
4730     }
4731
4732   if (bb_vinfo)
4733     {
4734       gcc_assert (PURE_SLP_STMT (stmt_info));
4735
4736       scalar_type = TREE_TYPE (gimple_get_lhs (stmt));
4737       if (vect_print_dump_info (REPORT_DETAILS))
4738         {
4739           fprintf (vect_dump, "get vectype for scalar type:  ");
4740           print_generic_expr (vect_dump, scalar_type, TDF_SLIM);
4741         }
4742
4743       vectype = get_vectype_for_scalar_type (scalar_type);
4744       if (!vectype)
4745         {
4746           if (vect_print_dump_info (REPORT_DETAILS))
4747             {
4748                fprintf (vect_dump, "not SLPed: unsupported data-type ");
4749                print_generic_expr (vect_dump, scalar_type, TDF_SLIM);
4750             }
4751           return false;
4752         }
4753
4754       if (vect_print_dump_info (REPORT_DETAILS))
4755         {
4756           fprintf (vect_dump, "vectype:  ");
4757           print_generic_expr (vect_dump, vectype, TDF_SLIM);
4758         }
4759
4760       STMT_VINFO_VECTYPE (stmt_info) = vectype;
4761    }
4762
4763   if (STMT_VINFO_RELEVANT_P (stmt_info))
4764     {
4765       gcc_assert (!VECTOR_MODE_P (TYPE_MODE (gimple_expr_type (stmt))));
4766       gcc_assert (STMT_VINFO_VECTYPE (stmt_info));
4767       *need_to_vectorize = true;
4768     }
4769
4770    ok = true;
4771    if (!bb_vinfo
4772        && (STMT_VINFO_RELEVANT_P (stmt_info)
4773            || STMT_VINFO_DEF_TYPE (stmt_info) == vect_reduction_def))
4774       ok = (vectorizable_type_promotion (stmt, NULL, NULL, NULL)
4775             || vectorizable_type_demotion (stmt, NULL, NULL, NULL)
4776             || vectorizable_conversion (stmt, NULL, NULL, NULL)
4777             || vectorizable_shift (stmt, NULL, NULL, NULL)
4778             || vectorizable_operation (stmt, NULL, NULL, NULL)
4779             || vectorizable_assignment (stmt, NULL, NULL, NULL)
4780             || vectorizable_load (stmt, NULL, NULL, NULL, NULL)
4781             || vectorizable_call (stmt, NULL, NULL)
4782             || vectorizable_store (stmt, NULL, NULL, NULL)
4783             || vectorizable_reduction (stmt, NULL, NULL, NULL)
4784             || vectorizable_condition (stmt, NULL, NULL, NULL, 0));
4785     else
4786       {
4787         if (bb_vinfo)
4788           ok = (vectorizable_shift (stmt, NULL, NULL, node)
4789                 || vectorizable_operation (stmt, NULL, NULL, node)
4790                 || vectorizable_assignment (stmt, NULL, NULL, node)
4791                 || vectorizable_load (stmt, NULL, NULL, node, NULL)
4792                 || vectorizable_store (stmt, NULL, NULL, node));
4793       }
4794
4795   if (!ok)
4796     {
4797       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
4798         {
4799           fprintf (vect_dump, "not vectorized: relevant stmt not ");
4800           fprintf (vect_dump, "supported: ");
4801           print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
4802         }
4803
4804       return false;
4805     }
4806
4807   if (bb_vinfo)
4808     return true;
4809
4810   /* Stmts that are (also) "live" (i.e. - that are used out of the loop)
4811       need extra handling, except for vectorizable reductions.  */
4812   if (STMT_VINFO_LIVE_P (stmt_info)
4813       && STMT_VINFO_TYPE (stmt_info) != reduc_vec_info_type)
4814     ok = vectorizable_live_operation (stmt, NULL, NULL);
4815
4816   if (!ok)
4817     {
4818       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
4819         {
4820           fprintf (vect_dump, "not vectorized: live stmt not ");
4821           fprintf (vect_dump, "supported: ");
4822           print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
4823         }
4824
4825        return false;
4826     }
4827
4828   if (!PURE_SLP_STMT (stmt_info))
4829     {
4830       /* Groups of strided accesses whose size is not a power of 2 are not
4831          vectorizable yet using loop-vectorization.  Therefore, if this stmt
4832          feeds non-SLP-able stmts (i.e., this stmt has to be both SLPed and
4833          loop-based vectorized), the loop cannot be vectorized.  */
4834       if (STMT_VINFO_STRIDED_ACCESS (stmt_info)
4835           && exact_log2 (DR_GROUP_SIZE (vinfo_for_stmt (
4836                                         DR_GROUP_FIRST_DR (stmt_info)))) == -1)
4837         {
4838           if (vect_print_dump_info (REPORT_DETAILS))
4839             {
4840               fprintf (vect_dump, "not vectorized: the size of group "
4841                                   "of strided accesses is not a power of 2");
4842               print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
4843             }
4844
4845           return false;
4846         }
4847     }
4848
4849   return true;
4850 }
4851
4852
4853 /* Function vect_transform_stmt.
4854
4855    Create a vectorized stmt to replace STMT, and insert it at BSI.  */
4856
4857 bool
4858 vect_transform_stmt (gimple stmt, gimple_stmt_iterator *gsi,
4859                      bool *strided_store, slp_tree slp_node,
4860                      slp_instance slp_node_instance)
4861 {
4862   bool is_store = false;
4863   gimple vec_stmt = NULL;
4864   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
4865   gimple orig_stmt_in_pattern;
4866   bool done;
4867
4868   switch (STMT_VINFO_TYPE (stmt_info))
4869     {
4870     case type_demotion_vec_info_type:
4871       done = vectorizable_type_demotion (stmt, gsi, &vec_stmt, slp_node);
4872       gcc_assert (done);
4873       break;
4874
4875     case type_promotion_vec_info_type:
4876       done = vectorizable_type_promotion (stmt, gsi, &vec_stmt, slp_node);
4877       gcc_assert (done);
4878       break;
4879
4880     case type_conversion_vec_info_type:
4881       done = vectorizable_conversion (stmt, gsi, &vec_stmt, slp_node);
4882       gcc_assert (done);
4883       break;
4884
4885     case induc_vec_info_type:
4886       gcc_assert (!slp_node);
4887       done = vectorizable_induction (stmt, gsi, &vec_stmt);
4888       gcc_assert (done);
4889       break;
4890
4891     case shift_vec_info_type:
4892       done = vectorizable_shift (stmt, gsi, &vec_stmt, slp_node);
4893       gcc_assert (done);
4894       break;
4895
4896     case op_vec_info_type:
4897       done = vectorizable_operation (stmt, gsi, &vec_stmt, slp_node);
4898       gcc_assert (done);
4899       break;
4900
4901     case assignment_vec_info_type:
4902       done = vectorizable_assignment (stmt, gsi, &vec_stmt, slp_node);
4903       gcc_assert (done);
4904       break;
4905
4906     case load_vec_info_type:
4907       done = vectorizable_load (stmt, gsi, &vec_stmt, slp_node,
4908                                 slp_node_instance);
4909       gcc_assert (done);
4910       break;
4911
4912     case store_vec_info_type:
4913       done = vectorizable_store (stmt, gsi, &vec_stmt, slp_node);
4914       gcc_assert (done);
4915       if (STMT_VINFO_STRIDED_ACCESS (stmt_info) && !slp_node)
4916         {
4917           /* In case of interleaving, the whole chain is vectorized when the
4918              last store in the chain is reached.  Store stmts before the last
4919              one are skipped, and there vec_stmt_info shouldn't be freed
4920              meanwhile.  */
4921           *strided_store = true;
4922           if (STMT_VINFO_VEC_STMT (stmt_info))
4923             is_store = true;
4924           }
4925       else
4926         is_store = true;
4927       break;
4928
4929     case condition_vec_info_type:
4930       gcc_assert (!slp_node);
4931       done = vectorizable_condition (stmt, gsi, &vec_stmt, NULL, 0);
4932       gcc_assert (done);
4933       break;
4934
4935     case call_vec_info_type:
4936       gcc_assert (!slp_node);
4937       done = vectorizable_call (stmt, gsi, &vec_stmt);
4938       stmt = gsi_stmt (*gsi);
4939       break;
4940
4941     case reduc_vec_info_type:
4942       done = vectorizable_reduction (stmt, gsi, &vec_stmt, slp_node);
4943       gcc_assert (done);
4944       break;
4945
4946     default:
4947       if (!STMT_VINFO_LIVE_P (stmt_info))
4948         {
4949           if (vect_print_dump_info (REPORT_DETAILS))
4950             fprintf (vect_dump, "stmt not supported.");
4951           gcc_unreachable ();
4952         }
4953     }
4954
4955   /* Handle inner-loop stmts whose DEF is used in the loop-nest that
4956      is being vectorized, but outside the immediately enclosing loop.  */
4957   if (vec_stmt
4958       && STMT_VINFO_LOOP_VINFO (stmt_info)
4959       && nested_in_vect_loop_p (LOOP_VINFO_LOOP (
4960                                 STMT_VINFO_LOOP_VINFO (stmt_info)), stmt)
4961       && STMT_VINFO_TYPE (stmt_info) != reduc_vec_info_type
4962       && (STMT_VINFO_RELEVANT (stmt_info) == vect_used_in_outer
4963           || STMT_VINFO_RELEVANT (stmt_info) ==
4964                                            vect_used_in_outer_by_reduction))
4965     {
4966       struct loop *innerloop = LOOP_VINFO_LOOP (
4967                                 STMT_VINFO_LOOP_VINFO (stmt_info))->inner;
4968       imm_use_iterator imm_iter;
4969       use_operand_p use_p;
4970       tree scalar_dest;
4971       gimple exit_phi;
4972
4973       if (vect_print_dump_info (REPORT_DETAILS))
4974         fprintf (vect_dump, "Record the vdef for outer-loop vectorization.");
4975
4976       /* Find the relevant loop-exit phi-node, and reord the vec_stmt there
4977         (to be used when vectorizing outer-loop stmts that use the DEF of
4978         STMT).  */
4979       if (gimple_code (stmt) == GIMPLE_PHI)
4980         scalar_dest = PHI_RESULT (stmt);
4981       else
4982         scalar_dest = gimple_assign_lhs (stmt);
4983
4984       FOR_EACH_IMM_USE_FAST (use_p, imm_iter, scalar_dest)
4985        {
4986          if (!flow_bb_inside_loop_p (innerloop, gimple_bb (USE_STMT (use_p))))
4987            {
4988              exit_phi = USE_STMT (use_p);
4989              STMT_VINFO_VEC_STMT (vinfo_for_stmt (exit_phi)) = vec_stmt;
4990            }
4991        }
4992     }
4993
4994   /* Handle stmts whose DEF is used outside the loop-nest that is
4995      being vectorized.  */
4996   if (STMT_VINFO_LIVE_P (stmt_info)
4997       && STMT_VINFO_TYPE (stmt_info) != reduc_vec_info_type)
4998     {
4999       done = vectorizable_live_operation (stmt, gsi, &vec_stmt);
5000       gcc_assert (done);
5001     }
5002
5003   if (vec_stmt)
5004     {
5005       STMT_VINFO_VEC_STMT (stmt_info) = vec_stmt;
5006       orig_stmt_in_pattern = STMT_VINFO_RELATED_STMT (stmt_info);
5007       if (orig_stmt_in_pattern)
5008         {
5009           stmt_vec_info stmt_vinfo = vinfo_for_stmt (orig_stmt_in_pattern);
5010           /* STMT was inserted by the vectorizer to replace a computation idiom.
5011              ORIG_STMT_IN_PATTERN is a stmt in the original sequence that
5012              computed this idiom.  We need to record a pointer to VEC_STMT in
5013              the stmt_info of ORIG_STMT_IN_PATTERN.  See more details in the
5014              documentation of vect_pattern_recog.  */
5015           if (STMT_VINFO_IN_PATTERN_P (stmt_vinfo))
5016             STMT_VINFO_VEC_STMT (stmt_vinfo) = vec_stmt;
5017         }
5018     }
5019
5020   return is_store;
5021 }
5022
5023
5024 /* Remove a group of stores (for SLP or interleaving), free their
5025    stmt_vec_info.  */
5026
5027 void
5028 vect_remove_stores (gimple first_stmt)
5029 {
5030   gimple next = first_stmt;
5031   gimple tmp;
5032   gimple_stmt_iterator next_si;
5033
5034   while (next)
5035     {
5036       /* Free the attached stmt_vec_info and remove the stmt.  */
5037       next_si = gsi_for_stmt (next);
5038       gsi_remove (&next_si, true);
5039       tmp = DR_GROUP_NEXT_DR (vinfo_for_stmt (next));
5040       free_stmt_vec_info (next);
5041       next = tmp;
5042     }
5043 }
5044
5045
5046 /* Function new_stmt_vec_info.
5047
5048    Create and initialize a new stmt_vec_info struct for STMT.  */
5049
5050 stmt_vec_info
5051 new_stmt_vec_info (gimple stmt, loop_vec_info loop_vinfo,
5052                    bb_vec_info bb_vinfo)
5053 {
5054   stmt_vec_info res;
5055   res = (stmt_vec_info) xcalloc (1, sizeof (struct _stmt_vec_info));
5056
5057   STMT_VINFO_TYPE (res) = undef_vec_info_type;
5058   STMT_VINFO_STMT (res) = stmt;
5059   STMT_VINFO_LOOP_VINFO (res) = loop_vinfo;
5060   STMT_VINFO_BB_VINFO (res) = bb_vinfo;
5061   STMT_VINFO_RELEVANT (res) = vect_unused_in_scope;
5062   STMT_VINFO_LIVE_P (res) = false;
5063   STMT_VINFO_VECTYPE (res) = NULL;
5064   STMT_VINFO_VEC_STMT (res) = NULL;
5065   STMT_VINFO_VECTORIZABLE (res) = true;
5066   STMT_VINFO_IN_PATTERN_P (res) = false;
5067   STMT_VINFO_RELATED_STMT (res) = NULL;
5068   STMT_VINFO_DATA_REF (res) = NULL;
5069
5070   STMT_VINFO_DR_BASE_ADDRESS (res) = NULL;
5071   STMT_VINFO_DR_OFFSET (res) = NULL;
5072   STMT_VINFO_DR_INIT (res) = NULL;
5073   STMT_VINFO_DR_STEP (res) = NULL;
5074   STMT_VINFO_DR_ALIGNED_TO (res) = NULL;
5075
5076   if (gimple_code (stmt) == GIMPLE_PHI
5077       && is_loop_header_bb_p (gimple_bb (stmt)))
5078     STMT_VINFO_DEF_TYPE (res) = vect_unknown_def_type;
5079   else
5080     STMT_VINFO_DEF_TYPE (res) = vect_internal_def;
5081
5082   STMT_VINFO_SAME_ALIGN_REFS (res) = VEC_alloc (dr_p, heap, 5);
5083   STMT_VINFO_INSIDE_OF_LOOP_COST (res) = 0;
5084   STMT_VINFO_OUTSIDE_OF_LOOP_COST (res) = 0;
5085   STMT_SLP_TYPE (res) = loop_vect;
5086   DR_GROUP_FIRST_DR (res) = NULL;
5087   DR_GROUP_NEXT_DR (res) = NULL;
5088   DR_GROUP_SIZE (res) = 0;
5089   DR_GROUP_STORE_COUNT (res) = 0;
5090   DR_GROUP_GAP (res) = 0;
5091   DR_GROUP_SAME_DR_STMT (res) = NULL;
5092   DR_GROUP_READ_WRITE_DEPENDENCE (res) = false;
5093
5094   return res;
5095 }
5096
5097
5098 /* Create a hash table for stmt_vec_info. */
5099
5100 void
5101 init_stmt_vec_info_vec (void)
5102 {
5103   gcc_assert (!stmt_vec_info_vec);
5104   stmt_vec_info_vec = VEC_alloc (vec_void_p, heap, 50);
5105 }
5106
5107
5108 /* Free hash table for stmt_vec_info. */
5109
5110 void
5111 free_stmt_vec_info_vec (void)
5112 {
5113   gcc_assert (stmt_vec_info_vec);
5114   VEC_free (vec_void_p, heap, stmt_vec_info_vec);
5115 }
5116
5117
5118 /* Free stmt vectorization related info.  */
5119
5120 void
5121 free_stmt_vec_info (gimple stmt)
5122 {
5123   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
5124
5125   if (!stmt_info)
5126     return;
5127
5128   VEC_free (dr_p, heap, STMT_VINFO_SAME_ALIGN_REFS (stmt_info));
5129   set_vinfo_for_stmt (stmt, NULL);
5130   free (stmt_info);
5131 }
5132
5133
5134 /* Function get_vectype_for_scalar_type_and_size.
5135
5136    Returns the vector type corresponding to SCALAR_TYPE  and SIZE as supported
5137    by the target.  */
5138
5139 static tree
5140 get_vectype_for_scalar_type_and_size (tree scalar_type, unsigned size)
5141 {
5142   enum machine_mode inner_mode = TYPE_MODE (scalar_type);
5143   enum machine_mode simd_mode;
5144   unsigned int nbytes = GET_MODE_SIZE (inner_mode);
5145   int nunits;
5146   tree vectype;
5147
5148   if (nbytes == 0)
5149     return NULL_TREE;
5150
5151   /* We can't build a vector type of elements with alignment bigger than
5152      their size.  */
5153   if (nbytes < TYPE_ALIGN_UNIT (scalar_type))
5154     return NULL_TREE;
5155
5156   /* If we'd build a vector type of elements whose mode precision doesn't
5157      match their types precision we'll get mismatched types on vector
5158      extracts via BIT_FIELD_REFs.  This effectively means we disable
5159      vectorization of bool and/or enum types in some languages.  */
5160   if (INTEGRAL_TYPE_P (scalar_type)
5161       && GET_MODE_BITSIZE (inner_mode) != TYPE_PRECISION (scalar_type))
5162     return NULL_TREE;
5163
5164   if (GET_MODE_CLASS (inner_mode) != MODE_INT
5165       && GET_MODE_CLASS (inner_mode) != MODE_FLOAT)
5166     return NULL_TREE;
5167
5168   /* We shouldn't end up building VECTOR_TYPEs of non-scalar components.
5169      When the component mode passes the above test simply use a type
5170      corresponding to that mode.  The theory is that any use that
5171      would cause problems with this will disable vectorization anyway.  */
5172   if (!SCALAR_FLOAT_TYPE_P (scalar_type)
5173       && !INTEGRAL_TYPE_P (scalar_type)
5174       && !POINTER_TYPE_P (scalar_type))
5175     scalar_type = lang_hooks.types.type_for_mode (inner_mode, 1);
5176
5177   /* If no size was supplied use the mode the target prefers.   Otherwise
5178      lookup a vector mode of the specified size.  */
5179   if (size == 0)
5180     simd_mode = targetm.vectorize.preferred_simd_mode (inner_mode);
5181   else
5182     simd_mode = mode_for_vector (inner_mode, size / nbytes);
5183   nunits = GET_MODE_SIZE (simd_mode) / nbytes;
5184   if (nunits <= 1)
5185     return NULL_TREE;
5186
5187   vectype = build_vector_type (scalar_type, nunits);
5188   if (vect_print_dump_info (REPORT_DETAILS))
5189     {
5190       fprintf (vect_dump, "get vectype with %d units of type ", nunits);
5191       print_generic_expr (vect_dump, scalar_type, TDF_SLIM);
5192     }
5193
5194   if (!vectype)
5195     return NULL_TREE;
5196
5197   if (vect_print_dump_info (REPORT_DETAILS))
5198     {
5199       fprintf (vect_dump, "vectype: ");
5200       print_generic_expr (vect_dump, vectype, TDF_SLIM);
5201     }
5202
5203   if (!VECTOR_MODE_P (TYPE_MODE (vectype))
5204       && !INTEGRAL_MODE_P (TYPE_MODE (vectype)))
5205     {
5206       if (vect_print_dump_info (REPORT_DETAILS))
5207         fprintf (vect_dump, "mode not supported by target.");
5208       return NULL_TREE;
5209     }
5210
5211   return vectype;
5212 }
5213
5214 unsigned int current_vector_size;
5215
5216 /* Function get_vectype_for_scalar_type.
5217
5218    Returns the vector type corresponding to SCALAR_TYPE as supported
5219    by the target.  */
5220
5221 tree
5222 get_vectype_for_scalar_type (tree scalar_type)
5223 {
5224   tree vectype;
5225   vectype = get_vectype_for_scalar_type_and_size (scalar_type,
5226                                                   current_vector_size);
5227   if (vectype
5228       && current_vector_size == 0)
5229     current_vector_size = GET_MODE_SIZE (TYPE_MODE (vectype));
5230   return vectype;
5231 }
5232
5233 /* Function get_same_sized_vectype
5234
5235    Returns a vector type corresponding to SCALAR_TYPE of size
5236    VECTOR_TYPE if supported by the target.  */
5237
5238 tree
5239 get_same_sized_vectype (tree scalar_type, tree vector_type)
5240 {
5241   return get_vectype_for_scalar_type_and_size
5242            (scalar_type, GET_MODE_SIZE (TYPE_MODE (vector_type)));
5243 }
5244
5245 /* Function vect_is_simple_use.
5246
5247    Input:
5248    LOOP_VINFO - the vect info of the loop that is being vectorized.
5249    BB_VINFO - the vect info of the basic block that is being vectorized.
5250    OPERAND - operand of a stmt in the loop or bb.
5251    DEF - the defining stmt in case OPERAND is an SSA_NAME.
5252
5253    Returns whether a stmt with OPERAND can be vectorized.
5254    For loops, supportable operands are constants, loop invariants, and operands
5255    that are defined by the current iteration of the loop.  Unsupportable
5256    operands are those that are defined by a previous iteration of the loop (as
5257    is the case in reduction/induction computations).
5258    For basic blocks, supportable operands are constants and bb invariants.
5259    For now, operands defined outside the basic block are not supported.  */
5260
5261 bool
5262 vect_is_simple_use (tree operand, loop_vec_info loop_vinfo,
5263                     bb_vec_info bb_vinfo, gimple *def_stmt,
5264                     tree *def, enum vect_def_type *dt)
5265 {
5266   basic_block bb;
5267   stmt_vec_info stmt_vinfo;
5268   struct loop *loop = NULL;
5269
5270   if (loop_vinfo)
5271     loop = LOOP_VINFO_LOOP (loop_vinfo);
5272
5273   *def_stmt = NULL;
5274   *def = NULL_TREE;
5275
5276   if (vect_print_dump_info (REPORT_DETAILS))
5277     {
5278       fprintf (vect_dump, "vect_is_simple_use: operand ");
5279       print_generic_expr (vect_dump, operand, TDF_SLIM);
5280     }
5281
5282   if (TREE_CODE (operand) == INTEGER_CST || TREE_CODE (operand) == REAL_CST)
5283     {
5284       *dt = vect_constant_def;
5285       return true;
5286     }
5287
5288   if (is_gimple_min_invariant (operand))
5289     {
5290       *def = operand;
5291       *dt = vect_external_def;
5292       return true;
5293     }
5294
5295   if (TREE_CODE (operand) == PAREN_EXPR)
5296     {
5297       if (vect_print_dump_info (REPORT_DETAILS))
5298         fprintf (vect_dump, "non-associatable copy.");
5299       operand = TREE_OPERAND (operand, 0);
5300     }
5301
5302   if (TREE_CODE (operand) != SSA_NAME)
5303     {
5304       if (vect_print_dump_info (REPORT_DETAILS))
5305         fprintf (vect_dump, "not ssa-name.");
5306       return false;
5307     }
5308
5309   *def_stmt = SSA_NAME_DEF_STMT (operand);
5310   if (*def_stmt == NULL)
5311     {
5312       if (vect_print_dump_info (REPORT_DETAILS))
5313         fprintf (vect_dump, "no def_stmt.");
5314       return false;
5315     }
5316
5317   if (vect_print_dump_info (REPORT_DETAILS))
5318     {
5319       fprintf (vect_dump, "def_stmt: ");
5320       print_gimple_stmt (vect_dump, *def_stmt, 0, TDF_SLIM);
5321     }
5322
5323   /* Empty stmt is expected only in case of a function argument.
5324      (Otherwise - we expect a phi_node or a GIMPLE_ASSIGN).  */
5325   if (gimple_nop_p (*def_stmt))
5326     {
5327       *def = operand;
5328       *dt = vect_external_def;
5329       return true;
5330     }
5331
5332   bb = gimple_bb (*def_stmt);
5333
5334   if ((loop && !flow_bb_inside_loop_p (loop, bb))
5335       || (!loop && bb != BB_VINFO_BB (bb_vinfo))
5336       || (!loop && gimple_code (*def_stmt) == GIMPLE_PHI))
5337     *dt = vect_external_def;
5338   else
5339     {
5340       stmt_vinfo = vinfo_for_stmt (*def_stmt);
5341       *dt = STMT_VINFO_DEF_TYPE (stmt_vinfo);
5342     }
5343
5344   if (*dt == vect_unknown_def_type)
5345     {
5346       if (vect_print_dump_info (REPORT_DETAILS))
5347         fprintf (vect_dump, "Unsupported pattern.");
5348       return false;
5349     }
5350
5351   if (vect_print_dump_info (REPORT_DETAILS))
5352     fprintf (vect_dump, "type of def: %d.",*dt);
5353
5354   switch (gimple_code (*def_stmt))
5355     {
5356     case GIMPLE_PHI:
5357       *def = gimple_phi_result (*def_stmt);
5358       break;
5359
5360     case GIMPLE_ASSIGN:
5361       *def = gimple_assign_lhs (*def_stmt);
5362       break;
5363
5364     case GIMPLE_CALL:
5365       *def = gimple_call_lhs (*def_stmt);
5366       if (*def != NULL)
5367         break;
5368       /* FALLTHRU */
5369     default:
5370       if (vect_print_dump_info (REPORT_DETAILS))
5371         fprintf (vect_dump, "unsupported defining stmt: ");
5372       return false;
5373     }
5374
5375   return true;
5376 }
5377
5378 /* Function vect_is_simple_use_1.
5379
5380    Same as vect_is_simple_use_1 but also determines the vector operand
5381    type of OPERAND and stores it to *VECTYPE.  If the definition of
5382    OPERAND is vect_uninitialized_def, vect_constant_def or
5383    vect_external_def *VECTYPE will be set to NULL_TREE and the caller
5384    is responsible to compute the best suited vector type for the
5385    scalar operand.  */
5386
5387 bool
5388 vect_is_simple_use_1 (tree operand, loop_vec_info loop_vinfo,
5389                       bb_vec_info bb_vinfo, gimple *def_stmt,
5390                       tree *def, enum vect_def_type *dt, tree *vectype)
5391 {
5392   if (!vect_is_simple_use (operand, loop_vinfo, bb_vinfo, def_stmt, def, dt))
5393     return false;
5394
5395   /* Now get a vector type if the def is internal, otherwise supply
5396      NULL_TREE and leave it up to the caller to figure out a proper
5397      type for the use stmt.  */
5398   if (*dt == vect_internal_def
5399       || *dt == vect_induction_def
5400       || *dt == vect_reduction_def
5401       || *dt == vect_double_reduction_def
5402       || *dt == vect_nested_cycle)
5403     {
5404       stmt_vec_info stmt_info = vinfo_for_stmt (*def_stmt);
5405       if (STMT_VINFO_IN_PATTERN_P (stmt_info))
5406         stmt_info = vinfo_for_stmt (STMT_VINFO_RELATED_STMT (stmt_info));
5407       *vectype = STMT_VINFO_VECTYPE (stmt_info);
5408       gcc_assert (*vectype != NULL_TREE);
5409     }
5410   else if (*dt == vect_uninitialized_def
5411            || *dt == vect_constant_def
5412            || *dt == vect_external_def)
5413     *vectype = NULL_TREE;
5414   else
5415     gcc_unreachable ();
5416
5417   return true;
5418 }
5419
5420
5421 /* Function supportable_widening_operation
5422
5423    Check whether an operation represented by the code CODE is a
5424    widening operation that is supported by the target platform in
5425    vector form (i.e., when operating on arguments of type VECTYPE_IN
5426    producing a result of type VECTYPE_OUT).
5427
5428    Widening operations we currently support are NOP (CONVERT), FLOAT
5429    and WIDEN_MULT.  This function checks if these operations are supported
5430    by the target platform either directly (via vector tree-codes), or via
5431    target builtins.
5432
5433    Output:
5434    - CODE1 and CODE2 are codes of vector operations to be used when
5435    vectorizing the operation, if available.
5436    - DECL1 and DECL2 are decls of target builtin functions to be used
5437    when vectorizing the operation, if available.  In this case,
5438    CODE1 and CODE2 are CALL_EXPR.
5439    - MULTI_STEP_CVT determines the number of required intermediate steps in
5440    case of multi-step conversion (like char->short->int - in that case
5441    MULTI_STEP_CVT will be 1).
5442    - INTERM_TYPES contains the intermediate type required to perform the
5443    widening operation (short in the above example).  */
5444
5445 bool
5446 supportable_widening_operation (enum tree_code code, gimple stmt,
5447                                 tree vectype_out, tree vectype_in,
5448                                 tree *decl1, tree *decl2,
5449                                 enum tree_code *code1, enum tree_code *code2,
5450                                 int *multi_step_cvt,
5451                                 VEC (tree, heap) **interm_types)
5452 {
5453   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
5454   loop_vec_info loop_info = STMT_VINFO_LOOP_VINFO (stmt_info);
5455   struct loop *vect_loop = LOOP_VINFO_LOOP (loop_info);
5456   bool ordered_p;
5457   enum machine_mode vec_mode;
5458   enum insn_code icode1, icode2;
5459   optab optab1, optab2;
5460   tree vectype = vectype_in;
5461   tree wide_vectype = vectype_out;
5462   enum tree_code c1, c2;
5463
5464   /* The result of a vectorized widening operation usually requires two vectors
5465      (because the widened results do not fit int one vector). The generated
5466      vector results would normally be expected to be generated in the same
5467      order as in the original scalar computation, i.e. if 8 results are
5468      generated in each vector iteration, they are to be organized as follows:
5469         vect1: [res1,res2,res3,res4], vect2: [res5,res6,res7,res8].
5470
5471      However, in the special case that the result of the widening operation is
5472      used in a reduction computation only, the order doesn't matter (because
5473      when vectorizing a reduction we change the order of the computation).
5474      Some targets can take advantage of this and generate more efficient code.
5475      For example, targets like Altivec, that support widen_mult using a sequence
5476      of {mult_even,mult_odd} generate the following vectors:
5477         vect1: [res1,res3,res5,res7], vect2: [res2,res4,res6,res8].
5478
5479      When vectorizing outer-loops, we execute the inner-loop sequentially
5480      (each vectorized inner-loop iteration contributes to VF outer-loop
5481      iterations in parallel).  We therefore don't allow to change the order
5482      of the computation in the inner-loop during outer-loop vectorization.  */
5483
5484    if (STMT_VINFO_RELEVANT (stmt_info) == vect_used_by_reduction
5485        && !nested_in_vect_loop_p (vect_loop, stmt))
5486      ordered_p = false;
5487    else
5488      ordered_p = true;
5489
5490   if (!ordered_p
5491       && code == WIDEN_MULT_EXPR
5492       && targetm.vectorize.builtin_mul_widen_even
5493       && targetm.vectorize.builtin_mul_widen_even (vectype)
5494       && targetm.vectorize.builtin_mul_widen_odd
5495       && targetm.vectorize.builtin_mul_widen_odd (vectype))
5496     {
5497       if (vect_print_dump_info (REPORT_DETAILS))
5498         fprintf (vect_dump, "Unordered widening operation detected.");
5499
5500       *code1 = *code2 = CALL_EXPR;
5501       *decl1 = targetm.vectorize.builtin_mul_widen_even (vectype);
5502       *decl2 = targetm.vectorize.builtin_mul_widen_odd (vectype);
5503       return true;
5504     }
5505
5506   switch (code)
5507     {
5508     case WIDEN_MULT_EXPR:
5509       if (BYTES_BIG_ENDIAN)
5510         {
5511           c1 = VEC_WIDEN_MULT_HI_EXPR;
5512           c2 = VEC_WIDEN_MULT_LO_EXPR;
5513         }
5514       else
5515         {
5516           c2 = VEC_WIDEN_MULT_HI_EXPR;
5517           c1 = VEC_WIDEN_MULT_LO_EXPR;
5518         }
5519       break;
5520
5521     CASE_CONVERT:
5522       if (BYTES_BIG_ENDIAN)
5523         {
5524           c1 = VEC_UNPACK_HI_EXPR;
5525           c2 = VEC_UNPACK_LO_EXPR;
5526         }
5527       else
5528         {
5529           c2 = VEC_UNPACK_HI_EXPR;
5530           c1 = VEC_UNPACK_LO_EXPR;
5531         }
5532       break;
5533
5534     case FLOAT_EXPR:
5535       if (BYTES_BIG_ENDIAN)
5536         {
5537           c1 = VEC_UNPACK_FLOAT_HI_EXPR;
5538           c2 = VEC_UNPACK_FLOAT_LO_EXPR;
5539         }
5540       else
5541         {
5542           c2 = VEC_UNPACK_FLOAT_HI_EXPR;
5543           c1 = VEC_UNPACK_FLOAT_LO_EXPR;
5544         }
5545       break;
5546
5547     case FIX_TRUNC_EXPR:
5548       /* ??? Not yet implemented due to missing VEC_UNPACK_FIX_TRUNC_HI_EXPR/
5549          VEC_UNPACK_FIX_TRUNC_LO_EXPR tree codes and optabs used for
5550          computing the operation.  */
5551       return false;
5552
5553     default:
5554       gcc_unreachable ();
5555     }
5556
5557   if (code == FIX_TRUNC_EXPR)
5558     {
5559       /* The signedness is determined from output operand.  */
5560       optab1 = optab_for_tree_code (c1, vectype_out, optab_default);
5561       optab2 = optab_for_tree_code (c2, vectype_out, optab_default);
5562     }
5563   else
5564     {
5565       optab1 = optab_for_tree_code (c1, vectype, optab_default);
5566       optab2 = optab_for_tree_code (c2, vectype, optab_default);
5567     }
5568
5569   if (!optab1 || !optab2)
5570     return false;
5571
5572   vec_mode = TYPE_MODE (vectype);
5573   if ((icode1 = optab_handler (optab1, vec_mode)) == CODE_FOR_nothing
5574        || (icode2 = optab_handler (optab2, vec_mode)) == CODE_FOR_nothing)
5575     return false;
5576
5577   /* Check if it's a multi-step conversion that can be done using intermediate
5578      types.  */
5579   if (insn_data[icode1].operand[0].mode != TYPE_MODE (wide_vectype)
5580        || insn_data[icode2].operand[0].mode != TYPE_MODE (wide_vectype))
5581     {
5582       int i;
5583       tree prev_type = vectype, intermediate_type;
5584       enum machine_mode intermediate_mode, prev_mode = vec_mode;
5585       optab optab3, optab4;
5586
5587       if (!CONVERT_EXPR_CODE_P (code))
5588         return false;
5589
5590       *code1 = c1;
5591       *code2 = c2;
5592
5593       /* We assume here that there will not be more than MAX_INTERM_CVT_STEPS
5594          intermediate steps in promotion sequence.  We try
5595          MAX_INTERM_CVT_STEPS to get to NARROW_VECTYPE, and fail if we do
5596          not.  */
5597       *interm_types = VEC_alloc (tree, heap, MAX_INTERM_CVT_STEPS);
5598       for (i = 0; i < 3; i++)
5599         {
5600           intermediate_mode = insn_data[icode1].operand[0].mode;
5601           intermediate_type = lang_hooks.types.type_for_mode (intermediate_mode,
5602                                                      TYPE_UNSIGNED (prev_type));
5603           optab3 = optab_for_tree_code (c1, intermediate_type, optab_default);
5604           optab4 = optab_for_tree_code (c2, intermediate_type, optab_default);
5605
5606           if (!optab3 || !optab4
5607               || ((icode1 = optab_handler (optab1, prev_mode))
5608                   == CODE_FOR_nothing)
5609               || insn_data[icode1].operand[0].mode != intermediate_mode
5610               || ((icode2 = optab_handler (optab2, prev_mode))
5611                   == CODE_FOR_nothing)
5612               || insn_data[icode2].operand[0].mode != intermediate_mode
5613               || ((icode1 = optab_handler (optab3, intermediate_mode))
5614                   == CODE_FOR_nothing)
5615               || ((icode2 = optab_handler (optab4, intermediate_mode))
5616                   == CODE_FOR_nothing))
5617             return false;
5618
5619           VEC_quick_push (tree, *interm_types, intermediate_type);
5620           (*multi_step_cvt)++;
5621
5622           if (insn_data[icode1].operand[0].mode == TYPE_MODE (wide_vectype)
5623               && insn_data[icode2].operand[0].mode == TYPE_MODE (wide_vectype))
5624             return true;
5625
5626           prev_type = intermediate_type;
5627           prev_mode = intermediate_mode;
5628         }
5629
5630        return false;
5631     }
5632
5633   *code1 = c1;
5634   *code2 = c2;
5635   return true;
5636 }
5637
5638
5639 /* Function supportable_narrowing_operation
5640
5641    Check whether an operation represented by the code CODE is a
5642    narrowing operation that is supported by the target platform in
5643    vector form (i.e., when operating on arguments of type VECTYPE_IN
5644    and producing a result of type VECTYPE_OUT).
5645
5646    Narrowing operations we currently support are NOP (CONVERT) and
5647    FIX_TRUNC.  This function checks if these operations are supported by
5648    the target platform directly via vector tree-codes.
5649
5650    Output:
5651    - CODE1 is the code of a vector operation to be used when
5652    vectorizing the operation, if available.
5653    - MULTI_STEP_CVT determines the number of required intermediate steps in
5654    case of multi-step conversion (like int->short->char - in that case
5655    MULTI_STEP_CVT will be 1).
5656    - INTERM_TYPES contains the intermediate type required to perform the
5657    narrowing operation (short in the above example).   */
5658
5659 bool
5660 supportable_narrowing_operation (enum tree_code code,
5661                                  tree vectype_out, tree vectype_in,
5662                                  enum tree_code *code1, int *multi_step_cvt,
5663                                  VEC (tree, heap) **interm_types)
5664 {
5665   enum machine_mode vec_mode;
5666   enum insn_code icode1;
5667   optab optab1, interm_optab;
5668   tree vectype = vectype_in;
5669   tree narrow_vectype = vectype_out;
5670   enum tree_code c1;
5671   tree intermediate_type, prev_type;
5672   int i;
5673
5674   switch (code)
5675     {
5676     CASE_CONVERT:
5677       c1 = VEC_PACK_TRUNC_EXPR;
5678       break;
5679
5680     case FIX_TRUNC_EXPR:
5681       c1 = VEC_PACK_FIX_TRUNC_EXPR;
5682       break;
5683
5684     case FLOAT_EXPR:
5685       /* ??? Not yet implemented due to missing VEC_PACK_FLOAT_EXPR
5686          tree code and optabs used for computing the operation.  */
5687       return false;
5688
5689     default:
5690       gcc_unreachable ();
5691     }
5692
5693   if (code == FIX_TRUNC_EXPR)
5694     /* The signedness is determined from output operand.  */
5695     optab1 = optab_for_tree_code (c1, vectype_out, optab_default);
5696   else
5697     optab1 = optab_for_tree_code (c1, vectype, optab_default);
5698
5699   if (!optab1)
5700     return false;
5701
5702   vec_mode = TYPE_MODE (vectype);
5703   if ((icode1 = optab_handler (optab1, vec_mode)) == CODE_FOR_nothing)
5704     return false;
5705
5706   /* Check if it's a multi-step conversion that can be done using intermediate
5707      types.  */
5708   if (insn_data[icode1].operand[0].mode != TYPE_MODE (narrow_vectype))
5709     {
5710       enum machine_mode intermediate_mode, prev_mode = vec_mode;
5711
5712       *code1 = c1;
5713       prev_type = vectype;
5714       /* We assume here that there will not be more than MAX_INTERM_CVT_STEPS
5715          intermediate steps in promotion sequence.  We try
5716          MAX_INTERM_CVT_STEPS to get to NARROW_VECTYPE, and fail if we do
5717          not.  */
5718       *interm_types = VEC_alloc (tree, heap, MAX_INTERM_CVT_STEPS);
5719       for (i = 0; i < 3; i++)
5720         {
5721           intermediate_mode = insn_data[icode1].operand[0].mode;
5722           intermediate_type = lang_hooks.types.type_for_mode (intermediate_mode,
5723                                                      TYPE_UNSIGNED (prev_type));
5724           interm_optab = optab_for_tree_code (c1, intermediate_type,
5725                                               optab_default);
5726           if (!interm_optab
5727               || ((icode1 = optab_handler (optab1, prev_mode))
5728                   == CODE_FOR_nothing)
5729               || insn_data[icode1].operand[0].mode != intermediate_mode
5730               || ((icode1 = optab_handler (interm_optab, intermediate_mode))
5731                   == CODE_FOR_nothing))
5732             return false;
5733
5734           VEC_quick_push (tree, *interm_types, intermediate_type);
5735           (*multi_step_cvt)++;
5736
5737           if (insn_data[icode1].operand[0].mode == TYPE_MODE (narrow_vectype))
5738             return true;
5739
5740           prev_type = intermediate_type;
5741           prev_mode = intermediate_mode;
5742         }
5743
5744       return false;
5745     }
5746
5747   *code1 = c1;
5748   return true;
5749 }