cgraph.c (cgraph_turn_edge_to_speculative): Fix debug output.
[official-gcc.git] / gcc / fortran / trans-openmp.c
blob2765561e889ebafbf430f475941eb8f3e244805c
1 /* OpenMP directive translation -- generate GCC trees from gfc_code.
2 Copyright (C) 2005-2013 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 "tree.h"
26 #include "gimple.h" /* For create_tmp_var_raw. */
27 #include "diagnostic-core.h" /* For internal_error. */
28 #include "gfortran.h"
29 #include "trans.h"
30 #include "trans-stmt.h"
31 #include "trans-types.h"
32 #include "trans-array.h"
33 #include "trans-const.h"
34 #include "arith.h"
36 int ompws_flags;
38 /* True if OpenMP should privatize what this DECL points to rather
39 than the DECL itself. */
41 bool
42 gfc_omp_privatize_by_reference (const_tree decl)
44 tree type = TREE_TYPE (decl);
46 if (TREE_CODE (type) == REFERENCE_TYPE
47 && (!DECL_ARTIFICIAL (decl) || TREE_CODE (decl) == PARM_DECL))
48 return true;
50 if (TREE_CODE (type) == POINTER_TYPE)
52 /* Array POINTER/ALLOCATABLE have aggregate types, all user variables
53 that have POINTER_TYPE type and don't have GFC_POINTER_TYPE_P
54 set are supposed to be privatized by reference. */
55 if (GFC_POINTER_TYPE_P (type))
56 return false;
58 if (!DECL_ARTIFICIAL (decl)
59 && TREE_CODE (TREE_TYPE (type)) != FUNCTION_TYPE)
60 return true;
62 /* Some arrays are expanded as DECL_ARTIFICIAL pointers
63 by the frontend. */
64 if (DECL_LANG_SPECIFIC (decl)
65 && GFC_DECL_SAVED_DESCRIPTOR (decl))
66 return true;
69 return false;
72 /* True if OpenMP sharing attribute of DECL is predetermined. */
74 enum omp_clause_default_kind
75 gfc_omp_predetermined_sharing (tree decl)
77 if (DECL_ARTIFICIAL (decl)
78 && ! GFC_DECL_RESULT (decl)
79 && ! (DECL_LANG_SPECIFIC (decl)
80 && GFC_DECL_SAVED_DESCRIPTOR (decl)))
81 return OMP_CLAUSE_DEFAULT_SHARED;
83 /* Cray pointees shouldn't be listed in any clauses and should be
84 gimplified to dereference of the corresponding Cray pointer.
85 Make them all private, so that they are emitted in the debug
86 information. */
87 if (GFC_DECL_CRAY_POINTEE (decl))
88 return OMP_CLAUSE_DEFAULT_PRIVATE;
90 /* Assumed-size arrays are predetermined shared. */
91 if (TREE_CODE (decl) == PARM_DECL
92 && GFC_ARRAY_TYPE_P (TREE_TYPE (decl))
93 && GFC_TYPE_ARRAY_AKIND (TREE_TYPE (decl)) == GFC_ARRAY_UNKNOWN
94 && GFC_TYPE_ARRAY_UBOUND (TREE_TYPE (decl),
95 GFC_TYPE_ARRAY_RANK (TREE_TYPE (decl)) - 1)
96 == NULL)
97 return OMP_CLAUSE_DEFAULT_SHARED;
99 /* Dummy procedures aren't considered variables by OpenMP, thus are
100 disallowed in OpenMP clauses. They are represented as PARM_DECLs
101 in the middle-end, so return OMP_CLAUSE_DEFAULT_FIRSTPRIVATE here
102 to avoid complaining about their uses with default(none). */
103 if (TREE_CODE (decl) == PARM_DECL
104 && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
105 && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == FUNCTION_TYPE)
106 return OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
108 /* COMMON and EQUIVALENCE decls are shared. They
109 are only referenced through DECL_VALUE_EXPR of the variables
110 contained in them. If those are privatized, they will not be
111 gimplified to the COMMON or EQUIVALENCE decls. */
112 if (GFC_DECL_COMMON_OR_EQUIV (decl) && ! DECL_HAS_VALUE_EXPR_P (decl))
113 return OMP_CLAUSE_DEFAULT_SHARED;
115 if (GFC_DECL_RESULT (decl) && ! DECL_HAS_VALUE_EXPR_P (decl))
116 return OMP_CLAUSE_DEFAULT_SHARED;
118 return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
121 /* Return decl that should be used when reporting DEFAULT(NONE)
122 diagnostics. */
124 tree
125 gfc_omp_report_decl (tree decl)
127 if (DECL_ARTIFICIAL (decl)
128 && DECL_LANG_SPECIFIC (decl)
129 && GFC_DECL_SAVED_DESCRIPTOR (decl))
130 return GFC_DECL_SAVED_DESCRIPTOR (decl);
132 return decl;
135 /* Return true if DECL in private clause needs
136 OMP_CLAUSE_PRIVATE_OUTER_REF on the private clause. */
137 bool
138 gfc_omp_private_outer_ref (tree decl)
140 tree type = TREE_TYPE (decl);
142 if (GFC_DESCRIPTOR_TYPE_P (type)
143 && GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_ALLOCATABLE)
144 return true;
146 return false;
149 /* Return code to initialize DECL with its default constructor, or
150 NULL if there's nothing to do. */
152 tree
153 gfc_omp_clause_default_ctor (tree clause, tree decl, tree outer)
155 tree type = TREE_TYPE (decl), rank, size, esize, ptr, cond, then_b, else_b;
156 stmtblock_t block, cond_block;
158 if (! GFC_DESCRIPTOR_TYPE_P (type)
159 || GFC_TYPE_ARRAY_AKIND (type) != GFC_ARRAY_ALLOCATABLE)
160 return NULL;
162 gcc_assert (outer != NULL);
163 gcc_assert (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_PRIVATE
164 || OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_LASTPRIVATE);
166 /* Allocatable arrays in PRIVATE clauses need to be set to
167 "not currently allocated" allocation status if outer
168 array is "not currently allocated", otherwise should be allocated. */
169 gfc_start_block (&block);
171 gfc_init_block (&cond_block);
173 gfc_add_modify (&cond_block, decl, outer);
174 rank = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (type) - 1];
175 size = gfc_conv_descriptor_ubound_get (decl, rank);
176 size = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
177 size, gfc_conv_descriptor_lbound_get (decl, rank));
178 size = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
179 size, gfc_index_one_node);
180 if (GFC_TYPE_ARRAY_RANK (type) > 1)
181 size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
182 size, gfc_conv_descriptor_stride_get (decl, rank));
183 esize = fold_convert (gfc_array_index_type,
184 TYPE_SIZE_UNIT (gfc_get_element_type (type)));
185 size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
186 size, esize);
187 size = gfc_evaluate_now (fold_convert (size_type_node, size), &cond_block);
189 ptr = gfc_create_var (pvoid_type_node, NULL);
190 gfc_allocate_using_malloc (&cond_block, ptr, size, NULL_TREE);
191 gfc_conv_descriptor_data_set (&cond_block, decl, ptr);
193 then_b = gfc_finish_block (&cond_block);
195 gfc_init_block (&cond_block);
196 gfc_conv_descriptor_data_set (&cond_block, decl, null_pointer_node);
197 else_b = gfc_finish_block (&cond_block);
199 cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
200 fold_convert (pvoid_type_node,
201 gfc_conv_descriptor_data_get (outer)),
202 null_pointer_node);
203 gfc_add_expr_to_block (&block, build3_loc (input_location, COND_EXPR,
204 void_type_node, cond, then_b, else_b));
206 return gfc_finish_block (&block);
209 /* Build and return code for a copy constructor from SRC to DEST. */
211 tree
212 gfc_omp_clause_copy_ctor (tree clause, tree dest, tree src)
214 tree type = TREE_TYPE (dest), ptr, size, esize, rank, call;
215 tree cond, then_b, else_b;
216 stmtblock_t block, cond_block;
218 if (! GFC_DESCRIPTOR_TYPE_P (type)
219 || GFC_TYPE_ARRAY_AKIND (type) != GFC_ARRAY_ALLOCATABLE)
220 return build2_v (MODIFY_EXPR, dest, src);
222 gcc_assert (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_FIRSTPRIVATE);
224 /* Allocatable arrays in FIRSTPRIVATE clauses need to be allocated
225 and copied from SRC. */
226 gfc_start_block (&block);
228 gfc_init_block (&cond_block);
230 gfc_add_modify (&cond_block, dest, src);
231 rank = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (type) - 1];
232 size = gfc_conv_descriptor_ubound_get (dest, rank);
233 size = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
234 size, gfc_conv_descriptor_lbound_get (dest, rank));
235 size = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
236 size, gfc_index_one_node);
237 if (GFC_TYPE_ARRAY_RANK (type) > 1)
238 size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
239 size, gfc_conv_descriptor_stride_get (dest, rank));
240 esize = fold_convert (gfc_array_index_type,
241 TYPE_SIZE_UNIT (gfc_get_element_type (type)));
242 size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
243 size, esize);
244 size = gfc_evaluate_now (fold_convert (size_type_node, size), &cond_block);
246 ptr = gfc_create_var (pvoid_type_node, NULL);
247 gfc_allocate_using_malloc (&cond_block, ptr, size, NULL_TREE);
248 gfc_conv_descriptor_data_set (&cond_block, dest, ptr);
250 call = build_call_expr_loc (input_location,
251 builtin_decl_explicit (BUILT_IN_MEMCPY),
252 3, ptr,
253 fold_convert (pvoid_type_node,
254 gfc_conv_descriptor_data_get (src)),
255 size);
256 gfc_add_expr_to_block (&cond_block, fold_convert (void_type_node, call));
257 then_b = gfc_finish_block (&cond_block);
259 gfc_init_block (&cond_block);
260 gfc_conv_descriptor_data_set (&cond_block, dest, null_pointer_node);
261 else_b = gfc_finish_block (&cond_block);
263 cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
264 fold_convert (pvoid_type_node,
265 gfc_conv_descriptor_data_get (src)),
266 null_pointer_node);
267 gfc_add_expr_to_block (&block, build3_loc (input_location, COND_EXPR,
268 void_type_node, cond, then_b, else_b));
270 return gfc_finish_block (&block);
273 /* Similarly, except use an assignment operator instead. */
275 tree
276 gfc_omp_clause_assign_op (tree clause ATTRIBUTE_UNUSED, tree dest, tree src)
278 tree type = TREE_TYPE (dest), rank, size, esize, call;
279 stmtblock_t block;
281 if (! GFC_DESCRIPTOR_TYPE_P (type)
282 || GFC_TYPE_ARRAY_AKIND (type) != GFC_ARRAY_ALLOCATABLE)
283 return build2_v (MODIFY_EXPR, dest, src);
285 /* Handle copying allocatable arrays. */
286 gfc_start_block (&block);
288 rank = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (type) - 1];
289 size = gfc_conv_descriptor_ubound_get (dest, rank);
290 size = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
291 size, gfc_conv_descriptor_lbound_get (dest, rank));
292 size = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
293 size, gfc_index_one_node);
294 if (GFC_TYPE_ARRAY_RANK (type) > 1)
295 size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
296 size, gfc_conv_descriptor_stride_get (dest, rank));
297 esize = fold_convert (gfc_array_index_type,
298 TYPE_SIZE_UNIT (gfc_get_element_type (type)));
299 size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
300 size, esize);
301 size = gfc_evaluate_now (fold_convert (size_type_node, size), &block);
302 call = build_call_expr_loc (input_location,
303 builtin_decl_explicit (BUILT_IN_MEMCPY), 3,
304 fold_convert (pvoid_type_node,
305 gfc_conv_descriptor_data_get (dest)),
306 fold_convert (pvoid_type_node,
307 gfc_conv_descriptor_data_get (src)),
308 size);
309 gfc_add_expr_to_block (&block, fold_convert (void_type_node, call));
311 return gfc_finish_block (&block);
314 /* Build and return code destructing DECL. Return NULL if nothing
315 to be done. */
317 tree
318 gfc_omp_clause_dtor (tree clause ATTRIBUTE_UNUSED, tree decl)
320 tree type = TREE_TYPE (decl);
322 if (! GFC_DESCRIPTOR_TYPE_P (type)
323 || GFC_TYPE_ARRAY_AKIND (type) != GFC_ARRAY_ALLOCATABLE)
324 return NULL;
326 /* Allocatable arrays in FIRSTPRIVATE/LASTPRIVATE etc. clauses need
327 to be deallocated if they were allocated. */
328 return gfc_trans_dealloc_allocated (decl, false, NULL);
332 /* Return true if DECL's DECL_VALUE_EXPR (if any) should be
333 disregarded in OpenMP construct, because it is going to be
334 remapped during OpenMP lowering. SHARED is true if DECL
335 is going to be shared, false if it is going to be privatized. */
337 bool
338 gfc_omp_disregard_value_expr (tree decl, bool shared)
340 if (GFC_DECL_COMMON_OR_EQUIV (decl)
341 && DECL_HAS_VALUE_EXPR_P (decl))
343 tree value = DECL_VALUE_EXPR (decl);
345 if (TREE_CODE (value) == COMPONENT_REF
346 && TREE_CODE (TREE_OPERAND (value, 0)) == VAR_DECL
347 && GFC_DECL_COMMON_OR_EQUIV (TREE_OPERAND (value, 0)))
349 /* If variable in COMMON or EQUIVALENCE is privatized, return
350 true, as just that variable is supposed to be privatized,
351 not the whole COMMON or whole EQUIVALENCE.
352 For shared variables in COMMON or EQUIVALENCE, let them be
353 gimplified to DECL_VALUE_EXPR, so that for multiple shared vars
354 from the same COMMON or EQUIVALENCE just one sharing of the
355 whole COMMON or EQUIVALENCE is enough. */
356 return ! shared;
360 if (GFC_DECL_RESULT (decl) && DECL_HAS_VALUE_EXPR_P (decl))
361 return ! shared;
363 return false;
366 /* Return true if DECL that is shared iff SHARED is true should
367 be put into OMP_CLAUSE_PRIVATE with OMP_CLAUSE_PRIVATE_DEBUG
368 flag set. */
370 bool
371 gfc_omp_private_debug_clause (tree decl, bool shared)
373 if (GFC_DECL_CRAY_POINTEE (decl))
374 return true;
376 if (GFC_DECL_COMMON_OR_EQUIV (decl)
377 && DECL_HAS_VALUE_EXPR_P (decl))
379 tree value = DECL_VALUE_EXPR (decl);
381 if (TREE_CODE (value) == COMPONENT_REF
382 && TREE_CODE (TREE_OPERAND (value, 0)) == VAR_DECL
383 && GFC_DECL_COMMON_OR_EQUIV (TREE_OPERAND (value, 0)))
384 return shared;
387 return false;
390 /* Register language specific type size variables as potentially OpenMP
391 firstprivate variables. */
393 void
394 gfc_omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *ctx, tree type)
396 if (GFC_ARRAY_TYPE_P (type) || GFC_DESCRIPTOR_TYPE_P (type))
398 int r;
400 gcc_assert (TYPE_LANG_SPECIFIC (type) != NULL);
401 for (r = 0; r < GFC_TYPE_ARRAY_RANK (type); r++)
403 omp_firstprivatize_variable (ctx, GFC_TYPE_ARRAY_LBOUND (type, r));
404 omp_firstprivatize_variable (ctx, GFC_TYPE_ARRAY_UBOUND (type, r));
405 omp_firstprivatize_variable (ctx, GFC_TYPE_ARRAY_STRIDE (type, r));
407 omp_firstprivatize_variable (ctx, GFC_TYPE_ARRAY_SIZE (type));
408 omp_firstprivatize_variable (ctx, GFC_TYPE_ARRAY_OFFSET (type));
413 static inline tree
414 gfc_trans_add_clause (tree node, tree tail)
416 OMP_CLAUSE_CHAIN (node) = tail;
417 return node;
420 static tree
421 gfc_trans_omp_variable (gfc_symbol *sym)
423 tree t = gfc_get_symbol_decl (sym);
424 tree parent_decl;
425 int parent_flag;
426 bool return_value;
427 bool alternate_entry;
428 bool entry_master;
430 return_value = sym->attr.function && sym->result == sym;
431 alternate_entry = sym->attr.function && sym->attr.entry
432 && sym->result == sym;
433 entry_master = sym->attr.result
434 && sym->ns->proc_name->attr.entry_master
435 && !gfc_return_by_reference (sym->ns->proc_name);
436 parent_decl = DECL_CONTEXT (current_function_decl);
438 if ((t == parent_decl && return_value)
439 || (sym->ns && sym->ns->proc_name
440 && sym->ns->proc_name->backend_decl == parent_decl
441 && (alternate_entry || entry_master)))
442 parent_flag = 1;
443 else
444 parent_flag = 0;
446 /* Special case for assigning the return value of a function.
447 Self recursive functions must have an explicit return value. */
448 if (return_value && (t == current_function_decl || parent_flag))
449 t = gfc_get_fake_result_decl (sym, parent_flag);
451 /* Similarly for alternate entry points. */
452 else if (alternate_entry
453 && (sym->ns->proc_name->backend_decl == current_function_decl
454 || parent_flag))
456 gfc_entry_list *el = NULL;
458 for (el = sym->ns->entries; el; el = el->next)
459 if (sym == el->sym)
461 t = gfc_get_fake_result_decl (sym, parent_flag);
462 break;
466 else if (entry_master
467 && (sym->ns->proc_name->backend_decl == current_function_decl
468 || parent_flag))
469 t = gfc_get_fake_result_decl (sym, parent_flag);
471 return t;
474 static tree
475 gfc_trans_omp_variable_list (enum omp_clause_code code, gfc_namelist *namelist,
476 tree list)
478 for (; namelist != NULL; namelist = namelist->next)
479 if (namelist->sym->attr.referenced)
481 tree t = gfc_trans_omp_variable (namelist->sym);
482 if (t != error_mark_node)
484 tree node = build_omp_clause (input_location, code);
485 OMP_CLAUSE_DECL (node) = t;
486 list = gfc_trans_add_clause (node, list);
489 return list;
492 static void
493 gfc_trans_omp_array_reduction (tree c, gfc_symbol *sym, locus where)
495 gfc_symtree *root1 = NULL, *root2 = NULL, *root3 = NULL, *root4 = NULL;
496 gfc_symtree *symtree1, *symtree2, *symtree3, *symtree4 = NULL;
497 gfc_symbol init_val_sym, outer_sym, intrinsic_sym;
498 gfc_expr *e1, *e2, *e3, *e4;
499 gfc_ref *ref;
500 tree decl, backend_decl, stmt, type, outer_decl;
501 locus old_loc = gfc_current_locus;
502 const char *iname;
503 bool t;
505 decl = OMP_CLAUSE_DECL (c);
506 gfc_current_locus = where;
507 type = TREE_TYPE (decl);
508 outer_decl = create_tmp_var_raw (type, NULL);
509 if (TREE_CODE (decl) == PARM_DECL
510 && TREE_CODE (type) == REFERENCE_TYPE
511 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (type))
512 && GFC_TYPE_ARRAY_AKIND (TREE_TYPE (type)) == GFC_ARRAY_ALLOCATABLE)
514 decl = build_fold_indirect_ref (decl);
515 type = TREE_TYPE (type);
518 /* Create a fake symbol for init value. */
519 memset (&init_val_sym, 0, sizeof (init_val_sym));
520 init_val_sym.ns = sym->ns;
521 init_val_sym.name = sym->name;
522 init_val_sym.ts = sym->ts;
523 init_val_sym.attr.referenced = 1;
524 init_val_sym.declared_at = where;
525 init_val_sym.attr.flavor = FL_VARIABLE;
526 backend_decl = omp_reduction_init (c, gfc_sym_type (&init_val_sym));
527 init_val_sym.backend_decl = backend_decl;
529 /* Create a fake symbol for the outer array reference. */
530 outer_sym = *sym;
531 outer_sym.as = gfc_copy_array_spec (sym->as);
532 outer_sym.attr.dummy = 0;
533 outer_sym.attr.result = 0;
534 outer_sym.attr.flavor = FL_VARIABLE;
535 outer_sym.backend_decl = outer_decl;
536 if (decl != OMP_CLAUSE_DECL (c))
537 outer_sym.backend_decl = build_fold_indirect_ref (outer_decl);
539 /* Create fake symtrees for it. */
540 symtree1 = gfc_new_symtree (&root1, sym->name);
541 symtree1->n.sym = sym;
542 gcc_assert (symtree1 == root1);
544 symtree2 = gfc_new_symtree (&root2, sym->name);
545 symtree2->n.sym = &init_val_sym;
546 gcc_assert (symtree2 == root2);
548 symtree3 = gfc_new_symtree (&root3, sym->name);
549 symtree3->n.sym = &outer_sym;
550 gcc_assert (symtree3 == root3);
552 /* Create expressions. */
553 e1 = gfc_get_expr ();
554 e1->expr_type = EXPR_VARIABLE;
555 e1->where = where;
556 e1->symtree = symtree1;
557 e1->ts = sym->ts;
558 e1->ref = ref = gfc_get_ref ();
559 ref->type = REF_ARRAY;
560 ref->u.ar.where = where;
561 ref->u.ar.as = sym->as;
562 ref->u.ar.type = AR_FULL;
563 ref->u.ar.dimen = 0;
564 t = gfc_resolve_expr (e1);
565 gcc_assert (t);
567 e2 = gfc_get_expr ();
568 e2->expr_type = EXPR_VARIABLE;
569 e2->where = where;
570 e2->symtree = symtree2;
571 e2->ts = sym->ts;
572 t = gfc_resolve_expr (e2);
573 gcc_assert (t);
575 e3 = gfc_copy_expr (e1);
576 e3->symtree = symtree3;
577 t = gfc_resolve_expr (e3);
578 gcc_assert (t);
580 iname = NULL;
581 switch (OMP_CLAUSE_REDUCTION_CODE (c))
583 case PLUS_EXPR:
584 case MINUS_EXPR:
585 e4 = gfc_add (e3, e1);
586 break;
587 case MULT_EXPR:
588 e4 = gfc_multiply (e3, e1);
589 break;
590 case TRUTH_ANDIF_EXPR:
591 e4 = gfc_and (e3, e1);
592 break;
593 case TRUTH_ORIF_EXPR:
594 e4 = gfc_or (e3, e1);
595 break;
596 case EQ_EXPR:
597 e4 = gfc_eqv (e3, e1);
598 break;
599 case NE_EXPR:
600 e4 = gfc_neqv (e3, e1);
601 break;
602 case MIN_EXPR:
603 iname = "min";
604 break;
605 case MAX_EXPR:
606 iname = "max";
607 break;
608 case BIT_AND_EXPR:
609 iname = "iand";
610 break;
611 case BIT_IOR_EXPR:
612 iname = "ior";
613 break;
614 case BIT_XOR_EXPR:
615 iname = "ieor";
616 break;
617 default:
618 gcc_unreachable ();
620 if (iname != NULL)
622 memset (&intrinsic_sym, 0, sizeof (intrinsic_sym));
623 intrinsic_sym.ns = sym->ns;
624 intrinsic_sym.name = iname;
625 intrinsic_sym.ts = sym->ts;
626 intrinsic_sym.attr.referenced = 1;
627 intrinsic_sym.attr.intrinsic = 1;
628 intrinsic_sym.attr.function = 1;
629 intrinsic_sym.result = &intrinsic_sym;
630 intrinsic_sym.declared_at = where;
632 symtree4 = gfc_new_symtree (&root4, iname);
633 symtree4->n.sym = &intrinsic_sym;
634 gcc_assert (symtree4 == root4);
636 e4 = gfc_get_expr ();
637 e4->expr_type = EXPR_FUNCTION;
638 e4->where = where;
639 e4->symtree = symtree4;
640 e4->value.function.isym = gfc_find_function (iname);
641 e4->value.function.actual = gfc_get_actual_arglist ();
642 e4->value.function.actual->expr = e3;
643 e4->value.function.actual->next = gfc_get_actual_arglist ();
644 e4->value.function.actual->next->expr = e1;
646 /* e1 and e3 have been stored as arguments of e4, avoid sharing. */
647 e1 = gfc_copy_expr (e1);
648 e3 = gfc_copy_expr (e3);
649 t = gfc_resolve_expr (e4);
650 gcc_assert (t);
652 /* Create the init statement list. */
653 pushlevel ();
654 if (GFC_DESCRIPTOR_TYPE_P (type)
655 && GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_ALLOCATABLE)
657 /* If decl is an allocatable array, it needs to be allocated
658 with the same bounds as the outer var. */
659 tree rank, size, esize, ptr;
660 stmtblock_t block;
662 gfc_start_block (&block);
664 gfc_add_modify (&block, decl, outer_sym.backend_decl);
665 rank = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (type) - 1];
666 size = gfc_conv_descriptor_ubound_get (decl, rank);
667 size = fold_build2_loc (input_location, MINUS_EXPR,
668 gfc_array_index_type, size,
669 gfc_conv_descriptor_lbound_get (decl, rank));
670 size = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
671 size, gfc_index_one_node);
672 if (GFC_TYPE_ARRAY_RANK (type) > 1)
673 size = fold_build2_loc (input_location, MULT_EXPR,
674 gfc_array_index_type, size,
675 gfc_conv_descriptor_stride_get (decl, rank));
676 esize = fold_convert (gfc_array_index_type,
677 TYPE_SIZE_UNIT (gfc_get_element_type (type)));
678 size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
679 size, esize);
680 size = gfc_evaluate_now (fold_convert (size_type_node, size), &block);
682 ptr = gfc_create_var (pvoid_type_node, NULL);
683 gfc_allocate_using_malloc (&block, ptr, size, NULL_TREE);
684 gfc_conv_descriptor_data_set (&block, decl, ptr);
686 gfc_add_expr_to_block (&block, gfc_trans_assignment (e1, e2, false,
687 false));
688 stmt = gfc_finish_block (&block);
690 else
691 stmt = gfc_trans_assignment (e1, e2, false, false);
692 if (TREE_CODE (stmt) != BIND_EXPR)
693 stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
694 else
695 poplevel (0, 0);
696 OMP_CLAUSE_REDUCTION_INIT (c) = stmt;
698 /* Create the merge statement list. */
699 pushlevel ();
700 if (GFC_DESCRIPTOR_TYPE_P (type)
701 && GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_ALLOCATABLE)
703 /* If decl is an allocatable array, it needs to be deallocated
704 afterwards. */
705 stmtblock_t block;
707 gfc_start_block (&block);
708 gfc_add_expr_to_block (&block, gfc_trans_assignment (e3, e4, false,
709 true));
710 gfc_add_expr_to_block (&block, gfc_trans_dealloc_allocated (decl, false,
711 NULL));
712 stmt = gfc_finish_block (&block);
714 else
715 stmt = gfc_trans_assignment (e3, e4, false, true);
716 if (TREE_CODE (stmt) != BIND_EXPR)
717 stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
718 else
719 poplevel (0, 0);
720 OMP_CLAUSE_REDUCTION_MERGE (c) = stmt;
722 /* And stick the placeholder VAR_DECL into the clause as well. */
723 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = outer_decl;
725 gfc_current_locus = old_loc;
727 gfc_free_expr (e1);
728 gfc_free_expr (e2);
729 gfc_free_expr (e3);
730 gfc_free_expr (e4);
731 free (symtree1);
732 free (symtree2);
733 free (symtree3);
734 free (symtree4);
735 gfc_free_array_spec (outer_sym.as);
738 static tree
739 gfc_trans_omp_reduction_list (gfc_namelist *namelist, tree list,
740 enum tree_code reduction_code, locus where)
742 for (; namelist != NULL; namelist = namelist->next)
743 if (namelist->sym->attr.referenced)
745 tree t = gfc_trans_omp_variable (namelist->sym);
746 if (t != error_mark_node)
748 tree node = build_omp_clause (where.lb->location,
749 OMP_CLAUSE_REDUCTION);
750 OMP_CLAUSE_DECL (node) = t;
751 OMP_CLAUSE_REDUCTION_CODE (node) = reduction_code;
752 if (namelist->sym->attr.dimension)
753 gfc_trans_omp_array_reduction (node, namelist->sym, where);
754 list = gfc_trans_add_clause (node, list);
757 return list;
760 static tree
761 gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
762 locus where)
764 tree omp_clauses = NULL_TREE, chunk_size, c;
765 int list;
766 enum omp_clause_code clause_code;
767 gfc_se se;
769 if (clauses == NULL)
770 return NULL_TREE;
772 for (list = 0; list < OMP_LIST_NUM; list++)
774 gfc_namelist *n = clauses->lists[list];
776 if (n == NULL)
777 continue;
778 if (list >= OMP_LIST_REDUCTION_FIRST
779 && list <= OMP_LIST_REDUCTION_LAST)
781 enum tree_code reduction_code;
782 switch (list)
784 case OMP_LIST_PLUS:
785 reduction_code = PLUS_EXPR;
786 break;
787 case OMP_LIST_MULT:
788 reduction_code = MULT_EXPR;
789 break;
790 case OMP_LIST_SUB:
791 reduction_code = MINUS_EXPR;
792 break;
793 case OMP_LIST_AND:
794 reduction_code = TRUTH_ANDIF_EXPR;
795 break;
796 case OMP_LIST_OR:
797 reduction_code = TRUTH_ORIF_EXPR;
798 break;
799 case OMP_LIST_EQV:
800 reduction_code = EQ_EXPR;
801 break;
802 case OMP_LIST_NEQV:
803 reduction_code = NE_EXPR;
804 break;
805 case OMP_LIST_MAX:
806 reduction_code = MAX_EXPR;
807 break;
808 case OMP_LIST_MIN:
809 reduction_code = MIN_EXPR;
810 break;
811 case OMP_LIST_IAND:
812 reduction_code = BIT_AND_EXPR;
813 break;
814 case OMP_LIST_IOR:
815 reduction_code = BIT_IOR_EXPR;
816 break;
817 case OMP_LIST_IEOR:
818 reduction_code = BIT_XOR_EXPR;
819 break;
820 default:
821 gcc_unreachable ();
823 omp_clauses
824 = gfc_trans_omp_reduction_list (n, omp_clauses, reduction_code,
825 where);
826 continue;
828 switch (list)
830 case OMP_LIST_PRIVATE:
831 clause_code = OMP_CLAUSE_PRIVATE;
832 goto add_clause;
833 case OMP_LIST_SHARED:
834 clause_code = OMP_CLAUSE_SHARED;
835 goto add_clause;
836 case OMP_LIST_FIRSTPRIVATE:
837 clause_code = OMP_CLAUSE_FIRSTPRIVATE;
838 goto add_clause;
839 case OMP_LIST_LASTPRIVATE:
840 clause_code = OMP_CLAUSE_LASTPRIVATE;
841 goto add_clause;
842 case OMP_LIST_COPYIN:
843 clause_code = OMP_CLAUSE_COPYIN;
844 goto add_clause;
845 case OMP_LIST_COPYPRIVATE:
846 clause_code = OMP_CLAUSE_COPYPRIVATE;
847 /* FALLTHROUGH */
848 add_clause:
849 omp_clauses
850 = gfc_trans_omp_variable_list (clause_code, n, omp_clauses);
851 break;
852 default:
853 break;
857 if (clauses->if_expr)
859 tree if_var;
861 gfc_init_se (&se, NULL);
862 gfc_conv_expr (&se, clauses->if_expr);
863 gfc_add_block_to_block (block, &se.pre);
864 if_var = gfc_evaluate_now (se.expr, block);
865 gfc_add_block_to_block (block, &se.post);
867 c = build_omp_clause (where.lb->location, OMP_CLAUSE_IF);
868 OMP_CLAUSE_IF_EXPR (c) = if_var;
869 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
872 if (clauses->final_expr)
874 tree final_var;
876 gfc_init_se (&se, NULL);
877 gfc_conv_expr (&se, clauses->final_expr);
878 gfc_add_block_to_block (block, &se.pre);
879 final_var = gfc_evaluate_now (se.expr, block);
880 gfc_add_block_to_block (block, &se.post);
882 c = build_omp_clause (where.lb->location, OMP_CLAUSE_FINAL);
883 OMP_CLAUSE_FINAL_EXPR (c) = final_var;
884 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
887 if (clauses->num_threads)
889 tree num_threads;
891 gfc_init_se (&se, NULL);
892 gfc_conv_expr (&se, clauses->num_threads);
893 gfc_add_block_to_block (block, &se.pre);
894 num_threads = gfc_evaluate_now (se.expr, block);
895 gfc_add_block_to_block (block, &se.post);
897 c = build_omp_clause (where.lb->location, OMP_CLAUSE_NUM_THREADS);
898 OMP_CLAUSE_NUM_THREADS_EXPR (c) = num_threads;
899 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
902 chunk_size = NULL_TREE;
903 if (clauses->chunk_size)
905 gfc_init_se (&se, NULL);
906 gfc_conv_expr (&se, clauses->chunk_size);
907 gfc_add_block_to_block (block, &se.pre);
908 chunk_size = gfc_evaluate_now (se.expr, block);
909 gfc_add_block_to_block (block, &se.post);
912 if (clauses->sched_kind != OMP_SCHED_NONE)
914 c = build_omp_clause (where.lb->location, OMP_CLAUSE_SCHEDULE);
915 OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = chunk_size;
916 switch (clauses->sched_kind)
918 case OMP_SCHED_STATIC:
919 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_STATIC;
920 break;
921 case OMP_SCHED_DYNAMIC:
922 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_DYNAMIC;
923 break;
924 case OMP_SCHED_GUIDED:
925 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_GUIDED;
926 break;
927 case OMP_SCHED_RUNTIME:
928 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_RUNTIME;
929 break;
930 case OMP_SCHED_AUTO:
931 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_AUTO;
932 break;
933 default:
934 gcc_unreachable ();
936 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
939 if (clauses->default_sharing != OMP_DEFAULT_UNKNOWN)
941 c = build_omp_clause (where.lb->location, OMP_CLAUSE_DEFAULT);
942 switch (clauses->default_sharing)
944 case OMP_DEFAULT_NONE:
945 OMP_CLAUSE_DEFAULT_KIND (c) = OMP_CLAUSE_DEFAULT_NONE;
946 break;
947 case OMP_DEFAULT_SHARED:
948 OMP_CLAUSE_DEFAULT_KIND (c) = OMP_CLAUSE_DEFAULT_SHARED;
949 break;
950 case OMP_DEFAULT_PRIVATE:
951 OMP_CLAUSE_DEFAULT_KIND (c) = OMP_CLAUSE_DEFAULT_PRIVATE;
952 break;
953 case OMP_DEFAULT_FIRSTPRIVATE:
954 OMP_CLAUSE_DEFAULT_KIND (c) = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
955 break;
956 default:
957 gcc_unreachable ();
959 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
962 if (clauses->nowait)
964 c = build_omp_clause (where.lb->location, OMP_CLAUSE_NOWAIT);
965 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
968 if (clauses->ordered)
970 c = build_omp_clause (where.lb->location, OMP_CLAUSE_ORDERED);
971 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
974 if (clauses->untied)
976 c = build_omp_clause (where.lb->location, OMP_CLAUSE_UNTIED);
977 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
980 if (clauses->mergeable)
982 c = build_omp_clause (where.lb->location, OMP_CLAUSE_MERGEABLE);
983 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
986 if (clauses->collapse)
988 c = build_omp_clause (where.lb->location, OMP_CLAUSE_COLLAPSE);
989 OMP_CLAUSE_COLLAPSE_EXPR (c)
990 = build_int_cst (integer_type_node, clauses->collapse);
991 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
994 return omp_clauses;
997 /* Like gfc_trans_code, but force creation of a BIND_EXPR around it. */
999 static tree
1000 gfc_trans_omp_code (gfc_code *code, bool force_empty)
1002 tree stmt;
1004 pushlevel ();
1005 stmt = gfc_trans_code (code);
1006 if (TREE_CODE (stmt) != BIND_EXPR)
1008 if (!IS_EMPTY_STMT (stmt) || force_empty)
1010 tree block = poplevel (1, 0);
1011 stmt = build3_v (BIND_EXPR, NULL, stmt, block);
1013 else
1014 poplevel (0, 0);
1016 else
1017 poplevel (0, 0);
1018 return stmt;
1022 static tree gfc_trans_omp_sections (gfc_code *, gfc_omp_clauses *);
1023 static tree gfc_trans_omp_workshare (gfc_code *, gfc_omp_clauses *);
1025 static tree
1026 gfc_trans_omp_atomic (gfc_code *code)
1028 gfc_code *atomic_code = code;
1029 gfc_se lse;
1030 gfc_se rse;
1031 gfc_se vse;
1032 gfc_expr *expr2, *e;
1033 gfc_symbol *var;
1034 stmtblock_t block;
1035 tree lhsaddr, type, rhs, x;
1036 enum tree_code op = ERROR_MARK;
1037 enum tree_code aop = OMP_ATOMIC;
1038 bool var_on_left = false;
1040 code = code->block->next;
1041 gcc_assert (code->op == EXEC_ASSIGN);
1042 var = code->expr1->symtree->n.sym;
1044 gfc_init_se (&lse, NULL);
1045 gfc_init_se (&rse, NULL);
1046 gfc_init_se (&vse, NULL);
1047 gfc_start_block (&block);
1049 expr2 = code->expr2;
1050 if (expr2->expr_type == EXPR_FUNCTION
1051 && expr2->value.function.isym->id == GFC_ISYM_CONVERSION)
1052 expr2 = expr2->value.function.actual->expr;
1054 switch (atomic_code->ext.omp_atomic)
1056 case GFC_OMP_ATOMIC_READ:
1057 gfc_conv_expr (&vse, code->expr1);
1058 gfc_add_block_to_block (&block, &vse.pre);
1060 gfc_conv_expr (&lse, expr2);
1061 gfc_add_block_to_block (&block, &lse.pre);
1062 type = TREE_TYPE (lse.expr);
1063 lhsaddr = gfc_build_addr_expr (NULL, lse.expr);
1065 x = build1 (OMP_ATOMIC_READ, type, lhsaddr);
1066 x = convert (TREE_TYPE (vse.expr), x);
1067 gfc_add_modify (&block, vse.expr, x);
1069 gfc_add_block_to_block (&block, &lse.pre);
1070 gfc_add_block_to_block (&block, &rse.pre);
1072 return gfc_finish_block (&block);
1073 case GFC_OMP_ATOMIC_CAPTURE:
1074 aop = OMP_ATOMIC_CAPTURE_NEW;
1075 if (expr2->expr_type == EXPR_VARIABLE)
1077 aop = OMP_ATOMIC_CAPTURE_OLD;
1078 gfc_conv_expr (&vse, code->expr1);
1079 gfc_add_block_to_block (&block, &vse.pre);
1081 gfc_conv_expr (&lse, expr2);
1082 gfc_add_block_to_block (&block, &lse.pre);
1083 gfc_init_se (&lse, NULL);
1084 code = code->next;
1085 var = code->expr1->symtree->n.sym;
1086 expr2 = code->expr2;
1087 if (expr2->expr_type == EXPR_FUNCTION
1088 && expr2->value.function.isym->id == GFC_ISYM_CONVERSION)
1089 expr2 = expr2->value.function.actual->expr;
1091 break;
1092 default:
1093 break;
1096 gfc_conv_expr (&lse, code->expr1);
1097 gfc_add_block_to_block (&block, &lse.pre);
1098 type = TREE_TYPE (lse.expr);
1099 lhsaddr = gfc_build_addr_expr (NULL, lse.expr);
1101 if (atomic_code->ext.omp_atomic == GFC_OMP_ATOMIC_WRITE)
1103 gfc_conv_expr (&rse, expr2);
1104 gfc_add_block_to_block (&block, &rse.pre);
1106 else if (expr2->expr_type == EXPR_OP)
1108 gfc_expr *e;
1109 switch (expr2->value.op.op)
1111 case INTRINSIC_PLUS:
1112 op = PLUS_EXPR;
1113 break;
1114 case INTRINSIC_TIMES:
1115 op = MULT_EXPR;
1116 break;
1117 case INTRINSIC_MINUS:
1118 op = MINUS_EXPR;
1119 break;
1120 case INTRINSIC_DIVIDE:
1121 if (expr2->ts.type == BT_INTEGER)
1122 op = TRUNC_DIV_EXPR;
1123 else
1124 op = RDIV_EXPR;
1125 break;
1126 case INTRINSIC_AND:
1127 op = TRUTH_ANDIF_EXPR;
1128 break;
1129 case INTRINSIC_OR:
1130 op = TRUTH_ORIF_EXPR;
1131 break;
1132 case INTRINSIC_EQV:
1133 op = EQ_EXPR;
1134 break;
1135 case INTRINSIC_NEQV:
1136 op = NE_EXPR;
1137 break;
1138 default:
1139 gcc_unreachable ();
1141 e = expr2->value.op.op1;
1142 if (e->expr_type == EXPR_FUNCTION
1143 && e->value.function.isym->id == GFC_ISYM_CONVERSION)
1144 e = e->value.function.actual->expr;
1145 if (e->expr_type == EXPR_VARIABLE
1146 && e->symtree != NULL
1147 && e->symtree->n.sym == var)
1149 expr2 = expr2->value.op.op2;
1150 var_on_left = true;
1152 else
1154 e = expr2->value.op.op2;
1155 if (e->expr_type == EXPR_FUNCTION
1156 && e->value.function.isym->id == GFC_ISYM_CONVERSION)
1157 e = e->value.function.actual->expr;
1158 gcc_assert (e->expr_type == EXPR_VARIABLE
1159 && e->symtree != NULL
1160 && e->symtree->n.sym == var);
1161 expr2 = expr2->value.op.op1;
1162 var_on_left = false;
1164 gfc_conv_expr (&rse, expr2);
1165 gfc_add_block_to_block (&block, &rse.pre);
1167 else
1169 gcc_assert (expr2->expr_type == EXPR_FUNCTION);
1170 switch (expr2->value.function.isym->id)
1172 case GFC_ISYM_MIN:
1173 op = MIN_EXPR;
1174 break;
1175 case GFC_ISYM_MAX:
1176 op = MAX_EXPR;
1177 break;
1178 case GFC_ISYM_IAND:
1179 op = BIT_AND_EXPR;
1180 break;
1181 case GFC_ISYM_IOR:
1182 op = BIT_IOR_EXPR;
1183 break;
1184 case GFC_ISYM_IEOR:
1185 op = BIT_XOR_EXPR;
1186 break;
1187 default:
1188 gcc_unreachable ();
1190 e = expr2->value.function.actual->expr;
1191 gcc_assert (e->expr_type == EXPR_VARIABLE
1192 && e->symtree != NULL
1193 && e->symtree->n.sym == var);
1195 gfc_conv_expr (&rse, expr2->value.function.actual->next->expr);
1196 gfc_add_block_to_block (&block, &rse.pre);
1197 if (expr2->value.function.actual->next->next != NULL)
1199 tree accum = gfc_create_var (TREE_TYPE (rse.expr), NULL);
1200 gfc_actual_arglist *arg;
1202 gfc_add_modify (&block, accum, rse.expr);
1203 for (arg = expr2->value.function.actual->next->next; arg;
1204 arg = arg->next)
1206 gfc_init_block (&rse.pre);
1207 gfc_conv_expr (&rse, arg->expr);
1208 gfc_add_block_to_block (&block, &rse.pre);
1209 x = fold_build2_loc (input_location, op, TREE_TYPE (accum),
1210 accum, rse.expr);
1211 gfc_add_modify (&block, accum, x);
1214 rse.expr = accum;
1217 expr2 = expr2->value.function.actual->next->expr;
1220 lhsaddr = save_expr (lhsaddr);
1221 rhs = gfc_evaluate_now (rse.expr, &block);
1223 if (atomic_code->ext.omp_atomic == GFC_OMP_ATOMIC_WRITE)
1224 x = rhs;
1225 else
1227 x = convert (TREE_TYPE (rhs),
1228 build_fold_indirect_ref_loc (input_location, lhsaddr));
1229 if (var_on_left)
1230 x = fold_build2_loc (input_location, op, TREE_TYPE (rhs), x, rhs);
1231 else
1232 x = fold_build2_loc (input_location, op, TREE_TYPE (rhs), rhs, x);
1235 if (TREE_CODE (TREE_TYPE (rhs)) == COMPLEX_TYPE
1236 && TREE_CODE (type) != COMPLEX_TYPE)
1237 x = fold_build1_loc (input_location, REALPART_EXPR,
1238 TREE_TYPE (TREE_TYPE (rhs)), x);
1240 gfc_add_block_to_block (&block, &lse.pre);
1241 gfc_add_block_to_block (&block, &rse.pre);
1243 if (aop == OMP_ATOMIC)
1245 x = build2_v (OMP_ATOMIC, lhsaddr, convert (type, x));
1246 gfc_add_expr_to_block (&block, x);
1248 else
1250 if (aop == OMP_ATOMIC_CAPTURE_NEW)
1252 code = code->next;
1253 expr2 = code->expr2;
1254 if (expr2->expr_type == EXPR_FUNCTION
1255 && expr2->value.function.isym->id == GFC_ISYM_CONVERSION)
1256 expr2 = expr2->value.function.actual->expr;
1258 gcc_assert (expr2->expr_type == EXPR_VARIABLE);
1259 gfc_conv_expr (&vse, code->expr1);
1260 gfc_add_block_to_block (&block, &vse.pre);
1262 gfc_init_se (&lse, NULL);
1263 gfc_conv_expr (&lse, expr2);
1264 gfc_add_block_to_block (&block, &lse.pre);
1266 x = build2 (aop, type, lhsaddr, convert (type, x));
1267 x = convert (TREE_TYPE (vse.expr), x);
1268 gfc_add_modify (&block, vse.expr, x);
1271 return gfc_finish_block (&block);
1274 static tree
1275 gfc_trans_omp_barrier (void)
1277 tree decl = builtin_decl_explicit (BUILT_IN_GOMP_BARRIER);
1278 return build_call_expr_loc (input_location, decl, 0);
1281 static tree
1282 gfc_trans_omp_critical (gfc_code *code)
1284 tree name = NULL_TREE, stmt;
1285 if (code->ext.omp_name != NULL)
1286 name = get_identifier (code->ext.omp_name);
1287 stmt = gfc_trans_code (code->block->next);
1288 return build2_loc (input_location, OMP_CRITICAL, void_type_node, stmt, name);
1291 typedef struct dovar_init_d {
1292 tree var;
1293 tree init;
1294 } dovar_init;
1297 static tree
1298 gfc_trans_omp_do (gfc_code *code, stmtblock_t *pblock,
1299 gfc_omp_clauses *do_clauses, tree par_clauses)
1301 gfc_se se;
1302 tree dovar, stmt, from, to, step, type, init, cond, incr;
1303 tree count = NULL_TREE, cycle_label, tmp, omp_clauses;
1304 stmtblock_t block;
1305 stmtblock_t body;
1306 gfc_omp_clauses *clauses = code->ext.omp_clauses;
1307 int i, collapse = clauses->collapse;
1308 vec<dovar_init> inits = vNULL;
1309 dovar_init *di;
1310 unsigned ix;
1312 if (collapse <= 0)
1313 collapse = 1;
1315 code = code->block->next;
1316 gcc_assert (code->op == EXEC_DO);
1318 init = make_tree_vec (collapse);
1319 cond = make_tree_vec (collapse);
1320 incr = make_tree_vec (collapse);
1322 if (pblock == NULL)
1324 gfc_start_block (&block);
1325 pblock = &block;
1328 omp_clauses = gfc_trans_omp_clauses (pblock, do_clauses, code->loc);
1330 for (i = 0; i < collapse; i++)
1332 int simple = 0;
1333 int dovar_found = 0;
1334 tree dovar_decl;
1336 if (clauses)
1338 gfc_namelist *n;
1339 for (n = clauses->lists[OMP_LIST_LASTPRIVATE]; n != NULL;
1340 n = n->next)
1341 if (code->ext.iterator->var->symtree->n.sym == n->sym)
1342 break;
1343 if (n != NULL)
1344 dovar_found = 1;
1345 else if (n == NULL)
1346 for (n = clauses->lists[OMP_LIST_PRIVATE]; n != NULL; n = n->next)
1347 if (code->ext.iterator->var->symtree->n.sym == n->sym)
1348 break;
1349 if (n != NULL)
1350 dovar_found++;
1353 /* Evaluate all the expressions in the iterator. */
1354 gfc_init_se (&se, NULL);
1355 gfc_conv_expr_lhs (&se, code->ext.iterator->var);
1356 gfc_add_block_to_block (pblock, &se.pre);
1357 dovar = se.expr;
1358 type = TREE_TYPE (dovar);
1359 gcc_assert (TREE_CODE (type) == INTEGER_TYPE);
1361 gfc_init_se (&se, NULL);
1362 gfc_conv_expr_val (&se, code->ext.iterator->start);
1363 gfc_add_block_to_block (pblock, &se.pre);
1364 from = gfc_evaluate_now (se.expr, pblock);
1366 gfc_init_se (&se, NULL);
1367 gfc_conv_expr_val (&se, code->ext.iterator->end);
1368 gfc_add_block_to_block (pblock, &se.pre);
1369 to = gfc_evaluate_now (se.expr, pblock);
1371 gfc_init_se (&se, NULL);
1372 gfc_conv_expr_val (&se, code->ext.iterator->step);
1373 gfc_add_block_to_block (pblock, &se.pre);
1374 step = gfc_evaluate_now (se.expr, pblock);
1375 dovar_decl = dovar;
1377 /* Special case simple loops. */
1378 if (TREE_CODE (dovar) == VAR_DECL)
1380 if (integer_onep (step))
1381 simple = 1;
1382 else if (tree_int_cst_equal (step, integer_minus_one_node))
1383 simple = -1;
1385 else
1386 dovar_decl
1387 = gfc_trans_omp_variable (code->ext.iterator->var->symtree->n.sym);
1389 /* Loop body. */
1390 if (simple)
1392 TREE_VEC_ELT (init, i) = build2_v (MODIFY_EXPR, dovar, from);
1393 /* The condition should not be folded. */
1394 TREE_VEC_ELT (cond, i) = build2_loc (input_location, simple > 0
1395 ? LE_EXPR : GE_EXPR,
1396 boolean_type_node, dovar, to);
1397 TREE_VEC_ELT (incr, i) = fold_build2_loc (input_location, PLUS_EXPR,
1398 type, dovar, step);
1399 TREE_VEC_ELT (incr, i) = fold_build2_loc (input_location,
1400 MODIFY_EXPR,
1401 type, dovar,
1402 TREE_VEC_ELT (incr, i));
1404 else
1406 /* STEP is not 1 or -1. Use:
1407 for (count = 0; count < (to + step - from) / step; count++)
1409 dovar = from + count * step;
1410 body;
1411 cycle_label:;
1412 } */
1413 tmp = fold_build2_loc (input_location, MINUS_EXPR, type, step, from);
1414 tmp = fold_build2_loc (input_location, PLUS_EXPR, type, to, tmp);
1415 tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR, type, tmp,
1416 step);
1417 tmp = gfc_evaluate_now (tmp, pblock);
1418 count = gfc_create_var (type, "count");
1419 TREE_VEC_ELT (init, i) = build2_v (MODIFY_EXPR, count,
1420 build_int_cst (type, 0));
1421 /* The condition should not be folded. */
1422 TREE_VEC_ELT (cond, i) = build2_loc (input_location, LT_EXPR,
1423 boolean_type_node,
1424 count, tmp);
1425 TREE_VEC_ELT (incr, i) = fold_build2_loc (input_location, PLUS_EXPR,
1426 type, count,
1427 build_int_cst (type, 1));
1428 TREE_VEC_ELT (incr, i) = fold_build2_loc (input_location,
1429 MODIFY_EXPR, type, count,
1430 TREE_VEC_ELT (incr, i));
1432 /* Initialize DOVAR. */
1433 tmp = fold_build2_loc (input_location, MULT_EXPR, type, count, step);
1434 tmp = fold_build2_loc (input_location, PLUS_EXPR, type, from, tmp);
1435 dovar_init e = {dovar, tmp};
1436 inits.safe_push (e);
1439 if (!dovar_found)
1441 tmp = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
1442 OMP_CLAUSE_DECL (tmp) = dovar_decl;
1443 omp_clauses = gfc_trans_add_clause (tmp, omp_clauses);
1445 else if (dovar_found == 2)
1447 tree c = NULL;
1449 tmp = NULL;
1450 if (!simple)
1452 /* If dovar is lastprivate, but different counter is used,
1453 dovar += step needs to be added to
1454 OMP_CLAUSE_LASTPRIVATE_STMT, otherwise the copied dovar
1455 will have the value on entry of the last loop, rather
1456 than value after iterator increment. */
1457 tmp = gfc_evaluate_now (step, pblock);
1458 tmp = fold_build2_loc (input_location, PLUS_EXPR, type, dovar,
1459 tmp);
1460 tmp = fold_build2_loc (input_location, MODIFY_EXPR, type,
1461 dovar, tmp);
1462 for (c = omp_clauses; c ; c = OMP_CLAUSE_CHAIN (c))
1463 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
1464 && OMP_CLAUSE_DECL (c) == dovar_decl)
1466 OMP_CLAUSE_LASTPRIVATE_STMT (c) = tmp;
1467 break;
1470 if (c == NULL && par_clauses != NULL)
1472 for (c = par_clauses; c ; c = OMP_CLAUSE_CHAIN (c))
1473 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
1474 && OMP_CLAUSE_DECL (c) == dovar_decl)
1476 tree l = build_omp_clause (input_location,
1477 OMP_CLAUSE_LASTPRIVATE);
1478 OMP_CLAUSE_DECL (l) = dovar_decl;
1479 OMP_CLAUSE_CHAIN (l) = omp_clauses;
1480 OMP_CLAUSE_LASTPRIVATE_STMT (l) = tmp;
1481 omp_clauses = l;
1482 OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_SHARED);
1483 break;
1486 gcc_assert (simple || c != NULL);
1488 if (!simple)
1490 tmp = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
1491 OMP_CLAUSE_DECL (tmp) = count;
1492 omp_clauses = gfc_trans_add_clause (tmp, omp_clauses);
1495 if (i + 1 < collapse)
1496 code = code->block->next;
1499 if (pblock != &block)
1501 pushlevel ();
1502 gfc_start_block (&block);
1505 gfc_start_block (&body);
1507 FOR_EACH_VEC_ELT (inits, ix, di)
1508 gfc_add_modify (&body, di->var, di->init);
1509 inits.release ();
1511 /* Cycle statement is implemented with a goto. Exit statement must not be
1512 present for this loop. */
1513 cycle_label = gfc_build_label_decl (NULL_TREE);
1515 /* Put these labels where they can be found later. */
1517 code->cycle_label = cycle_label;
1518 code->exit_label = NULL_TREE;
1520 /* Main loop body. */
1521 tmp = gfc_trans_omp_code (code->block->next, true);
1522 gfc_add_expr_to_block (&body, tmp);
1524 /* Label for cycle statements (if needed). */
1525 if (TREE_USED (cycle_label))
1527 tmp = build1_v (LABEL_EXPR, cycle_label);
1528 gfc_add_expr_to_block (&body, tmp);
1531 /* End of loop body. */
1532 stmt = make_node (OMP_FOR);
1534 TREE_TYPE (stmt) = void_type_node;
1535 OMP_FOR_BODY (stmt) = gfc_finish_block (&body);
1536 OMP_FOR_CLAUSES (stmt) = omp_clauses;
1537 OMP_FOR_INIT (stmt) = init;
1538 OMP_FOR_COND (stmt) = cond;
1539 OMP_FOR_INCR (stmt) = incr;
1540 gfc_add_expr_to_block (&block, stmt);
1542 return gfc_finish_block (&block);
1545 static tree
1546 gfc_trans_omp_flush (void)
1548 tree decl = builtin_decl_explicit (BUILT_IN_SYNC_SYNCHRONIZE);
1549 return build_call_expr_loc (input_location, decl, 0);
1552 static tree
1553 gfc_trans_omp_master (gfc_code *code)
1555 tree stmt = gfc_trans_code (code->block->next);
1556 if (IS_EMPTY_STMT (stmt))
1557 return stmt;
1558 return build1_v (OMP_MASTER, stmt);
1561 static tree
1562 gfc_trans_omp_ordered (gfc_code *code)
1564 return build1_v (OMP_ORDERED, gfc_trans_code (code->block->next));
1567 static tree
1568 gfc_trans_omp_parallel (gfc_code *code)
1570 stmtblock_t block;
1571 tree stmt, omp_clauses;
1573 gfc_start_block (&block);
1574 omp_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
1575 code->loc);
1576 stmt = gfc_trans_omp_code (code->block->next, true);
1577 stmt = build2_loc (input_location, OMP_PARALLEL, void_type_node, stmt,
1578 omp_clauses);
1579 gfc_add_expr_to_block (&block, stmt);
1580 return gfc_finish_block (&block);
1583 static tree
1584 gfc_trans_omp_parallel_do (gfc_code *code)
1586 stmtblock_t block, *pblock = NULL;
1587 gfc_omp_clauses parallel_clauses, do_clauses;
1588 tree stmt, omp_clauses = NULL_TREE;
1590 gfc_start_block (&block);
1592 memset (&do_clauses, 0, sizeof (do_clauses));
1593 if (code->ext.omp_clauses != NULL)
1595 memcpy (&parallel_clauses, code->ext.omp_clauses,
1596 sizeof (parallel_clauses));
1597 do_clauses.sched_kind = parallel_clauses.sched_kind;
1598 do_clauses.chunk_size = parallel_clauses.chunk_size;
1599 do_clauses.ordered = parallel_clauses.ordered;
1600 do_clauses.collapse = parallel_clauses.collapse;
1601 parallel_clauses.sched_kind = OMP_SCHED_NONE;
1602 parallel_clauses.chunk_size = NULL;
1603 parallel_clauses.ordered = false;
1604 parallel_clauses.collapse = 0;
1605 omp_clauses = gfc_trans_omp_clauses (&block, &parallel_clauses,
1606 code->loc);
1608 do_clauses.nowait = true;
1609 if (!do_clauses.ordered && do_clauses.sched_kind != OMP_SCHED_STATIC)
1610 pblock = &block;
1611 else
1612 pushlevel ();
1613 stmt = gfc_trans_omp_do (code, pblock, &do_clauses, omp_clauses);
1614 if (TREE_CODE (stmt) != BIND_EXPR)
1615 stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
1616 else
1617 poplevel (0, 0);
1618 stmt = build2_loc (input_location, OMP_PARALLEL, void_type_node, stmt,
1619 omp_clauses);
1620 OMP_PARALLEL_COMBINED (stmt) = 1;
1621 gfc_add_expr_to_block (&block, stmt);
1622 return gfc_finish_block (&block);
1625 static tree
1626 gfc_trans_omp_parallel_sections (gfc_code *code)
1628 stmtblock_t block;
1629 gfc_omp_clauses section_clauses;
1630 tree stmt, omp_clauses;
1632 memset (&section_clauses, 0, sizeof (section_clauses));
1633 section_clauses.nowait = true;
1635 gfc_start_block (&block);
1636 omp_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
1637 code->loc);
1638 pushlevel ();
1639 stmt = gfc_trans_omp_sections (code, &section_clauses);
1640 if (TREE_CODE (stmt) != BIND_EXPR)
1641 stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
1642 else
1643 poplevel (0, 0);
1644 stmt = build2_loc (input_location, OMP_PARALLEL, void_type_node, stmt,
1645 omp_clauses);
1646 OMP_PARALLEL_COMBINED (stmt) = 1;
1647 gfc_add_expr_to_block (&block, stmt);
1648 return gfc_finish_block (&block);
1651 static tree
1652 gfc_trans_omp_parallel_workshare (gfc_code *code)
1654 stmtblock_t block;
1655 gfc_omp_clauses workshare_clauses;
1656 tree stmt, omp_clauses;
1658 memset (&workshare_clauses, 0, sizeof (workshare_clauses));
1659 workshare_clauses.nowait = true;
1661 gfc_start_block (&block);
1662 omp_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
1663 code->loc);
1664 pushlevel ();
1665 stmt = gfc_trans_omp_workshare (code, &workshare_clauses);
1666 if (TREE_CODE (stmt) != BIND_EXPR)
1667 stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
1668 else
1669 poplevel (0, 0);
1670 stmt = build2_loc (input_location, OMP_PARALLEL, void_type_node, stmt,
1671 omp_clauses);
1672 OMP_PARALLEL_COMBINED (stmt) = 1;
1673 gfc_add_expr_to_block (&block, stmt);
1674 return gfc_finish_block (&block);
1677 static tree
1678 gfc_trans_omp_sections (gfc_code *code, gfc_omp_clauses *clauses)
1680 stmtblock_t block, body;
1681 tree omp_clauses, stmt;
1682 bool has_lastprivate = clauses->lists[OMP_LIST_LASTPRIVATE] != NULL;
1684 gfc_start_block (&block);
1686 omp_clauses = gfc_trans_omp_clauses (&block, clauses, code->loc);
1688 gfc_init_block (&body);
1689 for (code = code->block; code; code = code->block)
1691 /* Last section is special because of lastprivate, so even if it
1692 is empty, chain it in. */
1693 stmt = gfc_trans_omp_code (code->next,
1694 has_lastprivate && code->block == NULL);
1695 if (! IS_EMPTY_STMT (stmt))
1697 stmt = build1_v (OMP_SECTION, stmt);
1698 gfc_add_expr_to_block (&body, stmt);
1701 stmt = gfc_finish_block (&body);
1703 stmt = build2_loc (input_location, OMP_SECTIONS, void_type_node, stmt,
1704 omp_clauses);
1705 gfc_add_expr_to_block (&block, stmt);
1707 return gfc_finish_block (&block);
1710 static tree
1711 gfc_trans_omp_single (gfc_code *code, gfc_omp_clauses *clauses)
1713 tree omp_clauses = gfc_trans_omp_clauses (NULL, clauses, code->loc);
1714 tree stmt = gfc_trans_omp_code (code->block->next, true);
1715 stmt = build2_loc (input_location, OMP_SINGLE, void_type_node, stmt,
1716 omp_clauses);
1717 return stmt;
1720 static tree
1721 gfc_trans_omp_task (gfc_code *code)
1723 stmtblock_t block;
1724 tree stmt, omp_clauses;
1726 gfc_start_block (&block);
1727 omp_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
1728 code->loc);
1729 stmt = gfc_trans_omp_code (code->block->next, true);
1730 stmt = build2_loc (input_location, OMP_TASK, void_type_node, stmt,
1731 omp_clauses);
1732 gfc_add_expr_to_block (&block, stmt);
1733 return gfc_finish_block (&block);
1736 static tree
1737 gfc_trans_omp_taskwait (void)
1739 tree decl = builtin_decl_explicit (BUILT_IN_GOMP_TASKWAIT);
1740 return build_call_expr_loc (input_location, decl, 0);
1743 static tree
1744 gfc_trans_omp_taskyield (void)
1746 tree decl = builtin_decl_explicit (BUILT_IN_GOMP_TASKYIELD);
1747 return build_call_expr_loc (input_location, decl, 0);
1750 static tree
1751 gfc_trans_omp_workshare (gfc_code *code, gfc_omp_clauses *clauses)
1753 tree res, tmp, stmt;
1754 stmtblock_t block, *pblock = NULL;
1755 stmtblock_t singleblock;
1756 int saved_ompws_flags;
1757 bool singleblock_in_progress = false;
1758 /* True if previous gfc_code in workshare construct is not workshared. */
1759 bool prev_singleunit;
1761 code = code->block->next;
1763 pushlevel ();
1765 gfc_start_block (&block);
1766 pblock = &block;
1768 ompws_flags = OMPWS_WORKSHARE_FLAG;
1769 prev_singleunit = false;
1771 /* Translate statements one by one to trees until we reach
1772 the end of the workshare construct. Adjacent gfc_codes that
1773 are a single unit of work are clustered and encapsulated in a
1774 single OMP_SINGLE construct. */
1775 for (; code; code = code->next)
1777 if (code->here != 0)
1779 res = gfc_trans_label_here (code);
1780 gfc_add_expr_to_block (pblock, res);
1783 /* No dependence analysis, use for clauses with wait.
1784 If this is the last gfc_code, use default omp_clauses. */
1785 if (code->next == NULL && clauses->nowait)
1786 ompws_flags |= OMPWS_NOWAIT;
1788 /* By default, every gfc_code is a single unit of work. */
1789 ompws_flags |= OMPWS_CURR_SINGLEUNIT;
1790 ompws_flags &= ~OMPWS_SCALARIZER_WS;
1792 switch (code->op)
1794 case EXEC_NOP:
1795 res = NULL_TREE;
1796 break;
1798 case EXEC_ASSIGN:
1799 res = gfc_trans_assign (code);
1800 break;
1802 case EXEC_POINTER_ASSIGN:
1803 res = gfc_trans_pointer_assign (code);
1804 break;
1806 case EXEC_INIT_ASSIGN:
1807 res = gfc_trans_init_assign (code);
1808 break;
1810 case EXEC_FORALL:
1811 res = gfc_trans_forall (code);
1812 break;
1814 case EXEC_WHERE:
1815 res = gfc_trans_where (code);
1816 break;
1818 case EXEC_OMP_ATOMIC:
1819 res = gfc_trans_omp_directive (code);
1820 break;
1822 case EXEC_OMP_PARALLEL:
1823 case EXEC_OMP_PARALLEL_DO:
1824 case EXEC_OMP_PARALLEL_SECTIONS:
1825 case EXEC_OMP_PARALLEL_WORKSHARE:
1826 case EXEC_OMP_CRITICAL:
1827 saved_ompws_flags = ompws_flags;
1828 ompws_flags = 0;
1829 res = gfc_trans_omp_directive (code);
1830 ompws_flags = saved_ompws_flags;
1831 break;
1833 default:
1834 internal_error ("gfc_trans_omp_workshare(): Bad statement code");
1837 gfc_set_backend_locus (&code->loc);
1839 if (res != NULL_TREE && ! IS_EMPTY_STMT (res))
1841 if (prev_singleunit)
1843 if (ompws_flags & OMPWS_CURR_SINGLEUNIT)
1844 /* Add current gfc_code to single block. */
1845 gfc_add_expr_to_block (&singleblock, res);
1846 else
1848 /* Finish single block and add it to pblock. */
1849 tmp = gfc_finish_block (&singleblock);
1850 tmp = build2_loc (input_location, OMP_SINGLE,
1851 void_type_node, tmp, NULL_TREE);
1852 gfc_add_expr_to_block (pblock, tmp);
1853 /* Add current gfc_code to pblock. */
1854 gfc_add_expr_to_block (pblock, res);
1855 singleblock_in_progress = false;
1858 else
1860 if (ompws_flags & OMPWS_CURR_SINGLEUNIT)
1862 /* Start single block. */
1863 gfc_init_block (&singleblock);
1864 gfc_add_expr_to_block (&singleblock, res);
1865 singleblock_in_progress = true;
1867 else
1868 /* Add the new statement to the block. */
1869 gfc_add_expr_to_block (pblock, res);
1871 prev_singleunit = (ompws_flags & OMPWS_CURR_SINGLEUNIT) != 0;
1875 /* Finish remaining SINGLE block, if we were in the middle of one. */
1876 if (singleblock_in_progress)
1878 /* Finish single block and add it to pblock. */
1879 tmp = gfc_finish_block (&singleblock);
1880 tmp = build2_loc (input_location, OMP_SINGLE, void_type_node, tmp,
1881 clauses->nowait
1882 ? build_omp_clause (input_location, OMP_CLAUSE_NOWAIT)
1883 : NULL_TREE);
1884 gfc_add_expr_to_block (pblock, tmp);
1887 stmt = gfc_finish_block (pblock);
1888 if (TREE_CODE (stmt) != BIND_EXPR)
1890 if (!IS_EMPTY_STMT (stmt))
1892 tree bindblock = poplevel (1, 0);
1893 stmt = build3_v (BIND_EXPR, NULL, stmt, bindblock);
1895 else
1896 poplevel (0, 0);
1898 else
1899 poplevel (0, 0);
1901 if (IS_EMPTY_STMT (stmt) && !clauses->nowait)
1902 stmt = gfc_trans_omp_barrier ();
1904 ompws_flags = 0;
1905 return stmt;
1908 tree
1909 gfc_trans_omp_directive (gfc_code *code)
1911 switch (code->op)
1913 case EXEC_OMP_ATOMIC:
1914 return gfc_trans_omp_atomic (code);
1915 case EXEC_OMP_BARRIER:
1916 return gfc_trans_omp_barrier ();
1917 case EXEC_OMP_CRITICAL:
1918 return gfc_trans_omp_critical (code);
1919 case EXEC_OMP_DO:
1920 return gfc_trans_omp_do (code, NULL, code->ext.omp_clauses, NULL);
1921 case EXEC_OMP_FLUSH:
1922 return gfc_trans_omp_flush ();
1923 case EXEC_OMP_MASTER:
1924 return gfc_trans_omp_master (code);
1925 case EXEC_OMP_ORDERED:
1926 return gfc_trans_omp_ordered (code);
1927 case EXEC_OMP_PARALLEL:
1928 return gfc_trans_omp_parallel (code);
1929 case EXEC_OMP_PARALLEL_DO:
1930 return gfc_trans_omp_parallel_do (code);
1931 case EXEC_OMP_PARALLEL_SECTIONS:
1932 return gfc_trans_omp_parallel_sections (code);
1933 case EXEC_OMP_PARALLEL_WORKSHARE:
1934 return gfc_trans_omp_parallel_workshare (code);
1935 case EXEC_OMP_SECTIONS:
1936 return gfc_trans_omp_sections (code, code->ext.omp_clauses);
1937 case EXEC_OMP_SINGLE:
1938 return gfc_trans_omp_single (code, code->ext.omp_clauses);
1939 case EXEC_OMP_TASK:
1940 return gfc_trans_omp_task (code);
1941 case EXEC_OMP_TASKWAIT:
1942 return gfc_trans_omp_taskwait ();
1943 case EXEC_OMP_TASKYIELD:
1944 return gfc_trans_omp_taskyield ();
1945 case EXEC_OMP_WORKSHARE:
1946 return gfc_trans_omp_workshare (code, code->ext.omp_clauses);
1947 default:
1948 gcc_unreachable ();