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
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
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/>. */
26 #include "coretypes.h"
29 #include "gimple-expr.h"
32 #include "gomp-constants.h"
35 /* Complete a #pragma oacc wait construct. LOC is the location of
39 c_finish_oacc_wait (location_t loc
, tree parms
, tree clauses
)
41 const int nparms
= list_length (parms
);
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
);
51 t
= build_int_cst (integer_type_node
, GOMP_ASYNC_SYNC
);
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
))));
62 args
->quick_push (OMP_CLAUSE_WAIT_EXPR (t
));
65 stmt
= build_call_expr_loc_vec (loc
, stmt
, args
);
72 /* Complete a #pragma omp master construct. STMT is the structured-block
73 that follows the pragma. LOC is the l*/
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
);
83 /* Complete a #pragma omp taskgroup construct. STMT is the structured-block
84 that follows the pragma. LOC is the l*/
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
);
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. */
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. */
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
);
125 /* Complete a #pragma omp barrier construct. LOC is the location of
129 c_finish_omp_barrier (location_t loc
)
133 x
= builtin_decl_explicit (BUILT_IN_GOMP_BARRIER
);
134 x
= build_call_expr_loc (loc
, x
, 0);
139 /* Complete a #pragma omp taskwait construct. LOC is the location of the
143 c_finish_omp_taskwait (location_t loc
)
147 x
= builtin_decl_explicit (BUILT_IN_GOMP_TASKWAIT
);
148 x
= build_call_expr_loc (loc
, x
, 0);
153 /* Complete a #pragma omp taskyield construct. LOC is the location of the
157 c_finish_omp_taskyield (location_t loc
)
161 x
= builtin_decl_explicit (BUILT_IN_GOMP_TASKYIELD
);
162 x
= build_call_expr_loc (loc
, x
, 0);
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*. */
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
,
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
210 addr
= build_unary_op (loc
, ADDR_EXPR
, lhs
, 0);
211 if (addr
== error_mark_node
)
212 return error_mark_node
;
214 addr
= save_expr (addr
);
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
,
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. */
242 rhs
= build_binary_op (loc
, opcode
, rhs
, lhs
, 1);
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. */
275 if (code
== OMP_ATOMIC
)
276 error_at (loc
, "%<#pragma omp atomic update%> uses two different "
277 "variables for memory");
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
,
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
);
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
);
330 x
= omit_one_operand_loc (loc
, type
, x
, pre
);
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
340 c_finish_omp_flush (location_t loc
)
344 x
= builtin_decl_explicit (BUILT_IN_SYNC_SYNCHRONIZE
);
345 x
= build_call_expr_loc (loc
, x
, 0);
350 /* Check and canonicalize OMP_FOR increment expression.
351 Helper function for c_finish_omp_for. */
354 check_omp_for_incr_expr (location_t loc
, tree exp
, tree decl
)
358 if (!INTEGRAL_TYPE_P (TREE_TYPE (exp
))
359 || TYPE_PRECISION (TREE_TYPE (exp
)) < TYPE_PRECISION (TREE_TYPE (decl
)))
360 return error_mark_node
;
363 return build_int_cst (TREE_TYPE (exp
), 0);
365 switch (TREE_CODE (exp
))
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
);
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));
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
);
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
);
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. */
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
);
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
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
)
458 if ((code
== CILK_SIMD
|| code
== CILK_FOR
)
459 && !c_check_cilk_loop (locus
, TREE_VEC_ELT (declv
, 0)))
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
);
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
);
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. */
488 elocus
= DECL_SOURCE_LOCATION (decl
);
490 init
= DECL_INITIAL (decl
);
493 error_at (elocus
, "%qE is not initialized", decl
);
494 init
= integer_zero_node
;
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. */
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");
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.
541 according to ISO will be evaluated as:
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))
565 else if (decl
== TREE_OPERAND (cond
, 1))
568 swap_tree_comparison (TREE_CODE (cond
)));
569 TREE_OPERAND (cond
, 1) = TREE_OPERAND (cond
, 0);
570 TREE_OPERAND (cond
, 0) = decl
;
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
)
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
)
599 error_at (elocus
, "invalid controlling predicate");
604 if (incr
== NULL_TREE
)
606 error_at (elocus
, "missing increment expression");
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
)
628 incr
= c_omp_for_incr_canonicalize_ptr (elocus
, decl
, incr
);
632 if (TREE_CODE (TREE_OPERAND (incr
, 0)) != SAVE_EXPR
633 || TREE_CODE (TREE_OPERAND (incr
, 1)) != MODIFY_EXPR
)
635 incr
= TREE_OPERAND (incr
, 1);
638 if (TREE_OPERAND (incr
, 0) != decl
)
640 if (TREE_OPERAND (incr
, 1) == decl
)
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
))
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
)
653 tree t
= check_omp_for_incr_expr (elocus
,
654 TREE_OPERAND (incr
, 1),
656 if (t
!= error_mark_node
)
659 t
= build2 (PLUS_EXPR
, TREE_TYPE (decl
), decl
, t
);
660 incr
= build2 (MODIFY_EXPR
, void_type_node
, decl
, t
);
670 error_at (elocus
, "invalid increment expression");
675 TREE_VEC_ELT (initv
, i
) = init
;
676 TREE_VEC_ELT (incrv
, i
) = incr
;
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
);
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
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
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
;
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
)
733 error_at (loc
, "initializer expression refers to "
734 "iteration variable %qD", *tp
);
737 error_at (loc
, "condition expression refers to "
738 "iteration variable %qD", *tp
);
741 error_at (loc
, "increment expression refers to "
742 "iteration variable %qD", *tp
);
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
))
753 return walk_tree_1 (&TREE_OPERAND (*tp
, 0), c_omp_check_loop_iv_r
, data
,
760 /* Diagnose invalid references to loop iterators in lb, b and incr
764 c_omp_check_loop_iv (tree stmt
, tree declv
, walk_tree_lh lh
)
767 struct c_omp_check_loop_iv_data data
;
772 data
.stmt_loc
= EXPR_LOCATION (stmt
);
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));
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
792 if (decl
== TREE_VEC_ELT (declv
, i
))
794 data
.expr_loc
= EXPR_LOCATION (cond
);
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);
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
);
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
);
822 /* Similar, but allows to check the init or cond expressions individually. */
825 c_omp_check_loop_iv_exprs (location_t stmt_loc
, tree declv
, tree decl
,
826 tree init
, tree cond
, walk_tree_lh lh
)
829 struct c_omp_check_loop_iv_data data
;
833 data
.stmt_loc
= stmt_loc
;
838 data
.expr_loc
= EXPR_LOCATION (init
);
841 c_omp_check_loop_iv_r
, &data
, &pset
, lh
);
845 gcc_assert (COMPARISON_CLASS_P (cond
));
846 data
.expr_loc
= EXPR_LOCATION (init
);
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
);
852 walk_tree_1 (&TREE_OPERAND (cond
, 0),
853 c_omp_check_loop_iv_r
, &data
, &pset
, lh
);
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 */
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
))
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
:
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
;
890 /* Parallel/kernels clauses. */
892 OMP_CLAUSE_CHAIN (clauses
) = *not_loop_clauses
;
893 *not_loop_clauses
= 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
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 */
931 c_omp_split_clauses (location_t loc
, enum tree_code code
,
932 omp_clause_mask mask
, tree clauses
, tree
*cclauses
)
935 enum c_omp_clause_split s
;
938 for (i
= 0; i
< C_OMP_CLAUSE_SPLIT_COUNT
; i
++)
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)
947 cclauses
[C_OMP_CLAUSE_SPLIT_FOR
]
948 = build_omp_clause (loc
, OMP_CLAUSE_NOWAIT
);
951 cclauses
[C_OMP_CLAUSE_SPLIT_SECTIONS
]
952 = build_omp_clause (loc
, OMP_CLAUSE_NOWAIT
);
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
:
967 case OMP_CLAUSE_IS_DEVICE_PTR
:
968 case OMP_CLAUSE_DEFAULTMAP
:
969 s
= C_OMP_CLAUSE_SPLIT_TARGET
;
971 case OMP_CLAUSE_NUM_TEAMS
:
972 case OMP_CLAUSE_THREAD_LIMIT
:
973 s
= C_OMP_CLAUSE_SPLIT_TEAMS
;
975 case OMP_CLAUSE_DIST_SCHEDULE
:
976 s
= C_OMP_CLAUSE_SPLIT_DISTRIBUTE
;
978 case OMP_CLAUSE_COPYIN
:
979 case OMP_CLAUSE_NUM_THREADS
:
980 case OMP_CLAUSE_PROC_BIND
:
981 s
= C_OMP_CLAUSE_SPLIT_PARALLEL
;
983 case OMP_CLAUSE_ORDERED
:
984 case OMP_CLAUSE_NOWAIT
:
985 s
= C_OMP_CLAUSE_SPLIT_FOR
;
987 case OMP_CLAUSE_SCHEDULE
:
988 s
= C_OMP_CLAUSE_SPLIT_FOR
;
989 if (code
!= OMP_SIMD
)
990 OMP_CLAUSE_SCHEDULE_SIMD (clauses
) = 0;
992 case OMP_CLAUSE_SAFELEN
:
993 case OMP_CLAUSE_SIMDLEN
:
994 case OMP_CLAUSE_ALIGNED
:
995 s
= C_OMP_CLAUSE_SPLIT_SIMD
;
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
;
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
;
1025 /* This must be #pragma omp target simd */
1026 s
= C_OMP_CLAUSE_SPLIT_SIMD
;
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
;
1044 s
= C_OMP_CLAUSE_SPLIT_FOR
;
1046 else if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_NOGROUP
))
1048 s
= C_OMP_CLAUSE_SPLIT_TASKLOOP
;
1050 s
= C_OMP_CLAUSE_SPLIT_DISTRIBUTE
;
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
:
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 ();
1067 /* Firstprivate clause is supported on all constructs but
1068 simd. Put it on the outermost of those and duplicate on teams
1070 case OMP_CLAUSE_FIRSTPRIVATE
:
1071 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_MAP
))
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
;
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
))
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
;
1106 s
= C_OMP_CLAUSE_SPLIT_DISTRIBUTE
;
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
))
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
;
1143 /* This must be #pragma omp for simd. */
1144 gcc_assert (code
== OMP_SIMD
);
1145 s
= C_OMP_CLAUSE_SPLIT_FOR
;
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
;
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
))
1170 s
= C_OMP_CLAUSE_SPLIT_PARALLEL
;
1172 s
= C_OMP_CLAUSE_SPLIT_FOR
;
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
))
1183 s
= C_OMP_CLAUSE_SPLIT_PARALLEL
;
1185 s
= C_OMP_CLAUSE_SPLIT_FOR
;
1186 OMP_CLAUSE_CHAIN (c
) = cclauses
[s
];
1189 s
= C_OMP_CLAUSE_SPLIT_SIMD
;
1191 /* Shared and default clauses are allowed on parallel, teams and
1193 case OMP_CLAUSE_SHARED
:
1194 case OMP_CLAUSE_DEFAULT
:
1195 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_NOGROUP
))
1198 s
= C_OMP_CLAUSE_SPLIT_TASKLOOP
;
1201 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_NUM_TEAMS
))
1204 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_NUM_THREADS
))
1207 s
= C_OMP_CLAUSE_SPLIT_TEAMS
;
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
);
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
;
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
))
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
;
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
;
1269 s
= C_OMP_CLAUSE_SPLIT_TEAMS
;
1272 if ((mask
& (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_NOGROUP
))
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
),
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
;
1299 error_at (OMP_CLAUSE_LOCATION (clauses
),
1300 "expected %<parallel%> or %<target%> %<if%> "
1306 s
= C_OMP_CLAUSE_SPLIT_PARALLEL
;
1309 s
= C_OMP_CLAUSE_SPLIT_TARGET
;
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
;
1317 s
= C_OMP_CLAUSE_SPLIT_FOR
;
1322 OMP_CLAUSE_CHAIN (clauses
) = cclauses
[s
];
1323 cclauses
[s
] = clauses
;
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. */
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
))
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
));
1373 /* Change PARM_DECLs in OMP_CLAUSE_DECL of #pragma omp declare simd
1374 CLAUSES on FNDECL into argument indexes and sort them. */
1377 c_omp_declare_simd_clauses_to_numbers (tree parms
, tree clauses
)
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
);
1391 for (arg
= parms
, idx
= 0; arg
;
1392 arg
= TREE_CHAIN (arg
), idx
++)
1395 if (arg
== NULL_TREE
)
1397 error_at (OMP_CLAUSE_LOCATION (c
),
1398 "%qD is not an function argument", decl
);
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
++)
1410 if (arg
== NULL_TREE
)
1412 error_at (OMP_CLAUSE_LOCATION (c
),
1413 "%qD is not an function argument", decl
);
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
);
1427 for (i
= 0; i
< len
; i
++)
1428 OMP_CLAUSE_CHAIN (clvec
[i
]) = (i
< len
- 1) ? clvec
[i
+ 1] : NULL_TREE
;
1431 clauses
= NULL_TREE
;
1436 /* Change argument indexes in CLAUSES of FNDECL back to PARM_DECLs. */
1439 c_omp_declare_simd_clauses_to_decls (tree fndecl
, tree clauses
)
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
;
1450 for (arg
= DECL_ARGUMENTS (fndecl
), i
= 0; arg
;
1451 arg
= TREE_CHAIN (arg
), i
++)
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
++)
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
;