configure.ac (multiarch): Use $enableval instead of $withval.
[official-gcc.git] / gcc / tree-vectorizer.h
blobe533d2c60860b042d4d2e52725e92d6bac1d957b
1 /* Vectorizer
2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
3 Free Software Foundation, Inc.
4 Contributed by Dorit Naishlos <dorit@il.ibm.com>
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
22 #ifndef GCC_TREE_VECTORIZER_H
23 #define GCC_TREE_VECTORIZER_H
25 #include "tree-data-ref.h"
26 #include "target.h"
28 typedef source_location LOC;
29 #define UNKNOWN_LOC UNKNOWN_LOCATION
30 #define EXPR_LOC(e) EXPR_LOCATION(e)
31 #define LOC_FILE(l) LOCATION_FILE (l)
32 #define LOC_LINE(l) LOCATION_LINE (l)
34 /* Used for naming of new temporaries. */
35 enum vect_var_kind {
36 vect_simple_var,
37 vect_pointer_var,
38 vect_scalar_var
41 /* Defines type of operation. */
42 enum operation_type {
43 unary_op = 1,
44 binary_op,
45 ternary_op
48 /* Define type of available alignment support. */
49 enum dr_alignment_support {
50 dr_unaligned_unsupported,
51 dr_unaligned_supported,
52 dr_explicit_realign,
53 dr_explicit_realign_optimized,
54 dr_aligned
57 /* Define type of def-use cross-iteration cycle. */
58 enum vect_def_type {
59 vect_uninitialized_def = 0,
60 vect_constant_def = 1,
61 vect_external_def,
62 vect_internal_def,
63 vect_induction_def,
64 vect_reduction_def,
65 vect_double_reduction_def,
66 vect_nested_cycle,
67 vect_unknown_def_type
70 #define VECTORIZABLE_CYCLE_DEF(D) (((D) == vect_reduction_def) \
71 || ((D) == vect_double_reduction_def) \
72 || ((D) == vect_nested_cycle))
74 /* Structure to encapsulate information about a group of like
75 instructions to be presented to the target cost model. */
76 typedef struct _stmt_info_for_cost {
77 int count;
78 enum vect_cost_for_stmt kind;
79 gimple stmt;
80 int misalign;
81 } stmt_info_for_cost;
84 typedef vec<stmt_info_for_cost> stmt_vector_for_cost;
86 static inline void
87 add_stmt_info_to_vec (stmt_vector_for_cost *stmt_cost_vec, int count,
88 enum vect_cost_for_stmt kind, gimple stmt, int misalign)
90 stmt_info_for_cost si;
91 si.count = count;
92 si.kind = kind;
93 si.stmt = stmt;
94 si.misalign = misalign;
95 stmt_cost_vec->safe_push (si);
98 /************************************************************************
99 SLP
100 ************************************************************************/
101 typedef void *slp_void_p;
103 /* A computation tree of an SLP instance. Each node corresponds to a group of
104 stmts to be packed in a SIMD stmt. */
105 typedef struct _slp_tree {
106 /* Nodes that contain def-stmts of this node statements operands. */
107 vec<slp_void_p> children;
108 /* A group of scalar stmts to be vectorized together. */
109 vec<gimple> stmts;
110 /* Vectorized stmt/s. */
111 vec<gimple> vec_stmts;
112 /* Number of vector stmts that are created to replace the group of scalar
113 stmts. It is calculated during the transformation phase as the number of
114 scalar elements in one scalar iteration (GROUP_SIZE) multiplied by VF
115 divided by vector size. */
116 unsigned int vec_stmts_size;
117 } *slp_tree;
120 /* SLP instance is a sequence of stmts in a loop that can be packed into
121 SIMD stmts. */
122 typedef struct _slp_instance {
123 /* The root of SLP tree. */
124 slp_tree root;
126 /* Size of groups of scalar stmts that will be replaced by SIMD stmt/s. */
127 unsigned int group_size;
129 /* The unrolling factor required to vectorized this SLP instance. */
130 unsigned int unrolling_factor;
132 /* Vectorization costs associated with SLP instance. */
133 stmt_vector_for_cost body_cost_vec;
135 /* Loads permutation relatively to the stores, NULL if there is no
136 permutation. */
137 vec<int> load_permutation;
139 /* The group of nodes that contain loads of this SLP instance. */
140 vec<slp_tree> loads;
142 /* The first scalar load of the instance. The created vector loads will be
143 inserted before this statement. */
144 gimple first_load;
145 } *slp_instance;
148 /* Access Functions. */
149 #define SLP_INSTANCE_TREE(S) (S)->root
150 #define SLP_INSTANCE_GROUP_SIZE(S) (S)->group_size
151 #define SLP_INSTANCE_UNROLLING_FACTOR(S) (S)->unrolling_factor
152 #define SLP_INSTANCE_BODY_COST_VEC(S) (S)->body_cost_vec
153 #define SLP_INSTANCE_LOAD_PERMUTATION(S) (S)->load_permutation
154 #define SLP_INSTANCE_LOADS(S) (S)->loads
155 #define SLP_INSTANCE_FIRST_LOAD_STMT(S) (S)->first_load
157 #define SLP_TREE_CHILDREN(S) (S)->children
158 #define SLP_TREE_SCALAR_STMTS(S) (S)->stmts
159 #define SLP_TREE_VEC_STMTS(S) (S)->vec_stmts
160 #define SLP_TREE_NUMBER_OF_VEC_STMTS(S) (S)->vec_stmts_size
162 /* This structure is used in creation of an SLP tree. Each instance
163 corresponds to the same operand in a group of scalar stmts in an SLP
164 node. */
165 typedef struct _slp_oprnd_info
167 /* Def-stmts for the operands. */
168 vec<gimple> def_stmts;
169 /* Information about the first statement, its vector def-type, type, the
170 operand itself in case it's constant, and an indication if it's a pattern
171 stmt. */
172 enum vect_def_type first_dt;
173 tree first_def_type;
174 tree first_const_oprnd;
175 bool first_pattern;
176 } *slp_oprnd_info;
180 typedef struct _vect_peel_info
182 int npeel;
183 struct data_reference *dr;
184 unsigned int count;
185 } *vect_peel_info;
187 typedef struct _vect_peel_extended_info
189 struct _vect_peel_info peel_info;
190 unsigned int inside_cost;
191 unsigned int outside_cost;
192 stmt_vector_for_cost body_cost_vec;
193 } *vect_peel_extended_info;
195 /*-----------------------------------------------------------------*/
196 /* Info on vectorized loops. */
197 /*-----------------------------------------------------------------*/
198 typedef struct _loop_vec_info {
200 /* The loop to which this info struct refers to. */
201 struct loop *loop;
203 /* The loop basic blocks. */
204 basic_block *bbs;
206 /* Number of iterations. */
207 tree num_iters;
208 tree num_iters_unchanged;
210 /* Minimum number of iterations below which vectorization is expected to
211 not be profitable (as estimated by the cost model).
212 -1 indicates that vectorization will not be profitable.
213 FORNOW: This field is an int. Will be a tree in the future, to represent
214 values unknown at compile time. */
215 int min_profitable_iters;
217 /* Is the loop vectorizable? */
218 bool vectorizable;
220 /* Unrolling factor */
221 int vectorization_factor;
223 /* The loop location in the source. */
224 LOC loop_line_number;
226 /* Unknown DRs according to which loop was peeled. */
227 struct data_reference *unaligned_dr;
229 /* peeling_for_alignment indicates whether peeling for alignment will take
230 place, and what the peeling factor should be:
231 peeling_for_alignment = X means:
232 If X=0: Peeling for alignment will not be applied.
233 If X>0: Peel first X iterations.
234 If X=-1: Generate a runtime test to calculate the number of iterations
235 to be peeled, using the dataref recorded in the field
236 unaligned_dr. */
237 int peeling_for_alignment;
239 /* The mask used to check the alignment of pointers or arrays. */
240 int ptr_mask;
242 /* The loop nest in which the data dependences are computed. */
243 vec<loop_p> loop_nest;
245 /* All data references in the loop. */
246 vec<data_reference_p> datarefs;
248 /* All data dependences in the loop. */
249 vec<ddr_p> ddrs;
251 /* Data Dependence Relations defining address ranges that are candidates
252 for a run-time aliasing check. */
253 vec<ddr_p> may_alias_ddrs;
255 /* Statements in the loop that have data references that are candidates for a
256 runtime (loop versioning) misalignment check. */
257 vec<gimple> may_misalign_stmts;
259 /* All interleaving chains of stores in the loop, represented by the first
260 stmt in the chain. */
261 vec<gimple> grouped_stores;
263 /* All SLP instances in the loop. This is a subset of the set of GROUP_STORES
264 of the loop. */
265 vec<slp_instance> slp_instances;
267 /* The unrolling factor needed to SLP the loop. In case of that pure SLP is
268 applied to the loop, i.e., no unrolling is needed, this is 1. */
269 unsigned slp_unrolling_factor;
271 /* Reduction cycles detected in the loop. Used in loop-aware SLP. */
272 vec<gimple> reductions;
274 /* All reduction chains in the loop, represented by the first
275 stmt in the chain. */
276 vec<gimple> reduction_chains;
278 /* Hash table used to choose the best peeling option. */
279 htab_t peeling_htab;
281 /* Cost data used by the target cost model. */
282 void *target_cost_data;
284 /* When we have grouped data accesses with gaps, we may introduce invalid
285 memory accesses. We peel the last iteration of the loop to prevent
286 this. */
287 bool peeling_for_gaps;
289 /* Reductions are canonicalized so that the last operand is the reduction
290 operand. If this places a constant into RHS1, this decanonicalizes
291 GIMPLE for other phases, so we must track when this has occurred and
292 fix it up. */
293 bool operands_swapped;
295 } *loop_vec_info;
297 /* Access Functions. */
298 #define LOOP_VINFO_LOOP(L) (L)->loop
299 #define LOOP_VINFO_BBS(L) (L)->bbs
300 #define LOOP_VINFO_NITERS(L) (L)->num_iters
301 /* Since LOOP_VINFO_NITERS can change after prologue peeling
302 retain total unchanged scalar loop iterations for cost model. */
303 #define LOOP_VINFO_NITERS_UNCHANGED(L) (L)->num_iters_unchanged
304 #define LOOP_VINFO_COST_MODEL_MIN_ITERS(L) (L)->min_profitable_iters
305 #define LOOP_VINFO_VECTORIZABLE_P(L) (L)->vectorizable
306 #define LOOP_VINFO_VECT_FACTOR(L) (L)->vectorization_factor
307 #define LOOP_VINFO_PTR_MASK(L) (L)->ptr_mask
308 #define LOOP_VINFO_LOOP_NEST(L) (L)->loop_nest
309 #define LOOP_VINFO_DATAREFS(L) (L)->datarefs
310 #define LOOP_VINFO_DDRS(L) (L)->ddrs
311 #define LOOP_VINFO_INT_NITERS(L) (TREE_INT_CST_LOW ((L)->num_iters))
312 #define LOOP_PEELING_FOR_ALIGNMENT(L) (L)->peeling_for_alignment
313 #define LOOP_VINFO_UNALIGNED_DR(L) (L)->unaligned_dr
314 #define LOOP_VINFO_MAY_MISALIGN_STMTS(L) (L)->may_misalign_stmts
315 #define LOOP_VINFO_LOC(L) (L)->loop_line_number
316 #define LOOP_VINFO_MAY_ALIAS_DDRS(L) (L)->may_alias_ddrs
317 #define LOOP_VINFO_GROUPED_STORES(L) (L)->grouped_stores
318 #define LOOP_VINFO_SLP_INSTANCES(L) (L)->slp_instances
319 #define LOOP_VINFO_SLP_UNROLLING_FACTOR(L) (L)->slp_unrolling_factor
320 #define LOOP_VINFO_REDUCTIONS(L) (L)->reductions
321 #define LOOP_VINFO_REDUCTION_CHAINS(L) (L)->reduction_chains
322 #define LOOP_VINFO_PEELING_HTAB(L) (L)->peeling_htab
323 #define LOOP_VINFO_TARGET_COST_DATA(L) (L)->target_cost_data
324 #define LOOP_VINFO_PEELING_FOR_GAPS(L) (L)->peeling_for_gaps
325 #define LOOP_VINFO_OPERANDS_SWAPPED(L) (L)->operands_swapped
327 #define LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT(L) \
328 (L)->may_misalign_stmts.length () > 0
329 #define LOOP_REQUIRES_VERSIONING_FOR_ALIAS(L) \
330 (L)->may_alias_ddrs.length () > 0
332 #define NITERS_KNOWN_P(n) \
333 (host_integerp ((n),0) \
334 && TREE_INT_CST_LOW ((n)) > 0)
336 #define LOOP_VINFO_NITERS_KNOWN_P(L) \
337 NITERS_KNOWN_P((L)->num_iters)
339 static inline loop_vec_info
340 loop_vec_info_for_loop (struct loop *loop)
342 return (loop_vec_info) loop->aux;
345 static inline bool
346 nested_in_vect_loop_p (struct loop *loop, gimple stmt)
348 return (loop->inner
349 && (loop->inner == (gimple_bb (stmt))->loop_father));
352 typedef struct _bb_vec_info {
354 basic_block bb;
355 /* All interleaving chains of stores in the basic block, represented by the
356 first stmt in the chain. */
357 vec<gimple> grouped_stores;
359 /* All SLP instances in the basic block. This is a subset of the set of
360 GROUP_STORES of the basic block. */
361 vec<slp_instance> slp_instances;
363 /* All data references in the basic block. */
364 vec<data_reference_p> datarefs;
366 /* All data dependences in the basic block. */
367 vec<ddr_p> ddrs;
369 /* Cost data used by the target cost model. */
370 void *target_cost_data;
372 } *bb_vec_info;
374 #define BB_VINFO_BB(B) (B)->bb
375 #define BB_VINFO_GROUPED_STORES(B) (B)->grouped_stores
376 #define BB_VINFO_SLP_INSTANCES(B) (B)->slp_instances
377 #define BB_VINFO_DATAREFS(B) (B)->datarefs
378 #define BB_VINFO_DDRS(B) (B)->ddrs
379 #define BB_VINFO_TARGET_COST_DATA(B) (B)->target_cost_data
381 static inline bb_vec_info
382 vec_info_for_bb (basic_block bb)
384 return (bb_vec_info) bb->aux;
387 /*-----------------------------------------------------------------*/
388 /* Info on vectorized defs. */
389 /*-----------------------------------------------------------------*/
390 enum stmt_vec_info_type {
391 undef_vec_info_type = 0,
392 load_vec_info_type,
393 store_vec_info_type,
394 shift_vec_info_type,
395 op_vec_info_type,
396 call_vec_info_type,
397 assignment_vec_info_type,
398 condition_vec_info_type,
399 reduc_vec_info_type,
400 induc_vec_info_type,
401 type_promotion_vec_info_type,
402 type_demotion_vec_info_type,
403 type_conversion_vec_info_type,
404 loop_exit_ctrl_vec_info_type
407 /* Indicates whether/how a variable is used in the scope of loop/basic
408 block. */
409 enum vect_relevant {
410 vect_unused_in_scope = 0,
411 /* The def is in the inner loop, and the use is in the outer loop, and the
412 use is a reduction stmt. */
413 vect_used_in_outer_by_reduction,
414 /* The def is in the inner loop, and the use is in the outer loop (and is
415 not part of reduction). */
416 vect_used_in_outer,
418 /* defs that feed computations that end up (only) in a reduction. These
419 defs may be used by non-reduction stmts, but eventually, any
420 computations/values that are affected by these defs are used to compute
421 a reduction (i.e. don't get stored to memory, for example). We use this
422 to identify computations that we can change the order in which they are
423 computed. */
424 vect_used_by_reduction,
426 vect_used_in_scope
429 /* The type of vectorization that can be applied to the stmt: regular loop-based
430 vectorization; pure SLP - the stmt is a part of SLP instances and does not
431 have uses outside SLP instances; or hybrid SLP and loop-based - the stmt is
432 a part of SLP instance and also must be loop-based vectorized, since it has
433 uses outside SLP sequences.
435 In the loop context the meanings of pure and hybrid SLP are slightly
436 different. By saying that pure SLP is applied to the loop, we mean that we
437 exploit only intra-iteration parallelism in the loop; i.e., the loop can be
438 vectorized without doing any conceptual unrolling, cause we don't pack
439 together stmts from different iterations, only within a single iteration.
440 Loop hybrid SLP means that we exploit both intra-iteration and
441 inter-iteration parallelism (e.g., number of elements in the vector is 4
442 and the slp-group-size is 2, in which case we don't have enough parallelism
443 within an iteration, so we obtain the rest of the parallelism from subsequent
444 iterations by unrolling the loop by 2). */
445 enum slp_vect_type {
446 loop_vect = 0,
447 pure_slp,
448 hybrid
452 typedef struct data_reference *dr_p;
454 typedef struct _stmt_vec_info {
456 enum stmt_vec_info_type type;
458 /* Indicates whether this stmts is part of a computation whose result is
459 used outside the loop. */
460 bool live;
462 /* Stmt is part of some pattern (computation idiom) */
463 bool in_pattern_p;
465 /* For loads only, if there is a store with the same location, this field is
466 TRUE. */
467 bool read_write_dep;
469 /* The stmt to which this info struct refers to. */
470 gimple stmt;
472 /* The loop_vec_info with respect to which STMT is vectorized. */
473 loop_vec_info loop_vinfo;
475 /* The vector type to be used for the LHS of this statement. */
476 tree vectype;
478 /* The vectorized version of the stmt. */
479 gimple vectorized_stmt;
482 /** The following is relevant only for stmts that contain a non-scalar
483 data-ref (array/pointer/struct access). A GIMPLE stmt is expected to have
484 at most one such data-ref. **/
486 /* Information about the data-ref (access function, etc),
487 relative to the inner-most containing loop. */
488 struct data_reference *data_ref_info;
490 /* Information about the data-ref relative to this loop
491 nest (the loop that is being considered for vectorization). */
492 tree dr_base_address;
493 tree dr_init;
494 tree dr_offset;
495 tree dr_step;
496 tree dr_aligned_to;
498 /* For loop PHI nodes, the evolution part of it. This makes sure
499 this information is still available in vect_update_ivs_after_vectorizer
500 where we may not be able to re-analyze the PHI nodes evolution as
501 peeling for the prologue loop can make it unanalyzable. The evolution
502 part is still correct though. */
503 tree loop_phi_evolution_part;
505 /* Used for various bookkeeping purposes, generally holding a pointer to
506 some other stmt S that is in some way "related" to this stmt.
507 Current use of this field is:
508 If this stmt is part of a pattern (i.e. the field 'in_pattern_p' is
509 true): S is the "pattern stmt" that represents (and replaces) the
510 sequence of stmts that constitutes the pattern. Similarly, the
511 related_stmt of the "pattern stmt" points back to this stmt (which is
512 the last stmt in the original sequence of stmts that constitutes the
513 pattern). */
514 gimple related_stmt;
516 /* Used to keep a sequence of def stmts of a pattern stmt if such exists. */
517 gimple_seq pattern_def_seq;
519 /* List of datarefs that are known to have the same alignment as the dataref
520 of this stmt. */
521 vec<dr_p> same_align_refs;
523 /* Classify the def of this stmt. */
524 enum vect_def_type def_type;
526 /* Whether the stmt is SLPed, loop-based vectorized, or both. */
527 enum slp_vect_type slp_type;
529 /* Interleaving and reduction chains info. */
530 /* First element in the group. */
531 gimple first_element;
532 /* Pointer to the next element in the group. */
533 gimple next_element;
534 /* For data-refs, in case that two or more stmts share data-ref, this is the
535 pointer to the previously detected stmt with the same dr. */
536 gimple same_dr_stmt;
537 /* The size of the group. */
538 unsigned int size;
539 /* For stores, number of stores from this group seen. We vectorize the last
540 one. */
541 unsigned int store_count;
542 /* For loads only, the gap from the previous load. For consecutive loads, GAP
543 is 1. */
544 unsigned int gap;
546 /* Not all stmts in the loop need to be vectorized. e.g, the increment
547 of the loop induction variable and computation of array indexes. relevant
548 indicates whether the stmt needs to be vectorized. */
549 enum vect_relevant relevant;
551 /* The bb_vec_info with respect to which STMT is vectorized. */
552 bb_vec_info bb_vinfo;
554 /* Is this statement vectorizable or should it be skipped in (partial)
555 vectorization. */
556 bool vectorizable;
558 /* For loads only, true if this is a gather load. */
559 bool gather_p;
560 bool stride_load_p;
561 } *stmt_vec_info;
563 /* Access Functions. */
564 #define STMT_VINFO_TYPE(S) (S)->type
565 #define STMT_VINFO_STMT(S) (S)->stmt
566 #define STMT_VINFO_LOOP_VINFO(S) (S)->loop_vinfo
567 #define STMT_VINFO_BB_VINFO(S) (S)->bb_vinfo
568 #define STMT_VINFO_RELEVANT(S) (S)->relevant
569 #define STMT_VINFO_LIVE_P(S) (S)->live
570 #define STMT_VINFO_VECTYPE(S) (S)->vectype
571 #define STMT_VINFO_VEC_STMT(S) (S)->vectorized_stmt
572 #define STMT_VINFO_VECTORIZABLE(S) (S)->vectorizable
573 #define STMT_VINFO_DATA_REF(S) (S)->data_ref_info
574 #define STMT_VINFO_GATHER_P(S) (S)->gather_p
575 #define STMT_VINFO_STRIDE_LOAD_P(S) (S)->stride_load_p
577 #define STMT_VINFO_DR_BASE_ADDRESS(S) (S)->dr_base_address
578 #define STMT_VINFO_DR_INIT(S) (S)->dr_init
579 #define STMT_VINFO_DR_OFFSET(S) (S)->dr_offset
580 #define STMT_VINFO_DR_STEP(S) (S)->dr_step
581 #define STMT_VINFO_DR_ALIGNED_TO(S) (S)->dr_aligned_to
583 #define STMT_VINFO_IN_PATTERN_P(S) (S)->in_pattern_p
584 #define STMT_VINFO_RELATED_STMT(S) (S)->related_stmt
585 #define STMT_VINFO_PATTERN_DEF_SEQ(S) (S)->pattern_def_seq
586 #define STMT_VINFO_SAME_ALIGN_REFS(S) (S)->same_align_refs
587 #define STMT_VINFO_DEF_TYPE(S) (S)->def_type
588 #define STMT_VINFO_GROUP_FIRST_ELEMENT(S) (S)->first_element
589 #define STMT_VINFO_GROUP_NEXT_ELEMENT(S) (S)->next_element
590 #define STMT_VINFO_GROUP_SIZE(S) (S)->size
591 #define STMT_VINFO_GROUP_STORE_COUNT(S) (S)->store_count
592 #define STMT_VINFO_GROUP_GAP(S) (S)->gap
593 #define STMT_VINFO_GROUP_SAME_DR_STMT(S) (S)->same_dr_stmt
594 #define STMT_VINFO_GROUP_READ_WRITE_DEPENDENCE(S) (S)->read_write_dep
595 #define STMT_VINFO_GROUPED_ACCESS(S) ((S)->first_element != NULL && (S)->data_ref_info)
596 #define STMT_VINFO_LOOP_PHI_EVOLUTION_PART(S) (S)->loop_phi_evolution_part
598 #define GROUP_FIRST_ELEMENT(S) (S)->first_element
599 #define GROUP_NEXT_ELEMENT(S) (S)->next_element
600 #define GROUP_SIZE(S) (S)->size
601 #define GROUP_STORE_COUNT(S) (S)->store_count
602 #define GROUP_GAP(S) (S)->gap
603 #define GROUP_SAME_DR_STMT(S) (S)->same_dr_stmt
604 #define GROUP_READ_WRITE_DEPENDENCE(S) (S)->read_write_dep
606 #define STMT_VINFO_RELEVANT_P(S) ((S)->relevant != vect_unused_in_scope)
608 #define HYBRID_SLP_STMT(S) ((S)->slp_type == hybrid)
609 #define PURE_SLP_STMT(S) ((S)->slp_type == pure_slp)
610 #define STMT_SLP_TYPE(S) (S)->slp_type
612 #define VECT_MAX_COST 1000
614 /* The maximum number of intermediate steps required in multi-step type
615 conversion. */
616 #define MAX_INTERM_CVT_STEPS 3
618 /* The maximum vectorization factor supported by any target (V32QI). */
619 #define MAX_VECTORIZATION_FACTOR 32
621 /* Avoid GTY(()) on stmt_vec_info. */
622 typedef void *vec_void_p;
624 extern vec<vec_void_p> stmt_vec_info_vec;
626 void init_stmt_vec_info_vec (void);
627 void free_stmt_vec_info_vec (void);
629 /* Return a stmt_vec_info corresponding to STMT. */
631 static inline stmt_vec_info
632 vinfo_for_stmt (gimple stmt)
634 unsigned int uid = gimple_uid (stmt);
635 if (uid == 0)
636 return NULL;
638 return (stmt_vec_info) stmt_vec_info_vec[uid - 1];
641 /* Set vectorizer information INFO for STMT. */
643 static inline void
644 set_vinfo_for_stmt (gimple stmt, stmt_vec_info info)
646 unsigned int uid = gimple_uid (stmt);
647 if (uid == 0)
649 gcc_checking_assert (info);
650 uid = stmt_vec_info_vec.length () + 1;
651 gimple_set_uid (stmt, uid);
652 stmt_vec_info_vec.safe_push ((vec_void_p) info);
654 else
655 stmt_vec_info_vec[uid - 1] = (vec_void_p) info;
658 /* Return the earlier statement between STMT1 and STMT2. */
660 static inline gimple
661 get_earlier_stmt (gimple stmt1, gimple stmt2)
663 unsigned int uid1, uid2;
665 if (stmt1 == NULL)
666 return stmt2;
668 if (stmt2 == NULL)
669 return stmt1;
671 uid1 = gimple_uid (stmt1);
672 uid2 = gimple_uid (stmt2);
674 if (uid1 == 0 || uid2 == 0)
675 return NULL;
677 gcc_checking_assert (uid1 <= stmt_vec_info_vec.length ()
678 && uid2 <= stmt_vec_info_vec.length ());
680 if (uid1 < uid2)
681 return stmt1;
682 else
683 return stmt2;
686 /* Return the later statement between STMT1 and STMT2. */
688 static inline gimple
689 get_later_stmt (gimple stmt1, gimple stmt2)
691 unsigned int uid1, uid2;
693 if (stmt1 == NULL)
694 return stmt2;
696 if (stmt2 == NULL)
697 return stmt1;
699 uid1 = gimple_uid (stmt1);
700 uid2 = gimple_uid (stmt2);
702 if (uid1 == 0 || uid2 == 0)
703 return NULL;
705 gcc_assert (uid1 <= stmt_vec_info_vec.length ());
706 gcc_assert (uid2 <= stmt_vec_info_vec.length ());
708 if (uid1 > uid2)
709 return stmt1;
710 else
711 return stmt2;
714 /* Return TRUE if a statement represented by STMT_INFO is a part of a
715 pattern. */
717 static inline bool
718 is_pattern_stmt_p (stmt_vec_info stmt_info)
720 gimple related_stmt;
721 stmt_vec_info related_stmt_info;
723 related_stmt = STMT_VINFO_RELATED_STMT (stmt_info);
724 if (related_stmt
725 && (related_stmt_info = vinfo_for_stmt (related_stmt))
726 && STMT_VINFO_IN_PATTERN_P (related_stmt_info))
727 return true;
729 return false;
732 /* Return true if BB is a loop header. */
734 static inline bool
735 is_loop_header_bb_p (basic_block bb)
737 if (bb == (bb->loop_father)->header)
738 return true;
739 gcc_checking_assert (EDGE_COUNT (bb->preds) == 1);
740 return false;
743 /* Return pow2 (X). */
745 static inline int
746 vect_pow2 (int x)
748 int i, res = 1;
750 for (i = 0; i < x; i++)
751 res *= 2;
753 return res;
756 /* Alias targetm.vectorize.builtin_vectorization_cost. */
758 static inline int
759 builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost,
760 tree vectype, int misalign)
762 return targetm.vectorize.builtin_vectorization_cost (type_of_cost,
763 vectype, misalign);
766 /* Get cost by calling cost target builtin. */
768 static inline
769 int vect_get_stmt_cost (enum vect_cost_for_stmt type_of_cost)
771 return builtin_vectorization_cost (type_of_cost, NULL, 0);
774 /* Alias targetm.vectorize.init_cost. */
776 static inline void *
777 init_cost (struct loop *loop_info)
779 return targetm.vectorize.init_cost (loop_info);
782 /* Alias targetm.vectorize.add_stmt_cost. */
784 static inline unsigned
785 add_stmt_cost (void *data, int count, enum vect_cost_for_stmt kind,
786 stmt_vec_info stmt_info, int misalign,
787 enum vect_cost_model_location where)
789 return targetm.vectorize.add_stmt_cost (data, count, kind,
790 stmt_info, misalign, where);
793 /* Alias targetm.vectorize.finish_cost. */
795 static inline void
796 finish_cost (void *data, unsigned *prologue_cost,
797 unsigned *body_cost, unsigned *epilogue_cost)
799 targetm.vectorize.finish_cost (data, prologue_cost, body_cost, epilogue_cost);
802 /* Alias targetm.vectorize.destroy_cost_data. */
804 static inline void
805 destroy_cost_data (void *data)
807 targetm.vectorize.destroy_cost_data (data);
811 /*-----------------------------------------------------------------*/
812 /* Info on data references alignment. */
813 /*-----------------------------------------------------------------*/
815 /* Reflects actual alignment of first access in the vectorized loop,
816 taking into account peeling/versioning if applied. */
817 #define DR_MISALIGNMENT(DR) ((int) (size_t) (DR)->aux)
818 #define SET_DR_MISALIGNMENT(DR, VAL) ((DR)->aux = (void *) (size_t) (VAL))
820 /* Return TRUE if the data access is aligned, and FALSE otherwise. */
822 static inline bool
823 aligned_access_p (struct data_reference *data_ref_info)
825 return (DR_MISALIGNMENT (data_ref_info) == 0);
828 /* Return TRUE if the alignment of the data access is known, and FALSE
829 otherwise. */
831 static inline bool
832 known_alignment_for_access_p (struct data_reference *data_ref_info)
834 return (DR_MISALIGNMENT (data_ref_info) != -1);
837 /* Source location */
838 extern LOC vect_location;
840 /*-----------------------------------------------------------------*/
841 /* Function prototypes. */
842 /*-----------------------------------------------------------------*/
844 /* Simple loop peeling and versioning utilities for vectorizer's purposes -
845 in tree-vect-loop-manip.c. */
846 extern void slpeel_make_loop_iterate_ntimes (struct loop *, tree);
847 extern bool slpeel_can_duplicate_loop_p (const struct loop *, const_edge);
848 extern void vect_loop_versioning (loop_vec_info, unsigned int, bool);
849 extern void vect_do_peeling_for_loop_bound (loop_vec_info, tree *,
850 unsigned int, bool);
851 extern void vect_do_peeling_for_alignment (loop_vec_info, unsigned int, bool);
852 extern LOC find_loop_location (struct loop *);
853 extern bool vect_can_advance_ivs_p (loop_vec_info);
855 /* In tree-vect-stmts.c. */
856 extern unsigned int current_vector_size;
857 extern tree get_vectype_for_scalar_type (tree);
858 extern tree get_same_sized_vectype (tree, tree);
859 extern bool vect_is_simple_use (tree, gimple, loop_vec_info,
860 bb_vec_info, gimple *,
861 tree *, enum vect_def_type *);
862 extern bool vect_is_simple_use_1 (tree, gimple, loop_vec_info,
863 bb_vec_info, gimple *,
864 tree *, enum vect_def_type *, tree *);
865 extern bool supportable_widening_operation (enum tree_code, gimple, tree, tree,
866 enum tree_code *, enum tree_code *,
867 int *, vec<tree> *);
868 extern bool supportable_narrowing_operation (enum tree_code, tree, tree,
869 enum tree_code *,
870 int *, vec<tree> *);
871 extern stmt_vec_info new_stmt_vec_info (gimple stmt, loop_vec_info,
872 bb_vec_info);
873 extern void free_stmt_vec_info (gimple stmt);
874 extern tree vectorizable_function (gimple, tree, tree);
875 extern void vect_model_simple_cost (stmt_vec_info, int, enum vect_def_type *,
876 stmt_vector_for_cost *,
877 stmt_vector_for_cost *);
878 extern void vect_model_store_cost (stmt_vec_info, int, bool,
879 enum vect_def_type, slp_tree,
880 stmt_vector_for_cost *,
881 stmt_vector_for_cost *);
882 extern void vect_model_load_cost (stmt_vec_info, int, bool, slp_tree,
883 stmt_vector_for_cost *,
884 stmt_vector_for_cost *);
885 extern unsigned record_stmt_cost (stmt_vector_for_cost *, int,
886 enum vect_cost_for_stmt, stmt_vec_info,
887 int, enum vect_cost_model_location);
888 extern void vect_finish_stmt_generation (gimple, gimple,
889 gimple_stmt_iterator *);
890 extern bool vect_mark_stmts_to_be_vectorized (loop_vec_info);
891 extern tree vect_get_vec_def_for_operand (tree, gimple, tree *);
892 extern tree vect_init_vector (gimple, tree, tree,
893 gimple_stmt_iterator *);
894 extern tree vect_get_vec_def_for_stmt_copy (enum vect_def_type, tree);
895 extern bool vect_transform_stmt (gimple, gimple_stmt_iterator *,
896 bool *, slp_tree, slp_instance);
897 extern void vect_remove_stores (gimple);
898 extern bool vect_analyze_stmt (gimple, bool *, slp_tree);
899 extern bool vectorizable_condition (gimple, gimple_stmt_iterator *, gimple *,
900 tree, int, slp_tree);
901 extern void vect_get_load_cost (struct data_reference *, int, bool,
902 unsigned int *, unsigned int *,
903 stmt_vector_for_cost *,
904 stmt_vector_for_cost *, bool);
905 extern void vect_get_store_cost (struct data_reference *, int,
906 unsigned int *, stmt_vector_for_cost *);
907 extern bool vect_supportable_shift (enum tree_code, tree);
908 extern void vect_get_vec_defs (tree, tree, gimple, vec<tree> *,
909 vec<tree> *, slp_tree, int);
910 extern tree vect_gen_perm_mask (tree, unsigned char *);
912 /* In tree-vect-data-refs.c. */
913 extern bool vect_can_force_dr_alignment_p (const_tree, unsigned int);
914 extern enum dr_alignment_support vect_supportable_dr_alignment
915 (struct data_reference *, bool);
916 extern tree vect_get_smallest_scalar_type (gimple, HOST_WIDE_INT *,
917 HOST_WIDE_INT *);
918 extern bool vect_analyze_data_ref_dependences (loop_vec_info, bb_vec_info,
919 int *);
920 extern bool vect_enhance_data_refs_alignment (loop_vec_info);
921 extern bool vect_analyze_data_refs_alignment (loop_vec_info, bb_vec_info);
922 extern bool vect_verify_datarefs_alignment (loop_vec_info, bb_vec_info);
923 extern bool vect_analyze_data_ref_accesses (loop_vec_info, bb_vec_info);
924 extern bool vect_prune_runtime_alias_test_list (loop_vec_info);
925 extern tree vect_check_gather (gimple, loop_vec_info, tree *, tree *,
926 int *);
927 extern bool vect_check_strided_load (gimple, loop_vec_info, tree *, tree *);
928 extern bool vect_analyze_data_refs (loop_vec_info, bb_vec_info, int *);
929 extern tree vect_create_data_ref_ptr (gimple, tree, struct loop *, tree,
930 tree *, gimple_stmt_iterator *,
931 gimple *, bool, bool *);
932 extern tree bump_vector_ptr (tree, gimple, gimple_stmt_iterator *, gimple, tree);
933 extern tree vect_create_destination_var (tree, tree);
934 extern bool vect_grouped_store_supported (tree, unsigned HOST_WIDE_INT);
935 extern bool vect_store_lanes_supported (tree, unsigned HOST_WIDE_INT);
936 extern bool vect_grouped_load_supported (tree, unsigned HOST_WIDE_INT);
937 extern bool vect_load_lanes_supported (tree, unsigned HOST_WIDE_INT);
938 extern void vect_permute_store_chain (vec<tree> ,unsigned int, gimple,
939 gimple_stmt_iterator *, vec<tree> *);
940 extern tree vect_setup_realignment (gimple, gimple_stmt_iterator *, tree *,
941 enum dr_alignment_support, tree,
942 struct loop **);
943 extern void vect_transform_grouped_load (gimple, vec<tree> , int,
944 gimple_stmt_iterator *);
945 extern void vect_record_grouped_load_vectors (gimple, vec<tree> );
946 extern int vect_get_place_in_interleaving_chain (gimple, gimple);
947 extern tree vect_get_new_vect_var (tree, enum vect_var_kind, const char *);
948 extern tree vect_create_addr_base_for_vector_ref (gimple, gimple_seq *,
949 tree, struct loop *);
951 /* In tree-vect-loop.c. */
952 /* FORNOW: Used in tree-parloops.c. */
953 extern void destroy_loop_vec_info (loop_vec_info, bool);
954 extern gimple vect_force_simple_reduction (loop_vec_info, gimple, bool, bool *);
955 /* Drive for loop analysis stage. */
956 extern loop_vec_info vect_analyze_loop (struct loop *);
957 /* Drive for loop transformation stage. */
958 extern void vect_transform_loop (loop_vec_info);
959 extern loop_vec_info vect_analyze_loop_form (struct loop *);
960 extern bool vectorizable_live_operation (gimple, gimple_stmt_iterator *,
961 gimple *);
962 extern bool vectorizable_reduction (gimple, gimple_stmt_iterator *, gimple *,
963 slp_tree);
964 extern bool vectorizable_induction (gimple, gimple_stmt_iterator *, gimple *);
965 extern tree get_initial_def_for_reduction (gimple, tree, tree *);
966 extern int vect_min_worthwhile_factor (enum tree_code);
967 extern int vect_get_known_peeling_cost (loop_vec_info, int, int *, int,
968 stmt_vector_for_cost *,
969 stmt_vector_for_cost *);
970 extern int vect_get_single_scalar_iteration_cost (loop_vec_info);
972 /* In tree-vect-slp.c. */
973 extern void vect_free_slp_instance (slp_instance);
974 extern bool vect_transform_slp_perm_load (gimple, vec<tree> ,
975 gimple_stmt_iterator *, int,
976 slp_instance, bool);
977 extern bool vect_schedule_slp (loop_vec_info, bb_vec_info);
978 extern void vect_update_slp_costs_according_to_vf (loop_vec_info);
979 extern bool vect_analyze_slp (loop_vec_info, bb_vec_info);
980 extern bool vect_make_slp_decision (loop_vec_info);
981 extern void vect_detect_hybrid_slp (loop_vec_info);
982 extern void vect_get_slp_defs (vec<tree> , slp_tree,
983 vec<slp_void_p> *, int);
985 extern LOC find_bb_location (basic_block);
986 extern bb_vec_info vect_slp_analyze_bb (basic_block);
987 extern void vect_slp_transform_bb (basic_block);
989 /* In tree-vect-patterns.c. */
990 /* Pattern recognition functions.
991 Additional pattern recognition functions can (and will) be added
992 in the future. */
993 typedef gimple (* vect_recog_func_ptr) (vec<gimple> *, tree *, tree *);
994 #define NUM_PATTERNS 10
995 void vect_pattern_recog (loop_vec_info, bb_vec_info);
997 /* In tree-vectorizer.c. */
998 unsigned vectorize_loops (void);
1000 #endif /* GCC_TREE_VECTORIZER_H */