Mercurial > hg > CbC > CbC_gcc
comparison gcc/tree-vectorizer.h @ 145:1830386684a0
gcc-9.2.0
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 11:34:05 +0900 |
parents | 84e7813d76e9 |
children |
comparison
equal
deleted
inserted
replaced
131:84e7813d76e9 | 145:1830386684a0 |
---|---|
1 /* Vectorizer | 1 /* Vectorizer |
2 Copyright (C) 2003-2018 Free Software Foundation, Inc. | 2 Copyright (C) 2003-2020 Free Software Foundation, Inc. |
3 Contributed by Dorit Naishlos <dorit@il.ibm.com> | 3 Contributed by Dorit Naishlos <dorit@il.ibm.com> |
4 | 4 |
5 This file is part of GCC. | 5 This file is part of GCC. |
6 | 6 |
7 GCC is free software; you can redistribute it and/or modify it under | 7 GCC is free software; you can redistribute it and/or modify it under |
19 <http://www.gnu.org/licenses/>. */ | 19 <http://www.gnu.org/licenses/>. */ |
20 | 20 |
21 #ifndef GCC_TREE_VECTORIZER_H | 21 #ifndef GCC_TREE_VECTORIZER_H |
22 #define GCC_TREE_VECTORIZER_H | 22 #define GCC_TREE_VECTORIZER_H |
23 | 23 |
24 typedef struct _stmt_vec_info *stmt_vec_info; | 24 typedef class _stmt_vec_info *stmt_vec_info; |
25 | 25 |
26 #include "tree-data-ref.h" | 26 #include "tree-data-ref.h" |
27 #include "tree-hash-traits.h" | 27 #include "tree-hash-traits.h" |
28 #include "target.h" | 28 #include "target.h" |
29 #include <utility> | |
29 | 30 |
30 /* Used for naming of new temporaries. */ | 31 /* Used for naming of new temporaries. */ |
31 enum vect_var_kind { | 32 enum vect_var_kind { |
32 vect_simple_var, | 33 vect_simple_var, |
33 vect_pointer_var, | 34 vect_pointer_var, |
118 struct _slp_tree { | 119 struct _slp_tree { |
119 /* Nodes that contain def-stmts of this node statements operands. */ | 120 /* Nodes that contain def-stmts of this node statements operands. */ |
120 vec<slp_tree> children; | 121 vec<slp_tree> children; |
121 /* A group of scalar stmts to be vectorized together. */ | 122 /* A group of scalar stmts to be vectorized together. */ |
122 vec<stmt_vec_info> stmts; | 123 vec<stmt_vec_info> stmts; |
124 /* A group of scalar operands to be vectorized together. */ | |
125 vec<tree> ops; | |
123 /* Load permutation relative to the stores, NULL if there is no | 126 /* Load permutation relative to the stores, NULL if there is no |
124 permutation. */ | 127 permutation. */ |
125 vec<unsigned> load_permutation; | 128 vec<unsigned> load_permutation; |
126 /* Vectorized stmt/s. */ | 129 /* Vectorized stmt/s. */ |
127 vec<stmt_vec_info> vec_stmts; | 130 vec<stmt_vec_info> vec_stmts; |
128 /* Number of vector stmts that are created to replace the group of scalar | 131 /* Number of vector stmts that are created to replace the group of scalar |
129 stmts. It is calculated during the transformation phase as the number of | 132 stmts. It is calculated during the transformation phase as the number of |
130 scalar elements in one scalar iteration (GROUP_SIZE) multiplied by VF | 133 scalar elements in one scalar iteration (GROUP_SIZE) multiplied by VF |
131 divided by vector size. */ | 134 divided by vector size. */ |
132 unsigned int vec_stmts_size; | 135 unsigned int vec_stmts_size; |
136 /* Reference count in the SLP graph. */ | |
137 unsigned int refcnt; | |
138 /* The maximum number of vector elements for the subtree rooted | |
139 at this node. */ | |
140 poly_uint64 max_nunits; | |
133 /* Whether the scalar computations use two different operators. */ | 141 /* Whether the scalar computations use two different operators. */ |
134 bool two_operators; | 142 bool two_operators; |
135 /* The DEF type of this node. */ | 143 /* The DEF type of this node. */ |
136 enum vect_def_type def_type; | 144 enum vect_def_type def_type; |
137 }; | 145 }; |
138 | 146 |
139 | 147 |
140 /* SLP instance is a sequence of stmts in a loop that can be packed into | 148 /* SLP instance is a sequence of stmts in a loop that can be packed into |
141 SIMD stmts. */ | 149 SIMD stmts. */ |
142 typedef struct _slp_instance { | 150 typedef class _slp_instance { |
151 public: | |
143 /* The root of SLP tree. */ | 152 /* The root of SLP tree. */ |
144 slp_tree root; | 153 slp_tree root; |
154 | |
155 /* For vector constructors, the constructor stmt that the SLP tree is built | |
156 from, NULL otherwise. */ | |
157 stmt_vec_info root_stmt; | |
145 | 158 |
146 /* Size of groups of scalar stmts that will be replaced by SIMD stmt/s. */ | 159 /* Size of groups of scalar stmts that will be replaced by SIMD stmt/s. */ |
147 unsigned int group_size; | 160 unsigned int group_size; |
148 | 161 |
149 /* The unrolling factor required to vectorized this SLP instance. */ | 162 /* The unrolling factor required to vectorized this SLP instance. */ |
160 /* Access Functions. */ | 173 /* Access Functions. */ |
161 #define SLP_INSTANCE_TREE(S) (S)->root | 174 #define SLP_INSTANCE_TREE(S) (S)->root |
162 #define SLP_INSTANCE_GROUP_SIZE(S) (S)->group_size | 175 #define SLP_INSTANCE_GROUP_SIZE(S) (S)->group_size |
163 #define SLP_INSTANCE_UNROLLING_FACTOR(S) (S)->unrolling_factor | 176 #define SLP_INSTANCE_UNROLLING_FACTOR(S) (S)->unrolling_factor |
164 #define SLP_INSTANCE_LOADS(S) (S)->loads | 177 #define SLP_INSTANCE_LOADS(S) (S)->loads |
178 #define SLP_INSTANCE_ROOT_STMT(S) (S)->root_stmt | |
165 | 179 |
166 #define SLP_TREE_CHILDREN(S) (S)->children | 180 #define SLP_TREE_CHILDREN(S) (S)->children |
167 #define SLP_TREE_SCALAR_STMTS(S) (S)->stmts | 181 #define SLP_TREE_SCALAR_STMTS(S) (S)->stmts |
182 #define SLP_TREE_SCALAR_OPS(S) (S)->ops | |
168 #define SLP_TREE_VEC_STMTS(S) (S)->vec_stmts | 183 #define SLP_TREE_VEC_STMTS(S) (S)->vec_stmts |
169 #define SLP_TREE_NUMBER_OF_VEC_STMTS(S) (S)->vec_stmts_size | 184 #define SLP_TREE_NUMBER_OF_VEC_STMTS(S) (S)->vec_stmts_size |
170 #define SLP_TREE_LOAD_PERMUTATION(S) (S)->load_permutation | 185 #define SLP_TREE_LOAD_PERMUTATION(S) (S)->load_permutation |
171 #define SLP_TREE_TWO_OPERATORS(S) (S)->two_operators | 186 #define SLP_TREE_TWO_OPERATORS(S) (S)->two_operators |
172 #define SLP_TREE_DEF_TYPE(S) (S)->def_type | 187 #define SLP_TREE_DEF_TYPE(S) (S)->def_type |
173 | 188 |
174 | 189 /* Key for map that records association between |
190 scalar conditions and corresponding loop mask, and | |
191 is populated by vect_record_loop_mask. */ | |
192 | |
193 struct scalar_cond_masked_key | |
194 { | |
195 scalar_cond_masked_key (tree t, unsigned ncopies_) | |
196 : ncopies (ncopies_) | |
197 { | |
198 get_cond_ops_from_tree (t); | |
199 } | |
200 | |
201 void get_cond_ops_from_tree (tree); | |
202 | |
203 unsigned ncopies; | |
204 tree_code code; | |
205 tree op0; | |
206 tree op1; | |
207 }; | |
208 | |
209 template<> | |
210 struct default_hash_traits<scalar_cond_masked_key> | |
211 { | |
212 typedef scalar_cond_masked_key compare_type; | |
213 typedef scalar_cond_masked_key value_type; | |
214 | |
215 static inline hashval_t | |
216 hash (value_type v) | |
217 { | |
218 inchash::hash h; | |
219 h.add_int (v.code); | |
220 inchash::add_expr (v.op0, h, 0); | |
221 inchash::add_expr (v.op1, h, 0); | |
222 h.add_int (v.ncopies); | |
223 return h.end (); | |
224 } | |
225 | |
226 static inline bool | |
227 equal (value_type existing, value_type candidate) | |
228 { | |
229 return (existing.ncopies == candidate.ncopies | |
230 && existing.code == candidate.code | |
231 && operand_equal_p (existing.op0, candidate.op0, 0) | |
232 && operand_equal_p (existing.op1, candidate.op1, 0)); | |
233 } | |
234 | |
235 static const bool empty_zero_p = true; | |
236 | |
237 static inline void | |
238 mark_empty (value_type &v) | |
239 { | |
240 v.ncopies = 0; | |
241 } | |
242 | |
243 static inline bool | |
244 is_empty (value_type v) | |
245 { | |
246 return v.ncopies == 0; | |
247 } | |
248 | |
249 static inline void mark_deleted (value_type &) {} | |
250 | |
251 static inline bool is_deleted (const value_type &) | |
252 { | |
253 return false; | |
254 } | |
255 | |
256 static inline void remove (value_type &) {} | |
257 }; | |
258 | |
259 typedef hash_set<scalar_cond_masked_key> scalar_cond_masked_set_type; | |
175 | 260 |
176 /* Describes two objects whose addresses must be unequal for the vectorized | 261 /* Describes two objects whose addresses must be unequal for the vectorized |
177 loop to be valid. */ | 262 loop to be valid. */ |
178 typedef std::pair<tree, tree> vec_object_pair; | 263 typedef std::pair<tree, tree> vec_object_pair; |
179 | 264 |
180 /* Records that vectorization is only possible if abs (EXPR) >= MIN_VALUE. | 265 /* Records that vectorization is only possible if abs (EXPR) >= MIN_VALUE. |
181 UNSIGNED_P is true if we can assume that abs (EXPR) == EXPR. */ | 266 UNSIGNED_P is true if we can assume that abs (EXPR) == EXPR. */ |
182 struct vec_lower_bound { | 267 class vec_lower_bound { |
268 public: | |
183 vec_lower_bound () {} | 269 vec_lower_bound () {} |
184 vec_lower_bound (tree e, bool u, poly_uint64 m) | 270 vec_lower_bound (tree e, bool u, poly_uint64 m) |
185 : expr (e), unsigned_p (u), min_value (m) {} | 271 : expr (e), unsigned_p (u), min_value (m) {} |
186 | 272 |
187 tree expr; | 273 tree expr; |
189 poly_uint64 min_value; | 275 poly_uint64 min_value; |
190 }; | 276 }; |
191 | 277 |
192 /* Vectorizer state shared between different analyses like vector sizes | 278 /* Vectorizer state shared between different analyses like vector sizes |
193 of the same CFG region. */ | 279 of the same CFG region. */ |
194 struct vec_info_shared { | 280 class vec_info_shared { |
281 public: | |
195 vec_info_shared(); | 282 vec_info_shared(); |
196 ~vec_info_shared(); | 283 ~vec_info_shared(); |
197 | 284 |
198 void save_datarefs(); | 285 void save_datarefs(); |
199 void check_datarefs(); | 286 void check_datarefs(); |
209 an auto_vec. */ | 296 an auto_vec. */ |
210 vec<ddr_p> ddrs; | 297 vec<ddr_p> ddrs; |
211 }; | 298 }; |
212 | 299 |
213 /* Vectorizer state common between loop and basic-block vectorization. */ | 300 /* Vectorizer state common between loop and basic-block vectorization. */ |
214 struct vec_info { | 301 class vec_info { |
302 public: | |
303 typedef hash_set<int_hash<machine_mode, E_VOIDmode, E_BLKmode> > mode_set; | |
215 enum vec_kind { bb, loop }; | 304 enum vec_kind { bb, loop }; |
216 | 305 |
217 vec_info (vec_kind, void *, vec_info_shared *); | 306 vec_info (vec_kind, void *, vec_info_shared *); |
218 ~vec_info (); | 307 ~vec_info (); |
219 | 308 |
220 stmt_vec_info add_stmt (gimple *); | 309 stmt_vec_info add_stmt (gimple *); |
221 stmt_vec_info lookup_stmt (gimple *); | 310 stmt_vec_info lookup_stmt (gimple *); |
222 stmt_vec_info lookup_def (tree); | 311 stmt_vec_info lookup_def (tree); |
223 stmt_vec_info lookup_single_use (tree); | 312 stmt_vec_info lookup_single_use (tree); |
224 struct dr_vec_info *lookup_dr (data_reference *); | 313 class dr_vec_info *lookup_dr (data_reference *); |
225 void move_dr (stmt_vec_info, stmt_vec_info); | 314 void move_dr (stmt_vec_info, stmt_vec_info); |
226 void remove_stmt (stmt_vec_info); | 315 void remove_stmt (stmt_vec_info); |
227 void replace_stmt (gimple_stmt_iterator *, stmt_vec_info, gimple *); | 316 void replace_stmt (gimple_stmt_iterator *, stmt_vec_info, gimple *); |
228 | 317 |
229 /* The type of vectorization. */ | 318 /* The type of vectorization. */ |
246 stmt in the chain. */ | 335 stmt in the chain. */ |
247 auto_vec<stmt_vec_info> grouped_stores; | 336 auto_vec<stmt_vec_info> grouped_stores; |
248 | 337 |
249 /* Cost data used by the target cost model. */ | 338 /* Cost data used by the target cost model. */ |
250 void *target_cost_data; | 339 void *target_cost_data; |
340 | |
341 /* The set of vector modes used in the vectorized region. */ | |
342 mode_set used_vector_modes; | |
343 | |
344 /* The argument we should pass to related_vector_mode when looking up | |
345 the vector mode for a scalar mode, or VOIDmode if we haven't yet | |
346 made any decisions about which vector modes to use. */ | |
347 machine_mode vector_mode; | |
251 | 348 |
252 private: | 349 private: |
253 stmt_vec_info new_stmt_vec_info (gimple *stmt); | 350 stmt_vec_info new_stmt_vec_info (gimple *stmt); |
254 void set_vinfo_for_stmt (gimple *, stmt_vec_info); | 351 void set_vinfo_for_stmt (gimple *, stmt_vec_info); |
255 void free_stmt_vec_infos (); | 352 void free_stmt_vec_infos (); |
256 void free_stmt_vec_info (stmt_vec_info); | 353 void free_stmt_vec_info (stmt_vec_info); |
257 }; | 354 }; |
258 | 355 |
259 struct _loop_vec_info; | 356 class _loop_vec_info; |
260 struct _bb_vec_info; | 357 class _bb_vec_info; |
261 | 358 |
262 template<> | 359 template<> |
263 template<> | 360 template<> |
264 inline bool | 361 inline bool |
265 is_a_helper <_loop_vec_info *>::test (vec_info *i) | 362 is_a_helper <_loop_vec_info *>::test (vec_info *i) |
370 vec<tree> masks; | 467 vec<tree> masks; |
371 }; | 468 }; |
372 | 469 |
373 typedef auto_vec<rgroup_masks> vec_loop_masks; | 470 typedef auto_vec<rgroup_masks> vec_loop_masks; |
374 | 471 |
472 typedef auto_vec<std::pair<data_reference*, tree> > drs_init_vec; | |
473 | |
375 /*-----------------------------------------------------------------*/ | 474 /*-----------------------------------------------------------------*/ |
376 /* Info on vectorized loops. */ | 475 /* Info on vectorized loops. */ |
377 /*-----------------------------------------------------------------*/ | 476 /*-----------------------------------------------------------------*/ |
378 typedef struct _loop_vec_info : public vec_info { | 477 typedef class _loop_vec_info : public vec_info { |
379 _loop_vec_info (struct loop *, vec_info_shared *); | 478 public: |
479 _loop_vec_info (class loop *, vec_info_shared *); | |
380 ~_loop_vec_info (); | 480 ~_loop_vec_info (); |
381 | 481 |
382 /* The loop to which this info struct refers to. */ | 482 /* The loop to which this info struct refers to. */ |
383 struct loop *loop; | 483 class loop *loop; |
384 | 484 |
385 /* The loop basic blocks. */ | 485 /* The loop basic blocks. */ |
386 basic_block *bbs; | 486 basic_block *bbs; |
387 | 487 |
388 /* Number of latch executions. */ | 488 /* Number of latch executions. */ |
392 /* Number of iterations of the original loop. */ | 492 /* Number of iterations of the original loop. */ |
393 tree num_iters_unchanged; | 493 tree num_iters_unchanged; |
394 /* Condition under which this loop is analyzed and versioned. */ | 494 /* Condition under which this loop is analyzed and versioned. */ |
395 tree num_iters_assumptions; | 495 tree num_iters_assumptions; |
396 | 496 |
397 /* Threshold of number of iterations below which vectorzation will not be | 497 /* Threshold of number of iterations below which vectorization will not be |
398 performed. It is calculated from MIN_PROFITABLE_ITERS and | 498 performed. It is calculated from MIN_PROFITABLE_ITERS and |
399 PARAM_MIN_VECT_LOOP_BOUND. */ | 499 param_min_vect_loop_bound. */ |
400 unsigned int th; | 500 unsigned int th; |
401 | 501 |
402 /* When applying loop versioning, the vector form should only be used | 502 /* When applying loop versioning, the vector form should only be used |
403 if the number of scalar iterations is >= this value, on top of all | 503 if the number of scalar iterations is >= this value, on top of all |
404 the other requirements. Ignored when loop versioning is not being | 504 the other requirements. Ignored when loop versioning is not being |
414 | 514 |
415 /* The masks that a fully-masked loop should use to avoid operating | 515 /* The masks that a fully-masked loop should use to avoid operating |
416 on inactive scalars. */ | 516 on inactive scalars. */ |
417 vec_loop_masks masks; | 517 vec_loop_masks masks; |
418 | 518 |
519 /* Set of scalar conditions that have loop mask applied. */ | |
520 scalar_cond_masked_set_type scalar_cond_masked_set; | |
521 | |
419 /* If we are using a loop mask to align memory addresses, this variable | 522 /* If we are using a loop mask to align memory addresses, this variable |
420 contains the number of vector elements that we should skip in the | 523 contains the number of vector elements that we should skip in the |
421 first iteration of the vector loop (i.e. the number of leading | 524 first iteration of the vector loop (i.e. the number of leading |
422 elements that should be false in the first mask). */ | 525 elements that should be false in the first mask). */ |
423 tree mask_skip_niters; | 526 tree mask_skip_niters; |
424 | 527 |
425 /* Type of the variables to use in the WHILE_ULT call for fully-masked | 528 /* Type of the variables to use in the WHILE_ULT call for fully-masked |
426 loops. */ | 529 loops. */ |
427 tree mask_compare_type; | 530 tree mask_compare_type; |
428 | 531 |
532 /* For #pragma omp simd if (x) loops the x expression. If constant 0, | |
533 the loop should not be vectorized, if constant non-zero, simd_if_cond | |
534 shouldn't be set and loop vectorized normally, if SSA_NAME, the loop | |
535 should be versioned on that condition, using scalar loop if the condition | |
536 is false and vectorized loop otherwise. */ | |
537 tree simd_if_cond; | |
538 | |
539 /* Type of the IV to use in the WHILE_ULT call for fully-masked | |
540 loops. */ | |
541 tree iv_type; | |
542 | |
429 /* Unknown DRs according to which loop was peeled. */ | 543 /* Unknown DRs according to which loop was peeled. */ |
430 struct dr_vec_info *unaligned_dr; | 544 class dr_vec_info *unaligned_dr; |
431 | 545 |
432 /* peeling_for_alignment indicates whether peeling for alignment will take | 546 /* peeling_for_alignment indicates whether peeling for alignment will take |
433 place, and what the peeling factor should be: | 547 place, and what the peeling factor should be: |
434 peeling_for_alignment = X means: | 548 peeling_for_alignment = X means: |
435 If X=0: Peeling for alignment will not be applied. | 549 If X=0: Peeling for alignment will not be applied. |
476 auto_vec<stmt_info_for_cost> scalar_cost_vec; | 590 auto_vec<stmt_info_for_cost> scalar_cost_vec; |
477 | 591 |
478 /* Map of IV base/step expressions to inserted name in the preheader. */ | 592 /* Map of IV base/step expressions to inserted name in the preheader. */ |
479 hash_map<tree_operand_hash, tree> *ivexpr_map; | 593 hash_map<tree_operand_hash, tree> *ivexpr_map; |
480 | 594 |
595 /* Map of OpenMP "omp simd array" scan variables to corresponding | |
596 rhs of the store of the initializer. */ | |
597 hash_map<tree, tree> *scan_map; | |
598 | |
481 /* The unrolling factor needed to SLP the loop. In case of that pure SLP is | 599 /* The unrolling factor needed to SLP the loop. In case of that pure SLP is |
482 applied to the loop, i.e., no unrolling is needed, this is 1. */ | 600 applied to the loop, i.e., no unrolling is needed, this is 1. */ |
483 poly_uint64 slp_unrolling_factor; | 601 poly_uint64 slp_unrolling_factor; |
484 | 602 |
485 /* Cost of a single scalar iteration. */ | 603 /* Cost of a single scalar iteration. */ |
486 int single_scalar_iteration_cost; | 604 int single_scalar_iteration_cost; |
605 | |
606 /* The cost of the vector prologue and epilogue, including peeled | |
607 iterations and set-up code. */ | |
608 int vec_outside_cost; | |
609 | |
610 /* The cost of the vector loop body. */ | |
611 int vec_inside_cost; | |
487 | 612 |
488 /* Is the loop vectorizable? */ | 613 /* Is the loop vectorizable? */ |
489 bool vectorizable; | 614 bool vectorizable; |
490 | 615 |
491 /* Records whether we still have the option of using a fully-masked loop. */ | 616 /* Records whether we still have the option of using a fully-masked loop. */ |
500 bool peeling_for_gaps; | 625 bool peeling_for_gaps; |
501 | 626 |
502 /* When the number of iterations is not a multiple of the vector size | 627 /* When the number of iterations is not a multiple of the vector size |
503 we need to peel off iterations at the end to form an epilogue loop. */ | 628 we need to peel off iterations at the end to form an epilogue loop. */ |
504 bool peeling_for_niter; | 629 bool peeling_for_niter; |
505 | |
506 /* Reductions are canonicalized so that the last operand is the reduction | |
507 operand. If this places a constant into RHS1, this decanonicalizes | |
508 GIMPLE for other phases, so we must track when this has occurred and | |
509 fix it up. */ | |
510 bool operands_swapped; | |
511 | 630 |
512 /* True if there are no loop carried data dependencies in the loop. | 631 /* True if there are no loop carried data dependencies in the loop. |
513 If loop->safelen <= 1, then this is always true, either the loop | 632 If loop->safelen <= 1, then this is always true, either the loop |
514 didn't have any loop carried data dependencies, or the loop is being | 633 didn't have any loop carried data dependencies, or the loop is being |
515 vectorized guarded with some runtime alias checks, or couldn't | 634 vectorized guarded with some runtime alias checks, or couldn't |
529 bool no_data_dependencies; | 648 bool no_data_dependencies; |
530 | 649 |
531 /* Mark loops having masked stores. */ | 650 /* Mark loops having masked stores. */ |
532 bool has_mask_store; | 651 bool has_mask_store; |
533 | 652 |
653 /* Queued scaling factor for the scalar loop. */ | |
654 profile_probability scalar_loop_scaling; | |
655 | |
534 /* If if-conversion versioned this loop before conversion, this is the | 656 /* If if-conversion versioned this loop before conversion, this is the |
535 loop version without if-conversion. */ | 657 loop version without if-conversion. */ |
536 struct loop *scalar_loop; | 658 class loop *scalar_loop; |
537 | 659 |
538 /* For loops being epilogues of already vectorized loops | 660 /* For loops being epilogues of already vectorized loops |
539 this points to the original vectorized loop. Otherwise NULL. */ | 661 this points to the original vectorized loop. Otherwise NULL. */ |
540 _loop_vec_info *orig_loop_info; | 662 _loop_vec_info *orig_loop_info; |
663 | |
664 /* Used to store loop_vec_infos of epilogues of this loop during | |
665 analysis. */ | |
666 vec<_loop_vec_info *> epilogue_vinfos; | |
541 | 667 |
542 } *loop_vec_info; | 668 } *loop_vec_info; |
543 | 669 |
544 /* Access Functions. */ | 670 /* Access Functions. */ |
545 #define LOOP_VINFO_LOOP(L) (L)->loop | 671 #define LOOP_VINFO_LOOP(L) (L)->loop |
559 #define LOOP_VINFO_VECT_FACTOR(L) (L)->vectorization_factor | 685 #define LOOP_VINFO_VECT_FACTOR(L) (L)->vectorization_factor |
560 #define LOOP_VINFO_MAX_VECT_FACTOR(L) (L)->max_vectorization_factor | 686 #define LOOP_VINFO_MAX_VECT_FACTOR(L) (L)->max_vectorization_factor |
561 #define LOOP_VINFO_MASKS(L) (L)->masks | 687 #define LOOP_VINFO_MASKS(L) (L)->masks |
562 #define LOOP_VINFO_MASK_SKIP_NITERS(L) (L)->mask_skip_niters | 688 #define LOOP_VINFO_MASK_SKIP_NITERS(L) (L)->mask_skip_niters |
563 #define LOOP_VINFO_MASK_COMPARE_TYPE(L) (L)->mask_compare_type | 689 #define LOOP_VINFO_MASK_COMPARE_TYPE(L) (L)->mask_compare_type |
690 #define LOOP_VINFO_MASK_IV_TYPE(L) (L)->iv_type | |
564 #define LOOP_VINFO_PTR_MASK(L) (L)->ptr_mask | 691 #define LOOP_VINFO_PTR_MASK(L) (L)->ptr_mask |
565 #define LOOP_VINFO_LOOP_NEST(L) (L)->shared->loop_nest | 692 #define LOOP_VINFO_LOOP_NEST(L) (L)->shared->loop_nest |
566 #define LOOP_VINFO_DATAREFS(L) (L)->shared->datarefs | 693 #define LOOP_VINFO_DATAREFS(L) (L)->shared->datarefs |
567 #define LOOP_VINFO_DDRS(L) (L)->shared->ddrs | 694 #define LOOP_VINFO_DDRS(L) (L)->shared->ddrs |
568 #define LOOP_VINFO_INT_NITERS(L) (TREE_INT_CST_LOW ((L)->num_iters)) | 695 #define LOOP_VINFO_INT_NITERS(L) (TREE_INT_CST_LOW ((L)->num_iters)) |
579 #define LOOP_VINFO_SLP_UNROLLING_FACTOR(L) (L)->slp_unrolling_factor | 706 #define LOOP_VINFO_SLP_UNROLLING_FACTOR(L) (L)->slp_unrolling_factor |
580 #define LOOP_VINFO_REDUCTIONS(L) (L)->reductions | 707 #define LOOP_VINFO_REDUCTIONS(L) (L)->reductions |
581 #define LOOP_VINFO_REDUCTION_CHAINS(L) (L)->reduction_chains | 708 #define LOOP_VINFO_REDUCTION_CHAINS(L) (L)->reduction_chains |
582 #define LOOP_VINFO_TARGET_COST_DATA(L) (L)->target_cost_data | 709 #define LOOP_VINFO_TARGET_COST_DATA(L) (L)->target_cost_data |
583 #define LOOP_VINFO_PEELING_FOR_GAPS(L) (L)->peeling_for_gaps | 710 #define LOOP_VINFO_PEELING_FOR_GAPS(L) (L)->peeling_for_gaps |
584 #define LOOP_VINFO_OPERANDS_SWAPPED(L) (L)->operands_swapped | |
585 #define LOOP_VINFO_PEELING_FOR_NITER(L) (L)->peeling_for_niter | 711 #define LOOP_VINFO_PEELING_FOR_NITER(L) (L)->peeling_for_niter |
586 #define LOOP_VINFO_NO_DATA_DEPENDENCIES(L) (L)->no_data_dependencies | 712 #define LOOP_VINFO_NO_DATA_DEPENDENCIES(L) (L)->no_data_dependencies |
587 #define LOOP_VINFO_SCALAR_LOOP(L) (L)->scalar_loop | 713 #define LOOP_VINFO_SCALAR_LOOP(L) (L)->scalar_loop |
714 #define LOOP_VINFO_SCALAR_LOOP_SCALING(L) (L)->scalar_loop_scaling | |
588 #define LOOP_VINFO_HAS_MASK_STORE(L) (L)->has_mask_store | 715 #define LOOP_VINFO_HAS_MASK_STORE(L) (L)->has_mask_store |
589 #define LOOP_VINFO_SCALAR_ITERATION_COST(L) (L)->scalar_cost_vec | 716 #define LOOP_VINFO_SCALAR_ITERATION_COST(L) (L)->scalar_cost_vec |
590 #define LOOP_VINFO_SINGLE_SCALAR_ITERATION_COST(L) (L)->single_scalar_iteration_cost | 717 #define LOOP_VINFO_SINGLE_SCALAR_ITERATION_COST(L) (L)->single_scalar_iteration_cost |
591 #define LOOP_VINFO_ORIG_LOOP_INFO(L) (L)->orig_loop_info | 718 #define LOOP_VINFO_ORIG_LOOP_INFO(L) (L)->orig_loop_info |
719 #define LOOP_VINFO_SIMD_IF_COND(L) (L)->simd_if_cond | |
592 | 720 |
593 #define LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT(L) \ | 721 #define LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT(L) \ |
594 ((L)->may_misalign_stmts.length () > 0) | 722 ((L)->may_misalign_stmts.length () > 0) |
595 #define LOOP_REQUIRES_VERSIONING_FOR_ALIAS(L) \ | 723 #define LOOP_REQUIRES_VERSIONING_FOR_ALIAS(L) \ |
596 ((L)->comp_alias_ddrs.length () > 0 \ | 724 ((L)->comp_alias_ddrs.length () > 0 \ |
597 || (L)->check_unequal_addrs.length () > 0 \ | 725 || (L)->check_unequal_addrs.length () > 0 \ |
598 || (L)->lower_bounds.length () > 0) | 726 || (L)->lower_bounds.length () > 0) |
599 #define LOOP_REQUIRES_VERSIONING_FOR_NITERS(L) \ | 727 #define LOOP_REQUIRES_VERSIONING_FOR_NITERS(L) \ |
600 (LOOP_VINFO_NITERS_ASSUMPTIONS (L)) | 728 (LOOP_VINFO_NITERS_ASSUMPTIONS (L)) |
729 #define LOOP_REQUIRES_VERSIONING_FOR_SIMD_IF_COND(L) \ | |
730 (LOOP_VINFO_SIMD_IF_COND (L)) | |
601 #define LOOP_REQUIRES_VERSIONING(L) \ | 731 #define LOOP_REQUIRES_VERSIONING(L) \ |
602 (LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT (L) \ | 732 (LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT (L) \ |
603 || LOOP_REQUIRES_VERSIONING_FOR_ALIAS (L) \ | 733 || LOOP_REQUIRES_VERSIONING_FOR_ALIAS (L) \ |
604 || LOOP_REQUIRES_VERSIONING_FOR_NITERS (L)) | 734 || LOOP_REQUIRES_VERSIONING_FOR_NITERS (L) \ |
735 || LOOP_REQUIRES_VERSIONING_FOR_SIMD_IF_COND (L)) | |
605 | 736 |
606 #define LOOP_VINFO_NITERS_KNOWN_P(L) \ | 737 #define LOOP_VINFO_NITERS_KNOWN_P(L) \ |
607 (tree_fits_shwi_p ((L)->num_iters) && tree_to_shwi ((L)->num_iters) > 0) | 738 (tree_fits_shwi_p ((L)->num_iters) && tree_to_shwi ((L)->num_iters) > 0) |
608 | 739 |
609 #define LOOP_VINFO_EPILOGUE_P(L) \ | 740 #define LOOP_VINFO_EPILOGUE_P(L) \ |
617 propagating an opt_problem * describing the failure back up the call | 748 propagating an opt_problem * describing the failure back up the call |
618 stack. */ | 749 stack. */ |
619 typedef opt_pointer_wrapper <loop_vec_info> opt_loop_vec_info; | 750 typedef opt_pointer_wrapper <loop_vec_info> opt_loop_vec_info; |
620 | 751 |
621 static inline loop_vec_info | 752 static inline loop_vec_info |
622 loop_vec_info_for_loop (struct loop *loop) | 753 loop_vec_info_for_loop (class loop *loop) |
623 { | 754 { |
624 return (loop_vec_info) loop->aux; | 755 return (loop_vec_info) loop->aux; |
625 } | 756 } |
626 | 757 |
627 typedef struct _bb_vec_info : public vec_info | 758 typedef class _bb_vec_info : public vec_info |
628 { | 759 { |
760 public: | |
629 _bb_vec_info (gimple_stmt_iterator, gimple_stmt_iterator, vec_info_shared *); | 761 _bb_vec_info (gimple_stmt_iterator, gimple_stmt_iterator, vec_info_shared *); |
630 ~_bb_vec_info (); | 762 ~_bb_vec_info (); |
631 | 763 |
632 basic_block bb; | 764 basic_block bb; |
633 gimple_stmt_iterator region_begin; | 765 gimple_stmt_iterator region_begin; |
664 reduc_vec_info_type, | 796 reduc_vec_info_type, |
665 induc_vec_info_type, | 797 induc_vec_info_type, |
666 type_promotion_vec_info_type, | 798 type_promotion_vec_info_type, |
667 type_demotion_vec_info_type, | 799 type_demotion_vec_info_type, |
668 type_conversion_vec_info_type, | 800 type_conversion_vec_info_type, |
801 cycle_phi_info_type, | |
802 lc_phi_info_type, | |
669 loop_exit_ctrl_vec_info_type | 803 loop_exit_ctrl_vec_info_type |
670 }; | 804 }; |
671 | 805 |
672 /* Indicates whether/how a variable is used in the scope of loop/basic | 806 /* Indicates whether/how a variable is used in the scope of loop/basic |
673 block. */ | 807 block. */ |
762 | 896 |
763 /* The access uses gather loads or scatter stores. */ | 897 /* The access uses gather loads or scatter stores. */ |
764 VMAT_GATHER_SCATTER | 898 VMAT_GATHER_SCATTER |
765 }; | 899 }; |
766 | 900 |
767 struct dr_vec_info { | 901 class dr_vec_info { |
902 public: | |
768 /* The data reference itself. */ | 903 /* The data reference itself. */ |
769 data_reference *dr; | 904 data_reference *dr; |
770 /* The statement that contains the data reference. */ | 905 /* The statement that contains the data reference. */ |
771 stmt_vec_info stmt; | 906 stmt_vec_info stmt; |
772 /* The misalignment in bytes of the reference, or -1 if not known. */ | 907 /* The misalignment in bytes of the reference, or -1 if not known. */ |
773 int misalignment; | 908 int misalignment; |
774 /* The byte alignment that we'd ideally like the reference to have, | 909 /* The byte alignment that we'd ideally like the reference to have, |
775 and the value that misalignment is measured against. */ | 910 and the value that misalignment is measured against. */ |
776 int target_alignment; | 911 poly_uint64 target_alignment; |
777 /* If true the alignment of base_decl needs to be increased. */ | 912 /* If true the alignment of base_decl needs to be increased. */ |
778 bool base_misaligned; | 913 bool base_misaligned; |
779 tree base_decl; | 914 tree base_decl; |
915 | |
916 /* Stores current vectorized loop's offset. To be added to the DR's | |
917 offset to calculate current offset of data reference. */ | |
918 tree offset; | |
780 }; | 919 }; |
781 | 920 |
782 typedef struct data_reference *dr_p; | 921 typedef struct data_reference *dr_p; |
783 | 922 |
784 struct _stmt_vec_info { | 923 class _stmt_vec_info { |
924 public: | |
785 | 925 |
786 enum stmt_vec_info_type type; | 926 enum stmt_vec_info_type type; |
787 | 927 |
788 /* Indicates whether this stmts is part of a computation whose result is | 928 /* Indicates whether this stmts is part of a computation whose result is |
789 used outside the loop. */ | 929 used outside the loop. */ |
868 /* Interleaving and reduction chains info. */ | 1008 /* Interleaving and reduction chains info. */ |
869 /* First element in the group. */ | 1009 /* First element in the group. */ |
870 stmt_vec_info first_element; | 1010 stmt_vec_info first_element; |
871 /* Pointer to the next element in the group. */ | 1011 /* Pointer to the next element in the group. */ |
872 stmt_vec_info next_element; | 1012 stmt_vec_info next_element; |
873 /* For data-refs, in case that two or more stmts share data-ref, this is the | |
874 pointer to the previously detected stmt with the same dr. */ | |
875 stmt_vec_info same_dr_stmt; | |
876 /* The size of the group. */ | 1013 /* The size of the group. */ |
877 unsigned int size; | 1014 unsigned int size; |
878 /* For stores, number of stores from this group seen. We vectorize the last | 1015 /* For stores, number of stores from this group seen. We vectorize the last |
879 one. */ | 1016 one. */ |
880 unsigned int store_count; | 1017 unsigned int store_count; |
896 | 1033 |
897 /* True if this is an access with loop-invariant stride. */ | 1034 /* True if this is an access with loop-invariant stride. */ |
898 bool strided_p; | 1035 bool strided_p; |
899 | 1036 |
900 /* For both loads and stores. */ | 1037 /* For both loads and stores. */ |
901 bool simd_lane_access_p; | 1038 unsigned simd_lane_access_p : 3; |
902 | 1039 |
903 /* Classifies how the load or store is going to be implemented | 1040 /* Classifies how the load or store is going to be implemented |
904 for loop vectorization. */ | 1041 for loop vectorization. */ |
905 vect_memory_access_type memory_access_type; | 1042 vect_memory_access_type memory_access_type; |
906 | 1043 |
907 /* For reduction loops, this is the type of reduction. */ | 1044 /* For INTEGER_INDUC_COND_REDUCTION, the initial value to be used. */ |
908 enum vect_reduction_type v_reduc_type; | 1045 tree induc_cond_initial_val; |
909 | 1046 |
910 /* For CONST_COND_REDUCTION, record the reduc code. */ | 1047 /* If not NULL the value to be added to compute final reduction value. */ |
911 enum tree_code const_cond_reduc_code; | 1048 tree reduc_epilogue_adjustment; |
912 | 1049 |
913 /* On a reduction PHI the reduction type as detected by | 1050 /* On a reduction PHI the reduction type as detected by |
914 vect_force_simple_reduction. */ | 1051 vect_is_simple_reduction and vectorizable_reduction. */ |
915 enum vect_reduction_type reduc_type; | 1052 enum vect_reduction_type reduc_type; |
1053 | |
1054 /* The original reduction code, to be used in the epilogue. */ | |
1055 enum tree_code reduc_code; | |
1056 /* An internal function we should use in the epilogue. */ | |
1057 internal_fn reduc_fn; | |
1058 | |
1059 /* On a stmt participating in the reduction the index of the operand | |
1060 on the reduction SSA cycle. */ | |
1061 int reduc_idx; | |
916 | 1062 |
917 /* On a reduction PHI the def returned by vect_force_simple_reduction. | 1063 /* On a reduction PHI the def returned by vect_force_simple_reduction. |
918 On the def returned by vect_force_simple_reduction the | 1064 On the def returned by vect_force_simple_reduction the |
919 corresponding PHI. */ | 1065 corresponding PHI. */ |
920 stmt_vec_info reduc_def; | 1066 stmt_vec_info reduc_def; |
1067 | |
1068 /* The vector input type relevant for reduction vectorization. */ | |
1069 tree reduc_vectype_in; | |
1070 | |
1071 /* The vector type for performing the actual reduction. */ | |
1072 tree reduc_vectype; | |
1073 | |
1074 /* Whether we force a single cycle PHI during reduction vectorization. */ | |
1075 bool force_single_cycle; | |
1076 | |
1077 /* Whether on this stmt reduction meta is recorded. */ | |
1078 bool is_reduc_info; | |
921 | 1079 |
922 /* The number of scalar stmt references from active SLP instances. */ | 1080 /* The number of scalar stmt references from active SLP instances. */ |
923 unsigned int num_slp_uses; | 1081 unsigned int num_slp_uses; |
924 | 1082 |
925 /* If nonzero, the lhs of the statement could be truncated to this | 1083 /* If nonzero, the lhs of the statement could be truncated to this |
934 /* If OPERATION_BITS is nonzero, the statement could be performed on | 1092 /* If OPERATION_BITS is nonzero, the statement could be performed on |
935 an integer with the sign and number of bits given by OPERATION_SIGN | 1093 an integer with the sign and number of bits given by OPERATION_SIGN |
936 and OPERATION_BITS without changing the result. */ | 1094 and OPERATION_BITS without changing the result. */ |
937 unsigned int operation_precision; | 1095 unsigned int operation_precision; |
938 signop operation_sign; | 1096 signop operation_sign; |
1097 | |
1098 /* If the statement produces a boolean result, this value describes | |
1099 how we should choose the associated vector type. The possible | |
1100 values are: | |
1101 | |
1102 - an integer precision N if we should use the vector mask type | |
1103 associated with N-bit integers. This is only used if all relevant | |
1104 input booleans also want the vector mask type for N-bit integers, | |
1105 or if we can convert them into that form by pattern-matching. | |
1106 | |
1107 - ~0U if we considered choosing a vector mask type but decided | |
1108 to treat the boolean as a normal integer type instead. | |
1109 | |
1110 - 0 otherwise. This means either that the operation isn't one that | |
1111 could have a vector mask type (and so should have a normal vector | |
1112 type instead) or that we simply haven't made a choice either way. */ | |
1113 unsigned int mask_precision; | |
1114 | |
1115 /* True if this is only suitable for SLP vectorization. */ | |
1116 bool slp_vect_only_p; | |
939 }; | 1117 }; |
940 | 1118 |
941 /* Information about a gather/scatter call. */ | 1119 /* Information about a gather/scatter call. */ |
942 struct gather_scatter_info { | 1120 struct gather_scatter_info { |
943 /* The internal function to use for the gather/scatter operation, | 1121 /* The internal function to use for the gather/scatter operation, |
996 #define STMT_VINFO_DATA_REF(S) ((S)->dr_aux.dr + 0) | 1174 #define STMT_VINFO_DATA_REF(S) ((S)->dr_aux.dr + 0) |
997 #define STMT_VINFO_GATHER_SCATTER_P(S) (S)->gather_scatter_p | 1175 #define STMT_VINFO_GATHER_SCATTER_P(S) (S)->gather_scatter_p |
998 #define STMT_VINFO_STRIDED_P(S) (S)->strided_p | 1176 #define STMT_VINFO_STRIDED_P(S) (S)->strided_p |
999 #define STMT_VINFO_MEMORY_ACCESS_TYPE(S) (S)->memory_access_type | 1177 #define STMT_VINFO_MEMORY_ACCESS_TYPE(S) (S)->memory_access_type |
1000 #define STMT_VINFO_SIMD_LANE_ACCESS_P(S) (S)->simd_lane_access_p | 1178 #define STMT_VINFO_SIMD_LANE_ACCESS_P(S) (S)->simd_lane_access_p |
1001 #define STMT_VINFO_VEC_REDUCTION_TYPE(S) (S)->v_reduc_type | 1179 #define STMT_VINFO_VEC_INDUC_COND_INITIAL_VAL(S) (S)->induc_cond_initial_val |
1002 #define STMT_VINFO_VEC_CONST_COND_REDUC_CODE(S) (S)->const_cond_reduc_code | 1180 #define STMT_VINFO_REDUC_EPILOGUE_ADJUSTMENT(S) (S)->reduc_epilogue_adjustment |
1181 #define STMT_VINFO_REDUC_IDX(S) (S)->reduc_idx | |
1182 #define STMT_VINFO_FORCE_SINGLE_CYCLE(S) (S)->force_single_cycle | |
1003 | 1183 |
1004 #define STMT_VINFO_DR_WRT_VEC_LOOP(S) (S)->dr_wrt_vec_loop | 1184 #define STMT_VINFO_DR_WRT_VEC_LOOP(S) (S)->dr_wrt_vec_loop |
1005 #define STMT_VINFO_DR_BASE_ADDRESS(S) (S)->dr_wrt_vec_loop.base_address | 1185 #define STMT_VINFO_DR_BASE_ADDRESS(S) (S)->dr_wrt_vec_loop.base_address |
1006 #define STMT_VINFO_DR_INIT(S) (S)->dr_wrt_vec_loop.init | 1186 #define STMT_VINFO_DR_INIT(S) (S)->dr_wrt_vec_loop.init |
1007 #define STMT_VINFO_DR_OFFSET(S) (S)->dr_wrt_vec_loop.offset | 1187 #define STMT_VINFO_DR_OFFSET(S) (S)->dr_wrt_vec_loop.offset |
1028 #define STMT_VINFO_LOOP_PHI_EVOLUTION_BASE_UNCHANGED(S) (S)->loop_phi_evolution_base_unchanged | 1208 #define STMT_VINFO_LOOP_PHI_EVOLUTION_BASE_UNCHANGED(S) (S)->loop_phi_evolution_base_unchanged |
1029 #define STMT_VINFO_LOOP_PHI_EVOLUTION_PART(S) (S)->loop_phi_evolution_part | 1209 #define STMT_VINFO_LOOP_PHI_EVOLUTION_PART(S) (S)->loop_phi_evolution_part |
1030 #define STMT_VINFO_MIN_NEG_DIST(S) (S)->min_neg_dist | 1210 #define STMT_VINFO_MIN_NEG_DIST(S) (S)->min_neg_dist |
1031 #define STMT_VINFO_NUM_SLP_USES(S) (S)->num_slp_uses | 1211 #define STMT_VINFO_NUM_SLP_USES(S) (S)->num_slp_uses |
1032 #define STMT_VINFO_REDUC_TYPE(S) (S)->reduc_type | 1212 #define STMT_VINFO_REDUC_TYPE(S) (S)->reduc_type |
1213 #define STMT_VINFO_REDUC_CODE(S) (S)->reduc_code | |
1214 #define STMT_VINFO_REDUC_FN(S) (S)->reduc_fn | |
1033 #define STMT_VINFO_REDUC_DEF(S) (S)->reduc_def | 1215 #define STMT_VINFO_REDUC_DEF(S) (S)->reduc_def |
1216 #define STMT_VINFO_REDUC_VECTYPE(S) (S)->reduc_vectype | |
1217 #define STMT_VINFO_REDUC_VECTYPE_IN(S) (S)->reduc_vectype_in | |
1218 #define STMT_VINFO_SLP_VECT_ONLY(S) (S)->slp_vect_only_p | |
1034 | 1219 |
1035 #define DR_GROUP_FIRST_ELEMENT(S) \ | 1220 #define DR_GROUP_FIRST_ELEMENT(S) \ |
1036 (gcc_checking_assert ((S)->dr_aux.dr), (S)->first_element) | 1221 (gcc_checking_assert ((S)->dr_aux.dr), (S)->first_element) |
1037 #define DR_GROUP_NEXT_ELEMENT(S) \ | 1222 #define DR_GROUP_NEXT_ELEMENT(S) \ |
1038 (gcc_checking_assert ((S)->dr_aux.dr), (S)->next_element) | 1223 (gcc_checking_assert ((S)->dr_aux.dr), (S)->next_element) |
1040 (gcc_checking_assert ((S)->dr_aux.dr), (S)->size) | 1225 (gcc_checking_assert ((S)->dr_aux.dr), (S)->size) |
1041 #define DR_GROUP_STORE_COUNT(S) \ | 1226 #define DR_GROUP_STORE_COUNT(S) \ |
1042 (gcc_checking_assert ((S)->dr_aux.dr), (S)->store_count) | 1227 (gcc_checking_assert ((S)->dr_aux.dr), (S)->store_count) |
1043 #define DR_GROUP_GAP(S) \ | 1228 #define DR_GROUP_GAP(S) \ |
1044 (gcc_checking_assert ((S)->dr_aux.dr), (S)->gap) | 1229 (gcc_checking_assert ((S)->dr_aux.dr), (S)->gap) |
1045 #define DR_GROUP_SAME_DR_STMT(S) \ | |
1046 (gcc_checking_assert ((S)->dr_aux.dr), (S)->same_dr_stmt) | |
1047 | 1230 |
1048 #define REDUC_GROUP_FIRST_ELEMENT(S) \ | 1231 #define REDUC_GROUP_FIRST_ELEMENT(S) \ |
1049 (gcc_checking_assert (!(S)->dr_aux.dr), (S)->first_element) | 1232 (gcc_checking_assert (!(S)->dr_aux.dr), (S)->first_element) |
1050 #define REDUC_GROUP_NEXT_ELEMENT(S) \ | 1233 #define REDUC_GROUP_NEXT_ELEMENT(S) \ |
1051 (gcc_checking_assert (!(S)->dr_aux.dr), (S)->next_element) | 1234 (gcc_checking_assert (!(S)->dr_aux.dr), (S)->next_element) |
1077 || TREE_CODE (TYPE) == ENUMERAL_TYPE) \ | 1260 || TREE_CODE (TYPE) == ENUMERAL_TYPE) \ |
1078 && TYPE_PRECISION (TYPE) == 1 \ | 1261 && TYPE_PRECISION (TYPE) == 1 \ |
1079 && TYPE_UNSIGNED (TYPE))) | 1262 && TYPE_UNSIGNED (TYPE))) |
1080 | 1263 |
1081 static inline bool | 1264 static inline bool |
1082 nested_in_vect_loop_p (struct loop *loop, stmt_vec_info stmt_info) | 1265 nested_in_vect_loop_p (class loop *loop, stmt_vec_info stmt_info) |
1083 { | 1266 { |
1084 return (loop->inner | 1267 return (loop->inner |
1085 && (loop->inner == (gimple_bb (stmt_info->stmt))->loop_father)); | 1268 && (loop->inner == (gimple_bb (stmt_info->stmt))->loop_father)); |
1086 } | 1269 } |
1087 | 1270 |
1088 /* Return the earlier statement between STMT1_INFO and STMT2_INFO. */ | 1271 /* Return true if STMT_INFO should produce a vector mask type rather than |
1272 a normal nonmask type. */ | |
1273 | |
1274 static inline bool | |
1275 vect_use_mask_type_p (stmt_vec_info stmt_info) | |
1276 { | |
1277 return stmt_info->mask_precision && stmt_info->mask_precision != ~0U; | |
1278 } | |
1279 | |
1280 /* Return TRUE if a statement represented by STMT_INFO is a part of a | |
1281 pattern. */ | |
1282 | |
1283 static inline bool | |
1284 is_pattern_stmt_p (stmt_vec_info stmt_info) | |
1285 { | |
1286 return stmt_info->pattern_stmt_p; | |
1287 } | |
1288 | |
1289 /* If STMT_INFO is a pattern statement, return the statement that it | |
1290 replaces, otherwise return STMT_INFO itself. */ | |
1291 | |
1292 inline stmt_vec_info | |
1293 vect_orig_stmt (stmt_vec_info stmt_info) | |
1294 { | |
1295 if (is_pattern_stmt_p (stmt_info)) | |
1296 return STMT_VINFO_RELATED_STMT (stmt_info); | |
1297 return stmt_info; | |
1298 } | |
1299 | |
1300 /* Return the later statement between STMT1_INFO and STMT2_INFO. */ | |
1089 | 1301 |
1090 static inline stmt_vec_info | 1302 static inline stmt_vec_info |
1091 get_earlier_stmt (stmt_vec_info stmt1_info, stmt_vec_info stmt2_info) | 1303 get_later_stmt (stmt_vec_info stmt1_info, stmt_vec_info stmt2_info) |
1092 { | 1304 { |
1093 gcc_checking_assert ((STMT_VINFO_IN_PATTERN_P (stmt1_info) | 1305 if (gimple_uid (vect_orig_stmt (stmt1_info)->stmt) |
1094 || !STMT_VINFO_RELATED_STMT (stmt1_info)) | 1306 > gimple_uid (vect_orig_stmt (stmt2_info)->stmt)) |
1095 && (STMT_VINFO_IN_PATTERN_P (stmt2_info) | |
1096 || !STMT_VINFO_RELATED_STMT (stmt2_info))); | |
1097 | |
1098 if (gimple_uid (stmt1_info->stmt) < gimple_uid (stmt2_info->stmt)) | |
1099 return stmt1_info; | 1307 return stmt1_info; |
1100 else | 1308 else |
1101 return stmt2_info; | 1309 return stmt2_info; |
1102 } | |
1103 | |
1104 /* Return the later statement between STMT1_INFO and STMT2_INFO. */ | |
1105 | |
1106 static inline stmt_vec_info | |
1107 get_later_stmt (stmt_vec_info stmt1_info, stmt_vec_info stmt2_info) | |
1108 { | |
1109 gcc_checking_assert ((STMT_VINFO_IN_PATTERN_P (stmt1_info) | |
1110 || !STMT_VINFO_RELATED_STMT (stmt1_info)) | |
1111 && (STMT_VINFO_IN_PATTERN_P (stmt2_info) | |
1112 || !STMT_VINFO_RELATED_STMT (stmt2_info))); | |
1113 | |
1114 if (gimple_uid (stmt1_info->stmt) > gimple_uid (stmt2_info->stmt)) | |
1115 return stmt1_info; | |
1116 else | |
1117 return stmt2_info; | |
1118 } | |
1119 | |
1120 /* Return TRUE if a statement represented by STMT_INFO is a part of a | |
1121 pattern. */ | |
1122 | |
1123 static inline bool | |
1124 is_pattern_stmt_p (stmt_vec_info stmt_info) | |
1125 { | |
1126 return stmt_info->pattern_stmt_p; | |
1127 } | |
1128 | |
1129 /* If STMT_INFO is a pattern statement, return the statement that it | |
1130 replaces, otherwise return STMT_INFO itself. */ | |
1131 | |
1132 inline stmt_vec_info | |
1133 vect_orig_stmt (stmt_vec_info stmt_info) | |
1134 { | |
1135 if (is_pattern_stmt_p (stmt_info)) | |
1136 return STMT_VINFO_RELATED_STMT (stmt_info); | |
1137 return stmt_info; | |
1138 } | 1310 } |
1139 | 1311 |
1140 /* If STMT_INFO has been replaced by a pattern statement, return the | 1312 /* If STMT_INFO has been replaced by a pattern statement, return the |
1141 replacement statement, otherwise return STMT_INFO itself. */ | 1313 replacement statement, otherwise return STMT_INFO itself. */ |
1142 | 1314 |
1191 } | 1363 } |
1192 | 1364 |
1193 /* Alias targetm.vectorize.init_cost. */ | 1365 /* Alias targetm.vectorize.init_cost. */ |
1194 | 1366 |
1195 static inline void * | 1367 static inline void * |
1196 init_cost (struct loop *loop_info) | 1368 init_cost (class loop *loop_info) |
1197 { | 1369 { |
1198 return targetm.vectorize.init_cost (loop_info); | 1370 return targetm.vectorize.init_cost (loop_info); |
1199 } | 1371 } |
1200 | 1372 |
1201 extern void dump_stmt_cost (FILE *, void *, int, enum vect_cost_for_stmt, | 1373 extern void dump_stmt_cost (FILE *, void *, int, enum vect_cost_for_stmt, |
1297 vect_known_alignment_in_bytes (dr_vec_info *dr_info) | 1469 vect_known_alignment_in_bytes (dr_vec_info *dr_info) |
1298 { | 1470 { |
1299 if (DR_MISALIGNMENT (dr_info) == DR_MISALIGNMENT_UNKNOWN) | 1471 if (DR_MISALIGNMENT (dr_info) == DR_MISALIGNMENT_UNKNOWN) |
1300 return TYPE_ALIGN_UNIT (TREE_TYPE (DR_REF (dr_info->dr))); | 1472 return TYPE_ALIGN_UNIT (TREE_TYPE (DR_REF (dr_info->dr))); |
1301 if (DR_MISALIGNMENT (dr_info) == 0) | 1473 if (DR_MISALIGNMENT (dr_info) == 0) |
1302 return DR_TARGET_ALIGNMENT (dr_info); | 1474 return known_alignment (DR_TARGET_ALIGNMENT (dr_info)); |
1303 return DR_MISALIGNMENT (dr_info) & -DR_MISALIGNMENT (dr_info); | 1475 return DR_MISALIGNMENT (dr_info) & -DR_MISALIGNMENT (dr_info); |
1304 } | 1476 } |
1305 | 1477 |
1306 /* Return the behavior of DR_INFO with respect to the vectorization context | 1478 /* Return the behavior of DR_INFO with respect to the vectorization context |
1307 (which for outer loop vectorization might not be the behavior recorded | 1479 (which for outer loop vectorization might not be the behavior recorded |
1317 return &DR_INNERMOST (dr_info->dr); | 1489 return &DR_INNERMOST (dr_info->dr); |
1318 else | 1490 else |
1319 return &STMT_VINFO_DR_WRT_VEC_LOOP (stmt_info); | 1491 return &STMT_VINFO_DR_WRT_VEC_LOOP (stmt_info); |
1320 } | 1492 } |
1321 | 1493 |
1494 /* Return the offset calculated by adding the offset of this DR_INFO to the | |
1495 corresponding data_reference's offset. If CHECK_OUTER then use | |
1496 vect_dr_behavior to select the appropriate data_reference to use. */ | |
1497 | |
1498 inline tree | |
1499 get_dr_vinfo_offset (dr_vec_info *dr_info, bool check_outer = false) | |
1500 { | |
1501 innermost_loop_behavior *base; | |
1502 if (check_outer) | |
1503 base = vect_dr_behavior (dr_info); | |
1504 else | |
1505 base = &dr_info->dr->innermost; | |
1506 | |
1507 tree offset = base->offset; | |
1508 | |
1509 if (!dr_info->offset) | |
1510 return offset; | |
1511 | |
1512 offset = fold_convert (sizetype, offset); | |
1513 return fold_build2 (PLUS_EXPR, TREE_TYPE (dr_info->offset), offset, | |
1514 dr_info->offset); | |
1515 } | |
1516 | |
1517 | |
1322 /* Return true if the vect cost model is unlimited. */ | 1518 /* Return true if the vect cost model is unlimited. */ |
1323 static inline bool | 1519 static inline bool |
1324 unlimited_cost_model (loop_p loop) | 1520 unlimited_cost_model (loop_p loop) |
1325 { | 1521 { |
1326 if (loop != NULL && loop->force_vectorize | 1522 if (loop != NULL && loop->force_vectorize |
1360 { | 1556 { |
1361 return vect_get_num_vectors (LOOP_VINFO_VECT_FACTOR (loop_vinfo), vectype); | 1557 return vect_get_num_vectors (LOOP_VINFO_VECT_FACTOR (loop_vinfo), vectype); |
1362 } | 1558 } |
1363 | 1559 |
1364 /* Update maximum unit count *MAX_NUNITS so that it accounts for | 1560 /* Update maximum unit count *MAX_NUNITS so that it accounts for |
1561 NUNITS. *MAX_NUNITS can be 1 if we haven't yet recorded anything. */ | |
1562 | |
1563 static inline void | |
1564 vect_update_max_nunits (poly_uint64 *max_nunits, poly_uint64 nunits) | |
1565 { | |
1566 /* All unit counts have the form vec_info::vector_size * X for some | |
1567 rational X, so two unit sizes must have a common multiple. | |
1568 Everything is a multiple of the initial value of 1. */ | |
1569 *max_nunits = force_common_multiple (*max_nunits, nunits); | |
1570 } | |
1571 | |
1572 /* Update maximum unit count *MAX_NUNITS so that it accounts for | |
1365 the number of units in vector type VECTYPE. *MAX_NUNITS can be 1 | 1573 the number of units in vector type VECTYPE. *MAX_NUNITS can be 1 |
1366 if we haven't yet recorded any vector types. */ | 1574 if we haven't yet recorded any vector types. */ |
1367 | 1575 |
1368 static inline void | 1576 static inline void |
1369 vect_update_max_nunits (poly_uint64 *max_nunits, tree vectype) | 1577 vect_update_max_nunits (poly_uint64 *max_nunits, tree vectype) |
1370 { | 1578 { |
1371 /* All unit counts have the form current_vector_size * X for some | 1579 vect_update_max_nunits (max_nunits, TYPE_VECTOR_SUBPARTS (vectype)); |
1372 rational X, so two unit sizes must have a common multiple. | |
1373 Everything is a multiple of the initial value of 1. */ | |
1374 poly_uint64 nunits = TYPE_VECTOR_SUBPARTS (vectype); | |
1375 *max_nunits = force_common_multiple (*max_nunits, nunits); | |
1376 } | 1580 } |
1377 | 1581 |
1378 /* Return the vectorization factor that should be used for costing | 1582 /* Return the vectorization factor that should be used for costing |
1379 purposes while vectorizing the loop described by LOOP_VINFO. | 1583 purposes while vectorizing the loop described by LOOP_VINFO. |
1380 Pick a reasonable estimate if the vectorization factor isn't | 1584 Pick a reasonable estimate if the vectorization factor isn't |
1416 | 1620 |
1417 inline unsigned int | 1621 inline unsigned int |
1418 vect_get_scalar_dr_size (dr_vec_info *dr_info) | 1622 vect_get_scalar_dr_size (dr_vec_info *dr_info) |
1419 { | 1623 { |
1420 return tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (dr_info->dr)))); | 1624 return tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (dr_info->dr)))); |
1625 } | |
1626 | |
1627 /* Return true if LOOP_VINFO requires a runtime check for whether the | |
1628 vector loop is profitable. */ | |
1629 | |
1630 inline bool | |
1631 vect_apply_runtime_profitability_check_p (loop_vec_info loop_vinfo) | |
1632 { | |
1633 unsigned int th = LOOP_VINFO_COST_MODEL_THRESHOLD (loop_vinfo); | |
1634 return (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo) | |
1635 && th >= vect_vf_for_cost (loop_vinfo)); | |
1421 } | 1636 } |
1422 | 1637 |
1423 /* Source location + hotness information. */ | 1638 /* Source location + hotness information. */ |
1424 extern dump_user_location_t vect_location; | 1639 extern dump_user_location_t vect_location; |
1425 | 1640 |
1436 in a nested scope implicitly default to MSG_PRIORITY_INTERNALS. */ | 1651 in a nested scope implicitly default to MSG_PRIORITY_INTERNALS. */ |
1437 | 1652 |
1438 #define DUMP_VECT_SCOPE(MSG) \ | 1653 #define DUMP_VECT_SCOPE(MSG) \ |
1439 AUTO_DUMP_SCOPE (MSG, vect_location) | 1654 AUTO_DUMP_SCOPE (MSG, vect_location) |
1440 | 1655 |
1656 /* A sentinel class for ensuring that the "vect_location" global gets | |
1657 reset at the end of a scope. | |
1658 | |
1659 The "vect_location" global is used during dumping and contains a | |
1660 location_t, which could contain references to a tree block via the | |
1661 ad-hoc data. This data is used for tracking inlining information, | |
1662 but it's not a GC root; it's simply assumed that such locations never | |
1663 get accessed if the blocks are optimized away. | |
1664 | |
1665 Hence we need to ensure that such locations are purged at the end | |
1666 of any operations using them (e.g. via this class). */ | |
1667 | |
1668 class auto_purge_vect_location | |
1669 { | |
1670 public: | |
1671 ~auto_purge_vect_location (); | |
1672 }; | |
1673 | |
1441 /*-----------------------------------------------------------------*/ | 1674 /*-----------------------------------------------------------------*/ |
1442 /* Function prototypes. */ | 1675 /* Function prototypes. */ |
1443 /*-----------------------------------------------------------------*/ | 1676 /*-----------------------------------------------------------------*/ |
1444 | 1677 |
1445 /* Simple loop peeling and versioning utilities for vectorizer's purposes - | 1678 /* Simple loop peeling and versioning utilities for vectorizer's purposes - |
1446 in tree-vect-loop-manip.c. */ | 1679 in tree-vect-loop-manip.c. */ |
1447 extern void vect_set_loop_condition (struct loop *, loop_vec_info, | 1680 extern void vect_set_loop_condition (class loop *, loop_vec_info, |
1448 tree, tree, tree, bool); | 1681 tree, tree, tree, bool); |
1449 extern bool slpeel_can_duplicate_loop_p (const struct loop *, const_edge); | 1682 extern bool slpeel_can_duplicate_loop_p (const class loop *, const_edge); |
1450 struct loop *slpeel_tree_duplicate_loop_to_edge_cfg (struct loop *, | 1683 class loop *slpeel_tree_duplicate_loop_to_edge_cfg (class loop *, |
1451 struct loop *, edge); | 1684 class loop *, edge); |
1452 extern void vect_loop_versioning (loop_vec_info, unsigned int, bool, | 1685 class loop *vect_loop_versioning (loop_vec_info, gimple *); |
1453 poly_uint64); | 1686 extern class loop *vect_do_peeling (loop_vec_info, tree, tree, |
1454 extern struct loop *vect_do_peeling (loop_vec_info, tree, tree, | 1687 tree *, tree *, tree *, int, bool, bool, |
1455 tree *, tree *, tree *, int, bool, bool); | 1688 tree *); |
1456 extern void vect_prepare_for_masked_peels (loop_vec_info); | 1689 extern void vect_prepare_for_masked_peels (loop_vec_info); |
1457 extern dump_user_location_t find_loop_location (struct loop *); | 1690 extern dump_user_location_t find_loop_location (class loop *); |
1458 extern bool vect_can_advance_ivs_p (loop_vec_info); | 1691 extern bool vect_can_advance_ivs_p (loop_vec_info); |
1692 extern void vect_update_inits_of_drs (loop_vec_info, tree, tree_code); | |
1459 | 1693 |
1460 /* In tree-vect-stmts.c. */ | 1694 /* In tree-vect-stmts.c. */ |
1461 extern poly_uint64 current_vector_size; | 1695 extern tree get_related_vectype_for_scalar_type (machine_mode, tree, |
1462 extern tree get_vectype_for_scalar_type (tree); | 1696 poly_uint64 = 0); |
1463 extern tree get_vectype_for_scalar_type_and_size (tree, poly_uint64); | 1697 extern tree get_vectype_for_scalar_type (vec_info *, tree, unsigned int = 0); |
1464 extern tree get_mask_type_for_scalar_type (tree); | 1698 extern tree get_vectype_for_scalar_type (vec_info *, tree, slp_tree); |
1699 extern tree get_mask_type_for_scalar_type (vec_info *, tree, unsigned int = 0); | |
1465 extern tree get_same_sized_vectype (tree, tree); | 1700 extern tree get_same_sized_vectype (tree, tree); |
1701 extern bool vect_chooses_same_modes_p (vec_info *, machine_mode); | |
1466 extern bool vect_get_loop_mask_type (loop_vec_info); | 1702 extern bool vect_get_loop_mask_type (loop_vec_info); |
1467 extern bool vect_is_simple_use (tree, vec_info *, enum vect_def_type *, | 1703 extern bool vect_is_simple_use (tree, vec_info *, enum vect_def_type *, |
1468 stmt_vec_info * = NULL, gimple ** = NULL); | 1704 stmt_vec_info * = NULL, gimple ** = NULL); |
1469 extern bool vect_is_simple_use (tree, vec_info *, enum vect_def_type *, | 1705 extern bool vect_is_simple_use (tree, vec_info *, enum vect_def_type *, |
1470 tree *, stmt_vec_info * = NULL, | 1706 tree *, stmt_vec_info * = NULL, |
1472 extern bool supportable_widening_operation (enum tree_code, stmt_vec_info, | 1708 extern bool supportable_widening_operation (enum tree_code, stmt_vec_info, |
1473 tree, tree, enum tree_code *, | 1709 tree, tree, enum tree_code *, |
1474 enum tree_code *, int *, | 1710 enum tree_code *, int *, |
1475 vec<tree> *); | 1711 vec<tree> *); |
1476 extern bool supportable_narrowing_operation (enum tree_code, tree, tree, | 1712 extern bool supportable_narrowing_operation (enum tree_code, tree, tree, |
1477 enum tree_code *, | 1713 enum tree_code *, int *, |
1478 int *, vec<tree> *); | 1714 vec<tree> *); |
1479 extern unsigned record_stmt_cost (stmt_vector_for_cost *, int, | 1715 extern unsigned record_stmt_cost (stmt_vector_for_cost *, int, |
1480 enum vect_cost_for_stmt, stmt_vec_info, | 1716 enum vect_cost_for_stmt, stmt_vec_info, |
1481 int, enum vect_cost_model_location); | 1717 int, enum vect_cost_model_location); |
1482 extern stmt_vec_info vect_finish_replace_stmt (stmt_vec_info, gimple *); | 1718 extern stmt_vec_info vect_finish_replace_stmt (stmt_vec_info, gimple *); |
1483 extern stmt_vec_info vect_finish_stmt_generation (stmt_vec_info, gimple *, | 1719 extern stmt_vec_info vect_finish_stmt_generation (stmt_vec_info, gimple *, |
1484 gimple_stmt_iterator *); | 1720 gimple_stmt_iterator *); |
1485 extern opt_result vect_mark_stmts_to_be_vectorized (loop_vec_info); | 1721 extern opt_result vect_mark_stmts_to_be_vectorized (loop_vec_info, bool *); |
1486 extern tree vect_get_store_rhs (stmt_vec_info); | 1722 extern tree vect_get_store_rhs (stmt_vec_info); |
1487 extern tree vect_get_vec_def_for_operand_1 (stmt_vec_info, enum vect_def_type); | 1723 extern tree vect_get_vec_def_for_operand_1 (stmt_vec_info, enum vect_def_type); |
1488 extern tree vect_get_vec_def_for_operand (tree, stmt_vec_info, tree = NULL); | 1724 extern tree vect_get_vec_def_for_operand (tree, stmt_vec_info, tree = NULL); |
1489 extern void vect_get_vec_defs (tree, tree, stmt_vec_info, vec<tree> *, | 1725 extern void vect_get_vec_defs (tree, tree, stmt_vec_info, vec<tree> *, |
1490 vec<tree> *, slp_tree); | 1726 vec<tree> *, slp_tree); |
1494 gimple_stmt_iterator *); | 1730 gimple_stmt_iterator *); |
1495 extern tree vect_get_vec_def_for_stmt_copy (vec_info *, tree); | 1731 extern tree vect_get_vec_def_for_stmt_copy (vec_info *, tree); |
1496 extern bool vect_transform_stmt (stmt_vec_info, gimple_stmt_iterator *, | 1732 extern bool vect_transform_stmt (stmt_vec_info, gimple_stmt_iterator *, |
1497 slp_tree, slp_instance); | 1733 slp_tree, slp_instance); |
1498 extern void vect_remove_stores (stmt_vec_info); | 1734 extern void vect_remove_stores (stmt_vec_info); |
1735 extern bool vect_nop_conversion_p (stmt_vec_info); | |
1499 extern opt_result vect_analyze_stmt (stmt_vec_info, bool *, slp_tree, | 1736 extern opt_result vect_analyze_stmt (stmt_vec_info, bool *, slp_tree, |
1500 slp_instance, stmt_vector_for_cost *); | 1737 slp_instance, stmt_vector_for_cost *); |
1501 extern bool vectorizable_condition (stmt_vec_info, gimple_stmt_iterator *, | |
1502 stmt_vec_info *, tree, int, slp_tree, | |
1503 stmt_vector_for_cost *); | |
1504 extern void vect_get_load_cost (stmt_vec_info, int, bool, | 1738 extern void vect_get_load_cost (stmt_vec_info, int, bool, |
1505 unsigned int *, unsigned int *, | 1739 unsigned int *, unsigned int *, |
1506 stmt_vector_for_cost *, | 1740 stmt_vector_for_cost *, |
1507 stmt_vector_for_cost *, bool); | 1741 stmt_vector_for_cost *, bool); |
1508 extern void vect_get_store_cost (stmt_vec_info, int, | 1742 extern void vect_get_store_cost (stmt_vec_info, int, |
1509 unsigned int *, stmt_vector_for_cost *); | 1743 unsigned int *, stmt_vector_for_cost *); |
1510 extern bool vect_supportable_shift (enum tree_code, tree); | 1744 extern bool vect_supportable_shift (vec_info *, enum tree_code, tree); |
1511 extern tree vect_gen_perm_mask_any (tree, const vec_perm_indices &); | 1745 extern tree vect_gen_perm_mask_any (tree, const vec_perm_indices &); |
1512 extern tree vect_gen_perm_mask_checked (tree, const vec_perm_indices &); | 1746 extern tree vect_gen_perm_mask_checked (tree, const vec_perm_indices &); |
1513 extern void optimize_mask_stores (struct loop*); | 1747 extern void optimize_mask_stores (class loop*); |
1514 extern gcall *vect_gen_while (tree, tree, tree); | 1748 extern gcall *vect_gen_while (tree, tree, tree); |
1515 extern tree vect_gen_while_not (gimple_seq *, tree, tree, tree); | 1749 extern tree vect_gen_while_not (gimple_seq *, tree, tree, tree); |
1516 extern opt_result vect_get_vector_types_for_stmt (stmt_vec_info, tree *, | 1750 extern opt_result vect_get_vector_types_for_stmt (stmt_vec_info, tree *, |
1517 tree *); | 1751 tree *, unsigned int = 0); |
1518 extern opt_tree vect_get_mask_type_for_stmt (stmt_vec_info); | 1752 extern opt_tree vect_get_mask_type_for_stmt (stmt_vec_info, unsigned int = 0); |
1519 | 1753 |
1520 /* In tree-vect-data-refs.c. */ | 1754 /* In tree-vect-data-refs.c. */ |
1521 extern bool vect_can_force_dr_alignment_p (const_tree, unsigned int); | 1755 extern bool vect_can_force_dr_alignment_p (const_tree, poly_uint64); |
1522 extern enum dr_alignment_support vect_supportable_dr_alignment | 1756 extern enum dr_alignment_support vect_supportable_dr_alignment |
1523 (dr_vec_info *, bool); | 1757 (dr_vec_info *, bool); |
1524 extern tree vect_get_smallest_scalar_type (stmt_vec_info, HOST_WIDE_INT *, | 1758 extern tree vect_get_smallest_scalar_type (stmt_vec_info, HOST_WIDE_INT *, |
1525 HOST_WIDE_INT *); | 1759 HOST_WIDE_INT *); |
1526 extern opt_result vect_analyze_data_ref_dependences (loop_vec_info, unsigned int *); | 1760 extern opt_result vect_analyze_data_ref_dependences (loop_vec_info, unsigned int *); |
1529 extern opt_result vect_analyze_data_refs_alignment (loop_vec_info); | 1763 extern opt_result vect_analyze_data_refs_alignment (loop_vec_info); |
1530 extern opt_result vect_verify_datarefs_alignment (loop_vec_info); | 1764 extern opt_result vect_verify_datarefs_alignment (loop_vec_info); |
1531 extern bool vect_slp_analyze_and_verify_instance_alignment (slp_instance); | 1765 extern bool vect_slp_analyze_and_verify_instance_alignment (slp_instance); |
1532 extern opt_result vect_analyze_data_ref_accesses (vec_info *); | 1766 extern opt_result vect_analyze_data_ref_accesses (vec_info *); |
1533 extern opt_result vect_prune_runtime_alias_test_list (loop_vec_info); | 1767 extern opt_result vect_prune_runtime_alias_test_list (loop_vec_info); |
1534 extern bool vect_gather_scatter_fn_p (bool, bool, tree, tree, unsigned int, | 1768 extern bool vect_gather_scatter_fn_p (vec_info *, bool, bool, tree, tree, |
1535 signop, int, internal_fn *, tree *); | 1769 tree, int, internal_fn *, tree *); |
1536 extern bool vect_check_gather_scatter (stmt_vec_info, loop_vec_info, | 1770 extern bool vect_check_gather_scatter (stmt_vec_info, loop_vec_info, |
1537 gather_scatter_info *); | 1771 gather_scatter_info *); |
1538 extern opt_result vect_find_stmt_data_reference (loop_p, gimple *, | 1772 extern opt_result vect_find_stmt_data_reference (loop_p, gimple *, |
1539 vec<data_reference_p> *); | 1773 vec<data_reference_p> *); |
1540 extern opt_result vect_analyze_data_refs (vec_info *, poly_uint64 *); | 1774 extern opt_result vect_analyze_data_refs (vec_info *, poly_uint64 *, bool *); |
1541 extern void vect_record_base_alignments (vec_info *); | 1775 extern void vect_record_base_alignments (vec_info *); |
1542 extern tree vect_create_data_ref_ptr (stmt_vec_info, tree, struct loop *, tree, | 1776 extern tree vect_create_data_ref_ptr (stmt_vec_info, tree, class loop *, tree, |
1543 tree *, gimple_stmt_iterator *, | 1777 tree *, gimple_stmt_iterator *, |
1544 gimple **, bool, | 1778 gimple **, bool, |
1545 tree = NULL_TREE, tree = NULL_TREE); | 1779 tree = NULL_TREE, tree = NULL_TREE); |
1546 extern tree bump_vector_ptr (tree, gimple *, gimple_stmt_iterator *, | 1780 extern tree bump_vector_ptr (tree, gimple *, gimple_stmt_iterator *, |
1547 stmt_vec_info, tree); | 1781 stmt_vec_info, tree); |
1553 extern bool vect_load_lanes_supported (tree, unsigned HOST_WIDE_INT, bool); | 1787 extern bool vect_load_lanes_supported (tree, unsigned HOST_WIDE_INT, bool); |
1554 extern void vect_permute_store_chain (vec<tree> ,unsigned int, stmt_vec_info, | 1788 extern void vect_permute_store_chain (vec<tree> ,unsigned int, stmt_vec_info, |
1555 gimple_stmt_iterator *, vec<tree> *); | 1789 gimple_stmt_iterator *, vec<tree> *); |
1556 extern tree vect_setup_realignment (stmt_vec_info, gimple_stmt_iterator *, | 1790 extern tree vect_setup_realignment (stmt_vec_info, gimple_stmt_iterator *, |
1557 tree *, enum dr_alignment_support, tree, | 1791 tree *, enum dr_alignment_support, tree, |
1558 struct loop **); | 1792 class loop **); |
1559 extern void vect_transform_grouped_load (stmt_vec_info, vec<tree> , int, | 1793 extern void vect_transform_grouped_load (stmt_vec_info, vec<tree> , int, |
1560 gimple_stmt_iterator *); | 1794 gimple_stmt_iterator *); |
1561 extern void vect_record_grouped_load_vectors (stmt_vec_info, vec<tree>); | 1795 extern void vect_record_grouped_load_vectors (stmt_vec_info, vec<tree>); |
1562 extern tree vect_get_new_vect_var (tree, enum vect_var_kind, const char *); | 1796 extern tree vect_get_new_vect_var (tree, enum vect_var_kind, const char *); |
1563 extern tree vect_get_new_ssa_name (tree, enum vect_var_kind, | 1797 extern tree vect_get_new_ssa_name (tree, enum vect_var_kind, |
1564 const char * = NULL); | 1798 const char * = NULL); |
1565 extern tree vect_create_addr_base_for_vector_ref (stmt_vec_info, gimple_seq *, | 1799 extern tree vect_create_addr_base_for_vector_ref (stmt_vec_info, gimple_seq *, |
1566 tree, tree = NULL_TREE); | 1800 tree, tree = NULL_TREE); |
1567 | 1801 |
1568 /* In tree-vect-loop.c. */ | 1802 /* In tree-vect-loop.c. */ |
1569 /* FORNOW: Used in tree-parloops.c. */ | 1803 extern widest_int vect_iv_limit_for_full_masking (loop_vec_info loop_vinfo); |
1570 extern stmt_vec_info vect_force_simple_reduction (loop_vec_info, stmt_vec_info, | 1804 /* Used in tree-vect-loop-manip.c */ |
1571 bool *, bool); | 1805 extern void determine_peel_for_niter (loop_vec_info); |
1572 /* Used in gimple-loop-interchange.c. */ | 1806 /* Used in gimple-loop-interchange.c and tree-parloops.c. */ |
1573 extern bool check_reduction_path (dump_user_location_t, loop_p, gphi *, tree, | 1807 extern bool check_reduction_path (dump_user_location_t, loop_p, gphi *, tree, |
1574 enum tree_code); | 1808 enum tree_code); |
1809 extern bool needs_fold_left_reduction_p (tree, tree_code); | |
1575 /* Drive for loop analysis stage. */ | 1810 /* Drive for loop analysis stage. */ |
1576 extern opt_loop_vec_info vect_analyze_loop (struct loop *, | 1811 extern opt_loop_vec_info vect_analyze_loop (class loop *, vec_info_shared *); |
1577 loop_vec_info, | |
1578 vec_info_shared *); | |
1579 extern tree vect_build_loop_niters (loop_vec_info, bool * = NULL); | 1812 extern tree vect_build_loop_niters (loop_vec_info, bool * = NULL); |
1580 extern void vect_gen_vector_loop_niters (loop_vec_info, tree, tree *, | 1813 extern void vect_gen_vector_loop_niters (loop_vec_info, tree, tree *, |
1581 tree *, bool); | 1814 tree *, bool); |
1582 extern tree vect_halve_mask_nunits (tree); | 1815 extern tree vect_halve_mask_nunits (tree, machine_mode); |
1583 extern tree vect_double_mask_nunits (tree); | 1816 extern tree vect_double_mask_nunits (tree, machine_mode); |
1584 extern void vect_record_loop_mask (loop_vec_info, vec_loop_masks *, | 1817 extern void vect_record_loop_mask (loop_vec_info, vec_loop_masks *, |
1585 unsigned int, tree); | 1818 unsigned int, tree, tree); |
1586 extern tree vect_get_loop_mask (gimple_stmt_iterator *, vec_loop_masks *, | 1819 extern tree vect_get_loop_mask (gimple_stmt_iterator *, vec_loop_masks *, |
1587 unsigned int, tree, unsigned int); | 1820 unsigned int, tree, unsigned int); |
1821 extern stmt_vec_info info_for_reduction (stmt_vec_info); | |
1588 | 1822 |
1589 /* Drive for loop transformation stage. */ | 1823 /* Drive for loop transformation stage. */ |
1590 extern struct loop *vect_transform_loop (loop_vec_info); | 1824 extern class loop *vect_transform_loop (loop_vec_info, gimple *); |
1591 extern opt_loop_vec_info vect_analyze_loop_form (struct loop *, | 1825 extern opt_loop_vec_info vect_analyze_loop_form (class loop *, |
1592 vec_info_shared *); | 1826 vec_info_shared *); |
1593 extern bool vectorizable_live_operation (stmt_vec_info, gimple_stmt_iterator *, | 1827 extern bool vectorizable_live_operation (stmt_vec_info, gimple_stmt_iterator *, |
1594 slp_tree, int, stmt_vec_info *, | 1828 slp_tree, slp_instance, int, |
1595 stmt_vector_for_cost *); | 1829 bool, stmt_vector_for_cost *); |
1596 extern bool vectorizable_reduction (stmt_vec_info, gimple_stmt_iterator *, | 1830 extern bool vectorizable_reduction (stmt_vec_info, slp_tree, slp_instance, |
1597 stmt_vec_info *, slp_tree, slp_instance, | |
1598 stmt_vector_for_cost *); | 1831 stmt_vector_for_cost *); |
1599 extern bool vectorizable_induction (stmt_vec_info, gimple_stmt_iterator *, | 1832 extern bool vectorizable_induction (stmt_vec_info, gimple_stmt_iterator *, |
1600 stmt_vec_info *, slp_tree, | 1833 stmt_vec_info *, slp_tree, |
1601 stmt_vector_for_cost *); | 1834 stmt_vector_for_cost *); |
1602 extern tree get_initial_def_for_reduction (stmt_vec_info, tree, tree *); | 1835 extern bool vect_transform_reduction (stmt_vec_info, gimple_stmt_iterator *, |
1836 stmt_vec_info *, slp_tree); | |
1837 extern bool vect_transform_cycle_phi (stmt_vec_info, stmt_vec_info *, | |
1838 slp_tree, slp_instance); | |
1839 extern bool vectorizable_lc_phi (stmt_vec_info, stmt_vec_info *, slp_tree); | |
1603 extern bool vect_worthwhile_without_simd_p (vec_info *, tree_code); | 1840 extern bool vect_worthwhile_without_simd_p (vec_info *, tree_code); |
1604 extern int vect_get_known_peeling_cost (loop_vec_info, int, int *, | 1841 extern int vect_get_known_peeling_cost (loop_vec_info, int, int *, |
1605 stmt_vector_for_cost *, | 1842 stmt_vector_for_cost *, |
1606 stmt_vector_for_cost *, | 1843 stmt_vector_for_cost *, |
1607 stmt_vector_for_cost *); | 1844 stmt_vector_for_cost *); |
1615 extern bool vect_slp_analyze_operations (vec_info *); | 1852 extern bool vect_slp_analyze_operations (vec_info *); |
1616 extern void vect_schedule_slp (vec_info *); | 1853 extern void vect_schedule_slp (vec_info *); |
1617 extern opt_result vect_analyze_slp (vec_info *, unsigned); | 1854 extern opt_result vect_analyze_slp (vec_info *, unsigned); |
1618 extern bool vect_make_slp_decision (loop_vec_info); | 1855 extern bool vect_make_slp_decision (loop_vec_info); |
1619 extern void vect_detect_hybrid_slp (loop_vec_info); | 1856 extern void vect_detect_hybrid_slp (loop_vec_info); |
1620 extern void vect_get_slp_defs (vec<tree> , slp_tree, vec<vec<tree> > *); | 1857 extern void vect_get_slp_defs (slp_tree, vec<vec<tree> > *, unsigned n = -1U); |
1621 extern bool vect_slp_bb (basic_block); | 1858 extern bool vect_slp_bb (basic_block); |
1622 extern stmt_vec_info vect_find_last_scalar_stmt_in_slp (slp_tree); | 1859 extern stmt_vec_info vect_find_last_scalar_stmt_in_slp (slp_tree); |
1623 extern bool is_simple_and_all_uses_invariant (stmt_vec_info, loop_vec_info); | 1860 extern bool is_simple_and_all_uses_invariant (stmt_vec_info, loop_vec_info); |
1624 extern bool can_duplicate_and_interleave_p (unsigned int, machine_mode, | 1861 extern bool can_duplicate_and_interleave_p (vec_info *, unsigned int, tree, |
1625 unsigned int * = NULL, | 1862 unsigned int * = NULL, |
1626 tree * = NULL, tree * = NULL); | 1863 tree * = NULL, tree * = NULL); |
1627 extern void duplicate_and_interleave (gimple_seq *, tree, vec<tree>, | 1864 extern void duplicate_and_interleave (vec_info *, gimple_seq *, tree, |
1628 unsigned int, vec<tree> &); | 1865 vec<tree>, unsigned int, vec<tree> &); |
1629 extern int vect_get_place_in_interleaving_chain (stmt_vec_info, stmt_vec_info); | 1866 extern int vect_get_place_in_interleaving_chain (stmt_vec_info, stmt_vec_info); |
1630 | 1867 |
1631 /* In tree-vect-patterns.c. */ | 1868 /* In tree-vect-patterns.c. */ |
1632 /* Pattern recognition functions. | 1869 /* Pattern recognition functions. |
1633 Additional pattern recognition functions can (and will) be added | 1870 Additional pattern recognition functions can (and will) be added |
1634 in the future. */ | 1871 in the future. */ |
1635 void vect_pattern_recog (vec_info *); | 1872 void vect_pattern_recog (vec_info *); |
1636 | 1873 |
1637 /* In tree-vectorizer.c. */ | 1874 /* In tree-vectorizer.c. */ |
1638 unsigned vectorize_loops (void); | 1875 unsigned vectorize_loops (void); |
1639 void vect_free_loop_info_assumptions (struct loop *); | 1876 void vect_free_loop_info_assumptions (class loop *); |
1877 gimple *vect_loop_vectorized_call (class loop *, gcond **cond = NULL); | |
1878 | |
1640 | 1879 |
1641 #endif /* GCC_TREE_VECTORIZER_H */ | 1880 #endif /* GCC_TREE_VECTORIZER_H */ |