1 /* OpenMP directive translation -- generate GCC trees from gfc_code.
2 Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
3 Free Software Foundation, Inc.
4 Contributed by Jakub Jelinek <jakub@redhat.com>
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
25 #include "coretypes.h"
27 #include "gimple.h" /* For create_tmp_var_raw. */
28 #include "diagnostic-core.h" /* For internal_error. */
31 #include "trans-stmt.h"
32 #include "trans-types.h"
33 #include "trans-array.h"
34 #include "trans-const.h"
39 /* True if OpenMP should privatize what this DECL points to rather
40 than the DECL itself. */
43 gfc_omp_privatize_by_reference (const_tree decl)
45 tree type = TREE_TYPE (decl);
47 if (TREE_CODE (type) == REFERENCE_TYPE
48 && (!DECL_ARTIFICIAL (decl) || TREE_CODE (decl) == PARM_DECL))
51 if (TREE_CODE (type) == POINTER_TYPE)
53 /* Array POINTER/ALLOCATABLE have aggregate types, all user variables
54 that have POINTER_TYPE type and don't have GFC_POINTER_TYPE_P
55 set are supposed to be privatized by reference. */
56 if (GFC_POINTER_TYPE_P (type))
59 if (!DECL_ARTIFICIAL (decl)
60 && TREE_CODE (TREE_TYPE (type)) != FUNCTION_TYPE)
63 /* Some arrays are expanded as DECL_ARTIFICIAL pointers
65 if (DECL_LANG_SPECIFIC (decl)
66 && GFC_DECL_SAVED_DESCRIPTOR (decl))
73 /* True if OpenMP sharing attribute of DECL is predetermined. */
75 enum omp_clause_default_kind
76 gfc_omp_predetermined_sharing (tree decl)
78 if (DECL_ARTIFICIAL (decl)
79 && ! GFC_DECL_RESULT (decl)
80 && ! (DECL_LANG_SPECIFIC (decl)
81 && GFC_DECL_SAVED_DESCRIPTOR (decl)))
82 return OMP_CLAUSE_DEFAULT_SHARED;
84 /* Cray pointees shouldn't be listed in any clauses and should be
85 gimplified to dereference of the corresponding Cray pointer.
86 Make them all private, so that they are emitted in the debug
88 if (GFC_DECL_CRAY_POINTEE (decl))
89 return OMP_CLAUSE_DEFAULT_PRIVATE;
91 /* Assumed-size arrays are predetermined shared. */
92 if (TREE_CODE (decl) == PARM_DECL
93 && GFC_ARRAY_TYPE_P (TREE_TYPE (decl))
94 && GFC_TYPE_ARRAY_AKIND (TREE_TYPE (decl)) == GFC_ARRAY_UNKNOWN
95 && GFC_TYPE_ARRAY_UBOUND (TREE_TYPE (decl),
96 GFC_TYPE_ARRAY_RANK (TREE_TYPE (decl)) - 1)
98 return OMP_CLAUSE_DEFAULT_SHARED;
100 /* Dummy procedures aren't considered variables by OpenMP, thus are
101 disallowed in OpenMP clauses. They are represented as PARM_DECLs
102 in the middle-end, so return OMP_CLAUSE_DEFAULT_FIRSTPRIVATE here
103 to avoid complaining about their uses with default(none). */
104 if (TREE_CODE (decl) == PARM_DECL
105 && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
106 && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == FUNCTION_TYPE)
107 return OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
109 /* COMMON and EQUIVALENCE decls are shared. They
110 are only referenced through DECL_VALUE_EXPR of the variables
111 contained in them. If those are privatized, they will not be
112 gimplified to the COMMON or EQUIVALENCE decls. */
113 if (GFC_DECL_COMMON_OR_EQUIV (decl) && ! DECL_HAS_VALUE_EXPR_P (decl))
114 return OMP_CLAUSE_DEFAULT_SHARED;
116 if (GFC_DECL_RESULT (decl) && ! DECL_HAS_VALUE_EXPR_P (decl))
117 return OMP_CLAUSE_DEFAULT_SHARED;
119 return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
122 /* Return decl that should be used when reporting DEFAULT(NONE)
126 gfc_omp_report_decl (tree decl)
128 if (DECL_ARTIFICIAL (decl)
129 && DECL_LANG_SPECIFIC (decl)
130 && GFC_DECL_SAVED_DESCRIPTOR (decl))
131 return GFC_DECL_SAVED_DESCRIPTOR (decl);
136 /* Return true if DECL in private clause needs
137 OMP_CLAUSE_PRIVATE_OUTER_REF on the private clause. */
139 gfc_omp_private_outer_ref (tree decl)
141 tree type = TREE_TYPE (decl);
143 if (GFC_DESCRIPTOR_TYPE_P (type)
144 && GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_ALLOCATABLE)
150 /* Return code to initialize DECL with its default constructor, or
151 NULL if there's nothing to do. */
154 gfc_omp_clause_default_ctor (tree clause, tree decl, tree outer)
156 tree type = TREE_TYPE (decl), rank, size, esize, ptr, cond, then_b, else_b;
157 stmtblock_t block, cond_block;
159 if (! GFC_DESCRIPTOR_TYPE_P (type)
160 || GFC_TYPE_ARRAY_AKIND (type) != GFC_ARRAY_ALLOCATABLE)
163 gcc_assert (outer != NULL);
164 gcc_assert (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_PRIVATE
165 || OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_LASTPRIVATE);
167 /* Allocatable arrays in PRIVATE clauses need to be set to
168 "not currently allocated" allocation status if outer
169 array is "not currently allocated", otherwise should be allocated. */
170 gfc_start_block (&block);
172 gfc_init_block (&cond_block);
174 gfc_add_modify (&cond_block, decl, outer);
175 rank = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (type) - 1];
176 size = gfc_conv_descriptor_ubound_get (decl, rank);
177 size = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
178 size, gfc_conv_descriptor_lbound_get (decl, rank));
179 size = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
180 size, gfc_index_one_node);
181 if (GFC_TYPE_ARRAY_RANK (type) > 1)
182 size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
183 size, gfc_conv_descriptor_stride_get (decl, rank));
184 esize = fold_convert (gfc_array_index_type,
185 TYPE_SIZE_UNIT (gfc_get_element_type (type)));
186 size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
188 size = gfc_evaluate_now (fold_convert (size_type_node, size), &cond_block);
190 ptr = gfc_create_var (pvoid_type_node, NULL);
191 gfc_allocate_using_malloc (&cond_block, ptr, size, NULL_TREE);
192 gfc_conv_descriptor_data_set (&cond_block, decl, ptr);
194 then_b = gfc_finish_block (&cond_block);
196 gfc_init_block (&cond_block);
197 gfc_conv_descriptor_data_set (&cond_block, decl, null_pointer_node);
198 else_b = gfc_finish_block (&cond_block);
200 cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
201 fold_convert (pvoid_type_node,
202 gfc_conv_descriptor_data_get (outer)),
204 gfc_add_expr_to_block (&block, build3_loc (input_location, COND_EXPR,
205 void_type_node, cond, then_b, else_b));
207 return gfc_finish_block (&block);
210 /* Build and return code for a copy constructor from SRC to DEST. */
213 gfc_omp_clause_copy_ctor (tree clause, tree dest, tree src)
215 tree type = TREE_TYPE (dest), ptr, size, esize, rank, call;
216 tree cond, then_b, else_b;
217 stmtblock_t block, cond_block;
219 if (! GFC_DESCRIPTOR_TYPE_P (type)
220 || GFC_TYPE_ARRAY_AKIND (type) != GFC_ARRAY_ALLOCATABLE)
221 return build2_v (MODIFY_EXPR, dest, src);
223 gcc_assert (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_FIRSTPRIVATE);
225 /* Allocatable arrays in FIRSTPRIVATE clauses need to be allocated
226 and copied from SRC. */
227 gfc_start_block (&block);
229 gfc_init_block (&cond_block);
231 gfc_add_modify (&cond_block, dest, src);
232 rank = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (type) - 1];
233 size = gfc_conv_descriptor_ubound_get (dest, rank);
234 size = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
235 size, gfc_conv_descriptor_lbound_get (dest, rank));
236 size = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
237 size, gfc_index_one_node);
238 if (GFC_TYPE_ARRAY_RANK (type) > 1)
239 size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
240 size, gfc_conv_descriptor_stride_get (dest, rank));
241 esize = fold_convert (gfc_array_index_type,
242 TYPE_SIZE_UNIT (gfc_get_element_type (type)));
243 size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
245 size = gfc_evaluate_now (fold_convert (size_type_node, size), &cond_block);
247 ptr = gfc_create_var (pvoid_type_node, NULL);
248 gfc_allocate_using_malloc (&cond_block, ptr, size, NULL_TREE);
249 gfc_conv_descriptor_data_set (&cond_block, dest, ptr);
251 call = build_call_expr_loc (input_location,
252 builtin_decl_explicit (BUILT_IN_MEMCPY),
254 fold_convert (pvoid_type_node,
255 gfc_conv_descriptor_data_get (src)),
257 gfc_add_expr_to_block (&cond_block, fold_convert (void_type_node, call));
258 then_b = gfc_finish_block (&cond_block);
260 gfc_init_block (&cond_block);
261 gfc_conv_descriptor_data_set (&cond_block, dest, null_pointer_node);
262 else_b = gfc_finish_block (&cond_block);
264 cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
265 fold_convert (pvoid_type_node,
266 gfc_conv_descriptor_data_get (src)),
268 gfc_add_expr_to_block (&block, build3_loc (input_location, COND_EXPR,
269 void_type_node, cond, then_b, else_b));
271 return gfc_finish_block (&block);
274 /* Similarly, except use an assignment operator instead. */
277 gfc_omp_clause_assign_op (tree clause ATTRIBUTE_UNUSED, tree dest, tree src)
279 tree type = TREE_TYPE (dest), rank, size, esize, call;
282 if (! GFC_DESCRIPTOR_TYPE_P (type)
283 || GFC_TYPE_ARRAY_AKIND (type) != GFC_ARRAY_ALLOCATABLE)
284 return build2_v (MODIFY_EXPR, dest, src);
286 /* Handle copying allocatable arrays. */
287 gfc_start_block (&block);
289 rank = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (type) - 1];
290 size = gfc_conv_descriptor_ubound_get (dest, rank);
291 size = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
292 size, gfc_conv_descriptor_lbound_get (dest, rank));
293 size = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
294 size, gfc_index_one_node);
295 if (GFC_TYPE_ARRAY_RANK (type) > 1)
296 size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
297 size, gfc_conv_descriptor_stride_get (dest, rank));
298 esize = fold_convert (gfc_array_index_type,
299 TYPE_SIZE_UNIT (gfc_get_element_type (type)));
300 size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
302 size = gfc_evaluate_now (fold_convert (size_type_node, size), &block);
303 call = build_call_expr_loc (input_location,
304 builtin_decl_explicit (BUILT_IN_MEMCPY), 3,
305 fold_convert (pvoid_type_node,
306 gfc_conv_descriptor_data_get (dest)),
307 fold_convert (pvoid_type_node,
308 gfc_conv_descriptor_data_get (src)),
310 gfc_add_expr_to_block (&block, fold_convert (void_type_node, call));
312 return gfc_finish_block (&block);
315 /* Build and return code destructing DECL. Return NULL if nothing
319 gfc_omp_clause_dtor (tree clause ATTRIBUTE_UNUSED, tree decl)
321 tree type = TREE_TYPE (decl);
323 if (! GFC_DESCRIPTOR_TYPE_P (type)
324 || GFC_TYPE_ARRAY_AKIND (type) != GFC_ARRAY_ALLOCATABLE)
327 /* Allocatable arrays in FIRSTPRIVATE/LASTPRIVATE etc. clauses need
328 to be deallocated if they were allocated. */
329 return gfc_trans_dealloc_allocated (decl, false);
333 /* Return true if DECL's DECL_VALUE_EXPR (if any) should be
334 disregarded in OpenMP construct, because it is going to be
335 remapped during OpenMP lowering. SHARED is true if DECL
336 is going to be shared, false if it is going to be privatized. */
339 gfc_omp_disregard_value_expr (tree decl, bool shared)
341 if (GFC_DECL_COMMON_OR_EQUIV (decl)
342 && DECL_HAS_VALUE_EXPR_P (decl))
344 tree value = DECL_VALUE_EXPR (decl);
346 if (TREE_CODE (value) == COMPONENT_REF
347 && TREE_CODE (TREE_OPERAND (value, 0)) == VAR_DECL
348 && GFC_DECL_COMMON_OR_EQUIV (TREE_OPERAND (value, 0)))
350 /* If variable in COMMON or EQUIVALENCE is privatized, return
351 true, as just that variable is supposed to be privatized,
352 not the whole COMMON or whole EQUIVALENCE.
353 For shared variables in COMMON or EQUIVALENCE, let them be
354 gimplified to DECL_VALUE_EXPR, so that for multiple shared vars
355 from the same COMMON or EQUIVALENCE just one sharing of the
356 whole COMMON or EQUIVALENCE is enough. */
361 if (GFC_DECL_RESULT (decl) && DECL_HAS_VALUE_EXPR_P (decl))
367 /* Return true if DECL that is shared iff SHARED is true should
368 be put into OMP_CLAUSE_PRIVATE with OMP_CLAUSE_PRIVATE_DEBUG
372 gfc_omp_private_debug_clause (tree decl, bool shared)
374 if (GFC_DECL_CRAY_POINTEE (decl))
377 if (GFC_DECL_COMMON_OR_EQUIV (decl)
378 && DECL_HAS_VALUE_EXPR_P (decl))
380 tree value = DECL_VALUE_EXPR (decl);
382 if (TREE_CODE (value) == COMPONENT_REF
383 && TREE_CODE (TREE_OPERAND (value, 0)) == VAR_DECL
384 && GFC_DECL_COMMON_OR_EQUIV (TREE_OPERAND (value, 0)))
391 /* Register language specific type size variables as potentially OpenMP
392 firstprivate variables. */
395 gfc_omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *ctx, tree type)
397 if (GFC_ARRAY_TYPE_P (type) || GFC_DESCRIPTOR_TYPE_P (type))
401 gcc_assert (TYPE_LANG_SPECIFIC (type) != NULL);
402 for (r = 0; r < GFC_TYPE_ARRAY_RANK (type); r++)
404 omp_firstprivatize_variable (ctx, GFC_TYPE_ARRAY_LBOUND (type, r));
405 omp_firstprivatize_variable (ctx, GFC_TYPE_ARRAY_UBOUND (type, r));
406 omp_firstprivatize_variable (ctx, GFC_TYPE_ARRAY_STRIDE (type, r));
408 omp_firstprivatize_variable (ctx, GFC_TYPE_ARRAY_SIZE (type));
409 omp_firstprivatize_variable (ctx, GFC_TYPE_ARRAY_OFFSET (type));
415 gfc_trans_add_clause (tree node, tree tail)
417 OMP_CLAUSE_CHAIN (node) = tail;
422 gfc_trans_omp_variable (gfc_symbol *sym)
424 tree t = gfc_get_symbol_decl (sym);
428 bool alternate_entry;
431 return_value = sym->attr.function && sym->result == sym;
432 alternate_entry = sym->attr.function && sym->attr.entry
433 && sym->result == sym;
434 entry_master = sym->attr.result
435 && sym->ns->proc_name->attr.entry_master
436 && !gfc_return_by_reference (sym->ns->proc_name);
437 parent_decl = DECL_CONTEXT (current_function_decl);
439 if ((t == parent_decl && return_value)
440 || (sym->ns && sym->ns->proc_name
441 && sym->ns->proc_name->backend_decl == parent_decl
442 && (alternate_entry || entry_master)))
447 /* Special case for assigning the return value of a function.
448 Self recursive functions must have an explicit return value. */
449 if (return_value && (t == current_function_decl || parent_flag))
450 t = gfc_get_fake_result_decl (sym, parent_flag);
452 /* Similarly for alternate entry points. */
453 else if (alternate_entry
454 && (sym->ns->proc_name->backend_decl == current_function_decl
457 gfc_entry_list *el = NULL;
459 for (el = sym->ns->entries; el; el = el->next)
462 t = gfc_get_fake_result_decl (sym, parent_flag);
467 else if (entry_master
468 && (sym->ns->proc_name->backend_decl == current_function_decl
470 t = gfc_get_fake_result_decl (sym, parent_flag);
476 gfc_trans_omp_variable_list (enum omp_clause_code code, gfc_namelist *namelist,
479 for (; namelist != NULL; namelist = namelist->next)
480 if (namelist->sym->attr.referenced)
482 tree t = gfc_trans_omp_variable (namelist->sym);
483 if (t != error_mark_node)
485 tree node = build_omp_clause (input_location, code);
486 OMP_CLAUSE_DECL (node) = t;
487 list = gfc_trans_add_clause (node, list);
494 gfc_trans_omp_array_reduction (tree c, gfc_symbol *sym, locus where)
496 gfc_symtree *root1 = NULL, *root2 = NULL, *root3 = NULL, *root4 = NULL;
497 gfc_symtree *symtree1, *symtree2, *symtree3, *symtree4 = NULL;
498 gfc_symbol init_val_sym, outer_sym, intrinsic_sym;
499 gfc_expr *e1, *e2, *e3, *e4;
501 tree decl, backend_decl, stmt, type, outer_decl;
502 locus old_loc = gfc_current_locus;
506 decl = OMP_CLAUSE_DECL (c);
507 gfc_current_locus = where;
508 type = TREE_TYPE (decl);
509 outer_decl = create_tmp_var_raw (type, NULL);
510 if (TREE_CODE (decl) == PARM_DECL
511 && TREE_CODE (type) == REFERENCE_TYPE
512 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (type))
513 && GFC_TYPE_ARRAY_AKIND (TREE_TYPE (type)) == GFC_ARRAY_ALLOCATABLE)
515 decl = build_fold_indirect_ref (decl);
516 type = TREE_TYPE (type);
519 /* Create a fake symbol for init value. */
520 memset (&init_val_sym, 0, sizeof (init_val_sym));
521 init_val_sym.ns = sym->ns;
522 init_val_sym.name = sym->name;
523 init_val_sym.ts = sym->ts;
524 init_val_sym.attr.referenced = 1;
525 init_val_sym.declared_at = where;
526 init_val_sym.attr.flavor = FL_VARIABLE;
527 backend_decl = omp_reduction_init (c, gfc_sym_type (&init_val_sym));
528 init_val_sym.backend_decl = backend_decl;
530 /* Create a fake symbol for the outer array reference. */
532 outer_sym.as = gfc_copy_array_spec (sym->as);
533 outer_sym.attr.dummy = 0;
534 outer_sym.attr.result = 0;
535 outer_sym.attr.flavor = FL_VARIABLE;
536 outer_sym.backend_decl = outer_decl;
537 if (decl != OMP_CLAUSE_DECL (c))
538 outer_sym.backend_decl = build_fold_indirect_ref (outer_decl);
540 /* Create fake symtrees for it. */
541 symtree1 = gfc_new_symtree (&root1, sym->name);
542 symtree1->n.sym = sym;
543 gcc_assert (symtree1 == root1);
545 symtree2 = gfc_new_symtree (&root2, sym->name);
546 symtree2->n.sym = &init_val_sym;
547 gcc_assert (symtree2 == root2);
549 symtree3 = gfc_new_symtree (&root3, sym->name);
550 symtree3->n.sym = &outer_sym;
551 gcc_assert (symtree3 == root3);
553 /* Create expressions. */
554 e1 = gfc_get_expr ();
555 e1->expr_type = EXPR_VARIABLE;
557 e1->symtree = symtree1;
559 e1->ref = ref = gfc_get_ref ();
560 ref->type = REF_ARRAY;
561 ref->u.ar.where = where;
562 ref->u.ar.as = sym->as;
563 ref->u.ar.type = AR_FULL;
565 t = gfc_resolve_expr (e1);
566 gcc_assert (t == SUCCESS);
568 e2 = gfc_get_expr ();
569 e2->expr_type = EXPR_VARIABLE;
571 e2->symtree = symtree2;
573 t = gfc_resolve_expr (e2);
574 gcc_assert (t == SUCCESS);
576 e3 = gfc_copy_expr (e1);
577 e3->symtree = symtree3;
578 t = gfc_resolve_expr (e3);
579 gcc_assert (t == SUCCESS);
582 switch (OMP_CLAUSE_REDUCTION_CODE (c))
586 e4 = gfc_add (e3, e1);
589 e4 = gfc_multiply (e3, e1);
591 case TRUTH_ANDIF_EXPR:
592 e4 = gfc_and (e3, e1);
594 case TRUTH_ORIF_EXPR:
595 e4 = gfc_or (e3, e1);
598 e4 = gfc_eqv (e3, e1);
601 e4 = gfc_neqv (e3, e1);
623 memset (&intrinsic_sym, 0, sizeof (intrinsic_sym));
624 intrinsic_sym.ns = sym->ns;
625 intrinsic_sym.name = iname;
626 intrinsic_sym.ts = sym->ts;
627 intrinsic_sym.attr.referenced = 1;
628 intrinsic_sym.attr.intrinsic = 1;
629 intrinsic_sym.attr.function = 1;
630 intrinsic_sym.result = &intrinsic_sym;
631 intrinsic_sym.declared_at = where;
633 symtree4 = gfc_new_symtree (&root4, iname);
634 symtree4->n.sym = &intrinsic_sym;
635 gcc_assert (symtree4 == root4);
637 e4 = gfc_get_expr ();
638 e4->expr_type = EXPR_FUNCTION;
640 e4->symtree = symtree4;
641 e4->value.function.isym = gfc_find_function (iname);
642 e4->value.function.actual = gfc_get_actual_arglist ();
643 e4->value.function.actual->expr = e3;
644 e4->value.function.actual->next = gfc_get_actual_arglist ();
645 e4->value.function.actual->next->expr = e1;
647 /* e1 and e3 have been stored as arguments of e4, avoid sharing. */
648 e1 = gfc_copy_expr (e1);
649 e3 = gfc_copy_expr (e3);
650 t = gfc_resolve_expr (e4);
651 gcc_assert (t == SUCCESS);
653 /* Create the init statement list. */
655 if (GFC_DESCRIPTOR_TYPE_P (type)
656 && GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_ALLOCATABLE)
658 /* If decl is an allocatable array, it needs to be allocated
659 with the same bounds as the outer var. */
660 tree rank, size, esize, ptr;
663 gfc_start_block (&block);
665 gfc_add_modify (&block, decl, outer_sym.backend_decl);
666 rank = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (type) - 1];
667 size = gfc_conv_descriptor_ubound_get (decl, rank);
668 size = fold_build2_loc (input_location, MINUS_EXPR,
669 gfc_array_index_type, size,
670 gfc_conv_descriptor_lbound_get (decl, rank));
671 size = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
672 size, gfc_index_one_node);
673 if (GFC_TYPE_ARRAY_RANK (type) > 1)
674 size = fold_build2_loc (input_location, MULT_EXPR,
675 gfc_array_index_type, size,
676 gfc_conv_descriptor_stride_get (decl, rank));
677 esize = fold_convert (gfc_array_index_type,
678 TYPE_SIZE_UNIT (gfc_get_element_type (type)));
679 size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
681 size = gfc_evaluate_now (fold_convert (size_type_node, size), &block);
683 ptr = gfc_create_var (pvoid_type_node, NULL);
684 gfc_allocate_using_malloc (&block, ptr, size, NULL_TREE);
685 gfc_conv_descriptor_data_set (&block, decl, ptr);
687 gfc_add_expr_to_block (&block, gfc_trans_assignment (e1, e2, false,
689 stmt = gfc_finish_block (&block);
692 stmt = gfc_trans_assignment (e1, e2, false, false);
693 if (TREE_CODE (stmt) != BIND_EXPR)
694 stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0, 0));
697 OMP_CLAUSE_REDUCTION_INIT (c) = stmt;
699 /* Create the merge statement list. */
701 if (GFC_DESCRIPTOR_TYPE_P (type)
702 && GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_ALLOCATABLE)
704 /* If decl is an allocatable array, it needs to be deallocated
708 gfc_start_block (&block);
709 gfc_add_expr_to_block (&block, gfc_trans_assignment (e3, e4, false,
711 gfc_add_expr_to_block (&block, gfc_trans_dealloc_allocated (decl, false));
712 stmt = gfc_finish_block (&block);
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, 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;
735 gfc_free_array_spec (outer_sym.as);
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);
761 gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
764 tree omp_clauses = NULL_TREE, chunk_size, c;
766 enum omp_clause_code clause_code;
772 for (list = 0; list < OMP_LIST_NUM; list++)
774 gfc_namelist *n = clauses->lists[list];
778 if (list >= OMP_LIST_REDUCTION_FIRST
779 && list <= OMP_LIST_REDUCTION_LAST)
781 enum tree_code reduction_code;
785 reduction_code = PLUS_EXPR;
788 reduction_code = MULT_EXPR;
791 reduction_code = MINUS_EXPR;
794 reduction_code = TRUTH_ANDIF_EXPR;
797 reduction_code = TRUTH_ORIF_EXPR;
800 reduction_code = EQ_EXPR;
803 reduction_code = NE_EXPR;
806 reduction_code = MAX_EXPR;
809 reduction_code = MIN_EXPR;
812 reduction_code = BIT_AND_EXPR;
815 reduction_code = BIT_IOR_EXPR;
818 reduction_code = BIT_XOR_EXPR;
824 = gfc_trans_omp_reduction_list (n, omp_clauses, reduction_code,
830 case OMP_LIST_PRIVATE:
831 clause_code = OMP_CLAUSE_PRIVATE;
833 case OMP_LIST_SHARED:
834 clause_code = OMP_CLAUSE_SHARED;
836 case OMP_LIST_FIRSTPRIVATE:
837 clause_code = OMP_CLAUSE_FIRSTPRIVATE;
839 case OMP_LIST_LASTPRIVATE:
840 clause_code = OMP_CLAUSE_LASTPRIVATE;
842 case OMP_LIST_COPYIN:
843 clause_code = OMP_CLAUSE_COPYIN;
845 case OMP_LIST_COPYPRIVATE:
846 clause_code = OMP_CLAUSE_COPYPRIVATE;
850 = gfc_trans_omp_variable_list (clause_code, n, omp_clauses);
857 if (clauses->if_expr)
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)
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)
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;
921 case OMP_SCHED_DYNAMIC:
922 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_DYNAMIC;
924 case OMP_SCHED_GUIDED:
925 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_GUIDED;
927 case OMP_SCHED_RUNTIME:
928 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_RUNTIME;
931 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_AUTO;
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;
947 case OMP_DEFAULT_SHARED:
948 OMP_CLAUSE_DEFAULT_KIND (c) = OMP_CLAUSE_DEFAULT_SHARED;
950 case OMP_DEFAULT_PRIVATE:
951 OMP_CLAUSE_DEFAULT_KIND (c) = OMP_CLAUSE_DEFAULT_PRIVATE;
953 case OMP_DEFAULT_FIRSTPRIVATE:
954 OMP_CLAUSE_DEFAULT_KIND (c) = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
959 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
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);
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);
997 /* Like gfc_trans_code, but force creation of a BIND_EXPR around it. */
1000 gfc_trans_omp_code (gfc_code *code, bool force_empty)
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, 0);
1011 stmt = build3_v (BIND_EXPR, NULL, stmt, block);
1022 static tree gfc_trans_omp_sections (gfc_code *, gfc_omp_clauses *);
1023 static tree gfc_trans_omp_workshare (gfc_code *, gfc_omp_clauses *);
1026 gfc_trans_omp_atomic (gfc_code *code)
1028 gfc_code *atomic_code = code;
1032 gfc_expr *expr2, *e;
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);
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;
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)
1109 switch (expr2->value.op.op)
1111 case INTRINSIC_PLUS:
1114 case INTRINSIC_TIMES:
1117 case INTRINSIC_MINUS:
1120 case INTRINSIC_DIVIDE:
1121 if (expr2->ts.type == BT_INTEGER)
1122 op = TRUNC_DIV_EXPR;
1127 op = TRUTH_ANDIF_EXPR;
1130 op = TRUTH_ORIF_EXPR;
1135 case INTRINSIC_NEQV:
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;
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);
1169 gcc_assert (expr2->expr_type == EXPR_FUNCTION);
1170 switch (expr2->value.function.isym->id)
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;
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),
1211 gfc_add_modify (&block, accum, x);
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)
1227 x = convert (TREE_TYPE (rhs),
1228 build_fold_indirect_ref_loc (input_location, lhsaddr));
1230 x = fold_build2_loc (input_location, op, TREE_TYPE (rhs), x, rhs);
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);
1250 if (aop == OMP_ATOMIC_CAPTURE_NEW)
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);
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);
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 {
1296 DEF_VEC_O(dovar_init);
1297 DEF_VEC_ALLOC_O(dovar_init,heap);
1300 gfc_trans_omp_do (gfc_code *code, stmtblock_t *pblock,
1301 gfc_omp_clauses *do_clauses, tree par_clauses)
1304 tree dovar, stmt, from, to, step, type, init, cond, incr;
1305 tree count = NULL_TREE, cycle_label, tmp, omp_clauses;
1308 gfc_omp_clauses *clauses = code->ext.omp_clauses;
1309 int i, collapse = clauses->collapse;
1310 VEC(dovar_init,heap) *inits = NULL;
1317 code = code->block->next;
1318 gcc_assert (code->op == EXEC_DO);
1320 init = make_tree_vec (collapse);
1321 cond = make_tree_vec (collapse);
1322 incr = make_tree_vec (collapse);
1326 gfc_start_block (&block);
1330 omp_clauses = gfc_trans_omp_clauses (pblock, do_clauses, code->loc);
1332 for (i = 0; i < collapse; i++)
1335 int dovar_found = 0;
1341 for (n = clauses->lists[OMP_LIST_LASTPRIVATE]; n != NULL;
1343 if (code->ext.iterator->var->symtree->n.sym == n->sym)
1348 for (n = clauses->lists[OMP_LIST_PRIVATE]; n != NULL; n = n->next)
1349 if (code->ext.iterator->var->symtree->n.sym == n->sym)
1355 /* Evaluate all the expressions in the iterator. */
1356 gfc_init_se (&se, NULL);
1357 gfc_conv_expr_lhs (&se, code->ext.iterator->var);
1358 gfc_add_block_to_block (pblock, &se.pre);
1360 type = TREE_TYPE (dovar);
1361 gcc_assert (TREE_CODE (type) == INTEGER_TYPE);
1363 gfc_init_se (&se, NULL);
1364 gfc_conv_expr_val (&se, code->ext.iterator->start);
1365 gfc_add_block_to_block (pblock, &se.pre);
1366 from = gfc_evaluate_now (se.expr, pblock);
1368 gfc_init_se (&se, NULL);
1369 gfc_conv_expr_val (&se, code->ext.iterator->end);
1370 gfc_add_block_to_block (pblock, &se.pre);
1371 to = gfc_evaluate_now (se.expr, pblock);
1373 gfc_init_se (&se, NULL);
1374 gfc_conv_expr_val (&se, code->ext.iterator->step);
1375 gfc_add_block_to_block (pblock, &se.pre);
1376 step = gfc_evaluate_now (se.expr, pblock);
1379 /* Special case simple loops. */
1380 if (TREE_CODE (dovar) == VAR_DECL)
1382 if (integer_onep (step))
1384 else if (tree_int_cst_equal (step, integer_minus_one_node))
1389 = gfc_trans_omp_variable (code->ext.iterator->var->symtree->n.sym);
1394 TREE_VEC_ELT (init, i) = build2_v (MODIFY_EXPR, dovar, from);
1395 /* The condition should not be folded. */
1396 TREE_VEC_ELT (cond, i) = build2_loc (input_location, simple > 0
1397 ? LE_EXPR : GE_EXPR,
1398 boolean_type_node, dovar, to);
1399 TREE_VEC_ELT (incr, i) = fold_build2_loc (input_location, PLUS_EXPR,
1401 TREE_VEC_ELT (incr, i) = fold_build2_loc (input_location,
1404 TREE_VEC_ELT (incr, i));
1408 /* STEP is not 1 or -1. Use:
1409 for (count = 0; count < (to + step - from) / step; count++)
1411 dovar = from + count * step;
1415 tmp = fold_build2_loc (input_location, MINUS_EXPR, type, step, from);
1416 tmp = fold_build2_loc (input_location, PLUS_EXPR, type, to, tmp);
1417 tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR, type, tmp,
1419 tmp = gfc_evaluate_now (tmp, pblock);
1420 count = gfc_create_var (type, "count");
1421 TREE_VEC_ELT (init, i) = build2_v (MODIFY_EXPR, count,
1422 build_int_cst (type, 0));
1423 /* The condition should not be folded. */
1424 TREE_VEC_ELT (cond, i) = build2_loc (input_location, LT_EXPR,
1427 TREE_VEC_ELT (incr, i) = fold_build2_loc (input_location, PLUS_EXPR,
1429 build_int_cst (type, 1));
1430 TREE_VEC_ELT (incr, i) = fold_build2_loc (input_location,
1431 MODIFY_EXPR, type, count,
1432 TREE_VEC_ELT (incr, i));
1434 /* Initialize DOVAR. */
1435 tmp = fold_build2_loc (input_location, MULT_EXPR, type, count, step);
1436 tmp = fold_build2_loc (input_location, PLUS_EXPR, type, from, tmp);
1437 di = VEC_safe_push (dovar_init, heap, inits, NULL);
1444 tmp = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
1445 OMP_CLAUSE_DECL (tmp) = dovar_decl;
1446 omp_clauses = gfc_trans_add_clause (tmp, omp_clauses);
1448 else if (dovar_found == 2)
1455 /* If dovar is lastprivate, but different counter is used,
1456 dovar += step needs to be added to
1457 OMP_CLAUSE_LASTPRIVATE_STMT, otherwise the copied dovar
1458 will have the value on entry of the last loop, rather
1459 than value after iterator increment. */
1460 tmp = gfc_evaluate_now (step, pblock);
1461 tmp = fold_build2_loc (input_location, PLUS_EXPR, type, dovar,
1463 tmp = fold_build2_loc (input_location, MODIFY_EXPR, type,
1465 for (c = omp_clauses; c ; c = OMP_CLAUSE_CHAIN (c))
1466 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
1467 && OMP_CLAUSE_DECL (c) == dovar_decl)
1469 OMP_CLAUSE_LASTPRIVATE_STMT (c) = tmp;
1473 if (c == NULL && par_clauses != NULL)
1475 for (c = par_clauses; c ; c = OMP_CLAUSE_CHAIN (c))
1476 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
1477 && OMP_CLAUSE_DECL (c) == dovar_decl)
1479 tree l = build_omp_clause (input_location,
1480 OMP_CLAUSE_LASTPRIVATE);
1481 OMP_CLAUSE_DECL (l) = dovar_decl;
1482 OMP_CLAUSE_CHAIN (l) = omp_clauses;
1483 OMP_CLAUSE_LASTPRIVATE_STMT (l) = tmp;
1485 OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_SHARED);
1489 gcc_assert (simple || c != NULL);
1493 tmp = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
1494 OMP_CLAUSE_DECL (tmp) = count;
1495 omp_clauses = gfc_trans_add_clause (tmp, omp_clauses);
1498 if (i + 1 < collapse)
1499 code = code->block->next;
1502 if (pblock != &block)
1505 gfc_start_block (&block);
1508 gfc_start_block (&body);
1510 FOR_EACH_VEC_ELT (dovar_init, inits, ix, di)
1511 gfc_add_modify (&body, di->var, di->init);
1512 VEC_free (dovar_init, heap, inits);
1514 /* Cycle statement is implemented with a goto. Exit statement must not be
1515 present for this loop. */
1516 cycle_label = gfc_build_label_decl (NULL_TREE);
1518 /* Put these labels where they can be found later. */
1520 code->cycle_label = cycle_label;
1521 code->exit_label = NULL_TREE;
1523 /* Main loop body. */
1524 tmp = gfc_trans_omp_code (code->block->next, true);
1525 gfc_add_expr_to_block (&body, tmp);
1527 /* Label for cycle statements (if needed). */
1528 if (TREE_USED (cycle_label))
1530 tmp = build1_v (LABEL_EXPR, cycle_label);
1531 gfc_add_expr_to_block (&body, tmp);
1534 /* End of loop body. */
1535 stmt = make_node (OMP_FOR);
1537 TREE_TYPE (stmt) = void_type_node;
1538 OMP_FOR_BODY (stmt) = gfc_finish_block (&body);
1539 OMP_FOR_CLAUSES (stmt) = omp_clauses;
1540 OMP_FOR_INIT (stmt) = init;
1541 OMP_FOR_COND (stmt) = cond;
1542 OMP_FOR_INCR (stmt) = incr;
1543 gfc_add_expr_to_block (&block, stmt);
1545 return gfc_finish_block (&block);
1549 gfc_trans_omp_flush (void)
1551 tree decl = builtin_decl_explicit (BUILT_IN_SYNC_SYNCHRONIZE);
1552 return build_call_expr_loc (input_location, decl, 0);
1556 gfc_trans_omp_master (gfc_code *code)
1558 tree stmt = gfc_trans_code (code->block->next);
1559 if (IS_EMPTY_STMT (stmt))
1561 return build1_v (OMP_MASTER, stmt);
1565 gfc_trans_omp_ordered (gfc_code *code)
1567 return build1_v (OMP_ORDERED, gfc_trans_code (code->block->next));
1571 gfc_trans_omp_parallel (gfc_code *code)
1574 tree stmt, omp_clauses;
1576 gfc_start_block (&block);
1577 omp_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
1579 stmt = gfc_trans_omp_code (code->block->next, true);
1580 stmt = build2_loc (input_location, OMP_PARALLEL, void_type_node, stmt,
1582 gfc_add_expr_to_block (&block, stmt);
1583 return gfc_finish_block (&block);
1587 gfc_trans_omp_parallel_do (gfc_code *code)
1589 stmtblock_t block, *pblock = NULL;
1590 gfc_omp_clauses parallel_clauses, do_clauses;
1591 tree stmt, omp_clauses = NULL_TREE;
1593 gfc_start_block (&block);
1595 memset (&do_clauses, 0, sizeof (do_clauses));
1596 if (code->ext.omp_clauses != NULL)
1598 memcpy (¶llel_clauses, code->ext.omp_clauses,
1599 sizeof (parallel_clauses));
1600 do_clauses.sched_kind = parallel_clauses.sched_kind;
1601 do_clauses.chunk_size = parallel_clauses.chunk_size;
1602 do_clauses.ordered = parallel_clauses.ordered;
1603 do_clauses.collapse = parallel_clauses.collapse;
1604 parallel_clauses.sched_kind = OMP_SCHED_NONE;
1605 parallel_clauses.chunk_size = NULL;
1606 parallel_clauses.ordered = false;
1607 parallel_clauses.collapse = 0;
1608 omp_clauses = gfc_trans_omp_clauses (&block, ¶llel_clauses,
1611 do_clauses.nowait = true;
1612 if (!do_clauses.ordered && do_clauses.sched_kind != OMP_SCHED_STATIC)
1616 stmt = gfc_trans_omp_do (code, pblock, &do_clauses, omp_clauses);
1617 if (TREE_CODE (stmt) != BIND_EXPR)
1618 stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0, 0));
1621 stmt = build2_loc (input_location, OMP_PARALLEL, void_type_node, stmt,
1623 OMP_PARALLEL_COMBINED (stmt) = 1;
1624 gfc_add_expr_to_block (&block, stmt);
1625 return gfc_finish_block (&block);
1629 gfc_trans_omp_parallel_sections (gfc_code *code)
1632 gfc_omp_clauses section_clauses;
1633 tree stmt, omp_clauses;
1635 memset (§ion_clauses, 0, sizeof (section_clauses));
1636 section_clauses.nowait = true;
1638 gfc_start_block (&block);
1639 omp_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
1642 stmt = gfc_trans_omp_sections (code, §ion_clauses);
1643 if (TREE_CODE (stmt) != BIND_EXPR)
1644 stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0, 0));
1647 stmt = build2_loc (input_location, OMP_PARALLEL, void_type_node, stmt,
1649 OMP_PARALLEL_COMBINED (stmt) = 1;
1650 gfc_add_expr_to_block (&block, stmt);
1651 return gfc_finish_block (&block);
1655 gfc_trans_omp_parallel_workshare (gfc_code *code)
1658 gfc_omp_clauses workshare_clauses;
1659 tree stmt, omp_clauses;
1661 memset (&workshare_clauses, 0, sizeof (workshare_clauses));
1662 workshare_clauses.nowait = true;
1664 gfc_start_block (&block);
1665 omp_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
1668 stmt = gfc_trans_omp_workshare (code, &workshare_clauses);
1669 if (TREE_CODE (stmt) != BIND_EXPR)
1670 stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0, 0));
1673 stmt = build2_loc (input_location, OMP_PARALLEL, void_type_node, stmt,
1675 OMP_PARALLEL_COMBINED (stmt) = 1;
1676 gfc_add_expr_to_block (&block, stmt);
1677 return gfc_finish_block (&block);
1681 gfc_trans_omp_sections (gfc_code *code, gfc_omp_clauses *clauses)
1683 stmtblock_t block, body;
1684 tree omp_clauses, stmt;
1685 bool has_lastprivate = clauses->lists[OMP_LIST_LASTPRIVATE] != NULL;
1687 gfc_start_block (&block);
1689 omp_clauses = gfc_trans_omp_clauses (&block, clauses, code->loc);
1691 gfc_init_block (&body);
1692 for (code = code->block; code; code = code->block)
1694 /* Last section is special because of lastprivate, so even if it
1695 is empty, chain it in. */
1696 stmt = gfc_trans_omp_code (code->next,
1697 has_lastprivate && code->block == NULL);
1698 if (! IS_EMPTY_STMT (stmt))
1700 stmt = build1_v (OMP_SECTION, stmt);
1701 gfc_add_expr_to_block (&body, stmt);
1704 stmt = gfc_finish_block (&body);
1706 stmt = build2_loc (input_location, OMP_SECTIONS, void_type_node, stmt,
1708 gfc_add_expr_to_block (&block, stmt);
1710 return gfc_finish_block (&block);
1714 gfc_trans_omp_single (gfc_code *code, gfc_omp_clauses *clauses)
1716 tree omp_clauses = gfc_trans_omp_clauses (NULL, clauses, code->loc);
1717 tree stmt = gfc_trans_omp_code (code->block->next, true);
1718 stmt = build2_loc (input_location, OMP_SINGLE, void_type_node, stmt,
1724 gfc_trans_omp_task (gfc_code *code)
1727 tree stmt, omp_clauses;
1729 gfc_start_block (&block);
1730 omp_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
1732 stmt = gfc_trans_omp_code (code->block->next, true);
1733 stmt = build2_loc (input_location, OMP_TASK, void_type_node, stmt,
1735 gfc_add_expr_to_block (&block, stmt);
1736 return gfc_finish_block (&block);
1740 gfc_trans_omp_taskwait (void)
1742 tree decl = builtin_decl_explicit (BUILT_IN_GOMP_TASKWAIT);
1743 return build_call_expr_loc (input_location, decl, 0);
1747 gfc_trans_omp_taskyield (void)
1749 tree decl = builtin_decl_explicit (BUILT_IN_GOMP_TASKYIELD);
1750 return build_call_expr_loc (input_location, decl, 0);
1754 gfc_trans_omp_workshare (gfc_code *code, gfc_omp_clauses *clauses)
1756 tree res, tmp, stmt;
1757 stmtblock_t block, *pblock = NULL;
1758 stmtblock_t singleblock;
1759 int saved_ompws_flags;
1760 bool singleblock_in_progress = false;
1761 /* True if previous gfc_code in workshare construct is not workshared. */
1762 bool prev_singleunit;
1764 code = code->block->next;
1768 gfc_start_block (&block);
1771 ompws_flags = OMPWS_WORKSHARE_FLAG;
1772 prev_singleunit = false;
1774 /* Translate statements one by one to trees until we reach
1775 the end of the workshare construct. Adjacent gfc_codes that
1776 are a single unit of work are clustered and encapsulated in a
1777 single OMP_SINGLE construct. */
1778 for (; code; code = code->next)
1780 if (code->here != 0)
1782 res = gfc_trans_label_here (code);
1783 gfc_add_expr_to_block (pblock, res);
1786 /* No dependence analysis, use for clauses with wait.
1787 If this is the last gfc_code, use default omp_clauses. */
1788 if (code->next == NULL && clauses->nowait)
1789 ompws_flags |= OMPWS_NOWAIT;
1791 /* By default, every gfc_code is a single unit of work. */
1792 ompws_flags |= OMPWS_CURR_SINGLEUNIT;
1793 ompws_flags &= ~OMPWS_SCALARIZER_WS;
1802 res = gfc_trans_assign (code);
1805 case EXEC_POINTER_ASSIGN:
1806 res = gfc_trans_pointer_assign (code);
1809 case EXEC_INIT_ASSIGN:
1810 res = gfc_trans_init_assign (code);
1814 res = gfc_trans_forall (code);
1818 res = gfc_trans_where (code);
1821 case EXEC_OMP_ATOMIC:
1822 res = gfc_trans_omp_directive (code);
1825 case EXEC_OMP_PARALLEL:
1826 case EXEC_OMP_PARALLEL_DO:
1827 case EXEC_OMP_PARALLEL_SECTIONS:
1828 case EXEC_OMP_PARALLEL_WORKSHARE:
1829 case EXEC_OMP_CRITICAL:
1830 saved_ompws_flags = ompws_flags;
1832 res = gfc_trans_omp_directive (code);
1833 ompws_flags = saved_ompws_flags;
1837 internal_error ("gfc_trans_omp_workshare(): Bad statement code");
1840 gfc_set_backend_locus (&code->loc);
1842 if (res != NULL_TREE && ! IS_EMPTY_STMT (res))
1844 if (prev_singleunit)
1846 if (ompws_flags & OMPWS_CURR_SINGLEUNIT)
1847 /* Add current gfc_code to single block. */
1848 gfc_add_expr_to_block (&singleblock, res);
1851 /* Finish single block and add it to pblock. */
1852 tmp = gfc_finish_block (&singleblock);
1853 tmp = build2_loc (input_location, OMP_SINGLE,
1854 void_type_node, tmp, NULL_TREE);
1855 gfc_add_expr_to_block (pblock, tmp);
1856 /* Add current gfc_code to pblock. */
1857 gfc_add_expr_to_block (pblock, res);
1858 singleblock_in_progress = false;
1863 if (ompws_flags & OMPWS_CURR_SINGLEUNIT)
1865 /* Start single block. */
1866 gfc_init_block (&singleblock);
1867 gfc_add_expr_to_block (&singleblock, res);
1868 singleblock_in_progress = true;
1871 /* Add the new statement to the block. */
1872 gfc_add_expr_to_block (pblock, res);
1874 prev_singleunit = (ompws_flags & OMPWS_CURR_SINGLEUNIT) != 0;
1878 /* Finish remaining SINGLE block, if we were in the middle of one. */
1879 if (singleblock_in_progress)
1881 /* Finish single block and add it to pblock. */
1882 tmp = gfc_finish_block (&singleblock);
1883 tmp = build2_loc (input_location, OMP_SINGLE, void_type_node, tmp,
1885 ? build_omp_clause (input_location, OMP_CLAUSE_NOWAIT)
1887 gfc_add_expr_to_block (pblock, tmp);
1890 stmt = gfc_finish_block (pblock);
1891 if (TREE_CODE (stmt) != BIND_EXPR)
1893 if (!IS_EMPTY_STMT (stmt))
1895 tree bindblock = poplevel (1, 0, 0);
1896 stmt = build3_v (BIND_EXPR, NULL, stmt, bindblock);
1904 if (IS_EMPTY_STMT (stmt) && !clauses->nowait)
1905 stmt = gfc_trans_omp_barrier ();
1912 gfc_trans_omp_directive (gfc_code *code)
1916 case EXEC_OMP_ATOMIC:
1917 return gfc_trans_omp_atomic (code);
1918 case EXEC_OMP_BARRIER:
1919 return gfc_trans_omp_barrier ();
1920 case EXEC_OMP_CRITICAL:
1921 return gfc_trans_omp_critical (code);
1923 return gfc_trans_omp_do (code, NULL, code->ext.omp_clauses, NULL);
1924 case EXEC_OMP_FLUSH:
1925 return gfc_trans_omp_flush ();
1926 case EXEC_OMP_MASTER:
1927 return gfc_trans_omp_master (code);
1928 case EXEC_OMP_ORDERED:
1929 return gfc_trans_omp_ordered (code);
1930 case EXEC_OMP_PARALLEL:
1931 return gfc_trans_omp_parallel (code);
1932 case EXEC_OMP_PARALLEL_DO:
1933 return gfc_trans_omp_parallel_do (code);
1934 case EXEC_OMP_PARALLEL_SECTIONS:
1935 return gfc_trans_omp_parallel_sections (code);
1936 case EXEC_OMP_PARALLEL_WORKSHARE:
1937 return gfc_trans_omp_parallel_workshare (code);
1938 case EXEC_OMP_SECTIONS:
1939 return gfc_trans_omp_sections (code, code->ext.omp_clauses);
1940 case EXEC_OMP_SINGLE:
1941 return gfc_trans_omp_single (code, code->ext.omp_clauses);
1943 return gfc_trans_omp_task (code);
1944 case EXEC_OMP_TASKWAIT:
1945 return gfc_trans_omp_taskwait ();
1946 case EXEC_OMP_TASKYIELD:
1947 return gfc_trans_omp_taskyield ();
1948 case EXEC_OMP_WORKSHARE:
1949 return gfc_trans_omp_workshare (code, code->ext.omp_clauses);