gcc/
[official-gcc.git] / gcc / c-family / c-omp.c
blob87150459f81405d839f8485afabf19d261e6d2ea
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-2015 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 "tm.h"
28 #include "hash-set.h"
29 #include "machmode.h"
30 #include "vec.h"
31 #include "double-int.h"
32 #include "input.h"
33 #include "alias.h"
34 #include "symtab.h"
35 #include "wide-int.h"
36 #include "inchash.h"
37 #include "tree.h"
38 #include "c-common.h"
39 #include "c-pragma.h"
40 #include "gimple-expr.h"
41 #include "langhooks.h"
42 #include "omp-low.h"
43 #include "gomp-constants.h"
46 /* Complete a #pragma oacc wait construct. LOC is the location of
47 the #pragma. */
49 tree
50 c_finish_oacc_wait (location_t loc, tree parms, tree clauses)
52 const int nparms = list_length (parms);
53 tree stmt, t;
54 vec<tree, va_gc> *args;
56 vec_alloc (args, nparms + 2);
57 stmt = builtin_decl_explicit (BUILT_IN_GOACC_WAIT);
59 if (find_omp_clause (clauses, OMP_CLAUSE_ASYNC))
60 t = OMP_CLAUSE_ASYNC_EXPR (clauses);
61 else
62 t = build_int_cst (integer_type_node, GOMP_ASYNC_SYNC);
64 args->quick_push (t);
65 args->quick_push (build_int_cst (integer_type_node, nparms));
67 for (t = parms; t; t = TREE_CHAIN (t))
69 if (TREE_CODE (OMP_CLAUSE_WAIT_EXPR (t)) == INTEGER_CST)
70 args->quick_push (build_int_cst (integer_type_node,
71 TREE_INT_CST_LOW (OMP_CLAUSE_WAIT_EXPR (t))));
72 else
73 args->quick_push (OMP_CLAUSE_WAIT_EXPR (t));
76 stmt = build_call_expr_loc_vec (loc, stmt, args);
77 add_stmt (stmt);
79 vec_free (args);
81 return stmt;
84 /* Complete a #pragma omp master construct. STMT is the structured-block
85 that follows the pragma. LOC is the l*/
87 tree
88 c_finish_omp_master (location_t loc, tree stmt)
90 tree t = add_stmt (build1 (OMP_MASTER, void_type_node, stmt));
91 SET_EXPR_LOCATION (t, loc);
92 return t;
95 /* Complete a #pragma omp taskgroup construct. STMT is the structured-block
96 that follows the pragma. LOC is the l*/
98 tree
99 c_finish_omp_taskgroup (location_t loc, tree stmt)
101 tree t = add_stmt (build1 (OMP_TASKGROUP, void_type_node, stmt));
102 SET_EXPR_LOCATION (t, loc);
103 return t;
106 /* Complete a #pragma omp critical construct. STMT is the structured-block
107 that follows the pragma, NAME is the identifier in the pragma, or null
108 if it was omitted. LOC is the location of the #pragma. */
110 tree
111 c_finish_omp_critical (location_t loc, tree body, tree name)
113 tree stmt = make_node (OMP_CRITICAL);
114 TREE_TYPE (stmt) = void_type_node;
115 OMP_CRITICAL_BODY (stmt) = body;
116 OMP_CRITICAL_NAME (stmt) = name;
117 SET_EXPR_LOCATION (stmt, loc);
118 return add_stmt (stmt);
121 /* Complete a #pragma omp ordered construct. STMT is the structured-block
122 that follows the pragma. LOC is the location of the #pragma. */
124 tree
125 c_finish_omp_ordered (location_t loc, tree stmt)
127 tree t = build1 (OMP_ORDERED, void_type_node, stmt);
128 SET_EXPR_LOCATION (t, loc);
129 return add_stmt (t);
133 /* Complete a #pragma omp barrier construct. LOC is the location of
134 the #pragma. */
136 void
137 c_finish_omp_barrier (location_t loc)
139 tree x;
141 x = builtin_decl_explicit (BUILT_IN_GOMP_BARRIER);
142 x = build_call_expr_loc (loc, x, 0);
143 add_stmt (x);
147 /* Complete a #pragma omp taskwait construct. LOC is the location of the
148 pragma. */
150 void
151 c_finish_omp_taskwait (location_t loc)
153 tree x;
155 x = builtin_decl_explicit (BUILT_IN_GOMP_TASKWAIT);
156 x = build_call_expr_loc (loc, x, 0);
157 add_stmt (x);
161 /* Complete a #pragma omp taskyield construct. LOC is the location of the
162 pragma. */
164 void
165 c_finish_omp_taskyield (location_t loc)
167 tree x;
169 x = builtin_decl_explicit (BUILT_IN_GOMP_TASKYIELD);
170 x = build_call_expr_loc (loc, x, 0);
171 add_stmt (x);
175 /* Complete a #pragma omp atomic construct. For CODE OMP_ATOMIC
176 the expression to be implemented atomically is LHS opcode= RHS.
177 For OMP_ATOMIC_READ V = LHS, for OMP_ATOMIC_CAPTURE_{NEW,OLD} LHS
178 opcode= RHS with the new or old content of LHS returned.
179 LOC is the location of the atomic statement. The value returned
180 is either error_mark_node (if the construct was erroneous) or an
181 OMP_ATOMIC* node which should be added to the current statement
182 tree with add_stmt. */
184 tree
185 c_finish_omp_atomic (location_t loc, enum tree_code code,
186 enum tree_code opcode, tree lhs, tree rhs,
187 tree v, tree lhs1, tree rhs1, bool swapped, bool seq_cst)
189 tree x, type, addr, pre = NULL_TREE;
191 if (lhs == error_mark_node || rhs == error_mark_node
192 || v == error_mark_node || lhs1 == error_mark_node
193 || rhs1 == error_mark_node)
194 return error_mark_node;
196 /* ??? According to one reading of the OpenMP spec, complex type are
197 supported, but there are no atomic stores for any architecture.
198 But at least icc 9.0 doesn't support complex types here either.
199 And lets not even talk about vector types... */
200 type = TREE_TYPE (lhs);
201 if (!INTEGRAL_TYPE_P (type)
202 && !POINTER_TYPE_P (type)
203 && !SCALAR_FLOAT_TYPE_P (type))
205 error_at (loc, "invalid expression type for %<#pragma omp atomic%>");
206 return error_mark_node;
209 /* ??? Validate that rhs does not overlap lhs. */
211 /* Take and save the address of the lhs. From then on we'll reference it
212 via indirection. */
213 addr = build_unary_op (loc, ADDR_EXPR, lhs, 0);
214 if (addr == error_mark_node)
215 return error_mark_node;
216 addr = save_expr (addr);
217 if (TREE_CODE (addr) != SAVE_EXPR
218 && (TREE_CODE (addr) != ADDR_EXPR
219 || TREE_CODE (TREE_OPERAND (addr, 0)) != VAR_DECL))
221 /* Make sure LHS is simple enough so that goa_lhs_expr_p can recognize
222 it even after unsharing function body. */
223 tree var = create_tmp_var_raw (TREE_TYPE (addr));
224 DECL_CONTEXT (var) = current_function_decl;
225 addr = build4 (TARGET_EXPR, TREE_TYPE (addr), var, addr, NULL, NULL);
227 lhs = build_indirect_ref (loc, addr, RO_NULL);
229 if (code == OMP_ATOMIC_READ)
231 x = build1 (OMP_ATOMIC_READ, type, addr);
232 SET_EXPR_LOCATION (x, loc);
233 OMP_ATOMIC_SEQ_CST (x) = seq_cst;
234 return build_modify_expr (loc, v, NULL_TREE, NOP_EXPR,
235 loc, x, NULL_TREE);
238 /* There are lots of warnings, errors, and conversions that need to happen
239 in the course of interpreting a statement. Use the normal mechanisms
240 to do this, and then take it apart again. */
241 if (swapped)
243 rhs = build2_loc (loc, opcode, TREE_TYPE (lhs), rhs, lhs);
244 opcode = NOP_EXPR;
246 bool save = in_late_binary_op;
247 in_late_binary_op = true;
248 x = build_modify_expr (loc, lhs, NULL_TREE, opcode, loc, rhs, NULL_TREE);
249 in_late_binary_op = save;
250 if (x == error_mark_node)
251 return error_mark_node;
252 if (TREE_CODE (x) == COMPOUND_EXPR)
254 pre = TREE_OPERAND (x, 0);
255 gcc_assert (TREE_CODE (pre) == SAVE_EXPR);
256 x = TREE_OPERAND (x, 1);
258 gcc_assert (TREE_CODE (x) == MODIFY_EXPR);
259 rhs = TREE_OPERAND (x, 1);
261 /* Punt the actual generation of atomic operations to common code. */
262 if (code == OMP_ATOMIC)
263 type = void_type_node;
264 x = build2 (code, type, addr, rhs);
265 SET_EXPR_LOCATION (x, loc);
266 OMP_ATOMIC_SEQ_CST (x) = seq_cst;
268 /* Generally it is hard to prove lhs1 and lhs are the same memory
269 location, just diagnose different variables. */
270 if (rhs1
271 && TREE_CODE (rhs1) == VAR_DECL
272 && TREE_CODE (lhs) == VAR_DECL
273 && rhs1 != lhs)
275 if (code == OMP_ATOMIC)
276 error_at (loc, "%<#pragma omp atomic update%> uses two different variables for memory");
277 else
278 error_at (loc, "%<#pragma omp atomic capture%> uses two different variables for memory");
279 return error_mark_node;
282 if (code != OMP_ATOMIC)
284 /* Generally it is hard to prove lhs1 and lhs are the same memory
285 location, just diagnose different variables. */
286 if (lhs1 && TREE_CODE (lhs1) == VAR_DECL && TREE_CODE (lhs) == VAR_DECL)
288 if (lhs1 != lhs)
290 error_at (loc, "%<#pragma omp atomic capture%> uses two different variables for memory");
291 return error_mark_node;
294 x = build_modify_expr (loc, v, NULL_TREE, NOP_EXPR,
295 loc, x, NULL_TREE);
296 if (rhs1 && rhs1 != lhs)
298 tree rhs1addr = build_unary_op (loc, ADDR_EXPR, rhs1, 0);
299 if (rhs1addr == error_mark_node)
300 return error_mark_node;
301 x = omit_one_operand_loc (loc, type, x, rhs1addr);
303 if (lhs1 && lhs1 != lhs)
305 tree lhs1addr = build_unary_op (loc, ADDR_EXPR, lhs1, 0);
306 if (lhs1addr == error_mark_node)
307 return error_mark_node;
308 if (code == OMP_ATOMIC_CAPTURE_OLD)
309 x = omit_one_operand_loc (loc, type, x, lhs1addr);
310 else
312 x = save_expr (x);
313 x = omit_two_operands_loc (loc, type, x, x, lhs1addr);
317 else if (rhs1 && rhs1 != lhs)
319 tree rhs1addr = build_unary_op (loc, ADDR_EXPR, rhs1, 0);
320 if (rhs1addr == error_mark_node)
321 return error_mark_node;
322 x = omit_one_operand_loc (loc, type, x, rhs1addr);
325 if (pre)
326 x = omit_one_operand_loc (loc, type, x, pre);
327 return x;
331 /* Complete a #pragma omp flush construct. We don't do anything with
332 the variable list that the syntax allows. LOC is the location of
333 the #pragma. */
335 void
336 c_finish_omp_flush (location_t loc)
338 tree x;
340 x = builtin_decl_explicit (BUILT_IN_SYNC_SYNCHRONIZE);
341 x = build_call_expr_loc (loc, x, 0);
342 add_stmt (x);
346 /* Check and canonicalize OMP_FOR increment expression.
347 Helper function for c_finish_omp_for. */
349 static tree
350 check_omp_for_incr_expr (location_t loc, tree exp, tree decl)
352 tree t;
354 if (!INTEGRAL_TYPE_P (TREE_TYPE (exp))
355 || TYPE_PRECISION (TREE_TYPE (exp)) < TYPE_PRECISION (TREE_TYPE (decl)))
356 return error_mark_node;
358 if (exp == decl)
359 return build_int_cst (TREE_TYPE (exp), 0);
361 switch (TREE_CODE (exp))
363 CASE_CONVERT:
364 t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 0), decl);
365 if (t != error_mark_node)
366 return fold_convert_loc (loc, TREE_TYPE (exp), t);
367 break;
368 case MINUS_EXPR:
369 t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 0), decl);
370 if (t != error_mark_node)
371 return fold_build2_loc (loc, MINUS_EXPR,
372 TREE_TYPE (exp), t, TREE_OPERAND (exp, 1));
373 break;
374 case PLUS_EXPR:
375 t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 0), decl);
376 if (t != error_mark_node)
377 return fold_build2_loc (loc, PLUS_EXPR,
378 TREE_TYPE (exp), t, TREE_OPERAND (exp, 1));
379 t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 1), decl);
380 if (t != error_mark_node)
381 return fold_build2_loc (loc, PLUS_EXPR,
382 TREE_TYPE (exp), TREE_OPERAND (exp, 0), t);
383 break;
384 case COMPOUND_EXPR:
386 /* cp_build_modify_expr forces preevaluation of the RHS to make
387 sure that it is evaluated before the lvalue-rvalue conversion
388 is applied to the LHS. Reconstruct the original expression. */
389 tree op0 = TREE_OPERAND (exp, 0);
390 if (TREE_CODE (op0) == TARGET_EXPR
391 && !VOID_TYPE_P (TREE_TYPE (op0)))
393 tree op1 = TREE_OPERAND (exp, 1);
394 tree temp = TARGET_EXPR_SLOT (op0);
395 if (TREE_CODE_CLASS (TREE_CODE (op1)) == tcc_binary
396 && TREE_OPERAND (op1, 1) == temp)
398 op1 = copy_node (op1);
399 TREE_OPERAND (op1, 1) = TARGET_EXPR_INITIAL (op0);
400 return check_omp_for_incr_expr (loc, op1, decl);
403 break;
405 default:
406 break;
409 return error_mark_node;
412 /* If the OMP_FOR increment expression in INCR is of pointer type,
413 canonicalize it into an expression handled by gimplify_omp_for()
414 and return it. DECL is the iteration variable. */
416 static tree
417 c_omp_for_incr_canonicalize_ptr (location_t loc, tree decl, tree incr)
419 if (POINTER_TYPE_P (TREE_TYPE (decl))
420 && TREE_OPERAND (incr, 1))
422 tree t = fold_convert_loc (loc,
423 sizetype, TREE_OPERAND (incr, 1));
425 if (TREE_CODE (incr) == POSTDECREMENT_EXPR
426 || TREE_CODE (incr) == PREDECREMENT_EXPR)
427 t = fold_build1_loc (loc, NEGATE_EXPR, sizetype, t);
428 t = fold_build_pointer_plus (decl, t);
429 incr = build2 (MODIFY_EXPR, void_type_node, decl, t);
431 return incr;
434 /* Validate and generate OMP_FOR.
435 DECLV is a vector of iteration variables, for each collapsed loop.
436 INITV, CONDV and INCRV are vectors containing initialization
437 expressions, controlling predicates and increment expressions.
438 BODY is the body of the loop and PRE_BODY statements that go before
439 the loop. */
441 tree
442 c_finish_omp_for (location_t locus, enum tree_code code, tree declv,
443 tree initv, tree condv, tree incrv, tree body, tree pre_body)
445 location_t elocus;
446 bool fail = false;
447 int i;
449 if ((code == CILK_SIMD || code == CILK_FOR)
450 && !c_check_cilk_loop (locus, TREE_VEC_ELT (declv, 0)))
451 fail = true;
453 gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (initv));
454 gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (condv));
455 gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (incrv));
456 for (i = 0; i < TREE_VEC_LENGTH (declv); i++)
458 tree decl = TREE_VEC_ELT (declv, i);
459 tree init = TREE_VEC_ELT (initv, i);
460 tree cond = TREE_VEC_ELT (condv, i);
461 tree incr = TREE_VEC_ELT (incrv, i);
463 elocus = locus;
464 if (EXPR_HAS_LOCATION (init))
465 elocus = EXPR_LOCATION (init);
467 /* Validate the iteration variable. */
468 if (!INTEGRAL_TYPE_P (TREE_TYPE (decl))
469 && TREE_CODE (TREE_TYPE (decl)) != POINTER_TYPE)
471 error_at (elocus, "invalid type for iteration variable %qE", decl);
472 fail = true;
475 /* In the case of "for (int i = 0...)", init will be a decl. It should
476 have a DECL_INITIAL that we can turn into an assignment. */
477 if (init == decl)
479 elocus = DECL_SOURCE_LOCATION (decl);
481 init = DECL_INITIAL (decl);
482 if (init == NULL)
484 error_at (elocus, "%qE is not initialized", decl);
485 init = integer_zero_node;
486 fail = true;
489 init = build_modify_expr (elocus, decl, NULL_TREE, NOP_EXPR,
490 /* FIXME diagnostics: This should
491 be the location of the INIT. */
492 elocus,
493 init,
494 NULL_TREE);
496 if (init != error_mark_node)
498 gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
499 gcc_assert (TREE_OPERAND (init, 0) == decl);
502 if (cond == NULL_TREE)
504 error_at (elocus, "missing controlling predicate");
505 fail = true;
507 else
509 bool cond_ok = false;
511 if (EXPR_HAS_LOCATION (cond))
512 elocus = EXPR_LOCATION (cond);
514 if (TREE_CODE (cond) == LT_EXPR
515 || TREE_CODE (cond) == LE_EXPR
516 || TREE_CODE (cond) == GT_EXPR
517 || TREE_CODE (cond) == GE_EXPR
518 || TREE_CODE (cond) == NE_EXPR
519 || TREE_CODE (cond) == EQ_EXPR)
521 tree op0 = TREE_OPERAND (cond, 0);
522 tree op1 = TREE_OPERAND (cond, 1);
524 /* 2.5.1. The comparison in the condition is computed in
525 the type of DECL, otherwise the behavior is undefined.
527 For example:
528 long n; int i;
529 i < n;
531 according to ISO will be evaluated as:
532 (long)i < n;
534 We want to force:
535 i < (int)n; */
536 if (TREE_CODE (op0) == NOP_EXPR
537 && decl == TREE_OPERAND (op0, 0))
539 TREE_OPERAND (cond, 0) = TREE_OPERAND (op0, 0);
540 TREE_OPERAND (cond, 1)
541 = fold_build1_loc (elocus, NOP_EXPR, TREE_TYPE (decl),
542 TREE_OPERAND (cond, 1));
544 else if (TREE_CODE (op1) == NOP_EXPR
545 && decl == TREE_OPERAND (op1, 0))
547 TREE_OPERAND (cond, 1) = TREE_OPERAND (op1, 0);
548 TREE_OPERAND (cond, 0)
549 = fold_build1_loc (elocus, NOP_EXPR, TREE_TYPE (decl),
550 TREE_OPERAND (cond, 0));
553 if (decl == TREE_OPERAND (cond, 0))
554 cond_ok = true;
555 else if (decl == TREE_OPERAND (cond, 1))
557 TREE_SET_CODE (cond,
558 swap_tree_comparison (TREE_CODE (cond)));
559 TREE_OPERAND (cond, 1) = TREE_OPERAND (cond, 0);
560 TREE_OPERAND (cond, 0) = decl;
561 cond_ok = true;
564 if (TREE_CODE (cond) == NE_EXPR
565 || TREE_CODE (cond) == EQ_EXPR)
567 if (!INTEGRAL_TYPE_P (TREE_TYPE (decl)))
569 if (code != CILK_SIMD && code != CILK_FOR)
570 cond_ok = false;
572 else if (operand_equal_p (TREE_OPERAND (cond, 1),
573 TYPE_MIN_VALUE (TREE_TYPE (decl)),
575 TREE_SET_CODE (cond, TREE_CODE (cond) == NE_EXPR
576 ? GT_EXPR : LE_EXPR);
577 else if (operand_equal_p (TREE_OPERAND (cond, 1),
578 TYPE_MAX_VALUE (TREE_TYPE (decl)),
580 TREE_SET_CODE (cond, TREE_CODE (cond) == NE_EXPR
581 ? LT_EXPR : GE_EXPR);
582 else if (code != CILK_SIMD && code != CILK_FOR)
583 cond_ok = false;
587 if (!cond_ok)
589 error_at (elocus, "invalid controlling predicate");
590 fail = true;
594 if (incr == NULL_TREE)
596 error_at (elocus, "missing increment expression");
597 fail = true;
599 else
601 bool incr_ok = false;
603 if (EXPR_HAS_LOCATION (incr))
604 elocus = EXPR_LOCATION (incr);
606 /* Check all the valid increment expressions: v++, v--, ++v, --v,
607 v = v + incr, v = incr + v and v = v - incr. */
608 switch (TREE_CODE (incr))
610 case POSTINCREMENT_EXPR:
611 case PREINCREMENT_EXPR:
612 case POSTDECREMENT_EXPR:
613 case PREDECREMENT_EXPR:
614 if (TREE_OPERAND (incr, 0) != decl)
615 break;
617 incr_ok = true;
618 incr = c_omp_for_incr_canonicalize_ptr (elocus, decl, incr);
619 break;
621 case COMPOUND_EXPR:
622 if (TREE_CODE (TREE_OPERAND (incr, 0)) != SAVE_EXPR
623 || TREE_CODE (TREE_OPERAND (incr, 1)) != MODIFY_EXPR)
624 break;
625 incr = TREE_OPERAND (incr, 1);
626 /* FALLTHRU */
627 case MODIFY_EXPR:
628 if (TREE_OPERAND (incr, 0) != decl)
629 break;
630 if (TREE_OPERAND (incr, 1) == decl)
631 break;
632 if (TREE_CODE (TREE_OPERAND (incr, 1)) == PLUS_EXPR
633 && (TREE_OPERAND (TREE_OPERAND (incr, 1), 0) == decl
634 || TREE_OPERAND (TREE_OPERAND (incr, 1), 1) == decl))
635 incr_ok = true;
636 else if ((TREE_CODE (TREE_OPERAND (incr, 1)) == MINUS_EXPR
637 || (TREE_CODE (TREE_OPERAND (incr, 1))
638 == POINTER_PLUS_EXPR))
639 && TREE_OPERAND (TREE_OPERAND (incr, 1), 0) == decl)
640 incr_ok = true;
641 else
643 tree t = check_omp_for_incr_expr (elocus,
644 TREE_OPERAND (incr, 1),
645 decl);
646 if (t != error_mark_node)
648 incr_ok = true;
649 t = build2 (PLUS_EXPR, TREE_TYPE (decl), decl, t);
650 incr = build2 (MODIFY_EXPR, void_type_node, decl, t);
653 break;
655 default:
656 break;
658 if (!incr_ok)
660 error_at (elocus, "invalid increment expression");
661 fail = true;
665 TREE_VEC_ELT (initv, i) = init;
666 TREE_VEC_ELT (incrv, i) = incr;
669 if (fail)
670 return NULL;
671 else
673 tree t = make_node (code);
675 TREE_TYPE (t) = void_type_node;
676 OMP_FOR_INIT (t) = initv;
677 OMP_FOR_COND (t) = condv;
678 OMP_FOR_INCR (t) = incrv;
679 OMP_FOR_BODY (t) = body;
680 OMP_FOR_PRE_BODY (t) = pre_body;
682 SET_EXPR_LOCATION (t, locus);
683 return add_stmt (t);
687 /* Right now we have 14 different combined constructs, this
688 function attempts to split or duplicate clauses for combined
689 constructs. CODE is the innermost construct in the combined construct,
690 and MASK allows to determine which constructs are combined together,
691 as every construct has at least one clause that no other construct
692 has (except for OMP_SECTIONS, but that can be only combined with parallel).
693 Combined constructs are:
694 #pragma omp parallel for
695 #pragma omp parallel sections
696 #pragma omp parallel for simd
697 #pragma omp for simd
698 #pragma omp distribute simd
699 #pragma omp distribute parallel for
700 #pragma omp distribute parallel for simd
701 #pragma omp teams distribute
702 #pragma omp teams distribute parallel for
703 #pragma omp teams distribute parallel for simd
704 #pragma omp target teams
705 #pragma omp target teams distribute
706 #pragma omp target teams distribute parallel for
707 #pragma omp target teams distribute parallel for simd */
709 void
710 c_omp_split_clauses (location_t loc, enum tree_code code,
711 omp_clause_mask mask, tree clauses, tree *cclauses)
713 tree next, c;
714 enum c_omp_clause_split s;
715 int i;
717 for (i = 0; i < C_OMP_CLAUSE_SPLIT_COUNT; i++)
718 cclauses[i] = NULL;
719 /* Add implicit nowait clause on
720 #pragma omp parallel {for,for simd,sections}. */
721 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
722 switch (code)
724 case OMP_FOR:
725 case OMP_SIMD:
726 cclauses[C_OMP_CLAUSE_SPLIT_FOR]
727 = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
728 break;
729 case OMP_SECTIONS:
730 cclauses[C_OMP_CLAUSE_SPLIT_SECTIONS]
731 = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
732 break;
733 default:
734 break;
737 for (; clauses ; clauses = next)
739 next = OMP_CLAUSE_CHAIN (clauses);
741 switch (OMP_CLAUSE_CODE (clauses))
743 /* First the clauses that are unique to some constructs. */
744 case OMP_CLAUSE_DEVICE:
745 case OMP_CLAUSE_MAP:
746 s = C_OMP_CLAUSE_SPLIT_TARGET;
747 break;
748 case OMP_CLAUSE_NUM_TEAMS:
749 case OMP_CLAUSE_THREAD_LIMIT:
750 s = C_OMP_CLAUSE_SPLIT_TEAMS;
751 break;
752 case OMP_CLAUSE_DIST_SCHEDULE:
753 s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
754 break;
755 case OMP_CLAUSE_COPYIN:
756 case OMP_CLAUSE_NUM_THREADS:
757 case OMP_CLAUSE_PROC_BIND:
758 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
759 break;
760 case OMP_CLAUSE_ORDERED:
761 case OMP_CLAUSE_SCHEDULE:
762 case OMP_CLAUSE_NOWAIT:
763 s = C_OMP_CLAUSE_SPLIT_FOR;
764 break;
765 case OMP_CLAUSE_SAFELEN:
766 case OMP_CLAUSE_LINEAR:
767 case OMP_CLAUSE_ALIGNED:
768 s = C_OMP_CLAUSE_SPLIT_SIMD;
769 break;
770 /* Duplicate this to all of distribute, for and simd. */
771 case OMP_CLAUSE_COLLAPSE:
772 if (code == OMP_SIMD)
774 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
775 OMP_CLAUSE_COLLAPSE);
776 OMP_CLAUSE_COLLAPSE_EXPR (c)
777 = OMP_CLAUSE_COLLAPSE_EXPR (clauses);
778 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
779 cclauses[C_OMP_CLAUSE_SPLIT_SIMD] = c;
781 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)) != 0)
783 if ((mask & (OMP_CLAUSE_MASK_1
784 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
786 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
787 OMP_CLAUSE_COLLAPSE);
788 OMP_CLAUSE_COLLAPSE_EXPR (c)
789 = OMP_CLAUSE_COLLAPSE_EXPR (clauses);
790 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
791 cclauses[C_OMP_CLAUSE_SPLIT_FOR] = c;
792 s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
794 else
795 s = C_OMP_CLAUSE_SPLIT_FOR;
797 else
798 s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
799 break;
800 /* Private clause is supported on all constructs but target,
801 it is enough to put it on the innermost one. For
802 #pragma omp {for,sections} put it on parallel though,
803 as that's what we did for OpenMP 3.1. */
804 case OMP_CLAUSE_PRIVATE:
805 switch (code)
807 case OMP_SIMD: s = C_OMP_CLAUSE_SPLIT_SIMD; break;
808 case OMP_FOR: case OMP_SECTIONS:
809 case OMP_PARALLEL: s = C_OMP_CLAUSE_SPLIT_PARALLEL; break;
810 case OMP_DISTRIBUTE: s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE; break;
811 case OMP_TEAMS: s = C_OMP_CLAUSE_SPLIT_TEAMS; break;
812 default: gcc_unreachable ();
814 break;
815 /* Firstprivate clause is supported on all constructs but
816 target and simd. Put it on the outermost of those and
817 duplicate on parallel. */
818 case OMP_CLAUSE_FIRSTPRIVATE:
819 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS))
820 != 0)
822 if ((mask & ((OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS)
823 | (OMP_CLAUSE_MASK_1
824 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE))) != 0)
826 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
827 OMP_CLAUSE_FIRSTPRIVATE);
828 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
829 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL];
830 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] = c;
831 if ((mask & (OMP_CLAUSE_MASK_1
832 << PRAGMA_OMP_CLAUSE_NUM_TEAMS)) != 0)
833 s = C_OMP_CLAUSE_SPLIT_TEAMS;
834 else
835 s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
837 else
838 /* This must be
839 #pragma omp parallel{, for{, simd}, sections}. */
840 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
842 else if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS))
843 != 0)
845 /* This must be one of
846 #pragma omp {,target }teams distribute
847 #pragma omp target teams
848 #pragma omp {,target }teams distribute simd. */
849 gcc_assert (code == OMP_DISTRIBUTE
850 || code == OMP_TEAMS
851 || code == OMP_SIMD);
852 s = C_OMP_CLAUSE_SPLIT_TEAMS;
854 else if ((mask & (OMP_CLAUSE_MASK_1
855 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
857 /* This must be #pragma omp distribute simd. */
858 gcc_assert (code == OMP_SIMD);
859 s = C_OMP_CLAUSE_SPLIT_TEAMS;
861 else
863 /* This must be #pragma omp for simd. */
864 gcc_assert (code == OMP_SIMD);
865 s = C_OMP_CLAUSE_SPLIT_FOR;
867 break;
868 /* Lastprivate is allowed on for, sections and simd. In
869 parallel {for{, simd},sections} we actually want to put it on
870 parallel rather than for or sections. */
871 case OMP_CLAUSE_LASTPRIVATE:
872 if (code == OMP_FOR || code == OMP_SECTIONS)
874 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS))
875 != 0)
876 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
877 else
878 s = C_OMP_CLAUSE_SPLIT_FOR;
879 break;
881 gcc_assert (code == OMP_SIMD);
882 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)) != 0)
884 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
885 OMP_CLAUSE_LASTPRIVATE);
886 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
887 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS))
888 != 0)
889 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
890 else
891 s = C_OMP_CLAUSE_SPLIT_FOR;
892 OMP_CLAUSE_CHAIN (c) = cclauses[s];
893 cclauses[s] = c;
895 s = C_OMP_CLAUSE_SPLIT_SIMD;
896 break;
897 /* Shared and default clauses are allowed on private and teams. */
898 case OMP_CLAUSE_SHARED:
899 case OMP_CLAUSE_DEFAULT:
900 if (code == OMP_TEAMS)
902 s = C_OMP_CLAUSE_SPLIT_TEAMS;
903 break;
905 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS))
906 != 0)
908 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
909 OMP_CLAUSE_CODE (clauses));
910 if (OMP_CLAUSE_CODE (clauses) == OMP_CLAUSE_SHARED)
911 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
912 else
913 OMP_CLAUSE_DEFAULT_KIND (c)
914 = OMP_CLAUSE_DEFAULT_KIND (clauses);
915 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
916 cclauses[C_OMP_CLAUSE_SPLIT_TEAMS] = c;
919 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
920 break;
921 /* Reduction is allowed on simd, for, parallel, sections and teams.
922 Duplicate it on all of them, but omit on for or sections if
923 parallel is present. */
924 case OMP_CLAUSE_REDUCTION:
925 if (code == OMP_SIMD)
927 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
928 OMP_CLAUSE_REDUCTION);
929 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
930 OMP_CLAUSE_REDUCTION_CODE (c)
931 = OMP_CLAUSE_REDUCTION_CODE (clauses);
932 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
933 = OMP_CLAUSE_REDUCTION_PLACEHOLDER (clauses);
934 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
935 cclauses[C_OMP_CLAUSE_SPLIT_SIMD] = c;
937 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)) != 0)
939 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS))
940 != 0)
942 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
943 OMP_CLAUSE_REDUCTION);
944 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
945 OMP_CLAUSE_REDUCTION_CODE (c)
946 = OMP_CLAUSE_REDUCTION_CODE (clauses);
947 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
948 = OMP_CLAUSE_REDUCTION_PLACEHOLDER (clauses);
949 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL];
950 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] = c;
951 s = C_OMP_CLAUSE_SPLIT_TEAMS;
953 else if ((mask & (OMP_CLAUSE_MASK_1
954 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
955 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
956 else
957 s = C_OMP_CLAUSE_SPLIT_FOR;
959 else if (code == OMP_SECTIONS)
960 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
961 else
962 s = C_OMP_CLAUSE_SPLIT_TEAMS;
963 break;
964 case OMP_CLAUSE_IF:
965 /* FIXME: This is currently being discussed. */
966 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS))
967 != 0)
968 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
969 else
970 s = C_OMP_CLAUSE_SPLIT_TARGET;
971 break;
972 default:
973 gcc_unreachable ();
975 OMP_CLAUSE_CHAIN (clauses) = cclauses[s];
976 cclauses[s] = clauses;
981 /* qsort callback to compare #pragma omp declare simd clauses. */
983 static int
984 c_omp_declare_simd_clause_cmp (const void *p, const void *q)
986 tree a = *(const tree *) p;
987 tree b = *(const tree *) q;
988 if (OMP_CLAUSE_CODE (a) != OMP_CLAUSE_CODE (b))
990 if (OMP_CLAUSE_CODE (a) > OMP_CLAUSE_CODE (b))
991 return -1;
992 return 1;
994 if (OMP_CLAUSE_CODE (a) != OMP_CLAUSE_SIMDLEN
995 && OMP_CLAUSE_CODE (a) != OMP_CLAUSE_INBRANCH
996 && OMP_CLAUSE_CODE (a) != OMP_CLAUSE_NOTINBRANCH)
998 int c = tree_to_shwi (OMP_CLAUSE_DECL (a));
999 int d = tree_to_shwi (OMP_CLAUSE_DECL (b));
1000 if (c < d)
1001 return 1;
1002 if (c > d)
1003 return -1;
1005 return 0;
1008 /* Change PARM_DECLs in OMP_CLAUSE_DECL of #pragma omp declare simd
1009 CLAUSES on FNDECL into argument indexes and sort them. */
1011 tree
1012 c_omp_declare_simd_clauses_to_numbers (tree parms, tree clauses)
1014 tree c;
1015 vec<tree> clvec = vNULL;
1017 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
1019 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_SIMDLEN
1020 && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_INBRANCH
1021 && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_NOTINBRANCH)
1023 tree decl = OMP_CLAUSE_DECL (c);
1024 tree arg;
1025 int idx;
1026 for (arg = parms, idx = 0; arg;
1027 arg = TREE_CHAIN (arg), idx++)
1028 if (arg == decl)
1029 break;
1030 if (arg == NULL_TREE)
1032 error_at (OMP_CLAUSE_LOCATION (c),
1033 "%qD is not an function argument", decl);
1034 continue;
1036 OMP_CLAUSE_DECL (c) = build_int_cst (integer_type_node, idx);
1038 clvec.safe_push (c);
1040 if (!clvec.is_empty ())
1042 unsigned int len = clvec.length (), i;
1043 clvec.qsort (c_omp_declare_simd_clause_cmp);
1044 clauses = clvec[0];
1045 for (i = 0; i < len; i++)
1046 OMP_CLAUSE_CHAIN (clvec[i]) = (i < len - 1) ? clvec[i + 1] : NULL_TREE;
1048 clvec.release ();
1049 return clauses;
1052 /* Change argument indexes in CLAUSES of FNDECL back to PARM_DECLs. */
1054 void
1055 c_omp_declare_simd_clauses_to_decls (tree fndecl, tree clauses)
1057 tree c;
1059 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
1060 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_SIMDLEN
1061 && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_INBRANCH
1062 && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_NOTINBRANCH)
1064 int idx = tree_to_shwi (OMP_CLAUSE_DECL (c)), i;
1065 tree arg;
1066 for (arg = DECL_ARGUMENTS (fndecl), i = 0; arg;
1067 arg = TREE_CHAIN (arg), i++)
1068 if (i == idx)
1069 break;
1070 gcc_assert (arg);
1071 OMP_CLAUSE_DECL (c) = arg;
1075 /* True if OpenMP sharing attribute of DECL is predetermined. */
1077 enum omp_clause_default_kind
1078 c_omp_predetermined_sharing (tree decl)
1080 /* Variables with const-qualified type having no mutable member
1081 are predetermined shared. */
1082 if (TREE_READONLY (decl))
1083 return OMP_CLAUSE_DEFAULT_SHARED;
1085 return OMP_CLAUSE_DEFAULT_UNSPECIFIED;