]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/c-family/c-omp.c
[OpenMP] Fix mapping of artificial variables (PR94874)
[thirdparty/gcc.git] / gcc / c-family / c-omp.c
CommitLineData
41dbbb37 1/* This file contains routines to construct OpenACC and OpenMP constructs,
953ff289
DN
2 called from parsing in the C and C++ front ends.
3
8d9254fc 4 Copyright (C) 2005-2020 Free Software Foundation, Inc.
953ff289
DN
5 Contributed by Richard Henderson <rth@redhat.com>,
6 Diego Novillo <dnovillo@redhat.com>.
7
8This file is part of GCC.
9
10GCC is free software; you can redistribute it and/or modify it under
11the terms of the GNU General Public License as published by the Free
9dcd6f09 12Software Foundation; either version 3, or (at your option) any later
953ff289
DN
13version.
14
15GCC is distributed in the hope that it will be useful, but WITHOUT ANY
16WARRANTY; without even the implied warranty of MERCHANTABILITY or
17FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18for more details.
19
20You should have received a copy of the GNU General Public License
9dcd6f09
NC
21along with GCC; see the file COPYING3. If not see
22<http://www.gnu.org/licenses/>. */
953ff289
DN
23
24#include "config.h"
25#include "system.h"
26#include "coretypes.h"
69f293c9 27#include "options.h"
953ff289 28#include "c-common.h"
45b0be94 29#include "gimple-expr.h"
2adfab87 30#include "c-pragma.h"
28567c40 31#include "stringpool.h"
629b3d75 32#include "omp-general.h"
41dbbb37 33#include "gomp-constants.h"
28567c40 34#include "memmodel.h"
20de9568
JJ
35#include "attribs.h"
36#include "gimplify.h"
953ff289
DN
37
38
41dbbb37
TS
39/* Complete a #pragma oacc wait construct. LOC is the location of
40 the #pragma. */
41
42tree
43c_finish_oacc_wait (location_t loc, tree parms, tree clauses)
44{
45 const int nparms = list_length (parms);
46 tree stmt, t;
47 vec<tree, va_gc> *args;
48
49 vec_alloc (args, nparms + 2);
50 stmt = builtin_decl_explicit (BUILT_IN_GOACC_WAIT);
51
629b3d75 52 if (omp_find_clause (clauses, OMP_CLAUSE_ASYNC))
41dbbb37
TS
53 t = OMP_CLAUSE_ASYNC_EXPR (clauses);
54 else
55 t = build_int_cst (integer_type_node, GOMP_ASYNC_SYNC);
56
57 args->quick_push (t);
58 args->quick_push (build_int_cst (integer_type_node, nparms));
59
60 for (t = parms; t; t = TREE_CHAIN (t))
61 {
62 if (TREE_CODE (OMP_CLAUSE_WAIT_EXPR (t)) == INTEGER_CST)
63 args->quick_push (build_int_cst (integer_type_node,
64 TREE_INT_CST_LOW (OMP_CLAUSE_WAIT_EXPR (t))));
65 else
66 args->quick_push (OMP_CLAUSE_WAIT_EXPR (t));
67 }
68
69 stmt = build_call_expr_loc_vec (loc, stmt, args);
41dbbb37
TS
70
71 vec_free (args);
72
73 return stmt;
74}
75
953ff289 76/* Complete a #pragma omp master construct. STMT is the structured-block
28567c40 77 that follows the pragma. LOC is the location of the #pragma. */
953ff289
DN
78
79tree
c2255bc4 80c_finish_omp_master (location_t loc, tree stmt)
953ff289 81{
c2255bc4
AH
82 tree t = add_stmt (build1 (OMP_MASTER, void_type_node, stmt));
83 SET_EXPR_LOCATION (t, loc);
84 return t;
953ff289
DN
85}
86
28567c40
JJ
87/* Complete a #pragma omp taskgroup construct. BODY is the structured-block
88 that follows the pragma. LOC is the location of the #pragma. */
acf0174b
JJ
89
90tree
28567c40 91c_finish_omp_taskgroup (location_t loc, tree body, tree clauses)
acf0174b 92{
28567c40
JJ
93 tree stmt = make_node (OMP_TASKGROUP);
94 TREE_TYPE (stmt) = void_type_node;
95 OMP_TASKGROUP_BODY (stmt) = body;
96 OMP_TASKGROUP_CLAUSES (stmt) = clauses;
97 SET_EXPR_LOCATION (stmt, loc);
98 return add_stmt (stmt);
acf0174b
JJ
99}
100
28567c40 101/* Complete a #pragma omp critical construct. BODY is the structured-block
953ff289 102 that follows the pragma, NAME is the identifier in the pragma, or null
c2255bc4 103 if it was omitted. LOC is the location of the #pragma. */
953ff289
DN
104
105tree
d9a6bd32 106c_finish_omp_critical (location_t loc, tree body, tree name, tree clauses)
953ff289
DN
107{
108 tree stmt = make_node (OMP_CRITICAL);
109 TREE_TYPE (stmt) = void_type_node;
110 OMP_CRITICAL_BODY (stmt) = body;
111 OMP_CRITICAL_NAME (stmt) = name;
d9a6bd32 112 OMP_CRITICAL_CLAUSES (stmt) = clauses;
c2255bc4 113 SET_EXPR_LOCATION (stmt, loc);
953ff289
DN
114 return add_stmt (stmt);
115}
116
117/* Complete a #pragma omp ordered construct. STMT is the structured-block
c2255bc4 118 that follows the pragma. LOC is the location of the #pragma. */
953ff289
DN
119
120tree
d9a6bd32 121c_finish_omp_ordered (location_t loc, tree clauses, tree stmt)
953ff289 122{
d9a6bd32
JJ
123 tree t = make_node (OMP_ORDERED);
124 TREE_TYPE (t) = void_type_node;
125 OMP_ORDERED_BODY (t) = stmt;
d2e05fcb
JJ
126 if (!flag_openmp /* flag_openmp_simd */
127 && (OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_SIMD
128 || OMP_CLAUSE_CHAIN (clauses)))
129 clauses = build_omp_clause (loc, OMP_CLAUSE_SIMD);
d9a6bd32 130 OMP_ORDERED_CLAUSES (t) = clauses;
c2255bc4
AH
131 SET_EXPR_LOCATION (t, loc);
132 return add_stmt (t);
953ff289
DN
133}
134
135
c2255bc4
AH
136/* Complete a #pragma omp barrier construct. LOC is the location of
137 the #pragma. */
953ff289
DN
138
139void
c2255bc4 140c_finish_omp_barrier (location_t loc)
953ff289
DN
141{
142 tree x;
143
e79983f4 144 x = builtin_decl_explicit (BUILT_IN_GOMP_BARRIER);
db3927fb 145 x = build_call_expr_loc (loc, x, 0);
953ff289
DN
146 add_stmt (x);
147}
148
149
c2255bc4
AH
150/* Complete a #pragma omp taskwait construct. LOC is the location of the
151 pragma. */
a68ab351
JJ
152
153void
c2255bc4 154c_finish_omp_taskwait (location_t loc)
a68ab351
JJ
155{
156 tree x;
157
e79983f4 158 x = builtin_decl_explicit (BUILT_IN_GOMP_TASKWAIT);
db3927fb 159 x = build_call_expr_loc (loc, x, 0);
a68ab351
JJ
160 add_stmt (x);
161}
162
163
20906c66
JJ
164/* Complete a #pragma omp taskyield construct. LOC is the location of the
165 pragma. */
166
167void
168c_finish_omp_taskyield (location_t loc)
169{
170 tree x;
171
e79983f4 172 x = builtin_decl_explicit (BUILT_IN_GOMP_TASKYIELD);
20906c66
JJ
173 x = build_call_expr_loc (loc, x, 0);
174 add_stmt (x);
175}
176
177
178/* Complete a #pragma omp atomic construct. For CODE OMP_ATOMIC
179 the expression to be implemented atomically is LHS opcode= RHS.
180 For OMP_ATOMIC_READ V = LHS, for OMP_ATOMIC_CAPTURE_{NEW,OLD} LHS
181 opcode= RHS with the new or old content of LHS returned.
182 LOC is the location of the atomic statement. The value returned
183 is either error_mark_node (if the construct was erroneous) or an
184 OMP_ATOMIC* node which should be added to the current statement
e01d41e5
JJ
185 tree with add_stmt. If TEST is set, avoid calling save_expr
186 or create_tmp_var*. */
953ff289 187
fe89d797 188tree
20906c66
JJ
189c_finish_omp_atomic (location_t loc, enum tree_code code,
190 enum tree_code opcode, tree lhs, tree rhs,
28567c40
JJ
191 tree v, tree lhs1, tree rhs1, bool swapped,
192 enum omp_memory_order memory_order, bool test)
953ff289 193{
241f845a 194 tree x, type, addr, pre = NULL_TREE;
56b5041c 195 HOST_WIDE_INT bitpos = 0, bitsize = 0;
953ff289 196
20906c66
JJ
197 if (lhs == error_mark_node || rhs == error_mark_node
198 || v == error_mark_node || lhs1 == error_mark_node
199 || rhs1 == error_mark_node)
fe89d797 200 return error_mark_node;
953ff289
DN
201
202 /* ??? According to one reading of the OpenMP spec, complex type are
203 supported, but there are no atomic stores for any architecture.
204 But at least icc 9.0 doesn't support complex types here either.
205 And lets not even talk about vector types... */
206 type = TREE_TYPE (lhs);
207 if (!INTEGRAL_TYPE_P (type)
208 && !POINTER_TYPE_P (type)
209 && !SCALAR_FLOAT_TYPE_P (type))
210 {
c2255bc4 211 error_at (loc, "invalid expression type for %<#pragma omp atomic%>");
fe89d797 212 return error_mark_node;
953ff289 213 }
9dc5773f
JJ
214 if (TYPE_ATOMIC (type))
215 {
216 error_at (loc, "%<_Atomic%> expression in %<#pragma omp atomic%>");
217 return error_mark_node;
218 }
953ff289 219
4886ec8e
JJ
220 if (opcode == RDIV_EXPR)
221 opcode = TRUNC_DIV_EXPR;
222
953ff289 223 /* ??? Validate that rhs does not overlap lhs. */
56b5041c
JJ
224 tree blhs = NULL;
225 if (TREE_CODE (lhs) == COMPONENT_REF
226 && TREE_CODE (TREE_OPERAND (lhs, 1)) == FIELD_DECL
227 && DECL_C_BIT_FIELD (TREE_OPERAND (lhs, 1))
228 && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (lhs, 1)))
229 {
230 tree field = TREE_OPERAND (lhs, 1);
231 tree repr = DECL_BIT_FIELD_REPRESENTATIVE (field);
232 if (tree_fits_uhwi_p (DECL_FIELD_OFFSET (field))
233 && tree_fits_uhwi_p (DECL_FIELD_OFFSET (repr)))
234 bitpos = (tree_to_uhwi (DECL_FIELD_OFFSET (field))
235 - tree_to_uhwi (DECL_FIELD_OFFSET (repr))) * BITS_PER_UNIT;
236 else
237 bitpos = 0;
238 bitpos += (tree_to_uhwi (DECL_FIELD_BIT_OFFSET (field))
239 - tree_to_uhwi (DECL_FIELD_BIT_OFFSET (repr)));
240 gcc_assert (tree_fits_shwi_p (DECL_SIZE (field)));
241 bitsize = tree_to_shwi (DECL_SIZE (field));
242 blhs = lhs;
243 type = TREE_TYPE (repr);
244 lhs = build3 (COMPONENT_REF, TREE_TYPE (repr), TREE_OPERAND (lhs, 0),
245 repr, TREE_OPERAND (lhs, 2));
246 }
953ff289
DN
247
248 /* Take and save the address of the lhs. From then on we'll reference it
249 via indirection. */
e51fbec3 250 addr = build_unary_op (loc, ADDR_EXPR, lhs, false);
953ff289 251 if (addr == error_mark_node)
fe89d797 252 return error_mark_node;
e01d41e5
JJ
253 if (!test)
254 addr = save_expr (addr);
255 if (!test
256 && TREE_CODE (addr) != SAVE_EXPR
66bb4f32 257 && (TREE_CODE (addr) != ADDR_EXPR
0ae9bd27 258 || !VAR_P (TREE_OPERAND (addr, 0))))
66bb4f32
JJ
259 {
260 /* Make sure LHS is simple enough so that goa_lhs_expr_p can recognize
261 it even after unsharing function body. */
b731b390 262 tree var = create_tmp_var_raw (TREE_TYPE (addr));
a406865a 263 DECL_CONTEXT (var) = current_function_decl;
66bb4f32
JJ
264 addr = build4 (TARGET_EXPR, TREE_TYPE (addr), var, addr, NULL, NULL);
265 }
56b5041c 266 tree orig_lhs = lhs;
dd865ef6 267 lhs = build_indirect_ref (loc, addr, RO_NULL);
56b5041c 268 tree new_lhs = lhs;
953ff289 269
20906c66
JJ
270 if (code == OMP_ATOMIC_READ)
271 {
272 x = build1 (OMP_ATOMIC_READ, type, addr);
273 SET_EXPR_LOCATION (x, loc);
28567c40 274 OMP_ATOMIC_MEMORY_ORDER (x) = memory_order;
56b5041c
JJ
275 if (blhs)
276 x = build3_loc (loc, BIT_FIELD_REF, TREE_TYPE (blhs), x,
277 bitsize_int (bitsize), bitsize_int (bitpos));
20906c66
JJ
278 return build_modify_expr (loc, v, NULL_TREE, NOP_EXPR,
279 loc, x, NULL_TREE);
20906c66
JJ
280 }
281
953ff289
DN
282 /* There are lots of warnings, errors, and conversions that need to happen
283 in the course of interpreting a statement. Use the normal mechanisms
284 to do this, and then take it apart again. */
56b5041c
JJ
285 if (blhs)
286 {
287 lhs = build3_loc (loc, BIT_FIELD_REF, TREE_TYPE (blhs), lhs,
288 bitsize_int (bitsize), bitsize_int (bitpos));
289 if (swapped)
30af3a2b 290 rhs = build_binary_op (loc, opcode, rhs, lhs, true);
56b5041c 291 else if (opcode != NOP_EXPR)
30af3a2b 292 rhs = build_binary_op (loc, opcode, lhs, rhs, true);
56b5041c
JJ
293 opcode = NOP_EXPR;
294 }
295 else if (swapped)
acf0174b 296 {
30af3a2b 297 rhs = build_binary_op (loc, opcode, rhs, lhs, true);
acf0174b
JJ
298 opcode = NOP_EXPR;
299 }
241f845a
JJ
300 bool save = in_late_binary_op;
301 in_late_binary_op = true;
56b5041c
JJ
302 x = build_modify_expr (loc, blhs ? blhs : lhs, NULL_TREE, opcode,
303 loc, rhs, NULL_TREE);
241f845a 304 in_late_binary_op = save;
953ff289 305 if (x == error_mark_node)
fe89d797 306 return error_mark_node;
241f845a
JJ
307 if (TREE_CODE (x) == COMPOUND_EXPR)
308 {
309 pre = TREE_OPERAND (x, 0);
361af3e4 310 gcc_assert (TREE_CODE (pre) == SAVE_EXPR || tree_invariant_p (pre));
241f845a
JJ
311 x = TREE_OPERAND (x, 1);
312 }
b8698a0f 313 gcc_assert (TREE_CODE (x) == MODIFY_EXPR);
953ff289
DN
314 rhs = TREE_OPERAND (x, 1);
315
56b5041c
JJ
316 if (blhs)
317 rhs = build3_loc (loc, BIT_INSERT_EXPR, type, new_lhs,
318 rhs, bitsize_int (bitpos));
319
953ff289 320 /* Punt the actual generation of atomic operations to common code. */
20906c66
JJ
321 if (code == OMP_ATOMIC)
322 type = void_type_node;
323 x = build2 (code, type, addr, rhs);
c2255bc4 324 SET_EXPR_LOCATION (x, loc);
28567c40 325 OMP_ATOMIC_MEMORY_ORDER (x) = memory_order;
20906c66
JJ
326
327 /* Generally it is hard to prove lhs1 and lhs are the same memory
328 location, just diagnose different variables. */
329 if (rhs1
0ae9bd27 330 && VAR_P (rhs1)
56b5041c
JJ
331 && VAR_P (orig_lhs)
332 && rhs1 != orig_lhs
e01d41e5 333 && !test)
20906c66
JJ
334 {
335 if (code == OMP_ATOMIC)
e01d41e5
JJ
336 error_at (loc, "%<#pragma omp atomic update%> uses two different "
337 "variables for memory");
20906c66 338 else
e01d41e5
JJ
339 error_at (loc, "%<#pragma omp atomic capture%> uses two different "
340 "variables for memory");
20906c66
JJ
341 return error_mark_node;
342 }
343
56b5041c
JJ
344 if (lhs1
345 && lhs1 != orig_lhs
346 && TREE_CODE (lhs1) == COMPONENT_REF
347 && TREE_CODE (TREE_OPERAND (lhs1, 1)) == FIELD_DECL
348 && DECL_C_BIT_FIELD (TREE_OPERAND (lhs1, 1))
349 && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (lhs1, 1)))
350 {
351 tree field = TREE_OPERAND (lhs1, 1);
352 tree repr = DECL_BIT_FIELD_REPRESENTATIVE (field);
353 lhs1 = build3 (COMPONENT_REF, TREE_TYPE (repr), TREE_OPERAND (lhs1, 0),
354 repr, TREE_OPERAND (lhs1, 2));
355 }
356 if (rhs1
357 && rhs1 != orig_lhs
358 && TREE_CODE (rhs1) == COMPONENT_REF
359 && TREE_CODE (TREE_OPERAND (rhs1, 1)) == FIELD_DECL
360 && DECL_C_BIT_FIELD (TREE_OPERAND (rhs1, 1))
361 && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (rhs1, 1)))
362 {
363 tree field = TREE_OPERAND (rhs1, 1);
364 tree repr = DECL_BIT_FIELD_REPRESENTATIVE (field);
365 rhs1 = build3 (COMPONENT_REF, TREE_TYPE (repr), TREE_OPERAND (rhs1, 0),
366 repr, TREE_OPERAND (rhs1, 2));
367 }
368
20906c66
JJ
369 if (code != OMP_ATOMIC)
370 {
371 /* Generally it is hard to prove lhs1 and lhs are the same memory
372 location, just diagnose different variables. */
56b5041c 373 if (lhs1 && VAR_P (lhs1) && VAR_P (orig_lhs))
20906c66 374 {
56b5041c 375 if (lhs1 != orig_lhs && !test)
20906c66 376 {
e01d41e5
JJ
377 error_at (loc, "%<#pragma omp atomic capture%> uses two "
378 "different variables for memory");
20906c66
JJ
379 return error_mark_node;
380 }
381 }
56b5041c 382 if (blhs)
18a23298
JJ
383 {
384 x = build3_loc (loc, BIT_FIELD_REF, TREE_TYPE (blhs), x,
385 bitsize_int (bitsize), bitsize_int (bitpos));
386 type = TREE_TYPE (blhs);
387 }
20906c66
JJ
388 x = build_modify_expr (loc, v, NULL_TREE, NOP_EXPR,
389 loc, x, NULL_TREE);
56b5041c 390 if (rhs1 && rhs1 != orig_lhs)
20906c66 391 {
e51fbec3 392 tree rhs1addr = build_unary_op (loc, ADDR_EXPR, rhs1, false);
20906c66
JJ
393 if (rhs1addr == error_mark_node)
394 return error_mark_node;
395 x = omit_one_operand_loc (loc, type, x, rhs1addr);
396 }
56b5041c 397 if (lhs1 && lhs1 != orig_lhs)
20906c66 398 {
e51fbec3 399 tree lhs1addr = build_unary_op (loc, ADDR_EXPR, lhs1, false);
20906c66
JJ
400 if (lhs1addr == error_mark_node)
401 return error_mark_node;
402 if (code == OMP_ATOMIC_CAPTURE_OLD)
403 x = omit_one_operand_loc (loc, type, x, lhs1addr);
404 else
405 {
e01d41e5
JJ
406 if (!test)
407 x = save_expr (x);
20906c66
JJ
408 x = omit_two_operands_loc (loc, type, x, x, lhs1addr);
409 }
410 }
411 }
56b5041c 412 else if (rhs1 && rhs1 != orig_lhs)
20906c66 413 {
e51fbec3 414 tree rhs1addr = build_unary_op (loc, ADDR_EXPR, rhs1, false);
20906c66
JJ
415 if (rhs1addr == error_mark_node)
416 return error_mark_node;
417 x = omit_one_operand_loc (loc, type, x, rhs1addr);
418 }
419
241f845a
JJ
420 if (pre)
421 x = omit_one_operand_loc (loc, type, x, pre);
c2255bc4 422 return x;
953ff289
DN
423}
424
425
28567c40
JJ
426/* Return true if TYPE is the implementation's omp_depend_t. */
427
428bool
429c_omp_depend_t_p (tree type)
430{
431 type = TYPE_MAIN_VARIANT (type);
432 return (TREE_CODE (type) == RECORD_TYPE
433 && TYPE_NAME (type)
434 && ((TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
435 ? DECL_NAME (TYPE_NAME (type)) : TYPE_NAME (type))
436 == get_identifier ("omp_depend_t"))
437 && (!TYPE_CONTEXT (type)
438 || TREE_CODE (TYPE_CONTEXT (type)) == TRANSLATION_UNIT_DECL)
439 && COMPLETE_TYPE_P (type)
440 && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
441 && !compare_tree_int (TYPE_SIZE (type),
442 2 * tree_to_uhwi (TYPE_SIZE (ptr_type_node))));
443}
444
445
446/* Complete a #pragma omp depobj construct. LOC is the location of the
447 #pragma. */
448
449void
450c_finish_omp_depobj (location_t loc, tree depobj,
451 enum omp_clause_depend_kind kind, tree clause)
452{
453 tree t = NULL_TREE;
454 if (!error_operand_p (depobj))
455 {
456 if (!c_omp_depend_t_p (TREE_TYPE (depobj)))
457 {
458 error_at (EXPR_LOC_OR_LOC (depobj, loc),
459 "type of %<depobj%> expression is not %<omp_depend_t%>");
460 depobj = error_mark_node;
461 }
462 else if (TYPE_READONLY (TREE_TYPE (depobj)))
463 {
464 error_at (EXPR_LOC_OR_LOC (depobj, loc),
465 "%<const%> qualified %<depobj%> expression");
466 depobj = error_mark_node;
467 }
468 }
469 else
470 depobj = error_mark_node;
471
472 if (clause == error_mark_node)
473 return;
474
475 if (clause)
476 {
477 gcc_assert (TREE_CODE (clause) == OMP_CLAUSE
478 && OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_DEPEND);
479 if (OMP_CLAUSE_CHAIN (clause))
480 error_at (OMP_CLAUSE_LOCATION (clause),
481 "more than one locator in %<depend%> clause on %<depobj%> "
482 "construct");
483 switch (OMP_CLAUSE_DEPEND_KIND (clause))
484 {
485 case OMP_CLAUSE_DEPEND_DEPOBJ:
486 error_at (OMP_CLAUSE_LOCATION (clause),
487 "%<depobj%> dependence type specified in %<depend%> "
488 "clause on %<depobj%> construct");
489 return;
490 case OMP_CLAUSE_DEPEND_SOURCE:
491 case OMP_CLAUSE_DEPEND_SINK:
492 error_at (OMP_CLAUSE_LOCATION (clause),
493 "%<depend(%s)%> is only allowed in %<omp ordered%>",
494 OMP_CLAUSE_DEPEND_KIND (clause) == OMP_CLAUSE_DEPEND_SOURCE
495 ? "source" : "sink");
496 return;
497 case OMP_CLAUSE_DEPEND_IN:
498 case OMP_CLAUSE_DEPEND_OUT:
499 case OMP_CLAUSE_DEPEND_INOUT:
500 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
501 kind = OMP_CLAUSE_DEPEND_KIND (clause);
502 t = OMP_CLAUSE_DECL (clause);
503 gcc_assert (t);
504 if (TREE_CODE (t) == TREE_LIST
505 && TREE_PURPOSE (t)
506 && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
507 {
508 error_at (OMP_CLAUSE_LOCATION (clause),
509 "%<iterator%> modifier may not be specified on "
510 "%<depobj%> construct");
511 return;
512 }
513 if (TREE_CODE (t) == COMPOUND_EXPR)
514 {
515 tree t1 = build_fold_addr_expr (TREE_OPERAND (t, 1));
516 t = build2 (COMPOUND_EXPR, TREE_TYPE (t1), TREE_OPERAND (t, 0),
517 t1);
518 }
519 else
520 t = build_fold_addr_expr (t);
521 break;
522 default:
523 gcc_unreachable ();
524 }
525 }
526 else
527 gcc_assert (kind != OMP_CLAUSE_DEPEND_SOURCE);
528
529 if (depobj == error_mark_node)
530 return;
531
532 depobj = build_fold_addr_expr_loc (EXPR_LOC_OR_LOC (depobj, loc), depobj);
533 tree dtype
534 = build_pointer_type_for_mode (ptr_type_node, TYPE_MODE (ptr_type_node),
535 true);
536 depobj = fold_convert (dtype, depobj);
537 tree r;
538 if (clause)
539 {
540 depobj = save_expr (depobj);
541 r = build_indirect_ref (loc, depobj, RO_UNARY_STAR);
542 add_stmt (build2 (MODIFY_EXPR, void_type_node, r, t));
543 }
544 int k;
545 switch (kind)
546 {
547 case OMP_CLAUSE_DEPEND_IN:
548 k = GOMP_DEPEND_IN;
549 break;
550 case OMP_CLAUSE_DEPEND_OUT:
551 k = GOMP_DEPEND_OUT;
552 break;
553 case OMP_CLAUSE_DEPEND_INOUT:
554 k = GOMP_DEPEND_INOUT;
555 break;
556 case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
557 k = GOMP_DEPEND_MUTEXINOUTSET;
558 break;
559 case OMP_CLAUSE_DEPEND_LAST:
560 k = -1;
561 break;
562 default:
563 gcc_unreachable ();
564 }
565 t = build_int_cst (ptr_type_node, k);
566 depobj = build2_loc (loc, POINTER_PLUS_EXPR, TREE_TYPE (depobj), depobj,
567 TYPE_SIZE_UNIT (ptr_type_node));
568 r = build_indirect_ref (loc, depobj, RO_UNARY_STAR);
569 add_stmt (build2 (MODIFY_EXPR, void_type_node, r, t));
570}
571
572
c2255bc4
AH
573/* Complete a #pragma omp flush construct. We don't do anything with
574 the variable list that the syntax allows. LOC is the location of
575 the #pragma. */
953ff289
DN
576
577void
28567c40 578c_finish_omp_flush (location_t loc, int mo)
953ff289
DN
579{
580 tree x;
581
28567c40
JJ
582 if (mo == MEMMODEL_LAST)
583 {
584 x = builtin_decl_explicit (BUILT_IN_SYNC_SYNCHRONIZE);
585 x = build_call_expr_loc (loc, x, 0);
586 }
587 else
588 {
589 x = builtin_decl_explicit (BUILT_IN_ATOMIC_THREAD_FENCE);
590 x = build_call_expr_loc (loc, x, 1,
591 build_int_cst (integer_type_node, mo));
592 }
953ff289
DN
593 add_stmt (x);
594}
595
596
41dbbb37 597/* Check and canonicalize OMP_FOR increment expression.
953ff289
DN
598 Helper function for c_finish_omp_for. */
599
600static tree
db3927fb 601check_omp_for_incr_expr (location_t loc, tree exp, tree decl)
953ff289
DN
602{
603 tree t;
604
605 if (!INTEGRAL_TYPE_P (TREE_TYPE (exp))
606 || TYPE_PRECISION (TREE_TYPE (exp)) < TYPE_PRECISION (TREE_TYPE (decl)))
607 return error_mark_node;
608
609 if (exp == decl)
610 return build_int_cst (TREE_TYPE (exp), 0);
611
612 switch (TREE_CODE (exp))
613 {
1043771b 614 CASE_CONVERT:
db3927fb 615 t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 0), decl);
953ff289 616 if (t != error_mark_node)
db3927fb 617 return fold_convert_loc (loc, TREE_TYPE (exp), t);
953ff289
DN
618 break;
619 case MINUS_EXPR:
db3927fb 620 t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 0), decl);
953ff289 621 if (t != error_mark_node)
db3927fb 622 return fold_build2_loc (loc, MINUS_EXPR,
28567c40 623 TREE_TYPE (exp), t, TREE_OPERAND (exp, 1));
953ff289
DN
624 break;
625 case PLUS_EXPR:
db3927fb 626 t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 0), decl);
953ff289 627 if (t != error_mark_node)
db3927fb 628 return fold_build2_loc (loc, PLUS_EXPR,
28567c40 629 TREE_TYPE (exp), t, TREE_OPERAND (exp, 1));
db3927fb 630 t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 1), decl);
953ff289 631 if (t != error_mark_node)
db3927fb 632 return fold_build2_loc (loc, PLUS_EXPR,
28567c40 633 TREE_TYPE (exp), TREE_OPERAND (exp, 0), t);
953ff289 634 break;
4063e61b
JM
635 case COMPOUND_EXPR:
636 {
637 /* cp_build_modify_expr forces preevaluation of the RHS to make
638 sure that it is evaluated before the lvalue-rvalue conversion
639 is applied to the LHS. Reconstruct the original expression. */
640 tree op0 = TREE_OPERAND (exp, 0);
641 if (TREE_CODE (op0) == TARGET_EXPR
642 && !VOID_TYPE_P (TREE_TYPE (op0)))
643 {
644 tree op1 = TREE_OPERAND (exp, 1);
645 tree temp = TARGET_EXPR_SLOT (op0);
cf4ef6f7 646 if (BINARY_CLASS_P (op1)
4063e61b
JM
647 && TREE_OPERAND (op1, 1) == temp)
648 {
649 op1 = copy_node (op1);
650 TREE_OPERAND (op1, 1) = TARGET_EXPR_INITIAL (op0);
651 return check_omp_for_incr_expr (loc, op1, decl);
652 }
653 }
654 break;
655 }
953ff289
DN
656 default:
657 break;
658 }
659
660 return error_mark_node;
661}
662
c02065fc
AH
663/* If the OMP_FOR increment expression in INCR is of pointer type,
664 canonicalize it into an expression handled by gimplify_omp_for()
665 and return it. DECL is the iteration variable. */
666
667static tree
668c_omp_for_incr_canonicalize_ptr (location_t loc, tree decl, tree incr)
669{
670 if (POINTER_TYPE_P (TREE_TYPE (decl))
671 && TREE_OPERAND (incr, 1))
672 {
673 tree t = fold_convert_loc (loc,
674 sizetype, TREE_OPERAND (incr, 1));
675
676 if (TREE_CODE (incr) == POSTDECREMENT_EXPR
677 || TREE_CODE (incr) == PREDECREMENT_EXPR)
678 t = fold_build1_loc (loc, NEGATE_EXPR, sizetype, t);
679 t = fold_build_pointer_plus (decl, t);
680 incr = build2 (MODIFY_EXPR, void_type_node, decl, t);
681 }
682 return incr;
683}
684
41dbbb37 685/* Validate and generate OMP_FOR.
a68ab351 686 DECLV is a vector of iteration variables, for each collapsed loop.
d9a6bd32
JJ
687
688 ORIG_DECLV, if non-NULL, is a vector with the original iteration
689 variables (prior to any transformations, by say, C++ iterators).
690
a68ab351
JJ
691 INITV, CONDV and INCRV are vectors containing initialization
692 expressions, controlling predicates and increment expressions.
693 BODY is the body of the loop and PRE_BODY statements that go before
694 the loop. */
953ff289
DN
695
696tree
acf0174b 697c_finish_omp_for (location_t locus, enum tree_code code, tree declv,
d9a6bd32 698 tree orig_declv, tree initv, tree condv, tree incrv,
28567c40 699 tree body, tree pre_body, bool final_p)
953ff289 700{
a68ab351 701 location_t elocus;
953ff289 702 bool fail = false;
a68ab351 703 int i;
953ff289 704
a68ab351
JJ
705 gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (initv));
706 gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (condv));
707 gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (incrv));
708 for (i = 0; i < TREE_VEC_LENGTH (declv); i++)
953ff289 709 {
a68ab351
JJ
710 tree decl = TREE_VEC_ELT (declv, i);
711 tree init = TREE_VEC_ELT (initv, i);
712 tree cond = TREE_VEC_ELT (condv, i);
713 tree incr = TREE_VEC_ELT (incrv, i);
714
715 elocus = locus;
716 if (EXPR_HAS_LOCATION (init))
717 elocus = EXPR_LOCATION (init);
718
719 /* Validate the iteration variable. */
720 if (!INTEGRAL_TYPE_P (TREE_TYPE (decl))
721 && TREE_CODE (TREE_TYPE (decl)) != POINTER_TYPE)
722 {
c9f9eb5d 723 error_at (elocus, "invalid type for iteration variable %qE", decl);
a68ab351
JJ
724 fail = true;
725 }
9dc5773f
JJ
726 else if (TYPE_ATOMIC (TREE_TYPE (decl)))
727 {
728 error_at (elocus, "%<_Atomic%> iteration variable %qE", decl);
729 fail = true;
730 /* _Atomic iterator confuses stuff too much, so we risk ICE
731 trying to diagnose it further. */
732 continue;
733 }
953ff289 734
a68ab351
JJ
735 /* In the case of "for (int i = 0...)", init will be a decl. It should
736 have a DECL_INITIAL that we can turn into an assignment. */
737 if (init == decl)
738 {
739 elocus = DECL_SOURCE_LOCATION (decl);
740
741 init = DECL_INITIAL (decl);
742 if (init == NULL)
743 {
c9f9eb5d 744 error_at (elocus, "%qE is not initialized", decl);
a68ab351
JJ
745 init = integer_zero_node;
746 fail = true;
747 }
d9a6bd32 748 DECL_INITIAL (decl) = NULL_TREE;
953ff289 749
b8698a0f 750 init = build_modify_expr (elocus, decl, NULL_TREE, NOP_EXPR,
c2255bc4
AH
751 /* FIXME diagnostics: This should
752 be the location of the INIT. */
753 elocus,
754 init,
32e8bb8e 755 NULL_TREE);
a68ab351 756 }
c02065fc
AH
757 if (init != error_mark_node)
758 {
759 gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
760 gcc_assert (TREE_OPERAND (init, 0) == decl);
761 }
a68ab351
JJ
762
763 if (cond == NULL_TREE)
953ff289 764 {
c9f9eb5d 765 error_at (elocus, "missing controlling predicate");
953ff289
DN
766 fail = true;
767 }
a68ab351
JJ
768 else
769 {
770 bool cond_ok = false;
953ff289 771
a40ff0ae
JJ
772 /* E.g. C sizeof (vla) could add COMPOUND_EXPRs with
773 evaluation of the vla VAR_DECL. We need to readd
774 them to the non-decl operand. See PR45784. */
775 while (TREE_CODE (cond) == COMPOUND_EXPR)
776 cond = TREE_OPERAND (cond, 1);
777
a68ab351
JJ
778 if (EXPR_HAS_LOCATION (cond))
779 elocus = EXPR_LOCATION (cond);
953ff289 780
a68ab351
JJ
781 if (TREE_CODE (cond) == LT_EXPR
782 || TREE_CODE (cond) == LE_EXPR
783 || TREE_CODE (cond) == GT_EXPR
ea1199ee 784 || TREE_CODE (cond) == GE_EXPR
b83a701b
JJ
785 || TREE_CODE (cond) == NE_EXPR
786 || TREE_CODE (cond) == EQ_EXPR)
a68ab351
JJ
787 {
788 tree op0 = TREE_OPERAND (cond, 0);
789 tree op1 = TREE_OPERAND (cond, 1);
953ff289 790
a68ab351
JJ
791 /* 2.5.1. The comparison in the condition is computed in
792 the type of DECL, otherwise the behavior is undefined.
953ff289 793
a68ab351
JJ
794 For example:
795 long n; int i;
796 i < n;
953ff289 797
a68ab351
JJ
798 according to ISO will be evaluated as:
799 (long)i < n;
953ff289 800
a68ab351
JJ
801 We want to force:
802 i < (int)n; */
803 if (TREE_CODE (op0) == NOP_EXPR
804 && decl == TREE_OPERAND (op0, 0))
805 {
806 TREE_OPERAND (cond, 0) = TREE_OPERAND (op0, 0);
807 TREE_OPERAND (cond, 1)
db3927fb 808 = fold_build1_loc (elocus, NOP_EXPR, TREE_TYPE (decl),
a68ab351
JJ
809 TREE_OPERAND (cond, 1));
810 }
811 else if (TREE_CODE (op1) == NOP_EXPR
812 && decl == TREE_OPERAND (op1, 0))
813 {
814 TREE_OPERAND (cond, 1) = TREE_OPERAND (op1, 0);
815 TREE_OPERAND (cond, 0)
db3927fb 816 = fold_build1_loc (elocus, NOP_EXPR, TREE_TYPE (decl),
a68ab351
JJ
817 TREE_OPERAND (cond, 0));
818 }
953ff289 819
a68ab351
JJ
820 if (decl == TREE_OPERAND (cond, 0))
821 cond_ok = true;
822 else if (decl == TREE_OPERAND (cond, 1))
823 {
824 TREE_SET_CODE (cond,
825 swap_tree_comparison (TREE_CODE (cond)));
826 TREE_OPERAND (cond, 1) = TREE_OPERAND (cond, 0);
827 TREE_OPERAND (cond, 0) = decl;
828 cond_ok = true;
829 }
ea1199ee 830
b83a701b
JJ
831 if (TREE_CODE (cond) == NE_EXPR
832 || TREE_CODE (cond) == EQ_EXPR)
ea1199ee
JJ
833 {
834 if (!INTEGRAL_TYPE_P (TREE_TYPE (decl)))
9a771876 835 {
28567c40
JJ
836 if (code == OACC_LOOP || TREE_CODE (cond) == EQ_EXPR)
837 cond_ok = false;
9a771876 838 }
ea1199ee
JJ
839 else if (operand_equal_p (TREE_OPERAND (cond, 1),
840 TYPE_MIN_VALUE (TREE_TYPE (decl)),
841 0))
b83a701b
JJ
842 TREE_SET_CODE (cond, TREE_CODE (cond) == NE_EXPR
843 ? GT_EXPR : LE_EXPR);
ea1199ee
JJ
844 else if (operand_equal_p (TREE_OPERAND (cond, 1),
845 TYPE_MAX_VALUE (TREE_TYPE (decl)),
846 0))
b83a701b
JJ
847 TREE_SET_CODE (cond, TREE_CODE (cond) == NE_EXPR
848 ? LT_EXPR : GE_EXPR);
28567c40 849 else if (code == OACC_LOOP || TREE_CODE (cond) == EQ_EXPR)
ea1199ee
JJ
850 cond_ok = false;
851 }
a40ff0ae
JJ
852
853 if (cond_ok && TREE_VEC_ELT (condv, i) != cond)
854 {
855 tree ce = NULL_TREE, *pce = &ce;
856 tree type = TREE_TYPE (TREE_OPERAND (cond, 1));
857 for (tree c = TREE_VEC_ELT (condv, i); c != cond;
858 c = TREE_OPERAND (c, 1))
859 {
860 *pce = build2 (COMPOUND_EXPR, type, TREE_OPERAND (c, 0),
861 TREE_OPERAND (cond, 1));
862 pce = &TREE_OPERAND (*pce, 1);
863 }
864 TREE_OPERAND (cond, 1) = ce;
865 TREE_VEC_ELT (condv, i) = cond;
866 }
953ff289
DN
867 }
868
a68ab351 869 if (!cond_ok)
953ff289 870 {
c9f9eb5d 871 error_at (elocus, "invalid controlling predicate");
a68ab351 872 fail = true;
953ff289
DN
873 }
874 }
875
a68ab351 876 if (incr == NULL_TREE)
953ff289 877 {
c9f9eb5d 878 error_at (elocus, "missing increment expression");
953ff289
DN
879 fail = true;
880 }
a68ab351 881 else
953ff289 882 {
a68ab351 883 bool incr_ok = false;
953ff289 884
a68ab351
JJ
885 if (EXPR_HAS_LOCATION (incr))
886 elocus = EXPR_LOCATION (incr);
887
888 /* Check all the valid increment expressions: v++, v--, ++v, --v,
889 v = v + incr, v = incr + v and v = v - incr. */
890 switch (TREE_CODE (incr))
953ff289 891 {
a68ab351
JJ
892 case POSTINCREMENT_EXPR:
893 case PREINCREMENT_EXPR:
894 case POSTDECREMENT_EXPR:
895 case PREDECREMENT_EXPR:
896 if (TREE_OPERAND (incr, 0) != decl)
897 break;
898
899 incr_ok = true;
28567c40
JJ
900 if (!fail
901 && TREE_CODE (cond) == NE_EXPR
902 && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
903 && TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)))
904 && (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))))
905 != INTEGER_CST))
906 {
907 /* For pointer to VLA, transform != into < or >
908 depending on whether incr is increment or decrement. */
909 if (TREE_CODE (incr) == PREINCREMENT_EXPR
910 || TREE_CODE (incr) == POSTINCREMENT_EXPR)
911 TREE_SET_CODE (cond, LT_EXPR);
912 else
913 TREE_SET_CODE (cond, GT_EXPR);
914 }
c02065fc 915 incr = c_omp_for_incr_canonicalize_ptr (elocus, decl, incr);
a68ab351
JJ
916 break;
917
241f845a
JJ
918 case COMPOUND_EXPR:
919 if (TREE_CODE (TREE_OPERAND (incr, 0)) != SAVE_EXPR
920 || TREE_CODE (TREE_OPERAND (incr, 1)) != MODIFY_EXPR)
921 break;
922 incr = TREE_OPERAND (incr, 1);
923 /* FALLTHRU */
a68ab351
JJ
924 case MODIFY_EXPR:
925 if (TREE_OPERAND (incr, 0) != decl)
926 break;
927 if (TREE_OPERAND (incr, 1) == decl)
928 break;
929 if (TREE_CODE (TREE_OPERAND (incr, 1)) == PLUS_EXPR
930 && (TREE_OPERAND (TREE_OPERAND (incr, 1), 0) == decl
931 || TREE_OPERAND (TREE_OPERAND (incr, 1), 1) == decl))
932 incr_ok = true;
933 else if ((TREE_CODE (TREE_OPERAND (incr, 1)) == MINUS_EXPR
934 || (TREE_CODE (TREE_OPERAND (incr, 1))
935 == POINTER_PLUS_EXPR))
936 && TREE_OPERAND (TREE_OPERAND (incr, 1), 0) == decl)
937 incr_ok = true;
938 else
939 {
db3927fb
AH
940 tree t = check_omp_for_incr_expr (elocus,
941 TREE_OPERAND (incr, 1),
a68ab351
JJ
942 decl);
943 if (t != error_mark_node)
944 {
945 incr_ok = true;
946 t = build2 (PLUS_EXPR, TREE_TYPE (decl), decl, t);
947 incr = build2 (MODIFY_EXPR, void_type_node, decl, t);
948 }
949 }
28567c40
JJ
950 if (!fail
951 && incr_ok
952 && TREE_CODE (cond) == NE_EXPR)
953 {
954 tree i = TREE_OPERAND (incr, 1);
955 i = TREE_OPERAND (i, TREE_OPERAND (i, 0) == decl);
956 i = c_fully_fold (i, false, NULL);
957 if (!final_p
958 && TREE_CODE (i) != INTEGER_CST)
959 ;
960 else if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
961 {
962 tree unit
963 = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
964 if (unit)
965 {
966 enum tree_code ccode = GT_EXPR;
967 unit = c_fully_fold (unit, false, NULL);
968 i = fold_convert (TREE_TYPE (unit), i);
969 if (operand_equal_p (unit, i, 0))
970 ccode = LT_EXPR;
971 if (ccode == GT_EXPR)
972 {
973 i = fold_unary (NEGATE_EXPR, TREE_TYPE (i), i);
974 if (i == NULL_TREE
975 || !operand_equal_p (unit, i, 0))
976 {
977 error_at (elocus,
978 "increment is not constant 1 or "
a9c697b8 979 "-1 for %<!=%> condition");
28567c40
JJ
980 fail = true;
981 }
982 }
983 if (TREE_CODE (unit) != INTEGER_CST)
984 /* For pointer to VLA, transform != into < or >
985 depending on whether the pointer is
986 incremented or decremented in each
987 iteration. */
988 TREE_SET_CODE (cond, ccode);
989 }
990 }
991 else
992 {
993 if (!integer_onep (i) && !integer_minus_onep (i))
994 {
995 error_at (elocus,
996 "increment is not constant 1 or -1 for"
a9c697b8 997 " %<!=%> condition");
28567c40
JJ
998 fail = true;
999 }
1000 }
1001 }
a68ab351 1002 break;
953ff289 1003
a68ab351
JJ
1004 default:
1005 break;
1006 }
1007 if (!incr_ok)
1008 {
c9f9eb5d 1009 error_at (elocus, "invalid increment expression");
a68ab351
JJ
1010 fail = true;
1011 }
953ff289 1012 }
a68ab351
JJ
1013
1014 TREE_VEC_ELT (initv, i) = init;
1015 TREE_VEC_ELT (incrv, i) = incr;
953ff289
DN
1016 }
1017
1018 if (fail)
1019 return NULL;
1020 else
1021 {
acf0174b 1022 tree t = make_node (code);
953ff289
DN
1023
1024 TREE_TYPE (t) = void_type_node;
a68ab351
JJ
1025 OMP_FOR_INIT (t) = initv;
1026 OMP_FOR_COND (t) = condv;
1027 OMP_FOR_INCR (t) = incrv;
953ff289
DN
1028 OMP_FOR_BODY (t) = body;
1029 OMP_FOR_PRE_BODY (t) = pre_body;
e01d41e5 1030 OMP_FOR_ORIG_DECLS (t) = orig_declv;
953ff289
DN
1031
1032 SET_EXPR_LOCATION (t, locus);
e01d41e5 1033 return t;
953ff289
DN
1034 }
1035}
1036
e01d41e5
JJ
1037/* Type for passing data in between c_omp_check_loop_iv and
1038 c_omp_check_loop_iv_r. */
1039
1040struct c_omp_check_loop_iv_data
1041{
1042 tree declv;
1043 bool fail;
1044 location_t stmt_loc;
1045 location_t expr_loc;
1046 int kind;
1047 walk_tree_lh lh;
1048 hash_set<tree> *ppset;
1049};
1050
1051/* Helper function called via walk_tree, to diagnose uses
1052 of associated loop IVs inside of lb, b and incr expressions
1053 of OpenMP loops. */
1054
1055static tree
1056c_omp_check_loop_iv_r (tree *tp, int *walk_subtrees, void *data)
1057{
1058 struct c_omp_check_loop_iv_data *d
1059 = (struct c_omp_check_loop_iv_data *) data;
1060 if (DECL_P (*tp))
1061 {
1062 int i;
1063 for (i = 0; i < TREE_VEC_LENGTH (d->declv); i++)
0b27c3ed
JJ
1064 if (*tp == TREE_VEC_ELT (d->declv, i)
1065 || (TREE_CODE (TREE_VEC_ELT (d->declv, i)) == TREE_LIST
28567c40
JJ
1066 && *tp == TREE_PURPOSE (TREE_VEC_ELT (d->declv, i)))
1067 || (TREE_CODE (TREE_VEC_ELT (d->declv, i)) == TREE_LIST
1068 && TREE_CHAIN (TREE_VEC_ELT (d->declv, i))
1069 && (TREE_CODE (TREE_CHAIN (TREE_VEC_ELT (d->declv, i)))
1070 == TREE_VEC)
1071 && *tp == TREE_VEC_ELT (TREE_CHAIN (TREE_VEC_ELT (d->declv,
1072 i)), 2)))
e01d41e5
JJ
1073 {
1074 location_t loc = d->expr_loc;
1075 if (loc == UNKNOWN_LOCATION)
1076 loc = d->stmt_loc;
1077 switch (d->kind)
1078 {
1079 case 0:
1080 error_at (loc, "initializer expression refers to "
1081 "iteration variable %qD", *tp);
1082 break;
1083 case 1:
1084 error_at (loc, "condition expression refers to "
1085 "iteration variable %qD", *tp);
1086 break;
1087 case 2:
1088 error_at (loc, "increment expression refers to "
1089 "iteration variable %qD", *tp);
1090 break;
1091 }
1092 d->fail = true;
1093 }
1094 }
1095 /* Don't walk dtors added by C++ wrap_cleanups_r. */
1096 else if (TREE_CODE (*tp) == TRY_CATCH_EXPR
1097 && TRY_CATCH_IS_CLEANUP (*tp))
1098 {
1099 *walk_subtrees = 0;
1100 return walk_tree_1 (&TREE_OPERAND (*tp, 0), c_omp_check_loop_iv_r, data,
1101 d->ppset, d->lh);
1102 }
1103
1104 return NULL_TREE;
1105}
1106
1107/* Diagnose invalid references to loop iterators in lb, b and incr
1108 expressions. */
1109
1110bool
1111c_omp_check_loop_iv (tree stmt, tree declv, walk_tree_lh lh)
1112{
1113 hash_set<tree> pset;
1114 struct c_omp_check_loop_iv_data data;
1115 int i;
1116
1117 data.declv = declv;
1118 data.fail = false;
1119 data.stmt_loc = EXPR_LOCATION (stmt);
1120 data.lh = lh;
1121 data.ppset = &pset;
1122 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (stmt)); i++)
1123 {
1124 tree init = TREE_VEC_ELT (OMP_FOR_INIT (stmt), i);
1125 gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
1126 tree decl = TREE_OPERAND (init, 0);
1127 tree cond = TREE_VEC_ELT (OMP_FOR_COND (stmt), i);
1128 gcc_assert (COMPARISON_CLASS_P (cond));
1129 gcc_assert (TREE_OPERAND (cond, 0) == decl);
1130 tree incr = TREE_VEC_ELT (OMP_FOR_INCR (stmt), i);
1131 data.expr_loc = EXPR_LOCATION (TREE_OPERAND (init, 1));
1132 data.kind = 0;
1133 walk_tree_1 (&TREE_OPERAND (init, 1),
1134 c_omp_check_loop_iv_r, &data, &pset, lh);
1135 /* Don't warn for C++ random access iterators here, the
1136 expression then involves the subtraction and always refers
1137 to the original value. The C++ FE needs to warn on those
1138 earlier. */
0b27c3ed
JJ
1139 if (decl == TREE_VEC_ELT (declv, i)
1140 || (TREE_CODE (TREE_VEC_ELT (declv, i)) == TREE_LIST
1141 && decl == TREE_PURPOSE (TREE_VEC_ELT (declv, i))))
e01d41e5
JJ
1142 {
1143 data.expr_loc = EXPR_LOCATION (cond);
1144 data.kind = 1;
1145 walk_tree_1 (&TREE_OPERAND (cond, 1),
1146 c_omp_check_loop_iv_r, &data, &pset, lh);
1147 }
1148 if (TREE_CODE (incr) == MODIFY_EXPR)
1149 {
1150 gcc_assert (TREE_OPERAND (incr, 0) == decl);
1151 incr = TREE_OPERAND (incr, 1);
1152 data.kind = 2;
1153 if (TREE_CODE (incr) == PLUS_EXPR
1154 && TREE_OPERAND (incr, 1) == decl)
1155 {
1156 data.expr_loc = EXPR_LOCATION (TREE_OPERAND (incr, 0));
1157 walk_tree_1 (&TREE_OPERAND (incr, 0),
1158 c_omp_check_loop_iv_r, &data, &pset, lh);
1159 }
1160 else
1161 {
1162 data.expr_loc = EXPR_LOCATION (TREE_OPERAND (incr, 1));
1163 walk_tree_1 (&TREE_OPERAND (incr, 1),
1164 c_omp_check_loop_iv_r, &data, &pset, lh);
1165 }
1166 }
1167 }
1168 return !data.fail;
1169}
1170
1171/* Similar, but allows to check the init or cond expressions individually. */
1172
1173bool
1174c_omp_check_loop_iv_exprs (location_t stmt_loc, tree declv, tree decl,
1175 tree init, tree cond, walk_tree_lh lh)
1176{
1177 hash_set<tree> pset;
1178 struct c_omp_check_loop_iv_data data;
1179
1180 data.declv = declv;
1181 data.fail = false;
1182 data.stmt_loc = stmt_loc;
1183 data.lh = lh;
1184 data.ppset = &pset;
1185 if (init)
1186 {
1187 data.expr_loc = EXPR_LOCATION (init);
1188 data.kind = 0;
1189 walk_tree_1 (&init,
1190 c_omp_check_loop_iv_r, &data, &pset, lh);
1191 }
1192 if (cond)
1193 {
1194 gcc_assert (COMPARISON_CLASS_P (cond));
1195 data.expr_loc = EXPR_LOCATION (init);
1196 data.kind = 1;
1197 if (TREE_OPERAND (cond, 0) == decl)
1198 walk_tree_1 (&TREE_OPERAND (cond, 1),
1199 c_omp_check_loop_iv_r, &data, &pset, lh);
1200 else
1201 walk_tree_1 (&TREE_OPERAND (cond, 0),
1202 c_omp_check_loop_iv_r, &data, &pset, lh);
1203 }
1204 return !data.fail;
1205}
1206
88bae6f4
TS
1207/* This function splits clauses for OpenACC combined loop
1208 constructs. OpenACC combined loop constructs are:
1209 #pragma acc kernels loop
e01d41e5 1210 #pragma acc parallel loop */
88bae6f4
TS
1211
1212tree
e7ff0319
CP
1213c_oacc_split_loop_clauses (tree clauses, tree *not_loop_clauses,
1214 bool is_parallel)
88bae6f4 1215{
e7ff0319 1216 tree next, loop_clauses, nc;
88bae6f4
TS
1217
1218 loop_clauses = *not_loop_clauses = NULL_TREE;
1219 for (; clauses ; clauses = next)
1220 {
1221 next = OMP_CLAUSE_CHAIN (clauses);
1222
1223 switch (OMP_CLAUSE_CODE (clauses))
1224 {
7a5e4956 1225 /* Loop clauses. */
88bae6f4 1226 case OMP_CLAUSE_COLLAPSE:
7a5e4956
CP
1227 case OMP_CLAUSE_TILE:
1228 case OMP_CLAUSE_GANG:
1229 case OMP_CLAUSE_WORKER:
1230 case OMP_CLAUSE_VECTOR:
1231 case OMP_CLAUSE_AUTO:
1232 case OMP_CLAUSE_SEQ:
1233 case OMP_CLAUSE_INDEPENDENT:
1234 case OMP_CLAUSE_PRIVATE:
e7ff0319
CP
1235 OMP_CLAUSE_CHAIN (clauses) = loop_clauses;
1236 loop_clauses = clauses;
1237 break;
1238
1239 /* Reductions must be duplicated on both constructs. */
f62bf092 1240 case OMP_CLAUSE_REDUCTION:
e7ff0319
CP
1241 if (is_parallel)
1242 {
1243 nc = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1244 OMP_CLAUSE_REDUCTION);
1245 OMP_CLAUSE_DECL (nc) = OMP_CLAUSE_DECL (clauses);
1246 OMP_CLAUSE_REDUCTION_CODE (nc)
1247 = OMP_CLAUSE_REDUCTION_CODE (clauses);
1248 OMP_CLAUSE_CHAIN (nc) = *not_loop_clauses;
1249 *not_loop_clauses = nc;
1250 }
1251
88bae6f4
TS
1252 OMP_CLAUSE_CHAIN (clauses) = loop_clauses;
1253 loop_clauses = clauses;
1254 break;
1255
7a5e4956 1256 /* Parallel/kernels clauses. */
88bae6f4
TS
1257 default:
1258 OMP_CLAUSE_CHAIN (clauses) = *not_loop_clauses;
1259 *not_loop_clauses = clauses;
1260 break;
1261 }
1262 }
1263
1264 return loop_clauses;
1265}
1266
1267/* This function attempts to split or duplicate clauses for OpenMP
554a530f 1268 combined/composite constructs. Right now there are 30 different
acf0174b
JJ
1269 constructs. CODE is the innermost construct in the combined construct,
1270 and MASK allows to determine which constructs are combined together,
1271 as every construct has at least one clause that no other construct
28567c40
JJ
1272 has (except for OMP_SECTIONS, but that can be only combined with parallel,
1273 and OMP_MASTER, which doesn't have any clauses at all).
88bae6f4 1274 OpenMP combined/composite constructs are:
acf0174b
JJ
1275 #pragma omp distribute parallel for
1276 #pragma omp distribute parallel for simd
d9a6bd32
JJ
1277 #pragma omp distribute simd
1278 #pragma omp for simd
28567c40
JJ
1279 #pragma omp master taskloop
1280 #pragma omp master taskloop simd
d9a6bd32
JJ
1281 #pragma omp parallel for
1282 #pragma omp parallel for simd
554a530f 1283 #pragma omp parallel loop
28567c40
JJ
1284 #pragma omp parallel master
1285 #pragma omp parallel master taskloop
1286 #pragma omp parallel master taskloop simd
d9a6bd32
JJ
1287 #pragma omp parallel sections
1288 #pragma omp target parallel
1289 #pragma omp target parallel for
1290 #pragma omp target parallel for simd
554a530f 1291 #pragma omp target parallel loop
acf0174b
JJ
1292 #pragma omp target teams
1293 #pragma omp target teams distribute
1294 #pragma omp target teams distribute parallel for
d9a6bd32
JJ
1295 #pragma omp target teams distribute parallel for simd
1296 #pragma omp target teams distribute simd
554a530f 1297 #pragma omp target teams loop
d9a6bd32
JJ
1298 #pragma omp target simd
1299 #pragma omp taskloop simd
1300 #pragma omp teams distribute
1301 #pragma omp teams distribute parallel for
1302 #pragma omp teams distribute parallel for simd
554a530f
JJ
1303 #pragma omp teams distribute simd
1304 #pragma omp teams loop */
953ff289
DN
1305
1306void
acf0174b
JJ
1307c_omp_split_clauses (location_t loc, enum tree_code code,
1308 omp_clause_mask mask, tree clauses, tree *cclauses)
953ff289 1309{
acf0174b
JJ
1310 tree next, c;
1311 enum c_omp_clause_split s;
1312 int i;
953ff289 1313
acf0174b
JJ
1314 for (i = 0; i < C_OMP_CLAUSE_SPLIT_COUNT; i++)
1315 cclauses[i] = NULL;
1316 /* Add implicit nowait clause on
1317 #pragma omp parallel {for,for simd,sections}. */
acd15a28 1318 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
acf0174b
JJ
1319 switch (code)
1320 {
1321 case OMP_FOR:
1322 case OMP_SIMD:
28567c40
JJ
1323 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)) != 0)
1324 cclauses[C_OMP_CLAUSE_SPLIT_FOR]
1325 = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
acf0174b
JJ
1326 break;
1327 case OMP_SECTIONS:
1328 cclauses[C_OMP_CLAUSE_SPLIT_SECTIONS]
1329 = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
1330 break;
1331 default:
1332 break;
1333 }
953ff289
DN
1334
1335 for (; clauses ; clauses = next)
1336 {
1337 next = OMP_CLAUSE_CHAIN (clauses);
1338
aaf46ef9 1339 switch (OMP_CLAUSE_CODE (clauses))
953ff289 1340 {
acf0174b
JJ
1341 /* First the clauses that are unique to some constructs. */
1342 case OMP_CLAUSE_DEVICE:
1343 case OMP_CLAUSE_MAP:
d9a6bd32
JJ
1344 case OMP_CLAUSE_IS_DEVICE_PTR:
1345 case OMP_CLAUSE_DEFAULTMAP:
00631022 1346 case OMP_CLAUSE_DEPEND:
acf0174b
JJ
1347 s = C_OMP_CLAUSE_SPLIT_TARGET;
1348 break;
1349 case OMP_CLAUSE_NUM_TEAMS:
1350 case OMP_CLAUSE_THREAD_LIMIT:
1351 s = C_OMP_CLAUSE_SPLIT_TEAMS;
1352 break;
1353 case OMP_CLAUSE_DIST_SCHEDULE:
1354 s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
1355 break;
953ff289 1356 case OMP_CLAUSE_COPYIN:
953ff289 1357 case OMP_CLAUSE_NUM_THREADS:
acf0174b
JJ
1358 case OMP_CLAUSE_PROC_BIND:
1359 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
953ff289 1360 break;
953ff289 1361 case OMP_CLAUSE_ORDERED:
acf0174b
JJ
1362 s = C_OMP_CLAUSE_SPLIT_FOR;
1363 break;
d9a6bd32
JJ
1364 case OMP_CLAUSE_SCHEDULE:
1365 s = C_OMP_CLAUSE_SPLIT_FOR;
1366 if (code != OMP_SIMD)
1367 OMP_CLAUSE_SCHEDULE_SIMD (clauses) = 0;
1368 break;
acf0174b 1369 case OMP_CLAUSE_SAFELEN:
d9a6bd32 1370 case OMP_CLAUSE_SIMDLEN:
acf0174b 1371 case OMP_CLAUSE_ALIGNED:
28567c40 1372 case OMP_CLAUSE_NONTEMPORAL:
acf0174b
JJ
1373 s = C_OMP_CLAUSE_SPLIT_SIMD;
1374 break;
d9a6bd32
JJ
1375 case OMP_CLAUSE_GRAINSIZE:
1376 case OMP_CLAUSE_NUM_TASKS:
1377 case OMP_CLAUSE_FINAL:
1378 case OMP_CLAUSE_UNTIED:
1379 case OMP_CLAUSE_MERGEABLE:
1380 case OMP_CLAUSE_NOGROUP:
1381 case OMP_CLAUSE_PRIORITY:
1382 s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
1383 break;
554a530f
JJ
1384 case OMP_CLAUSE_BIND:
1385 s = C_OMP_CLAUSE_SPLIT_LOOP;
1386 break;
1387 /* Duplicate this to all of taskloop, distribute, for, simd and
1388 loop. */
a68ab351 1389 case OMP_CLAUSE_COLLAPSE:
acf0174b
JJ
1390 if (code == OMP_SIMD)
1391 {
d9a6bd32
JJ
1392 if ((mask & ((OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)
1393 | (OMP_CLAUSE_MASK_1
1394 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)
1395 | (OMP_CLAUSE_MASK_1
1396 << PRAGMA_OMP_CLAUSE_NOGROUP))) != 0)
1397 {
1398 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1399 OMP_CLAUSE_COLLAPSE);
1400 OMP_CLAUSE_COLLAPSE_EXPR (c)
1401 = OMP_CLAUSE_COLLAPSE_EXPR (clauses);
1402 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
1403 cclauses[C_OMP_CLAUSE_SPLIT_SIMD] = c;
1404 }
1405 else
1406 {
1407 /* This must be #pragma omp target simd */
1408 s = C_OMP_CLAUSE_SPLIT_SIMD;
1409 break;
1410 }
acf0174b 1411 }
acd15a28 1412 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)) != 0)
acf0174b 1413 {
acd15a28
JJ
1414 if ((mask & (OMP_CLAUSE_MASK_1
1415 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
acf0174b
JJ
1416 {
1417 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1418 OMP_CLAUSE_COLLAPSE);
1419 OMP_CLAUSE_COLLAPSE_EXPR (c)
1420 = OMP_CLAUSE_COLLAPSE_EXPR (clauses);
1421 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
1422 cclauses[C_OMP_CLAUSE_SPLIT_FOR] = c;
1423 s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
1424 }
1425 else
1426 s = C_OMP_CLAUSE_SPLIT_FOR;
1427 }
d9a6bd32
JJ
1428 else if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP))
1429 != 0)
1430 s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
554a530f
JJ
1431 else if (code == OMP_LOOP)
1432 s = C_OMP_CLAUSE_SPLIT_LOOP;
acf0174b
JJ
1433 else
1434 s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
1435 break;
28567c40
JJ
1436 /* Private clause is supported on all constructs but master,
1437 it is enough to put it on the innermost one other than master. For
acf0174b
JJ
1438 #pragma omp {for,sections} put it on parallel though,
1439 as that's what we did for OpenMP 3.1. */
1440 case OMP_CLAUSE_PRIVATE:
1441 switch (code)
1442 {
1443 case OMP_SIMD: s = C_OMP_CLAUSE_SPLIT_SIMD; break;
1444 case OMP_FOR: case OMP_SECTIONS:
1445 case OMP_PARALLEL: s = C_OMP_CLAUSE_SPLIT_PARALLEL; break;
1446 case OMP_DISTRIBUTE: s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE; break;
1447 case OMP_TEAMS: s = C_OMP_CLAUSE_SPLIT_TEAMS; break;
28567c40
JJ
1448 case OMP_MASTER: s = C_OMP_CLAUSE_SPLIT_PARALLEL; break;
1449 case OMP_TASKLOOP: s = C_OMP_CLAUSE_SPLIT_TASKLOOP; break;
554a530f 1450 case OMP_LOOP: s = C_OMP_CLAUSE_SPLIT_LOOP; break;
acf0174b
JJ
1451 default: gcc_unreachable ();
1452 }
1453 break;
1454 /* Firstprivate clause is supported on all constructs but
554a530f
JJ
1455 simd, master and loop. Put it on the outermost of those and
1456 duplicate on teams and parallel. */
acf0174b 1457 case OMP_CLAUSE_FIRSTPRIVATE:
d9a6bd32
JJ
1458 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP))
1459 != 0)
1460 {
1461 if (code == OMP_SIMD
1462 && (mask & ((OMP_CLAUSE_MASK_1
1463 << PRAGMA_OMP_CLAUSE_NUM_THREADS)
1464 | (OMP_CLAUSE_MASK_1
1465 << PRAGMA_OMP_CLAUSE_NUM_TEAMS))) == 0)
1466 {
1467 /* This must be #pragma omp target simd. */
1468 s = C_OMP_CLAUSE_SPLIT_TARGET;
1469 break;
1470 }
1471 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1472 OMP_CLAUSE_FIRSTPRIVATE);
1473 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
1474 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
1475 cclauses[C_OMP_CLAUSE_SPLIT_TARGET] = c;
1476 }
acd15a28
JJ
1477 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS))
1478 != 0)
acf0174b 1479 {
acd15a28
JJ
1480 if ((mask & ((OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS)
1481 | (OMP_CLAUSE_MASK_1
1482 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE))) != 0)
acf0174b
JJ
1483 {
1484 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1485 OMP_CLAUSE_FIRSTPRIVATE);
1486 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
1487 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL];
1488 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] = c;
acd15a28
JJ
1489 if ((mask & (OMP_CLAUSE_MASK_1
1490 << PRAGMA_OMP_CLAUSE_NUM_TEAMS)) != 0)
acf0174b
JJ
1491 s = C_OMP_CLAUSE_SPLIT_TEAMS;
1492 else
1493 s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
1494 }
28567c40
JJ
1495 else if ((mask & (OMP_CLAUSE_MASK_1
1496 << PRAGMA_OMP_CLAUSE_NOGROUP)) != 0)
1497 /* This must be
1498 #pragma omp parallel master taskloop{, simd}. */
1499 s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
acf0174b
JJ
1500 else
1501 /* This must be
554a530f 1502 #pragma omp parallel{, for{, simd}, sections,loop}
d9a6bd32
JJ
1503 or
1504 #pragma omp target parallel. */
acf0174b
JJ
1505 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1506 }
acd15a28
JJ
1507 else if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS))
1508 != 0)
acf0174b 1509 {
9cf32741 1510 /* This must be one of
554a530f 1511 #pragma omp {,target }teams {distribute,loop}
9cf32741
JJ
1512 #pragma omp target teams
1513 #pragma omp {,target }teams distribute simd. */
1514 gcc_assert (code == OMP_DISTRIBUTE
554a530f 1515 || code == OMP_LOOP
9cf32741
JJ
1516 || code == OMP_TEAMS
1517 || code == OMP_SIMD);
acf0174b
JJ
1518 s = C_OMP_CLAUSE_SPLIT_TEAMS;
1519 }
acd15a28
JJ
1520 else if ((mask & (OMP_CLAUSE_MASK_1
1521 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
acf0174b
JJ
1522 {
1523 /* This must be #pragma omp distribute simd. */
1524 gcc_assert (code == OMP_SIMD);
d9a6bd32
JJ
1525 s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
1526 }
1527 else if ((mask & (OMP_CLAUSE_MASK_1
1528 << PRAGMA_OMP_CLAUSE_NOGROUP)) != 0)
1529 {
28567c40
JJ
1530 /* This must be #pragma omp {,{,parallel }master }taskloop simd
1531 or
1532 #pragma omp {,parallel }master taskloop. */
1533 gcc_assert (code == OMP_SIMD || code == OMP_TASKLOOP);
d9a6bd32 1534 s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
acf0174b
JJ
1535 }
1536 else
1537 {
1538 /* This must be #pragma omp for simd. */
1539 gcc_assert (code == OMP_SIMD);
1540 s = C_OMP_CLAUSE_SPLIT_FOR;
1541 }
1542 break;
554a530f
JJ
1543 /* Lastprivate is allowed on distribute, for, sections, taskloop, loop
1544 and simd. In parallel {for{, simd},sections} we actually want to
1545 put it on parallel rather than for or sections. */
acf0174b 1546 case OMP_CLAUSE_LASTPRIVATE:
e01d41e5
JJ
1547 if (code == OMP_DISTRIBUTE)
1548 {
1549 s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
1550 break;
1551 }
1552 if ((mask & (OMP_CLAUSE_MASK_1
1553 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
1554 {
1555 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1556 OMP_CLAUSE_LASTPRIVATE);
1557 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
1558 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
28567c40
JJ
1559 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c)
1560 = OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (clauses);
e01d41e5
JJ
1561 cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE] = c;
1562 }
acf0174b
JJ
1563 if (code == OMP_FOR || code == OMP_SECTIONS)
1564 {
acd15a28
JJ
1565 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS))
1566 != 0)
acf0174b
JJ
1567 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1568 else
1569 s = C_OMP_CLAUSE_SPLIT_FOR;
1570 break;
1571 }
28567c40
JJ
1572 if (code == OMP_TASKLOOP)
1573 {
1574 s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
1575 break;
1576 }
554a530f
JJ
1577 if (code == OMP_LOOP)
1578 {
1579 s = C_OMP_CLAUSE_SPLIT_LOOP;
1580 break;
1581 }
acf0174b 1582 gcc_assert (code == OMP_SIMD);
acd15a28 1583 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)) != 0)
acf0174b
JJ
1584 {
1585 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1586 OMP_CLAUSE_LASTPRIVATE);
1587 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
28567c40
JJ
1588 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c)
1589 = OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (clauses);
acd15a28
JJ
1590 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS))
1591 != 0)
acf0174b
JJ
1592 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1593 else
1594 s = C_OMP_CLAUSE_SPLIT_FOR;
1595 OMP_CLAUSE_CHAIN (c) = cclauses[s];
1596 cclauses[s] = c;
1597 }
28567c40
JJ
1598 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP)) != 0)
1599 {
1600 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1601 OMP_CLAUSE_LASTPRIVATE);
1602 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
1603 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c)
1604 = OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (clauses);
1605 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
1606 cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP] = c;
1607 }
acf0174b
JJ
1608 s = C_OMP_CLAUSE_SPLIT_SIMD;
1609 break;
d9a6bd32
JJ
1610 /* Shared and default clauses are allowed on parallel, teams and
1611 taskloop. */
acf0174b
JJ
1612 case OMP_CLAUSE_SHARED:
1613 case OMP_CLAUSE_DEFAULT:
d9a6bd32
JJ
1614 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP))
1615 != 0)
acf0174b 1616 {
28567c40
JJ
1617 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS))
1618 != 0)
1619 {
1620 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1621 OMP_CLAUSE_CODE (clauses));
1622 if (OMP_CLAUSE_CODE (clauses) == OMP_CLAUSE_SHARED)
1623 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
1624 else
1625 OMP_CLAUSE_DEFAULT_KIND (c)
1626 = OMP_CLAUSE_DEFAULT_KIND (clauses);
1627 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL];
1628 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] = c;
1629 }
d9a6bd32 1630 s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
acf0174b
JJ
1631 break;
1632 }
acd15a28
JJ
1633 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS))
1634 != 0)
acf0174b 1635 {
d9a6bd32
JJ
1636 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS))
1637 == 0)
1638 {
1639 s = C_OMP_CLAUSE_SPLIT_TEAMS;
1640 break;
1641 }
acf0174b
JJ
1642 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1643 OMP_CLAUSE_CODE (clauses));
1644 if (OMP_CLAUSE_CODE (clauses) == OMP_CLAUSE_SHARED)
1645 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
1646 else
1647 OMP_CLAUSE_DEFAULT_KIND (c)
1648 = OMP_CLAUSE_DEFAULT_KIND (clauses);
1649 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
1650 cclauses[C_OMP_CLAUSE_SPLIT_TEAMS] = c;
acf0174b
JJ
1651 }
1652 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1653 break;
554a530f 1654 /* order clauses are allowed on for, simd and loop. */
1fdd6f04
JJ
1655 case OMP_CLAUSE_ORDER:
1656 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)) != 0)
1657 {
1658 if (code == OMP_SIMD)
1659 {
1660 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1661 OMP_CLAUSE_ORDER);
1662 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
1663 cclauses[C_OMP_CLAUSE_SPLIT_FOR] = c;
1664 s = C_OMP_CLAUSE_SPLIT_SIMD;
1665 }
1666 else
1667 s = C_OMP_CLAUSE_SPLIT_FOR;
1668 }
554a530f
JJ
1669 else if (code == OMP_LOOP)
1670 s = C_OMP_CLAUSE_SPLIT_LOOP;
1fdd6f04
JJ
1671 else
1672 s = C_OMP_CLAUSE_SPLIT_SIMD;
1673 break;
554a530f
JJ
1674 /* Reduction is allowed on simd, for, parallel, sections, taskloop,
1675 teams and loop. Duplicate it on all of them, but omit on for or
83eb9522 1676 sections if parallel is present (unless inscan, in that case
554a530f 1677 omit on parallel). If taskloop or loop is combined with
28567c40 1678 parallel, omit it on parallel. */
acf0174b 1679 case OMP_CLAUSE_REDUCTION:
28567c40
JJ
1680 if (OMP_CLAUSE_REDUCTION_TASK (clauses))
1681 {
554a530f 1682 if (code == OMP_SIMD || code == OMP_LOOP)
28567c40
JJ
1683 {
1684 error_at (OMP_CLAUSE_LOCATION (clauses),
1685 "invalid %<task%> reduction modifier on construct "
554a530f 1686 "combined with %<simd%> or %<loop%>");
28567c40
JJ
1687 OMP_CLAUSE_REDUCTION_TASK (clauses) = 0;
1688 }
1689 else if (code != OMP_SECTIONS
1690 && (mask & (OMP_CLAUSE_MASK_1
1a888209 1691 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) == 0
28567c40
JJ
1692 && (mask & (OMP_CLAUSE_MASK_1
1693 << PRAGMA_OMP_CLAUSE_SCHEDULE)) == 0)
1694 {
1695 error_at (OMP_CLAUSE_LOCATION (clauses),
1696 "invalid %<task%> reduction modifier on construct "
1697 "not combined with %<parallel%>, %<for%> or "
1698 "%<sections%>");
1699 OMP_CLAUSE_REDUCTION_TASK (clauses) = 0;
1700 }
1701 }
bf38f7e9
JJ
1702 if (OMP_CLAUSE_REDUCTION_INSCAN (clauses)
1703 && ((mask & ((OMP_CLAUSE_MASK_1
1704 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)
1705 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)))
1706 != 0))
1707 {
1708 error_at (OMP_CLAUSE_LOCATION (clauses),
1709 "%<inscan%> %<reduction%> clause on construct other "
1710 "than %<for%>, %<simd%>, %<for simd%>, "
1711 "%<parallel for%>, %<parallel for simd%>");
1712 OMP_CLAUSE_REDUCTION_INSCAN (clauses) = 0;
1713 }
acd15a28 1714 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)) != 0)
acf0174b 1715 {
d9a6bd32
JJ
1716 if (code == OMP_SIMD)
1717 {
1718 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1719 OMP_CLAUSE_REDUCTION);
1720 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
1721 OMP_CLAUSE_REDUCTION_CODE (c)
1722 = OMP_CLAUSE_REDUCTION_CODE (clauses);
1723 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
1724 = OMP_CLAUSE_REDUCTION_PLACEHOLDER (clauses);
1725 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c)
1726 = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (clauses);
bf38f7e9
JJ
1727 OMP_CLAUSE_REDUCTION_INSCAN (c)
1728 = OMP_CLAUSE_REDUCTION_INSCAN (clauses);
d9a6bd32
JJ
1729 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
1730 cclauses[C_OMP_CLAUSE_SPLIT_SIMD] = c;
1731 }
acd15a28
JJ
1732 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS))
1733 != 0)
acf0174b
JJ
1734 {
1735 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1736 OMP_CLAUSE_REDUCTION);
1737 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
1738 OMP_CLAUSE_REDUCTION_CODE (c)
1739 = OMP_CLAUSE_REDUCTION_CODE (clauses);
1740 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
1741 = OMP_CLAUSE_REDUCTION_PLACEHOLDER (clauses);
d9a6bd32
JJ
1742 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c)
1743 = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (clauses);
bf38f7e9
JJ
1744 OMP_CLAUSE_REDUCTION_INSCAN (c)
1745 = OMP_CLAUSE_REDUCTION_INSCAN (clauses);
28567c40
JJ
1746 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
1747 cclauses[C_OMP_CLAUSE_SPLIT_TEAMS] = c;
1748 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
acf0174b 1749 }
acd15a28 1750 else if ((mask & (OMP_CLAUSE_MASK_1
83eb9522
JJ
1751 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0
1752 && !OMP_CLAUSE_REDUCTION_INSCAN (clauses))
acf0174b
JJ
1753 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1754 else
1755 s = C_OMP_CLAUSE_SPLIT_FOR;
1756 }
28567c40
JJ
1757 else if (code == OMP_SECTIONS
1758 || code == OMP_PARALLEL
1759 || code == OMP_MASTER)
acf0174b 1760 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
28567c40
JJ
1761 else if (code == OMP_TASKLOOP)
1762 s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
554a530f
JJ
1763 else if (code == OMP_LOOP)
1764 s = C_OMP_CLAUSE_SPLIT_LOOP;
d9a6bd32 1765 else if (code == OMP_SIMD)
28567c40
JJ
1766 {
1767 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP))
1768 != 0)
1769 {
1770 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1771 OMP_CLAUSE_REDUCTION);
1772 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
1773 OMP_CLAUSE_REDUCTION_CODE (c)
1774 = OMP_CLAUSE_REDUCTION_CODE (clauses);
1775 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
1776 = OMP_CLAUSE_REDUCTION_PLACEHOLDER (clauses);
1777 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c)
1778 = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (clauses);
bf38f7e9
JJ
1779 OMP_CLAUSE_REDUCTION_INSCAN (c)
1780 = OMP_CLAUSE_REDUCTION_INSCAN (clauses);
28567c40
JJ
1781 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
1782 cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP] = c;
1783 }
1784 s = C_OMP_CLAUSE_SPLIT_SIMD;
1785 }
acf0174b
JJ
1786 else
1787 s = C_OMP_CLAUSE_SPLIT_TEAMS;
1788 break;
28567c40
JJ
1789 case OMP_CLAUSE_IN_REDUCTION:
1790 /* in_reduction on taskloop simd becomes reduction on the simd
1791 and keeps being in_reduction on taskloop. */
1792 if (code == OMP_SIMD)
1793 {
1794 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1795 OMP_CLAUSE_REDUCTION);
1796 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
1797 OMP_CLAUSE_REDUCTION_CODE (c)
1798 = OMP_CLAUSE_REDUCTION_CODE (clauses);
1799 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
1800 = OMP_CLAUSE_REDUCTION_PLACEHOLDER (clauses);
1801 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c)
1802 = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (clauses);
1803 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
1804 cclauses[C_OMP_CLAUSE_SPLIT_SIMD] = c;
1805 }
1806 s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
1807 break;
acf0174b 1808 case OMP_CLAUSE_IF:
28567c40
JJ
1809 if (OMP_CLAUSE_IF_MODIFIER (clauses) != ERROR_MARK)
1810 {
1811 s = C_OMP_CLAUSE_SPLIT_COUNT;
1812 switch (OMP_CLAUSE_IF_MODIFIER (clauses))
1813 {
1814 case OMP_PARALLEL:
1815 if ((mask & (OMP_CLAUSE_MASK_1
1816 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
1817 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1818 break;
1819 case OMP_SIMD:
1820 if (code == OMP_SIMD)
1821 s = C_OMP_CLAUSE_SPLIT_SIMD;
1822 break;
1823 case OMP_TASKLOOP:
1824 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP))
1825 != 0)
1826 s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
1827 break;
1828 case OMP_TARGET:
1829 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP))
1830 != 0)
1831 s = C_OMP_CLAUSE_SPLIT_TARGET;
1832 break;
1833 default:
1834 break;
1835 }
1836 if (s != C_OMP_CLAUSE_SPLIT_COUNT)
1837 break;
1838 /* Error-recovery here, invalid if-modifier specified, add the
1839 clause to just one construct. */
1840 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) != 0)
1841 s = C_OMP_CLAUSE_SPLIT_TARGET;
1842 else if ((mask & (OMP_CLAUSE_MASK_1
1843 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
1844 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1845 else if ((mask & (OMP_CLAUSE_MASK_1
1846 << PRAGMA_OMP_CLAUSE_NOGROUP)) != 0)
1847 s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
1848 else if (code == OMP_SIMD)
1849 s = C_OMP_CLAUSE_SPLIT_SIMD;
1850 else
1851 gcc_unreachable ();
1852 break;
1853 }
1854 /* Otherwise, duplicate if clause to all constructs. */
1855 if (code == OMP_SIMD)
1856 {
1857 if ((mask & ((OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)
1858 | (OMP_CLAUSE_MASK_1
1859 << PRAGMA_OMP_CLAUSE_NUM_THREADS)
1860 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP)))
1861 != 0)
1862 {
1863 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1864 OMP_CLAUSE_IF);
1865 OMP_CLAUSE_IF_MODIFIER (c)
1866 = OMP_CLAUSE_IF_MODIFIER (clauses);
1867 OMP_CLAUSE_IF_EXPR (c) = OMP_CLAUSE_IF_EXPR (clauses);
1868 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
1869 cclauses[C_OMP_CLAUSE_SPLIT_SIMD] = c;
1870 }
1871 else
1872 {
1873 s = C_OMP_CLAUSE_SPLIT_SIMD;
1874 break;
1875 }
1876 }
d9a6bd32 1877 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP))
acd15a28 1878 != 0)
28567c40
JJ
1879 {
1880 if ((mask & (OMP_CLAUSE_MASK_1
1881 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
1882 {
1883 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1884 OMP_CLAUSE_IF);
1885 OMP_CLAUSE_IF_MODIFIER (c)
1886 = OMP_CLAUSE_IF_MODIFIER (clauses);
1887 OMP_CLAUSE_IF_EXPR (c) = OMP_CLAUSE_IF_EXPR (clauses);
1888 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
1889 cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP] = c;
1890 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1891 }
1892 else
1893 s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
1894 }
d9a6bd32
JJ
1895 else if ((mask & (OMP_CLAUSE_MASK_1
1896 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
1897 {
1898 if ((mask & (OMP_CLAUSE_MASK_1
1899 << PRAGMA_OMP_CLAUSE_MAP)) != 0)
1900 {
28567c40
JJ
1901 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1902 OMP_CLAUSE_IF);
1903 OMP_CLAUSE_IF_MODIFIER (c)
1904 = OMP_CLAUSE_IF_MODIFIER (clauses);
1905 OMP_CLAUSE_IF_EXPR (c) = OMP_CLAUSE_IF_EXPR (clauses);
1906 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
1907 cclauses[C_OMP_CLAUSE_SPLIT_TARGET] = c;
1908 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
d9a6bd32
JJ
1909 }
1910 else
1911 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1912 }
acf0174b
JJ
1913 else
1914 s = C_OMP_CLAUSE_SPLIT_TARGET;
953ff289 1915 break;
d9a6bd32
JJ
1916 case OMP_CLAUSE_LINEAR:
1917 /* Linear clause is allowed on simd and for. Put it on the
1918 innermost construct. */
1919 if (code == OMP_SIMD)
1920 s = C_OMP_CLAUSE_SPLIT_SIMD;
1921 else
1922 s = C_OMP_CLAUSE_SPLIT_FOR;
1923 break;
00631022
JJ
1924 case OMP_CLAUSE_NOWAIT:
1925 /* Nowait clause is allowed on target, for and sections, but
1926 is not allowed on parallel for or parallel sections. Therefore,
1927 put it on target construct if present, because that can only
1928 be combined with parallel for{, simd} and not with for{, simd},
1929 otherwise to the worksharing construct. */
1930 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP))
1931 != 0)
1932 s = C_OMP_CLAUSE_SPLIT_TARGET;
1933 else
1934 s = C_OMP_CLAUSE_SPLIT_FOR;
1935 break;
953ff289
DN
1936 default:
1937 gcc_unreachable ();
1938 }
acf0174b
JJ
1939 OMP_CLAUSE_CHAIN (clauses) = cclauses[s];
1940 cclauses[s] = clauses;
953ff289 1941 }
595278be
MM
1942
1943 if (!flag_checking)
1944 return;
1945
d9a6bd32
JJ
1946 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) == 0)
1947 gcc_assert (cclauses[C_OMP_CLAUSE_SPLIT_TARGET] == NULL_TREE);
1948 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS)) == 0)
1949 gcc_assert (cclauses[C_OMP_CLAUSE_SPLIT_TEAMS] == NULL_TREE);
1950 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) == 0)
1951 gcc_assert (cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE] == NULL_TREE);
1952 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) == 0)
1953 gcc_assert (cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] == NULL_TREE);
1954 if ((mask & ((OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)
1955 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP))) == 0
554a530f
JJ
1956 && code != OMP_SECTIONS
1957 && code != OMP_LOOP)
d9a6bd32
JJ
1958 gcc_assert (cclauses[C_OMP_CLAUSE_SPLIT_FOR] == NULL_TREE);
1959 if (code != OMP_SIMD)
1960 gcc_assert (cclauses[C_OMP_CLAUSE_SPLIT_SIMD] == NULL_TREE);
953ff289
DN
1961}
1962
acf0174b
JJ
1963
1964/* qsort callback to compare #pragma omp declare simd clauses. */
1965
1966static int
1967c_omp_declare_simd_clause_cmp (const void *p, const void *q)
1968{
1969 tree a = *(const tree *) p;
1970 tree b = *(const tree *) q;
1971 if (OMP_CLAUSE_CODE (a) != OMP_CLAUSE_CODE (b))
1972 {
1973 if (OMP_CLAUSE_CODE (a) > OMP_CLAUSE_CODE (b))
1974 return -1;
1975 return 1;
1976 }
1977 if (OMP_CLAUSE_CODE (a) != OMP_CLAUSE_SIMDLEN
1978 && OMP_CLAUSE_CODE (a) != OMP_CLAUSE_INBRANCH
1979 && OMP_CLAUSE_CODE (a) != OMP_CLAUSE_NOTINBRANCH)
1980 {
9439e9a1
RS
1981 int c = tree_to_shwi (OMP_CLAUSE_DECL (a));
1982 int d = tree_to_shwi (OMP_CLAUSE_DECL (b));
acf0174b
JJ
1983 if (c < d)
1984 return 1;
1985 if (c > d)
1986 return -1;
1987 }
1988 return 0;
1989}
1990
1991/* Change PARM_DECLs in OMP_CLAUSE_DECL of #pragma omp declare simd
1992 CLAUSES on FNDECL into argument indexes and sort them. */
1993
1994tree
1995c_omp_declare_simd_clauses_to_numbers (tree parms, tree clauses)
1996{
1997 tree c;
1998 vec<tree> clvec = vNULL;
1999
2000 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
2001 {
2002 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_SIMDLEN
2003 && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_INBRANCH
2004 && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_NOTINBRANCH)
2005 {
2006 tree decl = OMP_CLAUSE_DECL (c);
2007 tree arg;
2008 int idx;
2009 for (arg = parms, idx = 0; arg;
2010 arg = TREE_CHAIN (arg), idx++)
2011 if (arg == decl)
2012 break;
2013 if (arg == NULL_TREE)
2014 {
2015 error_at (OMP_CLAUSE_LOCATION (c),
94e7f906 2016 "%qD is not a function argument", decl);
acf0174b
JJ
2017 continue;
2018 }
2019 OMP_CLAUSE_DECL (c) = build_int_cst (integer_type_node, idx);
e01d41e5
JJ
2020 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
2021 && OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (c))
2022 {
2023 decl = OMP_CLAUSE_LINEAR_STEP (c);
2024 for (arg = parms, idx = 0; arg;
2025 arg = TREE_CHAIN (arg), idx++)
2026 if (arg == decl)
2027 break;
2028 if (arg == NULL_TREE)
2029 {
2030 error_at (OMP_CLAUSE_LOCATION (c),
94e7f906 2031 "%qD is not a function argument", decl);
e01d41e5
JJ
2032 continue;
2033 }
2034 OMP_CLAUSE_LINEAR_STEP (c)
2035 = build_int_cst (integer_type_node, idx);
2036 }
acf0174b
JJ
2037 }
2038 clvec.safe_push (c);
2039 }
2040 if (!clvec.is_empty ())
2041 {
2042 unsigned int len = clvec.length (), i;
2043 clvec.qsort (c_omp_declare_simd_clause_cmp);
2044 clauses = clvec[0];
2045 for (i = 0; i < len; i++)
2046 OMP_CLAUSE_CHAIN (clvec[i]) = (i < len - 1) ? clvec[i + 1] : NULL_TREE;
2047 }
b03b462f
JJ
2048 else
2049 clauses = NULL_TREE;
acf0174b
JJ
2050 clvec.release ();
2051 return clauses;
2052}
2053
2054/* Change argument indexes in CLAUSES of FNDECL back to PARM_DECLs. */
2055
2056void
2057c_omp_declare_simd_clauses_to_decls (tree fndecl, tree clauses)
2058{
2059 tree c;
2060
2061 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
2062 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_SIMDLEN
2063 && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_INBRANCH
2064 && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_NOTINBRANCH)
2065 {
9439e9a1 2066 int idx = tree_to_shwi (OMP_CLAUSE_DECL (c)), i;
acf0174b
JJ
2067 tree arg;
2068 for (arg = DECL_ARGUMENTS (fndecl), i = 0; arg;
2069 arg = TREE_CHAIN (arg), i++)
2070 if (i == idx)
2071 break;
2072 gcc_assert (arg);
2073 OMP_CLAUSE_DECL (c) = arg;
e01d41e5
JJ
2074 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
2075 && OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (c))
2076 {
2077 idx = tree_to_shwi (OMP_CLAUSE_LINEAR_STEP (c));
2078 for (arg = DECL_ARGUMENTS (fndecl), i = 0; arg;
2079 arg = TREE_CHAIN (arg), i++)
2080 if (i == idx)
2081 break;
2082 gcc_assert (arg);
2083 OMP_CLAUSE_LINEAR_STEP (c) = arg;
2084 }
acf0174b
JJ
2085 }
2086}
2087
59bc434a
JJ
2088/* Return true for __func__ and similar function-local predefined
2089 variables (which are in OpenMP predetermined shared, allowed in
2090 shared/firstprivate clauses). */
2091
2092bool
2093c_omp_predefined_variable (tree decl)
2094{
2095 if (VAR_P (decl)
2096 && DECL_ARTIFICIAL (decl)
2097 && TREE_READONLY (decl)
2098 && TREE_STATIC (decl)
2099 && DECL_NAME (decl)
2100 && (DECL_NAME (decl) == ridpointers[RID_C99_FUNCTION_NAME]
2101 || DECL_NAME (decl) == ridpointers[RID_FUNCTION_NAME]
2102 || DECL_NAME (decl) == ridpointers[RID_PRETTY_FUNCTION_NAME]))
2103 return true;
2104 return false;
2105}
2106
93535a2b
TB
2107/* OMP_CLAUSE_DEFAULT_UNSPECIFIED unless OpenMP sharing attribute of DECL
2108 is predetermined. */
953ff289
DN
2109
2110enum omp_clause_default_kind
2111c_omp_predetermined_sharing (tree decl)
2112{
1c9ee609
JJ
2113 /* Predetermine artificial variables holding integral values, those
2114 are usually result of gimplify_one_sizepos or SAVE_EXPR
2115 gimplification. */
2116 if (VAR_P (decl)
2117 && DECL_ARTIFICIAL (decl)
2118 && INTEGRAL_TYPE_P (TREE_TYPE (decl)))
2119 return OMP_CLAUSE_DEFAULT_SHARED;
2120
59bc434a
JJ
2121 if (c_omp_predefined_variable (decl))
2122 return OMP_CLAUSE_DEFAULT_SHARED;
2123
953ff289
DN
2124 return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
2125}
94e7f906 2126
93535a2b
TB
2127/* OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED unless OpenMP mapping attribute
2128 of DECL is predetermined. */
2129
2130enum omp_clause_defaultmap_kind
2131c_omp_predetermined_mapping (tree decl)
2132{
2133 /* Predetermine artificial variables holding integral values, those
2134 are usually result of gimplify_one_sizepos or SAVE_EXPR
2135 gimplification. */
2136 if (VAR_P (decl)
2137 && DECL_ARTIFICIAL (decl)
2138 && INTEGRAL_TYPE_P (TREE_TYPE (decl)))
2139 return OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE;
2140
2141 if (c_omp_predefined_variable (decl))
2142 return OMP_CLAUSE_DEFAULTMAP_TO;
2143
2144 return OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED;
2145}
2146
2147
94e7f906
JJ
2148/* Diagnose errors in an OpenMP context selector, return CTX if
2149 it is correct or error_mark_node otherwise. */
2150
2151tree
2152c_omp_check_context_selector (location_t loc, tree ctx)
2153{
2154 /* Each trait-set-selector-name can only be specified once.
2155 There are just 4 set names. */
2156 for (tree t1 = ctx; t1; t1 = TREE_CHAIN (t1))
2157 for (tree t2 = TREE_CHAIN (t1); t2; t2 = TREE_CHAIN (t2))
2158 if (TREE_PURPOSE (t1) == TREE_PURPOSE (t2))
2159 {
2160 error_at (loc, "selector set %qs specified more than once",
2161 IDENTIFIER_POINTER (TREE_PURPOSE (t1)));
2162 return error_mark_node;
2163 }
2164 for (tree t = ctx; t; t = TREE_CHAIN (t))
2165 {
2166 /* Each trait-selector-name can only be specified once. */
2167 if (list_length (TREE_VALUE (t)) < 5)
2168 {
2169 for (tree t1 = TREE_VALUE (t); t1; t1 = TREE_CHAIN (t1))
2170 for (tree t2 = TREE_CHAIN (t1); t2; t2 = TREE_CHAIN (t2))
2171 if (TREE_PURPOSE (t1) == TREE_PURPOSE (t2))
2172 {
2173 error_at (loc,
2174 "selector %qs specified more than once in set %qs",
2175 IDENTIFIER_POINTER (TREE_PURPOSE (t1)),
2176 IDENTIFIER_POINTER (TREE_PURPOSE (t)));
2177 return error_mark_node;
2178 }
2179 }
2180 else
2181 {
2182 hash_set<tree> pset;
2183 for (tree t1 = TREE_VALUE (t); t1; t1 = TREE_CHAIN (t1))
2184 if (pset.add (TREE_PURPOSE (t1)))
2185 {
2186 error_at (loc,
2187 "selector %qs specified more than once in set %qs",
2188 IDENTIFIER_POINTER (TREE_PURPOSE (t1)),
2189 IDENTIFIER_POINTER (TREE_PURPOSE (t)));
2190 return error_mark_node;
2191 }
2192 }
2193
2194 static const char *const kind[] = {
2195 "host", "nohost", "cpu", "gpu", "fpga", "any", NULL };
2196 static const char *const vendor[] = {
2197 "amd", "arm", "bsc", "cray", "fujitsu", "gnu", "ibm", "intel",
d0ec7c93 2198 "llvm", "nvidia", "pgi", "ti", "unknown", NULL };
94e7f906
JJ
2199 static const char *const extension[] = { NULL };
2200 static const char *const atomic_default_mem_order[] = {
2201 "seq_cst", "relaxed", "acq_rel", NULL };
2202 struct known_properties { const char *set; const char *selector;
2203 const char *const *props; };
2204 known_properties props[] = {
2205 { "device", "kind", kind },
2206 { "implementation", "vendor", vendor },
2207 { "implementation", "extension", extension },
2208 { "implementation", "atomic_default_mem_order",
2209 atomic_default_mem_order } };
2210 for (tree t1 = TREE_VALUE (t); t1; t1 = TREE_CHAIN (t1))
2211 for (unsigned i = 0; i < ARRAY_SIZE (props); i++)
2212 if (!strcmp (IDENTIFIER_POINTER (TREE_PURPOSE (t1)),
2213 props[i].selector)
2214 && !strcmp (IDENTIFIER_POINTER (TREE_PURPOSE (t)),
2215 props[i].set))
2216 for (tree t2 = TREE_VALUE (t1); t2; t2 = TREE_CHAIN (t2))
2217 for (unsigned j = 0; ; j++)
2218 {
2219 if (props[i].props[j] == NULL)
2220 {
b2417b59
JJ
2221 if (TREE_PURPOSE (t2)
2222 && !strcmp (IDENTIFIER_POINTER (TREE_PURPOSE (t2)),
2223 " score"))
94e7f906
JJ
2224 break;
2225 if (props[i].props == atomic_default_mem_order)
2226 {
2227 error_at (loc,
2228 "incorrect property %qs of %qs selector",
2229 IDENTIFIER_POINTER (TREE_PURPOSE (t2)),
2230 "atomic_default_mem_order");
2231 return error_mark_node;
2232 }
b2417b59 2233 else if (TREE_PURPOSE (t2))
94e7f906
JJ
2234 warning_at (loc, 0,
2235 "unknown property %qs of %qs selector",
2236 IDENTIFIER_POINTER (TREE_PURPOSE (t2)),
2237 props[i].selector);
b2417b59
JJ
2238 else
2239 warning_at (loc, 0,
2240 "unknown property %qE of %qs selector",
2241 TREE_VALUE (t2), props[i].selector);
94e7f906
JJ
2242 break;
2243 }
b2417b59 2244 else if (TREE_PURPOSE (t2) == NULL_TREE)
94e7f906 2245 {
b2417b59
JJ
2246 const char *str = TREE_STRING_POINTER (TREE_VALUE (t2));
2247 if (!strcmp (str, props[i].props[j])
2248 && ((size_t) TREE_STRING_LENGTH (TREE_VALUE (t2))
2249 == strlen (str) + 1))
2250 break;
94e7f906 2251 }
b2417b59
JJ
2252 else if (!strcmp (IDENTIFIER_POINTER (TREE_PURPOSE (t2)),
2253 props[i].props[j]))
2254 break;
94e7f906
JJ
2255 }
2256 }
2257 return ctx;
2258}
2259
20de9568
JJ
2260/* Register VARIANT as variant of some base function marked with
2261 #pragma omp declare variant. CONSTRUCT is corresponding construct
2262 selector set. */
2263
2264void
2265c_omp_mark_declare_variant (location_t loc, tree variant, tree construct)
2266{
2267 tree attr = lookup_attribute ("omp declare variant variant",
2268 DECL_ATTRIBUTES (variant));
2269 if (attr == NULL_TREE)
2270 {
2271 attr = tree_cons (get_identifier ("omp declare variant variant"),
2272 unshare_expr (construct),
2273 DECL_ATTRIBUTES (variant));
2274 DECL_ATTRIBUTES (variant) = attr;
2275 return;
2276 }
917dd789
JJ
2277 if ((TREE_VALUE (attr) != NULL_TREE) != (construct != NULL_TREE)
2278 || (construct != NULL_TREE
2279 && omp_context_selector_set_compare ("construct", TREE_VALUE (attr),
2280 construct)))
2281 error_at (loc, "%qD used as a variant with incompatible %<construct%> "
20de9568
JJ
2282 "selector sets", variant);
2283}
519d7496
JB
2284
2285/* For OpenACC, the OMP_CLAUSE_MAP_KIND of an OMP_CLAUSE_MAP is used internally
2286 to distinguish clauses as seen by the user. Return the "friendly" clause
2287 name for error messages etc., where possible. See also
2288 c/c-parser.c:c_parser_oacc_data_clause and
2289 cp/parser.c:cp_parser_oacc_data_clause. */
2290
2291const char *
2292c_omp_map_clause_name (tree clause, bool oacc)
2293{
2294 if (oacc && OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_MAP)
2295 switch (OMP_CLAUSE_MAP_KIND (clause))
2296 {
2297 case GOMP_MAP_FORCE_ALLOC:
2298 case GOMP_MAP_ALLOC: return "create";
2299 case GOMP_MAP_FORCE_TO:
2300 case GOMP_MAP_TO: return "copyin";
2301 case GOMP_MAP_FORCE_FROM:
2302 case GOMP_MAP_FROM: return "copyout";
2303 case GOMP_MAP_FORCE_TOFROM:
2304 case GOMP_MAP_TOFROM: return "copy";
2305 case GOMP_MAP_RELEASE: return "delete";
2306 case GOMP_MAP_FORCE_PRESENT: return "present";
2307 case GOMP_MAP_ATTACH: return "attach";
2308 case GOMP_MAP_FORCE_DETACH:
2309 case GOMP_MAP_DETACH: return "detach";
2310 case GOMP_MAP_DEVICE_RESIDENT: return "device_resident";
2311 case GOMP_MAP_LINK: return "link";
2312 case GOMP_MAP_FORCE_DEVICEPTR: return "deviceptr";
2313 default: break;
2314 }
2315 return omp_clause_code_name[OMP_CLAUSE_CODE (clause)];
2316}