* cgraphunit.c (record_cdtor_fn): Declare all cdtors always inlined.
[official-gcc/constexpr.git] / gcc / fortran / trans-openmp.c
blob1af10369824bb629dd3e45e33c172c92785e883e
1 /* OpenMP directive translation -- generate GCC trees from gfc_code.
2 Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
3 Contributed by Jakub Jelinek <jakub@redhat.com>
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tree.h"
26 #include "tree-gimple.h"
27 #include "ggc.h"
28 #include "toplev.h"
29 #include "real.h"
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"
39 /* True if OpenMP should privatize what this DECL points to rather
40 than the DECL itself. */
42 bool
43 gfc_omp_privatize_by_reference (tree decl)
45 tree type = TREE_TYPE (decl);
47 if (TREE_CODE (type) == REFERENCE_TYPE)
48 return true;
50 if (TREE_CODE (type) == POINTER_TYPE)
52 /* Array POINTER/ALLOCATABLE have aggregate types, all user variables
53 that have POINTER_TYPE type and don't have GFC_POINTER_TYPE_P
54 set are supposed to be privatized by reference. */
55 if (GFC_POINTER_TYPE_P (type))
56 return false;
58 if (!DECL_ARTIFICIAL (decl))
59 return true;
61 /* Some arrays are expanded as DECL_ARTIFICIAL pointers
62 by the frontend. */
63 if (DECL_LANG_SPECIFIC (decl)
64 && GFC_DECL_SAVED_DESCRIPTOR (decl))
65 return true;
68 return false;
71 /* True if OpenMP sharing attribute of DECL is predetermined. */
73 enum omp_clause_default_kind
74 gfc_omp_predetermined_sharing (tree decl)
76 if (DECL_ARTIFICIAL (decl) && ! GFC_DECL_RESULT (decl))
77 return OMP_CLAUSE_DEFAULT_SHARED;
79 /* Cray pointees shouldn't be listed in any clauses and should be
80 gimplified to dereference of the corresponding Cray pointer.
81 Make them all private, so that they are emitted in the debug
82 information. */
83 if (GFC_DECL_CRAY_POINTEE (decl))
84 return OMP_CLAUSE_DEFAULT_PRIVATE;
86 /* COMMON and EQUIVALENCE decls are shared. They
87 are only referenced through DECL_VALUE_EXPR of the variables
88 contained in them. If those are privatized, they will not be
89 gimplified to the COMMON or EQUIVALENCE decls. */
90 if (GFC_DECL_COMMON_OR_EQUIV (decl) && ! DECL_HAS_VALUE_EXPR_P (decl))
91 return OMP_CLAUSE_DEFAULT_SHARED;
93 if (GFC_DECL_RESULT (decl) && ! DECL_HAS_VALUE_EXPR_P (decl))
94 return OMP_CLAUSE_DEFAULT_SHARED;
96 return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
100 /* Return code to initialize DECL with its default constructor, or
101 NULL if there's nothing to do. */
103 tree
104 gfc_omp_clause_default_ctor (tree clause ATTRIBUTE_UNUSED, tree decl)
106 tree type = TREE_TYPE (decl);
107 stmtblock_t block;
109 if (! GFC_DESCRIPTOR_TYPE_P (type))
110 return NULL;
112 /* Allocatable arrays in PRIVATE clauses need to be set to
113 "not currently allocated" allocation status. */
114 gfc_init_block (&block);
116 gfc_conv_descriptor_data_set_tuples (&block, decl, null_pointer_node);
118 return gfc_finish_block (&block);
122 /* Return true if DECL's DECL_VALUE_EXPR (if any) should be
123 disregarded in OpenMP construct, because it is going to be
124 remapped during OpenMP lowering. SHARED is true if DECL
125 is going to be shared, false if it is going to be privatized. */
127 bool
128 gfc_omp_disregard_value_expr (tree decl, bool shared)
130 if (GFC_DECL_COMMON_OR_EQUIV (decl)
131 && DECL_HAS_VALUE_EXPR_P (decl))
133 tree value = DECL_VALUE_EXPR (decl);
135 if (TREE_CODE (value) == COMPONENT_REF
136 && TREE_CODE (TREE_OPERAND (value, 0)) == VAR_DECL
137 && GFC_DECL_COMMON_OR_EQUIV (TREE_OPERAND (value, 0)))
139 /* If variable in COMMON or EQUIVALENCE is privatized, return
140 true, as just that variable is supposed to be privatized,
141 not the whole COMMON or whole EQUIVALENCE.
142 For shared variables in COMMON or EQUIVALENCE, let them be
143 gimplified to DECL_VALUE_EXPR, so that for multiple shared vars
144 from the same COMMON or EQUIVALENCE just one sharing of the
145 whole COMMON or EQUIVALENCE is enough. */
146 return ! shared;
150 if (GFC_DECL_RESULT (decl) && DECL_HAS_VALUE_EXPR_P (decl))
151 return ! shared;
153 return false;
156 /* Return true if DECL that is shared iff SHARED is true should
157 be put into OMP_CLAUSE_PRIVATE with OMP_CLAUSE_PRIVATE_DEBUG
158 flag set. */
160 bool
161 gfc_omp_private_debug_clause (tree decl, bool shared)
163 if (GFC_DECL_CRAY_POINTEE (decl))
164 return true;
166 if (GFC_DECL_COMMON_OR_EQUIV (decl)
167 && DECL_HAS_VALUE_EXPR_P (decl))
169 tree value = DECL_VALUE_EXPR (decl);
171 if (TREE_CODE (value) == COMPONENT_REF
172 && TREE_CODE (TREE_OPERAND (value, 0)) == VAR_DECL
173 && GFC_DECL_COMMON_OR_EQUIV (TREE_OPERAND (value, 0)))
174 return shared;
177 return false;
180 /* Register language specific type size variables as potentially OpenMP
181 firstprivate variables. */
183 void
184 gfc_omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *ctx, tree type)
186 if (GFC_ARRAY_TYPE_P (type) || GFC_DESCRIPTOR_TYPE_P (type))
188 int r;
190 gcc_assert (TYPE_LANG_SPECIFIC (type) != NULL);
191 for (r = 0; r < GFC_TYPE_ARRAY_RANK (type); r++)
193 omp_firstprivatize_variable (ctx, GFC_TYPE_ARRAY_LBOUND (type, r));
194 omp_firstprivatize_variable (ctx, GFC_TYPE_ARRAY_UBOUND (type, r));
195 omp_firstprivatize_variable (ctx, GFC_TYPE_ARRAY_STRIDE (type, r));
197 omp_firstprivatize_variable (ctx, GFC_TYPE_ARRAY_SIZE (type));
198 omp_firstprivatize_variable (ctx, GFC_TYPE_ARRAY_OFFSET (type));
203 static inline tree
204 gfc_trans_add_clause (tree node, tree tail)
206 OMP_CLAUSE_CHAIN (node) = tail;
207 return node;
210 static tree
211 gfc_trans_omp_variable (gfc_symbol *sym)
213 tree t = gfc_get_symbol_decl (sym);
214 tree parent_decl;
215 int parent_flag;
216 bool return_value;
217 bool alternate_entry;
218 bool entry_master;
220 return_value = sym->attr.function && sym->result == sym;
221 alternate_entry = sym->attr.function && sym->attr.entry
222 && sym->result == sym;
223 entry_master = sym->attr.result
224 && sym->ns->proc_name->attr.entry_master
225 && !gfc_return_by_reference (sym->ns->proc_name);
226 parent_decl = DECL_CONTEXT (current_function_decl);
228 if ((t == parent_decl && return_value)
229 || (sym->ns && sym->ns->proc_name
230 && sym->ns->proc_name->backend_decl == parent_decl
231 && (alternate_entry || entry_master)))
232 parent_flag = 1;
233 else
234 parent_flag = 0;
236 /* Special case for assigning the return value of a function.
237 Self recursive functions must have an explicit return value. */
238 if (return_value && (t == current_function_decl || parent_flag))
239 t = gfc_get_fake_result_decl (sym, parent_flag);
241 /* Similarly for alternate entry points. */
242 else if (alternate_entry
243 && (sym->ns->proc_name->backend_decl == current_function_decl
244 || parent_flag))
246 gfc_entry_list *el = NULL;
248 for (el = sym->ns->entries; el; el = el->next)
249 if (sym == el->sym)
251 t = gfc_get_fake_result_decl (sym, parent_flag);
252 break;
256 else if (entry_master
257 && (sym->ns->proc_name->backend_decl == current_function_decl
258 || parent_flag))
259 t = gfc_get_fake_result_decl (sym, parent_flag);
261 return t;
264 static tree
265 gfc_trans_omp_variable_list (enum omp_clause_code code, gfc_namelist *namelist,
266 tree list)
268 for (; namelist != NULL; namelist = namelist->next)
269 if (namelist->sym->attr.referenced)
271 tree t = gfc_trans_omp_variable (namelist->sym);
272 if (t != error_mark_node)
274 tree node = build_omp_clause (code);
275 OMP_CLAUSE_DECL (node) = t;
276 list = gfc_trans_add_clause (node, list);
279 return list;
282 static void
283 gfc_trans_omp_array_reduction (tree c, gfc_symbol *sym, locus where)
285 gfc_symtree *root1 = NULL, *root2 = NULL, *root3 = NULL, *root4 = NULL;
286 gfc_symtree *symtree1, *symtree2, *symtree3, *symtree4 = NULL;
287 gfc_symbol init_val_sym, outer_sym, intrinsic_sym;
288 gfc_expr *e1, *e2, *e3, *e4;
289 gfc_ref *ref;
290 tree decl, backend_decl, stmt;
291 locus old_loc = gfc_current_locus;
292 const char *iname;
293 try t;
295 decl = OMP_CLAUSE_DECL (c);
296 gfc_current_locus = where;
298 /* Create a fake symbol for init value. */
299 memset (&init_val_sym, 0, sizeof (init_val_sym));
300 init_val_sym.ns = sym->ns;
301 init_val_sym.name = sym->name;
302 init_val_sym.ts = sym->ts;
303 init_val_sym.attr.referenced = 1;
304 init_val_sym.declared_at = where;
305 init_val_sym.attr.flavor = FL_VARIABLE;
306 backend_decl = omp_reduction_init (c, gfc_sym_type (&init_val_sym));
307 init_val_sym.backend_decl = backend_decl;
309 /* Create a fake symbol for the outer array reference. */
310 outer_sym = *sym;
311 outer_sym.as = gfc_copy_array_spec (sym->as);
312 outer_sym.attr.dummy = 0;
313 outer_sym.attr.result = 0;
314 outer_sym.attr.flavor = FL_VARIABLE;
315 outer_sym.backend_decl = create_tmp_var_raw (TREE_TYPE (decl), NULL);
317 /* Create fake symtrees for it. */
318 symtree1 = gfc_new_symtree (&root1, sym->name);
319 symtree1->n.sym = sym;
320 gcc_assert (symtree1 == root1);
322 symtree2 = gfc_new_symtree (&root2, sym->name);
323 symtree2->n.sym = &init_val_sym;
324 gcc_assert (symtree2 == root2);
326 symtree3 = gfc_new_symtree (&root3, sym->name);
327 symtree3->n.sym = &outer_sym;
328 gcc_assert (symtree3 == root3);
330 /* Create expressions. */
331 e1 = gfc_get_expr ();
332 e1->expr_type = EXPR_VARIABLE;
333 e1->where = where;
334 e1->symtree = symtree1;
335 e1->ts = sym->ts;
336 e1->ref = ref = gfc_get_ref ();
337 ref->u.ar.where = where;
338 ref->u.ar.as = sym->as;
339 ref->u.ar.type = AR_FULL;
340 ref->u.ar.dimen = 0;
341 t = gfc_resolve_expr (e1);
342 gcc_assert (t == SUCCESS);
344 e2 = gfc_get_expr ();
345 e2->expr_type = EXPR_VARIABLE;
346 e2->where = where;
347 e2->symtree = symtree2;
348 e2->ts = sym->ts;
349 t = gfc_resolve_expr (e2);
350 gcc_assert (t == SUCCESS);
352 e3 = gfc_copy_expr (e1);
353 e3->symtree = symtree3;
354 t = gfc_resolve_expr (e3);
355 gcc_assert (t == SUCCESS);
357 iname = NULL;
358 switch (OMP_CLAUSE_REDUCTION_CODE (c))
360 case PLUS_EXPR:
361 case MINUS_EXPR:
362 e4 = gfc_add (e3, e1);
363 break;
364 case MULT_EXPR:
365 e4 = gfc_multiply (e3, e1);
366 break;
367 case TRUTH_ANDIF_EXPR:
368 e4 = gfc_and (e3, e1);
369 break;
370 case TRUTH_ORIF_EXPR:
371 e4 = gfc_or (e3, e1);
372 break;
373 case EQ_EXPR:
374 e4 = gfc_eqv (e3, e1);
375 break;
376 case NE_EXPR:
377 e4 = gfc_neqv (e3, e1);
378 break;
379 case MIN_EXPR:
380 iname = "min";
381 break;
382 case MAX_EXPR:
383 iname = "max";
384 break;
385 case BIT_AND_EXPR:
386 iname = "iand";
387 break;
388 case BIT_IOR_EXPR:
389 iname = "ior";
390 break;
391 case BIT_XOR_EXPR:
392 iname = "ieor";
393 break;
394 default:
395 gcc_unreachable ();
397 if (iname != NULL)
399 memset (&intrinsic_sym, 0, sizeof (intrinsic_sym));
400 intrinsic_sym.ns = sym->ns;
401 intrinsic_sym.name = iname;
402 intrinsic_sym.ts = sym->ts;
403 intrinsic_sym.attr.referenced = 1;
404 intrinsic_sym.attr.intrinsic = 1;
405 intrinsic_sym.attr.function = 1;
406 intrinsic_sym.result = &intrinsic_sym;
407 intrinsic_sym.declared_at = where;
409 symtree4 = gfc_new_symtree (&root4, iname);
410 symtree4->n.sym = &intrinsic_sym;
411 gcc_assert (symtree4 == root4);
413 e4 = gfc_get_expr ();
414 e4->expr_type = EXPR_FUNCTION;
415 e4->where = where;
416 e4->symtree = symtree4;
417 e4->value.function.isym = gfc_find_function (iname);
418 e4->value.function.actual = gfc_get_actual_arglist ();
419 e4->value.function.actual->expr = e3;
420 e4->value.function.actual->next = gfc_get_actual_arglist ();
421 e4->value.function.actual->next->expr = e1;
423 /* e1 and e3 have been stored as arguments of e4, avoid sharing. */
424 e1 = gfc_copy_expr (e1);
425 e3 = gfc_copy_expr (e3);
426 t = gfc_resolve_expr (e4);
427 gcc_assert (t == SUCCESS);
429 /* Create the init statement list. */
430 pushlevel (0);
431 stmt = gfc_trans_assignment (e1, e2, false);
432 if (TREE_CODE (stmt) != BIND_EXPR)
433 stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0, 0));
434 else
435 poplevel (0, 0, 0);
436 OMP_CLAUSE_REDUCTION_INIT (c) = stmt;
438 /* Create the merge statement list. */
439 pushlevel (0);
440 stmt = gfc_trans_assignment (e3, e4, false);
441 if (TREE_CODE (stmt) != BIND_EXPR)
442 stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0, 0));
443 else
444 poplevel (0, 0, 0);
445 OMP_CLAUSE_REDUCTION_MERGE (c) = stmt;
447 /* And stick the placeholder VAR_DECL into the clause as well. */
448 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = outer_sym.backend_decl;
450 gfc_current_locus = old_loc;
452 gfc_free_expr (e1);
453 gfc_free_expr (e2);
454 gfc_free_expr (e3);
455 gfc_free_expr (e4);
456 gfc_free (symtree1);
457 gfc_free (symtree2);
458 gfc_free (symtree3);
459 if (symtree4)
460 gfc_free (symtree4);
461 gfc_free_array_spec (outer_sym.as);
464 static tree
465 gfc_trans_omp_reduction_list (gfc_namelist *namelist, tree list,
466 enum tree_code reduction_code, locus where)
468 for (; namelist != NULL; namelist = namelist->next)
469 if (namelist->sym->attr.referenced)
471 tree t = gfc_trans_omp_variable (namelist->sym);
472 if (t != error_mark_node)
474 tree node = build_omp_clause (OMP_CLAUSE_REDUCTION);
475 OMP_CLAUSE_DECL (node) = t;
476 OMP_CLAUSE_REDUCTION_CODE (node) = reduction_code;
477 if (namelist->sym->attr.dimension)
478 gfc_trans_omp_array_reduction (node, namelist->sym, where);
479 list = gfc_trans_add_clause (node, list);
482 return list;
485 static tree
486 gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
487 locus where)
489 tree omp_clauses = NULL_TREE, chunk_size, c, old_clauses;
490 int list;
491 enum omp_clause_code clause_code;
492 gfc_se se;
494 if (clauses == NULL)
495 return NULL_TREE;
497 for (list = 0; list < OMP_LIST_NUM; list++)
499 gfc_namelist *n = clauses->lists[list];
501 if (n == NULL)
502 continue;
503 if (list >= OMP_LIST_REDUCTION_FIRST
504 && list <= OMP_LIST_REDUCTION_LAST)
506 enum tree_code reduction_code;
507 switch (list)
509 case OMP_LIST_PLUS:
510 reduction_code = PLUS_EXPR;
511 break;
512 case OMP_LIST_MULT:
513 reduction_code = MULT_EXPR;
514 break;
515 case OMP_LIST_SUB:
516 reduction_code = MINUS_EXPR;
517 break;
518 case OMP_LIST_AND:
519 reduction_code = TRUTH_ANDIF_EXPR;
520 break;
521 case OMP_LIST_OR:
522 reduction_code = TRUTH_ORIF_EXPR;
523 break;
524 case OMP_LIST_EQV:
525 reduction_code = EQ_EXPR;
526 break;
527 case OMP_LIST_NEQV:
528 reduction_code = NE_EXPR;
529 break;
530 case OMP_LIST_MAX:
531 reduction_code = MAX_EXPR;
532 break;
533 case OMP_LIST_MIN:
534 reduction_code = MIN_EXPR;
535 break;
536 case OMP_LIST_IAND:
537 reduction_code = BIT_AND_EXPR;
538 break;
539 case OMP_LIST_IOR:
540 reduction_code = BIT_IOR_EXPR;
541 break;
542 case OMP_LIST_IEOR:
543 reduction_code = BIT_XOR_EXPR;
544 break;
545 default:
546 gcc_unreachable ();
548 old_clauses = omp_clauses;
549 omp_clauses
550 = gfc_trans_omp_reduction_list (n, omp_clauses, reduction_code,
551 where);
552 continue;
554 switch (list)
556 case OMP_LIST_PRIVATE:
557 clause_code = OMP_CLAUSE_PRIVATE;
558 goto add_clause;
559 case OMP_LIST_SHARED:
560 clause_code = OMP_CLAUSE_SHARED;
561 goto add_clause;
562 case OMP_LIST_FIRSTPRIVATE:
563 clause_code = OMP_CLAUSE_FIRSTPRIVATE;
564 goto add_clause;
565 case OMP_LIST_LASTPRIVATE:
566 clause_code = OMP_CLAUSE_LASTPRIVATE;
567 goto add_clause;
568 case OMP_LIST_COPYIN:
569 clause_code = OMP_CLAUSE_COPYIN;
570 goto add_clause;
571 case OMP_LIST_COPYPRIVATE:
572 clause_code = OMP_CLAUSE_COPYPRIVATE;
573 /* FALLTHROUGH */
574 add_clause:
575 omp_clauses
576 = gfc_trans_omp_variable_list (clause_code, n, omp_clauses);
577 break;
578 default:
579 break;
583 if (clauses->if_expr)
585 tree if_var;
587 gfc_init_se (&se, NULL);
588 gfc_conv_expr (&se, clauses->if_expr);
589 gfc_add_block_to_block (block, &se.pre);
590 if_var = gfc_evaluate_now (se.expr, block);
591 gfc_add_block_to_block (block, &se.post);
593 c = build_omp_clause (OMP_CLAUSE_IF);
594 OMP_CLAUSE_IF_EXPR (c) = if_var;
595 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
598 if (clauses->num_threads)
600 tree num_threads;
602 gfc_init_se (&se, NULL);
603 gfc_conv_expr (&se, clauses->num_threads);
604 gfc_add_block_to_block (block, &se.pre);
605 num_threads = gfc_evaluate_now (se.expr, block);
606 gfc_add_block_to_block (block, &se.post);
608 c = build_omp_clause (OMP_CLAUSE_NUM_THREADS);
609 OMP_CLAUSE_NUM_THREADS_EXPR (c) = num_threads;
610 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
613 chunk_size = NULL_TREE;
614 if (clauses->chunk_size)
616 gfc_init_se (&se, NULL);
617 gfc_conv_expr (&se, clauses->chunk_size);
618 gfc_add_block_to_block (block, &se.pre);
619 chunk_size = gfc_evaluate_now (se.expr, block);
620 gfc_add_block_to_block (block, &se.post);
623 if (clauses->sched_kind != OMP_SCHED_NONE)
625 c = build_omp_clause (OMP_CLAUSE_SCHEDULE);
626 OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = chunk_size;
627 switch (clauses->sched_kind)
629 case OMP_SCHED_STATIC:
630 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_STATIC;
631 break;
632 case OMP_SCHED_DYNAMIC:
633 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_DYNAMIC;
634 break;
635 case OMP_SCHED_GUIDED:
636 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_GUIDED;
637 break;
638 case OMP_SCHED_RUNTIME:
639 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_RUNTIME;
640 break;
641 default:
642 gcc_unreachable ();
644 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
647 if (clauses->default_sharing != OMP_DEFAULT_UNKNOWN)
649 c = build_omp_clause (OMP_CLAUSE_DEFAULT);
650 switch (clauses->default_sharing)
652 case OMP_DEFAULT_NONE:
653 OMP_CLAUSE_DEFAULT_KIND (c) = OMP_CLAUSE_DEFAULT_NONE;
654 break;
655 case OMP_DEFAULT_SHARED:
656 OMP_CLAUSE_DEFAULT_KIND (c) = OMP_CLAUSE_DEFAULT_SHARED;
657 break;
658 case OMP_DEFAULT_PRIVATE:
659 OMP_CLAUSE_DEFAULT_KIND (c) = OMP_CLAUSE_DEFAULT_PRIVATE;
660 break;
661 default:
662 gcc_unreachable ();
664 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
667 if (clauses->nowait)
669 c = build_omp_clause (OMP_CLAUSE_NOWAIT);
670 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
673 if (clauses->ordered)
675 c = build_omp_clause (OMP_CLAUSE_ORDERED);
676 omp_clauses = gfc_trans_add_clause (c, omp_clauses);
679 return omp_clauses;
682 /* Like gfc_trans_code, but force creation of a BIND_EXPR around it. */
684 static tree
685 gfc_trans_omp_code (gfc_code *code, bool force_empty)
687 tree stmt;
689 pushlevel (0);
690 stmt = gfc_trans_code (code);
691 if (TREE_CODE (stmt) != BIND_EXPR)
693 if (!IS_EMPTY_STMT (stmt) || force_empty)
695 tree block = poplevel (1, 0, 0);
696 stmt = build3_v (BIND_EXPR, NULL, stmt, block);
698 else
699 poplevel (0, 0, 0);
701 else
702 poplevel (0, 0, 0);
703 return stmt;
707 static tree gfc_trans_omp_sections (gfc_code *, gfc_omp_clauses *);
708 static tree gfc_trans_omp_workshare (gfc_code *, gfc_omp_clauses *);
710 static tree
711 gfc_trans_omp_atomic (gfc_code *code)
713 gfc_se lse;
714 gfc_se rse;
715 gfc_expr *expr2, *e;
716 gfc_symbol *var;
717 stmtblock_t block;
718 tree lhsaddr, type, rhs, x;
719 enum tree_code op = ERROR_MARK;
720 bool var_on_left = false;
722 code = code->block->next;
723 gcc_assert (code->op == EXEC_ASSIGN);
724 gcc_assert (code->next == NULL);
725 var = code->expr->symtree->n.sym;
727 gfc_init_se (&lse, NULL);
728 gfc_init_se (&rse, NULL);
729 gfc_start_block (&block);
731 gfc_conv_expr (&lse, code->expr);
732 gfc_add_block_to_block (&block, &lse.pre);
733 type = TREE_TYPE (lse.expr);
734 lhsaddr = gfc_build_addr_expr (NULL, lse.expr);
736 expr2 = code->expr2;
737 if (expr2->expr_type == EXPR_FUNCTION
738 && expr2->value.function.isym->id == GFC_ISYM_CONVERSION)
739 expr2 = expr2->value.function.actual->expr;
741 if (expr2->expr_type == EXPR_OP)
743 gfc_expr *e;
744 switch (expr2->value.op.operator)
746 case INTRINSIC_PLUS:
747 op = PLUS_EXPR;
748 break;
749 case INTRINSIC_TIMES:
750 op = MULT_EXPR;
751 break;
752 case INTRINSIC_MINUS:
753 op = MINUS_EXPR;
754 break;
755 case INTRINSIC_DIVIDE:
756 if (expr2->ts.type == BT_INTEGER)
757 op = TRUNC_DIV_EXPR;
758 else
759 op = RDIV_EXPR;
760 break;
761 case INTRINSIC_AND:
762 op = TRUTH_ANDIF_EXPR;
763 break;
764 case INTRINSIC_OR:
765 op = TRUTH_ORIF_EXPR;
766 break;
767 case INTRINSIC_EQV:
768 op = EQ_EXPR;
769 break;
770 case INTRINSIC_NEQV:
771 op = NE_EXPR;
772 break;
773 default:
774 gcc_unreachable ();
776 e = expr2->value.op.op1;
777 if (e->expr_type == EXPR_FUNCTION
778 && e->value.function.isym->id == GFC_ISYM_CONVERSION)
779 e = e->value.function.actual->expr;
780 if (e->expr_type == EXPR_VARIABLE
781 && e->symtree != NULL
782 && e->symtree->n.sym == var)
784 expr2 = expr2->value.op.op2;
785 var_on_left = true;
787 else
789 e = expr2->value.op.op2;
790 if (e->expr_type == EXPR_FUNCTION
791 && e->value.function.isym->id == GFC_ISYM_CONVERSION)
792 e = e->value.function.actual->expr;
793 gcc_assert (e->expr_type == EXPR_VARIABLE
794 && e->symtree != NULL
795 && e->symtree->n.sym == var);
796 expr2 = expr2->value.op.op1;
797 var_on_left = false;
799 gfc_conv_expr (&rse, expr2);
800 gfc_add_block_to_block (&block, &rse.pre);
802 else
804 gcc_assert (expr2->expr_type == EXPR_FUNCTION);
805 switch (expr2->value.function.isym->id)
807 case GFC_ISYM_MIN:
808 op = MIN_EXPR;
809 break;
810 case GFC_ISYM_MAX:
811 op = MAX_EXPR;
812 break;
813 case GFC_ISYM_IAND:
814 op = BIT_AND_EXPR;
815 break;
816 case GFC_ISYM_IOR:
817 op = BIT_IOR_EXPR;
818 break;
819 case GFC_ISYM_IEOR:
820 op = BIT_XOR_EXPR;
821 break;
822 default:
823 gcc_unreachable ();
825 e = expr2->value.function.actual->expr;
826 gcc_assert (e->expr_type == EXPR_VARIABLE
827 && e->symtree != NULL
828 && e->symtree->n.sym == var);
830 gfc_conv_expr (&rse, expr2->value.function.actual->next->expr);
831 gfc_add_block_to_block (&block, &rse.pre);
832 if (expr2->value.function.actual->next->next != NULL)
834 tree accum = gfc_create_var (TREE_TYPE (rse.expr), NULL);
835 gfc_actual_arglist *arg;
837 gfc_add_modify_stmt (&block, accum, rse.expr);
838 for (arg = expr2->value.function.actual->next->next; arg;
839 arg = arg->next)
841 gfc_init_block (&rse.pre);
842 gfc_conv_expr (&rse, arg->expr);
843 gfc_add_block_to_block (&block, &rse.pre);
844 x = fold_build2 (op, TREE_TYPE (accum), accum, rse.expr);
845 gfc_add_modify_stmt (&block, accum, x);
848 rse.expr = accum;
851 expr2 = expr2->value.function.actual->next->expr;
854 lhsaddr = save_expr (lhsaddr);
855 rhs = gfc_evaluate_now (rse.expr, &block);
856 x = convert (TREE_TYPE (rhs), build_fold_indirect_ref (lhsaddr));
858 if (var_on_left)
859 x = fold_build2 (op, TREE_TYPE (rhs), x, rhs);
860 else
861 x = fold_build2 (op, TREE_TYPE (rhs), rhs, x);
863 if (TREE_CODE (TREE_TYPE (rhs)) == COMPLEX_TYPE
864 && TREE_CODE (type) != COMPLEX_TYPE)
865 x = build1 (REALPART_EXPR, TREE_TYPE (TREE_TYPE (rhs)), x);
867 x = build2_v (OMP_ATOMIC, lhsaddr, convert (type, x));
868 gfc_add_expr_to_block (&block, x);
870 gfc_add_block_to_block (&block, &lse.pre);
871 gfc_add_block_to_block (&block, &rse.pre);
873 return gfc_finish_block (&block);
876 static tree
877 gfc_trans_omp_barrier (void)
879 tree decl = built_in_decls [BUILT_IN_GOMP_BARRIER];
880 return build_call_expr (decl, 0);
883 static tree
884 gfc_trans_omp_critical (gfc_code *code)
886 tree name = NULL_TREE, stmt;
887 if (code->ext.omp_name != NULL)
888 name = get_identifier (code->ext.omp_name);
889 stmt = gfc_trans_code (code->block->next);
890 return build2_v (OMP_CRITICAL, stmt, name);
893 static tree
894 gfc_trans_omp_do (gfc_code *code, stmtblock_t *pblock,
895 gfc_omp_clauses *do_clauses)
897 gfc_se se;
898 tree dovar, stmt, from, to, step, type, init, cond, incr;
899 tree count = NULL_TREE, cycle_label, tmp, omp_clauses;
900 stmtblock_t block;
901 stmtblock_t body;
902 int simple = 0;
903 bool dovar_found = false;
904 gfc_omp_clauses *clauses = code->ext.omp_clauses;
906 code = code->block->next;
907 gcc_assert (code->op == EXEC_DO);
909 if (pblock == NULL)
911 gfc_start_block (&block);
912 pblock = &block;
915 omp_clauses = gfc_trans_omp_clauses (pblock, do_clauses, code->loc);
916 if (clauses)
918 gfc_namelist *n;
919 for (n = clauses->lists[OMP_LIST_LASTPRIVATE]; n != NULL; n = n->next)
920 if (code->ext.iterator->var->symtree->n.sym == n->sym)
921 break;
922 if (n == NULL)
923 for (n = clauses->lists[OMP_LIST_PRIVATE]; n != NULL; n = n->next)
924 if (code->ext.iterator->var->symtree->n.sym == n->sym)
925 break;
926 if (n != NULL)
927 dovar_found = true;
930 /* Evaluate all the expressions in the iterator. */
931 gfc_init_se (&se, NULL);
932 gfc_conv_expr_lhs (&se, code->ext.iterator->var);
933 gfc_add_block_to_block (pblock, &se.pre);
934 dovar = se.expr;
935 type = TREE_TYPE (dovar);
936 gcc_assert (TREE_CODE (type) == INTEGER_TYPE);
938 gfc_init_se (&se, NULL);
939 gfc_conv_expr_val (&se, code->ext.iterator->start);
940 gfc_add_block_to_block (pblock, &se.pre);
941 from = gfc_evaluate_now (se.expr, pblock);
943 gfc_init_se (&se, NULL);
944 gfc_conv_expr_val (&se, code->ext.iterator->end);
945 gfc_add_block_to_block (pblock, &se.pre);
946 to = gfc_evaluate_now (se.expr, pblock);
948 gfc_init_se (&se, NULL);
949 gfc_conv_expr_val (&se, code->ext.iterator->step);
950 gfc_add_block_to_block (pblock, &se.pre);
951 step = gfc_evaluate_now (se.expr, pblock);
953 /* Special case simple loops. */
954 if (integer_onep (step))
955 simple = 1;
956 else if (tree_int_cst_equal (step, integer_minus_one_node))
957 simple = -1;
959 /* Loop body. */
960 if (simple)
962 init = build2_v (GIMPLE_MODIFY_STMT, dovar, from);
963 cond = build2 (simple > 0 ? LE_EXPR : GE_EXPR, boolean_type_node,
964 dovar, to);
965 incr = fold_build2 (PLUS_EXPR, type, dovar, step);
966 incr = fold_build2 (GIMPLE_MODIFY_STMT, type, dovar, incr);
967 if (pblock != &block)
969 pushlevel (0);
970 gfc_start_block (&block);
972 gfc_start_block (&body);
974 else
976 /* STEP is not 1 or -1. Use:
977 for (count = 0; count < (to + step - from) / step; count++)
979 dovar = from + count * step;
980 body;
981 cycle_label:;
982 } */
983 tmp = fold_build2 (MINUS_EXPR, type, step, from);
984 tmp = fold_build2 (PLUS_EXPR, type, to, tmp);
985 tmp = fold_build2 (TRUNC_DIV_EXPR, type, tmp, step);
986 tmp = gfc_evaluate_now (tmp, pblock);
987 count = gfc_create_var (type, "count");
988 init = build2_v (GIMPLE_MODIFY_STMT, count, build_int_cst (type, 0));
989 cond = build2 (LT_EXPR, boolean_type_node, count, tmp);
990 incr = fold_build2 (PLUS_EXPR, type, count, build_int_cst (type, 1));
991 incr = fold_build2 (GIMPLE_MODIFY_STMT, type, count, incr);
993 if (pblock != &block)
995 pushlevel (0);
996 gfc_start_block (&block);
998 gfc_start_block (&body);
1000 /* Initialize DOVAR. */
1001 tmp = fold_build2 (MULT_EXPR, type, count, step);
1002 tmp = build2 (PLUS_EXPR, type, from, tmp);
1003 gfc_add_modify_stmt (&body, dovar, tmp);
1006 if (!dovar_found)
1008 tmp = build_omp_clause (OMP_CLAUSE_PRIVATE);
1009 OMP_CLAUSE_DECL (tmp) = dovar;
1010 omp_clauses = gfc_trans_add_clause (tmp, omp_clauses);
1012 if (!simple)
1014 tmp = build_omp_clause (OMP_CLAUSE_PRIVATE);
1015 OMP_CLAUSE_DECL (tmp) = count;
1016 omp_clauses = gfc_trans_add_clause (tmp, omp_clauses);
1019 /* Cycle statement is implemented with a goto. Exit statement must not be
1020 present for this loop. */
1021 cycle_label = gfc_build_label_decl (NULL_TREE);
1023 /* Put these labels where they can be found later. We put the
1024 labels in a TREE_LIST node (because TREE_CHAIN is already
1025 used). cycle_label goes in TREE_PURPOSE (backend_decl), exit
1026 label in TREE_VALUE (backend_decl). */
1028 code->block->backend_decl = tree_cons (cycle_label, NULL, NULL);
1030 /* Main loop body. */
1031 tmp = gfc_trans_omp_code (code->block->next, true);
1032 gfc_add_expr_to_block (&body, tmp);
1034 /* Label for cycle statements (if needed). */
1035 if (TREE_USED (cycle_label))
1037 tmp = build1_v (LABEL_EXPR, cycle_label);
1038 gfc_add_expr_to_block (&body, tmp);
1041 /* End of loop body. */
1042 stmt = make_node (OMP_FOR);
1044 TREE_TYPE (stmt) = void_type_node;
1045 OMP_FOR_BODY (stmt) = gfc_finish_block (&body);
1046 OMP_FOR_CLAUSES (stmt) = omp_clauses;
1047 OMP_FOR_INIT (stmt) = init;
1048 OMP_FOR_COND (stmt) = cond;
1049 OMP_FOR_INCR (stmt) = incr;
1050 gfc_add_expr_to_block (&block, stmt);
1052 return gfc_finish_block (&block);
1055 static tree
1056 gfc_trans_omp_flush (void)
1058 tree decl = built_in_decls [BUILT_IN_SYNCHRONIZE];
1059 return build_call_expr (decl, 0);
1062 static tree
1063 gfc_trans_omp_master (gfc_code *code)
1065 tree stmt = gfc_trans_code (code->block->next);
1066 if (IS_EMPTY_STMT (stmt))
1067 return stmt;
1068 return build1_v (OMP_MASTER, stmt);
1071 static tree
1072 gfc_trans_omp_ordered (gfc_code *code)
1074 return build1_v (OMP_ORDERED, gfc_trans_code (code->block->next));
1077 static tree
1078 gfc_trans_omp_parallel (gfc_code *code)
1080 stmtblock_t block;
1081 tree stmt, omp_clauses;
1083 gfc_start_block (&block);
1084 omp_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
1085 code->loc);
1086 stmt = gfc_trans_omp_code (code->block->next, true);
1087 stmt = build4_v (OMP_PARALLEL, stmt, omp_clauses, NULL, NULL);
1088 gfc_add_expr_to_block (&block, stmt);
1089 return gfc_finish_block (&block);
1092 static tree
1093 gfc_trans_omp_parallel_do (gfc_code *code)
1095 stmtblock_t block, *pblock = NULL;
1096 gfc_omp_clauses parallel_clauses, do_clauses;
1097 tree stmt, omp_clauses = NULL_TREE;
1099 gfc_start_block (&block);
1101 memset (&do_clauses, 0, sizeof (do_clauses));
1102 if (code->ext.omp_clauses != NULL)
1104 memcpy (&parallel_clauses, code->ext.omp_clauses,
1105 sizeof (parallel_clauses));
1106 do_clauses.sched_kind = parallel_clauses.sched_kind;
1107 do_clauses.chunk_size = parallel_clauses.chunk_size;
1108 do_clauses.ordered = parallel_clauses.ordered;
1109 parallel_clauses.sched_kind = OMP_SCHED_NONE;
1110 parallel_clauses.chunk_size = NULL;
1111 parallel_clauses.ordered = false;
1112 omp_clauses = gfc_trans_omp_clauses (&block, &parallel_clauses,
1113 code->loc);
1115 do_clauses.nowait = true;
1116 if (!do_clauses.ordered && do_clauses.sched_kind != OMP_SCHED_STATIC)
1117 pblock = &block;
1118 else
1119 pushlevel (0);
1120 stmt = gfc_trans_omp_do (code, pblock, &do_clauses);
1121 if (TREE_CODE (stmt) != BIND_EXPR)
1122 stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0, 0));
1123 else
1124 poplevel (0, 0, 0);
1125 stmt = build4_v (OMP_PARALLEL, stmt, omp_clauses, NULL, NULL);
1126 OMP_PARALLEL_COMBINED (stmt) = 1;
1127 gfc_add_expr_to_block (&block, stmt);
1128 return gfc_finish_block (&block);
1131 static tree
1132 gfc_trans_omp_parallel_sections (gfc_code *code)
1134 stmtblock_t block;
1135 gfc_omp_clauses section_clauses;
1136 tree stmt, omp_clauses;
1138 memset (&section_clauses, 0, sizeof (section_clauses));
1139 section_clauses.nowait = true;
1141 gfc_start_block (&block);
1142 omp_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
1143 code->loc);
1144 pushlevel (0);
1145 stmt = gfc_trans_omp_sections (code, &section_clauses);
1146 if (TREE_CODE (stmt) != BIND_EXPR)
1147 stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0, 0));
1148 else
1149 poplevel (0, 0, 0);
1150 stmt = build4_v (OMP_PARALLEL, stmt, omp_clauses, NULL, NULL);
1151 OMP_PARALLEL_COMBINED (stmt) = 1;
1152 gfc_add_expr_to_block (&block, stmt);
1153 return gfc_finish_block (&block);
1156 static tree
1157 gfc_trans_omp_parallel_workshare (gfc_code *code)
1159 stmtblock_t block;
1160 gfc_omp_clauses workshare_clauses;
1161 tree stmt, omp_clauses;
1163 memset (&workshare_clauses, 0, sizeof (workshare_clauses));
1164 workshare_clauses.nowait = true;
1166 gfc_start_block (&block);
1167 omp_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
1168 code->loc);
1169 pushlevel (0);
1170 stmt = gfc_trans_omp_workshare (code, &workshare_clauses);
1171 if (TREE_CODE (stmt) != BIND_EXPR)
1172 stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0, 0));
1173 else
1174 poplevel (0, 0, 0);
1175 stmt = build4_v (OMP_PARALLEL, stmt, omp_clauses, NULL, NULL);
1176 OMP_PARALLEL_COMBINED (stmt) = 1;
1177 gfc_add_expr_to_block (&block, stmt);
1178 return gfc_finish_block (&block);
1181 static tree
1182 gfc_trans_omp_sections (gfc_code *code, gfc_omp_clauses *clauses)
1184 stmtblock_t block, body;
1185 tree omp_clauses, stmt;
1186 bool has_lastprivate = clauses->lists[OMP_LIST_LASTPRIVATE] != NULL;
1188 gfc_start_block (&block);
1190 omp_clauses = gfc_trans_omp_clauses (&block, clauses, code->loc);
1192 gfc_init_block (&body);
1193 for (code = code->block; code; code = code->block)
1195 /* Last section is special because of lastprivate, so even if it
1196 is empty, chain it in. */
1197 stmt = gfc_trans_omp_code (code->next,
1198 has_lastprivate && code->block == NULL);
1199 if (! IS_EMPTY_STMT (stmt))
1201 stmt = build1_v (OMP_SECTION, stmt);
1202 gfc_add_expr_to_block (&body, stmt);
1205 stmt = gfc_finish_block (&body);
1207 stmt = build3_v (OMP_SECTIONS, stmt, omp_clauses, NULL_TREE);
1208 gfc_add_expr_to_block (&block, stmt);
1210 return gfc_finish_block (&block);
1213 static tree
1214 gfc_trans_omp_single (gfc_code *code, gfc_omp_clauses *clauses)
1216 tree omp_clauses = gfc_trans_omp_clauses (NULL, clauses, code->loc);
1217 tree stmt = gfc_trans_omp_code (code->block->next, true);
1218 stmt = build2_v (OMP_SINGLE, stmt, omp_clauses);
1219 return stmt;
1222 static tree
1223 gfc_trans_omp_workshare (gfc_code *code, gfc_omp_clauses *clauses)
1225 /* XXX */
1226 return gfc_trans_omp_single (code, clauses);
1229 tree
1230 gfc_trans_omp_directive (gfc_code *code)
1232 switch (code->op)
1234 case EXEC_OMP_ATOMIC:
1235 return gfc_trans_omp_atomic (code);
1236 case EXEC_OMP_BARRIER:
1237 return gfc_trans_omp_barrier ();
1238 case EXEC_OMP_CRITICAL:
1239 return gfc_trans_omp_critical (code);
1240 case EXEC_OMP_DO:
1241 return gfc_trans_omp_do (code, NULL, code->ext.omp_clauses);
1242 case EXEC_OMP_FLUSH:
1243 return gfc_trans_omp_flush ();
1244 case EXEC_OMP_MASTER:
1245 return gfc_trans_omp_master (code);
1246 case EXEC_OMP_ORDERED:
1247 return gfc_trans_omp_ordered (code);
1248 case EXEC_OMP_PARALLEL:
1249 return gfc_trans_omp_parallel (code);
1250 case EXEC_OMP_PARALLEL_DO:
1251 return gfc_trans_omp_parallel_do (code);
1252 case EXEC_OMP_PARALLEL_SECTIONS:
1253 return gfc_trans_omp_parallel_sections (code);
1254 case EXEC_OMP_PARALLEL_WORKSHARE:
1255 return gfc_trans_omp_parallel_workshare (code);
1256 case EXEC_OMP_SECTIONS:
1257 return gfc_trans_omp_sections (code, code->ext.omp_clauses);
1258 case EXEC_OMP_SINGLE:
1259 return gfc_trans_omp_single (code, code->ext.omp_clauses);
1260 case EXEC_OMP_WORKSHARE:
1261 return gfc_trans_omp_workshare (code, code->ext.omp_clauses);
1262 default:
1263 gcc_unreachable ();