[Vectorizer] Split vect_gen_perm_mask into _checked and _any variants
[platform/upstream/gcc.git] / gcc / tree-vect-data-refs.c
1 /* Data References Analysis and Manipulation Utilities for Vectorization.
2    Copyright (C) 2003-2014 Free Software Foundation, Inc.
3    Contributed by Dorit Naishlos <dorit@il.ibm.com>
4    and Ira Rosen <irar@il.ibm.com>
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
12
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3.  If not see
20 <http://www.gnu.org/licenses/>.  */
21
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "dumpfile.h"
26 #include "tm.h"
27 #include "tree.h"
28 #include "stor-layout.h"
29 #include "tm_p.h"
30 #include "target.h"
31 #include "predict.h"
32 #include "vec.h"
33 #include "hashtab.h"
34 #include "hash-set.h"
35 #include "machmode.h"
36 #include "hard-reg-set.h"
37 #include "input.h"
38 #include "function.h"
39 #include "dominance.h"
40 #include "cfg.h"
41 #include "basic-block.h"
42 #include "gimple-pretty-print.h"
43 #include "tree-ssa-alias.h"
44 #include "internal-fn.h"
45 #include "tree-eh.h"
46 #include "gimple-expr.h"
47 #include "is-a.h"
48 #include "gimple.h"
49 #include "gimplify.h"
50 #include "gimple-iterator.h"
51 #include "gimplify-me.h"
52 #include "gimple-ssa.h"
53 #include "tree-phinodes.h"
54 #include "ssa-iterators.h"
55 #include "stringpool.h"
56 #include "tree-ssanames.h"
57 #include "tree-ssa-loop-ivopts.h"
58 #include "tree-ssa-loop-manip.h"
59 #include "tree-ssa-loop.h"
60 #include "dumpfile.h"
61 #include "cfgloop.h"
62 #include "tree-chrec.h"
63 #include "tree-scalar-evolution.h"
64 #include "tree-vectorizer.h"
65 #include "diagnostic-core.h"
66 #include "hash-map.h"
67 #include "plugin-api.h"
68 #include "ipa-ref.h"
69 #include "cgraph.h"
70 /* Need to include rtl.h, expr.h, etc. for optabs.  */
71 #include "expr.h"
72 #include "insn-codes.h"
73 #include "optabs.h"
74 #include "builtins.h"
75 #include "varasm.h"
76
77 /* Return true if load- or store-lanes optab OPTAB is implemented for
78    COUNT vectors of type VECTYPE.  NAME is the name of OPTAB.  */
79
80 static bool
81 vect_lanes_optab_supported_p (const char *name, convert_optab optab,
82                               tree vectype, unsigned HOST_WIDE_INT count)
83 {
84   machine_mode mode, array_mode;
85   bool limit_p;
86
87   mode = TYPE_MODE (vectype);
88   limit_p = !targetm.array_mode_supported_p (mode, count);
89   array_mode = mode_for_size (count * GET_MODE_BITSIZE (mode),
90                               MODE_INT, limit_p);
91
92   if (array_mode == BLKmode)
93     {
94       if (dump_enabled_p ())
95         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
96                          "no array mode for %s[" HOST_WIDE_INT_PRINT_DEC "]\n",
97                          GET_MODE_NAME (mode), count);
98       return false;
99     }
100
101   if (convert_optab_handler (optab, array_mode, mode) == CODE_FOR_nothing)
102     {
103       if (dump_enabled_p ())
104         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
105                          "cannot use %s<%s><%s>\n", name,
106                          GET_MODE_NAME (array_mode), GET_MODE_NAME (mode));
107       return false;
108     }
109
110   if (dump_enabled_p ())
111     dump_printf_loc (MSG_NOTE, vect_location,
112                      "can use %s<%s><%s>\n", name, GET_MODE_NAME (array_mode),
113                      GET_MODE_NAME (mode));
114
115   return true;
116 }
117
118
119 /* Return the smallest scalar part of STMT.
120    This is used to determine the vectype of the stmt.  We generally set the
121    vectype according to the type of the result (lhs).  For stmts whose
122    result-type is different than the type of the arguments (e.g., demotion,
123    promotion), vectype will be reset appropriately (later).  Note that we have
124    to visit the smallest datatype in this function, because that determines the
125    VF.  If the smallest datatype in the loop is present only as the rhs of a
126    promotion operation - we'd miss it.
127    Such a case, where a variable of this datatype does not appear in the lhs
128    anywhere in the loop, can only occur if it's an invariant: e.g.:
129    'int_x = (int) short_inv', which we'd expect to have been optimized away by
130    invariant motion.  However, we cannot rely on invariant motion to always
131    take invariants out of the loop, and so in the case of promotion we also
132    have to check the rhs.
133    LHS_SIZE_UNIT and RHS_SIZE_UNIT contain the sizes of the corresponding
134    types.  */
135
136 tree
137 vect_get_smallest_scalar_type (gimple stmt, HOST_WIDE_INT *lhs_size_unit,
138                                HOST_WIDE_INT *rhs_size_unit)
139 {
140   tree scalar_type = gimple_expr_type (stmt);
141   HOST_WIDE_INT lhs, rhs;
142
143   lhs = rhs = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (scalar_type));
144
145   if (is_gimple_assign (stmt)
146       && (gimple_assign_cast_p (stmt)
147           || gimple_assign_rhs_code (stmt) == WIDEN_MULT_EXPR
148           || gimple_assign_rhs_code (stmt) == WIDEN_LSHIFT_EXPR
149           || gimple_assign_rhs_code (stmt) == FLOAT_EXPR))
150     {
151       tree rhs_type = TREE_TYPE (gimple_assign_rhs1 (stmt));
152
153       rhs = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (rhs_type));
154       if (rhs < lhs)
155         scalar_type = rhs_type;
156     }
157
158   *lhs_size_unit = lhs;
159   *rhs_size_unit = rhs;
160   return scalar_type;
161 }
162
163
164 /* Insert DDR into LOOP_VINFO list of ddrs that may alias and need to be
165    tested at run-time.  Return TRUE if DDR was successfully inserted.
166    Return false if versioning is not supported.  */
167
168 static bool
169 vect_mark_for_runtime_alias_test (ddr_p ddr, loop_vec_info loop_vinfo)
170 {
171   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
172
173   if ((unsigned) PARAM_VALUE (PARAM_VECT_MAX_VERSION_FOR_ALIAS_CHECKS) == 0)
174     return false;
175
176   if (dump_enabled_p ())
177     {
178       dump_printf_loc (MSG_NOTE, vect_location,
179                        "mark for run-time aliasing test between ");
180       dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (DDR_A (ddr)));
181       dump_printf (MSG_NOTE,  " and ");
182       dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (DDR_B (ddr)));
183       dump_printf (MSG_NOTE, "\n");
184     }
185
186   if (optimize_loop_nest_for_size_p (loop))
187     {
188       if (dump_enabled_p ())
189         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
190                          "versioning not supported when optimizing"
191                          " for size.\n");
192       return false;
193     }
194
195   /* FORNOW: We don't support versioning with outer-loop vectorization.  */
196   if (loop->inner)
197     {
198       if (dump_enabled_p ())
199         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
200                          "versioning not yet supported for outer-loops.\n");
201       return false;
202     }
203
204   /* FORNOW: We don't support creating runtime alias tests for non-constant
205      step.  */
206   if (TREE_CODE (DR_STEP (DDR_A (ddr))) != INTEGER_CST
207       || TREE_CODE (DR_STEP (DDR_B (ddr))) != INTEGER_CST)
208     {
209       if (dump_enabled_p ())
210         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
211                          "versioning not yet supported for non-constant "
212                          "step\n");
213       return false;
214     }
215
216   LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo).safe_push (ddr);
217   return true;
218 }
219
220
221 /* Function vect_analyze_data_ref_dependence.
222
223    Return TRUE if there (might) exist a dependence between a memory-reference
224    DRA and a memory-reference DRB.  When versioning for alias may check a
225    dependence at run-time, return FALSE.  Adjust *MAX_VF according to
226    the data dependence.  */
227
228 static bool
229 vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
230                                   loop_vec_info loop_vinfo, int *max_vf)
231 {
232   unsigned int i;
233   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
234   struct data_reference *dra = DDR_A (ddr);
235   struct data_reference *drb = DDR_B (ddr);
236   stmt_vec_info stmtinfo_a = vinfo_for_stmt (DR_STMT (dra));
237   stmt_vec_info stmtinfo_b = vinfo_for_stmt (DR_STMT (drb));
238   lambda_vector dist_v;
239   unsigned int loop_depth;
240
241   /* In loop analysis all data references should be vectorizable.  */
242   if (!STMT_VINFO_VECTORIZABLE (stmtinfo_a)
243       || !STMT_VINFO_VECTORIZABLE (stmtinfo_b))
244     gcc_unreachable ();
245
246   /* Independent data accesses.  */
247   if (DDR_ARE_DEPENDENT (ddr) == chrec_known)
248     return false;
249
250   if (dra == drb
251       || (DR_IS_READ (dra) && DR_IS_READ (drb)))
252     return false;
253
254   /* Even if we have an anti-dependence then, as the vectorized loop covers at
255      least two scalar iterations, there is always also a true dependence.
256      As the vectorizer does not re-order loads and stores we can ignore
257      the anti-dependence if TBAA can disambiguate both DRs similar to the
258      case with known negative distance anti-dependences (positive
259      distance anti-dependences would violate TBAA constraints).  */
260   if (((DR_IS_READ (dra) && DR_IS_WRITE (drb))
261        || (DR_IS_WRITE (dra) && DR_IS_READ (drb)))
262       && !alias_sets_conflict_p (get_alias_set (DR_REF (dra)),
263                                  get_alias_set (DR_REF (drb))))
264     return false;
265
266   /* Unknown data dependence.  */
267   if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know)
268     {
269       /* If user asserted safelen consecutive iterations can be
270          executed concurrently, assume independence.  */
271       if (loop->safelen >= 2)
272         {
273           if (loop->safelen < *max_vf)
274             *max_vf = loop->safelen;
275           LOOP_VINFO_NO_DATA_DEPENDENCIES (loop_vinfo) = false;
276           return false;
277         }
278
279       if (STMT_VINFO_GATHER_P (stmtinfo_a)
280           || STMT_VINFO_GATHER_P (stmtinfo_b))
281         {
282           if (dump_enabled_p ())
283             {
284               dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
285                                "versioning for alias not supported for: "
286                                "can't determine dependence between ");
287               dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM,
288                                  DR_REF (dra));
289               dump_printf (MSG_MISSED_OPTIMIZATION, " and ");
290               dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM,
291                                  DR_REF (drb));
292               dump_printf (MSG_MISSED_OPTIMIZATION, "\n");
293             }
294           return true;
295         }
296
297       if (dump_enabled_p ())
298         {
299           dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
300                            "versioning for alias required: "
301                            "can't determine dependence between ");
302           dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM,
303                              DR_REF (dra));
304           dump_printf (MSG_MISSED_OPTIMIZATION, " and ");
305           dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM,
306                              DR_REF (drb));
307           dump_printf (MSG_MISSED_OPTIMIZATION, "\n");
308         }
309
310       /* Add to list of ddrs that need to be tested at run-time.  */
311       return !vect_mark_for_runtime_alias_test (ddr, loop_vinfo);
312     }
313
314   /* Known data dependence.  */
315   if (DDR_NUM_DIST_VECTS (ddr) == 0)
316     {
317       /* If user asserted safelen consecutive iterations can be
318          executed concurrently, assume independence.  */
319       if (loop->safelen >= 2)
320         {
321           if (loop->safelen < *max_vf)
322             *max_vf = loop->safelen;
323           LOOP_VINFO_NO_DATA_DEPENDENCIES (loop_vinfo) = false;
324           return false;
325         }
326
327       if (STMT_VINFO_GATHER_P (stmtinfo_a)
328           || STMT_VINFO_GATHER_P (stmtinfo_b))
329         {
330           if (dump_enabled_p ())
331             {
332               dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
333                                "versioning for alias not supported for: "
334                                "bad dist vector for ");
335               dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM,
336                                  DR_REF (dra));
337               dump_printf (MSG_MISSED_OPTIMIZATION, " and ");
338               dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM,
339                                  DR_REF (drb));
340               dump_printf (MSG_MISSED_OPTIMIZATION, "\n");
341             }
342           return true;
343         }
344
345       if (dump_enabled_p ())
346         {
347           dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
348                            "versioning for alias required: "
349                            "bad dist vector for ");
350           dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, DR_REF (dra));
351           dump_printf (MSG_MISSED_OPTIMIZATION,  " and ");
352           dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, DR_REF (drb));
353           dump_printf (MSG_MISSED_OPTIMIZATION, "\n");
354         }
355       /* Add to list of ddrs that need to be tested at run-time.  */
356       return !vect_mark_for_runtime_alias_test (ddr, loop_vinfo);
357     }
358
359   loop_depth = index_in_loop_nest (loop->num, DDR_LOOP_NEST (ddr));
360   FOR_EACH_VEC_ELT (DDR_DIST_VECTS (ddr), i, dist_v)
361     {
362       int dist = dist_v[loop_depth];
363
364       if (dump_enabled_p ())
365         dump_printf_loc (MSG_NOTE, vect_location,
366                          "dependence distance  = %d.\n", dist);
367
368       if (dist == 0)
369         {
370           if (dump_enabled_p ())
371             {
372               dump_printf_loc (MSG_NOTE, vect_location,
373                                "dependence distance == 0 between ");
374               dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (dra));
375               dump_printf (MSG_NOTE, " and ");
376               dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (drb));
377               dump_printf (MSG_MISSED_OPTIMIZATION, "\n");
378             }
379
380           /* When we perform grouped accesses and perform implicit CSE
381              by detecting equal accesses and doing disambiguation with
382              runtime alias tests like for
383                 .. = a[i];
384                 .. = a[i+1];
385                 a[i] = ..;
386                 a[i+1] = ..;
387                 *p = ..;
388                 .. = a[i];
389                 .. = a[i+1];
390              where we will end up loading { a[i], a[i+1] } once, make
391              sure that inserting group loads before the first load and
392              stores after the last store will do the right thing.
393              Similar for groups like
394                 a[i] = ...;
395                 ... = a[i];
396                 a[i+1] = ...;
397              where loads from the group interleave with the store.  */
398           if (STMT_VINFO_GROUPED_ACCESS (stmtinfo_a)
399               || STMT_VINFO_GROUPED_ACCESS (stmtinfo_b))
400             {
401               gimple earlier_stmt;
402               earlier_stmt = get_earlier_stmt (DR_STMT (dra), DR_STMT (drb));
403               if (DR_IS_WRITE
404                     (STMT_VINFO_DATA_REF (vinfo_for_stmt (earlier_stmt))))
405                 {
406                   if (dump_enabled_p ())
407                     dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
408                                      "READ_WRITE dependence in interleaving."
409                                      "\n");
410                   return true;
411                 }
412             }
413
414           continue;
415         }
416
417       if (dist > 0 && DDR_REVERSED_P (ddr))
418         {
419           /* If DDR_REVERSED_P the order of the data-refs in DDR was
420              reversed (to make distance vector positive), and the actual
421              distance is negative.  */
422           if (dump_enabled_p ())
423             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
424                              "dependence distance negative.\n");
425           /* Record a negative dependence distance to later limit the
426              amount of stmt copying / unrolling we can perform.
427              Only need to handle read-after-write dependence.  */
428           if (DR_IS_READ (drb)
429               && (STMT_VINFO_MIN_NEG_DIST (stmtinfo_b) == 0
430                   || STMT_VINFO_MIN_NEG_DIST (stmtinfo_b) > (unsigned)dist))
431             STMT_VINFO_MIN_NEG_DIST (stmtinfo_b) = dist;
432           continue;
433         }
434
435       if (abs (dist) >= 2
436           && abs (dist) < *max_vf)
437         {
438           /* The dependence distance requires reduction of the maximal
439              vectorization factor.  */
440           *max_vf = abs (dist);
441           if (dump_enabled_p ())
442             dump_printf_loc (MSG_NOTE, vect_location,
443                              "adjusting maximal vectorization factor to %i\n",
444                              *max_vf);
445         }
446
447       if (abs (dist) >= *max_vf)
448         {
449           /* Dependence distance does not create dependence, as far as
450              vectorization is concerned, in this case.  */
451           if (dump_enabled_p ())
452             dump_printf_loc (MSG_NOTE, vect_location,
453                              "dependence distance >= VF.\n");
454           continue;
455         }
456
457       if (dump_enabled_p ())
458         {
459           dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
460                        "not vectorized, possible dependence "
461                        "between data-refs ");
462           dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (dra));
463           dump_printf (MSG_NOTE,  " and ");
464           dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (drb));
465           dump_printf (MSG_NOTE,  "\n");
466         }
467
468       return true;
469     }
470
471   return false;
472 }
473
474 /* Function vect_analyze_data_ref_dependences.
475
476    Examine all the data references in the loop, and make sure there do not
477    exist any data dependences between them.  Set *MAX_VF according to
478    the maximum vectorization factor the data dependences allow.  */
479
480 bool
481 vect_analyze_data_ref_dependences (loop_vec_info loop_vinfo, int *max_vf)
482 {
483   unsigned int i;
484   struct data_dependence_relation *ddr;
485
486   if (dump_enabled_p ())
487     dump_printf_loc (MSG_NOTE, vect_location,
488                      "=== vect_analyze_data_ref_dependences ===\n");
489
490   LOOP_VINFO_NO_DATA_DEPENDENCIES (loop_vinfo) = true;
491   if (!compute_all_dependences (LOOP_VINFO_DATAREFS (loop_vinfo),
492                                 &LOOP_VINFO_DDRS (loop_vinfo),
493                                 LOOP_VINFO_LOOP_NEST (loop_vinfo), true))
494     return false;
495
496   FOR_EACH_VEC_ELT (LOOP_VINFO_DDRS (loop_vinfo), i, ddr)
497     if (vect_analyze_data_ref_dependence (ddr, loop_vinfo, max_vf))
498       return false;
499
500   return true;
501 }
502
503
504 /* Function vect_slp_analyze_data_ref_dependence.
505
506    Return TRUE if there (might) exist a dependence between a memory-reference
507    DRA and a memory-reference DRB.  When versioning for alias may check a
508    dependence at run-time, return FALSE.  Adjust *MAX_VF according to
509    the data dependence.  */
510
511 static bool
512 vect_slp_analyze_data_ref_dependence (struct data_dependence_relation *ddr)
513 {
514   struct data_reference *dra = DDR_A (ddr);
515   struct data_reference *drb = DDR_B (ddr);
516
517   /* We need to check dependences of statements marked as unvectorizable
518      as well, they still can prohibit vectorization.  */
519
520   /* Independent data accesses.  */
521   if (DDR_ARE_DEPENDENT (ddr) == chrec_known)
522     return false;
523
524   if (dra == drb)
525     return false;
526
527   /* Read-read is OK.  */
528   if (DR_IS_READ (dra) && DR_IS_READ (drb))
529     return false;
530
531   /* If dra and drb are part of the same interleaving chain consider
532      them independent.  */
533   if (STMT_VINFO_GROUPED_ACCESS (vinfo_for_stmt (DR_STMT (dra)))
534       && (GROUP_FIRST_ELEMENT (vinfo_for_stmt (DR_STMT (dra)))
535           == GROUP_FIRST_ELEMENT (vinfo_for_stmt (DR_STMT (drb)))))
536     return false;
537
538   /* Unknown data dependence.  */
539   if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know)
540     {
541       if  (dump_enabled_p ())
542         {
543           dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
544                            "can't determine dependence between ");
545           dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, DR_REF (dra));
546           dump_printf (MSG_MISSED_OPTIMIZATION,  " and ");
547           dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, DR_REF (drb));
548           dump_printf (MSG_MISSED_OPTIMIZATION,  "\n");
549         }
550     }
551   else if (dump_enabled_p ())
552     {
553       dump_printf_loc (MSG_NOTE, vect_location,
554                        "determined dependence between ");
555       dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (dra));
556       dump_printf (MSG_NOTE, " and ");
557       dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (drb));
558       dump_printf (MSG_NOTE,  "\n");
559     }
560
561   /* We do not vectorize basic blocks with write-write dependencies.  */
562   if (DR_IS_WRITE (dra) && DR_IS_WRITE (drb))
563     return true;
564
565   /* If we have a read-write dependence check that the load is before the store.
566      When we vectorize basic blocks, vector load can be only before
567      corresponding scalar load, and vector store can be only after its
568      corresponding scalar store.  So the order of the acceses is preserved in
569      case the load is before the store.  */
570   gimple earlier_stmt = get_earlier_stmt (DR_STMT (dra), DR_STMT (drb));
571   if (DR_IS_READ (STMT_VINFO_DATA_REF (vinfo_for_stmt (earlier_stmt))))
572     {
573       /* That only holds for load-store pairs taking part in vectorization.  */
574       if (STMT_VINFO_VECTORIZABLE (vinfo_for_stmt (DR_STMT (dra)))
575           && STMT_VINFO_VECTORIZABLE (vinfo_for_stmt (DR_STMT (drb))))
576         return false;
577     }
578
579   return true;
580 }
581
582
583 /* Function vect_analyze_data_ref_dependences.
584
585    Examine all the data references in the basic-block, and make sure there
586    do not exist any data dependences between them.  Set *MAX_VF according to
587    the maximum vectorization factor the data dependences allow.  */
588
589 bool
590 vect_slp_analyze_data_ref_dependences (bb_vec_info bb_vinfo)
591 {
592   struct data_dependence_relation *ddr;
593   unsigned int i;
594
595   if (dump_enabled_p ())
596     dump_printf_loc (MSG_NOTE, vect_location,
597                      "=== vect_slp_analyze_data_ref_dependences ===\n");
598
599   if (!compute_all_dependences (BB_VINFO_DATAREFS (bb_vinfo),
600                                 &BB_VINFO_DDRS (bb_vinfo),
601                                 vNULL, true))
602     return false;
603
604   FOR_EACH_VEC_ELT (BB_VINFO_DDRS (bb_vinfo), i, ddr)
605     if (vect_slp_analyze_data_ref_dependence (ddr))
606       return false;
607
608   return true;
609 }
610
611
612 /* Function vect_compute_data_ref_alignment
613
614    Compute the misalignment of the data reference DR.
615
616    Output:
617    1. If during the misalignment computation it is found that the data reference
618       cannot be vectorized then false is returned.
619    2. DR_MISALIGNMENT (DR) is defined.
620
621    FOR NOW: No analysis is actually performed. Misalignment is calculated
622    only for trivial cases. TODO.  */
623
624 static bool
625 vect_compute_data_ref_alignment (struct data_reference *dr)
626 {
627   gimple stmt = DR_STMT (dr);
628   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
629   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
630   struct loop *loop = NULL;
631   tree ref = DR_REF (dr);
632   tree vectype;
633   tree base, base_addr;
634   bool base_aligned;
635   tree misalign;
636   tree aligned_to, alignment;
637
638   if (dump_enabled_p ())
639     dump_printf_loc (MSG_NOTE, vect_location,
640                      "vect_compute_data_ref_alignment:\n");
641
642   if (loop_vinfo)
643     loop = LOOP_VINFO_LOOP (loop_vinfo);
644
645   /* Initialize misalignment to unknown.  */
646   SET_DR_MISALIGNMENT (dr, -1);
647
648   /* Strided loads perform only component accesses, misalignment information
649      is irrelevant for them.  */
650   if (STMT_VINFO_STRIDE_LOAD_P (stmt_info))
651     return true;
652
653   misalign = DR_INIT (dr);
654   aligned_to = DR_ALIGNED_TO (dr);
655   base_addr = DR_BASE_ADDRESS (dr);
656   vectype = STMT_VINFO_VECTYPE (stmt_info);
657
658   /* In case the dataref is in an inner-loop of the loop that is being
659      vectorized (LOOP), we use the base and misalignment information
660      relative to the outer-loop (LOOP).  This is ok only if the misalignment
661      stays the same throughout the execution of the inner-loop, which is why
662      we have to check that the stride of the dataref in the inner-loop evenly
663      divides by the vector size.  */
664   if (loop && nested_in_vect_loop_p (loop, stmt))
665     {
666       tree step = DR_STEP (dr);
667       HOST_WIDE_INT dr_step = TREE_INT_CST_LOW (step);
668
669       if (dr_step % GET_MODE_SIZE (TYPE_MODE (vectype)) == 0)
670         {
671           if (dump_enabled_p ())
672             dump_printf_loc (MSG_NOTE, vect_location,
673                              "inner step divides the vector-size.\n");
674           misalign = STMT_VINFO_DR_INIT (stmt_info);
675           aligned_to = STMT_VINFO_DR_ALIGNED_TO (stmt_info);
676           base_addr = STMT_VINFO_DR_BASE_ADDRESS (stmt_info);
677         }
678       else
679         {
680           if (dump_enabled_p ())
681             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
682                              "inner step doesn't divide the vector-size.\n");
683           misalign = NULL_TREE;
684         }
685     }
686
687   /* Similarly, if we're doing basic-block vectorization, we can only use
688      base and misalignment information relative to an innermost loop if the
689      misalignment stays the same throughout the execution of the loop.
690      As above, this is the case if the stride of the dataref evenly divides
691      by the vector size.  */
692   if (!loop)
693     {
694       tree step = DR_STEP (dr);
695       HOST_WIDE_INT dr_step = TREE_INT_CST_LOW (step);
696
697       if (dr_step % GET_MODE_SIZE (TYPE_MODE (vectype)) != 0)
698         {
699           if (dump_enabled_p ())
700             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
701                              "SLP: step doesn't divide the vector-size.\n");
702           misalign = NULL_TREE;
703         }
704     }
705
706   base = build_fold_indirect_ref (base_addr);
707   alignment = ssize_int (TYPE_ALIGN (vectype)/BITS_PER_UNIT);
708
709   if ((aligned_to && tree_int_cst_compare (aligned_to, alignment) < 0)
710       || !misalign)
711     {
712       if (dump_enabled_p ())
713         {
714           dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
715                            "Unknown alignment for access: ");
716           dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, base);
717           dump_printf (MSG_MISSED_OPTIMIZATION, "\n");
718         }
719       return true;
720     }
721
722   if ((DECL_P (base)
723        && tree_int_cst_compare (ssize_int (DECL_ALIGN_UNIT (base)),
724                                 alignment) >= 0)
725       || (TREE_CODE (base_addr) == SSA_NAME
726           && tree_int_cst_compare (ssize_int (TYPE_ALIGN_UNIT (TREE_TYPE (
727                                                       TREE_TYPE (base_addr)))),
728                                    alignment) >= 0)
729       || (get_pointer_alignment (base_addr) >= TYPE_ALIGN (vectype)))
730     base_aligned = true;
731   else
732     base_aligned = false;
733
734   if (!base_aligned)
735     {
736       /* Do not change the alignment of global variables here if
737          flag_section_anchors is enabled as we already generated
738          RTL for other functions.  Most global variables should
739          have been aligned during the IPA increase_alignment pass.  */
740       if (!vect_can_force_dr_alignment_p (base, TYPE_ALIGN (vectype))
741           || (TREE_STATIC (base) && flag_section_anchors))
742         {
743           if (dump_enabled_p ())
744             {
745               dump_printf_loc (MSG_NOTE, vect_location,
746                                "can't force alignment of ref: ");
747               dump_generic_expr (MSG_NOTE, TDF_SLIM, ref);
748               dump_printf (MSG_NOTE, "\n");
749             }
750           return true;
751         }
752
753       /* Force the alignment of the decl.
754          NOTE: This is the only change to the code we make during
755          the analysis phase, before deciding to vectorize the loop.  */
756       if (dump_enabled_p ())
757         {
758           dump_printf_loc (MSG_NOTE, vect_location, "force alignment of ");
759           dump_generic_expr (MSG_NOTE, TDF_SLIM, ref);
760           dump_printf (MSG_NOTE, "\n");
761         }
762
763       ((dataref_aux *)dr->aux)->base_decl = base;
764       ((dataref_aux *)dr->aux)->base_misaligned = true;
765     }
766
767   /* If this is a backward running DR then first access in the larger
768      vectype actually is N-1 elements before the address in the DR.
769      Adjust misalign accordingly.  */
770   if (tree_int_cst_compare (DR_STEP (dr), size_zero_node) < 0)
771     {
772       tree offset = ssize_int (TYPE_VECTOR_SUBPARTS (vectype) - 1);
773       /* DR_STEP(dr) is the same as -TYPE_SIZE of the scalar type,
774          otherwise we wouldn't be here.  */
775       offset = fold_build2 (MULT_EXPR, ssizetype, offset, DR_STEP (dr));
776       /* PLUS because DR_STEP was negative.  */
777       misalign = size_binop (PLUS_EXPR, misalign, offset);
778     }
779
780   /* Modulo alignment.  */
781   misalign = size_binop (FLOOR_MOD_EXPR, misalign, alignment);
782
783   if (!tree_fits_uhwi_p (misalign))
784     {
785       /* Negative or overflowed misalignment value.  */
786       if (dump_enabled_p ())
787         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
788                          "unexpected misalign value\n");
789       return false;
790     }
791
792   SET_DR_MISALIGNMENT (dr, tree_to_uhwi (misalign));
793
794   if (dump_enabled_p ())
795     {
796       dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
797                        "misalign = %d bytes of ref ", DR_MISALIGNMENT (dr));
798       dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, ref);
799       dump_printf (MSG_MISSED_OPTIMIZATION, "\n");
800     }
801
802   return true;
803 }
804
805
806 /* Function vect_compute_data_refs_alignment
807
808    Compute the misalignment of data references in the loop.
809    Return FALSE if a data reference is found that cannot be vectorized.  */
810
811 static bool
812 vect_compute_data_refs_alignment (loop_vec_info loop_vinfo,
813                                   bb_vec_info bb_vinfo)
814 {
815   vec<data_reference_p> datarefs;
816   struct data_reference *dr;
817   unsigned int i;
818
819   if (loop_vinfo)
820     datarefs = LOOP_VINFO_DATAREFS (loop_vinfo);
821   else
822     datarefs = BB_VINFO_DATAREFS (bb_vinfo);
823
824   FOR_EACH_VEC_ELT (datarefs, i, dr)
825     if (STMT_VINFO_VECTORIZABLE (vinfo_for_stmt (DR_STMT (dr)))
826         && !vect_compute_data_ref_alignment (dr))
827       {
828         if (bb_vinfo)
829           {
830             /* Mark unsupported statement as unvectorizable.  */
831             STMT_VINFO_VECTORIZABLE (vinfo_for_stmt (DR_STMT (dr))) = false;
832             continue;
833           }
834         else
835           return false;
836       }
837
838   return true;
839 }
840
841
842 /* Function vect_update_misalignment_for_peel
843
844    DR - the data reference whose misalignment is to be adjusted.
845    DR_PEEL - the data reference whose misalignment is being made
846              zero in the vector loop by the peel.
847    NPEEL - the number of iterations in the peel loop if the misalignment
848            of DR_PEEL is known at compile time.  */
849
850 static void
851 vect_update_misalignment_for_peel (struct data_reference *dr,
852                                    struct data_reference *dr_peel, int npeel)
853 {
854   unsigned int i;
855   vec<dr_p> same_align_drs;
856   struct data_reference *current_dr;
857   int dr_size = GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (DR_REF (dr))));
858   int dr_peel_size = GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (DR_REF (dr_peel))));
859   stmt_vec_info stmt_info = vinfo_for_stmt (DR_STMT (dr));
860   stmt_vec_info peel_stmt_info = vinfo_for_stmt (DR_STMT (dr_peel));
861
862  /* For interleaved data accesses the step in the loop must be multiplied by
863      the size of the interleaving group.  */
864   if (STMT_VINFO_GROUPED_ACCESS (stmt_info))
865     dr_size *= GROUP_SIZE (vinfo_for_stmt (GROUP_FIRST_ELEMENT (stmt_info)));
866   if (STMT_VINFO_GROUPED_ACCESS (peel_stmt_info))
867     dr_peel_size *= GROUP_SIZE (peel_stmt_info);
868
869   /* It can be assumed that the data refs with the same alignment as dr_peel
870      are aligned in the vector loop.  */
871   same_align_drs
872     = STMT_VINFO_SAME_ALIGN_REFS (vinfo_for_stmt (DR_STMT (dr_peel)));
873   FOR_EACH_VEC_ELT (same_align_drs, i, current_dr)
874     {
875       if (current_dr != dr)
876         continue;
877       gcc_assert (DR_MISALIGNMENT (dr) / dr_size ==
878                   DR_MISALIGNMENT (dr_peel) / dr_peel_size);
879       SET_DR_MISALIGNMENT (dr, 0);
880       return;
881     }
882
883   if (known_alignment_for_access_p (dr)
884       && known_alignment_for_access_p (dr_peel))
885     {
886       bool negative = tree_int_cst_compare (DR_STEP (dr), size_zero_node) < 0;
887       int misal = DR_MISALIGNMENT (dr);
888       tree vectype = STMT_VINFO_VECTYPE (stmt_info);
889       misal += negative ? -npeel * dr_size : npeel * dr_size;
890       misal &= (TYPE_ALIGN (vectype) / BITS_PER_UNIT) - 1;
891       SET_DR_MISALIGNMENT (dr, misal);
892       return;
893     }
894
895   if (dump_enabled_p ())
896     dump_printf_loc (MSG_NOTE, vect_location, "Setting misalignment to -1.\n");
897   SET_DR_MISALIGNMENT (dr, -1);
898 }
899
900
901 /* Function vect_verify_datarefs_alignment
902
903    Return TRUE if all data references in the loop can be
904    handled with respect to alignment.  */
905
906 bool
907 vect_verify_datarefs_alignment (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo)
908 {
909   vec<data_reference_p> datarefs;
910   struct data_reference *dr;
911   enum dr_alignment_support supportable_dr_alignment;
912   unsigned int i;
913
914   if (loop_vinfo)
915     datarefs = LOOP_VINFO_DATAREFS (loop_vinfo);
916   else
917     datarefs = BB_VINFO_DATAREFS (bb_vinfo);
918
919   FOR_EACH_VEC_ELT (datarefs, i, dr)
920     {
921       gimple stmt = DR_STMT (dr);
922       stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
923
924       if (!STMT_VINFO_RELEVANT_P (stmt_info))
925         continue;
926
927       /* For interleaving, only the alignment of the first access matters. 
928          Skip statements marked as not vectorizable.  */
929       if ((STMT_VINFO_GROUPED_ACCESS (stmt_info)
930            && GROUP_FIRST_ELEMENT (stmt_info) != stmt)
931           || !STMT_VINFO_VECTORIZABLE (stmt_info))
932         continue;
933
934       /* Strided loads perform only component accesses, alignment is
935          irrelevant for them.  */
936       if (STMT_VINFO_STRIDE_LOAD_P (stmt_info))
937         continue;
938
939       supportable_dr_alignment = vect_supportable_dr_alignment (dr, false);
940       if (!supportable_dr_alignment)
941         {
942           if (dump_enabled_p ())
943             {
944               if (DR_IS_READ (dr))
945                 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
946                                  "not vectorized: unsupported unaligned load.");
947               else
948                 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
949                                  "not vectorized: unsupported unaligned "
950                                  "store.");
951
952               dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM,
953                                  DR_REF (dr));
954               dump_printf (MSG_MISSED_OPTIMIZATION, "\n");
955             }
956           return false;
957         }
958       if (supportable_dr_alignment != dr_aligned && dump_enabled_p ())
959         dump_printf_loc (MSG_NOTE, vect_location,
960                          "Vectorizing an unaligned access.\n");
961     }
962   return true;
963 }
964
965 /* Given an memory reference EXP return whether its alignment is less
966    than its size.  */
967
968 static bool
969 not_size_aligned (tree exp)
970 {
971   if (!tree_fits_uhwi_p (TYPE_SIZE (TREE_TYPE (exp))))
972     return true;
973
974   return (tree_to_uhwi (TYPE_SIZE (TREE_TYPE (exp)))
975           > get_object_alignment (exp));
976 }
977
978 /* Function vector_alignment_reachable_p
979
980    Return true if vector alignment for DR is reachable by peeling
981    a few loop iterations.  Return false otherwise.  */
982
983 static bool
984 vector_alignment_reachable_p (struct data_reference *dr)
985 {
986   gimple stmt = DR_STMT (dr);
987   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
988   tree vectype = STMT_VINFO_VECTYPE (stmt_info);
989
990   if (STMT_VINFO_GROUPED_ACCESS (stmt_info))
991     {
992       /* For interleaved access we peel only if number of iterations in
993          the prolog loop ({VF - misalignment}), is a multiple of the
994          number of the interleaved accesses.  */
995       int elem_size, mis_in_elements;
996       int nelements = TYPE_VECTOR_SUBPARTS (vectype);
997
998       /* FORNOW: handle only known alignment.  */
999       if (!known_alignment_for_access_p (dr))
1000         return false;
1001
1002       elem_size = GET_MODE_SIZE (TYPE_MODE (vectype)) / nelements;
1003       mis_in_elements = DR_MISALIGNMENT (dr) / elem_size;
1004
1005       if ((nelements - mis_in_elements) % GROUP_SIZE (stmt_info))
1006         return false;
1007     }
1008
1009   /* If misalignment is known at the compile time then allow peeling
1010      only if natural alignment is reachable through peeling.  */
1011   if (known_alignment_for_access_p (dr) && !aligned_access_p (dr))
1012     {
1013       HOST_WIDE_INT elmsize =
1014                 int_cst_value (TYPE_SIZE_UNIT (TREE_TYPE (vectype)));
1015       if (dump_enabled_p ())
1016         {
1017           dump_printf_loc (MSG_NOTE, vect_location,
1018                            "data size =" HOST_WIDE_INT_PRINT_DEC, elmsize);
1019           dump_printf (MSG_NOTE,
1020                        ". misalignment = %d.\n", DR_MISALIGNMENT (dr));
1021         }
1022       if (DR_MISALIGNMENT (dr) % elmsize)
1023         {
1024           if (dump_enabled_p ())
1025             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
1026                              "data size does not divide the misalignment.\n");
1027           return false;
1028         }
1029     }
1030
1031   if (!known_alignment_for_access_p (dr))
1032     {
1033       tree type = TREE_TYPE (DR_REF (dr));
1034       bool is_packed = not_size_aligned (DR_REF (dr));
1035       if (dump_enabled_p ())
1036         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
1037                          "Unknown misalignment, is_packed = %d\n",is_packed);
1038       if ((TYPE_USER_ALIGN (type) && !is_packed)
1039           || targetm.vectorize.vector_alignment_reachable (type, is_packed))
1040         return true;
1041       else
1042         return false;
1043     }
1044
1045   return true;
1046 }
1047
1048
1049 /* Calculate the cost of the memory access represented by DR.  */
1050
1051 static void
1052 vect_get_data_access_cost (struct data_reference *dr,
1053                            unsigned int *inside_cost,
1054                            unsigned int *outside_cost,
1055                            stmt_vector_for_cost *body_cost_vec)
1056 {
1057   gimple stmt = DR_STMT (dr);
1058   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
1059   int nunits = TYPE_VECTOR_SUBPARTS (STMT_VINFO_VECTYPE (stmt_info));
1060   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
1061   int vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
1062   int ncopies = vf / nunits;
1063
1064   if (DR_IS_READ (dr))
1065     vect_get_load_cost (dr, ncopies, true, inside_cost, outside_cost,
1066                         NULL, body_cost_vec, false);
1067   else
1068     vect_get_store_cost (dr, ncopies, inside_cost, body_cost_vec);
1069
1070   if (dump_enabled_p ())
1071     dump_printf_loc (MSG_NOTE, vect_location,
1072                      "vect_get_data_access_cost: inside_cost = %d, "
1073                      "outside_cost = %d.\n", *inside_cost, *outside_cost);
1074 }
1075
1076
1077 /* Insert DR into peeling hash table with NPEEL as key.  */
1078
1079 static void
1080 vect_peeling_hash_insert (loop_vec_info loop_vinfo, struct data_reference *dr,
1081                           int npeel)
1082 {
1083   struct _vect_peel_info elem, *slot;
1084   _vect_peel_info **new_slot;
1085   bool supportable_dr_alignment = vect_supportable_dr_alignment (dr, true);
1086
1087   elem.npeel = npeel;
1088   slot = LOOP_VINFO_PEELING_HTAB (loop_vinfo)->find (&elem);
1089   if (slot)
1090     slot->count++;
1091   else
1092     {
1093       slot = XNEW (struct _vect_peel_info);
1094       slot->npeel = npeel;
1095       slot->dr = dr;
1096       slot->count = 1;
1097       new_slot
1098         = LOOP_VINFO_PEELING_HTAB (loop_vinfo)->find_slot (slot, INSERT);
1099       *new_slot = slot;
1100     }
1101
1102   if (!supportable_dr_alignment
1103       && unlimited_cost_model (LOOP_VINFO_LOOP (loop_vinfo)))
1104     slot->count += VECT_MAX_COST;
1105 }
1106
1107
1108 /* Traverse peeling hash table to find peeling option that aligns maximum
1109    number of data accesses.  */
1110
1111 int
1112 vect_peeling_hash_get_most_frequent (_vect_peel_info **slot,
1113                                      _vect_peel_extended_info *max)
1114 {
1115   vect_peel_info elem = *slot;
1116
1117   if (elem->count > max->peel_info.count
1118       || (elem->count == max->peel_info.count
1119           && max->peel_info.npeel > elem->npeel))
1120     {
1121       max->peel_info.npeel = elem->npeel;
1122       max->peel_info.count = elem->count;
1123       max->peel_info.dr = elem->dr;
1124     }
1125
1126   return 1;
1127 }
1128
1129
1130 /* Traverse peeling hash table and calculate cost for each peeling option.
1131    Find the one with the lowest cost.  */
1132
1133 int
1134 vect_peeling_hash_get_lowest_cost (_vect_peel_info **slot,
1135                                    _vect_peel_extended_info *min)
1136 {
1137   vect_peel_info elem = *slot;
1138   int save_misalignment, dummy;
1139   unsigned int inside_cost = 0, outside_cost = 0, i;
1140   gimple stmt = DR_STMT (elem->dr);
1141   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
1142   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
1143   vec<data_reference_p> datarefs = LOOP_VINFO_DATAREFS (loop_vinfo);
1144   struct data_reference *dr;
1145   stmt_vector_for_cost prologue_cost_vec, body_cost_vec, epilogue_cost_vec;
1146   int single_iter_cost;
1147
1148   prologue_cost_vec.create (2);
1149   body_cost_vec.create (2);
1150   epilogue_cost_vec.create (2);
1151
1152   FOR_EACH_VEC_ELT (datarefs, i, dr)
1153     {
1154       stmt = DR_STMT (dr);
1155       stmt_info = vinfo_for_stmt (stmt);
1156       /* For interleaving, only the alignment of the first access
1157          matters.  */
1158       if (STMT_VINFO_GROUPED_ACCESS (stmt_info)
1159           && GROUP_FIRST_ELEMENT (stmt_info) != stmt)
1160         continue;
1161
1162       save_misalignment = DR_MISALIGNMENT (dr);
1163       vect_update_misalignment_for_peel (dr, elem->dr, elem->npeel);
1164       vect_get_data_access_cost (dr, &inside_cost, &outside_cost,
1165                                  &body_cost_vec);
1166       SET_DR_MISALIGNMENT (dr, save_misalignment);
1167     }
1168
1169   single_iter_cost = vect_get_single_scalar_iteration_cost (loop_vinfo);
1170   outside_cost += vect_get_known_peeling_cost (loop_vinfo, elem->npeel,
1171                                                &dummy, single_iter_cost,
1172                                                &prologue_cost_vec,
1173                                                &epilogue_cost_vec);
1174
1175   /* Prologue and epilogue costs are added to the target model later.
1176      These costs depend only on the scalar iteration cost, the
1177      number of peeling iterations finally chosen, and the number of
1178      misaligned statements.  So discard the information found here.  */
1179   prologue_cost_vec.release ();
1180   epilogue_cost_vec.release ();
1181
1182   if (inside_cost < min->inside_cost
1183       || (inside_cost == min->inside_cost && outside_cost < min->outside_cost))
1184     {
1185       min->inside_cost = inside_cost;
1186       min->outside_cost = outside_cost;
1187       min->body_cost_vec.release ();
1188       min->body_cost_vec = body_cost_vec;
1189       min->peel_info.dr = elem->dr;
1190       min->peel_info.npeel = elem->npeel;
1191     }
1192   else
1193     body_cost_vec.release ();
1194
1195   return 1;
1196 }
1197
1198
1199 /* Choose best peeling option by traversing peeling hash table and either
1200    choosing an option with the lowest cost (if cost model is enabled) or the
1201    option that aligns as many accesses as possible.  */
1202
1203 static struct data_reference *
1204 vect_peeling_hash_choose_best_peeling (loop_vec_info loop_vinfo,
1205                                        unsigned int *npeel,
1206                                        stmt_vector_for_cost *body_cost_vec)
1207 {
1208    struct _vect_peel_extended_info res;
1209
1210    res.peel_info.dr = NULL;
1211    res.body_cost_vec = stmt_vector_for_cost ();
1212
1213    if (!unlimited_cost_model (LOOP_VINFO_LOOP (loop_vinfo)))
1214      {
1215        res.inside_cost = INT_MAX;
1216        res.outside_cost = INT_MAX;
1217        LOOP_VINFO_PEELING_HTAB (loop_vinfo)
1218            ->traverse <_vect_peel_extended_info *,
1219                        vect_peeling_hash_get_lowest_cost> (&res);
1220      }
1221    else
1222      {
1223        res.peel_info.count = 0;
1224        LOOP_VINFO_PEELING_HTAB (loop_vinfo)
1225            ->traverse <_vect_peel_extended_info *,
1226                        vect_peeling_hash_get_most_frequent> (&res);
1227      }
1228
1229    *npeel = res.peel_info.npeel;
1230    *body_cost_vec = res.body_cost_vec;
1231    return res.peel_info.dr;
1232 }
1233
1234
1235 /* Function vect_enhance_data_refs_alignment
1236
1237    This pass will use loop versioning and loop peeling in order to enhance
1238    the alignment of data references in the loop.
1239
1240    FOR NOW: we assume that whatever versioning/peeling takes place, only the
1241    original loop is to be vectorized.  Any other loops that are created by
1242    the transformations performed in this pass - are not supposed to be
1243    vectorized.  This restriction will be relaxed.
1244
1245    This pass will require a cost model to guide it whether to apply peeling
1246    or versioning or a combination of the two.  For example, the scheme that
1247    intel uses when given a loop with several memory accesses, is as follows:
1248    choose one memory access ('p') which alignment you want to force by doing
1249    peeling.  Then, either (1) generate a loop in which 'p' is aligned and all
1250    other accesses are not necessarily aligned, or (2) use loop versioning to
1251    generate one loop in which all accesses are aligned, and another loop in
1252    which only 'p' is necessarily aligned.
1253
1254    ("Automatic Intra-Register Vectorization for the Intel Architecture",
1255    Aart J.C. Bik, Milind Girkar, Paul M. Grey and Ximmin Tian, International
1256    Journal of Parallel Programming, Vol. 30, No. 2, April 2002.)
1257
1258    Devising a cost model is the most critical aspect of this work.  It will
1259    guide us on which access to peel for, whether to use loop versioning, how
1260    many versions to create, etc.  The cost model will probably consist of
1261    generic considerations as well as target specific considerations (on
1262    powerpc for example, misaligned stores are more painful than misaligned
1263    loads).
1264
1265    Here are the general steps involved in alignment enhancements:
1266
1267      -- original loop, before alignment analysis:
1268         for (i=0; i<N; i++){
1269           x = q[i];                     # DR_MISALIGNMENT(q) = unknown
1270           p[i] = y;                     # DR_MISALIGNMENT(p) = unknown
1271         }
1272
1273      -- After vect_compute_data_refs_alignment:
1274         for (i=0; i<N; i++){
1275           x = q[i];                     # DR_MISALIGNMENT(q) = 3
1276           p[i] = y;                     # DR_MISALIGNMENT(p) = unknown
1277         }
1278
1279      -- Possibility 1: we do loop versioning:
1280      if (p is aligned) {
1281         for (i=0; i<N; i++){    # loop 1A
1282           x = q[i];                     # DR_MISALIGNMENT(q) = 3
1283           p[i] = y;                     # DR_MISALIGNMENT(p) = 0
1284         }
1285      }
1286      else {
1287         for (i=0; i<N; i++){    # loop 1B
1288           x = q[i];                     # DR_MISALIGNMENT(q) = 3
1289           p[i] = y;                     # DR_MISALIGNMENT(p) = unaligned
1290         }
1291      }
1292
1293      -- Possibility 2: we do loop peeling:
1294      for (i = 0; i < 3; i++){   # (scalar loop, not to be vectorized).
1295         x = q[i];
1296         p[i] = y;
1297      }
1298      for (i = 3; i < N; i++){   # loop 2A
1299         x = q[i];                       # DR_MISALIGNMENT(q) = 0
1300         p[i] = y;                       # DR_MISALIGNMENT(p) = unknown
1301      }
1302
1303      -- Possibility 3: combination of loop peeling and versioning:
1304      for (i = 0; i < 3; i++){   # (scalar loop, not to be vectorized).
1305         x = q[i];
1306         p[i] = y;
1307      }
1308      if (p is aligned) {
1309         for (i = 3; i<N; i++){  # loop 3A
1310           x = q[i];                     # DR_MISALIGNMENT(q) = 0
1311           p[i] = y;                     # DR_MISALIGNMENT(p) = 0
1312         }
1313      }
1314      else {
1315         for (i = 3; i<N; i++){  # loop 3B
1316           x = q[i];                     # DR_MISALIGNMENT(q) = 0
1317           p[i] = y;                     # DR_MISALIGNMENT(p) = unaligned
1318         }
1319      }
1320
1321      These loops are later passed to loop_transform to be vectorized.  The
1322      vectorizer will use the alignment information to guide the transformation
1323      (whether to generate regular loads/stores, or with special handling for
1324      misalignment).  */
1325
1326 bool
1327 vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
1328 {
1329   vec<data_reference_p> datarefs = LOOP_VINFO_DATAREFS (loop_vinfo);
1330   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
1331   enum dr_alignment_support supportable_dr_alignment;
1332   struct data_reference *dr0 = NULL, *first_store = NULL;
1333   struct data_reference *dr;
1334   unsigned int i, j;
1335   bool do_peeling = false;
1336   bool do_versioning = false;
1337   bool stat;
1338   gimple stmt;
1339   stmt_vec_info stmt_info;
1340   unsigned int npeel = 0;
1341   bool all_misalignments_unknown = true;
1342   unsigned int vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
1343   unsigned possible_npeel_number = 1;
1344   tree vectype;
1345   unsigned int nelements, mis, same_align_drs_max = 0;
1346   stmt_vector_for_cost body_cost_vec = stmt_vector_for_cost ();
1347
1348   if (dump_enabled_p ())
1349     dump_printf_loc (MSG_NOTE, vect_location,
1350                      "=== vect_enhance_data_refs_alignment ===\n");
1351
1352   /* While cost model enhancements are expected in the future, the high level
1353      view of the code at this time is as follows:
1354
1355      A) If there is a misaligned access then see if peeling to align
1356         this access can make all data references satisfy
1357         vect_supportable_dr_alignment.  If so, update data structures
1358         as needed and return true.
1359
1360      B) If peeling wasn't possible and there is a data reference with an
1361         unknown misalignment that does not satisfy vect_supportable_dr_alignment
1362         then see if loop versioning checks can be used to make all data
1363         references satisfy vect_supportable_dr_alignment.  If so, update
1364         data structures as needed and return true.
1365
1366      C) If neither peeling nor versioning were successful then return false if
1367         any data reference does not satisfy vect_supportable_dr_alignment.
1368
1369      D) Return true (all data references satisfy vect_supportable_dr_alignment).
1370
1371      Note, Possibility 3 above (which is peeling and versioning together) is not
1372      being done at this time.  */
1373
1374   /* (1) Peeling to force alignment.  */
1375
1376   /* (1.1) Decide whether to perform peeling, and how many iterations to peel:
1377      Considerations:
1378      + How many accesses will become aligned due to the peeling
1379      - How many accesses will become unaligned due to the peeling,
1380        and the cost of misaligned accesses.
1381      - The cost of peeling (the extra runtime checks, the increase
1382        in code size).  */
1383
1384   FOR_EACH_VEC_ELT (datarefs, i, dr)
1385     {
1386       stmt = DR_STMT (dr);
1387       stmt_info = vinfo_for_stmt (stmt);
1388
1389       if (!STMT_VINFO_RELEVANT_P (stmt_info))
1390         continue;
1391
1392       /* For interleaving, only the alignment of the first access
1393          matters.  */
1394       if (STMT_VINFO_GROUPED_ACCESS (stmt_info)
1395           && GROUP_FIRST_ELEMENT (stmt_info) != stmt)
1396         continue;
1397
1398       /* For invariant accesses there is nothing to enhance.  */
1399       if (integer_zerop (DR_STEP (dr)))
1400         continue;
1401
1402       /* Strided loads perform only component accesses, alignment is
1403          irrelevant for them.  */
1404       if (STMT_VINFO_STRIDE_LOAD_P (stmt_info))
1405         continue;
1406
1407       supportable_dr_alignment = vect_supportable_dr_alignment (dr, true);
1408       do_peeling = vector_alignment_reachable_p (dr);
1409       if (do_peeling)
1410         {
1411           if (known_alignment_for_access_p (dr))
1412             {
1413               unsigned int npeel_tmp;
1414               bool negative = tree_int_cst_compare (DR_STEP (dr),
1415                                                     size_zero_node) < 0;
1416
1417               /* Save info about DR in the hash table.  */
1418               if (!LOOP_VINFO_PEELING_HTAB (loop_vinfo))
1419                 LOOP_VINFO_PEELING_HTAB (loop_vinfo)
1420                   = new hash_table<peel_info_hasher> (1);
1421
1422               vectype = STMT_VINFO_VECTYPE (stmt_info);
1423               nelements = TYPE_VECTOR_SUBPARTS (vectype);
1424               mis = DR_MISALIGNMENT (dr) / GET_MODE_SIZE (TYPE_MODE (
1425                                                 TREE_TYPE (DR_REF (dr))));
1426               npeel_tmp = (negative
1427                            ? (mis - nelements) : (nelements - mis))
1428                   & (nelements - 1);
1429
1430               /* For multiple types, it is possible that the bigger type access
1431                  will have more than one peeling option.  E.g., a loop with two
1432                  types: one of size (vector size / 4), and the other one of
1433                  size (vector size / 8).  Vectorization factor will 8.  If both
1434                  access are misaligned by 3, the first one needs one scalar
1435                  iteration to be aligned, and the second one needs 5.  But the
1436                  the first one will be aligned also by peeling 5 scalar
1437                  iterations, and in that case both accesses will be aligned.
1438                  Hence, except for the immediate peeling amount, we also want
1439                  to try to add full vector size, while we don't exceed
1440                  vectorization factor.
1441                  We do this automtically for cost model, since we calculate cost
1442                  for every peeling option.  */
1443               if (unlimited_cost_model (LOOP_VINFO_LOOP (loop_vinfo)))
1444                 possible_npeel_number = vf /nelements;
1445
1446               /* Handle the aligned case. We may decide to align some other
1447                  access, making DR unaligned.  */
1448               if (DR_MISALIGNMENT (dr) == 0)
1449                 {
1450                   npeel_tmp = 0;
1451                   if (unlimited_cost_model (LOOP_VINFO_LOOP (loop_vinfo)))
1452                     possible_npeel_number++;
1453                 }
1454
1455               for (j = 0; j < possible_npeel_number; j++)
1456                 {
1457                   gcc_assert (npeel_tmp <= vf);
1458                   vect_peeling_hash_insert (loop_vinfo, dr, npeel_tmp);
1459                   npeel_tmp += nelements;
1460                 }
1461
1462               all_misalignments_unknown = false;
1463               /* Data-ref that was chosen for the case that all the
1464                  misalignments are unknown is not relevant anymore, since we
1465                  have a data-ref with known alignment.  */
1466               dr0 = NULL;
1467             }
1468           else
1469             {
1470               /* If we don't know any misalignment values, we prefer
1471                  peeling for data-ref that has the maximum number of data-refs
1472                  with the same alignment, unless the target prefers to align
1473                  stores over load.  */
1474               if (all_misalignments_unknown)
1475                 {
1476                   unsigned same_align_drs
1477                     = STMT_VINFO_SAME_ALIGN_REFS (stmt_info).length ();
1478                   if (!dr0
1479                       || same_align_drs_max < same_align_drs)
1480                     {
1481                       same_align_drs_max = same_align_drs;
1482                       dr0 = dr;
1483                     }
1484                   /* For data-refs with the same number of related
1485                      accesses prefer the one where the misalign
1486                      computation will be invariant in the outermost loop.  */
1487                   else if (same_align_drs_max == same_align_drs)
1488                     {
1489                       struct loop *ivloop0, *ivloop;
1490                       ivloop0 = outermost_invariant_loop_for_expr
1491                           (loop, DR_BASE_ADDRESS (dr0));
1492                       ivloop = outermost_invariant_loop_for_expr
1493                           (loop, DR_BASE_ADDRESS (dr));
1494                       if ((ivloop && !ivloop0)
1495                           || (ivloop && ivloop0
1496                               && flow_loop_nested_p (ivloop, ivloop0)))
1497                         dr0 = dr;
1498                     }
1499
1500                   if (!first_store && DR_IS_WRITE (dr))
1501                     first_store = dr;
1502                 }
1503
1504               /* If there are both known and unknown misaligned accesses in the
1505                  loop, we choose peeling amount according to the known
1506                  accesses.  */
1507               if (!supportable_dr_alignment)
1508                 {
1509                   dr0 = dr;
1510                   if (!first_store && DR_IS_WRITE (dr))
1511                     first_store = dr;
1512                 }
1513             }
1514         }
1515       else
1516         {
1517           if (!aligned_access_p (dr))
1518             {
1519               if (dump_enabled_p ())
1520                 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
1521                                  "vector alignment may not be reachable\n");
1522               break;
1523             }
1524         }
1525     }
1526
1527   /* Check if we can possibly peel the loop.  */
1528   if (!vect_can_advance_ivs_p (loop_vinfo)
1529       || !slpeel_can_duplicate_loop_p (loop, single_exit (loop)))
1530     do_peeling = false;
1531
1532   /* If we don't know how many times the peeling loop will run
1533      assume it will run VF-1 times and disable peeling if the remaining
1534      iters are less than the vectorization factor.  */
1535   if (do_peeling
1536       && all_misalignments_unknown
1537       && LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
1538       && (LOOP_VINFO_INT_NITERS (loop_vinfo)
1539           < 2 * (unsigned) LOOP_VINFO_VECT_FACTOR (loop_vinfo) - 1))
1540     do_peeling = false;
1541
1542   if (do_peeling
1543       && all_misalignments_unknown
1544       && vect_supportable_dr_alignment (dr0, false))
1545     {
1546       /* Check if the target requires to prefer stores over loads, i.e., if
1547          misaligned stores are more expensive than misaligned loads (taking
1548          drs with same alignment into account).  */
1549       if (first_store && DR_IS_READ (dr0))
1550         {
1551           unsigned int load_inside_cost = 0, load_outside_cost = 0;
1552           unsigned int store_inside_cost = 0, store_outside_cost = 0;
1553           unsigned int load_inside_penalty = 0, load_outside_penalty = 0;
1554           unsigned int store_inside_penalty = 0, store_outside_penalty = 0;
1555           stmt_vector_for_cost dummy;
1556           dummy.create (2);
1557
1558           vect_get_data_access_cost (dr0, &load_inside_cost, &load_outside_cost,
1559                                      &dummy);
1560           vect_get_data_access_cost (first_store, &store_inside_cost,
1561                                      &store_outside_cost, &dummy);
1562
1563           dummy.release ();
1564
1565           /* Calculate the penalty for leaving FIRST_STORE unaligned (by
1566              aligning the load DR0).  */
1567           load_inside_penalty = store_inside_cost;
1568           load_outside_penalty = store_outside_cost;
1569           for (i = 0;
1570                STMT_VINFO_SAME_ALIGN_REFS (vinfo_for_stmt (
1571                           DR_STMT (first_store))).iterate (i, &dr);
1572                i++)
1573             if (DR_IS_READ (dr))
1574               {
1575                 load_inside_penalty += load_inside_cost;
1576                 load_outside_penalty += load_outside_cost;
1577               }
1578             else
1579               {
1580                 load_inside_penalty += store_inside_cost;
1581                 load_outside_penalty += store_outside_cost;
1582               }
1583
1584           /* Calculate the penalty for leaving DR0 unaligned (by
1585              aligning the FIRST_STORE).  */
1586           store_inside_penalty = load_inside_cost;
1587           store_outside_penalty = load_outside_cost;
1588           for (i = 0;
1589                STMT_VINFO_SAME_ALIGN_REFS (vinfo_for_stmt (
1590                       DR_STMT (dr0))).iterate (i, &dr);
1591                i++)
1592             if (DR_IS_READ (dr))
1593               {
1594                 store_inside_penalty += load_inside_cost;
1595                 store_outside_penalty += load_outside_cost;
1596               }
1597             else
1598               {
1599                 store_inside_penalty += store_inside_cost;
1600                 store_outside_penalty += store_outside_cost;
1601               }
1602
1603           if (load_inside_penalty > store_inside_penalty
1604               || (load_inside_penalty == store_inside_penalty
1605                   && load_outside_penalty > store_outside_penalty))
1606             dr0 = first_store;
1607         }
1608
1609       /* In case there are only loads with different unknown misalignments, use
1610          peeling only if it may help to align other accesses in the loop.  */
1611       if (!first_store
1612           && !STMT_VINFO_SAME_ALIGN_REFS (
1613                   vinfo_for_stmt (DR_STMT (dr0))).length ()
1614           && vect_supportable_dr_alignment (dr0, false)
1615               != dr_unaligned_supported)
1616         do_peeling = false;
1617     }
1618
1619   if (do_peeling && !dr0)
1620     {
1621       /* Peeling is possible, but there is no data access that is not supported
1622          unless aligned. So we try to choose the best possible peeling.  */
1623
1624       /* We should get here only if there are drs with known misalignment.  */
1625       gcc_assert (!all_misalignments_unknown);
1626
1627       /* Choose the best peeling from the hash table.  */
1628       dr0 = vect_peeling_hash_choose_best_peeling (loop_vinfo, &npeel,
1629                                                    &body_cost_vec);
1630       if (!dr0 || !npeel)
1631         do_peeling = false;
1632
1633       /* If peeling by npeel will result in a remaining loop not iterating
1634          enough to be vectorized then do not peel.  */
1635       if (do_peeling
1636           && LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
1637           && (LOOP_VINFO_INT_NITERS (loop_vinfo)
1638               < LOOP_VINFO_VECT_FACTOR (loop_vinfo) + npeel))
1639         do_peeling = false;
1640     }
1641
1642   if (do_peeling)
1643     {
1644       stmt = DR_STMT (dr0);
1645       stmt_info = vinfo_for_stmt (stmt);
1646       vectype = STMT_VINFO_VECTYPE (stmt_info);
1647       nelements = TYPE_VECTOR_SUBPARTS (vectype);
1648
1649       if (known_alignment_for_access_p (dr0))
1650         {
1651           bool negative = tree_int_cst_compare (DR_STEP (dr0),
1652                                                 size_zero_node) < 0;
1653           if (!npeel)
1654             {
1655               /* Since it's known at compile time, compute the number of
1656                  iterations in the peeled loop (the peeling factor) for use in
1657                  updating DR_MISALIGNMENT values.  The peeling factor is the
1658                  vectorization factor minus the misalignment as an element
1659                  count.  */
1660               mis = DR_MISALIGNMENT (dr0);
1661               mis /= GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (DR_REF (dr0))));
1662               npeel = ((negative ? mis - nelements : nelements - mis)
1663                        & (nelements - 1));
1664             }
1665
1666           /* For interleaved data access every iteration accesses all the
1667              members of the group, therefore we divide the number of iterations
1668              by the group size.  */
1669           stmt_info = vinfo_for_stmt (DR_STMT (dr0));
1670           if (STMT_VINFO_GROUPED_ACCESS (stmt_info))
1671             npeel /= GROUP_SIZE (stmt_info);
1672
1673           if (dump_enabled_p ())
1674             dump_printf_loc (MSG_NOTE, vect_location,
1675                              "Try peeling by %d\n", npeel);
1676         }
1677
1678       /* Ensure that all data refs can be vectorized after the peel.  */
1679       FOR_EACH_VEC_ELT (datarefs, i, dr)
1680         {
1681           int save_misalignment;
1682
1683           if (dr == dr0)
1684             continue;
1685
1686           stmt = DR_STMT (dr);
1687           stmt_info = vinfo_for_stmt (stmt);
1688           /* For interleaving, only the alignment of the first access
1689             matters.  */
1690           if (STMT_VINFO_GROUPED_ACCESS (stmt_info)
1691               && GROUP_FIRST_ELEMENT (stmt_info) != stmt)
1692             continue;
1693
1694           /* Strided loads perform only component accesses, alignment is
1695              irrelevant for them.  */
1696           if (STMT_VINFO_STRIDE_LOAD_P (stmt_info))
1697             continue;
1698
1699           save_misalignment = DR_MISALIGNMENT (dr);
1700           vect_update_misalignment_for_peel (dr, dr0, npeel);
1701           supportable_dr_alignment = vect_supportable_dr_alignment (dr, false);
1702           SET_DR_MISALIGNMENT (dr, save_misalignment);
1703
1704           if (!supportable_dr_alignment)
1705             {
1706               do_peeling = false;
1707               break;
1708             }
1709         }
1710
1711       if (do_peeling && known_alignment_for_access_p (dr0) && npeel == 0)
1712         {
1713           stat = vect_verify_datarefs_alignment (loop_vinfo, NULL);
1714           if (!stat)
1715             do_peeling = false;
1716           else
1717             {
1718               body_cost_vec.release ();
1719               return stat;
1720             }
1721         }
1722
1723       if (do_peeling)
1724         {
1725           unsigned max_allowed_peel
1726             = PARAM_VALUE (PARAM_VECT_MAX_PEELING_FOR_ALIGNMENT);
1727           if (max_allowed_peel != (unsigned)-1)
1728             {
1729               unsigned max_peel = npeel;
1730               if (max_peel == 0)
1731                 {
1732                   gimple dr_stmt = DR_STMT (dr0);
1733                   stmt_vec_info vinfo = vinfo_for_stmt (dr_stmt);
1734                   tree vtype = STMT_VINFO_VECTYPE (vinfo);
1735                   max_peel = TYPE_VECTOR_SUBPARTS (vtype) - 1;
1736                 }
1737               if (max_peel > max_allowed_peel)
1738                 {
1739                   do_peeling = false;
1740                   if (dump_enabled_p ())
1741                     dump_printf_loc (MSG_NOTE, vect_location,
1742                         "Disable peeling, max peels reached: %d\n", max_peel);
1743                 }
1744             }
1745         }
1746
1747       if (do_peeling)
1748         {
1749           stmt_info_for_cost *si;
1750           void *data = LOOP_VINFO_TARGET_COST_DATA (loop_vinfo);
1751
1752           /* (1.2) Update the DR_MISALIGNMENT of each data reference DR_i.
1753              If the misalignment of DR_i is identical to that of dr0 then set
1754              DR_MISALIGNMENT (DR_i) to zero.  If the misalignment of DR_i and
1755              dr0 are known at compile time then increment DR_MISALIGNMENT (DR_i)
1756              by the peeling factor times the element size of DR_i (MOD the
1757              vectorization factor times the size).  Otherwise, the
1758              misalignment of DR_i must be set to unknown.  */
1759           FOR_EACH_VEC_ELT (datarefs, i, dr)
1760             if (dr != dr0)
1761               vect_update_misalignment_for_peel (dr, dr0, npeel);
1762
1763           LOOP_VINFO_UNALIGNED_DR (loop_vinfo) = dr0;
1764           if (npeel)
1765             LOOP_VINFO_PEELING_FOR_ALIGNMENT (loop_vinfo) = npeel;
1766           else
1767             LOOP_VINFO_PEELING_FOR_ALIGNMENT (loop_vinfo)
1768               = DR_MISALIGNMENT (dr0);
1769           SET_DR_MISALIGNMENT (dr0, 0);
1770           if (dump_enabled_p ())
1771             {
1772               dump_printf_loc (MSG_NOTE, vect_location,
1773                                "Alignment of access forced using peeling.\n");
1774               dump_printf_loc (MSG_NOTE, vect_location,
1775                                "Peeling for alignment will be applied.\n");
1776             }
1777           /* We've delayed passing the inside-loop peeling costs to the
1778              target cost model until we were sure peeling would happen.
1779              Do so now.  */
1780           if (body_cost_vec.exists ())
1781             {
1782               FOR_EACH_VEC_ELT (body_cost_vec, i, si)
1783                 {
1784                   struct _stmt_vec_info *stmt_info
1785                     = si->stmt ? vinfo_for_stmt (si->stmt) : NULL;
1786                   (void) add_stmt_cost (data, si->count, si->kind, stmt_info,
1787                                         si->misalign, vect_body);
1788                 }
1789               body_cost_vec.release ();
1790             }
1791
1792           stat = vect_verify_datarefs_alignment (loop_vinfo, NULL);
1793           gcc_assert (stat);
1794           return stat;
1795         }
1796     }
1797
1798   body_cost_vec.release ();
1799
1800   /* (2) Versioning to force alignment.  */
1801
1802   /* Try versioning if:
1803      1) optimize loop for speed
1804      2) there is at least one unsupported misaligned data ref with an unknown
1805         misalignment, and
1806      3) all misaligned data refs with a known misalignment are supported, and
1807      4) the number of runtime alignment checks is within reason.  */
1808
1809   do_versioning =
1810         optimize_loop_nest_for_speed_p (loop)
1811         && (!loop->inner); /* FORNOW */
1812
1813   if (do_versioning)
1814     {
1815       FOR_EACH_VEC_ELT (datarefs, i, dr)
1816         {
1817           stmt = DR_STMT (dr);
1818           stmt_info = vinfo_for_stmt (stmt);
1819
1820           /* For interleaving, only the alignment of the first access
1821              matters.  */
1822           if (aligned_access_p (dr)
1823               || (STMT_VINFO_GROUPED_ACCESS (stmt_info)
1824                   && GROUP_FIRST_ELEMENT (stmt_info) != stmt))
1825             continue;
1826
1827           /* Strided loads perform only component accesses, alignment is
1828              irrelevant for them.  */
1829           if (STMT_VINFO_STRIDE_LOAD_P (stmt_info))
1830             continue;
1831
1832           supportable_dr_alignment = vect_supportable_dr_alignment (dr, false);
1833
1834           if (!supportable_dr_alignment)
1835             {
1836               gimple stmt;
1837               int mask;
1838               tree vectype;
1839
1840               if (known_alignment_for_access_p (dr)
1841                   || LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo).length ()
1842                      >= (unsigned) PARAM_VALUE (PARAM_VECT_MAX_VERSION_FOR_ALIGNMENT_CHECKS))
1843                 {
1844                   do_versioning = false;
1845                   break;
1846                 }
1847
1848               stmt = DR_STMT (dr);
1849               vectype = STMT_VINFO_VECTYPE (vinfo_for_stmt (stmt));
1850               gcc_assert (vectype);
1851
1852               /* The rightmost bits of an aligned address must be zeros.
1853                  Construct the mask needed for this test.  For example,
1854                  GET_MODE_SIZE for the vector mode V4SI is 16 bytes so the
1855                  mask must be 15 = 0xf. */
1856               mask = GET_MODE_SIZE (TYPE_MODE (vectype)) - 1;
1857
1858               /* FORNOW: use the same mask to test all potentially unaligned
1859                  references in the loop.  The vectorizer currently supports
1860                  a single vector size, see the reference to
1861                  GET_MODE_NUNITS (TYPE_MODE (vectype)) where the
1862                  vectorization factor is computed.  */
1863               gcc_assert (!LOOP_VINFO_PTR_MASK (loop_vinfo)
1864                           || LOOP_VINFO_PTR_MASK (loop_vinfo) == mask);
1865               LOOP_VINFO_PTR_MASK (loop_vinfo) = mask;
1866               LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo).safe_push (
1867                       DR_STMT (dr));
1868             }
1869         }
1870
1871       /* Versioning requires at least one misaligned data reference.  */
1872       if (!LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT (loop_vinfo))
1873         do_versioning = false;
1874       else if (!do_versioning)
1875         LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo).truncate (0);
1876     }
1877
1878   if (do_versioning)
1879     {
1880       vec<gimple> may_misalign_stmts
1881         = LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo);
1882       gimple stmt;
1883
1884       /* It can now be assumed that the data references in the statements
1885          in LOOP_VINFO_MAY_MISALIGN_STMTS will be aligned in the version
1886          of the loop being vectorized.  */
1887       FOR_EACH_VEC_ELT (may_misalign_stmts, i, stmt)
1888         {
1889           stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
1890           dr = STMT_VINFO_DATA_REF (stmt_info);
1891           SET_DR_MISALIGNMENT (dr, 0);
1892           if (dump_enabled_p ())
1893             dump_printf_loc (MSG_NOTE, vect_location,
1894                              "Alignment of access forced using versioning.\n");
1895         }
1896
1897       if (dump_enabled_p ())
1898         dump_printf_loc (MSG_NOTE, vect_location,
1899                          "Versioning for alignment will be applied.\n");
1900
1901       /* Peeling and versioning can't be done together at this time.  */
1902       gcc_assert (! (do_peeling && do_versioning));
1903
1904       stat = vect_verify_datarefs_alignment (loop_vinfo, NULL);
1905       gcc_assert (stat);
1906       return stat;
1907     }
1908
1909   /* This point is reached if neither peeling nor versioning is being done.  */
1910   gcc_assert (! (do_peeling || do_versioning));
1911
1912   stat = vect_verify_datarefs_alignment (loop_vinfo, NULL);
1913   return stat;
1914 }
1915
1916
1917 /* Function vect_find_same_alignment_drs.
1918
1919    Update group and alignment relations according to the chosen
1920    vectorization factor.  */
1921
1922 static void
1923 vect_find_same_alignment_drs (struct data_dependence_relation *ddr,
1924                               loop_vec_info loop_vinfo)
1925 {
1926   unsigned int i;
1927   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
1928   int vectorization_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
1929   struct data_reference *dra = DDR_A (ddr);
1930   struct data_reference *drb = DDR_B (ddr);
1931   stmt_vec_info stmtinfo_a = vinfo_for_stmt (DR_STMT (dra));
1932   stmt_vec_info stmtinfo_b = vinfo_for_stmt (DR_STMT (drb));
1933   int dra_size = GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (DR_REF (dra))));
1934   int drb_size = GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (DR_REF (drb))));
1935   lambda_vector dist_v;
1936   unsigned int loop_depth;
1937
1938   if (DDR_ARE_DEPENDENT (ddr) == chrec_known)
1939     return;
1940
1941   if (dra == drb)
1942     return;
1943
1944   if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know)
1945     return;
1946
1947   /* Loop-based vectorization and known data dependence.  */
1948   if (DDR_NUM_DIST_VECTS (ddr) == 0)
1949     return;
1950
1951   /* Data-dependence analysis reports a distance vector of zero
1952      for data-references that overlap only in the first iteration
1953      but have different sign step (see PR45764).
1954      So as a sanity check require equal DR_STEP.  */
1955   if (!operand_equal_p (DR_STEP (dra), DR_STEP (drb), 0))
1956     return;
1957
1958   loop_depth = index_in_loop_nest (loop->num, DDR_LOOP_NEST (ddr));
1959   FOR_EACH_VEC_ELT (DDR_DIST_VECTS (ddr), i, dist_v)
1960     {
1961       int dist = dist_v[loop_depth];
1962
1963       if (dump_enabled_p ())
1964         dump_printf_loc (MSG_NOTE, vect_location,
1965                          "dependence distance  = %d.\n", dist);
1966
1967       /* Same loop iteration.  */
1968       if (dist == 0
1969           || (dist % vectorization_factor == 0 && dra_size == drb_size))
1970         {
1971           /* Two references with distance zero have the same alignment.  */
1972           STMT_VINFO_SAME_ALIGN_REFS (stmtinfo_a).safe_push (drb);
1973           STMT_VINFO_SAME_ALIGN_REFS (stmtinfo_b).safe_push (dra);
1974           if (dump_enabled_p ())
1975             {
1976               dump_printf_loc (MSG_NOTE, vect_location,
1977                                "accesses have the same alignment.\n");
1978               dump_printf (MSG_NOTE,
1979                            "dependence distance modulo vf == 0 between ");
1980               dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (dra));
1981               dump_printf (MSG_NOTE,  " and ");
1982               dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (drb));
1983               dump_printf (MSG_NOTE, "\n");
1984             }
1985         }
1986     }
1987 }
1988
1989
1990 /* Function vect_analyze_data_refs_alignment
1991
1992    Analyze the alignment of the data-references in the loop.
1993    Return FALSE if a data reference is found that cannot be vectorized.  */
1994
1995 bool
1996 vect_analyze_data_refs_alignment (loop_vec_info loop_vinfo,
1997                                   bb_vec_info bb_vinfo)
1998 {
1999   if (dump_enabled_p ())
2000     dump_printf_loc (MSG_NOTE, vect_location,
2001                      "=== vect_analyze_data_refs_alignment ===\n");
2002
2003   /* Mark groups of data references with same alignment using
2004      data dependence information.  */
2005   if (loop_vinfo)
2006     {
2007       vec<ddr_p> ddrs = LOOP_VINFO_DDRS (loop_vinfo);
2008       struct data_dependence_relation *ddr;
2009       unsigned int i;
2010
2011       FOR_EACH_VEC_ELT (ddrs, i, ddr)
2012         vect_find_same_alignment_drs (ddr, loop_vinfo);
2013     }
2014
2015   if (!vect_compute_data_refs_alignment (loop_vinfo, bb_vinfo))
2016     {
2017       if (dump_enabled_p ())
2018         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
2019                          "not vectorized: can't calculate alignment "
2020                          "for data ref.\n");
2021       return false;
2022     }
2023
2024   return true;
2025 }
2026
2027
2028 /* Analyze groups of accesses: check that DR belongs to a group of
2029    accesses of legal size, step, etc.  Detect gaps, single element
2030    interleaving, and other special cases. Set grouped access info.
2031    Collect groups of strided stores for further use in SLP analysis.  */
2032
2033 static bool
2034 vect_analyze_group_access (struct data_reference *dr)
2035 {
2036   tree step = DR_STEP (dr);
2037   tree scalar_type = TREE_TYPE (DR_REF (dr));
2038   HOST_WIDE_INT type_size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (scalar_type));
2039   gimple stmt = DR_STMT (dr);
2040   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
2041   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
2042   bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info);
2043   HOST_WIDE_INT dr_step = TREE_INT_CST_LOW (step);
2044   HOST_WIDE_INT groupsize, last_accessed_element = 1;
2045   bool slp_impossible = false;
2046   struct loop *loop = NULL;
2047
2048   if (loop_vinfo)
2049     loop = LOOP_VINFO_LOOP (loop_vinfo);
2050
2051   /* For interleaving, GROUPSIZE is STEP counted in elements, i.e., the
2052      size of the interleaving group (including gaps).  */
2053   groupsize = absu_hwi (dr_step) / type_size;
2054
2055   /* Not consecutive access is possible only if it is a part of interleaving.  */
2056   if (!GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt)))
2057     {
2058       /* Check if it this DR is a part of interleaving, and is a single
2059          element of the group that is accessed in the loop.  */
2060
2061       /* Gaps are supported only for loads. STEP must be a multiple of the type
2062          size.  The size of the group must be a power of 2.  */
2063       if (DR_IS_READ (dr)
2064           && (dr_step % type_size) == 0
2065           && groupsize > 0
2066           && exact_log2 (groupsize) != -1)
2067         {
2068           GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt)) = stmt;
2069           GROUP_SIZE (vinfo_for_stmt (stmt)) = groupsize;
2070           if (dump_enabled_p ())
2071             {
2072               dump_printf_loc (MSG_NOTE, vect_location,
2073                                "Detected single element interleaving ");
2074               dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (dr));
2075               dump_printf (MSG_NOTE, " step ");
2076               dump_generic_expr (MSG_NOTE, TDF_SLIM, step);
2077               dump_printf (MSG_NOTE, "\n");
2078             }
2079
2080           if (loop_vinfo)
2081             {
2082               if (dump_enabled_p ())
2083                 dump_printf_loc (MSG_NOTE, vect_location,
2084                                  "Data access with gaps requires scalar "
2085                                  "epilogue loop\n");
2086               if (loop->inner)
2087                 {
2088                   if (dump_enabled_p ())
2089                     dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
2090                                      "Peeling for outer loop is not"
2091                                      " supported\n");
2092                   return false;
2093                 }
2094
2095               LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo) = true;
2096             }
2097
2098           return true;
2099         }
2100
2101       if (dump_enabled_p ())
2102         {
2103           dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
2104                            "not consecutive access ");
2105           dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
2106           dump_printf (MSG_MISSED_OPTIMIZATION, "\n");
2107         }
2108
2109       if (bb_vinfo)
2110         {
2111           /* Mark the statement as unvectorizable.  */
2112           STMT_VINFO_VECTORIZABLE (vinfo_for_stmt (DR_STMT (dr))) = false;
2113           return true;
2114         }
2115
2116       return false;
2117     }
2118
2119   if (GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt)) == stmt)
2120     {
2121       /* First stmt in the interleaving chain. Check the chain.  */
2122       gimple next = GROUP_NEXT_ELEMENT (vinfo_for_stmt (stmt));
2123       struct data_reference *data_ref = dr;
2124       unsigned int count = 1;
2125       tree prev_init = DR_INIT (data_ref);
2126       gimple prev = stmt;
2127       HOST_WIDE_INT diff, gaps = 0;
2128       unsigned HOST_WIDE_INT count_in_bytes;
2129
2130       while (next)
2131         {
2132           /* Skip same data-refs.  In case that two or more stmts share
2133              data-ref (supported only for loads), we vectorize only the first
2134              stmt, and the rest get their vectorized loads from the first
2135              one.  */
2136           if (!tree_int_cst_compare (DR_INIT (data_ref),
2137                                      DR_INIT (STMT_VINFO_DATA_REF (
2138                                                    vinfo_for_stmt (next)))))
2139             {
2140               if (DR_IS_WRITE (data_ref))
2141                 {
2142                   if (dump_enabled_p ())
2143                     dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
2144                                      "Two store stmts share the same dr.\n");
2145                   return false;
2146                 }
2147
2148               /* For load use the same data-ref load.  */
2149               GROUP_SAME_DR_STMT (vinfo_for_stmt (next)) = prev;
2150
2151               prev = next;
2152               next = GROUP_NEXT_ELEMENT (vinfo_for_stmt (next));
2153               continue;
2154             }
2155
2156           prev = next;
2157           data_ref = STMT_VINFO_DATA_REF (vinfo_for_stmt (next));
2158
2159           /* All group members have the same STEP by construction.  */
2160           gcc_checking_assert (operand_equal_p (DR_STEP (data_ref), step, 0));
2161
2162           /* Check that the distance between two accesses is equal to the type
2163              size. Otherwise, we have gaps.  */
2164           diff = (TREE_INT_CST_LOW (DR_INIT (data_ref))
2165                   - TREE_INT_CST_LOW (prev_init)) / type_size;
2166           if (diff != 1)
2167             {
2168               /* FORNOW: SLP of accesses with gaps is not supported.  */
2169               slp_impossible = true;
2170               if (DR_IS_WRITE (data_ref))
2171                 {
2172                   if (dump_enabled_p ())
2173                     dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
2174                                      "interleaved store with gaps\n");
2175                   return false;
2176                 }
2177
2178               gaps += diff - 1;
2179             }
2180
2181           last_accessed_element += diff;
2182
2183           /* Store the gap from the previous member of the group. If there is no
2184              gap in the access, GROUP_GAP is always 1.  */
2185           GROUP_GAP (vinfo_for_stmt (next)) = diff;
2186
2187           prev_init = DR_INIT (data_ref);
2188           next = GROUP_NEXT_ELEMENT (vinfo_for_stmt (next));
2189           /* Count the number of data-refs in the chain.  */
2190           count++;
2191         }
2192
2193       /* COUNT is the number of accesses found, we multiply it by the size of
2194          the type to get COUNT_IN_BYTES.  */
2195       count_in_bytes = type_size * count;
2196
2197       /* Check that the size of the interleaving (including gaps) is not
2198          greater than STEP.  */
2199       if (dr_step != 0
2200           && absu_hwi (dr_step) < count_in_bytes + gaps * type_size)
2201         {
2202           if (dump_enabled_p ())
2203             {
2204               dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
2205                                "interleaving size is greater than step for ");
2206               dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM,
2207                                  DR_REF (dr));
2208               dump_printf (MSG_MISSED_OPTIMIZATION, "\n");
2209             }
2210           return false;
2211         }
2212
2213       /* Check that the size of the interleaving is equal to STEP for stores,
2214          i.e., that there are no gaps.  */
2215       if (dr_step != 0
2216           && absu_hwi (dr_step) != count_in_bytes)
2217         {
2218           if (DR_IS_READ (dr))
2219             {
2220               slp_impossible = true;
2221               /* There is a gap after the last load in the group. This gap is a
2222                  difference between the groupsize and the number of elements.
2223                  When there is no gap, this difference should be 0.  */
2224               GROUP_GAP (vinfo_for_stmt (stmt)) = groupsize - count;
2225             }
2226           else
2227             {
2228               if (dump_enabled_p ())
2229                 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
2230                                  "interleaved store with gaps\n");
2231               return false;
2232             }
2233         }
2234
2235       /* Check that STEP is a multiple of type size.  */
2236       if (dr_step != 0
2237           && (dr_step % type_size) != 0)
2238         {
2239           if (dump_enabled_p ())
2240             {
2241               dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
2242                                "step is not a multiple of type size: step ");
2243               dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, step);
2244               dump_printf (MSG_MISSED_OPTIMIZATION, " size ");
2245               dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM,
2246                                  TYPE_SIZE_UNIT (scalar_type));
2247               dump_printf (MSG_MISSED_OPTIMIZATION, "\n");
2248             }
2249           return false;
2250         }
2251
2252       if (groupsize == 0)
2253         groupsize = count;
2254
2255       GROUP_SIZE (vinfo_for_stmt (stmt)) = groupsize;
2256       if (dump_enabled_p ())
2257         dump_printf_loc (MSG_NOTE, vect_location,
2258                          "Detected interleaving of size %d\n", (int)groupsize);
2259
2260       /* SLP: create an SLP data structure for every interleaving group of
2261          stores for further analysis in vect_analyse_slp.  */
2262       if (DR_IS_WRITE (dr) && !slp_impossible)
2263         {
2264           if (loop_vinfo)
2265             LOOP_VINFO_GROUPED_STORES (loop_vinfo).safe_push (stmt);
2266           if (bb_vinfo)
2267             BB_VINFO_GROUPED_STORES (bb_vinfo).safe_push (stmt);
2268         }
2269
2270       /* There is a gap in the end of the group.  */
2271       if (groupsize - last_accessed_element > 0 && loop_vinfo)
2272         {
2273           if (dump_enabled_p ())
2274             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
2275                              "Data access with gaps requires scalar "
2276                              "epilogue loop\n");
2277           if (loop->inner)
2278             {
2279               if (dump_enabled_p ())
2280                 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
2281                                  "Peeling for outer loop is not supported\n");
2282               return false;
2283             }
2284
2285           LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo) = true;
2286         }
2287     }
2288
2289   return true;
2290 }
2291
2292
2293 /* Analyze the access pattern of the data-reference DR.
2294    In case of non-consecutive accesses call vect_analyze_group_access() to
2295    analyze groups of accesses.  */
2296
2297 static bool
2298 vect_analyze_data_ref_access (struct data_reference *dr)
2299 {
2300   tree step = DR_STEP (dr);
2301   tree scalar_type = TREE_TYPE (DR_REF (dr));
2302   gimple stmt = DR_STMT (dr);
2303   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
2304   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
2305   struct loop *loop = NULL;
2306
2307   if (loop_vinfo)
2308     loop = LOOP_VINFO_LOOP (loop_vinfo);
2309
2310   if (loop_vinfo && !step)
2311     {
2312       if (dump_enabled_p ())
2313         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
2314                          "bad data-ref access in loop\n");
2315       return false;
2316     }
2317
2318   /* Allow invariant loads in not nested loops.  */
2319   if (loop_vinfo && integer_zerop (step))
2320     {
2321       GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt)) = NULL;
2322       if (nested_in_vect_loop_p (loop, stmt))
2323         {
2324           if (dump_enabled_p ())
2325             dump_printf_loc (MSG_NOTE, vect_location,
2326                              "zero step in inner loop of nest\n");
2327           return false;
2328         }
2329       return DR_IS_READ (dr);
2330     }
2331
2332   if (loop && nested_in_vect_loop_p (loop, stmt))
2333     {
2334       /* Interleaved accesses are not yet supported within outer-loop
2335         vectorization for references in the inner-loop.  */
2336       GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt)) = NULL;
2337
2338       /* For the rest of the analysis we use the outer-loop step.  */
2339       step = STMT_VINFO_DR_STEP (stmt_info);
2340       if (integer_zerop (step))
2341         {
2342           if (dump_enabled_p ())
2343             dump_printf_loc (MSG_NOTE, vect_location,
2344                              "zero step in outer loop.\n");
2345           if (DR_IS_READ (dr))
2346             return true;
2347           else
2348             return false;
2349         }
2350     }
2351
2352   /* Consecutive?  */
2353   if (TREE_CODE (step) == INTEGER_CST)
2354     {
2355       HOST_WIDE_INT dr_step = TREE_INT_CST_LOW (step);
2356       if (!tree_int_cst_compare (step, TYPE_SIZE_UNIT (scalar_type))
2357           || (dr_step < 0
2358               && !compare_tree_int (TYPE_SIZE_UNIT (scalar_type), -dr_step)))
2359         {
2360           /* Mark that it is not interleaving.  */
2361           GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt)) = NULL;
2362           return true;
2363         }
2364     }
2365
2366   if (loop && nested_in_vect_loop_p (loop, stmt))
2367     {
2368       if (dump_enabled_p ())
2369         dump_printf_loc (MSG_NOTE, vect_location,
2370                          "grouped access in outer loop.\n");
2371       return false;
2372     }
2373
2374   /* Assume this is a DR handled by non-constant strided load case.  */
2375   if (TREE_CODE (step) != INTEGER_CST)
2376     return STMT_VINFO_STRIDE_LOAD_P (stmt_info);
2377
2378   /* Not consecutive access - check if it's a part of interleaving group.  */
2379   return vect_analyze_group_access (dr);
2380 }
2381
2382
2383
2384 /*  A helper function used in the comparator function to sort data
2385     references.  T1 and T2 are two data references to be compared.
2386     The function returns -1, 0, or 1.  */
2387
2388 static int
2389 compare_tree (tree t1, tree t2)
2390 {
2391   int i, cmp;
2392   enum tree_code code;
2393   char tclass;
2394
2395   if (t1 == t2)
2396     return 0;
2397   if (t1 == NULL)
2398     return -1;
2399   if (t2 == NULL)
2400     return 1;
2401
2402
2403   if (TREE_CODE (t1) != TREE_CODE (t2))
2404     return TREE_CODE (t1) < TREE_CODE (t2) ? -1 : 1;
2405
2406   code = TREE_CODE (t1);
2407   switch (code)
2408     {
2409     /* For const values, we can just use hash values for comparisons.  */
2410     case INTEGER_CST:
2411     case REAL_CST:
2412     case FIXED_CST:
2413     case STRING_CST:
2414     case COMPLEX_CST:
2415     case VECTOR_CST:
2416       {
2417         hashval_t h1 = iterative_hash_expr (t1, 0);
2418         hashval_t h2 = iterative_hash_expr (t2, 0);
2419         if (h1 != h2)
2420           return h1 < h2 ? -1 : 1;
2421         break;
2422       }
2423
2424     case SSA_NAME:
2425       cmp = compare_tree (SSA_NAME_VAR (t1), SSA_NAME_VAR (t2));
2426       if (cmp != 0)
2427         return cmp;
2428
2429       if (SSA_NAME_VERSION (t1) != SSA_NAME_VERSION (t2))
2430         return SSA_NAME_VERSION (t1) < SSA_NAME_VERSION (t2) ? -1 : 1;
2431       break;
2432
2433     default:
2434       tclass = TREE_CODE_CLASS (code);
2435
2436       /* For var-decl, we could compare their UIDs.  */
2437       if (tclass == tcc_declaration)
2438         {
2439           if (DECL_UID (t1) != DECL_UID (t2))
2440             return DECL_UID (t1) < DECL_UID (t2) ? -1 : 1;
2441           break;
2442         }
2443
2444       /* For expressions with operands, compare their operands recursively.  */
2445       for (i = TREE_OPERAND_LENGTH (t1) - 1; i >= 0; --i)
2446         {
2447           cmp = compare_tree (TREE_OPERAND (t1, i), TREE_OPERAND (t2, i));
2448           if (cmp != 0)
2449             return cmp;
2450         }
2451     }
2452
2453   return 0;
2454 }
2455
2456
2457 /* Compare two data-references DRA and DRB to group them into chunks
2458    suitable for grouping.  */
2459
2460 static int
2461 dr_group_sort_cmp (const void *dra_, const void *drb_)
2462 {
2463   data_reference_p dra = *(data_reference_p *)const_cast<void *>(dra_);
2464   data_reference_p drb = *(data_reference_p *)const_cast<void *>(drb_);
2465   int cmp;
2466
2467   /* Stabilize sort.  */
2468   if (dra == drb)
2469     return 0;
2470
2471   /* Ordering of DRs according to base.  */
2472   if (!operand_equal_p (DR_BASE_ADDRESS (dra), DR_BASE_ADDRESS (drb), 0))
2473     {
2474       cmp = compare_tree (DR_BASE_ADDRESS (dra), DR_BASE_ADDRESS (drb));
2475       if (cmp != 0)
2476         return cmp;
2477     }
2478
2479   /* And according to DR_OFFSET.  */
2480   if (!dr_equal_offsets_p (dra, drb))
2481     {
2482       cmp = compare_tree (DR_OFFSET (dra), DR_OFFSET (drb));
2483       if (cmp != 0)
2484         return cmp;
2485     }
2486
2487   /* Put reads before writes.  */
2488   if (DR_IS_READ (dra) != DR_IS_READ (drb))
2489     return DR_IS_READ (dra) ? -1 : 1;
2490
2491   /* Then sort after access size.  */
2492   if (!operand_equal_p (TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (dra))),
2493                         TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (drb))), 0))
2494     {
2495       cmp = compare_tree (TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (dra))),
2496                           TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (drb))));
2497       if (cmp != 0)
2498         return cmp;
2499     }
2500
2501   /* And after step.  */
2502   if (!operand_equal_p (DR_STEP (dra), DR_STEP (drb), 0))
2503     {
2504       cmp = compare_tree (DR_STEP (dra), DR_STEP (drb));
2505       if (cmp != 0)
2506         return cmp;
2507     }
2508
2509   /* Then sort after DR_INIT.  In case of identical DRs sort after stmt UID.  */
2510   cmp = tree_int_cst_compare (DR_INIT (dra), DR_INIT (drb));
2511   if (cmp == 0)
2512     return gimple_uid (DR_STMT (dra)) < gimple_uid (DR_STMT (drb)) ? -1 : 1;
2513   return cmp;
2514 }
2515
2516 /* Function vect_analyze_data_ref_accesses.
2517
2518    Analyze the access pattern of all the data references in the loop.
2519
2520    FORNOW: the only access pattern that is considered vectorizable is a
2521            simple step 1 (consecutive) access.
2522
2523    FORNOW: handle only arrays and pointer accesses.  */
2524
2525 bool
2526 vect_analyze_data_ref_accesses (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo)
2527 {
2528   unsigned int i;
2529   vec<data_reference_p> datarefs;
2530   struct data_reference *dr;
2531
2532   if (dump_enabled_p ())
2533     dump_printf_loc (MSG_NOTE, vect_location,
2534                      "=== vect_analyze_data_ref_accesses ===\n");
2535
2536   if (loop_vinfo)
2537     datarefs = LOOP_VINFO_DATAREFS (loop_vinfo);
2538   else
2539     datarefs = BB_VINFO_DATAREFS (bb_vinfo);
2540
2541   if (datarefs.is_empty ())
2542     return true;
2543
2544   /* Sort the array of datarefs to make building the interleaving chains
2545      linear.  Don't modify the original vector's order, it is needed for
2546      determining what dependencies are reversed.  */
2547   vec<data_reference_p> datarefs_copy = datarefs.copy ();
2548   datarefs_copy.qsort (dr_group_sort_cmp);
2549
2550   /* Build the interleaving chains.  */
2551   for (i = 0; i < datarefs_copy.length () - 1;)
2552     {
2553       data_reference_p dra = datarefs_copy[i];
2554       stmt_vec_info stmtinfo_a = vinfo_for_stmt (DR_STMT (dra));
2555       stmt_vec_info lastinfo = NULL;
2556       for (i = i + 1; i < datarefs_copy.length (); ++i)
2557         {
2558           data_reference_p drb = datarefs_copy[i];
2559           stmt_vec_info stmtinfo_b = vinfo_for_stmt (DR_STMT (drb));
2560
2561           /* ???  Imperfect sorting (non-compatible types, non-modulo
2562              accesses, same accesses) can lead to a group to be artificially
2563              split here as we don't just skip over those.  If it really
2564              matters we can push those to a worklist and re-iterate
2565              over them.  The we can just skip ahead to the next DR here.  */
2566
2567           /* Check that the data-refs have same first location (except init)
2568              and they are both either store or load (not load and store,
2569              not masked loads or stores).  */
2570           if (DR_IS_READ (dra) != DR_IS_READ (drb)
2571               || !operand_equal_p (DR_BASE_ADDRESS (dra),
2572                                    DR_BASE_ADDRESS (drb), 0)
2573               || !dr_equal_offsets_p (dra, drb)
2574               || !gimple_assign_single_p (DR_STMT (dra))
2575               || !gimple_assign_single_p (DR_STMT (drb)))
2576             break;
2577
2578           /* Check that the data-refs have the same constant size and step.  */
2579           tree sza = TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (dra)));
2580           tree szb = TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (drb)));
2581           if (!tree_fits_uhwi_p (sza)
2582               || !tree_fits_uhwi_p (szb)
2583               || !tree_int_cst_equal (sza, szb)
2584               || !tree_fits_shwi_p (DR_STEP (dra))
2585               || !tree_fits_shwi_p (DR_STEP (drb))
2586               || !tree_int_cst_equal (DR_STEP (dra), DR_STEP (drb)))
2587             break;
2588
2589           /* Do not place the same access in the interleaving chain twice.  */
2590           if (tree_int_cst_compare (DR_INIT (dra), DR_INIT (drb)) == 0)
2591             break;
2592
2593           /* Check the types are compatible.
2594              ???  We don't distinguish this during sorting.  */
2595           if (!types_compatible_p (TREE_TYPE (DR_REF (dra)),
2596                                    TREE_TYPE (DR_REF (drb))))
2597             break;
2598
2599           /* Sorting has ensured that DR_INIT (dra) <= DR_INIT (drb).  */
2600           HOST_WIDE_INT init_a = TREE_INT_CST_LOW (DR_INIT (dra));
2601           HOST_WIDE_INT init_b = TREE_INT_CST_LOW (DR_INIT (drb));
2602           gcc_assert (init_a < init_b);
2603
2604           /* If init_b == init_a + the size of the type * k, we have an
2605              interleaving, and DRA is accessed before DRB.  */
2606           HOST_WIDE_INT type_size_a = tree_to_uhwi (sza);
2607           if ((init_b - init_a) % type_size_a != 0)
2608             break;
2609
2610           /* The step (if not zero) is greater than the difference between
2611              data-refs' inits.  This splits groups into suitable sizes.  */
2612           HOST_WIDE_INT step = tree_to_shwi (DR_STEP (dra));
2613           if (step != 0 && step <= (init_b - init_a))
2614             break;
2615
2616           if (dump_enabled_p ())
2617             {
2618               dump_printf_loc (MSG_NOTE, vect_location,
2619                                "Detected interleaving ");
2620               dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (dra));
2621               dump_printf (MSG_NOTE,  " and ");
2622               dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (drb));
2623               dump_printf (MSG_NOTE, "\n");
2624             }
2625
2626           /* Link the found element into the group list.  */
2627           if (!GROUP_FIRST_ELEMENT (stmtinfo_a))
2628             {
2629               GROUP_FIRST_ELEMENT (stmtinfo_a) = DR_STMT (dra);
2630               lastinfo = stmtinfo_a;
2631             }
2632           GROUP_FIRST_ELEMENT (stmtinfo_b) = DR_STMT (dra);
2633           GROUP_NEXT_ELEMENT (lastinfo) = DR_STMT (drb);
2634           lastinfo = stmtinfo_b;
2635         }
2636     }
2637
2638   FOR_EACH_VEC_ELT (datarefs_copy, i, dr)
2639     if (STMT_VINFO_VECTORIZABLE (vinfo_for_stmt (DR_STMT (dr))) 
2640         && !vect_analyze_data_ref_access (dr))
2641       {
2642         if (dump_enabled_p ())
2643           dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
2644                            "not vectorized: complicated access pattern.\n");
2645
2646         if (bb_vinfo)
2647           {
2648             /* Mark the statement as not vectorizable.  */
2649             STMT_VINFO_VECTORIZABLE (vinfo_for_stmt (DR_STMT (dr))) = false;
2650             continue;
2651           }
2652         else
2653           {
2654             datarefs_copy.release ();
2655             return false;
2656           }
2657       }
2658
2659   datarefs_copy.release ();
2660   return true;
2661 }
2662
2663
2664 /* Operator == between two dr_with_seg_len objects.
2665
2666    This equality operator is used to make sure two data refs
2667    are the same one so that we will consider to combine the
2668    aliasing checks of those two pairs of data dependent data
2669    refs.  */
2670
2671 static bool
2672 operator == (const dr_with_seg_len& d1,
2673              const dr_with_seg_len& d2)
2674 {
2675   return operand_equal_p (DR_BASE_ADDRESS (d1.dr),
2676                           DR_BASE_ADDRESS (d2.dr), 0)
2677            && compare_tree (d1.offset, d2.offset) == 0
2678            && compare_tree (d1.seg_len, d2.seg_len) == 0;
2679 }
2680
2681 /* Function comp_dr_with_seg_len_pair.
2682
2683    Comparison function for sorting objects of dr_with_seg_len_pair_t
2684    so that we can combine aliasing checks in one scan.  */
2685
2686 static int
2687 comp_dr_with_seg_len_pair (const void *p1_, const void *p2_)
2688 {
2689   const dr_with_seg_len_pair_t* p1 = (const dr_with_seg_len_pair_t *) p1_;
2690   const dr_with_seg_len_pair_t* p2 = (const dr_with_seg_len_pair_t *) p2_;
2691
2692   const dr_with_seg_len &p11 = p1->first,
2693                         &p12 = p1->second,
2694                         &p21 = p2->first,
2695                         &p22 = p2->second;
2696
2697   /* For DR pairs (a, b) and (c, d), we only consider to merge the alias checks
2698      if a and c have the same basic address snd step, and b and d have the same
2699      address and step.  Therefore, if any a&c or b&d don't have the same address
2700      and step, we don't care the order of those two pairs after sorting.  */
2701   int comp_res;
2702
2703   if ((comp_res = compare_tree (DR_BASE_ADDRESS (p11.dr),
2704                                 DR_BASE_ADDRESS (p21.dr))) != 0)
2705     return comp_res;
2706   if ((comp_res = compare_tree (DR_BASE_ADDRESS (p12.dr),
2707                                 DR_BASE_ADDRESS (p22.dr))) != 0)
2708     return comp_res;
2709   if ((comp_res = compare_tree (DR_STEP (p11.dr), DR_STEP (p21.dr))) != 0)
2710     return comp_res;
2711   if ((comp_res = compare_tree (DR_STEP (p12.dr), DR_STEP (p22.dr))) != 0)
2712     return comp_res;
2713   if ((comp_res = compare_tree (p11.offset, p21.offset)) != 0)
2714     return comp_res;
2715   if ((comp_res = compare_tree (p12.offset, p22.offset)) != 0)
2716     return comp_res;
2717
2718   return 0;
2719 }
2720
2721 /* Function vect_vfa_segment_size.
2722
2723    Create an expression that computes the size of segment
2724    that will be accessed for a data reference.  The functions takes into
2725    account that realignment loads may access one more vector.
2726
2727    Input:
2728      DR: The data reference.
2729      LENGTH_FACTOR: segment length to consider.
2730
2731    Return an expression whose value is the size of segment which will be
2732    accessed by DR.  */
2733
2734 static tree
2735 vect_vfa_segment_size (struct data_reference *dr, tree length_factor)
2736 {
2737   tree segment_length;
2738
2739   if (integer_zerop (DR_STEP (dr)))
2740     segment_length = TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (dr)));
2741   else
2742     segment_length = size_binop (MULT_EXPR,
2743                                  fold_convert (sizetype, DR_STEP (dr)),
2744                                  fold_convert (sizetype, length_factor));
2745
2746   if (vect_supportable_dr_alignment (dr, false)
2747         == dr_explicit_realign_optimized)
2748     {
2749       tree vector_size = TYPE_SIZE_UNIT
2750                           (STMT_VINFO_VECTYPE (vinfo_for_stmt (DR_STMT (dr))));
2751
2752       segment_length = size_binop (PLUS_EXPR, segment_length, vector_size);
2753     }
2754   return segment_length;
2755 }
2756
2757 /* Function vect_prune_runtime_alias_test_list.
2758
2759    Prune a list of ddrs to be tested at run-time by versioning for alias.
2760    Merge several alias checks into one if possible.
2761    Return FALSE if resulting list of ddrs is longer then allowed by
2762    PARAM_VECT_MAX_VERSION_FOR_ALIAS_CHECKS, otherwise return TRUE.  */
2763
2764 bool
2765 vect_prune_runtime_alias_test_list (loop_vec_info loop_vinfo)
2766 {
2767   vec<ddr_p> may_alias_ddrs =
2768     LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo);
2769   vec<dr_with_seg_len_pair_t>& comp_alias_ddrs =
2770     LOOP_VINFO_COMP_ALIAS_DDRS (loop_vinfo);
2771   int vect_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
2772   tree scalar_loop_iters = LOOP_VINFO_NITERS (loop_vinfo);
2773
2774   ddr_p ddr;
2775   unsigned int i;
2776   tree length_factor;
2777
2778   if (dump_enabled_p ())
2779     dump_printf_loc (MSG_NOTE, vect_location,
2780                      "=== vect_prune_runtime_alias_test_list ===\n");
2781
2782   if (may_alias_ddrs.is_empty ())
2783     return true;
2784
2785   /* Basically, for each pair of dependent data refs store_ptr_0
2786      and load_ptr_0, we create an expression:
2787
2788      ((store_ptr_0 + store_segment_length_0) <= load_ptr_0)
2789      || (load_ptr_0 + load_segment_length_0) <= store_ptr_0))
2790
2791      for aliasing checks.  However, in some cases we can decrease
2792      the number of checks by combining two checks into one.  For
2793      example, suppose we have another pair of data refs store_ptr_0
2794      and load_ptr_1, and if the following condition is satisfied:
2795
2796      load_ptr_0 < load_ptr_1  &&
2797      load_ptr_1 - load_ptr_0 - load_segment_length_0 < store_segment_length_0
2798
2799      (this condition means, in each iteration of vectorized loop,
2800      the accessed memory of store_ptr_0 cannot be between the memory
2801      of load_ptr_0 and load_ptr_1.)
2802
2803      we then can use only the following expression to finish the
2804      alising checks between store_ptr_0 & load_ptr_0 and
2805      store_ptr_0 & load_ptr_1:
2806
2807      ((store_ptr_0 + store_segment_length_0) <= load_ptr_0)
2808      || (load_ptr_1 + load_segment_length_1 <= store_ptr_0))
2809
2810      Note that we only consider that load_ptr_0 and load_ptr_1 have the
2811      same basic address.  */
2812
2813   comp_alias_ddrs.create (may_alias_ddrs.length ());
2814
2815   /* First, we collect all data ref pairs for aliasing checks.  */
2816   FOR_EACH_VEC_ELT (may_alias_ddrs, i, ddr)
2817     {
2818       struct data_reference *dr_a, *dr_b;
2819       gimple dr_group_first_a, dr_group_first_b;
2820       tree segment_length_a, segment_length_b;
2821       gimple stmt_a, stmt_b;
2822
2823       dr_a = DDR_A (ddr);
2824       stmt_a = DR_STMT (DDR_A (ddr));
2825       dr_group_first_a = GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt_a));
2826       if (dr_group_first_a)
2827         {
2828           stmt_a = dr_group_first_a;
2829           dr_a = STMT_VINFO_DATA_REF (vinfo_for_stmt (stmt_a));
2830         }
2831
2832       dr_b = DDR_B (ddr);
2833       stmt_b = DR_STMT (DDR_B (ddr));
2834       dr_group_first_b = GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt_b));
2835       if (dr_group_first_b)
2836         {
2837           stmt_b = dr_group_first_b;
2838           dr_b = STMT_VINFO_DATA_REF (vinfo_for_stmt (stmt_b));
2839         }
2840
2841       if (!operand_equal_p (DR_STEP (dr_a), DR_STEP (dr_b), 0))
2842         length_factor = scalar_loop_iters;
2843       else
2844         length_factor = size_int (vect_factor);
2845       segment_length_a = vect_vfa_segment_size (dr_a, length_factor);
2846       segment_length_b = vect_vfa_segment_size (dr_b, length_factor);
2847
2848       dr_with_seg_len_pair_t dr_with_seg_len_pair
2849           (dr_with_seg_len (dr_a, segment_length_a),
2850            dr_with_seg_len (dr_b, segment_length_b));
2851
2852       if (compare_tree (DR_BASE_ADDRESS (dr_a), DR_BASE_ADDRESS (dr_b)) > 0)
2853         std::swap (dr_with_seg_len_pair.first, dr_with_seg_len_pair.second);
2854
2855       comp_alias_ddrs.safe_push (dr_with_seg_len_pair);
2856     }
2857
2858   /* Second, we sort the collected data ref pairs so that we can scan
2859      them once to combine all possible aliasing checks.  */
2860   comp_alias_ddrs.qsort (comp_dr_with_seg_len_pair);
2861
2862   /* Third, we scan the sorted dr pairs and check if we can combine
2863      alias checks of two neighbouring dr pairs.  */
2864   for (size_t i = 1; i < comp_alias_ddrs.length (); ++i)
2865     {
2866       /* Deal with two ddrs (dr_a1, dr_b1) and (dr_a2, dr_b2).  */
2867       dr_with_seg_len *dr_a1 = &comp_alias_ddrs[i-1].first,
2868                       *dr_b1 = &comp_alias_ddrs[i-1].second,
2869                       *dr_a2 = &comp_alias_ddrs[i].first,
2870                       *dr_b2 = &comp_alias_ddrs[i].second;
2871
2872       /* Remove duplicate data ref pairs.  */
2873       if (*dr_a1 == *dr_a2 && *dr_b1 == *dr_b2)
2874         {
2875           if (dump_enabled_p ())
2876             {
2877               dump_printf_loc (MSG_NOTE, vect_location,
2878                                "found equal ranges ");
2879               dump_generic_expr (MSG_NOTE, TDF_SLIM,
2880                                  DR_REF (dr_a1->dr));
2881               dump_printf (MSG_NOTE,  ", ");
2882               dump_generic_expr (MSG_NOTE, TDF_SLIM,
2883                                  DR_REF (dr_b1->dr));
2884               dump_printf (MSG_NOTE,  " and ");
2885               dump_generic_expr (MSG_NOTE, TDF_SLIM,
2886                                  DR_REF (dr_a2->dr));
2887               dump_printf (MSG_NOTE,  ", ");
2888               dump_generic_expr (MSG_NOTE, TDF_SLIM,
2889                                  DR_REF (dr_b2->dr));
2890               dump_printf (MSG_NOTE, "\n");
2891             }
2892
2893           comp_alias_ddrs.ordered_remove (i--);
2894           continue;
2895         }
2896
2897       if (*dr_a1 == *dr_a2 || *dr_b1 == *dr_b2)
2898         {
2899           /* We consider the case that DR_B1 and DR_B2 are same memrefs,
2900              and DR_A1 and DR_A2 are two consecutive memrefs.  */
2901           if (*dr_a1 == *dr_a2)
2902             {
2903               std::swap (dr_a1, dr_b1);
2904               std::swap (dr_a2, dr_b2);
2905             }
2906
2907           if (!operand_equal_p (DR_BASE_ADDRESS (dr_a1->dr),
2908                                 DR_BASE_ADDRESS (dr_a2->dr),
2909                                 0)
2910               || !tree_fits_shwi_p (dr_a1->offset)
2911               || !tree_fits_shwi_p (dr_a2->offset))
2912             continue;
2913
2914           HOST_WIDE_INT diff = (tree_to_shwi (dr_a2->offset)
2915                                 - tree_to_shwi (dr_a1->offset));
2916
2917
2918           /* Now we check if the following condition is satisfied:
2919
2920              DIFF - SEGMENT_LENGTH_A < SEGMENT_LENGTH_B
2921
2922              where DIFF = DR_A2->OFFSET - DR_A1->OFFSET.  However,
2923              SEGMENT_LENGTH_A or SEGMENT_LENGTH_B may not be constant so we
2924              have to make a best estimation.  We can get the minimum value
2925              of SEGMENT_LENGTH_B as a constant, represented by MIN_SEG_LEN_B,
2926              then either of the following two conditions can guarantee the
2927              one above:
2928
2929              1: DIFF <= MIN_SEG_LEN_B
2930              2: DIFF - SEGMENT_LENGTH_A < MIN_SEG_LEN_B
2931
2932              */
2933
2934           HOST_WIDE_INT  min_seg_len_b = (tree_fits_shwi_p (dr_b1->seg_len)
2935                                           ? tree_to_shwi (dr_b1->seg_len)
2936                                           : vect_factor);
2937
2938           if (diff <= min_seg_len_b
2939               || (tree_fits_shwi_p (dr_a1->seg_len)
2940                   && diff - tree_to_shwi (dr_a1->seg_len) < min_seg_len_b))
2941             {
2942               if (dump_enabled_p ())
2943                 {
2944                   dump_printf_loc (MSG_NOTE, vect_location,
2945                                    "merging ranges for ");
2946                   dump_generic_expr (MSG_NOTE, TDF_SLIM,
2947                                      DR_REF (dr_a1->dr));
2948                   dump_printf (MSG_NOTE,  ", ");
2949                   dump_generic_expr (MSG_NOTE, TDF_SLIM,
2950                                      DR_REF (dr_b1->dr));
2951                   dump_printf (MSG_NOTE,  " and ");
2952                   dump_generic_expr (MSG_NOTE, TDF_SLIM,
2953                                      DR_REF (dr_a2->dr));
2954                   dump_printf (MSG_NOTE,  ", ");
2955                   dump_generic_expr (MSG_NOTE, TDF_SLIM,
2956                                      DR_REF (dr_b2->dr));
2957                   dump_printf (MSG_NOTE, "\n");
2958                 }
2959
2960               dr_a1->seg_len = size_binop (PLUS_EXPR,
2961                                            dr_a2->seg_len, size_int (diff));
2962               comp_alias_ddrs.ordered_remove (i--);
2963             }
2964         }
2965     }
2966
2967   dump_printf_loc (MSG_NOTE, vect_location,
2968                    "improved number of alias checks from %d to %d\n",
2969                    may_alias_ddrs.length (), comp_alias_ddrs.length ());
2970   if ((int) comp_alias_ddrs.length () >
2971       PARAM_VALUE (PARAM_VECT_MAX_VERSION_FOR_ALIAS_CHECKS))
2972     return false;
2973
2974   return true;
2975 }
2976
2977 /* Check whether a non-affine read in stmt is suitable for gather load
2978    and if so, return a builtin decl for that operation.  */
2979
2980 tree
2981 vect_check_gather (gimple stmt, loop_vec_info loop_vinfo, tree *basep,
2982                    tree *offp, int *scalep)
2983 {
2984   HOST_WIDE_INT scale = 1, pbitpos, pbitsize;
2985   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
2986   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
2987   struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
2988   tree offtype = NULL_TREE;
2989   tree decl, base, off;
2990   machine_mode pmode;
2991   int punsignedp, pvolatilep;
2992
2993   base = DR_REF (dr);
2994   /* For masked loads/stores, DR_REF (dr) is an artificial MEM_REF,
2995      see if we can use the def stmt of the address.  */
2996   if (is_gimple_call (stmt)
2997       && gimple_call_internal_p (stmt)
2998       && (gimple_call_internal_fn (stmt) == IFN_MASK_LOAD
2999           || gimple_call_internal_fn (stmt) == IFN_MASK_STORE)
3000       && TREE_CODE (base) == MEM_REF
3001       && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME
3002       && integer_zerop (TREE_OPERAND (base, 1))
3003       && !expr_invariant_in_loop_p (loop, TREE_OPERAND (base, 0)))
3004     {
3005       gimple def_stmt = SSA_NAME_DEF_STMT (TREE_OPERAND (base, 0));
3006       if (is_gimple_assign (def_stmt)
3007           && gimple_assign_rhs_code (def_stmt) == ADDR_EXPR)
3008         base = TREE_OPERAND (gimple_assign_rhs1 (def_stmt), 0);
3009     }
3010
3011   /* The gather builtins need address of the form
3012      loop_invariant + vector * {1, 2, 4, 8}
3013      or
3014      loop_invariant + sign_extend (vector) * { 1, 2, 4, 8 }.
3015      Unfortunately DR_BASE_ADDRESS/DR_OFFSET can be a mixture
3016      of loop invariants/SSA_NAMEs defined in the loop, with casts,
3017      multiplications and additions in it.  To get a vector, we need
3018      a single SSA_NAME that will be defined in the loop and will
3019      contain everything that is not loop invariant and that can be
3020      vectorized.  The following code attempts to find such a preexistng
3021      SSA_NAME OFF and put the loop invariants into a tree BASE
3022      that can be gimplified before the loop.  */
3023   base = get_inner_reference (base, &pbitsize, &pbitpos, &off,
3024                               &pmode, &punsignedp, &pvolatilep, false);
3025   gcc_assert (base != NULL_TREE && (pbitpos % BITS_PER_UNIT) == 0);
3026
3027   if (TREE_CODE (base) == MEM_REF)
3028     {
3029       if (!integer_zerop (TREE_OPERAND (base, 1)))
3030         {
3031           if (off == NULL_TREE)
3032             {
3033               offset_int moff = mem_ref_offset (base);
3034               off = wide_int_to_tree (sizetype, moff);
3035             }
3036           else
3037             off = size_binop (PLUS_EXPR, off,
3038                               fold_convert (sizetype, TREE_OPERAND (base, 1)));
3039         }
3040       base = TREE_OPERAND (base, 0);
3041     }
3042   else
3043     base = build_fold_addr_expr (base);
3044
3045   if (off == NULL_TREE)
3046     off = size_zero_node;
3047
3048   /* If base is not loop invariant, either off is 0, then we start with just
3049      the constant offset in the loop invariant BASE and continue with base
3050      as OFF, otherwise give up.
3051      We could handle that case by gimplifying the addition of base + off
3052      into some SSA_NAME and use that as off, but for now punt.  */
3053   if (!expr_invariant_in_loop_p (loop, base))
3054     {
3055       if (!integer_zerop (off))
3056         return NULL_TREE;
3057       off = base;
3058       base = size_int (pbitpos / BITS_PER_UNIT);
3059     }
3060   /* Otherwise put base + constant offset into the loop invariant BASE
3061      and continue with OFF.  */
3062   else
3063     {
3064       base = fold_convert (sizetype, base);
3065       base = size_binop (PLUS_EXPR, base, size_int (pbitpos / BITS_PER_UNIT));
3066     }
3067
3068   /* OFF at this point may be either a SSA_NAME or some tree expression
3069      from get_inner_reference.  Try to peel off loop invariants from it
3070      into BASE as long as possible.  */
3071   STRIP_NOPS (off);
3072   while (offtype == NULL_TREE)
3073     {
3074       enum tree_code code;
3075       tree op0, op1, add = NULL_TREE;
3076
3077       if (TREE_CODE (off) == SSA_NAME)
3078         {
3079           gimple def_stmt = SSA_NAME_DEF_STMT (off);
3080
3081           if (expr_invariant_in_loop_p (loop, off))
3082             return NULL_TREE;
3083
3084           if (gimple_code (def_stmt) != GIMPLE_ASSIGN)
3085             break;
3086
3087           op0 = gimple_assign_rhs1 (def_stmt);
3088           code = gimple_assign_rhs_code (def_stmt);
3089           op1 = gimple_assign_rhs2 (def_stmt);
3090         }
3091       else
3092         {
3093           if (get_gimple_rhs_class (TREE_CODE (off)) == GIMPLE_TERNARY_RHS)
3094             return NULL_TREE;
3095           code = TREE_CODE (off);
3096           extract_ops_from_tree (off, &code, &op0, &op1);
3097         }
3098       switch (code)
3099         {
3100         case POINTER_PLUS_EXPR:
3101         case PLUS_EXPR:
3102           if (expr_invariant_in_loop_p (loop, op0))
3103             {
3104               add = op0;
3105               off = op1;
3106             do_add:
3107               add = fold_convert (sizetype, add);
3108               if (scale != 1)
3109                 add = size_binop (MULT_EXPR, add, size_int (scale));
3110               base = size_binop (PLUS_EXPR, base, add);
3111               continue;
3112             }
3113           if (expr_invariant_in_loop_p (loop, op1))
3114             {
3115               add = op1;
3116               off = op0;
3117               goto do_add;
3118             }
3119           break;
3120         case MINUS_EXPR:
3121           if (expr_invariant_in_loop_p (loop, op1))
3122             {
3123               add = fold_convert (sizetype, op1);
3124               add = size_binop (MINUS_EXPR, size_zero_node, add);
3125               off = op0;
3126               goto do_add;
3127             }
3128           break;
3129         case MULT_EXPR:
3130           if (scale == 1 && tree_fits_shwi_p (op1))
3131             {
3132               scale = tree_to_shwi (op1);
3133               off = op0;
3134               continue;
3135             }
3136           break;
3137         case SSA_NAME:
3138           off = op0;
3139           continue;
3140         CASE_CONVERT:
3141           if (!POINTER_TYPE_P (TREE_TYPE (op0))
3142               && !INTEGRAL_TYPE_P (TREE_TYPE (op0)))
3143             break;
3144           if (TYPE_PRECISION (TREE_TYPE (op0))
3145               == TYPE_PRECISION (TREE_TYPE (off)))
3146             {
3147               off = op0;
3148               continue;
3149             }
3150           if (TYPE_PRECISION (TREE_TYPE (op0))
3151               < TYPE_PRECISION (TREE_TYPE (off)))
3152             {
3153               off = op0;
3154               offtype = TREE_TYPE (off);
3155               STRIP_NOPS (off);
3156               continue;
3157             }
3158           break;
3159         default:
3160           break;
3161         }
3162       break;
3163     }
3164
3165   /* If at the end OFF still isn't a SSA_NAME or isn't
3166      defined in the loop, punt.  */
3167   if (TREE_CODE (off) != SSA_NAME
3168       || expr_invariant_in_loop_p (loop, off))
3169     return NULL_TREE;
3170
3171   if (offtype == NULL_TREE)
3172     offtype = TREE_TYPE (off);
3173
3174   decl = targetm.vectorize.builtin_gather (STMT_VINFO_VECTYPE (stmt_info),
3175                                            offtype, scale);
3176   if (decl == NULL_TREE)
3177     return NULL_TREE;
3178
3179   if (basep)
3180     *basep = base;
3181   if (offp)
3182     *offp = off;
3183   if (scalep)
3184     *scalep = scale;
3185   return decl;
3186 }
3187
3188 /* Function vect_analyze_data_refs.
3189
3190   Find all the data references in the loop or basic block.
3191
3192    The general structure of the analysis of data refs in the vectorizer is as
3193    follows:
3194    1- vect_analyze_data_refs(loop/bb): call
3195       compute_data_dependences_for_loop/bb to find and analyze all data-refs
3196       in the loop/bb and their dependences.
3197    2- vect_analyze_dependences(): apply dependence testing using ddrs.
3198    3- vect_analyze_drs_alignment(): check that ref_stmt.alignment is ok.
3199    4- vect_analyze_drs_access(): check that ref_stmt.step is ok.
3200
3201 */
3202
3203 bool
3204 vect_analyze_data_refs (loop_vec_info loop_vinfo,
3205                         bb_vec_info bb_vinfo,
3206                         int *min_vf, unsigned *n_stmts)
3207 {
3208   struct loop *loop = NULL;
3209   basic_block bb = NULL;
3210   unsigned int i;
3211   vec<data_reference_p> datarefs;
3212   struct data_reference *dr;
3213   tree scalar_type;
3214
3215   if (dump_enabled_p ())
3216     dump_printf_loc (MSG_NOTE, vect_location,
3217                      "=== vect_analyze_data_refs ===\n");
3218
3219   if (loop_vinfo)
3220     {
3221       basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
3222
3223       loop = LOOP_VINFO_LOOP (loop_vinfo);
3224       datarefs = LOOP_VINFO_DATAREFS (loop_vinfo);
3225       if (!find_loop_nest (loop, &LOOP_VINFO_LOOP_NEST (loop_vinfo)))
3226         {
3227           if (dump_enabled_p ())
3228             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
3229                              "not vectorized: loop contains function calls"
3230                              " or data references that cannot be analyzed\n");
3231           return false;
3232         }
3233
3234       for (i = 0; i < loop->num_nodes; i++)
3235         {
3236           gimple_stmt_iterator gsi;
3237
3238           for (gsi = gsi_start_bb (bbs[i]); !gsi_end_p (gsi); gsi_next (&gsi))
3239             {
3240               gimple stmt = gsi_stmt (gsi);
3241               if (is_gimple_debug (stmt))
3242                 continue;
3243               ++*n_stmts;
3244               if (!find_data_references_in_stmt (loop, stmt, &datarefs))
3245                 {
3246                   if (is_gimple_call (stmt) && loop->safelen)
3247                     {
3248                       tree fndecl = gimple_call_fndecl (stmt), op;
3249                       if (fndecl != NULL_TREE)
3250                         {
3251                           struct cgraph_node *node = cgraph_node::get (fndecl);
3252                           if (node != NULL && node->simd_clones != NULL)
3253                             {
3254                               unsigned int j, n = gimple_call_num_args (stmt);
3255                               for (j = 0; j < n; j++)
3256                                 {
3257                                   op = gimple_call_arg (stmt, j);
3258                                   if (DECL_P (op)
3259                                       || (REFERENCE_CLASS_P (op)
3260                                           && get_base_address (op)))
3261                                     break;
3262                                 }
3263                               op = gimple_call_lhs (stmt);
3264                               /* Ignore #pragma omp declare simd functions
3265                                  if they don't have data references in the
3266                                  call stmt itself.  */
3267                               if (j == n
3268                                   && !(op
3269                                        && (DECL_P (op)
3270                                            || (REFERENCE_CLASS_P (op)
3271                                                && get_base_address (op)))))
3272                                 continue;
3273                             }
3274                         }
3275                     }
3276                   LOOP_VINFO_DATAREFS (loop_vinfo) = datarefs;
3277                   if (dump_enabled_p ())
3278                     dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
3279                                      "not vectorized: loop contains function "
3280                                      "calls or data references that cannot "
3281                                      "be analyzed\n");
3282                   return false;
3283                 }
3284             }
3285         }
3286
3287       LOOP_VINFO_DATAREFS (loop_vinfo) = datarefs;
3288     }
3289   else
3290     {
3291       gimple_stmt_iterator gsi;
3292
3293       bb = BB_VINFO_BB (bb_vinfo);
3294       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
3295         {
3296           gimple stmt = gsi_stmt (gsi);
3297           if (is_gimple_debug (stmt))
3298             continue;
3299           ++*n_stmts;
3300           if (!find_data_references_in_stmt (NULL, stmt,
3301                                              &BB_VINFO_DATAREFS (bb_vinfo)))
3302             {
3303               /* Mark the rest of the basic-block as unvectorizable.  */
3304               for (; !gsi_end_p (gsi); gsi_next (&gsi))
3305                 {
3306                   stmt = gsi_stmt (gsi);
3307                   STMT_VINFO_VECTORIZABLE (vinfo_for_stmt (stmt)) = false;
3308                 }
3309               break;
3310             }
3311         }
3312
3313       datarefs = BB_VINFO_DATAREFS (bb_vinfo);
3314     }
3315
3316   /* Go through the data-refs, check that the analysis succeeded.  Update
3317      pointer from stmt_vec_info struct to DR and vectype.  */
3318
3319   FOR_EACH_VEC_ELT (datarefs, i, dr)
3320     {
3321       gimple stmt;
3322       stmt_vec_info stmt_info;
3323       tree base, offset, init;
3324       bool gather = false;
3325       bool simd_lane_access = false;
3326       int vf;
3327
3328 again:
3329       if (!dr || !DR_REF (dr))
3330         {
3331           if (dump_enabled_p ())
3332             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
3333                              "not vectorized: unhandled data-ref\n");
3334           return false;
3335         }
3336
3337       stmt = DR_STMT (dr);
3338       stmt_info = vinfo_for_stmt (stmt);
3339
3340       /* Discard clobbers from the dataref vector.  We will remove
3341          clobber stmts during vectorization.  */
3342       if (gimple_clobber_p (stmt))
3343         {
3344           free_data_ref (dr);
3345           if (i == datarefs.length () - 1)
3346             {
3347               datarefs.pop ();
3348               break;
3349             }
3350           datarefs.ordered_remove (i);
3351           dr = datarefs[i];
3352           goto again;
3353         }
3354
3355       /* Check that analysis of the data-ref succeeded.  */
3356       if (!DR_BASE_ADDRESS (dr) || !DR_OFFSET (dr) || !DR_INIT (dr)
3357           || !DR_STEP (dr))
3358         {
3359           bool maybe_gather
3360             = DR_IS_READ (dr)
3361               && !TREE_THIS_VOLATILE (DR_REF (dr))
3362               && targetm.vectorize.builtin_gather != NULL;
3363           bool maybe_simd_lane_access
3364             = loop_vinfo && loop->simduid;
3365
3366           /* If target supports vector gather loads, or if this might be
3367              a SIMD lane access, see if they can't be used.  */
3368           if (loop_vinfo
3369               && (maybe_gather || maybe_simd_lane_access)
3370               && !nested_in_vect_loop_p (loop, stmt))
3371             {
3372               struct data_reference *newdr
3373                 = create_data_ref (NULL, loop_containing_stmt (stmt),
3374                                    DR_REF (dr), stmt, true);
3375               gcc_assert (newdr != NULL && DR_REF (newdr));
3376               if (DR_BASE_ADDRESS (newdr)
3377                   && DR_OFFSET (newdr)
3378                   && DR_INIT (newdr)
3379                   && DR_STEP (newdr)
3380                   && integer_zerop (DR_STEP (newdr)))
3381                 {
3382                   if (maybe_simd_lane_access)
3383                     {
3384                       tree off = DR_OFFSET (newdr);
3385                       STRIP_NOPS (off);
3386                       if (TREE_CODE (DR_INIT (newdr)) == INTEGER_CST
3387                           && TREE_CODE (off) == MULT_EXPR
3388                           && tree_fits_uhwi_p (TREE_OPERAND (off, 1)))
3389                         {
3390                           tree step = TREE_OPERAND (off, 1);
3391                           off = TREE_OPERAND (off, 0);
3392                           STRIP_NOPS (off);
3393                           if (CONVERT_EXPR_P (off)
3394                               && TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (off,
3395                                                                           0)))
3396                                  < TYPE_PRECISION (TREE_TYPE (off)))
3397                             off = TREE_OPERAND (off, 0);
3398                           if (TREE_CODE (off) == SSA_NAME)
3399                             {
3400                               gimple def = SSA_NAME_DEF_STMT (off);
3401                               tree reft = TREE_TYPE (DR_REF (newdr));
3402                               if (is_gimple_call (def)
3403                                   && gimple_call_internal_p (def)
3404                                   && (gimple_call_internal_fn (def)
3405                                       == IFN_GOMP_SIMD_LANE))
3406                                 {
3407                                   tree arg = gimple_call_arg (def, 0);
3408                                   gcc_assert (TREE_CODE (arg) == SSA_NAME);
3409                                   arg = SSA_NAME_VAR (arg);
3410                                   if (arg == loop->simduid
3411                                       /* For now.  */
3412                                       && tree_int_cst_equal
3413                                            (TYPE_SIZE_UNIT (reft),
3414                                             step))
3415                                     {
3416                                       DR_OFFSET (newdr) = ssize_int (0);
3417                                       DR_STEP (newdr) = step;
3418                                       DR_ALIGNED_TO (newdr)
3419                                         = size_int (BIGGEST_ALIGNMENT);
3420                                       dr = newdr;
3421                                       simd_lane_access = true;
3422                                     }
3423                                 }
3424                             }
3425                         }
3426                     }
3427                   if (!simd_lane_access && maybe_gather)
3428                     {
3429                       dr = newdr;
3430                       gather = true;
3431                     }
3432                 }
3433               if (!gather && !simd_lane_access)
3434                 free_data_ref (newdr);
3435             }
3436
3437           if (!gather && !simd_lane_access)
3438             {
3439               if (dump_enabled_p ())
3440                 {
3441                   dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
3442                                    "not vectorized: data ref analysis "
3443                                    "failed ");
3444                   dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
3445                   dump_printf (MSG_MISSED_OPTIMIZATION, "\n");
3446                 }
3447
3448               if (bb_vinfo)
3449                 break;
3450
3451               return false;
3452             }
3453         }
3454
3455       if (TREE_CODE (DR_BASE_ADDRESS (dr)) == INTEGER_CST)
3456         {
3457           if (dump_enabled_p ())
3458             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
3459                              "not vectorized: base addr of dr is a "
3460                              "constant\n");
3461
3462           if (bb_vinfo)
3463             break;
3464
3465           if (gather || simd_lane_access)
3466             free_data_ref (dr);
3467           return false;
3468         }
3469
3470       if (TREE_THIS_VOLATILE (DR_REF (dr)))
3471         {
3472           if (dump_enabled_p ())
3473             {
3474               dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
3475                                "not vectorized: volatile type ");
3476               dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
3477               dump_printf (MSG_MISSED_OPTIMIZATION, "\n");
3478             }
3479
3480           if (bb_vinfo)
3481             break;
3482
3483           return false;
3484         }
3485
3486       if (stmt_can_throw_internal (stmt))
3487         {
3488           if (dump_enabled_p ())
3489             {
3490               dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
3491                                "not vectorized: statement can throw an "
3492                                "exception ");
3493               dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
3494               dump_printf (MSG_MISSED_OPTIMIZATION, "\n");
3495             }
3496
3497           if (bb_vinfo)
3498             break;
3499
3500           if (gather || simd_lane_access)
3501             free_data_ref (dr);
3502           return false;
3503         }
3504
3505       if (TREE_CODE (DR_REF (dr)) == COMPONENT_REF
3506           && DECL_BIT_FIELD (TREE_OPERAND (DR_REF (dr), 1)))
3507         {
3508           if (dump_enabled_p ())
3509             {
3510               dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
3511                                "not vectorized: statement is bitfield "
3512                                "access ");
3513               dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
3514               dump_printf (MSG_MISSED_OPTIMIZATION, "\n");
3515             }
3516
3517           if (bb_vinfo)
3518             break;
3519
3520           if (gather || simd_lane_access)
3521             free_data_ref (dr);
3522           return false;
3523         }
3524
3525       base = unshare_expr (DR_BASE_ADDRESS (dr));
3526       offset = unshare_expr (DR_OFFSET (dr));
3527       init = unshare_expr (DR_INIT (dr));
3528
3529       if (is_gimple_call (stmt)
3530           && (!gimple_call_internal_p (stmt)
3531               || (gimple_call_internal_fn (stmt) != IFN_MASK_LOAD
3532                   && gimple_call_internal_fn (stmt) != IFN_MASK_STORE)))
3533         {
3534           if (dump_enabled_p ())
3535             {
3536               dump_printf_loc (MSG_MISSED_OPTIMIZATION,  vect_location,
3537                                "not vectorized: dr in a call ");
3538               dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
3539               dump_printf (MSG_MISSED_OPTIMIZATION, "\n");
3540             }
3541
3542           if (bb_vinfo)
3543             break;
3544
3545           if (gather || simd_lane_access)
3546             free_data_ref (dr);
3547           return false;
3548         }
3549
3550       /* Update DR field in stmt_vec_info struct.  */
3551
3552       /* If the dataref is in an inner-loop of the loop that is considered for
3553          for vectorization, we also want to analyze the access relative to
3554          the outer-loop (DR contains information only relative to the
3555          inner-most enclosing loop).  We do that by building a reference to the
3556          first location accessed by the inner-loop, and analyze it relative to
3557          the outer-loop.  */
3558       if (loop && nested_in_vect_loop_p (loop, stmt))
3559         {
3560           tree outer_step, outer_base, outer_init;
3561           HOST_WIDE_INT pbitsize, pbitpos;
3562           tree poffset;
3563           machine_mode pmode;
3564           int punsignedp, pvolatilep;
3565           affine_iv base_iv, offset_iv;
3566           tree dinit;
3567
3568           /* Build a reference to the first location accessed by the
3569              inner-loop: *(BASE+INIT).  (The first location is actually
3570              BASE+INIT+OFFSET, but we add OFFSET separately later).  */
3571           tree inner_base = build_fold_indirect_ref
3572                                 (fold_build_pointer_plus (base, init));
3573
3574           if (dump_enabled_p ())
3575             {
3576               dump_printf_loc (MSG_NOTE, vect_location,
3577                                "analyze in outer-loop: ");
3578               dump_generic_expr (MSG_NOTE, TDF_SLIM, inner_base);
3579               dump_printf (MSG_NOTE, "\n");
3580             }
3581
3582           outer_base = get_inner_reference (inner_base, &pbitsize, &pbitpos,
3583                           &poffset, &pmode, &punsignedp, &pvolatilep, false);
3584           gcc_assert (outer_base != NULL_TREE);
3585
3586           if (pbitpos % BITS_PER_UNIT != 0)
3587             {
3588               if (dump_enabled_p ())
3589                 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
3590                                  "failed: bit offset alignment.\n");
3591               return false;
3592             }
3593
3594           outer_base = build_fold_addr_expr (outer_base);
3595           if (!simple_iv (loop, loop_containing_stmt (stmt), outer_base,
3596                           &base_iv, false))
3597             {
3598               if (dump_enabled_p ())
3599                 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
3600                                  "failed: evolution of base is not affine.\n");
3601               return false;
3602             }
3603
3604           if (offset)
3605             {
3606               if (poffset)
3607                 poffset = fold_build2 (PLUS_EXPR, TREE_TYPE (offset), offset,
3608                                        poffset);
3609               else
3610                 poffset = offset;
3611             }
3612
3613           if (!poffset)
3614             {
3615               offset_iv.base = ssize_int (0);
3616               offset_iv.step = ssize_int (0);
3617             }
3618           else if (!simple_iv (loop, loop_containing_stmt (stmt), poffset,
3619                                &offset_iv, false))
3620             {
3621               if (dump_enabled_p ())
3622                 dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
3623                                  "evolution of offset is not affine.\n");
3624               return false;
3625             }
3626
3627           outer_init = ssize_int (pbitpos / BITS_PER_UNIT);
3628           split_constant_offset (base_iv.base, &base_iv.base, &dinit);
3629           outer_init =  size_binop (PLUS_EXPR, outer_init, dinit);
3630           split_constant_offset (offset_iv.base, &offset_iv.base, &dinit);
3631           outer_init =  size_binop (PLUS_EXPR, outer_init, dinit);
3632
3633           outer_step = size_binop (PLUS_EXPR,
3634                                 fold_convert (ssizetype, base_iv.step),
3635                                 fold_convert (ssizetype, offset_iv.step));
3636
3637           STMT_VINFO_DR_STEP (stmt_info) = outer_step;
3638           /* FIXME: Use canonicalize_base_object_address (base_iv.base); */
3639           STMT_VINFO_DR_BASE_ADDRESS (stmt_info) = base_iv.base;
3640           STMT_VINFO_DR_INIT (stmt_info) = outer_init;
3641           STMT_VINFO_DR_OFFSET (stmt_info) =
3642                                 fold_convert (ssizetype, offset_iv.base);
3643           STMT_VINFO_DR_ALIGNED_TO (stmt_info) =
3644                                 size_int (highest_pow2_factor (offset_iv.base));
3645
3646           if (dump_enabled_p ())
3647             {
3648               dump_printf_loc (MSG_NOTE, vect_location,
3649                                "\touter base_address: ");
3650               dump_generic_expr (MSG_NOTE, TDF_SLIM,
3651                                  STMT_VINFO_DR_BASE_ADDRESS (stmt_info));
3652               dump_printf (MSG_NOTE, "\n\touter offset from base address: ");
3653               dump_generic_expr (MSG_NOTE, TDF_SLIM,
3654                                  STMT_VINFO_DR_OFFSET (stmt_info));
3655               dump_printf (MSG_NOTE,
3656                            "\n\touter constant offset from base address: ");
3657               dump_generic_expr (MSG_NOTE, TDF_SLIM,
3658                                  STMT_VINFO_DR_INIT (stmt_info));
3659               dump_printf (MSG_NOTE, "\n\touter step: ");
3660               dump_generic_expr (MSG_NOTE, TDF_SLIM,
3661                                  STMT_VINFO_DR_STEP (stmt_info));
3662               dump_printf (MSG_NOTE, "\n\touter aligned to: ");
3663               dump_generic_expr (MSG_NOTE, TDF_SLIM,
3664                                  STMT_VINFO_DR_ALIGNED_TO (stmt_info));
3665               dump_printf (MSG_NOTE, "\n");
3666             }
3667         }
3668
3669       if (STMT_VINFO_DATA_REF (stmt_info))
3670         {
3671           if (dump_enabled_p ())
3672             {
3673               dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
3674                                "not vectorized: more than one data ref "
3675                                "in stmt: ");
3676               dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
3677               dump_printf (MSG_MISSED_OPTIMIZATION, "\n");
3678             }
3679
3680           if (bb_vinfo)
3681             break;
3682
3683           if (gather || simd_lane_access)
3684             free_data_ref (dr);
3685           return false;
3686         }
3687
3688       STMT_VINFO_DATA_REF (stmt_info) = dr;
3689       if (simd_lane_access)
3690         {
3691           STMT_VINFO_SIMD_LANE_ACCESS_P (stmt_info) = true;
3692           free_data_ref (datarefs[i]);
3693           datarefs[i] = dr;
3694         }
3695
3696       /* Set vectype for STMT.  */
3697       scalar_type = TREE_TYPE (DR_REF (dr));
3698       STMT_VINFO_VECTYPE (stmt_info)
3699         = get_vectype_for_scalar_type (scalar_type);
3700       if (!STMT_VINFO_VECTYPE (stmt_info))
3701         {
3702           if (dump_enabled_p ())
3703             {
3704               dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
3705                                "not vectorized: no vectype for stmt: ");
3706               dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
3707               dump_printf (MSG_MISSED_OPTIMIZATION, " scalar_type: ");
3708               dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_DETAILS,
3709                                  scalar_type);
3710               dump_printf (MSG_MISSED_OPTIMIZATION, "\n");
3711             }
3712
3713           if (bb_vinfo)
3714             break;
3715
3716           if (gather || simd_lane_access)
3717             {
3718               STMT_VINFO_DATA_REF (stmt_info) = NULL;
3719               if (gather)
3720                 free_data_ref (dr);
3721             }
3722           return false;
3723         }
3724       else
3725         {
3726           if (dump_enabled_p ())
3727             {
3728               dump_printf_loc (MSG_NOTE, vect_location,
3729                                "got vectype for stmt: ");
3730               dump_gimple_stmt (MSG_NOTE, TDF_SLIM, stmt, 0);
3731               dump_generic_expr (MSG_NOTE, TDF_SLIM,
3732                                  STMT_VINFO_VECTYPE (stmt_info));
3733               dump_printf (MSG_NOTE, "\n");
3734             }
3735         }
3736
3737       /* Adjust the minimal vectorization factor according to the
3738          vector type.  */
3739       vf = TYPE_VECTOR_SUBPARTS (STMT_VINFO_VECTYPE (stmt_info));
3740       if (vf > *min_vf)
3741         *min_vf = vf;
3742
3743       if (gather)
3744         {
3745           tree off;
3746
3747           gather = 0 != vect_check_gather (stmt, loop_vinfo, NULL, &off, NULL);
3748           if (gather
3749               && get_vectype_for_scalar_type (TREE_TYPE (off)) == NULL_TREE)
3750             gather = false;
3751           if (!gather)
3752             {
3753               STMT_VINFO_DATA_REF (stmt_info) = NULL;
3754               free_data_ref (dr);
3755               if (dump_enabled_p ())
3756                 {
3757                   dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 
3758                                    "not vectorized: not suitable for gather "
3759                                    "load ");
3760                   dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
3761                   dump_printf (MSG_MISSED_OPTIMIZATION, "\n");
3762                 }
3763               return false;
3764             }
3765
3766           datarefs[i] = dr;
3767           STMT_VINFO_GATHER_P (stmt_info) = true;
3768         }
3769       else if (loop_vinfo
3770                && TREE_CODE (DR_STEP (dr)) != INTEGER_CST)
3771         {
3772           if (nested_in_vect_loop_p (loop, stmt)
3773               || !DR_IS_READ (dr))
3774             {
3775               if (dump_enabled_p ())
3776                 {
3777                   dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, 
3778                                    "not vectorized: not suitable for strided "
3779                                    "load ");
3780                   dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
3781                   dump_printf (MSG_MISSED_OPTIMIZATION, "\n");
3782                 }
3783               return false;
3784             }
3785           STMT_VINFO_STRIDE_LOAD_P (stmt_info) = true;
3786         }
3787     }
3788
3789   /* If we stopped analysis at the first dataref we could not analyze
3790      when trying to vectorize a basic-block mark the rest of the datarefs
3791      as not vectorizable and truncate the vector of datarefs.  That
3792      avoids spending useless time in analyzing their dependence.  */
3793   if (i != datarefs.length ())
3794     {
3795       gcc_assert (bb_vinfo != NULL);
3796       for (unsigned j = i; j < datarefs.length (); ++j)
3797         {
3798           data_reference_p dr = datarefs[j];
3799           STMT_VINFO_VECTORIZABLE (vinfo_for_stmt (DR_STMT (dr))) = false;
3800           free_data_ref (dr);
3801         }
3802       datarefs.truncate (i);
3803     }
3804
3805   return true;
3806 }
3807
3808
3809 /* Function vect_get_new_vect_var.
3810
3811    Returns a name for a new variable.  The current naming scheme appends the
3812    prefix "vect_" or "vect_p" (depending on the value of VAR_KIND) to
3813    the name of vectorizer generated variables, and appends that to NAME if
3814    provided.  */
3815
3816 tree
3817 vect_get_new_vect_var (tree type, enum vect_var_kind var_kind, const char *name)
3818 {
3819   const char *prefix;
3820   tree new_vect_var;
3821
3822   switch (var_kind)
3823   {
3824   case vect_simple_var:
3825     prefix = "vect";
3826     break;
3827   case vect_scalar_var:
3828     prefix = "stmp";
3829     break;
3830   case vect_pointer_var:
3831     prefix = "vectp";
3832     break;
3833   default:
3834     gcc_unreachable ();
3835   }
3836
3837   if (name)
3838     {
3839       char* tmp = concat (prefix, "_", name, NULL);
3840       new_vect_var = create_tmp_reg (type, tmp);
3841       free (tmp);
3842     }
3843   else
3844     new_vect_var = create_tmp_reg (type, prefix);
3845
3846   return new_vect_var;
3847 }
3848
3849
3850 /* Function vect_create_addr_base_for_vector_ref.
3851
3852    Create an expression that computes the address of the first memory location
3853    that will be accessed for a data reference.
3854
3855    Input:
3856    STMT: The statement containing the data reference.
3857    NEW_STMT_LIST: Must be initialized to NULL_TREE or a statement list.
3858    OFFSET: Optional. If supplied, it is be added to the initial address.
3859    LOOP:    Specify relative to which loop-nest should the address be computed.
3860             For example, when the dataref is in an inner-loop nested in an
3861             outer-loop that is now being vectorized, LOOP can be either the
3862             outer-loop, or the inner-loop.  The first memory location accessed
3863             by the following dataref ('in' points to short):
3864
3865                 for (i=0; i<N; i++)
3866                    for (j=0; j<M; j++)
3867                      s += in[i+j]
3868
3869             is as follows:
3870             if LOOP=i_loop:     &in             (relative to i_loop)
3871             if LOOP=j_loop:     &in+i*2B        (relative to j_loop)
3872    BYTE_OFFSET: Optional, defaulted to NULL.  If supplied, it is added to the
3873             initial address.  Unlike OFFSET, which is number of elements to
3874             be added, BYTE_OFFSET is measured in bytes.
3875
3876    Output:
3877    1. Return an SSA_NAME whose value is the address of the memory location of
3878       the first vector of the data reference.
3879    2. If new_stmt_list is not NULL_TREE after return then the caller must insert
3880       these statement(s) which define the returned SSA_NAME.
3881
3882    FORNOW: We are only handling array accesses with step 1.  */
3883
3884 tree
3885 vect_create_addr_base_for_vector_ref (gimple stmt,
3886                                       gimple_seq *new_stmt_list,
3887                                       tree offset,
3888                                       struct loop *loop,
3889                                       tree byte_offset)
3890 {
3891   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
3892   struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
3893   tree data_ref_base;
3894   const char *base_name;
3895   tree addr_base;
3896   tree dest;
3897   gimple_seq seq = NULL;
3898   tree base_offset;
3899   tree init;
3900   tree vect_ptr_type;
3901   tree step = TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (dr)));
3902   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
3903
3904   if (loop_vinfo && loop && loop != (gimple_bb (stmt))->loop_father)
3905     {
3906       struct loop *outer_loop = LOOP_VINFO_LOOP (loop_vinfo);
3907
3908       gcc_assert (nested_in_vect_loop_p (outer_loop, stmt));
3909
3910       data_ref_base = unshare_expr (STMT_VINFO_DR_BASE_ADDRESS (stmt_info));
3911       base_offset = unshare_expr (STMT_VINFO_DR_OFFSET (stmt_info));
3912       init = unshare_expr (STMT_VINFO_DR_INIT (stmt_info));
3913     }
3914   else
3915     {
3916       data_ref_base = unshare_expr (DR_BASE_ADDRESS (dr));
3917       base_offset = unshare_expr (DR_OFFSET (dr));
3918       init = unshare_expr (DR_INIT (dr));
3919     }
3920
3921   if (loop_vinfo)
3922     base_name = get_name (data_ref_base);
3923   else
3924     {
3925       base_offset = ssize_int (0);
3926       init = ssize_int (0);
3927       base_name = get_name (DR_REF (dr));
3928     }
3929
3930   /* Create base_offset */
3931   base_offset = size_binop (PLUS_EXPR,
3932                             fold_convert (sizetype, base_offset),
3933                             fold_convert (sizetype, init));
3934
3935   if (offset)
3936     {
3937       offset = fold_build2 (MULT_EXPR, sizetype,
3938                             fold_convert (sizetype, offset), step);
3939       base_offset = fold_build2 (PLUS_EXPR, sizetype,
3940                                  base_offset, offset);
3941     }
3942   if (byte_offset)
3943     {
3944       byte_offset = fold_convert (sizetype, byte_offset);
3945       base_offset = fold_build2 (PLUS_EXPR, sizetype,
3946                                  base_offset, byte_offset);
3947     }
3948
3949   /* base + base_offset */
3950   if (loop_vinfo)
3951     addr_base = fold_build_pointer_plus (data_ref_base, base_offset);
3952   else
3953     {
3954       addr_base = build1 (ADDR_EXPR,
3955                           build_pointer_type (TREE_TYPE (DR_REF (dr))),
3956                           unshare_expr (DR_REF (dr)));
3957     }
3958
3959   vect_ptr_type = build_pointer_type (STMT_VINFO_VECTYPE (stmt_info));
3960   addr_base = fold_convert (vect_ptr_type, addr_base);
3961   dest = vect_get_new_vect_var (vect_ptr_type, vect_pointer_var, base_name);
3962   addr_base = force_gimple_operand (addr_base, &seq, false, dest);
3963   gimple_seq_add_seq (new_stmt_list, seq);
3964
3965   if (DR_PTR_INFO (dr)
3966       && TREE_CODE (addr_base) == SSA_NAME)
3967     {
3968       duplicate_ssa_name_ptr_info (addr_base, DR_PTR_INFO (dr));
3969       unsigned int align = TYPE_ALIGN_UNIT (STMT_VINFO_VECTYPE (stmt_info));
3970       int misalign = DR_MISALIGNMENT (dr);
3971       if (offset || byte_offset || (misalign == -1))
3972         mark_ptr_info_alignment_unknown (SSA_NAME_PTR_INFO (addr_base));
3973       else
3974         set_ptr_info_alignment (SSA_NAME_PTR_INFO (addr_base), align, misalign);
3975     }
3976
3977   if (dump_enabled_p ())
3978     {
3979       dump_printf_loc (MSG_NOTE, vect_location, "created ");
3980       dump_generic_expr (MSG_NOTE, TDF_SLIM, addr_base);
3981       dump_printf (MSG_NOTE, "\n");
3982     }
3983
3984   return addr_base;
3985 }
3986
3987
3988 /* Function vect_create_data_ref_ptr.
3989
3990    Create a new pointer-to-AGGR_TYPE variable (ap), that points to the first
3991    location accessed in the loop by STMT, along with the def-use update
3992    chain to appropriately advance the pointer through the loop iterations.
3993    Also set aliasing information for the pointer.  This pointer is used by
3994    the callers to this function to create a memory reference expression for
3995    vector load/store access.
3996
3997    Input:
3998    1. STMT: a stmt that references memory. Expected to be of the form
3999          GIMPLE_ASSIGN <name, data-ref> or
4000          GIMPLE_ASSIGN <data-ref, name>.
4001    2. AGGR_TYPE: the type of the reference, which should be either a vector
4002         or an array.
4003    3. AT_LOOP: the loop where the vector memref is to be created.
4004    4. OFFSET (optional): an offset to be added to the initial address accessed
4005         by the data-ref in STMT.
4006    5. BSI: location where the new stmts are to be placed if there is no loop
4007    6. ONLY_INIT: indicate if ap is to be updated in the loop, or remain
4008         pointing to the initial address.
4009    7. BYTE_OFFSET (optional, defaults to NULL): a byte offset to be added
4010         to the initial address accessed by the data-ref in STMT.  This is
4011         similar to OFFSET, but OFFSET is counted in elements, while BYTE_OFFSET
4012         in bytes.
4013
4014    Output:
4015    1. Declare a new ptr to vector_type, and have it point to the base of the
4016       data reference (initial addressed accessed by the data reference).
4017       For example, for vector of type V8HI, the following code is generated:
4018
4019       v8hi *ap;
4020       ap = (v8hi *)initial_address;
4021
4022       if OFFSET is not supplied:
4023          initial_address = &a[init];
4024       if OFFSET is supplied:
4025          initial_address = &a[init + OFFSET];
4026       if BYTE_OFFSET is supplied:
4027          initial_address = &a[init] + BYTE_OFFSET;
4028
4029       Return the initial_address in INITIAL_ADDRESS.
4030
4031    2. If ONLY_INIT is true, just return the initial pointer.  Otherwise, also
4032       update the pointer in each iteration of the loop.
4033
4034       Return the increment stmt that updates the pointer in PTR_INCR.
4035
4036    3. Set INV_P to true if the access pattern of the data reference in the
4037       vectorized loop is invariant.  Set it to false otherwise.
4038
4039    4. Return the pointer.  */
4040
4041 tree
4042 vect_create_data_ref_ptr (gimple stmt, tree aggr_type, struct loop *at_loop,
4043                           tree offset, tree *initial_address,
4044                           gimple_stmt_iterator *gsi, gimple *ptr_incr,
4045                           bool only_init, bool *inv_p, tree byte_offset)
4046 {
4047   const char *base_name;
4048   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
4049   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
4050   struct loop *loop = NULL;
4051   bool nested_in_vect_loop = false;
4052   struct loop *containing_loop = NULL;
4053   tree aggr_ptr_type;
4054   tree aggr_ptr;
4055   tree new_temp;
4056   gimple vec_stmt;
4057   gimple_seq new_stmt_list = NULL;
4058   edge pe = NULL;
4059   basic_block new_bb;
4060   tree aggr_ptr_init;
4061   struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
4062   tree aptr;
4063   gimple_stmt_iterator incr_gsi;
4064   bool insert_after;
4065   tree indx_before_incr, indx_after_incr;
4066   gimple incr;
4067   tree step;
4068   bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info);
4069
4070   gcc_assert (TREE_CODE (aggr_type) == ARRAY_TYPE
4071               || TREE_CODE (aggr_type) == VECTOR_TYPE);
4072
4073   if (loop_vinfo)
4074     {
4075       loop = LOOP_VINFO_LOOP (loop_vinfo);
4076       nested_in_vect_loop = nested_in_vect_loop_p (loop, stmt);
4077       containing_loop = (gimple_bb (stmt))->loop_father;
4078       pe = loop_preheader_edge (loop);
4079     }
4080   else
4081     {
4082       gcc_assert (bb_vinfo);
4083       only_init = true;
4084       *ptr_incr = NULL;
4085     }
4086
4087   /* Check the step (evolution) of the load in LOOP, and record
4088      whether it's invariant.  */
4089   if (nested_in_vect_loop)
4090     step = STMT_VINFO_DR_STEP (stmt_info);
4091   else
4092     step = DR_STEP (STMT_VINFO_DATA_REF (stmt_info));
4093
4094   if (integer_zerop (step))
4095     *inv_p = true;
4096   else
4097     *inv_p = false;
4098
4099   /* Create an expression for the first address accessed by this load
4100      in LOOP.  */
4101   base_name = get_name (DR_BASE_ADDRESS (dr));
4102
4103   if (dump_enabled_p ())
4104     {
4105       tree dr_base_type = TREE_TYPE (DR_BASE_OBJECT (dr));
4106       dump_printf_loc (MSG_NOTE, vect_location,
4107                        "create %s-pointer variable to type: ",
4108                        get_tree_code_name (TREE_CODE (aggr_type)));
4109       dump_generic_expr (MSG_NOTE, TDF_SLIM, aggr_type);
4110       if (TREE_CODE (dr_base_type) == ARRAY_TYPE)
4111         dump_printf (MSG_NOTE, "  vectorizing an array ref: ");
4112       else if (TREE_CODE (dr_base_type) == VECTOR_TYPE)
4113         dump_printf (MSG_NOTE, "  vectorizing a vector ref: ");
4114       else if (TREE_CODE (dr_base_type) == RECORD_TYPE)
4115         dump_printf (MSG_NOTE, "  vectorizing a record based array ref: ");
4116       else
4117         dump_printf (MSG_NOTE, "  vectorizing a pointer ref: ");
4118       dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_BASE_OBJECT (dr));
4119       dump_printf (MSG_NOTE, "\n");
4120     }
4121
4122   /* (1) Create the new aggregate-pointer variable.
4123      Vector and array types inherit the alias set of their component
4124      type by default so we need to use a ref-all pointer if the data
4125      reference does not conflict with the created aggregated data
4126      reference because it is not addressable.  */
4127   bool need_ref_all = false;
4128   if (!alias_sets_conflict_p (get_alias_set (aggr_type),
4129                               get_alias_set (DR_REF (dr))))
4130     need_ref_all = true;
4131   /* Likewise for any of the data references in the stmt group.  */
4132   else if (STMT_VINFO_GROUP_SIZE (stmt_info) > 1)
4133     {
4134       gimple orig_stmt = STMT_VINFO_GROUP_FIRST_ELEMENT (stmt_info);
4135       do
4136         {
4137           stmt_vec_info sinfo = vinfo_for_stmt (orig_stmt);
4138           struct data_reference *sdr = STMT_VINFO_DATA_REF (sinfo);
4139           if (!alias_sets_conflict_p (get_alias_set (aggr_type),
4140                                       get_alias_set (DR_REF (sdr))))
4141             {
4142               need_ref_all = true;
4143               break;
4144             }
4145           orig_stmt = STMT_VINFO_GROUP_NEXT_ELEMENT (sinfo);
4146         }
4147       while (orig_stmt);
4148     }
4149   aggr_ptr_type = build_pointer_type_for_mode (aggr_type, ptr_mode,
4150                                                need_ref_all);
4151   aggr_ptr = vect_get_new_vect_var (aggr_ptr_type, vect_pointer_var, base_name);
4152
4153
4154   /* Note: If the dataref is in an inner-loop nested in LOOP, and we are
4155      vectorizing LOOP (i.e., outer-loop vectorization), we need to create two
4156      def-use update cycles for the pointer: one relative to the outer-loop
4157      (LOOP), which is what steps (3) and (4) below do.  The other is relative
4158      to the inner-loop (which is the inner-most loop containing the dataref),
4159      and this is done be step (5) below.
4160
4161      When vectorizing inner-most loops, the vectorized loop (LOOP) is also the
4162      inner-most loop, and so steps (3),(4) work the same, and step (5) is
4163      redundant.  Steps (3),(4) create the following:
4164
4165         vp0 = &base_addr;
4166         LOOP:   vp1 = phi(vp0,vp2)
4167                 ...
4168                 ...
4169                 vp2 = vp1 + step
4170                 goto LOOP
4171
4172      If there is an inner-loop nested in loop, then step (5) will also be
4173      applied, and an additional update in the inner-loop will be created:
4174
4175         vp0 = &base_addr;
4176         LOOP:   vp1 = phi(vp0,vp2)
4177                 ...
4178         inner:     vp3 = phi(vp1,vp4)
4179                    vp4 = vp3 + inner_step
4180                    if () goto inner
4181                 ...
4182                 vp2 = vp1 + step
4183                 if () goto LOOP   */
4184
4185   /* (2) Calculate the initial address of the aggregate-pointer, and set
4186      the aggregate-pointer to point to it before the loop.  */
4187
4188   /* Create: (&(base[init_val+offset]+byte_offset) in the loop preheader.  */
4189
4190   new_temp = vect_create_addr_base_for_vector_ref (stmt, &new_stmt_list,
4191                                                    offset, loop, byte_offset);
4192   if (new_stmt_list)
4193     {
4194       if (pe)
4195         {
4196           new_bb = gsi_insert_seq_on_edge_immediate (pe, new_stmt_list);
4197           gcc_assert (!new_bb);
4198         }
4199       else
4200         gsi_insert_seq_before (gsi, new_stmt_list, GSI_SAME_STMT);
4201     }
4202
4203   *initial_address = new_temp;
4204
4205   /* Create: p = (aggr_type *) initial_base  */
4206   if (TREE_CODE (new_temp) != SSA_NAME
4207       || !useless_type_conversion_p (aggr_ptr_type, TREE_TYPE (new_temp)))
4208     {
4209       vec_stmt = gimple_build_assign (aggr_ptr,
4210                                       fold_convert (aggr_ptr_type, new_temp));
4211       aggr_ptr_init = make_ssa_name (aggr_ptr, vec_stmt);
4212       /* Copy the points-to information if it exists. */
4213       if (DR_PTR_INFO (dr))
4214         duplicate_ssa_name_ptr_info (aggr_ptr_init, DR_PTR_INFO (dr));
4215       gimple_assign_set_lhs (vec_stmt, aggr_ptr_init);
4216       if (pe)
4217         {
4218           new_bb = gsi_insert_on_edge_immediate (pe, vec_stmt);
4219           gcc_assert (!new_bb);
4220         }
4221       else
4222         gsi_insert_before (gsi, vec_stmt, GSI_SAME_STMT);
4223     }
4224   else
4225     aggr_ptr_init = new_temp;
4226
4227   /* (3) Handle the updating of the aggregate-pointer inside the loop.
4228      This is needed when ONLY_INIT is false, and also when AT_LOOP is the
4229      inner-loop nested in LOOP (during outer-loop vectorization).  */
4230
4231   /* No update in loop is required.  */
4232   if (only_init && (!loop_vinfo || at_loop == loop))
4233     aptr = aggr_ptr_init;
4234   else
4235     {
4236       /* The step of the aggregate pointer is the type size.  */
4237       tree iv_step = TYPE_SIZE_UNIT (aggr_type);
4238       /* One exception to the above is when the scalar step of the load in
4239          LOOP is zero. In this case the step here is also zero.  */
4240       if (*inv_p)
4241         iv_step = size_zero_node;
4242       else if (tree_int_cst_sgn (step) == -1)
4243         iv_step = fold_build1 (NEGATE_EXPR, TREE_TYPE (iv_step), iv_step);
4244
4245       standard_iv_increment_position (loop, &incr_gsi, &insert_after);
4246
4247       create_iv (aggr_ptr_init,
4248                  fold_convert (aggr_ptr_type, iv_step),
4249                  aggr_ptr, loop, &incr_gsi, insert_after,
4250                  &indx_before_incr, &indx_after_incr);
4251       incr = gsi_stmt (incr_gsi);
4252       set_vinfo_for_stmt (incr, new_stmt_vec_info (incr, loop_vinfo, NULL));
4253
4254       /* Copy the points-to information if it exists. */
4255       if (DR_PTR_INFO (dr))
4256         {
4257           duplicate_ssa_name_ptr_info (indx_before_incr, DR_PTR_INFO (dr));
4258           duplicate_ssa_name_ptr_info (indx_after_incr, DR_PTR_INFO (dr));
4259         }
4260       if (ptr_incr)
4261         *ptr_incr = incr;
4262
4263       aptr = indx_before_incr;
4264     }
4265
4266   if (!nested_in_vect_loop || only_init)
4267     return aptr;
4268
4269
4270   /* (4) Handle the updating of the aggregate-pointer inside the inner-loop
4271      nested in LOOP, if exists.  */
4272
4273   gcc_assert (nested_in_vect_loop);
4274   if (!only_init)
4275     {
4276       standard_iv_increment_position (containing_loop, &incr_gsi,
4277                                       &insert_after);
4278       create_iv (aptr, fold_convert (aggr_ptr_type, DR_STEP (dr)), aggr_ptr,
4279                  containing_loop, &incr_gsi, insert_after, &indx_before_incr,
4280                  &indx_after_incr);
4281       incr = gsi_stmt (incr_gsi);
4282       set_vinfo_for_stmt (incr, new_stmt_vec_info (incr, loop_vinfo, NULL));
4283
4284       /* Copy the points-to information if it exists. */
4285       if (DR_PTR_INFO (dr))
4286         {
4287           duplicate_ssa_name_ptr_info (indx_before_incr, DR_PTR_INFO (dr));
4288           duplicate_ssa_name_ptr_info (indx_after_incr, DR_PTR_INFO (dr));
4289         }
4290       if (ptr_incr)
4291         *ptr_incr = incr;
4292
4293       return indx_before_incr;
4294     }
4295   else
4296     gcc_unreachable ();
4297 }
4298
4299
4300 /* Function bump_vector_ptr
4301
4302    Increment a pointer (to a vector type) by vector-size. If requested,
4303    i.e. if PTR-INCR is given, then also connect the new increment stmt
4304    to the existing def-use update-chain of the pointer, by modifying
4305    the PTR_INCR as illustrated below:
4306
4307    The pointer def-use update-chain before this function:
4308                         DATAREF_PTR = phi (p_0, p_2)
4309                         ....
4310         PTR_INCR:       p_2 = DATAREF_PTR + step
4311
4312    The pointer def-use update-chain after this function:
4313                         DATAREF_PTR = phi (p_0, p_2)
4314                         ....
4315                         NEW_DATAREF_PTR = DATAREF_PTR + BUMP
4316                         ....
4317         PTR_INCR:       p_2 = NEW_DATAREF_PTR + step
4318
4319    Input:
4320    DATAREF_PTR - ssa_name of a pointer (to vector type) that is being updated
4321                  in the loop.
4322    PTR_INCR - optional. The stmt that updates the pointer in each iteration of
4323               the loop.  The increment amount across iterations is expected
4324               to be vector_size.
4325    BSI - location where the new update stmt is to be placed.
4326    STMT - the original scalar memory-access stmt that is being vectorized.
4327    BUMP - optional. The offset by which to bump the pointer. If not given,
4328           the offset is assumed to be vector_size.
4329
4330    Output: Return NEW_DATAREF_PTR as illustrated above.
4331
4332 */
4333
4334 tree
4335 bump_vector_ptr (tree dataref_ptr, gimple ptr_incr, gimple_stmt_iterator *gsi,
4336                  gimple stmt, tree bump)
4337 {
4338   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
4339   struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
4340   tree vectype = STMT_VINFO_VECTYPE (stmt_info);
4341   tree update = TYPE_SIZE_UNIT (vectype);
4342   gimple incr_stmt;
4343   ssa_op_iter iter;
4344   use_operand_p use_p;
4345   tree new_dataref_ptr;
4346
4347   if (bump)
4348     update = bump;
4349
4350   new_dataref_ptr = copy_ssa_name (dataref_ptr, NULL);
4351   incr_stmt = gimple_build_assign_with_ops (POINTER_PLUS_EXPR, new_dataref_ptr,
4352                                             dataref_ptr, update);
4353   vect_finish_stmt_generation (stmt, incr_stmt, gsi);
4354
4355   /* Copy the points-to information if it exists. */
4356   if (DR_PTR_INFO (dr))
4357     {
4358       duplicate_ssa_name_ptr_info (new_dataref_ptr, DR_PTR_INFO (dr));
4359       mark_ptr_info_alignment_unknown (SSA_NAME_PTR_INFO (new_dataref_ptr));
4360     }
4361
4362   if (!ptr_incr)
4363     return new_dataref_ptr;
4364
4365   /* Update the vector-pointer's cross-iteration increment.  */
4366   FOR_EACH_SSA_USE_OPERAND (use_p, ptr_incr, iter, SSA_OP_USE)
4367     {
4368       tree use = USE_FROM_PTR (use_p);
4369
4370       if (use == dataref_ptr)
4371         SET_USE (use_p, new_dataref_ptr);
4372       else
4373         gcc_assert (tree_int_cst_compare (use, update) == 0);
4374     }
4375
4376   return new_dataref_ptr;
4377 }
4378
4379
4380 /* Function vect_create_destination_var.
4381
4382    Create a new temporary of type VECTYPE.  */
4383
4384 tree
4385 vect_create_destination_var (tree scalar_dest, tree vectype)
4386 {
4387   tree vec_dest;
4388   const char *name;
4389   char *new_name;
4390   tree type;
4391   enum vect_var_kind kind;
4392
4393   kind = vectype ? vect_simple_var : vect_scalar_var;
4394   type = vectype ? vectype : TREE_TYPE (scalar_dest);
4395
4396   gcc_assert (TREE_CODE (scalar_dest) == SSA_NAME);
4397
4398   name = get_name (scalar_dest);
4399   if (name)
4400     asprintf (&new_name, "%s_%u", name, SSA_NAME_VERSION (scalar_dest));
4401   else
4402     asprintf (&new_name, "_%u", SSA_NAME_VERSION (scalar_dest));
4403   vec_dest = vect_get_new_vect_var (type, kind, new_name);
4404   free (new_name);
4405
4406   return vec_dest;
4407 }
4408
4409 /* Function vect_grouped_store_supported.
4410
4411    Returns TRUE if interleave high and interleave low permutations
4412    are supported, and FALSE otherwise.  */
4413
4414 bool
4415 vect_grouped_store_supported (tree vectype, unsigned HOST_WIDE_INT count)
4416 {
4417   machine_mode mode = TYPE_MODE (vectype);
4418
4419   /* vect_permute_store_chain requires the group size to be equal to 3 or
4420      be a power of two.  */
4421   if (count != 3 && exact_log2 (count) == -1)
4422     {
4423       if (dump_enabled_p ())
4424         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
4425                          "the size of the group of accesses"
4426                          " is not a power of 2 or not eqaul to 3\n");
4427       return false;
4428     }
4429
4430   /* Check that the permutation is supported.  */
4431   if (VECTOR_MODE_P (mode))
4432     {
4433       unsigned int i, nelt = GET_MODE_NUNITS (mode);
4434       unsigned char *sel = XALLOCAVEC (unsigned char, nelt);
4435
4436       if (count == 3)
4437         {
4438           unsigned int j0 = 0, j1 = 0, j2 = 0;
4439           unsigned int i, j;
4440
4441           for (j = 0; j < 3; j++)
4442             {
4443               int nelt0 = ((3 - j) * nelt) % 3;
4444               int nelt1 = ((3 - j) * nelt + 1) % 3;
4445               int nelt2 = ((3 - j) * nelt + 2) % 3;
4446               for (i = 0; i < nelt; i++)
4447                 {
4448                   if (3 * i + nelt0 < nelt)
4449                     sel[3 * i + nelt0] = j0++;
4450                   if (3 * i + nelt1 < nelt)
4451                     sel[3 * i + nelt1] = nelt + j1++;
4452                   if (3 * i + nelt2 < nelt)
4453                     sel[3 * i + nelt2] = 0;
4454                 }
4455               if (!can_vec_perm_p (mode, false, sel))
4456                 {
4457                   if (dump_enabled_p ())
4458                     dump_printf (MSG_MISSED_OPTIMIZATION,
4459                                  "permutaion op not supported by target.\n");
4460                   return false;
4461                 }
4462
4463               for (i = 0; i < nelt; i++)
4464                 {
4465                   if (3 * i + nelt0 < nelt)
4466                     sel[3 * i + nelt0] = 3 * i + nelt0;
4467                   if (3 * i + nelt1 < nelt)
4468                     sel[3 * i + nelt1] = 3 * i + nelt1;
4469                   if (3 * i + nelt2 < nelt)
4470                     sel[3 * i + nelt2] = nelt + j2++;
4471                 }
4472               if (!can_vec_perm_p (mode, false, sel))
4473                 {
4474                   if (dump_enabled_p ())
4475                     dump_printf (MSG_MISSED_OPTIMIZATION,
4476                                  "permutaion op not supported by target.\n");
4477                   return false;
4478                 }
4479             }
4480           return true;
4481         }
4482       else
4483         {
4484           /* If length is not equal to 3 then only power of 2 is supported.  */
4485           gcc_assert (exact_log2 (count) != -1);
4486
4487           for (i = 0; i < nelt / 2; i++)
4488             {
4489               sel[i * 2] = i;
4490               sel[i * 2 + 1] = i + nelt;
4491             }
4492             if (can_vec_perm_p (mode, false, sel))
4493               {
4494                 for (i = 0; i < nelt; i++)
4495                   sel[i] += nelt / 2;
4496                 if (can_vec_perm_p (mode, false, sel))
4497                   return true;
4498               }
4499         }
4500     }
4501
4502   if (dump_enabled_p ())
4503     dump_printf (MSG_MISSED_OPTIMIZATION,
4504                  "permutaion op not supported by target.\n");
4505   return false;
4506 }
4507
4508
4509 /* Return TRUE if vec_store_lanes is available for COUNT vectors of
4510    type VECTYPE.  */
4511
4512 bool
4513 vect_store_lanes_supported (tree vectype, unsigned HOST_WIDE_INT count)
4514 {
4515   return vect_lanes_optab_supported_p ("vec_store_lanes",
4516                                        vec_store_lanes_optab,
4517                                        vectype, count);
4518 }
4519
4520
4521 /* Function vect_permute_store_chain.
4522
4523    Given a chain of interleaved stores in DR_CHAIN of LENGTH that must be
4524    a power of 2 or equal to 3, generate interleave_high/low stmts to reorder
4525    the data correctly for the stores.  Return the final references for stores
4526    in RESULT_CHAIN.
4527
4528    E.g., LENGTH is 4 and the scalar type is short, i.e., VF is 8.
4529    The input is 4 vectors each containing 8 elements.  We assign a number to
4530    each element, the input sequence is:
4531
4532    1st vec:   0  1  2  3  4  5  6  7
4533    2nd vec:   8  9 10 11 12 13 14 15
4534    3rd vec:  16 17 18 19 20 21 22 23
4535    4th vec:  24 25 26 27 28 29 30 31
4536
4537    The output sequence should be:
4538
4539    1st vec:  0  8 16 24  1  9 17 25
4540    2nd vec:  2 10 18 26  3 11 19 27
4541    3rd vec:  4 12 20 28  5 13 21 30
4542    4th vec:  6 14 22 30  7 15 23 31
4543
4544    i.e., we interleave the contents of the four vectors in their order.
4545
4546    We use interleave_high/low instructions to create such output.  The input of
4547    each interleave_high/low operation is two vectors:
4548    1st vec    2nd vec
4549    0 1 2 3    4 5 6 7
4550    the even elements of the result vector are obtained left-to-right from the
4551    high/low elements of the first vector.  The odd elements of the result are
4552    obtained left-to-right from the high/low elements of the second vector.
4553    The output of interleave_high will be:   0 4 1 5
4554    and of interleave_low:                   2 6 3 7
4555
4556
4557    The permutation is done in log LENGTH stages.  In each stage interleave_high
4558    and interleave_low stmts are created for each pair of vectors in DR_CHAIN,
4559    where the first argument is taken from the first half of DR_CHAIN and the
4560    second argument from it's second half.
4561    In our example,
4562
4563    I1: interleave_high (1st vec, 3rd vec)
4564    I2: interleave_low (1st vec, 3rd vec)
4565    I3: interleave_high (2nd vec, 4th vec)
4566    I4: interleave_low (2nd vec, 4th vec)
4567
4568    The output for the first stage is:
4569
4570    I1:  0 16  1 17  2 18  3 19
4571    I2:  4 20  5 21  6 22  7 23
4572    I3:  8 24  9 25 10 26 11 27
4573    I4: 12 28 13 29 14 30 15 31
4574
4575    The output of the second stage, i.e. the final result is:
4576
4577    I1:  0  8 16 24  1  9 17 25
4578    I2:  2 10 18 26  3 11 19 27
4579    I3:  4 12 20 28  5 13 21 30
4580    I4:  6 14 22 30  7 15 23 31.  */
4581
4582 void
4583 vect_permute_store_chain (vec<tree> dr_chain,
4584                           unsigned int length,
4585                           gimple stmt,
4586                           gimple_stmt_iterator *gsi,
4587                           vec<tree> *result_chain)
4588 {
4589   tree vect1, vect2, high, low;
4590   gimple perm_stmt;
4591   tree vectype = STMT_VINFO_VECTYPE (vinfo_for_stmt (stmt));
4592   tree perm_mask_low, perm_mask_high;
4593   tree data_ref;
4594   tree perm3_mask_low, perm3_mask_high;
4595   unsigned int i, n, log_length = exact_log2 (length);
4596   unsigned int j, nelt = TYPE_VECTOR_SUBPARTS (vectype);
4597   unsigned char *sel = XALLOCAVEC (unsigned char, nelt);
4598
4599   result_chain->quick_grow (length);
4600   memcpy (result_chain->address (), dr_chain.address (),
4601           length * sizeof (tree));
4602
4603   if (length == 3)
4604     {
4605       unsigned int j0 = 0, j1 = 0, j2 = 0;
4606
4607       for (j = 0; j < 3; j++)
4608         {
4609           int nelt0 = ((3 - j) * nelt) % 3;
4610           int nelt1 = ((3 - j) * nelt + 1) % 3;
4611           int nelt2 = ((3 - j) * nelt + 2) % 3;
4612
4613           for (i = 0; i < nelt; i++)
4614             {
4615               if (3 * i + nelt0 < nelt)
4616                 sel[3 * i + nelt0] = j0++;
4617               if (3 * i + nelt1 < nelt)
4618                 sel[3 * i + nelt1] = nelt + j1++;
4619               if (3 * i + nelt2 < nelt)
4620                 sel[3 * i + nelt2] = 0;
4621             }
4622           perm3_mask_low = vect_gen_perm_mask_checked (vectype, sel);
4623
4624           for (i = 0; i < nelt; i++)
4625             {
4626               if (3 * i + nelt0 < nelt)
4627                 sel[3 * i + nelt0] = 3 * i + nelt0;
4628               if (3 * i + nelt1 < nelt)
4629                 sel[3 * i + nelt1] = 3 * i + nelt1;
4630               if (3 * i + nelt2 < nelt)
4631                 sel[3 * i + nelt2] = nelt + j2++;
4632             }
4633           perm3_mask_high = vect_gen_perm_mask_checked (vectype, sel);
4634
4635           vect1 = dr_chain[0];
4636           vect2 = dr_chain[1];
4637
4638           /* Create interleaving stmt:
4639              low = VEC_PERM_EXPR <vect1, vect2,
4640                                   {j, nelt, *, j + 1, nelt + j + 1, *,
4641                                    j + 2, nelt + j + 2, *, ...}>  */
4642           data_ref = make_temp_ssa_name (vectype, NULL, "vect_shuffle3_low");
4643           perm_stmt = gimple_build_assign_with_ops (VEC_PERM_EXPR, data_ref,
4644                                                     vect1, vect2,
4645                                                     perm3_mask_low);
4646           vect_finish_stmt_generation (stmt, perm_stmt, gsi);
4647
4648           vect1 = data_ref;
4649           vect2 = dr_chain[2];
4650           /* Create interleaving stmt:
4651              low = VEC_PERM_EXPR <vect1, vect2,
4652                                   {0, 1, nelt + j, 3, 4, nelt + j + 1,
4653                                    6, 7, nelt + j + 2, ...}>  */
4654           data_ref = make_temp_ssa_name (vectype, NULL, "vect_shuffle3_high");
4655           perm_stmt = gimple_build_assign_with_ops (VEC_PERM_EXPR, data_ref,
4656                                                     vect1, vect2,
4657                                                     perm3_mask_high);
4658           vect_finish_stmt_generation (stmt, perm_stmt, gsi);
4659           (*result_chain)[j] = data_ref;
4660         }
4661     }
4662   else
4663     {
4664       /* If length is not equal to 3 then only power of 2 is supported.  */
4665       gcc_assert (exact_log2 (length) != -1);
4666
4667       for (i = 0, n = nelt / 2; i < n; i++)
4668         {
4669           sel[i * 2] = i;
4670           sel[i * 2 + 1] = i + nelt;
4671         }
4672         perm_mask_high = vect_gen_perm_mask_checked (vectype, sel);
4673
4674         for (i = 0; i < nelt; i++)
4675           sel[i] += nelt / 2;
4676         perm_mask_low = vect_gen_perm_mask_checked (vectype, sel);
4677
4678         for (i = 0, n = log_length; i < n; i++)
4679           {
4680             for (j = 0; j < length/2; j++)
4681               {
4682                 vect1 = dr_chain[j];
4683                 vect2 = dr_chain[j+length/2];
4684
4685                 /* Create interleaving stmt:
4686                    high = VEC_PERM_EXPR <vect1, vect2, {0, nelt, 1, nelt+1,
4687                                                         ...}>  */
4688                 high = make_temp_ssa_name (vectype, NULL, "vect_inter_high");
4689                 perm_stmt
4690                   = gimple_build_assign_with_ops (VEC_PERM_EXPR, high,
4691                                                   vect1, vect2, perm_mask_high);
4692                 vect_finish_stmt_generation (stmt, perm_stmt, gsi);
4693                 (*result_chain)[2*j] = high;
4694
4695                 /* Create interleaving stmt:
4696                    low = VEC_PERM_EXPR <vect1, vect2,
4697                                         {nelt/2, nelt*3/2, nelt/2+1, nelt*3/2+1,
4698                                          ...}>  */
4699                 low = make_temp_ssa_name (vectype, NULL, "vect_inter_low");
4700                 perm_stmt
4701                   = gimple_build_assign_with_ops (VEC_PERM_EXPR, low,
4702                                                   vect1, vect2, perm_mask_low);
4703                 vect_finish_stmt_generation (stmt, perm_stmt, gsi);
4704                 (*result_chain)[2*j+1] = low;
4705               }
4706             memcpy (dr_chain.address (), result_chain->address (),
4707                     length * sizeof (tree));
4708           }
4709     }
4710 }
4711
4712 /* Function vect_setup_realignment
4713
4714    This function is called when vectorizing an unaligned load using
4715    the dr_explicit_realign[_optimized] scheme.
4716    This function generates the following code at the loop prolog:
4717
4718       p = initial_addr;
4719    x  msq_init = *(floor(p));   # prolog load
4720       realignment_token = call target_builtin;
4721     loop:
4722    x  msq = phi (msq_init, ---)
4723
4724    The stmts marked with x are generated only for the case of
4725    dr_explicit_realign_optimized.
4726
4727    The code above sets up a new (vector) pointer, pointing to the first
4728    location accessed by STMT, and a "floor-aligned" load using that pointer.
4729    It also generates code to compute the "realignment-token" (if the relevant
4730    target hook was defined), and creates a phi-node at the loop-header bb
4731    whose arguments are the result of the prolog-load (created by this
4732    function) and the result of a load that takes place in the loop (to be
4733    created by the caller to this function).
4734
4735    For the case of dr_explicit_realign_optimized:
4736    The caller to this function uses the phi-result (msq) to create the
4737    realignment code inside the loop, and sets up the missing phi argument,
4738    as follows:
4739     loop:
4740       msq = phi (msq_init, lsq)
4741       lsq = *(floor(p'));        # load in loop
4742       result = realign_load (msq, lsq, realignment_token);
4743
4744    For the case of dr_explicit_realign:
4745     loop:
4746       msq = *(floor(p));        # load in loop
4747       p' = p + (VS-1);
4748       lsq = *(floor(p'));       # load in loop
4749       result = realign_load (msq, lsq, realignment_token);
4750
4751    Input:
4752    STMT - (scalar) load stmt to be vectorized. This load accesses
4753           a memory location that may be unaligned.
4754    BSI - place where new code is to be inserted.
4755    ALIGNMENT_SUPPORT_SCHEME - which of the two misalignment handling schemes
4756                               is used.
4757
4758    Output:
4759    REALIGNMENT_TOKEN - the result of a call to the builtin_mask_for_load
4760                        target hook, if defined.
4761    Return value - the result of the loop-header phi node.  */
4762
4763 tree
4764 vect_setup_realignment (gimple stmt, gimple_stmt_iterator *gsi,
4765                         tree *realignment_token,
4766                         enum dr_alignment_support alignment_support_scheme,
4767                         tree init_addr,
4768                         struct loop **at_loop)
4769 {
4770   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
4771   tree vectype = STMT_VINFO_VECTYPE (stmt_info);
4772   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
4773   struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
4774   struct loop *loop = NULL;
4775   edge pe = NULL;
4776   tree scalar_dest = gimple_assign_lhs (stmt);
4777   tree vec_dest;
4778   gimple inc;
4779   tree ptr;
4780   tree data_ref;
4781   gimple new_stmt;
4782   basic_block new_bb;
4783   tree msq_init = NULL_TREE;
4784   tree new_temp;
4785   gimple phi_stmt;
4786   tree msq = NULL_TREE;
4787   gimple_seq stmts = NULL;
4788   bool inv_p;
4789   bool compute_in_loop = false;
4790   bool nested_in_vect_loop = false;
4791   struct loop *containing_loop = (gimple_bb (stmt))->loop_father;
4792   struct loop *loop_for_initial_load = NULL;
4793
4794   if (loop_vinfo)
4795     {
4796       loop = LOOP_VINFO_LOOP (loop_vinfo);
4797       nested_in_vect_loop = nested_in_vect_loop_p (loop, stmt);
4798     }
4799
4800   gcc_assert (alignment_support_scheme == dr_explicit_realign
4801               || alignment_support_scheme == dr_explicit_realign_optimized);
4802
4803   /* We need to generate three things:
4804      1. the misalignment computation
4805      2. the extra vector load (for the optimized realignment scheme).
4806      3. the phi node for the two vectors from which the realignment is
4807       done (for the optimized realignment scheme).  */
4808
4809   /* 1. Determine where to generate the misalignment computation.
4810
4811      If INIT_ADDR is NULL_TREE, this indicates that the misalignment
4812      calculation will be generated by this function, outside the loop (in the
4813      preheader).  Otherwise, INIT_ADDR had already been computed for us by the
4814      caller, inside the loop.
4815
4816      Background: If the misalignment remains fixed throughout the iterations of
4817      the loop, then both realignment schemes are applicable, and also the
4818      misalignment computation can be done outside LOOP.  This is because we are
4819      vectorizing LOOP, and so the memory accesses in LOOP advance in steps that
4820      are a multiple of VS (the Vector Size), and therefore the misalignment in
4821      different vectorized LOOP iterations is always the same.
4822      The problem arises only if the memory access is in an inner-loop nested
4823      inside LOOP, which is now being vectorized using outer-loop vectorization.
4824      This is the only case when the misalignment of the memory access may not
4825      remain fixed throughout the iterations of the inner-loop (as explained in
4826      detail in vect_supportable_dr_alignment).  In this case, not only is the
4827      optimized realignment scheme not applicable, but also the misalignment
4828      computation (and generation of the realignment token that is passed to
4829      REALIGN_LOAD) have to be done inside the loop.
4830
4831      In short, INIT_ADDR indicates whether we are in a COMPUTE_IN_LOOP mode
4832      or not, which in turn determines if the misalignment is computed inside
4833      the inner-loop, or outside LOOP.  */
4834
4835   if (init_addr != NULL_TREE || !loop_vinfo)
4836     {
4837       compute_in_loop = true;
4838       gcc_assert (alignment_support_scheme == dr_explicit_realign);
4839     }
4840
4841
4842   /* 2. Determine where to generate the extra vector load.
4843
4844      For the optimized realignment scheme, instead of generating two vector
4845      loads in each iteration, we generate a single extra vector load in the
4846      preheader of the loop, and in each iteration reuse the result of the
4847      vector load from the previous iteration.  In case the memory access is in
4848      an inner-loop nested inside LOOP, which is now being vectorized using
4849      outer-loop vectorization, we need to determine whether this initial vector
4850      load should be generated at the preheader of the inner-loop, or can be
4851      generated at the preheader of LOOP.  If the memory access has no evolution
4852      in LOOP, it can be generated in the preheader of LOOP. Otherwise, it has
4853      to be generated inside LOOP (in the preheader of the inner-loop).  */
4854
4855   if (nested_in_vect_loop)
4856     {
4857       tree outerloop_step = STMT_VINFO_DR_STEP (stmt_info);
4858       bool invariant_in_outerloop =
4859             (tree_int_cst_compare (outerloop_step, size_zero_node) == 0);
4860       loop_for_initial_load = (invariant_in_outerloop ? loop : loop->inner);
4861     }
4862   else
4863     loop_for_initial_load = loop;
4864   if (at_loop)
4865     *at_loop = loop_for_initial_load;
4866
4867   if (loop_for_initial_load)
4868     pe = loop_preheader_edge (loop_for_initial_load);
4869
4870   /* 3. For the case of the optimized realignment, create the first vector
4871       load at the loop preheader.  */
4872
4873   if (alignment_support_scheme == dr_explicit_realign_optimized)
4874     {
4875       /* Create msq_init = *(floor(p1)) in the loop preheader  */
4876
4877       gcc_assert (!compute_in_loop);
4878       vec_dest = vect_create_destination_var (scalar_dest, vectype);
4879       ptr = vect_create_data_ref_ptr (stmt, vectype, loop_for_initial_load,
4880                                       NULL_TREE, &init_addr, NULL, &inc,
4881                                       true, &inv_p);
4882       new_temp = copy_ssa_name (ptr, NULL);
4883       new_stmt = gimple_build_assign_with_ops
4884                    (BIT_AND_EXPR, new_temp, ptr,
4885                     build_int_cst (TREE_TYPE (ptr),
4886                                    -(HOST_WIDE_INT)TYPE_ALIGN_UNIT (vectype)));
4887       new_bb = gsi_insert_on_edge_immediate (pe, new_stmt);
4888       gcc_assert (!new_bb);
4889       data_ref
4890         = build2 (MEM_REF, TREE_TYPE (vec_dest), new_temp,
4891                   build_int_cst (reference_alias_ptr_type (DR_REF (dr)), 0));
4892       new_stmt = gimple_build_assign (vec_dest, data_ref);
4893       new_temp = make_ssa_name (vec_dest, new_stmt);
4894       gimple_assign_set_lhs (new_stmt, new_temp);
4895       if (pe)
4896         {
4897           new_bb = gsi_insert_on_edge_immediate (pe, new_stmt);
4898           gcc_assert (!new_bb);
4899         }
4900       else
4901          gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
4902
4903       msq_init = gimple_assign_lhs (new_stmt);
4904     }
4905
4906   /* 4. Create realignment token using a target builtin, if available.
4907       It is done either inside the containing loop, or before LOOP (as
4908       determined above).  */
4909
4910   if (targetm.vectorize.builtin_mask_for_load)
4911     {
4912       tree builtin_decl;
4913
4914       /* Compute INIT_ADDR - the initial addressed accessed by this memref.  */
4915       if (!init_addr)
4916         {
4917           /* Generate the INIT_ADDR computation outside LOOP.  */
4918           init_addr = vect_create_addr_base_for_vector_ref (stmt, &stmts,
4919                                                         NULL_TREE, loop);
4920           if (loop)
4921             {
4922               pe = loop_preheader_edge (loop);
4923               new_bb = gsi_insert_seq_on_edge_immediate (pe, stmts);
4924               gcc_assert (!new_bb);
4925             }
4926           else
4927              gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
4928         }
4929
4930       builtin_decl = targetm.vectorize.builtin_mask_for_load ();
4931       new_stmt = gimple_build_call (builtin_decl, 1, init_addr);
4932       vec_dest =
4933         vect_create_destination_var (scalar_dest,
4934                                      gimple_call_return_type (new_stmt));
4935       new_temp = make_ssa_name (vec_dest, new_stmt);
4936       gimple_call_set_lhs (new_stmt, new_temp);
4937
4938       if (compute_in_loop)
4939         gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
4940       else
4941         {
4942           /* Generate the misalignment computation outside LOOP.  */
4943           pe = loop_preheader_edge (loop);
4944           new_bb = gsi_insert_on_edge_immediate (pe, new_stmt);
4945           gcc_assert (!new_bb);
4946         }
4947
4948       *realignment_token = gimple_call_lhs (new_stmt);
4949
4950       /* The result of the CALL_EXPR to this builtin is determined from
4951          the value of the parameter and no global variables are touched
4952          which makes the builtin a "const" function.  Requiring the
4953          builtin to have the "const" attribute makes it unnecessary
4954          to call mark_call_clobbered.  */
4955       gcc_assert (TREE_READONLY (builtin_decl));
4956     }
4957
4958   if (alignment_support_scheme == dr_explicit_realign)
4959     return msq;
4960
4961   gcc_assert (!compute_in_loop);
4962   gcc_assert (alignment_support_scheme == dr_explicit_realign_optimized);
4963
4964
4965   /* 5. Create msq = phi <msq_init, lsq> in loop  */
4966
4967   pe = loop_preheader_edge (containing_loop);
4968   vec_dest = vect_create_destination_var (scalar_dest, vectype);
4969   msq = make_ssa_name (vec_dest, NULL);
4970   phi_stmt = create_phi_node (msq, containing_loop->header);
4971   add_phi_arg (phi_stmt, msq_init, pe, UNKNOWN_LOCATION);
4972
4973   return msq;
4974 }
4975
4976
4977 /* Function vect_grouped_load_supported.
4978
4979    Returns TRUE if even and odd permutations are supported,
4980    and FALSE otherwise.  */
4981
4982 bool
4983 vect_grouped_load_supported (tree vectype, unsigned HOST_WIDE_INT count)
4984 {
4985   machine_mode mode = TYPE_MODE (vectype);
4986
4987   /* vect_permute_load_chain requires the group size to be equal to 3 or
4988      be a power of two.  */
4989   if (count != 3 && exact_log2 (count) == -1)
4990     {
4991       if (dump_enabled_p ())
4992         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
4993                          "the size of the group of accesses"
4994                          " is not a power of 2 or not equal to 3\n");
4995       return false;
4996     }
4997
4998   /* Check that the permutation is supported.  */
4999   if (VECTOR_MODE_P (mode))
5000     {
5001       unsigned int i, j, nelt = GET_MODE_NUNITS (mode);
5002       unsigned char *sel = XALLOCAVEC (unsigned char, nelt);
5003
5004       if (count == 3)
5005         {
5006           unsigned int k;
5007           for (k = 0; k < 3; k++)
5008             {
5009               for (i = 0; i < nelt; i++)
5010                 if (3 * i + k < 2 * nelt)
5011                   sel[i] = 3 * i + k;
5012                 else
5013                   sel[i] = 0;
5014               if (!can_vec_perm_p (mode, false, sel))
5015                 {
5016                   if (dump_enabled_p ())
5017                     dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
5018                                      "shuffle of 3 loads is not supported by"
5019                                      " target\n");
5020                     return false;
5021                 }
5022               for (i = 0, j = 0; i < nelt; i++)
5023                 if (3 * i + k < 2 * nelt)
5024                   sel[i] = i;
5025                 else
5026                   sel[i] = nelt + ((nelt + k) % 3) + 3 * (j++);
5027               if (!can_vec_perm_p (mode, false, sel))
5028                 {
5029                   if (dump_enabled_p ())
5030                     dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
5031                                      "shuffle of 3 loads is not supported by"
5032                                      " target\n");
5033                   return false;
5034                 }
5035             }
5036           return true;
5037         }
5038       else
5039         {
5040           /* If length is not equal to 3 then only power of 2 is supported.  */
5041           gcc_assert (exact_log2 (count) != -1);
5042           for (i = 0; i < nelt; i++)
5043             sel[i] = i * 2;
5044           if (can_vec_perm_p (mode, false, sel))
5045             {
5046               for (i = 0; i < nelt; i++)
5047                 sel[i] = i * 2 + 1;
5048               if (can_vec_perm_p (mode, false, sel))
5049                 return true;
5050             }
5051         }
5052     }
5053
5054   if (dump_enabled_p ())
5055     dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
5056                      "extract even/odd not supported by target\n");
5057   return false;
5058 }
5059
5060 /* Return TRUE if vec_load_lanes is available for COUNT vectors of
5061    type VECTYPE.  */
5062
5063 bool
5064 vect_load_lanes_supported (tree vectype, unsigned HOST_WIDE_INT count)
5065 {
5066   return vect_lanes_optab_supported_p ("vec_load_lanes",
5067                                        vec_load_lanes_optab,
5068                                        vectype, count);
5069 }
5070
5071 /* Function vect_permute_load_chain.
5072
5073    Given a chain of interleaved loads in DR_CHAIN of LENGTH that must be
5074    a power of 2 or equal to 3, generate extract_even/odd stmts to reorder
5075    the input data correctly.  Return the final references for loads in
5076    RESULT_CHAIN.
5077
5078    E.g., LENGTH is 4 and the scalar type is short, i.e., VF is 8.
5079    The input is 4 vectors each containing 8 elements. We assign a number to each
5080    element, the input sequence is:
5081
5082    1st vec:   0  1  2  3  4  5  6  7
5083    2nd vec:   8  9 10 11 12 13 14 15
5084    3rd vec:  16 17 18 19 20 21 22 23
5085    4th vec:  24 25 26 27 28 29 30 31
5086
5087    The output sequence should be:
5088
5089    1st vec:  0 4  8 12 16 20 24 28
5090    2nd vec:  1 5  9 13 17 21 25 29
5091    3rd vec:  2 6 10 14 18 22 26 30
5092    4th vec:  3 7 11 15 19 23 27 31
5093
5094    i.e., the first output vector should contain the first elements of each
5095    interleaving group, etc.
5096
5097    We use extract_even/odd instructions to create such output.  The input of
5098    each extract_even/odd operation is two vectors
5099    1st vec    2nd vec
5100    0 1 2 3    4 5 6 7
5101
5102    and the output is the vector of extracted even/odd elements.  The output of
5103    extract_even will be:   0 2 4 6
5104    and of extract_odd:     1 3 5 7
5105
5106
5107    The permutation is done in log LENGTH stages.  In each stage extract_even
5108    and extract_odd stmts are created for each pair of vectors in DR_CHAIN in
5109    their order.  In our example,
5110
5111    E1: extract_even (1st vec, 2nd vec)
5112    E2: extract_odd (1st vec, 2nd vec)
5113    E3: extract_even (3rd vec, 4th vec)
5114    E4: extract_odd (3rd vec, 4th vec)
5115
5116    The output for the first stage will be:
5117
5118    E1:  0  2  4  6  8 10 12 14
5119    E2:  1  3  5  7  9 11 13 15
5120    E3: 16 18 20 22 24 26 28 30
5121    E4: 17 19 21 23 25 27 29 31
5122
5123    In order to proceed and create the correct sequence for the next stage (or
5124    for the correct output, if the second stage is the last one, as in our
5125    example), we first put the output of extract_even operation and then the
5126    output of extract_odd in RESULT_CHAIN (which is then copied to DR_CHAIN).
5127    The input for the second stage is:
5128
5129    1st vec (E1):  0  2  4  6  8 10 12 14
5130    2nd vec (E3): 16 18 20 22 24 26 28 30
5131    3rd vec (E2):  1  3  5  7  9 11 13 15
5132    4th vec (E4): 17 19 21 23 25 27 29 31
5133
5134    The output of the second stage:
5135
5136    E1: 0 4  8 12 16 20 24 28
5137    E2: 2 6 10 14 18 22 26 30
5138    E3: 1 5  9 13 17 21 25 29
5139    E4: 3 7 11 15 19 23 27 31
5140
5141    And RESULT_CHAIN after reordering:
5142
5143    1st vec (E1):  0 4  8 12 16 20 24 28
5144    2nd vec (E3):  1 5  9 13 17 21 25 29
5145    3rd vec (E2):  2 6 10 14 18 22 26 30
5146    4th vec (E4):  3 7 11 15 19 23 27 31.  */
5147
5148 static void
5149 vect_permute_load_chain (vec<tree> dr_chain,
5150                          unsigned int length,
5151                          gimple stmt,
5152                          gimple_stmt_iterator *gsi,
5153                          vec<tree> *result_chain)
5154 {
5155   tree data_ref, first_vect, second_vect;
5156   tree perm_mask_even, perm_mask_odd;
5157   tree perm3_mask_low, perm3_mask_high;
5158   gimple perm_stmt;
5159   tree vectype = STMT_VINFO_VECTYPE (vinfo_for_stmt (stmt));
5160   unsigned int i, j, log_length = exact_log2 (length);
5161   unsigned nelt = TYPE_VECTOR_SUBPARTS (vectype);
5162   unsigned char *sel = XALLOCAVEC (unsigned char, nelt);
5163
5164   result_chain->quick_grow (length);
5165   memcpy (result_chain->address (), dr_chain.address (),
5166           length * sizeof (tree));
5167
5168   if (length == 3)
5169     {
5170       unsigned int k;
5171
5172       for (k = 0; k < 3; k++)
5173         {
5174           for (i = 0; i < nelt; i++)
5175             if (3 * i + k < 2 * nelt)
5176               sel[i] = 3 * i + k;
5177             else
5178               sel[i] = 0;
5179           perm3_mask_low = vect_gen_perm_mask_checked (vectype, sel);
5180
5181           for (i = 0, j = 0; i < nelt; i++)
5182             if (3 * i + k < 2 * nelt)
5183               sel[i] = i;
5184             else
5185               sel[i] = nelt + ((nelt + k) % 3) + 3 * (j++);
5186
5187           perm3_mask_high = vect_gen_perm_mask_checked (vectype, sel);
5188
5189           first_vect = dr_chain[0];
5190           second_vect = dr_chain[1];
5191
5192           /* Create interleaving stmt (low part of):
5193              low = VEC_PERM_EXPR <first_vect, second_vect2, {k, 3 + k, 6 + k,
5194                                                              ...}>  */
5195           data_ref = make_temp_ssa_name (vectype, NULL, "vect_shuffle3_low");
5196           perm_stmt = gimple_build_assign_with_ops (VEC_PERM_EXPR, data_ref,
5197                                                     first_vect, second_vect,
5198                                                     perm3_mask_low);
5199           vect_finish_stmt_generation (stmt, perm_stmt, gsi);
5200
5201           /* Create interleaving stmt (high part of):
5202              high = VEC_PERM_EXPR <first_vect, second_vect2, {k, 3 + k, 6 + k,
5203                                                               ...}>  */
5204           first_vect = data_ref;
5205           second_vect = dr_chain[2];
5206           data_ref = make_temp_ssa_name (vectype, NULL, "vect_shuffle3_high");
5207           perm_stmt = gimple_build_assign_with_ops (VEC_PERM_EXPR, data_ref,
5208                                                     first_vect, second_vect,
5209                                                     perm3_mask_high);
5210           vect_finish_stmt_generation (stmt, perm_stmt, gsi);
5211           (*result_chain)[k] = data_ref;
5212         }
5213     }
5214   else
5215     {
5216       /* If length is not equal to 3 then only power of 2 is supported.  */
5217       gcc_assert (exact_log2 (length) != -1);
5218
5219       for (i = 0; i < nelt; ++i)
5220         sel[i] = i * 2;
5221       perm_mask_even = vect_gen_perm_mask_checked (vectype, sel);
5222
5223       for (i = 0; i < nelt; ++i)
5224         sel[i] = i * 2 + 1;
5225       perm_mask_odd = vect_gen_perm_mask_checked (vectype, sel);
5226
5227       for (i = 0; i < log_length; i++)
5228         {
5229           for (j = 0; j < length; j += 2)
5230             {
5231               first_vect = dr_chain[j];
5232               second_vect = dr_chain[j+1];
5233
5234               /* data_ref = permute_even (first_data_ref, second_data_ref);  */
5235               data_ref = make_temp_ssa_name (vectype, NULL, "vect_perm_even");
5236               perm_stmt = gimple_build_assign_with_ops (VEC_PERM_EXPR, data_ref,
5237                                                         first_vect, second_vect,
5238                                                         perm_mask_even);
5239               vect_finish_stmt_generation (stmt, perm_stmt, gsi);
5240               (*result_chain)[j/2] = data_ref;
5241
5242               /* data_ref = permute_odd (first_data_ref, second_data_ref);  */
5243               data_ref = make_temp_ssa_name (vectype, NULL, "vect_perm_odd");
5244               perm_stmt = gimple_build_assign_with_ops (VEC_PERM_EXPR, data_ref,
5245                                                         first_vect, second_vect,
5246                                                         perm_mask_odd);
5247               vect_finish_stmt_generation (stmt, perm_stmt, gsi);
5248               (*result_chain)[j/2+length/2] = data_ref;
5249             }
5250           memcpy (dr_chain.address (), result_chain->address (),
5251                   length * sizeof (tree));
5252         }
5253     }
5254 }
5255
5256 /* Function vect_shift_permute_load_chain.
5257
5258    Given a chain of loads in DR_CHAIN of LENGTH 2 or 3, generate
5259    sequence of stmts to reorder the input data accordingly.
5260    Return the final references for loads in RESULT_CHAIN.
5261    Return true if successed, false otherwise.
5262
5263    E.g., LENGTH is 3 and the scalar type is short, i.e., VF is 8.
5264    The input is 3 vectors each containing 8 elements.  We assign a
5265    number to each element, the input sequence is:
5266
5267    1st vec:   0  1  2  3  4  5  6  7
5268    2nd vec:   8  9 10 11 12 13 14 15
5269    3rd vec:  16 17 18 19 20 21 22 23
5270
5271    The output sequence should be:
5272
5273    1st vec:  0 3 6  9 12 15 18 21
5274    2nd vec:  1 4 7 10 13 16 19 22
5275    3rd vec:  2 5 8 11 14 17 20 23
5276
5277    We use 3 shuffle instructions and 3 * 3 - 1 shifts to create such output.
5278
5279    First we shuffle all 3 vectors to get correct elements order:
5280
5281    1st vec:  ( 0  3  6) ( 1  4  7) ( 2  5)
5282    2nd vec:  ( 8 11 14) ( 9 12 15) (10 13)
5283    3rd vec:  (16 19 22) (17 20 23) (18 21)
5284
5285    Next we unite and shift vector 3 times:
5286
5287    1st step:
5288      shift right by 6 the concatenation of:
5289      "1st vec" and  "2nd vec"
5290        ( 0  3  6) ( 1  4  7) |( 2  5) _ ( 8 11 14) ( 9 12 15)| (10 13)
5291      "2nd vec" and  "3rd vec"
5292        ( 8 11 14) ( 9 12 15) |(10 13) _ (16 19 22) (17 20 23)| (18 21)
5293      "3rd vec" and  "1st vec"
5294        (16 19 22) (17 20 23) |(18 21) _ ( 0  3  6) ( 1  4  7)| ( 2  5)
5295                              | New vectors                   |
5296
5297      So that now new vectors are:
5298
5299      1st vec:  ( 2  5) ( 8 11 14) ( 9 12 15)
5300      2nd vec:  (10 13) (16 19 22) (17 20 23)
5301      3rd vec:  (18 21) ( 0  3  6) ( 1  4  7)
5302
5303    2nd step:
5304      shift right by 5 the concatenation of:
5305      "1st vec" and  "3rd vec"
5306        ( 2  5) ( 8 11 14) |( 9 12 15) _ (18 21) ( 0  3  6)| ( 1  4  7)
5307      "2nd vec" and  "1st vec"
5308        (10 13) (16 19 22) |(17 20 23) _ ( 2  5) ( 8 11 14)| ( 9 12 15)
5309      "3rd vec" and  "2nd vec"
5310        (18 21) ( 0  3  6) |( 1  4  7) _ (10 13) (16 19 22)| (17 20 23)
5311                           | New vectors                   |
5312
5313      So that now new vectors are:
5314
5315      1st vec:  ( 9 12 15) (18 21) ( 0  3  6)
5316      2nd vec:  (17 20 23) ( 2  5) ( 8 11 14)
5317      3rd vec:  ( 1  4  7) (10 13) (16 19 22) READY
5318
5319    3rd step:
5320      shift right by 5 the concatenation of:
5321      "1st vec" and  "1st vec"
5322        ( 9 12 15) (18 21) |( 0  3  6) _ ( 9 12 15) (18 21)| ( 0  3  6)
5323      shift right by 3 the concatenation of:
5324      "2nd vec" and  "2nd vec"
5325                (17 20 23) |( 2  5) ( 8 11 14) _ (17 20 23)| ( 2  5) ( 8 11 14)
5326                           | New vectors                   |
5327
5328      So that now all vectors are READY:
5329      1st vec:  ( 0  3  6) ( 9 12 15) (18 21)
5330      2nd vec:  ( 2  5) ( 8 11 14) (17 20 23)
5331      3rd vec:  ( 1  4  7) (10 13) (16 19 22)
5332
5333    This algorithm is faster than one in vect_permute_load_chain if:
5334      1.  "shift of a concatination" is faster than general permutation.
5335          This is usually so.
5336      2.  The TARGET machine can't execute vector instructions in parallel.
5337          This is because each step of the algorithm depends on previous.
5338          The algorithm in vect_permute_load_chain is much more parallel.
5339
5340    The algorithm is applicable only for LOAD CHAIN LENGTH less than VF.
5341 */
5342
5343 static bool
5344 vect_shift_permute_load_chain (vec<tree> dr_chain,
5345                                unsigned int length,
5346                                gimple stmt,
5347                                gimple_stmt_iterator *gsi,
5348                                vec<tree> *result_chain)
5349 {
5350   tree vect[3], vect_shift[3], data_ref, first_vect, second_vect;
5351   tree perm2_mask1, perm2_mask2, perm3_mask;
5352   tree select_mask, shift1_mask, shift2_mask, shift3_mask, shift4_mask;
5353   gimple perm_stmt;
5354
5355   tree vectype = STMT_VINFO_VECTYPE (vinfo_for_stmt (stmt));
5356   unsigned int i;
5357   unsigned nelt = TYPE_VECTOR_SUBPARTS (vectype);
5358   unsigned char *sel = XALLOCAVEC (unsigned char, nelt);
5359   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
5360   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
5361
5362   result_chain->quick_grow (length);
5363   memcpy (result_chain->address (), dr_chain.address (),
5364           length * sizeof (tree));
5365
5366   if (exact_log2 (length) != -1 && LOOP_VINFO_VECT_FACTOR (loop_vinfo) > 4)
5367     {
5368       unsigned int j, log_length = exact_log2 (length);
5369       for (i = 0; i < nelt / 2; ++i)
5370         sel[i] = i * 2;
5371       for (i = 0; i < nelt / 2; ++i)
5372         sel[nelt / 2 + i] = i * 2 + 1;
5373       if (!can_vec_perm_p (TYPE_MODE (vectype), false, sel))
5374         {
5375           if (dump_enabled_p ())
5376             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
5377                              "shuffle of 2 fields structure is not \
5378                               supported by target\n");
5379           return false;
5380         }
5381       perm2_mask1 = vect_gen_perm_mask_checked (vectype, sel);
5382
5383       for (i = 0; i < nelt / 2; ++i)
5384         sel[i] = i * 2 + 1;
5385       for (i = 0; i < nelt / 2; ++i)
5386         sel[nelt / 2 + i] = i * 2;
5387       if (!can_vec_perm_p (TYPE_MODE (vectype), false, sel))
5388         {
5389           if (dump_enabled_p ())
5390             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
5391                              "shuffle of 2 fields structure is not \
5392                               supported by target\n");
5393           return false;
5394         }
5395       perm2_mask2 = vect_gen_perm_mask_checked (vectype, sel);
5396
5397       /* Generating permutation constant to shift all elements.
5398          For vector length 8 it is {4 5 6 7 8 9 10 11}.  */
5399       for (i = 0; i < nelt; i++)
5400         sel[i] = nelt / 2 + i;
5401       if (!can_vec_perm_p (TYPE_MODE (vectype), false, sel))
5402         {
5403           if (dump_enabled_p ())
5404             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
5405                              "shift permutation is not supported by target\n");
5406           return false;
5407         }
5408       shift1_mask = vect_gen_perm_mask_checked (vectype, sel);
5409
5410       /* Generating permutation constant to select vector from 2.
5411          For vector length 8 it is {0 1 2 3 12 13 14 15}.  */
5412       for (i = 0; i < nelt / 2; i++)
5413         sel[i] = i;
5414       for (i = nelt / 2; i < nelt; i++)
5415         sel[i] = nelt + i;
5416       if (!can_vec_perm_p (TYPE_MODE (vectype), false, sel))
5417         {
5418           if (dump_enabled_p ())
5419             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
5420                              "select is not supported by target\n");
5421           return false;
5422         }
5423       select_mask = vect_gen_perm_mask_checked (vectype, sel);
5424
5425       for (i = 0; i < log_length; i++)
5426         {
5427           for (j = 0; j < length; j += 2)
5428             {
5429               first_vect = dr_chain[j];
5430               second_vect = dr_chain[j + 1];
5431
5432               data_ref = make_temp_ssa_name (vectype, NULL, "vect_shuffle2");
5433               perm_stmt = gimple_build_assign_with_ops (VEC_PERM_EXPR, data_ref,
5434                                                         first_vect, first_vect,
5435                                                         perm2_mask1);
5436               vect_finish_stmt_generation (stmt, perm_stmt, gsi);
5437               vect[0] = data_ref;
5438
5439               data_ref = make_temp_ssa_name (vectype, NULL, "vect_shuffle2");
5440               perm_stmt = gimple_build_assign_with_ops (VEC_PERM_EXPR, data_ref,
5441                                                         second_vect, second_vect,
5442                                                         perm2_mask2);
5443               vect_finish_stmt_generation (stmt, perm_stmt, gsi);
5444               vect[1] = data_ref;
5445
5446               data_ref = make_temp_ssa_name (vectype, NULL, "vect_shift");
5447               perm_stmt = gimple_build_assign_with_ops (VEC_PERM_EXPR, data_ref,
5448                                                         vect[0], vect[1],
5449                                                         shift1_mask);
5450               vect_finish_stmt_generation (stmt, perm_stmt, gsi);
5451               (*result_chain)[j/2 + length/2] = data_ref;
5452
5453               data_ref = make_temp_ssa_name (vectype, NULL, "vect_select");
5454               perm_stmt = gimple_build_assign_with_ops (VEC_PERM_EXPR, data_ref,
5455                                                         vect[0], vect[1],
5456                                                         select_mask);
5457               vect_finish_stmt_generation (stmt, perm_stmt, gsi);
5458               (*result_chain)[j/2] = data_ref;
5459             }
5460           memcpy (dr_chain.address (), result_chain->address (),
5461                   length * sizeof (tree));
5462         }
5463       return true;
5464     }
5465   if (length == 3 && LOOP_VINFO_VECT_FACTOR (loop_vinfo) > 2)
5466     {
5467       unsigned int k = 0, l = 0;
5468
5469       /* Generating permutation constant to get all elements in rigth order.
5470          For vector length 8 it is {0 3 6 1 4 7 2 5}.  */
5471       for (i = 0; i < nelt; i++)
5472         {
5473           if (3 * k + (l % 3) >= nelt)
5474             {
5475               k = 0;
5476               l += (3 - (nelt % 3));
5477             }
5478           sel[i] = 3 * k + (l % 3);
5479           k++;
5480         }
5481       if (!can_vec_perm_p (TYPE_MODE (vectype), false, sel))
5482         {
5483           if (dump_enabled_p ())
5484             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
5485                              "shuffle of 3 fields structure is not \
5486                               supported by target\n");
5487           return false;
5488         }
5489       perm3_mask = vect_gen_perm_mask_checked (vectype, sel);
5490
5491       /* Generating permutation constant to shift all elements.
5492          For vector length 8 it is {6 7 8 9 10 11 12 13}.  */
5493       for (i = 0; i < nelt; i++)
5494         sel[i] = 2 * (nelt / 3) + (nelt % 3) + i;
5495       if (!can_vec_perm_p (TYPE_MODE (vectype), false, sel))
5496         {
5497           if (dump_enabled_p ())
5498             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
5499                              "shift permutation is not supported by target\n");
5500           return false;
5501         }
5502       shift1_mask = vect_gen_perm_mask_checked (vectype, sel);
5503
5504       /* Generating permutation constant to shift all elements.
5505          For vector length 8 it is {5 6 7 8 9 10 11 12}.  */
5506       for (i = 0; i < nelt; i++)
5507         sel[i] = 2 * (nelt / 3) + 1 + i;
5508       if (!can_vec_perm_p (TYPE_MODE (vectype), false, sel))
5509         {
5510           if (dump_enabled_p ())
5511             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
5512                              "shift permutation is not supported by target\n");
5513           return false;
5514         }
5515       shift2_mask = vect_gen_perm_mask_checked (vectype, sel);
5516
5517       /* Generating permutation constant to shift all elements.
5518          For vector length 8 it is {3 4 5 6 7 8 9 10}.  */
5519       for (i = 0; i < nelt; i++)
5520         sel[i] = (nelt / 3) + (nelt % 3) / 2 + i;
5521       if (!can_vec_perm_p (TYPE_MODE (vectype), false, sel))
5522         {
5523           if (dump_enabled_p ())
5524             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
5525                              "shift permutation is not supported by target\n");
5526           return false;
5527         }
5528       shift3_mask = vect_gen_perm_mask_checked (vectype, sel);
5529
5530       /* Generating permutation constant to shift all elements.
5531          For vector length 8 it is {5 6 7 8 9 10 11 12}.  */
5532       for (i = 0; i < nelt; i++)
5533         sel[i] = 2 * (nelt / 3) + (nelt % 3) / 2 + i;
5534       if (!can_vec_perm_p (TYPE_MODE (vectype), false, sel))
5535         {
5536           if (dump_enabled_p ())
5537             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
5538                              "shift permutation is not supported by target\n");
5539           return false;
5540         }
5541       shift4_mask = vect_gen_perm_mask_checked (vectype, sel);
5542
5543       for (k = 0; k < 3; k++)
5544         {
5545           data_ref = make_temp_ssa_name (vectype, NULL, "vect_shuffle3");
5546           perm_stmt = gimple_build_assign_with_ops (VEC_PERM_EXPR, data_ref,
5547                                                     dr_chain[k], dr_chain[k],
5548                                                     perm3_mask);
5549           vect_finish_stmt_generation (stmt, perm_stmt, gsi);
5550           vect[k] = data_ref;
5551         }
5552
5553       for (k = 0; k < 3; k++)
5554         {
5555           data_ref = make_temp_ssa_name (vectype, NULL, "vect_shift1");
5556           perm_stmt = gimple_build_assign_with_ops (VEC_PERM_EXPR, data_ref,
5557                                                     vect[k % 3],
5558                                                     vect[(k + 1) % 3],
5559                                                     shift1_mask);
5560           vect_finish_stmt_generation (stmt, perm_stmt, gsi);
5561           vect_shift[k] = data_ref;
5562         }
5563
5564       for (k = 0; k < 3; k++)
5565         {
5566           data_ref = make_temp_ssa_name (vectype, NULL, "vect_shift2");
5567           perm_stmt = gimple_build_assign_with_ops (VEC_PERM_EXPR, data_ref,
5568                                                     vect_shift[(4 - k) % 3],
5569                                                     vect_shift[(3 - k) % 3],
5570                                                     shift2_mask);
5571           vect_finish_stmt_generation (stmt, perm_stmt, gsi);
5572           vect[k] = data_ref;
5573         }
5574
5575       (*result_chain)[3 - (nelt % 3)] = vect[2];
5576
5577       data_ref = make_temp_ssa_name (vectype, NULL, "vect_shift3");
5578       perm_stmt = gimple_build_assign_with_ops (VEC_PERM_EXPR, data_ref,
5579                                                 vect[0], vect[0],
5580                                                 shift3_mask);
5581       vect_finish_stmt_generation (stmt, perm_stmt, gsi);
5582       (*result_chain)[nelt % 3] = data_ref;
5583
5584       data_ref = make_temp_ssa_name (vectype, NULL, "vect_shift4");
5585       perm_stmt = gimple_build_assign_with_ops (VEC_PERM_EXPR, data_ref,
5586                                                 vect[1], vect[1],
5587                                                 shift4_mask);
5588       vect_finish_stmt_generation (stmt, perm_stmt, gsi);
5589       (*result_chain)[0] = data_ref;
5590       return true;
5591     }
5592   return false;
5593 }
5594
5595 /* Function vect_transform_grouped_load.
5596
5597    Given a chain of input interleaved data-refs (in DR_CHAIN), build statements
5598    to perform their permutation and ascribe the result vectorized statements to
5599    the scalar statements.
5600 */
5601
5602 void
5603 vect_transform_grouped_load (gimple stmt, vec<tree> dr_chain, int size,
5604                              gimple_stmt_iterator *gsi)
5605 {
5606   machine_mode mode;
5607   vec<tree> result_chain = vNULL;
5608
5609   /* DR_CHAIN contains input data-refs that are a part of the interleaving.
5610      RESULT_CHAIN is the output of vect_permute_load_chain, it contains permuted
5611      vectors, that are ready for vector computation.  */
5612   result_chain.create (size);
5613
5614   /* If reassociation width for vector type is 2 or greater target machine can
5615      execute 2 or more vector instructions in parallel.  Otherwise try to
5616      get chain for loads group using vect_shift_permute_load_chain.  */
5617   mode = TYPE_MODE (STMT_VINFO_VECTYPE (vinfo_for_stmt (stmt)));
5618   if (targetm.sched.reassociation_width (VEC_PERM_EXPR, mode) > 1
5619       || !vect_shift_permute_load_chain (dr_chain, size, stmt,
5620                                          gsi, &result_chain))
5621     vect_permute_load_chain (dr_chain, size, stmt, gsi, &result_chain);
5622   vect_record_grouped_load_vectors (stmt, result_chain);
5623   result_chain.release ();
5624 }
5625
5626 /* RESULT_CHAIN contains the output of a group of grouped loads that were
5627    generated as part of the vectorization of STMT.  Assign the statement
5628    for each vector to the associated scalar statement.  */
5629
5630 void
5631 vect_record_grouped_load_vectors (gimple stmt, vec<tree> result_chain)
5632 {
5633   gimple first_stmt = GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt));
5634   gimple next_stmt, new_stmt;
5635   unsigned int i, gap_count;
5636   tree tmp_data_ref;
5637
5638   /* Put a permuted data-ref in the VECTORIZED_STMT field.
5639      Since we scan the chain starting from it's first node, their order
5640      corresponds the order of data-refs in RESULT_CHAIN.  */
5641   next_stmt = first_stmt;
5642   gap_count = 1;
5643   FOR_EACH_VEC_ELT (result_chain, i, tmp_data_ref)
5644     {
5645       if (!next_stmt)
5646         break;
5647
5648       /* Skip the gaps.  Loads created for the gaps will be removed by dead
5649        code elimination pass later.  No need to check for the first stmt in
5650        the group, since it always exists.
5651        GROUP_GAP is the number of steps in elements from the previous
5652        access (if there is no gap GROUP_GAP is 1).  We skip loads that
5653        correspond to the gaps.  */
5654       if (next_stmt != first_stmt
5655           && gap_count < GROUP_GAP (vinfo_for_stmt (next_stmt)))
5656       {
5657         gap_count++;
5658         continue;
5659       }
5660
5661       while (next_stmt)
5662         {
5663           new_stmt = SSA_NAME_DEF_STMT (tmp_data_ref);
5664           /* We assume that if VEC_STMT is not NULL, this is a case of multiple
5665              copies, and we put the new vector statement in the first available
5666              RELATED_STMT.  */
5667           if (!STMT_VINFO_VEC_STMT (vinfo_for_stmt (next_stmt)))
5668             STMT_VINFO_VEC_STMT (vinfo_for_stmt (next_stmt)) = new_stmt;
5669           else
5670             {
5671               if (!GROUP_SAME_DR_STMT (vinfo_for_stmt (next_stmt)))
5672                 {
5673                   gimple prev_stmt =
5674                     STMT_VINFO_VEC_STMT (vinfo_for_stmt (next_stmt));
5675                   gimple rel_stmt =
5676                     STMT_VINFO_RELATED_STMT (vinfo_for_stmt (prev_stmt));
5677                   while (rel_stmt)
5678                     {
5679                       prev_stmt = rel_stmt;
5680                       rel_stmt =
5681                         STMT_VINFO_RELATED_STMT (vinfo_for_stmt (rel_stmt));
5682                     }
5683
5684                   STMT_VINFO_RELATED_STMT (vinfo_for_stmt (prev_stmt)) =
5685                     new_stmt;
5686                 }
5687             }
5688
5689           next_stmt = GROUP_NEXT_ELEMENT (vinfo_for_stmt (next_stmt));
5690           gap_count = 1;
5691           /* If NEXT_STMT accesses the same DR as the previous statement,
5692              put the same TMP_DATA_REF as its vectorized statement; otherwise
5693              get the next data-ref from RESULT_CHAIN.  */
5694           if (!next_stmt || !GROUP_SAME_DR_STMT (vinfo_for_stmt (next_stmt)))
5695             break;
5696         }
5697     }
5698 }
5699
5700 /* Function vect_force_dr_alignment_p.
5701
5702    Returns whether the alignment of a DECL can be forced to be aligned
5703    on ALIGNMENT bit boundary.  */
5704
5705 bool
5706 vect_can_force_dr_alignment_p (const_tree decl, unsigned int alignment)
5707 {
5708   if (TREE_CODE (decl) != VAR_DECL)
5709     return false;
5710
5711   /* With -fno-toplevel-reorder we may have already output the constant.  */
5712   if (TREE_ASM_WRITTEN (decl))
5713     return false;
5714
5715   /* Constant pool entries may be shared and not properly merged by LTO.  */
5716   if (DECL_IN_CONSTANT_POOL (decl))
5717     return false;
5718
5719   if (TREE_PUBLIC (decl) || DECL_EXTERNAL (decl))
5720     {
5721       symtab_node *snode;
5722
5723       /* We cannot change alignment of symbols that may bind to symbols
5724          in other translation unit that may contain a definition with lower
5725          alignment.  */
5726       if (!decl_binds_to_current_def_p (decl))
5727         return false;
5728
5729       /* When compiling partition, be sure the symbol is not output by other
5730          partition.  */
5731       snode = symtab_node::get (decl);
5732       if (flag_ltrans
5733           && (snode->in_other_partition
5734               || snode->get_partitioning_class () == SYMBOL_DUPLICATE))
5735         return false;
5736     }
5737
5738   /* Do not override the alignment as specified by the ABI when the used
5739      attribute is set.  */
5740   if (DECL_PRESERVE_P (decl))
5741     return false;
5742
5743   /* Do not override explicit alignment set by the user when an explicit
5744      section name is also used.  This is a common idiom used by many
5745      software projects.  */
5746   if (TREE_STATIC (decl) 
5747       && DECL_SECTION_NAME (decl) != NULL
5748       && !symtab_node::get (decl)->implicit_section)
5749     return false;
5750
5751   /* If symbol is an alias, we need to check that target is OK.  */
5752   if (TREE_STATIC (decl))
5753     {
5754       tree target = symtab_node::get (decl)->ultimate_alias_target ()->decl;
5755       if (target != decl)
5756         {
5757           if (DECL_PRESERVE_P (target))
5758             return false;
5759           decl = target;
5760         }
5761     }
5762
5763   if (TREE_STATIC (decl))
5764     return (alignment <= MAX_OFILE_ALIGNMENT);
5765   else
5766     return (alignment <= MAX_STACK_ALIGNMENT);
5767 }
5768
5769
5770 /* Return whether the data reference DR is supported with respect to its
5771    alignment.
5772    If CHECK_ALIGNED_ACCESSES is TRUE, check if the access is supported even
5773    it is aligned, i.e., check if it is possible to vectorize it with different
5774    alignment.  */
5775
5776 enum dr_alignment_support
5777 vect_supportable_dr_alignment (struct data_reference *dr,
5778                                bool check_aligned_accesses)
5779 {
5780   gimple stmt = DR_STMT (dr);
5781   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
5782   tree vectype = STMT_VINFO_VECTYPE (stmt_info);
5783   machine_mode mode = TYPE_MODE (vectype);
5784   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
5785   struct loop *vect_loop = NULL;
5786   bool nested_in_vect_loop = false;
5787
5788   if (aligned_access_p (dr) && !check_aligned_accesses)
5789     return dr_aligned;
5790
5791   /* For now assume all conditional loads/stores support unaligned
5792      access without any special code.  */
5793   if (is_gimple_call (stmt)
5794       && gimple_call_internal_p (stmt)
5795       && (gimple_call_internal_fn (stmt) == IFN_MASK_LOAD
5796           || gimple_call_internal_fn (stmt) == IFN_MASK_STORE))
5797     return dr_unaligned_supported;
5798
5799   if (loop_vinfo)
5800     {
5801       vect_loop = LOOP_VINFO_LOOP (loop_vinfo);
5802       nested_in_vect_loop = nested_in_vect_loop_p (vect_loop, stmt);
5803     }
5804
5805   /* Possibly unaligned access.  */
5806
5807   /* We can choose between using the implicit realignment scheme (generating
5808      a misaligned_move stmt) and the explicit realignment scheme (generating
5809      aligned loads with a REALIGN_LOAD).  There are two variants to the
5810      explicit realignment scheme: optimized, and unoptimized.
5811      We can optimize the realignment only if the step between consecutive
5812      vector loads is equal to the vector size.  Since the vector memory
5813      accesses advance in steps of VS (Vector Size) in the vectorized loop, it
5814      is guaranteed that the misalignment amount remains the same throughout the
5815      execution of the vectorized loop.  Therefore, we can create the
5816      "realignment token" (the permutation mask that is passed to REALIGN_LOAD)
5817      at the loop preheader.
5818
5819      However, in the case of outer-loop vectorization, when vectorizing a
5820      memory access in the inner-loop nested within the LOOP that is now being
5821      vectorized, while it is guaranteed that the misalignment of the
5822      vectorized memory access will remain the same in different outer-loop
5823      iterations, it is *not* guaranteed that is will remain the same throughout
5824      the execution of the inner-loop.  This is because the inner-loop advances
5825      with the original scalar step (and not in steps of VS).  If the inner-loop
5826      step happens to be a multiple of VS, then the misalignment remains fixed
5827      and we can use the optimized realignment scheme.  For example:
5828
5829       for (i=0; i<N; i++)
5830         for (j=0; j<M; j++)
5831           s += a[i+j];
5832
5833      When vectorizing the i-loop in the above example, the step between
5834      consecutive vector loads is 1, and so the misalignment does not remain
5835      fixed across the execution of the inner-loop, and the realignment cannot
5836      be optimized (as illustrated in the following pseudo vectorized loop):
5837
5838       for (i=0; i<N; i+=4)
5839         for (j=0; j<M; j++){
5840           vs += vp[i+j]; // misalignment of &vp[i+j] is {0,1,2,3,0,1,2,3,...}
5841                          // when j is {0,1,2,3,4,5,6,7,...} respectively.
5842                          // (assuming that we start from an aligned address).
5843           }
5844
5845      We therefore have to use the unoptimized realignment scheme:
5846
5847       for (i=0; i<N; i+=4)
5848           for (j=k; j<M; j+=4)
5849           vs += vp[i+j]; // misalignment of &vp[i+j] is always k (assuming
5850                            // that the misalignment of the initial address is
5851                            // 0).
5852
5853      The loop can then be vectorized as follows:
5854
5855       for (k=0; k<4; k++){
5856         rt = get_realignment_token (&vp[k]);
5857         for (i=0; i<N; i+=4){
5858           v1 = vp[i+k];
5859           for (j=k; j<M; j+=4){
5860             v2 = vp[i+j+VS-1];
5861             va = REALIGN_LOAD <v1,v2,rt>;
5862             vs += va;
5863             v1 = v2;
5864           }
5865         }
5866     } */
5867
5868   if (DR_IS_READ (dr))
5869     {
5870       bool is_packed = false;
5871       tree type = (TREE_TYPE (DR_REF (dr)));
5872
5873       if (optab_handler (vec_realign_load_optab, mode) != CODE_FOR_nothing
5874           && (!targetm.vectorize.builtin_mask_for_load
5875               || targetm.vectorize.builtin_mask_for_load ()))
5876         {
5877           tree vectype = STMT_VINFO_VECTYPE (stmt_info);
5878           if ((nested_in_vect_loop
5879                && (TREE_INT_CST_LOW (DR_STEP (dr))
5880                    != GET_MODE_SIZE (TYPE_MODE (vectype))))
5881               || !loop_vinfo)
5882             return dr_explicit_realign;
5883           else
5884             return dr_explicit_realign_optimized;
5885         }
5886       if (!known_alignment_for_access_p (dr))
5887         is_packed = not_size_aligned (DR_REF (dr));
5888
5889       if ((TYPE_USER_ALIGN (type) && !is_packed)
5890           || targetm.vectorize.
5891                support_vector_misalignment (mode, type,
5892                                             DR_MISALIGNMENT (dr), is_packed))
5893         /* Can't software pipeline the loads, but can at least do them.  */
5894         return dr_unaligned_supported;
5895     }
5896   else
5897     {
5898       bool is_packed = false;
5899       tree type = (TREE_TYPE (DR_REF (dr)));
5900
5901       if (!known_alignment_for_access_p (dr))
5902         is_packed = not_size_aligned (DR_REF (dr));
5903
5904      if ((TYPE_USER_ALIGN (type) && !is_packed)
5905          || targetm.vectorize.
5906               support_vector_misalignment (mode, type,
5907                                            DR_MISALIGNMENT (dr), is_packed))
5908        return dr_unaligned_supported;
5909     }
5910
5911   /* Unsupported.  */
5912   return dr_unaligned_unsupported;
5913 }