]>
Commit | Line | Data |
---|---|---|
79fe1b3b | 1 | /* Loop Vectorization |
17385e0d | 2 | Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. |
79fe1b3b DN |
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 2, 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 COPYING. If not, write to the Free | |
19 | Software Foundation, 59 Temple Place - Suite 330, Boston, MA | |
20 | 02111-1307, USA. */ | |
21 | ||
22 | #ifndef GCC_TREE_VECTORIZER_H | |
23 | #define GCC_TREE_VECTORIZER_H | |
24 | ||
7353a8c1 LB |
25 | #ifdef USE_MAPPED_LOCATION |
26 | typedef source_location LOC; | |
27 | #define UNKNOWN_LOC UNKNOWN_LOCATION | |
28 | #define EXPR_LOC(e) EXPR_LOCATION(e) | |
29 | #define LOC_FILE(l) LOCATION_FILE (l) | |
30 | #define LOC_LINE(l) LOCATION_LINE (l) | |
31 | #else | |
32 | typedef source_locus LOC; | |
33 | #define UNKNOWN_LOC NULL | |
34 | #define EXPR_LOC(e) EXPR_LOCUS(e) | |
35 | #define LOC_FILE(l) (l)->file | |
36 | #define LOC_LINE(l) (l)->line | |
37 | #endif | |
38 | ||
79fe1b3b DN |
39 | /* Used for naming of new temporaries. */ |
40 | enum vect_var_kind { | |
41 | vect_simple_var, | |
42 | vect_pointer_var | |
43 | }; | |
44 | ||
8c27b7d4 | 45 | /* Defines type of operation: unary or binary. */ |
79fe1b3b DN |
46 | enum operation_type { |
47 | unary_op = 1, | |
48 | binary_op | |
49 | }; | |
50 | ||
0dc0a70b DN |
51 | /* Define type of available alignment support. */ |
52 | enum dr_alignment_support { | |
53 | dr_unaligned_unsupported, | |
54 | dr_unaligned_supported, | |
55 | dr_unaligned_software_pipeline, | |
56 | dr_aligned | |
57 | }; | |
58 | ||
c866976a LB |
59 | /* Define verbosity levels. */ |
60 | enum verbosity_levels { | |
61 | REPORT_NONE, | |
62 | REPORT_VECTORIZED_LOOPS, | |
63 | REPORT_UNVECTORIZED_LOOPS, | |
64 | REPORT_ALIGNMENT, | |
65 | REPORT_BAD_FORM_LOOPS, | |
66 | REPORT_OUTER_LOOPS, | |
67 | REPORT_DETAILS, | |
68 | /* New verbosity levels should be added before this one. */ | |
69 | MAX_VERBOSITY_LEVEL | |
70 | }; | |
71 | ||
ef302293 LB |
72 | /*-----------------------------------------------------------------*/ |
73 | /* Info on vectorized loops. */ | |
74 | /*-----------------------------------------------------------------*/ | |
75 | typedef struct _loop_vec_info { | |
76 | ||
77 | /* The loop to which this info struct refers to. */ | |
78 | struct loop *loop; | |
79 | ||
80 | /* The loop basic blocks. */ | |
81 | basic_block *bbs; | |
82 | ||
83 | /* The loop exit_condition. */ | |
84 | tree exit_cond; | |
85 | ||
86 | /* Number of iterations. */ | |
87 | tree num_iters; | |
88 | ||
89 | /* Is the loop vectorizable? */ | |
90 | bool vectorizable; | |
91 | ||
92 | /* Unrolling factor */ | |
93 | int vectorization_factor; | |
94 | ||
95 | /* Unknown DRs according to which loop was peeled. */ | |
96 | struct data_reference *unaligned_dr; | |
97 | ||
5f55a1ba DN |
98 | /* peeling_for_alignment indicates whether peeling for alignment will take |
99 | place, and what the peeling factor should be: | |
100 | peeling_for_alignment = X means: | |
101 | If X=0: Peeling for alignment will not be applied. | |
102 | If X>0: Peel first X iterations. | |
103 | If X=-1: Generate a runtime test to calculate the number of iterations | |
104 | to be peeled, using the dataref recorded in the field | |
105 | unaligned_dr. */ | |
106 | int peeling_for_alignment; | |
ef302293 LB |
107 | |
108 | /* All data references in the loop that are being written to. */ | |
109 | varray_type data_ref_writes; | |
110 | ||
111 | /* All data references in the loop that are being read from. */ | |
112 | varray_type data_ref_reads; | |
113 | ||
7353a8c1 LB |
114 | /* The loop location in the source. */ |
115 | LOC loop_line_number; | |
ef302293 LB |
116 | } *loop_vec_info; |
117 | ||
118 | /* Access Functions. */ | |
119 | #define LOOP_VINFO_LOOP(L) (L)->loop | |
120 | #define LOOP_VINFO_BBS(L) (L)->bbs | |
121 | #define LOOP_VINFO_EXIT_COND(L) (L)->exit_cond | |
122 | #define LOOP_VINFO_NITERS(L) (L)->num_iters | |
123 | #define LOOP_VINFO_VECTORIZABLE_P(L) (L)->vectorizable | |
124 | #define LOOP_VINFO_VECT_FACTOR(L) (L)->vectorization_factor | |
125 | #define LOOP_VINFO_DATAREF_WRITES(L) (L)->data_ref_writes | |
126 | #define LOOP_VINFO_DATAREF_READS(L) (L)->data_ref_reads | |
127 | #define LOOP_VINFO_INT_NITERS(L) (TREE_INT_CST_LOW ((L)->num_iters)) | |
5f55a1ba | 128 | #define LOOP_PEELING_FOR_ALIGNMENT(L) (L)->peeling_for_alignment |
ef302293 | 129 | #define LOOP_VINFO_UNALIGNED_DR(L) (L)->unaligned_dr |
7353a8c1 LB |
130 | #define LOOP_VINFO_LOC(L) (L)->loop_line_number |
131 | ||
132 | #define LOOP_LOC(L) LOOP_VINFO_LOC(L) | |
ef302293 LB |
133 | |
134 | ||
135 | #define LOOP_VINFO_NITERS_KNOWN_P(L) \ | |
136 | (host_integerp ((L)->num_iters,0) \ | |
137 | && TREE_INT_CST_LOW ((L)->num_iters) > 0) | |
138 | ||
79fe1b3b DN |
139 | /*-----------------------------------------------------------------*/ |
140 | /* Info on vectorized defs. */ | |
141 | /*-----------------------------------------------------------------*/ | |
142 | enum stmt_vec_info_type { | |
143 | undef_vec_info_type = 0, | |
144 | load_vec_info_type, | |
145 | store_vec_info_type, | |
146 | op_vec_info_type, | |
147 | assignment_vec_info_type | |
148 | }; | |
149 | ||
150 | typedef struct _stmt_vec_info { | |
151 | ||
152 | enum stmt_vec_info_type type; | |
153 | ||
154 | /* The stmt to which this info struct refers to. */ | |
155 | tree stmt; | |
156 | ||
ef302293 LB |
157 | /* The loop_vec_info with respect to which STMT is vectorized. */ |
158 | loop_vec_info loop_vinfo; | |
79fe1b3b DN |
159 | |
160 | /* Not all stmts in the loop need to be vectorized. e.g, the incrementation | |
161 | of the loop induction variable and computation of array indexes. relevant | |
162 | indicates whether the stmt needs to be vectorized. */ | |
163 | bool relevant; | |
164 | ||
165 | /* The vector type to be used. */ | |
166 | tree vectype; | |
167 | ||
168 | /* The vectorized version of the stmt. */ | |
169 | tree vectorized_stmt; | |
170 | ||
171 | ||
172 | /** The following is relevant only for stmts that contain a non-scalar | |
173 | data-ref (array/pointer/struct access). A GIMPLE stmt is expected to have | |
174 | at most one such data-ref. **/ | |
175 | ||
176 | /* Information about the data-ref (access function, etc). */ | |
177 | struct data_reference *data_ref_info; | |
178 | ||
179 | /* Aliasing information. */ | |
180 | tree memtag; | |
8bb46326 | 181 | struct ptr_info_def *ptr_info; |
c75ab022 | 182 | subvar_t subvars; |
6775f1f3 | 183 | |
1de6a873 | 184 | /** The following fields are used to store the information about |
a5ae3ad6 IR |
185 | data-reference. {base_address + initial_offset} is the first location |
186 | accessed by data-ref in the loop, and step is the stride of data-ref in | |
187 | the loop in bytes; | |
1de6a873 IR |
188 | e.g.: |
189 | ||
190 | Example 1 Example 2 | |
191 | data-ref a[j].b[i][j] a + 4B (a is int*) | |
a5ae3ad6 IR |
192 | |
193 | base_address &a a | |
1de6a873 IR |
194 | initial_offset j_0*D_j + i_0*D_i + C 4 |
195 | step D_j 4 | |
196 | ||
a5ae3ad6 IR |
197 | data-reference structure info: |
198 | base_name a NULL | |
199 | access_fn <access_fns of indexes of b> (0, +, 1) | |
200 | ||
1de6a873 | 201 | **/ |
a5ae3ad6 IR |
202 | /* The above base_address, offset and step. */ |
203 | tree base_address; | |
1de6a873 IR |
204 | tree initial_offset; |
205 | tree step; | |
206 | ||
207 | /* Alignment information. Whether the base of the data-reference is aligned | |
208 | to vectype. */ | |
209 | bool base_aligned_p; | |
210 | /* Alignment information. The offset of the data-reference from its base | |
211 | in bytes. */ | |
212 | tree misalignment; | |
79fe1b3b DN |
213 | } *stmt_vec_info; |
214 | ||
215 | /* Access Functions. */ | |
1de6a873 IR |
216 | #define STMT_VINFO_TYPE(S) (S)->type |
217 | #define STMT_VINFO_STMT(S) (S)->stmt | |
ef302293 | 218 | #define STMT_VINFO_LOOP_VINFO(S) (S)->loop_vinfo |
1de6a873 IR |
219 | #define STMT_VINFO_RELEVANT_P(S) (S)->relevant |
220 | #define STMT_VINFO_VECTYPE(S) (S)->vectype | |
221 | #define STMT_VINFO_VEC_STMT(S) (S)->vectorized_stmt | |
222 | #define STMT_VINFO_DATA_REF(S) (S)->data_ref_info | |
223 | #define STMT_VINFO_MEMTAG(S) (S)->memtag | |
8bb46326 DN |
224 | #define STMT_VINFO_PTR_INFO(S) (S)->ptr_info |
225 | #define STMT_VINFO_SUBVARS(S) (S)->subvars | |
a5ae3ad6 | 226 | #define STMT_VINFO_VECT_DR_BASE_ADDRESS(S)(S)->base_address |
1de6a873 IR |
227 | #define STMT_VINFO_VECT_INIT_OFFSET(S) (S)->initial_offset |
228 | #define STMT_VINFO_VECT_STEP(S) (S)->step | |
229 | #define STMT_VINFO_VECT_BASE_ALIGNED_P(S) (S)->base_aligned_p | |
230 | #define STMT_VINFO_VECT_MISALIGNMENT(S) (S)->misalignment | |
79fe1b3b DN |
231 | |
232 | static inline void set_stmt_info (stmt_ann_t ann, stmt_vec_info stmt_info); | |
233 | static inline stmt_vec_info vinfo_for_stmt (tree stmt); | |
234 | ||
235 | static inline void | |
236 | set_stmt_info (stmt_ann_t ann, stmt_vec_info stmt_info) | |
237 | { | |
238 | if (ann) | |
239 | ann->common.aux = (char *) stmt_info; | |
240 | } | |
241 | ||
242 | static inline stmt_vec_info | |
243 | vinfo_for_stmt (tree stmt) | |
244 | { | |
245 | stmt_ann_t ann = stmt_ann (stmt); | |
246 | return ann ? (stmt_vec_info) ann->common.aux : NULL; | |
247 | } | |
248 | ||
249 | /*-----------------------------------------------------------------*/ | |
250 | /* Info on data references alignment. */ | |
251 | /*-----------------------------------------------------------------*/ | |
252 | ||
5f55a1ba DN |
253 | /* Reflects actual alignment of first access in the vectorized loop, |
254 | taking into account peeling/versioning if applied. */ | |
79fe1b3b DN |
255 | #define DR_MISALIGNMENT(DR) (DR)->aux |
256 | ||
257 | static inline bool | |
258 | aligned_access_p (struct data_reference *data_ref_info) | |
259 | { | |
260 | return (DR_MISALIGNMENT (data_ref_info) == 0); | |
261 | } | |
262 | ||
263 | static inline bool | |
5f55a1ba | 264 | known_alignment_for_access_p (struct data_reference *data_ref_info) |
79fe1b3b | 265 | { |
5f55a1ba | 266 | return (DR_MISALIGNMENT (data_ref_info) != -1); |
79fe1b3b DN |
267 | } |
268 | ||
6775f1f3 IR |
269 | /* Perform signed modulo, always returning a non-negative value. */ |
270 | #define VECT_SMODULO(x,y) ((x) % (y) < 0 ? ((x) % (y) + (y)) : (x) % (y)) | |
271 | ||
f7064d11 DN |
272 | /* vect_dump will be set to stderr or dump_file if exist. */ |
273 | extern FILE *vect_dump; | |
274 | extern enum verbosity_levels vect_verbosity_level; | |
79fe1b3b | 275 | |
79fe1b3b DN |
276 | /*-----------------------------------------------------------------*/ |
277 | /* Function prototypes. */ | |
278 | /*-----------------------------------------------------------------*/ | |
279 | ||
f7064d11 DN |
280 | /************************************************************************* |
281 | Simple Loop Peeling Utilities - in tree-vectorizer.c | |
282 | *************************************************************************/ | |
283 | /* Entry point for peeling of simple loops. | |
284 | Peel the first/last iterations of a loop. | |
285 | It can be used outside of the vectorizer for loops that are simple enough | |
286 | (see function documentation). In the vectorizer it is used to peel the | |
287 | last few iterations when the loop bound is unknown or does not evenly | |
288 | divide by the vectorization factor, and to peel the first few iterations | |
289 | to force the alignment of data references in the loop. */ | |
290 | extern struct loop *slpeel_tree_peel_loop_to_edge | |
291 | (struct loop *, struct loops *, edge, tree, tree, bool); | |
292 | extern void slpeel_make_loop_iterate_ntimes (struct loop *, tree); | |
293 | extern bool slpeel_can_duplicate_loop_p (struct loop *, edge); | |
294 | #ifdef ENABLE_CHECKING | |
295 | extern void slpeel_verify_cfg_after_peeling (struct loop *, struct loop *); | |
296 | #endif | |
297 | ||
79fe1b3b | 298 | |
f7064d11 DN |
299 | /************************************************************************* |
300 | General Vectorization Utilities | |
301 | *************************************************************************/ | |
302 | /** In tree-vectorizer.c **/ | |
303 | extern tree vect_strip_conversion (tree); | |
304 | extern tree get_vectype_for_scalar_type (tree); | |
305 | extern bool vect_is_simple_use (tree , loop_vec_info, tree *); | |
306 | extern bool vect_is_simple_iv_evolution (unsigned, tree, tree *, tree *); | |
307 | extern bool vect_can_force_dr_alignment_p (tree, unsigned int); | |
308 | extern enum dr_alignment_support vect_supportable_dr_alignment | |
309 | (struct data_reference *); | |
310 | /* Creation and deletion of loop and stmt info structs. */ | |
79fe1b3b DN |
311 | extern loop_vec_info new_loop_vec_info (struct loop *loop); |
312 | extern void destroy_loop_vec_info (loop_vec_info); | |
ef302293 | 313 | extern stmt_vec_info new_stmt_vec_info (tree stmt, loop_vec_info); |
f7064d11 DN |
314 | /* Main driver. */ |
315 | extern void vectorize_loops (struct loops *); | |
316 | ||
317 | /** In tree-vect-analyze.c **/ | |
318 | /* Driver for analysis stage. */ | |
319 | extern loop_vec_info vect_analyze_loop (struct loop *); | |
320 | ||
321 | /** In tree-vect-transform.c **/ | |
322 | extern bool vectorizable_load (tree, block_stmt_iterator *, tree *); | |
323 | extern bool vectorizable_store (tree, block_stmt_iterator *, tree *); | |
324 | extern bool vectorizable_operation (tree, block_stmt_iterator *, tree *); | |
325 | extern bool vectorizable_assignment (tree, block_stmt_iterator *, tree *); | |
326 | /* Driver for transformation stage. */ | |
327 | extern void vect_transform_loop (loop_vec_info, struct loops *); | |
328 | ||
329 | /************************************************************************* | |
330 | Vectorization Debug Information - in tree-vectorizer.c | |
331 | *************************************************************************/ | |
332 | extern bool vect_print_dump_info (enum verbosity_levels, LOC); | |
333 | extern void vect_set_verbosity_level (const char *); | |
334 | extern LOC find_loop_location (struct loop *); | |
79fe1b3b DN |
335 | |
336 | #endif /* GCC_TREE_VECTORIZER_H */ |