]> 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
ca4c3545 1/* This file contains routines to construct OpenACC and OpenMP constructs,
1e8e9920 2 called from parsing in the C and C++ front ends.
3
f1717362 4 Copyright (C) 2005-2016 Free Software Foundation, Inc.
1e8e9920 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
8c4c00c1 12Software Foundation; either version 3, or (at your option) any later
1e8e9920 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
8c4c00c1 21along with GCC; see the file COPYING3. If not see
22<http://www.gnu.org/licenses/>. */
1e8e9920 23
24#include "config.h"
25#include "system.h"
26#include "coretypes.h"
6e803544 27#include "options.h"
1e8e9920 28#include "c-common.h"
a8783bee 29#include "gimple-expr.h"
4cba6f60 30#include "c-pragma.h"
ca4c3545 31#include "omp-low.h"
32#include "gomp-constants.h"
1e8e9920 33
34
ca4c3545 35/* Complete a #pragma oacc wait construct. LOC is the location of
36 the #pragma. */
37
38tree
39c_finish_oacc_wait (location_t loc, tree parms, tree clauses)
40{
41 const int nparms = list_length (parms);
42 tree stmt, t;
43 vec<tree, va_gc> *args;
44
45 vec_alloc (args, nparms + 2);
46 stmt = builtin_decl_explicit (BUILT_IN_GOACC_WAIT);
47
48 if (find_omp_clause (clauses, OMP_CLAUSE_ASYNC))
49 t = OMP_CLAUSE_ASYNC_EXPR (clauses);
50 else
51 t = build_int_cst (integer_type_node, GOMP_ASYNC_SYNC);
52
53 args->quick_push (t);
54 args->quick_push (build_int_cst (integer_type_node, nparms));
55
56 for (t = parms; t; t = TREE_CHAIN (t))
57 {
58 if (TREE_CODE (OMP_CLAUSE_WAIT_EXPR (t)) == INTEGER_CST)
59 args->quick_push (build_int_cst (integer_type_node,
60 TREE_INT_CST_LOW (OMP_CLAUSE_WAIT_EXPR (t))));
61 else
62 args->quick_push (OMP_CLAUSE_WAIT_EXPR (t));
63 }
64
65 stmt = build_call_expr_loc_vec (loc, stmt, args);
ca4c3545 66
67 vec_free (args);
68
69 return stmt;
70}
71
1e8e9920 72/* Complete a #pragma omp master construct. STMT is the structured-block
e60a6f7b 73 that follows the pragma. LOC is the l*/
1e8e9920 74
75tree
e60a6f7b 76c_finish_omp_master (location_t loc, tree stmt)
1e8e9920 77{
e60a6f7b 78 tree t = add_stmt (build1 (OMP_MASTER, void_type_node, stmt));
79 SET_EXPR_LOCATION (t, loc);
80 return t;
1e8e9920 81}
82
bc7bff74 83/* Complete a #pragma omp taskgroup construct. STMT is the structured-block
84 that follows the pragma. LOC is the l*/
85
86tree
87c_finish_omp_taskgroup (location_t loc, tree stmt)
88{
89 tree t = add_stmt (build1 (OMP_TASKGROUP, void_type_node, stmt));
90 SET_EXPR_LOCATION (t, loc);
91 return t;
92}
93
1e8e9920 94/* Complete a #pragma omp critical construct. STMT is the structured-block
95 that follows the pragma, NAME is the identifier in the pragma, or null
e60a6f7b 96 if it was omitted. LOC is the location of the #pragma. */
1e8e9920 97
98tree
43895be5 99c_finish_omp_critical (location_t loc, tree body, tree name, tree clauses)
1e8e9920 100{
101 tree stmt = make_node (OMP_CRITICAL);
102 TREE_TYPE (stmt) = void_type_node;
103 OMP_CRITICAL_BODY (stmt) = body;
104 OMP_CRITICAL_NAME (stmt) = name;
43895be5 105 OMP_CRITICAL_CLAUSES (stmt) = clauses;
e60a6f7b 106 SET_EXPR_LOCATION (stmt, loc);
1e8e9920 107 return add_stmt (stmt);
108}
109
110/* Complete a #pragma omp ordered construct. STMT is the structured-block
e60a6f7b 111 that follows the pragma. LOC is the location of the #pragma. */
1e8e9920 112
113tree
43895be5 114c_finish_omp_ordered (location_t loc, tree clauses, tree stmt)
1e8e9920 115{
43895be5 116 tree t = make_node (OMP_ORDERED);
117 TREE_TYPE (t) = void_type_node;
118 OMP_ORDERED_BODY (t) = stmt;
119 OMP_ORDERED_CLAUSES (t) = clauses;
e60a6f7b 120 SET_EXPR_LOCATION (t, loc);
121 return add_stmt (t);
1e8e9920 122}
123
124
e60a6f7b 125/* Complete a #pragma omp barrier construct. LOC is the location of
126 the #pragma. */
1e8e9920 127
128void
e60a6f7b 129c_finish_omp_barrier (location_t loc)
1e8e9920 130{
131 tree x;
132
b9a16870 133 x = builtin_decl_explicit (BUILT_IN_GOMP_BARRIER);
389dd41b 134 x = build_call_expr_loc (loc, x, 0);
1e8e9920 135 add_stmt (x);
136}
137
138
e60a6f7b 139/* Complete a #pragma omp taskwait construct. LOC is the location of the
140 pragma. */
fd6481cf 141
142void
e60a6f7b 143c_finish_omp_taskwait (location_t loc)
fd6481cf 144{
145 tree x;
146
b9a16870 147 x = builtin_decl_explicit (BUILT_IN_GOMP_TASKWAIT);
389dd41b 148 x = build_call_expr_loc (loc, x, 0);
fd6481cf 149 add_stmt (x);
150}
151
152
2169f33b 153/* Complete a #pragma omp taskyield construct. LOC is the location of the
154 pragma. */
155
156void
157c_finish_omp_taskyield (location_t loc)
158{
159 tree x;
160
b9a16870 161 x = builtin_decl_explicit (BUILT_IN_GOMP_TASKYIELD);
2169f33b 162 x = build_call_expr_loc (loc, x, 0);
163 add_stmt (x);
164}
165
166
167/* Complete a #pragma omp atomic construct. For CODE OMP_ATOMIC
168 the expression to be implemented atomically is LHS opcode= RHS.
169 For OMP_ATOMIC_READ V = LHS, for OMP_ATOMIC_CAPTURE_{NEW,OLD} LHS
170 opcode= RHS with the new or old content of LHS returned.
171 LOC is the location of the atomic statement. The value returned
172 is either error_mark_node (if the construct was erroneous) or an
173 OMP_ATOMIC* node which should be added to the current statement
9561765e 174 tree with add_stmt. If TEST is set, avoid calling save_expr
175 or create_tmp_var*. */
1e8e9920 176
d377303f 177tree
2169f33b 178c_finish_omp_atomic (location_t loc, enum tree_code code,
179 enum tree_code opcode, tree lhs, tree rhs,
9561765e 180 tree v, tree lhs1, tree rhs1, bool swapped, bool seq_cst,
181 bool test)
1e8e9920 182{
1248c663 183 tree x, type, addr, pre = NULL_TREE;
1e8e9920 184
2169f33b 185 if (lhs == error_mark_node || rhs == error_mark_node
186 || v == error_mark_node || lhs1 == error_mark_node
187 || rhs1 == error_mark_node)
d377303f 188 return error_mark_node;
1e8e9920 189
190 /* ??? According to one reading of the OpenMP spec, complex type are
191 supported, but there are no atomic stores for any architecture.
192 But at least icc 9.0 doesn't support complex types here either.
193 And lets not even talk about vector types... */
194 type = TREE_TYPE (lhs);
195 if (!INTEGRAL_TYPE_P (type)
196 && !POINTER_TYPE_P (type)
197 && !SCALAR_FLOAT_TYPE_P (type))
198 {
e60a6f7b 199 error_at (loc, "invalid expression type for %<#pragma omp atomic%>");
d377303f 200 return error_mark_node;
1e8e9920 201 }
202
bbf8fbec 203 if (opcode == RDIV_EXPR)
204 opcode = TRUNC_DIV_EXPR;
205
1e8e9920 206 /* ??? Validate that rhs does not overlap lhs. */
207
208 /* Take and save the address of the lhs. From then on we'll reference it
209 via indirection. */
e60a6f7b 210 addr = build_unary_op (loc, ADDR_EXPR, lhs, 0);
1e8e9920 211 if (addr == error_mark_node)
d377303f 212 return error_mark_node;
9561765e 213 if (!test)
214 addr = save_expr (addr);
215 if (!test
216 && TREE_CODE (addr) != SAVE_EXPR
eaa3785f 217 && (TREE_CODE (addr) != ADDR_EXPR
f48c7f4a 218 || !VAR_P (TREE_OPERAND (addr, 0))))
eaa3785f 219 {
220 /* Make sure LHS is simple enough so that goa_lhs_expr_p can recognize
221 it even after unsharing function body. */
f9e245b2 222 tree var = create_tmp_var_raw (TREE_TYPE (addr));
bfec3452 223 DECL_CONTEXT (var) = current_function_decl;
eaa3785f 224 addr = build4 (TARGET_EXPR, TREE_TYPE (addr), var, addr, NULL, NULL);
225 }
f08923b3 226 lhs = build_indirect_ref (loc, addr, RO_NULL);
1e8e9920 227
2169f33b 228 if (code == OMP_ATOMIC_READ)
229 {
230 x = build1 (OMP_ATOMIC_READ, type, addr);
231 SET_EXPR_LOCATION (x, loc);
bc7bff74 232 OMP_ATOMIC_SEQ_CST (x) = seq_cst;
2169f33b 233 return build_modify_expr (loc, v, NULL_TREE, NOP_EXPR,
234 loc, x, NULL_TREE);
2169f33b 235 }
236
1e8e9920 237 /* There are lots of warnings, errors, and conversions that need to happen
238 in the course of interpreting a statement. Use the normal mechanisms
239 to do this, and then take it apart again. */
bc7bff74 240 if (swapped)
241 {
bbf8fbec 242 rhs = build_binary_op (loc, opcode, rhs, lhs, 1);
bc7bff74 243 opcode = NOP_EXPR;
244 }
1248c663 245 bool save = in_late_binary_op;
246 in_late_binary_op = true;
bc7bff74 247 x = build_modify_expr (loc, lhs, NULL_TREE, opcode, loc, rhs, NULL_TREE);
1248c663 248 in_late_binary_op = save;
1e8e9920 249 if (x == error_mark_node)
d377303f 250 return error_mark_node;
1248c663 251 if (TREE_CODE (x) == COMPOUND_EXPR)
252 {
253 pre = TREE_OPERAND (x, 0);
254 gcc_assert (TREE_CODE (pre) == SAVE_EXPR);
255 x = TREE_OPERAND (x, 1);
256 }
48e1416a 257 gcc_assert (TREE_CODE (x) == MODIFY_EXPR);
1e8e9920 258 rhs = TREE_OPERAND (x, 1);
259
260 /* Punt the actual generation of atomic operations to common code. */
2169f33b 261 if (code == OMP_ATOMIC)
262 type = void_type_node;
263 x = build2 (code, type, addr, rhs);
e60a6f7b 264 SET_EXPR_LOCATION (x, loc);
bc7bff74 265 OMP_ATOMIC_SEQ_CST (x) = seq_cst;
2169f33b 266
267 /* Generally it is hard to prove lhs1 and lhs are the same memory
268 location, just diagnose different variables. */
269 if (rhs1
f48c7f4a 270 && VAR_P (rhs1)
271 && VAR_P (lhs)
9561765e 272 && rhs1 != lhs
273 && !test)
2169f33b 274 {
275 if (code == OMP_ATOMIC)
9561765e 276 error_at (loc, "%<#pragma omp atomic update%> uses two different "
277 "variables for memory");
2169f33b 278 else
9561765e 279 error_at (loc, "%<#pragma omp atomic capture%> uses two different "
280 "variables for memory");
2169f33b 281 return error_mark_node;
282 }
283
284 if (code != OMP_ATOMIC)
285 {
286 /* Generally it is hard to prove lhs1 and lhs are the same memory
287 location, just diagnose different variables. */
f48c7f4a 288 if (lhs1 && VAR_P (lhs1) && VAR_P (lhs))
2169f33b 289 {
9561765e 290 if (lhs1 != lhs && !test)
2169f33b 291 {
9561765e 292 error_at (loc, "%<#pragma omp atomic capture%> uses two "
293 "different variables for memory");
2169f33b 294 return error_mark_node;
295 }
296 }
297 x = build_modify_expr (loc, v, NULL_TREE, NOP_EXPR,
298 loc, x, NULL_TREE);
299 if (rhs1 && rhs1 != lhs)
300 {
301 tree rhs1addr = build_unary_op (loc, ADDR_EXPR, rhs1, 0);
302 if (rhs1addr == error_mark_node)
303 return error_mark_node;
304 x = omit_one_operand_loc (loc, type, x, rhs1addr);
305 }
306 if (lhs1 && lhs1 != lhs)
307 {
308 tree lhs1addr = build_unary_op (loc, ADDR_EXPR, lhs1, 0);
309 if (lhs1addr == error_mark_node)
310 return error_mark_node;
311 if (code == OMP_ATOMIC_CAPTURE_OLD)
312 x = omit_one_operand_loc (loc, type, x, lhs1addr);
313 else
314 {
9561765e 315 if (!test)
316 x = save_expr (x);
2169f33b 317 x = omit_two_operands_loc (loc, type, x, x, lhs1addr);
318 }
319 }
320 }
321 else if (rhs1 && rhs1 != lhs)
322 {
323 tree rhs1addr = build_unary_op (loc, ADDR_EXPR, rhs1, 0);
324 if (rhs1addr == error_mark_node)
325 return error_mark_node;
326 x = omit_one_operand_loc (loc, type, x, rhs1addr);
327 }
328
1248c663 329 if (pre)
330 x = omit_one_operand_loc (loc, type, x, pre);
e60a6f7b 331 return x;
1e8e9920 332}
333
334
e60a6f7b 335/* Complete a #pragma omp flush construct. We don't do anything with
336 the variable list that the syntax allows. LOC is the location of
337 the #pragma. */
1e8e9920 338
339void
e60a6f7b 340c_finish_omp_flush (location_t loc)
1e8e9920 341{
342 tree x;
343
b9a16870 344 x = builtin_decl_explicit (BUILT_IN_SYNC_SYNCHRONIZE);
389dd41b 345 x = build_call_expr_loc (loc, x, 0);
1e8e9920 346 add_stmt (x);
347}
348
349
ca4c3545 350/* Check and canonicalize OMP_FOR increment expression.
1e8e9920 351 Helper function for c_finish_omp_for. */
352
353static tree
389dd41b 354check_omp_for_incr_expr (location_t loc, tree exp, tree decl)
1e8e9920 355{
356 tree t;
357
358 if (!INTEGRAL_TYPE_P (TREE_TYPE (exp))
359 || TYPE_PRECISION (TREE_TYPE (exp)) < TYPE_PRECISION (TREE_TYPE (decl)))
360 return error_mark_node;
361
362 if (exp == decl)
363 return build_int_cst (TREE_TYPE (exp), 0);
364
365 switch (TREE_CODE (exp))
366 {
72dd6141 367 CASE_CONVERT:
389dd41b 368 t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 0), decl);
1e8e9920 369 if (t != error_mark_node)
389dd41b 370 return fold_convert_loc (loc, TREE_TYPE (exp), t);
1e8e9920 371 break;
372 case MINUS_EXPR:
389dd41b 373 t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 0), decl);
1e8e9920 374 if (t != error_mark_node)
389dd41b 375 return fold_build2_loc (loc, MINUS_EXPR,
376 TREE_TYPE (exp), t, TREE_OPERAND (exp, 1));
1e8e9920 377 break;
378 case PLUS_EXPR:
389dd41b 379 t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 0), decl);
1e8e9920 380 if (t != error_mark_node)
389dd41b 381 return fold_build2_loc (loc, PLUS_EXPR,
382 TREE_TYPE (exp), t, TREE_OPERAND (exp, 1));
383 t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 1), decl);
1e8e9920 384 if (t != error_mark_node)
389dd41b 385 return fold_build2_loc (loc, PLUS_EXPR,
386 TREE_TYPE (exp), TREE_OPERAND (exp, 0), t);
1e8e9920 387 break;
3115bda0 388 case COMPOUND_EXPR:
389 {
390 /* cp_build_modify_expr forces preevaluation of the RHS to make
391 sure that it is evaluated before the lvalue-rvalue conversion
392 is applied to the LHS. Reconstruct the original expression. */
393 tree op0 = TREE_OPERAND (exp, 0);
394 if (TREE_CODE (op0) == TARGET_EXPR
395 && !VOID_TYPE_P (TREE_TYPE (op0)))
396 {
397 tree op1 = TREE_OPERAND (exp, 1);
398 tree temp = TARGET_EXPR_SLOT (op0);
72f8014e 399 if (BINARY_CLASS_P (op1)
3115bda0 400 && TREE_OPERAND (op1, 1) == temp)
401 {
402 op1 = copy_node (op1);
403 TREE_OPERAND (op1, 1) = TARGET_EXPR_INITIAL (op0);
404 return check_omp_for_incr_expr (loc, op1, decl);
405 }
406 }
407 break;
408 }
1e8e9920 409 default:
410 break;
411 }
412
413 return error_mark_node;
414}
415
f2697631 416/* If the OMP_FOR increment expression in INCR is of pointer type,
417 canonicalize it into an expression handled by gimplify_omp_for()
418 and return it. DECL is the iteration variable. */
419
420static tree
421c_omp_for_incr_canonicalize_ptr (location_t loc, tree decl, tree incr)
422{
423 if (POINTER_TYPE_P (TREE_TYPE (decl))
424 && TREE_OPERAND (incr, 1))
425 {
426 tree t = fold_convert_loc (loc,
427 sizetype, TREE_OPERAND (incr, 1));
428
429 if (TREE_CODE (incr) == POSTDECREMENT_EXPR
430 || TREE_CODE (incr) == PREDECREMENT_EXPR)
431 t = fold_build1_loc (loc, NEGATE_EXPR, sizetype, t);
432 t = fold_build_pointer_plus (decl, t);
433 incr = build2 (MODIFY_EXPR, void_type_node, decl, t);
434 }
435 return incr;
436}
437
ca4c3545 438/* Validate and generate OMP_FOR.
fd6481cf 439 DECLV is a vector of iteration variables, for each collapsed loop.
43895be5 440
441 ORIG_DECLV, if non-NULL, is a vector with the original iteration
442 variables (prior to any transformations, by say, C++ iterators).
443
fd6481cf 444 INITV, CONDV and INCRV are vectors containing initialization
445 expressions, controlling predicates and increment expressions.
446 BODY is the body of the loop and PRE_BODY statements that go before
447 the loop. */
1e8e9920 448
449tree
bc7bff74 450c_finish_omp_for (location_t locus, enum tree_code code, tree declv,
43895be5 451 tree orig_declv, tree initv, tree condv, tree incrv,
452 tree body, tree pre_body)
1e8e9920 453{
fd6481cf 454 location_t elocus;
1e8e9920 455 bool fail = false;
fd6481cf 456 int i;
1e8e9920 457
40750995 458 if ((code == CILK_SIMD || code == CILK_FOR)
f2697631 459 && !c_check_cilk_loop (locus, TREE_VEC_ELT (declv, 0)))
460 fail = true;
461
fd6481cf 462 gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (initv));
463 gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (condv));
464 gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (incrv));
465 for (i = 0; i < TREE_VEC_LENGTH (declv); i++)
1e8e9920 466 {
fd6481cf 467 tree decl = TREE_VEC_ELT (declv, i);
468 tree init = TREE_VEC_ELT (initv, i);
469 tree cond = TREE_VEC_ELT (condv, i);
470 tree incr = TREE_VEC_ELT (incrv, i);
471
472 elocus = locus;
473 if (EXPR_HAS_LOCATION (init))
474 elocus = EXPR_LOCATION (init);
475
476 /* Validate the iteration variable. */
477 if (!INTEGRAL_TYPE_P (TREE_TYPE (decl))
478 && TREE_CODE (TREE_TYPE (decl)) != POINTER_TYPE)
479 {
b6889cb0 480 error_at (elocus, "invalid type for iteration variable %qE", decl);
fd6481cf 481 fail = true;
482 }
1e8e9920 483
fd6481cf 484 /* In the case of "for (int i = 0...)", init will be a decl. It should
485 have a DECL_INITIAL that we can turn into an assignment. */
486 if (init == decl)
487 {
488 elocus = DECL_SOURCE_LOCATION (decl);
489
490 init = DECL_INITIAL (decl);
491 if (init == NULL)
492 {
b6889cb0 493 error_at (elocus, "%qE is not initialized", decl);
fd6481cf 494 init = integer_zero_node;
495 fail = true;
496 }
43895be5 497 DECL_INITIAL (decl) = NULL_TREE;
1e8e9920 498
48e1416a 499 init = build_modify_expr (elocus, decl, NULL_TREE, NOP_EXPR,
e60a6f7b 500 /* FIXME diagnostics: This should
501 be the location of the INIT. */
502 elocus,
503 init,
8458f4ca 504 NULL_TREE);
fd6481cf 505 }
f2697631 506 if (init != error_mark_node)
507 {
508 gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
509 gcc_assert (TREE_OPERAND (init, 0) == decl);
510 }
fd6481cf 511
512 if (cond == NULL_TREE)
1e8e9920 513 {
b6889cb0 514 error_at (elocus, "missing controlling predicate");
1e8e9920 515 fail = true;
516 }
fd6481cf 517 else
518 {
519 bool cond_ok = false;
1e8e9920 520
fd6481cf 521 if (EXPR_HAS_LOCATION (cond))
522 elocus = EXPR_LOCATION (cond);
1e8e9920 523
fd6481cf 524 if (TREE_CODE (cond) == LT_EXPR
525 || TREE_CODE (cond) == LE_EXPR
526 || TREE_CODE (cond) == GT_EXPR
e060ba36 527 || TREE_CODE (cond) == GE_EXPR
abc3b078 528 || TREE_CODE (cond) == NE_EXPR
529 || TREE_CODE (cond) == EQ_EXPR)
fd6481cf 530 {
531 tree op0 = TREE_OPERAND (cond, 0);
532 tree op1 = TREE_OPERAND (cond, 1);
1e8e9920 533
fd6481cf 534 /* 2.5.1. The comparison in the condition is computed in
535 the type of DECL, otherwise the behavior is undefined.
1e8e9920 536
fd6481cf 537 For example:
538 long n; int i;
539 i < n;
1e8e9920 540
fd6481cf 541 according to ISO will be evaluated as:
542 (long)i < n;
1e8e9920 543
fd6481cf 544 We want to force:
545 i < (int)n; */
546 if (TREE_CODE (op0) == NOP_EXPR
547 && decl == TREE_OPERAND (op0, 0))
548 {
549 TREE_OPERAND (cond, 0) = TREE_OPERAND (op0, 0);
550 TREE_OPERAND (cond, 1)
389dd41b 551 = fold_build1_loc (elocus, NOP_EXPR, TREE_TYPE (decl),
fd6481cf 552 TREE_OPERAND (cond, 1));
553 }
554 else if (TREE_CODE (op1) == NOP_EXPR
555 && decl == TREE_OPERAND (op1, 0))
556 {
557 TREE_OPERAND (cond, 1) = TREE_OPERAND (op1, 0);
558 TREE_OPERAND (cond, 0)
389dd41b 559 = fold_build1_loc (elocus, NOP_EXPR, TREE_TYPE (decl),
fd6481cf 560 TREE_OPERAND (cond, 0));
561 }
1e8e9920 562
fd6481cf 563 if (decl == TREE_OPERAND (cond, 0))
564 cond_ok = true;
565 else if (decl == TREE_OPERAND (cond, 1))
566 {
567 TREE_SET_CODE (cond,
568 swap_tree_comparison (TREE_CODE (cond)));
569 TREE_OPERAND (cond, 1) = TREE_OPERAND (cond, 0);
570 TREE_OPERAND (cond, 0) = decl;
571 cond_ok = true;
572 }
e060ba36 573
abc3b078 574 if (TREE_CODE (cond) == NE_EXPR
575 || TREE_CODE (cond) == EQ_EXPR)
e060ba36 576 {
577 if (!INTEGRAL_TYPE_P (TREE_TYPE (decl)))
40750995 578 {
579 if (code != CILK_SIMD && code != CILK_FOR)
580 cond_ok = false;
581 }
e060ba36 582 else if (operand_equal_p (TREE_OPERAND (cond, 1),
583 TYPE_MIN_VALUE (TREE_TYPE (decl)),
584 0))
abc3b078 585 TREE_SET_CODE (cond, TREE_CODE (cond) == NE_EXPR
586 ? GT_EXPR : LE_EXPR);
e060ba36 587 else if (operand_equal_p (TREE_OPERAND (cond, 1),
588 TYPE_MAX_VALUE (TREE_TYPE (decl)),
589 0))
abc3b078 590 TREE_SET_CODE (cond, TREE_CODE (cond) == NE_EXPR
591 ? LT_EXPR : GE_EXPR);
40750995 592 else if (code != CILK_SIMD && code != CILK_FOR)
e060ba36 593 cond_ok = false;
594 }
1e8e9920 595 }
596
fd6481cf 597 if (!cond_ok)
1e8e9920 598 {
b6889cb0 599 error_at (elocus, "invalid controlling predicate");
fd6481cf 600 fail = true;
1e8e9920 601 }
602 }
603
fd6481cf 604 if (incr == NULL_TREE)
1e8e9920 605 {
b6889cb0 606 error_at (elocus, "missing increment expression");
1e8e9920 607 fail = true;
608 }
fd6481cf 609 else
1e8e9920 610 {
fd6481cf 611 bool incr_ok = false;
1e8e9920 612
fd6481cf 613 if (EXPR_HAS_LOCATION (incr))
614 elocus = EXPR_LOCATION (incr);
615
616 /* Check all the valid increment expressions: v++, v--, ++v, --v,
617 v = v + incr, v = incr + v and v = v - incr. */
618 switch (TREE_CODE (incr))
1e8e9920 619 {
fd6481cf 620 case POSTINCREMENT_EXPR:
621 case PREINCREMENT_EXPR:
622 case POSTDECREMENT_EXPR:
623 case PREDECREMENT_EXPR:
624 if (TREE_OPERAND (incr, 0) != decl)
625 break;
626
627 incr_ok = true;
f2697631 628 incr = c_omp_for_incr_canonicalize_ptr (elocus, decl, incr);
fd6481cf 629 break;
630
1248c663 631 case COMPOUND_EXPR:
632 if (TREE_CODE (TREE_OPERAND (incr, 0)) != SAVE_EXPR
633 || TREE_CODE (TREE_OPERAND (incr, 1)) != MODIFY_EXPR)
634 break;
635 incr = TREE_OPERAND (incr, 1);
636 /* FALLTHRU */
fd6481cf 637 case MODIFY_EXPR:
638 if (TREE_OPERAND (incr, 0) != decl)
639 break;
640 if (TREE_OPERAND (incr, 1) == decl)
641 break;
642 if (TREE_CODE (TREE_OPERAND (incr, 1)) == PLUS_EXPR
643 && (TREE_OPERAND (TREE_OPERAND (incr, 1), 0) == decl
644 || TREE_OPERAND (TREE_OPERAND (incr, 1), 1) == decl))
645 incr_ok = true;
646 else if ((TREE_CODE (TREE_OPERAND (incr, 1)) == MINUS_EXPR
647 || (TREE_CODE (TREE_OPERAND (incr, 1))
648 == POINTER_PLUS_EXPR))
649 && TREE_OPERAND (TREE_OPERAND (incr, 1), 0) == decl)
650 incr_ok = true;
651 else
652 {
389dd41b 653 tree t = check_omp_for_incr_expr (elocus,
654 TREE_OPERAND (incr, 1),
fd6481cf 655 decl);
656 if (t != error_mark_node)
657 {
658 incr_ok = true;
659 t = build2 (PLUS_EXPR, TREE_TYPE (decl), decl, t);
660 incr = build2 (MODIFY_EXPR, void_type_node, decl, t);
661 }
662 }
663 break;
1e8e9920 664
fd6481cf 665 default:
666 break;
667 }
668 if (!incr_ok)
669 {
b6889cb0 670 error_at (elocus, "invalid increment expression");
fd6481cf 671 fail = true;
672 }
1e8e9920 673 }
fd6481cf 674
675 TREE_VEC_ELT (initv, i) = init;
676 TREE_VEC_ELT (incrv, i) = incr;
1e8e9920 677 }
678
679 if (fail)
680 return NULL;
681 else
682 {
bc7bff74 683 tree t = make_node (code);
1e8e9920 684
685 TREE_TYPE (t) = void_type_node;
fd6481cf 686 OMP_FOR_INIT (t) = initv;
687 OMP_FOR_COND (t) = condv;
688 OMP_FOR_INCR (t) = incrv;
1e8e9920 689 OMP_FOR_BODY (t) = body;
690 OMP_FOR_PRE_BODY (t) = pre_body;
9561765e 691 OMP_FOR_ORIG_DECLS (t) = orig_declv;
1e8e9920 692
693 SET_EXPR_LOCATION (t, locus);
9561765e 694 return t;
1e8e9920 695 }
696}
697
9561765e 698/* Type for passing data in between c_omp_check_loop_iv and
699 c_omp_check_loop_iv_r. */
700
701struct c_omp_check_loop_iv_data
702{
703 tree declv;
704 bool fail;
705 location_t stmt_loc;
706 location_t expr_loc;
707 int kind;
708 walk_tree_lh lh;
709 hash_set<tree> *ppset;
710};
711
712/* Helper function called via walk_tree, to diagnose uses
713 of associated loop IVs inside of lb, b and incr expressions
714 of OpenMP loops. */
715
716static tree
717c_omp_check_loop_iv_r (tree *tp, int *walk_subtrees, void *data)
718{
719 struct c_omp_check_loop_iv_data *d
720 = (struct c_omp_check_loop_iv_data *) data;
721 if (DECL_P (*tp))
722 {
723 int i;
724 for (i = 0; i < TREE_VEC_LENGTH (d->declv); i++)
725 if (*tp == TREE_VEC_ELT (d->declv, i))
726 {
727 location_t loc = d->expr_loc;
728 if (loc == UNKNOWN_LOCATION)
729 loc = d->stmt_loc;
730 switch (d->kind)
731 {
732 case 0:
733 error_at (loc, "initializer expression refers to "
734 "iteration variable %qD", *tp);
735 break;
736 case 1:
737 error_at (loc, "condition expression refers to "
738 "iteration variable %qD", *tp);
739 break;
740 case 2:
741 error_at (loc, "increment expression refers to "
742 "iteration variable %qD", *tp);
743 break;
744 }
745 d->fail = true;
746 }
747 }
748 /* Don't walk dtors added by C++ wrap_cleanups_r. */
749 else if (TREE_CODE (*tp) == TRY_CATCH_EXPR
750 && TRY_CATCH_IS_CLEANUP (*tp))
751 {
752 *walk_subtrees = 0;
753 return walk_tree_1 (&TREE_OPERAND (*tp, 0), c_omp_check_loop_iv_r, data,
754 d->ppset, d->lh);
755 }
756
757 return NULL_TREE;
758}
759
760/* Diagnose invalid references to loop iterators in lb, b and incr
761 expressions. */
762
763bool
764c_omp_check_loop_iv (tree stmt, tree declv, walk_tree_lh lh)
765{
766 hash_set<tree> pset;
767 struct c_omp_check_loop_iv_data data;
768 int i;
769
770 data.declv = declv;
771 data.fail = false;
772 data.stmt_loc = EXPR_LOCATION (stmt);
773 data.lh = lh;
774 data.ppset = &pset;
775 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (stmt)); i++)
776 {
777 tree init = TREE_VEC_ELT (OMP_FOR_INIT (stmt), i);
778 gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
779 tree decl = TREE_OPERAND (init, 0);
780 tree cond = TREE_VEC_ELT (OMP_FOR_COND (stmt), i);
781 gcc_assert (COMPARISON_CLASS_P (cond));
782 gcc_assert (TREE_OPERAND (cond, 0) == decl);
783 tree incr = TREE_VEC_ELT (OMP_FOR_INCR (stmt), i);
784 data.expr_loc = EXPR_LOCATION (TREE_OPERAND (init, 1));
785 data.kind = 0;
786 walk_tree_1 (&TREE_OPERAND (init, 1),
787 c_omp_check_loop_iv_r, &data, &pset, lh);
788 /* Don't warn for C++ random access iterators here, the
789 expression then involves the subtraction and always refers
790 to the original value. The C++ FE needs to warn on those
791 earlier. */
792 if (decl == TREE_VEC_ELT (declv, i))
793 {
794 data.expr_loc = EXPR_LOCATION (cond);
795 data.kind = 1;
796 walk_tree_1 (&TREE_OPERAND (cond, 1),
797 c_omp_check_loop_iv_r, &data, &pset, lh);
798 }
799 if (TREE_CODE (incr) == MODIFY_EXPR)
800 {
801 gcc_assert (TREE_OPERAND (incr, 0) == decl);
802 incr = TREE_OPERAND (incr, 1);
803 data.kind = 2;
804 if (TREE_CODE (incr) == PLUS_EXPR
805 && TREE_OPERAND (incr, 1) == decl)
806 {
807 data.expr_loc = EXPR_LOCATION (TREE_OPERAND (incr, 0));
808 walk_tree_1 (&TREE_OPERAND (incr, 0),
809 c_omp_check_loop_iv_r, &data, &pset, lh);
810 }
811 else
812 {
813 data.expr_loc = EXPR_LOCATION (TREE_OPERAND (incr, 1));
814 walk_tree_1 (&TREE_OPERAND (incr, 1),
815 c_omp_check_loop_iv_r, &data, &pset, lh);
816 }
817 }
818 }
819 return !data.fail;
820}
821
822/* Similar, but allows to check the init or cond expressions individually. */
823
824bool
825c_omp_check_loop_iv_exprs (location_t stmt_loc, tree declv, tree decl,
826 tree init, tree cond, walk_tree_lh lh)
827{
828 hash_set<tree> pset;
829 struct c_omp_check_loop_iv_data data;
830
831 data.declv = declv;
832 data.fail = false;
833 data.stmt_loc = stmt_loc;
834 data.lh = lh;
835 data.ppset = &pset;
836 if (init)
837 {
838 data.expr_loc = EXPR_LOCATION (init);
839 data.kind = 0;
840 walk_tree_1 (&init,
841 c_omp_check_loop_iv_r, &data, &pset, lh);
842 }
843 if (cond)
844 {
845 gcc_assert (COMPARISON_CLASS_P (cond));
846 data.expr_loc = EXPR_LOCATION (init);
847 data.kind = 1;
848 if (TREE_OPERAND (cond, 0) == decl)
849 walk_tree_1 (&TREE_OPERAND (cond, 1),
850 c_omp_check_loop_iv_r, &data, &pset, lh);
851 else
852 walk_tree_1 (&TREE_OPERAND (cond, 0),
853 c_omp_check_loop_iv_r, &data, &pset, lh);
854 }
855 return !data.fail;
856}
857
2c4c8725 858/* This function splits clauses for OpenACC combined loop
859 constructs. OpenACC combined loop constructs are:
860 #pragma acc kernels loop
9561765e 861 #pragma acc parallel loop */
2c4c8725 862
863tree
864c_oacc_split_loop_clauses (tree clauses, tree *not_loop_clauses)
865{
ef014f95 866 tree next, loop_clauses, t;
2c4c8725 867
868 loop_clauses = *not_loop_clauses = NULL_TREE;
869 for (; clauses ; clauses = next)
870 {
871 next = OMP_CLAUSE_CHAIN (clauses);
872
873 switch (OMP_CLAUSE_CODE (clauses))
874 {
ef014f95 875 /* Loop clauses. */
2c4c8725 876 case OMP_CLAUSE_COLLAPSE:
ef014f95 877 case OMP_CLAUSE_TILE:
878 case OMP_CLAUSE_GANG:
879 case OMP_CLAUSE_WORKER:
880 case OMP_CLAUSE_VECTOR:
881 case OMP_CLAUSE_AUTO:
882 case OMP_CLAUSE_SEQ:
883 case OMP_CLAUSE_INDEPENDENT:
884 case OMP_CLAUSE_PRIVATE:
2c4c8725 885 OMP_CLAUSE_CHAIN (clauses) = loop_clauses;
886 loop_clauses = clauses;
887 break;
888
ef014f95 889 /* Reductions belong in both constructs. */
890 case OMP_CLAUSE_REDUCTION:
891 t = copy_node (clauses);
892 OMP_CLAUSE_CHAIN (t) = loop_clauses;
893 loop_clauses = t;
894
895 /* Parallel/kernels clauses. */
2c4c8725 896 default:
897 OMP_CLAUSE_CHAIN (clauses) = *not_loop_clauses;
898 *not_loop_clauses = clauses;
899 break;
900 }
901 }
902
903 return loop_clauses;
904}
905
906/* This function attempts to split or duplicate clauses for OpenMP
907 combined/composite constructs. Right now there are 21 different
bc7bff74 908 constructs. CODE is the innermost construct in the combined construct,
909 and MASK allows to determine which constructs are combined together,
910 as every construct has at least one clause that no other construct
911 has (except for OMP_SECTIONS, but that can be only combined with parallel).
2c4c8725 912 OpenMP combined/composite constructs are:
bc7bff74 913 #pragma omp distribute parallel for
914 #pragma omp distribute parallel for simd
43895be5 915 #pragma omp distribute simd
916 #pragma omp for simd
917 #pragma omp parallel for
918 #pragma omp parallel for simd
919 #pragma omp parallel sections
920 #pragma omp target parallel
921 #pragma omp target parallel for
922 #pragma omp target parallel for simd
bc7bff74 923 #pragma omp target teams
924 #pragma omp target teams distribute
925 #pragma omp target teams distribute parallel for
43895be5 926 #pragma omp target teams distribute parallel for simd
927 #pragma omp target teams distribute simd
928 #pragma omp target simd
929 #pragma omp taskloop simd
930 #pragma omp teams distribute
931 #pragma omp teams distribute parallel for
932 #pragma omp teams distribute parallel for simd
933 #pragma omp teams distribute simd */
1e8e9920 934
935void
bc7bff74 936c_omp_split_clauses (location_t loc, enum tree_code code,
937 omp_clause_mask mask, tree clauses, tree *cclauses)
1e8e9920 938{
bc7bff74 939 tree next, c;
940 enum c_omp_clause_split s;
941 int i;
1e8e9920 942
bc7bff74 943 for (i = 0; i < C_OMP_CLAUSE_SPLIT_COUNT; i++)
944 cclauses[i] = NULL;
945 /* Add implicit nowait clause on
946 #pragma omp parallel {for,for simd,sections}. */
d62c713e 947 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
bc7bff74 948 switch (code)
949 {
950 case OMP_FOR:
951 case OMP_SIMD:
952 cclauses[C_OMP_CLAUSE_SPLIT_FOR]
953 = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
954 break;
955 case OMP_SECTIONS:
956 cclauses[C_OMP_CLAUSE_SPLIT_SECTIONS]
957 = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
958 break;
959 default:
960 break;
961 }
1e8e9920 962
963 for (; clauses ; clauses = next)
964 {
965 next = OMP_CLAUSE_CHAIN (clauses);
966
55d6e7cd 967 switch (OMP_CLAUSE_CODE (clauses))
1e8e9920 968 {
bc7bff74 969 /* First the clauses that are unique to some constructs. */
970 case OMP_CLAUSE_DEVICE:
971 case OMP_CLAUSE_MAP:
43895be5 972 case OMP_CLAUSE_IS_DEVICE_PTR:
973 case OMP_CLAUSE_DEFAULTMAP:
bc7bff74 974 s = C_OMP_CLAUSE_SPLIT_TARGET;
975 break;
976 case OMP_CLAUSE_NUM_TEAMS:
977 case OMP_CLAUSE_THREAD_LIMIT:
978 s = C_OMP_CLAUSE_SPLIT_TEAMS;
979 break;
980 case OMP_CLAUSE_DIST_SCHEDULE:
981 s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
982 break;
1e8e9920 983 case OMP_CLAUSE_COPYIN:
1e8e9920 984 case OMP_CLAUSE_NUM_THREADS:
bc7bff74 985 case OMP_CLAUSE_PROC_BIND:
986 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1e8e9920 987 break;
1e8e9920 988 case OMP_CLAUSE_ORDERED:
bc7bff74 989 case OMP_CLAUSE_NOWAIT:
990 s = C_OMP_CLAUSE_SPLIT_FOR;
991 break;
43895be5 992 case OMP_CLAUSE_SCHEDULE:
993 s = C_OMP_CLAUSE_SPLIT_FOR;
994 if (code != OMP_SIMD)
995 OMP_CLAUSE_SCHEDULE_SIMD (clauses) = 0;
996 break;
bc7bff74 997 case OMP_CLAUSE_SAFELEN:
43895be5 998 case OMP_CLAUSE_SIMDLEN:
bc7bff74 999 case OMP_CLAUSE_ALIGNED:
1000 s = C_OMP_CLAUSE_SPLIT_SIMD;
1001 break;
43895be5 1002 case OMP_CLAUSE_GRAINSIZE:
1003 case OMP_CLAUSE_NUM_TASKS:
1004 case OMP_CLAUSE_FINAL:
1005 case OMP_CLAUSE_UNTIED:
1006 case OMP_CLAUSE_MERGEABLE:
1007 case OMP_CLAUSE_NOGROUP:
1008 case OMP_CLAUSE_PRIORITY:
1009 s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
1010 break;
1011 /* Duplicate this to all of taskloop, distribute, for and simd. */
fd6481cf 1012 case OMP_CLAUSE_COLLAPSE:
bc7bff74 1013 if (code == OMP_SIMD)
1014 {
43895be5 1015 if ((mask & ((OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)
1016 | (OMP_CLAUSE_MASK_1
1017 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)
1018 | (OMP_CLAUSE_MASK_1
1019 << PRAGMA_OMP_CLAUSE_NOGROUP))) != 0)
1020 {
1021 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1022 OMP_CLAUSE_COLLAPSE);
1023 OMP_CLAUSE_COLLAPSE_EXPR (c)
1024 = OMP_CLAUSE_COLLAPSE_EXPR (clauses);
1025 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
1026 cclauses[C_OMP_CLAUSE_SPLIT_SIMD] = c;
1027 }
1028 else
1029 {
1030 /* This must be #pragma omp target simd */
1031 s = C_OMP_CLAUSE_SPLIT_SIMD;
1032 break;
1033 }
bc7bff74 1034 }
d62c713e 1035 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)) != 0)
bc7bff74 1036 {
d62c713e 1037 if ((mask & (OMP_CLAUSE_MASK_1
1038 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
bc7bff74 1039 {
1040 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1041 OMP_CLAUSE_COLLAPSE);
1042 OMP_CLAUSE_COLLAPSE_EXPR (c)
1043 = OMP_CLAUSE_COLLAPSE_EXPR (clauses);
1044 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
1045 cclauses[C_OMP_CLAUSE_SPLIT_FOR] = c;
1046 s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
1047 }
1048 else
1049 s = C_OMP_CLAUSE_SPLIT_FOR;
1050 }
43895be5 1051 else if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP))
1052 != 0)
1053 s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
bc7bff74 1054 else
1055 s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
1056 break;
43895be5 1057 /* Private clause is supported on all constructs,
bc7bff74 1058 it is enough to put it on the innermost one. For
1059 #pragma omp {for,sections} put it on parallel though,
1060 as that's what we did for OpenMP 3.1. */
1061 case OMP_CLAUSE_PRIVATE:
1062 switch (code)
1063 {
1064 case OMP_SIMD: s = C_OMP_CLAUSE_SPLIT_SIMD; break;
1065 case OMP_FOR: case OMP_SECTIONS:
1066 case OMP_PARALLEL: s = C_OMP_CLAUSE_SPLIT_PARALLEL; break;
1067 case OMP_DISTRIBUTE: s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE; break;
1068 case OMP_TEAMS: s = C_OMP_CLAUSE_SPLIT_TEAMS; break;
1069 default: gcc_unreachable ();
1070 }
1071 break;
1072 /* Firstprivate clause is supported on all constructs but
43895be5 1073 simd. Put it on the outermost of those and duplicate on teams
1074 and parallel. */
bc7bff74 1075 case OMP_CLAUSE_FIRSTPRIVATE:
43895be5 1076 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP))
1077 != 0)
1078 {
1079 if (code == OMP_SIMD
1080 && (mask & ((OMP_CLAUSE_MASK_1
1081 << PRAGMA_OMP_CLAUSE_NUM_THREADS)
1082 | (OMP_CLAUSE_MASK_1
1083 << PRAGMA_OMP_CLAUSE_NUM_TEAMS))) == 0)
1084 {
1085 /* This must be #pragma omp target simd. */
1086 s = C_OMP_CLAUSE_SPLIT_TARGET;
1087 break;
1088 }
1089 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1090 OMP_CLAUSE_FIRSTPRIVATE);
1091 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
1092 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
1093 cclauses[C_OMP_CLAUSE_SPLIT_TARGET] = c;
1094 }
d62c713e 1095 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS))
1096 != 0)
bc7bff74 1097 {
d62c713e 1098 if ((mask & ((OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS)
1099 | (OMP_CLAUSE_MASK_1
1100 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE))) != 0)
bc7bff74 1101 {
1102 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1103 OMP_CLAUSE_FIRSTPRIVATE);
1104 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
1105 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL];
1106 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] = c;
d62c713e 1107 if ((mask & (OMP_CLAUSE_MASK_1
1108 << PRAGMA_OMP_CLAUSE_NUM_TEAMS)) != 0)
bc7bff74 1109 s = C_OMP_CLAUSE_SPLIT_TEAMS;
1110 else
1111 s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
1112 }
1113 else
1114 /* This must be
43895be5 1115 #pragma omp parallel{, for{, simd}, sections}
1116 or
1117 #pragma omp target parallel. */
bc7bff74 1118 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1119 }
d62c713e 1120 else if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS))
1121 != 0)
bc7bff74 1122 {
5fddcf34 1123 /* This must be one of
1124 #pragma omp {,target }teams distribute
1125 #pragma omp target teams
1126 #pragma omp {,target }teams distribute simd. */
1127 gcc_assert (code == OMP_DISTRIBUTE
1128 || code == OMP_TEAMS
1129 || code == OMP_SIMD);
bc7bff74 1130 s = C_OMP_CLAUSE_SPLIT_TEAMS;
1131 }
d62c713e 1132 else if ((mask & (OMP_CLAUSE_MASK_1
1133 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
bc7bff74 1134 {
1135 /* This must be #pragma omp distribute simd. */
1136 gcc_assert (code == OMP_SIMD);
43895be5 1137 s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
1138 }
1139 else if ((mask & (OMP_CLAUSE_MASK_1
1140 << PRAGMA_OMP_CLAUSE_NOGROUP)) != 0)
1141 {
1142 /* This must be #pragma omp taskloop simd. */
1143 gcc_assert (code == OMP_SIMD);
1144 s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
bc7bff74 1145 }
1146 else
1147 {
1148 /* This must be #pragma omp for simd. */
1149 gcc_assert (code == OMP_SIMD);
1150 s = C_OMP_CLAUSE_SPLIT_FOR;
1151 }
1152 break;
9561765e 1153 /* Lastprivate is allowed on distribute, for, sections and simd. In
bc7bff74 1154 parallel {for{, simd},sections} we actually want to put it on
1155 parallel rather than for or sections. */
1156 case OMP_CLAUSE_LASTPRIVATE:
9561765e 1157 if (code == OMP_DISTRIBUTE)
1158 {
1159 s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
1160 break;
1161 }
1162 if ((mask & (OMP_CLAUSE_MASK_1
1163 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
1164 {
1165 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1166 OMP_CLAUSE_LASTPRIVATE);
1167 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
1168 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
1169 cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE] = c;
1170 }
bc7bff74 1171 if (code == OMP_FOR || code == OMP_SECTIONS)
1172 {
d62c713e 1173 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS))
1174 != 0)
bc7bff74 1175 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1176 else
1177 s = C_OMP_CLAUSE_SPLIT_FOR;
1178 break;
1179 }
1180 gcc_assert (code == OMP_SIMD);
d62c713e 1181 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)) != 0)
bc7bff74 1182 {
1183 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1184 OMP_CLAUSE_LASTPRIVATE);
1185 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
d62c713e 1186 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS))
1187 != 0)
bc7bff74 1188 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1189 else
1190 s = C_OMP_CLAUSE_SPLIT_FOR;
1191 OMP_CLAUSE_CHAIN (c) = cclauses[s];
1192 cclauses[s] = c;
1193 }
1194 s = C_OMP_CLAUSE_SPLIT_SIMD;
1195 break;
43895be5 1196 /* Shared and default clauses are allowed on parallel, teams and
1197 taskloop. */
bc7bff74 1198 case OMP_CLAUSE_SHARED:
1199 case OMP_CLAUSE_DEFAULT:
43895be5 1200 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP))
1201 != 0)
bc7bff74 1202 {
43895be5 1203 s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
bc7bff74 1204 break;
1205 }
d62c713e 1206 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS))
1207 != 0)
bc7bff74 1208 {
43895be5 1209 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS))
1210 == 0)
1211 {
1212 s = C_OMP_CLAUSE_SPLIT_TEAMS;
1213 break;
1214 }
bc7bff74 1215 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1216 OMP_CLAUSE_CODE (clauses));
1217 if (OMP_CLAUSE_CODE (clauses) == OMP_CLAUSE_SHARED)
1218 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
1219 else
1220 OMP_CLAUSE_DEFAULT_KIND (c)
1221 = OMP_CLAUSE_DEFAULT_KIND (clauses);
1222 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
1223 cclauses[C_OMP_CLAUSE_SPLIT_TEAMS] = c;
bc7bff74 1224 }
1225 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1226 break;
1227 /* Reduction is allowed on simd, for, parallel, sections and teams.
1228 Duplicate it on all of them, but omit on for or sections if
1229 parallel is present. */
1230 case OMP_CLAUSE_REDUCTION:
d62c713e 1231 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)) != 0)
bc7bff74 1232 {
43895be5 1233 if (code == OMP_SIMD)
1234 {
1235 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1236 OMP_CLAUSE_REDUCTION);
1237 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
1238 OMP_CLAUSE_REDUCTION_CODE (c)
1239 = OMP_CLAUSE_REDUCTION_CODE (clauses);
1240 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
1241 = OMP_CLAUSE_REDUCTION_PLACEHOLDER (clauses);
1242 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c)
1243 = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (clauses);
1244 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
1245 cclauses[C_OMP_CLAUSE_SPLIT_SIMD] = c;
1246 }
d62c713e 1247 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS))
1248 != 0)
bc7bff74 1249 {
1250 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1251 OMP_CLAUSE_REDUCTION);
1252 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
1253 OMP_CLAUSE_REDUCTION_CODE (c)
1254 = OMP_CLAUSE_REDUCTION_CODE (clauses);
1255 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
1256 = OMP_CLAUSE_REDUCTION_PLACEHOLDER (clauses);
43895be5 1257 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c)
1258 = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (clauses);
bc7bff74 1259 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL];
1260 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] = c;
1261 s = C_OMP_CLAUSE_SPLIT_TEAMS;
1262 }
d62c713e 1263 else if ((mask & (OMP_CLAUSE_MASK_1
1264 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
bc7bff74 1265 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1266 else
1267 s = C_OMP_CLAUSE_SPLIT_FOR;
1268 }
43895be5 1269 else if (code == OMP_SECTIONS || code == OMP_PARALLEL)
bc7bff74 1270 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
43895be5 1271 else if (code == OMP_SIMD)
1272 s = C_OMP_CLAUSE_SPLIT_SIMD;
bc7bff74 1273 else
1274 s = C_OMP_CLAUSE_SPLIT_TEAMS;
1275 break;
1276 case OMP_CLAUSE_IF:
43895be5 1277 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP))
d62c713e 1278 != 0)
43895be5 1279 s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
1280 else if ((mask & (OMP_CLAUSE_MASK_1
1281 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
1282 {
1283 if ((mask & (OMP_CLAUSE_MASK_1
1284 << PRAGMA_OMP_CLAUSE_MAP)) != 0)
1285 {
1286 if (OMP_CLAUSE_IF_MODIFIER (clauses) == OMP_PARALLEL)
1287 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1288 else if (OMP_CLAUSE_IF_MODIFIER (clauses) == OMP_TARGET)
1289 s = C_OMP_CLAUSE_SPLIT_TARGET;
1290 else if (OMP_CLAUSE_IF_MODIFIER (clauses) == ERROR_MARK)
1291 {
1292 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1293 OMP_CLAUSE_IF);
1294 OMP_CLAUSE_IF_MODIFIER (c)
1295 = OMP_CLAUSE_IF_MODIFIER (clauses);
1296 OMP_CLAUSE_IF_EXPR (c) = OMP_CLAUSE_IF_EXPR (clauses);
1297 OMP_CLAUSE_CHAIN (c)
1298 = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
1299 cclauses[C_OMP_CLAUSE_SPLIT_TARGET] = c;
1300 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1301 }
1302 else
1303 {
1304 error_at (OMP_CLAUSE_LOCATION (clauses),
1305 "expected %<parallel%> or %<target%> %<if%> "
1306 "clause modifier");
1307 continue;
1308 }
1309 }
1310 else
1311 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1312 }
bc7bff74 1313 else
1314 s = C_OMP_CLAUSE_SPLIT_TARGET;
1e8e9920 1315 break;
43895be5 1316 case OMP_CLAUSE_LINEAR:
1317 /* Linear clause is allowed on simd and for. Put it on the
1318 innermost construct. */
1319 if (code == OMP_SIMD)
1320 s = C_OMP_CLAUSE_SPLIT_SIMD;
1321 else
1322 s = C_OMP_CLAUSE_SPLIT_FOR;
1323 break;
1e8e9920 1324 default:
1325 gcc_unreachable ();
1326 }
bc7bff74 1327 OMP_CLAUSE_CHAIN (clauses) = cclauses[s];
1328 cclauses[s] = clauses;
1e8e9920 1329 }
5e8689fb 1330
1331 if (!flag_checking)
1332 return;
1333
43895be5 1334 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) == 0)
1335 gcc_assert (cclauses[C_OMP_CLAUSE_SPLIT_TARGET] == NULL_TREE);
1336 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS)) == 0)
1337 gcc_assert (cclauses[C_OMP_CLAUSE_SPLIT_TEAMS] == NULL_TREE);
1338 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) == 0)
1339 gcc_assert (cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE] == NULL_TREE);
1340 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) == 0)
1341 gcc_assert (cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] == NULL_TREE);
1342 if ((mask & ((OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)
1343 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP))) == 0
1344 && code != OMP_SECTIONS)
1345 gcc_assert (cclauses[C_OMP_CLAUSE_SPLIT_FOR] == NULL_TREE);
1346 if (code != OMP_SIMD)
1347 gcc_assert (cclauses[C_OMP_CLAUSE_SPLIT_SIMD] == NULL_TREE);
1e8e9920 1348}
1349
bc7bff74 1350
1351/* qsort callback to compare #pragma omp declare simd clauses. */
1352
1353static int
1354c_omp_declare_simd_clause_cmp (const void *p, const void *q)
1355{
1356 tree a = *(const tree *) p;
1357 tree b = *(const tree *) q;
1358 if (OMP_CLAUSE_CODE (a) != OMP_CLAUSE_CODE (b))
1359 {
1360 if (OMP_CLAUSE_CODE (a) > OMP_CLAUSE_CODE (b))
1361 return -1;
1362 return 1;
1363 }
1364 if (OMP_CLAUSE_CODE (a) != OMP_CLAUSE_SIMDLEN
1365 && OMP_CLAUSE_CODE (a) != OMP_CLAUSE_INBRANCH
1366 && OMP_CLAUSE_CODE (a) != OMP_CLAUSE_NOTINBRANCH)
1367 {
fcb97e84 1368 int c = tree_to_shwi (OMP_CLAUSE_DECL (a));
1369 int d = tree_to_shwi (OMP_CLAUSE_DECL (b));
bc7bff74 1370 if (c < d)
1371 return 1;
1372 if (c > d)
1373 return -1;
1374 }
1375 return 0;
1376}
1377
1378/* Change PARM_DECLs in OMP_CLAUSE_DECL of #pragma omp declare simd
1379 CLAUSES on FNDECL into argument indexes and sort them. */
1380
1381tree
1382c_omp_declare_simd_clauses_to_numbers (tree parms, tree clauses)
1383{
1384 tree c;
1385 vec<tree> clvec = vNULL;
1386
1387 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
1388 {
1389 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_SIMDLEN
1390 && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_INBRANCH
1391 && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_NOTINBRANCH)
1392 {
1393 tree decl = OMP_CLAUSE_DECL (c);
1394 tree arg;
1395 int idx;
1396 for (arg = parms, idx = 0; arg;
1397 arg = TREE_CHAIN (arg), idx++)
1398 if (arg == decl)
1399 break;
1400 if (arg == NULL_TREE)
1401 {
1402 error_at (OMP_CLAUSE_LOCATION (c),
1403 "%qD is not an function argument", decl);
1404 continue;
1405 }
1406 OMP_CLAUSE_DECL (c) = build_int_cst (integer_type_node, idx);
9561765e 1407 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
1408 && OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (c))
1409 {
1410 decl = OMP_CLAUSE_LINEAR_STEP (c);
1411 for (arg = parms, idx = 0; arg;
1412 arg = TREE_CHAIN (arg), idx++)
1413 if (arg == decl)
1414 break;
1415 if (arg == NULL_TREE)
1416 {
1417 error_at (OMP_CLAUSE_LOCATION (c),
1418 "%qD is not an function argument", decl);
1419 continue;
1420 }
1421 OMP_CLAUSE_LINEAR_STEP (c)
1422 = build_int_cst (integer_type_node, idx);
1423 }
bc7bff74 1424 }
1425 clvec.safe_push (c);
1426 }
1427 if (!clvec.is_empty ())
1428 {
1429 unsigned int len = clvec.length (), i;
1430 clvec.qsort (c_omp_declare_simd_clause_cmp);
1431 clauses = clvec[0];
1432 for (i = 0; i < len; i++)
1433 OMP_CLAUSE_CHAIN (clvec[i]) = (i < len - 1) ? clvec[i + 1] : NULL_TREE;
1434 }
386ef929 1435 else
1436 clauses = NULL_TREE;
bc7bff74 1437 clvec.release ();
1438 return clauses;
1439}
1440
1441/* Change argument indexes in CLAUSES of FNDECL back to PARM_DECLs. */
1442
1443void
1444c_omp_declare_simd_clauses_to_decls (tree fndecl, tree clauses)
1445{
1446 tree c;
1447
1448 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
1449 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_SIMDLEN
1450 && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_INBRANCH
1451 && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_NOTINBRANCH)
1452 {
fcb97e84 1453 int idx = tree_to_shwi (OMP_CLAUSE_DECL (c)), i;
bc7bff74 1454 tree arg;
1455 for (arg = DECL_ARGUMENTS (fndecl), i = 0; arg;
1456 arg = TREE_CHAIN (arg), i++)
1457 if (i == idx)
1458 break;
1459 gcc_assert (arg);
1460 OMP_CLAUSE_DECL (c) = arg;
9561765e 1461 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
1462 && OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (c))
1463 {
1464 idx = tree_to_shwi (OMP_CLAUSE_LINEAR_STEP (c));
1465 for (arg = DECL_ARGUMENTS (fndecl), i = 0; arg;
1466 arg = TREE_CHAIN (arg), i++)
1467 if (i == idx)
1468 break;
1469 gcc_assert (arg);
1470 OMP_CLAUSE_LINEAR_STEP (c) = arg;
1471 }
bc7bff74 1472 }
1473}
1474
1e8e9920 1475/* True if OpenMP sharing attribute of DECL is predetermined. */
1476
1477enum omp_clause_default_kind
1478c_omp_predetermined_sharing (tree decl)
1479{
1480 /* Variables with const-qualified type having no mutable member
1481 are predetermined shared. */
1482 if (TREE_READONLY (decl))
1483 return OMP_CLAUSE_DEFAULT_SHARED;
1484
1485 return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
1486}