1 /* OpenMP directive translation -- generate GCC trees from gfc_code.
2 Copyright (C) 2005, 2006, 2007, 2008, 2009 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
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
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/>. */
24 #include "coretypes.h"
32 #include "trans-stmt.h"
33 #include "trans-types.h"
34 #include "trans-array.h"
35 #include "trans-const.h"
40 /* True if OpenMP should privatize what this DECL points to rather
41 than the DECL itself. */
44 gfc_omp_privatize_by_reference (const_tree decl)
46 tree type = TREE_TYPE (decl);
48 if (TREE_CODE (type) == REFERENCE_TYPE
49 && (!DECL_ARTIFICIAL (decl) || TREE_CODE (decl) == PARM_DECL))
52 if (TREE_CODE (type) == POINTER_TYPE)
54 /* Array POINTER/ALLOCATABLE have aggregate types, all user variables
55 that have POINTER_TYPE type and don't have GFC_POINTER_TYPE_P
56 set are supposed to be privatized by reference. */
57 if (GFC_POINTER_TYPE_P (type))
60 if (!DECL_ARTIFICIAL (decl))
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) && ! GFC_DECL_RESULT (decl))
79 return OMP_CLAUSE_DEFAULT_SHARED;
81 /* Cray pointees shouldn't be listed in any clauses and should be
82 gimplified to dereference of the corresponding Cray pointer.
83 Make them all private, so that they are emitted in the debug
85 if (GFC_DECL_CRAY_POINTEE (decl))
86 return OMP_CLAUSE_DEFAULT_PRIVATE;
88 /* Assumed-size arrays are predetermined to inherit sharing
89 attributes of the associated actual argument, which is 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)
97 return OMP_CLAUSE_DEFAULT_SHARED;
99 /* COMMON and EQUIVALENCE decls are shared. They
100 are only referenced through DECL_VALUE_EXPR of the variables
101 contained in them. If those are privatized, they will not be
102 gimplified to the COMMON or EQUIVALENCE decls. */
103 if (GFC_DECL_COMMON_OR_EQUIV (decl) && ! DECL_HAS_VALUE_EXPR_P (decl))
104 return OMP_CLAUSE_DEFAULT_SHARED;
106 if (GFC_DECL_RESULT (decl) && ! DECL_HAS_VALUE_EXPR_P (decl))
107 return OMP_CLAUSE_DEFAULT_SHARED;
109 return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
113 /* Return true if DECL in private clause needs
114 OMP_CLAUSE_PRIVATE_OUTER_REF on the private clause. */
116 gfc_omp_private_outer_ref (tree decl)
118 tree type = TREE_TYPE (decl);
120 if (GFC_DESCRIPTOR_TYPE_P (type)
121 && GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_ALLOCATABLE)
127 /* Return code to initialize DECL with its default constructor, or
128 NULL if there's nothing to do. */
131 gfc_omp_clause_default_ctor (tree clause, tree decl, tree outer)
133 tree type = TREE_TYPE (decl), rank, size, esize, ptr, cond, then_b, else_b;
134 stmtblock_t block, cond_block;
136 if (! GFC_DESCRIPTOR_TYPE_P (type)
137 || GFC_TYPE_ARRAY_AKIND (type) != GFC_ARRAY_ALLOCATABLE)
140 gcc_assert (outer != NULL);
141 gcc_assert (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_PRIVATE
142 || OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_LASTPRIVATE);
144 /* Allocatable arrays in PRIVATE clauses need to be set to
145 "not currently allocated" allocation status if outer
146 array is "not currently allocated", otherwise should be allocated. */
147 gfc_start_block (&block);
149 gfc_init_block (&cond_block);
151 gfc_add_modify (&cond_block, decl, outer);
152 rank = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (type) - 1];
153 size = gfc_conv_descriptor_ubound_get (decl, rank);
154 size = fold_build2 (MINUS_EXPR, gfc_array_index_type, size,
155 gfc_conv_descriptor_lbound_get (decl, rank));
156 size = fold_build2 (PLUS_EXPR, gfc_array_index_type, size,
158 if (GFC_TYPE_ARRAY_RANK (type) > 1)
159 size = fold_build2 (MULT_EXPR, gfc_array_index_type, size,
160 gfc_conv_descriptor_stride_get (decl, rank));
161 esize = fold_convert (gfc_array_index_type,
162 TYPE_SIZE_UNIT (gfc_get_element_type (type)));
163 size = fold_build2 (MULT_EXPR, gfc_array_index_type, size, esize);
164 size = gfc_evaluate_now (fold_convert (size_type_node, size), &cond_block);
165 ptr = gfc_allocate_array_with_status (&cond_block,
166 build_int_cst (pvoid_type_node, 0),
168 gfc_conv_descriptor_data_set (&cond_block, decl, ptr);
169 then_b = gfc_finish_block (&cond_block);
171 gfc_init_block (&cond_block);
172 gfc_conv_descriptor_data_set (&cond_block, decl, null_pointer_node);
173 else_b = gfc_finish_block (&cond_block);
175 cond = fold_build2 (NE_EXPR, boolean_type_node,
176 fold_convert (pvoid_type_node,
177 gfc_conv_descriptor_data_get (outer)),
179 gfc_add_expr_to_block (&block, build3 (COND_EXPR, void_type_node,
180 cond, then_b, else_b));
182 return gfc_finish_block (&block);
185 /* Build and return code for a copy constructor from SRC to DEST. */
188 gfc_omp_clause_copy_ctor (tree clause, tree dest, tree src)
190 tree type = TREE_TYPE (dest), ptr, size, esize, rank, call;
193 if (! GFC_DESCRIPTOR_TYPE_P (type)
194 || GFC_TYPE_ARRAY_AKIND (type) != GFC_ARRAY_ALLOCATABLE)
195 return build2_v (MODIFY_EXPR, dest, src);
197 gcc_assert (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_FIRSTPRIVATE);
199 /* Allocatable arrays in FIRSTPRIVATE clauses need to be allocated
200 and copied from SRC. */
201 gfc_start_block (&block);
203 gfc_add_modify (&block, dest, src);
204 rank = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (type) - 1];
205 size = gfc_conv_descriptor_ubound_get (dest, rank);
206 size = fold_build2 (MINUS_EXPR, gfc_array_index_type, size,
207 gfc_conv_descriptor_lbound_get (dest, rank));
208 size = fold_build2 (PLUS_EXPR, gfc_array_index_type, size,
210 if (GFC_TYPE_ARRAY_RANK (type) > 1)
211 size = fold_build2 (MULT_EXPR, gfc_array_index_type, size,
212 gfc_conv_descriptor_stride_get (dest, rank));
213 esize = fold_convert (gfc_array_index_type,
214 TYPE_SIZE_UNIT (gfc_get_element_type (type)));
215 size = fold_build2 (MULT_EXPR, gfc_array_index_type, size, esize);
216 size = gfc_evaluate_now (fold_convert (size_type_node, size), &block);
217 ptr = gfc_allocate_array_with_status (&block,
218 build_int_cst (pvoid_type_node, 0),
220 gfc_conv_descriptor_data_set (&block, dest, ptr);
221 call = build_call_expr_loc (input_location,
222 built_in_decls[BUILT_IN_MEMCPY], 3, ptr,
223 fold_convert (pvoid_type_node,
224 gfc_conv_descriptor_data_get (src)),
226 gfc_add_expr_to_block (&block, fold_convert (void_type_node, call));
228 return gfc_finish_block (&block);
231 /* Similarly, except use an assignment operator instead. */
234 gfc_omp_clause_assign_op (tree clause ATTRIBUTE_UNUSED, tree dest, tree src)
236 tree type = TREE_TYPE (dest), rank, size, esize, call;
239 if (! GFC_DESCRIPTOR_TYPE_P (type)
240 || GFC_TYPE_ARRAY_AKIND (type) != GFC_ARRAY_ALLOCATABLE)
241 return build2_v (MODIFY_EXPR, dest, src);
243 /* Handle copying allocatable arrays. */
244 gfc_start_block (&block);
246 rank = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (type) - 1];
247 size = gfc_conv_descriptor_ubound_get (dest, rank);
248 size = fold_build2 (MINUS_EXPR, gfc_array_index_type, size,
249 gfc_conv_descriptor_lbound_get (dest, rank));
250 size = fold_build2 (PLUS_EXPR, gfc_array_index_type, size,
252 if (GFC_TYPE_ARRAY_RANK (type) > 1)
253 size = fold_build2 (MULT_EXPR, gfc_array_index_type, size,
254 gfc_conv_descriptor_stride_get (dest, rank));
255 esize = fold_convert (gfc_array_index_type,
256 TYPE_SIZE_UNIT (gfc_get_element_type (type)));
257 size = fold_build2 (MULT_EXPR, gfc_array_index_type, size, esize);
258 size = gfc_evaluate_now (fold_convert (size_type_node, size), &block);
259 call = build_call_expr_loc (input_location,
260 built_in_decls[BUILT_IN_MEMCPY], 3,
261 fold_convert (pvoid_type_node,
262 gfc_conv_descriptor_data_get (dest)),
263 fold_convert (pvoid_type_node,
264 gfc_conv_descriptor_data_get (src)),
266 gfc_add_expr_to_block (&block, fold_convert (void_type_node, call));
268 return gfc_finish_block (&block);
271 /* Build and return code destructing DECL. Return NULL if nothing
275 gfc_omp_clause_dtor (tree clause ATTRIBUTE_UNUSED, tree decl)
277 tree type = TREE_TYPE (decl);
279 if (! GFC_DESCRIPTOR_TYPE_P (type)
280 || GFC_TYPE_ARRAY_AKIND (type) != GFC_ARRAY_ALLOCATABLE)
283 /* Allocatable arrays in FIRSTPRIVATE/LASTPRIVATE etc. clauses need
284 to be deallocated if they were allocated. */
285 return gfc_trans_dealloc_allocated (decl);
289 /* Return true if DECL's DECL_VALUE_EXPR (if any) should be
290 disregarded in OpenMP construct, because it is going to be
291 remapped during OpenMP lowering. SHARED is true if DECL
292 is going to be shared, false if it is going to be privatized. */
295 gfc_omp_disregard_value_expr (tree decl, bool shared)
297 if (GFC_DECL_COMMON_OR_EQUIV (decl)
298 && DECL_HAS_VALUE_EXPR_P (decl))
300 tree value = DECL_VALUE_EXPR (decl);
302 if (TREE_CODE (value) == COMPONENT_REF
303 && TREE_CODE (TREE_OPERAND (value, 0)) == VAR_DECL
304 && GFC_DECL_COMMON_OR_EQUIV (TREE_OPERAND (value, 0)))
306 /* If variable in COMMON or EQUIVALENCE is privatized, return
307 true, as just that variable is supposed to be privatized,
308 not the whole COMMON or whole EQUIVALENCE.
309 For shared variables in COMMON or EQUIVALENCE, let them be
310 gimplified to DECL_VALUE_EXPR, so that for multiple shared vars
311 from the same COMMON or EQUIVALENCE just one sharing of the
312 whole COMMON or EQUIVALENCE is enough. */
317 if (GFC_DECL_RESULT (decl) && DECL_HAS_VALUE_EXPR_P (decl))
323 /* Return true if DECL that is shared iff SHARED is true should
324 be put into OMP_CLAUSE_PRIVATE with OMP_CLAUSE_PRIVATE_DEBUG
328 gfc_omp_private_debug_clause (tree decl, bool shared)
330 if (GFC_DECL_CRAY_POINTEE (decl))
333 if (GFC_DECL_COMMON_OR_EQUIV (decl)
334 && DECL_HAS_VALUE_EXPR_P (decl))
336 tree value = DECL_VALUE_EXPR (decl);
338 if (TREE_CODE (value) == COMPONENT_REF
339 && TREE_CODE (TREE_OPERAND (value, 0)) == VAR_DECL
340 && GFC_DECL_COMMON_OR_EQUIV (TREE_OPERAND (value, 0)))
347 /* Register language specific type size variables as potentially OpenMP
348 firstprivate variables. */
351 gfc_omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *ctx, tree type)
353 if (GFC_ARRAY_TYPE_P (type) || GFC_DESCRIPTOR_TYPE_P (type))
357 gcc_assert (TYPE_LANG_SPECIFIC (type) != NULL);
358 for (r = 0; r < GFC_TYPE_ARRAY_RANK (type); r++)
360 omp_firstprivatize_variable (ctx, GFC_TYPE_ARRAY_LBOUND (type, r));
361 omp_firstprivatize_variable (ctx, GFC_TYPE_ARRAY_UBOUND (type, r));
362 omp_firstprivatize_variable (ctx, GFC_TYPE_ARRAY_STRIDE (type, r));
364 omp_firstprivatize_variable (ctx, GFC_TYPE_ARRAY_SIZE (type));
365 omp_firstprivatize_variable (ctx, GFC_TYPE_ARRAY_OFFSET (type));
371 gfc_trans_add_clause (tree node, tree tail)
373 OMP_CLAUSE_CHAIN (node) = tail;
378 gfc_trans_omp_variable (gfc_symbol *sym)
380 tree t = gfc_get_symbol_decl (sym);
384 bool alternate_entry;
387 return_value = sym->attr.function && sym->result == sym;
388 alternate_entry = sym->attr.function && sym->attr.entry
389 && sym->result == sym;
390 entry_master = sym->attr.result
391 && sym->ns->proc_name->attr.entry_master
392 && !gfc_return_by_reference (sym->ns->proc_name);
393 parent_decl = DECL_CONTEXT (current_function_decl);
395 if ((t == parent_decl && return_value)
396 || (sym->ns && sym->ns->proc_name
397 && sym->ns->proc_name->backend_decl == parent_decl
398 && (alternate_entry || entry_master)))
403 /* Special case for assigning the return value of a function.
404 Self recursive functions must have an explicit return value. */
405 if (return_value && (t == current_function_decl || parent_flag))
406 t = gfc_get_fake_result_decl (sym, parent_flag);
408 /* Similarly for alternate entry points. */
409 else if (alternate_entry
410 && (sym->ns->proc_name->backend_decl == current_function_decl
413 gfc_entry_list *el = NULL;
415 for (el = sym->ns->entries; el; el = el->next)
418 t = gfc_get_fake_result_decl (sym, parent_flag);
423 else if (entry_master
424 && (sym->ns->proc_name->backend_decl == current_function_decl
426 t = gfc_get_fake_result_decl (sym, parent_flag);
432 gfc_trans_omp_variable_list (enum omp_clause_code code, gfc_namelist *namelist,
435 for (; namelist != NULL; namelist = namelist->next)
436 if (namelist->sym->attr.referenced)
438 tree t = gfc_trans_omp_variable (namelist->sym);
439 if (t != error_mark_node)
441 tree node = build_omp_clause (input_location, code);
442 OMP_CLAUSE_DECL (node) = t;
443 list = gfc_trans_add_clause (node, list);
450 gfc_trans_omp_array_reduction (tree c, gfc_symbol *sym, locus where)
452 gfc_symtree *root1 = NULL, *root2 = NULL, *root3 = NULL, *root4 = NULL;
453 gfc_symtree *symtree1, *symtree2, *symtree3, *symtree4 = NULL;
454 gfc_symbol init_val_sym, outer_sym, intrinsic_sym;
455 gfc_expr *e1, *e2, *e3, *e4;
457 tree decl, backend_decl, stmt;
458 locus old_loc = gfc_current_locus;
462 decl = OMP_CLAUSE_DECL (c);
463 gfc_current_locus = where;
465 /* Create a fake symbol for init value. */
466 memset (&init_val_sym, 0, sizeof (init_val_sym));
467 init_val_sym.ns = sym->ns;
468 init_val_sym.name = sym->name;
469 init_val_sym.ts = sym->ts;
470 init_val_sym.attr.referenced = 1;
471 init_val_sym.declared_at = where;
472 init_val_sym.attr.flavor = FL_VARIABLE;
473 backend_decl = omp_reduction_init (c, gfc_sym_type (&init_val_sym));
474 init_val_sym.backend_decl = backend_decl;
476 /* Create a fake symbol for the outer array reference. */
478 outer_sym.as = gfc_copy_array_spec (sym->as);
479 outer_sym.attr.dummy = 0;
480 outer_sym.attr.result = 0;
481 outer_sym.attr.flavor = FL_VARIABLE;
482 outer_sym.backend_decl = create_tmp_var_raw (TREE_TYPE (decl), NULL);
484 /* Create fake symtrees for it. */
485 symtree1 = gfc_new_symtree (&root1, sym->name);
486 symtree1->n.sym = sym;
487 gcc_assert (symtree1 == root1);
489 symtree2 = gfc_new_symtree (&root2, sym->name);
490 symtree2->n.sym = &init_val_sym;
491 gcc_assert (symtree2 == root2);
493 symtree3 = gfc_new_symtree (&root3, sym->name);
494 symtree3->n.sym = &outer_sym;
495 gcc_assert (symtree3 == root3);
497 /* Create expressions. */
498 e1 = gfc_get_expr ();
499 e1->expr_type = EXPR_VARIABLE;
501 e1->symtree = symtree1;
503 e1->ref = ref = gfc_get_ref ();
504 ref->type = REF_ARRAY;
505 ref->u.ar.where = where;
506 ref->u.ar.as = sym->as;
507 ref->u.ar.type = AR_FULL;
509 t = gfc_resolve_expr (e1);
510 gcc_assert (t == SUCCESS);
512 e2 = gfc_get_expr ();
513 e2->expr_type = EXPR_VARIABLE;
515 e2->symtree = symtree2;
517 t = gfc_resolve_expr (e2);
518 gcc_assert (t == SUCCESS);
520 e3 = gfc_copy_expr (e1);
521 e3->symtree = symtree3;
522 t = gfc_resolve_expr (e3);
523 gcc_assert (t == SUCCESS);
526 switch (OMP_CLAUSE_REDUCTION_CODE (c))
530 e4 = gfc_add (e3, e1);
533 e4 = gfc_multiply (e3, e1);
535 case TRUTH_ANDIF_EXPR:
536 e4 = gfc_and (e3, e1);
538 case TRUTH_ORIF_EXPR:
539 e4 = gfc_or (e3, e1);
542 e4 = gfc_eqv (e3, e1);
545 e4 = gfc_neqv (e3, e1);
567 memset (&intrinsic_sym, 0, sizeof (intrinsic_sym));
568 intrinsic_sym.ns = sym->ns;
569 intrinsic_sym.name = iname;
570 intrinsic_sym.ts = sym->ts;
571 intrinsic_sym.attr.referenced = 1;
572 intrinsic_sym.attr.intrinsic = 1;
573 intrinsic_sym.attr.function = 1;
574 intrinsic_sym.result = &intrinsic_sym;
575 intrinsic_sym.declared_at = where;
577 symtree4 = gfc_new_symtree (&root4, iname);
578 symtree4->n.sym = &intrinsic_sym;
579 gcc_assert (symtree4 == root4);
581 e4 = gfc_get_expr ();
582 e4->expr_type = EXPR_FUNCTION;
584 e4->symtree = symtree4;
585 e4->value.function.isym = gfc_find_function (iname);
586 e4->value.function.actual = gfc_get_actual_arglist ();
587 e4->value.function.actual->expr = e3;
588 e4->value.function.actual->next = gfc_get_actual_arglist ();
589 e4->value.function.actual->next->expr = e1;
591 /* e1 and e3 have been stored as arguments of e4, avoid sharing. */
592 e1 = gfc_copy_expr (e1);
593 e3 = gfc_copy_expr (e3);
594 t = gfc_resolve_expr (e4);
595 gcc_assert (t == SUCCESS);
597 /* Create the init statement list. */
599 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl))
600 && GFC_TYPE_ARRAY_AKIND (TREE_TYPE (decl)) == GFC_ARRAY_ALLOCATABLE)
602 /* If decl is an allocatable array, it needs to be allocated
603 with the same bounds as the outer var. */
604 tree type = TREE_TYPE (decl), rank, size, esize, ptr;
607 gfc_start_block (&block);
609 gfc_add_modify (&block, decl, outer_sym.backend_decl);
610 rank = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (type) - 1];
611 size = gfc_conv_descriptor_ubound_get (decl, rank);
612 size = fold_build2 (MINUS_EXPR, gfc_array_index_type, size,
613 gfc_conv_descriptor_lbound_get (decl, rank));
614 size = fold_build2 (PLUS_EXPR, gfc_array_index_type, size,
616 if (GFC_TYPE_ARRAY_RANK (type) > 1)
617 size = fold_build2 (MULT_EXPR, gfc_array_index_type, size,
618 gfc_conv_descriptor_stride_get (decl, rank));
619 esize = fold_convert (gfc_array_index_type,
620 TYPE_SIZE_UNIT (gfc_get_element_type (type)));
621 size = fold_build2 (MULT_EXPR, gfc_array_index_type, size, esize);
622 size = gfc_evaluate_now (fold_convert (size_type_node, size), &block);
623 ptr = gfc_allocate_array_with_status (&block,
624 build_int_cst (pvoid_type_node, 0),
626 gfc_conv_descriptor_data_set (&block, decl, ptr);
627 gfc_add_expr_to_block (&block, gfc_trans_assignment (e1, e2, false));
628 stmt = gfc_finish_block (&block);
631 stmt = gfc_trans_assignment (e1, e2, false);
632 if (TREE_CODE (stmt) != BIND_EXPR)
633 stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0, 0));
636 OMP_CLAUSE_REDUCTION_INIT (c) = stmt;
638 /* Create the merge statement list. */
640 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl))
641 && GFC_TYPE_ARRAY_AKIND (TREE_TYPE (decl)) == GFC_ARRAY_ALLOCATABLE)
643 /* If decl is an allocatable array, it needs to be deallocated
647 gfc_start_block (&block);
648 gfc_add_expr_to_block (&block, gfc_trans_assignment (e3, e4, false));
649 gfc_add_expr_to_block (&block, gfc_trans_dealloc_allocated (decl));
650 stmt = gfc_finish_block (&block);
653 stmt = gfc_trans_assignment (e3, e4, false);
654 if (TREE_CODE (stmt) != BIND_EXPR)
655 stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0, 0));
658 OMP_CLAUSE_REDUCTION_MERGE (c) = stmt;
660 /* And stick the placeholder VAR_DECL into the clause as well. */
661 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = outer_sym.backend_decl;
663 gfc_current_locus = old_loc;
674 gfc_free_array_spec (outer_sym.as);
678 gfc_trans_omp_reduction_list (gfc_namelist *namelist, tree list,
679 enum tree_code reduction_code, locus where)
681 for (; namelist != NULL; namelist = namelist->next)
682 if (namelist->sym->attr.referenced)
684 tree t = gfc_trans_omp_variable (namelist->sym);
685 if (t != error_mark_node)
687 tree node = build_omp_clause (where.lb->location,
688 OMP_CLAUSE_REDUCTION);
689 OMP_CLAUSE_DECL (node) = t;
690 OMP_CLAUSE_REDUCTION_CODE (node) = reduction_code;
691 if (namelist->sym->attr.dimension)
692 gfc_trans_omp_array_reduction (node, namelist->sym, where);
693 list = gfc_trans_add_clause (node, list);
700 gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
703 tree omp_clauses = NULL_TREE, chunk_size, c, old_clauses;
705 enum omp_clause_code clause_code;
711 for (list = 0; list < OMP_LIST_NUM; list++)
713 gfc_namelist *n = clauses->lists[list];
717 if (list >= OMP_LIST_REDUCTION_FIRST
718 && list <= OMP_LIST_REDUCTION_LAST)
720 enum tree_code reduction_code;
724 reduction_code = PLUS_EXPR;
727 reduction_code = MULT_EXPR;
730 reduction_code = MINUS_EXPR;
733 reduction_code = TRUTH_ANDIF_EXPR;
736 reduction_code = TRUTH_ORIF_EXPR;
739 reduction_code = EQ_EXPR;
742 reduction_code = NE_EXPR;
745 reduction_code = MAX_EXPR;
748 reduction_code = MIN_EXPR;
751 reduction_code = BIT_AND_EXPR;
754 reduction_code = BIT_IOR_EXPR;
757 reduction_code = BIT_XOR_EXPR;
762 old_clauses = omp_clauses;
764 = gfc_trans_omp_reduction_list (n, omp_clauses, reduction_code,
770 case OMP_LIST_PRIVATE:
771 clause_code = OMP_CLAUSE_PRIVATE;
773 case OMP_LIST_SHARED:
774 clause_code = OMP_CLAUSE_SHARED;
776 case OMP_LIST_FIRSTPRIVATE:
777 clause_code = OMP_CLAUSE_FIRSTPRIVATE;
779 case OMP_LIST_LASTPRIVATE:
780 clause_code = OMP_CLAUSE_LASTPRIVATE;
782 case OMP_LIST_COPYIN:
783 clause_code = OMP_CLAUSE_COPYIN;
785 case OMP_LIST_COPYPRIVATE:
786 clause_code = OMP_CLAUSE_COPYPRIVATE;
790 = gfc_trans_omp_variable_list (clause_code, n, omp_clauses);
797 if (clauses->if_expr)
801 gfc_init_se (&se, NULL);
802 gfc_conv_expr (&se, clauses->if_expr);
803 gfc_add_block_to_block (block, &se.pre);
804 if_var = gfc_evaluate_now (se.expr, block);
805 gfc_add_block_to_block (block, &se.post);
807 c = build_omp_clause (where.lb->location, OMP_CLAUSE_IF);
808 OMP_CLAUSE_IF_EXPR (c) = if_var;
809 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
812 if (clauses->num_threads)
816 gfc_init_se (&se, NULL);
817 gfc_conv_expr (&se, clauses->num_threads);
818 gfc_add_block_to_block (block, &se.pre);
819 num_threads = gfc_evaluate_now (se.expr, block);
820 gfc_add_block_to_block (block, &se.post);
822 c = build_omp_clause (where.lb->location, OMP_CLAUSE_NUM_THREADS);
823 OMP_CLAUSE_NUM_THREADS_EXPR (c) = num_threads;
824 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
827 chunk_size = NULL_TREE;
828 if (clauses->chunk_size)
830 gfc_init_se (&se, NULL);
831 gfc_conv_expr (&se, clauses->chunk_size);
832 gfc_add_block_to_block (block, &se.pre);
833 chunk_size = gfc_evaluate_now (se.expr, block);
834 gfc_add_block_to_block (block, &se.post);
837 if (clauses->sched_kind != OMP_SCHED_NONE)
839 c = build_omp_clause (where.lb->location, OMP_CLAUSE_SCHEDULE);
840 OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = chunk_size;
841 switch (clauses->sched_kind)
843 case OMP_SCHED_STATIC:
844 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_STATIC;
846 case OMP_SCHED_DYNAMIC:
847 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_DYNAMIC;
849 case OMP_SCHED_GUIDED:
850 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_GUIDED;
852 case OMP_SCHED_RUNTIME:
853 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_RUNTIME;
856 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_AUTO;
861 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
864 if (clauses->default_sharing != OMP_DEFAULT_UNKNOWN)
866 c = build_omp_clause (where.lb->location, OMP_CLAUSE_DEFAULT);
867 switch (clauses->default_sharing)
869 case OMP_DEFAULT_NONE:
870 OMP_CLAUSE_DEFAULT_KIND (c) = OMP_CLAUSE_DEFAULT_NONE;
872 case OMP_DEFAULT_SHARED:
873 OMP_CLAUSE_DEFAULT_KIND (c) = OMP_CLAUSE_DEFAULT_SHARED;
875 case OMP_DEFAULT_PRIVATE:
876 OMP_CLAUSE_DEFAULT_KIND (c) = OMP_CLAUSE_DEFAULT_PRIVATE;
878 case OMP_DEFAULT_FIRSTPRIVATE:
879 OMP_CLAUSE_DEFAULT_KIND (c) = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
884 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
889 c = build_omp_clause (where.lb->location, OMP_CLAUSE_NOWAIT);
890 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
893 if (clauses->ordered)
895 c = build_omp_clause (where.lb->location, OMP_CLAUSE_ORDERED);
896 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
901 c = build_omp_clause (where.lb->location, OMP_CLAUSE_UNTIED);
902 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
905 if (clauses->collapse)
907 c = build_omp_clause (where.lb->location, OMP_CLAUSE_COLLAPSE);
908 OMP_CLAUSE_COLLAPSE_EXPR (c) = build_int_cst (NULL, clauses->collapse);
909 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
915 /* Like gfc_trans_code, but force creation of a BIND_EXPR around it. */
918 gfc_trans_omp_code (gfc_code *code, bool force_empty)
923 stmt = gfc_trans_code (code);
924 if (TREE_CODE (stmt) != BIND_EXPR)
926 if (!IS_EMPTY_STMT (stmt) || force_empty)
928 tree block = poplevel (1, 0, 0);
929 stmt = build3_v (BIND_EXPR, NULL, stmt, block);
940 static tree gfc_trans_omp_sections (gfc_code *, gfc_omp_clauses *);
941 static tree gfc_trans_omp_workshare (gfc_code *, gfc_omp_clauses *);
944 gfc_trans_omp_atomic (gfc_code *code)
951 tree lhsaddr, type, rhs, x;
952 enum tree_code op = ERROR_MARK;
953 bool var_on_left = false;
955 code = code->block->next;
956 gcc_assert (code->op == EXEC_ASSIGN);
957 gcc_assert (code->next == NULL);
958 var = code->expr1->symtree->n.sym;
960 gfc_init_se (&lse, NULL);
961 gfc_init_se (&rse, NULL);
962 gfc_start_block (&block);
964 gfc_conv_expr (&lse, code->expr1);
965 gfc_add_block_to_block (&block, &lse.pre);
966 type = TREE_TYPE (lse.expr);
967 lhsaddr = gfc_build_addr_expr (NULL, lse.expr);
970 if (expr2->expr_type == EXPR_FUNCTION
971 && expr2->value.function.isym->id == GFC_ISYM_CONVERSION)
972 expr2 = expr2->value.function.actual->expr;
974 if (expr2->expr_type == EXPR_OP)
977 switch (expr2->value.op.op)
982 case INTRINSIC_TIMES:
985 case INTRINSIC_MINUS:
988 case INTRINSIC_DIVIDE:
989 if (expr2->ts.type == BT_INTEGER)
995 op = TRUTH_ANDIF_EXPR;
998 op = TRUTH_ORIF_EXPR;
1003 case INTRINSIC_NEQV:
1009 e = expr2->value.op.op1;
1010 if (e->expr_type == EXPR_FUNCTION
1011 && e->value.function.isym->id == GFC_ISYM_CONVERSION)
1012 e = e->value.function.actual->expr;
1013 if (e->expr_type == EXPR_VARIABLE
1014 && e->symtree != NULL
1015 && e->symtree->n.sym == var)
1017 expr2 = expr2->value.op.op2;
1022 e = expr2->value.op.op2;
1023 if (e->expr_type == EXPR_FUNCTION
1024 && e->value.function.isym->id == GFC_ISYM_CONVERSION)
1025 e = e->value.function.actual->expr;
1026 gcc_assert (e->expr_type == EXPR_VARIABLE
1027 && e->symtree != NULL
1028 && e->symtree->n.sym == var);
1029 expr2 = expr2->value.op.op1;
1030 var_on_left = false;
1032 gfc_conv_expr (&rse, expr2);
1033 gfc_add_block_to_block (&block, &rse.pre);
1037 gcc_assert (expr2->expr_type == EXPR_FUNCTION);
1038 switch (expr2->value.function.isym->id)
1058 e = expr2->value.function.actual->expr;
1059 gcc_assert (e->expr_type == EXPR_VARIABLE
1060 && e->symtree != NULL
1061 && e->symtree->n.sym == var);
1063 gfc_conv_expr (&rse, expr2->value.function.actual->next->expr);
1064 gfc_add_block_to_block (&block, &rse.pre);
1065 if (expr2->value.function.actual->next->next != NULL)
1067 tree accum = gfc_create_var (TREE_TYPE (rse.expr), NULL);
1068 gfc_actual_arglist *arg;
1070 gfc_add_modify (&block, accum, rse.expr);
1071 for (arg = expr2->value.function.actual->next->next; arg;
1074 gfc_init_block (&rse.pre);
1075 gfc_conv_expr (&rse, arg->expr);
1076 gfc_add_block_to_block (&block, &rse.pre);
1077 x = fold_build2 (op, TREE_TYPE (accum), accum, rse.expr);
1078 gfc_add_modify (&block, accum, x);
1084 expr2 = expr2->value.function.actual->next->expr;
1087 lhsaddr = save_expr (lhsaddr);
1088 rhs = gfc_evaluate_now (rse.expr, &block);
1089 x = convert (TREE_TYPE (rhs), build_fold_indirect_ref_loc (input_location,
1093 x = fold_build2 (op, TREE_TYPE (rhs), x, rhs);
1095 x = fold_build2 (op, TREE_TYPE (rhs), rhs, x);
1097 if (TREE_CODE (TREE_TYPE (rhs)) == COMPLEX_TYPE
1098 && TREE_CODE (type) != COMPLEX_TYPE)
1099 x = fold_build1 (REALPART_EXPR, TREE_TYPE (TREE_TYPE (rhs)), x);
1101 x = build2_v (OMP_ATOMIC, lhsaddr, convert (type, x));
1102 gfc_add_expr_to_block (&block, x);
1104 gfc_add_block_to_block (&block, &lse.pre);
1105 gfc_add_block_to_block (&block, &rse.pre);
1107 return gfc_finish_block (&block);
1111 gfc_trans_omp_barrier (void)
1113 tree decl = built_in_decls [BUILT_IN_GOMP_BARRIER];
1114 return build_call_expr_loc (input_location, decl, 0);
1118 gfc_trans_omp_critical (gfc_code *code)
1120 tree name = NULL_TREE, stmt;
1121 if (code->ext.omp_name != NULL)
1122 name = get_identifier (code->ext.omp_name);
1123 stmt = gfc_trans_code (code->block->next);
1124 return build2 (OMP_CRITICAL, void_type_node, stmt, name);
1128 gfc_trans_omp_do (gfc_code *code, stmtblock_t *pblock,
1129 gfc_omp_clauses *do_clauses, tree par_clauses)
1132 tree dovar, stmt, from, to, step, type, init, cond, incr;
1133 tree count = NULL_TREE, cycle_label, tmp, omp_clauses;
1136 gfc_omp_clauses *clauses = code->ext.omp_clauses;
1137 gfc_code *outermost;
1138 int i, collapse = clauses->collapse;
1139 tree dovar_init = NULL_TREE;
1144 outermost = code = code->block->next;
1145 gcc_assert (code->op == EXEC_DO);
1147 init = make_tree_vec (collapse);
1148 cond = make_tree_vec (collapse);
1149 incr = make_tree_vec (collapse);
1153 gfc_start_block (&block);
1157 omp_clauses = gfc_trans_omp_clauses (pblock, do_clauses, code->loc);
1159 for (i = 0; i < collapse; i++)
1162 int dovar_found = 0;
1167 for (n = clauses->lists[OMP_LIST_LASTPRIVATE]; n != NULL;
1169 if (code->ext.iterator->var->symtree->n.sym == n->sym)
1174 for (n = clauses->lists[OMP_LIST_PRIVATE]; n != NULL; n = n->next)
1175 if (code->ext.iterator->var->symtree->n.sym == n->sym)
1181 /* Evaluate all the expressions in the iterator. */
1182 gfc_init_se (&se, NULL);
1183 gfc_conv_expr_lhs (&se, code->ext.iterator->var);
1184 gfc_add_block_to_block (pblock, &se.pre);
1186 type = TREE_TYPE (dovar);
1187 gcc_assert (TREE_CODE (type) == INTEGER_TYPE);
1189 gfc_init_se (&se, NULL);
1190 gfc_conv_expr_val (&se, code->ext.iterator->start);
1191 gfc_add_block_to_block (pblock, &se.pre);
1192 from = gfc_evaluate_now (se.expr, pblock);
1194 gfc_init_se (&se, NULL);
1195 gfc_conv_expr_val (&se, code->ext.iterator->end);
1196 gfc_add_block_to_block (pblock, &se.pre);
1197 to = gfc_evaluate_now (se.expr, pblock);
1199 gfc_init_se (&se, NULL);
1200 gfc_conv_expr_val (&se, code->ext.iterator->step);
1201 gfc_add_block_to_block (pblock, &se.pre);
1202 step = gfc_evaluate_now (se.expr, pblock);
1204 /* Special case simple loops. */
1205 if (integer_onep (step))
1207 else if (tree_int_cst_equal (step, integer_minus_one_node))
1213 TREE_VEC_ELT (init, i) = build2_v (MODIFY_EXPR, dovar, from);
1214 TREE_VEC_ELT (cond, i) = fold_build2 (simple > 0 ? LE_EXPR : GE_EXPR,
1215 boolean_type_node, dovar, to);
1216 TREE_VEC_ELT (incr, i) = fold_build2 (PLUS_EXPR, type, dovar, step);
1217 TREE_VEC_ELT (incr, i) = fold_build2 (MODIFY_EXPR, type, dovar,
1218 TREE_VEC_ELT (incr, i));
1222 /* STEP is not 1 or -1. Use:
1223 for (count = 0; count < (to + step - from) / step; count++)
1225 dovar = from + count * step;
1229 tmp = fold_build2 (MINUS_EXPR, type, step, from);
1230 tmp = fold_build2 (PLUS_EXPR, type, to, tmp);
1231 tmp = fold_build2 (TRUNC_DIV_EXPR, type, tmp, step);
1232 tmp = gfc_evaluate_now (tmp, pblock);
1233 count = gfc_create_var (type, "count");
1234 TREE_VEC_ELT (init, i) = build2_v (MODIFY_EXPR, count,
1235 build_int_cst (type, 0));
1236 TREE_VEC_ELT (cond, i) = fold_build2 (LT_EXPR, boolean_type_node,
1238 TREE_VEC_ELT (incr, i) = fold_build2 (PLUS_EXPR, type, count,
1239 build_int_cst (type, 1));
1240 TREE_VEC_ELT (incr, i) = fold_build2 (MODIFY_EXPR, type,
1241 count, TREE_VEC_ELT (incr, i));
1243 /* Initialize DOVAR. */
1244 tmp = fold_build2 (MULT_EXPR, type, count, step);
1245 tmp = fold_build2 (PLUS_EXPR, type, from, tmp);
1246 dovar_init = tree_cons (dovar, tmp, dovar_init);
1251 tmp = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
1252 OMP_CLAUSE_DECL (tmp) = dovar;
1253 omp_clauses = gfc_trans_add_clause (tmp, omp_clauses);
1255 else if (dovar_found == 2)
1262 /* If dovar is lastprivate, but different counter is used,
1263 dovar += step needs to be added to
1264 OMP_CLAUSE_LASTPRIVATE_STMT, otherwise the copied dovar
1265 will have the value on entry of the last loop, rather
1266 than value after iterator increment. */
1267 tmp = gfc_evaluate_now (step, pblock);
1268 tmp = fold_build2 (PLUS_EXPR, type, dovar, tmp);
1269 tmp = fold_build2 (MODIFY_EXPR, type, dovar, tmp);
1270 for (c = omp_clauses; c ; c = OMP_CLAUSE_CHAIN (c))
1271 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
1272 && OMP_CLAUSE_DECL (c) == dovar)
1274 OMP_CLAUSE_LASTPRIVATE_STMT (c) = tmp;
1278 if (c == NULL && par_clauses != NULL)
1280 for (c = par_clauses; c ; c = OMP_CLAUSE_CHAIN (c))
1281 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
1282 && OMP_CLAUSE_DECL (c) == dovar)
1284 tree l = build_omp_clause (input_location,
1285 OMP_CLAUSE_LASTPRIVATE);
1286 OMP_CLAUSE_DECL (l) = dovar;
1287 OMP_CLAUSE_CHAIN (l) = omp_clauses;
1288 OMP_CLAUSE_LASTPRIVATE_STMT (l) = tmp;
1290 OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_SHARED);
1294 gcc_assert (simple || c != NULL);
1298 tmp = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
1299 OMP_CLAUSE_DECL (tmp) = count;
1300 omp_clauses = gfc_trans_add_clause (tmp, omp_clauses);
1303 if (i + 1 < collapse)
1304 code = code->block->next;
1307 if (pblock != &block)
1310 gfc_start_block (&block);
1313 gfc_start_block (&body);
1315 dovar_init = nreverse (dovar_init);
1318 gfc_add_modify (&body, TREE_PURPOSE (dovar_init),
1319 TREE_VALUE (dovar_init));
1320 dovar_init = TREE_CHAIN (dovar_init);
1323 /* Cycle statement is implemented with a goto. Exit statement must not be
1324 present for this loop. */
1325 cycle_label = gfc_build_label_decl (NULL_TREE);
1327 /* Put these labels where they can be found later. We put the
1328 labels in a TREE_LIST node (because TREE_CHAIN is already
1329 used). cycle_label goes in TREE_PURPOSE (backend_decl), exit
1330 label in TREE_VALUE (backend_decl). */
1332 code->block->backend_decl = tree_cons (cycle_label, NULL, NULL);
1334 /* Main loop body. */
1335 tmp = gfc_trans_omp_code (code->block->next, true);
1336 gfc_add_expr_to_block (&body, tmp);
1338 /* Label for cycle statements (if needed). */
1339 if (TREE_USED (cycle_label))
1341 tmp = build1_v (LABEL_EXPR, cycle_label);
1342 gfc_add_expr_to_block (&body, tmp);
1345 /* End of loop body. */
1346 stmt = make_node (OMP_FOR);
1348 TREE_TYPE (stmt) = void_type_node;
1349 OMP_FOR_BODY (stmt) = gfc_finish_block (&body);
1350 OMP_FOR_CLAUSES (stmt) = omp_clauses;
1351 OMP_FOR_INIT (stmt) = init;
1352 OMP_FOR_COND (stmt) = cond;
1353 OMP_FOR_INCR (stmt) = incr;
1354 gfc_add_expr_to_block (&block, stmt);
1356 return gfc_finish_block (&block);
1360 gfc_trans_omp_flush (void)
1362 tree decl = built_in_decls [BUILT_IN_SYNCHRONIZE];
1363 return build_call_expr_loc (input_location, decl, 0);
1367 gfc_trans_omp_master (gfc_code *code)
1369 tree stmt = gfc_trans_code (code->block->next);
1370 if (IS_EMPTY_STMT (stmt))
1372 return build1_v (OMP_MASTER, stmt);
1376 gfc_trans_omp_ordered (gfc_code *code)
1378 return build1_v (OMP_ORDERED, gfc_trans_code (code->block->next));
1382 gfc_trans_omp_parallel (gfc_code *code)
1385 tree stmt, omp_clauses;
1387 gfc_start_block (&block);
1388 omp_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
1390 stmt = gfc_trans_omp_code (code->block->next, true);
1391 stmt = build2 (OMP_PARALLEL, void_type_node, stmt, omp_clauses);
1392 gfc_add_expr_to_block (&block, stmt);
1393 return gfc_finish_block (&block);
1397 gfc_trans_omp_parallel_do (gfc_code *code)
1399 stmtblock_t block, *pblock = NULL;
1400 gfc_omp_clauses parallel_clauses, do_clauses;
1401 tree stmt, omp_clauses = NULL_TREE;
1403 gfc_start_block (&block);
1405 memset (&do_clauses, 0, sizeof (do_clauses));
1406 if (code->ext.omp_clauses != NULL)
1408 memcpy (¶llel_clauses, code->ext.omp_clauses,
1409 sizeof (parallel_clauses));
1410 do_clauses.sched_kind = parallel_clauses.sched_kind;
1411 do_clauses.chunk_size = parallel_clauses.chunk_size;
1412 do_clauses.ordered = parallel_clauses.ordered;
1413 do_clauses.collapse = parallel_clauses.collapse;
1414 parallel_clauses.sched_kind = OMP_SCHED_NONE;
1415 parallel_clauses.chunk_size = NULL;
1416 parallel_clauses.ordered = false;
1417 parallel_clauses.collapse = 0;
1418 omp_clauses = gfc_trans_omp_clauses (&block, ¶llel_clauses,
1421 do_clauses.nowait = true;
1422 if (!do_clauses.ordered && do_clauses.sched_kind != OMP_SCHED_STATIC)
1426 stmt = gfc_trans_omp_do (code, pblock, &do_clauses, omp_clauses);
1427 if (TREE_CODE (stmt) != BIND_EXPR)
1428 stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0, 0));
1431 stmt = build2 (OMP_PARALLEL, void_type_node, stmt, omp_clauses);
1432 OMP_PARALLEL_COMBINED (stmt) = 1;
1433 gfc_add_expr_to_block (&block, stmt);
1434 return gfc_finish_block (&block);
1438 gfc_trans_omp_parallel_sections (gfc_code *code)
1441 gfc_omp_clauses section_clauses;
1442 tree stmt, omp_clauses;
1444 memset (§ion_clauses, 0, sizeof (section_clauses));
1445 section_clauses.nowait = true;
1447 gfc_start_block (&block);
1448 omp_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
1451 stmt = gfc_trans_omp_sections (code, §ion_clauses);
1452 if (TREE_CODE (stmt) != BIND_EXPR)
1453 stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0, 0));
1456 stmt = build2 (OMP_PARALLEL, void_type_node, stmt, omp_clauses);
1457 OMP_PARALLEL_COMBINED (stmt) = 1;
1458 gfc_add_expr_to_block (&block, stmt);
1459 return gfc_finish_block (&block);
1463 gfc_trans_omp_parallel_workshare (gfc_code *code)
1466 gfc_omp_clauses workshare_clauses;
1467 tree stmt, omp_clauses;
1469 memset (&workshare_clauses, 0, sizeof (workshare_clauses));
1470 workshare_clauses.nowait = true;
1472 gfc_start_block (&block);
1473 omp_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
1476 stmt = gfc_trans_omp_workshare (code, &workshare_clauses);
1477 if (TREE_CODE (stmt) != BIND_EXPR)
1478 stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0, 0));
1481 stmt = build2 (OMP_PARALLEL, void_type_node, stmt, omp_clauses);
1482 OMP_PARALLEL_COMBINED (stmt) = 1;
1483 gfc_add_expr_to_block (&block, stmt);
1484 return gfc_finish_block (&block);
1488 gfc_trans_omp_sections (gfc_code *code, gfc_omp_clauses *clauses)
1490 stmtblock_t block, body;
1491 tree omp_clauses, stmt;
1492 bool has_lastprivate = clauses->lists[OMP_LIST_LASTPRIVATE] != NULL;
1494 gfc_start_block (&block);
1496 omp_clauses = gfc_trans_omp_clauses (&block, clauses, code->loc);
1498 gfc_init_block (&body);
1499 for (code = code->block; code; code = code->block)
1501 /* Last section is special because of lastprivate, so even if it
1502 is empty, chain it in. */
1503 stmt = gfc_trans_omp_code (code->next,
1504 has_lastprivate && code->block == NULL);
1505 if (! IS_EMPTY_STMT (stmt))
1507 stmt = build1_v (OMP_SECTION, stmt);
1508 gfc_add_expr_to_block (&body, stmt);
1511 stmt = gfc_finish_block (&body);
1513 stmt = build2 (OMP_SECTIONS, void_type_node, stmt, omp_clauses);
1514 gfc_add_expr_to_block (&block, stmt);
1516 return gfc_finish_block (&block);
1520 gfc_trans_omp_single (gfc_code *code, gfc_omp_clauses *clauses)
1522 tree omp_clauses = gfc_trans_omp_clauses (NULL, clauses, code->loc);
1523 tree stmt = gfc_trans_omp_code (code->block->next, true);
1524 stmt = build2 (OMP_SINGLE, void_type_node, stmt, omp_clauses);
1529 gfc_trans_omp_task (gfc_code *code)
1532 tree stmt, omp_clauses;
1534 gfc_start_block (&block);
1535 omp_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
1537 stmt = gfc_trans_omp_code (code->block->next, true);
1538 stmt = build2 (OMP_TASK, void_type_node, stmt, omp_clauses);
1539 gfc_add_expr_to_block (&block, stmt);
1540 return gfc_finish_block (&block);
1544 gfc_trans_omp_taskwait (void)
1546 tree decl = built_in_decls [BUILT_IN_GOMP_TASKWAIT];
1547 return build_call_expr_loc (input_location, decl, 0);
1551 gfc_trans_omp_workshare (gfc_code *code, gfc_omp_clauses *clauses)
1553 tree res, tmp, stmt;
1554 stmtblock_t block, *pblock = NULL;
1555 stmtblock_t singleblock;
1556 int saved_ompws_flags;
1557 bool singleblock_in_progress = false;
1558 /* True if previous gfc_code in workshare construct is not workshared. */
1559 bool prev_singleunit;
1561 code = code->block->next;
1566 return build_empty_stmt (input_location);
1568 gfc_start_block (&block);
1571 ompws_flags = OMPWS_WORKSHARE_FLAG;
1572 prev_singleunit = false;
1574 /* Translate statements one by one to trees until we reach
1575 the end of the workshare construct. Adjacent gfc_codes that
1576 are a single unit of work are clustered and encapsulated in a
1577 single OMP_SINGLE construct. */
1578 for (; code; code = code->next)
1580 if (code->here != 0)
1582 res = gfc_trans_label_here (code);
1583 gfc_add_expr_to_block (pblock, res);
1586 /* No dependence analysis, use for clauses with wait.
1587 If this is the last gfc_code, use default omp_clauses. */
1588 if (code->next == NULL && clauses->nowait)
1589 ompws_flags |= OMPWS_NOWAIT;
1591 /* By default, every gfc_code is a single unit of work. */
1592 ompws_flags |= OMPWS_CURR_SINGLEUNIT;
1593 ompws_flags &= ~OMPWS_SCALARIZER_WS;
1602 res = gfc_trans_assign (code);
1605 case EXEC_POINTER_ASSIGN:
1606 res = gfc_trans_pointer_assign (code);
1609 case EXEC_INIT_ASSIGN:
1610 res = gfc_trans_init_assign (code);
1614 res = gfc_trans_forall (code);
1618 res = gfc_trans_where (code);
1621 case EXEC_OMP_ATOMIC:
1622 res = gfc_trans_omp_directive (code);
1625 case EXEC_OMP_PARALLEL:
1626 case EXEC_OMP_PARALLEL_DO:
1627 case EXEC_OMP_PARALLEL_SECTIONS:
1628 case EXEC_OMP_PARALLEL_WORKSHARE:
1629 case EXEC_OMP_CRITICAL:
1630 saved_ompws_flags = ompws_flags;
1632 res = gfc_trans_omp_directive (code);
1633 ompws_flags = saved_ompws_flags;
1637 internal_error ("gfc_trans_omp_workshare(): Bad statement code");
1640 gfc_set_backend_locus (&code->loc);
1642 if (res != NULL_TREE && ! IS_EMPTY_STMT (res))
1644 if (prev_singleunit)
1646 if (ompws_flags & OMPWS_CURR_SINGLEUNIT)
1647 /* Add current gfc_code to single block. */
1648 gfc_add_expr_to_block (&singleblock, res);
1651 /* Finish single block and add it to pblock. */
1652 tmp = gfc_finish_block (&singleblock);
1653 tmp = build2 (OMP_SINGLE, void_type_node, tmp, NULL_TREE);
1654 gfc_add_expr_to_block (pblock, tmp);
1655 /* Add current gfc_code to pblock. */
1656 gfc_add_expr_to_block (pblock, res);
1657 singleblock_in_progress = false;
1662 if (ompws_flags & OMPWS_CURR_SINGLEUNIT)
1664 /* Start single block. */
1665 gfc_init_block (&singleblock);
1666 gfc_add_expr_to_block (&singleblock, res);
1667 singleblock_in_progress = true;
1670 /* Add the new statement to the block. */
1671 gfc_add_expr_to_block (pblock, res);
1673 prev_singleunit = (ompws_flags & OMPWS_CURR_SINGLEUNIT) != 0;
1677 /* Finish remaining SINGLE block, if we were in the middle of one. */
1678 if (singleblock_in_progress)
1680 /* Finish single block and add it to pblock. */
1681 tmp = gfc_finish_block (&singleblock);
1682 tmp = build2 (OMP_SINGLE, void_type_node, tmp,
1684 ? build_omp_clause (input_location, OMP_CLAUSE_NOWAIT)
1686 gfc_add_expr_to_block (pblock, tmp);
1689 stmt = gfc_finish_block (pblock);
1690 if (TREE_CODE (stmt) != BIND_EXPR)
1692 if (!IS_EMPTY_STMT (stmt))
1694 tree bindblock = poplevel (1, 0, 0);
1695 stmt = build3_v (BIND_EXPR, NULL, stmt, bindblock);
1708 gfc_trans_omp_directive (gfc_code *code)
1712 case EXEC_OMP_ATOMIC:
1713 return gfc_trans_omp_atomic (code);
1714 case EXEC_OMP_BARRIER:
1715 return gfc_trans_omp_barrier ();
1716 case EXEC_OMP_CRITICAL:
1717 return gfc_trans_omp_critical (code);
1719 return gfc_trans_omp_do (code, NULL, code->ext.omp_clauses, NULL);
1720 case EXEC_OMP_FLUSH:
1721 return gfc_trans_omp_flush ();
1722 case EXEC_OMP_MASTER:
1723 return gfc_trans_omp_master (code);
1724 case EXEC_OMP_ORDERED:
1725 return gfc_trans_omp_ordered (code);
1726 case EXEC_OMP_PARALLEL:
1727 return gfc_trans_omp_parallel (code);
1728 case EXEC_OMP_PARALLEL_DO:
1729 return gfc_trans_omp_parallel_do (code);
1730 case EXEC_OMP_PARALLEL_SECTIONS:
1731 return gfc_trans_omp_parallel_sections (code);
1732 case EXEC_OMP_PARALLEL_WORKSHARE:
1733 return gfc_trans_omp_parallel_workshare (code);
1734 case EXEC_OMP_SECTIONS:
1735 return gfc_trans_omp_sections (code, code->ext.omp_clauses);
1736 case EXEC_OMP_SINGLE:
1737 return gfc_trans_omp_single (code, code->ext.omp_clauses);
1739 return gfc_trans_omp_task (code);
1740 case EXEC_OMP_TASKWAIT:
1741 return gfc_trans_omp_taskwait ();
1742 case EXEC_OMP_WORKSHARE:
1743 return gfc_trans_omp_workshare (code, code->ext.omp_clauses);