[19/46] Make vect_dr_stmt return a stmt_vec_info
[official-gcc.git] / gcc / c-family / c-omp.c
blob89849379ca7691e91d9ac1ac8cfa2a4672bbea76
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-2018 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 if (!flag_openmp /* flag_openmp_simd */
120 && (OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_SIMD
121 || OMP_CLAUSE_CHAIN (clauses)))
122 clauses = build_omp_clause (loc, OMP_CLAUSE_SIMD);
123 OMP_ORDERED_CLAUSES (t) = clauses;
124 SET_EXPR_LOCATION (t, loc);
125 return add_stmt (t);
129 /* Complete a #pragma omp barrier construct. LOC is the location of
130 the #pragma. */
132 void
133 c_finish_omp_barrier (location_t loc)
135 tree x;
137 x = builtin_decl_explicit (BUILT_IN_GOMP_BARRIER);
138 x = build_call_expr_loc (loc, x, 0);
139 add_stmt (x);
143 /* Complete a #pragma omp taskwait construct. LOC is the location of the
144 pragma. */
146 void
147 c_finish_omp_taskwait (location_t loc)
149 tree x;
151 x = builtin_decl_explicit (BUILT_IN_GOMP_TASKWAIT);
152 x = build_call_expr_loc (loc, x, 0);
153 add_stmt (x);
157 /* Complete a #pragma omp taskyield construct. LOC is the location of the
158 pragma. */
160 void
161 c_finish_omp_taskyield (location_t loc)
163 tree x;
165 x = builtin_decl_explicit (BUILT_IN_GOMP_TASKYIELD);
166 x = build_call_expr_loc (loc, x, 0);
167 add_stmt (x);
171 /* Complete a #pragma omp atomic construct. For CODE OMP_ATOMIC
172 the expression to be implemented atomically is LHS opcode= RHS.
173 For OMP_ATOMIC_READ V = LHS, for OMP_ATOMIC_CAPTURE_{NEW,OLD} LHS
174 opcode= RHS with the new or old content of LHS returned.
175 LOC is the location of the atomic statement. The value returned
176 is either error_mark_node (if the construct was erroneous) or an
177 OMP_ATOMIC* node which should be added to the current statement
178 tree with add_stmt. If TEST is set, avoid calling save_expr
179 or create_tmp_var*. */
181 tree
182 c_finish_omp_atomic (location_t loc, enum tree_code code,
183 enum tree_code opcode, tree lhs, tree rhs,
184 tree v, tree lhs1, tree rhs1, bool swapped, bool seq_cst,
185 bool test)
187 tree x, type, addr, pre = NULL_TREE;
188 HOST_WIDE_INT bitpos = 0, bitsize = 0;
190 if (lhs == error_mark_node || rhs == error_mark_node
191 || v == error_mark_node || lhs1 == error_mark_node
192 || rhs1 == error_mark_node)
193 return error_mark_node;
195 /* ??? According to one reading of the OpenMP spec, complex type are
196 supported, but there are no atomic stores for any architecture.
197 But at least icc 9.0 doesn't support complex types here either.
198 And lets not even talk about vector types... */
199 type = TREE_TYPE (lhs);
200 if (!INTEGRAL_TYPE_P (type)
201 && !POINTER_TYPE_P (type)
202 && !SCALAR_FLOAT_TYPE_P (type))
204 error_at (loc, "invalid expression type for %<#pragma omp atomic%>");
205 return error_mark_node;
207 if (TYPE_ATOMIC (type))
209 error_at (loc, "%<_Atomic%> expression in %<#pragma omp atomic%>");
210 return error_mark_node;
213 if (opcode == RDIV_EXPR)
214 opcode = TRUNC_DIV_EXPR;
216 /* ??? Validate that rhs does not overlap lhs. */
217 tree blhs = NULL;
218 if (TREE_CODE (lhs) == COMPONENT_REF
219 && TREE_CODE (TREE_OPERAND (lhs, 1)) == FIELD_DECL
220 && DECL_C_BIT_FIELD (TREE_OPERAND (lhs, 1))
221 && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (lhs, 1)))
223 tree field = TREE_OPERAND (lhs, 1);
224 tree repr = DECL_BIT_FIELD_REPRESENTATIVE (field);
225 if (tree_fits_uhwi_p (DECL_FIELD_OFFSET (field))
226 && tree_fits_uhwi_p (DECL_FIELD_OFFSET (repr)))
227 bitpos = (tree_to_uhwi (DECL_FIELD_OFFSET (field))
228 - tree_to_uhwi (DECL_FIELD_OFFSET (repr))) * BITS_PER_UNIT;
229 else
230 bitpos = 0;
231 bitpos += (tree_to_uhwi (DECL_FIELD_BIT_OFFSET (field))
232 - tree_to_uhwi (DECL_FIELD_BIT_OFFSET (repr)));
233 gcc_assert (tree_fits_shwi_p (DECL_SIZE (field)));
234 bitsize = tree_to_shwi (DECL_SIZE (field));
235 blhs = lhs;
236 type = TREE_TYPE (repr);
237 lhs = build3 (COMPONENT_REF, TREE_TYPE (repr), TREE_OPERAND (lhs, 0),
238 repr, TREE_OPERAND (lhs, 2));
241 /* Take and save the address of the lhs. From then on we'll reference it
242 via indirection. */
243 addr = build_unary_op (loc, ADDR_EXPR, lhs, false);
244 if (addr == error_mark_node)
245 return error_mark_node;
246 if (!test)
247 addr = save_expr (addr);
248 if (!test
249 && TREE_CODE (addr) != SAVE_EXPR
250 && (TREE_CODE (addr) != ADDR_EXPR
251 || !VAR_P (TREE_OPERAND (addr, 0))))
253 /* Make sure LHS is simple enough so that goa_lhs_expr_p can recognize
254 it even after unsharing function body. */
255 tree var = create_tmp_var_raw (TREE_TYPE (addr));
256 DECL_CONTEXT (var) = current_function_decl;
257 addr = build4 (TARGET_EXPR, TREE_TYPE (addr), var, addr, NULL, NULL);
259 tree orig_lhs = lhs;
260 lhs = build_indirect_ref (loc, addr, RO_NULL);
261 tree new_lhs = lhs;
263 if (code == OMP_ATOMIC_READ)
265 x = build1 (OMP_ATOMIC_READ, type, addr);
266 SET_EXPR_LOCATION (x, loc);
267 OMP_ATOMIC_SEQ_CST (x) = seq_cst;
268 if (blhs)
269 x = build3_loc (loc, BIT_FIELD_REF, TREE_TYPE (blhs), x,
270 bitsize_int (bitsize), bitsize_int (bitpos));
271 return build_modify_expr (loc, v, NULL_TREE, NOP_EXPR,
272 loc, x, NULL_TREE);
275 /* There are lots of warnings, errors, and conversions that need to happen
276 in the course of interpreting a statement. Use the normal mechanisms
277 to do this, and then take it apart again. */
278 if (blhs)
280 lhs = build3_loc (loc, BIT_FIELD_REF, TREE_TYPE (blhs), lhs,
281 bitsize_int (bitsize), bitsize_int (bitpos));
282 if (swapped)
283 rhs = build_binary_op (loc, opcode, rhs, lhs, true);
284 else if (opcode != NOP_EXPR)
285 rhs = build_binary_op (loc, opcode, lhs, rhs, true);
286 opcode = NOP_EXPR;
288 else if (swapped)
290 rhs = build_binary_op (loc, opcode, rhs, lhs, true);
291 opcode = NOP_EXPR;
293 bool save = in_late_binary_op;
294 in_late_binary_op = true;
295 x = build_modify_expr (loc, blhs ? blhs : lhs, NULL_TREE, opcode,
296 loc, rhs, NULL_TREE);
297 in_late_binary_op = save;
298 if (x == error_mark_node)
299 return error_mark_node;
300 if (TREE_CODE (x) == COMPOUND_EXPR)
302 pre = TREE_OPERAND (x, 0);
303 gcc_assert (TREE_CODE (pre) == SAVE_EXPR);
304 x = TREE_OPERAND (x, 1);
306 gcc_assert (TREE_CODE (x) == MODIFY_EXPR);
307 rhs = TREE_OPERAND (x, 1);
309 if (blhs)
310 rhs = build3_loc (loc, BIT_INSERT_EXPR, type, new_lhs,
311 rhs, bitsize_int (bitpos));
313 /* Punt the actual generation of atomic operations to common code. */
314 if (code == OMP_ATOMIC)
315 type = void_type_node;
316 x = build2 (code, type, addr, rhs);
317 SET_EXPR_LOCATION (x, loc);
318 OMP_ATOMIC_SEQ_CST (x) = seq_cst;
320 /* Generally it is hard to prove lhs1 and lhs are the same memory
321 location, just diagnose different variables. */
322 if (rhs1
323 && VAR_P (rhs1)
324 && VAR_P (orig_lhs)
325 && rhs1 != orig_lhs
326 && !test)
328 if (code == OMP_ATOMIC)
329 error_at (loc, "%<#pragma omp atomic update%> uses two different "
330 "variables for memory");
331 else
332 error_at (loc, "%<#pragma omp atomic capture%> uses two different "
333 "variables for memory");
334 return error_mark_node;
337 if (lhs1
338 && lhs1 != orig_lhs
339 && TREE_CODE (lhs1) == COMPONENT_REF
340 && TREE_CODE (TREE_OPERAND (lhs1, 1)) == FIELD_DECL
341 && DECL_C_BIT_FIELD (TREE_OPERAND (lhs1, 1))
342 && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (lhs1, 1)))
344 tree field = TREE_OPERAND (lhs1, 1);
345 tree repr = DECL_BIT_FIELD_REPRESENTATIVE (field);
346 lhs1 = build3 (COMPONENT_REF, TREE_TYPE (repr), TREE_OPERAND (lhs1, 0),
347 repr, TREE_OPERAND (lhs1, 2));
349 if (rhs1
350 && rhs1 != orig_lhs
351 && TREE_CODE (rhs1) == COMPONENT_REF
352 && TREE_CODE (TREE_OPERAND (rhs1, 1)) == FIELD_DECL
353 && DECL_C_BIT_FIELD (TREE_OPERAND (rhs1, 1))
354 && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (rhs1, 1)))
356 tree field = TREE_OPERAND (rhs1, 1);
357 tree repr = DECL_BIT_FIELD_REPRESENTATIVE (field);
358 rhs1 = build3 (COMPONENT_REF, TREE_TYPE (repr), TREE_OPERAND (rhs1, 0),
359 repr, TREE_OPERAND (rhs1, 2));
362 if (code != OMP_ATOMIC)
364 /* Generally it is hard to prove lhs1 and lhs are the same memory
365 location, just diagnose different variables. */
366 if (lhs1 && VAR_P (lhs1) && VAR_P (orig_lhs))
368 if (lhs1 != orig_lhs && !test)
370 error_at (loc, "%<#pragma omp atomic capture%> uses two "
371 "different variables for memory");
372 return error_mark_node;
375 if (blhs)
376 x = build3_loc (loc, BIT_FIELD_REF, TREE_TYPE (blhs), x,
377 bitsize_int (bitsize), bitsize_int (bitpos));
378 x = build_modify_expr (loc, v, NULL_TREE, NOP_EXPR,
379 loc, x, NULL_TREE);
380 if (rhs1 && rhs1 != orig_lhs)
382 tree rhs1addr = build_unary_op (loc, ADDR_EXPR, rhs1, false);
383 if (rhs1addr == error_mark_node)
384 return error_mark_node;
385 x = omit_one_operand_loc (loc, type, x, rhs1addr);
387 if (lhs1 && lhs1 != orig_lhs)
389 tree lhs1addr = build_unary_op (loc, ADDR_EXPR, lhs1, false);
390 if (lhs1addr == error_mark_node)
391 return error_mark_node;
392 if (code == OMP_ATOMIC_CAPTURE_OLD)
393 x = omit_one_operand_loc (loc, type, x, lhs1addr);
394 else
396 if (!test)
397 x = save_expr (x);
398 x = omit_two_operands_loc (loc, type, x, x, lhs1addr);
402 else if (rhs1 && rhs1 != orig_lhs)
404 tree rhs1addr = build_unary_op (loc, ADDR_EXPR, rhs1, false);
405 if (rhs1addr == error_mark_node)
406 return error_mark_node;
407 x = omit_one_operand_loc (loc, type, x, rhs1addr);
410 if (pre)
411 x = omit_one_operand_loc (loc, type, x, pre);
412 return x;
416 /* Complete a #pragma omp flush construct. We don't do anything with
417 the variable list that the syntax allows. LOC is the location of
418 the #pragma. */
420 void
421 c_finish_omp_flush (location_t loc)
423 tree x;
425 x = builtin_decl_explicit (BUILT_IN_SYNC_SYNCHRONIZE);
426 x = build_call_expr_loc (loc, x, 0);
427 add_stmt (x);
431 /* Check and canonicalize OMP_FOR increment expression.
432 Helper function for c_finish_omp_for. */
434 static tree
435 check_omp_for_incr_expr (location_t loc, tree exp, tree decl)
437 tree t;
439 if (!INTEGRAL_TYPE_P (TREE_TYPE (exp))
440 || TYPE_PRECISION (TREE_TYPE (exp)) < TYPE_PRECISION (TREE_TYPE (decl)))
441 return error_mark_node;
443 if (exp == decl)
444 return build_int_cst (TREE_TYPE (exp), 0);
446 switch (TREE_CODE (exp))
448 CASE_CONVERT:
449 t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 0), decl);
450 if (t != error_mark_node)
451 return fold_convert_loc (loc, TREE_TYPE (exp), t);
452 break;
453 case MINUS_EXPR:
454 t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 0), decl);
455 if (t != error_mark_node)
456 return fold_build2_loc (loc, MINUS_EXPR,
457 TREE_TYPE (exp), t, TREE_OPERAND (exp, 1));
458 break;
459 case PLUS_EXPR:
460 t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 0), decl);
461 if (t != error_mark_node)
462 return fold_build2_loc (loc, PLUS_EXPR,
463 TREE_TYPE (exp), t, TREE_OPERAND (exp, 1));
464 t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 1), decl);
465 if (t != error_mark_node)
466 return fold_build2_loc (loc, PLUS_EXPR,
467 TREE_TYPE (exp), TREE_OPERAND (exp, 0), t);
468 break;
469 case COMPOUND_EXPR:
471 /* cp_build_modify_expr forces preevaluation of the RHS to make
472 sure that it is evaluated before the lvalue-rvalue conversion
473 is applied to the LHS. Reconstruct the original expression. */
474 tree op0 = TREE_OPERAND (exp, 0);
475 if (TREE_CODE (op0) == TARGET_EXPR
476 && !VOID_TYPE_P (TREE_TYPE (op0)))
478 tree op1 = TREE_OPERAND (exp, 1);
479 tree temp = TARGET_EXPR_SLOT (op0);
480 if (BINARY_CLASS_P (op1)
481 && TREE_OPERAND (op1, 1) == temp)
483 op1 = copy_node (op1);
484 TREE_OPERAND (op1, 1) = TARGET_EXPR_INITIAL (op0);
485 return check_omp_for_incr_expr (loc, op1, decl);
488 break;
490 default:
491 break;
494 return error_mark_node;
497 /* If the OMP_FOR increment expression in INCR is of pointer type,
498 canonicalize it into an expression handled by gimplify_omp_for()
499 and return it. DECL is the iteration variable. */
501 static tree
502 c_omp_for_incr_canonicalize_ptr (location_t loc, tree decl, tree incr)
504 if (POINTER_TYPE_P (TREE_TYPE (decl))
505 && TREE_OPERAND (incr, 1))
507 tree t = fold_convert_loc (loc,
508 sizetype, TREE_OPERAND (incr, 1));
510 if (TREE_CODE (incr) == POSTDECREMENT_EXPR
511 || TREE_CODE (incr) == PREDECREMENT_EXPR)
512 t = fold_build1_loc (loc, NEGATE_EXPR, sizetype, t);
513 t = fold_build_pointer_plus (decl, t);
514 incr = build2 (MODIFY_EXPR, void_type_node, decl, t);
516 return incr;
519 /* Validate and generate OMP_FOR.
520 DECLV is a vector of iteration variables, for each collapsed loop.
522 ORIG_DECLV, if non-NULL, is a vector with the original iteration
523 variables (prior to any transformations, by say, C++ iterators).
525 INITV, CONDV and INCRV are vectors containing initialization
526 expressions, controlling predicates and increment expressions.
527 BODY is the body of the loop and PRE_BODY statements that go before
528 the loop. */
530 tree
531 c_finish_omp_for (location_t locus, enum tree_code code, tree declv,
532 tree orig_declv, tree initv, tree condv, tree incrv,
533 tree body, tree pre_body)
535 location_t elocus;
536 bool fail = false;
537 int i;
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 cond_ok = false;
672 else if (operand_equal_p (TREE_OPERAND (cond, 1),
673 TYPE_MIN_VALUE (TREE_TYPE (decl)),
675 TREE_SET_CODE (cond, TREE_CODE (cond) == NE_EXPR
676 ? GT_EXPR : LE_EXPR);
677 else if (operand_equal_p (TREE_OPERAND (cond, 1),
678 TYPE_MAX_VALUE (TREE_TYPE (decl)),
680 TREE_SET_CODE (cond, TREE_CODE (cond) == NE_EXPR
681 ? LT_EXPR : GE_EXPR);
682 else
683 cond_ok = false;
686 if (cond_ok && TREE_VEC_ELT (condv, i) != cond)
688 tree ce = NULL_TREE, *pce = &ce;
689 tree type = TREE_TYPE (TREE_OPERAND (cond, 1));
690 for (tree c = TREE_VEC_ELT (condv, i); c != cond;
691 c = TREE_OPERAND (c, 1))
693 *pce = build2 (COMPOUND_EXPR, type, TREE_OPERAND (c, 0),
694 TREE_OPERAND (cond, 1));
695 pce = &TREE_OPERAND (*pce, 1);
697 TREE_OPERAND (cond, 1) = ce;
698 TREE_VEC_ELT (condv, i) = cond;
702 if (!cond_ok)
704 error_at (elocus, "invalid controlling predicate");
705 fail = true;
709 if (incr == NULL_TREE)
711 error_at (elocus, "missing increment expression");
712 fail = true;
714 else
716 bool incr_ok = false;
718 if (EXPR_HAS_LOCATION (incr))
719 elocus = EXPR_LOCATION (incr);
721 /* Check all the valid increment expressions: v++, v--, ++v, --v,
722 v = v + incr, v = incr + v and v = v - incr. */
723 switch (TREE_CODE (incr))
725 case POSTINCREMENT_EXPR:
726 case PREINCREMENT_EXPR:
727 case POSTDECREMENT_EXPR:
728 case PREDECREMENT_EXPR:
729 if (TREE_OPERAND (incr, 0) != decl)
730 break;
732 incr_ok = true;
733 incr = c_omp_for_incr_canonicalize_ptr (elocus, decl, incr);
734 break;
736 case COMPOUND_EXPR:
737 if (TREE_CODE (TREE_OPERAND (incr, 0)) != SAVE_EXPR
738 || TREE_CODE (TREE_OPERAND (incr, 1)) != MODIFY_EXPR)
739 break;
740 incr = TREE_OPERAND (incr, 1);
741 /* FALLTHRU */
742 case MODIFY_EXPR:
743 if (TREE_OPERAND (incr, 0) != decl)
744 break;
745 if (TREE_OPERAND (incr, 1) == decl)
746 break;
747 if (TREE_CODE (TREE_OPERAND (incr, 1)) == PLUS_EXPR
748 && (TREE_OPERAND (TREE_OPERAND (incr, 1), 0) == decl
749 || TREE_OPERAND (TREE_OPERAND (incr, 1), 1) == decl))
750 incr_ok = true;
751 else if ((TREE_CODE (TREE_OPERAND (incr, 1)) == MINUS_EXPR
752 || (TREE_CODE (TREE_OPERAND (incr, 1))
753 == POINTER_PLUS_EXPR))
754 && TREE_OPERAND (TREE_OPERAND (incr, 1), 0) == decl)
755 incr_ok = true;
756 else
758 tree t = check_omp_for_incr_expr (elocus,
759 TREE_OPERAND (incr, 1),
760 decl);
761 if (t != error_mark_node)
763 incr_ok = true;
764 t = build2 (PLUS_EXPR, TREE_TYPE (decl), decl, t);
765 incr = build2 (MODIFY_EXPR, void_type_node, decl, t);
768 break;
770 default:
771 break;
773 if (!incr_ok)
775 error_at (elocus, "invalid increment expression");
776 fail = true;
780 TREE_VEC_ELT (initv, i) = init;
781 TREE_VEC_ELT (incrv, i) = incr;
784 if (fail)
785 return NULL;
786 else
788 tree t = make_node (code);
790 TREE_TYPE (t) = void_type_node;
791 OMP_FOR_INIT (t) = initv;
792 OMP_FOR_COND (t) = condv;
793 OMP_FOR_INCR (t) = incrv;
794 OMP_FOR_BODY (t) = body;
795 OMP_FOR_PRE_BODY (t) = pre_body;
796 OMP_FOR_ORIG_DECLS (t) = orig_declv;
798 SET_EXPR_LOCATION (t, locus);
799 return t;
803 /* Type for passing data in between c_omp_check_loop_iv and
804 c_omp_check_loop_iv_r. */
806 struct c_omp_check_loop_iv_data
808 tree declv;
809 bool fail;
810 location_t stmt_loc;
811 location_t expr_loc;
812 int kind;
813 walk_tree_lh lh;
814 hash_set<tree> *ppset;
817 /* Helper function called via walk_tree, to diagnose uses
818 of associated loop IVs inside of lb, b and incr expressions
819 of OpenMP loops. */
821 static tree
822 c_omp_check_loop_iv_r (tree *tp, int *walk_subtrees, void *data)
824 struct c_omp_check_loop_iv_data *d
825 = (struct c_omp_check_loop_iv_data *) data;
826 if (DECL_P (*tp))
828 int i;
829 for (i = 0; i < TREE_VEC_LENGTH (d->declv); i++)
830 if (*tp == TREE_VEC_ELT (d->declv, i)
831 || (TREE_CODE (TREE_VEC_ELT (d->declv, i)) == TREE_LIST
832 && *tp == TREE_PURPOSE (TREE_VEC_ELT (d->declv, i))))
834 location_t loc = d->expr_loc;
835 if (loc == UNKNOWN_LOCATION)
836 loc = d->stmt_loc;
837 switch (d->kind)
839 case 0:
840 error_at (loc, "initializer expression refers to "
841 "iteration variable %qD", *tp);
842 break;
843 case 1:
844 error_at (loc, "condition expression refers to "
845 "iteration variable %qD", *tp);
846 break;
847 case 2:
848 error_at (loc, "increment expression refers to "
849 "iteration variable %qD", *tp);
850 break;
852 d->fail = true;
855 /* Don't walk dtors added by C++ wrap_cleanups_r. */
856 else if (TREE_CODE (*tp) == TRY_CATCH_EXPR
857 && TRY_CATCH_IS_CLEANUP (*tp))
859 *walk_subtrees = 0;
860 return walk_tree_1 (&TREE_OPERAND (*tp, 0), c_omp_check_loop_iv_r, data,
861 d->ppset, d->lh);
864 return NULL_TREE;
867 /* Diagnose invalid references to loop iterators in lb, b and incr
868 expressions. */
870 bool
871 c_omp_check_loop_iv (tree stmt, tree declv, walk_tree_lh lh)
873 hash_set<tree> pset;
874 struct c_omp_check_loop_iv_data data;
875 int i;
877 data.declv = declv;
878 data.fail = false;
879 data.stmt_loc = EXPR_LOCATION (stmt);
880 data.lh = lh;
881 data.ppset = &pset;
882 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (stmt)); i++)
884 tree init = TREE_VEC_ELT (OMP_FOR_INIT (stmt), i);
885 gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
886 tree decl = TREE_OPERAND (init, 0);
887 tree cond = TREE_VEC_ELT (OMP_FOR_COND (stmt), i);
888 gcc_assert (COMPARISON_CLASS_P (cond));
889 gcc_assert (TREE_OPERAND (cond, 0) == decl);
890 tree incr = TREE_VEC_ELT (OMP_FOR_INCR (stmt), i);
891 data.expr_loc = EXPR_LOCATION (TREE_OPERAND (init, 1));
892 data.kind = 0;
893 walk_tree_1 (&TREE_OPERAND (init, 1),
894 c_omp_check_loop_iv_r, &data, &pset, lh);
895 /* Don't warn for C++ random access iterators here, the
896 expression then involves the subtraction and always refers
897 to the original value. The C++ FE needs to warn on those
898 earlier. */
899 if (decl == TREE_VEC_ELT (declv, i)
900 || (TREE_CODE (TREE_VEC_ELT (declv, i)) == TREE_LIST
901 && decl == TREE_PURPOSE (TREE_VEC_ELT (declv, i))))
903 data.expr_loc = EXPR_LOCATION (cond);
904 data.kind = 1;
905 walk_tree_1 (&TREE_OPERAND (cond, 1),
906 c_omp_check_loop_iv_r, &data, &pset, lh);
908 if (TREE_CODE (incr) == MODIFY_EXPR)
910 gcc_assert (TREE_OPERAND (incr, 0) == decl);
911 incr = TREE_OPERAND (incr, 1);
912 data.kind = 2;
913 if (TREE_CODE (incr) == PLUS_EXPR
914 && TREE_OPERAND (incr, 1) == decl)
916 data.expr_loc = EXPR_LOCATION (TREE_OPERAND (incr, 0));
917 walk_tree_1 (&TREE_OPERAND (incr, 0),
918 c_omp_check_loop_iv_r, &data, &pset, lh);
920 else
922 data.expr_loc = EXPR_LOCATION (TREE_OPERAND (incr, 1));
923 walk_tree_1 (&TREE_OPERAND (incr, 1),
924 c_omp_check_loop_iv_r, &data, &pset, lh);
928 return !data.fail;
931 /* Similar, but allows to check the init or cond expressions individually. */
933 bool
934 c_omp_check_loop_iv_exprs (location_t stmt_loc, tree declv, tree decl,
935 tree init, tree cond, walk_tree_lh lh)
937 hash_set<tree> pset;
938 struct c_omp_check_loop_iv_data data;
940 data.declv = declv;
941 data.fail = false;
942 data.stmt_loc = stmt_loc;
943 data.lh = lh;
944 data.ppset = &pset;
945 if (init)
947 data.expr_loc = EXPR_LOCATION (init);
948 data.kind = 0;
949 walk_tree_1 (&init,
950 c_omp_check_loop_iv_r, &data, &pset, lh);
952 if (cond)
954 gcc_assert (COMPARISON_CLASS_P (cond));
955 data.expr_loc = EXPR_LOCATION (init);
956 data.kind = 1;
957 if (TREE_OPERAND (cond, 0) == decl)
958 walk_tree_1 (&TREE_OPERAND (cond, 1),
959 c_omp_check_loop_iv_r, &data, &pset, lh);
960 else
961 walk_tree_1 (&TREE_OPERAND (cond, 0),
962 c_omp_check_loop_iv_r, &data, &pset, lh);
964 return !data.fail;
967 /* This function splits clauses for OpenACC combined loop
968 constructs. OpenACC combined loop constructs are:
969 #pragma acc kernels loop
970 #pragma acc parallel loop */
972 tree
973 c_oacc_split_loop_clauses (tree clauses, tree *not_loop_clauses,
974 bool is_parallel)
976 tree next, loop_clauses, nc;
978 loop_clauses = *not_loop_clauses = NULL_TREE;
979 for (; clauses ; clauses = next)
981 next = OMP_CLAUSE_CHAIN (clauses);
983 switch (OMP_CLAUSE_CODE (clauses))
985 /* Loop clauses. */
986 case OMP_CLAUSE_COLLAPSE:
987 case OMP_CLAUSE_TILE:
988 case OMP_CLAUSE_GANG:
989 case OMP_CLAUSE_WORKER:
990 case OMP_CLAUSE_VECTOR:
991 case OMP_CLAUSE_AUTO:
992 case OMP_CLAUSE_SEQ:
993 case OMP_CLAUSE_INDEPENDENT:
994 case OMP_CLAUSE_PRIVATE:
995 OMP_CLAUSE_CHAIN (clauses) = loop_clauses;
996 loop_clauses = clauses;
997 break;
999 /* Reductions must be duplicated on both constructs. */
1000 case OMP_CLAUSE_REDUCTION:
1001 if (is_parallel)
1003 nc = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1004 OMP_CLAUSE_REDUCTION);
1005 OMP_CLAUSE_DECL (nc) = OMP_CLAUSE_DECL (clauses);
1006 OMP_CLAUSE_REDUCTION_CODE (nc)
1007 = OMP_CLAUSE_REDUCTION_CODE (clauses);
1008 OMP_CLAUSE_CHAIN (nc) = *not_loop_clauses;
1009 *not_loop_clauses = nc;
1012 OMP_CLAUSE_CHAIN (clauses) = loop_clauses;
1013 loop_clauses = clauses;
1014 break;
1016 /* Parallel/kernels clauses. */
1017 default:
1018 OMP_CLAUSE_CHAIN (clauses) = *not_loop_clauses;
1019 *not_loop_clauses = clauses;
1020 break;
1024 return loop_clauses;
1027 /* This function attempts to split or duplicate clauses for OpenMP
1028 combined/composite constructs. Right now there are 21 different
1029 constructs. CODE is the innermost construct in the combined construct,
1030 and MASK allows to determine which constructs are combined together,
1031 as every construct has at least one clause that no other construct
1032 has (except for OMP_SECTIONS, but that can be only combined with parallel).
1033 OpenMP combined/composite constructs are:
1034 #pragma omp distribute parallel for
1035 #pragma omp distribute parallel for simd
1036 #pragma omp distribute simd
1037 #pragma omp for simd
1038 #pragma omp parallel for
1039 #pragma omp parallel for simd
1040 #pragma omp parallel sections
1041 #pragma omp target parallel
1042 #pragma omp target parallel for
1043 #pragma omp target parallel for simd
1044 #pragma omp target teams
1045 #pragma omp target teams distribute
1046 #pragma omp target teams distribute parallel for
1047 #pragma omp target teams distribute parallel for simd
1048 #pragma omp target teams distribute simd
1049 #pragma omp target simd
1050 #pragma omp taskloop simd
1051 #pragma omp teams distribute
1052 #pragma omp teams distribute parallel for
1053 #pragma omp teams distribute parallel for simd
1054 #pragma omp teams distribute simd */
1056 void
1057 c_omp_split_clauses (location_t loc, enum tree_code code,
1058 omp_clause_mask mask, tree clauses, tree *cclauses)
1060 tree next, c;
1061 enum c_omp_clause_split s;
1062 int i;
1064 for (i = 0; i < C_OMP_CLAUSE_SPLIT_COUNT; i++)
1065 cclauses[i] = NULL;
1066 /* Add implicit nowait clause on
1067 #pragma omp parallel {for,for simd,sections}. */
1068 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
1069 switch (code)
1071 case OMP_FOR:
1072 case OMP_SIMD:
1073 cclauses[C_OMP_CLAUSE_SPLIT_FOR]
1074 = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
1075 break;
1076 case OMP_SECTIONS:
1077 cclauses[C_OMP_CLAUSE_SPLIT_SECTIONS]
1078 = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
1079 break;
1080 default:
1081 break;
1084 for (; clauses ; clauses = next)
1086 next = OMP_CLAUSE_CHAIN (clauses);
1088 switch (OMP_CLAUSE_CODE (clauses))
1090 /* First the clauses that are unique to some constructs. */
1091 case OMP_CLAUSE_DEVICE:
1092 case OMP_CLAUSE_MAP:
1093 case OMP_CLAUSE_IS_DEVICE_PTR:
1094 case OMP_CLAUSE_DEFAULTMAP:
1095 case OMP_CLAUSE_DEPEND:
1096 s = C_OMP_CLAUSE_SPLIT_TARGET;
1097 break;
1098 case OMP_CLAUSE_NUM_TEAMS:
1099 case OMP_CLAUSE_THREAD_LIMIT:
1100 s = C_OMP_CLAUSE_SPLIT_TEAMS;
1101 break;
1102 case OMP_CLAUSE_DIST_SCHEDULE:
1103 s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
1104 break;
1105 case OMP_CLAUSE_COPYIN:
1106 case OMP_CLAUSE_NUM_THREADS:
1107 case OMP_CLAUSE_PROC_BIND:
1108 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1109 break;
1110 case OMP_CLAUSE_ORDERED:
1111 s = C_OMP_CLAUSE_SPLIT_FOR;
1112 break;
1113 case OMP_CLAUSE_SCHEDULE:
1114 s = C_OMP_CLAUSE_SPLIT_FOR;
1115 if (code != OMP_SIMD)
1116 OMP_CLAUSE_SCHEDULE_SIMD (clauses) = 0;
1117 break;
1118 case OMP_CLAUSE_SAFELEN:
1119 case OMP_CLAUSE_SIMDLEN:
1120 case OMP_CLAUSE_ALIGNED:
1121 s = C_OMP_CLAUSE_SPLIT_SIMD;
1122 break;
1123 case OMP_CLAUSE_GRAINSIZE:
1124 case OMP_CLAUSE_NUM_TASKS:
1125 case OMP_CLAUSE_FINAL:
1126 case OMP_CLAUSE_UNTIED:
1127 case OMP_CLAUSE_MERGEABLE:
1128 case OMP_CLAUSE_NOGROUP:
1129 case OMP_CLAUSE_PRIORITY:
1130 s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
1131 break;
1132 /* Duplicate this to all of taskloop, distribute, for and simd. */
1133 case OMP_CLAUSE_COLLAPSE:
1134 if (code == OMP_SIMD)
1136 if ((mask & ((OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)
1137 | (OMP_CLAUSE_MASK_1
1138 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)
1139 | (OMP_CLAUSE_MASK_1
1140 << PRAGMA_OMP_CLAUSE_NOGROUP))) != 0)
1142 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1143 OMP_CLAUSE_COLLAPSE);
1144 OMP_CLAUSE_COLLAPSE_EXPR (c)
1145 = OMP_CLAUSE_COLLAPSE_EXPR (clauses);
1146 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
1147 cclauses[C_OMP_CLAUSE_SPLIT_SIMD] = c;
1149 else
1151 /* This must be #pragma omp target simd */
1152 s = C_OMP_CLAUSE_SPLIT_SIMD;
1153 break;
1156 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)) != 0)
1158 if ((mask & (OMP_CLAUSE_MASK_1
1159 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
1161 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1162 OMP_CLAUSE_COLLAPSE);
1163 OMP_CLAUSE_COLLAPSE_EXPR (c)
1164 = OMP_CLAUSE_COLLAPSE_EXPR (clauses);
1165 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
1166 cclauses[C_OMP_CLAUSE_SPLIT_FOR] = c;
1167 s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
1169 else
1170 s = C_OMP_CLAUSE_SPLIT_FOR;
1172 else if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP))
1173 != 0)
1174 s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
1175 else
1176 s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
1177 break;
1178 /* Private clause is supported on all constructs,
1179 it is enough to put it on the innermost one. For
1180 #pragma omp {for,sections} put it on parallel though,
1181 as that's what we did for OpenMP 3.1. */
1182 case OMP_CLAUSE_PRIVATE:
1183 switch (code)
1185 case OMP_SIMD: s = C_OMP_CLAUSE_SPLIT_SIMD; break;
1186 case OMP_FOR: case OMP_SECTIONS:
1187 case OMP_PARALLEL: s = C_OMP_CLAUSE_SPLIT_PARALLEL; break;
1188 case OMP_DISTRIBUTE: s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE; break;
1189 case OMP_TEAMS: s = C_OMP_CLAUSE_SPLIT_TEAMS; break;
1190 default: gcc_unreachable ();
1192 break;
1193 /* Firstprivate clause is supported on all constructs but
1194 simd. Put it on the outermost of those and duplicate on teams
1195 and parallel. */
1196 case OMP_CLAUSE_FIRSTPRIVATE:
1197 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP))
1198 != 0)
1200 if (code == OMP_SIMD
1201 && (mask & ((OMP_CLAUSE_MASK_1
1202 << PRAGMA_OMP_CLAUSE_NUM_THREADS)
1203 | (OMP_CLAUSE_MASK_1
1204 << PRAGMA_OMP_CLAUSE_NUM_TEAMS))) == 0)
1206 /* This must be #pragma omp target simd. */
1207 s = C_OMP_CLAUSE_SPLIT_TARGET;
1208 break;
1210 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1211 OMP_CLAUSE_FIRSTPRIVATE);
1212 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
1213 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
1214 cclauses[C_OMP_CLAUSE_SPLIT_TARGET] = c;
1216 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS))
1217 != 0)
1219 if ((mask & ((OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS)
1220 | (OMP_CLAUSE_MASK_1
1221 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE))) != 0)
1223 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1224 OMP_CLAUSE_FIRSTPRIVATE);
1225 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
1226 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL];
1227 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] = c;
1228 if ((mask & (OMP_CLAUSE_MASK_1
1229 << PRAGMA_OMP_CLAUSE_NUM_TEAMS)) != 0)
1230 s = C_OMP_CLAUSE_SPLIT_TEAMS;
1231 else
1232 s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
1234 else
1235 /* This must be
1236 #pragma omp parallel{, for{, simd}, sections}
1238 #pragma omp target parallel. */
1239 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1241 else if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS))
1242 != 0)
1244 /* This must be one of
1245 #pragma omp {,target }teams distribute
1246 #pragma omp target teams
1247 #pragma omp {,target }teams distribute simd. */
1248 gcc_assert (code == OMP_DISTRIBUTE
1249 || code == OMP_TEAMS
1250 || code == OMP_SIMD);
1251 s = C_OMP_CLAUSE_SPLIT_TEAMS;
1253 else if ((mask & (OMP_CLAUSE_MASK_1
1254 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
1256 /* This must be #pragma omp distribute simd. */
1257 gcc_assert (code == OMP_SIMD);
1258 s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
1260 else if ((mask & (OMP_CLAUSE_MASK_1
1261 << PRAGMA_OMP_CLAUSE_NOGROUP)) != 0)
1263 /* This must be #pragma omp taskloop simd. */
1264 gcc_assert (code == OMP_SIMD);
1265 s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
1267 else
1269 /* This must be #pragma omp for simd. */
1270 gcc_assert (code == OMP_SIMD);
1271 s = C_OMP_CLAUSE_SPLIT_FOR;
1273 break;
1274 /* Lastprivate is allowed on distribute, for, sections and simd. In
1275 parallel {for{, simd},sections} we actually want to put it on
1276 parallel rather than for or sections. */
1277 case OMP_CLAUSE_LASTPRIVATE:
1278 if (code == OMP_DISTRIBUTE)
1280 s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
1281 break;
1283 if ((mask & (OMP_CLAUSE_MASK_1
1284 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
1286 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1287 OMP_CLAUSE_LASTPRIVATE);
1288 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
1289 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
1290 cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE] = c;
1292 if (code == OMP_FOR || code == OMP_SECTIONS)
1294 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS))
1295 != 0)
1296 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1297 else
1298 s = C_OMP_CLAUSE_SPLIT_FOR;
1299 break;
1301 gcc_assert (code == OMP_SIMD);
1302 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)) != 0)
1304 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1305 OMP_CLAUSE_LASTPRIVATE);
1306 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
1307 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS))
1308 != 0)
1309 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1310 else
1311 s = C_OMP_CLAUSE_SPLIT_FOR;
1312 OMP_CLAUSE_CHAIN (c) = cclauses[s];
1313 cclauses[s] = c;
1315 s = C_OMP_CLAUSE_SPLIT_SIMD;
1316 break;
1317 /* Shared and default clauses are allowed on parallel, teams and
1318 taskloop. */
1319 case OMP_CLAUSE_SHARED:
1320 case OMP_CLAUSE_DEFAULT:
1321 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP))
1322 != 0)
1324 s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
1325 break;
1327 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS))
1328 != 0)
1330 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS))
1331 == 0)
1333 s = C_OMP_CLAUSE_SPLIT_TEAMS;
1334 break;
1336 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1337 OMP_CLAUSE_CODE (clauses));
1338 if (OMP_CLAUSE_CODE (clauses) == OMP_CLAUSE_SHARED)
1339 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
1340 else
1341 OMP_CLAUSE_DEFAULT_KIND (c)
1342 = OMP_CLAUSE_DEFAULT_KIND (clauses);
1343 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
1344 cclauses[C_OMP_CLAUSE_SPLIT_TEAMS] = c;
1346 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1347 break;
1348 /* Reduction is allowed on simd, for, parallel, sections and teams.
1349 Duplicate it on all of them, but omit on for or sections if
1350 parallel is present. */
1351 case OMP_CLAUSE_REDUCTION:
1352 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)) != 0)
1354 if (code == OMP_SIMD)
1356 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1357 OMP_CLAUSE_REDUCTION);
1358 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
1359 OMP_CLAUSE_REDUCTION_CODE (c)
1360 = OMP_CLAUSE_REDUCTION_CODE (clauses);
1361 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
1362 = OMP_CLAUSE_REDUCTION_PLACEHOLDER (clauses);
1363 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c)
1364 = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (clauses);
1365 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
1366 cclauses[C_OMP_CLAUSE_SPLIT_SIMD] = c;
1368 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS))
1369 != 0)
1371 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1372 OMP_CLAUSE_REDUCTION);
1373 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
1374 OMP_CLAUSE_REDUCTION_CODE (c)
1375 = OMP_CLAUSE_REDUCTION_CODE (clauses);
1376 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
1377 = OMP_CLAUSE_REDUCTION_PLACEHOLDER (clauses);
1378 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c)
1379 = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (clauses);
1380 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL];
1381 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] = c;
1382 s = C_OMP_CLAUSE_SPLIT_TEAMS;
1384 else if ((mask & (OMP_CLAUSE_MASK_1
1385 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
1386 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1387 else
1388 s = C_OMP_CLAUSE_SPLIT_FOR;
1390 else if (code == OMP_SECTIONS || code == OMP_PARALLEL)
1391 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1392 else if (code == OMP_SIMD)
1393 s = C_OMP_CLAUSE_SPLIT_SIMD;
1394 else
1395 s = C_OMP_CLAUSE_SPLIT_TEAMS;
1396 break;
1397 case OMP_CLAUSE_IF:
1398 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP))
1399 != 0)
1400 s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
1401 else if ((mask & (OMP_CLAUSE_MASK_1
1402 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
1404 if ((mask & (OMP_CLAUSE_MASK_1
1405 << PRAGMA_OMP_CLAUSE_MAP)) != 0)
1407 if (OMP_CLAUSE_IF_MODIFIER (clauses) == OMP_PARALLEL)
1408 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1409 else if (OMP_CLAUSE_IF_MODIFIER (clauses) == OMP_TARGET)
1410 s = C_OMP_CLAUSE_SPLIT_TARGET;
1411 else if (OMP_CLAUSE_IF_MODIFIER (clauses) == ERROR_MARK)
1413 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1414 OMP_CLAUSE_IF);
1415 OMP_CLAUSE_IF_MODIFIER (c)
1416 = OMP_CLAUSE_IF_MODIFIER (clauses);
1417 OMP_CLAUSE_IF_EXPR (c) = OMP_CLAUSE_IF_EXPR (clauses);
1418 OMP_CLAUSE_CHAIN (c)
1419 = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
1420 cclauses[C_OMP_CLAUSE_SPLIT_TARGET] = c;
1421 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1423 else
1425 error_at (OMP_CLAUSE_LOCATION (clauses),
1426 "expected %<parallel%> or %<target%> %<if%> "
1427 "clause modifier");
1428 continue;
1431 else
1432 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1434 else
1435 s = C_OMP_CLAUSE_SPLIT_TARGET;
1436 break;
1437 case OMP_CLAUSE_LINEAR:
1438 /* Linear clause is allowed on simd and for. Put it on the
1439 innermost construct. */
1440 if (code == OMP_SIMD)
1441 s = C_OMP_CLAUSE_SPLIT_SIMD;
1442 else
1443 s = C_OMP_CLAUSE_SPLIT_FOR;
1444 break;
1445 case OMP_CLAUSE_NOWAIT:
1446 /* Nowait clause is allowed on target, for and sections, but
1447 is not allowed on parallel for or parallel sections. Therefore,
1448 put it on target construct if present, because that can only
1449 be combined with parallel for{, simd} and not with for{, simd},
1450 otherwise to the worksharing construct. */
1451 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP))
1452 != 0)
1453 s = C_OMP_CLAUSE_SPLIT_TARGET;
1454 else
1455 s = C_OMP_CLAUSE_SPLIT_FOR;
1456 break;
1457 default:
1458 gcc_unreachable ();
1460 OMP_CLAUSE_CHAIN (clauses) = cclauses[s];
1461 cclauses[s] = clauses;
1464 if (!flag_checking)
1465 return;
1467 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) == 0)
1468 gcc_assert (cclauses[C_OMP_CLAUSE_SPLIT_TARGET] == NULL_TREE);
1469 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS)) == 0)
1470 gcc_assert (cclauses[C_OMP_CLAUSE_SPLIT_TEAMS] == NULL_TREE);
1471 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) == 0)
1472 gcc_assert (cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE] == NULL_TREE);
1473 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) == 0)
1474 gcc_assert (cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] == NULL_TREE);
1475 if ((mask & ((OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)
1476 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP))) == 0
1477 && code != OMP_SECTIONS)
1478 gcc_assert (cclauses[C_OMP_CLAUSE_SPLIT_FOR] == NULL_TREE);
1479 if (code != OMP_SIMD)
1480 gcc_assert (cclauses[C_OMP_CLAUSE_SPLIT_SIMD] == NULL_TREE);
1484 /* qsort callback to compare #pragma omp declare simd clauses. */
1486 static int
1487 c_omp_declare_simd_clause_cmp (const void *p, const void *q)
1489 tree a = *(const tree *) p;
1490 tree b = *(const tree *) q;
1491 if (OMP_CLAUSE_CODE (a) != OMP_CLAUSE_CODE (b))
1493 if (OMP_CLAUSE_CODE (a) > OMP_CLAUSE_CODE (b))
1494 return -1;
1495 return 1;
1497 if (OMP_CLAUSE_CODE (a) != OMP_CLAUSE_SIMDLEN
1498 && OMP_CLAUSE_CODE (a) != OMP_CLAUSE_INBRANCH
1499 && OMP_CLAUSE_CODE (a) != OMP_CLAUSE_NOTINBRANCH)
1501 int c = tree_to_shwi (OMP_CLAUSE_DECL (a));
1502 int d = tree_to_shwi (OMP_CLAUSE_DECL (b));
1503 if (c < d)
1504 return 1;
1505 if (c > d)
1506 return -1;
1508 return 0;
1511 /* Change PARM_DECLs in OMP_CLAUSE_DECL of #pragma omp declare simd
1512 CLAUSES on FNDECL into argument indexes and sort them. */
1514 tree
1515 c_omp_declare_simd_clauses_to_numbers (tree parms, tree clauses)
1517 tree c;
1518 vec<tree> clvec = vNULL;
1520 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
1522 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_SIMDLEN
1523 && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_INBRANCH
1524 && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_NOTINBRANCH)
1526 tree decl = OMP_CLAUSE_DECL (c);
1527 tree arg;
1528 int idx;
1529 for (arg = parms, idx = 0; arg;
1530 arg = TREE_CHAIN (arg), idx++)
1531 if (arg == decl)
1532 break;
1533 if (arg == NULL_TREE)
1535 error_at (OMP_CLAUSE_LOCATION (c),
1536 "%qD is not an function argument", decl);
1537 continue;
1539 OMP_CLAUSE_DECL (c) = build_int_cst (integer_type_node, idx);
1540 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
1541 && OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (c))
1543 decl = OMP_CLAUSE_LINEAR_STEP (c);
1544 for (arg = parms, idx = 0; arg;
1545 arg = TREE_CHAIN (arg), idx++)
1546 if (arg == decl)
1547 break;
1548 if (arg == NULL_TREE)
1550 error_at (OMP_CLAUSE_LOCATION (c),
1551 "%qD is not an function argument", decl);
1552 continue;
1554 OMP_CLAUSE_LINEAR_STEP (c)
1555 = build_int_cst (integer_type_node, idx);
1558 clvec.safe_push (c);
1560 if (!clvec.is_empty ())
1562 unsigned int len = clvec.length (), i;
1563 clvec.qsort (c_omp_declare_simd_clause_cmp);
1564 clauses = clvec[0];
1565 for (i = 0; i < len; i++)
1566 OMP_CLAUSE_CHAIN (clvec[i]) = (i < len - 1) ? clvec[i + 1] : NULL_TREE;
1568 else
1569 clauses = NULL_TREE;
1570 clvec.release ();
1571 return clauses;
1574 /* Change argument indexes in CLAUSES of FNDECL back to PARM_DECLs. */
1576 void
1577 c_omp_declare_simd_clauses_to_decls (tree fndecl, tree clauses)
1579 tree c;
1581 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
1582 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_SIMDLEN
1583 && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_INBRANCH
1584 && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_NOTINBRANCH)
1586 int idx = tree_to_shwi (OMP_CLAUSE_DECL (c)), i;
1587 tree arg;
1588 for (arg = DECL_ARGUMENTS (fndecl), i = 0; arg;
1589 arg = TREE_CHAIN (arg), i++)
1590 if (i == idx)
1591 break;
1592 gcc_assert (arg);
1593 OMP_CLAUSE_DECL (c) = arg;
1594 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
1595 && OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (c))
1597 idx = tree_to_shwi (OMP_CLAUSE_LINEAR_STEP (c));
1598 for (arg = DECL_ARGUMENTS (fndecl), i = 0; arg;
1599 arg = TREE_CHAIN (arg), i++)
1600 if (i == idx)
1601 break;
1602 gcc_assert (arg);
1603 OMP_CLAUSE_LINEAR_STEP (c) = arg;
1608 /* True if OpenMP sharing attribute of DECL is predetermined. */
1610 enum omp_clause_default_kind
1611 c_omp_predetermined_sharing (tree decl)
1613 /* Variables with const-qualified type having no mutable member
1614 are predetermined shared. */
1615 if (TREE_READONLY (decl))
1616 return OMP_CLAUSE_DEFAULT_SHARED;
1618 /* Predetermine artificial variables holding integral values, those
1619 are usually result of gimplify_one_sizepos or SAVE_EXPR
1620 gimplification. */
1621 if (VAR_P (decl)
1622 && DECL_ARTIFICIAL (decl)
1623 && INTEGRAL_TYPE_P (TREE_TYPE (decl)))
1624 return OMP_CLAUSE_DEFAULT_SHARED;
1626 return OMP_CLAUSE_DEFAULT_UNSPECIFIED;