OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / tree-vectorizer.h
1 /* Vectorizer
2    Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
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
27 typedef source_location LOC;
28 #define UNKNOWN_LOC UNKNOWN_LOCATION
29 #define EXPR_LOC(e) EXPR_LOCATION(e)
30 #define LOC_FILE(l) LOCATION_FILE (l)
31 #define LOC_LINE(l) LOCATION_LINE (l)
32
33 /* Used for naming of new temporaries.  */
34 enum vect_var_kind {
35   vect_simple_var,
36   vect_pointer_var,
37   vect_scalar_var
38 };
39
40 /* Defines type of operation.  */
41 enum operation_type {
42   unary_op = 1,
43   binary_op,
44   ternary_op
45 };
46
47 /* Define type of available alignment support.  */
48 enum dr_alignment_support {
49   dr_unaligned_unsupported,
50   dr_unaligned_supported,
51   dr_explicit_realign,
52   dr_explicit_realign_optimized,
53   dr_aligned
54 };
55
56 /* Define type of def-use cross-iteration cycle.  */
57 enum vect_def_type {
58   vect_uninitialized_def = 0,
59   vect_constant_def = 1,
60   vect_external_def,
61   vect_internal_def,
62   vect_induction_def,
63   vect_reduction_def,
64   vect_double_reduction_def,
65   vect_nested_cycle,
66   vect_unknown_def_type
67 };
68
69 #define VECTORIZABLE_CYCLE_DEF(D) (((D) == vect_reduction_def)           \
70                                    || ((D) == vect_double_reduction_def) \
71                                    || ((D) == vect_nested_cycle))
72
73 /************************************************************************
74   SLP
75  ************************************************************************/
76
77 /* A computation tree of an SLP instance. Each node corresponds to a group of
78    stmts to be packed in a SIMD stmt.  */
79 typedef struct _slp_tree {
80   /* Only binary and unary operations are supported. LEFT child corresponds to
81      the first operand and RIGHT child to the second if the operation is
82      binary.  */
83   struct _slp_tree *left;
84   struct _slp_tree *right;
85   /* A group of scalar stmts to be vectorized together.  */
86   VEC (gimple, heap) *stmts;
87   /* Vectorized stmt/s.  */
88   VEC (gimple, heap) *vec_stmts;
89   /* Number of vector stmts that are created to replace the group of scalar
90      stmts. It is calculated during the transformation phase as the number of
91      scalar elements in one scalar iteration (GROUP_SIZE) multiplied by VF
92      divided by vector size.  */
93   unsigned int vec_stmts_size;
94   /* Vectorization costs associated with SLP node.  */
95   struct
96   {
97     int outside_of_loop;     /* Statements generated outside loop.  */
98     int inside_of_loop;      /* Statements generated inside loop.  */
99   } cost;
100 } *slp_tree;
101
102 DEF_VEC_P(slp_tree);
103 DEF_VEC_ALLOC_P(slp_tree, heap);
104
105 /* SLP instance is a sequence of stmts in a loop that can be packed into
106    SIMD stmts.  */
107 typedef struct _slp_instance {
108   /* The root of SLP tree.  */
109   slp_tree root;
110
111   /* Size of groups of scalar stmts that will be replaced by SIMD stmt/s.  */
112   unsigned int group_size;
113
114   /* The unrolling factor required to vectorized this SLP instance.  */
115   unsigned int unrolling_factor;
116
117   /* Vectorization costs associated with SLP instance.  */
118   struct
119   {
120     int outside_of_loop;     /* Statements generated outside loop.  */
121     int inside_of_loop;      /* Statements generated inside loop.  */
122   } cost;
123
124   /* Loads permutation relatively to the stores, NULL if there is no
125      permutation.  */
126   VEC (int, heap) *load_permutation;
127
128   /* The group of nodes that contain loads of this SLP instance.  */
129   VEC (slp_tree, heap) *loads;
130
131   /* The first scalar load of the instance. The created vector loads will be
132      inserted before this statement.  */
133   gimple first_load;
134 } *slp_instance;
135
136 DEF_VEC_P(slp_instance);
137 DEF_VEC_ALLOC_P(slp_instance, heap);
138
139 /* Access Functions.  */
140 #define SLP_INSTANCE_TREE(S)                     (S)->root
141 #define SLP_INSTANCE_GROUP_SIZE(S)               (S)->group_size
142 #define SLP_INSTANCE_UNROLLING_FACTOR(S)         (S)->unrolling_factor
143 #define SLP_INSTANCE_OUTSIDE_OF_LOOP_COST(S)     (S)->cost.outside_of_loop
144 #define SLP_INSTANCE_INSIDE_OF_LOOP_COST(S)      (S)->cost.inside_of_loop
145 #define SLP_INSTANCE_LOAD_PERMUTATION(S)         (S)->load_permutation
146 #define SLP_INSTANCE_LOADS(S)                    (S)->loads
147 #define SLP_INSTANCE_FIRST_LOAD_STMT(S)          (S)->first_load
148
149 #define SLP_TREE_LEFT(S)                         (S)->left
150 #define SLP_TREE_RIGHT(S)                        (S)->right
151 #define SLP_TREE_SCALAR_STMTS(S)                 (S)->stmts
152 #define SLP_TREE_VEC_STMTS(S)                    (S)->vec_stmts
153 #define SLP_TREE_NUMBER_OF_VEC_STMTS(S)          (S)->vec_stmts_size
154 #define SLP_TREE_OUTSIDE_OF_LOOP_COST(S)         (S)->cost.outside_of_loop
155 #define SLP_TREE_INSIDE_OF_LOOP_COST(S)          (S)->cost.inside_of_loop
156
157
158 typedef struct _vect_peel_info
159 {
160   int npeel;
161   struct data_reference *dr;
162   unsigned int count;
163 } *vect_peel_info;
164
165 typedef struct _vect_peel_extended_info
166 {
167   struct _vect_peel_info peel_info;
168   unsigned int inside_cost;
169   unsigned int outside_cost;
170 } *vect_peel_extended_info;
171
172 /*-----------------------------------------------------------------*/
173 /* Info on vectorized loops.                                       */
174 /*-----------------------------------------------------------------*/
175 typedef struct _loop_vec_info {
176
177   /* The loop to which this info struct refers to.  */
178   struct loop *loop;
179
180   /* The loop basic blocks.  */
181   basic_block *bbs;
182
183   /* Number of iterations.  */
184   tree num_iters;
185   tree num_iters_unchanged;
186
187   /* Minimum number of iterations below which vectorization is expected to
188      not be profitable (as estimated by the cost model).
189      -1 indicates that vectorization will not be profitable.
190      FORNOW: This field is an int. Will be a tree in the future, to represent
191              values unknown at compile time.  */
192   int min_profitable_iters;
193
194   /* Is the loop vectorizable? */
195   bool vectorizable;
196
197   /* Unrolling factor  */
198   int vectorization_factor;
199
200   /* The loop location in the source.  */
201   LOC loop_line_number;
202
203   /* Unknown DRs according to which loop was peeled.  */
204   struct data_reference *unaligned_dr;
205
206   /* peeling_for_alignment indicates whether peeling for alignment will take
207      place, and what the peeling factor should be:
208      peeling_for_alignment = X means:
209         If X=0: Peeling for alignment will not be applied.
210         If X>0: Peel first X iterations.
211         If X=-1: Generate a runtime test to calculate the number of iterations
212                  to be peeled, using the dataref recorded in the field
213                  unaligned_dr.  */
214   int peeling_for_alignment;
215
216   /* The mask used to check the alignment of pointers or arrays.  */
217   int ptr_mask;
218
219   /* The loop nest in which the data dependences are computed.  */
220   VEC (loop_p, heap) *loop_nest;
221
222   /* All data references in the loop.  */
223   VEC (data_reference_p, heap) *datarefs;
224
225   /* All data dependences in the loop.  */
226   VEC (ddr_p, heap) *ddrs;
227
228   /* Data Dependence Relations defining address ranges that are candidates
229      for a run-time aliasing check.  */
230   VEC (ddr_p, heap) *may_alias_ddrs;
231
232   /* Statements in the loop that have data references that are candidates for a
233      runtime (loop versioning) misalignment check.  */
234   VEC(gimple,heap) *may_misalign_stmts;
235
236   /* All interleaving chains of stores in the loop, represented by the first
237      stmt in the chain.  */
238   VEC(gimple, heap) *strided_stores;
239
240   /* All SLP instances in the loop. This is a subset of the set of STRIDED_STORES
241      of the loop.  */
242   VEC(slp_instance, heap) *slp_instances;
243
244   /* The unrolling factor needed to SLP the loop. In case of that pure SLP is
245      applied to the loop, i.e., no unrolling is needed, this is 1.  */
246   unsigned slp_unrolling_factor;
247
248   /* Reduction cycles detected in the loop. Used in loop-aware SLP.  */
249   VEC (gimple, heap) *reductions;
250
251   /* Hash table used to choose the best peeling option.  */
252   htab_t peeling_htab;
253
254   /* When we have strided data accesses with gaps, we may introduce invalid
255      memory accesses.  We peel the last iteration of the loop to prevent
256      this.  */
257   bool peeling_for_gaps;
258
259 } *loop_vec_info;
260
261 /* Access Functions.  */
262 #define LOOP_VINFO_LOOP(L)                 (L)->loop
263 #define LOOP_VINFO_BBS(L)                  (L)->bbs
264 #define LOOP_VINFO_NITERS(L)               (L)->num_iters
265 /* Since LOOP_VINFO_NITERS can change after prologue peeling
266    retain total unchanged scalar loop iterations for cost model.  */
267 #define LOOP_VINFO_NITERS_UNCHANGED(L)     (L)->num_iters_unchanged
268 #define LOOP_VINFO_COST_MODEL_MIN_ITERS(L) (L)->min_profitable_iters
269 #define LOOP_VINFO_VECTORIZABLE_P(L)       (L)->vectorizable
270 #define LOOP_VINFO_VECT_FACTOR(L)          (L)->vectorization_factor
271 #define LOOP_VINFO_PTR_MASK(L)             (L)->ptr_mask
272 #define LOOP_VINFO_LOOP_NEST(L)            (L)->loop_nest
273 #define LOOP_VINFO_DATAREFS(L)             (L)->datarefs
274 #define LOOP_VINFO_DDRS(L)                 (L)->ddrs
275 #define LOOP_VINFO_INT_NITERS(L)           (TREE_INT_CST_LOW ((L)->num_iters))
276 #define LOOP_PEELING_FOR_ALIGNMENT(L)      (L)->peeling_for_alignment
277 #define LOOP_VINFO_UNALIGNED_DR(L)         (L)->unaligned_dr
278 #define LOOP_VINFO_MAY_MISALIGN_STMTS(L)   (L)->may_misalign_stmts
279 #define LOOP_VINFO_LOC(L)                  (L)->loop_line_number
280 #define LOOP_VINFO_MAY_ALIAS_DDRS(L)       (L)->may_alias_ddrs
281 #define LOOP_VINFO_STRIDED_STORES(L)       (L)->strided_stores
282 #define LOOP_VINFO_SLP_INSTANCES(L)        (L)->slp_instances
283 #define LOOP_VINFO_SLP_UNROLLING_FACTOR(L) (L)->slp_unrolling_factor
284 #define LOOP_VINFO_REDUCTIONS(L)           (L)->reductions
285 #define LOOP_VINFO_PEELING_HTAB(L)         (L)->peeling_htab
286 #define LOOP_VINFO_PEELING_FOR_GAPS(L)     (L)->peeling_for_gaps
287
288 #define LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT(L) \
289 VEC_length (gimple, (L)->may_misalign_stmts) > 0
290 #define LOOP_REQUIRES_VERSIONING_FOR_ALIAS(L)     \
291 VEC_length (ddr_p, (L)->may_alias_ddrs) > 0
292
293 #define NITERS_KNOWN_P(n)                     \
294 (host_integerp ((n),0)                        \
295 && TREE_INT_CST_LOW ((n)) > 0)
296
297 #define LOOP_VINFO_NITERS_KNOWN_P(L)          \
298 NITERS_KNOWN_P((L)->num_iters)
299
300 static inline loop_vec_info
301 loop_vec_info_for_loop (struct loop *loop)
302 {
303   return (loop_vec_info) loop->aux;
304 }
305
306 static inline bool
307 nested_in_vect_loop_p (struct loop *loop, gimple stmt)
308 {
309   return (loop->inner
310           && (loop->inner == (gimple_bb (stmt))->loop_father));
311 }
312
313 typedef struct _bb_vec_info {
314
315   basic_block bb;
316   /* All interleaving chains of stores in the basic block, represented by the
317      first stmt in the chain.  */
318   VEC(gimple, heap) *strided_stores;
319
320   /* All SLP instances in the basic block. This is a subset of the set of
321      STRIDED_STORES of the basic block.  */
322   VEC(slp_instance, heap) *slp_instances;
323
324   /* All data references in the basic block.  */
325   VEC (data_reference_p, heap) *datarefs;
326
327   /* All data dependences in the basic block.  */
328   VEC (ddr_p, heap) *ddrs;
329 } *bb_vec_info;
330
331 #define BB_VINFO_BB(B)              (B)->bb
332 #define BB_VINFO_STRIDED_STORES(B)  (B)->strided_stores
333 #define BB_VINFO_SLP_INSTANCES(B)   (B)->slp_instances
334 #define BB_VINFO_DATAREFS(B)        (B)->datarefs
335 #define BB_VINFO_DDRS(B)            (B)->ddrs
336
337 static inline bb_vec_info
338 vec_info_for_bb (basic_block bb)
339 {
340   return (bb_vec_info) bb->aux;
341 }
342
343 /*-----------------------------------------------------------------*/
344 /* Info on vectorized defs.                                        */
345 /*-----------------------------------------------------------------*/
346 enum stmt_vec_info_type {
347   undef_vec_info_type = 0,
348   load_vec_info_type,
349   store_vec_info_type,
350   shift_vec_info_type,
351   op_vec_info_type,
352   call_vec_info_type,
353   assignment_vec_info_type,
354   condition_vec_info_type,
355   reduc_vec_info_type,
356   induc_vec_info_type,
357   type_promotion_vec_info_type,
358   type_demotion_vec_info_type,
359   type_conversion_vec_info_type,
360   loop_exit_ctrl_vec_info_type
361 };
362
363 /* Indicates whether/how a variable is used in the scope of loop/basic
364    block.  */
365 enum vect_relevant {
366   vect_unused_in_scope = 0,
367   /* The def is in the inner loop, and the use is in the outer loop, and the
368      use is a reduction stmt.  */
369   vect_used_in_outer_by_reduction,
370   /* The def is in the inner loop, and the use is in the outer loop (and is
371      not part of reduction).  */
372   vect_used_in_outer,
373
374   /* defs that feed computations that end up (only) in a reduction. These
375      defs may be used by non-reduction stmts, but eventually, any
376      computations/values that are affected by these defs are used to compute
377      a reduction (i.e. don't get stored to memory, for example). We use this
378      to identify computations that we can change the order in which they are
379      computed.  */
380   vect_used_by_reduction,
381
382   vect_used_in_scope
383 };
384
385 /* The type of vectorization that can be applied to the stmt: regular loop-based
386    vectorization; pure SLP - the stmt is a part of SLP instances and does not
387    have uses outside SLP instances; or hybrid SLP and loop-based - the stmt is
388    a part of SLP instance and also must be loop-based vectorized, since it has
389    uses outside SLP sequences.
390
391    In the loop context the meanings of pure and hybrid SLP are slightly
392    different. By saying that pure SLP is applied to the loop, we mean that we
393    exploit only intra-iteration parallelism in the loop; i.e., the loop can be
394    vectorized without doing any conceptual unrolling, cause we don't pack
395    together stmts from different iterations, only within a single iteration.
396    Loop hybrid SLP means that we exploit both intra-iteration and
397    inter-iteration parallelism (e.g., number of elements in the vector is 4
398    and the slp-group-size is 2, in which case we don't have enough parallelism
399    within an iteration, so we obtain the rest of the parallelism from subsequent
400    iterations by unrolling the loop by 2).  */
401 enum slp_vect_type {
402   loop_vect = 0,
403   pure_slp,
404   hybrid
405 };
406
407
408 typedef struct data_reference *dr_p;
409 DEF_VEC_P(dr_p);
410 DEF_VEC_ALLOC_P(dr_p,heap);
411
412 typedef struct _stmt_vec_info {
413
414   enum stmt_vec_info_type type;
415
416   /* Indicates whether this stmts is part of a computation whose result is
417      used outside the loop.  */
418   bool live;
419
420   /* Stmt is part of some pattern (computation idiom)  */
421   bool in_pattern_p;
422
423   /* For loads only, if there is a store with the same location, this field is
424      TRUE.  */
425   bool read_write_dep;
426
427   /* The stmt to which this info struct refers to.  */
428   gimple stmt;
429
430   /* The loop_vec_info with respect to which STMT is vectorized.  */
431   loop_vec_info loop_vinfo;
432
433   /* The vector type to be used for the LHS of this statement.  */
434   tree vectype;
435
436   /* The vectorized version of the stmt.  */
437   gimple vectorized_stmt;
438
439
440   /** The following is relevant only for stmts that contain a non-scalar
441      data-ref (array/pointer/struct access). A GIMPLE stmt is expected to have
442      at most one such data-ref.  **/
443
444   /* Information about the data-ref (access function, etc),
445      relative to the inner-most containing loop.  */
446   struct data_reference *data_ref_info;
447
448   /* Information about the data-ref relative to this loop
449      nest (the loop that is being considered for vectorization).  */
450   tree dr_base_address;
451   tree dr_init;
452   tree dr_offset;
453   tree dr_step;
454   tree dr_aligned_to;
455
456   /* Used for various bookkeeping purposes, generally holding a pointer to
457      some other stmt S that is in some way "related" to this stmt.
458      Current use of this field is:
459         If this stmt is part of a pattern (i.e. the field 'in_pattern_p' is
460         true): S is the "pattern stmt" that represents (and replaces) the
461         sequence of stmts that constitutes the pattern.  Similarly, the
462         related_stmt of the "pattern stmt" points back to this stmt (which is
463         the last stmt in the original sequence of stmts that constitutes the
464         pattern).  */
465   gimple related_stmt;
466
467   /* List of datarefs that are known to have the same alignment as the dataref
468      of this stmt.  */
469   VEC(dr_p,heap) *same_align_refs;
470
471   /* Classify the def of this stmt.  */
472   enum vect_def_type def_type;
473
474   /*  Whether the stmt is SLPed, loop-based vectorized, or both.  */
475   enum slp_vect_type slp_type;
476
477   /* Interleaving info.  */
478   /* First data-ref in the interleaving group.  */
479   gimple first_dr;
480   /* Pointer to the next data-ref in the group.  */
481   gimple next_dr;
482   /* In case that two or more stmts share data-ref, this is the pointer to the
483      previously detected stmt with the same dr.  */
484   gimple same_dr_stmt;
485   /* The size of the interleaving group.  */
486   unsigned int size;
487   /* For stores, number of stores from this group seen. We vectorize the last
488      one.  */
489   unsigned int store_count;
490   /* For loads only, the gap from the previous load. For consecutive loads, GAP
491      is 1.  */
492   unsigned int gap;
493
494   /* Not all stmts in the loop need to be vectorized. e.g, the increment
495      of the loop induction variable and computation of array indexes. relevant
496      indicates whether the stmt needs to be vectorized.  */
497   enum vect_relevant relevant;
498
499   /* Vectorization costs associated with statement.  */
500   struct
501   {
502     int outside_of_loop;     /* Statements generated outside loop.  */
503     int inside_of_loop;      /* Statements generated inside loop.  */
504   } cost;
505
506   /* The bb_vec_info with respect to which STMT is vectorized.  */
507   bb_vec_info bb_vinfo;
508
509   /* Is this statement vectorizable or should it be skipped in (partial)
510      vectorization.  */
511   bool vectorizable;
512 } *stmt_vec_info;
513
514 /* Access Functions.  */
515 #define STMT_VINFO_TYPE(S)                 (S)->type
516 #define STMT_VINFO_STMT(S)                 (S)->stmt
517 #define STMT_VINFO_LOOP_VINFO(S)           (S)->loop_vinfo
518 #define STMT_VINFO_BB_VINFO(S)             (S)->bb_vinfo
519 #define STMT_VINFO_RELEVANT(S)             (S)->relevant
520 #define STMT_VINFO_LIVE_P(S)               (S)->live
521 #define STMT_VINFO_VECTYPE(S)              (S)->vectype
522 #define STMT_VINFO_VEC_STMT(S)             (S)->vectorized_stmt
523 #define STMT_VINFO_VECTORIZABLE(S)         (S)->vectorizable
524 #define STMT_VINFO_DATA_REF(S)             (S)->data_ref_info
525
526 #define STMT_VINFO_DR_BASE_ADDRESS(S)      (S)->dr_base_address
527 #define STMT_VINFO_DR_INIT(S)              (S)->dr_init
528 #define STMT_VINFO_DR_OFFSET(S)            (S)->dr_offset
529 #define STMT_VINFO_DR_STEP(S)              (S)->dr_step
530 #define STMT_VINFO_DR_ALIGNED_TO(S)        (S)->dr_aligned_to
531
532 #define STMT_VINFO_IN_PATTERN_P(S)         (S)->in_pattern_p
533 #define STMT_VINFO_RELATED_STMT(S)         (S)->related_stmt
534 #define STMT_VINFO_SAME_ALIGN_REFS(S)      (S)->same_align_refs
535 #define STMT_VINFO_DEF_TYPE(S)             (S)->def_type
536 #define STMT_VINFO_DR_GROUP_FIRST_DR(S)    (S)->first_dr
537 #define STMT_VINFO_DR_GROUP_NEXT_DR(S)     (S)->next_dr
538 #define STMT_VINFO_DR_GROUP_SIZE(S)        (S)->size
539 #define STMT_VINFO_DR_GROUP_STORE_COUNT(S) (S)->store_count
540 #define STMT_VINFO_DR_GROUP_GAP(S)         (S)->gap
541 #define STMT_VINFO_DR_GROUP_SAME_DR_STMT(S)(S)->same_dr_stmt
542 #define STMT_VINFO_DR_GROUP_READ_WRITE_DEPENDENCE(S)  (S)->read_write_dep
543 #define STMT_VINFO_STRIDED_ACCESS(S)      ((S)->first_dr != NULL)
544
545 #define DR_GROUP_FIRST_DR(S)               (S)->first_dr
546 #define DR_GROUP_NEXT_DR(S)                (S)->next_dr
547 #define DR_GROUP_SIZE(S)                   (S)->size
548 #define DR_GROUP_STORE_COUNT(S)            (S)->store_count
549 #define DR_GROUP_GAP(S)                    (S)->gap
550 #define DR_GROUP_SAME_DR_STMT(S)           (S)->same_dr_stmt
551 #define DR_GROUP_READ_WRITE_DEPENDENCE(S)  (S)->read_write_dep
552
553 #define STMT_VINFO_RELEVANT_P(S)          ((S)->relevant != vect_unused_in_scope)
554 #define STMT_VINFO_OUTSIDE_OF_LOOP_COST(S) (S)->cost.outside_of_loop
555 #define STMT_VINFO_INSIDE_OF_LOOP_COST(S)  (S)->cost.inside_of_loop
556
557 #define HYBRID_SLP_STMT(S)                ((S)->slp_type == hybrid)
558 #define PURE_SLP_STMT(S)                  ((S)->slp_type == pure_slp)
559 #define STMT_SLP_TYPE(S)                   (S)->slp_type
560
561 #define VECT_MAX_COST 1000
562
563 /* The maximum number of intermediate steps required in multi-step type
564    conversion.  */
565 #define MAX_INTERM_CVT_STEPS         3
566
567 /* The maximum vectorization factor supported by any target (V32QI).  */
568 #define MAX_VECTORIZATION_FACTOR 32
569
570 /* Avoid GTY(()) on stmt_vec_info.  */
571 typedef void *vec_void_p;
572 DEF_VEC_P (vec_void_p);
573 DEF_VEC_ALLOC_P (vec_void_p, heap);
574
575 extern VEC(vec_void_p,heap) *stmt_vec_info_vec;
576
577 void init_stmt_vec_info_vec (void);
578 void free_stmt_vec_info_vec (void);
579
580 /* Return a stmt_vec_info corresponding to STMT.  */
581
582 static inline stmt_vec_info
583 vinfo_for_stmt (gimple stmt)
584 {
585   unsigned int uid = gimple_uid (stmt);
586   if (uid == 0)
587     return NULL;
588
589   return (stmt_vec_info) VEC_index (vec_void_p, stmt_vec_info_vec, uid - 1);
590 }
591
592 /* Set vectorizer information INFO for STMT.  */
593
594 static inline void
595 set_vinfo_for_stmt (gimple stmt, stmt_vec_info info)
596 {
597   unsigned int uid = gimple_uid (stmt);
598   if (uid == 0)
599     {
600       gcc_checking_assert (info);
601       uid = VEC_length (vec_void_p, stmt_vec_info_vec) + 1;
602       gimple_set_uid (stmt, uid);
603       VEC_safe_push (vec_void_p, heap, stmt_vec_info_vec, (vec_void_p) info);
604     }
605   else
606     VEC_replace (vec_void_p, stmt_vec_info_vec, uid - 1, (vec_void_p) info);
607 }
608
609 /* Return the earlier statement between STMT1 and STMT2.  */
610
611 static inline gimple
612 get_earlier_stmt (gimple stmt1, gimple stmt2)
613 {
614   unsigned int uid1, uid2;
615
616   if (stmt1 == NULL)
617     return stmt2;
618
619   if (stmt2 == NULL)
620     return stmt1;
621
622   uid1 = gimple_uid (stmt1);
623   uid2 = gimple_uid (stmt2);
624
625   if (uid1 == 0 || uid2 == 0)
626     return NULL;
627
628   gcc_checking_assert (uid1 <= VEC_length (vec_void_p, stmt_vec_info_vec)
629                        && uid2 <= VEC_length (vec_void_p, stmt_vec_info_vec));
630
631   if (uid1 < uid2)
632     return stmt1;
633   else
634     return stmt2;
635 }
636
637 /* Return the later statement between STMT1 and STMT2.  */
638
639 static inline gimple
640 get_later_stmt (gimple stmt1, gimple stmt2)
641 {
642   unsigned int uid1, uid2;
643
644   if (stmt1 == NULL)
645     return stmt2;
646
647   if (stmt2 == NULL)
648     return stmt1;
649
650   uid1 = gimple_uid (stmt1);
651   uid2 = gimple_uid (stmt2);
652
653   if (uid1 == 0 || uid2 == 0)
654     return NULL;
655
656   gcc_assert (uid1 <= VEC_length (vec_void_p, stmt_vec_info_vec));
657   gcc_assert (uid2 <= VEC_length (vec_void_p, stmt_vec_info_vec));
658
659   if (uid1 > uid2)
660     return stmt1;
661   else
662     return stmt2;
663 }
664
665 /* Return TRUE if a statement represented by STMT_INFO is a part of a
666    pattern.  */
667
668 static inline bool
669 is_pattern_stmt_p (stmt_vec_info stmt_info)
670 {
671   gimple related_stmt;
672   stmt_vec_info related_stmt_info;
673
674   related_stmt = STMT_VINFO_RELATED_STMT (stmt_info);
675   if (related_stmt
676       && (related_stmt_info = vinfo_for_stmt (related_stmt))
677       && STMT_VINFO_IN_PATTERN_P (related_stmt_info))
678     return true;
679
680   return false;
681 }
682
683 /* Return true if BB is a loop header.  */
684
685 static inline bool
686 is_loop_header_bb_p (basic_block bb)
687 {
688   if (bb == (bb->loop_father)->header)
689     return true;
690   gcc_checking_assert (EDGE_COUNT (bb->preds) == 1);
691   return false;
692 }
693
694 /* Set inside loop vectorization cost.  */
695
696 static inline void
697 stmt_vinfo_set_inside_of_loop_cost (stmt_vec_info stmt_info, slp_tree slp_node,
698                                     int cost)
699 {
700   if (slp_node)
701     SLP_TREE_INSIDE_OF_LOOP_COST (slp_node) = cost;
702   else
703     STMT_VINFO_INSIDE_OF_LOOP_COST (stmt_info) = cost;
704 }
705
706 /* Set inside loop vectorization cost.  */
707
708 static inline void
709 stmt_vinfo_set_outside_of_loop_cost (stmt_vec_info stmt_info, slp_tree slp_node,
710                                      int cost)
711 {
712   if (slp_node)
713     SLP_TREE_OUTSIDE_OF_LOOP_COST (slp_node) = cost;
714   else
715     STMT_VINFO_OUTSIDE_OF_LOOP_COST (stmt_info) = cost;
716 }
717
718 /* Return pow2 (X).  */
719
720 static inline int
721 vect_pow2 (int x)
722 {
723   int i, res = 1;
724
725   for (i = 0; i < x; i++)
726     res *= 2;
727
728   return res;
729 }
730
731 /*-----------------------------------------------------------------*/
732 /* Info on data references alignment.                              */
733 /*-----------------------------------------------------------------*/
734
735 /* Reflects actual alignment of first access in the vectorized loop,
736    taking into account peeling/versioning if applied.  */
737 #define DR_MISALIGNMENT(DR)   ((int) (size_t) (DR)->aux)
738 #define SET_DR_MISALIGNMENT(DR, VAL)   ((DR)->aux = (void *) (size_t) (VAL))
739
740 /* Return TRUE if the data access is aligned, and FALSE otherwise.  */
741
742 static inline bool
743 aligned_access_p (struct data_reference *data_ref_info)
744 {
745   return (DR_MISALIGNMENT (data_ref_info) == 0);
746 }
747
748 /* Return TRUE if the alignment of the data access is known, and FALSE
749    otherwise.  */
750
751 static inline bool
752 known_alignment_for_access_p (struct data_reference *data_ref_info)
753 {
754   return (DR_MISALIGNMENT (data_ref_info) != -1);
755 }
756
757 /* vect_dump will be set to stderr or dump_file if exist.  */
758 extern FILE *vect_dump;
759 extern LOC vect_loop_location;
760
761 /*-----------------------------------------------------------------*/
762 /* Function prototypes.                                            */
763 /*-----------------------------------------------------------------*/
764
765 /* Simple loop peeling and versioning utilities for vectorizer's purposes -
766    in tree-vect-loop-manip.c.  */
767 extern void slpeel_make_loop_iterate_ntimes (struct loop *, tree);
768 extern bool slpeel_can_duplicate_loop_p (const struct loop *, const_edge);
769 extern void vect_loop_versioning (loop_vec_info, bool, tree *, gimple_seq *);
770 extern void vect_do_peeling_for_loop_bound (loop_vec_info, tree *,
771                                             tree, gimple_seq);
772 extern void vect_do_peeling_for_alignment (loop_vec_info);
773 extern LOC find_loop_location (struct loop *);
774 extern bool vect_can_advance_ivs_p (loop_vec_info);
775
776 /* In tree-vect-stmts.c.  */
777 extern unsigned int current_vector_size;
778 extern tree get_vectype_for_scalar_type (tree);
779 extern tree get_same_sized_vectype (tree, tree);
780 extern bool vect_is_simple_use (tree, loop_vec_info, bb_vec_info, gimple *,
781                                 tree *,  enum vect_def_type *);
782 extern bool vect_is_simple_use_1 (tree, loop_vec_info, bb_vec_info, gimple *,
783                                   tree *,  enum vect_def_type *, tree *);
784 extern bool supportable_widening_operation (enum tree_code, gimple, tree, tree,
785                                             tree *, tree *, enum tree_code *,
786                                             enum tree_code *, int *,
787                                             VEC (tree, heap) **);
788 extern bool supportable_narrowing_operation (enum tree_code, tree, tree,
789                                              enum tree_code *,
790                                              int *, VEC (tree, heap) **);
791 extern stmt_vec_info new_stmt_vec_info (gimple stmt, loop_vec_info,
792                                         bb_vec_info);
793 extern void free_stmt_vec_info (gimple stmt);
794 extern tree vectorizable_function (gimple, tree, tree);
795 extern void vect_model_simple_cost (stmt_vec_info, int, enum vect_def_type *,
796                                     slp_tree);
797 extern void vect_model_store_cost (stmt_vec_info, int, enum vect_def_type,
798                                    slp_tree);
799 extern void vect_model_load_cost (stmt_vec_info, int, slp_tree);
800 extern void vect_finish_stmt_generation (gimple, gimple,
801                                          gimple_stmt_iterator *);
802 extern bool vect_mark_stmts_to_be_vectorized (loop_vec_info);
803 extern int cost_for_stmt (gimple);
804 extern tree vect_get_vec_def_for_operand (tree, gimple, tree *);
805 extern tree vect_init_vector (gimple, tree, tree,
806                               gimple_stmt_iterator *);
807 extern tree vect_get_vec_def_for_stmt_copy (enum vect_def_type, tree);
808 extern bool vect_transform_stmt (gimple, gimple_stmt_iterator *,
809                                  bool *, slp_tree, slp_instance);
810 extern void vect_remove_stores (gimple);
811 extern bool vect_analyze_stmt (gimple, bool *, slp_tree);
812 extern bool vectorizable_condition (gimple, gimple_stmt_iterator *, gimple *,
813                                     tree, int);
814 extern void vect_get_load_cost (struct data_reference *, int, bool,
815                                 unsigned int *, unsigned int *);
816 extern void vect_get_store_cost (struct data_reference *, int, unsigned int *);
817
818 /* In tree-vect-data-refs.c.  */
819 extern bool vect_can_force_dr_alignment_p (const_tree, unsigned int);
820 extern enum dr_alignment_support vect_supportable_dr_alignment
821                                            (struct data_reference *, bool);
822 extern tree vect_get_smallest_scalar_type (gimple, HOST_WIDE_INT *,
823                                            HOST_WIDE_INT *);
824 extern bool vect_analyze_data_ref_dependences (loop_vec_info, bb_vec_info,
825                                                int *, bool *);
826 extern bool vect_enhance_data_refs_alignment (loop_vec_info);
827 extern bool vect_analyze_data_refs_alignment (loop_vec_info, bb_vec_info);
828 extern bool vect_verify_datarefs_alignment (loop_vec_info, bb_vec_info);
829 extern bool vect_analyze_data_ref_accesses (loop_vec_info, bb_vec_info);
830 extern bool vect_prune_runtime_alias_test_list (loop_vec_info);
831 extern bool vect_analyze_data_refs (loop_vec_info, bb_vec_info, int *);
832 extern tree vect_create_data_ref_ptr (gimple, struct loop *, tree, tree *,
833                                       gimple *, bool, bool *);
834 extern tree bump_vector_ptr (tree, gimple, gimple_stmt_iterator *, gimple, tree);
835 extern tree vect_create_destination_var (tree, tree);
836 extern bool vect_strided_store_supported (tree);
837 extern bool vect_strided_load_supported (tree);
838 extern bool vect_permute_store_chain (VEC(tree,heap) *,unsigned int, gimple,
839                                     gimple_stmt_iterator *, VEC(tree,heap) **);
840 extern tree vect_setup_realignment (gimple, gimple_stmt_iterator *, tree *,
841                                     enum dr_alignment_support, tree,
842                                     struct loop **);
843 extern bool vect_permute_load_chain (VEC(tree,heap) *,unsigned int, gimple,
844                                     gimple_stmt_iterator *, VEC(tree,heap) **);
845 extern bool vect_transform_strided_load (gimple, VEC(tree,heap) *, int,
846                                          gimple_stmt_iterator *);
847 extern int vect_get_place_in_interleaving_chain (gimple, gimple);
848 extern tree vect_get_new_vect_var (tree, enum vect_var_kind, const char *);
849 extern tree vect_create_addr_base_for_vector_ref (gimple, gimple_seq *,
850                                                   tree, struct loop *);
851
852 /* In tree-vect-loop.c.  */
853 /* FORNOW: Used in tree-parloops.c.  */
854 extern void destroy_loop_vec_info (loop_vec_info, bool);
855 extern gimple vect_force_simple_reduction (loop_vec_info, gimple, bool, bool *);
856 /* Drive for loop analysis stage.  */
857 extern loop_vec_info vect_analyze_loop (struct loop *);
858 /* Drive for loop transformation stage.  */
859 extern void vect_transform_loop (loop_vec_info);
860 extern loop_vec_info vect_analyze_loop_form (struct loop *);
861 extern bool vectorizable_live_operation (gimple, gimple_stmt_iterator *,
862                                          gimple *);
863 extern bool vectorizable_reduction (gimple, gimple_stmt_iterator *, gimple *,
864                                     slp_tree);
865 extern bool vectorizable_induction (gimple, gimple_stmt_iterator *, gimple *);
866 extern int vect_estimate_min_profitable_iters (loop_vec_info);
867 extern tree get_initial_def_for_reduction (gimple, tree, tree *);
868 extern int vect_min_worthwhile_factor (enum tree_code);
869 extern int vect_get_known_peeling_cost (loop_vec_info, int, int *, int);
870 extern int vect_get_single_scalar_iteration_cost (loop_vec_info);
871
872 /* In tree-vect-slp.c.  */
873 extern void vect_free_slp_instance (slp_instance);
874 extern bool vect_transform_slp_perm_load (gimple, VEC (tree, heap) *,
875                                           gimple_stmt_iterator *, int,
876                                           slp_instance, bool);
877 extern bool vect_schedule_slp (loop_vec_info, bb_vec_info);
878 extern void vect_update_slp_costs_according_to_vf (loop_vec_info);
879 extern bool vect_analyze_slp (loop_vec_info, bb_vec_info);
880 extern void vect_make_slp_decision (loop_vec_info);
881 extern void vect_detect_hybrid_slp (loop_vec_info);
882 extern void vect_get_slp_defs (tree, tree, slp_tree, VEC (tree,heap) **,
883                                VEC (tree,heap) **, int);
884 extern LOC find_bb_location (basic_block);
885 extern bb_vec_info vect_slp_analyze_bb (basic_block);
886 extern void vect_slp_transform_bb (basic_block);
887
888 /* In tree-vect-patterns.c.  */
889 /* Pattern recognition functions.
890    Additional pattern recognition functions can (and will) be added
891    in the future.  */
892 typedef gimple (* vect_recog_func_ptr) (gimple, tree *, tree *);
893 #define NUM_PATTERNS 4
894 void vect_pattern_recog (loop_vec_info);
895
896 /* In tree-vectorizer.c.  */
897 unsigned vectorize_loops (void);
898 /* Vectorization debug information */
899 extern bool vect_print_dump_info (enum vect_verbosity_levels);
900
901 #endif  /* GCC_TREE_VECTORIZER_H  */