re PR tree-optimization/54570 (FAIL: gcc.dg/builtin-object-size-8.c execution test)
[gcc.git] / gcc / tree-vectorizer.h
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>
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
12
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
21
22 #ifndef GCC_TREE_VECTORIZER_H
23 #define GCC_TREE_VECTORIZER_H
24
25 #include "tree-data-ref.h"
26 #include "target.h"
27
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)
33
34 /* Used for naming of new temporaries. */
35 enum vect_var_kind {
36 vect_simple_var,
37 vect_pointer_var,
38 vect_scalar_var
39 };
40
41 /* Defines type of operation. */
42 enum operation_type {
43 unary_op = 1,
44 binary_op,
45 ternary_op
46 };
47
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
55 };
56
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
68 };
69
70 #define VECTORIZABLE_CYCLE_DEF(D) (((D) == vect_reduction_def) \
71 || ((D) == vect_double_reduction_def) \
72 || ((D) == vect_nested_cycle))
73
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;
82
83
84 typedef vec<stmt_info_for_cost> stmt_vector_for_cost;
85
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)
89 {
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);
96 }
97
98 /************************************************************************
99 SLP
100 ************************************************************************/
101 typedef void *slp_void_p;
102
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;
118
119
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;
125
126 /* Size of groups of scalar stmts that will be replaced by SIMD stmt/s. */
127 unsigned int group_size;
128
129 /* The unrolling factor required to vectorized this SLP instance. */
130 unsigned int unrolling_factor;
131
132 /* Vectorization costs associated with SLP instance. */
133 stmt_vector_for_cost body_cost_vec;
134
135 /* Loads permutation relatively to the stores, NULL if there is no
136 permutation. */
137 vec<int> load_permutation;
138
139 /* The group of nodes that contain loads of this SLP instance. */
140 vec<slp_tree> loads;
141
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;
146
147
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
156
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
161
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
166 {
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;
177
178
179
180 typedef struct _vect_peel_info
181 {
182 int npeel;
183 struct data_reference *dr;
184 unsigned int count;
185 } *vect_peel_info;
186
187 typedef struct _vect_peel_extended_info
188 {
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;
194
195 /*-----------------------------------------------------------------*/
196 /* Info on vectorized loops. */
197 /*-----------------------------------------------------------------*/
198 typedef struct _loop_vec_info {
199
200 /* The loop to which this info struct refers to. */
201 struct loop *loop;
202
203 /* The loop basic blocks. */
204 basic_block *bbs;
205
206 /* Number of iterations. */
207 tree num_iters;
208 tree num_iters_unchanged;
209
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;
216
217 /* Is the loop vectorizable? */
218 bool vectorizable;
219
220 /* Unrolling factor */
221 int vectorization_factor;
222
223 /* The loop location in the source. */
224 LOC loop_line_number;
225
226 /* Unknown DRs according to which loop was peeled. */
227 struct data_reference *unaligned_dr;
228
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;
238
239 /* The mask used to check the alignment of pointers or arrays. */
240 int ptr_mask;
241
242 /* The loop nest in which the data dependences are computed. */
243 vec<loop_p> loop_nest;
244
245 /* All data references in the loop. */
246 vec<data_reference_p> datarefs;
247
248 /* All data dependences in the loop. */
249 vec<ddr_p> ddrs;
250
251 /* Data Dependence Relations defining address ranges that are candidates
252 for a run-time aliasing check. */
253 vec<ddr_p> may_alias_ddrs;
254
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;
258
259 /* All interleaving chains of stores in the loop, represented by the first
260 stmt in the chain. */
261 vec<gimple> grouped_stores;
262
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;
266
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;
270
271 /* Reduction cycles detected in the loop. Used in loop-aware SLP. */
272 vec<gimple> reductions;
273
274 /* All reduction chains in the loop, represented by the first
275 stmt in the chain. */
276 vec<gimple> reduction_chains;
277
278 /* Hash table used to choose the best peeling option. */
279 htab_t peeling_htab;
280
281 /* Cost data used by the target cost model. */
282 void *target_cost_data;
283
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;
288
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;
294
295 } *loop_vec_info;
296
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
326
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
331
332 #define NITERS_KNOWN_P(n) \
333 (host_integerp ((n),0) \
334 && TREE_INT_CST_LOW ((n)) > 0)
335
336 #define LOOP_VINFO_NITERS_KNOWN_P(L) \
337 NITERS_KNOWN_P((L)->num_iters)
338
339 static inline loop_vec_info
340 loop_vec_info_for_loop (struct loop *loop)
341 {
342 return (loop_vec_info) loop->aux;
343 }
344
345 static inline bool
346 nested_in_vect_loop_p (struct loop *loop, gimple stmt)
347 {
348 return (loop->inner
349 && (loop->inner == (gimple_bb (stmt))->loop_father));
350 }
351
352 typedef struct _bb_vec_info {
353
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;
358
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;
362
363 /* All data references in the basic block. */
364 vec<data_reference_p> datarefs;
365
366 /* All data dependences in the basic block. */
367 vec<ddr_p> ddrs;
368
369 /* Cost data used by the target cost model. */
370 void *target_cost_data;
371
372 } *bb_vec_info;
373
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
380
381 static inline bb_vec_info
382 vec_info_for_bb (basic_block bb)
383 {
384 return (bb_vec_info) bb->aux;
385 }
386
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
405 };
406
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,
417
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,
425
426 vect_used_in_scope
427 };
428
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.
434
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
449 };
450
451
452 typedef struct data_reference *dr_p;
453
454 typedef struct _stmt_vec_info {
455
456 enum stmt_vec_info_type type;
457
458 /* Indicates whether this stmts is part of a computation whose result is
459 used outside the loop. */
460 bool live;
461
462 /* Stmt is part of some pattern (computation idiom) */
463 bool in_pattern_p;
464
465 /* For loads only, if there is a store with the same location, this field is
466 TRUE. */
467 bool read_write_dep;
468
469 /* The stmt to which this info struct refers to. */
470 gimple stmt;
471
472 /* The loop_vec_info with respect to which STMT is vectorized. */
473 loop_vec_info loop_vinfo;
474
475 /* The vector type to be used for the LHS of this statement. */
476 tree vectype;
477
478 /* The vectorized version of the stmt. */
479 gimple vectorized_stmt;
480
481
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. **/
485
486 /* Information about the data-ref (access function, etc),
487 relative to the inner-most containing loop. */
488 struct data_reference *data_ref_info;
489
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;
497
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;
504
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;
515
516 /* Used to keep a sequence of def stmts of a pattern stmt if such exists. */
517 gimple_seq pattern_def_seq;
518
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;
522
523 /* Classify the def of this stmt. */
524 enum vect_def_type def_type;
525
526 /* Whether the stmt is SLPed, loop-based vectorized, or both. */
527 enum slp_vect_type slp_type;
528
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;
545
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;
550
551 /* The bb_vec_info with respect to which STMT is vectorized. */
552 bb_vec_info bb_vinfo;
553
554 /* Is this statement vectorizable or should it be skipped in (partial)
555 vectorization. */
556 bool vectorizable;
557
558 /* For loads only, true if this is a gather load. */
559 bool gather_p;
560 bool stride_load_p;
561 } *stmt_vec_info;
562
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
576
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
582
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
597
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
605
606 #define STMT_VINFO_RELEVANT_P(S) ((S)->relevant != vect_unused_in_scope)
607
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
611
612 #define VECT_MAX_COST 1000
613
614 /* The maximum number of intermediate steps required in multi-step type
615 conversion. */
616 #define MAX_INTERM_CVT_STEPS 3
617
618 /* The maximum vectorization factor supported by any target (V32QI). */
619 #define MAX_VECTORIZATION_FACTOR 32
620
621 /* Avoid GTY(()) on stmt_vec_info. */
622 typedef void *vec_void_p;
623
624 extern vec<vec_void_p> stmt_vec_info_vec;
625
626 void init_stmt_vec_info_vec (void);
627 void free_stmt_vec_info_vec (void);
628
629 /* Return a stmt_vec_info corresponding to STMT. */
630
631 static inline stmt_vec_info
632 vinfo_for_stmt (gimple stmt)
633 {
634 unsigned int uid = gimple_uid (stmt);
635 if (uid == 0)
636 return NULL;
637
638 return (stmt_vec_info) stmt_vec_info_vec[uid - 1];
639 }
640
641 /* Set vectorizer information INFO for STMT. */
642
643 static inline void
644 set_vinfo_for_stmt (gimple stmt, stmt_vec_info info)
645 {
646 unsigned int uid = gimple_uid (stmt);
647 if (uid == 0)
648 {
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);
653 }
654 else
655 stmt_vec_info_vec[uid - 1] = (vec_void_p) info;
656 }
657
658 /* Return the earlier statement between STMT1 and STMT2. */
659
660 static inline gimple
661 get_earlier_stmt (gimple stmt1, gimple stmt2)
662 {
663 unsigned int uid1, uid2;
664
665 if (stmt1 == NULL)
666 return stmt2;
667
668 if (stmt2 == NULL)
669 return stmt1;
670
671 uid1 = gimple_uid (stmt1);
672 uid2 = gimple_uid (stmt2);
673
674 if (uid1 == 0 || uid2 == 0)
675 return NULL;
676
677 gcc_checking_assert (uid1 <= stmt_vec_info_vec.length ()
678 && uid2 <= stmt_vec_info_vec.length ());
679
680 if (uid1 < uid2)
681 return stmt1;
682 else
683 return stmt2;
684 }
685
686 /* Return the later statement between STMT1 and STMT2. */
687
688 static inline gimple
689 get_later_stmt (gimple stmt1, gimple stmt2)
690 {
691 unsigned int uid1, uid2;
692
693 if (stmt1 == NULL)
694 return stmt2;
695
696 if (stmt2 == NULL)
697 return stmt1;
698
699 uid1 = gimple_uid (stmt1);
700 uid2 = gimple_uid (stmt2);
701
702 if (uid1 == 0 || uid2 == 0)
703 return NULL;
704
705 gcc_assert (uid1 <= stmt_vec_info_vec.length ());
706 gcc_assert (uid2 <= stmt_vec_info_vec.length ());
707
708 if (uid1 > uid2)
709 return stmt1;
710 else
711 return stmt2;
712 }
713
714 /* Return TRUE if a statement represented by STMT_INFO is a part of a
715 pattern. */
716
717 static inline bool
718 is_pattern_stmt_p (stmt_vec_info stmt_info)
719 {
720 gimple related_stmt;
721 stmt_vec_info related_stmt_info;
722
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;
728
729 return false;
730 }
731
732 /* Return true if BB is a loop header. */
733
734 static inline bool
735 is_loop_header_bb_p (basic_block bb)
736 {
737 if (bb == (bb->loop_father)->header)
738 return true;
739 gcc_checking_assert (EDGE_COUNT (bb->preds) == 1);
740 return false;
741 }
742
743 /* Return pow2 (X). */
744
745 static inline int
746 vect_pow2 (int x)
747 {
748 int i, res = 1;
749
750 for (i = 0; i < x; i++)
751 res *= 2;
752
753 return res;
754 }
755
756 /* Alias targetm.vectorize.builtin_vectorization_cost. */
757
758 static inline int
759 builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost,
760 tree vectype, int misalign)
761 {
762 return targetm.vectorize.builtin_vectorization_cost (type_of_cost,
763 vectype, misalign);
764 }
765
766 /* Get cost by calling cost target builtin. */
767
768 static inline
769 int vect_get_stmt_cost (enum vect_cost_for_stmt type_of_cost)
770 {
771 return builtin_vectorization_cost (type_of_cost, NULL, 0);
772 }
773
774 /* Alias targetm.vectorize.init_cost. */
775
776 static inline void *
777 init_cost (struct loop *loop_info)
778 {
779 return targetm.vectorize.init_cost (loop_info);
780 }
781
782 /* Alias targetm.vectorize.add_stmt_cost. */
783
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)
788 {
789 return targetm.vectorize.add_stmt_cost (data, count, kind,
790 stmt_info, misalign, where);
791 }
792
793 /* Alias targetm.vectorize.finish_cost. */
794
795 static inline void
796 finish_cost (void *data, unsigned *prologue_cost,
797 unsigned *body_cost, unsigned *epilogue_cost)
798 {
799 targetm.vectorize.finish_cost (data, prologue_cost, body_cost, epilogue_cost);
800 }
801
802 /* Alias targetm.vectorize.destroy_cost_data. */
803
804 static inline void
805 destroy_cost_data (void *data)
806 {
807 targetm.vectorize.destroy_cost_data (data);
808 }
809
810
811 /*-----------------------------------------------------------------*/
812 /* Info on data references alignment. */
813 /*-----------------------------------------------------------------*/
814
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))
819
820 /* Return TRUE if the data access is aligned, and FALSE otherwise. */
821
822 static inline bool
823 aligned_access_p (struct data_reference *data_ref_info)
824 {
825 return (DR_MISALIGNMENT (data_ref_info) == 0);
826 }
827
828 /* Return TRUE if the alignment of the data access is known, and FALSE
829 otherwise. */
830
831 static inline bool
832 known_alignment_for_access_p (struct data_reference *data_ref_info)
833 {
834 return (DR_MISALIGNMENT (data_ref_info) != -1);
835 }
836
837 /* Source location */
838 extern LOC vect_location;
839
840 /*-----------------------------------------------------------------*/
841 /* Function prototypes. */
842 /*-----------------------------------------------------------------*/
843
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);
854
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 *);
911
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 *);
950
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);
971
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);
984
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);
988
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);
996
997 /* In tree-vectorizer.c. */
998 unsigned vectorize_loops (void);
999
1000 #endif /* GCC_TREE_VECTORIZER_H */