2005-03-29 Paul Brook <paul@codesourcery.com>
[official-gcc.git] / gcc / tree-vect-analyze.c
blobf3144e1af5779bacd55c564740e38729d4d03f98
1 /* Analysis Utilities for Loop Vectorization.
2 Copyright (C) 2003,2004,2005 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, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA. */
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "errors.h"
27 #include "ggc.h"
28 #include "tree.h"
29 #include "basic-block.h"
30 #include "diagnostic.h"
31 #include "tree-flow.h"
32 #include "tree-dump.h"
33 #include "timevar.h"
34 #include "cfgloop.h"
35 #include "expr.h"
36 #include "optabs.h"
37 #include "tree-chrec.h"
38 #include "tree-data-ref.h"
39 #include "tree-scalar-evolution.h"
40 #include "tree-vectorizer.h"
42 /* Main analysis functions. */
43 static loop_vec_info vect_analyze_loop_form (struct loop *);
44 static bool vect_analyze_data_refs (loop_vec_info);
45 static bool vect_mark_stmts_to_be_vectorized (loop_vec_info);
46 static bool vect_analyze_scalar_cycles (loop_vec_info);
47 static bool vect_analyze_data_ref_accesses (loop_vec_info);
48 static bool vect_analyze_data_ref_dependences (loop_vec_info);
49 static bool vect_analyze_data_refs_alignment (loop_vec_info);
50 static bool vect_compute_data_refs_alignment (loop_vec_info);
51 static void vect_enhance_data_refs_alignment (loop_vec_info);
52 static bool vect_analyze_operations (loop_vec_info);
53 static bool vect_determine_vectorization_factor (loop_vec_info);
55 /* Utility functions for the analyses. */
56 static bool exist_non_indexing_operands_for_use_p (tree, tree);
57 static void vect_mark_relevant (varray_type *, tree);
58 static bool vect_stmt_relevant_p (tree, loop_vec_info);
59 static tree vect_get_loop_niters (struct loop *, tree *);
60 static bool vect_analyze_data_ref_dependence
61 (struct data_reference *, struct data_reference *, loop_vec_info);
62 static bool vect_compute_data_ref_alignment (struct data_reference *);
63 static bool vect_analyze_data_ref_access (struct data_reference *);
64 static struct data_reference * vect_analyze_pointer_ref_access
65 (tree, tree, bool, tree, tree *, tree *);
66 static bool vect_can_advance_ivs_p (loop_vec_info);
67 static tree vect_get_ptr_offset (tree, tree, tree *);
68 static bool vect_analyze_offset_expr (tree, struct loop *, tree, tree *,
69 tree *, tree *);
70 static bool vect_base_addr_differ_p (struct data_reference *,
71 struct data_reference *drb, bool *);
72 static tree vect_object_analysis (tree, tree, bool, tree,
73 struct data_reference **, tree *, tree *,
74 tree *, bool *, tree *, subvar_t *);
75 static tree vect_address_analysis (tree, tree, bool, tree,
76 struct data_reference *, tree *, tree *,
77 tree *, bool *);
80 /* Function vect_get_ptr_offset
82 Compute the OFFSET modulo vector-type alignment of pointer REF in bits. */
84 static tree
85 vect_get_ptr_offset (tree ref ATTRIBUTE_UNUSED,
86 tree vectype ATTRIBUTE_UNUSED,
87 tree *offset ATTRIBUTE_UNUSED)
89 /* TODO: Use alignment information. */
90 return NULL_TREE;
94 /* Function vect_analyze_offset_expr
96 Given an offset expression EXPR received from get_inner_reference, analyze
97 it and create an expression for INITIAL_OFFSET by substituting the variables
98 of EXPR with initial_condition of the corresponding access_fn in the loop.
99 E.g.,
100 for i
101 for (j = 3; j < N; j++)
102 a[j].b[i][j] = 0;
104 For a[j].b[i][j], EXPR will be 'i * C_i + j * C_j + C'. 'i' cannot be
105 substituted, since its access_fn in the inner loop is i. 'j' will be
106 substituted with 3. An INITIAL_OFFSET will be 'i * C_i + C`', where
107 C` = 3 * C_j + C.
109 Compute MISALIGN (the misalignment of the data reference initial access from
110 its base) if possible. Misalignment can be calculated only if all the
111 variables can be substituted with constants, or if a variable is multiplied
112 by a multiple of VECTYPE_ALIGNMENT. In the above example, since 'i' cannot
113 be substituted, MISALIGN will be NULL_TREE in case that C_i is not a multiple
114 of VECTYPE_ALIGNMENT, and C` otherwise. (We perform MISALIGN modulo
115 VECTYPE_ALIGNMENT computation in the caller of this function).
117 STEP is an evolution of the data reference in this loop in bytes.
118 In the above example, STEP is C_j.
120 Return FALSE, if the analysis fails, e.g., there is no access_fn for a
121 variable. In this case, all the outputs (INITIAL_OFFSET, MISALIGN and STEP)
122 are NULL_TREEs. Otherwise, return TRUE.
126 static bool
127 vect_analyze_offset_expr (tree expr,
128 struct loop *loop,
129 tree vectype_alignment,
130 tree *initial_offset,
131 tree *misalign,
132 tree *step)
134 tree oprnd0;
135 tree oprnd1;
136 tree left_offset = ssize_int (0);
137 tree right_offset = ssize_int (0);
138 tree left_misalign = ssize_int (0);
139 tree right_misalign = ssize_int (0);
140 tree left_step = ssize_int (0);
141 tree right_step = ssize_int (0);
142 enum tree_code code;
143 tree init, evolution;
145 *step = NULL_TREE;
146 *misalign = NULL_TREE;
147 *initial_offset = NULL_TREE;
149 /* Strip conversions that don't narrow the mode. */
150 expr = vect_strip_conversion (expr);
151 if (!expr)
152 return false;
154 /* Stop conditions:
155 1. Constant. */
156 if (TREE_CODE (expr) == INTEGER_CST)
158 *initial_offset = fold_convert (ssizetype, expr);
159 *misalign = fold_convert (ssizetype, expr);
160 *step = ssize_int (0);
161 return true;
164 /* 2. Variable. Try to substitute with initial_condition of the corresponding
165 access_fn in the current loop. */
166 if (SSA_VAR_P (expr))
168 tree access_fn = analyze_scalar_evolution (loop, expr);
170 if (access_fn == chrec_dont_know)
171 /* No access_fn. */
172 return false;
174 init = initial_condition_in_loop_num (access_fn, loop->num);
175 if (init == expr && !expr_invariant_in_loop_p (loop, init))
176 /* Not enough information: may be not loop invariant.
177 E.g., for a[b[i]], we get a[D], where D=b[i]. EXPR is D, its
178 initial_condition is D, but it depends on i - loop's induction
179 variable. */
180 return false;
182 evolution = evolution_part_in_loop_num (access_fn, loop->num);
183 if (evolution && TREE_CODE (evolution) != INTEGER_CST)
184 /* Evolution is not constant. */
185 return false;
187 if (TREE_CODE (init) == INTEGER_CST)
188 *misalign = fold_convert (ssizetype, init);
189 else
190 /* Not constant, misalignment cannot be calculated. */
191 *misalign = NULL_TREE;
193 *initial_offset = fold_convert (ssizetype, init);
195 *step = evolution ? fold_convert (ssizetype, evolution) : ssize_int (0);
196 return true;
199 /* Recursive computation. */
200 if (!BINARY_CLASS_P (expr))
202 /* We expect to get binary expressions (PLUS/MINUS and MULT). */
203 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
205 fprintf (vect_dump, "Not binary expression ");
206 print_generic_expr (vect_dump, expr, TDF_SLIM);
208 return false;
210 oprnd0 = TREE_OPERAND (expr, 0);
211 oprnd1 = TREE_OPERAND (expr, 1);
213 if (!vect_analyze_offset_expr (oprnd0, loop, vectype_alignment, &left_offset,
214 &left_misalign, &left_step)
215 || !vect_analyze_offset_expr (oprnd1, loop, vectype_alignment,
216 &right_offset, &right_misalign, &right_step))
217 return false;
219 /* The type of the operation: plus, minus or mult. */
220 code = TREE_CODE (expr);
221 switch (code)
223 case MULT_EXPR:
224 if (TREE_CODE (right_offset) != INTEGER_CST)
225 /* RIGHT_OFFSET can be not constant. For example, for arrays of variable
226 sized types.
227 FORNOW: We don't support such cases. */
228 return false;
230 /* Strip conversions that don't narrow the mode. */
231 left_offset = vect_strip_conversion (left_offset);
232 if (!left_offset)
233 return false;
234 /* Misalignment computation. */
235 if (SSA_VAR_P (left_offset))
237 /* If the left side contains variables that can't be substituted with
238 constants, we check if the right side is a multiple of ALIGNMENT.
240 if (integer_zerop (size_binop (TRUNC_MOD_EXPR, right_offset,
241 fold_convert (ssizetype, vectype_alignment))))
242 *misalign = ssize_int (0);
243 else
244 /* If the remainder is not zero or the right side isn't constant,
245 we can't compute misalignment. */
246 *misalign = NULL_TREE;
248 else
250 /* The left operand was successfully substituted with constant. */
251 if (left_misalign)
252 /* In case of EXPR '(i * C1 + j) * C2', LEFT_MISALIGN is
253 NULL_TREE. */
254 *misalign = size_binop (code, left_misalign, right_misalign);
255 else
256 *misalign = NULL_TREE;
259 /* Step calculation. */
260 /* Multiply the step by the right operand. */
261 *step = size_binop (MULT_EXPR, left_step, right_offset);
262 break;
264 case PLUS_EXPR:
265 case MINUS_EXPR:
266 /* Combine the recursive calculations for step and misalignment. */
267 *step = size_binop (code, left_step, right_step);
269 if (left_misalign && right_misalign)
270 *misalign = size_binop (code, left_misalign, right_misalign);
271 else
272 *misalign = NULL_TREE;
274 break;
276 default:
277 gcc_unreachable ();
280 /* Compute offset. */
281 *initial_offset = fold_convert (ssizetype,
282 fold (build2 (code, TREE_TYPE (left_offset),
283 left_offset,
284 right_offset)));
285 return true;
289 /* Function vect_determine_vectorization_factor
291 Determine the vectorization factor (VF). VF is the number of data elements
292 that are operated upon in parallel in a single iteration of the vectorized
293 loop. For example, when vectorizing a loop that operates on 4byte elements,
294 on a target with vector size (VS) 16byte, the VF is set to 4, since 4
295 elements can fit in a single vector register.
297 We currently support vectorization of loops in which all types operated upon
298 are of the same size. Therefore this function currently sets VF according to
299 the size of the types operated upon, and fails if there are multiple sizes
300 in the loop.
302 VF is also the factor by which the loop iterations are strip-mined, e.g.:
303 original loop:
304 for (i=0; i<N; i++){
305 a[i] = b[i] + c[i];
308 vectorized loop:
309 for (i=0; i<N; i+=VF){
310 a[i:VF] = b[i:VF] + c[i:VF];
314 static bool
315 vect_determine_vectorization_factor (loop_vec_info loop_vinfo)
317 struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
318 basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
319 int nbbs = loop->num_nodes;
320 block_stmt_iterator si;
321 unsigned int vectorization_factor = 0;
322 int i;
323 tree scalar_type;
325 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
326 fprintf (vect_dump, "=== vect_determine_vectorization_factor ===");
328 for (i = 0; i < nbbs; i++)
330 basic_block bb = bbs[i];
332 for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
334 tree stmt = bsi_stmt (si);
335 unsigned int nunits;
336 stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
337 tree vectype;
339 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
341 fprintf (vect_dump, "==> examining statement: ");
342 print_generic_expr (vect_dump, stmt, TDF_SLIM);
345 gcc_assert (stmt_info);
346 /* skip stmts which do not need to be vectorized. */
347 if (!STMT_VINFO_RELEVANT_P (stmt_info))
348 continue;
350 if (VECTOR_MODE_P (TYPE_MODE (TREE_TYPE (stmt))))
352 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
353 LOOP_LOC (loop_vinfo)))
355 fprintf (vect_dump, "not vectorized: vector stmt in loop:");
356 print_generic_expr (vect_dump, stmt, TDF_SLIM);
358 return false;
361 if (STMT_VINFO_DATA_REF (stmt_info))
362 scalar_type = TREE_TYPE (DR_REF (STMT_VINFO_DATA_REF (stmt_info)));
363 else if (TREE_CODE (stmt) == MODIFY_EXPR)
364 scalar_type = TREE_TYPE (TREE_OPERAND (stmt, 0));
365 else
366 scalar_type = TREE_TYPE (stmt);
368 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
370 fprintf (vect_dump, "get vectype for scalar type: ");
371 print_generic_expr (vect_dump, scalar_type, TDF_SLIM);
374 vectype = get_vectype_for_scalar_type (scalar_type);
375 if (!vectype)
377 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
378 LOOP_LOC (loop_vinfo)))
380 fprintf (vect_dump, "not vectorized: unsupported data-type ");
381 print_generic_expr (vect_dump, scalar_type, TDF_SLIM);
383 return false;
385 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
387 fprintf (vect_dump, "vectype: ");
388 print_generic_expr (vect_dump, vectype, TDF_SLIM);
390 STMT_VINFO_VECTYPE (stmt_info) = vectype;
392 nunits = GET_MODE_NUNITS (TYPE_MODE (vectype));
393 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
394 fprintf (vect_dump, "nunits = %d", nunits);
396 if (vectorization_factor)
398 /* FORNOW: don't allow mixed units.
399 This restriction will be relaxed in the future. */
400 if (nunits != vectorization_factor)
402 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
403 LOOP_LOC (loop_vinfo)))
404 fprintf (vect_dump, "not vectorized: mixed data-types");
405 return false;
408 else
409 vectorization_factor = nunits;
411 #ifdef ENABLE_CHECKING
412 gcc_assert (GET_MODE_SIZE (TYPE_MODE (scalar_type))
413 * vectorization_factor == UNITS_PER_SIMD_WORD);
414 #endif
418 /* TODO: Analyze cost. Decide if worth while to vectorize. */
420 if (vectorization_factor <= 1)
422 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
423 LOOP_LOC (loop_vinfo)))
424 fprintf (vect_dump, "not vectorized: unsupported data-type");
425 return false;
427 LOOP_VINFO_VECT_FACTOR (loop_vinfo) = vectorization_factor;
429 return true;
433 /* Function vect_analyze_operations.
435 Scan the loop stmts and make sure they are all vectorizable. */
437 static bool
438 vect_analyze_operations (loop_vec_info loop_vinfo)
440 struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
441 basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
442 int nbbs = loop->num_nodes;
443 block_stmt_iterator si;
444 unsigned int vectorization_factor = 0;
445 int i;
446 bool ok;
448 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
449 fprintf (vect_dump, "=== vect_analyze_operations ===");
451 gcc_assert (LOOP_VINFO_VECT_FACTOR (loop_vinfo));
452 vectorization_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
454 for (i = 0; i < nbbs; i++)
456 basic_block bb = bbs[i];
458 for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
460 tree stmt = bsi_stmt (si);
461 stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
463 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
465 fprintf (vect_dump, "==> examining statement: ");
466 print_generic_expr (vect_dump, stmt, TDF_SLIM);
469 gcc_assert (stmt_info);
471 /* skip stmts which do not need to be vectorized.
472 this is expected to include:
473 - the COND_EXPR which is the loop exit condition
474 - any LABEL_EXPRs in the loop
475 - computations that are used only for array indexing or loop
476 control */
478 if (!STMT_VINFO_RELEVANT_P (stmt_info))
480 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
481 fprintf (vect_dump, "irrelevant.");
482 continue;
485 #ifdef ENABLE_CHECKING
486 if (STMT_VINFO_RELEVANT_P (stmt_info))
488 gcc_assert (!VECTOR_MODE_P (TYPE_MODE (TREE_TYPE (stmt))));
489 gcc_assert (STMT_VINFO_VECTYPE (stmt_info));
491 #endif
493 ok = (vectorizable_operation (stmt, NULL, NULL)
494 || vectorizable_assignment (stmt, NULL, NULL)
495 || vectorizable_load (stmt, NULL, NULL)
496 || vectorizable_store (stmt, NULL, NULL));
498 if (!ok)
500 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
501 LOOP_LOC (loop_vinfo)))
503 fprintf (vect_dump, "not vectorized: stmt not supported: ");
504 print_generic_expr (vect_dump, stmt, TDF_SLIM);
506 return false;
511 /* TODO: Analyze cost. Decide if worth while to vectorize. */
513 if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
514 && vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
515 fprintf (vect_dump,
516 "vectorization_factor = %d, niters = " HOST_WIDE_INT_PRINT_DEC,
517 vectorization_factor, LOOP_VINFO_INT_NITERS (loop_vinfo));
519 if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
520 && LOOP_VINFO_INT_NITERS (loop_vinfo) < vectorization_factor)
522 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
523 LOOP_LOC (loop_vinfo)))
524 fprintf (vect_dump, "not vectorized: iteration count too small.");
525 return false;
528 if (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
529 || LOOP_VINFO_INT_NITERS (loop_vinfo) % vectorization_factor != 0)
531 if (vect_print_dump_info (REPORT_DETAILS, LOOP_LOC (loop_vinfo)))
532 fprintf (vect_dump, "epilog loop required.");
533 if (!vect_can_advance_ivs_p (loop_vinfo))
535 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
536 LOOP_LOC (loop_vinfo)))
537 fprintf (vect_dump,
538 "not vectorized: can't create epilog loop 1.");
539 return false;
541 if (!slpeel_can_duplicate_loop_p (loop, loop->single_exit))
543 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
544 LOOP_LOC (loop_vinfo)))
545 fprintf (vect_dump,
546 "not vectorized: can't create epilog loop 2.");
547 return false;
551 return true;
555 /* Function exist_non_indexing_operands_for_use_p
557 USE is one of the uses attached to STMT. Check if USE is
558 used in STMT for anything other than indexing an array. */
560 static bool
561 exist_non_indexing_operands_for_use_p (tree use, tree stmt)
563 tree operand;
564 stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
566 /* USE corresponds to some operand in STMT. If there is no data
567 reference in STMT, then any operand that corresponds to USE
568 is not indexing an array. */
569 if (!STMT_VINFO_DATA_REF (stmt_info))
570 return true;
572 /* STMT has a data_ref. FORNOW this means that its of one of
573 the following forms:
574 -1- ARRAY_REF = var
575 -2- var = ARRAY_REF
576 (This should have been verified in analyze_data_refs).
578 'var' in the second case corresponds to a def, not a use,
579 so USE cannot correspond to any operands that are not used
580 for array indexing.
582 Therefore, all we need to check is if STMT falls into the
583 first case, and whether var corresponds to USE. */
585 if (TREE_CODE (TREE_OPERAND (stmt, 0)) == SSA_NAME)
586 return false;
588 operand = TREE_OPERAND (stmt, 1);
590 if (TREE_CODE (operand) != SSA_NAME)
591 return false;
593 if (operand == use)
594 return true;
596 return false;
600 /* Function vect_analyze_scalar_cycles.
602 Examine the cross iteration def-use cycles of scalar variables, by
603 analyzing the loop (scalar) PHIs; verify that the cross iteration def-use
604 cycles that they represent do not impede vectorization.
606 FORNOW: Reduction as in the following loop, is not supported yet:
607 loop1:
608 for (i=0; i<N; i++)
609 sum += a[i];
610 The cross-iteration cycle corresponding to variable 'sum' will be
611 considered too complicated and will impede vectorization.
613 FORNOW: Induction as in the following loop, is not supported yet:
614 loop2:
615 for (i=0; i<N; i++)
616 a[i] = i;
618 However, the following loop *is* vectorizable:
619 loop3:
620 for (i=0; i<N; i++)
621 a[i] = b[i];
623 In both loops there exists a def-use cycle for the variable i:
624 loop: i_2 = PHI (i_0, i_1)
625 a[i_2] = ...;
626 i_1 = i_2 + 1;
627 GOTO loop;
629 The evolution of the above cycle is considered simple enough,
630 however, we also check that the cycle does not need to be
631 vectorized, i.e - we check that the variable that this cycle
632 defines is only used for array indexing or in stmts that do not
633 need to be vectorized. This is not the case in loop2, but it
634 *is* the case in loop3. */
636 static bool
637 vect_analyze_scalar_cycles (loop_vec_info loop_vinfo)
639 tree phi;
640 struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
641 basic_block bb = loop->header;
642 tree dummy;
644 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
645 fprintf (vect_dump, "=== vect_analyze_scalar_cycles ===");
647 for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
649 tree access_fn = NULL;
651 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
653 fprintf (vect_dump, "Analyze phi: ");
654 print_generic_expr (vect_dump, phi, TDF_SLIM);
657 /* Skip virtual phi's. The data dependences that are associated with
658 virtual defs/uses (i.e., memory accesses) are analyzed elsewhere. */
660 if (!is_gimple_reg (SSA_NAME_VAR (PHI_RESULT (phi))))
662 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
663 fprintf (vect_dump, "virtual phi. skip.");
664 continue;
667 /* Analyze the evolution function. */
669 /* FORNOW: The only scalar cross-iteration cycles that we allow are
670 those of loop induction variables; This property is verified here.
672 Furthermore, if that induction variable is used in an operation
673 that needs to be vectorized (i.e, is not solely used to index
674 arrays and check the exit condition) - we do not support its
675 vectorization yet. This property is verified in vect_is_simple_use,
676 during vect_analyze_operations. */
678 access_fn = /* instantiate_parameters
679 (loop,*/
680 analyze_scalar_evolution (loop, PHI_RESULT (phi));
682 if (!access_fn)
684 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
685 LOOP_LOC (loop_vinfo)))
686 fprintf (vect_dump, "not vectorized: unsupported scalar cycle.");
687 return false;
690 if (vect_print_dump_info (REPORT_DETAILS,
691 LOOP_LOC (loop_vinfo)))
693 fprintf (vect_dump, "Access function of PHI: ");
694 print_generic_expr (vect_dump, access_fn, TDF_SLIM);
697 if (!vect_is_simple_iv_evolution (loop->num, access_fn, &dummy, &dummy))
699 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
700 LOOP_LOC (loop_vinfo)))
701 fprintf (vect_dump, "not vectorized: unsupported scalar cycle.");
702 return false;
706 return true;
710 /* Function vect_base_addr_differ_p.
712 This is the simplest data dependence test: determines whether the
713 data references A and B access the same array/region. Returns
714 false when the property is not computable at compile time.
715 Otherwise return true, and DIFFER_P will record the result. This
716 utility will not be necessary when alias_sets_conflict_p will be
717 less conservative. */
719 static bool
720 vect_base_addr_differ_p (struct data_reference *dra,
721 struct data_reference *drb,
722 bool *differ_p)
724 tree stmt_a = DR_STMT (dra);
725 stmt_vec_info stmt_info_a = vinfo_for_stmt (stmt_a);
726 tree stmt_b = DR_STMT (drb);
727 stmt_vec_info stmt_info_b = vinfo_for_stmt (stmt_b);
728 tree addr_a = STMT_VINFO_VECT_DR_BASE_ADDRESS (stmt_info_a);
729 tree addr_b = STMT_VINFO_VECT_DR_BASE_ADDRESS (stmt_info_b);
730 tree type_a = TREE_TYPE (addr_a);
731 tree type_b = TREE_TYPE (addr_b);
732 HOST_WIDE_INT alias_set_a, alias_set_b;
734 gcc_assert (POINTER_TYPE_P (type_a) && POINTER_TYPE_P (type_b));
736 /* Both references are ADDR_EXPR, i.e., we have the objects. */
737 if (TREE_CODE (addr_a) == ADDR_EXPR && TREE_CODE (addr_b) == ADDR_EXPR)
738 return array_base_name_differ_p (dra, drb, differ_p);
740 alias_set_a = (TREE_CODE (addr_a) == ADDR_EXPR) ?
741 get_alias_set (TREE_OPERAND (addr_a, 0)) : get_alias_set (addr_a);
742 alias_set_b = (TREE_CODE (addr_b) == ADDR_EXPR) ?
743 get_alias_set (TREE_OPERAND (addr_b, 0)) : get_alias_set (addr_b);
745 if (!alias_sets_conflict_p (alias_set_a, alias_set_b))
747 *differ_p = true;
748 return true;
751 /* An instruction writing through a restricted pointer is "independent" of any
752 instruction reading or writing through a different pointer, in the same
753 block/scope. */
754 else if ((TYPE_RESTRICT (type_a) && !DR_IS_READ (dra))
755 || (TYPE_RESTRICT (type_b) && !DR_IS_READ (drb)))
757 *differ_p = true;
758 return true;
760 return false;
764 /* Function vect_analyze_data_ref_dependence.
766 Return TRUE if there (might) exist a dependence between a memory-reference
767 DRA and a memory-reference DRB. */
769 static bool
770 vect_analyze_data_ref_dependence (struct data_reference *dra,
771 struct data_reference *drb,
772 loop_vec_info loop_vinfo)
774 bool differ_p;
775 struct data_dependence_relation *ddr;
777 if (!vect_base_addr_differ_p (dra, drb, &differ_p))
779 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
780 LOOP_LOC (loop_vinfo)))
782 fprintf (vect_dump,
783 "not vectorized: can't determine dependence between: ");
784 print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
785 fprintf (vect_dump, " and ");
786 print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
788 return true;
791 if (differ_p)
792 return false;
794 ddr = initialize_data_dependence_relation (dra, drb);
795 compute_affine_dependence (ddr);
797 if (DDR_ARE_DEPENDENT (ddr) == chrec_known)
798 return false;
800 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
801 LOOP_LOC (loop_vinfo)))
803 fprintf (vect_dump,
804 "not vectorized: possible dependence between data-refs ");
805 print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
806 fprintf (vect_dump, " and ");
807 print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
810 return true;
814 /* Function vect_analyze_data_ref_dependences.
816 Examine all the data references in the loop, and make sure there do not
817 exist any data dependences between them.
819 TODO: dependences which distance is greater than the vectorization factor
820 can be ignored. */
822 static bool
823 vect_analyze_data_ref_dependences (loop_vec_info loop_vinfo)
825 unsigned int i, j;
826 varray_type loop_write_refs = LOOP_VINFO_DATAREF_WRITES (loop_vinfo);
827 varray_type loop_read_refs = LOOP_VINFO_DATAREF_READS (loop_vinfo);
829 /* Examine store-store (output) dependences. */
831 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
832 fprintf (vect_dump, "=== vect_analyze_dependences ===");
834 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
835 fprintf (vect_dump, "compare all store-store pairs.");
837 for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_write_refs); i++)
839 for (j = i + 1; j < VARRAY_ACTIVE_SIZE (loop_write_refs); j++)
841 struct data_reference *dra =
842 VARRAY_GENERIC_PTR (loop_write_refs, i);
843 struct data_reference *drb =
844 VARRAY_GENERIC_PTR (loop_write_refs, j);
845 if (vect_analyze_data_ref_dependence (dra, drb, loop_vinfo))
846 return false;
850 /* Examine load-store (true/anti) dependences. */
852 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
853 fprintf (vect_dump, "compare all load-store pairs.");
855 for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_read_refs); i++)
857 for (j = 0; j < VARRAY_ACTIVE_SIZE (loop_write_refs); j++)
859 struct data_reference *dra = VARRAY_GENERIC_PTR (loop_read_refs, i);
860 struct data_reference *drb =
861 VARRAY_GENERIC_PTR (loop_write_refs, j);
862 if (vect_analyze_data_ref_dependence (dra, drb, loop_vinfo))
863 return false;
867 return true;
871 /* Function vect_compute_data_ref_alignment
873 Compute the misalignment of the data reference DR.
875 Output:
876 1. If during the misalignment computation it is found that the data reference
877 cannot be vectorized then false is returned.
878 2. DR_MISALIGNMENT (DR) is defined.
880 FOR NOW: No analysis is actually performed. Misalignment is calculated
881 only for trivial cases. TODO. */
883 static bool
884 vect_compute_data_ref_alignment (struct data_reference *dr)
886 tree stmt = DR_STMT (dr);
887 stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
888 tree ref = DR_REF (dr);
889 tree vectype;
890 tree base, alignment;
891 bool base_aligned_p;
892 tree misalign;
894 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
895 fprintf (vect_dump, "vect_compute_data_ref_alignment:");
897 /* Initialize misalignment to unknown. */
898 DR_MISALIGNMENT (dr) = -1;
900 misalign = STMT_VINFO_VECT_MISALIGNMENT (stmt_info);
901 base_aligned_p = STMT_VINFO_VECT_BASE_ALIGNED_P (stmt_info);
902 base = build_fold_indirect_ref (STMT_VINFO_VECT_DR_BASE_ADDRESS (stmt_info));
903 vectype = STMT_VINFO_VECTYPE (stmt_info);
905 if (!misalign)
907 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
909 fprintf (vect_dump, "Unknown alignment for access: ");
910 print_generic_expr (vect_dump, base, TDF_SLIM);
912 return true;
915 if (!base_aligned_p)
917 if (!vect_can_force_dr_alignment_p (base, TYPE_ALIGN (vectype)))
919 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
921 fprintf (vect_dump, "can't force alignment of ref: ");
922 print_generic_expr (vect_dump, ref, TDF_SLIM);
924 return true;
927 /* Force the alignment of the decl.
928 NOTE: This is the only change to the code we make during
929 the analysis phase, before deciding to vectorize the loop. */
930 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
931 fprintf (vect_dump, "force alignment");
932 DECL_ALIGN (base) = TYPE_ALIGN (vectype);
933 DECL_USER_ALIGN (base) = 1;
936 /* At this point we assume that the base is aligned. */
937 gcc_assert (base_aligned_p
938 || (TREE_CODE (base) == VAR_DECL
939 && DECL_ALIGN (base) >= TYPE_ALIGN (vectype)));
941 /* Alignment required, in bytes: */
942 alignment = ssize_int (TYPE_ALIGN (vectype)/BITS_PER_UNIT);
944 /* Modulo alignment. */
945 misalign = size_binop (TRUNC_MOD_EXPR, misalign, alignment);
946 if (tree_int_cst_sgn (misalign) < 0)
948 /* Negative misalignment value. */
949 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
950 fprintf (vect_dump, "unexpected misalign value");
951 return false;
954 DR_MISALIGNMENT (dr) = tree_low_cst (misalign, 1);
956 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
957 fprintf (vect_dump, "misalign = %d bytes", DR_MISALIGNMENT (dr));
959 return true;
963 /* Function vect_compute_data_refs_alignment
965 Compute the misalignment of data references in the loop.
966 This pass may take place at function granularity instead of at loop
967 granularity.
969 FOR NOW: No analysis is actually performed. Misalignment is calculated
970 only for trivial cases. TODO. */
972 static bool
973 vect_compute_data_refs_alignment (loop_vec_info loop_vinfo)
975 varray_type loop_write_datarefs = LOOP_VINFO_DATAREF_WRITES (loop_vinfo);
976 varray_type loop_read_datarefs = LOOP_VINFO_DATAREF_READS (loop_vinfo);
977 unsigned int i;
979 for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_write_datarefs); i++)
981 struct data_reference *dr = VARRAY_GENERIC_PTR (loop_write_datarefs, i);
982 if (!vect_compute_data_ref_alignment (dr))
983 return false;
986 for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_read_datarefs); i++)
988 struct data_reference *dr = VARRAY_GENERIC_PTR (loop_read_datarefs, i);
989 if (!vect_compute_data_ref_alignment (dr))
990 return false;
993 return true;
997 /* Function vect_enhance_data_refs_alignment
999 This pass will use loop versioning and loop peeling in order to enhance
1000 the alignment of data references in the loop.
1002 FOR NOW: we assume that whatever versioning/peeling takes place, only the
1003 original loop is to be vectorized; Any other loops that are created by
1004 the transformations performed in this pass - are not supposed to be
1005 vectorized. This restriction will be relaxed. */
1007 static void
1008 vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
1010 varray_type loop_read_datarefs = LOOP_VINFO_DATAREF_READS (loop_vinfo);
1011 varray_type loop_write_datarefs = LOOP_VINFO_DATAREF_WRITES (loop_vinfo);
1012 varray_type datarefs;
1013 struct data_reference *dr0 = NULL;
1014 unsigned int i, j;
1016 /* Sigh, a hack to make targets that do not define UNITS_PER_SIMD_WORD
1017 bootstrap. Copy UNITS_PER_SIMD_WORD to a local variable to avoid a
1018 "division by zero" error. This error would be issued because we
1019 we do "... % UNITS_PER_SIMD_WORD" below, and UNITS_PER_SIMD_WORD
1020 defaults to 0 if it is not defined by the target. */
1021 int units_per_simd_word = UNITS_PER_SIMD_WORD;
1024 This pass will require a cost model to guide it whether to apply peeling
1025 or versioning or a combination of the two. For example, the scheme that
1026 intel uses when given a loop with several memory accesses, is as follows:
1027 choose one memory access ('p') which alignment you want to force by doing
1028 peeling. Then, either (1) generate a loop in which 'p' is aligned and all
1029 other accesses are not necessarily aligned, or (2) use loop versioning to
1030 generate one loop in which all accesses are aligned, and another loop in
1031 which only 'p' is necessarily aligned.
1033 ("Automatic Intra-Register Vectorization for the Intel Architecture",
1034 Aart J.C. Bik, Milind Girkar, Paul M. Grey and Ximmin Tian, International
1035 Journal of Parallel Programming, Vol. 30, No. 2, April 2002.)
1037 Devising a cost model is the most critical aspect of this work. It will
1038 guide us on which access to peel for, whether to use loop versioning, how
1039 many versions to create, etc. The cost model will probably consist of
1040 generic considerations as well as target specific considerations (on
1041 powerpc for example, misaligned stores are more painful than misaligned
1042 loads).
1044 Here is the general steps involved in alignment enhancements:
1046 -- original loop, before alignment analysis:
1047 for (i=0; i<N; i++){
1048 x = q[i]; # DR_MISALIGNMENT(q) = unknown
1049 p[i] = y; # DR_MISALIGNMENT(p) = unknown
1052 -- After vect_compute_data_refs_alignment:
1053 for (i=0; i<N; i++){
1054 x = q[i]; # DR_MISALIGNMENT(q) = 3
1055 p[i] = y; # DR_MISALIGNMENT(p) = unknown
1058 -- Possibility 1: we do loop versioning:
1059 if (p is aligned) {
1060 for (i=0; i<N; i++){ # loop 1A
1061 x = q[i]; # DR_MISALIGNMENT(q) = 3
1062 p[i] = y; # DR_MISALIGNMENT(p) = 0
1065 else {
1066 for (i=0; i<N; i++){ # loop 1B
1067 x = q[i]; # DR_MISALIGNMENT(q) = 3
1068 p[i] = y; # DR_MISALIGNMENT(p) = unaligned
1072 -- Possibility 2: we do loop peeling:
1073 for (i = 0; i < 3; i++){ # (scalar loop, not to be vectorized).
1074 x = q[i];
1075 p[i] = y;
1077 for (i = 3; i < N; i++){ # loop 2A
1078 x = q[i]; # DR_MISALIGNMENT(q) = 0
1079 p[i] = y; # DR_MISALIGNMENT(p) = unknown
1082 -- Possibility 3: combination of loop peeling and versioning:
1083 for (i = 0; i < 3; i++){ # (scalar loop, not to be vectorized).
1084 x = q[i];
1085 p[i] = y;
1087 if (p is aligned) {
1088 for (i = 3; i<N; i++){ # loop 3A
1089 x = q[i]; # DR_MISALIGNMENT(q) = 0
1090 p[i] = y; # DR_MISALIGNMENT(p) = 0
1093 else {
1094 for (i = 3; i<N; i++){ # loop 3B
1095 x = q[i]; # DR_MISALIGNMENT(q) = 0
1096 p[i] = y; # DR_MISALIGNMENT(p) = unaligned
1100 These loops are later passed to loop_transform to be vectorized. The
1101 vectorizer will use the alignment information to guide the transformation
1102 (whether to generate regular loads/stores, or with special handling for
1103 misalignment).
1106 /* (1) Peeling to force alignment. */
1108 /* (1.1) Decide whether to perform peeling, and how many iterations to peel:
1109 Considerations:
1110 + How many accesses will become aligned due to the peeling
1111 - How many accesses will become unaligned due to the peeling,
1112 and the cost of misaligned accesses.
1113 - The cost of peeling (the extra runtime checks, the increase
1114 in code size).
1116 The scheme we use FORNOW: peel to force the alignment of the first
1117 misaligned store in the loop.
1118 Rationale: misaligned stores are not yet supported.
1120 TODO: Use a better cost model. */
1122 for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_write_datarefs); i++)
1124 dr0 = VARRAY_GENERIC_PTR (loop_write_datarefs, i);
1125 if (!aligned_access_p (dr0))
1127 LOOP_VINFO_UNALIGNED_DR (loop_vinfo) = dr0;
1128 LOOP_PEELING_FOR_ALIGNMENT (loop_vinfo) = DR_MISALIGNMENT (dr0);
1129 break;
1133 /* (1.2) Update the alignment info according to the peeling factor.
1134 If the misalignment of the DR we peel for is M, then the
1135 peeling factor is VF - M, and the misalignment of each access DR_i
1136 in the loop is DR_MISALIGNMENT (DR_i) + VF - M.
1137 If the misalignment of the DR we peel for is unknown, then the
1138 misalignment of each access DR_i in the loop is also unknown.
1140 TODO: - consider accesses that are known to have the same
1141 alignment, even if that alignment is unknown. */
1143 if (LOOP_PEELING_FOR_ALIGNMENT (loop_vinfo))
1145 int mis;
1146 int npeel = 0;
1148 if (known_alignment_for_access_p (dr0))
1150 /* Since it's known at compile time, compute the number of iterations
1151 in the peeled loop (the peeling factor) for use in updating
1152 DR_MISALIGNMENT values. The peeling factor is the vectorization
1153 factor minus the misalignment as an element count. */
1154 mis = DR_MISALIGNMENT (dr0);
1155 mis /= GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (DR_REF (dr0))));
1156 npeel = LOOP_VINFO_VECT_FACTOR (loop_vinfo) - mis;
1159 datarefs = loop_write_datarefs;
1160 for (j = 0; j < 2; j++)
1162 for (i = 0; i < VARRAY_ACTIVE_SIZE (datarefs); i++)
1164 struct data_reference *dr = VARRAY_GENERIC_PTR (datarefs, i);
1166 if (dr == dr0)
1167 continue;
1168 if (known_alignment_for_access_p (dr)
1169 && DR_MISALIGNMENT (dr) == DR_MISALIGNMENT (dr0))
1170 DR_MISALIGNMENT (dr) = 0;
1171 else if (known_alignment_for_access_p (dr)
1172 && known_alignment_for_access_p (dr0))
1174 int drsize = GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (DR_REF (dr))));
1176 DR_MISALIGNMENT (dr) += npeel * drsize;
1177 DR_MISALIGNMENT (dr) %= units_per_simd_word;
1179 else
1180 DR_MISALIGNMENT (dr) = -1;
1182 datarefs = loop_read_datarefs;
1185 DR_MISALIGNMENT (dr0) = 0;
1190 /* Function vect_analyze_data_refs_alignment
1192 Analyze the alignment of the data-references in the loop.
1193 FOR NOW: Until support for misliagned accesses is in place, only if all
1194 accesses are aligned can the loop be vectorized. This restriction will be
1195 relaxed. */
1197 static bool
1198 vect_analyze_data_refs_alignment (loop_vec_info loop_vinfo)
1200 varray_type loop_read_datarefs = LOOP_VINFO_DATAREF_READS (loop_vinfo);
1201 varray_type loop_write_datarefs = LOOP_VINFO_DATAREF_WRITES (loop_vinfo);
1202 enum dr_alignment_support supportable_dr_alignment;
1203 unsigned int i;
1205 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
1206 fprintf (vect_dump, "=== vect_analyze_data_refs_alignment ===");
1209 /* This pass may take place at function granularity instead of at loop
1210 granularity. */
1212 if (!vect_compute_data_refs_alignment (loop_vinfo))
1214 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
1215 LOOP_LOC (loop_vinfo)))
1216 fprintf (vect_dump,
1217 "not vectorized: can't calculate alignment for data ref.");
1218 return false;
1222 /* This pass will decide on using loop versioning and/or loop peeling in
1223 order to enhance the alignment of data references in the loop. */
1225 vect_enhance_data_refs_alignment (loop_vinfo);
1228 /* Finally, check that all the data references in the loop can be
1229 handled with respect to their alignment. */
1231 for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_read_datarefs); i++)
1233 struct data_reference *dr = VARRAY_GENERIC_PTR (loop_read_datarefs, i);
1234 supportable_dr_alignment = vect_supportable_dr_alignment (dr);
1235 if (!supportable_dr_alignment)
1237 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
1238 LOOP_LOC (loop_vinfo)))
1239 fprintf (vect_dump, "not vectorized: unsupported unaligned load.");
1240 return false;
1242 if (supportable_dr_alignment != dr_aligned
1243 && (vect_print_dump_info (REPORT_ALIGNMENT, LOOP_LOC (loop_vinfo))))
1244 fprintf (vect_dump, "Vectorizing an unaligned access.");
1246 for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_write_datarefs); i++)
1248 struct data_reference *dr = VARRAY_GENERIC_PTR (loop_write_datarefs, i);
1249 supportable_dr_alignment = vect_supportable_dr_alignment (dr);
1250 if (!supportable_dr_alignment)
1252 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
1253 LOOP_LOC (loop_vinfo)))
1254 fprintf (vect_dump, "not vectorized: unsupported unaligned store.");
1255 return false;
1257 if (supportable_dr_alignment != dr_aligned
1258 && (vect_print_dump_info (REPORT_ALIGNMENT, LOOP_LOC (loop_vinfo))))
1259 fprintf (vect_dump, "Vectorizing an unaligned access.");
1261 if (LOOP_VINFO_UNALIGNED_DR (loop_vinfo)
1262 && vect_print_dump_info (REPORT_ALIGNMENT, LOOP_LOC (loop_vinfo)))
1263 fprintf (vect_dump, "Alignment of access forced using peeling.");
1265 return true;
1269 /* Function vect_analyze_data_ref_access.
1271 Analyze the access pattern of the data-reference DR. For now, a data access
1272 has to consecutive to be considered vectorizable. */
1274 static bool
1275 vect_analyze_data_ref_access (struct data_reference *dr)
1277 tree stmt = DR_STMT (dr);
1278 stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
1279 tree step = STMT_VINFO_VECT_STEP (stmt_info);
1280 tree scalar_type = TREE_TYPE (DR_REF (dr));
1282 if (!step || tree_int_cst_compare (step, TYPE_SIZE_UNIT (scalar_type)))
1284 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
1285 fprintf (vect_dump, "not consecutive access");
1286 return false;
1288 return true;
1292 /* Function vect_analyze_data_ref_accesses.
1294 Analyze the access pattern of all the data references in the loop.
1296 FORNOW: the only access pattern that is considered vectorizable is a
1297 simple step 1 (consecutive) access.
1299 FORNOW: handle only arrays and pointer accesses. */
1301 static bool
1302 vect_analyze_data_ref_accesses (loop_vec_info loop_vinfo)
1304 unsigned int i;
1305 varray_type loop_write_datarefs = LOOP_VINFO_DATAREF_WRITES (loop_vinfo);
1306 varray_type loop_read_datarefs = LOOP_VINFO_DATAREF_READS (loop_vinfo);
1308 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
1309 fprintf (vect_dump, "=== vect_analyze_data_ref_accesses ===");
1311 for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_write_datarefs); i++)
1313 struct data_reference *dr = VARRAY_GENERIC_PTR (loop_write_datarefs, i);
1314 bool ok = vect_analyze_data_ref_access (dr);
1315 if (!ok)
1317 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
1318 LOOP_LOC (loop_vinfo)))
1319 fprintf (vect_dump, "not vectorized: complicated access pattern.");
1320 return false;
1324 for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_read_datarefs); i++)
1326 struct data_reference *dr = VARRAY_GENERIC_PTR (loop_read_datarefs, i);
1327 bool ok = vect_analyze_data_ref_access (dr);
1328 if (!ok)
1330 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
1331 LOOP_LOC (loop_vinfo)))
1332 fprintf (vect_dump, "not vectorized: complicated access pattern.");
1333 return false;
1337 return true;
1341 /* Function vect_analyze_pointer_ref_access.
1343 Input:
1344 STMT - a stmt that contains a data-ref.
1345 MEMREF - a data-ref in STMT, which is an INDIRECT_REF.
1346 ACCESS_FN - the access function of MEMREF.
1348 Output:
1349 If the data-ref access is vectorizable, return a data_reference structure
1350 that represents it (DR). Otherwise - return NULL.
1351 STEP - the stride of MEMREF in the loop.
1352 INIT - the initial condition of MEMREF in the loop.
1355 static struct data_reference *
1356 vect_analyze_pointer_ref_access (tree memref, tree stmt, bool is_read,
1357 tree access_fn, tree *ptr_init, tree *ptr_step)
1359 stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
1360 loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
1361 struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
1362 tree step, init;
1363 tree reftype, innertype;
1364 tree indx_access_fn;
1365 int loopnum = loop->num;
1366 struct data_reference *dr;
1368 if (!vect_is_simple_iv_evolution (loopnum, access_fn, &init, &step))
1370 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
1371 LOOP_LOC (loop_vinfo)))
1372 fprintf (vect_dump, "not vectorized: pointer access is not simple.");
1373 return NULL;
1376 STRIP_NOPS (init);
1378 if (!expr_invariant_in_loop_p (loop, init))
1380 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
1381 LOOP_LOC (loop_vinfo)))
1382 fprintf (vect_dump,
1383 "not vectorized: initial condition is not loop invariant.");
1384 return NULL;
1387 if (TREE_CODE (step) != INTEGER_CST)
1389 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
1390 LOOP_LOC (loop_vinfo)))
1391 fprintf (vect_dump,
1392 "not vectorized: non constant step for pointer access.");
1393 return NULL;
1396 reftype = TREE_TYPE (TREE_OPERAND (memref, 0));
1397 if (!POINTER_TYPE_P (reftype))
1399 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
1400 LOOP_LOC (loop_vinfo)))
1401 fprintf (vect_dump, "not vectorized: unexpected pointer access form.");
1402 return NULL;
1405 if (!POINTER_TYPE_P (TREE_TYPE (init)))
1407 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
1408 LOOP_LOC (loop_vinfo)))
1409 fprintf (vect_dump, "not vectorized: unexpected pointer access form.");
1410 return NULL;
1413 *ptr_step = fold_convert (ssizetype, step);
1414 innertype = TREE_TYPE (reftype);
1415 if (!COMPLETE_TYPE_P (innertype))
1417 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
1418 LOOP_LOC (loop_vinfo)))
1419 fprintf (vect_dump, "not vectorized: pointer to incomplete type.");
1420 return NULL;
1423 /* Check that STEP is a multiple of type size. */
1424 if (!integer_zerop (size_binop (TRUNC_MOD_EXPR, *ptr_step,
1425 fold_convert (ssizetype, TYPE_SIZE_UNIT (innertype)))))
1427 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
1428 LOOP_LOC (loop_vinfo)))
1429 fprintf (vect_dump, "not vectorized: non consecutive access.");
1430 return NULL;
1433 indx_access_fn =
1434 build_polynomial_chrec (loopnum, integer_zero_node, integer_one_node);
1435 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
1437 fprintf (vect_dump, "Access function of ptr indx: ");
1438 print_generic_expr (vect_dump, indx_access_fn, TDF_SLIM);
1440 dr = init_data_ref (stmt, memref, NULL_TREE, indx_access_fn, is_read);
1441 *ptr_init = init;
1442 return dr;
1446 /* Function vect_address_analysis
1448 Return the BASE of the address expression EXPR.
1449 Also compute the INITIAL_OFFSET from BASE, MISALIGN and STEP.
1451 Input:
1452 EXPR - the address expression that is being analyzed
1453 STMT - the statement that contains EXPR or its original memory reference
1454 IS_READ - TRUE if STMT reads from EXPR, FALSE if writes to EXPR
1455 VECTYPE - the type that defines the alignment (i.e, we compute
1456 alignment relative to TYPE_ALIGN(VECTYPE))
1457 DR - data_reference struct for the original memory reference
1459 Output:
1460 BASE (returned value) - the base of the data reference EXPR.
1461 INITIAL_OFFSET - initial offset of EXPR from BASE (an expression)
1462 MISALIGN - offset of EXPR from BASE in bytes (a constant) or NULL_TREE if the
1463 computation is impossible
1464 STEP - evolution of EXPR in the loop
1465 BASE_ALIGNED - indicates if BASE is aligned
1467 If something unexpected is encountered (an unsupported form of data-ref),
1468 then NULL_TREE is returned.
1471 static tree
1472 vect_address_analysis (tree expr, tree stmt, bool is_read, tree vectype,
1473 struct data_reference *dr, tree *offset, tree *misalign,
1474 tree *step, bool *base_aligned)
1476 tree oprnd0, oprnd1, base_address, offset_expr, base_addr0, base_addr1;
1477 tree address_offset = ssize_int (0), address_misalign = ssize_int (0);
1478 tree dummy;
1479 subvar_t dummy2;
1481 switch (TREE_CODE (expr))
1483 case PLUS_EXPR:
1484 case MINUS_EXPR:
1485 /* EXPR is of form {base +/- offset} (or {offset +/- base}). */
1486 oprnd0 = TREE_OPERAND (expr, 0);
1487 oprnd1 = TREE_OPERAND (expr, 1);
1489 STRIP_NOPS (oprnd0);
1490 STRIP_NOPS (oprnd1);
1492 /* Recursively try to find the base of the address contained in EXPR.
1493 For offset, the returned base will be NULL. */
1494 base_addr0 = vect_address_analysis (oprnd0, stmt, is_read, vectype, dr,
1495 &address_offset, &address_misalign, step,
1496 base_aligned);
1498 base_addr1 = vect_address_analysis (oprnd1, stmt, is_read, vectype, dr,
1499 &address_offset, &address_misalign, step,
1500 base_aligned);
1502 /* We support cases where only one of the operands contains an
1503 address. */
1504 if ((base_addr0 && base_addr1) || (!base_addr0 && !base_addr1))
1505 return NULL_TREE;
1507 /* To revert STRIP_NOPS. */
1508 oprnd0 = TREE_OPERAND (expr, 0);
1509 oprnd1 = TREE_OPERAND (expr, 1);
1511 offset_expr = base_addr0 ?
1512 fold_convert (ssizetype, oprnd1) : fold_convert (ssizetype, oprnd0);
1514 /* EXPR is of form {base +/- offset} (or {offset +/- base}). If offset is
1515 a number, we can add it to the misalignment value calculated for base,
1516 otherwise, misalignment is NULL. */
1517 if (TREE_CODE (offset_expr) == INTEGER_CST && address_misalign)
1518 *misalign = size_binop (TREE_CODE (expr), address_misalign,
1519 offset_expr);
1520 else
1521 *misalign = NULL_TREE;
1523 /* Combine offset (from EXPR {base + offset}) with the offset calculated
1524 for base. */
1525 *offset = size_binop (TREE_CODE (expr), address_offset, offset_expr);
1526 return base_addr0 ? base_addr0 : base_addr1;
1528 case ADDR_EXPR:
1529 base_address = vect_object_analysis (TREE_OPERAND (expr, 0), stmt,
1530 is_read, vectype, &dr, offset,
1531 misalign, step, base_aligned,
1532 &dummy, &dummy2);
1533 return base_address;
1535 case SSA_NAME:
1536 if (!POINTER_TYPE_P (TREE_TYPE (expr)))
1537 return NULL_TREE;
1539 if (TYPE_ALIGN (TREE_TYPE (TREE_TYPE (expr))) < TYPE_ALIGN (vectype))
1541 if (vect_get_ptr_offset (expr, vectype, misalign))
1542 *base_aligned = true;
1543 else
1544 *base_aligned = false;
1546 else
1548 *base_aligned = true;
1549 *misalign = ssize_int (0);
1551 *offset = ssize_int (0);
1552 *step = ssize_int (0);
1553 return expr;
1555 default:
1556 return NULL_TREE;
1561 /* Function vect_object_analysis
1563 Return the BASE of the data reference MEMREF.
1564 Also compute the INITIAL_OFFSET from BASE, MISALIGN and STEP.
1565 E.g., for EXPR a.b[i] + 4B, BASE is a, and OFFSET is the overall offset
1566 'a.b[i] + 4B' from a (can be an expression), MISALIGN is an OFFSET
1567 instantiated with initial_conditions of access_functions of variables,
1568 modulo alignment, and STEP is the evolution of the DR_REF in this loop.
1570 Function get_inner_reference is used for the above in case of ARRAY_REF and
1571 COMPONENT_REF.
1573 The structure of the function is as follows:
1574 Part 1:
1575 Case 1. For handled_component_p refs
1576 1.1 call get_inner_reference
1577 1.1.1 analyze offset expr received from get_inner_reference
1578 1.2. build data-reference structure for MEMREF
1579 (fall through with BASE)
1580 Case 2. For declarations
1581 2.1 check alignment
1582 2.2 update DR_BASE_NAME if necessary for alias
1583 Case 3. For INDIRECT_REFs
1584 3.1 get the access function
1585 3.2 analyze evolution of MEMREF
1586 3.3 set data-reference structure for MEMREF
1587 3.4 call vect_address_analysis to analyze INIT of the access function
1589 Part 2:
1590 Combine the results of object and address analysis to calculate
1591 INITIAL_OFFSET, STEP and misalignment info.
1593 Input:
1594 MEMREF - the memory reference that is being analyzed
1595 STMT - the statement that contains MEMREF
1596 IS_READ - TRUE if STMT reads from MEMREF, FALSE if writes to MEMREF
1597 VECTYPE - the type that defines the alignment (i.e, we compute
1598 alignment relative to TYPE_ALIGN(VECTYPE))
1600 Output:
1601 BASE_ADDRESS (returned value) - the base address of the data reference MEMREF
1602 E.g, if MEMREF is a.b[k].c[i][j] the returned
1603 base is &a.
1604 DR - data_reference struct for MEMREF
1605 INITIAL_OFFSET - initial offset of MEMREF from BASE (an expression)
1606 MISALIGN - offset of MEMREF from BASE in bytes (a constant) or NULL_TREE if
1607 the computation is impossible
1608 STEP - evolution of the DR_REF in the loop
1609 BASE_ALIGNED - indicates if BASE is aligned
1610 MEMTAG - memory tag for aliasing purposes
1611 SUBVAR - Sub-variables of the variable
1613 If something unexpected is encountered (an unsupported form of data-ref),
1614 then NULL_TREE is returned. */
1616 static tree
1617 vect_object_analysis (tree memref, tree stmt, bool is_read,
1618 tree vectype, struct data_reference **dr,
1619 tree *offset, tree *misalign, tree *step,
1620 bool *base_aligned, tree *memtag,
1621 subvar_t *subvars)
1623 tree base = NULL_TREE, base_address = NULL_TREE;
1624 tree object_offset = ssize_int (0), object_misalign = ssize_int (0);
1625 tree object_step = ssize_int (0), address_step = ssize_int (0);
1626 bool object_base_aligned = true, address_base_aligned = true;
1627 tree address_offset = ssize_int (0), address_misalign = ssize_int (0);
1628 HOST_WIDE_INT pbitsize, pbitpos;
1629 tree poffset, bit_pos_in_bytes;
1630 enum machine_mode pmode;
1631 int punsignedp, pvolatilep;
1632 tree ptr_step = ssize_int (0), ptr_init = NULL_TREE;
1633 stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
1634 loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
1635 struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
1636 struct data_reference *ptr_dr = NULL;
1637 tree access_fn, evolution_part, address_to_analyze;
1639 /* Part 1: */
1640 /* Case 1. handled_component_p refs. */
1641 if (handled_component_p (memref))
1643 /* 1.1 call get_inner_reference. */
1644 /* Find the base and the offset from it. */
1645 base = get_inner_reference (memref, &pbitsize, &pbitpos, &poffset,
1646 &pmode, &punsignedp, &pvolatilep, false);
1647 if (!base)
1648 return NULL_TREE;
1650 /* 1.1.1 analyze offset expr received from get_inner_reference. */
1651 if (poffset
1652 && !vect_analyze_offset_expr (poffset, loop, TYPE_SIZE_UNIT (vectype),
1653 &object_offset, &object_misalign, &object_step))
1655 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
1657 fprintf (vect_dump, "failed to compute offset or step for ");
1658 print_generic_expr (vect_dump, memref, TDF_SLIM);
1660 return NULL_TREE;
1663 /* Add bit position to OFFSET and MISALIGN. */
1665 bit_pos_in_bytes = ssize_int (pbitpos/BITS_PER_UNIT);
1666 /* Check that there is no remainder in bits. */
1667 if (pbitpos%BITS_PER_UNIT)
1669 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
1670 fprintf (vect_dump, "bit offset alignment.");
1671 return NULL_TREE;
1673 object_offset = size_binop (PLUS_EXPR, bit_pos_in_bytes, object_offset);
1674 if (object_misalign)
1675 object_misalign = size_binop (PLUS_EXPR, object_misalign,
1676 bit_pos_in_bytes);
1678 /* Create data-reference for MEMREF. TODO: handle COMPONENT_REFs. */
1679 if (!(*dr))
1681 if (TREE_CODE (memref) == ARRAY_REF)
1682 *dr = analyze_array (stmt, memref, is_read);
1683 else
1684 /* FORNOW. */
1685 return NULL_TREE;
1687 memref = base; /* To continue analysis of BASE. */
1688 /* fall through */
1691 /* Part 1: Case 2. Declarations. */
1692 if (DECL_P (memref))
1694 /* We expect to get a decl only if we already have a DR. */
1695 if (!(*dr))
1697 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
1699 fprintf (vect_dump, "unhandled decl ");
1700 print_generic_expr (vect_dump, memref, TDF_SLIM);
1702 return NULL_TREE;
1705 /* 2.1 check the alignment. */
1706 if (DECL_ALIGN (memref) >= TYPE_ALIGN (vectype))
1707 object_base_aligned = true;
1708 else
1709 object_base_aligned = false;
1711 /* 2.2 update DR_BASE_NAME if necessary. */
1712 if (!DR_BASE_NAME ((*dr)))
1713 /* For alias analysis. In case the analysis of INDIRECT_REF brought
1714 us to object. */
1715 DR_BASE_NAME ((*dr)) = memref;
1717 if (SSA_VAR_P (memref) && var_can_have_subvars (memref))
1718 *subvars = get_subvars_for_var (memref);
1719 base_address = build_fold_addr_expr (memref);
1720 *memtag = memref;
1723 /* Part 1: Case 3. INDIRECT_REFs. */
1724 else if (TREE_CODE (memref) == INDIRECT_REF)
1726 /* 3.1 get the access function. */
1727 access_fn = analyze_scalar_evolution (loop, TREE_OPERAND (memref, 0));
1728 if (!access_fn)
1730 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
1731 LOOP_LOC (loop_vinfo)))
1732 fprintf (vect_dump, "not vectorized: complicated pointer access.");
1733 return NULL_TREE;
1735 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
1737 fprintf (vect_dump, "Access function of ptr: ");
1738 print_generic_expr (vect_dump, access_fn, TDF_SLIM);
1741 /* 3.2 analyze evolution of MEMREF. */
1742 evolution_part = evolution_part_in_loop_num (access_fn, loop->num);
1743 if (evolution_part)
1745 ptr_dr = vect_analyze_pointer_ref_access (memref, stmt, is_read,
1746 access_fn, &ptr_init, &ptr_step);
1747 if (!(ptr_dr))
1748 return NULL_TREE;
1750 object_step = size_binop (PLUS_EXPR, object_step, ptr_step);
1751 address_to_analyze = ptr_init;
1753 else
1755 if (!(*dr))
1757 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
1758 LOOP_LOC (loop_vinfo)))
1759 fprintf (vect_dump, "not vectorized: ptr is loop invariant.");
1760 return NULL_TREE;
1762 /* Since there exists DR for MEMREF, we are analyzing the init of
1763 the access function, which not necessary has evolution in the
1764 loop. */
1765 address_to_analyze = initial_condition_in_loop_num (access_fn,
1766 loop->num);
1769 /* 3.3 set data-reference structure for MEMREF. */
1770 *dr = (*dr) ? *dr : ptr_dr;
1772 /* 3.4 call vect_address_analysis to analyze INIT of the access
1773 function. */
1774 base_address = vect_address_analysis (address_to_analyze, stmt, is_read,
1775 vectype, *dr, &address_offset, &address_misalign,
1776 &address_step, &address_base_aligned);
1777 if (!base_address)
1778 return NULL_TREE;
1780 switch (TREE_CODE (base_address))
1782 case SSA_NAME:
1783 *memtag = get_var_ann (SSA_NAME_VAR (base_address))->type_mem_tag;
1784 if (!(*memtag) && TREE_CODE (TREE_OPERAND (memref, 0)) == SSA_NAME)
1785 *memtag = get_var_ann (
1786 SSA_NAME_VAR (TREE_OPERAND (memref, 0)))->type_mem_tag;
1787 break;
1788 case ADDR_EXPR:
1789 *memtag = TREE_OPERAND (base_address, 0);
1790 break;
1791 default:
1792 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
1793 LOOP_LOC (loop_vinfo)))
1795 fprintf (vect_dump, "not vectorized: no memtag ref: ");
1796 print_generic_expr (vect_dump, memref, TDF_SLIM);
1798 return NULL_TREE;
1802 if (!base_address)
1803 /* MEMREF cannot be analyzed. */
1804 return NULL_TREE;
1806 if (SSA_VAR_P (*memtag) && var_can_have_subvars (*memtag))
1807 *subvars = get_subvars_for_var (*memtag);
1809 /* Part 2: Combine the results of object and address analysis to calculate
1810 INITIAL_OFFSET, STEP and misalignment info. */
1811 *offset = size_binop (PLUS_EXPR, object_offset, address_offset);
1812 if (object_misalign && address_misalign)
1813 *misalign = size_binop (PLUS_EXPR, object_misalign, address_misalign);
1814 else
1815 *misalign = NULL_TREE;
1816 *step = size_binop (PLUS_EXPR, object_step, address_step);
1817 *base_aligned = object_base_aligned && address_base_aligned;
1819 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
1821 fprintf (vect_dump, "Results of object analysis for: ");
1822 print_generic_expr (vect_dump, memref, TDF_SLIM);
1823 fprintf (vect_dump, "\n\tbase_address: ");
1824 print_generic_expr (vect_dump, base_address, TDF_SLIM);
1825 fprintf (vect_dump, "\n\toffset: ");
1826 print_generic_expr (vect_dump, *offset, TDF_SLIM);
1827 fprintf (vect_dump, "\n\tstep: ");
1828 print_generic_expr (vect_dump, *step, TDF_SLIM);
1829 fprintf (vect_dump, "\n\tbase aligned %d\n\tmisalign: ", *base_aligned);
1830 print_generic_expr (vect_dump, *misalign, TDF_SLIM);
1832 return base_address;
1836 /* Function vect_analyze_data_refs.
1838 Find all the data references in the loop.
1840 The general structure of the analysis of data refs in the vectorizer is as
1841 follows:
1842 1- vect_analyze_data_refs(loop):
1843 Find and analyze all data-refs in the loop:
1844 foreach ref
1845 base_address = vect_object_analysis(ref)
1846 1.1- vect_object_analysis(ref):
1847 Analyze ref, and build a DR (data_referece struct) for it;
1848 compute base, initial_offset, step and alignment.
1849 Call get_inner_reference for refs handled in this function.
1850 Call vect_addr_analysis(addr) to analyze pointer type expressions.
1851 Set ref_stmt.base, ref_stmt.initial_offset, ref_stmt.alignment,
1852 ref_stmt.memtag and ref_stmt.step accordingly.
1853 2- vect_analyze_dependences(): apply dependence testing using ref_stmt.DR
1854 3- vect_analyze_drs_alignment(): check that ref_stmt.alignment is ok.
1855 4- vect_analyze_drs_access(): check that ref_stmt.step is ok.
1857 FORNOW: Handle aligned INDIRECT_REFs and ARRAY_REFs
1858 which base is really an array (not a pointer) and which alignment
1859 can be forced. This restriction will be relaxed. */
1861 static bool
1862 vect_analyze_data_refs (loop_vec_info loop_vinfo)
1864 struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
1865 basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
1866 int nbbs = loop->num_nodes;
1867 block_stmt_iterator si;
1868 int j;
1869 struct data_reference *dr;
1871 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
1872 fprintf (vect_dump, "=== vect_analyze_data_refs ===");
1874 for (j = 0; j < nbbs; j++)
1876 basic_block bb = bbs[j];
1877 for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
1879 bool is_read = false;
1880 tree stmt = bsi_stmt (si);
1881 stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
1882 v_may_def_optype v_may_defs = STMT_V_MAY_DEF_OPS (stmt);
1883 v_must_def_optype v_must_defs = STMT_V_MUST_DEF_OPS (stmt);
1884 vuse_optype vuses = STMT_VUSE_OPS (stmt);
1885 varray_type *datarefs = NULL;
1886 int nvuses, nv_may_defs, nv_must_defs;
1887 tree memref = NULL;
1888 tree scalar_type, vectype;
1889 tree base, offset, misalign, step, tag;
1890 bool base_aligned;
1891 subvar_t subvars = NULL;
1893 /* Assumption: there exists a data-ref in stmt, if and only if
1894 it has vuses/vdefs. */
1896 if (!vuses && !v_may_defs && !v_must_defs)
1897 continue;
1899 nvuses = NUM_VUSES (vuses);
1900 nv_may_defs = NUM_V_MAY_DEFS (v_may_defs);
1901 nv_must_defs = NUM_V_MUST_DEFS (v_must_defs);
1903 if (nvuses && (nv_may_defs || nv_must_defs))
1905 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
1907 fprintf (vect_dump, "unexpected vdefs and vuses in stmt: ");
1908 print_generic_expr (vect_dump, stmt, TDF_SLIM);
1910 return false;
1913 if (TREE_CODE (stmt) != MODIFY_EXPR)
1915 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
1917 fprintf (vect_dump, "unexpected vops in stmt: ");
1918 print_generic_expr (vect_dump, stmt, TDF_SLIM);
1920 return false;
1923 if (vuses)
1925 memref = TREE_OPERAND (stmt, 1);
1926 datarefs = &(LOOP_VINFO_DATAREF_READS (loop_vinfo));
1927 is_read = true;
1929 else /* vdefs */
1931 memref = TREE_OPERAND (stmt, 0);
1932 datarefs = &(LOOP_VINFO_DATAREF_WRITES (loop_vinfo));
1933 is_read = false;
1936 scalar_type = TREE_TYPE (memref);
1937 vectype = get_vectype_for_scalar_type (scalar_type);
1938 if (!vectype)
1940 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
1942 fprintf (vect_dump, "no vectype for stmt: ");
1943 print_generic_expr (vect_dump, stmt, TDF_SLIM);
1944 fprintf (vect_dump, " scalar_type: ");
1945 print_generic_expr (vect_dump, scalar_type, TDF_DETAILS);
1947 /* It is not possible to vectorize this data reference. */
1948 return false;
1950 /* Analyze MEMREF. If it is of a supported form, build data_reference
1951 struct for it (DR). */
1952 dr = NULL;
1953 base = vect_object_analysis (memref, stmt, is_read, vectype, &dr,
1954 &offset, &misalign, &step,
1955 &base_aligned, &tag, &subvars);
1956 if (!base)
1958 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
1959 LOOP_LOC (loop_vinfo)))
1961 fprintf (vect_dump, "not vectorized: unhandled data ref: ");
1962 print_generic_expr (vect_dump, stmt, TDF_SLIM);
1964 return false;
1966 STMT_VINFO_VECT_DR_BASE_ADDRESS (stmt_info) = base;
1967 STMT_VINFO_VECT_INIT_OFFSET (stmt_info) = offset;
1968 STMT_VINFO_VECT_STEP (stmt_info) = step;
1969 STMT_VINFO_VECT_MISALIGNMENT (stmt_info) = misalign;
1970 STMT_VINFO_VECT_BASE_ALIGNED_P (stmt_info) = base_aligned;
1971 STMT_VINFO_MEMTAG (stmt_info) = tag;
1972 STMT_VINFO_SUBVARS (stmt_info) = subvars;
1973 STMT_VINFO_VECTYPE (stmt_info) = vectype;
1974 VARRAY_PUSH_GENERIC_PTR (*datarefs, dr);
1975 STMT_VINFO_DATA_REF (stmt_info) = dr;
1979 return true;
1983 /* Utility functions used by vect_mark_stmts_to_be_vectorized. */
1985 /* Function vect_mark_relevant.
1987 Mark STMT as "relevant for vectorization" and add it to WORKLIST. */
1989 static void
1990 vect_mark_relevant (varray_type *worklist, tree stmt)
1992 stmt_vec_info stmt_info;
1994 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
1995 fprintf (vect_dump, "mark relevant.");
1997 if (TREE_CODE (stmt) == PHI_NODE)
1999 VARRAY_PUSH_TREE (*worklist, stmt);
2000 return;
2003 stmt_info = vinfo_for_stmt (stmt);
2005 if (!stmt_info)
2007 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
2009 fprintf (vect_dump, "mark relevant: no stmt info!!.");
2010 print_generic_expr (vect_dump, stmt, TDF_SLIM);
2012 return;
2015 if (STMT_VINFO_RELEVANT_P (stmt_info))
2017 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
2018 fprintf (vect_dump, "already marked relevant.");
2019 return;
2022 STMT_VINFO_RELEVANT_P (stmt_info) = 1;
2023 VARRAY_PUSH_TREE (*worklist, stmt);
2027 /* Function vect_stmt_relevant_p.
2029 Return true if STMT in loop that is represented by LOOP_VINFO is
2030 "relevant for vectorization".
2032 A stmt is considered "relevant for vectorization" if:
2033 - it has uses outside the loop.
2034 - it has vdefs (it alters memory).
2035 - control stmts in the loop (except for the exit condition).
2037 CHECKME: what other side effects would the vectorizer allow? */
2039 static bool
2040 vect_stmt_relevant_p (tree stmt, loop_vec_info loop_vinfo)
2042 v_may_def_optype v_may_defs;
2043 v_must_def_optype v_must_defs;
2044 struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
2045 int i;
2046 dataflow_t df;
2047 int num_uses;
2049 /* cond stmt other than loop exit cond. */
2050 if (is_ctrl_stmt (stmt) && (stmt != LOOP_VINFO_EXIT_COND (loop_vinfo)))
2051 return true;
2053 /* changing memory. */
2054 if (TREE_CODE (stmt) != PHI_NODE)
2056 v_may_defs = STMT_V_MAY_DEF_OPS (stmt);
2057 v_must_defs = STMT_V_MUST_DEF_OPS (stmt);
2058 if (v_may_defs || v_must_defs)
2060 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
2061 fprintf (vect_dump, "vec_stmt_relevant_p: stmt has vdefs.");
2062 return true;
2066 /* uses outside the loop. */
2067 df = get_immediate_uses (stmt);
2068 num_uses = num_immediate_uses (df);
2069 for (i = 0; i < num_uses; i++)
2071 tree use = immediate_use (df, i);
2072 basic_block bb = bb_for_stmt (use);
2073 if (!flow_bb_inside_loop_p (loop, bb))
2075 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
2076 fprintf (vect_dump, "vec_stmt_relevant_p: used out of loop.");
2077 return true;
2081 return false;
2085 /* Function vect_mark_stmts_to_be_vectorized.
2087 Not all stmts in the loop need to be vectorized. For example:
2089 for i...
2090 for j...
2091 1. T0 = i + j
2092 2. T1 = a[T0]
2094 3. j = j + 1
2096 Stmt 1 and 3 do not need to be vectorized, because loop control and
2097 addressing of vectorized data-refs are handled differently.
2099 This pass detects such stmts. */
2101 static bool
2102 vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo)
2104 varray_type worklist;
2105 struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
2106 basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
2107 unsigned int nbbs = loop->num_nodes;
2108 block_stmt_iterator si;
2109 tree stmt;
2110 stmt_ann_t ann;
2111 unsigned int i;
2112 int j;
2113 use_optype use_ops;
2114 stmt_vec_info stmt_info;
2115 basic_block bb;
2116 tree phi;
2118 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
2119 fprintf (vect_dump, "=== vect_mark_stmts_to_be_vectorized ===");
2121 bb = loop->header;
2122 for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
2124 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
2126 fprintf (vect_dump, "init: phi relevant? ");
2127 print_generic_expr (vect_dump, phi, TDF_SLIM);
2130 if (vect_stmt_relevant_p (phi, loop_vinfo))
2132 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
2133 LOOP_LOC (loop_vinfo)))
2134 fprintf (vect_dump, "unsupported reduction/induction.");
2135 return false;
2139 VARRAY_TREE_INIT (worklist, 64, "work list");
2141 /* 1. Init worklist. */
2143 for (i = 0; i < nbbs; i++)
2145 bb = bbs[i];
2146 for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
2148 stmt = bsi_stmt (si);
2150 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
2152 fprintf (vect_dump, "init: stmt relevant? ");
2153 print_generic_expr (vect_dump, stmt, TDF_SLIM);
2156 stmt_info = vinfo_for_stmt (stmt);
2157 STMT_VINFO_RELEVANT_P (stmt_info) = 0;
2159 if (vect_stmt_relevant_p (stmt, loop_vinfo))
2160 vect_mark_relevant (&worklist, stmt);
2165 /* 2. Process_worklist */
2167 while (VARRAY_ACTIVE_SIZE (worklist) > 0)
2169 stmt = VARRAY_TOP_TREE (worklist);
2170 VARRAY_POP (worklist);
2172 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
2174 fprintf (vect_dump, "worklist: examine stmt: ");
2175 print_generic_expr (vect_dump, stmt, TDF_SLIM);
2178 /* Examine the USES in this statement. Mark all the statements which
2179 feed this statement's uses as "relevant", unless the USE is used as
2180 an array index. */
2182 if (TREE_CODE (stmt) == PHI_NODE)
2184 /* follow the def-use chain inside the loop. */
2185 for (j = 0; j < PHI_NUM_ARGS (stmt); j++)
2187 tree arg = PHI_ARG_DEF (stmt, j);
2188 tree def_stmt = NULL_TREE;
2189 basic_block bb;
2190 if (!vect_is_simple_use (arg, loop_vinfo, &def_stmt))
2192 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
2193 LOOP_LOC (loop_vinfo)))
2194 fprintf (vect_dump, "not vectorized: unsupported use in stmt.");
2195 varray_clear (worklist);
2196 return false;
2198 if (!def_stmt)
2199 continue;
2201 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
2203 fprintf (vect_dump, "worklist: def_stmt: ");
2204 print_generic_expr (vect_dump, def_stmt, TDF_SLIM);
2207 bb = bb_for_stmt (def_stmt);
2208 if (flow_bb_inside_loop_p (loop, bb))
2209 vect_mark_relevant (&worklist, def_stmt);
2213 ann = stmt_ann (stmt);
2214 use_ops = USE_OPS (ann);
2216 for (i = 0; i < NUM_USES (use_ops); i++)
2218 tree use = USE_OP (use_ops, i);
2220 /* We are only interested in uses that need to be vectorized. Uses
2221 that are used for address computation are not considered relevant.
2223 if (exist_non_indexing_operands_for_use_p (use, stmt))
2225 tree def_stmt = NULL_TREE;
2226 basic_block bb;
2227 if (!vect_is_simple_use (use, loop_vinfo, &def_stmt))
2229 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
2230 LOOP_LOC (loop_vinfo)))
2231 fprintf (vect_dump, "not vectorized: unsupported use in stmt.");
2232 varray_clear (worklist);
2233 return false;
2236 if (!def_stmt)
2237 continue;
2239 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
2241 fprintf (vect_dump, "worklist: examine use %d: ", i);
2242 print_generic_expr (vect_dump, use, TDF_SLIM);
2245 bb = bb_for_stmt (def_stmt);
2246 if (flow_bb_inside_loop_p (loop, bb))
2247 vect_mark_relevant (&worklist, def_stmt);
2250 } /* while worklist */
2252 varray_clear (worklist);
2253 return true;
2257 /* Function vect_can_advance_ivs_p
2259 In case the number of iterations that LOOP iterates in unknown at compile
2260 time, an epilog loop will be generated, and the loop induction variables
2261 (IVs) will be "advanced" to the value they are supposed to take just before
2262 the epilog loop. Here we check that the access function of the loop IVs
2263 and the expression that represents the loop bound are simple enough.
2264 These restrictions will be relaxed in the future. */
2266 static bool
2267 vect_can_advance_ivs_p (loop_vec_info loop_vinfo)
2269 struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
2270 basic_block bb = loop->header;
2271 tree phi;
2273 /* Analyze phi functions of the loop header. */
2275 for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
2277 tree access_fn = NULL;
2278 tree evolution_part;
2280 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
2282 fprintf (vect_dump, "Analyze phi: ");
2283 print_generic_expr (vect_dump, phi, TDF_SLIM);
2286 /* Skip virtual phi's. The data dependences that are associated with
2287 virtual defs/uses (i.e., memory accesses) are analyzed elsewhere. */
2289 if (!is_gimple_reg (SSA_NAME_VAR (PHI_RESULT (phi))))
2291 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
2292 fprintf (vect_dump, "virtual phi. skip.");
2293 continue;
2296 /* Analyze the evolution function. */
2298 access_fn = instantiate_parameters
2299 (loop, analyze_scalar_evolution (loop, PHI_RESULT (phi)));
2301 if (!access_fn)
2303 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
2304 fprintf (vect_dump, "No Access function.");
2305 return false;
2308 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
2310 fprintf (vect_dump, "Access function of PHI: ");
2311 print_generic_expr (vect_dump, access_fn, TDF_SLIM);
2314 evolution_part = evolution_part_in_loop_num (access_fn, loop->num);
2316 if (evolution_part == NULL_TREE)
2317 return false;
2319 /* FORNOW: We do not transform initial conditions of IVs
2320 which evolution functions are a polynomial of degree >= 2. */
2322 if (tree_is_chrec (evolution_part))
2323 return false;
2326 return true;
2330 /* Function vect_get_loop_niters.
2332 Determine how many iterations the loop is executed.
2333 If an expression that represents the number of iterations
2334 can be constructed, place it in NUMBER_OF_ITERATIONS.
2335 Return the loop exit condition. */
2337 static tree
2338 vect_get_loop_niters (struct loop *loop, tree *number_of_iterations)
2340 tree niters;
2342 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
2343 fprintf (vect_dump, "=== get_loop_niters ===");
2345 niters = number_of_iterations_in_loop (loop);
2347 if (niters != NULL_TREE
2348 && niters != chrec_dont_know)
2350 *number_of_iterations = niters;
2352 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
2354 fprintf (vect_dump, "==> get_loop_niters:" );
2355 print_generic_expr (vect_dump, *number_of_iterations, TDF_SLIM);
2359 return get_loop_exit_condition (loop);
2363 /* Function vect_analyze_loop_form.
2365 Verify the following restrictions (some may be relaxed in the future):
2366 - it's an inner-most loop
2367 - number of BBs = 2 (which are the loop header and the latch)
2368 - the loop has a pre-header
2369 - the loop has a single entry and exit
2370 - the loop exit condition is simple enough, and the number of iterations
2371 can be analyzed (a countable loop). */
2373 static loop_vec_info
2374 vect_analyze_loop_form (struct loop *loop)
2376 loop_vec_info loop_vinfo;
2377 tree loop_cond;
2378 tree number_of_iterations = NULL;
2379 LOC loop_loc;
2381 loop_loc = find_loop_location (loop);
2383 if (vect_print_dump_info (REPORT_DETAILS, loop_loc))
2384 fprintf (vect_dump, "=== vect_analyze_loop_form ===");
2386 if (loop->inner)
2388 if (vect_print_dump_info (REPORT_OUTER_LOOPS, loop_loc))
2389 fprintf (vect_dump, "not vectorized: nested loop.");
2390 return NULL;
2393 if (!loop->single_exit
2394 || loop->num_nodes != 2
2395 || EDGE_COUNT (loop->header->preds) != 2)
2397 if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS, loop_loc))
2399 if (!loop->single_exit)
2400 fprintf (vect_dump, "not vectorized: multiple exits.");
2401 else if (loop->num_nodes != 2)
2402 fprintf (vect_dump, "not vectorized: too many BBs in loop.");
2403 else if (EDGE_COUNT (loop->header->preds) != 2)
2404 fprintf (vect_dump, "not vectorized: too many incoming edges.");
2407 return NULL;
2410 /* We assume that the loop exit condition is at the end of the loop. i.e,
2411 that the loop is represented as a do-while (with a proper if-guard
2412 before the loop if needed), where the loop header contains all the
2413 executable statements, and the latch is empty. */
2414 if (!empty_block_p (loop->latch))
2416 if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS, loop_loc))
2417 fprintf (vect_dump, "not vectorized: unexpectd loop form.");
2418 return NULL;
2421 /* Make sure there exists a single-predecessor exit bb: */
2422 if (!single_pred_p (loop->single_exit->dest))
2424 edge e = loop->single_exit;
2425 if (!(e->flags & EDGE_ABNORMAL))
2427 loop_split_edge_with (e, NULL);
2428 if (vect_print_dump_info (REPORT_DETAILS, loop_loc))
2429 fprintf (vect_dump, "split exit edge.");
2431 else
2433 if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS, loop_loc))
2434 fprintf (vect_dump, "not vectorized: abnormal loop exit edge.");
2435 return NULL;
2439 if (empty_block_p (loop->header))
2441 if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS, loop_loc))
2442 fprintf (vect_dump, "not vectorized: empty loop.");
2443 return NULL;
2446 loop_cond = vect_get_loop_niters (loop, &number_of_iterations);
2447 if (!loop_cond)
2449 if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS, loop_loc))
2450 fprintf (vect_dump, "not vectorized: complicated exit condition.");
2451 return NULL;
2454 if (!number_of_iterations)
2456 if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS, loop_loc))
2457 fprintf (vect_dump,
2458 "not vectorized: number of iterations cannot be computed.");
2459 return NULL;
2462 if (chrec_contains_undetermined (number_of_iterations))
2464 if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS, loop_loc))
2465 fprintf (vect_dump, "Infinite number of iterations.");
2466 return false;
2469 loop_vinfo = new_loop_vec_info (loop);
2470 LOOP_VINFO_NITERS (loop_vinfo) = number_of_iterations;
2472 if (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo))
2474 if (vect_print_dump_info (REPORT_DETAILS, loop_loc))
2476 fprintf (vect_dump, "Symbolic number of iterations is ");
2477 print_generic_expr (vect_dump, number_of_iterations, TDF_DETAILS);
2480 else
2481 if (LOOP_VINFO_INT_NITERS (loop_vinfo) == 0)
2483 if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS, loop_loc))
2484 fprintf (vect_dump, "not vectorized: number of iterations = 0.");
2485 return NULL;
2488 LOOP_VINFO_EXIT_COND (loop_vinfo) = loop_cond;
2489 LOOP_VINFO_LOC (loop_vinfo) = loop_loc;
2491 return loop_vinfo;
2495 /* Function vect_analyze_loop.
2497 Apply a set of analyses on LOOP, and create a loop_vec_info struct
2498 for it. The different analyses will record information in the
2499 loop_vec_info struct. */
2500 loop_vec_info
2501 vect_analyze_loop (struct loop *loop)
2503 bool ok;
2504 loop_vec_info loop_vinfo;
2506 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
2507 fprintf (vect_dump, "===== analyze_loop_nest =====");
2509 /* Check the CFG characteristics of the loop (nesting, entry/exit, etc. */
2511 loop_vinfo = vect_analyze_loop_form (loop);
2512 if (!loop_vinfo)
2514 if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
2515 fprintf (vect_dump, "bad loop form.");
2516 return NULL;
2519 /* Find all data references in the loop (which correspond to vdefs/vuses)
2520 and analyze their evolution in the loop.
2522 FORNOW: Handle only simple, array references, which
2523 alignment can be forced, and aligned pointer-references. */
2525 ok = vect_analyze_data_refs (loop_vinfo);
2526 if (!ok)
2528 if (vect_print_dump_info (REPORT_DETAILS, LOOP_LOC (loop_vinfo)))
2529 fprintf (vect_dump, "bad data references.");
2530 destroy_loop_vec_info (loop_vinfo);
2531 return NULL;
2534 /* Data-flow analysis to detect stmts that do not need to be vectorized. */
2536 ok = vect_mark_stmts_to_be_vectorized (loop_vinfo);
2537 if (!ok)
2539 if (vect_print_dump_info (REPORT_DETAILS, LOOP_LOC (loop_vinfo)))
2540 fprintf (vect_dump, "unexpected pattern.");
2541 destroy_loop_vec_info (loop_vinfo);
2542 return NULL;
2545 /* Check that all cross-iteration scalar data-flow cycles are OK.
2546 Cross-iteration cycles caused by virtual phis are analyzed separately. */
2548 ok = vect_analyze_scalar_cycles (loop_vinfo);
2549 if (!ok)
2551 if (vect_print_dump_info (REPORT_DETAILS, LOOP_LOC (loop_vinfo)))
2552 fprintf (vect_dump, "bad scalar cycle.");
2553 destroy_loop_vec_info (loop_vinfo);
2554 return NULL;
2557 /* Analyze data dependences between the data-refs in the loop.
2558 FORNOW: fail at the first data dependence that we encounter. */
2560 ok = vect_analyze_data_ref_dependences (loop_vinfo);
2561 if (!ok)
2563 if (vect_print_dump_info (REPORT_DETAILS, LOOP_LOC (loop_vinfo)))
2564 fprintf (vect_dump, "bad data dependence.");
2565 destroy_loop_vec_info (loop_vinfo);
2566 return NULL;
2569 /* Analyze the access patterns of the data-refs in the loop (consecutive,
2570 complex, etc.). FORNOW: Only handle consecutive access pattern. */
2572 ok = vect_analyze_data_ref_accesses (loop_vinfo);
2573 if (!ok)
2575 if (vect_print_dump_info (REPORT_DETAILS, LOOP_LOC (loop_vinfo)))
2576 fprintf (vect_dump, "bad data access.");
2577 destroy_loop_vec_info (loop_vinfo);
2578 return NULL;
2581 ok = vect_determine_vectorization_factor (loop_vinfo);
2582 if (!ok)
2584 if (vect_print_dump_info (REPORT_DETAILS, LOOP_LOC (loop_vinfo)))
2585 fprintf (vect_dump, "can't determine vectorization factor.");
2586 destroy_loop_vec_info (loop_vinfo);
2587 return NULL;
2590 /* Analyze the alignment of the data-refs in the loop.
2591 FORNOW: Only aligned accesses are handled. */
2593 ok = vect_analyze_data_refs_alignment (loop_vinfo);
2594 if (!ok)
2596 if (vect_print_dump_info (REPORT_DETAILS, LOOP_LOC (loop_vinfo)))
2597 fprintf (vect_dump, "bad data alignment.");
2598 destroy_loop_vec_info (loop_vinfo);
2599 return NULL;
2602 /* Scan all the operations in the loop and make sure they are
2603 vectorizable. */
2605 ok = vect_analyze_operations (loop_vinfo);
2606 if (!ok)
2608 if (vect_print_dump_info (REPORT_DETAILS, LOOP_LOC (loop_vinfo)))
2609 fprintf (vect_dump, "bad operation or unsupported loop bound.");
2610 destroy_loop_vec_info (loop_vinfo);
2611 return NULL;
2614 LOOP_VINFO_VECTORIZABLE_P (loop_vinfo) = 1;
2616 return loop_vinfo;