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