]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/fortran/trans-openmp.c
re PR tree-optimization/43934 (LIM should handle PHI nodes)
[thirdparty/gcc.git] / gcc / fortran / trans-openmp.c
CommitLineData
6c7a4dfd 1/* OpenMP directive translation -- generate GCC trees from gfc_code.
23a5b65a 2 Copyright (C) 2005-2014 Free Software Foundation, Inc.
6c7a4dfd
JJ
3 Contributed by Jakub Jelinek <jakub@redhat.com>
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
d234d788 9Software Foundation; either version 3, or (at your option) any later
6c7a4dfd
JJ
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
d234d788
NC
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
6c7a4dfd
JJ
20
21
22#include "config.h"
23#include "system.h"
24#include "coretypes.h"
25#include "tree.h"
2fb9a547 26#include "gimple-expr.h"
45b0be94 27#include "gimplify.h" /* For create_tmp_var_raw. */
d8a2d370 28#include "stringpool.h"
c829d016 29#include "diagnostic-core.h" /* For internal_error. */
6c7a4dfd
JJ
30#include "gfortran.h"
31#include "trans.h"
32#include "trans-stmt.h"
33#include "trans-types.h"
34#include "trans-array.h"
35#include "trans-const.h"
36#include "arith.h"
0645c1a2 37#include "omp-low.h"
6c7a4dfd 38
34d01e1d 39int ompws_flags;
6c7a4dfd
JJ
40
41/* True if OpenMP should privatize what this DECL points to rather
42 than the DECL itself. */
43
44bool
58f9752a 45gfc_omp_privatize_by_reference (const_tree decl)
6c7a4dfd
JJ
46{
47 tree type = TREE_TYPE (decl);
48
36cefd39
JJ
49 if (TREE_CODE (type) == REFERENCE_TYPE
50 && (!DECL_ARTIFICIAL (decl) || TREE_CODE (decl) == PARM_DECL))
6c7a4dfd
JJ
51 return true;
52
53 if (TREE_CODE (type) == POINTER_TYPE)
54 {
e1c82219
JJ
55 /* Array POINTER/ALLOCATABLE have aggregate types, all user variables
56 that have POINTER_TYPE type and don't have GFC_POINTER_TYPE_P
57 set are supposed to be privatized by reference. */
58 if (GFC_POINTER_TYPE_P (type))
59 return false;
60
2b45bf21
JJ
61 if (!DECL_ARTIFICIAL (decl)
62 && TREE_CODE (TREE_TYPE (type)) != FUNCTION_TYPE)
6c7a4dfd
JJ
63 return true;
64
65 /* Some arrays are expanded as DECL_ARTIFICIAL pointers
66 by the frontend. */
67 if (DECL_LANG_SPECIFIC (decl)
68 && GFC_DECL_SAVED_DESCRIPTOR (decl))
69 return true;
70 }
71
72 return false;
73}
74
75/* True if OpenMP sharing attribute of DECL is predetermined. */
76
77enum omp_clause_default_kind
78gfc_omp_predetermined_sharing (tree decl)
79{
79943d19
JJ
80 if (DECL_ARTIFICIAL (decl)
81 && ! GFC_DECL_RESULT (decl)
82 && ! (DECL_LANG_SPECIFIC (decl)
83 && GFC_DECL_SAVED_DESCRIPTOR (decl)))
6c7a4dfd
JJ
84 return OMP_CLAUSE_DEFAULT_SHARED;
85
86 /* Cray pointees shouldn't be listed in any clauses and should be
87 gimplified to dereference of the corresponding Cray pointer.
88 Make them all private, so that they are emitted in the debug
89 information. */
90 if (GFC_DECL_CRAY_POINTEE (decl))
91 return OMP_CLAUSE_DEFAULT_PRIVATE;
92
20906c66 93 /* Assumed-size arrays are predetermined shared. */
a68ab351
JJ
94 if (TREE_CODE (decl) == PARM_DECL
95 && GFC_ARRAY_TYPE_P (TREE_TYPE (decl))
96 && GFC_TYPE_ARRAY_AKIND (TREE_TYPE (decl)) == GFC_ARRAY_UNKNOWN
97 && GFC_TYPE_ARRAY_UBOUND (TREE_TYPE (decl),
98 GFC_TYPE_ARRAY_RANK (TREE_TYPE (decl)) - 1)
99 == NULL)
100 return OMP_CLAUSE_DEFAULT_SHARED;
101
2b45bf21
JJ
102 /* Dummy procedures aren't considered variables by OpenMP, thus are
103 disallowed in OpenMP clauses. They are represented as PARM_DECLs
104 in the middle-end, so return OMP_CLAUSE_DEFAULT_FIRSTPRIVATE here
105 to avoid complaining about their uses with default(none). */
106 if (TREE_CODE (decl) == PARM_DECL
107 && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
108 && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == FUNCTION_TYPE)
109 return OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
110
6c7a4dfd
JJ
111 /* COMMON and EQUIVALENCE decls are shared. They
112 are only referenced through DECL_VALUE_EXPR of the variables
113 contained in them. If those are privatized, they will not be
114 gimplified to the COMMON or EQUIVALENCE decls. */
115 if (GFC_DECL_COMMON_OR_EQUIV (decl) && ! DECL_HAS_VALUE_EXPR_P (decl))
116 return OMP_CLAUSE_DEFAULT_SHARED;
117
118 if (GFC_DECL_RESULT (decl) && ! DECL_HAS_VALUE_EXPR_P (decl))
119 return OMP_CLAUSE_DEFAULT_SHARED;
120
121 return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
122}
123
79943d19
JJ
124/* Return decl that should be used when reporting DEFAULT(NONE)
125 diagnostics. */
126
127tree
128gfc_omp_report_decl (tree decl)
129{
130 if (DECL_ARTIFICIAL (decl)
131 && DECL_LANG_SPECIFIC (decl)
132 && GFC_DECL_SAVED_DESCRIPTOR (decl))
133 return GFC_DECL_SAVED_DESCRIPTOR (decl);
134
135 return decl;
136}
cd75853e 137
a68ab351
JJ
138/* Return true if DECL in private clause needs
139 OMP_CLAUSE_PRIVATE_OUTER_REF on the private clause. */
140bool
141gfc_omp_private_outer_ref (tree decl)
142{
143 tree type = TREE_TYPE (decl);
144
145 if (GFC_DESCRIPTOR_TYPE_P (type)
146 && GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_ALLOCATABLE)
147 return true;
148
149 return false;
150}
151
cd75853e
JJ
152/* Return code to initialize DECL with its default constructor, or
153 NULL if there's nothing to do. */
154
155tree
a68ab351 156gfc_omp_clause_default_ctor (tree clause, tree decl, tree outer)
cd75853e 157{
a68ab351
JJ
158 tree type = TREE_TYPE (decl), rank, size, esize, ptr, cond, then_b, else_b;
159 stmtblock_t block, cond_block;
cd75853e 160
a68ab351
JJ
161 if (! GFC_DESCRIPTOR_TYPE_P (type)
162 || GFC_TYPE_ARRAY_AKIND (type) != GFC_ARRAY_ALLOCATABLE)
cd75853e
JJ
163 return NULL;
164
acf0174b
JJ
165 if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_REDUCTION)
166 return NULL;
167
a68ab351
JJ
168 gcc_assert (outer != NULL);
169 gcc_assert (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_PRIVATE
170 || OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_LASTPRIVATE);
171
cd75853e 172 /* Allocatable arrays in PRIVATE clauses need to be set to
a68ab351
JJ
173 "not currently allocated" allocation status if outer
174 array is "not currently allocated", otherwise should be allocated. */
175 gfc_start_block (&block);
176
177 gfc_init_block (&cond_block);
178
726a989a 179 gfc_add_modify (&cond_block, decl, outer);
a68ab351 180 rank = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (type) - 1];
568e8e1e 181 size = gfc_conv_descriptor_ubound_get (decl, rank);
65a9ca82
TB
182 size = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
183 size, gfc_conv_descriptor_lbound_get (decl, rank));
184 size = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
185 size, gfc_index_one_node);
a68ab351 186 if (GFC_TYPE_ARRAY_RANK (type) > 1)
65a9ca82
TB
187 size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
188 size, gfc_conv_descriptor_stride_get (decl, rank));
a68ab351
JJ
189 esize = fold_convert (gfc_array_index_type,
190 TYPE_SIZE_UNIT (gfc_get_element_type (type)));
65a9ca82
TB
191 size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
192 size, esize);
a68ab351 193 size = gfc_evaluate_now (fold_convert (size_type_node, size), &cond_block);
4f13e17f
DC
194
195 ptr = gfc_create_var (pvoid_type_node, NULL);
196 gfc_allocate_using_malloc (&cond_block, ptr, size, NULL_TREE);
726a989a 197 gfc_conv_descriptor_data_set (&cond_block, decl, ptr);
4f13e17f 198
a68ab351
JJ
199 then_b = gfc_finish_block (&cond_block);
200
201 gfc_init_block (&cond_block);
726a989a 202 gfc_conv_descriptor_data_set (&cond_block, decl, null_pointer_node);
a68ab351
JJ
203 else_b = gfc_finish_block (&cond_block);
204
65a9ca82
TB
205 cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
206 fold_convert (pvoid_type_node,
207 gfc_conv_descriptor_data_get (outer)),
208 null_pointer_node);
5d44e5c8
TB
209 gfc_add_expr_to_block (&block, build3_loc (input_location, COND_EXPR,
210 void_type_node, cond, then_b, else_b));
cd75853e 211
a68ab351
JJ
212 return gfc_finish_block (&block);
213}
214
215/* Build and return code for a copy constructor from SRC to DEST. */
216
217tree
218gfc_omp_clause_copy_ctor (tree clause, tree dest, tree src)
219{
220 tree type = TREE_TYPE (dest), ptr, size, esize, rank, call;
20906c66
JJ
221 tree cond, then_b, else_b;
222 stmtblock_t block, cond_block;
a68ab351
JJ
223
224 if (! GFC_DESCRIPTOR_TYPE_P (type)
225 || GFC_TYPE_ARRAY_AKIND (type) != GFC_ARRAY_ALLOCATABLE)
726a989a 226 return build2_v (MODIFY_EXPR, dest, src);
a68ab351
JJ
227
228 gcc_assert (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_FIRSTPRIVATE);
229
230 /* Allocatable arrays in FIRSTPRIVATE clauses need to be allocated
231 and copied from SRC. */
232 gfc_start_block (&block);
233
20906c66
JJ
234 gfc_init_block (&cond_block);
235
236 gfc_add_modify (&cond_block, dest, src);
a68ab351 237 rank = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (type) - 1];
568e8e1e 238 size = gfc_conv_descriptor_ubound_get (dest, rank);
65a9ca82
TB
239 size = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
240 size, gfc_conv_descriptor_lbound_get (dest, rank));
241 size = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
242 size, gfc_index_one_node);
a68ab351 243 if (GFC_TYPE_ARRAY_RANK (type) > 1)
65a9ca82
TB
244 size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
245 size, gfc_conv_descriptor_stride_get (dest, rank));
a68ab351
JJ
246 esize = fold_convert (gfc_array_index_type,
247 TYPE_SIZE_UNIT (gfc_get_element_type (type)));
65a9ca82
TB
248 size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
249 size, esize);
20906c66 250 size = gfc_evaluate_now (fold_convert (size_type_node, size), &cond_block);
4f13e17f
DC
251
252 ptr = gfc_create_var (pvoid_type_node, NULL);
20906c66
JJ
253 gfc_allocate_using_malloc (&cond_block, ptr, size, NULL_TREE);
254 gfc_conv_descriptor_data_set (&cond_block, dest, ptr);
4f13e17f 255
db3927fb 256 call = build_call_expr_loc (input_location,
e79983f4
MM
257 builtin_decl_explicit (BUILT_IN_MEMCPY),
258 3, ptr,
a68ab351
JJ
259 fold_convert (pvoid_type_node,
260 gfc_conv_descriptor_data_get (src)),
261 size);
20906c66
JJ
262 gfc_add_expr_to_block (&cond_block, fold_convert (void_type_node, call));
263 then_b = gfc_finish_block (&cond_block);
264
265 gfc_init_block (&cond_block);
266 gfc_conv_descriptor_data_set (&cond_block, dest, null_pointer_node);
267 else_b = gfc_finish_block (&cond_block);
268
269 cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
270 fold_convert (pvoid_type_node,
271 gfc_conv_descriptor_data_get (src)),
272 null_pointer_node);
273 gfc_add_expr_to_block (&block, build3_loc (input_location, COND_EXPR,
274 void_type_node, cond, then_b, else_b));
cd75853e
JJ
275
276 return gfc_finish_block (&block);
277}
278
a68ab351
JJ
279/* Similarly, except use an assignment operator instead. */
280
281tree
282gfc_omp_clause_assign_op (tree clause ATTRIBUTE_UNUSED, tree dest, tree src)
283{
284 tree type = TREE_TYPE (dest), rank, size, esize, call;
285 stmtblock_t block;
286
287 if (! GFC_DESCRIPTOR_TYPE_P (type)
288 || GFC_TYPE_ARRAY_AKIND (type) != GFC_ARRAY_ALLOCATABLE)
726a989a 289 return build2_v (MODIFY_EXPR, dest, src);
a68ab351
JJ
290
291 /* Handle copying allocatable arrays. */
292 gfc_start_block (&block);
293
294 rank = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (type) - 1];
568e8e1e 295 size = gfc_conv_descriptor_ubound_get (dest, rank);
65a9ca82
TB
296 size = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
297 size, gfc_conv_descriptor_lbound_get (dest, rank));
298 size = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
299 size, gfc_index_one_node);
a68ab351 300 if (GFC_TYPE_ARRAY_RANK (type) > 1)
65a9ca82
TB
301 size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
302 size, gfc_conv_descriptor_stride_get (dest, rank));
a68ab351
JJ
303 esize = fold_convert (gfc_array_index_type,
304 TYPE_SIZE_UNIT (gfc_get_element_type (type)));
65a9ca82
TB
305 size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
306 size, esize);
a68ab351 307 size = gfc_evaluate_now (fold_convert (size_type_node, size), &block);
db3927fb 308 call = build_call_expr_loc (input_location,
e79983f4 309 builtin_decl_explicit (BUILT_IN_MEMCPY), 3,
a68ab351
JJ
310 fold_convert (pvoid_type_node,
311 gfc_conv_descriptor_data_get (dest)),
312 fold_convert (pvoid_type_node,
313 gfc_conv_descriptor_data_get (src)),
314 size);
315 gfc_add_expr_to_block (&block, fold_convert (void_type_node, call));
316
317 return gfc_finish_block (&block);
318}
319
320/* Build and return code destructing DECL. Return NULL if nothing
321 to be done. */
322
323tree
324gfc_omp_clause_dtor (tree clause ATTRIBUTE_UNUSED, tree decl)
325{
326 tree type = TREE_TYPE (decl);
327
328 if (! GFC_DESCRIPTOR_TYPE_P (type)
329 || GFC_TYPE_ARRAY_AKIND (type) != GFC_ARRAY_ALLOCATABLE)
330 return NULL;
331
acf0174b
JJ
332 if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_REDUCTION)
333 return NULL;
334
a68ab351
JJ
335 /* Allocatable arrays in FIRSTPRIVATE/LASTPRIVATE etc. clauses need
336 to be deallocated if they were allocated. */
ef292537 337 return gfc_trans_dealloc_allocated (decl, false, NULL);
a68ab351
JJ
338}
339
cd75853e 340
6c7a4dfd
JJ
341/* Return true if DECL's DECL_VALUE_EXPR (if any) should be
342 disregarded in OpenMP construct, because it is going to be
343 remapped during OpenMP lowering. SHARED is true if DECL
344 is going to be shared, false if it is going to be privatized. */
345
346bool
347gfc_omp_disregard_value_expr (tree decl, bool shared)
348{
349 if (GFC_DECL_COMMON_OR_EQUIV (decl)
350 && DECL_HAS_VALUE_EXPR_P (decl))
351 {
352 tree value = DECL_VALUE_EXPR (decl);
353
354 if (TREE_CODE (value) == COMPONENT_REF
355 && TREE_CODE (TREE_OPERAND (value, 0)) == VAR_DECL
356 && GFC_DECL_COMMON_OR_EQUIV (TREE_OPERAND (value, 0)))
357 {
358 /* If variable in COMMON or EQUIVALENCE is privatized, return
359 true, as just that variable is supposed to be privatized,
360 not the whole COMMON or whole EQUIVALENCE.
361 For shared variables in COMMON or EQUIVALENCE, let them be
362 gimplified to DECL_VALUE_EXPR, so that for multiple shared vars
363 from the same COMMON or EQUIVALENCE just one sharing of the
364 whole COMMON or EQUIVALENCE is enough. */
365 return ! shared;
366 }
367 }
368
369 if (GFC_DECL_RESULT (decl) && DECL_HAS_VALUE_EXPR_P (decl))
370 return ! shared;
371
372 return false;
373}
374
375/* Return true if DECL that is shared iff SHARED is true should
376 be put into OMP_CLAUSE_PRIVATE with OMP_CLAUSE_PRIVATE_DEBUG
377 flag set. */
378
379bool
380gfc_omp_private_debug_clause (tree decl, bool shared)
381{
382 if (GFC_DECL_CRAY_POINTEE (decl))
383 return true;
384
385 if (GFC_DECL_COMMON_OR_EQUIV (decl)
386 && DECL_HAS_VALUE_EXPR_P (decl))
387 {
388 tree value = DECL_VALUE_EXPR (decl);
389
390 if (TREE_CODE (value) == COMPONENT_REF
391 && TREE_CODE (TREE_OPERAND (value, 0)) == VAR_DECL
392 && GFC_DECL_COMMON_OR_EQUIV (TREE_OPERAND (value, 0)))
393 return shared;
394 }
395
396 return false;
397}
398
399/* Register language specific type size variables as potentially OpenMP
400 firstprivate variables. */
401
402void
403gfc_omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *ctx, tree type)
404{
405 if (GFC_ARRAY_TYPE_P (type) || GFC_DESCRIPTOR_TYPE_P (type))
406 {
407 int r;
408
409 gcc_assert (TYPE_LANG_SPECIFIC (type) != NULL);
410 for (r = 0; r < GFC_TYPE_ARRAY_RANK (type); r++)
411 {
412 omp_firstprivatize_variable (ctx, GFC_TYPE_ARRAY_LBOUND (type, r));
413 omp_firstprivatize_variable (ctx, GFC_TYPE_ARRAY_UBOUND (type, r));
414 omp_firstprivatize_variable (ctx, GFC_TYPE_ARRAY_STRIDE (type, r));
415 }
416 omp_firstprivatize_variable (ctx, GFC_TYPE_ARRAY_SIZE (type));
417 omp_firstprivatize_variable (ctx, GFC_TYPE_ARRAY_OFFSET (type));
418 }
419}
420
421
422static inline tree
423gfc_trans_add_clause (tree node, tree tail)
424{
425 OMP_CLAUSE_CHAIN (node) = tail;
426 return node;
427}
428
429static tree
dd2fc525 430gfc_trans_omp_variable (gfc_symbol *sym, bool declare_simd)
6c7a4dfd 431{
dd2fc525
JJ
432 if (declare_simd)
433 {
434 int cnt = 0;
435 gfc_symbol *proc_sym;
436 gfc_formal_arglist *f;
437
438 gcc_assert (sym->attr.dummy);
439 proc_sym = sym->ns->proc_name;
440 if (proc_sym->attr.entry_master)
441 ++cnt;
442 if (gfc_return_by_reference (proc_sym))
443 {
444 ++cnt;
445 if (proc_sym->ts.type == BT_CHARACTER)
446 ++cnt;
447 }
448 for (f = gfc_sym_get_dummy_args (proc_sym); f; f = f->next)
449 if (f->sym == sym)
450 break;
451 else if (f->sym)
452 ++cnt;
453 gcc_assert (f);
454 return build_int_cst (integer_type_node, cnt);
455 }
456
6c7a4dfd 457 tree t = gfc_get_symbol_decl (sym);
11a5f608
JJ
458 tree parent_decl;
459 int parent_flag;
460 bool return_value;
461 bool alternate_entry;
462 bool entry_master;
463
464 return_value = sym->attr.function && sym->result == sym;
465 alternate_entry = sym->attr.function && sym->attr.entry
466 && sym->result == sym;
467 entry_master = sym->attr.result
468 && sym->ns->proc_name->attr.entry_master
469 && !gfc_return_by_reference (sym->ns->proc_name);
dd2fc525
JJ
470 parent_decl = current_function_decl
471 ? DECL_CONTEXT (current_function_decl) : NULL_TREE;
11a5f608
JJ
472
473 if ((t == parent_decl && return_value)
474 || (sym->ns && sym->ns->proc_name
475 && sym->ns->proc_name->backend_decl == parent_decl
476 && (alternate_entry || entry_master)))
477 parent_flag = 1;
478 else
479 parent_flag = 0;
6c7a4dfd
JJ
480
481 /* Special case for assigning the return value of a function.
482 Self recursive functions must have an explicit return value. */
11a5f608
JJ
483 if (return_value && (t == current_function_decl || parent_flag))
484 t = gfc_get_fake_result_decl (sym, parent_flag);
6c7a4dfd
JJ
485
486 /* Similarly for alternate entry points. */
11a5f608
JJ
487 else if (alternate_entry
488 && (sym->ns->proc_name->backend_decl == current_function_decl
489 || parent_flag))
6c7a4dfd
JJ
490 {
491 gfc_entry_list *el = NULL;
492
493 for (el = sym->ns->entries; el; el = el->next)
494 if (sym == el->sym)
495 {
11a5f608 496 t = gfc_get_fake_result_decl (sym, parent_flag);
6c7a4dfd
JJ
497 break;
498 }
499 }
500
11a5f608
JJ
501 else if (entry_master
502 && (sym->ns->proc_name->backend_decl == current_function_decl
503 || parent_flag))
504 t = gfc_get_fake_result_decl (sym, parent_flag);
6c7a4dfd
JJ
505
506 return t;
507}
508
509static tree
dd2fc525
JJ
510gfc_trans_omp_variable_list (enum omp_clause_code code,
511 gfc_omp_namelist *namelist, tree list,
512 bool declare_simd)
6c7a4dfd
JJ
513{
514 for (; namelist != NULL; namelist = namelist->next)
dd2fc525 515 if (namelist->sym->attr.referenced || declare_simd)
6c7a4dfd 516 {
dd2fc525 517 tree t = gfc_trans_omp_variable (namelist->sym, declare_simd);
6c7a4dfd
JJ
518 if (t != error_mark_node)
519 {
c2255bc4 520 tree node = build_omp_clause (input_location, code);
6c7a4dfd
JJ
521 OMP_CLAUSE_DECL (node) = t;
522 list = gfc_trans_add_clause (node, list);
523 }
524 }
525 return list;
526}
527
528static void
529gfc_trans_omp_array_reduction (tree c, gfc_symbol *sym, locus where)
530{
531 gfc_symtree *root1 = NULL, *root2 = NULL, *root3 = NULL, *root4 = NULL;
532 gfc_symtree *symtree1, *symtree2, *symtree3, *symtree4 = NULL;
533 gfc_symbol init_val_sym, outer_sym, intrinsic_sym;
534 gfc_expr *e1, *e2, *e3, *e4;
535 gfc_ref *ref;
af3fcdb4 536 tree decl, backend_decl, stmt, type, outer_decl;
6c7a4dfd
JJ
537 locus old_loc = gfc_current_locus;
538 const char *iname;
524af0d6 539 bool t;
6c7a4dfd
JJ
540
541 decl = OMP_CLAUSE_DECL (c);
542 gfc_current_locus = where;
af3fcdb4
JJ
543 type = TREE_TYPE (decl);
544 outer_decl = create_tmp_var_raw (type, NULL);
545 if (TREE_CODE (decl) == PARM_DECL
546 && TREE_CODE (type) == REFERENCE_TYPE
547 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (type))
548 && GFC_TYPE_ARRAY_AKIND (TREE_TYPE (type)) == GFC_ARRAY_ALLOCATABLE)
549 {
550 decl = build_fold_indirect_ref (decl);
551 type = TREE_TYPE (type);
552 }
6c7a4dfd
JJ
553
554 /* Create a fake symbol for init value. */
555 memset (&init_val_sym, 0, sizeof (init_val_sym));
556 init_val_sym.ns = sym->ns;
557 init_val_sym.name = sym->name;
558 init_val_sym.ts = sym->ts;
559 init_val_sym.attr.referenced = 1;
560 init_val_sym.declared_at = where;
a7a53ca5 561 init_val_sym.attr.flavor = FL_VARIABLE;
6c7a4dfd
JJ
562 backend_decl = omp_reduction_init (c, gfc_sym_type (&init_val_sym));
563 init_val_sym.backend_decl = backend_decl;
564
565 /* Create a fake symbol for the outer array reference. */
566 outer_sym = *sym;
567 outer_sym.as = gfc_copy_array_spec (sym->as);
568 outer_sym.attr.dummy = 0;
569 outer_sym.attr.result = 0;
a7a53ca5 570 outer_sym.attr.flavor = FL_VARIABLE;
af3fcdb4
JJ
571 outer_sym.backend_decl = outer_decl;
572 if (decl != OMP_CLAUSE_DECL (c))
573 outer_sym.backend_decl = build_fold_indirect_ref (outer_decl);
6c7a4dfd
JJ
574
575 /* Create fake symtrees for it. */
576 symtree1 = gfc_new_symtree (&root1, sym->name);
577 symtree1->n.sym = sym;
578 gcc_assert (symtree1 == root1);
579
580 symtree2 = gfc_new_symtree (&root2, sym->name);
581 symtree2->n.sym = &init_val_sym;
582 gcc_assert (symtree2 == root2);
583
584 symtree3 = gfc_new_symtree (&root3, sym->name);
585 symtree3->n.sym = &outer_sym;
586 gcc_assert (symtree3 == root3);
587
588 /* Create expressions. */
589 e1 = gfc_get_expr ();
590 e1->expr_type = EXPR_VARIABLE;
591 e1->where = where;
592 e1->symtree = symtree1;
593 e1->ts = sym->ts;
594 e1->ref = ref = gfc_get_ref ();
8e1f752a 595 ref->type = REF_ARRAY;
6c7a4dfd
JJ
596 ref->u.ar.where = where;
597 ref->u.ar.as = sym->as;
598 ref->u.ar.type = AR_FULL;
599 ref->u.ar.dimen = 0;
600 t = gfc_resolve_expr (e1);
524af0d6 601 gcc_assert (t);
6c7a4dfd
JJ
602
603 e2 = gfc_get_expr ();
604 e2->expr_type = EXPR_VARIABLE;
605 e2->where = where;
606 e2->symtree = symtree2;
607 e2->ts = sym->ts;
608 t = gfc_resolve_expr (e2);
524af0d6 609 gcc_assert (t);
6c7a4dfd
JJ
610
611 e3 = gfc_copy_expr (e1);
612 e3->symtree = symtree3;
613 t = gfc_resolve_expr (e3);
524af0d6 614 gcc_assert (t);
6c7a4dfd
JJ
615
616 iname = NULL;
617 switch (OMP_CLAUSE_REDUCTION_CODE (c))
618 {
619 case PLUS_EXPR:
620 case MINUS_EXPR:
621 e4 = gfc_add (e3, e1);
622 break;
623 case MULT_EXPR:
624 e4 = gfc_multiply (e3, e1);
625 break;
626 case TRUTH_ANDIF_EXPR:
627 e4 = gfc_and (e3, e1);
628 break;
629 case TRUTH_ORIF_EXPR:
630 e4 = gfc_or (e3, e1);
631 break;
632 case EQ_EXPR:
633 e4 = gfc_eqv (e3, e1);
634 break;
635 case NE_EXPR:
636 e4 = gfc_neqv (e3, e1);
637 break;
638 case MIN_EXPR:
639 iname = "min";
640 break;
641 case MAX_EXPR:
642 iname = "max";
643 break;
644 case BIT_AND_EXPR:
645 iname = "iand";
646 break;
647 case BIT_IOR_EXPR:
648 iname = "ior";
649 break;
650 case BIT_XOR_EXPR:
651 iname = "ieor";
652 break;
653 default:
654 gcc_unreachable ();
655 }
656 if (iname != NULL)
657 {
658 memset (&intrinsic_sym, 0, sizeof (intrinsic_sym));
659 intrinsic_sym.ns = sym->ns;
660 intrinsic_sym.name = iname;
661 intrinsic_sym.ts = sym->ts;
662 intrinsic_sym.attr.referenced = 1;
663 intrinsic_sym.attr.intrinsic = 1;
664 intrinsic_sym.attr.function = 1;
665 intrinsic_sym.result = &intrinsic_sym;
666 intrinsic_sym.declared_at = where;
667
668 symtree4 = gfc_new_symtree (&root4, iname);
669 symtree4->n.sym = &intrinsic_sym;
670 gcc_assert (symtree4 == root4);
671
672 e4 = gfc_get_expr ();
673 e4->expr_type = EXPR_FUNCTION;
674 e4->where = where;
675 e4->symtree = symtree4;
676 e4->value.function.isym = gfc_find_function (iname);
677 e4->value.function.actual = gfc_get_actual_arglist ();
678 e4->value.function.actual->expr = e3;
679 e4->value.function.actual->next = gfc_get_actual_arglist ();
680 e4->value.function.actual->next->expr = e1;
681 }
682 /* e1 and e3 have been stored as arguments of e4, avoid sharing. */
683 e1 = gfc_copy_expr (e1);
684 e3 = gfc_copy_expr (e3);
685 t = gfc_resolve_expr (e4);
524af0d6 686 gcc_assert (t);
6c7a4dfd
JJ
687
688 /* Create the init statement list. */
87a60f68 689 pushlevel ();
af3fcdb4
JJ
690 if (GFC_DESCRIPTOR_TYPE_P (type)
691 && GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_ALLOCATABLE)
a68ab351
JJ
692 {
693 /* If decl is an allocatable array, it needs to be allocated
694 with the same bounds as the outer var. */
af3fcdb4 695 tree rank, size, esize, ptr;
a68ab351
JJ
696 stmtblock_t block;
697
698 gfc_start_block (&block);
699
726a989a 700 gfc_add_modify (&block, decl, outer_sym.backend_decl);
a68ab351 701 rank = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (type) - 1];
568e8e1e 702 size = gfc_conv_descriptor_ubound_get (decl, rank);
65a9ca82
TB
703 size = fold_build2_loc (input_location, MINUS_EXPR,
704 gfc_array_index_type, size,
705 gfc_conv_descriptor_lbound_get (decl, rank));
706 size = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
707 size, gfc_index_one_node);
a68ab351 708 if (GFC_TYPE_ARRAY_RANK (type) > 1)
65a9ca82
TB
709 size = fold_build2_loc (input_location, MULT_EXPR,
710 gfc_array_index_type, size,
711 gfc_conv_descriptor_stride_get (decl, rank));
a68ab351
JJ
712 esize = fold_convert (gfc_array_index_type,
713 TYPE_SIZE_UNIT (gfc_get_element_type (type)));
65a9ca82
TB
714 size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
715 size, esize);
a68ab351 716 size = gfc_evaluate_now (fold_convert (size_type_node, size), &block);
4f13e17f
DC
717
718 ptr = gfc_create_var (pvoid_type_node, NULL);
719 gfc_allocate_using_malloc (&block, ptr, size, NULL_TREE);
726a989a 720 gfc_conv_descriptor_data_set (&block, decl, ptr);
4f13e17f 721
2b56d6a4
TB
722 gfc_add_expr_to_block (&block, gfc_trans_assignment (e1, e2, false,
723 false));
a68ab351
JJ
724 stmt = gfc_finish_block (&block);
725 }
726 else
2b56d6a4 727 stmt = gfc_trans_assignment (e1, e2, false, false);
5b8fdd1f 728 if (TREE_CODE (stmt) != BIND_EXPR)
87a60f68 729 stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
5b8fdd1f 730 else
87a60f68 731 poplevel (0, 0);
5b8fdd1f 732 OMP_CLAUSE_REDUCTION_INIT (c) = stmt;
6c7a4dfd
JJ
733
734 /* Create the merge statement list. */
87a60f68 735 pushlevel ();
af3fcdb4
JJ
736 if (GFC_DESCRIPTOR_TYPE_P (type)
737 && GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_ALLOCATABLE)
a68ab351
JJ
738 {
739 /* If decl is an allocatable array, it needs to be deallocated
740 afterwards. */
741 stmtblock_t block;
742
743 gfc_start_block (&block);
2b56d6a4
TB
744 gfc_add_expr_to_block (&block, gfc_trans_assignment (e3, e4, false,
745 true));
ef292537
TB
746 gfc_add_expr_to_block (&block, gfc_trans_dealloc_allocated (decl, false,
747 NULL));
a68ab351
JJ
748 stmt = gfc_finish_block (&block);
749 }
750 else
2b56d6a4 751 stmt = gfc_trans_assignment (e3, e4, false, true);
5b8fdd1f 752 if (TREE_CODE (stmt) != BIND_EXPR)
87a60f68 753 stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
5b8fdd1f 754 else
87a60f68 755 poplevel (0, 0);
5b8fdd1f 756 OMP_CLAUSE_REDUCTION_MERGE (c) = stmt;
6c7a4dfd
JJ
757
758 /* And stick the placeholder VAR_DECL into the clause as well. */
af3fcdb4 759 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = outer_decl;
6c7a4dfd
JJ
760
761 gfc_current_locus = old_loc;
762
763 gfc_free_expr (e1);
764 gfc_free_expr (e2);
765 gfc_free_expr (e3);
766 gfc_free_expr (e4);
cede9502
JM
767 free (symtree1);
768 free (symtree2);
769 free (symtree3);
04695783 770 free (symtree4);
6c7a4dfd
JJ
771 gfc_free_array_spec (outer_sym.as);
772}
773
774static tree
dd2fc525 775gfc_trans_omp_reduction_list (gfc_omp_namelist *namelist, tree list,
11a5f608 776 enum tree_code reduction_code, locus where)
6c7a4dfd
JJ
777{
778 for (; namelist != NULL; namelist = namelist->next)
779 if (namelist->sym->attr.referenced)
780 {
dd2fc525 781 tree t = gfc_trans_omp_variable (namelist->sym, false);
6c7a4dfd
JJ
782 if (t != error_mark_node)
783 {
c2255bc4
AH
784 tree node = build_omp_clause (where.lb->location,
785 OMP_CLAUSE_REDUCTION);
6c7a4dfd
JJ
786 OMP_CLAUSE_DECL (node) = t;
787 OMP_CLAUSE_REDUCTION_CODE (node) = reduction_code;
788 if (namelist->sym->attr.dimension)
789 gfc_trans_omp_array_reduction (node, namelist->sym, where);
790 list = gfc_trans_add_clause (node, list);
791 }
792 }
793 return list;
794}
795
796static tree
797gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
dd2fc525 798 locus where, bool declare_simd = false)
6c7a4dfd 799{
c4fae39e 800 tree omp_clauses = NULL_TREE, chunk_size, c;
6c7a4dfd
JJ
801 int list;
802 enum omp_clause_code clause_code;
803 gfc_se se;
804
805 if (clauses == NULL)
806 return NULL_TREE;
807
808 for (list = 0; list < OMP_LIST_NUM; list++)
809 {
dd2fc525 810 gfc_omp_namelist *n = clauses->lists[list];
6c7a4dfd
JJ
811
812 if (n == NULL)
813 continue;
814 if (list >= OMP_LIST_REDUCTION_FIRST
815 && list <= OMP_LIST_REDUCTION_LAST)
816 {
817 enum tree_code reduction_code;
818 switch (list)
819 {
820 case OMP_LIST_PLUS:
821 reduction_code = PLUS_EXPR;
822 break;
823 case OMP_LIST_MULT:
824 reduction_code = MULT_EXPR;
825 break;
826 case OMP_LIST_SUB:
827 reduction_code = MINUS_EXPR;
828 break;
829 case OMP_LIST_AND:
830 reduction_code = TRUTH_ANDIF_EXPR;
831 break;
832 case OMP_LIST_OR:
833 reduction_code = TRUTH_ORIF_EXPR;
834 break;
835 case OMP_LIST_EQV:
836 reduction_code = EQ_EXPR;
837 break;
838 case OMP_LIST_NEQV:
839 reduction_code = NE_EXPR;
840 break;
841 case OMP_LIST_MAX:
842 reduction_code = MAX_EXPR;
843 break;
844 case OMP_LIST_MIN:
845 reduction_code = MIN_EXPR;
846 break;
847 case OMP_LIST_IAND:
848 reduction_code = BIT_AND_EXPR;
849 break;
850 case OMP_LIST_IOR:
851 reduction_code = BIT_IOR_EXPR;
852 break;
853 case OMP_LIST_IEOR:
854 reduction_code = BIT_XOR_EXPR;
855 break;
856 default:
857 gcc_unreachable ();
858 }
6c7a4dfd
JJ
859 omp_clauses
860 = gfc_trans_omp_reduction_list (n, omp_clauses, reduction_code,
861 where);
862 continue;
863 }
864 switch (list)
865 {
866 case OMP_LIST_PRIVATE:
867 clause_code = OMP_CLAUSE_PRIVATE;
868 goto add_clause;
869 case OMP_LIST_SHARED:
870 clause_code = OMP_CLAUSE_SHARED;
871 goto add_clause;
872 case OMP_LIST_FIRSTPRIVATE:
873 clause_code = OMP_CLAUSE_FIRSTPRIVATE;
874 goto add_clause;
875 case OMP_LIST_LASTPRIVATE:
876 clause_code = OMP_CLAUSE_LASTPRIVATE;
877 goto add_clause;
878 case OMP_LIST_COPYIN:
879 clause_code = OMP_CLAUSE_COPYIN;
880 goto add_clause;
881 case OMP_LIST_COPYPRIVATE:
882 clause_code = OMP_CLAUSE_COPYPRIVATE;
dd2fc525
JJ
883 goto add_clause;
884 case OMP_LIST_UNIFORM:
885 clause_code = OMP_CLAUSE_UNIFORM;
6c7a4dfd
JJ
886 /* FALLTHROUGH */
887 add_clause:
888 omp_clauses
dd2fc525
JJ
889 = gfc_trans_omp_variable_list (clause_code, n, omp_clauses,
890 declare_simd);
891 break;
892 case OMP_LIST_ALIGNED:
893 for (; n != NULL; n = n->next)
894 if (n->sym->attr.referenced || declare_simd)
895 {
896 tree t = gfc_trans_omp_variable (n->sym, declare_simd);
897 if (t != error_mark_node)
898 {
899 tree node = build_omp_clause (input_location,
900 OMP_CLAUSE_ALIGNED);
901 OMP_CLAUSE_DECL (node) = t;
902 if (n->expr)
903 {
904 tree alignment_var;
905
906 if (block == NULL)
907 alignment_var = gfc_conv_constant_to_tree (n->expr);
908 else
909 {
910 gfc_init_se (&se, NULL);
911 gfc_conv_expr (&se, n->expr);
912 gfc_add_block_to_block (block, &se.pre);
913 alignment_var = gfc_evaluate_now (se.expr, block);
914 gfc_add_block_to_block (block, &se.post);
915 }
916 OMP_CLAUSE_ALIGNED_ALIGNMENT (node) = alignment_var;
917 }
918 omp_clauses = gfc_trans_add_clause (node, omp_clauses);
919 }
920 }
921 break;
922 case OMP_LIST_LINEAR:
923 {
924 gfc_expr *last_step_expr = NULL;
925 tree last_step = NULL_TREE;
926
927 for (; n != NULL; n = n->next)
928 {
929 if (n->expr)
930 {
931 last_step_expr = n->expr;
932 last_step = NULL_TREE;
933 }
934 if (n->sym->attr.referenced || declare_simd)
935 {
936 tree t = gfc_trans_omp_variable (n->sym, declare_simd);
937 if (t != error_mark_node)
938 {
939 tree node = build_omp_clause (input_location,
940 OMP_CLAUSE_LINEAR);
941 OMP_CLAUSE_DECL (node) = t;
942 if (last_step_expr && last_step == NULL_TREE)
943 {
944 if (block == NULL)
945 last_step
946 = gfc_conv_constant_to_tree (last_step_expr);
947 else
948 {
949 gfc_init_se (&se, NULL);
950 gfc_conv_expr (&se, last_step_expr);
951 gfc_add_block_to_block (block, &se.pre);
952 last_step = gfc_evaluate_now (se.expr, block);
953 gfc_add_block_to_block (block, &se.post);
954 }
955 }
956 OMP_CLAUSE_LINEAR_STEP (node) = last_step;
957 omp_clauses = gfc_trans_add_clause (node, omp_clauses);
958 }
959 }
960 }
961 }
962 break;
963 case OMP_LIST_DEPEND_IN:
964 case OMP_LIST_DEPEND_OUT:
965 for (; n != NULL; n = n->next)
966 {
967 if (!n->sym->attr.referenced)
968 continue;
969
970 tree node = build_omp_clause (input_location, OMP_CLAUSE_DEPEND);
971 if (n->expr == NULL || n->expr->ref->u.ar.type == AR_FULL)
972 {
973 OMP_CLAUSE_DECL (node) = gfc_get_symbol_decl (n->sym);
974 if (DECL_P (OMP_CLAUSE_DECL (node)))
975 TREE_ADDRESSABLE (OMP_CLAUSE_DECL (node)) = 1;
976 }
977 else
978 {
979 tree ptr;
980 gfc_init_se (&se, NULL);
981 if (n->expr->ref->u.ar.type == AR_ELEMENT)
982 {
983 gfc_conv_expr_reference (&se, n->expr);
984 ptr = se.expr;
985 }
986 else
987 {
988 gfc_conv_expr_descriptor (&se, n->expr);
989 ptr = gfc_conv_array_data (se.expr);
990 }
991 gfc_add_block_to_block (block, &se.pre);
992 gfc_add_block_to_block (block, &se.post);
993 OMP_CLAUSE_DECL (node)
994 = fold_build1_loc (input_location, INDIRECT_REF,
995 TREE_TYPE (TREE_TYPE (ptr)), ptr);
996 }
997 OMP_CLAUSE_DEPEND_KIND (node)
998 = ((list == OMP_LIST_DEPEND_IN)
999 ? OMP_CLAUSE_DEPEND_IN : OMP_CLAUSE_DEPEND_OUT);
1000 omp_clauses = gfc_trans_add_clause (node, omp_clauses);
1001 }
6c7a4dfd
JJ
1002 break;
1003 default:
1004 break;
1005 }
1006 }
1007
1008 if (clauses->if_expr)
1009 {
1010 tree if_var;
1011
1012 gfc_init_se (&se, NULL);
1013 gfc_conv_expr (&se, clauses->if_expr);
1014 gfc_add_block_to_block (block, &se.pre);
1015 if_var = gfc_evaluate_now (se.expr, block);
1016 gfc_add_block_to_block (block, &se.post);
1017
c2255bc4 1018 c = build_omp_clause (where.lb->location, OMP_CLAUSE_IF);
6c7a4dfd
JJ
1019 OMP_CLAUSE_IF_EXPR (c) = if_var;
1020 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
1021 }
1022
20906c66
JJ
1023 if (clauses->final_expr)
1024 {
1025 tree final_var;
1026
1027 gfc_init_se (&se, NULL);
1028 gfc_conv_expr (&se, clauses->final_expr);
1029 gfc_add_block_to_block (block, &se.pre);
1030 final_var = gfc_evaluate_now (se.expr, block);
1031 gfc_add_block_to_block (block, &se.post);
1032
1033 c = build_omp_clause (where.lb->location, OMP_CLAUSE_FINAL);
1034 OMP_CLAUSE_FINAL_EXPR (c) = final_var;
1035 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
1036 }
1037
6c7a4dfd
JJ
1038 if (clauses->num_threads)
1039 {
1040 tree num_threads;
1041
1042 gfc_init_se (&se, NULL);
1043 gfc_conv_expr (&se, clauses->num_threads);
1044 gfc_add_block_to_block (block, &se.pre);
1045 num_threads = gfc_evaluate_now (se.expr, block);
1046 gfc_add_block_to_block (block, &se.post);
1047
c2255bc4 1048 c = build_omp_clause (where.lb->location, OMP_CLAUSE_NUM_THREADS);
6c7a4dfd
JJ
1049 OMP_CLAUSE_NUM_THREADS_EXPR (c) = num_threads;
1050 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
1051 }
1052
1053 chunk_size = NULL_TREE;
1054 if (clauses->chunk_size)
1055 {
1056 gfc_init_se (&se, NULL);
1057 gfc_conv_expr (&se, clauses->chunk_size);
1058 gfc_add_block_to_block (block, &se.pre);
1059 chunk_size = gfc_evaluate_now (se.expr, block);
1060 gfc_add_block_to_block (block, &se.post);
1061 }
1062
1063 if (clauses->sched_kind != OMP_SCHED_NONE)
1064 {
c2255bc4 1065 c = build_omp_clause (where.lb->location, OMP_CLAUSE_SCHEDULE);
6c7a4dfd
JJ
1066 OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = chunk_size;
1067 switch (clauses->sched_kind)
1068 {
1069 case OMP_SCHED_STATIC:
1070 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_STATIC;
1071 break;
1072 case OMP_SCHED_DYNAMIC:
1073 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_DYNAMIC;
1074 break;
1075 case OMP_SCHED_GUIDED:
1076 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_GUIDED;
1077 break;
1078 case OMP_SCHED_RUNTIME:
1079 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_RUNTIME;
1080 break;
a68ab351
JJ
1081 case OMP_SCHED_AUTO:
1082 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_AUTO;
1083 break;
6c7a4dfd
JJ
1084 default:
1085 gcc_unreachable ();
1086 }
1087 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
1088 }
1089
1090 if (clauses->default_sharing != OMP_DEFAULT_UNKNOWN)
1091 {
c2255bc4 1092 c = build_omp_clause (where.lb->location, OMP_CLAUSE_DEFAULT);
6c7a4dfd
JJ
1093 switch (clauses->default_sharing)
1094 {
1095 case OMP_DEFAULT_NONE:
1096 OMP_CLAUSE_DEFAULT_KIND (c) = OMP_CLAUSE_DEFAULT_NONE;
1097 break;
1098 case OMP_DEFAULT_SHARED:
1099 OMP_CLAUSE_DEFAULT_KIND (c) = OMP_CLAUSE_DEFAULT_SHARED;
1100 break;
1101 case OMP_DEFAULT_PRIVATE:
1102 OMP_CLAUSE_DEFAULT_KIND (c) = OMP_CLAUSE_DEFAULT_PRIVATE;
1103 break;
a68ab351
JJ
1104 case OMP_DEFAULT_FIRSTPRIVATE:
1105 OMP_CLAUSE_DEFAULT_KIND (c) = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
1106 break;
6c7a4dfd
JJ
1107 default:
1108 gcc_unreachable ();
1109 }
1110 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
1111 }
1112
1113 if (clauses->nowait)
1114 {
c2255bc4 1115 c = build_omp_clause (where.lb->location, OMP_CLAUSE_NOWAIT);
6c7a4dfd
JJ
1116 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
1117 }
1118
1119 if (clauses->ordered)
1120 {
c2255bc4 1121 c = build_omp_clause (where.lb->location, OMP_CLAUSE_ORDERED);
6c7a4dfd
JJ
1122 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
1123 }
1124
a68ab351
JJ
1125 if (clauses->untied)
1126 {
c2255bc4 1127 c = build_omp_clause (where.lb->location, OMP_CLAUSE_UNTIED);
a68ab351
JJ
1128 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
1129 }
1130
20906c66
JJ
1131 if (clauses->mergeable)
1132 {
1133 c = build_omp_clause (where.lb->location, OMP_CLAUSE_MERGEABLE);
1134 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
1135 }
1136
a68ab351
JJ
1137 if (clauses->collapse)
1138 {
c2255bc4 1139 c = build_omp_clause (where.lb->location, OMP_CLAUSE_COLLAPSE);
df09d1d5
RG
1140 OMP_CLAUSE_COLLAPSE_EXPR (c)
1141 = build_int_cst (integer_type_node, clauses->collapse);
a68ab351
JJ
1142 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
1143 }
1144
dd2fc525
JJ
1145 if (clauses->inbranch)
1146 {
1147 c = build_omp_clause (where.lb->location, OMP_CLAUSE_INBRANCH);
1148 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
1149 }
1150
1151 if (clauses->notinbranch)
1152 {
1153 c = build_omp_clause (where.lb->location, OMP_CLAUSE_NOTINBRANCH);
1154 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
1155 }
1156
1157 switch (clauses->cancel)
1158 {
1159 case OMP_CANCEL_UNKNOWN:
1160 break;
1161 case OMP_CANCEL_PARALLEL:
1162 c = build_omp_clause (where.lb->location, OMP_CLAUSE_PARALLEL);
1163 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
1164 break;
1165 case OMP_CANCEL_SECTIONS:
1166 c = build_omp_clause (where.lb->location, OMP_CLAUSE_SECTIONS);
1167 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
1168 break;
1169 case OMP_CANCEL_DO:
1170 c = build_omp_clause (where.lb->location, OMP_CLAUSE_FOR);
1171 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
1172 break;
1173 case OMP_CANCEL_TASKGROUP:
1174 c = build_omp_clause (where.lb->location, OMP_CLAUSE_TASKGROUP);
1175 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
1176 break;
1177 }
1178
1179 if (clauses->proc_bind != OMP_PROC_BIND_UNKNOWN)
1180 {
1181 c = build_omp_clause (where.lb->location, OMP_CLAUSE_PROC_BIND);
1182 switch (clauses->proc_bind)
1183 {
1184 case OMP_PROC_BIND_MASTER:
1185 OMP_CLAUSE_PROC_BIND_KIND (c) = OMP_CLAUSE_PROC_BIND_MASTER;
1186 break;
1187 case OMP_PROC_BIND_SPREAD:
1188 OMP_CLAUSE_PROC_BIND_KIND (c) = OMP_CLAUSE_PROC_BIND_SPREAD;
1189 break;
1190 case OMP_PROC_BIND_CLOSE:
1191 OMP_CLAUSE_PROC_BIND_KIND (c) = OMP_CLAUSE_PROC_BIND_CLOSE;
1192 break;
1193 default:
1194 gcc_unreachable ();
1195 }
1196 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
1197 }
1198
1199 if (clauses->safelen_expr)
1200 {
1201 tree safelen_var;
1202
1203 gfc_init_se (&se, NULL);
1204 gfc_conv_expr (&se, clauses->safelen_expr);
1205 gfc_add_block_to_block (block, &se.pre);
1206 safelen_var = gfc_evaluate_now (se.expr, block);
1207 gfc_add_block_to_block (block, &se.post);
1208
1209 c = build_omp_clause (where.lb->location, OMP_CLAUSE_SAFELEN);
1210 OMP_CLAUSE_SAFELEN_EXPR (c) = safelen_var;
1211 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
1212 }
1213
1214 if (clauses->simdlen_expr)
1215 {
1216 c = build_omp_clause (where.lb->location, OMP_CLAUSE_SIMDLEN);
1217 OMP_CLAUSE_SIMDLEN_EXPR (c)
1218 = gfc_conv_constant_to_tree (clauses->simdlen_expr);
1219 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
1220 }
1221
6c7a4dfd
JJ
1222 return omp_clauses;
1223}
1224
1225/* Like gfc_trans_code, but force creation of a BIND_EXPR around it. */
1226
1227static tree
1228gfc_trans_omp_code (gfc_code *code, bool force_empty)
1229{
1230 tree stmt;
1231
87a60f68 1232 pushlevel ();
6c7a4dfd
JJ
1233 stmt = gfc_trans_code (code);
1234 if (TREE_CODE (stmt) != BIND_EXPR)
1235 {
1236 if (!IS_EMPTY_STMT (stmt) || force_empty)
1237 {
87a60f68 1238 tree block = poplevel (1, 0);
6c7a4dfd
JJ
1239 stmt = build3_v (BIND_EXPR, NULL, stmt, block);
1240 }
1241 else
87a60f68 1242 poplevel (0, 0);
6c7a4dfd
JJ
1243 }
1244 else
87a60f68 1245 poplevel (0, 0);
6c7a4dfd
JJ
1246 return stmt;
1247}
1248
1249
1250static tree gfc_trans_omp_sections (gfc_code *, gfc_omp_clauses *);
1251static tree gfc_trans_omp_workshare (gfc_code *, gfc_omp_clauses *);
1252
1253static tree
1254gfc_trans_omp_atomic (gfc_code *code)
1255{
20906c66 1256 gfc_code *atomic_code = code;
6c7a4dfd
JJ
1257 gfc_se lse;
1258 gfc_se rse;
20906c66 1259 gfc_se vse;
6c7a4dfd
JJ
1260 gfc_expr *expr2, *e;
1261 gfc_symbol *var;
1262 stmtblock_t block;
1263 tree lhsaddr, type, rhs, x;
1264 enum tree_code op = ERROR_MARK;
20906c66 1265 enum tree_code aop = OMP_ATOMIC;
6c7a4dfd 1266 bool var_on_left = false;
dd2fc525 1267 bool seq_cst = (atomic_code->ext.omp_atomic & GFC_OMP_ATOMIC_SEQ_CST) != 0;
6c7a4dfd
JJ
1268
1269 code = code->block->next;
1270 gcc_assert (code->op == EXEC_ASSIGN);
a513927a 1271 var = code->expr1->symtree->n.sym;
6c7a4dfd
JJ
1272
1273 gfc_init_se (&lse, NULL);
1274 gfc_init_se (&rse, NULL);
20906c66 1275 gfc_init_se (&vse, NULL);
6c7a4dfd
JJ
1276 gfc_start_block (&block);
1277
6c7a4dfd
JJ
1278 expr2 = code->expr2;
1279 if (expr2->expr_type == EXPR_FUNCTION
cd5ecab6 1280 && expr2->value.function.isym->id == GFC_ISYM_CONVERSION)
6c7a4dfd
JJ
1281 expr2 = expr2->value.function.actual->expr;
1282
dd2fc525 1283 switch (atomic_code->ext.omp_atomic & GFC_OMP_ATOMIC_MASK)
20906c66
JJ
1284 {
1285 case GFC_OMP_ATOMIC_READ:
1286 gfc_conv_expr (&vse, code->expr1);
1287 gfc_add_block_to_block (&block, &vse.pre);
1288
1289 gfc_conv_expr (&lse, expr2);
1290 gfc_add_block_to_block (&block, &lse.pre);
1291 type = TREE_TYPE (lse.expr);
1292 lhsaddr = gfc_build_addr_expr (NULL, lse.expr);
1293
1294 x = build1 (OMP_ATOMIC_READ, type, lhsaddr);
dd2fc525 1295 OMP_ATOMIC_SEQ_CST (x) = seq_cst;
20906c66
JJ
1296 x = convert (TREE_TYPE (vse.expr), x);
1297 gfc_add_modify (&block, vse.expr, x);
1298
1299 gfc_add_block_to_block (&block, &lse.pre);
1300 gfc_add_block_to_block (&block, &rse.pre);
1301
1302 return gfc_finish_block (&block);
1303 case GFC_OMP_ATOMIC_CAPTURE:
1304 aop = OMP_ATOMIC_CAPTURE_NEW;
1305 if (expr2->expr_type == EXPR_VARIABLE)
1306 {
1307 aop = OMP_ATOMIC_CAPTURE_OLD;
1308 gfc_conv_expr (&vse, code->expr1);
1309 gfc_add_block_to_block (&block, &vse.pre);
1310
1311 gfc_conv_expr (&lse, expr2);
1312 gfc_add_block_to_block (&block, &lse.pre);
1313 gfc_init_se (&lse, NULL);
1314 code = code->next;
1315 var = code->expr1->symtree->n.sym;
1316 expr2 = code->expr2;
1317 if (expr2->expr_type == EXPR_FUNCTION
1318 && expr2->value.function.isym->id == GFC_ISYM_CONVERSION)
1319 expr2 = expr2->value.function.actual->expr;
1320 }
1321 break;
1322 default:
1323 break;
1324 }
1325
1326 gfc_conv_expr (&lse, code->expr1);
1327 gfc_add_block_to_block (&block, &lse.pre);
1328 type = TREE_TYPE (lse.expr);
1329 lhsaddr = gfc_build_addr_expr (NULL, lse.expr);
1330
dd2fc525
JJ
1331 if (((atomic_code->ext.omp_atomic & GFC_OMP_ATOMIC_MASK)
1332 == GFC_OMP_ATOMIC_WRITE)
1333 || (atomic_code->ext.omp_atomic & GFC_OMP_ATOMIC_SWAP))
20906c66
JJ
1334 {
1335 gfc_conv_expr (&rse, expr2);
1336 gfc_add_block_to_block (&block, &rse.pre);
1337 }
1338 else if (expr2->expr_type == EXPR_OP)
6c7a4dfd
JJ
1339 {
1340 gfc_expr *e;
a1ee985f 1341 switch (expr2->value.op.op)
6c7a4dfd
JJ
1342 {
1343 case INTRINSIC_PLUS:
1344 op = PLUS_EXPR;
1345 break;
1346 case INTRINSIC_TIMES:
1347 op = MULT_EXPR;
1348 break;
1349 case INTRINSIC_MINUS:
1350 op = MINUS_EXPR;
1351 break;
1352 case INTRINSIC_DIVIDE:
1353 if (expr2->ts.type == BT_INTEGER)
1354 op = TRUNC_DIV_EXPR;
1355 else
1356 op = RDIV_EXPR;
1357 break;
1358 case INTRINSIC_AND:
1359 op = TRUTH_ANDIF_EXPR;
1360 break;
1361 case INTRINSIC_OR:
1362 op = TRUTH_ORIF_EXPR;
1363 break;
1364 case INTRINSIC_EQV:
1365 op = EQ_EXPR;
1366 break;
1367 case INTRINSIC_NEQV:
1368 op = NE_EXPR;
1369 break;
1370 default:
1371 gcc_unreachable ();
1372 }
1373 e = expr2->value.op.op1;
1374 if (e->expr_type == EXPR_FUNCTION
cd5ecab6 1375 && e->value.function.isym->id == GFC_ISYM_CONVERSION)
6c7a4dfd
JJ
1376 e = e->value.function.actual->expr;
1377 if (e->expr_type == EXPR_VARIABLE
1378 && e->symtree != NULL
1379 && e->symtree->n.sym == var)
1380 {
1381 expr2 = expr2->value.op.op2;
1382 var_on_left = true;
1383 }
1384 else
1385 {
1386 e = expr2->value.op.op2;
1387 if (e->expr_type == EXPR_FUNCTION
cd5ecab6 1388 && e->value.function.isym->id == GFC_ISYM_CONVERSION)
6c7a4dfd
JJ
1389 e = e->value.function.actual->expr;
1390 gcc_assert (e->expr_type == EXPR_VARIABLE
1391 && e->symtree != NULL
1392 && e->symtree->n.sym == var);
1393 expr2 = expr2->value.op.op1;
1394 var_on_left = false;
1395 }
1396 gfc_conv_expr (&rse, expr2);
1397 gfc_add_block_to_block (&block, &rse.pre);
1398 }
1399 else
1400 {
1401 gcc_assert (expr2->expr_type == EXPR_FUNCTION);
cd5ecab6 1402 switch (expr2->value.function.isym->id)
6c7a4dfd
JJ
1403 {
1404 case GFC_ISYM_MIN:
1405 op = MIN_EXPR;
1406 break;
1407 case GFC_ISYM_MAX:
1408 op = MAX_EXPR;
1409 break;
1410 case GFC_ISYM_IAND:
1411 op = BIT_AND_EXPR;
1412 break;
1413 case GFC_ISYM_IOR:
1414 op = BIT_IOR_EXPR;
1415 break;
1416 case GFC_ISYM_IEOR:
1417 op = BIT_XOR_EXPR;
1418 break;
1419 default:
1420 gcc_unreachable ();
1421 }
1422 e = expr2->value.function.actual->expr;
1423 gcc_assert (e->expr_type == EXPR_VARIABLE
1424 && e->symtree != NULL
1425 && e->symtree->n.sym == var);
1426
1427 gfc_conv_expr (&rse, expr2->value.function.actual->next->expr);
1428 gfc_add_block_to_block (&block, &rse.pre);
1429 if (expr2->value.function.actual->next->next != NULL)
1430 {
1431 tree accum = gfc_create_var (TREE_TYPE (rse.expr), NULL);
1432 gfc_actual_arglist *arg;
1433
726a989a 1434 gfc_add_modify (&block, accum, rse.expr);
6c7a4dfd
JJ
1435 for (arg = expr2->value.function.actual->next->next; arg;
1436 arg = arg->next)
1437 {
1438 gfc_init_block (&rse.pre);
1439 gfc_conv_expr (&rse, arg->expr);
1440 gfc_add_block_to_block (&block, &rse.pre);
65a9ca82
TB
1441 x = fold_build2_loc (input_location, op, TREE_TYPE (accum),
1442 accum, rse.expr);
726a989a 1443 gfc_add_modify (&block, accum, x);
6c7a4dfd
JJ
1444 }
1445
1446 rse.expr = accum;
1447 }
1448
1449 expr2 = expr2->value.function.actual->next->expr;
1450 }
1451
1452 lhsaddr = save_expr (lhsaddr);
1453 rhs = gfc_evaluate_now (rse.expr, &block);
6c7a4dfd 1454
dd2fc525
JJ
1455 if (((atomic_code->ext.omp_atomic & GFC_OMP_ATOMIC_MASK)
1456 == GFC_OMP_ATOMIC_WRITE)
1457 || (atomic_code->ext.omp_atomic & GFC_OMP_ATOMIC_SWAP))
20906c66 1458 x = rhs;
6c7a4dfd 1459 else
20906c66
JJ
1460 {
1461 x = convert (TREE_TYPE (rhs),
1462 build_fold_indirect_ref_loc (input_location, lhsaddr));
1463 if (var_on_left)
1464 x = fold_build2_loc (input_location, op, TREE_TYPE (rhs), x, rhs);
1465 else
1466 x = fold_build2_loc (input_location, op, TREE_TYPE (rhs), rhs, x);
1467 }
6c7a4dfd
JJ
1468
1469 if (TREE_CODE (TREE_TYPE (rhs)) == COMPLEX_TYPE
1470 && TREE_CODE (type) != COMPLEX_TYPE)
65a9ca82
TB
1471 x = fold_build1_loc (input_location, REALPART_EXPR,
1472 TREE_TYPE (TREE_TYPE (rhs)), x);
6c7a4dfd 1473
6c7a4dfd
JJ
1474 gfc_add_block_to_block (&block, &lse.pre);
1475 gfc_add_block_to_block (&block, &rse.pre);
1476
20906c66
JJ
1477 if (aop == OMP_ATOMIC)
1478 {
1479 x = build2_v (OMP_ATOMIC, lhsaddr, convert (type, x));
dd2fc525 1480 OMP_ATOMIC_SEQ_CST (x) = seq_cst;
20906c66
JJ
1481 gfc_add_expr_to_block (&block, x);
1482 }
1483 else
1484 {
1485 if (aop == OMP_ATOMIC_CAPTURE_NEW)
1486 {
1487 code = code->next;
1488 expr2 = code->expr2;
1489 if (expr2->expr_type == EXPR_FUNCTION
1490 && expr2->value.function.isym->id == GFC_ISYM_CONVERSION)
1491 expr2 = expr2->value.function.actual->expr;
1492
1493 gcc_assert (expr2->expr_type == EXPR_VARIABLE);
1494 gfc_conv_expr (&vse, code->expr1);
1495 gfc_add_block_to_block (&block, &vse.pre);
1496
1497 gfc_init_se (&lse, NULL);
1498 gfc_conv_expr (&lse, expr2);
1499 gfc_add_block_to_block (&block, &lse.pre);
1500 }
1501 x = build2 (aop, type, lhsaddr, convert (type, x));
dd2fc525 1502 OMP_ATOMIC_SEQ_CST (x) = seq_cst;
20906c66
JJ
1503 x = convert (TREE_TYPE (vse.expr), x);
1504 gfc_add_modify (&block, vse.expr, x);
1505 }
1506
6c7a4dfd
JJ
1507 return gfc_finish_block (&block);
1508}
1509
1510static tree
1511gfc_trans_omp_barrier (void)
1512{
e79983f4 1513 tree decl = builtin_decl_explicit (BUILT_IN_GOMP_BARRIER);
db3927fb 1514 return build_call_expr_loc (input_location, decl, 0);
6c7a4dfd
JJ
1515}
1516
dd2fc525
JJ
1517static tree
1518gfc_trans_omp_cancel (gfc_code *code)
1519{
1520 int mask = 0;
1521 tree ifc = boolean_true_node;
1522 stmtblock_t block;
1523 switch (code->ext.omp_clauses->cancel)
1524 {
1525 case OMP_CANCEL_PARALLEL: mask = 1; break;
1526 case OMP_CANCEL_DO: mask = 2; break;
1527 case OMP_CANCEL_SECTIONS: mask = 4; break;
1528 case OMP_CANCEL_TASKGROUP: mask = 8; break;
1529 default: gcc_unreachable ();
1530 }
1531 gfc_start_block (&block);
1532 if (code->ext.omp_clauses->if_expr)
1533 {
1534 gfc_se se;
1535 tree if_var;
1536
1537 gfc_init_se (&se, NULL);
1538 gfc_conv_expr (&se, code->ext.omp_clauses->if_expr);
1539 gfc_add_block_to_block (&block, &se.pre);
1540 if_var = gfc_evaluate_now (se.expr, &block);
1541 gfc_add_block_to_block (&block, &se.post);
1542 tree type = TREE_TYPE (if_var);
1543 ifc = fold_build2_loc (input_location, NE_EXPR,
1544 boolean_type_node, if_var,
1545 build_zero_cst (type));
1546 }
1547 tree decl = builtin_decl_explicit (BUILT_IN_GOMP_CANCEL);
1548 tree c_bool_type = TREE_TYPE (TREE_TYPE (decl));
1549 ifc = fold_convert (c_bool_type, ifc);
1550 gfc_add_expr_to_block (&block,
1551 build_call_expr_loc (input_location, decl, 2,
1552 build_int_cst (integer_type_node,
1553 mask), ifc));
1554 return gfc_finish_block (&block);
1555}
1556
1557static tree
1558gfc_trans_omp_cancellation_point (gfc_code *code)
1559{
1560 int mask = 0;
1561 switch (code->ext.omp_clauses->cancel)
1562 {
1563 case OMP_CANCEL_PARALLEL: mask = 1; break;
1564 case OMP_CANCEL_DO: mask = 2; break;
1565 case OMP_CANCEL_SECTIONS: mask = 4; break;
1566 case OMP_CANCEL_TASKGROUP: mask = 8; break;
1567 default: gcc_unreachable ();
1568 }
1569 tree decl = builtin_decl_explicit (BUILT_IN_GOMP_CANCELLATION_POINT);
1570 return build_call_expr_loc (input_location, decl, 1,
1571 build_int_cst (integer_type_node, mask));
1572}
1573
6c7a4dfd
JJ
1574static tree
1575gfc_trans_omp_critical (gfc_code *code)
1576{
1577 tree name = NULL_TREE, stmt;
1578 if (code->ext.omp_name != NULL)
1579 name = get_identifier (code->ext.omp_name);
1580 stmt = gfc_trans_code (code->block->next);
5d44e5c8 1581 return build2_loc (input_location, OMP_CRITICAL, void_type_node, stmt, name);
6c7a4dfd
JJ
1582}
1583
04924d6a
NF
1584typedef struct dovar_init_d {
1585 tree var;
1586 tree init;
1587} dovar_init;
1588
04924d6a 1589
6c7a4dfd 1590static tree
dd2fc525 1591gfc_trans_omp_do (gfc_code *code, gfc_exec_op op, stmtblock_t *pblock,
a68ab351 1592 gfc_omp_clauses *do_clauses, tree par_clauses)
6c7a4dfd
JJ
1593{
1594 gfc_se se;
1595 tree dovar, stmt, from, to, step, type, init, cond, incr;
1596 tree count = NULL_TREE, cycle_label, tmp, omp_clauses;
1597 stmtblock_t block;
1598 stmtblock_t body;
742fae05 1599 gfc_omp_clauses *clauses = code->ext.omp_clauses;
a68ab351 1600 int i, collapse = clauses->collapse;
6e1aa848 1601 vec<dovar_init> inits = vNULL;
04924d6a
NF
1602 dovar_init *di;
1603 unsigned ix;
6c7a4dfd 1604
a68ab351
JJ
1605 if (collapse <= 0)
1606 collapse = 1;
1607
c4fae39e 1608 code = code->block->next;
6c7a4dfd
JJ
1609 gcc_assert (code->op == EXEC_DO);
1610
a68ab351
JJ
1611 init = make_tree_vec (collapse);
1612 cond = make_tree_vec (collapse);
1613 incr = make_tree_vec (collapse);
1614
6c7a4dfd
JJ
1615 if (pblock == NULL)
1616 {
1617 gfc_start_block (&block);
1618 pblock = &block;
1619 }
1620
742fae05 1621 omp_clauses = gfc_trans_omp_clauses (pblock, do_clauses, code->loc);
6c7a4dfd 1622
a68ab351 1623 for (i = 0; i < collapse; i++)
6c7a4dfd 1624 {
a68ab351
JJ
1625 int simple = 0;
1626 int dovar_found = 0;
281e33e1 1627 tree dovar_decl;
a68ab351
JJ
1628
1629 if (clauses)
6c7a4dfd 1630 {
dd2fc525
JJ
1631 gfc_omp_namelist *n;
1632 for (n = clauses->lists[(op == EXEC_OMP_SIMD && collapse == 1)
1633 ? OMP_LIST_LINEAR : OMP_LIST_LASTPRIVATE];
1634 n != NULL; n = n->next)
a68ab351
JJ
1635 if (code->ext.iterator->var->symtree->n.sym == n->sym)
1636 break;
1637 if (n != NULL)
1638 dovar_found = 1;
dd2fc525 1639 else if (n == NULL && op != EXEC_OMP_SIMD)
a68ab351
JJ
1640 for (n = clauses->lists[OMP_LIST_PRIVATE]; n != NULL; n = n->next)
1641 if (code->ext.iterator->var->symtree->n.sym == n->sym)
1642 break;
1643 if (n != NULL)
1644 dovar_found++;
6c7a4dfd 1645 }
a68ab351
JJ
1646
1647 /* Evaluate all the expressions in the iterator. */
1648 gfc_init_se (&se, NULL);
1649 gfc_conv_expr_lhs (&se, code->ext.iterator->var);
1650 gfc_add_block_to_block (pblock, &se.pre);
1651 dovar = se.expr;
1652 type = TREE_TYPE (dovar);
1653 gcc_assert (TREE_CODE (type) == INTEGER_TYPE);
1654
1655 gfc_init_se (&se, NULL);
1656 gfc_conv_expr_val (&se, code->ext.iterator->start);
1657 gfc_add_block_to_block (pblock, &se.pre);
1658 from = gfc_evaluate_now (se.expr, pblock);
1659
1660 gfc_init_se (&se, NULL);
1661 gfc_conv_expr_val (&se, code->ext.iterator->end);
1662 gfc_add_block_to_block (pblock, &se.pre);
1663 to = gfc_evaluate_now (se.expr, pblock);
1664
1665 gfc_init_se (&se, NULL);
1666 gfc_conv_expr_val (&se, code->ext.iterator->step);
1667 gfc_add_block_to_block (pblock, &se.pre);
1668 step = gfc_evaluate_now (se.expr, pblock);
281e33e1 1669 dovar_decl = dovar;
a68ab351
JJ
1670
1671 /* Special case simple loops. */
281e33e1
JJ
1672 if (TREE_CODE (dovar) == VAR_DECL)
1673 {
1674 if (integer_onep (step))
1675 simple = 1;
1676 else if (tree_int_cst_equal (step, integer_minus_one_node))
1677 simple = -1;
1678 }
1679 else
1680 dovar_decl
dd2fc525
JJ
1681 = gfc_trans_omp_variable (code->ext.iterator->var->symtree->n.sym,
1682 false);
a68ab351
JJ
1683
1684 /* Loop body. */
1685 if (simple)
6c7a4dfd 1686 {
726a989a 1687 TREE_VEC_ELT (init, i) = build2_v (MODIFY_EXPR, dovar, from);
edaadf74
JJ
1688 /* The condition should not be folded. */
1689 TREE_VEC_ELT (cond, i) = build2_loc (input_location, simple > 0
1690 ? LE_EXPR : GE_EXPR,
1691 boolean_type_node, dovar, to);
65a9ca82
TB
1692 TREE_VEC_ELT (incr, i) = fold_build2_loc (input_location, PLUS_EXPR,
1693 type, dovar, step);
1694 TREE_VEC_ELT (incr, i) = fold_build2_loc (input_location,
1695 MODIFY_EXPR,
1696 type, dovar,
1697 TREE_VEC_ELT (incr, i));
a68ab351
JJ
1698 }
1699 else
1700 {
1701 /* STEP is not 1 or -1. Use:
1702 for (count = 0; count < (to + step - from) / step; count++)
1703 {
1704 dovar = from + count * step;
1705 body;
1706 cycle_label:;
1707 } */
65a9ca82
TB
1708 tmp = fold_build2_loc (input_location, MINUS_EXPR, type, step, from);
1709 tmp = fold_build2_loc (input_location, PLUS_EXPR, type, to, tmp);
1710 tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR, type, tmp,
1711 step);
a68ab351
JJ
1712 tmp = gfc_evaluate_now (tmp, pblock);
1713 count = gfc_create_var (type, "count");
726a989a 1714 TREE_VEC_ELT (init, i) = build2_v (MODIFY_EXPR, count,
a68ab351 1715 build_int_cst (type, 0));
edaadf74
JJ
1716 /* The condition should not be folded. */
1717 TREE_VEC_ELT (cond, i) = build2_loc (input_location, LT_EXPR,
1718 boolean_type_node,
1719 count, tmp);
65a9ca82
TB
1720 TREE_VEC_ELT (incr, i) = fold_build2_loc (input_location, PLUS_EXPR,
1721 type, count,
1722 build_int_cst (type, 1));
1723 TREE_VEC_ELT (incr, i) = fold_build2_loc (input_location,
1724 MODIFY_EXPR, type, count,
1725 TREE_VEC_ELT (incr, i));
a68ab351
JJ
1726
1727 /* Initialize DOVAR. */
65a9ca82
TB
1728 tmp = fold_build2_loc (input_location, MULT_EXPR, type, count, step);
1729 tmp = fold_build2_loc (input_location, PLUS_EXPR, type, from, tmp);
f32682ca 1730 dovar_init e = {dovar, tmp};
9771b263 1731 inits.safe_push (e);
6c7a4dfd 1732 }
6c7a4dfd 1733
a68ab351
JJ
1734 if (!dovar_found)
1735 {
dd2fc525
JJ
1736 if (op == EXEC_OMP_SIMD)
1737 {
1738 if (collapse == 1)
1739 {
1740 tmp = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
1741 OMP_CLAUSE_LINEAR_STEP (tmp) = step;
1742 }
1743 else
1744 tmp = build_omp_clause (input_location, OMP_CLAUSE_LASTPRIVATE);
1745 if (!simple)
1746 dovar_found = 2;
1747 }
1748 else
1749 tmp = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
281e33e1 1750 OMP_CLAUSE_DECL (tmp) = dovar_decl;
a68ab351
JJ
1751 omp_clauses = gfc_trans_add_clause (tmp, omp_clauses);
1752 }
dd2fc525 1753 if (dovar_found == 2)
a68ab351
JJ
1754 {
1755 tree c = NULL;
1756
1757 tmp = NULL;
1758 if (!simple)
1759 {
1760 /* If dovar is lastprivate, but different counter is used,
1761 dovar += step needs to be added to
1762 OMP_CLAUSE_LASTPRIVATE_STMT, otherwise the copied dovar
1763 will have the value on entry of the last loop, rather
1764 than value after iterator increment. */
1765 tmp = gfc_evaluate_now (step, pblock);
65a9ca82
TB
1766 tmp = fold_build2_loc (input_location, PLUS_EXPR, type, dovar,
1767 tmp);
1768 tmp = fold_build2_loc (input_location, MODIFY_EXPR, type,
1769 dovar, tmp);
a68ab351
JJ
1770 for (c = omp_clauses; c ; c = OMP_CLAUSE_CHAIN (c))
1771 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
281e33e1 1772 && OMP_CLAUSE_DECL (c) == dovar_decl)
a68ab351
JJ
1773 {
1774 OMP_CLAUSE_LASTPRIVATE_STMT (c) = tmp;
1775 break;
1776 }
dd2fc525
JJ
1777 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
1778 && OMP_CLAUSE_DECL (c) == dovar_decl)
1779 {
1780 OMP_CLAUSE_LINEAR_STMT (c) = tmp;
1781 break;
1782 }
a68ab351 1783 }
dd2fc525 1784 if (c == NULL && op == EXEC_OMP_DO && par_clauses != NULL)
a68ab351
JJ
1785 {
1786 for (c = par_clauses; c ; c = OMP_CLAUSE_CHAIN (c))
1787 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
281e33e1 1788 && OMP_CLAUSE_DECL (c) == dovar_decl)
a68ab351 1789 {
c2255bc4
AH
1790 tree l = build_omp_clause (input_location,
1791 OMP_CLAUSE_LASTPRIVATE);
281e33e1 1792 OMP_CLAUSE_DECL (l) = dovar_decl;
a68ab351
JJ
1793 OMP_CLAUSE_CHAIN (l) = omp_clauses;
1794 OMP_CLAUSE_LASTPRIVATE_STMT (l) = tmp;
1795 omp_clauses = l;
1796 OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_SHARED);
1797 break;
1798 }
1799 }
1800 gcc_assert (simple || c != NULL);
1801 }
1802 if (!simple)
1803 {
dd2fc525
JJ
1804 if (op != EXEC_OMP_SIMD)
1805 tmp = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
1806 else if (collapse == 1)
1807 {
1808 tmp = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
1809 OMP_CLAUSE_LINEAR_STEP (tmp) = step;
1810 OMP_CLAUSE_LINEAR_NO_COPYIN (tmp) = 1;
1811 OMP_CLAUSE_LINEAR_NO_COPYOUT (tmp) = 1;
1812 }
1813 else
1814 tmp = build_omp_clause (input_location, OMP_CLAUSE_LASTPRIVATE);
a68ab351
JJ
1815 OMP_CLAUSE_DECL (tmp) = count;
1816 omp_clauses = gfc_trans_add_clause (tmp, omp_clauses);
1817 }
1818
1819 if (i + 1 < collapse)
1820 code = code->block->next;
6c7a4dfd
JJ
1821 }
1822
a68ab351 1823 if (pblock != &block)
6c7a4dfd 1824 {
87a60f68 1825 pushlevel ();
a68ab351 1826 gfc_start_block (&block);
6c7a4dfd 1827 }
a68ab351
JJ
1828
1829 gfc_start_block (&body);
1830
9771b263 1831 FOR_EACH_VEC_ELT (inits, ix, di)
04924d6a 1832 gfc_add_modify (&body, di->var, di->init);
9771b263 1833 inits.release ();
6c7a4dfd
JJ
1834
1835 /* Cycle statement is implemented with a goto. Exit statement must not be
1836 present for this loop. */
1837 cycle_label = gfc_build_label_decl (NULL_TREE);
1838
e7041633 1839 /* Put these labels where they can be found later. */
6c7a4dfd 1840
7602cb87
JJ
1841 code->cycle_label = cycle_label;
1842 code->exit_label = NULL_TREE;
6c7a4dfd
JJ
1843
1844 /* Main loop body. */
1845 tmp = gfc_trans_omp_code (code->block->next, true);
1846 gfc_add_expr_to_block (&body, tmp);
1847
1848 /* Label for cycle statements (if needed). */
1849 if (TREE_USED (cycle_label))
1850 {
1851 tmp = build1_v (LABEL_EXPR, cycle_label);
1852 gfc_add_expr_to_block (&body, tmp);
1853 }
1854
1855 /* End of loop body. */
dd2fc525 1856 stmt = make_node (op == EXEC_OMP_SIMD ? OMP_SIMD : OMP_FOR);
6c7a4dfd
JJ
1857
1858 TREE_TYPE (stmt) = void_type_node;
1859 OMP_FOR_BODY (stmt) = gfc_finish_block (&body);
1860 OMP_FOR_CLAUSES (stmt) = omp_clauses;
1861 OMP_FOR_INIT (stmt) = init;
1862 OMP_FOR_COND (stmt) = cond;
1863 OMP_FOR_INCR (stmt) = incr;
1864 gfc_add_expr_to_block (&block, stmt);
1865
1866 return gfc_finish_block (&block);
1867}
1868
1869static tree
1870gfc_trans_omp_flush (void)
1871{
e79983f4 1872 tree decl = builtin_decl_explicit (BUILT_IN_SYNC_SYNCHRONIZE);
db3927fb 1873 return build_call_expr_loc (input_location, decl, 0);
6c7a4dfd
JJ
1874}
1875
1876static tree
1877gfc_trans_omp_master (gfc_code *code)
1878{
1879 tree stmt = gfc_trans_code (code->block->next);
1880 if (IS_EMPTY_STMT (stmt))
1881 return stmt;
1882 return build1_v (OMP_MASTER, stmt);
1883}
1884
1885static tree
1886gfc_trans_omp_ordered (gfc_code *code)
1887{
1888 return build1_v (OMP_ORDERED, gfc_trans_code (code->block->next));
1889}
1890
1891static tree
1892gfc_trans_omp_parallel (gfc_code *code)
1893{
1894 stmtblock_t block;
1895 tree stmt, omp_clauses;
1896
1897 gfc_start_block (&block);
1898 omp_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
1899 code->loc);
1900 stmt = gfc_trans_omp_code (code->block->next, true);
5d44e5c8
TB
1901 stmt = build2_loc (input_location, OMP_PARALLEL, void_type_node, stmt,
1902 omp_clauses);
6c7a4dfd
JJ
1903 gfc_add_expr_to_block (&block, stmt);
1904 return gfc_finish_block (&block);
1905}
1906
dd2fc525
JJ
1907enum
1908{
1909 GFC_OMP_SPLIT_SIMD,
1910 GFC_OMP_SPLIT_DO,
1911 GFC_OMP_SPLIT_PARALLEL,
1912 GFC_OMP_SPLIT_NUM
1913};
1914
1915enum
1916{
1917 GFC_OMP_MASK_SIMD = (1 << GFC_OMP_SPLIT_SIMD),
1918 GFC_OMP_MASK_DO = (1 << GFC_OMP_SPLIT_DO),
1919 GFC_OMP_MASK_PARALLEL = (1 << GFC_OMP_SPLIT_PARALLEL)
1920};
1921
1922static void
1923gfc_split_omp_clauses (gfc_code *code,
1924 gfc_omp_clauses clausesa[GFC_OMP_SPLIT_NUM])
1925{
1926 int mask = 0, innermost = 0, i;
1927 memset (clausesa, 0, GFC_OMP_SPLIT_NUM * sizeof (gfc_omp_clauses));
1928 switch (code->op)
1929 {
1930 case EXEC_OMP_DO_SIMD:
1931 mask = GFC_OMP_MASK_DO | GFC_OMP_MASK_SIMD;
1932 innermost = GFC_OMP_SPLIT_SIMD;
1933 break;
1934 case EXEC_OMP_PARALLEL_DO:
1935 mask = GFC_OMP_MASK_PARALLEL | GFC_OMP_MASK_DO;
1936 innermost = GFC_OMP_SPLIT_DO;
1937 break;
1938 case EXEC_OMP_PARALLEL_DO_SIMD:
1939 mask = GFC_OMP_MASK_PARALLEL | GFC_OMP_MASK_DO | GFC_OMP_MASK_SIMD;
1940 innermost = GFC_OMP_SPLIT_SIMD;
1941 break;
1942 default:
1943 gcc_unreachable ();
1944 }
1945 if (code->ext.omp_clauses != NULL)
1946 {
1947 if (mask & GFC_OMP_MASK_PARALLEL)
1948 {
1949 /* First the clauses that are unique to some constructs. */
1950 clausesa[GFC_OMP_SPLIT_PARALLEL].lists[OMP_LIST_COPYIN]
1951 = code->ext.omp_clauses->lists[OMP_LIST_COPYIN];
1952 clausesa[GFC_OMP_SPLIT_PARALLEL].num_threads
1953 = code->ext.omp_clauses->num_threads;
1954 clausesa[GFC_OMP_SPLIT_PARALLEL].proc_bind
1955 = code->ext.omp_clauses->proc_bind;
1956 /* Shared and default clauses are allowed on parallel and teams. */
1957 clausesa[GFC_OMP_SPLIT_PARALLEL].lists[OMP_LIST_SHARED]
1958 = code->ext.omp_clauses->lists[OMP_LIST_SHARED];
1959 clausesa[GFC_OMP_SPLIT_PARALLEL].default_sharing
1960 = code->ext.omp_clauses->default_sharing;
1961 /* FIXME: This is currently being discussed. */
1962 clausesa[GFC_OMP_SPLIT_PARALLEL].if_expr
1963 = code->ext.omp_clauses->if_expr;
1964 }
1965 if (mask & GFC_OMP_MASK_DO)
1966 {
1967 /* First the clauses that are unique to some constructs. */
1968 clausesa[GFC_OMP_SPLIT_DO].ordered
1969 = code->ext.omp_clauses->ordered;
1970 clausesa[GFC_OMP_SPLIT_DO].sched_kind
1971 = code->ext.omp_clauses->sched_kind;
1972 clausesa[GFC_OMP_SPLIT_DO].chunk_size
1973 = code->ext.omp_clauses->chunk_size;
1974 clausesa[GFC_OMP_SPLIT_DO].nowait
1975 = code->ext.omp_clauses->nowait;
1976 /* Duplicate collapse. */
1977 clausesa[GFC_OMP_SPLIT_DO].collapse
1978 = code->ext.omp_clauses->collapse;
1979 }
1980 if (mask & GFC_OMP_MASK_SIMD)
1981 {
1982 clausesa[GFC_OMP_SPLIT_SIMD].safelen_expr
1983 = code->ext.omp_clauses->safelen_expr;
1984 clausesa[GFC_OMP_SPLIT_SIMD].lists[OMP_LIST_LINEAR]
1985 = code->ext.omp_clauses->lists[OMP_LIST_LINEAR];
1986 clausesa[GFC_OMP_SPLIT_SIMD].lists[OMP_LIST_ALIGNED]
1987 = code->ext.omp_clauses->lists[OMP_LIST_ALIGNED];
1988 /* Duplicate collapse. */
1989 clausesa[GFC_OMP_SPLIT_SIMD].collapse
1990 = code->ext.omp_clauses->collapse;
1991 }
1992 /* Private clause is supported on all constructs but target,
1993 it is enough to put it on the innermost one. For
1994 !$ omp do put it on parallel though,
1995 as that's what we did for OpenMP 3.1. */
1996 clausesa[innermost == GFC_OMP_SPLIT_DO
1997 ? (int) GFC_OMP_SPLIT_PARALLEL
1998 : innermost].lists[OMP_LIST_PRIVATE]
1999 = code->ext.omp_clauses->lists[OMP_LIST_PRIVATE];
2000 /* Firstprivate clause is supported on all constructs but
2001 target and simd. Put it on the outermost of those and
2002 duplicate on parallel. */
2003 if (mask & GFC_OMP_MASK_PARALLEL)
2004 clausesa[GFC_OMP_SPLIT_PARALLEL].lists[OMP_LIST_FIRSTPRIVATE]
2005 = code->ext.omp_clauses->lists[OMP_LIST_FIRSTPRIVATE];
2006 else if (mask & GFC_OMP_MASK_DO)
2007 clausesa[GFC_OMP_SPLIT_DO].lists[OMP_LIST_FIRSTPRIVATE]
2008 = code->ext.omp_clauses->lists[OMP_LIST_FIRSTPRIVATE];
2009 /* Lastprivate is allowed on do and simd. In
2010 parallel do{, simd} we actually want to put it on
2011 parallel rather than do. */
2012 if (mask & GFC_OMP_MASK_PARALLEL)
2013 clausesa[GFC_OMP_SPLIT_PARALLEL].lists[OMP_LIST_LASTPRIVATE]
2014 = code->ext.omp_clauses->lists[OMP_LIST_LASTPRIVATE];
2015 else if (mask & GFC_OMP_MASK_DO)
2016 clausesa[GFC_OMP_SPLIT_DO].lists[OMP_LIST_LASTPRIVATE]
2017 = code->ext.omp_clauses->lists[OMP_LIST_LASTPRIVATE];
2018 if (mask & GFC_OMP_MASK_SIMD)
2019 clausesa[GFC_OMP_SPLIT_SIMD].lists[OMP_LIST_LASTPRIVATE]
2020 = code->ext.omp_clauses->lists[OMP_LIST_LASTPRIVATE];
2021 /* Reduction is allowed on simd, do, parallel and teams.
2022 Duplicate it on all of them, but omit on do if
2023 parallel is present. */
2024 for (i = OMP_LIST_REDUCTION_FIRST; i <= OMP_LIST_REDUCTION_LAST; i++)
2025 {
2026 if (mask & GFC_OMP_MASK_PARALLEL)
2027 clausesa[GFC_OMP_SPLIT_PARALLEL].lists[i]
2028 = code->ext.omp_clauses->lists[i];
2029 else if (mask & GFC_OMP_MASK_DO)
2030 clausesa[GFC_OMP_SPLIT_DO].lists[i]
2031 = code->ext.omp_clauses->lists[i];
2032 if (mask & GFC_OMP_MASK_SIMD)
2033 clausesa[GFC_OMP_SPLIT_SIMD].lists[i]
2034 = code->ext.omp_clauses->lists[i];
2035 }
2036 }
2037 if ((mask & (GFC_OMP_MASK_PARALLEL | GFC_OMP_MASK_DO))
2038 == (GFC_OMP_MASK_PARALLEL | GFC_OMP_MASK_DO))
2039 clausesa[GFC_OMP_SPLIT_DO].nowait = true;
2040}
2041
6c7a4dfd 2042static tree
dd2fc525
JJ
2043gfc_trans_omp_do_simd (gfc_code *code, gfc_omp_clauses *clausesa,
2044 tree omp_clauses)
6c7a4dfd
JJ
2045{
2046 stmtblock_t block, *pblock = NULL;
dd2fc525
JJ
2047 gfc_omp_clauses clausesa_buf[GFC_OMP_SPLIT_NUM];
2048 tree stmt, body, omp_do_clauses = NULL_TREE;
6c7a4dfd
JJ
2049
2050 gfc_start_block (&block);
2051
dd2fc525 2052 if (clausesa == NULL)
6c7a4dfd 2053 {
dd2fc525
JJ
2054 clausesa = clausesa_buf;
2055 gfc_split_omp_clauses (code, clausesa);
6c7a4dfd 2056 }
dd2fc525
JJ
2057 omp_do_clauses
2058 = gfc_trans_omp_clauses (&block, &clausesa[GFC_OMP_SPLIT_DO], code->loc);
2059 pblock = &block;
2060 body = gfc_trans_omp_do (code, EXEC_OMP_SIMD, pblock,
2061 &clausesa[GFC_OMP_SPLIT_SIMD], omp_clauses);
2062 if (TREE_CODE (body) != BIND_EXPR)
2063 body = build3_v (BIND_EXPR, NULL, body, poplevel (1, 0));
2064 else
2065 poplevel (0, 0);
2066 stmt = make_node (OMP_FOR);
2067 TREE_TYPE (stmt) = void_type_node;
2068 OMP_FOR_BODY (stmt) = body;
2069 OMP_FOR_CLAUSES (stmt) = omp_do_clauses;
2070 gfc_add_expr_to_block (&block, stmt);
2071 return gfc_finish_block (&block);
2072}
2073
2074static tree
2075gfc_trans_omp_parallel_do (gfc_code *code)
2076{
2077 stmtblock_t block, *pblock = NULL;
2078 gfc_omp_clauses clausesa[GFC_OMP_SPLIT_NUM];
2079 tree stmt, omp_clauses = NULL_TREE;
2080
2081 gfc_start_block (&block);
2082
2083 gfc_split_omp_clauses (code, clausesa);
2084 omp_clauses
2085 = gfc_trans_omp_clauses (&block, &clausesa[GFC_OMP_SPLIT_PARALLEL],
2086 code->loc);
2087 if (!clausesa[GFC_OMP_SPLIT_DO].ordered
2088 && clausesa[GFC_OMP_SPLIT_DO].sched_kind != OMP_SCHED_STATIC)
6c7a4dfd
JJ
2089 pblock = &block;
2090 else
87a60f68 2091 pushlevel ();
dd2fc525
JJ
2092 stmt = gfc_trans_omp_do (code, EXEC_OMP_DO, pblock,
2093 &clausesa[GFC_OMP_SPLIT_DO], omp_clauses);
2094 if (TREE_CODE (stmt) != BIND_EXPR)
2095 stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
2096 else
2097 poplevel (0, 0);
2098 stmt = build2_loc (input_location, OMP_PARALLEL, void_type_node, stmt,
2099 omp_clauses);
2100 OMP_PARALLEL_COMBINED (stmt) = 1;
2101 gfc_add_expr_to_block (&block, stmt);
2102 return gfc_finish_block (&block);
2103}
2104
2105static tree
2106gfc_trans_omp_parallel_do_simd (gfc_code *code)
2107{
2108 stmtblock_t block;
2109 gfc_omp_clauses clausesa[GFC_OMP_SPLIT_NUM];
2110 tree stmt, omp_clauses = NULL_TREE;
2111
2112 gfc_start_block (&block);
2113
2114 gfc_split_omp_clauses (code, clausesa);
2115 omp_clauses
2116 = gfc_trans_omp_clauses (&block, &clausesa[GFC_OMP_SPLIT_PARALLEL],
2117 code->loc);
2118 pushlevel ();
2119 stmt = gfc_trans_omp_do_simd (code, clausesa, omp_clauses);
6c7a4dfd 2120 if (TREE_CODE (stmt) != BIND_EXPR)
87a60f68 2121 stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
6c7a4dfd 2122 else
87a60f68 2123 poplevel (0, 0);
5d44e5c8
TB
2124 stmt = build2_loc (input_location, OMP_PARALLEL, void_type_node, stmt,
2125 omp_clauses);
761041be 2126 OMP_PARALLEL_COMBINED (stmt) = 1;
6c7a4dfd
JJ
2127 gfc_add_expr_to_block (&block, stmt);
2128 return gfc_finish_block (&block);
2129}
2130
2131static tree
2132gfc_trans_omp_parallel_sections (gfc_code *code)
2133{
2134 stmtblock_t block;
2135 gfc_omp_clauses section_clauses;
2136 tree stmt, omp_clauses;
2137
2138 memset (&section_clauses, 0, sizeof (section_clauses));
2139 section_clauses.nowait = true;
2140
2141 gfc_start_block (&block);
2142 omp_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
2143 code->loc);
87a60f68 2144 pushlevel ();
6c7a4dfd
JJ
2145 stmt = gfc_trans_omp_sections (code, &section_clauses);
2146 if (TREE_CODE (stmt) != BIND_EXPR)
87a60f68 2147 stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
6c7a4dfd 2148 else
87a60f68 2149 poplevel (0, 0);
5d44e5c8
TB
2150 stmt = build2_loc (input_location, OMP_PARALLEL, void_type_node, stmt,
2151 omp_clauses);
761041be 2152 OMP_PARALLEL_COMBINED (stmt) = 1;
6c7a4dfd
JJ
2153 gfc_add_expr_to_block (&block, stmt);
2154 return gfc_finish_block (&block);
2155}
2156
2157static tree
2158gfc_trans_omp_parallel_workshare (gfc_code *code)
2159{
2160 stmtblock_t block;
2161 gfc_omp_clauses workshare_clauses;
2162 tree stmt, omp_clauses;
2163
2164 memset (&workshare_clauses, 0, sizeof (workshare_clauses));
2165 workshare_clauses.nowait = true;
2166
2167 gfc_start_block (&block);
2168 omp_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
2169 code->loc);
87a60f68 2170 pushlevel ();
6c7a4dfd
JJ
2171 stmt = gfc_trans_omp_workshare (code, &workshare_clauses);
2172 if (TREE_CODE (stmt) != BIND_EXPR)
87a60f68 2173 stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
6c7a4dfd 2174 else
87a60f68 2175 poplevel (0, 0);
5d44e5c8
TB
2176 stmt = build2_loc (input_location, OMP_PARALLEL, void_type_node, stmt,
2177 omp_clauses);
761041be 2178 OMP_PARALLEL_COMBINED (stmt) = 1;
6c7a4dfd
JJ
2179 gfc_add_expr_to_block (&block, stmt);
2180 return gfc_finish_block (&block);
2181}
2182
2183static tree
2184gfc_trans_omp_sections (gfc_code *code, gfc_omp_clauses *clauses)
2185{
2186 stmtblock_t block, body;
2187 tree omp_clauses, stmt;
2188 bool has_lastprivate = clauses->lists[OMP_LIST_LASTPRIVATE] != NULL;
2189
2190 gfc_start_block (&block);
2191
2192 omp_clauses = gfc_trans_omp_clauses (&block, clauses, code->loc);
2193
2194 gfc_init_block (&body);
2195 for (code = code->block; code; code = code->block)
2196 {
2197 /* Last section is special because of lastprivate, so even if it
2198 is empty, chain it in. */
2199 stmt = gfc_trans_omp_code (code->next,
2200 has_lastprivate && code->block == NULL);
2201 if (! IS_EMPTY_STMT (stmt))
2202 {
2203 stmt = build1_v (OMP_SECTION, stmt);
2204 gfc_add_expr_to_block (&body, stmt);
2205 }
2206 }
2207 stmt = gfc_finish_block (&body);
2208
5d44e5c8
TB
2209 stmt = build2_loc (input_location, OMP_SECTIONS, void_type_node, stmt,
2210 omp_clauses);
6c7a4dfd
JJ
2211 gfc_add_expr_to_block (&block, stmt);
2212
2213 return gfc_finish_block (&block);
2214}
2215
2216static tree
2217gfc_trans_omp_single (gfc_code *code, gfc_omp_clauses *clauses)
2218{
2219 tree omp_clauses = gfc_trans_omp_clauses (NULL, clauses, code->loc);
2220 tree stmt = gfc_trans_omp_code (code->block->next, true);
5d44e5c8
TB
2221 stmt = build2_loc (input_location, OMP_SINGLE, void_type_node, stmt,
2222 omp_clauses);
6c7a4dfd
JJ
2223 return stmt;
2224}
2225
a68ab351
JJ
2226static tree
2227gfc_trans_omp_task (gfc_code *code)
2228{
2229 stmtblock_t block;
726a989a 2230 tree stmt, omp_clauses;
a68ab351
JJ
2231
2232 gfc_start_block (&block);
2233 omp_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
2234 code->loc);
726a989a 2235 stmt = gfc_trans_omp_code (code->block->next, true);
5d44e5c8
TB
2236 stmt = build2_loc (input_location, OMP_TASK, void_type_node, stmt,
2237 omp_clauses);
a68ab351
JJ
2238 gfc_add_expr_to_block (&block, stmt);
2239 return gfc_finish_block (&block);
2240}
2241
dd2fc525
JJ
2242static tree
2243gfc_trans_omp_taskgroup (gfc_code *code)
2244{
2245 tree stmt = gfc_trans_code (code->block->next);
2246 return build1_loc (input_location, OMP_TASKGROUP, void_type_node, stmt);
2247}
2248
a68ab351
JJ
2249static tree
2250gfc_trans_omp_taskwait (void)
2251{
e79983f4 2252 tree decl = builtin_decl_explicit (BUILT_IN_GOMP_TASKWAIT);
db3927fb 2253 return build_call_expr_loc (input_location, decl, 0);
a68ab351
JJ
2254}
2255
20906c66
JJ
2256static tree
2257gfc_trans_omp_taskyield (void)
2258{
e79983f4 2259 tree decl = builtin_decl_explicit (BUILT_IN_GOMP_TASKYIELD);
20906c66
JJ
2260 return build_call_expr_loc (input_location, decl, 0);
2261}
2262
6c7a4dfd
JJ
2263static tree
2264gfc_trans_omp_workshare (gfc_code *code, gfc_omp_clauses *clauses)
2265{
34d01e1d
VL
2266 tree res, tmp, stmt;
2267 stmtblock_t block, *pblock = NULL;
2268 stmtblock_t singleblock;
2269 int saved_ompws_flags;
2270 bool singleblock_in_progress = false;
2271 /* True if previous gfc_code in workshare construct is not workshared. */
2272 bool prev_singleunit;
2273
2274 code = code->block->next;
2275
87a60f68 2276 pushlevel ();
34d01e1d 2277
34d01e1d
VL
2278 gfc_start_block (&block);
2279 pblock = &block;
2280
2281 ompws_flags = OMPWS_WORKSHARE_FLAG;
2282 prev_singleunit = false;
2283
2284 /* Translate statements one by one to trees until we reach
2285 the end of the workshare construct. Adjacent gfc_codes that
2286 are a single unit of work are clustered and encapsulated in a
2287 single OMP_SINGLE construct. */
2288 for (; code; code = code->next)
2289 {
2290 if (code->here != 0)
2291 {
2292 res = gfc_trans_label_here (code);
2293 gfc_add_expr_to_block (pblock, res);
2294 }
2295
2296 /* No dependence analysis, use for clauses with wait.
2297 If this is the last gfc_code, use default omp_clauses. */
2298 if (code->next == NULL && clauses->nowait)
2299 ompws_flags |= OMPWS_NOWAIT;
2300
2301 /* By default, every gfc_code is a single unit of work. */
2302 ompws_flags |= OMPWS_CURR_SINGLEUNIT;
2303 ompws_flags &= ~OMPWS_SCALARIZER_WS;
2304
2305 switch (code->op)
2306 {
2307 case EXEC_NOP:
2308 res = NULL_TREE;
2309 break;
2310
2311 case EXEC_ASSIGN:
2312 res = gfc_trans_assign (code);
2313 break;
2314
2315 case EXEC_POINTER_ASSIGN:
2316 res = gfc_trans_pointer_assign (code);
2317 break;
2318
2319 case EXEC_INIT_ASSIGN:
2320 res = gfc_trans_init_assign (code);
2321 break;
2322
2323 case EXEC_FORALL:
2324 res = gfc_trans_forall (code);
2325 break;
2326
2327 case EXEC_WHERE:
2328 res = gfc_trans_where (code);
2329 break;
2330
2331 case EXEC_OMP_ATOMIC:
2332 res = gfc_trans_omp_directive (code);
2333 break;
2334
2335 case EXEC_OMP_PARALLEL:
2336 case EXEC_OMP_PARALLEL_DO:
2337 case EXEC_OMP_PARALLEL_SECTIONS:
2338 case EXEC_OMP_PARALLEL_WORKSHARE:
2339 case EXEC_OMP_CRITICAL:
2340 saved_ompws_flags = ompws_flags;
2341 ompws_flags = 0;
2342 res = gfc_trans_omp_directive (code);
2343 ompws_flags = saved_ompws_flags;
2344 break;
2345
2346 default:
2347 internal_error ("gfc_trans_omp_workshare(): Bad statement code");
2348 }
2349
2350 gfc_set_backend_locus (&code->loc);
2351
2352 if (res != NULL_TREE && ! IS_EMPTY_STMT (res))
2353 {
34d01e1d
VL
2354 if (prev_singleunit)
2355 {
2356 if (ompws_flags & OMPWS_CURR_SINGLEUNIT)
2357 /* Add current gfc_code to single block. */
2358 gfc_add_expr_to_block (&singleblock, res);
2359 else
2360 {
2361 /* Finish single block and add it to pblock. */
2362 tmp = gfc_finish_block (&singleblock);
5d44e5c8
TB
2363 tmp = build2_loc (input_location, OMP_SINGLE,
2364 void_type_node, tmp, NULL_TREE);
34d01e1d
VL
2365 gfc_add_expr_to_block (pblock, tmp);
2366 /* Add current gfc_code to pblock. */
2367 gfc_add_expr_to_block (pblock, res);
2368 singleblock_in_progress = false;
2369 }
2370 }
2371 else
2372 {
2373 if (ompws_flags & OMPWS_CURR_SINGLEUNIT)
2374 {
2375 /* Start single block. */
2376 gfc_init_block (&singleblock);
2377 gfc_add_expr_to_block (&singleblock, res);
2378 singleblock_in_progress = true;
2379 }
2380 else
2381 /* Add the new statement to the block. */
2382 gfc_add_expr_to_block (pblock, res);
2383 }
2384 prev_singleunit = (ompws_flags & OMPWS_CURR_SINGLEUNIT) != 0;
2385 }
2386 }
2387
2388 /* Finish remaining SINGLE block, if we were in the middle of one. */
2389 if (singleblock_in_progress)
2390 {
2391 /* Finish single block and add it to pblock. */
2392 tmp = gfc_finish_block (&singleblock);
5d44e5c8
TB
2393 tmp = build2_loc (input_location, OMP_SINGLE, void_type_node, tmp,
2394 clauses->nowait
2395 ? build_omp_clause (input_location, OMP_CLAUSE_NOWAIT)
2396 : NULL_TREE);
34d01e1d
VL
2397 gfc_add_expr_to_block (pblock, tmp);
2398 }
2399
2400 stmt = gfc_finish_block (pblock);
2401 if (TREE_CODE (stmt) != BIND_EXPR)
2402 {
2403 if (!IS_EMPTY_STMT (stmt))
2404 {
87a60f68 2405 tree bindblock = poplevel (1, 0);
34d01e1d
VL
2406 stmt = build3_v (BIND_EXPR, NULL, stmt, bindblock);
2407 }
2408 else
87a60f68 2409 poplevel (0, 0);
34d01e1d
VL
2410 }
2411 else
87a60f68 2412 poplevel (0, 0);
34d01e1d 2413
c26dffff
JJ
2414 if (IS_EMPTY_STMT (stmt) && !clauses->nowait)
2415 stmt = gfc_trans_omp_barrier ();
2416
34d01e1d
VL
2417 ompws_flags = 0;
2418 return stmt;
6c7a4dfd
JJ
2419}
2420
2421tree
2422gfc_trans_omp_directive (gfc_code *code)
2423{
2424 switch (code->op)
2425 {
2426 case EXEC_OMP_ATOMIC:
2427 return gfc_trans_omp_atomic (code);
2428 case EXEC_OMP_BARRIER:
2429 return gfc_trans_omp_barrier ();
dd2fc525
JJ
2430 case EXEC_OMP_CANCEL:
2431 return gfc_trans_omp_cancel (code);
2432 case EXEC_OMP_CANCELLATION_POINT:
2433 return gfc_trans_omp_cancellation_point (code);
6c7a4dfd
JJ
2434 case EXEC_OMP_CRITICAL:
2435 return gfc_trans_omp_critical (code);
2436 case EXEC_OMP_DO:
dd2fc525
JJ
2437 case EXEC_OMP_SIMD:
2438 return gfc_trans_omp_do (code, code->op, NULL, code->ext.omp_clauses,
2439 NULL);
2440 case EXEC_OMP_DO_SIMD:
2441 return gfc_trans_omp_do_simd (code, NULL, NULL_TREE);
6c7a4dfd
JJ
2442 case EXEC_OMP_FLUSH:
2443 return gfc_trans_omp_flush ();
2444 case EXEC_OMP_MASTER:
2445 return gfc_trans_omp_master (code);
2446 case EXEC_OMP_ORDERED:
2447 return gfc_trans_omp_ordered (code);
2448 case EXEC_OMP_PARALLEL:
2449 return gfc_trans_omp_parallel (code);
2450 case EXEC_OMP_PARALLEL_DO:
2451 return gfc_trans_omp_parallel_do (code);
dd2fc525
JJ
2452 case EXEC_OMP_PARALLEL_DO_SIMD:
2453 return gfc_trans_omp_parallel_do_simd (code);
6c7a4dfd
JJ
2454 case EXEC_OMP_PARALLEL_SECTIONS:
2455 return gfc_trans_omp_parallel_sections (code);
2456 case EXEC_OMP_PARALLEL_WORKSHARE:
2457 return gfc_trans_omp_parallel_workshare (code);
2458 case EXEC_OMP_SECTIONS:
2459 return gfc_trans_omp_sections (code, code->ext.omp_clauses);
2460 case EXEC_OMP_SINGLE:
2461 return gfc_trans_omp_single (code, code->ext.omp_clauses);
a68ab351
JJ
2462 case EXEC_OMP_TASK:
2463 return gfc_trans_omp_task (code);
dd2fc525
JJ
2464 case EXEC_OMP_TASKGROUP:
2465 return gfc_trans_omp_taskgroup (code);
a68ab351
JJ
2466 case EXEC_OMP_TASKWAIT:
2467 return gfc_trans_omp_taskwait ();
20906c66
JJ
2468 case EXEC_OMP_TASKYIELD:
2469 return gfc_trans_omp_taskyield ();
6c7a4dfd
JJ
2470 case EXEC_OMP_WORKSHARE:
2471 return gfc_trans_omp_workshare (code, code->ext.omp_clauses);
2472 default:
2473 gcc_unreachable ();
2474 }
2475}
dd2fc525
JJ
2476
2477void
2478gfc_trans_omp_declare_simd (gfc_namespace *ns)
2479{
2480 if (ns->entries)
2481 return;
2482
2483 gfc_omp_declare_simd *ods;
2484 for (ods = ns->omp_declare_simd; ods; ods = ods->next)
2485 {
2486 tree c = gfc_trans_omp_clauses (NULL, ods->clauses, ods->where, true);
2487 tree fndecl = ns->proc_name->backend_decl;
2488 if (c != NULL_TREE)
2489 c = tree_cons (NULL_TREE, c, NULL_TREE);
2490 c = build_tree_list (get_identifier ("omp declare simd"), c);
2491 TREE_CHAIN (c) = DECL_ATTRIBUTES (fndecl);
2492 DECL_ATTRIBUTES (fndecl) = c;
2493 }
2494}