OSDN Git Service

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