net/internal/socktest: build sys_unix.go on AIX
[official-gcc.git] / gcc / c-family / c-omp.c
blobeef7ac0c769b50da04d5a2b4aa22b0d872cd00d7
1 /* This file contains routines to construct OpenACC and OpenMP constructs,
2 called from parsing in the C and C++ front ends.
4 Copyright (C) 2005-2017 Free Software Foundation, Inc.
5 Contributed by Richard Henderson <rth@redhat.com>,
6 Diego Novillo <dnovillo@redhat.com>.
8 This file is part of GCC.
10 GCC is free software; you can redistribute it and/or modify it under
11 the terms of the GNU General Public License as published by the Free
12 Software Foundation; either version 3, or (at your option) any later
13 version.
15 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
16 WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 for more details.
20 You should have received a copy of the GNU General Public License
21 along with GCC; see the file COPYING3. If not see
22 <http://www.gnu.org/licenses/>. */
24 #include "config.h"
25 #include "system.h"
26 #include "coretypes.h"
27 #include "options.h"
28 #include "c-common.h"
29 #include "gimple-expr.h"
30 #include "c-pragma.h"
31 #include "omp-general.h"
32 #include "gomp-constants.h"
35 /* Complete a #pragma oacc wait construct. LOC is the location of
36 the #pragma. */
38 tree
39 c_finish_oacc_wait (location_t loc, tree parms, tree clauses)
41 const int nparms = list_length (parms);
42 tree stmt, t;
43 vec<tree, va_gc> *args;
45 vec_alloc (args, nparms + 2);
46 stmt = builtin_decl_explicit (BUILT_IN_GOACC_WAIT);
48 if (omp_find_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);
53 args->quick_push (t);
54 args->quick_push (build_int_cst (integer_type_node, nparms));
56 for (t = parms; t; t = TREE_CHAIN (t))
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));
65 stmt = build_call_expr_loc_vec (loc, stmt, args);
67 vec_free (args);
69 return stmt;
72 /* Complete a #pragma omp master construct. STMT is the structured-block
73 that follows the pragma. LOC is the l*/
75 tree
76 c_finish_omp_master (location_t loc, tree stmt)
78 tree t = add_stmt (build1 (OMP_MASTER, void_type_node, stmt));
79 SET_EXPR_LOCATION (t, loc);
80 return t;
83 /* Complete a #pragma omp taskgroup construct. STMT is the structured-block
84 that follows the pragma. LOC is the l*/
86 tree
87 c_finish_omp_taskgroup (location_t loc, tree stmt)
89 tree t = add_stmt (build1 (OMP_TASKGROUP, void_type_node, stmt));
90 SET_EXPR_LOCATION (t, loc);
91 return t;
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
96 if it was omitted. LOC is the location of the #pragma. */
98 tree
99 c_finish_omp_critical (location_t loc, tree body, tree name, tree clauses)
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;
105 OMP_CRITICAL_CLAUSES (stmt) = clauses;
106 SET_EXPR_LOCATION (stmt, loc);
107 return add_stmt (stmt);
110 /* Complete a #pragma omp ordered construct. STMT is the structured-block
111 that follows the pragma. LOC is the location of the #pragma. */
113 tree
114 c_finish_omp_ordered (location_t loc, tree clauses, tree stmt)
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;
120 SET_EXPR_LOCATION (t, loc);
121 return add_stmt (t);
125 /* Complete a #pragma omp barrier construct. LOC is the location of
126 the #pragma. */
128 void
129 c_finish_omp_barrier (location_t loc)
131 tree x;
133 x = builtin_decl_explicit (BUILT_IN_GOMP_BARRIER);
134 x = build_call_expr_loc (loc, x, 0);
135 add_stmt (x);
139 /* Complete a #pragma omp taskwait construct. LOC is the location of the
140 pragma. */
142 void
143 c_finish_omp_taskwait (location_t loc)
145 tree x;
147 x = builtin_decl_explicit (BUILT_IN_GOMP_TASKWAIT);
148 x = build_call_expr_loc (loc, x, 0);
149 add_stmt (x);
153 /* Complete a #pragma omp taskyield construct. LOC is the location of the
154 pragma. */
156 void
157 c_finish_omp_taskyield (location_t loc)
159 tree x;
161 x = builtin_decl_explicit (BUILT_IN_GOMP_TASKYIELD);
162 x = build_call_expr_loc (loc, x, 0);
163 add_stmt (x);
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
174 tree with add_stmt. If TEST is set, avoid calling save_expr
175 or create_tmp_var*. */
177 tree
178 c_finish_omp_atomic (location_t loc, enum tree_code code,
179 enum tree_code opcode, tree lhs, tree rhs,
180 tree v, tree lhs1, tree rhs1, bool swapped, bool seq_cst,
181 bool test)
183 tree x, type, addr, pre = NULL_TREE;
184 HOST_WIDE_INT bitpos = 0, bitsize = 0;
186 if (lhs == error_mark_node || rhs == error_mark_node
187 || v == error_mark_node || lhs1 == error_mark_node
188 || rhs1 == error_mark_node)
189 return error_mark_node;
191 /* ??? According to one reading of the OpenMP spec, complex type are
192 supported, but there are no atomic stores for any architecture.
193 But at least icc 9.0 doesn't support complex types here either.
194 And lets not even talk about vector types... */
195 type = TREE_TYPE (lhs);
196 if (!INTEGRAL_TYPE_P (type)
197 && !POINTER_TYPE_P (type)
198 && !SCALAR_FLOAT_TYPE_P (type))
200 error_at (loc, "invalid expression type for %<#pragma omp atomic%>");
201 return error_mark_node;
203 if (TYPE_ATOMIC (type))
205 error_at (loc, "%<_Atomic%> expression in %<#pragma omp atomic%>");
206 return error_mark_node;
209 if (opcode == RDIV_EXPR)
210 opcode = TRUNC_DIV_EXPR;
212 /* ??? Validate that rhs does not overlap lhs. */
213 tree blhs = NULL;
214 if (TREE_CODE (lhs) == COMPONENT_REF
215 && TREE_CODE (TREE_OPERAND (lhs, 1)) == FIELD_DECL
216 && DECL_C_BIT_FIELD (TREE_OPERAND (lhs, 1))
217 && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (lhs, 1)))
219 tree field = TREE_OPERAND (lhs, 1);
220 tree repr = DECL_BIT_FIELD_REPRESENTATIVE (field);
221 if (tree_fits_uhwi_p (DECL_FIELD_OFFSET (field))
222 && tree_fits_uhwi_p (DECL_FIELD_OFFSET (repr)))
223 bitpos = (tree_to_uhwi (DECL_FIELD_OFFSET (field))
224 - tree_to_uhwi (DECL_FIELD_OFFSET (repr))) * BITS_PER_UNIT;
225 else
226 bitpos = 0;
227 bitpos += (tree_to_uhwi (DECL_FIELD_BIT_OFFSET (field))
228 - tree_to_uhwi (DECL_FIELD_BIT_OFFSET (repr)));
229 gcc_assert (tree_fits_shwi_p (DECL_SIZE (field)));
230 bitsize = tree_to_shwi (DECL_SIZE (field));
231 blhs = lhs;
232 type = TREE_TYPE (repr);
233 lhs = build3 (COMPONENT_REF, TREE_TYPE (repr), TREE_OPERAND (lhs, 0),
234 repr, TREE_OPERAND (lhs, 2));
237 /* Take and save the address of the lhs. From then on we'll reference it
238 via indirection. */
239 addr = build_unary_op (loc, ADDR_EXPR, lhs, false);
240 if (addr == error_mark_node)
241 return error_mark_node;
242 if (!test)
243 addr = save_expr (addr);
244 if (!test
245 && TREE_CODE (addr) != SAVE_EXPR
246 && (TREE_CODE (addr) != ADDR_EXPR
247 || !VAR_P (TREE_OPERAND (addr, 0))))
249 /* Make sure LHS is simple enough so that goa_lhs_expr_p can recognize
250 it even after unsharing function body. */
251 tree var = create_tmp_var_raw (TREE_TYPE (addr));
252 DECL_CONTEXT (var) = current_function_decl;
253 addr = build4 (TARGET_EXPR, TREE_TYPE (addr), var, addr, NULL, NULL);
255 tree orig_lhs = lhs;
256 lhs = build_indirect_ref (loc, addr, RO_NULL);
257 tree new_lhs = lhs;
259 if (code == OMP_ATOMIC_READ)
261 x = build1 (OMP_ATOMIC_READ, type, addr);
262 SET_EXPR_LOCATION (x, loc);
263 OMP_ATOMIC_SEQ_CST (x) = seq_cst;
264 if (blhs)
265 x = build3_loc (loc, BIT_FIELD_REF, TREE_TYPE (blhs), x,
266 bitsize_int (bitsize), bitsize_int (bitpos));
267 return build_modify_expr (loc, v, NULL_TREE, NOP_EXPR,
268 loc, x, NULL_TREE);
271 /* There are lots of warnings, errors, and conversions that need to happen
272 in the course of interpreting a statement. Use the normal mechanisms
273 to do this, and then take it apart again. */
274 if (blhs)
276 lhs = build3_loc (loc, BIT_FIELD_REF, TREE_TYPE (blhs), lhs,
277 bitsize_int (bitsize), bitsize_int (bitpos));
278 if (swapped)
279 rhs = build_binary_op (loc, opcode, rhs, lhs, true);
280 else if (opcode != NOP_EXPR)
281 rhs = build_binary_op (loc, opcode, lhs, rhs, true);
282 opcode = NOP_EXPR;
284 else if (swapped)
286 rhs = build_binary_op (loc, opcode, rhs, lhs, true);
287 opcode = NOP_EXPR;
289 bool save = in_late_binary_op;
290 in_late_binary_op = true;
291 x = build_modify_expr (loc, blhs ? blhs : lhs, NULL_TREE, opcode,
292 loc, rhs, NULL_TREE);
293 in_late_binary_op = save;
294 if (x == error_mark_node)
295 return error_mark_node;
296 if (TREE_CODE (x) == COMPOUND_EXPR)
298 pre = TREE_OPERAND (x, 0);
299 gcc_assert (TREE_CODE (pre) == SAVE_EXPR);
300 x = TREE_OPERAND (x, 1);
302 gcc_assert (TREE_CODE (x) == MODIFY_EXPR);
303 rhs = TREE_OPERAND (x, 1);
305 if (blhs)
306 rhs = build3_loc (loc, BIT_INSERT_EXPR, type, new_lhs,
307 rhs, bitsize_int (bitpos));
309 /* Punt the actual generation of atomic operations to common code. */
310 if (code == OMP_ATOMIC)
311 type = void_type_node;
312 x = build2 (code, type, addr, rhs);
313 SET_EXPR_LOCATION (x, loc);
314 OMP_ATOMIC_SEQ_CST (x) = seq_cst;
316 /* Generally it is hard to prove lhs1 and lhs are the same memory
317 location, just diagnose different variables. */
318 if (rhs1
319 && VAR_P (rhs1)
320 && VAR_P (orig_lhs)
321 && rhs1 != orig_lhs
322 && !test)
324 if (code == OMP_ATOMIC)
325 error_at (loc, "%<#pragma omp atomic update%> uses two different "
326 "variables for memory");
327 else
328 error_at (loc, "%<#pragma omp atomic capture%> uses two different "
329 "variables for memory");
330 return error_mark_node;
333 if (lhs1
334 && lhs1 != orig_lhs
335 && TREE_CODE (lhs1) == COMPONENT_REF
336 && TREE_CODE (TREE_OPERAND (lhs1, 1)) == FIELD_DECL
337 && DECL_C_BIT_FIELD (TREE_OPERAND (lhs1, 1))
338 && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (lhs1, 1)))
340 tree field = TREE_OPERAND (lhs1, 1);
341 tree repr = DECL_BIT_FIELD_REPRESENTATIVE (field);
342 lhs1 = build3 (COMPONENT_REF, TREE_TYPE (repr), TREE_OPERAND (lhs1, 0),
343 repr, TREE_OPERAND (lhs1, 2));
345 if (rhs1
346 && rhs1 != orig_lhs
347 && TREE_CODE (rhs1) == COMPONENT_REF
348 && TREE_CODE (TREE_OPERAND (rhs1, 1)) == FIELD_DECL
349 && DECL_C_BIT_FIELD (TREE_OPERAND (rhs1, 1))
350 && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (rhs1, 1)))
352 tree field = TREE_OPERAND (rhs1, 1);
353 tree repr = DECL_BIT_FIELD_REPRESENTATIVE (field);
354 rhs1 = build3 (COMPONENT_REF, TREE_TYPE (repr), TREE_OPERAND (rhs1, 0),
355 repr, TREE_OPERAND (rhs1, 2));
358 if (code != OMP_ATOMIC)
360 /* Generally it is hard to prove lhs1 and lhs are the same memory
361 location, just diagnose different variables. */
362 if (lhs1 && VAR_P (lhs1) && VAR_P (orig_lhs))
364 if (lhs1 != orig_lhs && !test)
366 error_at (loc, "%<#pragma omp atomic capture%> uses two "
367 "different variables for memory");
368 return error_mark_node;
371 if (blhs)
372 x = build3_loc (loc, BIT_FIELD_REF, TREE_TYPE (blhs), x,
373 bitsize_int (bitsize), bitsize_int (bitpos));
374 x = build_modify_expr (loc, v, NULL_TREE, NOP_EXPR,
375 loc, x, NULL_TREE);
376 if (rhs1 && rhs1 != orig_lhs)
378 tree rhs1addr = build_unary_op (loc, ADDR_EXPR, rhs1, false);
379 if (rhs1addr == error_mark_node)
380 return error_mark_node;
381 x = omit_one_operand_loc (loc, type, x, rhs1addr);
383 if (lhs1 && lhs1 != orig_lhs)
385 tree lhs1addr = build_unary_op (loc, ADDR_EXPR, lhs1, false);
386 if (lhs1addr == error_mark_node)
387 return error_mark_node;
388 if (code == OMP_ATOMIC_CAPTURE_OLD)
389 x = omit_one_operand_loc (loc, type, x, lhs1addr);
390 else
392 if (!test)
393 x = save_expr (x);
394 x = omit_two_operands_loc (loc, type, x, x, lhs1addr);
398 else if (rhs1 && rhs1 != orig_lhs)
400 tree rhs1addr = build_unary_op (loc, ADDR_EXPR, rhs1, false);
401 if (rhs1addr == error_mark_node)
402 return error_mark_node;
403 x = omit_one_operand_loc (loc, type, x, rhs1addr);
406 if (pre)
407 x = omit_one_operand_loc (loc, type, x, pre);
408 return x;
412 /* Complete a #pragma omp flush construct. We don't do anything with
413 the variable list that the syntax allows. LOC is the location of
414 the #pragma. */
416 void
417 c_finish_omp_flush (location_t loc)
419 tree x;
421 x = builtin_decl_explicit (BUILT_IN_SYNC_SYNCHRONIZE);
422 x = build_call_expr_loc (loc, x, 0);
423 add_stmt (x);
427 /* Check and canonicalize OMP_FOR increment expression.
428 Helper function for c_finish_omp_for. */
430 static tree
431 check_omp_for_incr_expr (location_t loc, tree exp, tree decl)
433 tree t;
435 if (!INTEGRAL_TYPE_P (TREE_TYPE (exp))
436 || TYPE_PRECISION (TREE_TYPE (exp)) < TYPE_PRECISION (TREE_TYPE (decl)))
437 return error_mark_node;
439 if (exp == decl)
440 return build_int_cst (TREE_TYPE (exp), 0);
442 switch (TREE_CODE (exp))
444 CASE_CONVERT:
445 t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 0), decl);
446 if (t != error_mark_node)
447 return fold_convert_loc (loc, TREE_TYPE (exp), t);
448 break;
449 case MINUS_EXPR:
450 t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 0), decl);
451 if (t != error_mark_node)
452 return fold_build2_loc (loc, MINUS_EXPR,
453 TREE_TYPE (exp), t, TREE_OPERAND (exp, 1));
454 break;
455 case PLUS_EXPR:
456 t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 0), decl);
457 if (t != error_mark_node)
458 return fold_build2_loc (loc, PLUS_EXPR,
459 TREE_TYPE (exp), t, TREE_OPERAND (exp, 1));
460 t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 1), decl);
461 if (t != error_mark_node)
462 return fold_build2_loc (loc, PLUS_EXPR,
463 TREE_TYPE (exp), TREE_OPERAND (exp, 0), t);
464 break;
465 case COMPOUND_EXPR:
467 /* cp_build_modify_expr forces preevaluation of the RHS to make
468 sure that it is evaluated before the lvalue-rvalue conversion
469 is applied to the LHS. Reconstruct the original expression. */
470 tree op0 = TREE_OPERAND (exp, 0);
471 if (TREE_CODE (op0) == TARGET_EXPR
472 && !VOID_TYPE_P (TREE_TYPE (op0)))
474 tree op1 = TREE_OPERAND (exp, 1);
475 tree temp = TARGET_EXPR_SLOT (op0);
476 if (BINARY_CLASS_P (op1)
477 && TREE_OPERAND (op1, 1) == temp)
479 op1 = copy_node (op1);
480 TREE_OPERAND (op1, 1) = TARGET_EXPR_INITIAL (op0);
481 return check_omp_for_incr_expr (loc, op1, decl);
484 break;
486 default:
487 break;
490 return error_mark_node;
493 /* If the OMP_FOR increment expression in INCR is of pointer type,
494 canonicalize it into an expression handled by gimplify_omp_for()
495 and return it. DECL is the iteration variable. */
497 static tree
498 c_omp_for_incr_canonicalize_ptr (location_t loc, tree decl, tree incr)
500 if (POINTER_TYPE_P (TREE_TYPE (decl))
501 && TREE_OPERAND (incr, 1))
503 tree t = fold_convert_loc (loc,
504 sizetype, TREE_OPERAND (incr, 1));
506 if (TREE_CODE (incr) == POSTDECREMENT_EXPR
507 || TREE_CODE (incr) == PREDECREMENT_EXPR)
508 t = fold_build1_loc (loc, NEGATE_EXPR, sizetype, t);
509 t = fold_build_pointer_plus (decl, t);
510 incr = build2 (MODIFY_EXPR, void_type_node, decl, t);
512 return incr;
515 /* Validate and generate OMP_FOR.
516 DECLV is a vector of iteration variables, for each collapsed loop.
518 ORIG_DECLV, if non-NULL, is a vector with the original iteration
519 variables (prior to any transformations, by say, C++ iterators).
521 INITV, CONDV and INCRV are vectors containing initialization
522 expressions, controlling predicates and increment expressions.
523 BODY is the body of the loop and PRE_BODY statements that go before
524 the loop. */
526 tree
527 c_finish_omp_for (location_t locus, enum tree_code code, tree declv,
528 tree orig_declv, tree initv, tree condv, tree incrv,
529 tree body, tree pre_body)
531 location_t elocus;
532 bool fail = false;
533 int i;
535 if ((code == CILK_SIMD || code == CILK_FOR)
536 && !c_check_cilk_loop (locus, TREE_VEC_ELT (declv, 0)))
537 fail = true;
539 gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (initv));
540 gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (condv));
541 gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (incrv));
542 for (i = 0; i < TREE_VEC_LENGTH (declv); i++)
544 tree decl = TREE_VEC_ELT (declv, i);
545 tree init = TREE_VEC_ELT (initv, i);
546 tree cond = TREE_VEC_ELT (condv, i);
547 tree incr = TREE_VEC_ELT (incrv, i);
549 elocus = locus;
550 if (EXPR_HAS_LOCATION (init))
551 elocus = EXPR_LOCATION (init);
553 /* Validate the iteration variable. */
554 if (!INTEGRAL_TYPE_P (TREE_TYPE (decl))
555 && TREE_CODE (TREE_TYPE (decl)) != POINTER_TYPE)
557 error_at (elocus, "invalid type for iteration variable %qE", decl);
558 fail = true;
560 else if (TYPE_ATOMIC (TREE_TYPE (decl)))
562 error_at (elocus, "%<_Atomic%> iteration variable %qE", decl);
563 fail = true;
564 /* _Atomic iterator confuses stuff too much, so we risk ICE
565 trying to diagnose it further. */
566 continue;
569 /* In the case of "for (int i = 0...)", init will be a decl. It should
570 have a DECL_INITIAL that we can turn into an assignment. */
571 if (init == decl)
573 elocus = DECL_SOURCE_LOCATION (decl);
575 init = DECL_INITIAL (decl);
576 if (init == NULL)
578 error_at (elocus, "%qE is not initialized", decl);
579 init = integer_zero_node;
580 fail = true;
582 DECL_INITIAL (decl) = NULL_TREE;
584 init = build_modify_expr (elocus, decl, NULL_TREE, NOP_EXPR,
585 /* FIXME diagnostics: This should
586 be the location of the INIT. */
587 elocus,
588 init,
589 NULL_TREE);
591 if (init != error_mark_node)
593 gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
594 gcc_assert (TREE_OPERAND (init, 0) == decl);
597 if (cond == NULL_TREE)
599 error_at (elocus, "missing controlling predicate");
600 fail = true;
602 else
604 bool cond_ok = false;
606 /* E.g. C sizeof (vla) could add COMPOUND_EXPRs with
607 evaluation of the vla VAR_DECL. We need to readd
608 them to the non-decl operand. See PR45784. */
609 while (TREE_CODE (cond) == COMPOUND_EXPR)
610 cond = TREE_OPERAND (cond, 1);
612 if (EXPR_HAS_LOCATION (cond))
613 elocus = EXPR_LOCATION (cond);
615 if (TREE_CODE (cond) == LT_EXPR
616 || TREE_CODE (cond) == LE_EXPR
617 || TREE_CODE (cond) == GT_EXPR
618 || TREE_CODE (cond) == GE_EXPR
619 || TREE_CODE (cond) == NE_EXPR
620 || TREE_CODE (cond) == EQ_EXPR)
622 tree op0 = TREE_OPERAND (cond, 0);
623 tree op1 = TREE_OPERAND (cond, 1);
625 /* 2.5.1. The comparison in the condition is computed in
626 the type of DECL, otherwise the behavior is undefined.
628 For example:
629 long n; int i;
630 i < n;
632 according to ISO will be evaluated as:
633 (long)i < n;
635 We want to force:
636 i < (int)n; */
637 if (TREE_CODE (op0) == NOP_EXPR
638 && decl == TREE_OPERAND (op0, 0))
640 TREE_OPERAND (cond, 0) = TREE_OPERAND (op0, 0);
641 TREE_OPERAND (cond, 1)
642 = fold_build1_loc (elocus, NOP_EXPR, TREE_TYPE (decl),
643 TREE_OPERAND (cond, 1));
645 else if (TREE_CODE (op1) == NOP_EXPR
646 && decl == TREE_OPERAND (op1, 0))
648 TREE_OPERAND (cond, 1) = TREE_OPERAND (op1, 0);
649 TREE_OPERAND (cond, 0)
650 = fold_build1_loc (elocus, NOP_EXPR, TREE_TYPE (decl),
651 TREE_OPERAND (cond, 0));
654 if (decl == TREE_OPERAND (cond, 0))
655 cond_ok = true;
656 else if (decl == TREE_OPERAND (cond, 1))
658 TREE_SET_CODE (cond,
659 swap_tree_comparison (TREE_CODE (cond)));
660 TREE_OPERAND (cond, 1) = TREE_OPERAND (cond, 0);
661 TREE_OPERAND (cond, 0) = decl;
662 cond_ok = true;
665 if (TREE_CODE (cond) == NE_EXPR
666 || TREE_CODE (cond) == EQ_EXPR)
668 if (!INTEGRAL_TYPE_P (TREE_TYPE (decl)))
670 if (code != CILK_SIMD && code != CILK_FOR)
671 cond_ok = false;
673 else if (operand_equal_p (TREE_OPERAND (cond, 1),
674 TYPE_MIN_VALUE (TREE_TYPE (decl)),
676 TREE_SET_CODE (cond, TREE_CODE (cond) == NE_EXPR
677 ? GT_EXPR : LE_EXPR);
678 else if (operand_equal_p (TREE_OPERAND (cond, 1),
679 TYPE_MAX_VALUE (TREE_TYPE (decl)),
681 TREE_SET_CODE (cond, TREE_CODE (cond) == NE_EXPR
682 ? LT_EXPR : GE_EXPR);
683 else if (code != CILK_SIMD && code != CILK_FOR)
684 cond_ok = false;
687 if (cond_ok && TREE_VEC_ELT (condv, i) != cond)
689 tree ce = NULL_TREE, *pce = &ce;
690 tree type = TREE_TYPE (TREE_OPERAND (cond, 1));
691 for (tree c = TREE_VEC_ELT (condv, i); c != cond;
692 c = TREE_OPERAND (c, 1))
694 *pce = build2 (COMPOUND_EXPR, type, TREE_OPERAND (c, 0),
695 TREE_OPERAND (cond, 1));
696 pce = &TREE_OPERAND (*pce, 1);
698 TREE_OPERAND (cond, 1) = ce;
699 TREE_VEC_ELT (condv, i) = cond;
703 if (!cond_ok)
705 error_at (elocus, "invalid controlling predicate");
706 fail = true;
710 if (incr == NULL_TREE)
712 error_at (elocus, "missing increment expression");
713 fail = true;
715 else
717 bool incr_ok = false;
719 if (EXPR_HAS_LOCATION (incr))
720 elocus = EXPR_LOCATION (incr);
722 /* Check all the valid increment expressions: v++, v--, ++v, --v,
723 v = v + incr, v = incr + v and v = v - incr. */
724 switch (TREE_CODE (incr))
726 case POSTINCREMENT_EXPR:
727 case PREINCREMENT_EXPR:
728 case POSTDECREMENT_EXPR:
729 case PREDECREMENT_EXPR:
730 if (TREE_OPERAND (incr, 0) != decl)
731 break;
733 incr_ok = true;
734 incr = c_omp_for_incr_canonicalize_ptr (elocus, decl, incr);
735 break;
737 case COMPOUND_EXPR:
738 if (TREE_CODE (TREE_OPERAND (incr, 0)) != SAVE_EXPR
739 || TREE_CODE (TREE_OPERAND (incr, 1)) != MODIFY_EXPR)
740 break;
741 incr = TREE_OPERAND (incr, 1);
742 /* FALLTHRU */
743 case MODIFY_EXPR:
744 if (TREE_OPERAND (incr, 0) != decl)
745 break;
746 if (TREE_OPERAND (incr, 1) == decl)
747 break;
748 if (TREE_CODE (TREE_OPERAND (incr, 1)) == PLUS_EXPR
749 && (TREE_OPERAND (TREE_OPERAND (incr, 1), 0) == decl
750 || TREE_OPERAND (TREE_OPERAND (incr, 1), 1) == decl))
751 incr_ok = true;
752 else if ((TREE_CODE (TREE_OPERAND (incr, 1)) == MINUS_EXPR
753 || (TREE_CODE (TREE_OPERAND (incr, 1))
754 == POINTER_PLUS_EXPR))
755 && TREE_OPERAND (TREE_OPERAND (incr, 1), 0) == decl)
756 incr_ok = true;
757 else
759 tree t = check_omp_for_incr_expr (elocus,
760 TREE_OPERAND (incr, 1),
761 decl);
762 if (t != error_mark_node)
764 incr_ok = true;
765 t = build2 (PLUS_EXPR, TREE_TYPE (decl), decl, t);
766 incr = build2 (MODIFY_EXPR, void_type_node, decl, t);
769 break;
771 default:
772 break;
774 if (!incr_ok)
776 error_at (elocus, "invalid increment expression");
777 fail = true;
781 TREE_VEC_ELT (initv, i) = init;
782 TREE_VEC_ELT (incrv, i) = incr;
785 if (fail)
786 return NULL;
787 else
789 tree t = make_node (code);
791 TREE_TYPE (t) = void_type_node;
792 OMP_FOR_INIT (t) = initv;
793 OMP_FOR_COND (t) = condv;
794 OMP_FOR_INCR (t) = incrv;
795 OMP_FOR_BODY (t) = body;
796 OMP_FOR_PRE_BODY (t) = pre_body;
797 OMP_FOR_ORIG_DECLS (t) = orig_declv;
799 SET_EXPR_LOCATION (t, locus);
800 return t;
804 /* Type for passing data in between c_omp_check_loop_iv and
805 c_omp_check_loop_iv_r. */
807 struct c_omp_check_loop_iv_data
809 tree declv;
810 bool fail;
811 location_t stmt_loc;
812 location_t expr_loc;
813 int kind;
814 walk_tree_lh lh;
815 hash_set<tree> *ppset;
818 /* Helper function called via walk_tree, to diagnose uses
819 of associated loop IVs inside of lb, b and incr expressions
820 of OpenMP loops. */
822 static tree
823 c_omp_check_loop_iv_r (tree *tp, int *walk_subtrees, void *data)
825 struct c_omp_check_loop_iv_data *d
826 = (struct c_omp_check_loop_iv_data *) data;
827 if (DECL_P (*tp))
829 int i;
830 for (i = 0; i < TREE_VEC_LENGTH (d->declv); i++)
831 if (*tp == TREE_VEC_ELT (d->declv, i))
833 location_t loc = d->expr_loc;
834 if (loc == UNKNOWN_LOCATION)
835 loc = d->stmt_loc;
836 switch (d->kind)
838 case 0:
839 error_at (loc, "initializer expression refers to "
840 "iteration variable %qD", *tp);
841 break;
842 case 1:
843 error_at (loc, "condition expression refers to "
844 "iteration variable %qD", *tp);
845 break;
846 case 2:
847 error_at (loc, "increment expression refers to "
848 "iteration variable %qD", *tp);
849 break;
851 d->fail = true;
854 /* Don't walk dtors added by C++ wrap_cleanups_r. */
855 else if (TREE_CODE (*tp) == TRY_CATCH_EXPR
856 && TRY_CATCH_IS_CLEANUP (*tp))
858 *walk_subtrees = 0;
859 return walk_tree_1 (&TREE_OPERAND (*tp, 0), c_omp_check_loop_iv_r, data,
860 d->ppset, d->lh);
863 return NULL_TREE;
866 /* Diagnose invalid references to loop iterators in lb, b and incr
867 expressions. */
869 bool
870 c_omp_check_loop_iv (tree stmt, tree declv, walk_tree_lh lh)
872 hash_set<tree> pset;
873 struct c_omp_check_loop_iv_data data;
874 int i;
876 data.declv = declv;
877 data.fail = false;
878 data.stmt_loc = EXPR_LOCATION (stmt);
879 data.lh = lh;
880 data.ppset = &pset;
881 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (stmt)); i++)
883 tree init = TREE_VEC_ELT (OMP_FOR_INIT (stmt), i);
884 gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
885 tree decl = TREE_OPERAND (init, 0);
886 tree cond = TREE_VEC_ELT (OMP_FOR_COND (stmt), i);
887 gcc_assert (COMPARISON_CLASS_P (cond));
888 gcc_assert (TREE_OPERAND (cond, 0) == decl);
889 tree incr = TREE_VEC_ELT (OMP_FOR_INCR (stmt), i);
890 data.expr_loc = EXPR_LOCATION (TREE_OPERAND (init, 1));
891 data.kind = 0;
892 walk_tree_1 (&TREE_OPERAND (init, 1),
893 c_omp_check_loop_iv_r, &data, &pset, lh);
894 /* Don't warn for C++ random access iterators here, the
895 expression then involves the subtraction and always refers
896 to the original value. The C++ FE needs to warn on those
897 earlier. */
898 if (decl == TREE_VEC_ELT (declv, i))
900 data.expr_loc = EXPR_LOCATION (cond);
901 data.kind = 1;
902 walk_tree_1 (&TREE_OPERAND (cond, 1),
903 c_omp_check_loop_iv_r, &data, &pset, lh);
905 if (TREE_CODE (incr) == MODIFY_EXPR)
907 gcc_assert (TREE_OPERAND (incr, 0) == decl);
908 incr = TREE_OPERAND (incr, 1);
909 data.kind = 2;
910 if (TREE_CODE (incr) == PLUS_EXPR
911 && TREE_OPERAND (incr, 1) == decl)
913 data.expr_loc = EXPR_LOCATION (TREE_OPERAND (incr, 0));
914 walk_tree_1 (&TREE_OPERAND (incr, 0),
915 c_omp_check_loop_iv_r, &data, &pset, lh);
917 else
919 data.expr_loc = EXPR_LOCATION (TREE_OPERAND (incr, 1));
920 walk_tree_1 (&TREE_OPERAND (incr, 1),
921 c_omp_check_loop_iv_r, &data, &pset, lh);
925 return !data.fail;
928 /* Similar, but allows to check the init or cond expressions individually. */
930 bool
931 c_omp_check_loop_iv_exprs (location_t stmt_loc, tree declv, tree decl,
932 tree init, tree cond, walk_tree_lh lh)
934 hash_set<tree> pset;
935 struct c_omp_check_loop_iv_data data;
937 data.declv = declv;
938 data.fail = false;
939 data.stmt_loc = stmt_loc;
940 data.lh = lh;
941 data.ppset = &pset;
942 if (init)
944 data.expr_loc = EXPR_LOCATION (init);
945 data.kind = 0;
946 walk_tree_1 (&init,
947 c_omp_check_loop_iv_r, &data, &pset, lh);
949 if (cond)
951 gcc_assert (COMPARISON_CLASS_P (cond));
952 data.expr_loc = EXPR_LOCATION (init);
953 data.kind = 1;
954 if (TREE_OPERAND (cond, 0) == decl)
955 walk_tree_1 (&TREE_OPERAND (cond, 1),
956 c_omp_check_loop_iv_r, &data, &pset, lh);
957 else
958 walk_tree_1 (&TREE_OPERAND (cond, 0),
959 c_omp_check_loop_iv_r, &data, &pset, lh);
961 return !data.fail;
964 /* This function splits clauses for OpenACC combined loop
965 constructs. OpenACC combined loop constructs are:
966 #pragma acc kernels loop
967 #pragma acc parallel loop */
969 tree
970 c_oacc_split_loop_clauses (tree clauses, tree *not_loop_clauses,
971 bool is_parallel)
973 tree next, loop_clauses, nc;
975 loop_clauses = *not_loop_clauses = NULL_TREE;
976 for (; clauses ; clauses = next)
978 next = OMP_CLAUSE_CHAIN (clauses);
980 switch (OMP_CLAUSE_CODE (clauses))
982 /* Loop clauses. */
983 case OMP_CLAUSE_COLLAPSE:
984 case OMP_CLAUSE_TILE:
985 case OMP_CLAUSE_GANG:
986 case OMP_CLAUSE_WORKER:
987 case OMP_CLAUSE_VECTOR:
988 case OMP_CLAUSE_AUTO:
989 case OMP_CLAUSE_SEQ:
990 case OMP_CLAUSE_INDEPENDENT:
991 case OMP_CLAUSE_PRIVATE:
992 OMP_CLAUSE_CHAIN (clauses) = loop_clauses;
993 loop_clauses = clauses;
994 break;
996 /* Reductions must be duplicated on both constructs. */
997 case OMP_CLAUSE_REDUCTION:
998 if (is_parallel)
1000 nc = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1001 OMP_CLAUSE_REDUCTION);
1002 OMP_CLAUSE_DECL (nc) = OMP_CLAUSE_DECL (clauses);
1003 OMP_CLAUSE_REDUCTION_CODE (nc)
1004 = OMP_CLAUSE_REDUCTION_CODE (clauses);
1005 OMP_CLAUSE_CHAIN (nc) = *not_loop_clauses;
1006 *not_loop_clauses = nc;
1009 OMP_CLAUSE_CHAIN (clauses) = loop_clauses;
1010 loop_clauses = clauses;
1011 break;
1013 /* Parallel/kernels clauses. */
1014 default:
1015 OMP_CLAUSE_CHAIN (clauses) = *not_loop_clauses;
1016 *not_loop_clauses = clauses;
1017 break;
1021 return loop_clauses;
1024 /* This function attempts to split or duplicate clauses for OpenMP
1025 combined/composite constructs. Right now there are 21 different
1026 constructs. CODE is the innermost construct in the combined construct,
1027 and MASK allows to determine which constructs are combined together,
1028 as every construct has at least one clause that no other construct
1029 has (except for OMP_SECTIONS, but that can be only combined with parallel).
1030 OpenMP combined/composite constructs are:
1031 #pragma omp distribute parallel for
1032 #pragma omp distribute parallel for simd
1033 #pragma omp distribute simd
1034 #pragma omp for simd
1035 #pragma omp parallel for
1036 #pragma omp parallel for simd
1037 #pragma omp parallel sections
1038 #pragma omp target parallel
1039 #pragma omp target parallel for
1040 #pragma omp target parallel for simd
1041 #pragma omp target teams
1042 #pragma omp target teams distribute
1043 #pragma omp target teams distribute parallel for
1044 #pragma omp target teams distribute parallel for simd
1045 #pragma omp target teams distribute simd
1046 #pragma omp target simd
1047 #pragma omp taskloop simd
1048 #pragma omp teams distribute
1049 #pragma omp teams distribute parallel for
1050 #pragma omp teams distribute parallel for simd
1051 #pragma omp teams distribute simd */
1053 void
1054 c_omp_split_clauses (location_t loc, enum tree_code code,
1055 omp_clause_mask mask, tree clauses, tree *cclauses)
1057 tree next, c;
1058 enum c_omp_clause_split s;
1059 int i;
1061 for (i = 0; i < C_OMP_CLAUSE_SPLIT_COUNT; i++)
1062 cclauses[i] = NULL;
1063 /* Add implicit nowait clause on
1064 #pragma omp parallel {for,for simd,sections}. */
1065 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
1066 switch (code)
1068 case OMP_FOR:
1069 case OMP_SIMD:
1070 cclauses[C_OMP_CLAUSE_SPLIT_FOR]
1071 = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
1072 break;
1073 case OMP_SECTIONS:
1074 cclauses[C_OMP_CLAUSE_SPLIT_SECTIONS]
1075 = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
1076 break;
1077 default:
1078 break;
1081 for (; clauses ; clauses = next)
1083 next = OMP_CLAUSE_CHAIN (clauses);
1085 switch (OMP_CLAUSE_CODE (clauses))
1087 /* First the clauses that are unique to some constructs. */
1088 case OMP_CLAUSE_DEVICE:
1089 case OMP_CLAUSE_MAP:
1090 case OMP_CLAUSE_IS_DEVICE_PTR:
1091 case OMP_CLAUSE_DEFAULTMAP:
1092 case OMP_CLAUSE_DEPEND:
1093 s = C_OMP_CLAUSE_SPLIT_TARGET;
1094 break;
1095 case OMP_CLAUSE_NUM_TEAMS:
1096 case OMP_CLAUSE_THREAD_LIMIT:
1097 s = C_OMP_CLAUSE_SPLIT_TEAMS;
1098 break;
1099 case OMP_CLAUSE_DIST_SCHEDULE:
1100 s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
1101 break;
1102 case OMP_CLAUSE_COPYIN:
1103 case OMP_CLAUSE_NUM_THREADS:
1104 case OMP_CLAUSE_PROC_BIND:
1105 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1106 break;
1107 case OMP_CLAUSE_ORDERED:
1108 s = C_OMP_CLAUSE_SPLIT_FOR;
1109 break;
1110 case OMP_CLAUSE_SCHEDULE:
1111 s = C_OMP_CLAUSE_SPLIT_FOR;
1112 if (code != OMP_SIMD)
1113 OMP_CLAUSE_SCHEDULE_SIMD (clauses) = 0;
1114 break;
1115 case OMP_CLAUSE_SAFELEN:
1116 case OMP_CLAUSE_SIMDLEN:
1117 case OMP_CLAUSE_ALIGNED:
1118 s = C_OMP_CLAUSE_SPLIT_SIMD;
1119 break;
1120 case OMP_CLAUSE_GRAINSIZE:
1121 case OMP_CLAUSE_NUM_TASKS:
1122 case OMP_CLAUSE_FINAL:
1123 case OMP_CLAUSE_UNTIED:
1124 case OMP_CLAUSE_MERGEABLE:
1125 case OMP_CLAUSE_NOGROUP:
1126 case OMP_CLAUSE_PRIORITY:
1127 s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
1128 break;
1129 /* Duplicate this to all of taskloop, distribute, for and simd. */
1130 case OMP_CLAUSE_COLLAPSE:
1131 if (code == OMP_SIMD)
1133 if ((mask & ((OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)
1134 | (OMP_CLAUSE_MASK_1
1135 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)
1136 | (OMP_CLAUSE_MASK_1
1137 << PRAGMA_OMP_CLAUSE_NOGROUP))) != 0)
1139 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1140 OMP_CLAUSE_COLLAPSE);
1141 OMP_CLAUSE_COLLAPSE_EXPR (c)
1142 = OMP_CLAUSE_COLLAPSE_EXPR (clauses);
1143 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
1144 cclauses[C_OMP_CLAUSE_SPLIT_SIMD] = c;
1146 else
1148 /* This must be #pragma omp target simd */
1149 s = C_OMP_CLAUSE_SPLIT_SIMD;
1150 break;
1153 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)) != 0)
1155 if ((mask & (OMP_CLAUSE_MASK_1
1156 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
1158 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1159 OMP_CLAUSE_COLLAPSE);
1160 OMP_CLAUSE_COLLAPSE_EXPR (c)
1161 = OMP_CLAUSE_COLLAPSE_EXPR (clauses);
1162 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
1163 cclauses[C_OMP_CLAUSE_SPLIT_FOR] = c;
1164 s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
1166 else
1167 s = C_OMP_CLAUSE_SPLIT_FOR;
1169 else if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP))
1170 != 0)
1171 s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
1172 else
1173 s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
1174 break;
1175 /* Private clause is supported on all constructs,
1176 it is enough to put it on the innermost one. For
1177 #pragma omp {for,sections} put it on parallel though,
1178 as that's what we did for OpenMP 3.1. */
1179 case OMP_CLAUSE_PRIVATE:
1180 switch (code)
1182 case OMP_SIMD: s = C_OMP_CLAUSE_SPLIT_SIMD; break;
1183 case OMP_FOR: case OMP_SECTIONS:
1184 case OMP_PARALLEL: s = C_OMP_CLAUSE_SPLIT_PARALLEL; break;
1185 case OMP_DISTRIBUTE: s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE; break;
1186 case OMP_TEAMS: s = C_OMP_CLAUSE_SPLIT_TEAMS; break;
1187 default: gcc_unreachable ();
1189 break;
1190 /* Firstprivate clause is supported on all constructs but
1191 simd. Put it on the outermost of those and duplicate on teams
1192 and parallel. */
1193 case OMP_CLAUSE_FIRSTPRIVATE:
1194 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP))
1195 != 0)
1197 if (code == OMP_SIMD
1198 && (mask & ((OMP_CLAUSE_MASK_1
1199 << PRAGMA_OMP_CLAUSE_NUM_THREADS)
1200 | (OMP_CLAUSE_MASK_1
1201 << PRAGMA_OMP_CLAUSE_NUM_TEAMS))) == 0)
1203 /* This must be #pragma omp target simd. */
1204 s = C_OMP_CLAUSE_SPLIT_TARGET;
1205 break;
1207 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1208 OMP_CLAUSE_FIRSTPRIVATE);
1209 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
1210 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
1211 cclauses[C_OMP_CLAUSE_SPLIT_TARGET] = c;
1213 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS))
1214 != 0)
1216 if ((mask & ((OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS)
1217 | (OMP_CLAUSE_MASK_1
1218 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE))) != 0)
1220 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1221 OMP_CLAUSE_FIRSTPRIVATE);
1222 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
1223 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL];
1224 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] = c;
1225 if ((mask & (OMP_CLAUSE_MASK_1
1226 << PRAGMA_OMP_CLAUSE_NUM_TEAMS)) != 0)
1227 s = C_OMP_CLAUSE_SPLIT_TEAMS;
1228 else
1229 s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
1231 else
1232 /* This must be
1233 #pragma omp parallel{, for{, simd}, sections}
1235 #pragma omp target parallel. */
1236 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1238 else if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS))
1239 != 0)
1241 /* This must be one of
1242 #pragma omp {,target }teams distribute
1243 #pragma omp target teams
1244 #pragma omp {,target }teams distribute simd. */
1245 gcc_assert (code == OMP_DISTRIBUTE
1246 || code == OMP_TEAMS
1247 || code == OMP_SIMD);
1248 s = C_OMP_CLAUSE_SPLIT_TEAMS;
1250 else if ((mask & (OMP_CLAUSE_MASK_1
1251 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
1253 /* This must be #pragma omp distribute simd. */
1254 gcc_assert (code == OMP_SIMD);
1255 s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
1257 else if ((mask & (OMP_CLAUSE_MASK_1
1258 << PRAGMA_OMP_CLAUSE_NOGROUP)) != 0)
1260 /* This must be #pragma omp taskloop simd. */
1261 gcc_assert (code == OMP_SIMD);
1262 s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
1264 else
1266 /* This must be #pragma omp for simd. */
1267 gcc_assert (code == OMP_SIMD);
1268 s = C_OMP_CLAUSE_SPLIT_FOR;
1270 break;
1271 /* Lastprivate is allowed on distribute, for, sections and simd. In
1272 parallel {for{, simd},sections} we actually want to put it on
1273 parallel rather than for or sections. */
1274 case OMP_CLAUSE_LASTPRIVATE:
1275 if (code == OMP_DISTRIBUTE)
1277 s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
1278 break;
1280 if ((mask & (OMP_CLAUSE_MASK_1
1281 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
1283 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1284 OMP_CLAUSE_LASTPRIVATE);
1285 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
1286 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
1287 cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE] = c;
1289 if (code == OMP_FOR || code == OMP_SECTIONS)
1291 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS))
1292 != 0)
1293 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1294 else
1295 s = C_OMP_CLAUSE_SPLIT_FOR;
1296 break;
1298 gcc_assert (code == OMP_SIMD);
1299 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)) != 0)
1301 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1302 OMP_CLAUSE_LASTPRIVATE);
1303 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
1304 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS))
1305 != 0)
1306 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1307 else
1308 s = C_OMP_CLAUSE_SPLIT_FOR;
1309 OMP_CLAUSE_CHAIN (c) = cclauses[s];
1310 cclauses[s] = c;
1312 s = C_OMP_CLAUSE_SPLIT_SIMD;
1313 break;
1314 /* Shared and default clauses are allowed on parallel, teams and
1315 taskloop. */
1316 case OMP_CLAUSE_SHARED:
1317 case OMP_CLAUSE_DEFAULT:
1318 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP))
1319 != 0)
1321 s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
1322 break;
1324 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS))
1325 != 0)
1327 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS))
1328 == 0)
1330 s = C_OMP_CLAUSE_SPLIT_TEAMS;
1331 break;
1333 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1334 OMP_CLAUSE_CODE (clauses));
1335 if (OMP_CLAUSE_CODE (clauses) == OMP_CLAUSE_SHARED)
1336 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
1337 else
1338 OMP_CLAUSE_DEFAULT_KIND (c)
1339 = OMP_CLAUSE_DEFAULT_KIND (clauses);
1340 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
1341 cclauses[C_OMP_CLAUSE_SPLIT_TEAMS] = c;
1343 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1344 break;
1345 /* Reduction is allowed on simd, for, parallel, sections and teams.
1346 Duplicate it on all of them, but omit on for or sections if
1347 parallel is present. */
1348 case OMP_CLAUSE_REDUCTION:
1349 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)) != 0)
1351 if (code == OMP_SIMD)
1353 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1354 OMP_CLAUSE_REDUCTION);
1355 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
1356 OMP_CLAUSE_REDUCTION_CODE (c)
1357 = OMP_CLAUSE_REDUCTION_CODE (clauses);
1358 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
1359 = OMP_CLAUSE_REDUCTION_PLACEHOLDER (clauses);
1360 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c)
1361 = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (clauses);
1362 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
1363 cclauses[C_OMP_CLAUSE_SPLIT_SIMD] = c;
1365 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS))
1366 != 0)
1368 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1369 OMP_CLAUSE_REDUCTION);
1370 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
1371 OMP_CLAUSE_REDUCTION_CODE (c)
1372 = OMP_CLAUSE_REDUCTION_CODE (clauses);
1373 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
1374 = OMP_CLAUSE_REDUCTION_PLACEHOLDER (clauses);
1375 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c)
1376 = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (clauses);
1377 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL];
1378 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] = c;
1379 s = C_OMP_CLAUSE_SPLIT_TEAMS;
1381 else if ((mask & (OMP_CLAUSE_MASK_1
1382 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
1383 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1384 else
1385 s = C_OMP_CLAUSE_SPLIT_FOR;
1387 else if (code == OMP_SECTIONS || code == OMP_PARALLEL)
1388 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1389 else if (code == OMP_SIMD)
1390 s = C_OMP_CLAUSE_SPLIT_SIMD;
1391 else
1392 s = C_OMP_CLAUSE_SPLIT_TEAMS;
1393 break;
1394 case OMP_CLAUSE_IF:
1395 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP))
1396 != 0)
1397 s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
1398 else if ((mask & (OMP_CLAUSE_MASK_1
1399 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
1401 if ((mask & (OMP_CLAUSE_MASK_1
1402 << PRAGMA_OMP_CLAUSE_MAP)) != 0)
1404 if (OMP_CLAUSE_IF_MODIFIER (clauses) == OMP_PARALLEL)
1405 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1406 else if (OMP_CLAUSE_IF_MODIFIER (clauses) == OMP_TARGET)
1407 s = C_OMP_CLAUSE_SPLIT_TARGET;
1408 else if (OMP_CLAUSE_IF_MODIFIER (clauses) == ERROR_MARK)
1410 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1411 OMP_CLAUSE_IF);
1412 OMP_CLAUSE_IF_MODIFIER (c)
1413 = OMP_CLAUSE_IF_MODIFIER (clauses);
1414 OMP_CLAUSE_IF_EXPR (c) = OMP_CLAUSE_IF_EXPR (clauses);
1415 OMP_CLAUSE_CHAIN (c)
1416 = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
1417 cclauses[C_OMP_CLAUSE_SPLIT_TARGET] = c;
1418 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1420 else
1422 error_at (OMP_CLAUSE_LOCATION (clauses),
1423 "expected %<parallel%> or %<target%> %<if%> "
1424 "clause modifier");
1425 continue;
1428 else
1429 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1431 else
1432 s = C_OMP_CLAUSE_SPLIT_TARGET;
1433 break;
1434 case OMP_CLAUSE_LINEAR:
1435 /* Linear clause is allowed on simd and for. Put it on the
1436 innermost construct. */
1437 if (code == OMP_SIMD)
1438 s = C_OMP_CLAUSE_SPLIT_SIMD;
1439 else
1440 s = C_OMP_CLAUSE_SPLIT_FOR;
1441 break;
1442 case OMP_CLAUSE_NOWAIT:
1443 /* Nowait clause is allowed on target, for and sections, but
1444 is not allowed on parallel for or parallel sections. Therefore,
1445 put it on target construct if present, because that can only
1446 be combined with parallel for{, simd} and not with for{, simd},
1447 otherwise to the worksharing construct. */
1448 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP))
1449 != 0)
1450 s = C_OMP_CLAUSE_SPLIT_TARGET;
1451 else
1452 s = C_OMP_CLAUSE_SPLIT_FOR;
1453 break;
1454 default:
1455 gcc_unreachable ();
1457 OMP_CLAUSE_CHAIN (clauses) = cclauses[s];
1458 cclauses[s] = clauses;
1461 if (!flag_checking)
1462 return;
1464 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) == 0)
1465 gcc_assert (cclauses[C_OMP_CLAUSE_SPLIT_TARGET] == NULL_TREE);
1466 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS)) == 0)
1467 gcc_assert (cclauses[C_OMP_CLAUSE_SPLIT_TEAMS] == NULL_TREE);
1468 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) == 0)
1469 gcc_assert (cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE] == NULL_TREE);
1470 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) == 0)
1471 gcc_assert (cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] == NULL_TREE);
1472 if ((mask & ((OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)
1473 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP))) == 0
1474 && code != OMP_SECTIONS)
1475 gcc_assert (cclauses[C_OMP_CLAUSE_SPLIT_FOR] == NULL_TREE);
1476 if (code != OMP_SIMD)
1477 gcc_assert (cclauses[C_OMP_CLAUSE_SPLIT_SIMD] == NULL_TREE);
1481 /* qsort callback to compare #pragma omp declare simd clauses. */
1483 static int
1484 c_omp_declare_simd_clause_cmp (const void *p, const void *q)
1486 tree a = *(const tree *) p;
1487 tree b = *(const tree *) q;
1488 if (OMP_CLAUSE_CODE (a) != OMP_CLAUSE_CODE (b))
1490 if (OMP_CLAUSE_CODE (a) > OMP_CLAUSE_CODE (b))
1491 return -1;
1492 return 1;
1494 if (OMP_CLAUSE_CODE (a) != OMP_CLAUSE_SIMDLEN
1495 && OMP_CLAUSE_CODE (a) != OMP_CLAUSE_INBRANCH
1496 && OMP_CLAUSE_CODE (a) != OMP_CLAUSE_NOTINBRANCH)
1498 int c = tree_to_shwi (OMP_CLAUSE_DECL (a));
1499 int d = tree_to_shwi (OMP_CLAUSE_DECL (b));
1500 if (c < d)
1501 return 1;
1502 if (c > d)
1503 return -1;
1505 return 0;
1508 /* Change PARM_DECLs in OMP_CLAUSE_DECL of #pragma omp declare simd
1509 CLAUSES on FNDECL into argument indexes and sort them. */
1511 tree
1512 c_omp_declare_simd_clauses_to_numbers (tree parms, tree clauses)
1514 tree c;
1515 vec<tree> clvec = vNULL;
1517 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
1519 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_SIMDLEN
1520 && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_INBRANCH
1521 && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_NOTINBRANCH)
1523 tree decl = OMP_CLAUSE_DECL (c);
1524 tree arg;
1525 int idx;
1526 for (arg = parms, idx = 0; arg;
1527 arg = TREE_CHAIN (arg), idx++)
1528 if (arg == decl)
1529 break;
1530 if (arg == NULL_TREE)
1532 error_at (OMP_CLAUSE_LOCATION (c),
1533 "%qD is not an function argument", decl);
1534 continue;
1536 OMP_CLAUSE_DECL (c) = build_int_cst (integer_type_node, idx);
1537 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
1538 && OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (c))
1540 decl = OMP_CLAUSE_LINEAR_STEP (c);
1541 for (arg = parms, idx = 0; arg;
1542 arg = TREE_CHAIN (arg), idx++)
1543 if (arg == decl)
1544 break;
1545 if (arg == NULL_TREE)
1547 error_at (OMP_CLAUSE_LOCATION (c),
1548 "%qD is not an function argument", decl);
1549 continue;
1551 OMP_CLAUSE_LINEAR_STEP (c)
1552 = build_int_cst (integer_type_node, idx);
1555 clvec.safe_push (c);
1557 if (!clvec.is_empty ())
1559 unsigned int len = clvec.length (), i;
1560 clvec.qsort (c_omp_declare_simd_clause_cmp);
1561 clauses = clvec[0];
1562 for (i = 0; i < len; i++)
1563 OMP_CLAUSE_CHAIN (clvec[i]) = (i < len - 1) ? clvec[i + 1] : NULL_TREE;
1565 else
1566 clauses = NULL_TREE;
1567 clvec.release ();
1568 return clauses;
1571 /* Change argument indexes in CLAUSES of FNDECL back to PARM_DECLs. */
1573 void
1574 c_omp_declare_simd_clauses_to_decls (tree fndecl, tree clauses)
1576 tree c;
1578 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
1579 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_SIMDLEN
1580 && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_INBRANCH
1581 && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_NOTINBRANCH)
1583 int idx = tree_to_shwi (OMP_CLAUSE_DECL (c)), i;
1584 tree arg;
1585 for (arg = DECL_ARGUMENTS (fndecl), i = 0; arg;
1586 arg = TREE_CHAIN (arg), i++)
1587 if (i == idx)
1588 break;
1589 gcc_assert (arg);
1590 OMP_CLAUSE_DECL (c) = arg;
1591 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
1592 && OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (c))
1594 idx = tree_to_shwi (OMP_CLAUSE_LINEAR_STEP (c));
1595 for (arg = DECL_ARGUMENTS (fndecl), i = 0; arg;
1596 arg = TREE_CHAIN (arg), i++)
1597 if (i == idx)
1598 break;
1599 gcc_assert (arg);
1600 OMP_CLAUSE_LINEAR_STEP (c) = arg;
1605 /* True if OpenMP sharing attribute of DECL is predetermined. */
1607 enum omp_clause_default_kind
1608 c_omp_predetermined_sharing (tree decl)
1610 /* Variables with const-qualified type having no mutable member
1611 are predetermined shared. */
1612 if (TREE_READONLY (decl))
1613 return OMP_CLAUSE_DEFAULT_SHARED;
1615 return OMP_CLAUSE_DEFAULT_UNSPECIFIED;