Daily bump.
[official-gcc.git] / gcc / c-family / c-omp.c
blob5469d0d56259bf6650622e6647c790a6dc7d3a60
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-2016 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-low.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 (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);
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;
185 if (lhs == error_mark_node || rhs == error_mark_node
186 || v == error_mark_node || lhs1 == error_mark_node
187 || rhs1 == error_mark_node)
188 return error_mark_node;
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))
199 error_at (loc, "invalid expression type for %<#pragma omp atomic%>");
200 return error_mark_node;
203 if (opcode == RDIV_EXPR)
204 opcode = TRUNC_DIV_EXPR;
206 /* ??? Validate that rhs does not overlap lhs. */
208 /* Take and save the address of the lhs. From then on we'll reference it
209 via indirection. */
210 addr = build_unary_op (loc, ADDR_EXPR, lhs, 0);
211 if (addr == error_mark_node)
212 return error_mark_node;
213 if (!test)
214 addr = save_expr (addr);
215 if (!test
216 && TREE_CODE (addr) != SAVE_EXPR
217 && (TREE_CODE (addr) != ADDR_EXPR
218 || !VAR_P (TREE_OPERAND (addr, 0))))
220 /* Make sure LHS is simple enough so that goa_lhs_expr_p can recognize
221 it even after unsharing function body. */
222 tree var = create_tmp_var_raw (TREE_TYPE (addr));
223 DECL_CONTEXT (var) = current_function_decl;
224 addr = build4 (TARGET_EXPR, TREE_TYPE (addr), var, addr, NULL, NULL);
226 lhs = build_indirect_ref (loc, addr, RO_NULL);
228 if (code == OMP_ATOMIC_READ)
230 x = build1 (OMP_ATOMIC_READ, type, addr);
231 SET_EXPR_LOCATION (x, loc);
232 OMP_ATOMIC_SEQ_CST (x) = seq_cst;
233 return build_modify_expr (loc, v, NULL_TREE, NOP_EXPR,
234 loc, x, NULL_TREE);
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. */
240 if (swapped)
242 rhs = build_binary_op (loc, opcode, rhs, lhs, 1);
243 opcode = NOP_EXPR;
245 bool save = in_late_binary_op;
246 in_late_binary_op = true;
247 x = build_modify_expr (loc, lhs, NULL_TREE, opcode, loc, rhs, NULL_TREE);
248 in_late_binary_op = save;
249 if (x == error_mark_node)
250 return error_mark_node;
251 if (TREE_CODE (x) == COMPOUND_EXPR)
253 pre = TREE_OPERAND (x, 0);
254 gcc_assert (TREE_CODE (pre) == SAVE_EXPR);
255 x = TREE_OPERAND (x, 1);
257 gcc_assert (TREE_CODE (x) == MODIFY_EXPR);
258 rhs = TREE_OPERAND (x, 1);
260 /* Punt the actual generation of atomic operations to common code. */
261 if (code == OMP_ATOMIC)
262 type = void_type_node;
263 x = build2 (code, type, addr, rhs);
264 SET_EXPR_LOCATION (x, loc);
265 OMP_ATOMIC_SEQ_CST (x) = seq_cst;
267 /* Generally it is hard to prove lhs1 and lhs are the same memory
268 location, just diagnose different variables. */
269 if (rhs1
270 && VAR_P (rhs1)
271 && VAR_P (lhs)
272 && rhs1 != lhs
273 && !test)
275 if (code == OMP_ATOMIC)
276 error_at (loc, "%<#pragma omp atomic update%> uses two different "
277 "variables for memory");
278 else
279 error_at (loc, "%<#pragma omp atomic capture%> uses two different "
280 "variables for memory");
281 return error_mark_node;
284 if (code != OMP_ATOMIC)
286 /* Generally it is hard to prove lhs1 and lhs are the same memory
287 location, just diagnose different variables. */
288 if (lhs1 && VAR_P (lhs1) && VAR_P (lhs))
290 if (lhs1 != lhs && !test)
292 error_at (loc, "%<#pragma omp atomic capture%> uses two "
293 "different variables for memory");
294 return error_mark_node;
297 x = build_modify_expr (loc, v, NULL_TREE, NOP_EXPR,
298 loc, x, NULL_TREE);
299 if (rhs1 && rhs1 != lhs)
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);
306 if (lhs1 && lhs1 != lhs)
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
315 if (!test)
316 x = save_expr (x);
317 x = omit_two_operands_loc (loc, type, x, x, lhs1addr);
321 else if (rhs1 && rhs1 != lhs)
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);
329 if (pre)
330 x = omit_one_operand_loc (loc, type, x, pre);
331 return x;
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. */
339 void
340 c_finish_omp_flush (location_t loc)
342 tree x;
344 x = builtin_decl_explicit (BUILT_IN_SYNC_SYNCHRONIZE);
345 x = build_call_expr_loc (loc, x, 0);
346 add_stmt (x);
350 /* Check and canonicalize OMP_FOR increment expression.
351 Helper function for c_finish_omp_for. */
353 static tree
354 check_omp_for_incr_expr (location_t loc, tree exp, tree decl)
356 tree t;
358 if (!INTEGRAL_TYPE_P (TREE_TYPE (exp))
359 || TYPE_PRECISION (TREE_TYPE (exp)) < TYPE_PRECISION (TREE_TYPE (decl)))
360 return error_mark_node;
362 if (exp == decl)
363 return build_int_cst (TREE_TYPE (exp), 0);
365 switch (TREE_CODE (exp))
367 CASE_CONVERT:
368 t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 0), decl);
369 if (t != error_mark_node)
370 return fold_convert_loc (loc, TREE_TYPE (exp), t);
371 break;
372 case MINUS_EXPR:
373 t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 0), decl);
374 if (t != error_mark_node)
375 return fold_build2_loc (loc, MINUS_EXPR,
376 TREE_TYPE (exp), t, TREE_OPERAND (exp, 1));
377 break;
378 case PLUS_EXPR:
379 t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 0), decl);
380 if (t != error_mark_node)
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);
384 if (t != error_mark_node)
385 return fold_build2_loc (loc, PLUS_EXPR,
386 TREE_TYPE (exp), TREE_OPERAND (exp, 0), t);
387 break;
388 case COMPOUND_EXPR:
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)))
397 tree op1 = TREE_OPERAND (exp, 1);
398 tree temp = TARGET_EXPR_SLOT (op0);
399 if (BINARY_CLASS_P (op1)
400 && TREE_OPERAND (op1, 1) == temp)
402 op1 = copy_node (op1);
403 TREE_OPERAND (op1, 1) = TARGET_EXPR_INITIAL (op0);
404 return check_omp_for_incr_expr (loc, op1, decl);
407 break;
409 default:
410 break;
413 return error_mark_node;
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. */
420 static tree
421 c_omp_for_incr_canonicalize_ptr (location_t loc, tree decl, tree incr)
423 if (POINTER_TYPE_P (TREE_TYPE (decl))
424 && TREE_OPERAND (incr, 1))
426 tree t = fold_convert_loc (loc,
427 sizetype, TREE_OPERAND (incr, 1));
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);
435 return incr;
438 /* Validate and generate OMP_FOR.
439 DECLV is a vector of iteration variables, for each collapsed loop.
441 ORIG_DECLV, if non-NULL, is a vector with the original iteration
442 variables (prior to any transformations, by say, C++ iterators).
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. */
449 tree
450 c_finish_omp_for (location_t locus, enum tree_code code, tree declv,
451 tree orig_declv, tree initv, tree condv, tree incrv,
452 tree body, tree pre_body)
454 location_t elocus;
455 bool fail = false;
456 int i;
458 if ((code == CILK_SIMD || code == CILK_FOR)
459 && !c_check_cilk_loop (locus, TREE_VEC_ELT (declv, 0)))
460 fail = true;
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++)
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);
472 elocus = locus;
473 if (EXPR_HAS_LOCATION (init))
474 elocus = EXPR_LOCATION (init);
476 /* Validate the iteration variable. */
477 if (!INTEGRAL_TYPE_P (TREE_TYPE (decl))
478 && TREE_CODE (TREE_TYPE (decl)) != POINTER_TYPE)
480 error_at (elocus, "invalid type for iteration variable %qE", decl);
481 fail = true;
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)
488 elocus = DECL_SOURCE_LOCATION (decl);
490 init = DECL_INITIAL (decl);
491 if (init == NULL)
493 error_at (elocus, "%qE is not initialized", decl);
494 init = integer_zero_node;
495 fail = true;
497 DECL_INITIAL (decl) = NULL_TREE;
499 init = build_modify_expr (elocus, decl, NULL_TREE, NOP_EXPR,
500 /* FIXME diagnostics: This should
501 be the location of the INIT. */
502 elocus,
503 init,
504 NULL_TREE);
506 if (init != error_mark_node)
508 gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
509 gcc_assert (TREE_OPERAND (init, 0) == decl);
512 if (cond == NULL_TREE)
514 error_at (elocus, "missing controlling predicate");
515 fail = true;
517 else
519 bool cond_ok = false;
521 if (EXPR_HAS_LOCATION (cond))
522 elocus = EXPR_LOCATION (cond);
524 if (TREE_CODE (cond) == LT_EXPR
525 || TREE_CODE (cond) == LE_EXPR
526 || TREE_CODE (cond) == GT_EXPR
527 || TREE_CODE (cond) == GE_EXPR
528 || TREE_CODE (cond) == NE_EXPR
529 || TREE_CODE (cond) == EQ_EXPR)
531 tree op0 = TREE_OPERAND (cond, 0);
532 tree op1 = TREE_OPERAND (cond, 1);
534 /* 2.5.1. The comparison in the condition is computed in
535 the type of DECL, otherwise the behavior is undefined.
537 For example:
538 long n; int i;
539 i < n;
541 according to ISO will be evaluated as:
542 (long)i < n;
544 We want to force:
545 i < (int)n; */
546 if (TREE_CODE (op0) == NOP_EXPR
547 && decl == TREE_OPERAND (op0, 0))
549 TREE_OPERAND (cond, 0) = TREE_OPERAND (op0, 0);
550 TREE_OPERAND (cond, 1)
551 = fold_build1_loc (elocus, NOP_EXPR, TREE_TYPE (decl),
552 TREE_OPERAND (cond, 1));
554 else if (TREE_CODE (op1) == NOP_EXPR
555 && decl == TREE_OPERAND (op1, 0))
557 TREE_OPERAND (cond, 1) = TREE_OPERAND (op1, 0);
558 TREE_OPERAND (cond, 0)
559 = fold_build1_loc (elocus, NOP_EXPR, TREE_TYPE (decl),
560 TREE_OPERAND (cond, 0));
563 if (decl == TREE_OPERAND (cond, 0))
564 cond_ok = true;
565 else if (decl == TREE_OPERAND (cond, 1))
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;
574 if (TREE_CODE (cond) == NE_EXPR
575 || TREE_CODE (cond) == EQ_EXPR)
577 if (!INTEGRAL_TYPE_P (TREE_TYPE (decl)))
579 if (code != CILK_SIMD && code != CILK_FOR)
580 cond_ok = false;
582 else if (operand_equal_p (TREE_OPERAND (cond, 1),
583 TYPE_MIN_VALUE (TREE_TYPE (decl)),
585 TREE_SET_CODE (cond, TREE_CODE (cond) == NE_EXPR
586 ? GT_EXPR : LE_EXPR);
587 else if (operand_equal_p (TREE_OPERAND (cond, 1),
588 TYPE_MAX_VALUE (TREE_TYPE (decl)),
590 TREE_SET_CODE (cond, TREE_CODE (cond) == NE_EXPR
591 ? LT_EXPR : GE_EXPR);
592 else if (code != CILK_SIMD && code != CILK_FOR)
593 cond_ok = false;
597 if (!cond_ok)
599 error_at (elocus, "invalid controlling predicate");
600 fail = true;
604 if (incr == NULL_TREE)
606 error_at (elocus, "missing increment expression");
607 fail = true;
609 else
611 bool incr_ok = false;
613 if (EXPR_HAS_LOCATION (incr))
614 elocus = EXPR_LOCATION (incr);
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))
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;
627 incr_ok = true;
628 incr = c_omp_for_incr_canonicalize_ptr (elocus, decl, incr);
629 break;
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 */
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
653 tree t = check_omp_for_incr_expr (elocus,
654 TREE_OPERAND (incr, 1),
655 decl);
656 if (t != error_mark_node)
658 incr_ok = true;
659 t = build2 (PLUS_EXPR, TREE_TYPE (decl), decl, t);
660 incr = build2 (MODIFY_EXPR, void_type_node, decl, t);
663 break;
665 default:
666 break;
668 if (!incr_ok)
670 error_at (elocus, "invalid increment expression");
671 fail = true;
675 TREE_VEC_ELT (initv, i) = init;
676 TREE_VEC_ELT (incrv, i) = incr;
679 if (fail)
680 return NULL;
681 else
683 tree t = make_node (code);
685 TREE_TYPE (t) = void_type_node;
686 OMP_FOR_INIT (t) = initv;
687 OMP_FOR_COND (t) = condv;
688 OMP_FOR_INCR (t) = incrv;
689 OMP_FOR_BODY (t) = body;
690 OMP_FOR_PRE_BODY (t) = pre_body;
691 OMP_FOR_ORIG_DECLS (t) = orig_declv;
693 SET_EXPR_LOCATION (t, locus);
694 return t;
698 /* Type for passing data in between c_omp_check_loop_iv and
699 c_omp_check_loop_iv_r. */
701 struct c_omp_check_loop_iv_data
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;
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. */
716 static tree
717 c_omp_check_loop_iv_r (tree *tp, int *walk_subtrees, void *data)
719 struct c_omp_check_loop_iv_data *d
720 = (struct c_omp_check_loop_iv_data *) data;
721 if (DECL_P (*tp))
723 int i;
724 for (i = 0; i < TREE_VEC_LENGTH (d->declv); i++)
725 if (*tp == TREE_VEC_ELT (d->declv, i))
727 location_t loc = d->expr_loc;
728 if (loc == UNKNOWN_LOCATION)
729 loc = d->stmt_loc;
730 switch (d->kind)
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;
745 d->fail = true;
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))
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);
757 return NULL_TREE;
760 /* Diagnose invalid references to loop iterators in lb, b and incr
761 expressions. */
763 bool
764 c_omp_check_loop_iv (tree stmt, tree declv, walk_tree_lh lh)
766 hash_set<tree> pset;
767 struct c_omp_check_loop_iv_data data;
768 int i;
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++)
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))
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);
799 if (TREE_CODE (incr) == MODIFY_EXPR)
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)
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);
811 else
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);
819 return !data.fail;
822 /* Similar, but allows to check the init or cond expressions individually. */
824 bool
825 c_omp_check_loop_iv_exprs (location_t stmt_loc, tree declv, tree decl,
826 tree init, tree cond, walk_tree_lh lh)
828 hash_set<tree> pset;
829 struct c_omp_check_loop_iv_data data;
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)
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);
843 if (cond)
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);
855 return !data.fail;
858 /* This function splits clauses for OpenACC combined loop
859 constructs. OpenACC combined loop constructs are:
860 #pragma acc kernels loop
861 #pragma acc parallel loop */
863 tree
864 c_oacc_split_loop_clauses (tree clauses, tree *not_loop_clauses)
866 tree next, loop_clauses;
868 loop_clauses = *not_loop_clauses = NULL_TREE;
869 for (; clauses ; clauses = next)
871 next = OMP_CLAUSE_CHAIN (clauses);
873 switch (OMP_CLAUSE_CODE (clauses))
875 /* Loop clauses. */
876 case OMP_CLAUSE_COLLAPSE:
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:
885 case OMP_CLAUSE_REDUCTION:
886 OMP_CLAUSE_CHAIN (clauses) = loop_clauses;
887 loop_clauses = clauses;
888 break;
890 /* Parallel/kernels clauses. */
891 default:
892 OMP_CLAUSE_CHAIN (clauses) = *not_loop_clauses;
893 *not_loop_clauses = clauses;
894 break;
898 return loop_clauses;
901 /* This function attempts to split or duplicate clauses for OpenMP
902 combined/composite constructs. Right now there are 21 different
903 constructs. CODE is the innermost construct in the combined construct,
904 and MASK allows to determine which constructs are combined together,
905 as every construct has at least one clause that no other construct
906 has (except for OMP_SECTIONS, but that can be only combined with parallel).
907 OpenMP combined/composite constructs are:
908 #pragma omp distribute parallel for
909 #pragma omp distribute parallel for simd
910 #pragma omp distribute simd
911 #pragma omp for simd
912 #pragma omp parallel for
913 #pragma omp parallel for simd
914 #pragma omp parallel sections
915 #pragma omp target parallel
916 #pragma omp target parallel for
917 #pragma omp target parallel for simd
918 #pragma omp target teams
919 #pragma omp target teams distribute
920 #pragma omp target teams distribute parallel for
921 #pragma omp target teams distribute parallel for simd
922 #pragma omp target teams distribute simd
923 #pragma omp target simd
924 #pragma omp taskloop simd
925 #pragma omp teams distribute
926 #pragma omp teams distribute parallel for
927 #pragma omp teams distribute parallel for simd
928 #pragma omp teams distribute simd */
930 void
931 c_omp_split_clauses (location_t loc, enum tree_code code,
932 omp_clause_mask mask, tree clauses, tree *cclauses)
934 tree next, c;
935 enum c_omp_clause_split s;
936 int i;
938 for (i = 0; i < C_OMP_CLAUSE_SPLIT_COUNT; i++)
939 cclauses[i] = NULL;
940 /* Add implicit nowait clause on
941 #pragma omp parallel {for,for simd,sections}. */
942 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
943 switch (code)
945 case OMP_FOR:
946 case OMP_SIMD:
947 cclauses[C_OMP_CLAUSE_SPLIT_FOR]
948 = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
949 break;
950 case OMP_SECTIONS:
951 cclauses[C_OMP_CLAUSE_SPLIT_SECTIONS]
952 = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
953 break;
954 default:
955 break;
958 for (; clauses ; clauses = next)
960 next = OMP_CLAUSE_CHAIN (clauses);
962 switch (OMP_CLAUSE_CODE (clauses))
964 /* First the clauses that are unique to some constructs. */
965 case OMP_CLAUSE_DEVICE:
966 case OMP_CLAUSE_MAP:
967 case OMP_CLAUSE_IS_DEVICE_PTR:
968 case OMP_CLAUSE_DEFAULTMAP:
969 s = C_OMP_CLAUSE_SPLIT_TARGET;
970 break;
971 case OMP_CLAUSE_NUM_TEAMS:
972 case OMP_CLAUSE_THREAD_LIMIT:
973 s = C_OMP_CLAUSE_SPLIT_TEAMS;
974 break;
975 case OMP_CLAUSE_DIST_SCHEDULE:
976 s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
977 break;
978 case OMP_CLAUSE_COPYIN:
979 case OMP_CLAUSE_NUM_THREADS:
980 case OMP_CLAUSE_PROC_BIND:
981 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
982 break;
983 case OMP_CLAUSE_ORDERED:
984 case OMP_CLAUSE_NOWAIT:
985 s = C_OMP_CLAUSE_SPLIT_FOR;
986 break;
987 case OMP_CLAUSE_SCHEDULE:
988 s = C_OMP_CLAUSE_SPLIT_FOR;
989 if (code != OMP_SIMD)
990 OMP_CLAUSE_SCHEDULE_SIMD (clauses) = 0;
991 break;
992 case OMP_CLAUSE_SAFELEN:
993 case OMP_CLAUSE_SIMDLEN:
994 case OMP_CLAUSE_ALIGNED:
995 s = C_OMP_CLAUSE_SPLIT_SIMD;
996 break;
997 case OMP_CLAUSE_GRAINSIZE:
998 case OMP_CLAUSE_NUM_TASKS:
999 case OMP_CLAUSE_FINAL:
1000 case OMP_CLAUSE_UNTIED:
1001 case OMP_CLAUSE_MERGEABLE:
1002 case OMP_CLAUSE_NOGROUP:
1003 case OMP_CLAUSE_PRIORITY:
1004 s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
1005 break;
1006 /* Duplicate this to all of taskloop, distribute, for and simd. */
1007 case OMP_CLAUSE_COLLAPSE:
1008 if (code == OMP_SIMD)
1010 if ((mask & ((OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)
1011 | (OMP_CLAUSE_MASK_1
1012 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)
1013 | (OMP_CLAUSE_MASK_1
1014 << PRAGMA_OMP_CLAUSE_NOGROUP))) != 0)
1016 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1017 OMP_CLAUSE_COLLAPSE);
1018 OMP_CLAUSE_COLLAPSE_EXPR (c)
1019 = OMP_CLAUSE_COLLAPSE_EXPR (clauses);
1020 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
1021 cclauses[C_OMP_CLAUSE_SPLIT_SIMD] = c;
1023 else
1025 /* This must be #pragma omp target simd */
1026 s = C_OMP_CLAUSE_SPLIT_SIMD;
1027 break;
1030 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)) != 0)
1032 if ((mask & (OMP_CLAUSE_MASK_1
1033 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
1035 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1036 OMP_CLAUSE_COLLAPSE);
1037 OMP_CLAUSE_COLLAPSE_EXPR (c)
1038 = OMP_CLAUSE_COLLAPSE_EXPR (clauses);
1039 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
1040 cclauses[C_OMP_CLAUSE_SPLIT_FOR] = c;
1041 s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
1043 else
1044 s = C_OMP_CLAUSE_SPLIT_FOR;
1046 else if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP))
1047 != 0)
1048 s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
1049 else
1050 s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
1051 break;
1052 /* Private clause is supported on all constructs,
1053 it is enough to put it on the innermost one. For
1054 #pragma omp {for,sections} put it on parallel though,
1055 as that's what we did for OpenMP 3.1. */
1056 case OMP_CLAUSE_PRIVATE:
1057 switch (code)
1059 case OMP_SIMD: s = C_OMP_CLAUSE_SPLIT_SIMD; break;
1060 case OMP_FOR: case OMP_SECTIONS:
1061 case OMP_PARALLEL: s = C_OMP_CLAUSE_SPLIT_PARALLEL; break;
1062 case OMP_DISTRIBUTE: s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE; break;
1063 case OMP_TEAMS: s = C_OMP_CLAUSE_SPLIT_TEAMS; break;
1064 default: gcc_unreachable ();
1066 break;
1067 /* Firstprivate clause is supported on all constructs but
1068 simd. Put it on the outermost of those and duplicate on teams
1069 and parallel. */
1070 case OMP_CLAUSE_FIRSTPRIVATE:
1071 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP))
1072 != 0)
1074 if (code == OMP_SIMD
1075 && (mask & ((OMP_CLAUSE_MASK_1
1076 << PRAGMA_OMP_CLAUSE_NUM_THREADS)
1077 | (OMP_CLAUSE_MASK_1
1078 << PRAGMA_OMP_CLAUSE_NUM_TEAMS))) == 0)
1080 /* This must be #pragma omp target simd. */
1081 s = C_OMP_CLAUSE_SPLIT_TARGET;
1082 break;
1084 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1085 OMP_CLAUSE_FIRSTPRIVATE);
1086 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
1087 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
1088 cclauses[C_OMP_CLAUSE_SPLIT_TARGET] = c;
1090 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS))
1091 != 0)
1093 if ((mask & ((OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS)
1094 | (OMP_CLAUSE_MASK_1
1095 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE))) != 0)
1097 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1098 OMP_CLAUSE_FIRSTPRIVATE);
1099 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
1100 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL];
1101 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] = c;
1102 if ((mask & (OMP_CLAUSE_MASK_1
1103 << PRAGMA_OMP_CLAUSE_NUM_TEAMS)) != 0)
1104 s = C_OMP_CLAUSE_SPLIT_TEAMS;
1105 else
1106 s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
1108 else
1109 /* This must be
1110 #pragma omp parallel{, for{, simd}, sections}
1112 #pragma omp target parallel. */
1113 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1115 else if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS))
1116 != 0)
1118 /* This must be one of
1119 #pragma omp {,target }teams distribute
1120 #pragma omp target teams
1121 #pragma omp {,target }teams distribute simd. */
1122 gcc_assert (code == OMP_DISTRIBUTE
1123 || code == OMP_TEAMS
1124 || code == OMP_SIMD);
1125 s = C_OMP_CLAUSE_SPLIT_TEAMS;
1127 else if ((mask & (OMP_CLAUSE_MASK_1
1128 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
1130 /* This must be #pragma omp distribute simd. */
1131 gcc_assert (code == OMP_SIMD);
1132 s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
1134 else if ((mask & (OMP_CLAUSE_MASK_1
1135 << PRAGMA_OMP_CLAUSE_NOGROUP)) != 0)
1137 /* This must be #pragma omp taskloop simd. */
1138 gcc_assert (code == OMP_SIMD);
1139 s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
1141 else
1143 /* This must be #pragma omp for simd. */
1144 gcc_assert (code == OMP_SIMD);
1145 s = C_OMP_CLAUSE_SPLIT_FOR;
1147 break;
1148 /* Lastprivate is allowed on distribute, for, sections and simd. In
1149 parallel {for{, simd},sections} we actually want to put it on
1150 parallel rather than for or sections. */
1151 case OMP_CLAUSE_LASTPRIVATE:
1152 if (code == OMP_DISTRIBUTE)
1154 s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
1155 break;
1157 if ((mask & (OMP_CLAUSE_MASK_1
1158 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
1160 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1161 OMP_CLAUSE_LASTPRIVATE);
1162 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
1163 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
1164 cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE] = c;
1166 if (code == OMP_FOR || code == OMP_SECTIONS)
1168 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS))
1169 != 0)
1170 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1171 else
1172 s = C_OMP_CLAUSE_SPLIT_FOR;
1173 break;
1175 gcc_assert (code == OMP_SIMD);
1176 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)) != 0)
1178 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1179 OMP_CLAUSE_LASTPRIVATE);
1180 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
1181 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS))
1182 != 0)
1183 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1184 else
1185 s = C_OMP_CLAUSE_SPLIT_FOR;
1186 OMP_CLAUSE_CHAIN (c) = cclauses[s];
1187 cclauses[s] = c;
1189 s = C_OMP_CLAUSE_SPLIT_SIMD;
1190 break;
1191 /* Shared and default clauses are allowed on parallel, teams and
1192 taskloop. */
1193 case OMP_CLAUSE_SHARED:
1194 case OMP_CLAUSE_DEFAULT:
1195 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP))
1196 != 0)
1198 s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
1199 break;
1201 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS))
1202 != 0)
1204 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS))
1205 == 0)
1207 s = C_OMP_CLAUSE_SPLIT_TEAMS;
1208 break;
1210 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1211 OMP_CLAUSE_CODE (clauses));
1212 if (OMP_CLAUSE_CODE (clauses) == OMP_CLAUSE_SHARED)
1213 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
1214 else
1215 OMP_CLAUSE_DEFAULT_KIND (c)
1216 = OMP_CLAUSE_DEFAULT_KIND (clauses);
1217 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
1218 cclauses[C_OMP_CLAUSE_SPLIT_TEAMS] = c;
1220 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1221 break;
1222 /* Reduction is allowed on simd, for, parallel, sections and teams.
1223 Duplicate it on all of them, but omit on for or sections if
1224 parallel is present. */
1225 case OMP_CLAUSE_REDUCTION:
1226 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)) != 0)
1228 if (code == OMP_SIMD)
1230 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1231 OMP_CLAUSE_REDUCTION);
1232 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
1233 OMP_CLAUSE_REDUCTION_CODE (c)
1234 = OMP_CLAUSE_REDUCTION_CODE (clauses);
1235 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
1236 = OMP_CLAUSE_REDUCTION_PLACEHOLDER (clauses);
1237 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c)
1238 = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (clauses);
1239 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
1240 cclauses[C_OMP_CLAUSE_SPLIT_SIMD] = c;
1242 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS))
1243 != 0)
1245 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1246 OMP_CLAUSE_REDUCTION);
1247 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
1248 OMP_CLAUSE_REDUCTION_CODE (c)
1249 = OMP_CLAUSE_REDUCTION_CODE (clauses);
1250 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
1251 = OMP_CLAUSE_REDUCTION_PLACEHOLDER (clauses);
1252 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c)
1253 = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (clauses);
1254 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL];
1255 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] = c;
1256 s = C_OMP_CLAUSE_SPLIT_TEAMS;
1258 else if ((mask & (OMP_CLAUSE_MASK_1
1259 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
1260 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1261 else
1262 s = C_OMP_CLAUSE_SPLIT_FOR;
1264 else if (code == OMP_SECTIONS || code == OMP_PARALLEL)
1265 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1266 else if (code == OMP_SIMD)
1267 s = C_OMP_CLAUSE_SPLIT_SIMD;
1268 else
1269 s = C_OMP_CLAUSE_SPLIT_TEAMS;
1270 break;
1271 case OMP_CLAUSE_IF:
1272 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP))
1273 != 0)
1274 s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
1275 else if ((mask & (OMP_CLAUSE_MASK_1
1276 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
1278 if ((mask & (OMP_CLAUSE_MASK_1
1279 << PRAGMA_OMP_CLAUSE_MAP)) != 0)
1281 if (OMP_CLAUSE_IF_MODIFIER (clauses) == OMP_PARALLEL)
1282 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1283 else if (OMP_CLAUSE_IF_MODIFIER (clauses) == OMP_TARGET)
1284 s = C_OMP_CLAUSE_SPLIT_TARGET;
1285 else if (OMP_CLAUSE_IF_MODIFIER (clauses) == ERROR_MARK)
1287 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1288 OMP_CLAUSE_IF);
1289 OMP_CLAUSE_IF_MODIFIER (c)
1290 = OMP_CLAUSE_IF_MODIFIER (clauses);
1291 OMP_CLAUSE_IF_EXPR (c) = OMP_CLAUSE_IF_EXPR (clauses);
1292 OMP_CLAUSE_CHAIN (c)
1293 = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
1294 cclauses[C_OMP_CLAUSE_SPLIT_TARGET] = c;
1295 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1297 else
1299 error_at (OMP_CLAUSE_LOCATION (clauses),
1300 "expected %<parallel%> or %<target%> %<if%> "
1301 "clause modifier");
1302 continue;
1305 else
1306 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1308 else
1309 s = C_OMP_CLAUSE_SPLIT_TARGET;
1310 break;
1311 case OMP_CLAUSE_LINEAR:
1312 /* Linear clause is allowed on simd and for. Put it on the
1313 innermost construct. */
1314 if (code == OMP_SIMD)
1315 s = C_OMP_CLAUSE_SPLIT_SIMD;
1316 else
1317 s = C_OMP_CLAUSE_SPLIT_FOR;
1318 break;
1319 default:
1320 gcc_unreachable ();
1322 OMP_CLAUSE_CHAIN (clauses) = cclauses[s];
1323 cclauses[s] = clauses;
1326 if (!flag_checking)
1327 return;
1329 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) == 0)
1330 gcc_assert (cclauses[C_OMP_CLAUSE_SPLIT_TARGET] == NULL_TREE);
1331 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS)) == 0)
1332 gcc_assert (cclauses[C_OMP_CLAUSE_SPLIT_TEAMS] == NULL_TREE);
1333 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) == 0)
1334 gcc_assert (cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE] == NULL_TREE);
1335 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) == 0)
1336 gcc_assert (cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] == NULL_TREE);
1337 if ((mask & ((OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)
1338 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP))) == 0
1339 && code != OMP_SECTIONS)
1340 gcc_assert (cclauses[C_OMP_CLAUSE_SPLIT_FOR] == NULL_TREE);
1341 if (code != OMP_SIMD)
1342 gcc_assert (cclauses[C_OMP_CLAUSE_SPLIT_SIMD] == NULL_TREE);
1346 /* qsort callback to compare #pragma omp declare simd clauses. */
1348 static int
1349 c_omp_declare_simd_clause_cmp (const void *p, const void *q)
1351 tree a = *(const tree *) p;
1352 tree b = *(const tree *) q;
1353 if (OMP_CLAUSE_CODE (a) != OMP_CLAUSE_CODE (b))
1355 if (OMP_CLAUSE_CODE (a) > OMP_CLAUSE_CODE (b))
1356 return -1;
1357 return 1;
1359 if (OMP_CLAUSE_CODE (a) != OMP_CLAUSE_SIMDLEN
1360 && OMP_CLAUSE_CODE (a) != OMP_CLAUSE_INBRANCH
1361 && OMP_CLAUSE_CODE (a) != OMP_CLAUSE_NOTINBRANCH)
1363 int c = tree_to_shwi (OMP_CLAUSE_DECL (a));
1364 int d = tree_to_shwi (OMP_CLAUSE_DECL (b));
1365 if (c < d)
1366 return 1;
1367 if (c > d)
1368 return -1;
1370 return 0;
1373 /* Change PARM_DECLs in OMP_CLAUSE_DECL of #pragma omp declare simd
1374 CLAUSES on FNDECL into argument indexes and sort them. */
1376 tree
1377 c_omp_declare_simd_clauses_to_numbers (tree parms, tree clauses)
1379 tree c;
1380 vec<tree> clvec = vNULL;
1382 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
1384 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_SIMDLEN
1385 && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_INBRANCH
1386 && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_NOTINBRANCH)
1388 tree decl = OMP_CLAUSE_DECL (c);
1389 tree arg;
1390 int idx;
1391 for (arg = parms, idx = 0; arg;
1392 arg = TREE_CHAIN (arg), idx++)
1393 if (arg == decl)
1394 break;
1395 if (arg == NULL_TREE)
1397 error_at (OMP_CLAUSE_LOCATION (c),
1398 "%qD is not an function argument", decl);
1399 continue;
1401 OMP_CLAUSE_DECL (c) = build_int_cst (integer_type_node, idx);
1402 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
1403 && OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (c))
1405 decl = OMP_CLAUSE_LINEAR_STEP (c);
1406 for (arg = parms, idx = 0; arg;
1407 arg = TREE_CHAIN (arg), idx++)
1408 if (arg == decl)
1409 break;
1410 if (arg == NULL_TREE)
1412 error_at (OMP_CLAUSE_LOCATION (c),
1413 "%qD is not an function argument", decl);
1414 continue;
1416 OMP_CLAUSE_LINEAR_STEP (c)
1417 = build_int_cst (integer_type_node, idx);
1420 clvec.safe_push (c);
1422 if (!clvec.is_empty ())
1424 unsigned int len = clvec.length (), i;
1425 clvec.qsort (c_omp_declare_simd_clause_cmp);
1426 clauses = clvec[0];
1427 for (i = 0; i < len; i++)
1428 OMP_CLAUSE_CHAIN (clvec[i]) = (i < len - 1) ? clvec[i + 1] : NULL_TREE;
1430 else
1431 clauses = NULL_TREE;
1432 clvec.release ();
1433 return clauses;
1436 /* Change argument indexes in CLAUSES of FNDECL back to PARM_DECLs. */
1438 void
1439 c_omp_declare_simd_clauses_to_decls (tree fndecl, tree clauses)
1441 tree c;
1443 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
1444 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_SIMDLEN
1445 && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_INBRANCH
1446 && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_NOTINBRANCH)
1448 int idx = tree_to_shwi (OMP_CLAUSE_DECL (c)), i;
1449 tree arg;
1450 for (arg = DECL_ARGUMENTS (fndecl), i = 0; arg;
1451 arg = TREE_CHAIN (arg), i++)
1452 if (i == idx)
1453 break;
1454 gcc_assert (arg);
1455 OMP_CLAUSE_DECL (c) = arg;
1456 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
1457 && OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (c))
1459 idx = tree_to_shwi (OMP_CLAUSE_LINEAR_STEP (c));
1460 for (arg = DECL_ARGUMENTS (fndecl), i = 0; arg;
1461 arg = TREE_CHAIN (arg), i++)
1462 if (i == idx)
1463 break;
1464 gcc_assert (arg);
1465 OMP_CLAUSE_LINEAR_STEP (c) = arg;
1470 /* True if OpenMP sharing attribute of DECL is predetermined. */
1472 enum omp_clause_default_kind
1473 c_omp_predetermined_sharing (tree decl)
1475 /* Variables with const-qualified type having no mutable member
1476 are predetermined shared. */
1477 if (TREE_READONLY (decl))
1478 return OMP_CLAUSE_DEFAULT_SHARED;
1480 return OMP_CLAUSE_DEFAULT_UNSPECIFIED;