Daily bump.
[official-gcc.git] / gcc / tree-vect-analyze.c
blob89555151387cbcf818d3abe188d24855aa334837
1 /* Analysis Utilities for Loop Vectorization.
2 Copyright (C) 2003,2004,2005,2006 Free Software Foundation, Inc.
3 Contributed by Dorit Naishlos <dorit@il.ibm.com>
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301, USA. */
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "ggc.h"
27 #include "tree.h"
28 #include "basic-block.h"
29 #include "diagnostic.h"
30 #include "tree-flow.h"
31 #include "tree-dump.h"
32 #include "timevar.h"
33 #include "cfgloop.h"
34 #include "expr.h"
35 #include "optabs.h"
36 #include "params.h"
37 #include "tree-chrec.h"
38 #include "tree-data-ref.h"
39 #include "tree-scalar-evolution.h"
40 #include "tree-vectorizer.h"
41 #include "toplev.h"
43 /* Main analysis functions. */
44 static loop_vec_info vect_analyze_loop_form (struct loop *);
45 static bool vect_analyze_data_refs (loop_vec_info);
46 static bool vect_mark_stmts_to_be_vectorized (loop_vec_info);
47 static void vect_analyze_scalar_cycles (loop_vec_info);
48 static bool vect_analyze_data_ref_accesses (loop_vec_info);
49 static bool vect_analyze_data_ref_dependences (loop_vec_info);
50 static bool vect_analyze_data_refs_alignment (loop_vec_info);
51 static bool vect_compute_data_refs_alignment (loop_vec_info);
52 static bool vect_enhance_data_refs_alignment (loop_vec_info);
53 static bool vect_analyze_operations (loop_vec_info);
54 static bool vect_determine_vectorization_factor (loop_vec_info);
56 /* Utility functions for the analyses. */
57 static bool exist_non_indexing_operands_for_use_p (tree, tree);
58 static tree vect_get_loop_niters (struct loop *, tree *);
59 static bool vect_analyze_data_ref_dependence
60 (struct data_dependence_relation *, loop_vec_info, bool);
61 static bool vect_compute_data_ref_alignment (struct data_reference *);
62 static bool vect_analyze_data_ref_access (struct data_reference *);
63 static bool vect_can_advance_ivs_p (loop_vec_info);
64 static void vect_update_misalignment_for_peel
65 (struct data_reference *, struct data_reference *, int npeel);
67 /* Function vect_determine_vectorization_factor
69 Determine the vectorization factor (VF). VF is the number of data elements
70 that are operated upon in parallel in a single iteration of the vectorized
71 loop. For example, when vectorizing a loop that operates on 4byte elements,
72 on a target with vector size (VS) 16byte, the VF is set to 4, since 4
73 elements can fit in a single vector register.
75 We currently support vectorization of loops in which all types operated upon
76 are of the same size. Therefore this function currently sets VF according to
77 the size of the types operated upon, and fails if there are multiple sizes
78 in the loop.
80 VF is also the factor by which the loop iterations are strip-mined, e.g.:
81 original loop:
82 for (i=0; i<N; i++){
83 a[i] = b[i] + c[i];
86 vectorized loop:
87 for (i=0; i<N; i+=VF){
88 a[i:VF] = b[i:VF] + c[i:VF];
92 static bool
93 vect_determine_vectorization_factor (loop_vec_info loop_vinfo)
95 struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
96 basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
97 int nbbs = loop->num_nodes;
98 block_stmt_iterator si;
99 unsigned int vectorization_factor = 0;
100 int i;
101 tree scalar_type;
103 if (vect_print_dump_info (REPORT_DETAILS))
104 fprintf (vect_dump, "=== vect_determine_vectorization_factor ===");
106 for (i = 0; i < nbbs; i++)
108 basic_block bb = bbs[i];
110 for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
112 tree stmt = bsi_stmt (si);
113 unsigned int nunits;
114 stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
115 tree vectype;
117 if (vect_print_dump_info (REPORT_DETAILS))
119 fprintf (vect_dump, "==> examining statement: ");
120 print_generic_expr (vect_dump, stmt, TDF_SLIM);
123 gcc_assert (stmt_info);
124 /* skip stmts which do not need to be vectorized. */
125 if (!STMT_VINFO_RELEVANT_P (stmt_info)
126 && !STMT_VINFO_LIVE_P (stmt_info))
128 if (vect_print_dump_info (REPORT_DETAILS))
129 fprintf (vect_dump, "skip.");
130 continue;
133 if (VECTOR_MODE_P (TYPE_MODE (TREE_TYPE (stmt))))
135 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
137 fprintf (vect_dump, "not vectorized: vector stmt in loop:");
138 print_generic_expr (vect_dump, stmt, TDF_SLIM);
140 return false;
143 if (STMT_VINFO_VECTYPE (stmt_info))
145 vectype = STMT_VINFO_VECTYPE (stmt_info);
146 scalar_type = TREE_TYPE (vectype);
148 else
150 if (STMT_VINFO_DATA_REF (stmt_info))
151 scalar_type =
152 TREE_TYPE (DR_REF (STMT_VINFO_DATA_REF (stmt_info)));
153 else if (TREE_CODE (stmt) == MODIFY_EXPR)
154 scalar_type = TREE_TYPE (TREE_OPERAND (stmt, 0));
155 else
156 scalar_type = TREE_TYPE (stmt);
158 if (vect_print_dump_info (REPORT_DETAILS))
160 fprintf (vect_dump, "get vectype for scalar type: ");
161 print_generic_expr (vect_dump, scalar_type, TDF_SLIM);
164 vectype = get_vectype_for_scalar_type (scalar_type);
165 if (!vectype)
167 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
169 fprintf (vect_dump,
170 "not vectorized: unsupported data-type ");
171 print_generic_expr (vect_dump, scalar_type, TDF_SLIM);
173 return false;
175 STMT_VINFO_VECTYPE (stmt_info) = vectype;
178 if (vect_print_dump_info (REPORT_DETAILS))
180 fprintf (vect_dump, "vectype: ");
181 print_generic_expr (vect_dump, vectype, TDF_SLIM);
184 nunits = TYPE_VECTOR_SUBPARTS (vectype);
185 if (vect_print_dump_info (REPORT_DETAILS))
186 fprintf (vect_dump, "nunits = %d", nunits);
188 if (!vectorization_factor
189 || (nunits > vectorization_factor))
190 vectorization_factor = nunits;
195 /* TODO: Analyze cost. Decide if worth while to vectorize. */
197 if (vectorization_factor <= 1)
199 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
200 fprintf (vect_dump, "not vectorized: unsupported data-type");
201 return false;
203 LOOP_VINFO_VECT_FACTOR (loop_vinfo) = vectorization_factor;
205 return true;
209 /* Function vect_analyze_operations.
211 Scan the loop stmts and make sure they are all vectorizable. */
213 static bool
214 vect_analyze_operations (loop_vec_info loop_vinfo)
216 struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
217 basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
218 int nbbs = loop->num_nodes;
219 block_stmt_iterator si;
220 unsigned int vectorization_factor = 0;
221 int i;
222 bool ok;
223 tree phi;
224 stmt_vec_info stmt_info;
225 bool need_to_vectorize = false;
227 if (vect_print_dump_info (REPORT_DETAILS))
228 fprintf (vect_dump, "=== vect_analyze_operations ===");
230 gcc_assert (LOOP_VINFO_VECT_FACTOR (loop_vinfo));
231 vectorization_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
233 for (i = 0; i < nbbs; i++)
235 basic_block bb = bbs[i];
237 for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
239 stmt_info = vinfo_for_stmt (phi);
240 if (vect_print_dump_info (REPORT_DETAILS))
242 fprintf (vect_dump, "examining phi: ");
243 print_generic_expr (vect_dump, phi, TDF_SLIM);
246 gcc_assert (stmt_info);
248 if (STMT_VINFO_LIVE_P (stmt_info))
250 /* FORNOW: not yet supported. */
251 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
252 fprintf (vect_dump, "not vectorized: value used after loop.");
253 return false;
256 if (STMT_VINFO_RELEVANT_P (stmt_info))
258 /* Most likely a reduction-like computation that is used
259 in the loop. */
260 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
261 fprintf (vect_dump, "not vectorized: unsupported pattern.");
262 return false;
266 for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
268 tree stmt = bsi_stmt (si);
269 stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
271 if (vect_print_dump_info (REPORT_DETAILS))
273 fprintf (vect_dump, "==> examining statement: ");
274 print_generic_expr (vect_dump, stmt, TDF_SLIM);
277 gcc_assert (stmt_info);
279 /* skip stmts which do not need to be vectorized.
280 this is expected to include:
281 - the COND_EXPR which is the loop exit condition
282 - any LABEL_EXPRs in the loop
283 - computations that are used only for array indexing or loop
284 control */
286 if (!STMT_VINFO_RELEVANT_P (stmt_info)
287 && !STMT_VINFO_LIVE_P (stmt_info))
289 if (vect_print_dump_info (REPORT_DETAILS))
290 fprintf (vect_dump, "irrelevant.");
291 continue;
294 if (STMT_VINFO_RELEVANT_P (stmt_info))
296 gcc_assert (!VECTOR_MODE_P (TYPE_MODE (TREE_TYPE (stmt))));
297 gcc_assert (STMT_VINFO_VECTYPE (stmt_info));
299 ok = (vectorizable_type_promotion (stmt, NULL, NULL)
300 || vectorizable_type_demotion (stmt, NULL, NULL)
301 || vectorizable_operation (stmt, NULL, NULL)
302 || vectorizable_assignment (stmt, NULL, NULL)
303 || vectorizable_load (stmt, NULL, NULL)
304 || vectorizable_call (stmt, NULL, NULL)
305 || vectorizable_store (stmt, NULL, NULL)
306 || vectorizable_condition (stmt, NULL, NULL));
308 if (!ok)
310 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
312 fprintf (vect_dump,
313 "not vectorized: relevant stmt not supported: ");
314 print_generic_expr (vect_dump, stmt, TDF_SLIM);
316 return false;
318 need_to_vectorize = true;
321 if (STMT_VINFO_LIVE_P (stmt_info))
323 ok = vectorizable_reduction (stmt, NULL, NULL);
325 if (ok)
326 need_to_vectorize = true;
327 else
328 ok = vectorizable_live_operation (stmt, NULL, NULL);
330 if (!ok)
332 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
334 fprintf (vect_dump,
335 "not vectorized: live stmt not supported: ");
336 print_generic_expr (vect_dump, stmt, TDF_SLIM);
338 return false;
341 } /* stmts in bb */
342 } /* bbs */
344 /* TODO: Analyze cost. Decide if worth while to vectorize. */
346 /* All operations in the loop are either irrelevant (deal with loop
347 control, or dead), or only used outside the loop and can be moved
348 out of the loop (e.g. invariants, inductions). The loop can be
349 optimized away by scalar optimizations. We're better off not
350 touching this loop. */
351 if (!need_to_vectorize)
353 if (vect_print_dump_info (REPORT_DETAILS))
354 fprintf (vect_dump,
355 "All the computation can be taken out of the loop.");
356 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
357 fprintf (vect_dump,
358 "not vectorized: redundant loop. no profit to vectorize.");
359 return false;
362 if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
363 && vect_print_dump_info (REPORT_DETAILS))
364 fprintf (vect_dump,
365 "vectorization_factor = %d, niters = " HOST_WIDE_INT_PRINT_DEC,
366 vectorization_factor, LOOP_VINFO_INT_NITERS (loop_vinfo));
368 if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
369 && LOOP_VINFO_INT_NITERS (loop_vinfo) < vectorization_factor)
371 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
372 fprintf (vect_dump, "not vectorized: iteration count too small.");
373 return false;
376 if (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
377 || LOOP_VINFO_INT_NITERS (loop_vinfo) % vectorization_factor != 0
378 || LOOP_PEELING_FOR_ALIGNMENT (loop_vinfo))
380 if (vect_print_dump_info (REPORT_DETAILS))
381 fprintf (vect_dump, "epilog loop required.");
382 if (!vect_can_advance_ivs_p (loop_vinfo))
384 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
385 fprintf (vect_dump,
386 "not vectorized: can't create epilog loop 1.");
387 return false;
389 if (!slpeel_can_duplicate_loop_p (loop, single_exit (loop)))
391 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
392 fprintf (vect_dump,
393 "not vectorized: can't create epilog loop 2.");
394 return false;
398 return true;
402 /* Function exist_non_indexing_operands_for_use_p
404 USE is one of the uses attached to STMT. Check if USE is
405 used in STMT for anything other than indexing an array. */
407 static bool
408 exist_non_indexing_operands_for_use_p (tree use, tree stmt)
410 tree operand;
411 stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
413 /* USE corresponds to some operand in STMT. If there is no data
414 reference in STMT, then any operand that corresponds to USE
415 is not indexing an array. */
416 if (!STMT_VINFO_DATA_REF (stmt_info))
417 return true;
419 /* STMT has a data_ref. FORNOW this means that its of one of
420 the following forms:
421 -1- ARRAY_REF = var
422 -2- var = ARRAY_REF
423 (This should have been verified in analyze_data_refs).
425 'var' in the second case corresponds to a def, not a use,
426 so USE cannot correspond to any operands that are not used
427 for array indexing.
429 Therefore, all we need to check is if STMT falls into the
430 first case, and whether var corresponds to USE. */
432 if (TREE_CODE (TREE_OPERAND (stmt, 0)) == SSA_NAME)
433 return false;
435 operand = TREE_OPERAND (stmt, 1);
437 if (TREE_CODE (operand) != SSA_NAME)
438 return false;
440 if (operand == use)
441 return true;
443 return false;
447 /* Function vect_analyze_scalar_cycles.
449 Examine the cross iteration def-use cycles of scalar variables, by
450 analyzing the loop (scalar) PHIs; Classify each cycle as one of the
451 following: invariant, induction, reduction, unknown.
453 Some forms of scalar cycles are not yet supported.
455 Example1: reduction: (unsupported yet)
457 loop1:
458 for (i=0; i<N; i++)
459 sum += a[i];
461 Example2: induction: (unsupported yet)
463 loop2:
464 for (i=0; i<N; i++)
465 a[i] = i;
467 Note: the following loop *is* vectorizable:
469 loop3:
470 for (i=0; i<N; i++)
471 a[i] = b[i];
473 even though it has a def-use cycle caused by the induction variable i:
475 loop: i_2 = PHI (i_0, i_1)
476 a[i_2] = ...;
477 i_1 = i_2 + 1;
478 GOTO loop;
480 because the def-use cycle in loop3 is considered "not relevant" - i.e.,
481 it does not need to be vectorized because it is only used for array
482 indexing (see 'mark_stmts_to_be_vectorized'). The def-use cycle in
483 loop2 on the other hand is relevant (it is being written to memory).
486 static void
487 vect_analyze_scalar_cycles (loop_vec_info loop_vinfo)
489 tree phi;
490 struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
491 basic_block bb = loop->header;
492 tree dummy;
494 if (vect_print_dump_info (REPORT_DETAILS))
495 fprintf (vect_dump, "=== vect_analyze_scalar_cycles ===");
497 for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
499 tree access_fn = NULL;
500 tree def = PHI_RESULT (phi);
501 stmt_vec_info stmt_vinfo = vinfo_for_stmt (phi);
502 tree reduc_stmt;
504 if (vect_print_dump_info (REPORT_DETAILS))
506 fprintf (vect_dump, "Analyze phi: ");
507 print_generic_expr (vect_dump, phi, TDF_SLIM);
510 /* Skip virtual phi's. The data dependences that are associated with
511 virtual defs/uses (i.e., memory accesses) are analyzed elsewhere. */
513 if (!is_gimple_reg (SSA_NAME_VAR (def)))
515 if (vect_print_dump_info (REPORT_DETAILS))
516 fprintf (vect_dump, "virtual phi. skip.");
517 continue;
520 STMT_VINFO_DEF_TYPE (stmt_vinfo) = vect_unknown_def_type;
522 /* Analyze the evolution function. */
524 access_fn = analyze_scalar_evolution (loop, def);
526 if (!access_fn)
527 continue;
529 if (vect_print_dump_info (REPORT_DETAILS))
531 fprintf (vect_dump, "Access function of PHI: ");
532 print_generic_expr (vect_dump, access_fn, TDF_SLIM);
535 if (vect_is_simple_iv_evolution (loop->num, access_fn, &dummy, &dummy))
537 if (vect_print_dump_info (REPORT_DETAILS))
538 fprintf (vect_dump, "Detected induction.");
539 STMT_VINFO_DEF_TYPE (stmt_vinfo) = vect_induction_def;
540 continue;
543 /* TODO: handle invariant phis */
545 reduc_stmt = vect_is_simple_reduction (loop, phi);
546 if (reduc_stmt)
548 if (vect_print_dump_info (REPORT_DETAILS))
549 fprintf (vect_dump, "Detected reduction.");
550 STMT_VINFO_DEF_TYPE (stmt_vinfo) = vect_reduction_def;
551 STMT_VINFO_DEF_TYPE (vinfo_for_stmt (reduc_stmt)) =
552 vect_reduction_def;
554 else
555 if (vect_print_dump_info (REPORT_DETAILS))
556 fprintf (vect_dump, "Unknown def-use cycle pattern.");
560 return;
564 /* Function vect_insert_into_interleaving_chain.
566 Insert DRA into the interleaving chain of DRB according to DRA's INIT. */
568 static void
569 vect_insert_into_interleaving_chain (struct data_reference *dra,
570 struct data_reference *drb)
572 tree prev, next, next_init;
573 stmt_vec_info stmtinfo_a = vinfo_for_stmt (DR_STMT (dra));
574 stmt_vec_info stmtinfo_b = vinfo_for_stmt (DR_STMT (drb));
576 prev = DR_GROUP_FIRST_DR (stmtinfo_b);
577 next = DR_GROUP_NEXT_DR (vinfo_for_stmt (prev));
578 while (next)
580 next_init = DR_INIT (STMT_VINFO_DATA_REF (vinfo_for_stmt (next)));
581 if (tree_int_cst_compare (next_init, DR_INIT (dra)) > 0)
583 /* Insert here. */
584 DR_GROUP_NEXT_DR (vinfo_for_stmt (prev)) = DR_STMT (dra);
585 DR_GROUP_NEXT_DR (stmtinfo_a) = next;
586 return;
588 prev = next;
589 next = DR_GROUP_NEXT_DR (vinfo_for_stmt (prev));
592 /* We got to the end of the list. Insert here. */
593 DR_GROUP_NEXT_DR (vinfo_for_stmt (prev)) = DR_STMT (dra);
594 DR_GROUP_NEXT_DR (stmtinfo_a) = NULL_TREE;
598 /* Function vect_update_interleaving_chain.
600 For two data-refs DRA and DRB that are a part of a chain interleaved data
601 accesses, update the interleaving chain. DRB's INIT is smaller than DRA's.
603 There are four possible cases:
604 1. New stmts - both DRA and DRB are not a part of any chain:
605 FIRST_DR = DRB
606 NEXT_DR (DRB) = DRA
607 2. DRB is a part of a chain and DRA is not:
608 no need to update FIRST_DR
609 no need to insert DRB
610 insert DRA according to init
611 3. DRA is a part of a chain and DRB is not:
612 if (init of FIRST_DR > init of DRB)
613 FIRST_DR = DRB
614 NEXT(FIRST_DR) = previous FIRST_DR
615 else
616 insert DRB according to its init
617 4. both DRA and DRB are in some interleaving chains:
618 choose the chain with the smallest init of FIRST_DR
619 insert the nodes of the second chain into the first one. */
621 static void
622 vect_update_interleaving_chain (struct data_reference *drb,
623 struct data_reference *dra)
625 stmt_vec_info stmtinfo_a = vinfo_for_stmt (DR_STMT (dra));
626 stmt_vec_info stmtinfo_b = vinfo_for_stmt (DR_STMT (drb));
627 tree next_init, init_dra_chain, init_drb_chain, first_a, first_b;
628 tree node, prev, next, node_init, first_stmt;
630 /* 1. New stmts - both DRA and DRB are not a part of any chain. */
631 if (!DR_GROUP_FIRST_DR (stmtinfo_a) && !DR_GROUP_FIRST_DR (stmtinfo_b))
633 DR_GROUP_FIRST_DR (stmtinfo_a) = DR_STMT (drb);
634 DR_GROUP_FIRST_DR (stmtinfo_b) = DR_STMT (drb);
635 DR_GROUP_NEXT_DR (stmtinfo_b) = DR_STMT (dra);
636 return;
639 /* 2. DRB is a part of a chain and DRA is not. */
640 if (!DR_GROUP_FIRST_DR (stmtinfo_a) && DR_GROUP_FIRST_DR (stmtinfo_b))
642 DR_GROUP_FIRST_DR (stmtinfo_a) = DR_GROUP_FIRST_DR (stmtinfo_b);
643 /* Insert DRA into the chain of DRB. */
644 vect_insert_into_interleaving_chain (dra, drb);
645 return;
648 /* 3. DRA is a part of a chain and DRB is not. */
649 if (DR_GROUP_FIRST_DR (stmtinfo_a) && !DR_GROUP_FIRST_DR (stmtinfo_b))
651 tree old_first_stmt = DR_GROUP_FIRST_DR (stmtinfo_a);
652 tree init_old = DR_INIT (STMT_VINFO_DATA_REF (vinfo_for_stmt (
653 old_first_stmt)));
654 tree tmp;
656 if (tree_int_cst_compare (init_old, DR_INIT (drb)) > 0)
658 /* DRB's init is smaller than the init of the stmt previously marked
659 as the first stmt of the interleaving chain of DRA. Therefore, we
660 update FIRST_STMT and put DRB in the head of the list. */
661 DR_GROUP_FIRST_DR (stmtinfo_b) = DR_STMT (drb);
662 DR_GROUP_NEXT_DR (stmtinfo_b) = old_first_stmt;
664 /* Update all the stmts in the list to point to the new FIRST_STMT. */
665 tmp = old_first_stmt;
666 while (tmp)
668 DR_GROUP_FIRST_DR (vinfo_for_stmt (tmp)) = DR_STMT (drb);
669 tmp = DR_GROUP_NEXT_DR (vinfo_for_stmt (tmp));
672 else
674 /* Insert DRB in the list of DRA. */
675 vect_insert_into_interleaving_chain (drb, dra);
676 DR_GROUP_FIRST_DR (stmtinfo_b) = DR_GROUP_FIRST_DR (stmtinfo_a);
678 return;
681 /* 4. both DRA and DRB are in some interleaving chains. */
682 first_a = DR_GROUP_FIRST_DR (stmtinfo_a);
683 first_b = DR_GROUP_FIRST_DR (stmtinfo_b);
684 if (first_a == first_b)
685 return;
686 init_dra_chain = DR_INIT (STMT_VINFO_DATA_REF (vinfo_for_stmt (first_a)));
687 init_drb_chain = DR_INIT (STMT_VINFO_DATA_REF (vinfo_for_stmt (first_b)));
689 if (tree_int_cst_compare (init_dra_chain, init_drb_chain) > 0)
691 /* Insert the nodes of DRA chain into the DRB chain.
692 After inserting a node, continue from this node of the DRB chain (don't
693 start from the beginning. */
694 node = DR_GROUP_FIRST_DR (stmtinfo_a);
695 prev = DR_GROUP_FIRST_DR (stmtinfo_b);
696 first_stmt = first_b;
698 else
700 /* Insert the nodes of DRB chain into the DRA chain.
701 After inserting a node, continue from this node of the DRA chain (don't
702 start from the beginning. */
703 node = DR_GROUP_FIRST_DR (stmtinfo_b);
704 prev = DR_GROUP_FIRST_DR (stmtinfo_a);
705 first_stmt = first_a;
708 while (node)
710 node_init = DR_INIT (STMT_VINFO_DATA_REF (vinfo_for_stmt (node)));
711 next = DR_GROUP_NEXT_DR (vinfo_for_stmt (prev));
712 while (next)
714 next_init = DR_INIT (STMT_VINFO_DATA_REF (vinfo_for_stmt (next)));
715 if (tree_int_cst_compare (next_init, node_init) > 0)
717 /* Insert here. */
718 DR_GROUP_NEXT_DR (vinfo_for_stmt (prev)) = node;
719 DR_GROUP_NEXT_DR (vinfo_for_stmt (node)) = next;
720 prev = node;
721 break;
723 prev = next;
724 next = DR_GROUP_NEXT_DR (vinfo_for_stmt (prev));
726 if (!next)
728 /* We got to the end of the list. Insert here. */
729 DR_GROUP_NEXT_DR (vinfo_for_stmt (prev)) = node;
730 DR_GROUP_NEXT_DR (vinfo_for_stmt (node)) = NULL_TREE;
731 prev = node;
733 DR_GROUP_FIRST_DR (vinfo_for_stmt (node)) = first_stmt;
734 node = DR_GROUP_NEXT_DR (vinfo_for_stmt (node));
739 /* Function vect_equal_offsets.
741 Check if OFFSET1 and OFFSET2 are identical expressions. */
743 static bool
744 vect_equal_offsets (tree offset1, tree offset2)
746 bool res0, res1;
748 STRIP_NOPS (offset1);
749 STRIP_NOPS (offset2);
751 if (offset1 == offset2)
752 return true;
754 if (TREE_CODE (offset1) != TREE_CODE (offset2)
755 || !BINARY_CLASS_P (offset1)
756 || !BINARY_CLASS_P (offset2))
757 return false;
759 res0 = vect_equal_offsets (TREE_OPERAND (offset1, 0),
760 TREE_OPERAND (offset2, 0));
761 res1 = vect_equal_offsets (TREE_OPERAND (offset1, 1),
762 TREE_OPERAND (offset2, 1));
764 return (res0 && res1);
768 /* Function vect_check_interleaving.
770 Check if DRA and DRB are a part of interleaving. In case they are, insert
771 DRA and DRB in an interleaving chain. */
773 static void
774 vect_check_interleaving (struct data_reference *dra,
775 struct data_reference *drb)
777 HOST_WIDE_INT type_size_a, type_size_b, diff_mod_size, step, init_a, init_b;
779 /* Check that the data-refs have same first location (except init) and they
780 are both either store or load (not load and store). */
781 if ((DR_BASE_ADDRESS (dra) != DR_BASE_ADDRESS (drb)
782 && (TREE_CODE (DR_BASE_ADDRESS (dra)) != ADDR_EXPR
783 || TREE_CODE (DR_BASE_ADDRESS (drb)) != ADDR_EXPR
784 || TREE_OPERAND (DR_BASE_ADDRESS (dra), 0)
785 != TREE_OPERAND (DR_BASE_ADDRESS (drb),0)))
786 || !vect_equal_offsets (DR_OFFSET (dra), DR_OFFSET (drb))
787 || !tree_int_cst_compare (DR_INIT (dra), DR_INIT (drb))
788 || DR_IS_READ (dra) != DR_IS_READ (drb))
789 return;
791 /* Check:
792 1. data-refs are of the same type
793 2. their steps are equal
794 3. the step is greater than the difference between data-refs' inits */
795 type_size_a = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (dra))));
796 type_size_b = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (drb))));
798 if (type_size_a != type_size_b
799 || tree_int_cst_compare (DR_STEP (dra), DR_STEP (drb)))
800 return;
802 init_a = TREE_INT_CST_LOW (DR_INIT (dra));
803 init_b = TREE_INT_CST_LOW (DR_INIT (drb));
804 step = TREE_INT_CST_LOW (DR_STEP (dra));
806 if (init_a > init_b)
808 /* If init_a == init_b + the size of the type * k, we have an interleaving,
809 and DRB is accessed before DRA. */
810 diff_mod_size = (init_a - init_b) % type_size_a;
812 if ((init_a - init_b) > step)
813 return;
815 if (diff_mod_size == 0)
817 vect_update_interleaving_chain (drb, dra);
818 if (vect_print_dump_info (REPORT_DR_DETAILS))
820 fprintf (vect_dump, "Detected interleaving ");
821 print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
822 fprintf (vect_dump, " and ");
823 print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
825 return;
828 else
830 /* If init_b == init_a + the size of the type * k, we have an
831 interleaving, and DRA is accessed before DRB. */
832 diff_mod_size = (init_b - init_a) % type_size_a;
834 if ((init_b - init_a) > step)
835 return;
837 if (diff_mod_size == 0)
839 vect_update_interleaving_chain (dra, drb);
840 if (vect_print_dump_info (REPORT_DR_DETAILS))
842 fprintf (vect_dump, "Detected interleaving ");
843 print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
844 fprintf (vect_dump, " and ");
845 print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
847 return;
853 /* Function vect_analyze_data_ref_dependence.
855 Return TRUE if there (might) exist a dependence between a memory-reference
856 DRA and a memory-reference DRB. */
858 static bool
859 vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
860 loop_vec_info loop_vinfo,
861 bool check_interleaving)
863 unsigned int i;
864 struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
865 int vectorization_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
866 struct data_reference *dra = DDR_A (ddr);
867 struct data_reference *drb = DDR_B (ddr);
868 stmt_vec_info stmtinfo_a = vinfo_for_stmt (DR_STMT (dra));
869 stmt_vec_info stmtinfo_b = vinfo_for_stmt (DR_STMT (drb));
870 int dra_size = GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (DR_REF (dra))));
871 int drb_size = GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (DR_REF (drb))));
872 lambda_vector dist_v;
873 unsigned int loop_depth;
875 if (DDR_ARE_DEPENDENT (ddr) == chrec_known)
877 /* Independent data accesses. */
878 if (check_interleaving)
879 vect_check_interleaving (dra, drb);
880 return false;
883 if ((DR_IS_READ (dra) && DR_IS_READ (drb)) || dra == drb)
884 return false;
886 if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know)
888 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
890 fprintf (vect_dump,
891 "not vectorized: can't determine dependence between ");
892 print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
893 fprintf (vect_dump, " and ");
894 print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
896 return true;
899 if (DDR_NUM_DIST_VECTS (ddr) == 0)
901 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
903 fprintf (vect_dump, "not vectorized: bad dist vector for ");
904 print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
905 fprintf (vect_dump, " and ");
906 print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
908 return true;
911 loop_depth = index_in_loop_nest (loop->num, DDR_LOOP_NEST (ddr));
912 for (i = 0; VEC_iterate (lambda_vector, DDR_DIST_VECTS (ddr), i, dist_v); i++)
914 int dist = dist_v[loop_depth];
916 if (vect_print_dump_info (REPORT_DR_DETAILS))
917 fprintf (vect_dump, "dependence distance = %d.", dist);
919 /* Same loop iteration. */
920 if (dist % vectorization_factor == 0 && dra_size == drb_size)
922 /* Two references with distance zero have the same alignment. */
923 VEC_safe_push (dr_p, heap, STMT_VINFO_SAME_ALIGN_REFS (stmtinfo_a), drb);
924 VEC_safe_push (dr_p, heap, STMT_VINFO_SAME_ALIGN_REFS (stmtinfo_b), dra);
925 if (vect_print_dump_info (REPORT_ALIGNMENT))
926 fprintf (vect_dump, "accesses have the same alignment.");
927 if (vect_print_dump_info (REPORT_DR_DETAILS))
929 fprintf (vect_dump, "dependence distance modulo vf == 0 between ");
930 print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
931 fprintf (vect_dump, " and ");
932 print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
934 continue;
937 if (abs (dist) >= vectorization_factor)
939 /* Dependence distance does not create dependence, as far as vectorization
940 is concerned, in this case. */
941 if (vect_print_dump_info (REPORT_DR_DETAILS))
942 fprintf (vect_dump, "dependence distance >= VF.");
943 continue;
946 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
948 fprintf (vect_dump,
949 "not vectorized: possible dependence between data-refs ");
950 print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
951 fprintf (vect_dump, " and ");
952 print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
955 return true;
958 return false;
962 /* Function vect_check_dependences.
964 Return TRUE if there is a store-store or load-store dependence between
965 data-refs in DDR, otherwise return FALSE. */
967 static bool
968 vect_check_dependences (struct data_dependence_relation *ddr)
970 struct data_reference *dra = DDR_A (ddr);
971 struct data_reference *drb = DDR_B (ddr);
973 if (DDR_ARE_DEPENDENT (ddr) == chrec_known || dra == drb)
974 /* Independent or same data accesses. */
975 return false;
977 if (DR_IS_READ (dra) == DR_IS_READ (drb) && DR_IS_READ (dra))
978 /* Two loads. */
979 return false;
981 if (vect_print_dump_info (REPORT_DR_DETAILS))
983 fprintf (vect_dump, "possible store or store/load dependence between ");
984 print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
985 fprintf (vect_dump, " and ");
986 print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
988 return true;
992 /* Function vect_analyze_data_ref_dependences.
994 Examine all the data references in the loop, and make sure there do not
995 exist any data dependences between them. */
997 static bool
998 vect_analyze_data_ref_dependences (loop_vec_info loop_vinfo)
1000 unsigned int i;
1001 VEC (ddr_p, heap) *ddrs = LOOP_VINFO_DDRS (loop_vinfo);
1002 struct data_dependence_relation *ddr;
1003 bool check_interleaving = true;
1005 if (vect_print_dump_info (REPORT_DETAILS))
1006 fprintf (vect_dump, "=== vect_analyze_dependences ===");
1008 /* We allow interleaving only if there are no store-store and load-store
1009 dependencies in the loop. */
1010 for (i = 0; VEC_iterate (ddr_p, ddrs, i, ddr); i++)
1012 if (vect_check_dependences (ddr))
1014 check_interleaving = false;
1015 break;
1019 for (i = 0; VEC_iterate (ddr_p, ddrs, i, ddr); i++)
1020 if (vect_analyze_data_ref_dependence (ddr, loop_vinfo, check_interleaving))
1021 return false;
1023 return true;
1027 /* Function vect_compute_data_ref_alignment
1029 Compute the misalignment of the data reference DR.
1031 Output:
1032 1. If during the misalignment computation it is found that the data reference
1033 cannot be vectorized then false is returned.
1034 2. DR_MISALIGNMENT (DR) is defined.
1036 FOR NOW: No analysis is actually performed. Misalignment is calculated
1037 only for trivial cases. TODO. */
1039 static bool
1040 vect_compute_data_ref_alignment (struct data_reference *dr)
1042 tree stmt = DR_STMT (dr);
1043 stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
1044 tree ref = DR_REF (dr);
1045 tree vectype;
1046 tree base, base_addr;
1047 bool base_aligned;
1048 tree misalign;
1049 tree aligned_to, alignment;
1051 if (vect_print_dump_info (REPORT_DETAILS))
1052 fprintf (vect_dump, "vect_compute_data_ref_alignment:");
1054 /* Initialize misalignment to unknown. */
1055 DR_MISALIGNMENT (dr) = -1;
1057 misalign = DR_OFFSET_MISALIGNMENT (dr);
1058 aligned_to = DR_ALIGNED_TO (dr);
1059 base_addr = DR_BASE_ADDRESS (dr);
1060 base = build_fold_indirect_ref (base_addr);
1061 vectype = STMT_VINFO_VECTYPE (stmt_info);
1062 alignment = ssize_int (TYPE_ALIGN (vectype)/BITS_PER_UNIT);
1064 if ((aligned_to && tree_int_cst_compare (aligned_to, alignment) < 0)
1065 || !misalign)
1067 if (vect_print_dump_info (REPORT_DETAILS))
1069 fprintf (vect_dump, "Unknown alignment for access: ");
1070 print_generic_expr (vect_dump, base, TDF_SLIM);
1072 return true;
1075 if ((DECL_P (base)
1076 && tree_int_cst_compare (ssize_int (DECL_ALIGN_UNIT (base)),
1077 alignment) >= 0)
1078 || (TREE_CODE (base_addr) == SSA_NAME
1079 && tree_int_cst_compare (ssize_int (TYPE_ALIGN_UNIT (TREE_TYPE (
1080 TREE_TYPE (base_addr)))),
1081 alignment) >= 0))
1082 base_aligned = true;
1083 else
1084 base_aligned = false;
1086 if (!base_aligned)
1088 /* Do not change the alignment of global variables if
1089 flag_section_anchors is enabled. */
1090 if (!vect_can_force_dr_alignment_p (base, TYPE_ALIGN (vectype))
1091 || (TREE_STATIC (base) && flag_section_anchors))
1093 if (vect_print_dump_info (REPORT_DETAILS))
1095 fprintf (vect_dump, "can't force alignment of ref: ");
1096 print_generic_expr (vect_dump, ref, TDF_SLIM);
1098 return true;
1101 /* Force the alignment of the decl.
1102 NOTE: This is the only change to the code we make during
1103 the analysis phase, before deciding to vectorize the loop. */
1104 if (vect_print_dump_info (REPORT_DETAILS))
1105 fprintf (vect_dump, "force alignment");
1106 DECL_ALIGN (base) = TYPE_ALIGN (vectype);
1107 DECL_USER_ALIGN (base) = 1;
1110 /* At this point we assume that the base is aligned. */
1111 gcc_assert (base_aligned
1112 || (TREE_CODE (base) == VAR_DECL
1113 && DECL_ALIGN (base) >= TYPE_ALIGN (vectype)));
1115 /* Modulo alignment. */
1116 misalign = size_binop (TRUNC_MOD_EXPR, misalign, alignment);
1118 if (!host_integerp (misalign, 1))
1120 /* Negative or overflowed misalignment value. */
1121 if (vect_print_dump_info (REPORT_DETAILS))
1122 fprintf (vect_dump, "unexpected misalign value");
1123 return false;
1126 DR_MISALIGNMENT (dr) = TREE_INT_CST_LOW (misalign);
1128 if (vect_print_dump_info (REPORT_DETAILS))
1130 fprintf (vect_dump, "misalign = %d bytes of ref ", DR_MISALIGNMENT (dr));
1131 print_generic_expr (vect_dump, ref, TDF_SLIM);
1134 return true;
1138 /* Function vect_compute_data_refs_alignment
1140 Compute the misalignment of data references in the loop.
1141 Return FALSE if a data reference is found that cannot be vectorized. */
1143 static bool
1144 vect_compute_data_refs_alignment (loop_vec_info loop_vinfo)
1146 VEC (data_reference_p, heap) *datarefs = LOOP_VINFO_DATAREFS (loop_vinfo);
1147 struct data_reference *dr;
1148 unsigned int i;
1150 for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++)
1151 if (!vect_compute_data_ref_alignment (dr))
1152 return false;
1154 return true;
1158 /* Function vect_update_misalignment_for_peel
1160 DR - the data reference whose misalignment is to be adjusted.
1161 DR_PEEL - the data reference whose misalignment is being made
1162 zero in the vector loop by the peel.
1163 NPEEL - the number of iterations in the peel loop if the misalignment
1164 of DR_PEEL is known at compile time. */
1166 static void
1167 vect_update_misalignment_for_peel (struct data_reference *dr,
1168 struct data_reference *dr_peel, int npeel)
1170 unsigned int i;
1171 VEC(dr_p,heap) *same_align_drs;
1172 struct data_reference *current_dr;
1173 int dr_size = GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (DR_REF (dr))));
1174 int dr_peel_size = GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (DR_REF (dr_peel))));
1175 stmt_vec_info stmt_info = vinfo_for_stmt (DR_STMT (dr));
1176 stmt_vec_info peel_stmt_info = vinfo_for_stmt (DR_STMT (dr_peel));
1178 /* For interleaved data accesses the step in the loop must be multiplied by
1179 the size of the interleaving group. */
1180 if (DR_GROUP_FIRST_DR (stmt_info))
1181 dr_size *= DR_GROUP_SIZE (vinfo_for_stmt (DR_GROUP_FIRST_DR (stmt_info)));
1182 if (DR_GROUP_FIRST_DR (peel_stmt_info))
1183 dr_peel_size *= DR_GROUP_SIZE (peel_stmt_info);
1185 if (known_alignment_for_access_p (dr)
1186 && known_alignment_for_access_p (dr_peel)
1187 && (DR_MISALIGNMENT (dr) / dr_size ==
1188 DR_MISALIGNMENT (dr_peel) / dr_peel_size))
1190 DR_MISALIGNMENT (dr) = 0;
1191 return;
1194 /* It can be assumed that the data refs with the same alignment as dr_peel
1195 are aligned in the vector loop. */
1196 same_align_drs
1197 = STMT_VINFO_SAME_ALIGN_REFS (vinfo_for_stmt (DR_STMT (dr_peel)));
1198 for (i = 0; VEC_iterate (dr_p, same_align_drs, i, current_dr); i++)
1200 if (current_dr != dr)
1201 continue;
1202 gcc_assert (DR_MISALIGNMENT (dr) / dr_size ==
1203 DR_MISALIGNMENT (dr_peel) / dr_peel_size);
1204 DR_MISALIGNMENT (dr) = 0;
1205 return;
1208 if (known_alignment_for_access_p (dr)
1209 && known_alignment_for_access_p (dr_peel))
1211 DR_MISALIGNMENT (dr) += npeel * dr_size;
1212 DR_MISALIGNMENT (dr) %= UNITS_PER_SIMD_WORD;
1213 return;
1216 if (vect_print_dump_info (REPORT_DETAILS))
1217 fprintf (vect_dump, "Setting misalignment to -1.");
1218 DR_MISALIGNMENT (dr) = -1;
1222 /* Function vect_verify_datarefs_alignment
1224 Return TRUE if all data references in the loop can be
1225 handled with respect to alignment. */
1227 static bool
1228 vect_verify_datarefs_alignment (loop_vec_info loop_vinfo)
1230 VEC (data_reference_p, heap) *datarefs = LOOP_VINFO_DATAREFS (loop_vinfo);
1231 struct data_reference *dr;
1232 enum dr_alignment_support supportable_dr_alignment;
1233 unsigned int i;
1235 for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++)
1237 tree stmt = DR_STMT (dr);
1238 stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
1240 /* For interleaving, only the alignment of the first access matters. */
1241 if (DR_GROUP_FIRST_DR (stmt_info)
1242 && DR_GROUP_FIRST_DR (stmt_info) != stmt)
1243 continue;
1245 supportable_dr_alignment = vect_supportable_dr_alignment (dr);
1246 if (!supportable_dr_alignment)
1248 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
1250 if (DR_IS_READ (dr))
1251 fprintf (vect_dump,
1252 "not vectorized: unsupported unaligned load.");
1253 else
1254 fprintf (vect_dump,
1255 "not vectorized: unsupported unaligned store.");
1257 return false;
1259 if (supportable_dr_alignment != dr_aligned
1260 && vect_print_dump_info (REPORT_ALIGNMENT))
1261 fprintf (vect_dump, "Vectorizing an unaligned access.");
1263 return true;
1267 /* Function vect_enhance_data_refs_alignment
1269 This pass will use loop versioning and loop peeling in order to enhance
1270 the alignment of data references in the loop.
1272 FOR NOW: we assume that whatever versioning/peeling takes place, only the
1273 original loop is to be vectorized; Any other loops that are created by
1274 the transformations performed in this pass - are not supposed to be
1275 vectorized. This restriction will be relaxed.
1277 This pass will require a cost model to guide it whether to apply peeling
1278 or versioning or a combination of the two. For example, the scheme that
1279 intel uses when given a loop with several memory accesses, is as follows:
1280 choose one memory access ('p') which alignment you want to force by doing
1281 peeling. Then, either (1) generate a loop in which 'p' is aligned and all
1282 other accesses are not necessarily aligned, or (2) use loop versioning to
1283 generate one loop in which all accesses are aligned, and another loop in
1284 which only 'p' is necessarily aligned.
1286 ("Automatic Intra-Register Vectorization for the Intel Architecture",
1287 Aart J.C. Bik, Milind Girkar, Paul M. Grey and Ximmin Tian, International
1288 Journal of Parallel Programming, Vol. 30, No. 2, April 2002.)
1290 Devising a cost model is the most critical aspect of this work. It will
1291 guide us on which access to peel for, whether to use loop versioning, how
1292 many versions to create, etc. The cost model will probably consist of
1293 generic considerations as well as target specific considerations (on
1294 powerpc for example, misaligned stores are more painful than misaligned
1295 loads).
1297 Here are the general steps involved in alignment enhancements:
1299 -- original loop, before alignment analysis:
1300 for (i=0; i<N; i++){
1301 x = q[i]; # DR_MISALIGNMENT(q) = unknown
1302 p[i] = y; # DR_MISALIGNMENT(p) = unknown
1305 -- After vect_compute_data_refs_alignment:
1306 for (i=0; i<N; i++){
1307 x = q[i]; # DR_MISALIGNMENT(q) = 3
1308 p[i] = y; # DR_MISALIGNMENT(p) = unknown
1311 -- Possibility 1: we do loop versioning:
1312 if (p is aligned) {
1313 for (i=0; i<N; i++){ # loop 1A
1314 x = q[i]; # DR_MISALIGNMENT(q) = 3
1315 p[i] = y; # DR_MISALIGNMENT(p) = 0
1318 else {
1319 for (i=0; i<N; i++){ # loop 1B
1320 x = q[i]; # DR_MISALIGNMENT(q) = 3
1321 p[i] = y; # DR_MISALIGNMENT(p) = unaligned
1325 -- Possibility 2: we do loop peeling:
1326 for (i = 0; i < 3; i++){ # (scalar loop, not to be vectorized).
1327 x = q[i];
1328 p[i] = y;
1330 for (i = 3; i < N; i++){ # loop 2A
1331 x = q[i]; # DR_MISALIGNMENT(q) = 0
1332 p[i] = y; # DR_MISALIGNMENT(p) = unknown
1335 -- Possibility 3: combination of loop peeling and versioning:
1336 for (i = 0; i < 3; i++){ # (scalar loop, not to be vectorized).
1337 x = q[i];
1338 p[i] = y;
1340 if (p is aligned) {
1341 for (i = 3; i<N; i++){ # loop 3A
1342 x = q[i]; # DR_MISALIGNMENT(q) = 0
1343 p[i] = y; # DR_MISALIGNMENT(p) = 0
1346 else {
1347 for (i = 3; i<N; i++){ # loop 3B
1348 x = q[i]; # DR_MISALIGNMENT(q) = 0
1349 p[i] = y; # DR_MISALIGNMENT(p) = unaligned
1353 These loops are later passed to loop_transform to be vectorized. The
1354 vectorizer will use the alignment information to guide the transformation
1355 (whether to generate regular loads/stores, or with special handling for
1356 misalignment). */
1358 static bool
1359 vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
1361 VEC (data_reference_p, heap) *datarefs = LOOP_VINFO_DATAREFS (loop_vinfo);
1362 enum dr_alignment_support supportable_dr_alignment;
1363 struct data_reference *dr0 = NULL;
1364 struct data_reference *dr;
1365 unsigned int i;
1366 bool do_peeling = false;
1367 bool do_versioning = false;
1368 bool stat;
1369 tree stmt;
1370 stmt_vec_info stmt_info;
1372 if (vect_print_dump_info (REPORT_DETAILS))
1373 fprintf (vect_dump, "=== vect_enhance_data_refs_alignment ===");
1375 /* While cost model enhancements are expected in the future, the high level
1376 view of the code at this time is as follows:
1378 A) If there is a misaligned write then see if peeling to align this write
1379 can make all data references satisfy vect_supportable_dr_alignment.
1380 If so, update data structures as needed and return true. Note that
1381 at this time vect_supportable_dr_alignment is known to return false
1382 for a a misaligned write.
1384 B) If peeling wasn't possible and there is a data reference with an
1385 unknown misalignment that does not satisfy vect_supportable_dr_alignment
1386 then see if loop versioning checks can be used to make all data
1387 references satisfy vect_supportable_dr_alignment. If so, update
1388 data structures as needed and return true.
1390 C) If neither peeling nor versioning were successful then return false if
1391 any data reference does not satisfy vect_supportable_dr_alignment.
1393 D) Return true (all data references satisfy vect_supportable_dr_alignment).
1395 Note, Possibility 3 above (which is peeling and versioning together) is not
1396 being done at this time. */
1398 /* (1) Peeling to force alignment. */
1400 /* (1.1) Decide whether to perform peeling, and how many iterations to peel:
1401 Considerations:
1402 + How many accesses will become aligned due to the peeling
1403 - How many accesses will become unaligned due to the peeling,
1404 and the cost of misaligned accesses.
1405 - The cost of peeling (the extra runtime checks, the increase
1406 in code size).
1408 The scheme we use FORNOW: peel to force the alignment of the first
1409 misaligned store in the loop.
1410 Rationale: misaligned stores are not yet supported.
1412 TODO: Use a cost model. */
1414 for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++)
1416 stmt = DR_STMT (dr);
1417 stmt_info = vinfo_for_stmt (stmt);
1419 /* For interleaving, only the alignment of the first access
1420 matters. */
1421 if (DR_GROUP_FIRST_DR (stmt_info)
1422 && DR_GROUP_FIRST_DR (stmt_info) != stmt)
1423 continue;
1425 if (!DR_IS_READ (dr) && !aligned_access_p (dr))
1427 if (DR_GROUP_FIRST_DR (stmt_info))
1429 /* For interleaved access we peel only if number of iterations in
1430 the prolog loop ({VF - misalignment}), is a multiple of the
1431 number of the interleaved accesses. */
1432 int elem_size, mis_in_elements;
1433 int vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
1435 /* FORNOW: handle only known alignment. */
1436 if (!known_alignment_for_access_p (dr))
1438 do_peeling = false;
1439 break;
1442 elem_size = UNITS_PER_SIMD_WORD / vf;
1443 mis_in_elements = DR_MISALIGNMENT (dr) / elem_size;
1445 if ((vf - mis_in_elements) % DR_GROUP_SIZE (stmt_info))
1447 do_peeling = false;
1448 break;
1451 dr0 = dr;
1452 do_peeling = true;
1453 break;
1457 /* Often peeling for alignment will require peeling for loop-bound, which in
1458 turn requires that we know how to adjust the loop ivs after the loop. */
1459 if (!vect_can_advance_ivs_p (loop_vinfo))
1460 do_peeling = false;
1462 if (do_peeling)
1464 int mis;
1465 int npeel = 0;
1467 if (known_alignment_for_access_p (dr0))
1469 /* Since it's known at compile time, compute the number of iterations
1470 in the peeled loop (the peeling factor) for use in updating
1471 DR_MISALIGNMENT values. The peeling factor is the vectorization
1472 factor minus the misalignment as an element count. */
1473 mis = DR_MISALIGNMENT (dr0);
1474 mis /= GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (DR_REF (dr0))));
1475 npeel = LOOP_VINFO_VECT_FACTOR (loop_vinfo) - mis;
1477 /* For interleaved data access every iteration accesses all the
1478 members of the group, therefore we divide the number of iterations
1479 by the group size. */
1480 stmt_info = vinfo_for_stmt (DR_STMT (dr0));
1481 if (DR_GROUP_FIRST_DR (stmt_info))
1482 npeel /= DR_GROUP_SIZE (stmt_info);
1484 if (vect_print_dump_info (REPORT_DETAILS))
1485 fprintf (vect_dump, "Try peeling by %d", npeel);
1488 /* Ensure that all data refs can be vectorized after the peel. */
1489 for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++)
1491 int save_misalignment;
1493 if (dr == dr0)
1494 continue;
1496 stmt = DR_STMT (dr);
1497 stmt_info = vinfo_for_stmt (stmt);
1498 /* For interleaving, only the alignment of the first access
1499 matters. */
1500 if (DR_GROUP_FIRST_DR (stmt_info)
1501 && DR_GROUP_FIRST_DR (stmt_info) != stmt)
1502 continue;
1504 save_misalignment = DR_MISALIGNMENT (dr);
1505 vect_update_misalignment_for_peel (dr, dr0, npeel);
1506 supportable_dr_alignment = vect_supportable_dr_alignment (dr);
1507 DR_MISALIGNMENT (dr) = save_misalignment;
1509 if (!supportable_dr_alignment)
1511 do_peeling = false;
1512 break;
1516 if (do_peeling)
1518 /* (1.2) Update the DR_MISALIGNMENT of each data reference DR_i.
1519 If the misalignment of DR_i is identical to that of dr0 then set
1520 DR_MISALIGNMENT (DR_i) to zero. If the misalignment of DR_i and
1521 dr0 are known at compile time then increment DR_MISALIGNMENT (DR_i)
1522 by the peeling factor times the element size of DR_i (MOD the
1523 vectorization factor times the size). Otherwise, the
1524 misalignment of DR_i must be set to unknown. */
1525 for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++)
1526 if (dr != dr0)
1527 vect_update_misalignment_for_peel (dr, dr0, npeel);
1529 LOOP_VINFO_UNALIGNED_DR (loop_vinfo) = dr0;
1530 LOOP_PEELING_FOR_ALIGNMENT (loop_vinfo) = DR_MISALIGNMENT (dr0);
1531 DR_MISALIGNMENT (dr0) = 0;
1532 if (vect_print_dump_info (REPORT_ALIGNMENT))
1533 fprintf (vect_dump, "Alignment of access forced using peeling.");
1535 if (vect_print_dump_info (REPORT_DETAILS))
1536 fprintf (vect_dump, "Peeling for alignment will be applied.");
1538 stat = vect_verify_datarefs_alignment (loop_vinfo);
1539 gcc_assert (stat);
1540 return stat;
1545 /* (2) Versioning to force alignment. */
1547 /* Try versioning if:
1548 1) flag_tree_vect_loop_version is TRUE
1549 2) optimize_size is FALSE
1550 3) there is at least one unsupported misaligned data ref with an unknown
1551 misalignment, and
1552 4) all misaligned data refs with a known misalignment are supported, and
1553 5) the number of runtime alignment checks is within reason. */
1555 do_versioning = flag_tree_vect_loop_version && (!optimize_size);
1557 if (do_versioning)
1559 for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++)
1561 stmt = DR_STMT (dr);
1562 stmt_info = vinfo_for_stmt (stmt);
1564 /* For interleaving, only the alignment of the first access
1565 matters. */
1566 if (aligned_access_p (dr)
1567 || (DR_GROUP_FIRST_DR (stmt_info)
1568 && DR_GROUP_FIRST_DR (stmt_info) != stmt))
1569 continue;
1571 supportable_dr_alignment = vect_supportable_dr_alignment (dr);
1573 if (!supportable_dr_alignment)
1575 tree stmt;
1576 int mask;
1577 tree vectype;
1579 if (known_alignment_for_access_p (dr)
1580 || VEC_length (tree,
1581 LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo))
1582 >= (unsigned) PARAM_VALUE (PARAM_VECT_MAX_VERSION_CHECKS))
1584 do_versioning = false;
1585 break;
1588 stmt = DR_STMT (dr);
1589 vectype = STMT_VINFO_VECTYPE (vinfo_for_stmt (stmt));
1590 gcc_assert (vectype);
1592 /* The rightmost bits of an aligned address must be zeros.
1593 Construct the mask needed for this test. For example,
1594 GET_MODE_SIZE for the vector mode V4SI is 16 bytes so the
1595 mask must be 15 = 0xf. */
1596 mask = GET_MODE_SIZE (TYPE_MODE (vectype)) - 1;
1598 /* FORNOW: use the same mask to test all potentially unaligned
1599 references in the loop. The vectorizer currently supports
1600 a single vector size, see the reference to
1601 GET_MODE_NUNITS (TYPE_MODE (vectype)) where the
1602 vectorization factor is computed. */
1603 gcc_assert (!LOOP_VINFO_PTR_MASK (loop_vinfo)
1604 || LOOP_VINFO_PTR_MASK (loop_vinfo) == mask);
1605 LOOP_VINFO_PTR_MASK (loop_vinfo) = mask;
1606 VEC_safe_push (tree, heap,
1607 LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo),
1608 DR_STMT (dr));
1612 /* Versioning requires at least one misaligned data reference. */
1613 if (VEC_length (tree, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo)) == 0)
1614 do_versioning = false;
1615 else if (!do_versioning)
1616 VEC_truncate (tree, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo), 0);
1619 if (do_versioning)
1621 VEC(tree,heap) *may_misalign_stmts
1622 = LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo);
1623 tree stmt;
1625 /* It can now be assumed that the data references in the statements
1626 in LOOP_VINFO_MAY_MISALIGN_STMTS will be aligned in the version
1627 of the loop being vectorized. */
1628 for (i = 0; VEC_iterate (tree, may_misalign_stmts, i, stmt); i++)
1630 stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
1631 dr = STMT_VINFO_DATA_REF (stmt_info);
1632 DR_MISALIGNMENT (dr) = 0;
1633 if (vect_print_dump_info (REPORT_ALIGNMENT))
1634 fprintf (vect_dump, "Alignment of access forced using versioning.");
1637 if (vect_print_dump_info (REPORT_DETAILS))
1638 fprintf (vect_dump, "Versioning for alignment will be applied.");
1640 /* Peeling and versioning can't be done together at this time. */
1641 gcc_assert (! (do_peeling && do_versioning));
1643 stat = vect_verify_datarefs_alignment (loop_vinfo);
1644 gcc_assert (stat);
1645 return stat;
1648 /* This point is reached if neither peeling nor versioning is being done. */
1649 gcc_assert (! (do_peeling || do_versioning));
1651 stat = vect_verify_datarefs_alignment (loop_vinfo);
1652 return stat;
1656 /* Function vect_analyze_data_refs_alignment
1658 Analyze the alignment of the data-references in the loop.
1659 Return FALSE if a data reference is found that cannot be vectorized. */
1661 static bool
1662 vect_analyze_data_refs_alignment (loop_vec_info loop_vinfo)
1664 if (vect_print_dump_info (REPORT_DETAILS))
1665 fprintf (vect_dump, "=== vect_analyze_data_refs_alignment ===");
1667 if (!vect_compute_data_refs_alignment (loop_vinfo))
1669 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
1670 fprintf (vect_dump,
1671 "not vectorized: can't calculate alignment for data ref.");
1672 return false;
1675 return true;
1679 /* Function vect_analyze_data_ref_access.
1681 Analyze the access pattern of the data-reference DR. For now, a data access
1682 has to be consecutive to be considered vectorizable. */
1684 static bool
1685 vect_analyze_data_ref_access (struct data_reference *dr)
1687 tree step = DR_STEP (dr);
1688 HOST_WIDE_INT dr_step = TREE_INT_CST_LOW (step);
1689 tree scalar_type = TREE_TYPE (DR_REF (dr));
1690 HOST_WIDE_INT type_size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (scalar_type));
1691 tree stmt = DR_STMT (dr);
1692 /* For interleaving, STRIDE is STEP counted in elements, i.e., the size of the
1693 interleaving group (including gaps). */
1694 HOST_WIDE_INT stride = dr_step / type_size;
1696 if (!step)
1698 if (vect_print_dump_info (REPORT_DETAILS))
1699 fprintf (vect_dump, "bad data-ref access");
1700 return false;
1703 /* Consecutive? */
1704 if (!tree_int_cst_compare (step, TYPE_SIZE_UNIT (scalar_type)))
1706 /* Mark that it is not interleaving. */
1707 DR_GROUP_FIRST_DR (vinfo_for_stmt (stmt)) = NULL_TREE;
1708 return true;
1711 /* Not consecutive access is possible only if it is a part of interleaving. */
1712 if (!DR_GROUP_FIRST_DR (vinfo_for_stmt (stmt)))
1714 /* Check if it this DR is a part of interleaving, and is a single
1715 element of the group that is accessed in the loop. */
1717 /* Gaps are supported only for loads. STEP must be a multiple of the type
1718 size. The size of the group must be a power of 2. */
1719 if (DR_IS_READ (dr)
1720 && (dr_step % type_size) == 0
1721 && stride > 0
1722 && exact_log2 (stride) != -1)
1724 DR_GROUP_FIRST_DR (vinfo_for_stmt (stmt)) = stmt;
1725 DR_GROUP_SIZE (vinfo_for_stmt (stmt)) = stride;
1726 if (vect_print_dump_info (REPORT_DR_DETAILS))
1728 fprintf (vect_dump, "Detected single element interleaving %d ",
1729 DR_GROUP_SIZE (vinfo_for_stmt (stmt)));
1730 print_generic_expr (vect_dump, DR_REF (dr), TDF_SLIM);
1731 fprintf (vect_dump, " step ");
1732 print_generic_expr (vect_dump, step, TDF_SLIM);
1734 return true;
1736 if (vect_print_dump_info (REPORT_DETAILS))
1737 fprintf (vect_dump, "not consecutive access");
1738 return false;
1741 if (DR_GROUP_FIRST_DR (vinfo_for_stmt (stmt)) == stmt)
1743 /* First stmt in the interleaving chain. Check the chain. */
1744 tree next = DR_GROUP_NEXT_DR (vinfo_for_stmt (stmt));
1745 struct data_reference *data_ref = dr;
1746 unsigned int count = 1;
1747 tree next_step;
1748 tree prev_init = DR_INIT (data_ref);
1749 tree prev = stmt;
1750 HOST_WIDE_INT diff, count_in_bytes;
1752 while (next)
1754 /* Skip same data-refs. In case that two or more stmts share data-ref
1755 (supported only for loads), we vectorize only the first stmt, and
1756 the rest get their vectorized loads from the the first one. */
1757 if (!tree_int_cst_compare (DR_INIT (data_ref),
1758 DR_INIT (STMT_VINFO_DATA_REF (
1759 vinfo_for_stmt (next)))))
1761 /* For load use the same data-ref load. (We check in
1762 vect_check_dependences() that there are no two stores to the
1763 same location). */
1764 DR_GROUP_SAME_DR_STMT (vinfo_for_stmt (next)) = prev;
1766 prev = next;
1767 next = DR_GROUP_NEXT_DR (vinfo_for_stmt (next));
1768 continue;
1770 prev = next;
1772 /* Check that all the accesses have the same STEP. */
1773 next_step = DR_STEP (STMT_VINFO_DATA_REF (vinfo_for_stmt (next)));
1774 if (tree_int_cst_compare (step, next_step))
1776 if (vect_print_dump_info (REPORT_DETAILS))
1777 fprintf (vect_dump, "not consecutive access in interleaving");
1778 return false;
1781 data_ref = STMT_VINFO_DATA_REF (vinfo_for_stmt (next));
1782 /* Check that the distance between two accesses is equal to the type
1783 size. Otherwise, we have gaps. */
1784 diff = (TREE_INT_CST_LOW (DR_INIT (data_ref))
1785 - TREE_INT_CST_LOW (prev_init)) / type_size;
1786 if (!DR_IS_READ (data_ref) && diff != 1)
1788 if (vect_print_dump_info (REPORT_DETAILS))
1789 fprintf (vect_dump, "interleaved store with gaps");
1790 return false;
1792 /* Store the gap from the previous member of the group. If there is no
1793 gap in the access, DR_GROUP_GAP is always 1. */
1794 DR_GROUP_GAP (vinfo_for_stmt (next)) = diff;
1796 prev_init = DR_INIT (data_ref);
1797 next = DR_GROUP_NEXT_DR (vinfo_for_stmt (next));
1798 /* Count the number of data-refs in the chain. */
1799 count++;
1802 /* COUNT is the number of accesses found, we multiply it by the size of
1803 the type to get COUNT_IN_BYTES. */
1804 count_in_bytes = type_size * count;
1805 /* Check the size of the interleaving is not greater than STEP. */
1806 if (dr_step < count_in_bytes)
1808 if (vect_print_dump_info (REPORT_DETAILS))
1810 fprintf (vect_dump, "interleaving size is greater than step for ");
1811 print_generic_expr (vect_dump, DR_REF (dr), TDF_SLIM);
1813 return false;
1816 /* Check that STEP is a multiple of type size. */
1817 if ((dr_step % type_size) != 0)
1819 if (vect_print_dump_info (REPORT_DETAILS))
1821 fprintf (vect_dump, "step is not a multiple of type size: step ");
1822 print_generic_expr (vect_dump, step, TDF_SLIM);
1823 fprintf (vect_dump, " size ");
1824 print_generic_expr (vect_dump, TYPE_SIZE_UNIT (scalar_type),
1825 TDF_SLIM);
1827 return false;
1830 /* FORNOW: we handle only interleaving that is a power of 2. */
1831 if (exact_log2 (stride) == -1)
1833 if (vect_print_dump_info (REPORT_DETAILS))
1834 fprintf (vect_dump, "interleaving is not a power of 2");
1835 return false;
1837 DR_GROUP_SIZE (vinfo_for_stmt (stmt)) = stride;
1839 return true;
1843 /* Function vect_analyze_data_ref_accesses.
1845 Analyze the access pattern of all the data references in the loop.
1847 FORNOW: the only access pattern that is considered vectorizable is a
1848 simple step 1 (consecutive) access.
1850 FORNOW: handle only arrays and pointer accesses. */
1852 static bool
1853 vect_analyze_data_ref_accesses (loop_vec_info loop_vinfo)
1855 unsigned int i;
1856 VEC (data_reference_p, heap) *datarefs = LOOP_VINFO_DATAREFS (loop_vinfo);
1857 struct data_reference *dr;
1859 if (vect_print_dump_info (REPORT_DETAILS))
1860 fprintf (vect_dump, "=== vect_analyze_data_ref_accesses ===");
1862 for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++)
1863 if (!vect_analyze_data_ref_access (dr))
1865 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
1866 fprintf (vect_dump, "not vectorized: complicated access pattern.");
1867 return false;
1870 return true;
1874 /* Function vect_analyze_data_refs.
1876 Find all the data references in the loop.
1878 The general structure of the analysis of data refs in the vectorizer is as
1879 follows:
1880 1- vect_analyze_data_refs(loop): call compute_data_dependences_for_loop to
1881 find and analyze all data-refs in the loop and their dependences.
1882 2- vect_analyze_dependences(): apply dependence testing using ddrs.
1883 3- vect_analyze_drs_alignment(): check that ref_stmt.alignment is ok.
1884 4- vect_analyze_drs_access(): check that ref_stmt.step is ok.
1888 static bool
1889 vect_analyze_data_refs (loop_vec_info loop_vinfo)
1891 struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
1892 unsigned int i;
1893 VEC (data_reference_p, heap) *datarefs;
1894 struct data_reference *dr;
1895 tree scalar_type;
1897 if (vect_print_dump_info (REPORT_DETAILS))
1898 fprintf (vect_dump, "=== vect_analyze_data_refs ===");
1900 compute_data_dependences_for_loop (loop, true,
1901 &LOOP_VINFO_DATAREFS (loop_vinfo),
1902 &LOOP_VINFO_DDRS (loop_vinfo));
1904 /* Go through the data-refs, check that the analysis succeeded. Update pointer
1905 from stmt_vec_info struct to DR and vectype. */
1906 datarefs = LOOP_VINFO_DATAREFS (loop_vinfo);
1908 for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++)
1910 tree stmt;
1911 stmt_vec_info stmt_info;
1913 if (!dr || !DR_REF (dr))
1915 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
1916 fprintf (vect_dump, "not vectorized: unhandled data-ref ");
1917 return false;
1920 /* Update DR field in stmt_vec_info struct. */
1921 stmt = DR_STMT (dr);
1922 stmt_info = vinfo_for_stmt (stmt);
1924 if (STMT_VINFO_DATA_REF (stmt_info))
1926 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
1928 fprintf (vect_dump,
1929 "not vectorized: more than one data ref in stmt: ");
1930 print_generic_expr (vect_dump, stmt, TDF_SLIM);
1932 return false;
1934 STMT_VINFO_DATA_REF (stmt_info) = dr;
1936 /* Check that analysis of the data-ref succeeded. */
1937 if (!DR_BASE_ADDRESS (dr) || !DR_OFFSET (dr) || !DR_INIT (dr)
1938 || !DR_STEP (dr))
1940 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
1942 fprintf (vect_dump, "not vectorized: data ref analysis failed ");
1943 print_generic_expr (vect_dump, stmt, TDF_SLIM);
1945 return false;
1947 if (!DR_MEMTAG (dr))
1949 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
1951 fprintf (vect_dump, "not vectorized: no memory tag for ");
1952 print_generic_expr (vect_dump, DR_REF (dr), TDF_SLIM);
1954 return false;
1957 /* Set vectype for STMT. */
1958 scalar_type = TREE_TYPE (DR_REF (dr));
1959 STMT_VINFO_VECTYPE (stmt_info) =
1960 get_vectype_for_scalar_type (scalar_type);
1961 if (!STMT_VINFO_VECTYPE (stmt_info))
1963 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
1965 fprintf (vect_dump,
1966 "not vectorized: no vectype for stmt: ");
1967 print_generic_expr (vect_dump, stmt, TDF_SLIM);
1968 fprintf (vect_dump, " scalar_type: ");
1969 print_generic_expr (vect_dump, scalar_type, TDF_DETAILS);
1971 return false;
1975 return true;
1979 /* Utility functions used by vect_mark_stmts_to_be_vectorized. */
1981 /* Function vect_mark_relevant.
1983 Mark STMT as "relevant for vectorization" and add it to WORKLIST. */
1985 static void
1986 vect_mark_relevant (VEC(tree,heap) **worklist, tree stmt,
1987 enum vect_relevant relevant, bool live_p)
1989 stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
1990 enum vect_relevant save_relevant = STMT_VINFO_RELEVANT (stmt_info);
1991 bool save_live_p = STMT_VINFO_LIVE_P (stmt_info);
1993 if (vect_print_dump_info (REPORT_DETAILS))
1994 fprintf (vect_dump, "mark relevant %d, live %d.", relevant, live_p);
1996 if (STMT_VINFO_IN_PATTERN_P (stmt_info))
1998 tree pattern_stmt;
2000 /* This is the last stmt in a sequence that was detected as a
2001 pattern that can potentially be vectorized. Don't mark the stmt
2002 as relevant/live because it's not going to vectorized.
2003 Instead mark the pattern-stmt that replaces it. */
2004 if (vect_print_dump_info (REPORT_DETAILS))
2005 fprintf (vect_dump, "last stmt in pattern. don't mark relevant/live.");
2006 pattern_stmt = STMT_VINFO_RELATED_STMT (stmt_info);
2007 stmt_info = vinfo_for_stmt (pattern_stmt);
2008 gcc_assert (STMT_VINFO_RELATED_STMT (stmt_info) == stmt);
2009 save_relevant = STMT_VINFO_RELEVANT (stmt_info);
2010 save_live_p = STMT_VINFO_LIVE_P (stmt_info);
2011 stmt = pattern_stmt;
2014 STMT_VINFO_LIVE_P (stmt_info) |= live_p;
2015 if (relevant > STMT_VINFO_RELEVANT (stmt_info))
2016 STMT_VINFO_RELEVANT (stmt_info) = relevant;
2018 if (TREE_CODE (stmt) == PHI_NODE)
2019 /* Don't put phi-nodes in the worklist. Phis that are marked relevant
2020 or live will fail vectorization later on. */
2021 return;
2023 if (STMT_VINFO_RELEVANT (stmt_info) == save_relevant
2024 && STMT_VINFO_LIVE_P (stmt_info) == save_live_p)
2026 if (vect_print_dump_info (REPORT_DETAILS))
2027 fprintf (vect_dump, "already marked relevant/live.");
2028 return;
2031 VEC_safe_push (tree, heap, *worklist, stmt);
2035 /* Function vect_stmt_relevant_p.
2037 Return true if STMT in loop that is represented by LOOP_VINFO is
2038 "relevant for vectorization".
2040 A stmt is considered "relevant for vectorization" if:
2041 - it has uses outside the loop.
2042 - it has vdefs (it alters memory).
2043 - control stmts in the loop (except for the exit condition).
2045 CHECKME: what other side effects would the vectorizer allow? */
2047 static bool
2048 vect_stmt_relevant_p (tree stmt, loop_vec_info loop_vinfo,
2049 enum vect_relevant *relevant, bool *live_p)
2051 struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
2052 ssa_op_iter op_iter;
2053 imm_use_iterator imm_iter;
2054 use_operand_p use_p;
2055 def_operand_p def_p;
2057 *relevant = vect_unused_in_loop;
2058 *live_p = false;
2060 /* cond stmt other than loop exit cond. */
2061 if (is_ctrl_stmt (stmt) && (stmt != LOOP_VINFO_EXIT_COND (loop_vinfo)))
2062 *relevant = vect_used_in_loop;
2064 /* changing memory. */
2065 if (TREE_CODE (stmt) != PHI_NODE)
2066 if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_VIRTUAL_DEFS))
2068 if (vect_print_dump_info (REPORT_DETAILS))
2069 fprintf (vect_dump, "vec_stmt_relevant_p: stmt has vdefs.");
2070 *relevant = vect_used_in_loop;
2073 /* uses outside the loop. */
2074 FOR_EACH_PHI_OR_STMT_DEF (def_p, stmt, op_iter, SSA_OP_DEF)
2076 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, DEF_FROM_PTR (def_p))
2078 basic_block bb = bb_for_stmt (USE_STMT (use_p));
2079 if (!flow_bb_inside_loop_p (loop, bb))
2081 if (vect_print_dump_info (REPORT_DETAILS))
2082 fprintf (vect_dump, "vec_stmt_relevant_p: used out of loop.");
2084 /* We expect all such uses to be in the loop exit phis
2085 (because of loop closed form) */
2086 gcc_assert (TREE_CODE (USE_STMT (use_p)) == PHI_NODE);
2087 gcc_assert (bb == single_exit (loop)->dest);
2089 *live_p = true;
2094 return (*live_p || *relevant);
2098 /* Function vect_mark_stmts_to_be_vectorized.
2100 Not all stmts in the loop need to be vectorized. For example:
2102 for i...
2103 for j...
2104 1. T0 = i + j
2105 2. T1 = a[T0]
2107 3. j = j + 1
2109 Stmt 1 and 3 do not need to be vectorized, because loop control and
2110 addressing of vectorized data-refs are handled differently.
2112 This pass detects such stmts. */
2114 static bool
2115 vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo)
2117 VEC(tree,heap) *worklist;
2118 struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
2119 basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
2120 unsigned int nbbs = loop->num_nodes;
2121 block_stmt_iterator si;
2122 tree stmt, use;
2123 stmt_ann_t ann;
2124 ssa_op_iter iter;
2125 unsigned int i;
2126 stmt_vec_info stmt_vinfo;
2127 basic_block bb;
2128 tree phi;
2129 bool live_p;
2130 enum vect_relevant relevant;
2131 tree def, def_stmt;
2132 enum vect_def_type dt;
2134 if (vect_print_dump_info (REPORT_DETAILS))
2135 fprintf (vect_dump, "=== vect_mark_stmts_to_be_vectorized ===");
2137 worklist = VEC_alloc (tree, heap, 64);
2139 /* 1. Init worklist. */
2141 bb = loop->header;
2142 for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
2144 if (vect_print_dump_info (REPORT_DETAILS))
2146 fprintf (vect_dump, "init: phi relevant? ");
2147 print_generic_expr (vect_dump, phi, TDF_SLIM);
2150 if (vect_stmt_relevant_p (phi, loop_vinfo, &relevant, &live_p))
2151 vect_mark_relevant (&worklist, phi, relevant, live_p);
2154 for (i = 0; i < nbbs; i++)
2156 bb = bbs[i];
2157 for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
2159 stmt = bsi_stmt (si);
2161 if (vect_print_dump_info (REPORT_DETAILS))
2163 fprintf (vect_dump, "init: stmt relevant? ");
2164 print_generic_expr (vect_dump, stmt, TDF_SLIM);
2167 if (vect_stmt_relevant_p (stmt, loop_vinfo, &relevant, &live_p))
2168 vect_mark_relevant (&worklist, stmt, relevant, live_p);
2173 /* 2. Process_worklist */
2175 while (VEC_length (tree, worklist) > 0)
2177 stmt = VEC_pop (tree, worklist);
2179 if (vect_print_dump_info (REPORT_DETAILS))
2181 fprintf (vect_dump, "worklist: examine stmt: ");
2182 print_generic_expr (vect_dump, stmt, TDF_SLIM);
2185 /* Examine the USEs of STMT. For each ssa-name USE that is defined
2186 in the loop, mark the stmt that defines it (DEF_STMT) as
2187 relevant/irrelevant and live/dead according to the liveness and
2188 relevance properties of STMT.
2191 gcc_assert (TREE_CODE (stmt) != PHI_NODE);
2193 ann = stmt_ann (stmt);
2194 stmt_vinfo = vinfo_for_stmt (stmt);
2196 relevant = STMT_VINFO_RELEVANT (stmt_vinfo);
2197 live_p = STMT_VINFO_LIVE_P (stmt_vinfo);
2199 /* Generally, the liveness and relevance properties of STMT are
2200 propagated to the DEF_STMTs of its USEs:
2201 STMT_VINFO_LIVE_P (DEF_STMT_info) <-- live_p
2202 STMT_VINFO_RELEVANT (DEF_STMT_info) <-- relevant
2204 Exceptions:
2206 (case 1)
2207 If USE is used only for address computations (e.g. array indexing),
2208 which does not need to be directly vectorized, then the
2209 liveness/relevance of the respective DEF_STMT is left unchanged.
2211 (case 2)
2212 If STMT has been identified as defining a reduction variable, then
2213 we have two cases:
2214 (case 2.1)
2215 The last use of STMT is the reduction-variable, which is defined
2216 by a loop-header-phi. We don't want to mark the phi as live or
2217 relevant (because it does not need to be vectorized, it is handled
2218 as part of the vectorization of the reduction), so in this case we
2219 skip the call to vect_mark_relevant.
2220 (case 2.2)
2221 The rest of the uses of STMT are defined in the loop body. For
2222 the def_stmt of these uses we want to set liveness/relevance
2223 as follows:
2224 STMT_VINFO_LIVE_P (DEF_STMT_info) <-- false
2225 STMT_VINFO_RELEVANT (DEF_STMT_info) <-- vect_used_by_reduction
2226 because even though STMT is classified as live (since it defines a
2227 value that is used across loop iterations) and irrelevant (since it
2228 is not used inside the loop), it will be vectorized, and therefore
2229 the corresponding DEF_STMTs need to marked as relevant.
2230 We distinguish between two kinds of relevant stmts - those that are
2231 used by a reduction computation, and those that are (also) used by
2232 a regular computation. This allows us later on to identify stmts
2233 that are used solely by a reduction, and therefore the order of
2234 the results that they produce does not have to be kept.
2237 /* case 2.2: */
2238 if (STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_reduction_def)
2240 gcc_assert (relevant == vect_unused_in_loop && live_p);
2241 relevant = vect_used_by_reduction;
2242 live_p = false;
2245 FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
2247 /* case 1: we are only interested in uses that need to be vectorized.
2248 Uses that are used for address computation are not considered
2249 relevant.
2251 if (!exist_non_indexing_operands_for_use_p (use, stmt))
2252 continue;
2254 if (!vect_is_simple_use (use, loop_vinfo, &def_stmt, &def, &dt))
2256 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
2257 fprintf (vect_dump, "not vectorized: unsupported use in stmt.");
2258 VEC_free (tree, heap, worklist);
2259 return false;
2262 if (!def_stmt || IS_EMPTY_STMT (def_stmt))
2263 continue;
2265 if (vect_print_dump_info (REPORT_DETAILS))
2267 fprintf (vect_dump, "worklist: examine use %d: ", i);
2268 print_generic_expr (vect_dump, use, TDF_SLIM);
2271 bb = bb_for_stmt (def_stmt);
2272 if (!flow_bb_inside_loop_p (loop, bb))
2273 continue;
2275 /* case 2.1: the reduction-use does not mark the defining-phi
2276 as relevant. */
2277 if (STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_reduction_def
2278 && TREE_CODE (def_stmt) == PHI_NODE)
2279 continue;
2281 vect_mark_relevant (&worklist, def_stmt, relevant, live_p);
2283 } /* while worklist */
2285 VEC_free (tree, heap, worklist);
2286 return true;
2290 /* Function vect_can_advance_ivs_p
2292 In case the number of iterations that LOOP iterates is unknown at compile
2293 time, an epilog loop will be generated, and the loop induction variables
2294 (IVs) will be "advanced" to the value they are supposed to take just before
2295 the epilog loop. Here we check that the access function of the loop IVs
2296 and the expression that represents the loop bound are simple enough.
2297 These restrictions will be relaxed in the future. */
2299 static bool
2300 vect_can_advance_ivs_p (loop_vec_info loop_vinfo)
2302 struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
2303 basic_block bb = loop->header;
2304 tree phi;
2306 /* Analyze phi functions of the loop header. */
2308 if (vect_print_dump_info (REPORT_DETAILS))
2309 fprintf (vect_dump, "vect_can_advance_ivs_p:");
2311 for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
2313 tree access_fn = NULL;
2314 tree evolution_part;
2316 if (vect_print_dump_info (REPORT_DETAILS))
2318 fprintf (vect_dump, "Analyze phi: ");
2319 print_generic_expr (vect_dump, phi, TDF_SLIM);
2322 /* Skip virtual phi's. The data dependences that are associated with
2323 virtual defs/uses (i.e., memory accesses) are analyzed elsewhere. */
2325 if (!is_gimple_reg (SSA_NAME_VAR (PHI_RESULT (phi))))
2327 if (vect_print_dump_info (REPORT_DETAILS))
2328 fprintf (vect_dump, "virtual phi. skip.");
2329 continue;
2332 /* Skip reduction phis. */
2334 if (STMT_VINFO_DEF_TYPE (vinfo_for_stmt (phi)) == vect_reduction_def)
2336 if (vect_print_dump_info (REPORT_DETAILS))
2337 fprintf (vect_dump, "reduc phi. skip.");
2338 continue;
2341 /* Analyze the evolution function. */
2343 access_fn = instantiate_parameters
2344 (loop, analyze_scalar_evolution (loop, PHI_RESULT (phi)));
2346 if (!access_fn)
2348 if (vect_print_dump_info (REPORT_DETAILS))
2349 fprintf (vect_dump, "No Access function.");
2350 return false;
2353 if (vect_print_dump_info (REPORT_DETAILS))
2355 fprintf (vect_dump, "Access function of PHI: ");
2356 print_generic_expr (vect_dump, access_fn, TDF_SLIM);
2359 evolution_part = evolution_part_in_loop_num (access_fn, loop->num);
2361 if (evolution_part == NULL_TREE)
2363 if (vect_print_dump_info (REPORT_DETAILS))
2364 fprintf (vect_dump, "No evolution.");
2365 return false;
2368 /* FORNOW: We do not transform initial conditions of IVs
2369 which evolution functions are a polynomial of degree >= 2. */
2371 if (tree_is_chrec (evolution_part))
2372 return false;
2375 return true;
2379 /* Function vect_get_loop_niters.
2381 Determine how many iterations the loop is executed.
2382 If an expression that represents the number of iterations
2383 can be constructed, place it in NUMBER_OF_ITERATIONS.
2384 Return the loop exit condition. */
2386 static tree
2387 vect_get_loop_niters (struct loop *loop, tree *number_of_iterations)
2389 tree niters;
2391 if (vect_print_dump_info (REPORT_DETAILS))
2392 fprintf (vect_dump, "=== get_loop_niters ===");
2394 niters = number_of_iterations_in_loop (loop);
2396 if (niters != NULL_TREE
2397 && niters != chrec_dont_know)
2399 *number_of_iterations = niters;
2401 if (vect_print_dump_info (REPORT_DETAILS))
2403 fprintf (vect_dump, "==> get_loop_niters:" );
2404 print_generic_expr (vect_dump, *number_of_iterations, TDF_SLIM);
2408 return get_loop_exit_condition (loop);
2412 /* Function vect_analyze_loop_form.
2414 Verify the following restrictions (some may be relaxed in the future):
2415 - it's an inner-most loop
2416 - number of BBs = 2 (which are the loop header and the latch)
2417 - the loop has a pre-header
2418 - the loop has a single entry and exit
2419 - the loop exit condition is simple enough, and the number of iterations
2420 can be analyzed (a countable loop). */
2422 static loop_vec_info
2423 vect_analyze_loop_form (struct loop *loop)
2425 loop_vec_info loop_vinfo;
2426 tree loop_cond;
2427 tree number_of_iterations = NULL;
2429 if (vect_print_dump_info (REPORT_DETAILS))
2430 fprintf (vect_dump, "=== vect_analyze_loop_form ===");
2432 if (loop->inner)
2434 if (vect_print_dump_info (REPORT_OUTER_LOOPS))
2435 fprintf (vect_dump, "not vectorized: nested loop.");
2436 return NULL;
2439 if (!single_exit (loop)
2440 || loop->num_nodes != 2
2441 || EDGE_COUNT (loop->header->preds) != 2)
2443 if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
2445 if (!single_exit (loop))
2446 fprintf (vect_dump, "not vectorized: multiple exits.");
2447 else if (loop->num_nodes != 2)
2448 fprintf (vect_dump, "not vectorized: too many BBs in loop.");
2449 else if (EDGE_COUNT (loop->header->preds) != 2)
2450 fprintf (vect_dump, "not vectorized: too many incoming edges.");
2453 return NULL;
2456 /* We assume that the loop exit condition is at the end of the loop. i.e,
2457 that the loop is represented as a do-while (with a proper if-guard
2458 before the loop if needed), where the loop header contains all the
2459 executable statements, and the latch is empty. */
2460 if (!empty_block_p (loop->latch)
2461 || phi_nodes (loop->latch))
2463 if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
2464 fprintf (vect_dump, "not vectorized: unexpected loop form.");
2465 return NULL;
2468 /* Make sure there exists a single-predecessor exit bb: */
2469 if (!single_pred_p (single_exit (loop)->dest))
2471 edge e = single_exit (loop);
2472 if (!(e->flags & EDGE_ABNORMAL))
2474 split_loop_exit_edge (e);
2475 if (vect_print_dump_info (REPORT_DETAILS))
2476 fprintf (vect_dump, "split exit edge.");
2478 else
2480 if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
2481 fprintf (vect_dump, "not vectorized: abnormal loop exit edge.");
2482 return NULL;
2486 if (empty_block_p (loop->header))
2488 if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
2489 fprintf (vect_dump, "not vectorized: empty loop.");
2490 return NULL;
2493 loop_cond = vect_get_loop_niters (loop, &number_of_iterations);
2494 if (!loop_cond)
2496 if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
2497 fprintf (vect_dump, "not vectorized: complicated exit condition.");
2498 return NULL;
2501 if (!number_of_iterations)
2503 if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
2504 fprintf (vect_dump,
2505 "not vectorized: number of iterations cannot be computed.");
2506 return NULL;
2509 if (chrec_contains_undetermined (number_of_iterations))
2511 if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
2512 fprintf (vect_dump, "Infinite number of iterations.");
2513 return false;
2516 loop_vinfo = new_loop_vec_info (loop);
2517 LOOP_VINFO_NITERS (loop_vinfo) = number_of_iterations;
2519 if (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo))
2521 if (vect_print_dump_info (REPORT_DETAILS))
2523 fprintf (vect_dump, "Symbolic number of iterations is ");
2524 print_generic_expr (vect_dump, number_of_iterations, TDF_DETAILS);
2527 else
2528 if (LOOP_VINFO_INT_NITERS (loop_vinfo) == 0)
2530 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
2531 fprintf (vect_dump, "not vectorized: number of iterations = 0.");
2532 return NULL;
2535 LOOP_VINFO_EXIT_COND (loop_vinfo) = loop_cond;
2537 return loop_vinfo;
2541 /* Function vect_analyze_loop.
2543 Apply a set of analyses on LOOP, and create a loop_vec_info struct
2544 for it. The different analyses will record information in the
2545 loop_vec_info struct. */
2546 loop_vec_info
2547 vect_analyze_loop (struct loop *loop)
2549 bool ok;
2550 loop_vec_info loop_vinfo;
2552 if (vect_print_dump_info (REPORT_DETAILS))
2553 fprintf (vect_dump, "===== analyze_loop_nest =====");
2555 /* Check the CFG characteristics of the loop (nesting, entry/exit, etc. */
2557 loop_vinfo = vect_analyze_loop_form (loop);
2558 if (!loop_vinfo)
2560 if (vect_print_dump_info (REPORT_DETAILS))
2561 fprintf (vect_dump, "bad loop form.");
2562 return NULL;
2565 /* Find all data references in the loop (which correspond to vdefs/vuses)
2566 and analyze their evolution in the loop.
2568 FORNOW: Handle only simple, array references, which
2569 alignment can be forced, and aligned pointer-references. */
2571 ok = vect_analyze_data_refs (loop_vinfo);
2572 if (!ok)
2574 if (vect_print_dump_info (REPORT_DETAILS))
2575 fprintf (vect_dump, "bad data references.");
2576 destroy_loop_vec_info (loop_vinfo);
2577 return NULL;
2580 /* Classify all cross-iteration scalar data-flow cycles.
2581 Cross-iteration cycles caused by virtual phis are analyzed separately. */
2583 vect_analyze_scalar_cycles (loop_vinfo);
2585 vect_pattern_recog (loop_vinfo);
2587 /* Data-flow analysis to detect stmts that do not need to be vectorized. */
2589 ok = vect_mark_stmts_to_be_vectorized (loop_vinfo);
2590 if (!ok)
2592 if (vect_print_dump_info (REPORT_DETAILS))
2593 fprintf (vect_dump, "unexpected pattern.");
2594 destroy_loop_vec_info (loop_vinfo);
2595 return NULL;
2598 /* Analyze the alignment of the data-refs in the loop.
2599 Fail if a data reference is found that cannot be vectorized. */
2601 ok = vect_analyze_data_refs_alignment (loop_vinfo);
2602 if (!ok)
2604 if (vect_print_dump_info (REPORT_DETAILS))
2605 fprintf (vect_dump, "bad data alignment.");
2606 destroy_loop_vec_info (loop_vinfo);
2607 return NULL;
2610 ok = vect_determine_vectorization_factor (loop_vinfo);
2611 if (!ok)
2613 if (vect_print_dump_info (REPORT_DETAILS))
2614 fprintf (vect_dump, "can't determine vectorization factor.");
2615 destroy_loop_vec_info (loop_vinfo);
2616 return NULL;
2619 /* Analyze data dependences between the data-refs in the loop.
2620 FORNOW: fail at the first data dependence that we encounter. */
2622 ok = vect_analyze_data_ref_dependences (loop_vinfo);
2623 if (!ok)
2625 if (vect_print_dump_info (REPORT_DETAILS))
2626 fprintf (vect_dump, "bad data dependence.");
2627 destroy_loop_vec_info (loop_vinfo);
2628 return NULL;
2631 /* Analyze the access patterns of the data-refs in the loop (consecutive,
2632 complex, etc.). FORNOW: Only handle consecutive access pattern. */
2634 ok = vect_analyze_data_ref_accesses (loop_vinfo);
2635 if (!ok)
2637 if (vect_print_dump_info (REPORT_DETAILS))
2638 fprintf (vect_dump, "bad data access.");
2639 destroy_loop_vec_info (loop_vinfo);
2640 return NULL;
2643 /* This pass will decide on using loop versioning and/or loop peeling in
2644 order to enhance the alignment of data references in the loop. */
2646 ok = vect_enhance_data_refs_alignment (loop_vinfo);
2647 if (!ok)
2649 if (vect_print_dump_info (REPORT_DETAILS))
2650 fprintf (vect_dump, "bad data alignment.");
2651 destroy_loop_vec_info (loop_vinfo);
2652 return NULL;
2655 /* Scan all the operations in the loop and make sure they are
2656 vectorizable. */
2658 ok = vect_analyze_operations (loop_vinfo);
2659 if (!ok)
2661 if (vect_print_dump_info (REPORT_DETAILS))
2662 fprintf (vect_dump, "bad operation or unsupported loop bound.");
2663 destroy_loop_vec_info (loop_vinfo);
2664 return NULL;
2667 LOOP_VINFO_VECTORIZABLE_P (loop_vinfo) = 1;
2669 return loop_vinfo;