GCC Middle and Back End API Reference
tree-vectorizer.h
Go to the documentation of this file.
1 /* Vectorizer
2  Copyright (C) 2003-2013 Free Software Foundation, Inc.
3  Contributed by Dorit Naishlos <dorit@il.ibm.com>
4 
5 This file is part of GCC.
6 
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
11 
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
20 
21 #ifndef GCC_TREE_VECTORIZER_H
22 #define GCC_TREE_VECTORIZER_H
23 
24 #include "tree-data-ref.h"
25 #include "target.h"
26 #include "hash-table.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. */
39 };
40 
41 /* Defines type of operation. */
43  unary_op = 1,
46 };
47 
48 /* Define type of available alignment support. */
55 };
56 
57 /* Define type of def-use cross-iteration cycle. */
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;
80  int misalign;
82 
83 
85 
86 static inline void
88  enum vect_cost_for_stmt kind, gimple stmt, int misalign)
89 {
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 struct _slp_tree *slp_tree;
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 struct _slp_tree {
106  /* Nodes that contain def-stmts of this node statements operands. */
108  /* A group of scalar stmts to be vectorized together. */
110  /* Load permutation relative to the stores, NULL if there is no
111  permutation. */
113  /* Vectorized stmt/s. */
115  /* Number of vector stmts that are created to replace the group of scalar
116  stmts. It is calculated during the transformation phase as the number of
117  scalar elements in one scalar iteration (GROUP_SIZE) multiplied by VF
118  divided by vector size. */
119  unsigned int vec_stmts_size;
120 };
121 
122 
123 /* SLP instance is a sequence of stmts in a loop that can be packed into
124  SIMD stmts. */
125 typedef struct _slp_instance {
126  /* The root of SLP tree. */
127  slp_tree root;
128 
129  /* Size of groups of scalar stmts that will be replaced by SIMD stmt/s. */
130  unsigned int group_size;
131 
132  /* The unrolling factor required to vectorized this SLP instance. */
133  unsigned int unrolling_factor;
134 
135  /* Vectorization costs associated with SLP instance. */
137 
138  /* The group of nodes that contain loads of this SLP instance. */
140 
141  /* The first scalar load of the instance. The created vector loads will be
142  inserted before this statement. */
144 } *slp_instance;
145 
146 
147 /* Access Functions. */
148 #define SLP_INSTANCE_TREE(S) (S)->root
149 #define SLP_INSTANCE_GROUP_SIZE(S) (S)->group_size
150 #define SLP_INSTANCE_UNROLLING_FACTOR(S) (S)->unrolling_factor
151 #define SLP_INSTANCE_BODY_COST_VEC(S) (S)->body_cost_vec
152 #define SLP_INSTANCE_LOADS(S) (S)->loads
153 #define SLP_INSTANCE_FIRST_LOAD_STMT(S) (S)->first_load
154 
155 #define SLP_TREE_CHILDREN(S) (S)->children
156 #define SLP_TREE_SCALAR_STMTS(S) (S)->stmts
157 #define SLP_TREE_VEC_STMTS(S) (S)->vec_stmts
158 #define SLP_TREE_NUMBER_OF_VEC_STMTS(S) (S)->vec_stmts_size
159 #define SLP_TREE_LOAD_PERMUTATION(S) (S)->load_permutation
160 
161 /* This structure is used in creation of an SLP tree. Each instance
162  corresponds to the same operand in a group of scalar stmts in an SLP
163  node. */
164 typedef struct _slp_oprnd_info
165 {
166  /* Def-stmts for the operands. */
168  /* Information about the first statement, its vector def-type, type, the
169  operand itself in case it's constant, and an indication if it's a pattern
170  stmt. */
174 } *slp_oprnd_info;
175 
176 
177 
178 typedef struct _vect_peel_info
179 {
180  int npeel;
182  unsigned int count;
183 } *vect_peel_info;
184 
186 {
188  unsigned int inside_cost;
189  unsigned int outside_cost;
192 
193 
194 /* Peeling hashtable helpers. */
195 
196 struct peel_info_hasher : typed_free_remove <_vect_peel_info>
197 {
200  static inline hashval_t hash (const value_type *);
201  static inline bool equal (const value_type *, const compare_type *);
202 };
203 
204 inline hashval_t
206 {
207  return (hashval_t) peel_info->npeel;
208 }
209 
210 inline bool
212 {
213  return (a->npeel == b->npeel);
214 }
215 
216 
217 /*-----------------------------------------------------------------*/
218 /* Info on vectorized loops. */
219 /*-----------------------------------------------------------------*/
220 typedef struct _loop_vec_info {
221 
222  /* The loop to which this info struct refers to. */
223  struct loop *loop;
224 
225  /* The loop basic blocks. */
227 
228  /* Number of iterations. */
231 
232  /* Minimum number of iterations below which vectorization is expected to
233  not be profitable (as estimated by the cost model).
234  -1 indicates that vectorization will not be profitable.
235  FORNOW: This field is an int. Will be a tree in the future, to represent
236  values unknown at compile time. */
238 
239  /* Is the loop vectorizable? */
241 
242  /* Unrolling factor */
244 
245  /* The loop location in the source. */
247 
248  /* Unknown DRs according to which loop was peeled. */
250 
251  /* peeling_for_alignment indicates whether peeling for alignment will take
252  place, and what the peeling factor should be:
253  peeling_for_alignment = X means:
254  If X=0: Peeling for alignment will not be applied.
255  If X>0: Peel first X iterations.
256  If X=-1: Generate a runtime test to calculate the number of iterations
257  to be peeled, using the dataref recorded in the field
258  unaligned_dr. */
260 
261  /* The mask used to check the alignment of pointers or arrays. */
262  int ptr_mask;
263 
264  /* The loop nest in which the data dependences are computed. */
266 
267  /* All data references in the loop. */
269 
270  /* All data dependences in the loop. */
272 
273  /* Data Dependence Relations defining address ranges that are candidates
274  for a run-time aliasing check. */
276 
277  /* Statements in the loop that have data references that are candidates for a
278  runtime (loop versioning) misalignment check. */
280 
281  /* All interleaving chains of stores in the loop, represented by the first
282  stmt in the chain. */
284 
285  /* All SLP instances in the loop. This is a subset of the set of GROUP_STORES
286  of the loop. */
288 
289  /* The unrolling factor needed to SLP the loop. In case of that pure SLP is
290  applied to the loop, i.e., no unrolling is needed, this is 1. */
292 
293  /* Reduction cycles detected in the loop. Used in loop-aware SLP. */
295 
296  /* All reduction chains in the loop, represented by the first
297  stmt in the chain. */
299 
300  /* Hash table used to choose the best peeling option. */
302 
303  /* Cost data used by the target cost model. */
305 
306  /* When we have grouped data accesses with gaps, we may introduce invalid
307  memory accesses. We peel the last iteration of the loop to prevent
308  this. */
310 
311  /* Reductions are canonicalized so that the last operand is the reduction
312  operand. If this places a constant into RHS1, this decanonicalizes
313  GIMPLE for other phases, so we must track when this has occurred and
314  fix it up. */
316 
317 } *loop_vec_info;
318 
319 /* Access Functions. */
320 #define LOOP_VINFO_LOOP(L) (L)->loop
321 #define LOOP_VINFO_BBS(L) (L)->bbs
322 #define LOOP_VINFO_NITERS(L) (L)->num_iters
323 /* Since LOOP_VINFO_NITERS can change after prologue peeling
324  retain total unchanged scalar loop iterations for cost model. */
325 #define LOOP_VINFO_NITERS_UNCHANGED(L) (L)->num_iters_unchanged
326 #define LOOP_VINFO_COST_MODEL_MIN_ITERS(L) (L)->min_profitable_iters
327 #define LOOP_VINFO_VECTORIZABLE_P(L) (L)->vectorizable
328 #define LOOP_VINFO_VECT_FACTOR(L) (L)->vectorization_factor
329 #define LOOP_VINFO_PTR_MASK(L) (L)->ptr_mask
330 #define LOOP_VINFO_LOOP_NEST(L) (L)->loop_nest
331 #define LOOP_VINFO_DATAREFS(L) (L)->datarefs
332 #define LOOP_VINFO_DDRS(L) (L)->ddrs
333 #define LOOP_VINFO_INT_NITERS(L) (TREE_INT_CST_LOW ((L)->num_iters))
334 #define LOOP_PEELING_FOR_ALIGNMENT(L) (L)->peeling_for_alignment
335 #define LOOP_VINFO_UNALIGNED_DR(L) (L)->unaligned_dr
336 #define LOOP_VINFO_MAY_MISALIGN_STMTS(L) (L)->may_misalign_stmts
337 #define LOOP_VINFO_LOC(L) (L)->loop_line_number
338 #define LOOP_VINFO_MAY_ALIAS_DDRS(L) (L)->may_alias_ddrs
339 #define LOOP_VINFO_GROUPED_STORES(L) (L)->grouped_stores
340 #define LOOP_VINFO_SLP_INSTANCES(L) (L)->slp_instances
341 #define LOOP_VINFO_SLP_UNROLLING_FACTOR(L) (L)->slp_unrolling_factor
342 #define LOOP_VINFO_REDUCTIONS(L) (L)->reductions
343 #define LOOP_VINFO_REDUCTION_CHAINS(L) (L)->reduction_chains
344 #define LOOP_VINFO_PEELING_HTAB(L) (L)->peeling_htab
345 #define LOOP_VINFO_TARGET_COST_DATA(L) (L)->target_cost_data
346 #define LOOP_VINFO_PEELING_FOR_GAPS(L) (L)->peeling_for_gaps
347 #define LOOP_VINFO_OPERANDS_SWAPPED(L) (L)->operands_swapped
348 
349 #define LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT(L) \
350 (L)->may_misalign_stmts.length () > 0
351 #define LOOP_REQUIRES_VERSIONING_FOR_ALIAS(L) \
352 (L)->may_alias_ddrs.length () > 0
353 
354 #define NITERS_KNOWN_P(n) \
355 (host_integerp ((n),0) \
356 && TREE_INT_CST_LOW ((n)) > 0)
357 
358 #define LOOP_VINFO_NITERS_KNOWN_P(L) \
359 NITERS_KNOWN_P((L)->num_iters)
360 
361 static inline loop_vec_info
363 {
364  return (loop_vec_info) loop->aux;
365 }
366 
367 static inline bool
369 {
370  return (loop->inner
371  && (loop->inner == (gimple_bb (stmt))->loop_father));
372 }
373 
374 typedef struct _bb_vec_info {
375 
377  /* All interleaving chains of stores in the basic block, represented by the
378  first stmt in the chain. */
380 
381  /* All SLP instances in the basic block. This is a subset of the set of
382  GROUP_STORES of the basic block. */
384 
385  /* All data references in the basic block. */
387 
388  /* All data dependences in the basic block. */
390 
391  /* Cost data used by the target cost model. */
393 
394 } *bb_vec_info;
395 
396 #define BB_VINFO_BB(B) (B)->bb
397 #define BB_VINFO_GROUPED_STORES(B) (B)->grouped_stores
398 #define BB_VINFO_SLP_INSTANCES(B) (B)->slp_instances
399 #define BB_VINFO_DATAREFS(B) (B)->datarefs
400 #define BB_VINFO_DDRS(B) (B)->ddrs
401 #define BB_VINFO_TARGET_COST_DATA(B) (B)->target_cost_data
402 
403 static inline bb_vec_info
405 {
406  return (bb_vec_info) bb->aux;
407 }
408 
409 /*-----------------------------------------------------------------*/
410 /* Info on vectorized defs. */
411 /*-----------------------------------------------------------------*/
427 };
428 
429 /* Indicates whether/how a variable is used in the scope of loop/basic
430  block. */
433  /* The def is in the inner loop, and the use is in the outer loop, and the
434  use is a reduction stmt. */
436  /* The def is in the inner loop, and the use is in the outer loop (and is
437  not part of reduction). */
439 
440  /* defs that feed computations that end up (only) in a reduction. These
441  defs may be used by non-reduction stmts, but eventually, any
442  computations/values that are affected by these defs are used to compute
443  a reduction (i.e. don't get stored to memory, for example). We use this
444  to identify computations that we can change the order in which they are
445  computed. */
447 
449 };
450 
451 /* The type of vectorization that can be applied to the stmt: regular loop-based
452  vectorization; pure SLP - the stmt is a part of SLP instances and does not
453  have uses outside SLP instances; or hybrid SLP and loop-based - the stmt is
454  a part of SLP instance and also must be loop-based vectorized, since it has
455  uses outside SLP sequences.
456 
457  In the loop context the meanings of pure and hybrid SLP are slightly
458  different. By saying that pure SLP is applied to the loop, we mean that we
459  exploit only intra-iteration parallelism in the loop; i.e., the loop can be
460  vectorized without doing any conceptual unrolling, cause we don't pack
461  together stmts from different iterations, only within a single iteration.
462  Loop hybrid SLP means that we exploit both intra-iteration and
463  inter-iteration parallelism (e.g., number of elements in the vector is 4
464  and the slp-group-size is 2, in which case we don't have enough parallelism
465  within an iteration, so we obtain the rest of the parallelism from subsequent
466  iterations by unrolling the loop by 2). */
471 };
472 
473 
474 typedef struct data_reference *dr_p;
475 
476 typedef struct _stmt_vec_info {
477 
479 
480  /* Indicates whether this stmts is part of a computation whose result is
481  used outside the loop. */
482  bool live;
483 
484  /* Stmt is part of some pattern (computation idiom) */
486 
487  /* The stmt to which this info struct refers to. */
489 
490  /* The loop_vec_info with respect to which STMT is vectorized. */
492 
493  /* The vector type to be used for the LHS of this statement. */
495 
496  /* The vectorized version of the stmt. */
498 
499 
504  /* Information about the data-ref (access function, etc),
505  relative to the inner-most containing loop. */
507 
508  /* Information about the data-ref relative to this loop
509  nest (the loop that is being considered for vectorization). */
515 
516  /* For loop PHI nodes, the evolution part of it. This makes sure
517  this information is still available in vect_update_ivs_after_vectorizer
518  where we may not be able to re-analyze the PHI nodes evolution as
519  peeling for the prologue loop can make it unanalyzable. The evolution
520  part is still correct though. */
522 
523  /* Used for various bookkeeping purposes, generally holding a pointer to
524  some other stmt S that is in some way "related" to this stmt.
525  Current use of this field is:
526  If this stmt is part of a pattern (i.e. the field 'in_pattern_p' is
527  true): S is the "pattern stmt" that represents (and replaces) the
528  sequence of stmts that constitutes the pattern. Similarly, the
529  related_stmt of the "pattern stmt" points back to this stmt (which is
530  the last stmt in the original sequence of stmts that constitutes the
531  pattern). */
533 
534  /* Used to keep a sequence of def stmts of a pattern stmt if such exists. */
536 
537  /* List of datarefs that are known to have the same alignment as the dataref
538  of this stmt. */
540 
541  /* Classify the def of this stmt. */
543 
544  /* Whether the stmt is SLPed, loop-based vectorized, or both. */
546 
547  /* Interleaving and reduction chains info. */
548  /* First element in the group. */
550  /* Pointer to the next element in the group. */
552  /* For data-refs, in case that two or more stmts share data-ref, this is the
553  pointer to the previously detected stmt with the same dr. */
555  /* The size of the group. */
556  unsigned int size;
557  /* For stores, number of stores from this group seen. We vectorize the last
558  one. */
559  unsigned int store_count;
560  /* For loads only, the gap from the previous load. For consecutive loads, GAP
561  is 1. */
562  unsigned int gap;
563 
564  /* Not all stmts in the loop need to be vectorized. e.g, the increment
565  of the loop induction variable and computation of array indexes. relevant
566  indicates whether the stmt needs to be vectorized. */
568 
569  /* The bb_vec_info with respect to which STMT is vectorized. */
571 
572  /* Is this statement vectorizable or should it be skipped in (partial)
573  vectorization. */
575 
576  /* For loads only, true if this is a gather load. */
577  bool gather_p;
579 
580  /* For both loads and stores. */
582 } *stmt_vec_info;
583 
584 /* Access Functions. */
585 #define STMT_VINFO_TYPE(S) (S)->type
586 #define STMT_VINFO_STMT(S) (S)->stmt
587 #define STMT_VINFO_LOOP_VINFO(S) (S)->loop_vinfo
588 #define STMT_VINFO_BB_VINFO(S) (S)->bb_vinfo
589 #define STMT_VINFO_RELEVANT(S) (S)->relevant
590 #define STMT_VINFO_LIVE_P(S) (S)->live
591 #define STMT_VINFO_VECTYPE(S) (S)->vectype
592 #define STMT_VINFO_VEC_STMT(S) (S)->vectorized_stmt
593 #define STMT_VINFO_VECTORIZABLE(S) (S)->vectorizable
594 #define STMT_VINFO_DATA_REF(S) (S)->data_ref_info
595 #define STMT_VINFO_GATHER_P(S) (S)->gather_p
596 #define STMT_VINFO_STRIDE_LOAD_P(S) (S)->stride_load_p
597 #define STMT_VINFO_SIMD_LANE_ACCESS_P(S) (S)->simd_lane_access_p
598 
599 #define STMT_VINFO_DR_BASE_ADDRESS(S) (S)->dr_base_address
600 #define STMT_VINFO_DR_INIT(S) (S)->dr_init
601 #define STMT_VINFO_DR_OFFSET(S) (S)->dr_offset
602 #define STMT_VINFO_DR_STEP(S) (S)->dr_step
603 #define STMT_VINFO_DR_ALIGNED_TO(S) (S)->dr_aligned_to
604 
605 #define STMT_VINFO_IN_PATTERN_P(S) (S)->in_pattern_p
606 #define STMT_VINFO_RELATED_STMT(S) (S)->related_stmt
607 #define STMT_VINFO_PATTERN_DEF_SEQ(S) (S)->pattern_def_seq
608 #define STMT_VINFO_SAME_ALIGN_REFS(S) (S)->same_align_refs
609 #define STMT_VINFO_DEF_TYPE(S) (S)->def_type
610 #define STMT_VINFO_GROUP_FIRST_ELEMENT(S) (S)->first_element
611 #define STMT_VINFO_GROUP_NEXT_ELEMENT(S) (S)->next_element
612 #define STMT_VINFO_GROUP_SIZE(S) (S)->size
613 #define STMT_VINFO_GROUP_STORE_COUNT(S) (S)->store_count
614 #define STMT_VINFO_GROUP_GAP(S) (S)->gap
615 #define STMT_VINFO_GROUP_SAME_DR_STMT(S) (S)->same_dr_stmt
616 #define STMT_VINFO_GROUPED_ACCESS(S) ((S)->first_element != NULL && (S)->data_ref_info)
617 #define STMT_VINFO_LOOP_PHI_EVOLUTION_PART(S) (S)->loop_phi_evolution_part
618 
619 #define GROUP_FIRST_ELEMENT(S) (S)->first_element
620 #define GROUP_NEXT_ELEMENT(S) (S)->next_element
621 #define GROUP_SIZE(S) (S)->size
622 #define GROUP_STORE_COUNT(S) (S)->store_count
623 #define GROUP_GAP(S) (S)->gap
624 #define GROUP_SAME_DR_STMT(S) (S)->same_dr_stmt
625 
626 #define STMT_VINFO_RELEVANT_P(S) ((S)->relevant != vect_unused_in_scope)
627 
628 #define HYBRID_SLP_STMT(S) ((S)->slp_type == hybrid)
629 #define PURE_SLP_STMT(S) ((S)->slp_type == pure_slp)
630 #define STMT_SLP_TYPE(S) (S)->slp_type
631 
632 #define VECT_MAX_COST 1000
633 
634 /* The maximum number of intermediate steps required in multi-step type
635  conversion. */
636 #define MAX_INTERM_CVT_STEPS 3
637 
638 /* The maximum vectorization factor supported by any target (V32QI). */
639 #define MAX_VECTORIZATION_FACTOR 32
640 
641 /* Avoid GTY(()) on stmt_vec_info. */
642 typedef void *vec_void_p;
643 
645 
646 void init_stmt_vec_info_vec (void);
647 void free_stmt_vec_info_vec (void);
648 
649 /* Return a stmt_vec_info corresponding to STMT. */
650 
651 static inline stmt_vec_info
653 {
654  unsigned int uid = gimple_uid (stmt);
655  if (uid == 0)
656  return NULL;
657 
658  return (stmt_vec_info) stmt_vec_info_vec[uid - 1];
659 }
660 
661 /* Set vectorizer information INFO for STMT. */
662 
663 static inline void
665 {
666  unsigned int uid = gimple_uid (stmt);
667  if (uid == 0)
668  {
669  gcc_checking_assert (info);
670  uid = stmt_vec_info_vec.length () + 1;
671  gimple_set_uid (stmt, uid);
672  stmt_vec_info_vec.safe_push ((vec_void_p) info);
673  }
674  else
675  stmt_vec_info_vec[uid - 1] = (vec_void_p) info;
676 }
677 
678 /* Return the earlier statement between STMT1 and STMT2. */
679 
680 static inline gimple
682 {
683  unsigned int uid1, uid2;
684 
685  if (stmt1 == NULL)
686  return stmt2;
687 
688  if (stmt2 == NULL)
689  return stmt1;
690 
691  uid1 = gimple_uid (stmt1);
692  uid2 = gimple_uid (stmt2);
693 
694  if (uid1 == 0 || uid2 == 0)
695  return NULL;
696 
697  gcc_checking_assert (uid1 <= stmt_vec_info_vec.length ()
698  && uid2 <= stmt_vec_info_vec.length ());
699 
700  if (uid1 < uid2)
701  return stmt1;
702  else
703  return stmt2;
704 }
705 
706 /* Return the later statement between STMT1 and STMT2. */
707 
708 static inline gimple
710 {
711  unsigned int uid1, uid2;
712 
713  if (stmt1 == NULL)
714  return stmt2;
715 
716  if (stmt2 == NULL)
717  return stmt1;
718 
719  uid1 = gimple_uid (stmt1);
720  uid2 = gimple_uid (stmt2);
721 
722  if (uid1 == 0 || uid2 == 0)
723  return NULL;
724 
725  gcc_assert (uid1 <= stmt_vec_info_vec.length ());
726  gcc_assert (uid2 <= stmt_vec_info_vec.length ());
727 
728  if (uid1 > uid2)
729  return stmt1;
730  else
731  return stmt2;
732 }
733 
734 /* Return TRUE if a statement represented by STMT_INFO is a part of a
735  pattern. */
736 
737 static inline bool
739 {
740  gimple related_stmt;
741  stmt_vec_info related_stmt_info;
742 
743  related_stmt = STMT_VINFO_RELATED_STMT (stmt_info);
744  if (related_stmt
745  && (related_stmt_info = vinfo_for_stmt (related_stmt))
746  && STMT_VINFO_IN_PATTERN_P (related_stmt_info))
747  return true;
748 
749  return false;
750 }
751 
752 /* Return true if BB is a loop header. */
753 
754 static inline bool
756 {
757  if (bb == (bb->loop_father)->header)
758  return true;
759  gcc_checking_assert (EDGE_COUNT (bb->preds) == 1);
760  return false;
761 }
762 
763 /* Return pow2 (X). */
764 
765 static inline int
766 vect_pow2 (int x)
767 {
768  int i, res = 1;
769 
770  for (i = 0; i < x; i++)
771  res *= 2;
772 
773  return res;
774 }
775 
776 /* Alias targetm.vectorize.builtin_vectorization_cost. */
777 
778 static inline int
780  tree vectype, int misalign)
781 {
782  return targetm.vectorize.builtin_vectorization_cost (type_of_cost,
783  vectype, misalign);
784 }
785 
786 /* Get cost by calling cost target builtin. */
787 
788 static inline
789 int vect_get_stmt_cost (enum vect_cost_for_stmt type_of_cost)
790 {
791  return builtin_vectorization_cost (type_of_cost, NULL, 0);
792 }
793 
794 /* Alias targetm.vectorize.init_cost. */
795 
796 static inline void *
797 init_cost (struct loop *loop_info)
798 {
799  return targetm.vectorize.init_cost (loop_info);
800 }
801 
802 /* Alias targetm.vectorize.add_stmt_cost. */
803 
804 static inline unsigned
806  stmt_vec_info stmt_info, int misalign,
807  enum vect_cost_model_location where)
808 {
809  return targetm.vectorize.add_stmt_cost (data, count, kind,
810  stmt_info, misalign, where);
811 }
812 
813 /* Alias targetm.vectorize.finish_cost. */
814 
815 static inline void
816 finish_cost (void *data, unsigned *prologue_cost,
817  unsigned *body_cost, unsigned *epilogue_cost)
818 {
819  targetm.vectorize.finish_cost (data, prologue_cost, body_cost, epilogue_cost);
820 }
821 
822 /* Alias targetm.vectorize.destroy_cost_data. */
823 
824 static inline void
826 {
827  targetm.vectorize.destroy_cost_data (data);
828 }
829 
830 
831 /*-----------------------------------------------------------------*/
832 /* Info on data references alignment. */
833 /*-----------------------------------------------------------------*/
834 
835 /* Reflects actual alignment of first access in the vectorized loop,
836  taking into account peeling/versioning if applied. */
837 #define DR_MISALIGNMENT(DR) ((int) (size_t) (DR)->aux)
838 #define SET_DR_MISALIGNMENT(DR, VAL) ((DR)->aux = (void *) (size_t) (VAL))
839 
840 /* Return TRUE if the data access is aligned, and FALSE otherwise. */
841 
842 static inline bool
843 aligned_access_p (struct data_reference *data_ref_info)
844 {
845  return (DR_MISALIGNMENT (data_ref_info) == 0);
846 }
847 
848 /* Return TRUE if the alignment of the data access is known, and FALSE
849  otherwise. */
850 
851 static inline bool
853 {
854  return (DR_MISALIGNMENT (data_ref_info) != -1);
855 }
856 
857 /* Source location */
858 extern LOC vect_location;
859 
860 /*-----------------------------------------------------------------*/
861 /* Function prototypes. */
862 /*-----------------------------------------------------------------*/
863 
864 /* Simple loop peeling and versioning utilities for vectorizer's purposes -
865  in tree-vect-loop-manip.c. */
866 extern void slpeel_make_loop_iterate_ntimes (struct loop *, tree);
867 extern bool slpeel_can_duplicate_loop_p (const struct loop *, const_edge);
868 extern void vect_loop_versioning (loop_vec_info, unsigned int, bool);
870  unsigned int, bool);
871 extern void vect_do_peeling_for_alignment (loop_vec_info, unsigned int, bool);
872 extern LOC find_loop_location (struct loop *);
874 
875 /* In tree-vect-stmts.c. */
876 extern unsigned int current_vector_size;
880  bb_vec_info, gimple *,
881  tree *, enum vect_def_type *);
883  bb_vec_info, gimple *,
884  tree *, enum vect_def_type *, tree *);
886  enum tree_code *, enum tree_code *,
887  int *, vec<tree> *);
889  enum tree_code *,
890  int *, vec<tree> *);
892  bb_vec_info);
893 extern void free_stmt_vec_info (gimple stmt);
895 extern void vect_model_simple_cost (stmt_vec_info, int, enum vect_def_type *,
898 extern void vect_model_store_cost (stmt_vec_info, int, bool,
899  enum vect_def_type, slp_tree,
902 extern void vect_model_load_cost (stmt_vec_info, int, bool, slp_tree,
905 extern unsigned record_stmt_cost (stmt_vector_for_cost *, int,
907  int, enum vect_cost_model_location);
916  bool *, slp_tree, slp_instance);
917 extern void vect_remove_stores (gimple);
918 extern bool vect_analyze_stmt (gimple, bool *, slp_tree);
920  tree, int, slp_tree);
921 extern void vect_get_load_cost (struct data_reference *, int, bool,
922  unsigned int *, unsigned int *,
924  stmt_vector_for_cost *, bool);
925 extern void vect_get_store_cost (struct data_reference *, int,
926  unsigned int *, stmt_vector_for_cost *);
927 extern bool vect_supportable_shift (enum tree_code, tree);
928 extern void vect_get_vec_defs (tree, tree, gimple, vec<tree> *,
929  vec<tree> *, slp_tree, int);
930 extern tree vect_gen_perm_mask (tree, unsigned char *);
931 
932 /* In tree-vect-data-refs.c. */
933 extern bool vect_can_force_dr_alignment_p (const_tree, unsigned int);
935  (struct data_reference *, bool);
937  HOST_WIDE_INT *);
946  int *);
947 extern bool vect_analyze_data_refs (loop_vec_info, bb_vec_info, int *);
948 extern tree vect_create_data_ref_ptr (gimple, tree, struct loop *, tree,
950  gimple *, bool, bool *);
953 extern bool vect_grouped_store_supported (tree, unsigned HOST_WIDE_INT);
954 extern bool vect_store_lanes_supported (tree, unsigned HOST_WIDE_INT);
955 extern bool vect_grouped_load_supported (tree, unsigned HOST_WIDE_INT);
956 extern bool vect_load_lanes_supported (tree, unsigned HOST_WIDE_INT);
957 extern void vect_permute_store_chain (vec<tree> ,unsigned int, gimple,
961  struct loop **);
962 extern void vect_transform_grouped_load (gimple, vec<tree> , int,
965 extern tree vect_get_new_vect_var (tree, enum vect_var_kind, const char *);
967  tree, struct loop *);
968 
969 /* In tree-vect-loop.c. */
970 /* FORNOW: Used in tree-parloops.c. */
971 extern void destroy_loop_vec_info (loop_vec_info, bool);
973 /* Drive for loop analysis stage. */
974 extern loop_vec_info vect_analyze_loop (struct loop *);
975 /* Drive for loop transformation stage. */
976 extern void vect_transform_loop (loop_vec_info);
977 extern loop_vec_info vect_analyze_loop_form (struct loop *);
979  gimple *);
981  slp_tree);
984 extern int vect_min_worthwhile_factor (enum tree_code);
985 extern int vect_get_known_peeling_cost (loop_vec_info, int, int *, int,
989 
990 /* In tree-vect-slp.c. */
992 extern bool vect_transform_slp_perm_load (slp_tree, vec<tree> ,
993  gimple_stmt_iterator *, int,
994  slp_instance, bool);
1000 extern void vect_get_slp_defs (vec<tree> , slp_tree,
1001  vec<vec<tree> > *, int);
1002 
1005 extern void vect_slp_transform_bb (basic_block);
1006 
1007 /* In tree-vect-patterns.c. */
1008 /* Pattern recognition functions.
1009  Additional pattern recognition functions can (and will) be added
1010  in the future. */
1012 #define NUM_PATTERNS 11
1014 
1015 /* In tree-vectorizer.c. */
1016 unsigned vectorize_loops (void);
1017 
1018 #endif /* GCC_TREE_VECTORIZER_H */