xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/c-family/c-omp.c (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
1 /* This file contains routines to construct OpenACC and OpenMP constructs,
2    called from parsing in the C and C++ front ends.
3 
4    Copyright (C) 2005-2020 Free Software Foundation, Inc.
5    Contributed by Richard Henderson <rth@redhat.com>,
6 		  Diego Novillo <dnovillo@redhat.com>.
7 
8 This file is part of GCC.
9 
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.
14 
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.
19 
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/>.  */
23 
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 "stringpool.h"
32 #include "omp-general.h"
33 #include "gomp-constants.h"
34 #include "memmodel.h"
35 #include "attribs.h"
36 #include "gimplify.h"
37 
38 
39 /* Complete a #pragma oacc wait construct.  LOC is the location of
40    the #pragma.  */
41 
42 tree
c_finish_oacc_wait(location_t loc,tree parms,tree clauses)43 c_finish_oacc_wait (location_t loc, tree parms, tree clauses)
44 {
45   const int nparms = list_length (parms);
46   tree stmt, t;
47   vec<tree, va_gc> *args;
48 
49   vec_alloc (args, nparms + 2);
50   stmt = builtin_decl_explicit (BUILT_IN_GOACC_WAIT);
51 
52   if (omp_find_clause (clauses, OMP_CLAUSE_ASYNC))
53     t = OMP_CLAUSE_ASYNC_EXPR (clauses);
54   else
55     t = build_int_cst (integer_type_node, GOMP_ASYNC_SYNC);
56 
57   args->quick_push (t);
58   args->quick_push (build_int_cst (integer_type_node, nparms));
59 
60   for (t = parms; t; t = TREE_CHAIN (t))
61     {
62       if (TREE_CODE (OMP_CLAUSE_WAIT_EXPR (t)) == INTEGER_CST)
63 	args->quick_push (build_int_cst (integer_type_node,
64 			TREE_INT_CST_LOW (OMP_CLAUSE_WAIT_EXPR (t))));
65       else
66 	args->quick_push (OMP_CLAUSE_WAIT_EXPR (t));
67     }
68 
69   stmt = build_call_expr_loc_vec (loc, stmt, args);
70 
71   vec_free (args);
72 
73   return stmt;
74 }
75 
76 /* Complete a #pragma omp master construct.  STMT is the structured-block
77    that follows the pragma.  LOC is the location of the #pragma.  */
78 
79 tree
c_finish_omp_master(location_t loc,tree stmt)80 c_finish_omp_master (location_t loc, tree stmt)
81 {
82   tree t = add_stmt (build1 (OMP_MASTER, void_type_node, stmt));
83   SET_EXPR_LOCATION (t, loc);
84   return t;
85 }
86 
87 /* Complete a #pragma omp taskgroup construct.  BODY is the structured-block
88    that follows the pragma.  LOC is the location of the #pragma.  */
89 
90 tree
c_finish_omp_taskgroup(location_t loc,tree body,tree clauses)91 c_finish_omp_taskgroup (location_t loc, tree body, tree clauses)
92 {
93   tree stmt = make_node (OMP_TASKGROUP);
94   TREE_TYPE (stmt) = void_type_node;
95   OMP_TASKGROUP_BODY (stmt) = body;
96   OMP_TASKGROUP_CLAUSES (stmt) = clauses;
97   SET_EXPR_LOCATION (stmt, loc);
98   return add_stmt (stmt);
99 }
100 
101 /* Complete a #pragma omp critical construct.  BODY is the structured-block
102    that follows the pragma, NAME is the identifier in the pragma, or null
103    if it was omitted.  LOC is the location of the #pragma.  */
104 
105 tree
c_finish_omp_critical(location_t loc,tree body,tree name,tree clauses)106 c_finish_omp_critical (location_t loc, tree body, tree name, tree clauses)
107 {
108   tree stmt = make_node (OMP_CRITICAL);
109   TREE_TYPE (stmt) = void_type_node;
110   OMP_CRITICAL_BODY (stmt) = body;
111   OMP_CRITICAL_NAME (stmt) = name;
112   OMP_CRITICAL_CLAUSES (stmt) = clauses;
113   SET_EXPR_LOCATION (stmt, loc);
114   return add_stmt (stmt);
115 }
116 
117 /* Complete a #pragma omp ordered construct.  STMT is the structured-block
118    that follows the pragma.  LOC is the location of the #pragma.  */
119 
120 tree
c_finish_omp_ordered(location_t loc,tree clauses,tree stmt)121 c_finish_omp_ordered (location_t loc, tree clauses, tree stmt)
122 {
123   tree t = make_node (OMP_ORDERED);
124   TREE_TYPE (t) = void_type_node;
125   OMP_ORDERED_BODY (t) = stmt;
126   if (!flag_openmp	/* flag_openmp_simd */
127       && (OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_SIMD
128 	  || OMP_CLAUSE_CHAIN (clauses)))
129     clauses = build_omp_clause (loc, OMP_CLAUSE_SIMD);
130   OMP_ORDERED_CLAUSES (t) = clauses;
131   SET_EXPR_LOCATION (t, loc);
132   return add_stmt (t);
133 }
134 
135 
136 /* Complete a #pragma omp barrier construct.  LOC is the location of
137    the #pragma.  */
138 
139 void
c_finish_omp_barrier(location_t loc)140 c_finish_omp_barrier (location_t loc)
141 {
142   tree x;
143 
144   x = builtin_decl_explicit (BUILT_IN_GOMP_BARRIER);
145   x = build_call_expr_loc (loc, x, 0);
146   add_stmt (x);
147 }
148 
149 
150 /* Complete a #pragma omp taskwait construct.  LOC is the location of the
151    pragma.  */
152 
153 void
c_finish_omp_taskwait(location_t loc)154 c_finish_omp_taskwait (location_t loc)
155 {
156   tree x;
157 
158   x = builtin_decl_explicit (BUILT_IN_GOMP_TASKWAIT);
159   x = build_call_expr_loc (loc, x, 0);
160   add_stmt (x);
161 }
162 
163 
164 /* Complete a #pragma omp taskyield construct.  LOC is the location of the
165    pragma.  */
166 
167 void
c_finish_omp_taskyield(location_t loc)168 c_finish_omp_taskyield (location_t loc)
169 {
170   tree x;
171 
172   x = builtin_decl_explicit (BUILT_IN_GOMP_TASKYIELD);
173   x = build_call_expr_loc (loc, x, 0);
174   add_stmt (x);
175 }
176 
177 
178 /* Complete a #pragma omp atomic construct.  For CODE OMP_ATOMIC
179    the expression to be implemented atomically is LHS opcode= RHS.
180    For OMP_ATOMIC_READ V = LHS, for OMP_ATOMIC_CAPTURE_{NEW,OLD} LHS
181    opcode= RHS with the new or old content of LHS returned.
182    LOC is the location of the atomic statement.  The value returned
183    is either error_mark_node (if the construct was erroneous) or an
184    OMP_ATOMIC* node which should be added to the current statement
185    tree with add_stmt.  If TEST is set, avoid calling save_expr
186    or create_tmp_var*.  */
187 
188 tree
c_finish_omp_atomic(location_t loc,enum tree_code code,enum tree_code opcode,tree lhs,tree rhs,tree v,tree lhs1,tree rhs1,bool swapped,enum omp_memory_order memory_order,bool test)189 c_finish_omp_atomic (location_t loc, enum tree_code code,
190 		     enum tree_code opcode, tree lhs, tree rhs,
191 		     tree v, tree lhs1, tree rhs1, bool swapped,
192 		     enum omp_memory_order memory_order, bool test)
193 {
194   tree x, type, addr, pre = NULL_TREE;
195   HOST_WIDE_INT bitpos = 0, bitsize = 0;
196 
197   if (lhs == error_mark_node || rhs == error_mark_node
198       || v == error_mark_node || lhs1 == error_mark_node
199       || rhs1 == error_mark_node)
200     return error_mark_node;
201 
202   /* ??? According to one reading of the OpenMP spec, complex type are
203      supported, but there are no atomic stores for any architecture.
204      But at least icc 9.0 doesn't support complex types here either.
205      And lets not even talk about vector types...  */
206   type = TREE_TYPE (lhs);
207   if (!INTEGRAL_TYPE_P (type)
208       && !POINTER_TYPE_P (type)
209       && !SCALAR_FLOAT_TYPE_P (type))
210     {
211       error_at (loc, "invalid expression type for %<#pragma omp atomic%>");
212       return error_mark_node;
213     }
214   if (TYPE_ATOMIC (type))
215     {
216       error_at (loc, "%<_Atomic%> expression in %<#pragma omp atomic%>");
217       return error_mark_node;
218     }
219 
220   if (opcode == RDIV_EXPR)
221     opcode = TRUNC_DIV_EXPR;
222 
223   /* ??? Validate that rhs does not overlap lhs.  */
224   tree blhs = NULL;
225   if (TREE_CODE (lhs) == COMPONENT_REF
226       && TREE_CODE (TREE_OPERAND (lhs, 1)) == FIELD_DECL
227       && DECL_C_BIT_FIELD (TREE_OPERAND (lhs, 1))
228       && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (lhs, 1)))
229     {
230       tree field = TREE_OPERAND (lhs, 1);
231       tree repr = DECL_BIT_FIELD_REPRESENTATIVE (field);
232       if (tree_fits_uhwi_p (DECL_FIELD_OFFSET (field))
233 	  && tree_fits_uhwi_p (DECL_FIELD_OFFSET (repr)))
234 	bitpos = (tree_to_uhwi (DECL_FIELD_OFFSET (field))
235 		  - tree_to_uhwi (DECL_FIELD_OFFSET (repr))) * BITS_PER_UNIT;
236       else
237 	bitpos = 0;
238       bitpos += (tree_to_uhwi (DECL_FIELD_BIT_OFFSET (field))
239 		 - tree_to_uhwi (DECL_FIELD_BIT_OFFSET (repr)));
240       gcc_assert (tree_fits_shwi_p (DECL_SIZE (field)));
241       bitsize = tree_to_shwi (DECL_SIZE (field));
242       blhs = lhs;
243       type = TREE_TYPE (repr);
244       lhs = build3 (COMPONENT_REF, TREE_TYPE (repr), TREE_OPERAND (lhs, 0),
245 		    repr, TREE_OPERAND (lhs, 2));
246     }
247 
248   /* Take and save the address of the lhs.  From then on we'll reference it
249      via indirection.  */
250   addr = build_unary_op (loc, ADDR_EXPR, lhs, false);
251   if (addr == error_mark_node)
252     return error_mark_node;
253   if (!test)
254     addr = save_expr (addr);
255   if (!test
256       && TREE_CODE (addr) != SAVE_EXPR
257       && (TREE_CODE (addr) != ADDR_EXPR
258 	  || !VAR_P (TREE_OPERAND (addr, 0))))
259     {
260       /* Make sure LHS is simple enough so that goa_lhs_expr_p can recognize
261 	 it even after unsharing function body.  */
262       tree var = create_tmp_var_raw (TREE_TYPE (addr));
263       DECL_CONTEXT (var) = current_function_decl;
264       addr = build4 (TARGET_EXPR, TREE_TYPE (addr), var, addr, NULL, NULL);
265     }
266   tree orig_lhs = lhs;
267   lhs = build_indirect_ref (loc, addr, RO_NULL);
268   tree new_lhs = lhs;
269 
270   if (code == OMP_ATOMIC_READ)
271     {
272       x = build1 (OMP_ATOMIC_READ, type, addr);
273       SET_EXPR_LOCATION (x, loc);
274       OMP_ATOMIC_MEMORY_ORDER (x) = memory_order;
275       if (blhs)
276 	x = build3_loc (loc, BIT_FIELD_REF, TREE_TYPE (blhs), x,
277 			bitsize_int (bitsize), bitsize_int (bitpos));
278       return build_modify_expr (loc, v, NULL_TREE, NOP_EXPR,
279 				loc, x, NULL_TREE);
280     }
281 
282   /* There are lots of warnings, errors, and conversions that need to happen
283      in the course of interpreting a statement.  Use the normal mechanisms
284      to do this, and then take it apart again.  */
285   if (blhs)
286     {
287       lhs = build3_loc (loc, BIT_FIELD_REF, TREE_TYPE (blhs), lhs,
288 			bitsize_int (bitsize), bitsize_int (bitpos));
289       if (swapped)
290 	rhs = build_binary_op (loc, opcode, rhs, lhs, true);
291       else if (opcode != NOP_EXPR)
292 	rhs = build_binary_op (loc, opcode, lhs, rhs, true);
293       opcode = NOP_EXPR;
294     }
295   else if (swapped)
296     {
297       rhs = build_binary_op (loc, opcode, rhs, lhs, true);
298       opcode = NOP_EXPR;
299     }
300   bool save = in_late_binary_op;
301   in_late_binary_op = true;
302   x = build_modify_expr (loc, blhs ? blhs : lhs, NULL_TREE, opcode,
303 			 loc, rhs, NULL_TREE);
304   in_late_binary_op = save;
305   if (x == error_mark_node)
306     return error_mark_node;
307   if (TREE_CODE (x) == COMPOUND_EXPR)
308     {
309       pre = TREE_OPERAND (x, 0);
310       gcc_assert (TREE_CODE (pre) == SAVE_EXPR || tree_invariant_p (pre));
311       x = TREE_OPERAND (x, 1);
312     }
313   gcc_assert (TREE_CODE (x) == MODIFY_EXPR);
314   rhs = TREE_OPERAND (x, 1);
315 
316   if (blhs)
317     rhs = build3_loc (loc, BIT_INSERT_EXPR, type, new_lhs,
318 		      rhs, bitsize_int (bitpos));
319 
320   /* Punt the actual generation of atomic operations to common code.  */
321   if (code == OMP_ATOMIC)
322     type = void_type_node;
323   x = build2 (code, type, addr, rhs);
324   SET_EXPR_LOCATION (x, loc);
325   OMP_ATOMIC_MEMORY_ORDER (x) = memory_order;
326 
327   /* Generally it is hard to prove lhs1 and lhs are the same memory
328      location, just diagnose different variables.  */
329   if (rhs1
330       && VAR_P (rhs1)
331       && VAR_P (orig_lhs)
332       && rhs1 != orig_lhs
333       && !test)
334     {
335       if (code == OMP_ATOMIC)
336 	error_at (loc, "%<#pragma omp atomic update%> uses two different "
337 		       "variables for memory");
338       else
339 	error_at (loc, "%<#pragma omp atomic capture%> uses two different "
340 		       "variables for memory");
341       return error_mark_node;
342     }
343 
344   if (lhs1
345       && lhs1 != orig_lhs
346       && TREE_CODE (lhs1) == COMPONENT_REF
347       && TREE_CODE (TREE_OPERAND (lhs1, 1)) == FIELD_DECL
348       && DECL_C_BIT_FIELD (TREE_OPERAND (lhs1, 1))
349       && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (lhs1, 1)))
350     {
351       tree field = TREE_OPERAND (lhs1, 1);
352       tree repr = DECL_BIT_FIELD_REPRESENTATIVE (field);
353       lhs1 = build3 (COMPONENT_REF, TREE_TYPE (repr), TREE_OPERAND (lhs1, 0),
354 		     repr, TREE_OPERAND (lhs1, 2));
355     }
356   if (rhs1
357       && rhs1 != orig_lhs
358       && TREE_CODE (rhs1) == COMPONENT_REF
359       && TREE_CODE (TREE_OPERAND (rhs1, 1)) == FIELD_DECL
360       && DECL_C_BIT_FIELD (TREE_OPERAND (rhs1, 1))
361       && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (rhs1, 1)))
362     {
363       tree field = TREE_OPERAND (rhs1, 1);
364       tree repr = DECL_BIT_FIELD_REPRESENTATIVE (field);
365       rhs1 = build3 (COMPONENT_REF, TREE_TYPE (repr), TREE_OPERAND (rhs1, 0),
366 		     repr, TREE_OPERAND (rhs1, 2));
367     }
368 
369   if (code != OMP_ATOMIC)
370     {
371       /* Generally it is hard to prove lhs1 and lhs are the same memory
372 	 location, just diagnose different variables.  */
373       if (lhs1 && VAR_P (lhs1) && VAR_P (orig_lhs))
374 	{
375 	  if (lhs1 != orig_lhs && !test)
376 	    {
377 	      error_at (loc, "%<#pragma omp atomic capture%> uses two "
378 			     "different variables for memory");
379 	      return error_mark_node;
380 	    }
381 	}
382       if (blhs)
383 	{
384 	  x = build3_loc (loc, BIT_FIELD_REF, TREE_TYPE (blhs), x,
385 			  bitsize_int (bitsize), bitsize_int (bitpos));
386 	  type = TREE_TYPE (blhs);
387 	}
388       x = build_modify_expr (loc, v, NULL_TREE, NOP_EXPR,
389 			     loc, x, NULL_TREE);
390       if (rhs1 && rhs1 != orig_lhs)
391 	{
392 	  tree rhs1addr = build_unary_op (loc, ADDR_EXPR, rhs1, false);
393 	  if (rhs1addr == error_mark_node)
394 	    return error_mark_node;
395 	  x = omit_one_operand_loc (loc, type, x, rhs1addr);
396 	}
397       if (lhs1 && lhs1 != orig_lhs)
398 	{
399 	  tree lhs1addr = build_unary_op (loc, ADDR_EXPR, lhs1, false);
400 	  if (lhs1addr == error_mark_node)
401 	    return error_mark_node;
402 	  if (code == OMP_ATOMIC_CAPTURE_OLD)
403 	    x = omit_one_operand_loc (loc, type, x, lhs1addr);
404 	  else
405 	    {
406 	      if (!test)
407 		x = save_expr (x);
408 	      x = omit_two_operands_loc (loc, type, x, x, lhs1addr);
409 	    }
410 	}
411     }
412   else if (rhs1 && rhs1 != orig_lhs)
413     {
414       tree rhs1addr = build_unary_op (loc, ADDR_EXPR, rhs1, false);
415       if (rhs1addr == error_mark_node)
416 	return error_mark_node;
417       x = omit_one_operand_loc (loc, type, x, rhs1addr);
418     }
419 
420   if (pre)
421     x = omit_one_operand_loc (loc, type, x, pre);
422   return x;
423 }
424 
425 
426 /* Return true if TYPE is the implementation's omp_depend_t.  */
427 
428 bool
c_omp_depend_t_p(tree type)429 c_omp_depend_t_p (tree type)
430 {
431   type = TYPE_MAIN_VARIANT (type);
432   return (TREE_CODE (type) == RECORD_TYPE
433 	  && TYPE_NAME (type)
434 	  && ((TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
435 	       ? DECL_NAME (TYPE_NAME (type)) : TYPE_NAME (type))
436 	      == get_identifier ("omp_depend_t"))
437 	  && (!TYPE_CONTEXT (type)
438 	      || TREE_CODE (TYPE_CONTEXT (type)) == TRANSLATION_UNIT_DECL)
439 	  && COMPLETE_TYPE_P (type)
440 	  && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
441 	  && !compare_tree_int (TYPE_SIZE (type),
442 				2 * tree_to_uhwi (TYPE_SIZE (ptr_type_node))));
443 }
444 
445 
446 /* Complete a #pragma omp depobj construct.  LOC is the location of the
447    #pragma.  */
448 
449 void
c_finish_omp_depobj(location_t loc,tree depobj,enum omp_clause_depend_kind kind,tree clause)450 c_finish_omp_depobj (location_t loc, tree depobj,
451 		     enum omp_clause_depend_kind kind, tree clause)
452 {
453   tree t = NULL_TREE;
454   if (!error_operand_p (depobj))
455     {
456       if (!c_omp_depend_t_p (TREE_TYPE (depobj)))
457 	{
458 	  error_at (EXPR_LOC_OR_LOC (depobj, loc),
459 		    "type of %<depobj%> expression is not %<omp_depend_t%>");
460 	  depobj = error_mark_node;
461 	}
462       else if (TYPE_READONLY (TREE_TYPE (depobj)))
463 	{
464 	  error_at (EXPR_LOC_OR_LOC (depobj, loc),
465 		    "%<const%> qualified %<depobj%> expression");
466 	  depobj = error_mark_node;
467 	}
468     }
469   else
470     depobj = error_mark_node;
471 
472   if (clause == error_mark_node)
473     return;
474 
475   if (clause)
476     {
477       gcc_assert (TREE_CODE (clause) == OMP_CLAUSE
478 		  && OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_DEPEND);
479       if (OMP_CLAUSE_CHAIN (clause))
480 	error_at (OMP_CLAUSE_LOCATION (clause),
481 		  "more than one locator in %<depend%> clause on %<depobj%> "
482 		  "construct");
483       switch (OMP_CLAUSE_DEPEND_KIND (clause))
484 	{
485 	case OMP_CLAUSE_DEPEND_DEPOBJ:
486 	  error_at (OMP_CLAUSE_LOCATION (clause),
487 		    "%<depobj%> dependence type specified in %<depend%> "
488 		    "clause on %<depobj%> construct");
489 	  return;
490 	case OMP_CLAUSE_DEPEND_SOURCE:
491 	case OMP_CLAUSE_DEPEND_SINK:
492 	  error_at (OMP_CLAUSE_LOCATION (clause),
493 		    "%<depend(%s)%> is only allowed in %<omp ordered%>",
494 		    OMP_CLAUSE_DEPEND_KIND (clause) == OMP_CLAUSE_DEPEND_SOURCE
495 		    ? "source" : "sink");
496 	  return;
497 	case OMP_CLAUSE_DEPEND_IN:
498 	case OMP_CLAUSE_DEPEND_OUT:
499 	case OMP_CLAUSE_DEPEND_INOUT:
500 	case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
501 	  kind = OMP_CLAUSE_DEPEND_KIND (clause);
502 	  t = OMP_CLAUSE_DECL (clause);
503 	  gcc_assert (t);
504 	  if (TREE_CODE (t) == TREE_LIST
505 	      && TREE_PURPOSE (t)
506 	      && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
507 	    {
508 	      error_at (OMP_CLAUSE_LOCATION (clause),
509 			"%<iterator%> modifier may not be specified on "
510 			"%<depobj%> construct");
511 	      return;
512 	    }
513 	  if (TREE_CODE (t) == COMPOUND_EXPR)
514 	    {
515 	      tree t1 = build_fold_addr_expr (TREE_OPERAND (t, 1));
516 	      t = build2 (COMPOUND_EXPR, TREE_TYPE (t1), TREE_OPERAND (t, 0),
517 			  t1);
518 	    }
519 	  else
520 	    t = build_fold_addr_expr (t);
521 	  break;
522 	default:
523 	  gcc_unreachable ();
524 	}
525     }
526   else
527     gcc_assert (kind != OMP_CLAUSE_DEPEND_SOURCE);
528 
529   if (depobj == error_mark_node)
530     return;
531 
532   depobj = build_fold_addr_expr_loc (EXPR_LOC_OR_LOC (depobj, loc), depobj);
533   tree dtype
534     = build_pointer_type_for_mode (ptr_type_node, TYPE_MODE (ptr_type_node),
535 				   true);
536   depobj = fold_convert (dtype, depobj);
537   tree r;
538   if (clause)
539     {
540       depobj = save_expr (depobj);
541       r = build_indirect_ref (loc, depobj, RO_UNARY_STAR);
542       add_stmt (build2 (MODIFY_EXPR, void_type_node, r, t));
543     }
544   int k;
545   switch (kind)
546     {
547     case OMP_CLAUSE_DEPEND_IN:
548       k = GOMP_DEPEND_IN;
549       break;
550     case OMP_CLAUSE_DEPEND_OUT:
551       k = GOMP_DEPEND_OUT;
552       break;
553     case OMP_CLAUSE_DEPEND_INOUT:
554       k = GOMP_DEPEND_INOUT;
555       break;
556     case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
557       k = GOMP_DEPEND_MUTEXINOUTSET;
558       break;
559     case OMP_CLAUSE_DEPEND_LAST:
560       k = -1;
561       break;
562     default:
563       gcc_unreachable ();
564     }
565   t = build_int_cst (ptr_type_node, k);
566   depobj = build2_loc (loc, POINTER_PLUS_EXPR, TREE_TYPE (depobj), depobj,
567 		       TYPE_SIZE_UNIT (ptr_type_node));
568   r = build_indirect_ref (loc, depobj, RO_UNARY_STAR);
569   add_stmt (build2 (MODIFY_EXPR, void_type_node, r, t));
570 }
571 
572 
573 /* Complete a #pragma omp flush construct.  We don't do anything with
574    the variable list that the syntax allows.  LOC is the location of
575    the #pragma.  */
576 
577 void
c_finish_omp_flush(location_t loc,int mo)578 c_finish_omp_flush (location_t loc, int mo)
579 {
580   tree x;
581 
582   if (mo == MEMMODEL_LAST)
583     {
584       x = builtin_decl_explicit (BUILT_IN_SYNC_SYNCHRONIZE);
585       x = build_call_expr_loc (loc, x, 0);
586     }
587   else
588     {
589       x = builtin_decl_explicit (BUILT_IN_ATOMIC_THREAD_FENCE);
590       x = build_call_expr_loc (loc, x, 1,
591 			       build_int_cst (integer_type_node, mo));
592     }
593   add_stmt (x);
594 }
595 
596 
597 /* Check and canonicalize OMP_FOR increment expression.
598    Helper function for c_finish_omp_for.  */
599 
600 static tree
check_omp_for_incr_expr(location_t loc,tree exp,tree decl)601 check_omp_for_incr_expr (location_t loc, tree exp, tree decl)
602 {
603   tree t;
604 
605   if (!INTEGRAL_TYPE_P (TREE_TYPE (exp))
606       || TYPE_PRECISION (TREE_TYPE (exp)) < TYPE_PRECISION (TREE_TYPE (decl)))
607     return error_mark_node;
608 
609   if (exp == decl)
610     return build_int_cst (TREE_TYPE (exp), 0);
611 
612   switch (TREE_CODE (exp))
613     {
614     CASE_CONVERT:
615       t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 0), decl);
616       if (t != error_mark_node)
617         return fold_convert_loc (loc, TREE_TYPE (exp), t);
618       break;
619     case MINUS_EXPR:
620       t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 0), decl);
621       if (t != error_mark_node)
622         return fold_build2_loc (loc, MINUS_EXPR,
623 				TREE_TYPE (exp), t, TREE_OPERAND (exp, 1));
624       break;
625     case PLUS_EXPR:
626       t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 0), decl);
627       if (t != error_mark_node)
628         return fold_build2_loc (loc, PLUS_EXPR,
629 				TREE_TYPE (exp), t, TREE_OPERAND (exp, 1));
630       t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 1), decl);
631       if (t != error_mark_node)
632         return fold_build2_loc (loc, PLUS_EXPR,
633 				TREE_TYPE (exp), TREE_OPERAND (exp, 0), t);
634       break;
635     case COMPOUND_EXPR:
636       {
637 	/* cp_build_modify_expr forces preevaluation of the RHS to make
638 	   sure that it is evaluated before the lvalue-rvalue conversion
639 	   is applied to the LHS.  Reconstruct the original expression.  */
640 	tree op0 = TREE_OPERAND (exp, 0);
641 	if (TREE_CODE (op0) == TARGET_EXPR
642 	    && !VOID_TYPE_P (TREE_TYPE (op0)))
643 	  {
644 	    tree op1 = TREE_OPERAND (exp, 1);
645 	    tree temp = TARGET_EXPR_SLOT (op0);
646 	    if (BINARY_CLASS_P (op1)
647 		&& TREE_OPERAND (op1, 1) == temp)
648 	      {
649 		op1 = copy_node (op1);
650 		TREE_OPERAND (op1, 1) = TARGET_EXPR_INITIAL (op0);
651 		return check_omp_for_incr_expr (loc, op1, decl);
652 	      }
653 	  }
654 	break;
655       }
656     default:
657       break;
658     }
659 
660   return error_mark_node;
661 }
662 
663 /* If the OMP_FOR increment expression in INCR is of pointer type,
664    canonicalize it into an expression handled by gimplify_omp_for()
665    and return it.  DECL is the iteration variable.  */
666 
667 static tree
c_omp_for_incr_canonicalize_ptr(location_t loc,tree decl,tree incr)668 c_omp_for_incr_canonicalize_ptr (location_t loc, tree decl, tree incr)
669 {
670   if (POINTER_TYPE_P (TREE_TYPE (decl))
671       && TREE_OPERAND (incr, 1))
672     {
673       tree t = fold_convert_loc (loc,
674 				 sizetype, TREE_OPERAND (incr, 1));
675 
676       if (TREE_CODE (incr) == POSTDECREMENT_EXPR
677 	  || TREE_CODE (incr) == PREDECREMENT_EXPR)
678 	t = fold_build1_loc (loc, NEGATE_EXPR, sizetype, t);
679       t = fold_build_pointer_plus (decl, t);
680       incr = build2 (MODIFY_EXPR, void_type_node, decl, t);
681     }
682   return incr;
683 }
684 
685 /* Validate and generate OMP_FOR.
686    DECLV is a vector of iteration variables, for each collapsed loop.
687 
688    ORIG_DECLV, if non-NULL, is a vector with the original iteration
689    variables (prior to any transformations, by say, C++ iterators).
690 
691    INITV, CONDV and INCRV are vectors containing initialization
692    expressions, controlling predicates and increment expressions.
693    BODY is the body of the loop and PRE_BODY statements that go before
694    the loop.  */
695 
696 tree
c_finish_omp_for(location_t locus,enum tree_code code,tree declv,tree orig_declv,tree initv,tree condv,tree incrv,tree body,tree pre_body,bool final_p)697 c_finish_omp_for (location_t locus, enum tree_code code, tree declv,
698 		  tree orig_declv, tree initv, tree condv, tree incrv,
699 		  tree body, tree pre_body, bool final_p)
700 {
701   location_t elocus;
702   bool fail = false;
703   int i;
704 
705   gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (initv));
706   gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (condv));
707   gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (incrv));
708   for (i = 0; i < TREE_VEC_LENGTH (declv); i++)
709     {
710       tree decl = TREE_VEC_ELT (declv, i);
711       tree init = TREE_VEC_ELT (initv, i);
712       tree cond = TREE_VEC_ELT (condv, i);
713       tree incr = TREE_VEC_ELT (incrv, i);
714 
715       elocus = locus;
716       if (EXPR_HAS_LOCATION (init))
717 	elocus = EXPR_LOCATION (init);
718 
719       /* Validate the iteration variable.  */
720       if (!INTEGRAL_TYPE_P (TREE_TYPE (decl))
721 	  && TREE_CODE (TREE_TYPE (decl)) != POINTER_TYPE)
722 	{
723 	  error_at (elocus, "invalid type for iteration variable %qE", decl);
724 	  fail = true;
725 	}
726       else if (TYPE_ATOMIC (TREE_TYPE (decl)))
727 	{
728 	  error_at (elocus, "%<_Atomic%> iteration variable %qE", decl);
729 	  fail = true;
730 	  /* _Atomic iterator confuses stuff too much, so we risk ICE
731 	     trying to diagnose it further.  */
732 	  continue;
733 	}
734 
735       /* In the case of "for (int i = 0...)", init will be a decl.  It should
736 	 have a DECL_INITIAL that we can turn into an assignment.  */
737       if (init == decl)
738 	{
739 	  elocus = DECL_SOURCE_LOCATION (decl);
740 
741 	  init = DECL_INITIAL (decl);
742 	  if (init == NULL)
743 	    {
744 	      error_at (elocus, "%qE is not initialized", decl);
745 	      init = integer_zero_node;
746 	      fail = true;
747 	    }
748 	  DECL_INITIAL (decl) = NULL_TREE;
749 
750 	  init = build_modify_expr (elocus, decl, NULL_TREE, NOP_EXPR,
751 	      			    /* FIXME diagnostics: This should
752 				       be the location of the INIT.  */
753 	      			    elocus,
754 				    init,
755 				    NULL_TREE);
756 	}
757       if (init != error_mark_node)
758 	{
759 	  gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
760 	  gcc_assert (TREE_OPERAND (init, 0) == decl);
761 	}
762 
763       if (cond == NULL_TREE)
764 	{
765 	  error_at (elocus, "missing controlling predicate");
766 	  fail = true;
767 	}
768       else
769 	{
770 	  bool cond_ok = false;
771 
772 	  /* E.g. C sizeof (vla) could add COMPOUND_EXPRs with
773 	     evaluation of the vla VAR_DECL.  We need to readd
774 	     them to the non-decl operand.  See PR45784.  */
775 	  while (TREE_CODE (cond) == COMPOUND_EXPR)
776 	    cond = TREE_OPERAND (cond, 1);
777 
778 	  if (EXPR_HAS_LOCATION (cond))
779 	    elocus = EXPR_LOCATION (cond);
780 
781 	  if (TREE_CODE (cond) == LT_EXPR
782 	      || TREE_CODE (cond) == LE_EXPR
783 	      || TREE_CODE (cond) == GT_EXPR
784 	      || TREE_CODE (cond) == GE_EXPR
785 	      || TREE_CODE (cond) == NE_EXPR
786 	      || TREE_CODE (cond) == EQ_EXPR)
787 	    {
788 	      tree op0 = TREE_OPERAND (cond, 0);
789 	      tree op1 = TREE_OPERAND (cond, 1);
790 
791 	      /* 2.5.1.  The comparison in the condition is computed in
792 		 the type of DECL, otherwise the behavior is undefined.
793 
794 		 For example:
795 		 long n; int i;
796 		 i < n;
797 
798 		 according to ISO will be evaluated as:
799 		 (long)i < n;
800 
801 		 We want to force:
802 		 i < (int)n;  */
803 	      if (TREE_CODE (op0) == NOP_EXPR
804 		  && decl == TREE_OPERAND (op0, 0))
805 		{
806 		  TREE_OPERAND (cond, 0) = TREE_OPERAND (op0, 0);
807 		  TREE_OPERAND (cond, 1)
808 		    = fold_build1_loc (elocus, NOP_EXPR, TREE_TYPE (decl),
809 				   TREE_OPERAND (cond, 1));
810 		}
811 	      else if (TREE_CODE (op1) == NOP_EXPR
812 		       && decl == TREE_OPERAND (op1, 0))
813 		{
814 		  TREE_OPERAND (cond, 1) = TREE_OPERAND (op1, 0);
815 		  TREE_OPERAND (cond, 0)
816 		    = fold_build1_loc (elocus, NOP_EXPR, TREE_TYPE (decl),
817 				   TREE_OPERAND (cond, 0));
818 		}
819 
820 	      if (decl == TREE_OPERAND (cond, 0))
821 		cond_ok = true;
822 	      else if (decl == TREE_OPERAND (cond, 1))
823 		{
824 		  TREE_SET_CODE (cond,
825 				 swap_tree_comparison (TREE_CODE (cond)));
826 		  TREE_OPERAND (cond, 1) = TREE_OPERAND (cond, 0);
827 		  TREE_OPERAND (cond, 0) = decl;
828 		  cond_ok = true;
829 		}
830 
831 	      if (TREE_CODE (cond) == NE_EXPR
832 		  || TREE_CODE (cond) == EQ_EXPR)
833 		{
834 		  if (!INTEGRAL_TYPE_P (TREE_TYPE (decl)))
835 		    {
836 		      if (code == OACC_LOOP || TREE_CODE (cond) == EQ_EXPR)
837 			cond_ok = false;
838 		    }
839 		  else if (operand_equal_p (TREE_OPERAND (cond, 1),
840 					    TYPE_MIN_VALUE (TREE_TYPE (decl)),
841 					    0))
842 		    TREE_SET_CODE (cond, TREE_CODE (cond) == NE_EXPR
843 					 ? GT_EXPR : LE_EXPR);
844 		  else if (operand_equal_p (TREE_OPERAND (cond, 1),
845 					    TYPE_MAX_VALUE (TREE_TYPE (decl)),
846 					    0))
847 		    TREE_SET_CODE (cond, TREE_CODE (cond) == NE_EXPR
848 					 ? LT_EXPR : GE_EXPR);
849 		  else if (code == OACC_LOOP || TREE_CODE (cond) == EQ_EXPR)
850 		    cond_ok = false;
851 		}
852 
853 	      if (cond_ok && TREE_VEC_ELT (condv, i) != cond)
854 		{
855 		  tree ce = NULL_TREE, *pce = &ce;
856 		  tree type = TREE_TYPE (TREE_OPERAND (cond, 1));
857 		  for (tree c = TREE_VEC_ELT (condv, i); c != cond;
858 		       c = TREE_OPERAND (c, 1))
859 		    {
860 		      *pce = build2 (COMPOUND_EXPR, type, TREE_OPERAND (c, 0),
861 				     TREE_OPERAND (cond, 1));
862 		      pce = &TREE_OPERAND (*pce, 1);
863 		    }
864 		  TREE_OPERAND (cond, 1) = ce;
865 		  TREE_VEC_ELT (condv, i) = cond;
866 		}
867 	    }
868 
869 	  if (!cond_ok)
870 	    {
871 	      error_at (elocus, "invalid controlling predicate");
872 	      fail = true;
873 	    }
874 	}
875 
876       if (incr == NULL_TREE)
877 	{
878 	  error_at (elocus, "missing increment expression");
879 	  fail = true;
880 	}
881       else
882 	{
883 	  bool incr_ok = false;
884 
885 	  if (EXPR_HAS_LOCATION (incr))
886 	    elocus = EXPR_LOCATION (incr);
887 
888 	  /* Check all the valid increment expressions: v++, v--, ++v, --v,
889 	     v = v + incr, v = incr + v and v = v - incr.  */
890 	  switch (TREE_CODE (incr))
891 	    {
892 	    case POSTINCREMENT_EXPR:
893 	    case PREINCREMENT_EXPR:
894 	    case POSTDECREMENT_EXPR:
895 	    case PREDECREMENT_EXPR:
896 	      if (TREE_OPERAND (incr, 0) != decl)
897 		break;
898 
899 	      incr_ok = true;
900 	      if (!fail
901 		  && TREE_CODE (cond) == NE_EXPR
902 		  && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
903 		  && TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)))
904 		  && (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))))
905 		      != INTEGER_CST))
906 		{
907 		  /* For pointer to VLA, transform != into < or >
908 		     depending on whether incr is increment or decrement.  */
909 		  if (TREE_CODE (incr) == PREINCREMENT_EXPR
910 		      || TREE_CODE (incr) == POSTINCREMENT_EXPR)
911 		    TREE_SET_CODE (cond, LT_EXPR);
912 		  else
913 		    TREE_SET_CODE (cond, GT_EXPR);
914 		}
915 	      incr = c_omp_for_incr_canonicalize_ptr (elocus, decl, incr);
916 	      break;
917 
918 	    case COMPOUND_EXPR:
919 	      if (TREE_CODE (TREE_OPERAND (incr, 0)) != SAVE_EXPR
920 		  || TREE_CODE (TREE_OPERAND (incr, 1)) != MODIFY_EXPR)
921 		break;
922 	      incr = TREE_OPERAND (incr, 1);
923 	      /* FALLTHRU */
924 	    case MODIFY_EXPR:
925 	      if (TREE_OPERAND (incr, 0) != decl)
926 		break;
927 	      if (TREE_OPERAND (incr, 1) == decl)
928 		break;
929 	      if (TREE_CODE (TREE_OPERAND (incr, 1)) == PLUS_EXPR
930 		  && (TREE_OPERAND (TREE_OPERAND (incr, 1), 0) == decl
931 		      || TREE_OPERAND (TREE_OPERAND (incr, 1), 1) == decl))
932 		incr_ok = true;
933 	      else if ((TREE_CODE (TREE_OPERAND (incr, 1)) == MINUS_EXPR
934 			|| (TREE_CODE (TREE_OPERAND (incr, 1))
935 			    == POINTER_PLUS_EXPR))
936 		       && TREE_OPERAND (TREE_OPERAND (incr, 1), 0) == decl)
937 		incr_ok = true;
938 	      else
939 		{
940 		  tree t = check_omp_for_incr_expr (elocus,
941 						    TREE_OPERAND (incr, 1),
942 						    decl);
943 		  if (t != error_mark_node)
944 		    {
945 		      incr_ok = true;
946 		      t = build2 (PLUS_EXPR, TREE_TYPE (decl), decl, t);
947 		      incr = build2 (MODIFY_EXPR, void_type_node, decl, t);
948 		    }
949 		}
950 	      if (!fail
951 		  && incr_ok
952 		  && TREE_CODE (cond) == NE_EXPR)
953 		{
954 		  tree i = TREE_OPERAND (incr, 1);
955 		  i = TREE_OPERAND (i, TREE_OPERAND (i, 0) == decl);
956 		  i = c_fully_fold (i, false, NULL);
957 		  if (!final_p
958 		      && TREE_CODE (i) != INTEGER_CST)
959 		    ;
960 		  else if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
961 		    {
962 		      tree unit
963 			= TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
964 		      if (unit)
965 			{
966 			  enum tree_code ccode = GT_EXPR;
967 			  unit = c_fully_fold (unit, false, NULL);
968 			  i = fold_convert (TREE_TYPE (unit), i);
969 			  if (operand_equal_p (unit, i, 0))
970 			    ccode = LT_EXPR;
971 			  if (ccode == GT_EXPR)
972 			    {
973 			      i = fold_unary (NEGATE_EXPR, TREE_TYPE (i), i);
974 			      if (i == NULL_TREE
975 				  || !operand_equal_p (unit, i, 0))
976 				{
977 				  error_at (elocus,
978 					    "increment is not constant 1 or "
979 					    "-1 for %<!=%> condition");
980 				  fail = true;
981 				}
982 			    }
983 			  if (TREE_CODE (unit) != INTEGER_CST)
984 			    /* For pointer to VLA, transform != into < or >
985 			       depending on whether the pointer is
986 			       incremented or decremented in each
987 			       iteration.  */
988 			    TREE_SET_CODE (cond, ccode);
989 			}
990 		    }
991 		  else
992 		    {
993 		      if (!integer_onep (i) && !integer_minus_onep (i))
994 			{
995 			  error_at (elocus,
996 				    "increment is not constant 1 or -1 for"
997 				    " %<!=%> condition");
998 			  fail = true;
999 			}
1000 		    }
1001 		}
1002 	      break;
1003 
1004 	    default:
1005 	      break;
1006 	    }
1007 	  if (!incr_ok)
1008 	    {
1009 	      error_at (elocus, "invalid increment expression");
1010 	      fail = true;
1011 	    }
1012 	}
1013 
1014       TREE_VEC_ELT (initv, i) = init;
1015       TREE_VEC_ELT (incrv, i) = incr;
1016     }
1017 
1018   if (fail)
1019     return NULL;
1020   else
1021     {
1022       tree t = make_node (code);
1023 
1024       TREE_TYPE (t) = void_type_node;
1025       OMP_FOR_INIT (t) = initv;
1026       OMP_FOR_COND (t) = condv;
1027       OMP_FOR_INCR (t) = incrv;
1028       OMP_FOR_BODY (t) = body;
1029       OMP_FOR_PRE_BODY (t) = pre_body;
1030       OMP_FOR_ORIG_DECLS (t) = orig_declv;
1031 
1032       SET_EXPR_LOCATION (t, locus);
1033       return t;
1034     }
1035 }
1036 
1037 /* Type for passing data in between c_omp_check_loop_iv and
1038    c_omp_check_loop_iv_r.  */
1039 
1040 struct c_omp_check_loop_iv_data
1041 {
1042   tree declv;
1043   bool fail;
1044   location_t stmt_loc;
1045   location_t expr_loc;
1046   int kind;
1047   walk_tree_lh lh;
1048   hash_set<tree> *ppset;
1049 };
1050 
1051 /* Helper function called via walk_tree, to diagnose uses
1052    of associated loop IVs inside of lb, b and incr expressions
1053    of OpenMP loops.  */
1054 
1055 static tree
c_omp_check_loop_iv_r(tree * tp,int * walk_subtrees,void * data)1056 c_omp_check_loop_iv_r (tree *tp, int *walk_subtrees, void *data)
1057 {
1058   struct c_omp_check_loop_iv_data *d
1059     = (struct c_omp_check_loop_iv_data *) data;
1060   if (DECL_P (*tp))
1061     {
1062       int i;
1063       for (i = 0; i < TREE_VEC_LENGTH (d->declv); i++)
1064 	if (*tp == TREE_VEC_ELT (d->declv, i)
1065 	    || (TREE_CODE (TREE_VEC_ELT (d->declv, i)) == TREE_LIST
1066 		&& *tp == TREE_PURPOSE (TREE_VEC_ELT (d->declv, i)))
1067 	    || (TREE_CODE (TREE_VEC_ELT (d->declv, i)) == TREE_LIST
1068 		&& TREE_CHAIN (TREE_VEC_ELT (d->declv, i))
1069 		&& (TREE_CODE (TREE_CHAIN (TREE_VEC_ELT (d->declv, i)))
1070 		    == TREE_VEC)
1071 		&& *tp == TREE_VEC_ELT (TREE_CHAIN (TREE_VEC_ELT (d->declv,
1072 								  i)), 2)))
1073 	  {
1074 	    location_t loc = d->expr_loc;
1075 	    if (loc == UNKNOWN_LOCATION)
1076 	      loc = d->stmt_loc;
1077 	    switch (d->kind)
1078 	      {
1079 	      case 0:
1080 		error_at (loc, "initializer expression refers to "
1081 			       "iteration variable %qD", *tp);
1082 		break;
1083 	      case 1:
1084 		error_at (loc, "condition expression refers to "
1085 			       "iteration variable %qD", *tp);
1086 		break;
1087 	      case 2:
1088 		error_at (loc, "increment expression refers to "
1089 			       "iteration variable %qD", *tp);
1090 		break;
1091 	      }
1092 	    d->fail = true;
1093 	  }
1094     }
1095   /* Don't walk dtors added by C++ wrap_cleanups_r.  */
1096   else if (TREE_CODE (*tp) == TRY_CATCH_EXPR
1097 	   && TRY_CATCH_IS_CLEANUP (*tp))
1098     {
1099       *walk_subtrees = 0;
1100       return walk_tree_1 (&TREE_OPERAND (*tp, 0), c_omp_check_loop_iv_r, data,
1101 			  d->ppset, d->lh);
1102     }
1103 
1104   return NULL_TREE;
1105 }
1106 
1107 /* Diagnose invalid references to loop iterators in lb, b and incr
1108    expressions.  */
1109 
1110 bool
c_omp_check_loop_iv(tree stmt,tree declv,walk_tree_lh lh)1111 c_omp_check_loop_iv (tree stmt, tree declv, walk_tree_lh lh)
1112 {
1113   hash_set<tree> pset;
1114   struct c_omp_check_loop_iv_data data;
1115   int i;
1116 
1117   data.declv = declv;
1118   data.fail = false;
1119   data.stmt_loc = EXPR_LOCATION (stmt);
1120   data.lh = lh;
1121   data.ppset = &pset;
1122   for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (stmt)); i++)
1123     {
1124       tree init = TREE_VEC_ELT (OMP_FOR_INIT (stmt), i);
1125       gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
1126       tree decl = TREE_OPERAND (init, 0);
1127       tree cond = TREE_VEC_ELT (OMP_FOR_COND (stmt), i);
1128       gcc_assert (COMPARISON_CLASS_P (cond));
1129       gcc_assert (TREE_OPERAND (cond, 0) == decl);
1130       tree incr = TREE_VEC_ELT (OMP_FOR_INCR (stmt), i);
1131       data.expr_loc = EXPR_LOCATION (TREE_OPERAND (init, 1));
1132       data.kind = 0;
1133       walk_tree_1 (&TREE_OPERAND (init, 1),
1134 		   c_omp_check_loop_iv_r, &data, &pset, lh);
1135       /* Don't warn for C++ random access iterators here, the
1136 	 expression then involves the subtraction and always refers
1137 	 to the original value.  The C++ FE needs to warn on those
1138 	 earlier.  */
1139       if (decl == TREE_VEC_ELT (declv, i)
1140 	  || (TREE_CODE (TREE_VEC_ELT (declv, i)) == TREE_LIST
1141 	      && decl == TREE_PURPOSE (TREE_VEC_ELT (declv, i))))
1142 	{
1143 	  data.expr_loc = EXPR_LOCATION (cond);
1144 	  data.kind = 1;
1145 	  walk_tree_1 (&TREE_OPERAND (cond, 1),
1146 		       c_omp_check_loop_iv_r, &data, &pset, lh);
1147 	}
1148       if (TREE_CODE (incr) == MODIFY_EXPR)
1149 	{
1150 	  gcc_assert (TREE_OPERAND (incr, 0) == decl);
1151 	  incr = TREE_OPERAND (incr, 1);
1152 	  data.kind = 2;
1153 	  if (TREE_CODE (incr) == PLUS_EXPR
1154 	      && TREE_OPERAND (incr, 1) == decl)
1155 	    {
1156 	      data.expr_loc = EXPR_LOCATION (TREE_OPERAND (incr, 0));
1157 	      walk_tree_1 (&TREE_OPERAND (incr, 0),
1158 			   c_omp_check_loop_iv_r, &data, &pset, lh);
1159 	    }
1160 	  else
1161 	    {
1162 	      data.expr_loc = EXPR_LOCATION (TREE_OPERAND (incr, 1));
1163 	      walk_tree_1 (&TREE_OPERAND (incr, 1),
1164 			   c_omp_check_loop_iv_r, &data, &pset, lh);
1165 	    }
1166 	}
1167     }
1168   return !data.fail;
1169 }
1170 
1171 /* Similar, but allows to check the init or cond expressions individually.  */
1172 
1173 bool
c_omp_check_loop_iv_exprs(location_t stmt_loc,tree declv,tree decl,tree init,tree cond,walk_tree_lh lh)1174 c_omp_check_loop_iv_exprs (location_t stmt_loc, tree declv, tree decl,
1175 			   tree init, tree cond, walk_tree_lh lh)
1176 {
1177   hash_set<tree> pset;
1178   struct c_omp_check_loop_iv_data data;
1179 
1180   data.declv = declv;
1181   data.fail = false;
1182   data.stmt_loc = stmt_loc;
1183   data.lh = lh;
1184   data.ppset = &pset;
1185   if (init)
1186     {
1187       data.expr_loc = EXPR_LOCATION (init);
1188       data.kind = 0;
1189       walk_tree_1 (&init,
1190 		   c_omp_check_loop_iv_r, &data, &pset, lh);
1191     }
1192   if (cond)
1193     {
1194       gcc_assert (COMPARISON_CLASS_P (cond));
1195       data.expr_loc = EXPR_LOCATION (init);
1196       data.kind = 1;
1197       if (TREE_OPERAND (cond, 0) == decl)
1198 	walk_tree_1 (&TREE_OPERAND (cond, 1),
1199 		     c_omp_check_loop_iv_r, &data, &pset, lh);
1200       else
1201 	walk_tree_1 (&TREE_OPERAND (cond, 0),
1202 		     c_omp_check_loop_iv_r, &data, &pset, lh);
1203     }
1204   return !data.fail;
1205 }
1206 
1207 /* This function splits clauses for OpenACC combined loop
1208    constructs.  OpenACC combined loop constructs are:
1209    #pragma acc kernels loop
1210    #pragma acc parallel loop  */
1211 
1212 tree
c_oacc_split_loop_clauses(tree clauses,tree * not_loop_clauses,bool is_parallel)1213 c_oacc_split_loop_clauses (tree clauses, tree *not_loop_clauses,
1214 			   bool is_parallel)
1215 {
1216   tree next, loop_clauses, nc;
1217 
1218   loop_clauses = *not_loop_clauses = NULL_TREE;
1219   for (; clauses ; clauses = next)
1220     {
1221       next = OMP_CLAUSE_CHAIN (clauses);
1222 
1223       switch (OMP_CLAUSE_CODE (clauses))
1224         {
1225 	  /* Loop clauses.  */
1226 	case OMP_CLAUSE_COLLAPSE:
1227 	case OMP_CLAUSE_TILE:
1228 	case OMP_CLAUSE_GANG:
1229 	case OMP_CLAUSE_WORKER:
1230 	case OMP_CLAUSE_VECTOR:
1231 	case OMP_CLAUSE_AUTO:
1232 	case OMP_CLAUSE_SEQ:
1233 	case OMP_CLAUSE_INDEPENDENT:
1234 	case OMP_CLAUSE_PRIVATE:
1235 	  OMP_CLAUSE_CHAIN (clauses) = loop_clauses;
1236 	  loop_clauses = clauses;
1237 	  break;
1238 
1239 	  /* Reductions must be duplicated on both constructs.  */
1240 	case OMP_CLAUSE_REDUCTION:
1241 	  if (is_parallel)
1242 	    {
1243 	      nc = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1244 				     OMP_CLAUSE_REDUCTION);
1245 	      OMP_CLAUSE_DECL (nc) = OMP_CLAUSE_DECL (clauses);
1246 	      OMP_CLAUSE_REDUCTION_CODE (nc)
1247 		= OMP_CLAUSE_REDUCTION_CODE (clauses);
1248 	      OMP_CLAUSE_CHAIN (nc) = *not_loop_clauses;
1249 	      *not_loop_clauses = nc;
1250 	    }
1251 
1252 	  OMP_CLAUSE_CHAIN (clauses) = loop_clauses;
1253 	  loop_clauses = clauses;
1254 	  break;
1255 
1256 	  /* Parallel/kernels clauses.  */
1257 	default:
1258 	  OMP_CLAUSE_CHAIN (clauses) = *not_loop_clauses;
1259 	  *not_loop_clauses = clauses;
1260 	  break;
1261 	}
1262     }
1263 
1264   return loop_clauses;
1265 }
1266 
1267 /* This function attempts to split or duplicate clauses for OpenMP
1268    combined/composite constructs.  Right now there are 30 different
1269    constructs.  CODE is the innermost construct in the combined construct,
1270    and MASK allows to determine which constructs are combined together,
1271    as every construct has at least one clause that no other construct
1272    has (except for OMP_SECTIONS, but that can be only combined with parallel,
1273    and OMP_MASTER, which doesn't have any clauses at all).
1274    OpenMP combined/composite constructs are:
1275    #pragma omp distribute parallel for
1276    #pragma omp distribute parallel for simd
1277    #pragma omp distribute simd
1278    #pragma omp for simd
1279    #pragma omp master taskloop
1280    #pragma omp master taskloop simd
1281    #pragma omp parallel for
1282    #pragma omp parallel for simd
1283    #pragma omp parallel loop
1284    #pragma omp parallel master
1285    #pragma omp parallel master taskloop
1286    #pragma omp parallel master taskloop simd
1287    #pragma omp parallel sections
1288    #pragma omp target parallel
1289    #pragma omp target parallel for
1290    #pragma omp target parallel for simd
1291    #pragma omp target parallel loop
1292    #pragma omp target teams
1293    #pragma omp target teams distribute
1294    #pragma omp target teams distribute parallel for
1295    #pragma omp target teams distribute parallel for simd
1296    #pragma omp target teams distribute simd
1297    #pragma omp target teams loop
1298    #pragma omp target simd
1299    #pragma omp taskloop simd
1300    #pragma omp teams distribute
1301    #pragma omp teams distribute parallel for
1302    #pragma omp teams distribute parallel for simd
1303    #pragma omp teams distribute simd
1304    #pragma omp teams loop  */
1305 
1306 void
c_omp_split_clauses(location_t loc,enum tree_code code,omp_clause_mask mask,tree clauses,tree * cclauses)1307 c_omp_split_clauses (location_t loc, enum tree_code code,
1308 		     omp_clause_mask mask, tree clauses, tree *cclauses)
1309 {
1310   tree next, c;
1311   enum c_omp_clause_split s;
1312   int i;
1313 
1314   for (i = 0; i < C_OMP_CLAUSE_SPLIT_COUNT; i++)
1315     cclauses[i] = NULL;
1316   /* Add implicit nowait clause on
1317      #pragma omp parallel {for,for simd,sections}.  */
1318   if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
1319     switch (code)
1320       {
1321       case OMP_FOR:
1322       case OMP_SIMD:
1323 	if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)) != 0)
1324 	  cclauses[C_OMP_CLAUSE_SPLIT_FOR]
1325 	    = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
1326 	break;
1327       case OMP_SECTIONS:
1328 	cclauses[C_OMP_CLAUSE_SPLIT_SECTIONS]
1329 	  = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
1330 	break;
1331       default:
1332 	break;
1333       }
1334 
1335   for (; clauses ; clauses = next)
1336     {
1337       next = OMP_CLAUSE_CHAIN (clauses);
1338 
1339       switch (OMP_CLAUSE_CODE (clauses))
1340 	{
1341 	/* First the clauses that are unique to some constructs.  */
1342 	case OMP_CLAUSE_DEVICE:
1343 	case OMP_CLAUSE_MAP:
1344 	case OMP_CLAUSE_IS_DEVICE_PTR:
1345 	case OMP_CLAUSE_DEFAULTMAP:
1346 	case OMP_CLAUSE_DEPEND:
1347 	  s = C_OMP_CLAUSE_SPLIT_TARGET;
1348 	  break;
1349 	case OMP_CLAUSE_NUM_TEAMS:
1350 	case OMP_CLAUSE_THREAD_LIMIT:
1351 	  s = C_OMP_CLAUSE_SPLIT_TEAMS;
1352 	  break;
1353 	case OMP_CLAUSE_DIST_SCHEDULE:
1354 	  s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
1355 	  break;
1356 	case OMP_CLAUSE_COPYIN:
1357 	case OMP_CLAUSE_NUM_THREADS:
1358 	case OMP_CLAUSE_PROC_BIND:
1359 	  s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1360 	  break;
1361 	case OMP_CLAUSE_ORDERED:
1362 	  s = C_OMP_CLAUSE_SPLIT_FOR;
1363 	  break;
1364 	case OMP_CLAUSE_SCHEDULE:
1365 	  s = C_OMP_CLAUSE_SPLIT_FOR;
1366 	  if (code != OMP_SIMD)
1367 	    OMP_CLAUSE_SCHEDULE_SIMD (clauses) = 0;
1368 	  break;
1369 	case OMP_CLAUSE_SAFELEN:
1370 	case OMP_CLAUSE_SIMDLEN:
1371 	case OMP_CLAUSE_ALIGNED:
1372 	case OMP_CLAUSE_NONTEMPORAL:
1373 	  s = C_OMP_CLAUSE_SPLIT_SIMD;
1374 	  break;
1375 	case OMP_CLAUSE_GRAINSIZE:
1376 	case OMP_CLAUSE_NUM_TASKS:
1377 	case OMP_CLAUSE_FINAL:
1378 	case OMP_CLAUSE_UNTIED:
1379 	case OMP_CLAUSE_MERGEABLE:
1380 	case OMP_CLAUSE_NOGROUP:
1381 	case OMP_CLAUSE_PRIORITY:
1382 	  s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
1383 	  break;
1384 	case OMP_CLAUSE_BIND:
1385 	  s = C_OMP_CLAUSE_SPLIT_LOOP;
1386 	  break;
1387 	/* Duplicate this to all of taskloop, distribute, for, simd and
1388 	   loop.  */
1389 	case OMP_CLAUSE_COLLAPSE:
1390 	  if (code == OMP_SIMD)
1391 	    {
1392 	      if ((mask & ((OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)
1393 			   | (OMP_CLAUSE_MASK_1
1394 			      << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)
1395 			   | (OMP_CLAUSE_MASK_1
1396 			      << PRAGMA_OMP_CLAUSE_NOGROUP))) != 0)
1397 		{
1398 		  c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1399 					OMP_CLAUSE_COLLAPSE);
1400 		  OMP_CLAUSE_COLLAPSE_EXPR (c)
1401 		    = OMP_CLAUSE_COLLAPSE_EXPR (clauses);
1402 		  OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
1403 		  cclauses[C_OMP_CLAUSE_SPLIT_SIMD] = c;
1404 		}
1405 	      else
1406 		{
1407 		  /* This must be #pragma omp target simd */
1408 		  s = C_OMP_CLAUSE_SPLIT_SIMD;
1409 		  break;
1410 		}
1411 	    }
1412 	  if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)) != 0)
1413 	    {
1414 	      if ((mask & (OMP_CLAUSE_MASK_1
1415 			   << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
1416 		{
1417 		  c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1418 					OMP_CLAUSE_COLLAPSE);
1419 		  OMP_CLAUSE_COLLAPSE_EXPR (c)
1420 		    = OMP_CLAUSE_COLLAPSE_EXPR (clauses);
1421 		  OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
1422 		  cclauses[C_OMP_CLAUSE_SPLIT_FOR] = c;
1423 		  s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
1424 		}
1425 	      else
1426 		s = C_OMP_CLAUSE_SPLIT_FOR;
1427 	    }
1428 	  else if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP))
1429 		   != 0)
1430 	    s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
1431 	  else if (code == OMP_LOOP)
1432 	    s = C_OMP_CLAUSE_SPLIT_LOOP;
1433 	  else
1434 	    s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
1435 	  break;
1436 	/* Private clause is supported on all constructs but master,
1437 	   it is enough to put it on the innermost one other than master.  For
1438 	   #pragma omp {for,sections} put it on parallel though,
1439 	   as that's what we did for OpenMP 3.1.  */
1440 	case OMP_CLAUSE_PRIVATE:
1441 	  switch (code)
1442 	    {
1443 	    case OMP_SIMD: s = C_OMP_CLAUSE_SPLIT_SIMD; break;
1444 	    case OMP_FOR: case OMP_SECTIONS:
1445 	    case OMP_PARALLEL: s = C_OMP_CLAUSE_SPLIT_PARALLEL; break;
1446 	    case OMP_DISTRIBUTE: s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE; break;
1447 	    case OMP_TEAMS: s = C_OMP_CLAUSE_SPLIT_TEAMS; break;
1448 	    case OMP_MASTER: s = C_OMP_CLAUSE_SPLIT_PARALLEL; break;
1449 	    case OMP_TASKLOOP: s = C_OMP_CLAUSE_SPLIT_TASKLOOP; break;
1450 	    case OMP_LOOP: s = C_OMP_CLAUSE_SPLIT_LOOP; break;
1451 	    default: gcc_unreachable ();
1452 	    }
1453 	  break;
1454 	/* Firstprivate clause is supported on all constructs but
1455 	   simd, master and loop.  Put it on the outermost of those and
1456 	   duplicate on teams and parallel.  */
1457 	case OMP_CLAUSE_FIRSTPRIVATE:
1458 	  if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP))
1459 	      != 0)
1460 	    {
1461 	      if (code == OMP_SIMD
1462 		  && (mask & ((OMP_CLAUSE_MASK_1
1463 			       << PRAGMA_OMP_CLAUSE_NUM_THREADS)
1464 			      | (OMP_CLAUSE_MASK_1
1465 				 << PRAGMA_OMP_CLAUSE_NUM_TEAMS))) == 0)
1466 		{
1467 		  /* This must be #pragma omp target simd.  */
1468 		  s = C_OMP_CLAUSE_SPLIT_TARGET;
1469 		  break;
1470 		}
1471 	      c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1472 				    OMP_CLAUSE_FIRSTPRIVATE);
1473 	      OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
1474 	      OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
1475 	      cclauses[C_OMP_CLAUSE_SPLIT_TARGET] = c;
1476 	    }
1477 	  if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS))
1478 	      != 0)
1479 	    {
1480 	      if ((mask & ((OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS)
1481 			   | (OMP_CLAUSE_MASK_1
1482 			      << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE))) != 0)
1483 		{
1484 		  c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1485 					OMP_CLAUSE_FIRSTPRIVATE);
1486 		  OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
1487 		  OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL];
1488 		  cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] = c;
1489 		  if ((mask & (OMP_CLAUSE_MASK_1
1490 			       << PRAGMA_OMP_CLAUSE_NUM_TEAMS)) != 0)
1491 		    s = C_OMP_CLAUSE_SPLIT_TEAMS;
1492 		  else
1493 		    s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
1494 		}
1495 	      else if ((mask & (OMP_CLAUSE_MASK_1
1496 				<< PRAGMA_OMP_CLAUSE_NOGROUP)) != 0)
1497 		/* This must be
1498 		   #pragma omp parallel master taskloop{, simd}.  */
1499 		s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
1500 	      else
1501 		/* This must be
1502 		   #pragma omp parallel{, for{, simd}, sections,loop}
1503 		   or
1504 		   #pragma omp target parallel.  */
1505 		s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1506 	    }
1507 	  else if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS))
1508 		   != 0)
1509 	    {
1510 	      /* This must be one of
1511 		 #pragma omp {,target }teams {distribute,loop}
1512 		 #pragma omp target teams
1513 		 #pragma omp {,target }teams distribute simd.  */
1514 	      gcc_assert (code == OMP_DISTRIBUTE
1515 			  || code == OMP_LOOP
1516 			  || code == OMP_TEAMS
1517 			  || code == OMP_SIMD);
1518 	      s = C_OMP_CLAUSE_SPLIT_TEAMS;
1519 	    }
1520 	  else if ((mask & (OMP_CLAUSE_MASK_1
1521 			    << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
1522 	    {
1523 	      /* This must be #pragma omp distribute simd.  */
1524 	      gcc_assert (code == OMP_SIMD);
1525 	      s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
1526 	    }
1527 	  else if ((mask & (OMP_CLAUSE_MASK_1
1528 			    << PRAGMA_OMP_CLAUSE_NOGROUP)) != 0)
1529 	    {
1530 	      /* This must be #pragma omp {,{,parallel }master }taskloop simd
1531 		 or
1532 		 #pragma omp {,parallel }master taskloop.  */
1533 	      gcc_assert (code == OMP_SIMD || code == OMP_TASKLOOP);
1534 	      s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
1535 	    }
1536 	  else
1537 	    {
1538 	      /* This must be #pragma omp for simd.  */
1539 	      gcc_assert (code == OMP_SIMD);
1540 	      s = C_OMP_CLAUSE_SPLIT_FOR;
1541 	    }
1542 	  break;
1543 	/* Lastprivate is allowed on distribute, for, sections, taskloop, loop
1544 	   and simd.  In parallel {for{, simd},sections} we actually want to
1545 	   put it on parallel rather than for or sections.  */
1546 	case OMP_CLAUSE_LASTPRIVATE:
1547 	  if (code == OMP_DISTRIBUTE)
1548 	    {
1549 	      s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
1550 	      break;
1551 	    }
1552 	  if ((mask & (OMP_CLAUSE_MASK_1
1553 		       << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
1554 	    {
1555 	      c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1556 				    OMP_CLAUSE_LASTPRIVATE);
1557 	      OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
1558 	      OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
1559 	      OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c)
1560 		= OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (clauses);
1561 	      cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE] = c;
1562 	    }
1563 	  if (code == OMP_FOR || code == OMP_SECTIONS)
1564 	    {
1565 	      if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS))
1566 		  != 0)
1567 		s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1568 	      else
1569 		s = C_OMP_CLAUSE_SPLIT_FOR;
1570 	      break;
1571 	    }
1572 	  if (code == OMP_TASKLOOP)
1573 	    {
1574 	      s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
1575 	      break;
1576 	    }
1577 	  if (code == OMP_LOOP)
1578 	    {
1579 	      s = C_OMP_CLAUSE_SPLIT_LOOP;
1580 	      break;
1581 	    }
1582 	  gcc_assert (code == OMP_SIMD);
1583 	  if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)) != 0)
1584 	    {
1585 	      c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1586 				    OMP_CLAUSE_LASTPRIVATE);
1587 	      OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
1588 	      OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c)
1589 		= OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (clauses);
1590 	      if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS))
1591 		  != 0)
1592 		s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1593 	      else
1594 		s = C_OMP_CLAUSE_SPLIT_FOR;
1595 	      OMP_CLAUSE_CHAIN (c) = cclauses[s];
1596 	      cclauses[s] = c;
1597 	    }
1598 	  if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP)) != 0)
1599 	    {
1600 	      c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1601 				    OMP_CLAUSE_LASTPRIVATE);
1602 	      OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
1603 	      OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c)
1604 		= OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (clauses);
1605 	      OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
1606 	      cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP] = c;
1607 	    }
1608 	  s = C_OMP_CLAUSE_SPLIT_SIMD;
1609 	  break;
1610 	/* Shared and default clauses are allowed on parallel, teams and
1611 	   taskloop.  */
1612 	case OMP_CLAUSE_SHARED:
1613 	case OMP_CLAUSE_DEFAULT:
1614 	  if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP))
1615 	      != 0)
1616 	    {
1617 	      if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS))
1618 		  != 0)
1619 		{
1620 		  c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1621 					OMP_CLAUSE_CODE (clauses));
1622 		  if (OMP_CLAUSE_CODE (clauses) == OMP_CLAUSE_SHARED)
1623 		    OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
1624 		  else
1625 		    OMP_CLAUSE_DEFAULT_KIND (c)
1626 		      = OMP_CLAUSE_DEFAULT_KIND (clauses);
1627 		  OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL];
1628 		  cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] = c;
1629 		}
1630 	      s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
1631 	      break;
1632 	    }
1633 	  if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS))
1634 	      != 0)
1635 	    {
1636 	      if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS))
1637 		  == 0)
1638 		{
1639 		  s = C_OMP_CLAUSE_SPLIT_TEAMS;
1640 		  break;
1641 		}
1642 	      c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1643 				    OMP_CLAUSE_CODE (clauses));
1644 	      if (OMP_CLAUSE_CODE (clauses) == OMP_CLAUSE_SHARED)
1645 		OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
1646 	      else
1647 		OMP_CLAUSE_DEFAULT_KIND (c)
1648 		  = OMP_CLAUSE_DEFAULT_KIND (clauses);
1649 	      OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
1650 	      cclauses[C_OMP_CLAUSE_SPLIT_TEAMS] = c;
1651 	    }
1652 	  s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1653 	  break;
1654 	/* order clauses are allowed on for, simd and loop.  */
1655 	case OMP_CLAUSE_ORDER:
1656 	  if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)) != 0)
1657 	    {
1658 	      if (code == OMP_SIMD)
1659 		{
1660 		  c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1661 					OMP_CLAUSE_ORDER);
1662 		  OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
1663 		  cclauses[C_OMP_CLAUSE_SPLIT_FOR] = c;
1664 		  s = C_OMP_CLAUSE_SPLIT_SIMD;
1665 		}
1666 	      else
1667 		s = C_OMP_CLAUSE_SPLIT_FOR;
1668 	    }
1669 	  else if (code == OMP_LOOP)
1670 	    s = C_OMP_CLAUSE_SPLIT_LOOP;
1671 	  else
1672 	    s = C_OMP_CLAUSE_SPLIT_SIMD;
1673 	  break;
1674 	/* Reduction is allowed on simd, for, parallel, sections, taskloop,
1675 	   teams and loop.  Duplicate it on all of them, but omit on for or
1676 	   sections if parallel is present (unless inscan, in that case
1677 	   omit on parallel).  If taskloop or loop is combined with
1678 	   parallel, omit it on parallel.  */
1679 	case OMP_CLAUSE_REDUCTION:
1680 	  if (OMP_CLAUSE_REDUCTION_TASK (clauses))
1681 	    {
1682 	      if (code == OMP_SIMD || code == OMP_LOOP)
1683 		{
1684 		  error_at (OMP_CLAUSE_LOCATION (clauses),
1685 			    "invalid %<task%> reduction modifier on construct "
1686 			    "combined with %<simd%> or %<loop%>");
1687 		  OMP_CLAUSE_REDUCTION_TASK (clauses) = 0;
1688 		}
1689 	      else if (code != OMP_SECTIONS
1690 		       && (mask & (OMP_CLAUSE_MASK_1
1691 				   << PRAGMA_OMP_CLAUSE_NUM_THREADS)) == 0
1692 		       && (mask & (OMP_CLAUSE_MASK_1
1693 				   << PRAGMA_OMP_CLAUSE_SCHEDULE)) == 0)
1694 		{
1695 		  error_at (OMP_CLAUSE_LOCATION (clauses),
1696 			    "invalid %<task%> reduction modifier on construct "
1697 			    "not combined with %<parallel%>, %<for%> or "
1698 			    "%<sections%>");
1699 		  OMP_CLAUSE_REDUCTION_TASK (clauses) = 0;
1700 		}
1701 	    }
1702 	  if (OMP_CLAUSE_REDUCTION_INSCAN (clauses)
1703 	      && ((mask & ((OMP_CLAUSE_MASK_1
1704 			    << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)
1705 			   | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)))
1706 		  != 0))
1707 	    {
1708 	      error_at (OMP_CLAUSE_LOCATION (clauses),
1709 			"%<inscan%> %<reduction%> clause on construct other "
1710 			"than %<for%>, %<simd%>, %<for simd%>, "
1711 			"%<parallel for%>, %<parallel for simd%>");
1712 	      OMP_CLAUSE_REDUCTION_INSCAN (clauses) = 0;
1713 	    }
1714 	  if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)) != 0)
1715 	    {
1716 	      if (code == OMP_SIMD)
1717 		{
1718 		  c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1719 					OMP_CLAUSE_REDUCTION);
1720 		  OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
1721 		  OMP_CLAUSE_REDUCTION_CODE (c)
1722 		    = OMP_CLAUSE_REDUCTION_CODE (clauses);
1723 		  OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
1724 		    = OMP_CLAUSE_REDUCTION_PLACEHOLDER (clauses);
1725 		  OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c)
1726 		    = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (clauses);
1727 		  OMP_CLAUSE_REDUCTION_INSCAN (c)
1728 		    = OMP_CLAUSE_REDUCTION_INSCAN (clauses);
1729 		  OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
1730 		  cclauses[C_OMP_CLAUSE_SPLIT_SIMD] = c;
1731 		}
1732 	      if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS))
1733 		  != 0)
1734 		{
1735 		  c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1736 					OMP_CLAUSE_REDUCTION);
1737 		  OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
1738 		  OMP_CLAUSE_REDUCTION_CODE (c)
1739 		    = OMP_CLAUSE_REDUCTION_CODE (clauses);
1740 		  OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
1741 		    = OMP_CLAUSE_REDUCTION_PLACEHOLDER (clauses);
1742 		  OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c)
1743 		    = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (clauses);
1744 		  OMP_CLAUSE_REDUCTION_INSCAN (c)
1745 		    = OMP_CLAUSE_REDUCTION_INSCAN (clauses);
1746 		  OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
1747 		  cclauses[C_OMP_CLAUSE_SPLIT_TEAMS] = c;
1748 		  s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1749 		}
1750 	      else if ((mask & (OMP_CLAUSE_MASK_1
1751 				<< PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0
1752 		       && !OMP_CLAUSE_REDUCTION_INSCAN (clauses))
1753 		s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1754 	      else
1755 		s = C_OMP_CLAUSE_SPLIT_FOR;
1756 	    }
1757 	  else if (code == OMP_SECTIONS
1758 		   || code == OMP_PARALLEL
1759 		   || code == OMP_MASTER)
1760 	    s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1761 	  else if (code == OMP_TASKLOOP)
1762 	    s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
1763 	  else if (code == OMP_LOOP)
1764 	    s = C_OMP_CLAUSE_SPLIT_LOOP;
1765 	  else if (code == OMP_SIMD)
1766 	    {
1767 	      if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP))
1768 		  != 0)
1769 		{
1770 		  c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1771 					OMP_CLAUSE_REDUCTION);
1772 		  OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
1773 		  OMP_CLAUSE_REDUCTION_CODE (c)
1774 		    = OMP_CLAUSE_REDUCTION_CODE (clauses);
1775 		  OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
1776 		    = OMP_CLAUSE_REDUCTION_PLACEHOLDER (clauses);
1777 		  OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c)
1778 		    = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (clauses);
1779 		  OMP_CLAUSE_REDUCTION_INSCAN (c)
1780 		    = OMP_CLAUSE_REDUCTION_INSCAN (clauses);
1781 		  OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
1782 		  cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP] = c;
1783 		}
1784 	      s = C_OMP_CLAUSE_SPLIT_SIMD;
1785 	    }
1786 	  else
1787 	    s = C_OMP_CLAUSE_SPLIT_TEAMS;
1788 	  break;
1789 	case OMP_CLAUSE_IN_REDUCTION:
1790 	  /* in_reduction on taskloop simd becomes reduction on the simd
1791 	     and keeps being in_reduction on taskloop.  */
1792 	  if (code == OMP_SIMD)
1793 	    {
1794 	      c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1795 				    OMP_CLAUSE_REDUCTION);
1796 	      OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
1797 	      OMP_CLAUSE_REDUCTION_CODE (c)
1798 		= OMP_CLAUSE_REDUCTION_CODE (clauses);
1799 	      OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
1800 		= OMP_CLAUSE_REDUCTION_PLACEHOLDER (clauses);
1801 	      OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c)
1802 		= OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (clauses);
1803 	      OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
1804 	      cclauses[C_OMP_CLAUSE_SPLIT_SIMD] = c;
1805 	    }
1806 	  s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
1807 	  break;
1808 	case OMP_CLAUSE_IF:
1809 	  if (OMP_CLAUSE_IF_MODIFIER (clauses) != ERROR_MARK)
1810 	    {
1811 	      s = C_OMP_CLAUSE_SPLIT_COUNT;
1812 	      switch (OMP_CLAUSE_IF_MODIFIER (clauses))
1813 		{
1814 		case OMP_PARALLEL:
1815 		  if ((mask & (OMP_CLAUSE_MASK_1
1816 			       << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
1817 		    s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1818 		  break;
1819 		case OMP_SIMD:
1820 		  if (code == OMP_SIMD)
1821 		    s = C_OMP_CLAUSE_SPLIT_SIMD;
1822 		  break;
1823 		case OMP_TASKLOOP:
1824 		  if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP))
1825 		      != 0)
1826 		    s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
1827 		  break;
1828 		case OMP_TARGET:
1829 		  if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP))
1830 		      != 0)
1831 		    s = C_OMP_CLAUSE_SPLIT_TARGET;
1832 		  break;
1833 		default:
1834 		  break;
1835 		}
1836 	      if (s != C_OMP_CLAUSE_SPLIT_COUNT)
1837 		break;
1838 	      /* Error-recovery here, invalid if-modifier specified, add the
1839 		 clause to just one construct.  */
1840 	      if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) != 0)
1841 		s = C_OMP_CLAUSE_SPLIT_TARGET;
1842 	      else if ((mask & (OMP_CLAUSE_MASK_1
1843 				<< PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
1844 		s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1845 	      else if ((mask & (OMP_CLAUSE_MASK_1
1846 				<< PRAGMA_OMP_CLAUSE_NOGROUP)) != 0)
1847 		s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
1848 	      else if (code == OMP_SIMD)
1849 		s = C_OMP_CLAUSE_SPLIT_SIMD;
1850 	      else
1851 		gcc_unreachable ();
1852 	      break;
1853 	    }
1854 	  /* Otherwise, duplicate if clause to all constructs.  */
1855 	  if (code == OMP_SIMD)
1856 	    {
1857 	      if ((mask & ((OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)
1858 			   | (OMP_CLAUSE_MASK_1
1859 			      << PRAGMA_OMP_CLAUSE_NUM_THREADS)
1860 			   | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP)))
1861 		  != 0)
1862 		{
1863 		  c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1864 					OMP_CLAUSE_IF);
1865 		  OMP_CLAUSE_IF_MODIFIER (c)
1866 		    = OMP_CLAUSE_IF_MODIFIER (clauses);
1867 		  OMP_CLAUSE_IF_EXPR (c) = OMP_CLAUSE_IF_EXPR (clauses);
1868 		  OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
1869 		  cclauses[C_OMP_CLAUSE_SPLIT_SIMD] = c;
1870 		}
1871 	      else
1872 		{
1873 		  s = C_OMP_CLAUSE_SPLIT_SIMD;
1874 		  break;
1875 		}
1876 	    }
1877 	  if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP))
1878 	      != 0)
1879 	    {
1880 	      if ((mask & (OMP_CLAUSE_MASK_1
1881 			   << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
1882 		{
1883 		  c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1884 					OMP_CLAUSE_IF);
1885 		  OMP_CLAUSE_IF_MODIFIER (c)
1886 		    = OMP_CLAUSE_IF_MODIFIER (clauses);
1887 		  OMP_CLAUSE_IF_EXPR (c) = OMP_CLAUSE_IF_EXPR (clauses);
1888 		  OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
1889 		  cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP] = c;
1890 		  s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1891 		}
1892 	      else
1893 		s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
1894 	    }
1895 	  else if ((mask & (OMP_CLAUSE_MASK_1
1896 			    << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
1897 	    {
1898 	      if ((mask & (OMP_CLAUSE_MASK_1
1899 			   << PRAGMA_OMP_CLAUSE_MAP)) != 0)
1900 		{
1901 		  c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
1902 					OMP_CLAUSE_IF);
1903 		  OMP_CLAUSE_IF_MODIFIER (c)
1904 		    = OMP_CLAUSE_IF_MODIFIER (clauses);
1905 		  OMP_CLAUSE_IF_EXPR (c) = OMP_CLAUSE_IF_EXPR (clauses);
1906 		  OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
1907 		  cclauses[C_OMP_CLAUSE_SPLIT_TARGET] = c;
1908 		  s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1909 		}
1910 	      else
1911 		s = C_OMP_CLAUSE_SPLIT_PARALLEL;
1912 	    }
1913 	  else
1914 	    s = C_OMP_CLAUSE_SPLIT_TARGET;
1915 	  break;
1916 	case OMP_CLAUSE_LINEAR:
1917 	  /* Linear clause is allowed on simd and for.  Put it on the
1918 	     innermost construct.  */
1919 	  if (code == OMP_SIMD)
1920 	    s = C_OMP_CLAUSE_SPLIT_SIMD;
1921 	  else
1922 	    s = C_OMP_CLAUSE_SPLIT_FOR;
1923 	  break;
1924 	case OMP_CLAUSE_NOWAIT:
1925 	  /* Nowait clause is allowed on target, for and sections, but
1926 	     is not allowed on parallel for or parallel sections.  Therefore,
1927 	     put it on target construct if present, because that can only
1928 	     be combined with parallel for{, simd} and not with for{, simd},
1929 	     otherwise to the worksharing construct.  */
1930 	  if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP))
1931 	      != 0)
1932 	    s = C_OMP_CLAUSE_SPLIT_TARGET;
1933 	  else
1934 	    s = C_OMP_CLAUSE_SPLIT_FOR;
1935 	  break;
1936 	default:
1937 	  gcc_unreachable ();
1938 	}
1939       OMP_CLAUSE_CHAIN (clauses) = cclauses[s];
1940       cclauses[s] = clauses;
1941     }
1942 
1943   if (!flag_checking)
1944     return;
1945 
1946   if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) == 0)
1947     gcc_assert (cclauses[C_OMP_CLAUSE_SPLIT_TARGET] == NULL_TREE);
1948   if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS)) == 0)
1949     gcc_assert (cclauses[C_OMP_CLAUSE_SPLIT_TEAMS] == NULL_TREE);
1950   if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) == 0)
1951     gcc_assert (cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE] == NULL_TREE);
1952   if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) == 0)
1953     gcc_assert (cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] == NULL_TREE);
1954   if ((mask & ((OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)
1955 	       | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP))) == 0
1956       && code != OMP_SECTIONS
1957       && code != OMP_LOOP)
1958     gcc_assert (cclauses[C_OMP_CLAUSE_SPLIT_FOR] == NULL_TREE);
1959   if (code != OMP_SIMD)
1960     gcc_assert (cclauses[C_OMP_CLAUSE_SPLIT_SIMD] == NULL_TREE);
1961 }
1962 
1963 
1964 /* qsort callback to compare #pragma omp declare simd clauses.  */
1965 
1966 static int
c_omp_declare_simd_clause_cmp(const void * p,const void * q)1967 c_omp_declare_simd_clause_cmp (const void *p, const void *q)
1968 {
1969   tree a = *(const tree *) p;
1970   tree b = *(const tree *) q;
1971   if (OMP_CLAUSE_CODE (a) != OMP_CLAUSE_CODE (b))
1972     {
1973       if (OMP_CLAUSE_CODE (a) > OMP_CLAUSE_CODE (b))
1974 	return -1;
1975       return 1;
1976     }
1977   if (OMP_CLAUSE_CODE (a) != OMP_CLAUSE_SIMDLEN
1978       && OMP_CLAUSE_CODE (a) != OMP_CLAUSE_INBRANCH
1979       && OMP_CLAUSE_CODE (a) != OMP_CLAUSE_NOTINBRANCH)
1980     {
1981       int c = tree_to_shwi (OMP_CLAUSE_DECL (a));
1982       int d = tree_to_shwi (OMP_CLAUSE_DECL (b));
1983       if (c < d)
1984 	return 1;
1985       if (c > d)
1986 	return -1;
1987     }
1988   return 0;
1989 }
1990 
1991 /* Change PARM_DECLs in OMP_CLAUSE_DECL of #pragma omp declare simd
1992    CLAUSES on FNDECL into argument indexes and sort them.  */
1993 
1994 tree
c_omp_declare_simd_clauses_to_numbers(tree parms,tree clauses)1995 c_omp_declare_simd_clauses_to_numbers (tree parms, tree clauses)
1996 {
1997   tree c;
1998   vec<tree> clvec = vNULL;
1999 
2000   for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
2001     {
2002       if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_SIMDLEN
2003 	  && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_INBRANCH
2004 	  && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_NOTINBRANCH)
2005 	{
2006 	  tree decl = OMP_CLAUSE_DECL (c);
2007 	  tree arg;
2008 	  int idx;
2009 	  for (arg = parms, idx = 0; arg;
2010 	       arg = TREE_CHAIN (arg), idx++)
2011 	    if (arg == decl)
2012 	      break;
2013 	  if (arg == NULL_TREE)
2014 	    {
2015 	      error_at (OMP_CLAUSE_LOCATION (c),
2016 			"%qD is not a function argument", decl);
2017 	      continue;
2018 	    }
2019 	  OMP_CLAUSE_DECL (c) = build_int_cst (integer_type_node, idx);
2020 	  if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
2021 	      && OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (c))
2022 	    {
2023 	      decl = OMP_CLAUSE_LINEAR_STEP (c);
2024 	      for (arg = parms, idx = 0; arg;
2025 		   arg = TREE_CHAIN (arg), idx++)
2026 		if (arg == decl)
2027 		  break;
2028 	      if (arg == NULL_TREE)
2029 		{
2030 		  error_at (OMP_CLAUSE_LOCATION (c),
2031 			    "%qD is not a function argument", decl);
2032 		  continue;
2033 		}
2034 	      OMP_CLAUSE_LINEAR_STEP (c)
2035 		= build_int_cst (integer_type_node, idx);
2036 	    }
2037 	}
2038       clvec.safe_push (c);
2039     }
2040   if (!clvec.is_empty ())
2041     {
2042       unsigned int len = clvec.length (), i;
2043       clvec.qsort (c_omp_declare_simd_clause_cmp);
2044       clauses = clvec[0];
2045       for (i = 0; i < len; i++)
2046 	OMP_CLAUSE_CHAIN (clvec[i]) = (i < len - 1) ? clvec[i + 1] : NULL_TREE;
2047     }
2048   else
2049     clauses = NULL_TREE;
2050   clvec.release ();
2051   return clauses;
2052 }
2053 
2054 /* Change argument indexes in CLAUSES of FNDECL back to PARM_DECLs.  */
2055 
2056 void
c_omp_declare_simd_clauses_to_decls(tree fndecl,tree clauses)2057 c_omp_declare_simd_clauses_to_decls (tree fndecl, tree clauses)
2058 {
2059   tree c;
2060 
2061   for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
2062     if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_SIMDLEN
2063 	&& OMP_CLAUSE_CODE (c) != OMP_CLAUSE_INBRANCH
2064 	&& OMP_CLAUSE_CODE (c) != OMP_CLAUSE_NOTINBRANCH)
2065       {
2066 	int idx = tree_to_shwi (OMP_CLAUSE_DECL (c)), i;
2067 	tree arg;
2068 	for (arg = DECL_ARGUMENTS (fndecl), i = 0; arg;
2069 	     arg = TREE_CHAIN (arg), i++)
2070 	  if (i == idx)
2071 	    break;
2072 	gcc_assert (arg);
2073 	OMP_CLAUSE_DECL (c) = arg;
2074 	if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
2075 	    && OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (c))
2076 	  {
2077 	    idx = tree_to_shwi (OMP_CLAUSE_LINEAR_STEP (c));
2078 	    for (arg = DECL_ARGUMENTS (fndecl), i = 0; arg;
2079 		 arg = TREE_CHAIN (arg), i++)
2080 	      if (i == idx)
2081 		break;
2082 	    gcc_assert (arg);
2083 	    OMP_CLAUSE_LINEAR_STEP (c) = arg;
2084 	  }
2085       }
2086 }
2087 
2088 /* Return true for __func__ and similar function-local predefined
2089    variables (which are in OpenMP predetermined shared, allowed in
2090    shared/firstprivate clauses).  */
2091 
2092 bool
c_omp_predefined_variable(tree decl)2093 c_omp_predefined_variable (tree decl)
2094 {
2095   if (VAR_P (decl)
2096       && DECL_ARTIFICIAL (decl)
2097       && TREE_STATIC (decl)
2098       && DECL_NAME (decl))
2099     {
2100       if (TREE_READONLY (decl)
2101 	  && (DECL_NAME (decl) == ridpointers[RID_C99_FUNCTION_NAME]
2102 	      || DECL_NAME (decl) == ridpointers[RID_FUNCTION_NAME]
2103 	      || DECL_NAME (decl) == ridpointers[RID_PRETTY_FUNCTION_NAME]))
2104 	return true;
2105       /* For UBSan handle the same also ubsan_create_data created
2106 	 variables.  There is no magic flag for those, but user variables
2107 	 shouldn't be DECL_ARTIFICIAL or have TYPE_ARTIFICIAL type with
2108 	 such names.  */
2109       if ((flag_sanitize & (SANITIZE_UNDEFINED
2110 			    | SANITIZE_UNDEFINED_NONDEFAULT)) != 0
2111 	  && DECL_IGNORED_P (decl)
2112 	  && !TREE_READONLY (decl)
2113 	  && TREE_CODE (DECL_NAME (decl)) == IDENTIFIER_NODE
2114 	  && TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE
2115 	  && TYPE_ARTIFICIAL (TREE_TYPE (decl))
2116 	  && TYPE_NAME (TREE_TYPE (decl))
2117 	  && TREE_CODE (TYPE_NAME (TREE_TYPE (decl))) == TYPE_DECL
2118 	  && DECL_NAME (TYPE_NAME (TREE_TYPE (decl)))
2119 	  && (TREE_CODE (DECL_NAME (TYPE_NAME (TREE_TYPE (decl))))
2120 	      == IDENTIFIER_NODE))
2121 	{
2122 	  tree id1 = DECL_NAME (decl);
2123 	  tree id2 = DECL_NAME (TYPE_NAME (TREE_TYPE (decl)));
2124 	  if (IDENTIFIER_LENGTH (id1) >= sizeof ("ubsan_data") - 1
2125 	      && IDENTIFIER_LENGTH (id2) >= sizeof ("__ubsan__data")
2126 	      && !memcmp (IDENTIFIER_POINTER (id2), "__ubsan_",
2127 			  sizeof ("__ubsan_") - 1)
2128 	      && !memcmp (IDENTIFIER_POINTER (id2) + IDENTIFIER_LENGTH (id2)
2129 			  - sizeof ("_data") + 1, "_data",
2130 			  sizeof ("_data") - 1)
2131 	      && strstr (IDENTIFIER_POINTER (id1), "ubsan_data"))
2132 	    return true;
2133 	}
2134     }
2135   return false;
2136 }
2137 
2138 /* True if OpenMP sharing attribute of DECL is predetermined.  */
2139 
2140 enum omp_clause_default_kind
c_omp_predetermined_sharing(tree decl)2141 c_omp_predetermined_sharing (tree decl)
2142 {
2143   /* Predetermine artificial variables holding integral values, those
2144      are usually result of gimplify_one_sizepos or SAVE_EXPR
2145      gimplification.  */
2146   if (VAR_P (decl)
2147       && DECL_ARTIFICIAL (decl)
2148       && INTEGRAL_TYPE_P (TREE_TYPE (decl)))
2149     return OMP_CLAUSE_DEFAULT_SHARED;
2150 
2151   if (c_omp_predefined_variable (decl))
2152     return OMP_CLAUSE_DEFAULT_SHARED;
2153 
2154   return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
2155 }
2156 
2157 /* Diagnose errors in an OpenMP context selector, return CTX if
2158    it is correct or error_mark_node otherwise.  */
2159 
2160 tree
c_omp_check_context_selector(location_t loc,tree ctx)2161 c_omp_check_context_selector (location_t loc, tree ctx)
2162 {
2163   /* Each trait-set-selector-name can only be specified once.
2164      There are just 4 set names.  */
2165   for (tree t1 = ctx; t1; t1 = TREE_CHAIN (t1))
2166     for (tree t2 = TREE_CHAIN (t1); t2; t2 = TREE_CHAIN (t2))
2167       if (TREE_PURPOSE (t1) == TREE_PURPOSE (t2))
2168 	{
2169 	  error_at (loc, "selector set %qs specified more than once",
2170 	  	    IDENTIFIER_POINTER (TREE_PURPOSE (t1)));
2171 	  return error_mark_node;
2172 	}
2173   for (tree t = ctx; t; t = TREE_CHAIN (t))
2174     {
2175       /* Each trait-selector-name can only be specified once.  */
2176       if (list_length (TREE_VALUE (t)) < 5)
2177 	{
2178 	  for (tree t1 = TREE_VALUE (t); t1; t1 = TREE_CHAIN (t1))
2179 	    for (tree t2 = TREE_CHAIN (t1); t2; t2 = TREE_CHAIN (t2))
2180 	      if (TREE_PURPOSE (t1) == TREE_PURPOSE (t2))
2181 		{
2182 		  error_at (loc,
2183 			    "selector %qs specified more than once in set %qs",
2184 			    IDENTIFIER_POINTER (TREE_PURPOSE (t1)),
2185 			    IDENTIFIER_POINTER (TREE_PURPOSE (t)));
2186 		  return error_mark_node;
2187 		}
2188 	}
2189       else
2190 	{
2191 	  hash_set<tree> pset;
2192 	  for (tree t1 = TREE_VALUE (t); t1; t1 = TREE_CHAIN (t1))
2193 	    if (pset.add (TREE_PURPOSE (t1)))
2194 	      {
2195 		error_at (loc,
2196 			  "selector %qs specified more than once in set %qs",
2197 			  IDENTIFIER_POINTER (TREE_PURPOSE (t1)),
2198 			  IDENTIFIER_POINTER (TREE_PURPOSE (t)));
2199 		return error_mark_node;
2200 	      }
2201 	}
2202 
2203       static const char *const kind[] = {
2204 	"host", "nohost", "cpu", "gpu", "fpga", "any", NULL };
2205       static const char *const vendor[] = {
2206 	"amd", "arm", "bsc", "cray", "fujitsu", "gnu", "ibm", "intel",
2207 	"llvm", "nvidia", "pgi", "ti", "unknown", NULL };
2208       static const char *const extension[] = { NULL };
2209       static const char *const atomic_default_mem_order[] = {
2210 	"seq_cst", "relaxed", "acq_rel", NULL };
2211       struct known_properties { const char *set; const char *selector;
2212 				const char *const *props; };
2213       known_properties props[] = {
2214 	{ "device", "kind", kind },
2215 	{ "implementation", "vendor", vendor },
2216 	{ "implementation", "extension", extension },
2217 	{ "implementation", "atomic_default_mem_order",
2218 	  atomic_default_mem_order } };
2219       for (tree t1 = TREE_VALUE (t); t1; t1 = TREE_CHAIN (t1))
2220 	for (unsigned i = 0; i < ARRAY_SIZE (props); i++)
2221 	  if (!strcmp (IDENTIFIER_POINTER (TREE_PURPOSE (t1)),
2222 					   props[i].selector)
2223 	      && !strcmp (IDENTIFIER_POINTER (TREE_PURPOSE (t)),
2224 					      props[i].set))
2225 	    for (tree t2 = TREE_VALUE (t1); t2; t2 = TREE_CHAIN (t2))
2226 	      for (unsigned j = 0; ; j++)
2227 		{
2228 		  if (props[i].props[j] == NULL)
2229 		    {
2230 		      if (TREE_PURPOSE (t2)
2231 			  && !strcmp (IDENTIFIER_POINTER (TREE_PURPOSE (t2)),
2232 				      " score"))
2233 			break;
2234 		      if (props[i].props == atomic_default_mem_order)
2235 			{
2236 			  error_at (loc,
2237 				    "incorrect property %qs of %qs selector",
2238 				    IDENTIFIER_POINTER (TREE_PURPOSE (t2)),
2239 				    "atomic_default_mem_order");
2240 			  return error_mark_node;
2241 			}
2242 		      else if (TREE_PURPOSE (t2))
2243 			warning_at (loc, 0,
2244 				    "unknown property %qs of %qs selector",
2245 				    IDENTIFIER_POINTER (TREE_PURPOSE (t2)),
2246 				    props[i].selector);
2247 		      else
2248 			warning_at (loc, 0,
2249 				    "unknown property %qE of %qs selector",
2250 				    TREE_VALUE (t2), props[i].selector);
2251 		      break;
2252 		    }
2253 		  else if (TREE_PURPOSE (t2) == NULL_TREE)
2254 		    {
2255 		      const char *str = TREE_STRING_POINTER (TREE_VALUE (t2));
2256 		      if (!strcmp (str, props[i].props[j])
2257 			  && ((size_t) TREE_STRING_LENGTH (TREE_VALUE (t2))
2258 			      == strlen (str) + 1))
2259 			break;
2260 		    }
2261 		  else if (!strcmp (IDENTIFIER_POINTER (TREE_PURPOSE (t2)),
2262 				    props[i].props[j]))
2263 		    break;
2264 		}
2265     }
2266   return ctx;
2267 }
2268 
2269 /* Register VARIANT as variant of some base function marked with
2270    #pragma omp declare variant.  CONSTRUCT is corresponding construct
2271    selector set.  */
2272 
2273 void
c_omp_mark_declare_variant(location_t loc,tree variant,tree construct)2274 c_omp_mark_declare_variant (location_t loc, tree variant, tree construct)
2275 {
2276   tree attr = lookup_attribute ("omp declare variant variant",
2277 				DECL_ATTRIBUTES (variant));
2278   if (attr == NULL_TREE)
2279     {
2280       attr = tree_cons (get_identifier ("omp declare variant variant"),
2281 			unshare_expr (construct),
2282 			DECL_ATTRIBUTES (variant));
2283       DECL_ATTRIBUTES (variant) = attr;
2284       return;
2285     }
2286   if ((TREE_VALUE (attr) != NULL_TREE) != (construct != NULL_TREE)
2287       || (construct != NULL_TREE
2288 	  && omp_context_selector_set_compare ("construct", TREE_VALUE (attr),
2289 					       construct)))
2290     error_at (loc, "%qD used as a variant with incompatible %<construct%> "
2291 		   "selector sets", variant);
2292 }
2293 
2294 /* For OpenACC, the OMP_CLAUSE_MAP_KIND of an OMP_CLAUSE_MAP is used internally
2295    to distinguish clauses as seen by the user.  Return the "friendly" clause
2296    name for error messages etc., where possible.  See also
2297    c/c-parser.c:c_parser_oacc_data_clause and
2298    cp/parser.c:cp_parser_oacc_data_clause.  */
2299 
2300 const char *
c_omp_map_clause_name(tree clause,bool oacc)2301 c_omp_map_clause_name (tree clause, bool oacc)
2302 {
2303   if (oacc && OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_MAP)
2304     switch (OMP_CLAUSE_MAP_KIND (clause))
2305     {
2306     case GOMP_MAP_FORCE_ALLOC:
2307     case GOMP_MAP_ALLOC: return "create";
2308     case GOMP_MAP_FORCE_TO:
2309     case GOMP_MAP_TO: return "copyin";
2310     case GOMP_MAP_FORCE_FROM:
2311     case GOMP_MAP_FROM: return "copyout";
2312     case GOMP_MAP_FORCE_TOFROM:
2313     case GOMP_MAP_TOFROM: return "copy";
2314     case GOMP_MAP_RELEASE: return "delete";
2315     case GOMP_MAP_FORCE_PRESENT: return "present";
2316     case GOMP_MAP_ATTACH: return "attach";
2317     case GOMP_MAP_FORCE_DETACH:
2318     case GOMP_MAP_DETACH: return "detach";
2319     case GOMP_MAP_DEVICE_RESIDENT: return "device_resident";
2320     case GOMP_MAP_LINK: return "link";
2321     case GOMP_MAP_FORCE_DEVICEPTR: return "deviceptr";
2322     default: break;
2323     }
2324   return omp_clause_code_name[OMP_CLAUSE_CODE (clause)];
2325 }
2326