annotate gcc/omp-general.c @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 /* General types and functions that are uselful for processing of OpenMP,
kono
parents:
diff changeset
2 OpenACC and similar directivers at various stages of compilation.
kono
parents:
diff changeset
3
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
4 Copyright (C) 2005-2018 Free Software Foundation, Inc.
111
kono
parents:
diff changeset
5
kono
parents:
diff changeset
6 This file is part of GCC.
kono
parents:
diff changeset
7
kono
parents:
diff changeset
8 GCC is free software; you can redistribute it and/or modify it under
kono
parents:
diff changeset
9 the terms of the GNU General Public License as published by the Free
kono
parents:
diff changeset
10 Software Foundation; either version 3, or (at your option) any later
kono
parents:
diff changeset
11 version.
kono
parents:
diff changeset
12
kono
parents:
diff changeset
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
kono
parents:
diff changeset
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
kono
parents:
diff changeset
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
kono
parents:
diff changeset
16 for more details.
kono
parents:
diff changeset
17
kono
parents:
diff changeset
18 You should have received a copy of the GNU General Public License
kono
parents:
diff changeset
19 along with GCC; see the file COPYING3. If not see
kono
parents:
diff changeset
20 <http://www.gnu.org/licenses/>. */
kono
parents:
diff changeset
21
kono
parents:
diff changeset
22 /* Find an OMP clause of type KIND within CLAUSES. */
kono
parents:
diff changeset
23
kono
parents:
diff changeset
24 #include "config.h"
kono
parents:
diff changeset
25 #include "system.h"
kono
parents:
diff changeset
26 #include "coretypes.h"
kono
parents:
diff changeset
27 #include "backend.h"
kono
parents:
diff changeset
28 #include "target.h"
kono
parents:
diff changeset
29 #include "tree.h"
kono
parents:
diff changeset
30 #include "gimple.h"
kono
parents:
diff changeset
31 #include "ssa.h"
kono
parents:
diff changeset
32 #include "diagnostic-core.h"
kono
parents:
diff changeset
33 #include "fold-const.h"
kono
parents:
diff changeset
34 #include "langhooks.h"
kono
parents:
diff changeset
35 #include "omp-general.h"
kono
parents:
diff changeset
36 #include "stringpool.h"
kono
parents:
diff changeset
37 #include "attribs.h"
kono
parents:
diff changeset
38
kono
parents:
diff changeset
39 tree
kono
parents:
diff changeset
40 omp_find_clause (tree clauses, enum omp_clause_code kind)
kono
parents:
diff changeset
41 {
kono
parents:
diff changeset
42 for (; clauses ; clauses = OMP_CLAUSE_CHAIN (clauses))
kono
parents:
diff changeset
43 if (OMP_CLAUSE_CODE (clauses) == kind)
kono
parents:
diff changeset
44 return clauses;
kono
parents:
diff changeset
45
kono
parents:
diff changeset
46 return NULL_TREE;
kono
parents:
diff changeset
47 }
kono
parents:
diff changeset
48
kono
parents:
diff changeset
49 /* Return true if DECL is a reference type. */
kono
parents:
diff changeset
50
kono
parents:
diff changeset
51 bool
kono
parents:
diff changeset
52 omp_is_reference (tree decl)
kono
parents:
diff changeset
53 {
kono
parents:
diff changeset
54 return lang_hooks.decls.omp_privatize_by_reference (decl);
kono
parents:
diff changeset
55 }
kono
parents:
diff changeset
56
kono
parents:
diff changeset
57 /* Adjust *COND_CODE and *N2 so that the former is either LT_EXPR or
kono
parents:
diff changeset
58 GT_EXPR. */
kono
parents:
diff changeset
59
kono
parents:
diff changeset
60 void
kono
parents:
diff changeset
61 omp_adjust_for_condition (location_t loc, enum tree_code *cond_code, tree *n2)
kono
parents:
diff changeset
62 {
kono
parents:
diff changeset
63 switch (*cond_code)
kono
parents:
diff changeset
64 {
kono
parents:
diff changeset
65 case LT_EXPR:
kono
parents:
diff changeset
66 case GT_EXPR:
kono
parents:
diff changeset
67 case NE_EXPR:
kono
parents:
diff changeset
68 break;
kono
parents:
diff changeset
69 case LE_EXPR:
kono
parents:
diff changeset
70 if (POINTER_TYPE_P (TREE_TYPE (*n2)))
kono
parents:
diff changeset
71 *n2 = fold_build_pointer_plus_hwi_loc (loc, *n2, 1);
kono
parents:
diff changeset
72 else
kono
parents:
diff changeset
73 *n2 = fold_build2_loc (loc, PLUS_EXPR, TREE_TYPE (*n2), *n2,
kono
parents:
diff changeset
74 build_int_cst (TREE_TYPE (*n2), 1));
kono
parents:
diff changeset
75 *cond_code = LT_EXPR;
kono
parents:
diff changeset
76 break;
kono
parents:
diff changeset
77 case GE_EXPR:
kono
parents:
diff changeset
78 if (POINTER_TYPE_P (TREE_TYPE (*n2)))
kono
parents:
diff changeset
79 *n2 = fold_build_pointer_plus_hwi_loc (loc, *n2, -1);
kono
parents:
diff changeset
80 else
kono
parents:
diff changeset
81 *n2 = fold_build2_loc (loc, MINUS_EXPR, TREE_TYPE (*n2), *n2,
kono
parents:
diff changeset
82 build_int_cst (TREE_TYPE (*n2), 1));
kono
parents:
diff changeset
83 *cond_code = GT_EXPR;
kono
parents:
diff changeset
84 break;
kono
parents:
diff changeset
85 default:
kono
parents:
diff changeset
86 gcc_unreachable ();
kono
parents:
diff changeset
87 }
kono
parents:
diff changeset
88 }
kono
parents:
diff changeset
89
kono
parents:
diff changeset
90 /* Return the looping step from INCR, extracted from the step of a gimple omp
kono
parents:
diff changeset
91 for statement. */
kono
parents:
diff changeset
92
kono
parents:
diff changeset
93 tree
kono
parents:
diff changeset
94 omp_get_for_step_from_incr (location_t loc, tree incr)
kono
parents:
diff changeset
95 {
kono
parents:
diff changeset
96 tree step;
kono
parents:
diff changeset
97 switch (TREE_CODE (incr))
kono
parents:
diff changeset
98 {
kono
parents:
diff changeset
99 case PLUS_EXPR:
kono
parents:
diff changeset
100 step = TREE_OPERAND (incr, 1);
kono
parents:
diff changeset
101 break;
kono
parents:
diff changeset
102 case POINTER_PLUS_EXPR:
kono
parents:
diff changeset
103 step = fold_convert (ssizetype, TREE_OPERAND (incr, 1));
kono
parents:
diff changeset
104 break;
kono
parents:
diff changeset
105 case MINUS_EXPR:
kono
parents:
diff changeset
106 step = TREE_OPERAND (incr, 1);
kono
parents:
diff changeset
107 step = fold_build1_loc (loc, NEGATE_EXPR, TREE_TYPE (step), step);
kono
parents:
diff changeset
108 break;
kono
parents:
diff changeset
109 default:
kono
parents:
diff changeset
110 gcc_unreachable ();
kono
parents:
diff changeset
111 }
kono
parents:
diff changeset
112 return step;
kono
parents:
diff changeset
113 }
kono
parents:
diff changeset
114
kono
parents:
diff changeset
115 /* Extract the header elements of parallel loop FOR_STMT and store
kono
parents:
diff changeset
116 them into *FD. */
kono
parents:
diff changeset
117
kono
parents:
diff changeset
118 void
kono
parents:
diff changeset
119 omp_extract_for_data (gomp_for *for_stmt, struct omp_for_data *fd,
kono
parents:
diff changeset
120 struct omp_for_data_loop *loops)
kono
parents:
diff changeset
121 {
kono
parents:
diff changeset
122 tree t, var, *collapse_iter, *collapse_count;
kono
parents:
diff changeset
123 tree count = NULL_TREE, iter_type = long_integer_type_node;
kono
parents:
diff changeset
124 struct omp_for_data_loop *loop;
kono
parents:
diff changeset
125 int i;
kono
parents:
diff changeset
126 struct omp_for_data_loop dummy_loop;
kono
parents:
diff changeset
127 location_t loc = gimple_location (for_stmt);
kono
parents:
diff changeset
128 bool simd = gimple_omp_for_kind (for_stmt) & GF_OMP_FOR_SIMD;
kono
parents:
diff changeset
129 bool distribute = gimple_omp_for_kind (for_stmt)
kono
parents:
diff changeset
130 == GF_OMP_FOR_KIND_DISTRIBUTE;
kono
parents:
diff changeset
131 bool taskloop = gimple_omp_for_kind (for_stmt)
kono
parents:
diff changeset
132 == GF_OMP_FOR_KIND_TASKLOOP;
kono
parents:
diff changeset
133 tree iterv, countv;
kono
parents:
diff changeset
134
kono
parents:
diff changeset
135 fd->for_stmt = for_stmt;
kono
parents:
diff changeset
136 fd->pre = NULL;
kono
parents:
diff changeset
137 fd->have_nowait = distribute || simd;
kono
parents:
diff changeset
138 fd->have_ordered = false;
kono
parents:
diff changeset
139 fd->tiling = NULL_TREE;
kono
parents:
diff changeset
140 fd->collapse = 1;
kono
parents:
diff changeset
141 fd->ordered = 0;
kono
parents:
diff changeset
142 fd->sched_kind = OMP_CLAUSE_SCHEDULE_STATIC;
kono
parents:
diff changeset
143 fd->sched_modifiers = 0;
kono
parents:
diff changeset
144 fd->chunk_size = NULL_TREE;
kono
parents:
diff changeset
145 fd->simd_schedule = false;
kono
parents:
diff changeset
146 collapse_iter = NULL;
kono
parents:
diff changeset
147 collapse_count = NULL;
kono
parents:
diff changeset
148
kono
parents:
diff changeset
149 for (t = gimple_omp_for_clauses (for_stmt); t ; t = OMP_CLAUSE_CHAIN (t))
kono
parents:
diff changeset
150 switch (OMP_CLAUSE_CODE (t))
kono
parents:
diff changeset
151 {
kono
parents:
diff changeset
152 case OMP_CLAUSE_NOWAIT:
kono
parents:
diff changeset
153 fd->have_nowait = true;
kono
parents:
diff changeset
154 break;
kono
parents:
diff changeset
155 case OMP_CLAUSE_ORDERED:
kono
parents:
diff changeset
156 fd->have_ordered = true;
kono
parents:
diff changeset
157 if (OMP_CLAUSE_ORDERED_EXPR (t))
kono
parents:
diff changeset
158 fd->ordered = tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (t));
kono
parents:
diff changeset
159 break;
kono
parents:
diff changeset
160 case OMP_CLAUSE_SCHEDULE:
kono
parents:
diff changeset
161 gcc_assert (!distribute && !taskloop);
kono
parents:
diff changeset
162 fd->sched_kind
kono
parents:
diff changeset
163 = (enum omp_clause_schedule_kind)
kono
parents:
diff changeset
164 (OMP_CLAUSE_SCHEDULE_KIND (t) & OMP_CLAUSE_SCHEDULE_MASK);
kono
parents:
diff changeset
165 fd->sched_modifiers = (OMP_CLAUSE_SCHEDULE_KIND (t)
kono
parents:
diff changeset
166 & ~OMP_CLAUSE_SCHEDULE_MASK);
kono
parents:
diff changeset
167 fd->chunk_size = OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (t);
kono
parents:
diff changeset
168 fd->simd_schedule = OMP_CLAUSE_SCHEDULE_SIMD (t);
kono
parents:
diff changeset
169 break;
kono
parents:
diff changeset
170 case OMP_CLAUSE_DIST_SCHEDULE:
kono
parents:
diff changeset
171 gcc_assert (distribute);
kono
parents:
diff changeset
172 fd->chunk_size = OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (t);
kono
parents:
diff changeset
173 break;
kono
parents:
diff changeset
174 case OMP_CLAUSE_COLLAPSE:
kono
parents:
diff changeset
175 fd->collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (t));
kono
parents:
diff changeset
176 if (fd->collapse > 1)
kono
parents:
diff changeset
177 {
kono
parents:
diff changeset
178 collapse_iter = &OMP_CLAUSE_COLLAPSE_ITERVAR (t);
kono
parents:
diff changeset
179 collapse_count = &OMP_CLAUSE_COLLAPSE_COUNT (t);
kono
parents:
diff changeset
180 }
kono
parents:
diff changeset
181 break;
kono
parents:
diff changeset
182 case OMP_CLAUSE_TILE:
kono
parents:
diff changeset
183 fd->tiling = OMP_CLAUSE_TILE_LIST (t);
kono
parents:
diff changeset
184 fd->collapse = list_length (fd->tiling);
kono
parents:
diff changeset
185 gcc_assert (fd->collapse);
kono
parents:
diff changeset
186 collapse_iter = &OMP_CLAUSE_TILE_ITERVAR (t);
kono
parents:
diff changeset
187 collapse_count = &OMP_CLAUSE_TILE_COUNT (t);
kono
parents:
diff changeset
188 break;
kono
parents:
diff changeset
189 default:
kono
parents:
diff changeset
190 break;
kono
parents:
diff changeset
191 }
kono
parents:
diff changeset
192
kono
parents:
diff changeset
193 if (fd->collapse > 1 || fd->tiling)
kono
parents:
diff changeset
194 fd->loops = loops;
kono
parents:
diff changeset
195 else
kono
parents:
diff changeset
196 fd->loops = &fd->loop;
kono
parents:
diff changeset
197
kono
parents:
diff changeset
198 if (fd->ordered && fd->collapse == 1 && loops != NULL)
kono
parents:
diff changeset
199 {
kono
parents:
diff changeset
200 fd->loops = loops;
kono
parents:
diff changeset
201 iterv = NULL_TREE;
kono
parents:
diff changeset
202 countv = NULL_TREE;
kono
parents:
diff changeset
203 collapse_iter = &iterv;
kono
parents:
diff changeset
204 collapse_count = &countv;
kono
parents:
diff changeset
205 }
kono
parents:
diff changeset
206
kono
parents:
diff changeset
207 /* FIXME: for now map schedule(auto) to schedule(static).
kono
parents:
diff changeset
208 There should be analysis to determine whether all iterations
kono
parents:
diff changeset
209 are approximately the same amount of work (then schedule(static)
kono
parents:
diff changeset
210 is best) or if it varies (then schedule(dynamic,N) is better). */
kono
parents:
diff changeset
211 if (fd->sched_kind == OMP_CLAUSE_SCHEDULE_AUTO)
kono
parents:
diff changeset
212 {
kono
parents:
diff changeset
213 fd->sched_kind = OMP_CLAUSE_SCHEDULE_STATIC;
kono
parents:
diff changeset
214 gcc_assert (fd->chunk_size == NULL);
kono
parents:
diff changeset
215 }
kono
parents:
diff changeset
216 gcc_assert ((fd->collapse == 1 && !fd->tiling) || collapse_iter != NULL);
kono
parents:
diff changeset
217 if (taskloop)
kono
parents:
diff changeset
218 fd->sched_kind = OMP_CLAUSE_SCHEDULE_RUNTIME;
kono
parents:
diff changeset
219 if (fd->sched_kind == OMP_CLAUSE_SCHEDULE_RUNTIME)
kono
parents:
diff changeset
220 gcc_assert (fd->chunk_size == NULL);
kono
parents:
diff changeset
221 else if (fd->chunk_size == NULL)
kono
parents:
diff changeset
222 {
kono
parents:
diff changeset
223 /* We only need to compute a default chunk size for ordered
kono
parents:
diff changeset
224 static loops and dynamic loops. */
kono
parents:
diff changeset
225 if (fd->sched_kind != OMP_CLAUSE_SCHEDULE_STATIC
kono
parents:
diff changeset
226 || fd->have_ordered)
kono
parents:
diff changeset
227 fd->chunk_size = (fd->sched_kind == OMP_CLAUSE_SCHEDULE_STATIC)
kono
parents:
diff changeset
228 ? integer_zero_node : integer_one_node;
kono
parents:
diff changeset
229 }
kono
parents:
diff changeset
230
kono
parents:
diff changeset
231 int cnt = fd->ordered ? fd->ordered : fd->collapse;
kono
parents:
diff changeset
232 for (i = 0; i < cnt; i++)
kono
parents:
diff changeset
233 {
kono
parents:
diff changeset
234 if (i == 0
kono
parents:
diff changeset
235 && fd->collapse == 1
kono
parents:
diff changeset
236 && !fd->tiling
kono
parents:
diff changeset
237 && (fd->ordered == 0 || loops == NULL))
kono
parents:
diff changeset
238 loop = &fd->loop;
kono
parents:
diff changeset
239 else if (loops != NULL)
kono
parents:
diff changeset
240 loop = loops + i;
kono
parents:
diff changeset
241 else
kono
parents:
diff changeset
242 loop = &dummy_loop;
kono
parents:
diff changeset
243
kono
parents:
diff changeset
244 loop->v = gimple_omp_for_index (for_stmt, i);
kono
parents:
diff changeset
245 gcc_assert (SSA_VAR_P (loop->v));
kono
parents:
diff changeset
246 gcc_assert (TREE_CODE (TREE_TYPE (loop->v)) == INTEGER_TYPE
kono
parents:
diff changeset
247 || TREE_CODE (TREE_TYPE (loop->v)) == POINTER_TYPE);
kono
parents:
diff changeset
248 var = TREE_CODE (loop->v) == SSA_NAME ? SSA_NAME_VAR (loop->v) : loop->v;
kono
parents:
diff changeset
249 loop->n1 = gimple_omp_for_initial (for_stmt, i);
kono
parents:
diff changeset
250
kono
parents:
diff changeset
251 loop->cond_code = gimple_omp_for_cond (for_stmt, i);
kono
parents:
diff changeset
252 loop->n2 = gimple_omp_for_final (for_stmt, i);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
253 gcc_assert (loop->cond_code != NE_EXPR);
111
kono
parents:
diff changeset
254 omp_adjust_for_condition (loc, &loop->cond_code, &loop->n2);
kono
parents:
diff changeset
255
kono
parents:
diff changeset
256 t = gimple_omp_for_incr (for_stmt, i);
kono
parents:
diff changeset
257 gcc_assert (TREE_OPERAND (t, 0) == var);
kono
parents:
diff changeset
258 loop->step = omp_get_for_step_from_incr (loc, t);
kono
parents:
diff changeset
259
kono
parents:
diff changeset
260 if (simd
kono
parents:
diff changeset
261 || (fd->sched_kind == OMP_CLAUSE_SCHEDULE_STATIC
kono
parents:
diff changeset
262 && !fd->have_ordered))
kono
parents:
diff changeset
263 {
kono
parents:
diff changeset
264 if (fd->collapse == 1 && !fd->tiling)
kono
parents:
diff changeset
265 iter_type = TREE_TYPE (loop->v);
kono
parents:
diff changeset
266 else if (i == 0
kono
parents:
diff changeset
267 || TYPE_PRECISION (iter_type)
kono
parents:
diff changeset
268 < TYPE_PRECISION (TREE_TYPE (loop->v)))
kono
parents:
diff changeset
269 iter_type
kono
parents:
diff changeset
270 = build_nonstandard_integer_type
kono
parents:
diff changeset
271 (TYPE_PRECISION (TREE_TYPE (loop->v)), 1);
kono
parents:
diff changeset
272 }
kono
parents:
diff changeset
273 else if (iter_type != long_long_unsigned_type_node)
kono
parents:
diff changeset
274 {
kono
parents:
diff changeset
275 if (POINTER_TYPE_P (TREE_TYPE (loop->v)))
kono
parents:
diff changeset
276 iter_type = long_long_unsigned_type_node;
kono
parents:
diff changeset
277 else if (TYPE_UNSIGNED (TREE_TYPE (loop->v))
kono
parents:
diff changeset
278 && TYPE_PRECISION (TREE_TYPE (loop->v))
kono
parents:
diff changeset
279 >= TYPE_PRECISION (iter_type))
kono
parents:
diff changeset
280 {
kono
parents:
diff changeset
281 tree n;
kono
parents:
diff changeset
282
kono
parents:
diff changeset
283 if (loop->cond_code == LT_EXPR)
kono
parents:
diff changeset
284 n = fold_build2_loc (loc,
kono
parents:
diff changeset
285 PLUS_EXPR, TREE_TYPE (loop->v),
kono
parents:
diff changeset
286 loop->n2, loop->step);
kono
parents:
diff changeset
287 else
kono
parents:
diff changeset
288 n = loop->n1;
kono
parents:
diff changeset
289 if (TREE_CODE (n) != INTEGER_CST
kono
parents:
diff changeset
290 || tree_int_cst_lt (TYPE_MAX_VALUE (iter_type), n))
kono
parents:
diff changeset
291 iter_type = long_long_unsigned_type_node;
kono
parents:
diff changeset
292 }
kono
parents:
diff changeset
293 else if (TYPE_PRECISION (TREE_TYPE (loop->v))
kono
parents:
diff changeset
294 > TYPE_PRECISION (iter_type))
kono
parents:
diff changeset
295 {
kono
parents:
diff changeset
296 tree n1, n2;
kono
parents:
diff changeset
297
kono
parents:
diff changeset
298 if (loop->cond_code == LT_EXPR)
kono
parents:
diff changeset
299 {
kono
parents:
diff changeset
300 n1 = loop->n1;
kono
parents:
diff changeset
301 n2 = fold_build2_loc (loc,
kono
parents:
diff changeset
302 PLUS_EXPR, TREE_TYPE (loop->v),
kono
parents:
diff changeset
303 loop->n2, loop->step);
kono
parents:
diff changeset
304 }
kono
parents:
diff changeset
305 else
kono
parents:
diff changeset
306 {
kono
parents:
diff changeset
307 n1 = fold_build2_loc (loc,
kono
parents:
diff changeset
308 MINUS_EXPR, TREE_TYPE (loop->v),
kono
parents:
diff changeset
309 loop->n2, loop->step);
kono
parents:
diff changeset
310 n2 = loop->n1;
kono
parents:
diff changeset
311 }
kono
parents:
diff changeset
312 if (TREE_CODE (n1) != INTEGER_CST
kono
parents:
diff changeset
313 || TREE_CODE (n2) != INTEGER_CST
kono
parents:
diff changeset
314 || !tree_int_cst_lt (TYPE_MIN_VALUE (iter_type), n1)
kono
parents:
diff changeset
315 || !tree_int_cst_lt (n2, TYPE_MAX_VALUE (iter_type)))
kono
parents:
diff changeset
316 iter_type = long_long_unsigned_type_node;
kono
parents:
diff changeset
317 }
kono
parents:
diff changeset
318 }
kono
parents:
diff changeset
319
kono
parents:
diff changeset
320 if (i >= fd->collapse)
kono
parents:
diff changeset
321 continue;
kono
parents:
diff changeset
322
kono
parents:
diff changeset
323 if (collapse_count && *collapse_count == NULL)
kono
parents:
diff changeset
324 {
kono
parents:
diff changeset
325 t = fold_binary (loop->cond_code, boolean_type_node,
kono
parents:
diff changeset
326 fold_convert (TREE_TYPE (loop->v), loop->n1),
kono
parents:
diff changeset
327 fold_convert (TREE_TYPE (loop->v), loop->n2));
kono
parents:
diff changeset
328 if (t && integer_zerop (t))
kono
parents:
diff changeset
329 count = build_zero_cst (long_long_unsigned_type_node);
kono
parents:
diff changeset
330 else if ((i == 0 || count != NULL_TREE)
kono
parents:
diff changeset
331 && TREE_CODE (TREE_TYPE (loop->v)) == INTEGER_TYPE
kono
parents:
diff changeset
332 && TREE_CONSTANT (loop->n1)
kono
parents:
diff changeset
333 && TREE_CONSTANT (loop->n2)
kono
parents:
diff changeset
334 && TREE_CODE (loop->step) == INTEGER_CST)
kono
parents:
diff changeset
335 {
kono
parents:
diff changeset
336 tree itype = TREE_TYPE (loop->v);
kono
parents:
diff changeset
337
kono
parents:
diff changeset
338 if (POINTER_TYPE_P (itype))
kono
parents:
diff changeset
339 itype = signed_type_for (itype);
kono
parents:
diff changeset
340 t = build_int_cst (itype, (loop->cond_code == LT_EXPR ? -1 : 1));
kono
parents:
diff changeset
341 t = fold_build2_loc (loc,
kono
parents:
diff changeset
342 PLUS_EXPR, itype,
kono
parents:
diff changeset
343 fold_convert_loc (loc, itype, loop->step), t);
kono
parents:
diff changeset
344 t = fold_build2_loc (loc, PLUS_EXPR, itype, t,
kono
parents:
diff changeset
345 fold_convert_loc (loc, itype, loop->n2));
kono
parents:
diff changeset
346 t = fold_build2_loc (loc, MINUS_EXPR, itype, t,
kono
parents:
diff changeset
347 fold_convert_loc (loc, itype, loop->n1));
kono
parents:
diff changeset
348 if (TYPE_UNSIGNED (itype) && loop->cond_code == GT_EXPR)
kono
parents:
diff changeset
349 t = fold_build2_loc (loc, TRUNC_DIV_EXPR, itype,
kono
parents:
diff changeset
350 fold_build1_loc (loc, NEGATE_EXPR, itype, t),
kono
parents:
diff changeset
351 fold_build1_loc (loc, NEGATE_EXPR, itype,
kono
parents:
diff changeset
352 fold_convert_loc (loc, itype,
kono
parents:
diff changeset
353 loop->step)));
kono
parents:
diff changeset
354 else
kono
parents:
diff changeset
355 t = fold_build2_loc (loc, TRUNC_DIV_EXPR, itype, t,
kono
parents:
diff changeset
356 fold_convert_loc (loc, itype, loop->step));
kono
parents:
diff changeset
357 t = fold_convert_loc (loc, long_long_unsigned_type_node, t);
kono
parents:
diff changeset
358 if (count != NULL_TREE)
kono
parents:
diff changeset
359 count = fold_build2_loc (loc,
kono
parents:
diff changeset
360 MULT_EXPR, long_long_unsigned_type_node,
kono
parents:
diff changeset
361 count, t);
kono
parents:
diff changeset
362 else
kono
parents:
diff changeset
363 count = t;
kono
parents:
diff changeset
364 if (TREE_CODE (count) != INTEGER_CST)
kono
parents:
diff changeset
365 count = NULL_TREE;
kono
parents:
diff changeset
366 }
kono
parents:
diff changeset
367 else if (count && !integer_zerop (count))
kono
parents:
diff changeset
368 count = NULL_TREE;
kono
parents:
diff changeset
369 }
kono
parents:
diff changeset
370 }
kono
parents:
diff changeset
371
kono
parents:
diff changeset
372 if (count
kono
parents:
diff changeset
373 && !simd
kono
parents:
diff changeset
374 && (fd->sched_kind != OMP_CLAUSE_SCHEDULE_STATIC
kono
parents:
diff changeset
375 || fd->have_ordered))
kono
parents:
diff changeset
376 {
kono
parents:
diff changeset
377 if (!tree_int_cst_lt (count, TYPE_MAX_VALUE (long_integer_type_node)))
kono
parents:
diff changeset
378 iter_type = long_long_unsigned_type_node;
kono
parents:
diff changeset
379 else
kono
parents:
diff changeset
380 iter_type = long_integer_type_node;
kono
parents:
diff changeset
381 }
kono
parents:
diff changeset
382 else if (collapse_iter && *collapse_iter != NULL)
kono
parents:
diff changeset
383 iter_type = TREE_TYPE (*collapse_iter);
kono
parents:
diff changeset
384 fd->iter_type = iter_type;
kono
parents:
diff changeset
385 if (collapse_iter && *collapse_iter == NULL)
kono
parents:
diff changeset
386 *collapse_iter = create_tmp_var (iter_type, ".iter");
kono
parents:
diff changeset
387 if (collapse_count && *collapse_count == NULL)
kono
parents:
diff changeset
388 {
kono
parents:
diff changeset
389 if (count)
kono
parents:
diff changeset
390 *collapse_count = fold_convert_loc (loc, iter_type, count);
kono
parents:
diff changeset
391 else
kono
parents:
diff changeset
392 *collapse_count = create_tmp_var (iter_type, ".count");
kono
parents:
diff changeset
393 }
kono
parents:
diff changeset
394
kono
parents:
diff changeset
395 if (fd->collapse > 1 || fd->tiling || (fd->ordered && loops))
kono
parents:
diff changeset
396 {
kono
parents:
diff changeset
397 fd->loop.v = *collapse_iter;
kono
parents:
diff changeset
398 fd->loop.n1 = build_int_cst (TREE_TYPE (fd->loop.v), 0);
kono
parents:
diff changeset
399 fd->loop.n2 = *collapse_count;
kono
parents:
diff changeset
400 fd->loop.step = build_int_cst (TREE_TYPE (fd->loop.v), 1);
kono
parents:
diff changeset
401 fd->loop.cond_code = LT_EXPR;
kono
parents:
diff changeset
402 }
kono
parents:
diff changeset
403 else if (loops)
kono
parents:
diff changeset
404 loops[0] = fd->loop;
kono
parents:
diff changeset
405 }
kono
parents:
diff changeset
406
kono
parents:
diff changeset
407 /* Build a call to GOMP_barrier. */
kono
parents:
diff changeset
408
kono
parents:
diff changeset
409 gimple *
kono
parents:
diff changeset
410 omp_build_barrier (tree lhs)
kono
parents:
diff changeset
411 {
kono
parents:
diff changeset
412 tree fndecl = builtin_decl_explicit (lhs ? BUILT_IN_GOMP_BARRIER_CANCEL
kono
parents:
diff changeset
413 : BUILT_IN_GOMP_BARRIER);
kono
parents:
diff changeset
414 gcall *g = gimple_build_call (fndecl, 0);
kono
parents:
diff changeset
415 if (lhs)
kono
parents:
diff changeset
416 gimple_call_set_lhs (g, lhs);
kono
parents:
diff changeset
417 return g;
kono
parents:
diff changeset
418 }
kono
parents:
diff changeset
419
kono
parents:
diff changeset
420 /* Return maximum possible vectorization factor for the target. */
kono
parents:
diff changeset
421
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
422 poly_uint64
111
kono
parents:
diff changeset
423 omp_max_vf (void)
kono
parents:
diff changeset
424 {
kono
parents:
diff changeset
425 if (!optimize
kono
parents:
diff changeset
426 || optimize_debug
kono
parents:
diff changeset
427 || !flag_tree_loop_optimize
kono
parents:
diff changeset
428 || (!flag_tree_loop_vectorize
kono
parents:
diff changeset
429 && global_options_set.x_flag_tree_loop_vectorize))
kono
parents:
diff changeset
430 return 1;
kono
parents:
diff changeset
431
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
432 auto_vector_sizes sizes;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
433 targetm.vectorize.autovectorize_vector_sizes (&sizes);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
434 if (!sizes.is_empty ())
111
kono
parents:
diff changeset
435 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
436 poly_uint64 vf = 0;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
437 for (unsigned int i = 0; i < sizes.length (); ++i)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
438 vf = ordered_max (vf, sizes[i]);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
439 return vf;
111
kono
parents:
diff changeset
440 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
441
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
442 machine_mode vqimode = targetm.vectorize.preferred_simd_mode (QImode);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
443 if (GET_MODE_CLASS (vqimode) == MODE_VECTOR_INT)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
444 return GET_MODE_NUNITS (vqimode);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
445
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
446 return 1;
111
kono
parents:
diff changeset
447 }
kono
parents:
diff changeset
448
kono
parents:
diff changeset
449 /* Return maximum SIMT width if offloading may target SIMT hardware. */
kono
parents:
diff changeset
450
kono
parents:
diff changeset
451 int
kono
parents:
diff changeset
452 omp_max_simt_vf (void)
kono
parents:
diff changeset
453 {
kono
parents:
diff changeset
454 if (!optimize)
kono
parents:
diff changeset
455 return 0;
kono
parents:
diff changeset
456 if (ENABLE_OFFLOADING)
kono
parents:
diff changeset
457 for (const char *c = getenv ("OFFLOAD_TARGET_NAMES"); c;)
kono
parents:
diff changeset
458 {
kono
parents:
diff changeset
459 if (!strncmp (c, "nvptx", strlen ("nvptx")))
kono
parents:
diff changeset
460 return 32;
kono
parents:
diff changeset
461 else if ((c = strchr (c, ',')))
kono
parents:
diff changeset
462 c++;
kono
parents:
diff changeset
463 }
kono
parents:
diff changeset
464 return 0;
kono
parents:
diff changeset
465 }
kono
parents:
diff changeset
466
kono
parents:
diff changeset
467 /* Encode an oacc launch argument. This matches the GOMP_LAUNCH_PACK
kono
parents:
diff changeset
468 macro on gomp-constants.h. We do not check for overflow. */
kono
parents:
diff changeset
469
kono
parents:
diff changeset
470 tree
kono
parents:
diff changeset
471 oacc_launch_pack (unsigned code, tree device, unsigned op)
kono
parents:
diff changeset
472 {
kono
parents:
diff changeset
473 tree res;
kono
parents:
diff changeset
474
kono
parents:
diff changeset
475 res = build_int_cst (unsigned_type_node, GOMP_LAUNCH_PACK (code, 0, op));
kono
parents:
diff changeset
476 if (device)
kono
parents:
diff changeset
477 {
kono
parents:
diff changeset
478 device = fold_build2 (LSHIFT_EXPR, unsigned_type_node,
kono
parents:
diff changeset
479 device, build_int_cst (unsigned_type_node,
kono
parents:
diff changeset
480 GOMP_LAUNCH_DEVICE_SHIFT));
kono
parents:
diff changeset
481 res = fold_build2 (BIT_IOR_EXPR, unsigned_type_node, res, device);
kono
parents:
diff changeset
482 }
kono
parents:
diff changeset
483 return res;
kono
parents:
diff changeset
484 }
kono
parents:
diff changeset
485
kono
parents:
diff changeset
486 /* FIXME: What is the following comment for? */
kono
parents:
diff changeset
487 /* Look for compute grid dimension clauses and convert to an attribute
kono
parents:
diff changeset
488 attached to FN. This permits the target-side code to (a) massage
kono
parents:
diff changeset
489 the dimensions, (b) emit that data and (c) optimize. Non-constant
kono
parents:
diff changeset
490 dimensions are pushed onto ARGS.
kono
parents:
diff changeset
491
kono
parents:
diff changeset
492 The attribute value is a TREE_LIST. A set of dimensions is
kono
parents:
diff changeset
493 represented as a list of INTEGER_CST. Those that are runtime
kono
parents:
diff changeset
494 exprs are represented as an INTEGER_CST of zero.
kono
parents:
diff changeset
495
kono
parents:
diff changeset
496 TODO: Normally the attribute will just contain a single such list. If
kono
parents:
diff changeset
497 however it contains a list of lists, this will represent the use of
kono
parents:
diff changeset
498 device_type. Each member of the outer list is an assoc list of
kono
parents:
diff changeset
499 dimensions, keyed by the device type. The first entry will be the
kono
parents:
diff changeset
500 default. Well, that's the plan. */
kono
parents:
diff changeset
501
kono
parents:
diff changeset
502 /* Replace any existing oacc fn attribute with updated dimensions. */
kono
parents:
diff changeset
503
kono
parents:
diff changeset
504 void
kono
parents:
diff changeset
505 oacc_replace_fn_attrib (tree fn, tree dims)
kono
parents:
diff changeset
506 {
kono
parents:
diff changeset
507 tree ident = get_identifier (OACC_FN_ATTRIB);
kono
parents:
diff changeset
508 tree attribs = DECL_ATTRIBUTES (fn);
kono
parents:
diff changeset
509
kono
parents:
diff changeset
510 /* If we happen to be present as the first attrib, drop it. */
kono
parents:
diff changeset
511 if (attribs && TREE_PURPOSE (attribs) == ident)
kono
parents:
diff changeset
512 attribs = TREE_CHAIN (attribs);
kono
parents:
diff changeset
513 DECL_ATTRIBUTES (fn) = tree_cons (ident, dims, attribs);
kono
parents:
diff changeset
514 }
kono
parents:
diff changeset
515
kono
parents:
diff changeset
516 /* Scan CLAUSES for launch dimensions and attach them to the oacc
kono
parents:
diff changeset
517 function attribute. Push any that are non-constant onto the ARGS
kono
parents:
diff changeset
518 list, along with an appropriate GOMP_LAUNCH_DIM tag. */
kono
parents:
diff changeset
519
kono
parents:
diff changeset
520 void
kono
parents:
diff changeset
521 oacc_set_fn_attrib (tree fn, tree clauses, vec<tree> *args)
kono
parents:
diff changeset
522 {
kono
parents:
diff changeset
523 /* Must match GOMP_DIM ordering. */
kono
parents:
diff changeset
524 static const omp_clause_code ids[]
kono
parents:
diff changeset
525 = { OMP_CLAUSE_NUM_GANGS, OMP_CLAUSE_NUM_WORKERS,
kono
parents:
diff changeset
526 OMP_CLAUSE_VECTOR_LENGTH };
kono
parents:
diff changeset
527 unsigned ix;
kono
parents:
diff changeset
528 tree dims[GOMP_DIM_MAX];
kono
parents:
diff changeset
529
kono
parents:
diff changeset
530 tree attr = NULL_TREE;
kono
parents:
diff changeset
531 unsigned non_const = 0;
kono
parents:
diff changeset
532
kono
parents:
diff changeset
533 for (ix = GOMP_DIM_MAX; ix--;)
kono
parents:
diff changeset
534 {
kono
parents:
diff changeset
535 tree clause = omp_find_clause (clauses, ids[ix]);
kono
parents:
diff changeset
536 tree dim = NULL_TREE;
kono
parents:
diff changeset
537
kono
parents:
diff changeset
538 if (clause)
kono
parents:
diff changeset
539 dim = OMP_CLAUSE_EXPR (clause, ids[ix]);
kono
parents:
diff changeset
540 dims[ix] = dim;
kono
parents:
diff changeset
541 if (dim && TREE_CODE (dim) != INTEGER_CST)
kono
parents:
diff changeset
542 {
kono
parents:
diff changeset
543 dim = integer_zero_node;
kono
parents:
diff changeset
544 non_const |= GOMP_DIM_MASK (ix);
kono
parents:
diff changeset
545 }
kono
parents:
diff changeset
546 attr = tree_cons (NULL_TREE, dim, attr);
kono
parents:
diff changeset
547 }
kono
parents:
diff changeset
548
kono
parents:
diff changeset
549 oacc_replace_fn_attrib (fn, attr);
kono
parents:
diff changeset
550
kono
parents:
diff changeset
551 if (non_const)
kono
parents:
diff changeset
552 {
kono
parents:
diff changeset
553 /* Push a dynamic argument set. */
kono
parents:
diff changeset
554 args->safe_push (oacc_launch_pack (GOMP_LAUNCH_DIM,
kono
parents:
diff changeset
555 NULL_TREE, non_const));
kono
parents:
diff changeset
556 for (unsigned ix = 0; ix != GOMP_DIM_MAX; ix++)
kono
parents:
diff changeset
557 if (non_const & GOMP_DIM_MASK (ix))
kono
parents:
diff changeset
558 args->safe_push (dims[ix]);
kono
parents:
diff changeset
559 }
kono
parents:
diff changeset
560 }
kono
parents:
diff changeset
561
kono
parents:
diff changeset
562 /* Process the routine's dimension clauess to generate an attribute
kono
parents:
diff changeset
563 value. Issue diagnostics as appropriate. We default to SEQ
kono
parents:
diff changeset
564 (OpenACC 2.5 clarifies this). All dimensions have a size of zero
kono
parents:
diff changeset
565 (dynamic). TREE_PURPOSE is set to indicate whether that dimension
kono
parents:
diff changeset
566 can have a loop partitioned on it. non-zero indicates
kono
parents:
diff changeset
567 yes, zero indicates no. By construction once a non-zero has been
kono
parents:
diff changeset
568 reached, further inner dimensions must also be non-zero. We set
kono
parents:
diff changeset
569 TREE_VALUE to zero for the dimensions that may be partitioned and
kono
parents:
diff changeset
570 1 for the other ones -- if a loop is (erroneously) spawned at
kono
parents:
diff changeset
571 an outer level, we don't want to try and partition it. */
kono
parents:
diff changeset
572
kono
parents:
diff changeset
573 tree
kono
parents:
diff changeset
574 oacc_build_routine_dims (tree clauses)
kono
parents:
diff changeset
575 {
kono
parents:
diff changeset
576 /* Must match GOMP_DIM ordering. */
kono
parents:
diff changeset
577 static const omp_clause_code ids[]
kono
parents:
diff changeset
578 = {OMP_CLAUSE_GANG, OMP_CLAUSE_WORKER, OMP_CLAUSE_VECTOR, OMP_CLAUSE_SEQ};
kono
parents:
diff changeset
579 int ix;
kono
parents:
diff changeset
580 int level = -1;
kono
parents:
diff changeset
581
kono
parents:
diff changeset
582 for (; clauses; clauses = OMP_CLAUSE_CHAIN (clauses))
kono
parents:
diff changeset
583 for (ix = GOMP_DIM_MAX + 1; ix--;)
kono
parents:
diff changeset
584 if (OMP_CLAUSE_CODE (clauses) == ids[ix])
kono
parents:
diff changeset
585 {
kono
parents:
diff changeset
586 if (level >= 0)
kono
parents:
diff changeset
587 error_at (OMP_CLAUSE_LOCATION (clauses),
kono
parents:
diff changeset
588 "multiple loop axes specified for routine");
kono
parents:
diff changeset
589 level = ix;
kono
parents:
diff changeset
590 break;
kono
parents:
diff changeset
591 }
kono
parents:
diff changeset
592
kono
parents:
diff changeset
593 /* Default to SEQ. */
kono
parents:
diff changeset
594 if (level < 0)
kono
parents:
diff changeset
595 level = GOMP_DIM_MAX;
kono
parents:
diff changeset
596
kono
parents:
diff changeset
597 tree dims = NULL_TREE;
kono
parents:
diff changeset
598
kono
parents:
diff changeset
599 for (ix = GOMP_DIM_MAX; ix--;)
kono
parents:
diff changeset
600 dims = tree_cons (build_int_cst (boolean_type_node, ix >= level),
kono
parents:
diff changeset
601 build_int_cst (integer_type_node, ix < level), dims);
kono
parents:
diff changeset
602
kono
parents:
diff changeset
603 return dims;
kono
parents:
diff changeset
604 }
kono
parents:
diff changeset
605
kono
parents:
diff changeset
606 /* Retrieve the oacc function attrib and return it. Non-oacc
kono
parents:
diff changeset
607 functions will return NULL. */
kono
parents:
diff changeset
608
kono
parents:
diff changeset
609 tree
kono
parents:
diff changeset
610 oacc_get_fn_attrib (tree fn)
kono
parents:
diff changeset
611 {
kono
parents:
diff changeset
612 return lookup_attribute (OACC_FN_ATTRIB, DECL_ATTRIBUTES (fn));
kono
parents:
diff changeset
613 }
kono
parents:
diff changeset
614
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
615 /* Return true if FN is an OpenMP or OpenACC offloading function. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
616
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
617 bool
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
618 offloading_function_p (tree fn)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
619 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
620 tree attrs = DECL_ATTRIBUTES (fn);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
621 return (lookup_attribute ("omp declare target", attrs)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
622 || lookup_attribute ("omp target entrypoint", attrs));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
623 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
624
111
kono
parents:
diff changeset
625 /* Extract an oacc execution dimension from FN. FN must be an
kono
parents:
diff changeset
626 offloaded function or routine that has already had its execution
kono
parents:
diff changeset
627 dimensions lowered to the target-specific values. */
kono
parents:
diff changeset
628
kono
parents:
diff changeset
629 int
kono
parents:
diff changeset
630 oacc_get_fn_dim_size (tree fn, int axis)
kono
parents:
diff changeset
631 {
kono
parents:
diff changeset
632 tree attrs = oacc_get_fn_attrib (fn);
kono
parents:
diff changeset
633
kono
parents:
diff changeset
634 gcc_assert (axis < GOMP_DIM_MAX);
kono
parents:
diff changeset
635
kono
parents:
diff changeset
636 tree dims = TREE_VALUE (attrs);
kono
parents:
diff changeset
637 while (axis--)
kono
parents:
diff changeset
638 dims = TREE_CHAIN (dims);
kono
parents:
diff changeset
639
kono
parents:
diff changeset
640 int size = TREE_INT_CST_LOW (TREE_VALUE (dims));
kono
parents:
diff changeset
641
kono
parents:
diff changeset
642 return size;
kono
parents:
diff changeset
643 }
kono
parents:
diff changeset
644
kono
parents:
diff changeset
645 /* Extract the dimension axis from an IFN_GOACC_DIM_POS or
kono
parents:
diff changeset
646 IFN_GOACC_DIM_SIZE call. */
kono
parents:
diff changeset
647
kono
parents:
diff changeset
648 int
kono
parents:
diff changeset
649 oacc_get_ifn_dim_arg (const gimple *stmt)
kono
parents:
diff changeset
650 {
kono
parents:
diff changeset
651 gcc_checking_assert (gimple_call_internal_fn (stmt) == IFN_GOACC_DIM_SIZE
kono
parents:
diff changeset
652 || gimple_call_internal_fn (stmt) == IFN_GOACC_DIM_POS);
kono
parents:
diff changeset
653 tree arg = gimple_call_arg (stmt, 0);
kono
parents:
diff changeset
654 HOST_WIDE_INT axis = TREE_INT_CST_LOW (arg);
kono
parents:
diff changeset
655
kono
parents:
diff changeset
656 gcc_checking_assert (axis >= 0 && axis < GOMP_DIM_MAX);
kono
parents:
diff changeset
657 return (int) axis;
kono
parents:
diff changeset
658 }