Add function part to a same comdat group (PR ipa/80212).
[official-gcc.git] / gcc / fortran / trans-openmp.c
blob662036f514db105c685deacc1a4da19b88b037d9
1 /* OpenMP directive translation -- generate GCC trees from gfc_code.
2 Copyright (C) 2005-2017 Free Software Foundation, Inc.
3 Contributed by Jakub Jelinek <jakub@redhat.com>
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "options.h"
26 #include "tree.h"
27 #include "gfortran.h"
28 #include "gimple-expr.h"
29 #include "trans.h"
30 #include "stringpool.h"
31 #include "fold-const.h"
32 #include "gimplify.h" /* For create_tmp_var_raw. */
33 #include "trans-stmt.h"
34 #include "trans-types.h"
35 #include "trans-array.h"
36 #include "trans-const.h"
37 #include "arith.h"
38 #include "gomp-constants.h"
39 #include "omp-general.h"
40 #include "omp-low.h"
41 #undef GCC_DIAG_STYLE
42 #define GCC_DIAG_STYLE __gcc_tdiag__
43 #include "diagnostic-core.h"
44 #undef GCC_DIAG_STYLE
45 #define GCC_DIAG_STYLE __gcc_gfc__
47 int ompws_flags;
49 /* True if OpenMP should privatize what this DECL points to rather
50 than the DECL itself. */
52 bool
53 gfc_omp_privatize_by_reference (const_tree decl)
55 tree type = TREE_TYPE (decl);
57 if (TREE_CODE (type) == REFERENCE_TYPE
58 && (!DECL_ARTIFICIAL (decl) || TREE_CODE (decl) == PARM_DECL))
59 return true;
61 if (TREE_CODE (type) == POINTER_TYPE)
63 /* Array POINTER/ALLOCATABLE have aggregate types, all user variables
64 that have POINTER_TYPE type and aren't scalar pointers, scalar
65 allocatables, Cray pointees or C pointers are supposed to be
66 privatized by reference. */
67 if (GFC_DECL_GET_SCALAR_POINTER (decl)
68 || GFC_DECL_GET_SCALAR_ALLOCATABLE (decl)
69 || GFC_DECL_CRAY_POINTEE (decl)
70 || GFC_DECL_ASSOCIATE_VAR_P (decl)
71 || VOID_TYPE_P (TREE_TYPE (TREE_TYPE (decl))))
72 return false;
74 if (!DECL_ARTIFICIAL (decl)
75 && TREE_CODE (TREE_TYPE (type)) != FUNCTION_TYPE)
76 return true;
78 /* Some arrays are expanded as DECL_ARTIFICIAL pointers
79 by the frontend. */
80 if (DECL_LANG_SPECIFIC (decl)
81 && GFC_DECL_SAVED_DESCRIPTOR (decl))
82 return true;
85 return false;
88 /* True if OpenMP sharing attribute of DECL is predetermined. */
90 enum omp_clause_default_kind
91 gfc_omp_predetermined_sharing (tree decl)
93 /* Associate names preserve the association established during ASSOCIATE.
94 As they are implemented either as pointers to the selector or array
95 descriptor and shouldn't really change in the ASSOCIATE region,
96 this decl can be either shared or firstprivate. If it is a pointer,
97 use firstprivate, as it is cheaper that way, otherwise make it shared. */
98 if (GFC_DECL_ASSOCIATE_VAR_P (decl))
100 if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
101 return OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
102 else
103 return OMP_CLAUSE_DEFAULT_SHARED;
106 if (DECL_ARTIFICIAL (decl)
107 && ! GFC_DECL_RESULT (decl)
108 && ! (DECL_LANG_SPECIFIC (decl)
109 && GFC_DECL_SAVED_DESCRIPTOR (decl)))
110 return OMP_CLAUSE_DEFAULT_SHARED;
112 /* Cray pointees shouldn't be listed in any clauses and should be
113 gimplified to dereference of the corresponding Cray pointer.
114 Make them all private, so that they are emitted in the debug
115 information. */
116 if (GFC_DECL_CRAY_POINTEE (decl))
117 return OMP_CLAUSE_DEFAULT_PRIVATE;
119 /* Assumed-size arrays are predetermined shared. */
120 if (TREE_CODE (decl) == PARM_DECL
121 && GFC_ARRAY_TYPE_P (TREE_TYPE (decl))
122 && GFC_TYPE_ARRAY_AKIND (TREE_TYPE (decl)) == GFC_ARRAY_UNKNOWN
123 && GFC_TYPE_ARRAY_UBOUND (TREE_TYPE (decl),
124 GFC_TYPE_ARRAY_RANK (TREE_TYPE (decl)) - 1)
125 == NULL)
126 return OMP_CLAUSE_DEFAULT_SHARED;
128 /* Dummy procedures aren't considered variables by OpenMP, thus are
129 disallowed in OpenMP clauses. They are represented as PARM_DECLs
130 in the middle-end, so return OMP_CLAUSE_DEFAULT_FIRSTPRIVATE here
131 to avoid complaining about their uses with default(none). */
132 if (TREE_CODE (decl) == PARM_DECL
133 && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
134 && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == FUNCTION_TYPE)
135 return OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
137 /* COMMON and EQUIVALENCE decls are shared. They
138 are only referenced through DECL_VALUE_EXPR of the variables
139 contained in them. If those are privatized, they will not be
140 gimplified to the COMMON or EQUIVALENCE decls. */
141 if (GFC_DECL_COMMON_OR_EQUIV (decl) && ! DECL_HAS_VALUE_EXPR_P (decl))
142 return OMP_CLAUSE_DEFAULT_SHARED;
144 if (GFC_DECL_RESULT (decl) && ! DECL_HAS_VALUE_EXPR_P (decl))
145 return OMP_CLAUSE_DEFAULT_SHARED;
147 /* These are either array or derived parameters, or vtables.
148 In the former cases, the OpenMP standard doesn't consider them to be
149 variables at all (they can't be redefined), but they can nevertheless appear
150 in parallel/task regions and for default(none) purposes treat them as shared.
151 For vtables likely the same handling is desirable. */
152 if (VAR_P (decl) && TREE_READONLY (decl) && TREE_STATIC (decl))
153 return OMP_CLAUSE_DEFAULT_SHARED;
155 return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
158 /* Return decl that should be used when reporting DEFAULT(NONE)
159 diagnostics. */
161 tree
162 gfc_omp_report_decl (tree decl)
164 if (DECL_ARTIFICIAL (decl)
165 && DECL_LANG_SPECIFIC (decl)
166 && GFC_DECL_SAVED_DESCRIPTOR (decl))
167 return GFC_DECL_SAVED_DESCRIPTOR (decl);
169 return decl;
172 /* Return true if TYPE has any allocatable components. */
174 static bool
175 gfc_has_alloc_comps (tree type, tree decl)
177 tree field, ftype;
179 if (POINTER_TYPE_P (type))
181 if (GFC_DECL_GET_SCALAR_ALLOCATABLE (decl))
182 type = TREE_TYPE (type);
183 else if (GFC_DECL_GET_SCALAR_POINTER (decl))
184 return false;
187 if (GFC_DESCRIPTOR_TYPE_P (type) || GFC_ARRAY_TYPE_P (type))
188 type = gfc_get_element_type (type);
190 if (TREE_CODE (type) != RECORD_TYPE)
191 return false;
193 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
195 ftype = TREE_TYPE (field);
196 if (GFC_DECL_GET_SCALAR_ALLOCATABLE (field))
197 return true;
198 if (GFC_DESCRIPTOR_TYPE_P (ftype)
199 && GFC_TYPE_ARRAY_AKIND (ftype) == GFC_ARRAY_ALLOCATABLE)
200 return true;
201 if (gfc_has_alloc_comps (ftype, field))
202 return true;
204 return false;
207 /* Return true if DECL in private clause needs
208 OMP_CLAUSE_PRIVATE_OUTER_REF on the private clause. */
209 bool
210 gfc_omp_private_outer_ref (tree decl)
212 tree type = TREE_TYPE (decl);
214 if (gfc_omp_privatize_by_reference (decl))
215 type = TREE_TYPE (type);
217 if (GFC_DESCRIPTOR_TYPE_P (type)
218 && GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_ALLOCATABLE)
219 return true;
221 if (GFC_DECL_GET_SCALAR_ALLOCATABLE (decl))
222 return true;
224 if (gfc_has_alloc_comps (type, decl))
225 return true;
227 return false;
230 /* Callback for gfc_omp_unshare_expr. */
232 static tree
233 gfc_omp_unshare_expr_r (tree *tp, int *walk_subtrees, void *)
235 tree t = *tp;
236 enum tree_code code = TREE_CODE (t);
238 /* Stop at types, decls, constants like copy_tree_r. */
239 if (TREE_CODE_CLASS (code) == tcc_type
240 || TREE_CODE_CLASS (code) == tcc_declaration
241 || TREE_CODE_CLASS (code) == tcc_constant
242 || code == BLOCK)
243 *walk_subtrees = 0;
244 else if (handled_component_p (t)
245 || TREE_CODE (t) == MEM_REF)
247 *tp = unshare_expr (t);
248 *walk_subtrees = 0;
251 return NULL_TREE;
254 /* Unshare in expr anything that the FE which normally doesn't
255 care much about tree sharing (because during gimplification
256 everything is unshared) could cause problems with tree sharing
257 at omp-low.c time. */
259 static tree
260 gfc_omp_unshare_expr (tree expr)
262 walk_tree (&expr, gfc_omp_unshare_expr_r, NULL, NULL);
263 return expr;
266 enum walk_alloc_comps
268 WALK_ALLOC_COMPS_DTOR,
269 WALK_ALLOC_COMPS_DEFAULT_CTOR,
270 WALK_ALLOC_COMPS_COPY_CTOR
273 /* Handle allocatable components in OpenMP clauses. */
275 static tree
276 gfc_walk_alloc_comps (tree decl, tree dest, tree var,
277 enum walk_alloc_comps kind)
279 stmtblock_t block, tmpblock;
280 tree type = TREE_TYPE (decl), then_b, tem, field;
281 gfc_init_block (&block);
283 if (GFC_ARRAY_TYPE_P (type) || GFC_DESCRIPTOR_TYPE_P (type))
285 if (GFC_DESCRIPTOR_TYPE_P (type))
287 gfc_init_block (&tmpblock);
288 tem = gfc_full_array_size (&tmpblock, decl,
289 GFC_TYPE_ARRAY_RANK (type));
290 then_b = gfc_finish_block (&tmpblock);
291 gfc_add_expr_to_block (&block, gfc_omp_unshare_expr (then_b));
292 tem = gfc_omp_unshare_expr (tem);
293 tem = fold_build2_loc (input_location, MINUS_EXPR,
294 gfc_array_index_type, tem,
295 gfc_index_one_node);
297 else
299 if (!TYPE_DOMAIN (type)
300 || TYPE_MAX_VALUE (TYPE_DOMAIN (type)) == NULL_TREE
301 || TYPE_MIN_VALUE (TYPE_DOMAIN (type)) == error_mark_node
302 || TYPE_MAX_VALUE (TYPE_DOMAIN (type)) == error_mark_node)
304 tem = fold_build2 (EXACT_DIV_EXPR, sizetype,
305 TYPE_SIZE_UNIT (type),
306 TYPE_SIZE_UNIT (TREE_TYPE (type)));
307 tem = size_binop (MINUS_EXPR, tem, size_one_node);
309 else
310 tem = array_type_nelts (type);
311 tem = fold_convert (gfc_array_index_type, tem);
314 tree nelems = gfc_evaluate_now (tem, &block);
315 tree index = gfc_create_var (gfc_array_index_type, "S");
317 gfc_init_block (&tmpblock);
318 tem = gfc_conv_array_data (decl);
319 tree declvar = build_fold_indirect_ref_loc (input_location, tem);
320 tree declvref = gfc_build_array_ref (declvar, index, NULL);
321 tree destvar, destvref = NULL_TREE;
322 if (dest)
324 tem = gfc_conv_array_data (dest);
325 destvar = build_fold_indirect_ref_loc (input_location, tem);
326 destvref = gfc_build_array_ref (destvar, index, NULL);
328 gfc_add_expr_to_block (&tmpblock,
329 gfc_walk_alloc_comps (declvref, destvref,
330 var, kind));
332 gfc_loopinfo loop;
333 gfc_init_loopinfo (&loop);
334 loop.dimen = 1;
335 loop.from[0] = gfc_index_zero_node;
336 loop.loopvar[0] = index;
337 loop.to[0] = nelems;
338 gfc_trans_scalarizing_loops (&loop, &tmpblock);
339 gfc_add_block_to_block (&block, &loop.pre);
340 return gfc_finish_block (&block);
342 else if (GFC_DECL_GET_SCALAR_ALLOCATABLE (var))
344 decl = build_fold_indirect_ref_loc (input_location, decl);
345 if (dest)
346 dest = build_fold_indirect_ref_loc (input_location, dest);
347 type = TREE_TYPE (decl);
350 gcc_assert (TREE_CODE (type) == RECORD_TYPE);
351 for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
353 tree ftype = TREE_TYPE (field);
354 tree declf, destf = NULL_TREE;
355 bool has_alloc_comps = gfc_has_alloc_comps (ftype, field);
356 if ((!GFC_DESCRIPTOR_TYPE_P (ftype)
357 || GFC_TYPE_ARRAY_AKIND (ftype) != GFC_ARRAY_ALLOCATABLE)
358 && !GFC_DECL_GET_SCALAR_ALLOCATABLE (field)
359 && !has_alloc_comps)
360 continue;
361 declf = fold_build3_loc (input_location, COMPONENT_REF, ftype,
362 decl, field, NULL_TREE);
363 if (dest)
364 destf = fold_build3_loc (input_location, COMPONENT_REF, ftype,
365 dest, field, NULL_TREE);
367 tem = NULL_TREE;
368 switch (kind)
370 case WALK_ALLOC_COMPS_DTOR:
371 break;
372 case WALK_ALLOC_COMPS_DEFAULT_CTOR:
373 if (GFC_DESCRIPTOR_TYPE_P (ftype)
374 && GFC_TYPE_ARRAY_AKIND (ftype) == GFC_ARRAY_ALLOCATABLE)
376 gfc_add_modify (&block, unshare_expr (destf),
377 unshare_expr (declf));
378 tem = gfc_duplicate_allocatable_nocopy
379 (destf, declf, ftype,
380 GFC_TYPE_ARRAY_RANK (ftype));
382 else if (GFC_DECL_GET_SCALAR_ALLOCATABLE (field))
383 tem = gfc_duplicate_allocatable_nocopy (destf, declf, ftype, 0);
384 break;
385 case WALK_ALLOC_COMPS_COPY_CTOR:
386 if (GFC_DESCRIPTOR_TYPE_P (ftype)
387 && GFC_TYPE_ARRAY_AKIND (ftype) == GFC_ARRAY_ALLOCATABLE)
388 tem = gfc_duplicate_allocatable (destf, declf, ftype,
389 GFC_TYPE_ARRAY_RANK (ftype),
390 NULL_TREE);
391 else if (GFC_DECL_GET_SCALAR_ALLOCATABLE (field))
392 tem = gfc_duplicate_allocatable (destf, declf, ftype, 0,
393 NULL_TREE);
394 break;
396 if (tem)
397 gfc_add_expr_to_block (&block, gfc_omp_unshare_expr (tem));
398 if (has_alloc_comps)
400 gfc_init_block (&tmpblock);
401 gfc_add_expr_to_block (&tmpblock,
402 gfc_walk_alloc_comps (declf, destf,
403 field, kind));
404 then_b = gfc_finish_block (&tmpblock);
405 if (GFC_DESCRIPTOR_TYPE_P (ftype)
406 && GFC_TYPE_ARRAY_AKIND (ftype) == GFC_ARRAY_ALLOCATABLE)
407 tem = gfc_conv_descriptor_data_get (unshare_expr (declf));
408 else if (GFC_DECL_GET_SCALAR_ALLOCATABLE (field))
409 tem = unshare_expr (declf);
410 else
411 tem = NULL_TREE;
412 if (tem)
414 tem = fold_convert (pvoid_type_node, tem);
415 tem = fold_build2_loc (input_location, NE_EXPR,
416 boolean_type_node, tem,
417 null_pointer_node);
418 then_b = build3_loc (input_location, COND_EXPR, void_type_node,
419 tem, then_b,
420 build_empty_stmt (input_location));
422 gfc_add_expr_to_block (&block, then_b);
424 if (kind == WALK_ALLOC_COMPS_DTOR)
426 if (GFC_DESCRIPTOR_TYPE_P (ftype)
427 && GFC_TYPE_ARRAY_AKIND (ftype) == GFC_ARRAY_ALLOCATABLE)
429 tem = gfc_conv_descriptor_data_get (unshare_expr (declf));
430 tem = gfc_deallocate_with_status (tem, NULL_TREE, NULL_TREE,
431 NULL_TREE, NULL_TREE, true,
432 NULL,
433 GFC_CAF_COARRAY_NOCOARRAY);
434 gfc_add_expr_to_block (&block, gfc_omp_unshare_expr (tem));
436 else if (GFC_DECL_GET_SCALAR_ALLOCATABLE (field))
438 tem = gfc_call_free (unshare_expr (declf));
439 gfc_add_expr_to_block (&block, gfc_omp_unshare_expr (tem));
444 return gfc_finish_block (&block);
447 /* Return code to initialize DECL with its default constructor, or
448 NULL if there's nothing to do. */
450 tree
451 gfc_omp_clause_default_ctor (tree clause, tree decl, tree outer)
453 tree type = TREE_TYPE (decl), size, ptr, cond, then_b, else_b;
454 stmtblock_t block, cond_block;
456 gcc_assert (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_PRIVATE
457 || OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_LASTPRIVATE
458 || OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_LINEAR
459 || OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_REDUCTION);
461 if ((! GFC_DESCRIPTOR_TYPE_P (type)
462 || GFC_TYPE_ARRAY_AKIND (type) != GFC_ARRAY_ALLOCATABLE)
463 && !GFC_DECL_GET_SCALAR_ALLOCATABLE (OMP_CLAUSE_DECL (clause)))
465 if (gfc_has_alloc_comps (type, OMP_CLAUSE_DECL (clause)))
467 gcc_assert (outer);
468 gfc_start_block (&block);
469 tree tem = gfc_walk_alloc_comps (outer, decl,
470 OMP_CLAUSE_DECL (clause),
471 WALK_ALLOC_COMPS_DEFAULT_CTOR);
472 gfc_add_expr_to_block (&block, tem);
473 return gfc_finish_block (&block);
475 return NULL_TREE;
478 gcc_assert (outer != NULL_TREE);
480 /* Allocatable arrays and scalars in PRIVATE clauses need to be set to
481 "not currently allocated" allocation status if outer
482 array is "not currently allocated", otherwise should be allocated. */
483 gfc_start_block (&block);
485 gfc_init_block (&cond_block);
487 if (GFC_DESCRIPTOR_TYPE_P (type))
489 gfc_add_modify (&cond_block, decl, outer);
490 tree rank = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (type) - 1];
491 size = gfc_conv_descriptor_ubound_get (decl, rank);
492 size = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
493 size,
494 gfc_conv_descriptor_lbound_get (decl, rank));
495 size = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
496 size, gfc_index_one_node);
497 if (GFC_TYPE_ARRAY_RANK (type) > 1)
498 size = fold_build2_loc (input_location, MULT_EXPR,
499 gfc_array_index_type, size,
500 gfc_conv_descriptor_stride_get (decl, rank));
501 tree esize = fold_convert (gfc_array_index_type,
502 TYPE_SIZE_UNIT (gfc_get_element_type (type)));
503 size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
504 size, esize);
505 size = unshare_expr (size);
506 size = gfc_evaluate_now (fold_convert (size_type_node, size),
507 &cond_block);
509 else
510 size = fold_convert (size_type_node, TYPE_SIZE_UNIT (TREE_TYPE (type)));
511 ptr = gfc_create_var (pvoid_type_node, NULL);
512 gfc_allocate_using_malloc (&cond_block, ptr, size, NULL_TREE);
513 if (GFC_DESCRIPTOR_TYPE_P (type))
514 gfc_conv_descriptor_data_set (&cond_block, unshare_expr (decl), ptr);
515 else
516 gfc_add_modify (&cond_block, unshare_expr (decl),
517 fold_convert (TREE_TYPE (decl), ptr));
518 if (gfc_has_alloc_comps (type, OMP_CLAUSE_DECL (clause)))
520 tree tem = gfc_walk_alloc_comps (outer, decl,
521 OMP_CLAUSE_DECL (clause),
522 WALK_ALLOC_COMPS_DEFAULT_CTOR);
523 gfc_add_expr_to_block (&cond_block, tem);
525 then_b = gfc_finish_block (&cond_block);
527 /* Reduction clause requires allocated ALLOCATABLE. */
528 if (OMP_CLAUSE_CODE (clause) != OMP_CLAUSE_REDUCTION)
530 gfc_init_block (&cond_block);
531 if (GFC_DESCRIPTOR_TYPE_P (type))
532 gfc_conv_descriptor_data_set (&cond_block, unshare_expr (decl),
533 null_pointer_node);
534 else
535 gfc_add_modify (&cond_block, unshare_expr (decl),
536 build_zero_cst (TREE_TYPE (decl)));
537 else_b = gfc_finish_block (&cond_block);
539 tree tem = fold_convert (pvoid_type_node,
540 GFC_DESCRIPTOR_TYPE_P (type)
541 ? gfc_conv_descriptor_data_get (outer) : outer);
542 tem = unshare_expr (tem);
543 cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
544 tem, null_pointer_node);
545 gfc_add_expr_to_block (&block,
546 build3_loc (input_location, COND_EXPR,
547 void_type_node, cond, then_b,
548 else_b));
550 else
551 gfc_add_expr_to_block (&block, then_b);
553 return gfc_finish_block (&block);
556 /* Build and return code for a copy constructor from SRC to DEST. */
558 tree
559 gfc_omp_clause_copy_ctor (tree clause, tree dest, tree src)
561 tree type = TREE_TYPE (dest), ptr, size, call;
562 tree cond, then_b, else_b;
563 stmtblock_t block, cond_block;
565 gcc_assert (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_FIRSTPRIVATE
566 || OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_LINEAR);
568 if ((! GFC_DESCRIPTOR_TYPE_P (type)
569 || GFC_TYPE_ARRAY_AKIND (type) != GFC_ARRAY_ALLOCATABLE)
570 && !GFC_DECL_GET_SCALAR_ALLOCATABLE (OMP_CLAUSE_DECL (clause)))
572 if (gfc_has_alloc_comps (type, OMP_CLAUSE_DECL (clause)))
574 gfc_start_block (&block);
575 gfc_add_modify (&block, dest, src);
576 tree tem = gfc_walk_alloc_comps (src, dest, OMP_CLAUSE_DECL (clause),
577 WALK_ALLOC_COMPS_COPY_CTOR);
578 gfc_add_expr_to_block (&block, tem);
579 return gfc_finish_block (&block);
581 else
582 return build2_v (MODIFY_EXPR, dest, src);
585 /* Allocatable arrays in FIRSTPRIVATE clauses need to be allocated
586 and copied from SRC. */
587 gfc_start_block (&block);
589 gfc_init_block (&cond_block);
591 gfc_add_modify (&cond_block, dest, src);
592 if (GFC_DESCRIPTOR_TYPE_P (type))
594 tree rank = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (type) - 1];
595 size = gfc_conv_descriptor_ubound_get (dest, rank);
596 size = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
597 size,
598 gfc_conv_descriptor_lbound_get (dest, rank));
599 size = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
600 size, gfc_index_one_node);
601 if (GFC_TYPE_ARRAY_RANK (type) > 1)
602 size = fold_build2_loc (input_location, MULT_EXPR,
603 gfc_array_index_type, size,
604 gfc_conv_descriptor_stride_get (dest, rank));
605 tree esize = fold_convert (gfc_array_index_type,
606 TYPE_SIZE_UNIT (gfc_get_element_type (type)));
607 size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
608 size, esize);
609 size = unshare_expr (size);
610 size = gfc_evaluate_now (fold_convert (size_type_node, size),
611 &cond_block);
613 else
614 size = fold_convert (size_type_node, TYPE_SIZE_UNIT (TREE_TYPE (type)));
615 ptr = gfc_create_var (pvoid_type_node, NULL);
616 gfc_allocate_using_malloc (&cond_block, ptr, size, NULL_TREE);
617 if (GFC_DESCRIPTOR_TYPE_P (type))
618 gfc_conv_descriptor_data_set (&cond_block, unshare_expr (dest), ptr);
619 else
620 gfc_add_modify (&cond_block, unshare_expr (dest),
621 fold_convert (TREE_TYPE (dest), ptr));
623 tree srcptr = GFC_DESCRIPTOR_TYPE_P (type)
624 ? gfc_conv_descriptor_data_get (src) : src;
625 srcptr = unshare_expr (srcptr);
626 srcptr = fold_convert (pvoid_type_node, srcptr);
627 call = build_call_expr_loc (input_location,
628 builtin_decl_explicit (BUILT_IN_MEMCPY), 3, ptr,
629 srcptr, size);
630 gfc_add_expr_to_block (&cond_block, fold_convert (void_type_node, call));
631 if (gfc_has_alloc_comps (type, OMP_CLAUSE_DECL (clause)))
633 tree tem = gfc_walk_alloc_comps (src, dest,
634 OMP_CLAUSE_DECL (clause),
635 WALK_ALLOC_COMPS_COPY_CTOR);
636 gfc_add_expr_to_block (&cond_block, tem);
638 then_b = gfc_finish_block (&cond_block);
640 gfc_init_block (&cond_block);
641 if (GFC_DESCRIPTOR_TYPE_P (type))
642 gfc_conv_descriptor_data_set (&cond_block, unshare_expr (dest),
643 null_pointer_node);
644 else
645 gfc_add_modify (&cond_block, unshare_expr (dest),
646 build_zero_cst (TREE_TYPE (dest)));
647 else_b = gfc_finish_block (&cond_block);
649 cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
650 unshare_expr (srcptr), null_pointer_node);
651 gfc_add_expr_to_block (&block,
652 build3_loc (input_location, COND_EXPR,
653 void_type_node, cond, then_b, else_b));
655 return gfc_finish_block (&block);
658 /* Similarly, except use an intrinsic or pointer assignment operator
659 instead. */
661 tree
662 gfc_omp_clause_assign_op (tree clause, tree dest, tree src)
664 tree type = TREE_TYPE (dest), ptr, size, call, nonalloc;
665 tree cond, then_b, else_b;
666 stmtblock_t block, cond_block, cond_block2, inner_block;
668 if ((! GFC_DESCRIPTOR_TYPE_P (type)
669 || GFC_TYPE_ARRAY_AKIND (type) != GFC_ARRAY_ALLOCATABLE)
670 && !GFC_DECL_GET_SCALAR_ALLOCATABLE (OMP_CLAUSE_DECL (clause)))
672 if (gfc_has_alloc_comps (type, OMP_CLAUSE_DECL (clause)))
674 gfc_start_block (&block);
675 /* First dealloc any allocatable components in DEST. */
676 tree tem = gfc_walk_alloc_comps (dest, NULL_TREE,
677 OMP_CLAUSE_DECL (clause),
678 WALK_ALLOC_COMPS_DTOR);
679 gfc_add_expr_to_block (&block, tem);
680 /* Then copy over toplevel data. */
681 gfc_add_modify (&block, dest, src);
682 /* Finally allocate any allocatable components and copy. */
683 tem = gfc_walk_alloc_comps (src, dest, OMP_CLAUSE_DECL (clause),
684 WALK_ALLOC_COMPS_COPY_CTOR);
685 gfc_add_expr_to_block (&block, tem);
686 return gfc_finish_block (&block);
688 else
689 return build2_v (MODIFY_EXPR, dest, src);
692 gfc_start_block (&block);
694 if (gfc_has_alloc_comps (type, OMP_CLAUSE_DECL (clause)))
696 then_b = gfc_walk_alloc_comps (dest, NULL_TREE, OMP_CLAUSE_DECL (clause),
697 WALK_ALLOC_COMPS_DTOR);
698 tree tem = fold_convert (pvoid_type_node,
699 GFC_DESCRIPTOR_TYPE_P (type)
700 ? gfc_conv_descriptor_data_get (dest) : dest);
701 tem = unshare_expr (tem);
702 cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
703 tem, null_pointer_node);
704 tem = build3_loc (input_location, COND_EXPR, void_type_node, cond,
705 then_b, build_empty_stmt (input_location));
706 gfc_add_expr_to_block (&block, tem);
709 gfc_init_block (&cond_block);
711 if (GFC_DESCRIPTOR_TYPE_P (type))
713 tree rank = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (type) - 1];
714 size = gfc_conv_descriptor_ubound_get (src, rank);
715 size = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
716 size,
717 gfc_conv_descriptor_lbound_get (src, rank));
718 size = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
719 size, gfc_index_one_node);
720 if (GFC_TYPE_ARRAY_RANK (type) > 1)
721 size = fold_build2_loc (input_location, MULT_EXPR,
722 gfc_array_index_type, size,
723 gfc_conv_descriptor_stride_get (src, rank));
724 tree esize = fold_convert (gfc_array_index_type,
725 TYPE_SIZE_UNIT (gfc_get_element_type (type)));
726 size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
727 size, esize);
728 size = unshare_expr (size);
729 size = gfc_evaluate_now (fold_convert (size_type_node, size),
730 &cond_block);
732 else
733 size = fold_convert (size_type_node, TYPE_SIZE_UNIT (TREE_TYPE (type)));
734 ptr = gfc_create_var (pvoid_type_node, NULL);
736 tree destptr = GFC_DESCRIPTOR_TYPE_P (type)
737 ? gfc_conv_descriptor_data_get (dest) : dest;
738 destptr = unshare_expr (destptr);
739 destptr = fold_convert (pvoid_type_node, destptr);
740 gfc_add_modify (&cond_block, ptr, destptr);
742 nonalloc = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
743 destptr, null_pointer_node);
744 cond = nonalloc;
745 if (GFC_DESCRIPTOR_TYPE_P (type))
747 int i;
748 for (i = 0; i < GFC_TYPE_ARRAY_RANK (type); i++)
750 tree rank = gfc_rank_cst[i];
751 tree tem = gfc_conv_descriptor_ubound_get (src, rank);
752 tem = fold_build2_loc (input_location, MINUS_EXPR,
753 gfc_array_index_type, tem,
754 gfc_conv_descriptor_lbound_get (src, rank));
755 tem = fold_build2_loc (input_location, PLUS_EXPR,
756 gfc_array_index_type, tem,
757 gfc_conv_descriptor_lbound_get (dest, rank));
758 tem = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
759 tem, gfc_conv_descriptor_ubound_get (dest,
760 rank));
761 cond = fold_build2_loc (input_location, TRUTH_ORIF_EXPR,
762 boolean_type_node, cond, tem);
766 gfc_init_block (&cond_block2);
768 if (GFC_DESCRIPTOR_TYPE_P (type))
770 gfc_init_block (&inner_block);
771 gfc_allocate_using_malloc (&inner_block, ptr, size, NULL_TREE);
772 then_b = gfc_finish_block (&inner_block);
774 gfc_init_block (&inner_block);
775 gfc_add_modify (&inner_block, ptr,
776 gfc_call_realloc (&inner_block, ptr, size));
777 else_b = gfc_finish_block (&inner_block);
779 gfc_add_expr_to_block (&cond_block2,
780 build3_loc (input_location, COND_EXPR,
781 void_type_node,
782 unshare_expr (nonalloc),
783 then_b, else_b));
784 gfc_add_modify (&cond_block2, dest, src);
785 gfc_conv_descriptor_data_set (&cond_block2, unshare_expr (dest), ptr);
787 else
789 gfc_allocate_using_malloc (&cond_block2, ptr, size, NULL_TREE);
790 gfc_add_modify (&cond_block2, unshare_expr (dest),
791 fold_convert (type, ptr));
793 then_b = gfc_finish_block (&cond_block2);
794 else_b = build_empty_stmt (input_location);
796 gfc_add_expr_to_block (&cond_block,
797 build3_loc (input_location, COND_EXPR,
798 void_type_node, unshare_expr (cond),
799 then_b, else_b));
801 tree srcptr = GFC_DESCRIPTOR_TYPE_P (type)
802 ? gfc_conv_descriptor_data_get (src) : src;
803 srcptr = unshare_expr (srcptr);
804 srcptr = fold_convert (pvoid_type_node, srcptr);
805 call = build_call_expr_loc (input_location,
806 builtin_decl_explicit (BUILT_IN_MEMCPY), 3, ptr,
807 srcptr, size);
808 gfc_add_expr_to_block (&cond_block, fold_convert (void_type_node, call));
809 if (gfc_has_alloc_comps (type, OMP_CLAUSE_DECL (clause)))
811 tree tem = gfc_walk_alloc_comps (src, dest,
812 OMP_CLAUSE_DECL (clause),
813 WALK_ALLOC_COMPS_COPY_CTOR);
814 gfc_add_expr_to_block (&cond_block, tem);
816 then_b = gfc_finish_block (&cond_block);
818 if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_COPYIN)
820 gfc_init_block (&cond_block);
821 if (GFC_DESCRIPTOR_TYPE_P (type))
823 tree tmp = gfc_conv_descriptor_data_get (unshare_expr (dest));
824 tmp = gfc_deallocate_with_status (tmp, NULL_TREE, NULL_TREE,
825 NULL_TREE, NULL_TREE, true, NULL,
826 GFC_CAF_COARRAY_NOCOARRAY);
827 gfc_add_expr_to_block (&cond_block, tmp);
829 else
831 destptr = gfc_evaluate_now (destptr, &cond_block);
832 gfc_add_expr_to_block (&cond_block, gfc_call_free (destptr));
833 gfc_add_modify (&cond_block, unshare_expr (dest),
834 build_zero_cst (TREE_TYPE (dest)));
836 else_b = gfc_finish_block (&cond_block);
838 cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
839 unshare_expr (srcptr), null_pointer_node);
840 gfc_add_expr_to_block (&block,
841 build3_loc (input_location, COND_EXPR,
842 void_type_node, cond,
843 then_b, else_b));
845 else
846 gfc_add_expr_to_block (&block, then_b);
848 return gfc_finish_block (&block);
851 static void
852 gfc_omp_linear_clause_add_loop (stmtblock_t *block, tree dest, tree src,
853 tree add, tree nelems)
855 stmtblock_t tmpblock;
856 tree desta, srca, index = gfc_create_var (gfc_array_index_type, "S");
857 nelems = gfc_evaluate_now (nelems, block);
859 gfc_init_block (&tmpblock);
860 if (TREE_CODE (TREE_TYPE (dest)) == ARRAY_TYPE)
862 desta = gfc_build_array_ref (dest, index, NULL);
863 srca = gfc_build_array_ref (src, index, NULL);
865 else
867 gcc_assert (POINTER_TYPE_P (TREE_TYPE (dest)));
868 tree idx = fold_build2 (MULT_EXPR, sizetype,
869 fold_convert (sizetype, index),
870 TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (dest))));
871 desta = build_fold_indirect_ref (fold_build2 (POINTER_PLUS_EXPR,
872 TREE_TYPE (dest), dest,
873 idx));
874 srca = build_fold_indirect_ref (fold_build2 (POINTER_PLUS_EXPR,
875 TREE_TYPE (src), src,
876 idx));
878 gfc_add_modify (&tmpblock, desta,
879 fold_build2 (PLUS_EXPR, TREE_TYPE (desta),
880 srca, add));
882 gfc_loopinfo loop;
883 gfc_init_loopinfo (&loop);
884 loop.dimen = 1;
885 loop.from[0] = gfc_index_zero_node;
886 loop.loopvar[0] = index;
887 loop.to[0] = nelems;
888 gfc_trans_scalarizing_loops (&loop, &tmpblock);
889 gfc_add_block_to_block (block, &loop.pre);
892 /* Build and return code for a constructor of DEST that initializes
893 it to SRC plus ADD (ADD is scalar integer). */
895 tree
896 gfc_omp_clause_linear_ctor (tree clause, tree dest, tree src, tree add)
898 tree type = TREE_TYPE (dest), ptr, size, nelems = NULL_TREE;
899 stmtblock_t block;
901 gcc_assert (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_LINEAR);
903 gfc_start_block (&block);
904 add = gfc_evaluate_now (add, &block);
906 if ((! GFC_DESCRIPTOR_TYPE_P (type)
907 || GFC_TYPE_ARRAY_AKIND (type) != GFC_ARRAY_ALLOCATABLE)
908 && !GFC_DECL_GET_SCALAR_ALLOCATABLE (OMP_CLAUSE_DECL (clause)))
910 gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
911 if (!TYPE_DOMAIN (type)
912 || TYPE_MAX_VALUE (TYPE_DOMAIN (type)) == NULL_TREE
913 || TYPE_MIN_VALUE (TYPE_DOMAIN (type)) == error_mark_node
914 || TYPE_MAX_VALUE (TYPE_DOMAIN (type)) == error_mark_node)
916 nelems = fold_build2 (EXACT_DIV_EXPR, sizetype,
917 TYPE_SIZE_UNIT (type),
918 TYPE_SIZE_UNIT (TREE_TYPE (type)));
919 nelems = size_binop (MINUS_EXPR, nelems, size_one_node);
921 else
922 nelems = array_type_nelts (type);
923 nelems = fold_convert (gfc_array_index_type, nelems);
925 gfc_omp_linear_clause_add_loop (&block, dest, src, add, nelems);
926 return gfc_finish_block (&block);
929 /* Allocatable arrays in LINEAR clauses need to be allocated
930 and copied from SRC. */
931 gfc_add_modify (&block, dest, src);
932 if (GFC_DESCRIPTOR_TYPE_P (type))
934 tree rank = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (type) - 1];
935 size = gfc_conv_descriptor_ubound_get (dest, rank);
936 size = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
937 size,
938 gfc_conv_descriptor_lbound_get (dest, rank));
939 size = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
940 size, gfc_index_one_node);
941 if (GFC_TYPE_ARRAY_RANK (type) > 1)
942 size = fold_build2_loc (input_location, MULT_EXPR,
943 gfc_array_index_type, size,
944 gfc_conv_descriptor_stride_get (dest, rank));
945 tree esize = fold_convert (gfc_array_index_type,
946 TYPE_SIZE_UNIT (gfc_get_element_type (type)));
947 nelems = gfc_evaluate_now (unshare_expr (size), &block);
948 size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
949 nelems, unshare_expr (esize));
950 size = gfc_evaluate_now (fold_convert (size_type_node, size),
951 &block);
952 nelems = fold_build2_loc (input_location, MINUS_EXPR,
953 gfc_array_index_type, nelems,
954 gfc_index_one_node);
956 else
957 size = fold_convert (size_type_node, TYPE_SIZE_UNIT (TREE_TYPE (type)));
958 ptr = gfc_create_var (pvoid_type_node, NULL);
959 gfc_allocate_using_malloc (&block, ptr, size, NULL_TREE);
960 if (GFC_DESCRIPTOR_TYPE_P (type))
962 gfc_conv_descriptor_data_set (&block, unshare_expr (dest), ptr);
963 tree etype = gfc_get_element_type (type);
964 ptr = fold_convert (build_pointer_type (etype), ptr);
965 tree srcptr = gfc_conv_descriptor_data_get (unshare_expr (src));
966 srcptr = fold_convert (build_pointer_type (etype), srcptr);
967 gfc_omp_linear_clause_add_loop (&block, ptr, srcptr, add, nelems);
969 else
971 gfc_add_modify (&block, unshare_expr (dest),
972 fold_convert (TREE_TYPE (dest), ptr));
973 ptr = fold_convert (TREE_TYPE (dest), ptr);
974 tree dstm = build_fold_indirect_ref (ptr);
975 tree srcm = build_fold_indirect_ref (unshare_expr (src));
976 gfc_add_modify (&block, dstm,
977 fold_build2 (PLUS_EXPR, TREE_TYPE (add), srcm, add));
979 return gfc_finish_block (&block);
982 /* Build and return code destructing DECL. Return NULL if nothing
983 to be done. */
985 tree
986 gfc_omp_clause_dtor (tree clause, tree decl)
988 tree type = TREE_TYPE (decl), tem;
990 if ((! GFC_DESCRIPTOR_TYPE_P (type)
991 || GFC_TYPE_ARRAY_AKIND (type) != GFC_ARRAY_ALLOCATABLE)
992 && !GFC_DECL_GET_SCALAR_ALLOCATABLE (OMP_CLAUSE_DECL (clause)))
994 if (gfc_has_alloc_comps (type, OMP_CLAUSE_DECL (clause)))
995 return gfc_walk_alloc_comps (decl, NULL_TREE,
996 OMP_CLAUSE_DECL (clause),
997 WALK_ALLOC_COMPS_DTOR);
998 return NULL_TREE;
1001 if (GFC_DESCRIPTOR_TYPE_P (type))
1003 /* Allocatable arrays in FIRSTPRIVATE/LASTPRIVATE etc. clauses need
1004 to be deallocated if they were allocated. */
1005 tem = gfc_conv_descriptor_data_get (decl);
1006 tem = gfc_deallocate_with_status (tem, NULL_TREE, NULL_TREE, NULL_TREE,
1007 NULL_TREE, true, NULL,
1008 GFC_CAF_COARRAY_NOCOARRAY);
1010 else
1011 tem = gfc_call_free (decl);
1012 tem = gfc_omp_unshare_expr (tem);
1014 if (gfc_has_alloc_comps (type, OMP_CLAUSE_DECL (clause)))
1016 stmtblock_t block;
1017 tree then_b;
1019 gfc_init_block (&block);
1020 gfc_add_expr_to_block (&block,
1021 gfc_walk_alloc_comps (decl, NULL_TREE,
1022 OMP_CLAUSE_DECL (clause),
1023 WALK_ALLOC_COMPS_DTOR));
1024 gfc_add_expr_to_block (&block, tem);
1025 then_b = gfc_finish_block (&block);
1027 tem = fold_convert (pvoid_type_node,
1028 GFC_DESCRIPTOR_TYPE_P (type)
1029 ? gfc_conv_descriptor_data_get (decl) : decl);
1030 tem = unshare_expr (tem);
1031 tree cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
1032 tem, null_pointer_node);
1033 tem = build3_loc (input_location, COND_EXPR, void_type_node, cond,
1034 then_b, build_empty_stmt (input_location));
1036 return tem;
1040 void
1041 gfc_omp_finish_clause (tree c, gimple_seq *pre_p)
1043 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP)
1044 return;
1046 tree decl = OMP_CLAUSE_DECL (c);
1048 /* Assumed-size arrays can't be mapped implicitly, they have to be
1049 mapped explicitly using array sections. */
1050 if (TREE_CODE (decl) == PARM_DECL
1051 && GFC_ARRAY_TYPE_P (TREE_TYPE (decl))
1052 && GFC_TYPE_ARRAY_AKIND (TREE_TYPE (decl)) == GFC_ARRAY_UNKNOWN
1053 && GFC_TYPE_ARRAY_UBOUND (TREE_TYPE (decl),
1054 GFC_TYPE_ARRAY_RANK (TREE_TYPE (decl)) - 1)
1055 == NULL)
1057 error_at (OMP_CLAUSE_LOCATION (c),
1058 "implicit mapping of assumed size array %qD", decl);
1059 return;
1062 tree c2 = NULL_TREE, c3 = NULL_TREE, c4 = NULL_TREE;
1063 if (POINTER_TYPE_P (TREE_TYPE (decl)))
1065 if (!gfc_omp_privatize_by_reference (decl)
1066 && !GFC_DECL_GET_SCALAR_POINTER (decl)
1067 && !GFC_DECL_GET_SCALAR_ALLOCATABLE (decl)
1068 && !GFC_DECL_CRAY_POINTEE (decl)
1069 && !GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (decl))))
1070 return;
1071 tree orig_decl = decl;
1072 c4 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
1073 OMP_CLAUSE_SET_MAP_KIND (c4, GOMP_MAP_POINTER);
1074 OMP_CLAUSE_DECL (c4) = decl;
1075 OMP_CLAUSE_SIZE (c4) = size_int (0);
1076 decl = build_fold_indirect_ref (decl);
1077 OMP_CLAUSE_DECL (c) = decl;
1078 OMP_CLAUSE_SIZE (c) = NULL_TREE;
1079 if (TREE_CODE (TREE_TYPE (orig_decl)) == REFERENCE_TYPE
1080 && (GFC_DECL_GET_SCALAR_POINTER (orig_decl)
1081 || GFC_DECL_GET_SCALAR_ALLOCATABLE (orig_decl)))
1083 c3 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
1084 OMP_CLAUSE_SET_MAP_KIND (c3, GOMP_MAP_POINTER);
1085 OMP_CLAUSE_DECL (c3) = unshare_expr (decl);
1086 OMP_CLAUSE_SIZE (c3) = size_int (0);
1087 decl = build_fold_indirect_ref (decl);
1088 OMP_CLAUSE_DECL (c) = decl;
1091 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)))
1093 stmtblock_t block;
1094 gfc_start_block (&block);
1095 tree type = TREE_TYPE (decl);
1096 tree ptr = gfc_conv_descriptor_data_get (decl);
1097 ptr = fold_convert (build_pointer_type (char_type_node), ptr);
1098 ptr = build_fold_indirect_ref (ptr);
1099 OMP_CLAUSE_DECL (c) = ptr;
1100 c2 = build_omp_clause (input_location, OMP_CLAUSE_MAP);
1101 OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_TO_PSET);
1102 OMP_CLAUSE_DECL (c2) = decl;
1103 OMP_CLAUSE_SIZE (c2) = TYPE_SIZE_UNIT (type);
1104 c3 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
1105 OMP_CLAUSE_SET_MAP_KIND (c3, GOMP_MAP_POINTER);
1106 OMP_CLAUSE_DECL (c3) = gfc_conv_descriptor_data_get (decl);
1107 OMP_CLAUSE_SIZE (c3) = size_int (0);
1108 tree size = create_tmp_var (gfc_array_index_type);
1109 tree elemsz = TYPE_SIZE_UNIT (gfc_get_element_type (type));
1110 elemsz = fold_convert (gfc_array_index_type, elemsz);
1111 if (GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_POINTER
1112 || GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_POINTER_CONT)
1114 stmtblock_t cond_block;
1115 tree tem, then_b, else_b, zero, cond;
1117 gfc_init_block (&cond_block);
1118 tem = gfc_full_array_size (&cond_block, decl,
1119 GFC_TYPE_ARRAY_RANK (type));
1120 gfc_add_modify (&cond_block, size, tem);
1121 gfc_add_modify (&cond_block, size,
1122 fold_build2 (MULT_EXPR, gfc_array_index_type,
1123 size, elemsz));
1124 then_b = gfc_finish_block (&cond_block);
1125 gfc_init_block (&cond_block);
1126 zero = build_int_cst (gfc_array_index_type, 0);
1127 gfc_add_modify (&cond_block, size, zero);
1128 else_b = gfc_finish_block (&cond_block);
1129 tem = gfc_conv_descriptor_data_get (decl);
1130 tem = fold_convert (pvoid_type_node, tem);
1131 cond = fold_build2_loc (input_location, NE_EXPR,
1132 boolean_type_node, tem, null_pointer_node);
1133 gfc_add_expr_to_block (&block, build3_loc (input_location, COND_EXPR,
1134 void_type_node, cond,
1135 then_b, else_b));
1137 else
1139 gfc_add_modify (&block, size,
1140 gfc_full_array_size (&block, decl,
1141 GFC_TYPE_ARRAY_RANK (type)));
1142 gfc_add_modify (&block, size,
1143 fold_build2 (MULT_EXPR, gfc_array_index_type,
1144 size, elemsz));
1146 OMP_CLAUSE_SIZE (c) = size;
1147 tree stmt = gfc_finish_block (&block);
1148 gimplify_and_add (stmt, pre_p);
1150 tree last = c;
1151 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
1152 OMP_CLAUSE_SIZE (c)
1153 = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
1154 : TYPE_SIZE_UNIT (TREE_TYPE (decl));
1155 if (c2)
1157 OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (last);
1158 OMP_CLAUSE_CHAIN (last) = c2;
1159 last = c2;
1161 if (c3)
1163 OMP_CLAUSE_CHAIN (c3) = OMP_CLAUSE_CHAIN (last);
1164 OMP_CLAUSE_CHAIN (last) = c3;
1165 last = c3;
1167 if (c4)
1169 OMP_CLAUSE_CHAIN (c4) = OMP_CLAUSE_CHAIN (last);
1170 OMP_CLAUSE_CHAIN (last) = c4;
1171 last = c4;
1176 /* Return true if DECL is a scalar variable (for the purpose of
1177 implicit firstprivatization). */
1179 bool
1180 gfc_omp_scalar_p (tree decl)
1182 tree type = TREE_TYPE (decl);
1183 if (TREE_CODE (type) == REFERENCE_TYPE)
1184 type = TREE_TYPE (type);
1185 if (TREE_CODE (type) == POINTER_TYPE)
1187 if (GFC_DECL_GET_SCALAR_ALLOCATABLE (decl)
1188 || GFC_DECL_GET_SCALAR_POINTER (decl))
1189 type = TREE_TYPE (type);
1190 if (GFC_ARRAY_TYPE_P (type)
1191 || GFC_CLASS_TYPE_P (type))
1192 return false;
1194 if (TYPE_STRING_FLAG (type))
1195 return false;
1196 if (INTEGRAL_TYPE_P (type)
1197 || SCALAR_FLOAT_TYPE_P (type)
1198 || COMPLEX_FLOAT_TYPE_P (type))
1199 return true;
1200 return false;
1204 /* Return true if DECL's DECL_VALUE_EXPR (if any) should be
1205 disregarded in OpenMP construct, because it is going to be
1206 remapped during OpenMP lowering. SHARED is true if DECL
1207 is going to be shared, false if it is going to be privatized. */
1209 bool
1210 gfc_omp_disregard_value_expr (tree decl, bool shared)
1212 if (GFC_DECL_COMMON_OR_EQUIV (decl)
1213 && DECL_HAS_VALUE_EXPR_P (decl))
1215 tree value = DECL_VALUE_EXPR (decl);
1217 if (TREE_CODE (value) == COMPONENT_REF
1218 && VAR_P (TREE_OPERAND (value, 0))
1219 && GFC_DECL_COMMON_OR_EQUIV (TREE_OPERAND (value, 0)))
1221 /* If variable in COMMON or EQUIVALENCE is privatized, return
1222 true, as just that variable is supposed to be privatized,
1223 not the whole COMMON or whole EQUIVALENCE.
1224 For shared variables in COMMON or EQUIVALENCE, let them be
1225 gimplified to DECL_VALUE_EXPR, so that for multiple shared vars
1226 from the same COMMON or EQUIVALENCE just one sharing of the
1227 whole COMMON or EQUIVALENCE is enough. */
1228 return ! shared;
1232 if (GFC_DECL_RESULT (decl) && DECL_HAS_VALUE_EXPR_P (decl))
1233 return ! shared;
1235 return false;
1238 /* Return true if DECL that is shared iff SHARED is true should
1239 be put into OMP_CLAUSE_PRIVATE with OMP_CLAUSE_PRIVATE_DEBUG
1240 flag set. */
1242 bool
1243 gfc_omp_private_debug_clause (tree decl, bool shared)
1245 if (GFC_DECL_CRAY_POINTEE (decl))
1246 return true;
1248 if (GFC_DECL_COMMON_OR_EQUIV (decl)
1249 && DECL_HAS_VALUE_EXPR_P (decl))
1251 tree value = DECL_VALUE_EXPR (decl);
1253 if (TREE_CODE (value) == COMPONENT_REF
1254 && VAR_P (TREE_OPERAND (value, 0))
1255 && GFC_DECL_COMMON_OR_EQUIV (TREE_OPERAND (value, 0)))
1256 return shared;
1259 return false;
1262 /* Register language specific type size variables as potentially OpenMP
1263 firstprivate variables. */
1265 void
1266 gfc_omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *ctx, tree type)
1268 if (GFC_ARRAY_TYPE_P (type) || GFC_DESCRIPTOR_TYPE_P (type))
1270 int r;
1272 gcc_assert (TYPE_LANG_SPECIFIC (type) != NULL);
1273 for (r = 0; r < GFC_TYPE_ARRAY_RANK (type); r++)
1275 omp_firstprivatize_variable (ctx, GFC_TYPE_ARRAY_LBOUND (type, r));
1276 omp_firstprivatize_variable (ctx, GFC_TYPE_ARRAY_UBOUND (type, r));
1277 omp_firstprivatize_variable (ctx, GFC_TYPE_ARRAY_STRIDE (type, r));
1279 omp_firstprivatize_variable (ctx, GFC_TYPE_ARRAY_SIZE (type));
1280 omp_firstprivatize_variable (ctx, GFC_TYPE_ARRAY_OFFSET (type));
1285 static inline tree
1286 gfc_trans_add_clause (tree node, tree tail)
1288 OMP_CLAUSE_CHAIN (node) = tail;
1289 return node;
1292 static tree
1293 gfc_trans_omp_variable (gfc_symbol *sym, bool declare_simd)
1295 if (declare_simd)
1297 int cnt = 0;
1298 gfc_symbol *proc_sym;
1299 gfc_formal_arglist *f;
1301 gcc_assert (sym->attr.dummy);
1302 proc_sym = sym->ns->proc_name;
1303 if (proc_sym->attr.entry_master)
1304 ++cnt;
1305 if (gfc_return_by_reference (proc_sym))
1307 ++cnt;
1308 if (proc_sym->ts.type == BT_CHARACTER)
1309 ++cnt;
1311 for (f = gfc_sym_get_dummy_args (proc_sym); f; f = f->next)
1312 if (f->sym == sym)
1313 break;
1314 else if (f->sym)
1315 ++cnt;
1316 gcc_assert (f);
1317 return build_int_cst (integer_type_node, cnt);
1320 tree t = gfc_get_symbol_decl (sym);
1321 tree parent_decl;
1322 int parent_flag;
1323 bool return_value;
1324 bool alternate_entry;
1325 bool entry_master;
1327 return_value = sym->attr.function && sym->result == sym;
1328 alternate_entry = sym->attr.function && sym->attr.entry
1329 && sym->result == sym;
1330 entry_master = sym->attr.result
1331 && sym->ns->proc_name->attr.entry_master
1332 && !gfc_return_by_reference (sym->ns->proc_name);
1333 parent_decl = current_function_decl
1334 ? DECL_CONTEXT (current_function_decl) : NULL_TREE;
1336 if ((t == parent_decl && return_value)
1337 || (sym->ns && sym->ns->proc_name
1338 && sym->ns->proc_name->backend_decl == parent_decl
1339 && (alternate_entry || entry_master)))
1340 parent_flag = 1;
1341 else
1342 parent_flag = 0;
1344 /* Special case for assigning the return value of a function.
1345 Self recursive functions must have an explicit return value. */
1346 if (return_value && (t == current_function_decl || parent_flag))
1347 t = gfc_get_fake_result_decl (sym, parent_flag);
1349 /* Similarly for alternate entry points. */
1350 else if (alternate_entry
1351 && (sym->ns->proc_name->backend_decl == current_function_decl
1352 || parent_flag))
1354 gfc_entry_list *el = NULL;
1356 for (el = sym->ns->entries; el; el = el->next)
1357 if (sym == el->sym)
1359 t = gfc_get_fake_result_decl (sym, parent_flag);
1360 break;
1364 else if (entry_master
1365 && (sym->ns->proc_name->backend_decl == current_function_decl
1366 || parent_flag))
1367 t = gfc_get_fake_result_decl (sym, parent_flag);
1369 return t;
1372 static tree
1373 gfc_trans_omp_variable_list (enum omp_clause_code code,
1374 gfc_omp_namelist *namelist, tree list,
1375 bool declare_simd)
1377 for (; namelist != NULL; namelist = namelist->next)
1378 if (namelist->sym->attr.referenced || declare_simd)
1380 tree t = gfc_trans_omp_variable (namelist->sym, declare_simd);
1381 if (t != error_mark_node)
1383 tree node = build_omp_clause (input_location, code);
1384 OMP_CLAUSE_DECL (node) = t;
1385 list = gfc_trans_add_clause (node, list);
1388 return list;
1391 struct omp_udr_find_orig_data
1393 gfc_omp_udr *omp_udr;
1394 bool omp_orig_seen;
1397 static int
1398 omp_udr_find_orig (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
1399 void *data)
1401 struct omp_udr_find_orig_data *cd = (struct omp_udr_find_orig_data *) data;
1402 if ((*e)->expr_type == EXPR_VARIABLE
1403 && (*e)->symtree->n.sym == cd->omp_udr->omp_orig)
1404 cd->omp_orig_seen = true;
1406 return 0;
1409 static void
1410 gfc_trans_omp_array_reduction_or_udr (tree c, gfc_omp_namelist *n, locus where)
1412 gfc_symbol *sym = n->sym;
1413 gfc_symtree *root1 = NULL, *root2 = NULL, *root3 = NULL, *root4 = NULL;
1414 gfc_symtree *symtree1, *symtree2, *symtree3, *symtree4 = NULL;
1415 gfc_symbol init_val_sym, outer_sym, intrinsic_sym;
1416 gfc_symbol omp_var_copy[4];
1417 gfc_expr *e1, *e2, *e3, *e4;
1418 gfc_ref *ref;
1419 tree decl, backend_decl, stmt, type, outer_decl;
1420 locus old_loc = gfc_current_locus;
1421 const char *iname;
1422 bool t;
1423 gfc_omp_udr *udr = n->udr ? n->udr->udr : NULL;
1425 decl = OMP_CLAUSE_DECL (c);
1426 gfc_current_locus = where;
1427 type = TREE_TYPE (decl);
1428 outer_decl = create_tmp_var_raw (type);
1429 if (TREE_CODE (decl) == PARM_DECL
1430 && TREE_CODE (type) == REFERENCE_TYPE
1431 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (type))
1432 && GFC_TYPE_ARRAY_AKIND (TREE_TYPE (type)) == GFC_ARRAY_ALLOCATABLE)
1434 decl = build_fold_indirect_ref (decl);
1435 type = TREE_TYPE (type);
1438 /* Create a fake symbol for init value. */
1439 memset (&init_val_sym, 0, sizeof (init_val_sym));
1440 init_val_sym.ns = sym->ns;
1441 init_val_sym.name = sym->name;
1442 init_val_sym.ts = sym->ts;
1443 init_val_sym.attr.referenced = 1;
1444 init_val_sym.declared_at = where;
1445 init_val_sym.attr.flavor = FL_VARIABLE;
1446 if (OMP_CLAUSE_REDUCTION_CODE (c) != ERROR_MARK)
1447 backend_decl = omp_reduction_init (c, gfc_sym_type (&init_val_sym));
1448 else if (udr->initializer_ns)
1449 backend_decl = NULL;
1450 else
1451 switch (sym->ts.type)
1453 case BT_LOGICAL:
1454 case BT_INTEGER:
1455 case BT_REAL:
1456 case BT_COMPLEX:
1457 backend_decl = build_zero_cst (gfc_sym_type (&init_val_sym));
1458 break;
1459 default:
1460 backend_decl = NULL_TREE;
1461 break;
1463 init_val_sym.backend_decl = backend_decl;
1465 /* Create a fake symbol for the outer array reference. */
1466 outer_sym = *sym;
1467 if (sym->as)
1468 outer_sym.as = gfc_copy_array_spec (sym->as);
1469 outer_sym.attr.dummy = 0;
1470 outer_sym.attr.result = 0;
1471 outer_sym.attr.flavor = FL_VARIABLE;
1472 outer_sym.backend_decl = outer_decl;
1473 if (decl != OMP_CLAUSE_DECL (c))
1474 outer_sym.backend_decl = build_fold_indirect_ref (outer_decl);
1476 /* Create fake symtrees for it. */
1477 symtree1 = gfc_new_symtree (&root1, sym->name);
1478 symtree1->n.sym = sym;
1479 gcc_assert (symtree1 == root1);
1481 symtree2 = gfc_new_symtree (&root2, sym->name);
1482 symtree2->n.sym = &init_val_sym;
1483 gcc_assert (symtree2 == root2);
1485 symtree3 = gfc_new_symtree (&root3, sym->name);
1486 symtree3->n.sym = &outer_sym;
1487 gcc_assert (symtree3 == root3);
1489 memset (omp_var_copy, 0, sizeof omp_var_copy);
1490 if (udr)
1492 omp_var_copy[0] = *udr->omp_out;
1493 omp_var_copy[1] = *udr->omp_in;
1494 *udr->omp_out = outer_sym;
1495 *udr->omp_in = *sym;
1496 if (udr->initializer_ns)
1498 omp_var_copy[2] = *udr->omp_priv;
1499 omp_var_copy[3] = *udr->omp_orig;
1500 *udr->omp_priv = *sym;
1501 *udr->omp_orig = outer_sym;
1505 /* Create expressions. */
1506 e1 = gfc_get_expr ();
1507 e1->expr_type = EXPR_VARIABLE;
1508 e1->where = where;
1509 e1->symtree = symtree1;
1510 e1->ts = sym->ts;
1511 if (sym->attr.dimension)
1513 e1->ref = ref = gfc_get_ref ();
1514 ref->type = REF_ARRAY;
1515 ref->u.ar.where = where;
1516 ref->u.ar.as = sym->as;
1517 ref->u.ar.type = AR_FULL;
1518 ref->u.ar.dimen = 0;
1520 t = gfc_resolve_expr (e1);
1521 gcc_assert (t);
1523 e2 = NULL;
1524 if (backend_decl != NULL_TREE)
1526 e2 = gfc_get_expr ();
1527 e2->expr_type = EXPR_VARIABLE;
1528 e2->where = where;
1529 e2->symtree = symtree2;
1530 e2->ts = sym->ts;
1531 t = gfc_resolve_expr (e2);
1532 gcc_assert (t);
1534 else if (udr->initializer_ns == NULL)
1536 gcc_assert (sym->ts.type == BT_DERIVED);
1537 e2 = gfc_default_initializer (&sym->ts);
1538 gcc_assert (e2);
1539 t = gfc_resolve_expr (e2);
1540 gcc_assert (t);
1542 else if (n->udr->initializer->op == EXEC_ASSIGN)
1544 e2 = gfc_copy_expr (n->udr->initializer->expr2);
1545 t = gfc_resolve_expr (e2);
1546 gcc_assert (t);
1548 if (udr && udr->initializer_ns)
1550 struct omp_udr_find_orig_data cd;
1551 cd.omp_udr = udr;
1552 cd.omp_orig_seen = false;
1553 gfc_code_walker (&n->udr->initializer,
1554 gfc_dummy_code_callback, omp_udr_find_orig, &cd);
1555 if (cd.omp_orig_seen)
1556 OMP_CLAUSE_REDUCTION_OMP_ORIG_REF (c) = 1;
1559 e3 = gfc_copy_expr (e1);
1560 e3->symtree = symtree3;
1561 t = gfc_resolve_expr (e3);
1562 gcc_assert (t);
1564 iname = NULL;
1565 e4 = NULL;
1566 switch (OMP_CLAUSE_REDUCTION_CODE (c))
1568 case PLUS_EXPR:
1569 case MINUS_EXPR:
1570 e4 = gfc_add (e3, e1);
1571 break;
1572 case MULT_EXPR:
1573 e4 = gfc_multiply (e3, e1);
1574 break;
1575 case TRUTH_ANDIF_EXPR:
1576 e4 = gfc_and (e3, e1);
1577 break;
1578 case TRUTH_ORIF_EXPR:
1579 e4 = gfc_or (e3, e1);
1580 break;
1581 case EQ_EXPR:
1582 e4 = gfc_eqv (e3, e1);
1583 break;
1584 case NE_EXPR:
1585 e4 = gfc_neqv (e3, e1);
1586 break;
1587 case MIN_EXPR:
1588 iname = "min";
1589 break;
1590 case MAX_EXPR:
1591 iname = "max";
1592 break;
1593 case BIT_AND_EXPR:
1594 iname = "iand";
1595 break;
1596 case BIT_IOR_EXPR:
1597 iname = "ior";
1598 break;
1599 case BIT_XOR_EXPR:
1600 iname = "ieor";
1601 break;
1602 case ERROR_MARK:
1603 if (n->udr->combiner->op == EXEC_ASSIGN)
1605 gfc_free_expr (e3);
1606 e3 = gfc_copy_expr (n->udr->combiner->expr1);
1607 e4 = gfc_copy_expr (n->udr->combiner->expr2);
1608 t = gfc_resolve_expr (e3);
1609 gcc_assert (t);
1610 t = gfc_resolve_expr (e4);
1611 gcc_assert (t);
1613 break;
1614 default:
1615 gcc_unreachable ();
1617 if (iname != NULL)
1619 memset (&intrinsic_sym, 0, sizeof (intrinsic_sym));
1620 intrinsic_sym.ns = sym->ns;
1621 intrinsic_sym.name = iname;
1622 intrinsic_sym.ts = sym->ts;
1623 intrinsic_sym.attr.referenced = 1;
1624 intrinsic_sym.attr.intrinsic = 1;
1625 intrinsic_sym.attr.function = 1;
1626 intrinsic_sym.result = &intrinsic_sym;
1627 intrinsic_sym.declared_at = where;
1629 symtree4 = gfc_new_symtree (&root4, iname);
1630 symtree4->n.sym = &intrinsic_sym;
1631 gcc_assert (symtree4 == root4);
1633 e4 = gfc_get_expr ();
1634 e4->expr_type = EXPR_FUNCTION;
1635 e4->where = where;
1636 e4->symtree = symtree4;
1637 e4->value.function.actual = gfc_get_actual_arglist ();
1638 e4->value.function.actual->expr = e3;
1639 e4->value.function.actual->next = gfc_get_actual_arglist ();
1640 e4->value.function.actual->next->expr = e1;
1642 if (OMP_CLAUSE_REDUCTION_CODE (c) != ERROR_MARK)
1644 /* e1 and e3 have been stored as arguments of e4, avoid sharing. */
1645 e1 = gfc_copy_expr (e1);
1646 e3 = gfc_copy_expr (e3);
1647 t = gfc_resolve_expr (e4);
1648 gcc_assert (t);
1651 /* Create the init statement list. */
1652 pushlevel ();
1653 if (e2)
1654 stmt = gfc_trans_assignment (e1, e2, false, false);
1655 else
1656 stmt = gfc_trans_call (n->udr->initializer, false,
1657 NULL_TREE, NULL_TREE, false);
1658 if (TREE_CODE (stmt) != BIND_EXPR)
1659 stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
1660 else
1661 poplevel (0, 0);
1662 OMP_CLAUSE_REDUCTION_INIT (c) = stmt;
1664 /* Create the merge statement list. */
1665 pushlevel ();
1666 if (e4)
1667 stmt = gfc_trans_assignment (e3, e4, false, true);
1668 else
1669 stmt = gfc_trans_call (n->udr->combiner, false,
1670 NULL_TREE, NULL_TREE, false);
1671 if (TREE_CODE (stmt) != BIND_EXPR)
1672 stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
1673 else
1674 poplevel (0, 0);
1675 OMP_CLAUSE_REDUCTION_MERGE (c) = stmt;
1677 /* And stick the placeholder VAR_DECL into the clause as well. */
1678 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = outer_decl;
1680 gfc_current_locus = old_loc;
1682 gfc_free_expr (e1);
1683 if (e2)
1684 gfc_free_expr (e2);
1685 gfc_free_expr (e3);
1686 if (e4)
1687 gfc_free_expr (e4);
1688 free (symtree1);
1689 free (symtree2);
1690 free (symtree3);
1691 free (symtree4);
1692 if (outer_sym.as)
1693 gfc_free_array_spec (outer_sym.as);
1695 if (udr)
1697 *udr->omp_out = omp_var_copy[0];
1698 *udr->omp_in = omp_var_copy[1];
1699 if (udr->initializer_ns)
1701 *udr->omp_priv = omp_var_copy[2];
1702 *udr->omp_orig = omp_var_copy[3];
1707 static tree
1708 gfc_trans_omp_reduction_list (gfc_omp_namelist *namelist, tree list,
1709 locus where, bool mark_addressable)
1711 for (; namelist != NULL; namelist = namelist->next)
1712 if (namelist->sym->attr.referenced)
1714 tree t = gfc_trans_omp_variable (namelist->sym, false);
1715 if (t != error_mark_node)
1717 tree node = build_omp_clause (where.lb->location,
1718 OMP_CLAUSE_REDUCTION);
1719 OMP_CLAUSE_DECL (node) = t;
1720 if (mark_addressable)
1721 TREE_ADDRESSABLE (t) = 1;
1722 switch (namelist->u.reduction_op)
1724 case OMP_REDUCTION_PLUS:
1725 OMP_CLAUSE_REDUCTION_CODE (node) = PLUS_EXPR;
1726 break;
1727 case OMP_REDUCTION_MINUS:
1728 OMP_CLAUSE_REDUCTION_CODE (node) = MINUS_EXPR;
1729 break;
1730 case OMP_REDUCTION_TIMES:
1731 OMP_CLAUSE_REDUCTION_CODE (node) = MULT_EXPR;
1732 break;
1733 case OMP_REDUCTION_AND:
1734 OMP_CLAUSE_REDUCTION_CODE (node) = TRUTH_ANDIF_EXPR;
1735 break;
1736 case OMP_REDUCTION_OR:
1737 OMP_CLAUSE_REDUCTION_CODE (node) = TRUTH_ORIF_EXPR;
1738 break;
1739 case OMP_REDUCTION_EQV:
1740 OMP_CLAUSE_REDUCTION_CODE (node) = EQ_EXPR;
1741 break;
1742 case OMP_REDUCTION_NEQV:
1743 OMP_CLAUSE_REDUCTION_CODE (node) = NE_EXPR;
1744 break;
1745 case OMP_REDUCTION_MAX:
1746 OMP_CLAUSE_REDUCTION_CODE (node) = MAX_EXPR;
1747 break;
1748 case OMP_REDUCTION_MIN:
1749 OMP_CLAUSE_REDUCTION_CODE (node) = MIN_EXPR;
1750 break;
1751 case OMP_REDUCTION_IAND:
1752 OMP_CLAUSE_REDUCTION_CODE (node) = BIT_AND_EXPR;
1753 break;
1754 case OMP_REDUCTION_IOR:
1755 OMP_CLAUSE_REDUCTION_CODE (node) = BIT_IOR_EXPR;
1756 break;
1757 case OMP_REDUCTION_IEOR:
1758 OMP_CLAUSE_REDUCTION_CODE (node) = BIT_XOR_EXPR;
1759 break;
1760 case OMP_REDUCTION_USER:
1761 OMP_CLAUSE_REDUCTION_CODE (node) = ERROR_MARK;
1762 break;
1763 default:
1764 gcc_unreachable ();
1766 if (namelist->sym->attr.dimension
1767 || namelist->u.reduction_op == OMP_REDUCTION_USER
1768 || namelist->sym->attr.allocatable)
1769 gfc_trans_omp_array_reduction_or_udr (node, namelist, where);
1770 list = gfc_trans_add_clause (node, list);
1773 return list;
1776 static inline tree
1777 gfc_convert_expr_to_tree (stmtblock_t *block, gfc_expr *expr)
1779 gfc_se se;
1780 tree result;
1782 gfc_init_se (&se, NULL );
1783 gfc_conv_expr (&se, expr);
1784 gfc_add_block_to_block (block, &se.pre);
1785 result = gfc_evaluate_now (se.expr, block);
1786 gfc_add_block_to_block (block, &se.post);
1788 return result;
1791 static vec<tree, va_heap, vl_embed> *doacross_steps;
1793 static tree
1794 gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
1795 locus where, bool declare_simd = false)
1797 tree omp_clauses = NULL_TREE, chunk_size, c;
1798 int list, ifc;
1799 enum omp_clause_code clause_code;
1800 gfc_se se;
1802 if (clauses == NULL)
1803 return NULL_TREE;
1805 for (list = 0; list < OMP_LIST_NUM; list++)
1807 gfc_omp_namelist *n = clauses->lists[list];
1809 if (n == NULL)
1810 continue;
1811 switch (list)
1813 case OMP_LIST_REDUCTION:
1814 /* An OpenACC async clause indicates the need to set reduction
1815 arguments addressable, to allow asynchronous copy-out. */
1816 omp_clauses = gfc_trans_omp_reduction_list (n, omp_clauses, where,
1817 clauses->async);
1818 break;
1819 case OMP_LIST_PRIVATE:
1820 clause_code = OMP_CLAUSE_PRIVATE;
1821 goto add_clause;
1822 case OMP_LIST_SHARED:
1823 clause_code = OMP_CLAUSE_SHARED;
1824 goto add_clause;
1825 case OMP_LIST_FIRSTPRIVATE:
1826 clause_code = OMP_CLAUSE_FIRSTPRIVATE;
1827 goto add_clause;
1828 case OMP_LIST_LASTPRIVATE:
1829 clause_code = OMP_CLAUSE_LASTPRIVATE;
1830 goto add_clause;
1831 case OMP_LIST_COPYIN:
1832 clause_code = OMP_CLAUSE_COPYIN;
1833 goto add_clause;
1834 case OMP_LIST_COPYPRIVATE:
1835 clause_code = OMP_CLAUSE_COPYPRIVATE;
1836 goto add_clause;
1837 case OMP_LIST_UNIFORM:
1838 clause_code = OMP_CLAUSE_UNIFORM;
1839 goto add_clause;
1840 case OMP_LIST_USE_DEVICE:
1841 case OMP_LIST_USE_DEVICE_PTR:
1842 clause_code = OMP_CLAUSE_USE_DEVICE_PTR;
1843 goto add_clause;
1844 case OMP_LIST_IS_DEVICE_PTR:
1845 clause_code = OMP_CLAUSE_IS_DEVICE_PTR;
1846 goto add_clause;
1848 add_clause:
1849 omp_clauses
1850 = gfc_trans_omp_variable_list (clause_code, n, omp_clauses,
1851 declare_simd);
1852 break;
1853 case OMP_LIST_ALIGNED:
1854 for (; n != NULL; n = n->next)
1855 if (n->sym->attr.referenced || declare_simd)
1857 tree t = gfc_trans_omp_variable (n->sym, declare_simd);
1858 if (t != error_mark_node)
1860 tree node = build_omp_clause (input_location,
1861 OMP_CLAUSE_ALIGNED);
1862 OMP_CLAUSE_DECL (node) = t;
1863 if (n->expr)
1865 tree alignment_var;
1867 if (declare_simd)
1868 alignment_var = gfc_conv_constant_to_tree (n->expr);
1869 else
1871 gfc_init_se (&se, NULL);
1872 gfc_conv_expr (&se, n->expr);
1873 gfc_add_block_to_block (block, &se.pre);
1874 alignment_var = gfc_evaluate_now (se.expr, block);
1875 gfc_add_block_to_block (block, &se.post);
1877 OMP_CLAUSE_ALIGNED_ALIGNMENT (node) = alignment_var;
1879 omp_clauses = gfc_trans_add_clause (node, omp_clauses);
1882 break;
1883 case OMP_LIST_LINEAR:
1885 gfc_expr *last_step_expr = NULL;
1886 tree last_step = NULL_TREE;
1887 bool last_step_parm = false;
1889 for (; n != NULL; n = n->next)
1891 if (n->expr)
1893 last_step_expr = n->expr;
1894 last_step = NULL_TREE;
1895 last_step_parm = false;
1897 if (n->sym->attr.referenced || declare_simd)
1899 tree t = gfc_trans_omp_variable (n->sym, declare_simd);
1900 if (t != error_mark_node)
1902 tree node = build_omp_clause (input_location,
1903 OMP_CLAUSE_LINEAR);
1904 OMP_CLAUSE_DECL (node) = t;
1905 omp_clause_linear_kind kind;
1906 switch (n->u.linear_op)
1908 case OMP_LINEAR_DEFAULT:
1909 kind = OMP_CLAUSE_LINEAR_DEFAULT;
1910 break;
1911 case OMP_LINEAR_REF:
1912 kind = OMP_CLAUSE_LINEAR_REF;
1913 break;
1914 case OMP_LINEAR_VAL:
1915 kind = OMP_CLAUSE_LINEAR_VAL;
1916 break;
1917 case OMP_LINEAR_UVAL:
1918 kind = OMP_CLAUSE_LINEAR_UVAL;
1919 break;
1920 default:
1921 gcc_unreachable ();
1923 OMP_CLAUSE_LINEAR_KIND (node) = kind;
1924 if (last_step_expr && last_step == NULL_TREE)
1926 if (!declare_simd)
1928 gfc_init_se (&se, NULL);
1929 gfc_conv_expr (&se, last_step_expr);
1930 gfc_add_block_to_block (block, &se.pre);
1931 last_step = gfc_evaluate_now (se.expr, block);
1932 gfc_add_block_to_block (block, &se.post);
1934 else if (last_step_expr->expr_type == EXPR_VARIABLE)
1936 gfc_symbol *s = last_step_expr->symtree->n.sym;
1937 last_step = gfc_trans_omp_variable (s, true);
1938 last_step_parm = true;
1940 else
1941 last_step
1942 = gfc_conv_constant_to_tree (last_step_expr);
1944 if (last_step_parm)
1946 OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (node) = 1;
1947 OMP_CLAUSE_LINEAR_STEP (node) = last_step;
1949 else
1951 tree type = gfc_typenode_for_spec (&n->sym->ts);
1952 OMP_CLAUSE_LINEAR_STEP (node)
1953 = fold_convert (type, last_step);
1955 if (n->sym->attr.dimension || n->sym->attr.allocatable)
1956 OMP_CLAUSE_LINEAR_ARRAY (node) = 1;
1957 omp_clauses = gfc_trans_add_clause (node, omp_clauses);
1962 break;
1963 case OMP_LIST_DEPEND:
1964 for (; n != NULL; n = n->next)
1966 if (n->u.depend_op == OMP_DEPEND_SINK_FIRST)
1968 tree vec = NULL_TREE;
1969 unsigned int i;
1970 for (i = 0; ; i++)
1972 tree addend = integer_zero_node, t;
1973 bool neg = false;
1974 if (n->expr)
1976 addend = gfc_conv_constant_to_tree (n->expr);
1977 if (TREE_CODE (addend) == INTEGER_CST
1978 && tree_int_cst_sgn (addend) == -1)
1980 neg = true;
1981 addend = const_unop (NEGATE_EXPR,
1982 TREE_TYPE (addend), addend);
1985 t = gfc_trans_omp_variable (n->sym, false);
1986 if (t != error_mark_node)
1988 if (i < vec_safe_length (doacross_steps)
1989 && !integer_zerop (addend)
1990 && (*doacross_steps)[i])
1992 tree step = (*doacross_steps)[i];
1993 addend = fold_convert (TREE_TYPE (step), addend);
1994 addend = build2 (TRUNC_DIV_EXPR,
1995 TREE_TYPE (step), addend, step);
1997 vec = tree_cons (addend, t, vec);
1998 if (neg)
1999 OMP_CLAUSE_DEPEND_SINK_NEGATIVE (vec) = 1;
2001 if (n->next == NULL
2002 || n->next->u.depend_op != OMP_DEPEND_SINK)
2003 break;
2004 n = n->next;
2006 if (vec == NULL_TREE)
2007 continue;
2009 tree node = build_omp_clause (input_location,
2010 OMP_CLAUSE_DEPEND);
2011 OMP_CLAUSE_DEPEND_KIND (node) = OMP_CLAUSE_DEPEND_SINK;
2012 OMP_CLAUSE_DECL (node) = nreverse (vec);
2013 omp_clauses = gfc_trans_add_clause (node, omp_clauses);
2014 continue;
2017 if (!n->sym->attr.referenced)
2018 continue;
2020 tree node = build_omp_clause (input_location, OMP_CLAUSE_DEPEND);
2021 if (n->expr == NULL || n->expr->ref->u.ar.type == AR_FULL)
2023 tree decl = gfc_get_symbol_decl (n->sym);
2024 if (gfc_omp_privatize_by_reference (decl))
2025 decl = build_fold_indirect_ref (decl);
2026 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)))
2028 decl = gfc_conv_descriptor_data_get (decl);
2029 decl = fold_convert (build_pointer_type (char_type_node),
2030 decl);
2031 decl = build_fold_indirect_ref (decl);
2033 else if (DECL_P (decl))
2034 TREE_ADDRESSABLE (decl) = 1;
2035 OMP_CLAUSE_DECL (node) = decl;
2037 else
2039 tree ptr;
2040 gfc_init_se (&se, NULL);
2041 if (n->expr->ref->u.ar.type == AR_ELEMENT)
2043 gfc_conv_expr_reference (&se, n->expr);
2044 ptr = se.expr;
2046 else
2048 gfc_conv_expr_descriptor (&se, n->expr);
2049 ptr = gfc_conv_array_data (se.expr);
2051 gfc_add_block_to_block (block, &se.pre);
2052 gfc_add_block_to_block (block, &se.post);
2053 ptr = fold_convert (build_pointer_type (char_type_node),
2054 ptr);
2055 OMP_CLAUSE_DECL (node) = build_fold_indirect_ref (ptr);
2057 switch (n->u.depend_op)
2059 case OMP_DEPEND_IN:
2060 OMP_CLAUSE_DEPEND_KIND (node) = OMP_CLAUSE_DEPEND_IN;
2061 break;
2062 case OMP_DEPEND_OUT:
2063 OMP_CLAUSE_DEPEND_KIND (node) = OMP_CLAUSE_DEPEND_OUT;
2064 break;
2065 case OMP_DEPEND_INOUT:
2066 OMP_CLAUSE_DEPEND_KIND (node) = OMP_CLAUSE_DEPEND_INOUT;
2067 break;
2068 default:
2069 gcc_unreachable ();
2071 omp_clauses = gfc_trans_add_clause (node, omp_clauses);
2073 break;
2074 case OMP_LIST_MAP:
2075 for (; n != NULL; n = n->next)
2077 if (!n->sym->attr.referenced)
2078 continue;
2080 tree node = build_omp_clause (input_location, OMP_CLAUSE_MAP);
2081 tree node2 = NULL_TREE;
2082 tree node3 = NULL_TREE;
2083 tree node4 = NULL_TREE;
2084 tree decl = gfc_get_symbol_decl (n->sym);
2085 if (DECL_P (decl))
2086 TREE_ADDRESSABLE (decl) = 1;
2087 if (n->expr == NULL || n->expr->ref->u.ar.type == AR_FULL)
2089 if (POINTER_TYPE_P (TREE_TYPE (decl))
2090 && (gfc_omp_privatize_by_reference (decl)
2091 || GFC_DECL_GET_SCALAR_POINTER (decl)
2092 || GFC_DECL_GET_SCALAR_ALLOCATABLE (decl)
2093 || GFC_DECL_CRAY_POINTEE (decl)
2094 || GFC_DESCRIPTOR_TYPE_P
2095 (TREE_TYPE (TREE_TYPE (decl)))))
2097 tree orig_decl = decl;
2098 node4 = build_omp_clause (input_location,
2099 OMP_CLAUSE_MAP);
2100 OMP_CLAUSE_SET_MAP_KIND (node4, GOMP_MAP_POINTER);
2101 OMP_CLAUSE_DECL (node4) = decl;
2102 OMP_CLAUSE_SIZE (node4) = size_int (0);
2103 decl = build_fold_indirect_ref (decl);
2104 if (TREE_CODE (TREE_TYPE (orig_decl)) == REFERENCE_TYPE
2105 && (GFC_DECL_GET_SCALAR_POINTER (orig_decl)
2106 || GFC_DECL_GET_SCALAR_ALLOCATABLE (orig_decl)))
2108 node3 = build_omp_clause (input_location,
2109 OMP_CLAUSE_MAP);
2110 OMP_CLAUSE_SET_MAP_KIND (node3, GOMP_MAP_POINTER);
2111 OMP_CLAUSE_DECL (node3) = decl;
2112 OMP_CLAUSE_SIZE (node3) = size_int (0);
2113 decl = build_fold_indirect_ref (decl);
2116 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)))
2118 tree type = TREE_TYPE (decl);
2119 tree ptr = gfc_conv_descriptor_data_get (decl);
2120 ptr = fold_convert (build_pointer_type (char_type_node),
2121 ptr);
2122 ptr = build_fold_indirect_ref (ptr);
2123 OMP_CLAUSE_DECL (node) = ptr;
2124 node2 = build_omp_clause (input_location,
2125 OMP_CLAUSE_MAP);
2126 OMP_CLAUSE_SET_MAP_KIND (node2, GOMP_MAP_TO_PSET);
2127 OMP_CLAUSE_DECL (node2) = decl;
2128 OMP_CLAUSE_SIZE (node2) = TYPE_SIZE_UNIT (type);
2129 node3 = build_omp_clause (input_location,
2130 OMP_CLAUSE_MAP);
2131 OMP_CLAUSE_SET_MAP_KIND (node3, GOMP_MAP_POINTER);
2132 OMP_CLAUSE_DECL (node3)
2133 = gfc_conv_descriptor_data_get (decl);
2134 OMP_CLAUSE_SIZE (node3) = size_int (0);
2136 /* We have to check for n->sym->attr.dimension because
2137 of scalar coarrays. */
2138 if (n->sym->attr.pointer && n->sym->attr.dimension)
2140 stmtblock_t cond_block;
2141 tree size
2142 = gfc_create_var (gfc_array_index_type, NULL);
2143 tree tem, then_b, else_b, zero, cond;
2145 gfc_init_block (&cond_block);
2147 = gfc_full_array_size (&cond_block, decl,
2148 GFC_TYPE_ARRAY_RANK (type));
2149 gfc_add_modify (&cond_block, size, tem);
2150 then_b = gfc_finish_block (&cond_block);
2151 gfc_init_block (&cond_block);
2152 zero = build_int_cst (gfc_array_index_type, 0);
2153 gfc_add_modify (&cond_block, size, zero);
2154 else_b = gfc_finish_block (&cond_block);
2155 tem = gfc_conv_descriptor_data_get (decl);
2156 tem = fold_convert (pvoid_type_node, tem);
2157 cond = fold_build2_loc (input_location, NE_EXPR,
2158 boolean_type_node,
2159 tem, null_pointer_node);
2160 gfc_add_expr_to_block (block,
2161 build3_loc (input_location,
2162 COND_EXPR,
2163 void_type_node,
2164 cond, then_b,
2165 else_b));
2166 OMP_CLAUSE_SIZE (node) = size;
2168 else if (n->sym->attr.dimension)
2169 OMP_CLAUSE_SIZE (node)
2170 = gfc_full_array_size (block, decl,
2171 GFC_TYPE_ARRAY_RANK (type));
2172 if (n->sym->attr.dimension)
2174 tree elemsz
2175 = TYPE_SIZE_UNIT (gfc_get_element_type (type));
2176 elemsz = fold_convert (gfc_array_index_type, elemsz);
2177 OMP_CLAUSE_SIZE (node)
2178 = fold_build2 (MULT_EXPR, gfc_array_index_type,
2179 OMP_CLAUSE_SIZE (node), elemsz);
2182 else
2183 OMP_CLAUSE_DECL (node) = decl;
2185 else
2187 tree ptr, ptr2;
2188 gfc_init_se (&se, NULL);
2189 if (n->expr->ref->u.ar.type == AR_ELEMENT)
2191 gfc_conv_expr_reference (&se, n->expr);
2192 gfc_add_block_to_block (block, &se.pre);
2193 ptr = se.expr;
2194 OMP_CLAUSE_SIZE (node)
2195 = TYPE_SIZE_UNIT (TREE_TYPE (ptr));
2197 else
2199 gfc_conv_expr_descriptor (&se, n->expr);
2200 ptr = gfc_conv_array_data (se.expr);
2201 tree type = TREE_TYPE (se.expr);
2202 gfc_add_block_to_block (block, &se.pre);
2203 OMP_CLAUSE_SIZE (node)
2204 = gfc_full_array_size (block, se.expr,
2205 GFC_TYPE_ARRAY_RANK (type));
2206 tree elemsz
2207 = TYPE_SIZE_UNIT (gfc_get_element_type (type));
2208 elemsz = fold_convert (gfc_array_index_type, elemsz);
2209 OMP_CLAUSE_SIZE (node)
2210 = fold_build2 (MULT_EXPR, gfc_array_index_type,
2211 OMP_CLAUSE_SIZE (node), elemsz);
2213 gfc_add_block_to_block (block, &se.post);
2214 ptr = fold_convert (build_pointer_type (char_type_node),
2215 ptr);
2216 OMP_CLAUSE_DECL (node) = build_fold_indirect_ref (ptr);
2218 if (POINTER_TYPE_P (TREE_TYPE (decl))
2219 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (decl))))
2221 node4 = build_omp_clause (input_location,
2222 OMP_CLAUSE_MAP);
2223 OMP_CLAUSE_SET_MAP_KIND (node4, GOMP_MAP_POINTER);
2224 OMP_CLAUSE_DECL (node4) = decl;
2225 OMP_CLAUSE_SIZE (node4) = size_int (0);
2226 decl = build_fold_indirect_ref (decl);
2228 ptr = fold_convert (sizetype, ptr);
2229 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)))
2231 tree type = TREE_TYPE (decl);
2232 ptr2 = gfc_conv_descriptor_data_get (decl);
2233 node2 = build_omp_clause (input_location,
2234 OMP_CLAUSE_MAP);
2235 OMP_CLAUSE_SET_MAP_KIND (node2, GOMP_MAP_TO_PSET);
2236 OMP_CLAUSE_DECL (node2) = decl;
2237 OMP_CLAUSE_SIZE (node2) = TYPE_SIZE_UNIT (type);
2238 node3 = build_omp_clause (input_location,
2239 OMP_CLAUSE_MAP);
2240 OMP_CLAUSE_SET_MAP_KIND (node3, GOMP_MAP_POINTER);
2241 OMP_CLAUSE_DECL (node3)
2242 = gfc_conv_descriptor_data_get (decl);
2244 else
2246 if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
2247 ptr2 = build_fold_addr_expr (decl);
2248 else
2250 gcc_assert (POINTER_TYPE_P (TREE_TYPE (decl)));
2251 ptr2 = decl;
2253 node3 = build_omp_clause (input_location,
2254 OMP_CLAUSE_MAP);
2255 OMP_CLAUSE_SET_MAP_KIND (node3, GOMP_MAP_POINTER);
2256 OMP_CLAUSE_DECL (node3) = decl;
2258 ptr2 = fold_convert (sizetype, ptr2);
2259 OMP_CLAUSE_SIZE (node3)
2260 = fold_build2 (MINUS_EXPR, sizetype, ptr, ptr2);
2262 switch (n->u.map_op)
2264 case OMP_MAP_ALLOC:
2265 OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_ALLOC);
2266 break;
2267 case OMP_MAP_TO:
2268 OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_TO);
2269 break;
2270 case OMP_MAP_FROM:
2271 OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_FROM);
2272 break;
2273 case OMP_MAP_TOFROM:
2274 OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_TOFROM);
2275 break;
2276 case OMP_MAP_ALWAYS_TO:
2277 OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_ALWAYS_TO);
2278 break;
2279 case OMP_MAP_ALWAYS_FROM:
2280 OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_ALWAYS_FROM);
2281 break;
2282 case OMP_MAP_ALWAYS_TOFROM:
2283 OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_ALWAYS_TOFROM);
2284 break;
2285 case OMP_MAP_RELEASE:
2286 OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_RELEASE);
2287 break;
2288 case OMP_MAP_DELETE:
2289 OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_DELETE);
2290 break;
2291 case OMP_MAP_FORCE_ALLOC:
2292 OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_FORCE_ALLOC);
2293 break;
2294 case OMP_MAP_FORCE_TO:
2295 OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_FORCE_TO);
2296 break;
2297 case OMP_MAP_FORCE_FROM:
2298 OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_FORCE_FROM);
2299 break;
2300 case OMP_MAP_FORCE_TOFROM:
2301 OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_FORCE_TOFROM);
2302 break;
2303 case OMP_MAP_FORCE_PRESENT:
2304 OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_FORCE_PRESENT);
2305 break;
2306 case OMP_MAP_FORCE_DEVICEPTR:
2307 OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_FORCE_DEVICEPTR);
2308 break;
2309 default:
2310 gcc_unreachable ();
2312 omp_clauses = gfc_trans_add_clause (node, omp_clauses);
2313 if (node2)
2314 omp_clauses = gfc_trans_add_clause (node2, omp_clauses);
2315 if (node3)
2316 omp_clauses = gfc_trans_add_clause (node3, omp_clauses);
2317 if (node4)
2318 omp_clauses = gfc_trans_add_clause (node4, omp_clauses);
2320 break;
2321 case OMP_LIST_TO:
2322 case OMP_LIST_FROM:
2323 case OMP_LIST_CACHE:
2324 for (; n != NULL; n = n->next)
2326 if (!n->sym->attr.referenced)
2327 continue;
2329 switch (list)
2331 case OMP_LIST_TO:
2332 clause_code = OMP_CLAUSE_TO;
2333 break;
2334 case OMP_LIST_FROM:
2335 clause_code = OMP_CLAUSE_FROM;
2336 break;
2337 case OMP_LIST_CACHE:
2338 clause_code = OMP_CLAUSE__CACHE_;
2339 break;
2340 default:
2341 gcc_unreachable ();
2343 tree node = build_omp_clause (input_location, clause_code);
2344 if (n->expr == NULL || n->expr->ref->u.ar.type == AR_FULL)
2346 tree decl = gfc_get_symbol_decl (n->sym);
2347 if (gfc_omp_privatize_by_reference (decl))
2348 decl = build_fold_indirect_ref (decl);
2349 else if (DECL_P (decl))
2350 TREE_ADDRESSABLE (decl) = 1;
2351 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)))
2353 tree type = TREE_TYPE (decl);
2354 tree ptr = gfc_conv_descriptor_data_get (decl);
2355 ptr = fold_convert (build_pointer_type (char_type_node),
2356 ptr);
2357 ptr = build_fold_indirect_ref (ptr);
2358 OMP_CLAUSE_DECL (node) = ptr;
2359 OMP_CLAUSE_SIZE (node)
2360 = gfc_full_array_size (block, decl,
2361 GFC_TYPE_ARRAY_RANK (type));
2362 tree elemsz
2363 = TYPE_SIZE_UNIT (gfc_get_element_type (type));
2364 elemsz = fold_convert (gfc_array_index_type, elemsz);
2365 OMP_CLAUSE_SIZE (node)
2366 = fold_build2 (MULT_EXPR, gfc_array_index_type,
2367 OMP_CLAUSE_SIZE (node), elemsz);
2369 else
2370 OMP_CLAUSE_DECL (node) = decl;
2372 else
2374 tree ptr;
2375 gfc_init_se (&se, NULL);
2376 if (n->expr->ref->u.ar.type == AR_ELEMENT)
2378 gfc_conv_expr_reference (&se, n->expr);
2379 ptr = se.expr;
2380 gfc_add_block_to_block (block, &se.pre);
2381 OMP_CLAUSE_SIZE (node)
2382 = TYPE_SIZE_UNIT (TREE_TYPE (ptr));
2384 else
2386 gfc_conv_expr_descriptor (&se, n->expr);
2387 ptr = gfc_conv_array_data (se.expr);
2388 tree type = TREE_TYPE (se.expr);
2389 gfc_add_block_to_block (block, &se.pre);
2390 OMP_CLAUSE_SIZE (node)
2391 = gfc_full_array_size (block, se.expr,
2392 GFC_TYPE_ARRAY_RANK (type));
2393 tree elemsz
2394 = TYPE_SIZE_UNIT (gfc_get_element_type (type));
2395 elemsz = fold_convert (gfc_array_index_type, elemsz);
2396 OMP_CLAUSE_SIZE (node)
2397 = fold_build2 (MULT_EXPR, gfc_array_index_type,
2398 OMP_CLAUSE_SIZE (node), elemsz);
2400 gfc_add_block_to_block (block, &se.post);
2401 ptr = fold_convert (build_pointer_type (char_type_node),
2402 ptr);
2403 OMP_CLAUSE_DECL (node) = build_fold_indirect_ref (ptr);
2405 omp_clauses = gfc_trans_add_clause (node, omp_clauses);
2407 break;
2408 default:
2409 break;
2413 if (clauses->if_expr)
2415 tree if_var;
2417 gfc_init_se (&se, NULL);
2418 gfc_conv_expr (&se, clauses->if_expr);
2419 gfc_add_block_to_block (block, &se.pre);
2420 if_var = gfc_evaluate_now (se.expr, block);
2421 gfc_add_block_to_block (block, &se.post);
2423 c = build_omp_clause (where.lb->location, OMP_CLAUSE_IF);
2424 OMP_CLAUSE_IF_MODIFIER (c) = ERROR_MARK;
2425 OMP_CLAUSE_IF_EXPR (c) = if_var;
2426 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
2428 for (ifc = 0; ifc < OMP_IF_LAST; ifc++)
2429 if (clauses->if_exprs[ifc])
2431 tree if_var;
2433 gfc_init_se (&se, NULL);
2434 gfc_conv_expr (&se, clauses->if_exprs[ifc]);
2435 gfc_add_block_to_block (block, &se.pre);
2436 if_var = gfc_evaluate_now (se.expr, block);
2437 gfc_add_block_to_block (block, &se.post);
2439 c = build_omp_clause (where.lb->location, OMP_CLAUSE_IF);
2440 switch (ifc)
2442 case OMP_IF_PARALLEL:
2443 OMP_CLAUSE_IF_MODIFIER (c) = OMP_PARALLEL;
2444 break;
2445 case OMP_IF_TASK:
2446 OMP_CLAUSE_IF_MODIFIER (c) = OMP_TASK;
2447 break;
2448 case OMP_IF_TASKLOOP:
2449 OMP_CLAUSE_IF_MODIFIER (c) = OMP_TASKLOOP;
2450 break;
2451 case OMP_IF_TARGET:
2452 OMP_CLAUSE_IF_MODIFIER (c) = OMP_TARGET;
2453 break;
2454 case OMP_IF_TARGET_DATA:
2455 OMP_CLAUSE_IF_MODIFIER (c) = OMP_TARGET_DATA;
2456 break;
2457 case OMP_IF_TARGET_UPDATE:
2458 OMP_CLAUSE_IF_MODIFIER (c) = OMP_TARGET_UPDATE;
2459 break;
2460 case OMP_IF_TARGET_ENTER_DATA:
2461 OMP_CLAUSE_IF_MODIFIER (c) = OMP_TARGET_ENTER_DATA;
2462 break;
2463 case OMP_IF_TARGET_EXIT_DATA:
2464 OMP_CLAUSE_IF_MODIFIER (c) = OMP_TARGET_EXIT_DATA;
2465 break;
2466 default:
2467 gcc_unreachable ();
2469 OMP_CLAUSE_IF_EXPR (c) = if_var;
2470 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
2473 if (clauses->final_expr)
2475 tree final_var;
2477 gfc_init_se (&se, NULL);
2478 gfc_conv_expr (&se, clauses->final_expr);
2479 gfc_add_block_to_block (block, &se.pre);
2480 final_var = gfc_evaluate_now (se.expr, block);
2481 gfc_add_block_to_block (block, &se.post);
2483 c = build_omp_clause (where.lb->location, OMP_CLAUSE_FINAL);
2484 OMP_CLAUSE_FINAL_EXPR (c) = final_var;
2485 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
2488 if (clauses->num_threads)
2490 tree num_threads;
2492 gfc_init_se (&se, NULL);
2493 gfc_conv_expr (&se, clauses->num_threads);
2494 gfc_add_block_to_block (block, &se.pre);
2495 num_threads = gfc_evaluate_now (se.expr, block);
2496 gfc_add_block_to_block (block, &se.post);
2498 c = build_omp_clause (where.lb->location, OMP_CLAUSE_NUM_THREADS);
2499 OMP_CLAUSE_NUM_THREADS_EXPR (c) = num_threads;
2500 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
2503 chunk_size = NULL_TREE;
2504 if (clauses->chunk_size)
2506 gfc_init_se (&se, NULL);
2507 gfc_conv_expr (&se, clauses->chunk_size);
2508 gfc_add_block_to_block (block, &se.pre);
2509 chunk_size = gfc_evaluate_now (se.expr, block);
2510 gfc_add_block_to_block (block, &se.post);
2513 if (clauses->sched_kind != OMP_SCHED_NONE)
2515 c = build_omp_clause (where.lb->location, OMP_CLAUSE_SCHEDULE);
2516 OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = chunk_size;
2517 switch (clauses->sched_kind)
2519 case OMP_SCHED_STATIC:
2520 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_STATIC;
2521 break;
2522 case OMP_SCHED_DYNAMIC:
2523 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_DYNAMIC;
2524 break;
2525 case OMP_SCHED_GUIDED:
2526 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_GUIDED;
2527 break;
2528 case OMP_SCHED_RUNTIME:
2529 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_RUNTIME;
2530 break;
2531 case OMP_SCHED_AUTO:
2532 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_AUTO;
2533 break;
2534 default:
2535 gcc_unreachable ();
2537 if (clauses->sched_monotonic)
2538 OMP_CLAUSE_SCHEDULE_KIND (c)
2539 = (omp_clause_schedule_kind) (OMP_CLAUSE_SCHEDULE_KIND (c)
2540 | OMP_CLAUSE_SCHEDULE_MONOTONIC);
2541 else if (clauses->sched_nonmonotonic)
2542 OMP_CLAUSE_SCHEDULE_KIND (c)
2543 = (omp_clause_schedule_kind) (OMP_CLAUSE_SCHEDULE_KIND (c)
2544 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC);
2545 if (clauses->sched_simd)
2546 OMP_CLAUSE_SCHEDULE_SIMD (c) = 1;
2547 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
2550 if (clauses->default_sharing != OMP_DEFAULT_UNKNOWN)
2552 c = build_omp_clause (where.lb->location, OMP_CLAUSE_DEFAULT);
2553 switch (clauses->default_sharing)
2555 case OMP_DEFAULT_NONE:
2556 OMP_CLAUSE_DEFAULT_KIND (c) = OMP_CLAUSE_DEFAULT_NONE;
2557 break;
2558 case OMP_DEFAULT_SHARED:
2559 OMP_CLAUSE_DEFAULT_KIND (c) = OMP_CLAUSE_DEFAULT_SHARED;
2560 break;
2561 case OMP_DEFAULT_PRIVATE:
2562 OMP_CLAUSE_DEFAULT_KIND (c) = OMP_CLAUSE_DEFAULT_PRIVATE;
2563 break;
2564 case OMP_DEFAULT_FIRSTPRIVATE:
2565 OMP_CLAUSE_DEFAULT_KIND (c) = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
2566 break;
2567 default:
2568 gcc_unreachable ();
2570 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
2573 if (clauses->nowait)
2575 c = build_omp_clause (where.lb->location, OMP_CLAUSE_NOWAIT);
2576 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
2579 if (clauses->ordered)
2581 c = build_omp_clause (where.lb->location, OMP_CLAUSE_ORDERED);
2582 OMP_CLAUSE_ORDERED_EXPR (c)
2583 = clauses->orderedc ? build_int_cst (integer_type_node,
2584 clauses->orderedc) : NULL_TREE;
2585 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
2588 if (clauses->untied)
2590 c = build_omp_clause (where.lb->location, OMP_CLAUSE_UNTIED);
2591 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
2594 if (clauses->mergeable)
2596 c = build_omp_clause (where.lb->location, OMP_CLAUSE_MERGEABLE);
2597 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
2600 if (clauses->collapse)
2602 c = build_omp_clause (where.lb->location, OMP_CLAUSE_COLLAPSE);
2603 OMP_CLAUSE_COLLAPSE_EXPR (c)
2604 = build_int_cst (integer_type_node, clauses->collapse);
2605 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
2608 if (clauses->inbranch)
2610 c = build_omp_clause (where.lb->location, OMP_CLAUSE_INBRANCH);
2611 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
2614 if (clauses->notinbranch)
2616 c = build_omp_clause (where.lb->location, OMP_CLAUSE_NOTINBRANCH);
2617 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
2620 switch (clauses->cancel)
2622 case OMP_CANCEL_UNKNOWN:
2623 break;
2624 case OMP_CANCEL_PARALLEL:
2625 c = build_omp_clause (where.lb->location, OMP_CLAUSE_PARALLEL);
2626 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
2627 break;
2628 case OMP_CANCEL_SECTIONS:
2629 c = build_omp_clause (where.lb->location, OMP_CLAUSE_SECTIONS);
2630 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
2631 break;
2632 case OMP_CANCEL_DO:
2633 c = build_omp_clause (where.lb->location, OMP_CLAUSE_FOR);
2634 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
2635 break;
2636 case OMP_CANCEL_TASKGROUP:
2637 c = build_omp_clause (where.lb->location, OMP_CLAUSE_TASKGROUP);
2638 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
2639 break;
2642 if (clauses->proc_bind != OMP_PROC_BIND_UNKNOWN)
2644 c = build_omp_clause (where.lb->location, OMP_CLAUSE_PROC_BIND);
2645 switch (clauses->proc_bind)
2647 case OMP_PROC_BIND_MASTER:
2648 OMP_CLAUSE_PROC_BIND_KIND (c) = OMP_CLAUSE_PROC_BIND_MASTER;
2649 break;
2650 case OMP_PROC_BIND_SPREAD:
2651 OMP_CLAUSE_PROC_BIND_KIND (c) = OMP_CLAUSE_PROC_BIND_SPREAD;
2652 break;
2653 case OMP_PROC_BIND_CLOSE:
2654 OMP_CLAUSE_PROC_BIND_KIND (c) = OMP_CLAUSE_PROC_BIND_CLOSE;
2655 break;
2656 default:
2657 gcc_unreachable ();
2659 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
2662 if (clauses->safelen_expr)
2664 tree safelen_var;
2666 gfc_init_se (&se, NULL);
2667 gfc_conv_expr (&se, clauses->safelen_expr);
2668 gfc_add_block_to_block (block, &se.pre);
2669 safelen_var = gfc_evaluate_now (se.expr, block);
2670 gfc_add_block_to_block (block, &se.post);
2672 c = build_omp_clause (where.lb->location, OMP_CLAUSE_SAFELEN);
2673 OMP_CLAUSE_SAFELEN_EXPR (c) = safelen_var;
2674 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
2677 if (clauses->simdlen_expr)
2679 if (declare_simd)
2681 c = build_omp_clause (where.lb->location, OMP_CLAUSE_SIMDLEN);
2682 OMP_CLAUSE_SIMDLEN_EXPR (c)
2683 = gfc_conv_constant_to_tree (clauses->simdlen_expr);
2684 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
2686 else
2688 tree simdlen_var;
2690 gfc_init_se (&se, NULL);
2691 gfc_conv_expr (&se, clauses->simdlen_expr);
2692 gfc_add_block_to_block (block, &se.pre);
2693 simdlen_var = gfc_evaluate_now (se.expr, block);
2694 gfc_add_block_to_block (block, &se.post);
2696 c = build_omp_clause (where.lb->location, OMP_CLAUSE_SIMDLEN);
2697 OMP_CLAUSE_SIMDLEN_EXPR (c) = simdlen_var;
2698 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
2702 if (clauses->num_teams)
2704 tree num_teams;
2706 gfc_init_se (&se, NULL);
2707 gfc_conv_expr (&se, clauses->num_teams);
2708 gfc_add_block_to_block (block, &se.pre);
2709 num_teams = gfc_evaluate_now (se.expr, block);
2710 gfc_add_block_to_block (block, &se.post);
2712 c = build_omp_clause (where.lb->location, OMP_CLAUSE_NUM_TEAMS);
2713 OMP_CLAUSE_NUM_TEAMS_EXPR (c) = num_teams;
2714 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
2717 if (clauses->device)
2719 tree device;
2721 gfc_init_se (&se, NULL);
2722 gfc_conv_expr (&se, clauses->device);
2723 gfc_add_block_to_block (block, &se.pre);
2724 device = gfc_evaluate_now (se.expr, block);
2725 gfc_add_block_to_block (block, &se.post);
2727 c = build_omp_clause (where.lb->location, OMP_CLAUSE_DEVICE);
2728 OMP_CLAUSE_DEVICE_ID (c) = device;
2729 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
2732 if (clauses->thread_limit)
2734 tree thread_limit;
2736 gfc_init_se (&se, NULL);
2737 gfc_conv_expr (&se, clauses->thread_limit);
2738 gfc_add_block_to_block (block, &se.pre);
2739 thread_limit = gfc_evaluate_now (se.expr, block);
2740 gfc_add_block_to_block (block, &se.post);
2742 c = build_omp_clause (where.lb->location, OMP_CLAUSE_THREAD_LIMIT);
2743 OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = thread_limit;
2744 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
2747 chunk_size = NULL_TREE;
2748 if (clauses->dist_chunk_size)
2750 gfc_init_se (&se, NULL);
2751 gfc_conv_expr (&se, clauses->dist_chunk_size);
2752 gfc_add_block_to_block (block, &se.pre);
2753 chunk_size = gfc_evaluate_now (se.expr, block);
2754 gfc_add_block_to_block (block, &se.post);
2757 if (clauses->dist_sched_kind != OMP_SCHED_NONE)
2759 c = build_omp_clause (where.lb->location, OMP_CLAUSE_DIST_SCHEDULE);
2760 OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c) = chunk_size;
2761 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
2764 if (clauses->grainsize)
2766 tree grainsize;
2768 gfc_init_se (&se, NULL);
2769 gfc_conv_expr (&se, clauses->grainsize);
2770 gfc_add_block_to_block (block, &se.pre);
2771 grainsize = gfc_evaluate_now (se.expr, block);
2772 gfc_add_block_to_block (block, &se.post);
2774 c = build_omp_clause (where.lb->location, OMP_CLAUSE_GRAINSIZE);
2775 OMP_CLAUSE_GRAINSIZE_EXPR (c) = grainsize;
2776 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
2779 if (clauses->num_tasks)
2781 tree num_tasks;
2783 gfc_init_se (&se, NULL);
2784 gfc_conv_expr (&se, clauses->num_tasks);
2785 gfc_add_block_to_block (block, &se.pre);
2786 num_tasks = gfc_evaluate_now (se.expr, block);
2787 gfc_add_block_to_block (block, &se.post);
2789 c = build_omp_clause (where.lb->location, OMP_CLAUSE_NUM_TASKS);
2790 OMP_CLAUSE_NUM_TASKS_EXPR (c) = num_tasks;
2791 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
2794 if (clauses->priority)
2796 tree priority;
2798 gfc_init_se (&se, NULL);
2799 gfc_conv_expr (&se, clauses->priority);
2800 gfc_add_block_to_block (block, &se.pre);
2801 priority = gfc_evaluate_now (se.expr, block);
2802 gfc_add_block_to_block (block, &se.post);
2804 c = build_omp_clause (where.lb->location, OMP_CLAUSE_PRIORITY);
2805 OMP_CLAUSE_PRIORITY_EXPR (c) = priority;
2806 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
2809 if (clauses->hint)
2811 tree hint;
2813 gfc_init_se (&se, NULL);
2814 gfc_conv_expr (&se, clauses->hint);
2815 gfc_add_block_to_block (block, &se.pre);
2816 hint = gfc_evaluate_now (se.expr, block);
2817 gfc_add_block_to_block (block, &se.post);
2819 c = build_omp_clause (where.lb->location, OMP_CLAUSE_HINT);
2820 OMP_CLAUSE_HINT_EXPR (c) = hint;
2821 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
2824 if (clauses->simd)
2826 c = build_omp_clause (where.lb->location, OMP_CLAUSE_SIMD);
2827 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
2829 if (clauses->threads)
2831 c = build_omp_clause (where.lb->location, OMP_CLAUSE_THREADS);
2832 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
2834 if (clauses->nogroup)
2836 c = build_omp_clause (where.lb->location, OMP_CLAUSE_NOGROUP);
2837 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
2839 if (clauses->defaultmap)
2841 c = build_omp_clause (where.lb->location, OMP_CLAUSE_DEFAULTMAP);
2842 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
2844 if (clauses->depend_source)
2846 c = build_omp_clause (where.lb->location, OMP_CLAUSE_DEPEND);
2847 OMP_CLAUSE_DEPEND_KIND (c) = OMP_CLAUSE_DEPEND_SOURCE;
2848 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
2851 if (clauses->async)
2853 c = build_omp_clause (where.lb->location, OMP_CLAUSE_ASYNC);
2854 if (clauses->async_expr)
2855 OMP_CLAUSE_ASYNC_EXPR (c)
2856 = gfc_convert_expr_to_tree (block, clauses->async_expr);
2857 else
2858 OMP_CLAUSE_ASYNC_EXPR (c) = NULL;
2859 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
2861 if (clauses->seq)
2863 c = build_omp_clause (where.lb->location, OMP_CLAUSE_SEQ);
2864 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
2866 if (clauses->par_auto)
2868 c = build_omp_clause (where.lb->location, OMP_CLAUSE_AUTO);
2869 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
2871 if (clauses->independent)
2873 c = build_omp_clause (where.lb->location, OMP_CLAUSE_INDEPENDENT);
2874 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
2876 if (clauses->wait_list)
2878 gfc_expr_list *el;
2880 for (el = clauses->wait_list; el; el = el->next)
2882 c = build_omp_clause (where.lb->location, OMP_CLAUSE_WAIT);
2883 OMP_CLAUSE_DECL (c) = gfc_convert_expr_to_tree (block, el->expr);
2884 OMP_CLAUSE_CHAIN (c) = omp_clauses;
2885 omp_clauses = c;
2888 if (clauses->num_gangs_expr)
2890 tree num_gangs_var
2891 = gfc_convert_expr_to_tree (block, clauses->num_gangs_expr);
2892 c = build_omp_clause (where.lb->location, OMP_CLAUSE_NUM_GANGS);
2893 OMP_CLAUSE_NUM_GANGS_EXPR (c) = num_gangs_var;
2894 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
2896 if (clauses->num_workers_expr)
2898 tree num_workers_var
2899 = gfc_convert_expr_to_tree (block, clauses->num_workers_expr);
2900 c = build_omp_clause (where.lb->location, OMP_CLAUSE_NUM_WORKERS);
2901 OMP_CLAUSE_NUM_WORKERS_EXPR (c) = num_workers_var;
2902 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
2904 if (clauses->vector_length_expr)
2906 tree vector_length_var
2907 = gfc_convert_expr_to_tree (block, clauses->vector_length_expr);
2908 c = build_omp_clause (where.lb->location, OMP_CLAUSE_VECTOR_LENGTH);
2909 OMP_CLAUSE_VECTOR_LENGTH_EXPR (c) = vector_length_var;
2910 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
2912 if (clauses->tile_list)
2914 vec<tree, va_gc> *tvec;
2915 gfc_expr_list *el;
2917 vec_alloc (tvec, 4);
2919 for (el = clauses->tile_list; el; el = el->next)
2920 vec_safe_push (tvec, gfc_convert_expr_to_tree (block, el->expr));
2922 c = build_omp_clause (where.lb->location, OMP_CLAUSE_TILE);
2923 OMP_CLAUSE_TILE_LIST (c) = build_tree_list_vec (tvec);
2924 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
2925 tvec->truncate (0);
2927 if (clauses->vector)
2929 if (clauses->vector_expr)
2931 tree vector_var
2932 = gfc_convert_expr_to_tree (block, clauses->vector_expr);
2933 c = build_omp_clause (where.lb->location, OMP_CLAUSE_VECTOR);
2934 OMP_CLAUSE_VECTOR_EXPR (c) = vector_var;
2935 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
2937 else
2939 c = build_omp_clause (where.lb->location, OMP_CLAUSE_VECTOR);
2940 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
2943 if (clauses->worker)
2945 if (clauses->worker_expr)
2947 tree worker_var
2948 = gfc_convert_expr_to_tree (block, clauses->worker_expr);
2949 c = build_omp_clause (where.lb->location, OMP_CLAUSE_WORKER);
2950 OMP_CLAUSE_WORKER_EXPR (c) = worker_var;
2951 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
2953 else
2955 c = build_omp_clause (where.lb->location, OMP_CLAUSE_WORKER);
2956 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
2959 if (clauses->gang)
2961 tree arg;
2962 c = build_omp_clause (where.lb->location, OMP_CLAUSE_GANG);
2963 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
2964 if (clauses->gang_num_expr)
2966 arg = gfc_convert_expr_to_tree (block, clauses->gang_num_expr);
2967 OMP_CLAUSE_GANG_EXPR (c) = arg;
2969 if (clauses->gang_static)
2971 arg = clauses->gang_static_expr
2972 ? gfc_convert_expr_to_tree (block, clauses->gang_static_expr)
2973 : integer_minus_one_node;
2974 OMP_CLAUSE_GANG_STATIC_EXPR (c) = arg;
2978 return nreverse (omp_clauses);
2981 /* Like gfc_trans_code, but force creation of a BIND_EXPR around it. */
2983 static tree
2984 gfc_trans_omp_code (gfc_code *code, bool force_empty)
2986 tree stmt;
2988 pushlevel ();
2989 stmt = gfc_trans_code (code);
2990 if (TREE_CODE (stmt) != BIND_EXPR)
2992 if (!IS_EMPTY_STMT (stmt) || force_empty)
2994 tree block = poplevel (1, 0);
2995 stmt = build3_v (BIND_EXPR, NULL, stmt, block);
2997 else
2998 poplevel (0, 0);
3000 else
3001 poplevel (0, 0);
3002 return stmt;
3005 /* Trans OpenACC directives. */
3006 /* parallel, kernels, data and host_data. */
3007 static tree
3008 gfc_trans_oacc_construct (gfc_code *code)
3010 stmtblock_t block;
3011 tree stmt, oacc_clauses;
3012 enum tree_code construct_code;
3014 switch (code->op)
3016 case EXEC_OACC_PARALLEL:
3017 construct_code = OACC_PARALLEL;
3018 break;
3019 case EXEC_OACC_KERNELS:
3020 construct_code = OACC_KERNELS;
3021 break;
3022 case EXEC_OACC_DATA:
3023 construct_code = OACC_DATA;
3024 break;
3025 case EXEC_OACC_HOST_DATA:
3026 construct_code = OACC_HOST_DATA;
3027 break;
3028 default:
3029 gcc_unreachable ();
3032 gfc_start_block (&block);
3033 oacc_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
3034 code->loc);
3035 stmt = gfc_trans_omp_code (code->block->next, true);
3036 stmt = build2_loc (input_location, construct_code, void_type_node, stmt,
3037 oacc_clauses);
3038 gfc_add_expr_to_block (&block, stmt);
3039 return gfc_finish_block (&block);
3042 /* update, enter_data, exit_data, cache. */
3043 static tree
3044 gfc_trans_oacc_executable_directive (gfc_code *code)
3046 stmtblock_t block;
3047 tree stmt, oacc_clauses;
3048 enum tree_code construct_code;
3050 switch (code->op)
3052 case EXEC_OACC_UPDATE:
3053 construct_code = OACC_UPDATE;
3054 break;
3055 case EXEC_OACC_ENTER_DATA:
3056 construct_code = OACC_ENTER_DATA;
3057 break;
3058 case EXEC_OACC_EXIT_DATA:
3059 construct_code = OACC_EXIT_DATA;
3060 break;
3061 case EXEC_OACC_CACHE:
3062 construct_code = OACC_CACHE;
3063 break;
3064 default:
3065 gcc_unreachable ();
3068 gfc_start_block (&block);
3069 oacc_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
3070 code->loc);
3071 stmt = build1_loc (input_location, construct_code, void_type_node,
3072 oacc_clauses);
3073 gfc_add_expr_to_block (&block, stmt);
3074 return gfc_finish_block (&block);
3077 static tree
3078 gfc_trans_oacc_wait_directive (gfc_code *code)
3080 stmtblock_t block;
3081 tree stmt, t;
3082 vec<tree, va_gc> *args;
3083 int nparms = 0;
3084 gfc_expr_list *el;
3085 gfc_omp_clauses *clauses = code->ext.omp_clauses;
3086 location_t loc = input_location;
3088 for (el = clauses->wait_list; el; el = el->next)
3089 nparms++;
3091 vec_alloc (args, nparms + 2);
3092 stmt = builtin_decl_explicit (BUILT_IN_GOACC_WAIT);
3094 gfc_start_block (&block);
3096 if (clauses->async_expr)
3097 t = gfc_convert_expr_to_tree (&block, clauses->async_expr);
3098 else
3099 t = build_int_cst (integer_type_node, -2);
3101 args->quick_push (t);
3102 args->quick_push (build_int_cst (integer_type_node, nparms));
3104 for (el = clauses->wait_list; el; el = el->next)
3105 args->quick_push (gfc_convert_expr_to_tree (&block, el->expr));
3107 stmt = build_call_expr_loc_vec (loc, stmt, args);
3108 gfc_add_expr_to_block (&block, stmt);
3110 vec_free (args);
3112 return gfc_finish_block (&block);
3115 static tree gfc_trans_omp_sections (gfc_code *, gfc_omp_clauses *);
3116 static tree gfc_trans_omp_workshare (gfc_code *, gfc_omp_clauses *);
3118 static tree
3119 gfc_trans_omp_atomic (gfc_code *code)
3121 gfc_code *atomic_code = code;
3122 gfc_se lse;
3123 gfc_se rse;
3124 gfc_se vse;
3125 gfc_expr *expr2, *e;
3126 gfc_symbol *var;
3127 stmtblock_t block;
3128 tree lhsaddr, type, rhs, x;
3129 enum tree_code op = ERROR_MARK;
3130 enum tree_code aop = OMP_ATOMIC;
3131 bool var_on_left = false;
3132 bool seq_cst = (atomic_code->ext.omp_atomic & GFC_OMP_ATOMIC_SEQ_CST) != 0;
3134 code = code->block->next;
3135 gcc_assert (code->op == EXEC_ASSIGN);
3136 var = code->expr1->symtree->n.sym;
3138 gfc_init_se (&lse, NULL);
3139 gfc_init_se (&rse, NULL);
3140 gfc_init_se (&vse, NULL);
3141 gfc_start_block (&block);
3143 expr2 = code->expr2;
3144 if (((atomic_code->ext.omp_atomic & GFC_OMP_ATOMIC_MASK)
3145 != GFC_OMP_ATOMIC_WRITE)
3146 && (atomic_code->ext.omp_atomic & GFC_OMP_ATOMIC_SWAP) == 0
3147 && expr2->expr_type == EXPR_FUNCTION
3148 && expr2->value.function.isym
3149 && expr2->value.function.isym->id == GFC_ISYM_CONVERSION)
3150 expr2 = expr2->value.function.actual->expr;
3152 switch (atomic_code->ext.omp_atomic & GFC_OMP_ATOMIC_MASK)
3154 case GFC_OMP_ATOMIC_READ:
3155 gfc_conv_expr (&vse, code->expr1);
3156 gfc_add_block_to_block (&block, &vse.pre);
3158 gfc_conv_expr (&lse, expr2);
3159 gfc_add_block_to_block (&block, &lse.pre);
3160 type = TREE_TYPE (lse.expr);
3161 lhsaddr = gfc_build_addr_expr (NULL, lse.expr);
3163 x = build1 (OMP_ATOMIC_READ, type, lhsaddr);
3164 OMP_ATOMIC_SEQ_CST (x) = seq_cst;
3165 x = convert (TREE_TYPE (vse.expr), x);
3166 gfc_add_modify (&block, vse.expr, x);
3168 gfc_add_block_to_block (&block, &lse.pre);
3169 gfc_add_block_to_block (&block, &rse.pre);
3171 return gfc_finish_block (&block);
3172 case GFC_OMP_ATOMIC_CAPTURE:
3173 aop = OMP_ATOMIC_CAPTURE_NEW;
3174 if (expr2->expr_type == EXPR_VARIABLE)
3176 aop = OMP_ATOMIC_CAPTURE_OLD;
3177 gfc_conv_expr (&vse, code->expr1);
3178 gfc_add_block_to_block (&block, &vse.pre);
3180 gfc_conv_expr (&lse, expr2);
3181 gfc_add_block_to_block (&block, &lse.pre);
3182 gfc_init_se (&lse, NULL);
3183 code = code->next;
3184 var = code->expr1->symtree->n.sym;
3185 expr2 = code->expr2;
3186 if (expr2->expr_type == EXPR_FUNCTION
3187 && expr2->value.function.isym
3188 && expr2->value.function.isym->id == GFC_ISYM_CONVERSION)
3189 expr2 = expr2->value.function.actual->expr;
3191 break;
3192 default:
3193 break;
3196 gfc_conv_expr (&lse, code->expr1);
3197 gfc_add_block_to_block (&block, &lse.pre);
3198 type = TREE_TYPE (lse.expr);
3199 lhsaddr = gfc_build_addr_expr (NULL, lse.expr);
3201 if (((atomic_code->ext.omp_atomic & GFC_OMP_ATOMIC_MASK)
3202 == GFC_OMP_ATOMIC_WRITE)
3203 || (atomic_code->ext.omp_atomic & GFC_OMP_ATOMIC_SWAP))
3205 gfc_conv_expr (&rse, expr2);
3206 gfc_add_block_to_block (&block, &rse.pre);
3208 else if (expr2->expr_type == EXPR_OP)
3210 gfc_expr *e;
3211 switch (expr2->value.op.op)
3213 case INTRINSIC_PLUS:
3214 op = PLUS_EXPR;
3215 break;
3216 case INTRINSIC_TIMES:
3217 op = MULT_EXPR;
3218 break;
3219 case INTRINSIC_MINUS:
3220 op = MINUS_EXPR;
3221 break;
3222 case INTRINSIC_DIVIDE:
3223 if (expr2->ts.type == BT_INTEGER)
3224 op = TRUNC_DIV_EXPR;
3225 else
3226 op = RDIV_EXPR;
3227 break;
3228 case INTRINSIC_AND:
3229 op = TRUTH_ANDIF_EXPR;
3230 break;
3231 case INTRINSIC_OR:
3232 op = TRUTH_ORIF_EXPR;
3233 break;
3234 case INTRINSIC_EQV:
3235 op = EQ_EXPR;
3236 break;
3237 case INTRINSIC_NEQV:
3238 op = NE_EXPR;
3239 break;
3240 default:
3241 gcc_unreachable ();
3243 e = expr2->value.op.op1;
3244 if (e->expr_type == EXPR_FUNCTION
3245 && e->value.function.isym
3246 && e->value.function.isym->id == GFC_ISYM_CONVERSION)
3247 e = e->value.function.actual->expr;
3248 if (e->expr_type == EXPR_VARIABLE
3249 && e->symtree != NULL
3250 && e->symtree->n.sym == var)
3252 expr2 = expr2->value.op.op2;
3253 var_on_left = true;
3255 else
3257 e = expr2->value.op.op2;
3258 if (e->expr_type == EXPR_FUNCTION
3259 && e->value.function.isym
3260 && e->value.function.isym->id == GFC_ISYM_CONVERSION)
3261 e = e->value.function.actual->expr;
3262 gcc_assert (e->expr_type == EXPR_VARIABLE
3263 && e->symtree != NULL
3264 && e->symtree->n.sym == var);
3265 expr2 = expr2->value.op.op1;
3266 var_on_left = false;
3268 gfc_conv_expr (&rse, expr2);
3269 gfc_add_block_to_block (&block, &rse.pre);
3271 else
3273 gcc_assert (expr2->expr_type == EXPR_FUNCTION);
3274 switch (expr2->value.function.isym->id)
3276 case GFC_ISYM_MIN:
3277 op = MIN_EXPR;
3278 break;
3279 case GFC_ISYM_MAX:
3280 op = MAX_EXPR;
3281 break;
3282 case GFC_ISYM_IAND:
3283 op = BIT_AND_EXPR;
3284 break;
3285 case GFC_ISYM_IOR:
3286 op = BIT_IOR_EXPR;
3287 break;
3288 case GFC_ISYM_IEOR:
3289 op = BIT_XOR_EXPR;
3290 break;
3291 default:
3292 gcc_unreachable ();
3294 e = expr2->value.function.actual->expr;
3295 gcc_assert (e->expr_type == EXPR_VARIABLE
3296 && e->symtree != NULL
3297 && e->symtree->n.sym == var);
3299 gfc_conv_expr (&rse, expr2->value.function.actual->next->expr);
3300 gfc_add_block_to_block (&block, &rse.pre);
3301 if (expr2->value.function.actual->next->next != NULL)
3303 tree accum = gfc_create_var (TREE_TYPE (rse.expr), NULL);
3304 gfc_actual_arglist *arg;
3306 gfc_add_modify (&block, accum, rse.expr);
3307 for (arg = expr2->value.function.actual->next->next; arg;
3308 arg = arg->next)
3310 gfc_init_block (&rse.pre);
3311 gfc_conv_expr (&rse, arg->expr);
3312 gfc_add_block_to_block (&block, &rse.pre);
3313 x = fold_build2_loc (input_location, op, TREE_TYPE (accum),
3314 accum, rse.expr);
3315 gfc_add_modify (&block, accum, x);
3318 rse.expr = accum;
3321 expr2 = expr2->value.function.actual->next->expr;
3324 lhsaddr = save_expr (lhsaddr);
3325 if (TREE_CODE (lhsaddr) != SAVE_EXPR
3326 && (TREE_CODE (lhsaddr) != ADDR_EXPR
3327 || !VAR_P (TREE_OPERAND (lhsaddr, 0))))
3329 /* Make sure LHS is simple enough so that goa_lhs_expr_p can recognize
3330 it even after unsharing function body. */
3331 tree var = create_tmp_var_raw (TREE_TYPE (lhsaddr));
3332 DECL_CONTEXT (var) = current_function_decl;
3333 lhsaddr = build4 (TARGET_EXPR, TREE_TYPE (lhsaddr), var, lhsaddr,
3334 NULL_TREE, NULL_TREE);
3337 rhs = gfc_evaluate_now (rse.expr, &block);
3339 if (((atomic_code->ext.omp_atomic & GFC_OMP_ATOMIC_MASK)
3340 == GFC_OMP_ATOMIC_WRITE)
3341 || (atomic_code->ext.omp_atomic & GFC_OMP_ATOMIC_SWAP))
3342 x = rhs;
3343 else
3345 x = convert (TREE_TYPE (rhs),
3346 build_fold_indirect_ref_loc (input_location, lhsaddr));
3347 if (var_on_left)
3348 x = fold_build2_loc (input_location, op, TREE_TYPE (rhs), x, rhs);
3349 else
3350 x = fold_build2_loc (input_location, op, TREE_TYPE (rhs), rhs, x);
3353 if (TREE_CODE (TREE_TYPE (rhs)) == COMPLEX_TYPE
3354 && TREE_CODE (type) != COMPLEX_TYPE)
3355 x = fold_build1_loc (input_location, REALPART_EXPR,
3356 TREE_TYPE (TREE_TYPE (rhs)), x);
3358 gfc_add_block_to_block (&block, &lse.pre);
3359 gfc_add_block_to_block (&block, &rse.pre);
3361 if (aop == OMP_ATOMIC)
3363 x = build2_v (OMP_ATOMIC, lhsaddr, convert (type, x));
3364 OMP_ATOMIC_SEQ_CST (x) = seq_cst;
3365 gfc_add_expr_to_block (&block, x);
3367 else
3369 if (aop == OMP_ATOMIC_CAPTURE_NEW)
3371 code = code->next;
3372 expr2 = code->expr2;
3373 if (expr2->expr_type == EXPR_FUNCTION
3374 && expr2->value.function.isym
3375 && expr2->value.function.isym->id == GFC_ISYM_CONVERSION)
3376 expr2 = expr2->value.function.actual->expr;
3378 gcc_assert (expr2->expr_type == EXPR_VARIABLE);
3379 gfc_conv_expr (&vse, code->expr1);
3380 gfc_add_block_to_block (&block, &vse.pre);
3382 gfc_init_se (&lse, NULL);
3383 gfc_conv_expr (&lse, expr2);
3384 gfc_add_block_to_block (&block, &lse.pre);
3386 x = build2 (aop, type, lhsaddr, convert (type, x));
3387 OMP_ATOMIC_SEQ_CST (x) = seq_cst;
3388 x = convert (TREE_TYPE (vse.expr), x);
3389 gfc_add_modify (&block, vse.expr, x);
3392 return gfc_finish_block (&block);
3395 static tree
3396 gfc_trans_omp_barrier (void)
3398 tree decl = builtin_decl_explicit (BUILT_IN_GOMP_BARRIER);
3399 return build_call_expr_loc (input_location, decl, 0);
3402 static tree
3403 gfc_trans_omp_cancel (gfc_code *code)
3405 int mask = 0;
3406 tree ifc = boolean_true_node;
3407 stmtblock_t block;
3408 switch (code->ext.omp_clauses->cancel)
3410 case OMP_CANCEL_PARALLEL: mask = 1; break;
3411 case OMP_CANCEL_DO: mask = 2; break;
3412 case OMP_CANCEL_SECTIONS: mask = 4; break;
3413 case OMP_CANCEL_TASKGROUP: mask = 8; break;
3414 default: gcc_unreachable ();
3416 gfc_start_block (&block);
3417 if (code->ext.omp_clauses->if_expr)
3419 gfc_se se;
3420 tree if_var;
3422 gfc_init_se (&se, NULL);
3423 gfc_conv_expr (&se, code->ext.omp_clauses->if_expr);
3424 gfc_add_block_to_block (&block, &se.pre);
3425 if_var = gfc_evaluate_now (se.expr, &block);
3426 gfc_add_block_to_block (&block, &se.post);
3427 tree type = TREE_TYPE (if_var);
3428 ifc = fold_build2_loc (input_location, NE_EXPR,
3429 boolean_type_node, if_var,
3430 build_zero_cst (type));
3432 tree decl = builtin_decl_explicit (BUILT_IN_GOMP_CANCEL);
3433 tree c_bool_type = TREE_TYPE (TREE_TYPE (decl));
3434 ifc = fold_convert (c_bool_type, ifc);
3435 gfc_add_expr_to_block (&block,
3436 build_call_expr_loc (input_location, decl, 2,
3437 build_int_cst (integer_type_node,
3438 mask), ifc));
3439 return gfc_finish_block (&block);
3442 static tree
3443 gfc_trans_omp_cancellation_point (gfc_code *code)
3445 int mask = 0;
3446 switch (code->ext.omp_clauses->cancel)
3448 case OMP_CANCEL_PARALLEL: mask = 1; break;
3449 case OMP_CANCEL_DO: mask = 2; break;
3450 case OMP_CANCEL_SECTIONS: mask = 4; break;
3451 case OMP_CANCEL_TASKGROUP: mask = 8; break;
3452 default: gcc_unreachable ();
3454 tree decl = builtin_decl_explicit (BUILT_IN_GOMP_CANCELLATION_POINT);
3455 return build_call_expr_loc (input_location, decl, 1,
3456 build_int_cst (integer_type_node, mask));
3459 static tree
3460 gfc_trans_omp_critical (gfc_code *code)
3462 tree name = NULL_TREE, stmt;
3463 if (code->ext.omp_clauses != NULL)
3464 name = get_identifier (code->ext.omp_clauses->critical_name);
3465 stmt = gfc_trans_code (code->block->next);
3466 return build3_loc (input_location, OMP_CRITICAL, void_type_node, stmt,
3467 NULL_TREE, name);
3470 typedef struct dovar_init_d {
3471 tree var;
3472 tree init;
3473 } dovar_init;
3476 static tree
3477 gfc_trans_omp_do (gfc_code *code, gfc_exec_op op, stmtblock_t *pblock,
3478 gfc_omp_clauses *do_clauses, tree par_clauses)
3480 gfc_se se;
3481 tree dovar, stmt, from, to, step, type, init, cond, incr, orig_decls;
3482 tree count = NULL_TREE, cycle_label, tmp, omp_clauses;
3483 stmtblock_t block;
3484 stmtblock_t body;
3485 gfc_omp_clauses *clauses = code->ext.omp_clauses;
3486 int i, collapse = clauses->collapse;
3487 vec<dovar_init> inits = vNULL;
3488 dovar_init *di;
3489 unsigned ix;
3490 vec<tree, va_heap, vl_embed> *saved_doacross_steps = doacross_steps;
3491 gfc_expr_list *tile = do_clauses ? do_clauses->tile_list : clauses->tile_list;
3493 /* Both collapsed and tiled loops are lowered the same way. In
3494 OpenACC, those clauses are not compatible, so prioritize the tile
3495 clause, if present. */
3496 if (tile)
3498 collapse = 0;
3499 for (gfc_expr_list *el = tile; el; el = el->next)
3500 collapse++;
3503 doacross_steps = NULL;
3504 if (clauses->orderedc)
3505 collapse = clauses->orderedc;
3506 if (collapse <= 0)
3507 collapse = 1;
3509 code = code->block->next;
3510 gcc_assert (code->op == EXEC_DO);
3512 init = make_tree_vec (collapse);
3513 cond = make_tree_vec (collapse);
3514 incr = make_tree_vec (collapse);
3515 orig_decls = clauses->orderedc ? make_tree_vec (collapse) : NULL_TREE;
3517 if (pblock == NULL)
3519 gfc_start_block (&block);
3520 pblock = &block;
3523 /* simd schedule modifier is only useful for composite do simd and other
3524 constructs including that, where gfc_trans_omp_do is only called
3525 on the simd construct and DO's clauses are translated elsewhere. */
3526 do_clauses->sched_simd = false;
3528 omp_clauses = gfc_trans_omp_clauses (pblock, do_clauses, code->loc);
3530 for (i = 0; i < collapse; i++)
3532 int simple = 0;
3533 int dovar_found = 0;
3534 tree dovar_decl;
3536 if (clauses)
3538 gfc_omp_namelist *n = NULL;
3539 if (op != EXEC_OMP_DISTRIBUTE)
3540 for (n = clauses->lists[(op == EXEC_OMP_SIMD && collapse == 1)
3541 ? OMP_LIST_LINEAR : OMP_LIST_LASTPRIVATE];
3542 n != NULL; n = n->next)
3543 if (code->ext.iterator->var->symtree->n.sym == n->sym)
3544 break;
3545 if (n != NULL)
3546 dovar_found = 1;
3547 else if (n == NULL && op != EXEC_OMP_SIMD)
3548 for (n = clauses->lists[OMP_LIST_PRIVATE]; n != NULL; n = n->next)
3549 if (code->ext.iterator->var->symtree->n.sym == n->sym)
3550 break;
3551 if (n != NULL)
3552 dovar_found++;
3555 /* Evaluate all the expressions in the iterator. */
3556 gfc_init_se (&se, NULL);
3557 gfc_conv_expr_lhs (&se, code->ext.iterator->var);
3558 gfc_add_block_to_block (pblock, &se.pre);
3559 dovar = se.expr;
3560 type = TREE_TYPE (dovar);
3561 gcc_assert (TREE_CODE (type) == INTEGER_TYPE);
3563 gfc_init_se (&se, NULL);
3564 gfc_conv_expr_val (&se, code->ext.iterator->start);
3565 gfc_add_block_to_block (pblock, &se.pre);
3566 from = gfc_evaluate_now (se.expr, pblock);
3568 gfc_init_se (&se, NULL);
3569 gfc_conv_expr_val (&se, code->ext.iterator->end);
3570 gfc_add_block_to_block (pblock, &se.pre);
3571 to = gfc_evaluate_now (se.expr, pblock);
3573 gfc_init_se (&se, NULL);
3574 gfc_conv_expr_val (&se, code->ext.iterator->step);
3575 gfc_add_block_to_block (pblock, &se.pre);
3576 step = gfc_evaluate_now (se.expr, pblock);
3577 dovar_decl = dovar;
3579 /* Special case simple loops. */
3580 if (VAR_P (dovar))
3582 if (integer_onep (step))
3583 simple = 1;
3584 else if (tree_int_cst_equal (step, integer_minus_one_node))
3585 simple = -1;
3587 else
3588 dovar_decl
3589 = gfc_trans_omp_variable (code->ext.iterator->var->symtree->n.sym,
3590 false);
3592 /* Loop body. */
3593 if (simple)
3595 TREE_VEC_ELT (init, i) = build2_v (MODIFY_EXPR, dovar, from);
3596 /* The condition should not be folded. */
3597 TREE_VEC_ELT (cond, i) = build2_loc (input_location, simple > 0
3598 ? LE_EXPR : GE_EXPR,
3599 boolean_type_node, dovar, to);
3600 TREE_VEC_ELT (incr, i) = fold_build2_loc (input_location, PLUS_EXPR,
3601 type, dovar, step);
3602 TREE_VEC_ELT (incr, i) = fold_build2_loc (input_location,
3603 MODIFY_EXPR,
3604 type, dovar,
3605 TREE_VEC_ELT (incr, i));
3607 else
3609 /* STEP is not 1 or -1. Use:
3610 for (count = 0; count < (to + step - from) / step; count++)
3612 dovar = from + count * step;
3613 body;
3614 cycle_label:;
3615 } */
3616 tmp = fold_build2_loc (input_location, MINUS_EXPR, type, step, from);
3617 tmp = fold_build2_loc (input_location, PLUS_EXPR, type, to, tmp);
3618 tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR, type, tmp,
3619 step);
3620 tmp = gfc_evaluate_now (tmp, pblock);
3621 count = gfc_create_var (type, "count");
3622 TREE_VEC_ELT (init, i) = build2_v (MODIFY_EXPR, count,
3623 build_int_cst (type, 0));
3624 /* The condition should not be folded. */
3625 TREE_VEC_ELT (cond, i) = build2_loc (input_location, LT_EXPR,
3626 boolean_type_node,
3627 count, tmp);
3628 TREE_VEC_ELT (incr, i) = fold_build2_loc (input_location, PLUS_EXPR,
3629 type, count,
3630 build_int_cst (type, 1));
3631 TREE_VEC_ELT (incr, i) = fold_build2_loc (input_location,
3632 MODIFY_EXPR, type, count,
3633 TREE_VEC_ELT (incr, i));
3635 /* Initialize DOVAR. */
3636 tmp = fold_build2_loc (input_location, MULT_EXPR, type, count, step);
3637 tmp = fold_build2_loc (input_location, PLUS_EXPR, type, from, tmp);
3638 dovar_init e = {dovar, tmp};
3639 inits.safe_push (e);
3640 if (clauses->orderedc)
3642 if (doacross_steps == NULL)
3643 vec_safe_grow_cleared (doacross_steps, clauses->orderedc);
3644 (*doacross_steps)[i] = step;
3647 if (orig_decls)
3648 TREE_VEC_ELT (orig_decls, i) = dovar_decl;
3650 if (dovar_found == 2
3651 && op == EXEC_OMP_SIMD
3652 && collapse == 1
3653 && !simple)
3655 for (tmp = omp_clauses; tmp; tmp = OMP_CLAUSE_CHAIN (tmp))
3656 if (OMP_CLAUSE_CODE (tmp) == OMP_CLAUSE_LINEAR
3657 && OMP_CLAUSE_DECL (tmp) == dovar)
3659 OMP_CLAUSE_LINEAR_NO_COPYIN (tmp) = 1;
3660 break;
3663 if (!dovar_found)
3665 if (op == EXEC_OMP_SIMD)
3667 if (collapse == 1)
3669 tmp = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
3670 OMP_CLAUSE_LINEAR_STEP (tmp) = step;
3671 OMP_CLAUSE_LINEAR_NO_COPYIN (tmp) = 1;
3673 else
3674 tmp = build_omp_clause (input_location, OMP_CLAUSE_LASTPRIVATE);
3675 if (!simple)
3676 dovar_found = 2;
3678 else
3679 tmp = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
3680 OMP_CLAUSE_DECL (tmp) = dovar_decl;
3681 omp_clauses = gfc_trans_add_clause (tmp, omp_clauses);
3683 if (dovar_found == 2)
3685 tree c = NULL;
3687 tmp = NULL;
3688 if (!simple)
3690 /* If dovar is lastprivate, but different counter is used,
3691 dovar += step needs to be added to
3692 OMP_CLAUSE_LASTPRIVATE_STMT, otherwise the copied dovar
3693 will have the value on entry of the last loop, rather
3694 than value after iterator increment. */
3695 if (clauses->orderedc)
3697 if (clauses->collapse <= 1 || i >= clauses->collapse)
3698 tmp = count;
3699 else
3700 tmp = fold_build2_loc (input_location, PLUS_EXPR,
3701 type, count, build_one_cst (type));
3702 tmp = fold_build2_loc (input_location, MULT_EXPR, type,
3703 tmp, step);
3704 tmp = fold_build2_loc (input_location, PLUS_EXPR, type,
3705 from, tmp);
3707 else
3709 tmp = gfc_evaluate_now (step, pblock);
3710 tmp = fold_build2_loc (input_location, PLUS_EXPR, type,
3711 dovar, tmp);
3713 tmp = fold_build2_loc (input_location, MODIFY_EXPR, type,
3714 dovar, tmp);
3715 for (c = omp_clauses; c ; c = OMP_CLAUSE_CHAIN (c))
3716 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
3717 && OMP_CLAUSE_DECL (c) == dovar_decl)
3719 OMP_CLAUSE_LASTPRIVATE_STMT (c) = tmp;
3720 break;
3722 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
3723 && OMP_CLAUSE_DECL (c) == dovar_decl)
3725 OMP_CLAUSE_LINEAR_STMT (c) = tmp;
3726 break;
3729 if (c == NULL && op == EXEC_OMP_DO && par_clauses != NULL)
3731 for (c = par_clauses; c ; c = OMP_CLAUSE_CHAIN (c))
3732 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
3733 && OMP_CLAUSE_DECL (c) == dovar_decl)
3735 tree l = build_omp_clause (input_location,
3736 OMP_CLAUSE_LASTPRIVATE);
3737 OMP_CLAUSE_DECL (l) = dovar_decl;
3738 OMP_CLAUSE_CHAIN (l) = omp_clauses;
3739 OMP_CLAUSE_LASTPRIVATE_STMT (l) = tmp;
3740 omp_clauses = l;
3741 OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_SHARED);
3742 break;
3745 gcc_assert (simple || c != NULL);
3747 if (!simple)
3749 if (op != EXEC_OMP_SIMD)
3750 tmp = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
3751 else if (collapse == 1)
3753 tmp = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
3754 OMP_CLAUSE_LINEAR_STEP (tmp) = build_int_cst (type, 1);
3755 OMP_CLAUSE_LINEAR_NO_COPYIN (tmp) = 1;
3756 OMP_CLAUSE_LINEAR_NO_COPYOUT (tmp) = 1;
3758 else
3759 tmp = build_omp_clause (input_location, OMP_CLAUSE_LASTPRIVATE);
3760 OMP_CLAUSE_DECL (tmp) = count;
3761 omp_clauses = gfc_trans_add_clause (tmp, omp_clauses);
3764 if (i + 1 < collapse)
3765 code = code->block->next;
3768 if (pblock != &block)
3770 pushlevel ();
3771 gfc_start_block (&block);
3774 gfc_start_block (&body);
3776 FOR_EACH_VEC_ELT (inits, ix, di)
3777 gfc_add_modify (&body, di->var, di->init);
3778 inits.release ();
3780 /* Cycle statement is implemented with a goto. Exit statement must not be
3781 present for this loop. */
3782 cycle_label = gfc_build_label_decl (NULL_TREE);
3784 /* Put these labels where they can be found later. */
3786 code->cycle_label = cycle_label;
3787 code->exit_label = NULL_TREE;
3789 /* Main loop body. */
3790 tmp = gfc_trans_omp_code (code->block->next, true);
3791 gfc_add_expr_to_block (&body, tmp);
3793 /* Label for cycle statements (if needed). */
3794 if (TREE_USED (cycle_label))
3796 tmp = build1_v (LABEL_EXPR, cycle_label);
3797 gfc_add_expr_to_block (&body, tmp);
3800 /* End of loop body. */
3801 switch (op)
3803 case EXEC_OMP_SIMD: stmt = make_node (OMP_SIMD); break;
3804 case EXEC_OMP_DO: stmt = make_node (OMP_FOR); break;
3805 case EXEC_OMP_DISTRIBUTE: stmt = make_node (OMP_DISTRIBUTE); break;
3806 case EXEC_OMP_TASKLOOP: stmt = make_node (OMP_TASKLOOP); break;
3807 case EXEC_OACC_LOOP: stmt = make_node (OACC_LOOP); break;
3808 default: gcc_unreachable ();
3811 TREE_TYPE (stmt) = void_type_node;
3812 OMP_FOR_BODY (stmt) = gfc_finish_block (&body);
3813 OMP_FOR_CLAUSES (stmt) = omp_clauses;
3814 OMP_FOR_INIT (stmt) = init;
3815 OMP_FOR_COND (stmt) = cond;
3816 OMP_FOR_INCR (stmt) = incr;
3817 if (orig_decls)
3818 OMP_FOR_ORIG_DECLS (stmt) = orig_decls;
3819 gfc_add_expr_to_block (&block, stmt);
3821 vec_free (doacross_steps);
3822 doacross_steps = saved_doacross_steps;
3824 return gfc_finish_block (&block);
3827 /* parallel loop and kernels loop. */
3828 static tree
3829 gfc_trans_oacc_combined_directive (gfc_code *code)
3831 stmtblock_t block, *pblock = NULL;
3832 gfc_omp_clauses construct_clauses, loop_clauses;
3833 tree stmt, oacc_clauses = NULL_TREE;
3834 enum tree_code construct_code;
3836 switch (code->op)
3838 case EXEC_OACC_PARALLEL_LOOP:
3839 construct_code = OACC_PARALLEL;
3840 break;
3841 case EXEC_OACC_KERNELS_LOOP:
3842 construct_code = OACC_KERNELS;
3843 break;
3844 default:
3845 gcc_unreachable ();
3848 gfc_start_block (&block);
3850 memset (&loop_clauses, 0, sizeof (loop_clauses));
3851 if (code->ext.omp_clauses != NULL)
3853 memcpy (&construct_clauses, code->ext.omp_clauses,
3854 sizeof (construct_clauses));
3855 loop_clauses.collapse = construct_clauses.collapse;
3856 loop_clauses.gang = construct_clauses.gang;
3857 loop_clauses.gang_static = construct_clauses.gang_static;
3858 loop_clauses.gang_num_expr = construct_clauses.gang_num_expr;
3859 loop_clauses.gang_static_expr = construct_clauses.gang_static_expr;
3860 loop_clauses.vector = construct_clauses.vector;
3861 loop_clauses.vector_expr = construct_clauses.vector_expr;
3862 loop_clauses.worker = construct_clauses.worker;
3863 loop_clauses.worker_expr = construct_clauses.worker_expr;
3864 loop_clauses.seq = construct_clauses.seq;
3865 loop_clauses.par_auto = construct_clauses.par_auto;
3866 loop_clauses.independent = construct_clauses.independent;
3867 loop_clauses.tile_list = construct_clauses.tile_list;
3868 loop_clauses.lists[OMP_LIST_PRIVATE]
3869 = construct_clauses.lists[OMP_LIST_PRIVATE];
3870 loop_clauses.lists[OMP_LIST_REDUCTION]
3871 = construct_clauses.lists[OMP_LIST_REDUCTION];
3872 construct_clauses.gang = false;
3873 construct_clauses.gang_static = false;
3874 construct_clauses.gang_num_expr = NULL;
3875 construct_clauses.gang_static_expr = NULL;
3876 construct_clauses.vector = false;
3877 construct_clauses.vector_expr = NULL;
3878 construct_clauses.worker = false;
3879 construct_clauses.worker_expr = NULL;
3880 construct_clauses.seq = false;
3881 construct_clauses.par_auto = false;
3882 construct_clauses.independent = false;
3883 construct_clauses.independent = false;
3884 construct_clauses.tile_list = NULL;
3885 construct_clauses.lists[OMP_LIST_PRIVATE] = NULL;
3886 if (construct_code == OACC_KERNELS)
3887 construct_clauses.lists[OMP_LIST_REDUCTION] = NULL;
3888 oacc_clauses = gfc_trans_omp_clauses (&block, &construct_clauses,
3889 code->loc);
3891 if (!loop_clauses.seq)
3892 pblock = &block;
3893 else
3894 pushlevel ();
3895 stmt = gfc_trans_omp_do (code, EXEC_OACC_LOOP, pblock, &loop_clauses, NULL);
3896 if (TREE_CODE (stmt) != BIND_EXPR)
3897 stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
3898 else
3899 poplevel (0, 0);
3900 stmt = build2_loc (input_location, construct_code, void_type_node, stmt,
3901 oacc_clauses);
3902 gfc_add_expr_to_block (&block, stmt);
3903 return gfc_finish_block (&block);
3906 static tree
3907 gfc_trans_omp_flush (void)
3909 tree decl = builtin_decl_explicit (BUILT_IN_SYNC_SYNCHRONIZE);
3910 return build_call_expr_loc (input_location, decl, 0);
3913 static tree
3914 gfc_trans_omp_master (gfc_code *code)
3916 tree stmt = gfc_trans_code (code->block->next);
3917 if (IS_EMPTY_STMT (stmt))
3918 return stmt;
3919 return build1_v (OMP_MASTER, stmt);
3922 static tree
3923 gfc_trans_omp_ordered (gfc_code *code)
3925 tree omp_clauses = gfc_trans_omp_clauses (NULL, code->ext.omp_clauses,
3926 code->loc);
3927 return build2_loc (input_location, OMP_ORDERED, void_type_node,
3928 code->block ? gfc_trans_code (code->block->next)
3929 : NULL_TREE, omp_clauses);
3932 static tree
3933 gfc_trans_omp_parallel (gfc_code *code)
3935 stmtblock_t block;
3936 tree stmt, omp_clauses;
3938 gfc_start_block (&block);
3939 omp_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
3940 code->loc);
3941 pushlevel ();
3942 stmt = gfc_trans_omp_code (code->block->next, true);
3943 stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
3944 stmt = build2_loc (input_location, OMP_PARALLEL, void_type_node, stmt,
3945 omp_clauses);
3946 gfc_add_expr_to_block (&block, stmt);
3947 return gfc_finish_block (&block);
3950 enum
3952 GFC_OMP_SPLIT_SIMD,
3953 GFC_OMP_SPLIT_DO,
3954 GFC_OMP_SPLIT_PARALLEL,
3955 GFC_OMP_SPLIT_DISTRIBUTE,
3956 GFC_OMP_SPLIT_TEAMS,
3957 GFC_OMP_SPLIT_TARGET,
3958 GFC_OMP_SPLIT_TASKLOOP,
3959 GFC_OMP_SPLIT_NUM
3962 enum
3964 GFC_OMP_MASK_SIMD = (1 << GFC_OMP_SPLIT_SIMD),
3965 GFC_OMP_MASK_DO = (1 << GFC_OMP_SPLIT_DO),
3966 GFC_OMP_MASK_PARALLEL = (1 << GFC_OMP_SPLIT_PARALLEL),
3967 GFC_OMP_MASK_DISTRIBUTE = (1 << GFC_OMP_SPLIT_DISTRIBUTE),
3968 GFC_OMP_MASK_TEAMS = (1 << GFC_OMP_SPLIT_TEAMS),
3969 GFC_OMP_MASK_TARGET = (1 << GFC_OMP_SPLIT_TARGET),
3970 GFC_OMP_MASK_TASKLOOP = (1 << GFC_OMP_SPLIT_TASKLOOP)
3973 static void
3974 gfc_split_omp_clauses (gfc_code *code,
3975 gfc_omp_clauses clausesa[GFC_OMP_SPLIT_NUM])
3977 int mask = 0, innermost = 0;
3978 memset (clausesa, 0, GFC_OMP_SPLIT_NUM * sizeof (gfc_omp_clauses));
3979 switch (code->op)
3981 case EXEC_OMP_DISTRIBUTE:
3982 innermost = GFC_OMP_SPLIT_DISTRIBUTE;
3983 break;
3984 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO:
3985 mask = GFC_OMP_MASK_DISTRIBUTE | GFC_OMP_MASK_PARALLEL | GFC_OMP_MASK_DO;
3986 innermost = GFC_OMP_SPLIT_DO;
3987 break;
3988 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD:
3989 mask = GFC_OMP_MASK_DISTRIBUTE | GFC_OMP_MASK_PARALLEL
3990 | GFC_OMP_MASK_DO | GFC_OMP_MASK_SIMD;
3991 innermost = GFC_OMP_SPLIT_SIMD;
3992 break;
3993 case EXEC_OMP_DISTRIBUTE_SIMD:
3994 mask = GFC_OMP_MASK_DISTRIBUTE | GFC_OMP_MASK_SIMD;
3995 innermost = GFC_OMP_SPLIT_SIMD;
3996 break;
3997 case EXEC_OMP_DO:
3998 innermost = GFC_OMP_SPLIT_DO;
3999 break;
4000 case EXEC_OMP_DO_SIMD:
4001 mask = GFC_OMP_MASK_DO | GFC_OMP_MASK_SIMD;
4002 innermost = GFC_OMP_SPLIT_SIMD;
4003 break;
4004 case EXEC_OMP_PARALLEL:
4005 innermost = GFC_OMP_SPLIT_PARALLEL;
4006 break;
4007 case EXEC_OMP_PARALLEL_DO:
4008 mask = GFC_OMP_MASK_PARALLEL | GFC_OMP_MASK_DO;
4009 innermost = GFC_OMP_SPLIT_DO;
4010 break;
4011 case EXEC_OMP_PARALLEL_DO_SIMD:
4012 mask = GFC_OMP_MASK_PARALLEL | GFC_OMP_MASK_DO | GFC_OMP_MASK_SIMD;
4013 innermost = GFC_OMP_SPLIT_SIMD;
4014 break;
4015 case EXEC_OMP_SIMD:
4016 innermost = GFC_OMP_SPLIT_SIMD;
4017 break;
4018 case EXEC_OMP_TARGET:
4019 innermost = GFC_OMP_SPLIT_TARGET;
4020 break;
4021 case EXEC_OMP_TARGET_PARALLEL:
4022 mask = GFC_OMP_MASK_TARGET | GFC_OMP_MASK_PARALLEL;
4023 innermost = GFC_OMP_SPLIT_PARALLEL;
4024 break;
4025 case EXEC_OMP_TARGET_PARALLEL_DO:
4026 mask = GFC_OMP_MASK_TARGET | GFC_OMP_MASK_PARALLEL | GFC_OMP_MASK_DO;
4027 innermost = GFC_OMP_SPLIT_DO;
4028 break;
4029 case EXEC_OMP_TARGET_PARALLEL_DO_SIMD:
4030 mask = GFC_OMP_MASK_TARGET | GFC_OMP_MASK_PARALLEL | GFC_OMP_MASK_DO
4031 | GFC_OMP_MASK_SIMD;
4032 innermost = GFC_OMP_SPLIT_SIMD;
4033 break;
4034 case EXEC_OMP_TARGET_SIMD:
4035 mask = GFC_OMP_MASK_TARGET | GFC_OMP_MASK_SIMD;
4036 innermost = GFC_OMP_SPLIT_SIMD;
4037 break;
4038 case EXEC_OMP_TARGET_TEAMS:
4039 mask = GFC_OMP_MASK_TARGET | GFC_OMP_MASK_TEAMS;
4040 innermost = GFC_OMP_SPLIT_TEAMS;
4041 break;
4042 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
4043 mask = GFC_OMP_MASK_TARGET | GFC_OMP_MASK_TEAMS
4044 | GFC_OMP_MASK_DISTRIBUTE;
4045 innermost = GFC_OMP_SPLIT_DISTRIBUTE;
4046 break;
4047 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
4048 mask = GFC_OMP_MASK_TARGET | GFC_OMP_MASK_TEAMS | GFC_OMP_MASK_DISTRIBUTE
4049 | GFC_OMP_MASK_PARALLEL | GFC_OMP_MASK_DO;
4050 innermost = GFC_OMP_SPLIT_DO;
4051 break;
4052 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
4053 mask = GFC_OMP_MASK_TARGET | GFC_OMP_MASK_TEAMS | GFC_OMP_MASK_DISTRIBUTE
4054 | GFC_OMP_MASK_PARALLEL | GFC_OMP_MASK_DO | GFC_OMP_MASK_SIMD;
4055 innermost = GFC_OMP_SPLIT_SIMD;
4056 break;
4057 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
4058 mask = GFC_OMP_MASK_TARGET | GFC_OMP_MASK_TEAMS
4059 | GFC_OMP_MASK_DISTRIBUTE | GFC_OMP_MASK_SIMD;
4060 innermost = GFC_OMP_SPLIT_SIMD;
4061 break;
4062 case EXEC_OMP_TASKLOOP:
4063 innermost = GFC_OMP_SPLIT_TASKLOOP;
4064 break;
4065 case EXEC_OMP_TASKLOOP_SIMD:
4066 mask = GFC_OMP_MASK_TASKLOOP | GFC_OMP_MASK_SIMD;
4067 innermost = GFC_OMP_SPLIT_SIMD;
4068 break;
4069 case EXEC_OMP_TEAMS:
4070 innermost = GFC_OMP_SPLIT_TEAMS;
4071 break;
4072 case EXEC_OMP_TEAMS_DISTRIBUTE:
4073 mask = GFC_OMP_MASK_TEAMS | GFC_OMP_MASK_DISTRIBUTE;
4074 innermost = GFC_OMP_SPLIT_DISTRIBUTE;
4075 break;
4076 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
4077 mask = GFC_OMP_MASK_TEAMS | GFC_OMP_MASK_DISTRIBUTE
4078 | GFC_OMP_MASK_PARALLEL | GFC_OMP_MASK_DO;
4079 innermost = GFC_OMP_SPLIT_DO;
4080 break;
4081 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
4082 mask = GFC_OMP_MASK_TEAMS | GFC_OMP_MASK_DISTRIBUTE
4083 | GFC_OMP_MASK_PARALLEL | GFC_OMP_MASK_DO | GFC_OMP_MASK_SIMD;
4084 innermost = GFC_OMP_SPLIT_SIMD;
4085 break;
4086 case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD:
4087 mask = GFC_OMP_MASK_TEAMS | GFC_OMP_MASK_DISTRIBUTE | GFC_OMP_MASK_SIMD;
4088 innermost = GFC_OMP_SPLIT_SIMD;
4089 break;
4090 default:
4091 gcc_unreachable ();
4093 if (mask == 0)
4095 clausesa[innermost] = *code->ext.omp_clauses;
4096 return;
4098 if (code->ext.omp_clauses != NULL)
4100 if (mask & GFC_OMP_MASK_TARGET)
4102 /* First the clauses that are unique to some constructs. */
4103 clausesa[GFC_OMP_SPLIT_TARGET].lists[OMP_LIST_MAP]
4104 = code->ext.omp_clauses->lists[OMP_LIST_MAP];
4105 clausesa[GFC_OMP_SPLIT_TARGET].lists[OMP_LIST_IS_DEVICE_PTR]
4106 = code->ext.omp_clauses->lists[OMP_LIST_IS_DEVICE_PTR];
4107 clausesa[GFC_OMP_SPLIT_TARGET].device
4108 = code->ext.omp_clauses->device;
4109 clausesa[GFC_OMP_SPLIT_TARGET].defaultmap
4110 = code->ext.omp_clauses->defaultmap;
4111 clausesa[GFC_OMP_SPLIT_TARGET].if_exprs[OMP_IF_TARGET]
4112 = code->ext.omp_clauses->if_exprs[OMP_IF_TARGET];
4113 /* And this is copied to all. */
4114 clausesa[GFC_OMP_SPLIT_PARALLEL].if_expr
4115 = code->ext.omp_clauses->if_expr;
4117 if (mask & GFC_OMP_MASK_TEAMS)
4119 /* First the clauses that are unique to some constructs. */
4120 clausesa[GFC_OMP_SPLIT_TEAMS].num_teams
4121 = code->ext.omp_clauses->num_teams;
4122 clausesa[GFC_OMP_SPLIT_TEAMS].thread_limit
4123 = code->ext.omp_clauses->thread_limit;
4124 /* Shared and default clauses are allowed on parallel, teams
4125 and taskloop. */
4126 clausesa[GFC_OMP_SPLIT_TEAMS].lists[OMP_LIST_SHARED]
4127 = code->ext.omp_clauses->lists[OMP_LIST_SHARED];
4128 clausesa[GFC_OMP_SPLIT_TEAMS].default_sharing
4129 = code->ext.omp_clauses->default_sharing;
4131 if (mask & GFC_OMP_MASK_DISTRIBUTE)
4133 /* First the clauses that are unique to some constructs. */
4134 clausesa[GFC_OMP_SPLIT_DISTRIBUTE].dist_sched_kind
4135 = code->ext.omp_clauses->dist_sched_kind;
4136 clausesa[GFC_OMP_SPLIT_DISTRIBUTE].dist_chunk_size
4137 = code->ext.omp_clauses->dist_chunk_size;
4138 /* Duplicate collapse. */
4139 clausesa[GFC_OMP_SPLIT_DISTRIBUTE].collapse
4140 = code->ext.omp_clauses->collapse;
4142 if (mask & GFC_OMP_MASK_PARALLEL)
4144 /* First the clauses that are unique to some constructs. */
4145 clausesa[GFC_OMP_SPLIT_PARALLEL].lists[OMP_LIST_COPYIN]
4146 = code->ext.omp_clauses->lists[OMP_LIST_COPYIN];
4147 clausesa[GFC_OMP_SPLIT_PARALLEL].num_threads
4148 = code->ext.omp_clauses->num_threads;
4149 clausesa[GFC_OMP_SPLIT_PARALLEL].proc_bind
4150 = code->ext.omp_clauses->proc_bind;
4151 /* Shared and default clauses are allowed on parallel, teams
4152 and taskloop. */
4153 clausesa[GFC_OMP_SPLIT_PARALLEL].lists[OMP_LIST_SHARED]
4154 = code->ext.omp_clauses->lists[OMP_LIST_SHARED];
4155 clausesa[GFC_OMP_SPLIT_PARALLEL].default_sharing
4156 = code->ext.omp_clauses->default_sharing;
4157 clausesa[GFC_OMP_SPLIT_PARALLEL].if_exprs[OMP_IF_PARALLEL]
4158 = code->ext.omp_clauses->if_exprs[OMP_IF_PARALLEL];
4159 /* And this is copied to all. */
4160 clausesa[GFC_OMP_SPLIT_PARALLEL].if_expr
4161 = code->ext.omp_clauses->if_expr;
4163 if (mask & GFC_OMP_MASK_DO)
4165 /* First the clauses that are unique to some constructs. */
4166 clausesa[GFC_OMP_SPLIT_DO].ordered
4167 = code->ext.omp_clauses->ordered;
4168 clausesa[GFC_OMP_SPLIT_DO].orderedc
4169 = code->ext.omp_clauses->orderedc;
4170 clausesa[GFC_OMP_SPLIT_DO].sched_kind
4171 = code->ext.omp_clauses->sched_kind;
4172 if (innermost == GFC_OMP_SPLIT_SIMD)
4173 clausesa[GFC_OMP_SPLIT_DO].sched_simd
4174 = code->ext.omp_clauses->sched_simd;
4175 clausesa[GFC_OMP_SPLIT_DO].sched_monotonic
4176 = code->ext.omp_clauses->sched_monotonic;
4177 clausesa[GFC_OMP_SPLIT_DO].sched_nonmonotonic
4178 = code->ext.omp_clauses->sched_nonmonotonic;
4179 clausesa[GFC_OMP_SPLIT_DO].chunk_size
4180 = code->ext.omp_clauses->chunk_size;
4181 clausesa[GFC_OMP_SPLIT_DO].nowait
4182 = code->ext.omp_clauses->nowait;
4183 /* Duplicate collapse. */
4184 clausesa[GFC_OMP_SPLIT_DO].collapse
4185 = code->ext.omp_clauses->collapse;
4187 if (mask & GFC_OMP_MASK_SIMD)
4189 clausesa[GFC_OMP_SPLIT_SIMD].safelen_expr
4190 = code->ext.omp_clauses->safelen_expr;
4191 clausesa[GFC_OMP_SPLIT_SIMD].simdlen_expr
4192 = code->ext.omp_clauses->simdlen_expr;
4193 clausesa[GFC_OMP_SPLIT_SIMD].lists[OMP_LIST_ALIGNED]
4194 = code->ext.omp_clauses->lists[OMP_LIST_ALIGNED];
4195 /* Duplicate collapse. */
4196 clausesa[GFC_OMP_SPLIT_SIMD].collapse
4197 = code->ext.omp_clauses->collapse;
4199 if (mask & GFC_OMP_MASK_TASKLOOP)
4201 /* First the clauses that are unique to some constructs. */
4202 clausesa[GFC_OMP_SPLIT_TASKLOOP].nogroup
4203 = code->ext.omp_clauses->nogroup;
4204 clausesa[GFC_OMP_SPLIT_TASKLOOP].grainsize
4205 = code->ext.omp_clauses->grainsize;
4206 clausesa[GFC_OMP_SPLIT_TASKLOOP].num_tasks
4207 = code->ext.omp_clauses->num_tasks;
4208 clausesa[GFC_OMP_SPLIT_TASKLOOP].priority
4209 = code->ext.omp_clauses->priority;
4210 clausesa[GFC_OMP_SPLIT_TASKLOOP].final_expr
4211 = code->ext.omp_clauses->final_expr;
4212 clausesa[GFC_OMP_SPLIT_TASKLOOP].untied
4213 = code->ext.omp_clauses->untied;
4214 clausesa[GFC_OMP_SPLIT_TASKLOOP].mergeable
4215 = code->ext.omp_clauses->mergeable;
4216 clausesa[GFC_OMP_SPLIT_TASKLOOP].if_exprs[OMP_IF_TASKLOOP]
4217 = code->ext.omp_clauses->if_exprs[OMP_IF_TASKLOOP];
4218 /* And this is copied to all. */
4219 clausesa[GFC_OMP_SPLIT_TASKLOOP].if_expr
4220 = code->ext.omp_clauses->if_expr;
4221 /* Shared and default clauses are allowed on parallel, teams
4222 and taskloop. */
4223 clausesa[GFC_OMP_SPLIT_TASKLOOP].lists[OMP_LIST_SHARED]
4224 = code->ext.omp_clauses->lists[OMP_LIST_SHARED];
4225 clausesa[GFC_OMP_SPLIT_TASKLOOP].default_sharing
4226 = code->ext.omp_clauses->default_sharing;
4227 /* Duplicate collapse. */
4228 clausesa[GFC_OMP_SPLIT_TASKLOOP].collapse
4229 = code->ext.omp_clauses->collapse;
4231 /* Private clause is supported on all constructs,
4232 it is enough to put it on the innermost one. For
4233 !$ omp parallel do put it on parallel though,
4234 as that's what we did for OpenMP 3.1. */
4235 clausesa[innermost == GFC_OMP_SPLIT_DO
4236 ? (int) GFC_OMP_SPLIT_PARALLEL
4237 : innermost].lists[OMP_LIST_PRIVATE]
4238 = code->ext.omp_clauses->lists[OMP_LIST_PRIVATE];
4239 /* Firstprivate clause is supported on all constructs but
4240 simd. Put it on the outermost of those and duplicate
4241 on parallel and teams. */
4242 if (mask & GFC_OMP_MASK_TARGET)
4243 clausesa[GFC_OMP_SPLIT_TARGET].lists[OMP_LIST_FIRSTPRIVATE]
4244 = code->ext.omp_clauses->lists[OMP_LIST_FIRSTPRIVATE];
4245 if (mask & GFC_OMP_MASK_TEAMS)
4246 clausesa[GFC_OMP_SPLIT_TEAMS].lists[OMP_LIST_FIRSTPRIVATE]
4247 = code->ext.omp_clauses->lists[OMP_LIST_FIRSTPRIVATE];
4248 else if (mask & GFC_OMP_MASK_DISTRIBUTE)
4249 clausesa[GFC_OMP_SPLIT_DISTRIBUTE].lists[OMP_LIST_FIRSTPRIVATE]
4250 = code->ext.omp_clauses->lists[OMP_LIST_FIRSTPRIVATE];
4251 if (mask & GFC_OMP_MASK_PARALLEL)
4252 clausesa[GFC_OMP_SPLIT_PARALLEL].lists[OMP_LIST_FIRSTPRIVATE]
4253 = code->ext.omp_clauses->lists[OMP_LIST_FIRSTPRIVATE];
4254 else if (mask & GFC_OMP_MASK_DO)
4255 clausesa[GFC_OMP_SPLIT_DO].lists[OMP_LIST_FIRSTPRIVATE]
4256 = code->ext.omp_clauses->lists[OMP_LIST_FIRSTPRIVATE];
4257 /* Lastprivate is allowed on distribute, do and simd.
4258 In parallel do{, simd} we actually want to put it on
4259 parallel rather than do. */
4260 if (mask & GFC_OMP_MASK_DISTRIBUTE)
4261 clausesa[GFC_OMP_SPLIT_DISTRIBUTE].lists[OMP_LIST_LASTPRIVATE]
4262 = code->ext.omp_clauses->lists[OMP_LIST_LASTPRIVATE];
4263 if (mask & GFC_OMP_MASK_PARALLEL)
4264 clausesa[GFC_OMP_SPLIT_PARALLEL].lists[OMP_LIST_LASTPRIVATE]
4265 = code->ext.omp_clauses->lists[OMP_LIST_LASTPRIVATE];
4266 else if (mask & GFC_OMP_MASK_DO)
4267 clausesa[GFC_OMP_SPLIT_DO].lists[OMP_LIST_LASTPRIVATE]
4268 = code->ext.omp_clauses->lists[OMP_LIST_LASTPRIVATE];
4269 if (mask & GFC_OMP_MASK_SIMD)
4270 clausesa[GFC_OMP_SPLIT_SIMD].lists[OMP_LIST_LASTPRIVATE]
4271 = code->ext.omp_clauses->lists[OMP_LIST_LASTPRIVATE];
4272 /* Reduction is allowed on simd, do, parallel and teams.
4273 Duplicate it on all of them, but omit on do if
4274 parallel is present. */
4275 if (mask & GFC_OMP_MASK_TEAMS)
4276 clausesa[GFC_OMP_SPLIT_TEAMS].lists[OMP_LIST_REDUCTION]
4277 = code->ext.omp_clauses->lists[OMP_LIST_REDUCTION];
4278 if (mask & GFC_OMP_MASK_PARALLEL)
4279 clausesa[GFC_OMP_SPLIT_PARALLEL].lists[OMP_LIST_REDUCTION]
4280 = code->ext.omp_clauses->lists[OMP_LIST_REDUCTION];
4281 else if (mask & GFC_OMP_MASK_DO)
4282 clausesa[GFC_OMP_SPLIT_DO].lists[OMP_LIST_REDUCTION]
4283 = code->ext.omp_clauses->lists[OMP_LIST_REDUCTION];
4284 if (mask & GFC_OMP_MASK_SIMD)
4285 clausesa[GFC_OMP_SPLIT_SIMD].lists[OMP_LIST_REDUCTION]
4286 = code->ext.omp_clauses->lists[OMP_LIST_REDUCTION];
4287 /* Linear clause is supported on do and simd,
4288 put it on the innermost one. */
4289 clausesa[innermost].lists[OMP_LIST_LINEAR]
4290 = code->ext.omp_clauses->lists[OMP_LIST_LINEAR];
4292 if ((mask & (GFC_OMP_MASK_PARALLEL | GFC_OMP_MASK_DO))
4293 == (GFC_OMP_MASK_PARALLEL | GFC_OMP_MASK_DO))
4294 clausesa[GFC_OMP_SPLIT_DO].nowait = true;
4297 static tree
4298 gfc_trans_omp_do_simd (gfc_code *code, stmtblock_t *pblock,
4299 gfc_omp_clauses *clausesa, tree omp_clauses)
4301 stmtblock_t block;
4302 gfc_omp_clauses clausesa_buf[GFC_OMP_SPLIT_NUM];
4303 tree stmt, body, omp_do_clauses = NULL_TREE;
4305 if (pblock == NULL)
4306 gfc_start_block (&block);
4307 else
4308 gfc_init_block (&block);
4310 if (clausesa == NULL)
4312 clausesa = clausesa_buf;
4313 gfc_split_omp_clauses (code, clausesa);
4315 if (flag_openmp)
4316 omp_do_clauses
4317 = gfc_trans_omp_clauses (&block, &clausesa[GFC_OMP_SPLIT_DO], code->loc);
4318 body = gfc_trans_omp_do (code, EXEC_OMP_SIMD, pblock ? pblock : &block,
4319 &clausesa[GFC_OMP_SPLIT_SIMD], omp_clauses);
4320 if (pblock == NULL)
4322 if (TREE_CODE (body) != BIND_EXPR)
4323 body = build3_v (BIND_EXPR, NULL, body, poplevel (1, 0));
4324 else
4325 poplevel (0, 0);
4327 else if (TREE_CODE (body) != BIND_EXPR)
4328 body = build3_v (BIND_EXPR, NULL, body, NULL_TREE);
4329 if (flag_openmp)
4331 stmt = make_node (OMP_FOR);
4332 TREE_TYPE (stmt) = void_type_node;
4333 OMP_FOR_BODY (stmt) = body;
4334 OMP_FOR_CLAUSES (stmt) = omp_do_clauses;
4336 else
4337 stmt = body;
4338 gfc_add_expr_to_block (&block, stmt);
4339 return gfc_finish_block (&block);
4342 static tree
4343 gfc_trans_omp_parallel_do (gfc_code *code, stmtblock_t *pblock,
4344 gfc_omp_clauses *clausesa)
4346 stmtblock_t block, *new_pblock = pblock;
4347 gfc_omp_clauses clausesa_buf[GFC_OMP_SPLIT_NUM];
4348 tree stmt, omp_clauses = NULL_TREE;
4350 if (pblock == NULL)
4351 gfc_start_block (&block);
4352 else
4353 gfc_init_block (&block);
4355 if (clausesa == NULL)
4357 clausesa = clausesa_buf;
4358 gfc_split_omp_clauses (code, clausesa);
4360 omp_clauses
4361 = gfc_trans_omp_clauses (&block, &clausesa[GFC_OMP_SPLIT_PARALLEL],
4362 code->loc);
4363 if (pblock == NULL)
4365 if (!clausesa[GFC_OMP_SPLIT_DO].ordered
4366 && clausesa[GFC_OMP_SPLIT_DO].sched_kind != OMP_SCHED_STATIC)
4367 new_pblock = &block;
4368 else
4369 pushlevel ();
4371 stmt = gfc_trans_omp_do (code, EXEC_OMP_DO, new_pblock,
4372 &clausesa[GFC_OMP_SPLIT_DO], omp_clauses);
4373 if (pblock == NULL)
4375 if (TREE_CODE (stmt) != BIND_EXPR)
4376 stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
4377 else
4378 poplevel (0, 0);
4380 else if (TREE_CODE (stmt) != BIND_EXPR)
4381 stmt = build3_v (BIND_EXPR, NULL, stmt, NULL_TREE);
4382 stmt = build2_loc (input_location, OMP_PARALLEL, void_type_node, stmt,
4383 omp_clauses);
4384 OMP_PARALLEL_COMBINED (stmt) = 1;
4385 gfc_add_expr_to_block (&block, stmt);
4386 return gfc_finish_block (&block);
4389 static tree
4390 gfc_trans_omp_parallel_do_simd (gfc_code *code, stmtblock_t *pblock,
4391 gfc_omp_clauses *clausesa)
4393 stmtblock_t block;
4394 gfc_omp_clauses clausesa_buf[GFC_OMP_SPLIT_NUM];
4395 tree stmt, omp_clauses = NULL_TREE;
4397 if (pblock == NULL)
4398 gfc_start_block (&block);
4399 else
4400 gfc_init_block (&block);
4402 if (clausesa == NULL)
4404 clausesa = clausesa_buf;
4405 gfc_split_omp_clauses (code, clausesa);
4407 if (flag_openmp)
4408 omp_clauses
4409 = gfc_trans_omp_clauses (&block, &clausesa[GFC_OMP_SPLIT_PARALLEL],
4410 code->loc);
4411 if (pblock == NULL)
4412 pushlevel ();
4413 stmt = gfc_trans_omp_do_simd (code, pblock, clausesa, omp_clauses);
4414 if (pblock == NULL)
4416 if (TREE_CODE (stmt) != BIND_EXPR)
4417 stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
4418 else
4419 poplevel (0, 0);
4421 else if (TREE_CODE (stmt) != BIND_EXPR)
4422 stmt = build3_v (BIND_EXPR, NULL, stmt, NULL_TREE);
4423 if (flag_openmp)
4425 stmt = build2_loc (input_location, OMP_PARALLEL, void_type_node, stmt,
4426 omp_clauses);
4427 OMP_PARALLEL_COMBINED (stmt) = 1;
4429 gfc_add_expr_to_block (&block, stmt);
4430 return gfc_finish_block (&block);
4433 static tree
4434 gfc_trans_omp_parallel_sections (gfc_code *code)
4436 stmtblock_t block;
4437 gfc_omp_clauses section_clauses;
4438 tree stmt, omp_clauses;
4440 memset (&section_clauses, 0, sizeof (section_clauses));
4441 section_clauses.nowait = true;
4443 gfc_start_block (&block);
4444 omp_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
4445 code->loc);
4446 pushlevel ();
4447 stmt = gfc_trans_omp_sections (code, &section_clauses);
4448 if (TREE_CODE (stmt) != BIND_EXPR)
4449 stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
4450 else
4451 poplevel (0, 0);
4452 stmt = build2_loc (input_location, OMP_PARALLEL, void_type_node, stmt,
4453 omp_clauses);
4454 OMP_PARALLEL_COMBINED (stmt) = 1;
4455 gfc_add_expr_to_block (&block, stmt);
4456 return gfc_finish_block (&block);
4459 static tree
4460 gfc_trans_omp_parallel_workshare (gfc_code *code)
4462 stmtblock_t block;
4463 gfc_omp_clauses workshare_clauses;
4464 tree stmt, omp_clauses;
4466 memset (&workshare_clauses, 0, sizeof (workshare_clauses));
4467 workshare_clauses.nowait = true;
4469 gfc_start_block (&block);
4470 omp_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
4471 code->loc);
4472 pushlevel ();
4473 stmt = gfc_trans_omp_workshare (code, &workshare_clauses);
4474 stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
4475 stmt = build2_loc (input_location, OMP_PARALLEL, void_type_node, stmt,
4476 omp_clauses);
4477 OMP_PARALLEL_COMBINED (stmt) = 1;
4478 gfc_add_expr_to_block (&block, stmt);
4479 return gfc_finish_block (&block);
4482 static tree
4483 gfc_trans_omp_sections (gfc_code *code, gfc_omp_clauses *clauses)
4485 stmtblock_t block, body;
4486 tree omp_clauses, stmt;
4487 bool has_lastprivate = clauses->lists[OMP_LIST_LASTPRIVATE] != NULL;
4489 gfc_start_block (&block);
4491 omp_clauses = gfc_trans_omp_clauses (&block, clauses, code->loc);
4493 gfc_init_block (&body);
4494 for (code = code->block; code; code = code->block)
4496 /* Last section is special because of lastprivate, so even if it
4497 is empty, chain it in. */
4498 stmt = gfc_trans_omp_code (code->next,
4499 has_lastprivate && code->block == NULL);
4500 if (! IS_EMPTY_STMT (stmt))
4502 stmt = build1_v (OMP_SECTION, stmt);
4503 gfc_add_expr_to_block (&body, stmt);
4506 stmt = gfc_finish_block (&body);
4508 stmt = build2_loc (input_location, OMP_SECTIONS, void_type_node, stmt,
4509 omp_clauses);
4510 gfc_add_expr_to_block (&block, stmt);
4512 return gfc_finish_block (&block);
4515 static tree
4516 gfc_trans_omp_single (gfc_code *code, gfc_omp_clauses *clauses)
4518 tree omp_clauses = gfc_trans_omp_clauses (NULL, clauses, code->loc);
4519 tree stmt = gfc_trans_omp_code (code->block->next, true);
4520 stmt = build2_loc (input_location, OMP_SINGLE, void_type_node, stmt,
4521 omp_clauses);
4522 return stmt;
4525 static tree
4526 gfc_trans_omp_task (gfc_code *code)
4528 stmtblock_t block;
4529 tree stmt, omp_clauses;
4531 gfc_start_block (&block);
4532 omp_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
4533 code->loc);
4534 pushlevel ();
4535 stmt = gfc_trans_omp_code (code->block->next, true);
4536 stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
4537 stmt = build2_loc (input_location, OMP_TASK, void_type_node, stmt,
4538 omp_clauses);
4539 gfc_add_expr_to_block (&block, stmt);
4540 return gfc_finish_block (&block);
4543 static tree
4544 gfc_trans_omp_taskgroup (gfc_code *code)
4546 tree stmt = gfc_trans_code (code->block->next);
4547 return build1_loc (input_location, OMP_TASKGROUP, void_type_node, stmt);
4550 static tree
4551 gfc_trans_omp_taskwait (void)
4553 tree decl = builtin_decl_explicit (BUILT_IN_GOMP_TASKWAIT);
4554 return build_call_expr_loc (input_location, decl, 0);
4557 static tree
4558 gfc_trans_omp_taskyield (void)
4560 tree decl = builtin_decl_explicit (BUILT_IN_GOMP_TASKYIELD);
4561 return build_call_expr_loc (input_location, decl, 0);
4564 static tree
4565 gfc_trans_omp_distribute (gfc_code *code, gfc_omp_clauses *clausesa)
4567 stmtblock_t block;
4568 gfc_omp_clauses clausesa_buf[GFC_OMP_SPLIT_NUM];
4569 tree stmt, omp_clauses = NULL_TREE;
4571 gfc_start_block (&block);
4572 if (clausesa == NULL)
4574 clausesa = clausesa_buf;
4575 gfc_split_omp_clauses (code, clausesa);
4577 if (flag_openmp)
4578 omp_clauses
4579 = gfc_trans_omp_clauses (&block, &clausesa[GFC_OMP_SPLIT_DISTRIBUTE],
4580 code->loc);
4581 switch (code->op)
4583 case EXEC_OMP_DISTRIBUTE:
4584 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
4585 case EXEC_OMP_TEAMS_DISTRIBUTE:
4586 /* This is handled in gfc_trans_omp_do. */
4587 gcc_unreachable ();
4588 break;
4589 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO:
4590 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
4591 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
4592 stmt = gfc_trans_omp_parallel_do (code, &block, clausesa);
4593 if (TREE_CODE (stmt) != BIND_EXPR)
4594 stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
4595 else
4596 poplevel (0, 0);
4597 break;
4598 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD:
4599 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
4600 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
4601 stmt = gfc_trans_omp_parallel_do_simd (code, &block, clausesa);
4602 if (TREE_CODE (stmt) != BIND_EXPR)
4603 stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
4604 else
4605 poplevel (0, 0);
4606 break;
4607 case EXEC_OMP_DISTRIBUTE_SIMD:
4608 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
4609 case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD:
4610 stmt = gfc_trans_omp_do (code, EXEC_OMP_SIMD, &block,
4611 &clausesa[GFC_OMP_SPLIT_SIMD], NULL_TREE);
4612 if (TREE_CODE (stmt) != BIND_EXPR)
4613 stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
4614 else
4615 poplevel (0, 0);
4616 break;
4617 default:
4618 gcc_unreachable ();
4620 if (flag_openmp)
4622 tree distribute = make_node (OMP_DISTRIBUTE);
4623 TREE_TYPE (distribute) = void_type_node;
4624 OMP_FOR_BODY (distribute) = stmt;
4625 OMP_FOR_CLAUSES (distribute) = omp_clauses;
4626 stmt = distribute;
4628 gfc_add_expr_to_block (&block, stmt);
4629 return gfc_finish_block (&block);
4632 static tree
4633 gfc_trans_omp_teams (gfc_code *code, gfc_omp_clauses *clausesa,
4634 tree omp_clauses)
4636 stmtblock_t block;
4637 gfc_omp_clauses clausesa_buf[GFC_OMP_SPLIT_NUM];
4638 tree stmt;
4639 bool combined = true;
4641 gfc_start_block (&block);
4642 if (clausesa == NULL)
4644 clausesa = clausesa_buf;
4645 gfc_split_omp_clauses (code, clausesa);
4647 if (flag_openmp)
4648 omp_clauses
4649 = chainon (omp_clauses,
4650 gfc_trans_omp_clauses (&block, &clausesa[GFC_OMP_SPLIT_TEAMS],
4651 code->loc));
4652 switch (code->op)
4654 case EXEC_OMP_TARGET_TEAMS:
4655 case EXEC_OMP_TEAMS:
4656 stmt = gfc_trans_omp_code (code->block->next, true);
4657 combined = false;
4658 break;
4659 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
4660 case EXEC_OMP_TEAMS_DISTRIBUTE:
4661 stmt = gfc_trans_omp_do (code, EXEC_OMP_DISTRIBUTE, NULL,
4662 &clausesa[GFC_OMP_SPLIT_DISTRIBUTE],
4663 NULL);
4664 break;
4665 default:
4666 stmt = gfc_trans_omp_distribute (code, clausesa);
4667 break;
4669 if (flag_openmp)
4671 stmt = build2_loc (input_location, OMP_TEAMS, void_type_node, stmt,
4672 omp_clauses);
4673 if (combined)
4674 OMP_TEAMS_COMBINED (stmt) = 1;
4676 gfc_add_expr_to_block (&block, stmt);
4677 return gfc_finish_block (&block);
4680 static tree
4681 gfc_trans_omp_target (gfc_code *code)
4683 stmtblock_t block;
4684 gfc_omp_clauses clausesa[GFC_OMP_SPLIT_NUM];
4685 tree stmt, omp_clauses = NULL_TREE;
4687 gfc_start_block (&block);
4688 gfc_split_omp_clauses (code, clausesa);
4689 if (flag_openmp)
4690 omp_clauses
4691 = gfc_trans_omp_clauses (&block, &clausesa[GFC_OMP_SPLIT_TARGET],
4692 code->loc);
4693 switch (code->op)
4695 case EXEC_OMP_TARGET:
4696 pushlevel ();
4697 stmt = gfc_trans_omp_code (code->block->next, true);
4698 stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
4699 break;
4700 case EXEC_OMP_TARGET_PARALLEL:
4702 stmtblock_t iblock;
4704 gfc_start_block (&iblock);
4705 tree inner_clauses
4706 = gfc_trans_omp_clauses (&block, &clausesa[GFC_OMP_SPLIT_PARALLEL],
4707 code->loc);
4708 stmt = gfc_trans_omp_code (code->block->next, true);
4709 stmt = build2_loc (input_location, OMP_PARALLEL, void_type_node, stmt,
4710 inner_clauses);
4711 gfc_add_expr_to_block (&iblock, stmt);
4712 stmt = gfc_finish_block (&iblock);
4713 if (TREE_CODE (stmt) != BIND_EXPR)
4714 stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
4715 else
4716 poplevel (0, 0);
4718 break;
4719 case EXEC_OMP_TARGET_PARALLEL_DO:
4720 case EXEC_OMP_TARGET_PARALLEL_DO_SIMD:
4721 stmt = gfc_trans_omp_parallel_do (code, &block, clausesa);
4722 if (TREE_CODE (stmt) != BIND_EXPR)
4723 stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
4724 else
4725 poplevel (0, 0);
4726 break;
4727 case EXEC_OMP_TARGET_SIMD:
4728 stmt = gfc_trans_omp_do (code, EXEC_OMP_SIMD, &block,
4729 &clausesa[GFC_OMP_SPLIT_SIMD], NULL_TREE);
4730 if (TREE_CODE (stmt) != BIND_EXPR)
4731 stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
4732 else
4733 poplevel (0, 0);
4734 break;
4735 default:
4736 if (flag_openmp
4737 && (clausesa[GFC_OMP_SPLIT_TEAMS].num_teams
4738 || clausesa[GFC_OMP_SPLIT_TEAMS].thread_limit))
4740 gfc_omp_clauses clausesb;
4741 tree teams_clauses;
4742 /* For combined !$omp target teams, the num_teams and
4743 thread_limit clauses are evaluated before entering the
4744 target construct. */
4745 memset (&clausesb, '\0', sizeof (clausesb));
4746 clausesb.num_teams = clausesa[GFC_OMP_SPLIT_TEAMS].num_teams;
4747 clausesb.thread_limit = clausesa[GFC_OMP_SPLIT_TEAMS].thread_limit;
4748 clausesa[GFC_OMP_SPLIT_TEAMS].num_teams = NULL;
4749 clausesa[GFC_OMP_SPLIT_TEAMS].thread_limit = NULL;
4750 teams_clauses
4751 = gfc_trans_omp_clauses (&block, &clausesb, code->loc);
4752 pushlevel ();
4753 stmt = gfc_trans_omp_teams (code, clausesa, teams_clauses);
4755 else
4757 pushlevel ();
4758 stmt = gfc_trans_omp_teams (code, clausesa, NULL_TREE);
4760 if (TREE_CODE (stmt) != BIND_EXPR)
4761 stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
4762 else
4763 poplevel (0, 0);
4764 break;
4766 if (flag_openmp)
4768 stmt = build2_loc (input_location, OMP_TARGET, void_type_node, stmt,
4769 omp_clauses);
4770 if (code->op != EXEC_OMP_TARGET)
4771 OMP_TARGET_COMBINED (stmt) = 1;
4773 gfc_add_expr_to_block (&block, stmt);
4774 return gfc_finish_block (&block);
4777 static tree
4778 gfc_trans_omp_taskloop (gfc_code *code)
4780 stmtblock_t block;
4781 gfc_omp_clauses clausesa[GFC_OMP_SPLIT_NUM];
4782 tree stmt, omp_clauses = NULL_TREE;
4784 gfc_start_block (&block);
4785 gfc_split_omp_clauses (code, clausesa);
4786 if (flag_openmp)
4787 omp_clauses
4788 = gfc_trans_omp_clauses (&block, &clausesa[GFC_OMP_SPLIT_TASKLOOP],
4789 code->loc);
4790 switch (code->op)
4792 case EXEC_OMP_TASKLOOP:
4793 /* This is handled in gfc_trans_omp_do. */
4794 gcc_unreachable ();
4795 break;
4796 case EXEC_OMP_TASKLOOP_SIMD:
4797 stmt = gfc_trans_omp_do (code, EXEC_OMP_SIMD, &block,
4798 &clausesa[GFC_OMP_SPLIT_SIMD], NULL_TREE);
4799 if (TREE_CODE (stmt) != BIND_EXPR)
4800 stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
4801 else
4802 poplevel (0, 0);
4803 break;
4804 default:
4805 gcc_unreachable ();
4807 if (flag_openmp)
4809 tree taskloop = make_node (OMP_TASKLOOP);
4810 TREE_TYPE (taskloop) = void_type_node;
4811 OMP_FOR_BODY (taskloop) = stmt;
4812 OMP_FOR_CLAUSES (taskloop) = omp_clauses;
4813 stmt = taskloop;
4815 gfc_add_expr_to_block (&block, stmt);
4816 return gfc_finish_block (&block);
4819 static tree
4820 gfc_trans_omp_target_data (gfc_code *code)
4822 stmtblock_t block;
4823 tree stmt, omp_clauses;
4825 gfc_start_block (&block);
4826 omp_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
4827 code->loc);
4828 stmt = gfc_trans_omp_code (code->block->next, true);
4829 stmt = build2_loc (input_location, OMP_TARGET_DATA, void_type_node, stmt,
4830 omp_clauses);
4831 gfc_add_expr_to_block (&block, stmt);
4832 return gfc_finish_block (&block);
4835 static tree
4836 gfc_trans_omp_target_enter_data (gfc_code *code)
4838 stmtblock_t block;
4839 tree stmt, omp_clauses;
4841 gfc_start_block (&block);
4842 omp_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
4843 code->loc);
4844 stmt = build1_loc (input_location, OMP_TARGET_ENTER_DATA, void_type_node,
4845 omp_clauses);
4846 gfc_add_expr_to_block (&block, stmt);
4847 return gfc_finish_block (&block);
4850 static tree
4851 gfc_trans_omp_target_exit_data (gfc_code *code)
4853 stmtblock_t block;
4854 tree stmt, omp_clauses;
4856 gfc_start_block (&block);
4857 omp_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
4858 code->loc);
4859 stmt = build1_loc (input_location, OMP_TARGET_EXIT_DATA, void_type_node,
4860 omp_clauses);
4861 gfc_add_expr_to_block (&block, stmt);
4862 return gfc_finish_block (&block);
4865 static tree
4866 gfc_trans_omp_target_update (gfc_code *code)
4868 stmtblock_t block;
4869 tree stmt, omp_clauses;
4871 gfc_start_block (&block);
4872 omp_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
4873 code->loc);
4874 stmt = build1_loc (input_location, OMP_TARGET_UPDATE, void_type_node,
4875 omp_clauses);
4876 gfc_add_expr_to_block (&block, stmt);
4877 return gfc_finish_block (&block);
4880 static tree
4881 gfc_trans_omp_workshare (gfc_code *code, gfc_omp_clauses *clauses)
4883 tree res, tmp, stmt;
4884 stmtblock_t block, *pblock = NULL;
4885 stmtblock_t singleblock;
4886 int saved_ompws_flags;
4887 bool singleblock_in_progress = false;
4888 /* True if previous gfc_code in workshare construct is not workshared. */
4889 bool prev_singleunit;
4891 code = code->block->next;
4893 pushlevel ();
4895 gfc_start_block (&block);
4896 pblock = &block;
4898 ompws_flags = OMPWS_WORKSHARE_FLAG;
4899 prev_singleunit = false;
4901 /* Translate statements one by one to trees until we reach
4902 the end of the workshare construct. Adjacent gfc_codes that
4903 are a single unit of work are clustered and encapsulated in a
4904 single OMP_SINGLE construct. */
4905 for (; code; code = code->next)
4907 if (code->here != 0)
4909 res = gfc_trans_label_here (code);
4910 gfc_add_expr_to_block (pblock, res);
4913 /* No dependence analysis, use for clauses with wait.
4914 If this is the last gfc_code, use default omp_clauses. */
4915 if (code->next == NULL && clauses->nowait)
4916 ompws_flags |= OMPWS_NOWAIT;
4918 /* By default, every gfc_code is a single unit of work. */
4919 ompws_flags |= OMPWS_CURR_SINGLEUNIT;
4920 ompws_flags &= ~(OMPWS_SCALARIZER_WS | OMPWS_SCALARIZER_BODY);
4922 switch (code->op)
4924 case EXEC_NOP:
4925 res = NULL_TREE;
4926 break;
4928 case EXEC_ASSIGN:
4929 res = gfc_trans_assign (code);
4930 break;
4932 case EXEC_POINTER_ASSIGN:
4933 res = gfc_trans_pointer_assign (code);
4934 break;
4936 case EXEC_INIT_ASSIGN:
4937 res = gfc_trans_init_assign (code);
4938 break;
4940 case EXEC_FORALL:
4941 res = gfc_trans_forall (code);
4942 break;
4944 case EXEC_WHERE:
4945 res = gfc_trans_where (code);
4946 break;
4948 case EXEC_OMP_ATOMIC:
4949 res = gfc_trans_omp_directive (code);
4950 break;
4952 case EXEC_OMP_PARALLEL:
4953 case EXEC_OMP_PARALLEL_DO:
4954 case EXEC_OMP_PARALLEL_SECTIONS:
4955 case EXEC_OMP_PARALLEL_WORKSHARE:
4956 case EXEC_OMP_CRITICAL:
4957 saved_ompws_flags = ompws_flags;
4958 ompws_flags = 0;
4959 res = gfc_trans_omp_directive (code);
4960 ompws_flags = saved_ompws_flags;
4961 break;
4963 default:
4964 gfc_internal_error ("gfc_trans_omp_workshare(): Bad statement code");
4967 gfc_set_backend_locus (&code->loc);
4969 if (res != NULL_TREE && ! IS_EMPTY_STMT (res))
4971 if (prev_singleunit)
4973 if (ompws_flags & OMPWS_CURR_SINGLEUNIT)
4974 /* Add current gfc_code to single block. */
4975 gfc_add_expr_to_block (&singleblock, res);
4976 else
4978 /* Finish single block and add it to pblock. */
4979 tmp = gfc_finish_block (&singleblock);
4980 tmp = build2_loc (input_location, OMP_SINGLE,
4981 void_type_node, tmp, NULL_TREE);
4982 gfc_add_expr_to_block (pblock, tmp);
4983 /* Add current gfc_code to pblock. */
4984 gfc_add_expr_to_block (pblock, res);
4985 singleblock_in_progress = false;
4988 else
4990 if (ompws_flags & OMPWS_CURR_SINGLEUNIT)
4992 /* Start single block. */
4993 gfc_init_block (&singleblock);
4994 gfc_add_expr_to_block (&singleblock, res);
4995 singleblock_in_progress = true;
4997 else
4998 /* Add the new statement to the block. */
4999 gfc_add_expr_to_block (pblock, res);
5001 prev_singleunit = (ompws_flags & OMPWS_CURR_SINGLEUNIT) != 0;
5005 /* Finish remaining SINGLE block, if we were in the middle of one. */
5006 if (singleblock_in_progress)
5008 /* Finish single block and add it to pblock. */
5009 tmp = gfc_finish_block (&singleblock);
5010 tmp = build2_loc (input_location, OMP_SINGLE, void_type_node, tmp,
5011 clauses->nowait
5012 ? build_omp_clause (input_location, OMP_CLAUSE_NOWAIT)
5013 : NULL_TREE);
5014 gfc_add_expr_to_block (pblock, tmp);
5017 stmt = gfc_finish_block (pblock);
5018 if (TREE_CODE (stmt) != BIND_EXPR)
5020 if (!IS_EMPTY_STMT (stmt))
5022 tree bindblock = poplevel (1, 0);
5023 stmt = build3_v (BIND_EXPR, NULL, stmt, bindblock);
5025 else
5026 poplevel (0, 0);
5028 else
5029 poplevel (0, 0);
5031 if (IS_EMPTY_STMT (stmt) && !clauses->nowait)
5032 stmt = gfc_trans_omp_barrier ();
5034 ompws_flags = 0;
5035 return stmt;
5038 tree
5039 gfc_trans_oacc_declare (gfc_code *code)
5041 stmtblock_t block;
5042 tree stmt, oacc_clauses;
5043 enum tree_code construct_code;
5045 construct_code = OACC_DATA;
5047 gfc_start_block (&block);
5049 oacc_clauses = gfc_trans_omp_clauses (&block, code->ext.oacc_declare->clauses,
5050 code->loc);
5051 stmt = gfc_trans_omp_code (code->block->next, true);
5052 stmt = build2_loc (input_location, construct_code, void_type_node, stmt,
5053 oacc_clauses);
5054 gfc_add_expr_to_block (&block, stmt);
5056 return gfc_finish_block (&block);
5059 tree
5060 gfc_trans_oacc_directive (gfc_code *code)
5062 switch (code->op)
5064 case EXEC_OACC_PARALLEL_LOOP:
5065 case EXEC_OACC_KERNELS_LOOP:
5066 return gfc_trans_oacc_combined_directive (code);
5067 case EXEC_OACC_PARALLEL:
5068 case EXEC_OACC_KERNELS:
5069 case EXEC_OACC_DATA:
5070 case EXEC_OACC_HOST_DATA:
5071 return gfc_trans_oacc_construct (code);
5072 case EXEC_OACC_LOOP:
5073 return gfc_trans_omp_do (code, code->op, NULL, code->ext.omp_clauses,
5074 NULL);
5075 case EXEC_OACC_UPDATE:
5076 case EXEC_OACC_CACHE:
5077 case EXEC_OACC_ENTER_DATA:
5078 case EXEC_OACC_EXIT_DATA:
5079 return gfc_trans_oacc_executable_directive (code);
5080 case EXEC_OACC_WAIT:
5081 return gfc_trans_oacc_wait_directive (code);
5082 case EXEC_OACC_ATOMIC:
5083 return gfc_trans_omp_atomic (code);
5084 case EXEC_OACC_DECLARE:
5085 return gfc_trans_oacc_declare (code);
5086 default:
5087 gcc_unreachable ();
5091 tree
5092 gfc_trans_omp_directive (gfc_code *code)
5094 switch (code->op)
5096 case EXEC_OMP_ATOMIC:
5097 return gfc_trans_omp_atomic (code);
5098 case EXEC_OMP_BARRIER:
5099 return gfc_trans_omp_barrier ();
5100 case EXEC_OMP_CANCEL:
5101 return gfc_trans_omp_cancel (code);
5102 case EXEC_OMP_CANCELLATION_POINT:
5103 return gfc_trans_omp_cancellation_point (code);
5104 case EXEC_OMP_CRITICAL:
5105 return gfc_trans_omp_critical (code);
5106 case EXEC_OMP_DISTRIBUTE:
5107 case EXEC_OMP_DO:
5108 case EXEC_OMP_SIMD:
5109 case EXEC_OMP_TASKLOOP:
5110 return gfc_trans_omp_do (code, code->op, NULL, code->ext.omp_clauses,
5111 NULL);
5112 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO:
5113 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD:
5114 case EXEC_OMP_DISTRIBUTE_SIMD:
5115 return gfc_trans_omp_distribute (code, NULL);
5116 case EXEC_OMP_DO_SIMD:
5117 return gfc_trans_omp_do_simd (code, NULL, NULL, NULL_TREE);
5118 case EXEC_OMP_FLUSH:
5119 return gfc_trans_omp_flush ();
5120 case EXEC_OMP_MASTER:
5121 return gfc_trans_omp_master (code);
5122 case EXEC_OMP_ORDERED:
5123 return gfc_trans_omp_ordered (code);
5124 case EXEC_OMP_PARALLEL:
5125 return gfc_trans_omp_parallel (code);
5126 case EXEC_OMP_PARALLEL_DO:
5127 return gfc_trans_omp_parallel_do (code, NULL, NULL);
5128 case EXEC_OMP_PARALLEL_DO_SIMD:
5129 return gfc_trans_omp_parallel_do_simd (code, NULL, NULL);
5130 case EXEC_OMP_PARALLEL_SECTIONS:
5131 return gfc_trans_omp_parallel_sections (code);
5132 case EXEC_OMP_PARALLEL_WORKSHARE:
5133 return gfc_trans_omp_parallel_workshare (code);
5134 case EXEC_OMP_SECTIONS:
5135 return gfc_trans_omp_sections (code, code->ext.omp_clauses);
5136 case EXEC_OMP_SINGLE:
5137 return gfc_trans_omp_single (code, code->ext.omp_clauses);
5138 case EXEC_OMP_TARGET:
5139 case EXEC_OMP_TARGET_PARALLEL:
5140 case EXEC_OMP_TARGET_PARALLEL_DO:
5141 case EXEC_OMP_TARGET_PARALLEL_DO_SIMD:
5142 case EXEC_OMP_TARGET_SIMD:
5143 case EXEC_OMP_TARGET_TEAMS:
5144 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
5145 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
5146 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
5147 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
5148 return gfc_trans_omp_target (code);
5149 case EXEC_OMP_TARGET_DATA:
5150 return gfc_trans_omp_target_data (code);
5151 case EXEC_OMP_TARGET_ENTER_DATA:
5152 return gfc_trans_omp_target_enter_data (code);
5153 case EXEC_OMP_TARGET_EXIT_DATA:
5154 return gfc_trans_omp_target_exit_data (code);
5155 case EXEC_OMP_TARGET_UPDATE:
5156 return gfc_trans_omp_target_update (code);
5157 case EXEC_OMP_TASK:
5158 return gfc_trans_omp_task (code);
5159 case EXEC_OMP_TASKGROUP:
5160 return gfc_trans_omp_taskgroup (code);
5161 case EXEC_OMP_TASKLOOP_SIMD:
5162 return gfc_trans_omp_taskloop (code);
5163 case EXEC_OMP_TASKWAIT:
5164 return gfc_trans_omp_taskwait ();
5165 case EXEC_OMP_TASKYIELD:
5166 return gfc_trans_omp_taskyield ();
5167 case EXEC_OMP_TEAMS:
5168 case EXEC_OMP_TEAMS_DISTRIBUTE:
5169 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
5170 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
5171 case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD:
5172 return gfc_trans_omp_teams (code, NULL, NULL_TREE);
5173 case EXEC_OMP_WORKSHARE:
5174 return gfc_trans_omp_workshare (code, code->ext.omp_clauses);
5175 default:
5176 gcc_unreachable ();
5180 void
5181 gfc_trans_omp_declare_simd (gfc_namespace *ns)
5183 if (ns->entries)
5184 return;
5186 gfc_omp_declare_simd *ods;
5187 for (ods = ns->omp_declare_simd; ods; ods = ods->next)
5189 tree c = gfc_trans_omp_clauses (NULL, ods->clauses, ods->where, true);
5190 tree fndecl = ns->proc_name->backend_decl;
5191 if (c != NULL_TREE)
5192 c = tree_cons (NULL_TREE, c, NULL_TREE);
5193 c = build_tree_list (get_identifier ("omp declare simd"), c);
5194 TREE_CHAIN (c) = DECL_ATTRIBUTES (fndecl);
5195 DECL_ATTRIBUTES (fndecl) = c;