1 /* OpenMP directive matching and resolving.
2 Copyright (C) 2005, 2006, 2007
3 Free Software Foundation, Inc.
4 Contributed by Jakub Jelinek
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to the Free
20 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
29 #include "pointer-set.h"
33 /* Match an end of OpenMP directive. End of OpenMP directive is optional
34 whitespace, followed by '\n' or comment '!'. */
37 gfc_match_omp_eos (void)
42 old_loc = gfc_current_locus;
43 gfc_gobble_whitespace ();
58 gfc_current_locus = old_loc;
62 /* Free an omp_clauses structure. */
65 gfc_free_omp_clauses (gfc_omp_clauses *c)
71 gfc_free_expr (c->if_expr);
72 gfc_free_expr (c->num_threads);
73 gfc_free_expr (c->chunk_size);
74 for (i = 0; i < OMP_LIST_NUM; i++)
75 gfc_free_namelist (c->lists[i]);
79 /* Match a variable/common block list and construct a namelist from it. */
82 gfc_match_omp_variable_list (const char *str, gfc_namelist **list,
85 gfc_namelist *head, *tail, *p;
87 char n[GFC_MAX_SYMBOL_LEN+1];
94 old_loc = gfc_current_locus;
102 m = gfc_match_symbol (&sym, 1);
106 gfc_set_sym_referenced (sym);
107 p = gfc_get_namelist ();
126 m = gfc_match (" / %n /", n);
127 if (m == MATCH_ERROR)
132 st = gfc_find_symtree (gfc_current_ns->common_root, n);
135 gfc_error ("COMMON block /%s/ not found at %C", n);
138 for (sym = st->n.common->head; sym; sym = sym->common_next)
140 gfc_set_sym_referenced (sym);
141 p = gfc_get_namelist ();
153 if (gfc_match_char (')') == MATCH_YES)
155 if (gfc_match_char (',') != MATCH_YES)
160 list = &(*list)->next;
166 gfc_error ("Syntax error in OpenMP variable list at %C");
169 gfc_free_namelist (head);
170 gfc_current_locus = old_loc;
174 #define OMP_CLAUSE_PRIVATE (1 << 0)
175 #define OMP_CLAUSE_FIRSTPRIVATE (1 << 1)
176 #define OMP_CLAUSE_LASTPRIVATE (1 << 2)
177 #define OMP_CLAUSE_COPYPRIVATE (1 << 3)
178 #define OMP_CLAUSE_SHARED (1 << 4)
179 #define OMP_CLAUSE_COPYIN (1 << 5)
180 #define OMP_CLAUSE_REDUCTION (1 << 6)
181 #define OMP_CLAUSE_IF (1 << 7)
182 #define OMP_CLAUSE_NUM_THREADS (1 << 8)
183 #define OMP_CLAUSE_SCHEDULE (1 << 9)
184 #define OMP_CLAUSE_DEFAULT (1 << 10)
185 #define OMP_CLAUSE_ORDERED (1 << 11)
187 /* Match OpenMP directive clauses. MASK is a bitmask of
188 clauses that are allowed for a particular directive. */
191 gfc_match_omp_clauses (gfc_omp_clauses **cp, int mask)
193 gfc_omp_clauses *c = gfc_get_omp_clauses ();
195 bool needs_space = true, first = true;
200 if ((first || gfc_match_char (',') != MATCH_YES)
201 && (needs_space && gfc_match_space () != MATCH_YES))
205 gfc_gobble_whitespace ();
206 if ((mask & OMP_CLAUSE_IF) && c->if_expr == NULL
207 && gfc_match ("if ( %e )", &c->if_expr) == MATCH_YES)
209 if ((mask & OMP_CLAUSE_NUM_THREADS) && c->num_threads == NULL
210 && gfc_match ("num_threads ( %e )", &c->num_threads) == MATCH_YES)
212 if ((mask & OMP_CLAUSE_PRIVATE)
213 && gfc_match_omp_variable_list ("private (",
214 &c->lists[OMP_LIST_PRIVATE], true)
217 if ((mask & OMP_CLAUSE_FIRSTPRIVATE)
218 && gfc_match_omp_variable_list ("firstprivate (",
219 &c->lists[OMP_LIST_FIRSTPRIVATE],
223 if ((mask & OMP_CLAUSE_LASTPRIVATE)
224 && gfc_match_omp_variable_list ("lastprivate (",
225 &c->lists[OMP_LIST_LASTPRIVATE],
229 if ((mask & OMP_CLAUSE_COPYPRIVATE)
230 && gfc_match_omp_variable_list ("copyprivate (",
231 &c->lists[OMP_LIST_COPYPRIVATE],
235 if ((mask & OMP_CLAUSE_SHARED)
236 && gfc_match_omp_variable_list ("shared (",
237 &c->lists[OMP_LIST_SHARED], true)
240 if ((mask & OMP_CLAUSE_COPYIN)
241 && gfc_match_omp_variable_list ("copyin (",
242 &c->lists[OMP_LIST_COPYIN], true)
245 old_loc = gfc_current_locus;
246 if ((mask & OMP_CLAUSE_REDUCTION)
247 && gfc_match ("reduction ( ") == MATCH_YES)
249 int reduction = OMP_LIST_NUM;
250 char buffer[GFC_MAX_SYMBOL_LEN + 1];
251 if (gfc_match_char ('+') == MATCH_YES)
252 reduction = OMP_LIST_PLUS;
253 else if (gfc_match_char ('*') == MATCH_YES)
254 reduction = OMP_LIST_MULT;
255 else if (gfc_match_char ('-') == MATCH_YES)
256 reduction = OMP_LIST_SUB;
257 else if (gfc_match (".and.") == MATCH_YES)
258 reduction = OMP_LIST_AND;
259 else if (gfc_match (".or.") == MATCH_YES)
260 reduction = OMP_LIST_OR;
261 else if (gfc_match (".eqv.") == MATCH_YES)
262 reduction = OMP_LIST_EQV;
263 else if (gfc_match (".neqv.") == MATCH_YES)
264 reduction = OMP_LIST_NEQV;
265 else if (gfc_match_name (buffer) == MATCH_YES)
268 const char *n = buffer;
270 gfc_find_symbol (buffer, NULL, 1, &sym);
273 if (sym->attr.intrinsic)
275 else if ((sym->attr.flavor != FL_UNKNOWN
276 && sym->attr.flavor != FL_PROCEDURE)
277 || sym->attr.external
282 || sym->attr.subroutine
285 || sym->attr.cray_pointer
286 || sym->attr.cray_pointee
287 || (sym->attr.proc != PROC_UNKNOWN
288 && sym->attr.proc != PROC_INTRINSIC)
289 || sym->attr.if_source != IFSRC_UNKNOWN
290 || sym == sym->ns->proc_name)
292 gfc_error_now ("%s is not INTRINSIC procedure name "
299 if (strcmp (n, "max") == 0)
300 reduction = OMP_LIST_MAX;
301 else if (strcmp (n, "min") == 0)
302 reduction = OMP_LIST_MIN;
303 else if (strcmp (n, "iand") == 0)
304 reduction = OMP_LIST_IAND;
305 else if (strcmp (n, "ior") == 0)
306 reduction = OMP_LIST_IOR;
307 else if (strcmp (n, "ieor") == 0)
308 reduction = OMP_LIST_IEOR;
309 if (reduction != OMP_LIST_NUM
311 && ! sym->attr.intrinsic
312 && ! sym->attr.use_assoc
313 && ((sym->attr.flavor == FL_UNKNOWN
314 && gfc_add_flavor (&sym->attr, FL_PROCEDURE,
315 sym->name, NULL) == FAILURE)
316 || gfc_add_intrinsic (&sym->attr, NULL) == FAILURE))
318 gfc_free_omp_clauses (c);
322 if (reduction != OMP_LIST_NUM
323 && gfc_match_omp_variable_list (" :", &c->lists[reduction],
328 gfc_current_locus = old_loc;
330 if ((mask & OMP_CLAUSE_DEFAULT)
331 && c->default_sharing == OMP_DEFAULT_UNKNOWN)
333 if (gfc_match ("default ( shared )") == MATCH_YES)
334 c->default_sharing = OMP_DEFAULT_SHARED;
335 else if (gfc_match ("default ( private )") == MATCH_YES)
336 c->default_sharing = OMP_DEFAULT_PRIVATE;
337 else if (gfc_match ("default ( none )") == MATCH_YES)
338 c->default_sharing = OMP_DEFAULT_NONE;
339 if (c->default_sharing != OMP_DEFAULT_UNKNOWN)
342 old_loc = gfc_current_locus;
343 if ((mask & OMP_CLAUSE_SCHEDULE)
344 && c->sched_kind == OMP_SCHED_NONE
345 && gfc_match ("schedule ( ") == MATCH_YES)
347 if (gfc_match ("static") == MATCH_YES)
348 c->sched_kind = OMP_SCHED_STATIC;
349 else if (gfc_match ("dynamic") == MATCH_YES)
350 c->sched_kind = OMP_SCHED_DYNAMIC;
351 else if (gfc_match ("guided") == MATCH_YES)
352 c->sched_kind = OMP_SCHED_GUIDED;
353 else if (gfc_match ("runtime") == MATCH_YES)
354 c->sched_kind = OMP_SCHED_RUNTIME;
355 if (c->sched_kind != OMP_SCHED_NONE)
358 if (c->sched_kind != OMP_SCHED_RUNTIME)
359 m = gfc_match (" , %e )", &c->chunk_size);
361 m = gfc_match_char (')');
363 c->sched_kind = OMP_SCHED_NONE;
365 if (c->sched_kind != OMP_SCHED_NONE)
368 gfc_current_locus = old_loc;
370 if ((mask & OMP_CLAUSE_ORDERED) && !c->ordered
371 && gfc_match ("ordered") == MATCH_YES)
373 c->ordered = needs_space = true;
380 if (gfc_match_omp_eos () != MATCH_YES)
382 gfc_free_omp_clauses (c);
390 #define OMP_PARALLEL_CLAUSES \
391 (OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_SHARED \
392 | OMP_CLAUSE_COPYIN | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_IF \
393 | OMP_CLAUSE_NUM_THREADS | OMP_CLAUSE_DEFAULT)
394 #define OMP_DO_CLAUSES \
395 (OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE \
396 | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION \
397 | OMP_CLAUSE_SCHEDULE | OMP_CLAUSE_ORDERED)
398 #define OMP_SECTIONS_CLAUSES \
399 (OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE \
400 | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION)
403 gfc_match_omp_parallel (void)
406 if (gfc_match_omp_clauses (&c, OMP_PARALLEL_CLAUSES) != MATCH_YES)
408 new_st.op = EXEC_OMP_PARALLEL;
409 new_st.ext.omp_clauses = c;
415 gfc_match_omp_critical (void)
417 char n[GFC_MAX_SYMBOL_LEN+1];
419 if (gfc_match (" ( %n )", n) != MATCH_YES)
421 if (gfc_match_omp_eos () != MATCH_YES)
423 new_st.op = EXEC_OMP_CRITICAL;
424 new_st.ext.omp_name = n[0] ? xstrdup (n) : NULL;
430 gfc_match_omp_do (void)
433 if (gfc_match_omp_clauses (&c, OMP_DO_CLAUSES) != MATCH_YES)
435 new_st.op = EXEC_OMP_DO;
436 new_st.ext.omp_clauses = c;
442 gfc_match_omp_flush (void)
444 gfc_namelist *list = NULL;
445 gfc_match_omp_variable_list (" (", &list, true);
446 if (gfc_match_omp_eos () != MATCH_YES)
448 gfc_free_namelist (list);
451 new_st.op = EXEC_OMP_FLUSH;
452 new_st.ext.omp_namelist = list;
458 gfc_match_omp_threadprivate (void)
461 char n[GFC_MAX_SYMBOL_LEN+1];
466 old_loc = gfc_current_locus;
468 m = gfc_match (" (");
474 m = gfc_match_symbol (&sym, 0);
478 if (sym->attr.in_common)
479 gfc_error_now ("Threadprivate variable at %C is an element of "
481 else if (gfc_add_threadprivate (&sym->attr, sym->name,
482 &sym->declared_at) == FAILURE)
491 m = gfc_match (" / %n /", n);
492 if (m == MATCH_ERROR)
494 if (m == MATCH_NO || n[0] == '\0')
497 st = gfc_find_symtree (gfc_current_ns->common_root, n);
500 gfc_error ("COMMON block /%s/ not found at %C", n);
503 st->n.common->threadprivate = 1;
504 for (sym = st->n.common->head; sym; sym = sym->common_next)
505 if (gfc_add_threadprivate (&sym->attr, sym->name,
506 &sym->declared_at) == FAILURE)
510 if (gfc_match_char (')') == MATCH_YES)
512 if (gfc_match_char (',') != MATCH_YES)
519 gfc_error ("Syntax error in !$OMP THREADPRIVATE list at %C");
522 gfc_current_locus = old_loc;
528 gfc_match_omp_parallel_do (void)
531 if (gfc_match_omp_clauses (&c, OMP_PARALLEL_CLAUSES | OMP_DO_CLAUSES)
534 new_st.op = EXEC_OMP_PARALLEL_DO;
535 new_st.ext.omp_clauses = c;
541 gfc_match_omp_parallel_sections (void)
544 if (gfc_match_omp_clauses (&c, OMP_PARALLEL_CLAUSES | OMP_SECTIONS_CLAUSES)
547 new_st.op = EXEC_OMP_PARALLEL_SECTIONS;
548 new_st.ext.omp_clauses = c;
554 gfc_match_omp_parallel_workshare (void)
557 if (gfc_match_omp_clauses (&c, OMP_PARALLEL_CLAUSES) != MATCH_YES)
559 new_st.op = EXEC_OMP_PARALLEL_WORKSHARE;
560 new_st.ext.omp_clauses = c;
566 gfc_match_omp_sections (void)
569 if (gfc_match_omp_clauses (&c, OMP_SECTIONS_CLAUSES) != MATCH_YES)
571 new_st.op = EXEC_OMP_SECTIONS;
572 new_st.ext.omp_clauses = c;
578 gfc_match_omp_single (void)
581 if (gfc_match_omp_clauses (&c, OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE)
584 new_st.op = EXEC_OMP_SINGLE;
585 new_st.ext.omp_clauses = c;
591 gfc_match_omp_workshare (void)
593 if (gfc_match_omp_eos () != MATCH_YES)
595 new_st.op = EXEC_OMP_WORKSHARE;
596 new_st.ext.omp_clauses = gfc_get_omp_clauses ();
602 gfc_match_omp_master (void)
604 if (gfc_match_omp_eos () != MATCH_YES)
606 new_st.op = EXEC_OMP_MASTER;
607 new_st.ext.omp_clauses = NULL;
613 gfc_match_omp_ordered (void)
615 if (gfc_match_omp_eos () != MATCH_YES)
617 new_st.op = EXEC_OMP_ORDERED;
618 new_st.ext.omp_clauses = NULL;
624 gfc_match_omp_atomic (void)
626 if (gfc_match_omp_eos () != MATCH_YES)
628 new_st.op = EXEC_OMP_ATOMIC;
629 new_st.ext.omp_clauses = NULL;
635 gfc_match_omp_barrier (void)
637 if (gfc_match_omp_eos () != MATCH_YES)
639 new_st.op = EXEC_OMP_BARRIER;
640 new_st.ext.omp_clauses = NULL;
646 gfc_match_omp_end_nowait (void)
649 if (gfc_match ("% nowait") == MATCH_YES)
651 if (gfc_match_omp_eos () != MATCH_YES)
653 new_st.op = EXEC_OMP_END_NOWAIT;
654 new_st.ext.omp_bool = nowait;
660 gfc_match_omp_end_single (void)
663 if (gfc_match ("% nowait") == MATCH_YES)
665 new_st.op = EXEC_OMP_END_NOWAIT;
666 new_st.ext.omp_bool = true;
669 if (gfc_match_omp_clauses (&c, OMP_CLAUSE_COPYPRIVATE) != MATCH_YES)
671 new_st.op = EXEC_OMP_END_SINGLE;
672 new_st.ext.omp_clauses = c;
677 /* OpenMP directive resolving routines. */
680 resolve_omp_clauses (gfc_code *code)
682 gfc_omp_clauses *omp_clauses = code->ext.omp_clauses;
685 static const char *clause_names[]
686 = { "PRIVATE", "FIRSTPRIVATE", "LASTPRIVATE", "COPYPRIVATE", "SHARED",
687 "COPYIN", "REDUCTION" };
689 if (omp_clauses == NULL)
692 if (omp_clauses->if_expr)
694 gfc_expr *expr = omp_clauses->if_expr;
695 if (gfc_resolve_expr (expr) == FAILURE
696 || expr->ts.type != BT_LOGICAL || expr->rank != 0)
697 gfc_error ("IF clause at %L requires a scalar LOGICAL expression",
700 if (omp_clauses->num_threads)
702 gfc_expr *expr = omp_clauses->num_threads;
703 if (gfc_resolve_expr (expr) == FAILURE
704 || expr->ts.type != BT_INTEGER || expr->rank != 0)
705 gfc_error ("NUM_THREADS clause at %L requires a scalar "
706 "INTEGER expression", &expr->where);
708 if (omp_clauses->chunk_size)
710 gfc_expr *expr = omp_clauses->chunk_size;
711 if (gfc_resolve_expr (expr) == FAILURE
712 || expr->ts.type != BT_INTEGER || expr->rank != 0)
713 gfc_error ("SCHEDULE clause's chunk_size at %L requires "
714 "a scalar INTEGER expression", &expr->where);
717 /* Check that no symbol appears on multiple clauses, except that
718 a symbol can appear on both firstprivate and lastprivate. */
719 for (list = 0; list < OMP_LIST_NUM; list++)
720 for (n = omp_clauses->lists[list]; n; n = n->next)
723 for (list = 0; list < OMP_LIST_NUM; list++)
724 if (list != OMP_LIST_FIRSTPRIVATE && list != OMP_LIST_LASTPRIVATE)
725 for (n = omp_clauses->lists[list]; n; n = n->next)
727 gfc_error ("Symbol '%s' present on multiple clauses at %L",
728 n->sym->name, &code->loc);
732 gcc_assert (OMP_LIST_LASTPRIVATE == OMP_LIST_FIRSTPRIVATE + 1);
733 for (list = OMP_LIST_FIRSTPRIVATE; list <= OMP_LIST_LASTPRIVATE; list++)
734 for (n = omp_clauses->lists[list]; n; n = n->next)
737 gfc_error ("Symbol '%s' present on multiple clauses at %L",
738 n->sym->name, &code->loc);
742 for (n = omp_clauses->lists[OMP_LIST_FIRSTPRIVATE]; n; n = n->next)
744 gfc_error ("Symbol '%s' present on multiple clauses at %L",
745 n->sym->name, &code->loc);
749 for (n = omp_clauses->lists[OMP_LIST_LASTPRIVATE]; n; n = n->next)
752 for (n = omp_clauses->lists[OMP_LIST_LASTPRIVATE]; n; n = n->next)
754 gfc_error ("Symbol '%s' present on multiple clauses at %L",
755 n->sym->name, &code->loc);
759 for (list = 0; list < OMP_LIST_NUM; list++)
760 if ((n = omp_clauses->lists[list]) != NULL)
764 if (list < OMP_LIST_REDUCTION_FIRST)
765 name = clause_names[list];
766 else if (list <= OMP_LIST_REDUCTION_LAST)
767 name = clause_names[OMP_LIST_REDUCTION_FIRST];
773 case OMP_LIST_COPYIN:
774 for (; n != NULL; n = n->next)
776 if (!n->sym->attr.threadprivate)
777 gfc_error ("Non-THREADPRIVATE object '%s' in COPYIN clause"
778 " at %L", n->sym->name, &code->loc);
779 if (n->sym->attr.allocatable)
780 gfc_error ("COPYIN clause object '%s' is ALLOCATABLE at %L",
781 n->sym->name, &code->loc);
782 if (n->sym->ts.type == BT_DERIVED && n->sym->ts.derived->attr.alloc_comp)
783 gfc_error ("COPYIN clause object '%s' at %L has ALLOCATABLE components",
784 n->sym->name, &code->loc);
787 case OMP_LIST_COPYPRIVATE:
788 for (; n != NULL; n = n->next)
790 if (n->sym->as && n->sym->as->type == AS_ASSUMED_SIZE)
791 gfc_error ("Assumed size array '%s' in COPYPRIVATE clause "
792 "at %L", n->sym->name, &code->loc);
793 if (n->sym->attr.allocatable)
794 gfc_error ("COPYPRIVATE clause object '%s' is ALLOCATABLE "
795 "at %L", n->sym->name, &code->loc);
796 if (n->sym->ts.type == BT_DERIVED && n->sym->ts.derived->attr.alloc_comp)
797 gfc_error ("COPYPRIVATE clause object '%s' at %L has ALLOCATABLE components",
798 n->sym->name, &code->loc);
801 case OMP_LIST_SHARED:
802 for (; n != NULL; n = n->next)
804 if (n->sym->attr.threadprivate)
805 gfc_error ("THREADPRIVATE object '%s' in SHARED clause at "
806 "%L", n->sym->name, &code->loc);
807 if (n->sym->attr.cray_pointee)
808 gfc_error ("Cray pointee '%s' in SHARED clause at %L",
809 n->sym->name, &code->loc);
813 for (; n != NULL; n = n->next)
815 if (n->sym->attr.threadprivate)
816 gfc_error ("THREADPRIVATE object '%s' in %s clause at %L",
817 n->sym->name, name, &code->loc);
818 if (n->sym->attr.cray_pointee)
819 gfc_error ("Cray pointee '%s' in %s clause at %L",
820 n->sym->name, name, &code->loc);
821 if (list != OMP_LIST_PRIVATE)
823 if (n->sym->attr.pointer)
824 gfc_error ("POINTER object '%s' in %s clause at %L",
825 n->sym->name, name, &code->loc);
826 if (n->sym->attr.allocatable)
827 gfc_error ("%s clause object '%s' is ALLOCATABLE at %L",
828 name, n->sym->name, &code->loc);
829 /* Variables in REDUCTION-clauses must be of intrinsic type (flagged below). */
830 if ((list < OMP_LIST_REDUCTION_FIRST || list > OMP_LIST_REDUCTION_LAST) &&
831 n->sym->ts.type == BT_DERIVED && n->sym->ts.derived->attr.alloc_comp)
832 gfc_error ("%s clause object '%s' has ALLOCATABLE components at %L",
833 name, n->sym->name, &code->loc);
834 if (n->sym->attr.cray_pointer)
835 gfc_error ("Cray pointer '%s' in %s clause at %L",
836 n->sym->name, name, &code->loc);
838 if (n->sym->as && n->sym->as->type == AS_ASSUMED_SIZE)
839 gfc_error ("Assumed size array '%s' in %s clause at %L",
840 n->sym->name, name, &code->loc);
841 if (n->sym->attr.in_namelist
842 && (list < OMP_LIST_REDUCTION_FIRST
843 || list > OMP_LIST_REDUCTION_LAST))
844 gfc_error ("Variable '%s' in %s clause is used in "
845 "NAMELIST statement at %L",
846 n->sym->name, name, &code->loc);
852 if (!gfc_numeric_ts (&n->sym->ts))
853 gfc_error ("%c REDUCTION variable '%s' at %L must be of intrinsic type, got %s",
854 list == OMP_LIST_PLUS ? '+'
855 : list == OMP_LIST_MULT ? '*' : '-',
856 n->sym->name, &code->loc,
857 gfc_typename (&n->sym->ts));
863 if (n->sym->ts.type != BT_LOGICAL)
864 gfc_error ("%s REDUCTION variable '%s' must be LOGICAL "
866 list == OMP_LIST_AND ? ".AND."
867 : list == OMP_LIST_OR ? ".OR."
868 : list == OMP_LIST_EQV ? ".EQV." : ".NEQV.",
869 n->sym->name, &code->loc);
873 if (n->sym->ts.type != BT_INTEGER
874 && n->sym->ts.type != BT_REAL)
875 gfc_error ("%s REDUCTION variable '%s' must be "
876 "INTEGER or REAL at %L",
877 list == OMP_LIST_MAX ? "MAX" : "MIN",
878 n->sym->name, &code->loc);
883 if (n->sym->ts.type != BT_INTEGER)
884 gfc_error ("%s REDUCTION variable '%s' must be INTEGER "
886 list == OMP_LIST_IAND ? "IAND"
887 : list == OMP_LIST_MULT ? "IOR" : "IEOR",
888 n->sym->name, &code->loc);
890 /* Workaround for PR middle-end/26316, nothing really needs
891 to be done here for OMP_LIST_PRIVATE. */
892 case OMP_LIST_PRIVATE:
893 gcc_assert (code->op != EXEC_NOP);
904 /* Return true if SYM is ever referenced in EXPR except in the SE node. */
907 expr_references_sym (gfc_expr *e, gfc_symbol *s, gfc_expr *se)
909 gfc_actual_arglist *arg;
910 if (e == NULL || e == se)
912 switch (e->expr_type)
919 if (e->symtree != NULL
920 && e->symtree->n.sym == s)
925 && (expr_references_sym (e->ref->u.ss.start, s, se)
926 || expr_references_sym (e->ref->u.ss.end, s, se)))
930 if (expr_references_sym (e->value.op.op2, s, se))
932 return expr_references_sym (e->value.op.op1, s, se);
934 for (arg = e->value.function.actual; arg; arg = arg->next)
935 if (expr_references_sym (arg->expr, s, se))
944 /* If EXPR is a conversion function that widens the type
945 if WIDENING is true or narrows the type if WIDENING is false,
946 return the inner expression, otherwise return NULL. */
949 is_conversion (gfc_expr *expr, bool widening)
951 gfc_typespec *ts1, *ts2;
953 if (expr->expr_type != EXPR_FUNCTION
954 || expr->value.function.isym == NULL
955 || expr->value.function.esym != NULL
956 || expr->value.function.isym->id != GFC_ISYM_CONVERSION)
962 ts2 = &expr->value.function.actual->expr->ts;
966 ts1 = &expr->value.function.actual->expr->ts;
970 if (ts1->type > ts2->type
971 || (ts1->type == ts2->type && ts1->kind > ts2->kind))
972 return expr->value.function.actual->expr;
979 resolve_omp_atomic (gfc_code *code)
984 code = code->block->next;
985 gcc_assert (code->op == EXEC_ASSIGN);
986 gcc_assert (code->next == NULL);
988 if (code->expr->expr_type != EXPR_VARIABLE
989 || code->expr->symtree == NULL
990 || code->expr->rank != 0
991 || (code->expr->ts.type != BT_INTEGER
992 && code->expr->ts.type != BT_REAL
993 && code->expr->ts.type != BT_COMPLEX
994 && code->expr->ts.type != BT_LOGICAL))
996 gfc_error ("!$OMP ATOMIC statement must set a scalar variable of "
997 "intrinsic type at %L", &code->loc);
1001 var = code->expr->symtree->n.sym;
1002 expr2 = is_conversion (code->expr2, false);
1004 expr2 = code->expr2;
1006 if (expr2->expr_type == EXPR_OP)
1008 gfc_expr *v = NULL, *e, *c;
1009 gfc_intrinsic_op op = expr2->value.op.operator;
1010 gfc_intrinsic_op alt_op = INTRINSIC_NONE;
1014 case INTRINSIC_PLUS:
1015 alt_op = INTRINSIC_MINUS;
1017 case INTRINSIC_TIMES:
1018 alt_op = INTRINSIC_DIVIDE;
1020 case INTRINSIC_MINUS:
1021 alt_op = INTRINSIC_PLUS;
1023 case INTRINSIC_DIVIDE:
1024 alt_op = INTRINSIC_TIMES;
1030 alt_op = INTRINSIC_NEQV;
1032 case INTRINSIC_NEQV:
1033 alt_op = INTRINSIC_EQV;
1036 gfc_error ("!$OMP ATOMIC assignment operator must be "
1037 "+, *, -, /, .AND., .OR., .EQV. or .NEQV. at %L",
1042 /* Check for var = var op expr resp. var = expr op var where
1043 expr doesn't reference var and var op expr is mathematically
1044 equivalent to var op (expr) resp. expr op var equivalent to
1045 (expr) op var. We rely here on the fact that the matcher
1046 for x op1 y op2 z where op1 and op2 have equal precedence
1047 returns (x op1 y) op2 z. */
1048 e = expr2->value.op.op2;
1049 if (e->expr_type == EXPR_VARIABLE
1050 && e->symtree != NULL
1051 && e->symtree->n.sym == var)
1053 else if ((c = is_conversion (e, true)) != NULL
1054 && c->expr_type == EXPR_VARIABLE
1055 && c->symtree != NULL
1056 && c->symtree->n.sym == var)
1060 gfc_expr **p = NULL, **q;
1061 for (q = &expr2->value.op.op1; (e = *q) != NULL; )
1062 if (e->expr_type == EXPR_VARIABLE
1063 && e->symtree != NULL
1064 && e->symtree->n.sym == var)
1069 else if ((c = is_conversion (e, true)) != NULL)
1070 q = &e->value.function.actual->expr;
1071 else if (e->expr_type != EXPR_OP
1072 || (e->value.op.operator != op
1073 && e->value.op.operator != alt_op)
1079 q = &e->value.op.op1;
1084 gfc_error ("!$OMP ATOMIC assignment must be var = var op expr "
1085 "or var = expr op var at %L", &expr2->where);
1092 switch (e->value.op.operator)
1094 case INTRINSIC_MINUS:
1095 case INTRINSIC_DIVIDE:
1097 case INTRINSIC_NEQV:
1098 gfc_error ("!$OMP ATOMIC var = var op expr not "
1099 "mathematically equivalent to var = var op "
1100 "(expr) at %L", &expr2->where);
1106 /* Canonicalize into var = var op (expr). */
1107 *p = e->value.op.op2;
1108 e->value.op.op2 = expr2;
1110 if (code->expr2 == expr2)
1111 code->expr2 = expr2 = e;
1113 code->expr2->value.function.actual->expr = expr2 = e;
1115 if (!gfc_compare_types (&expr2->value.op.op1->ts, &expr2->ts))
1117 for (p = &expr2->value.op.op1; *p != v;
1118 p = &(*p)->value.function.actual->expr)
1121 gfc_free_expr (expr2->value.op.op1);
1122 expr2->value.op.op1 = v;
1123 gfc_convert_type (v, &expr2->ts, 2);
1128 if (e->rank != 0 || expr_references_sym (code->expr2, var, v))
1130 gfc_error ("expr in !$OMP ATOMIC assignment var = var op expr "
1131 "must be scalar and cannot reference var at %L",
1136 else if (expr2->expr_type == EXPR_FUNCTION
1137 && expr2->value.function.isym != NULL
1138 && expr2->value.function.esym == NULL
1139 && expr2->value.function.actual != NULL
1140 && expr2->value.function.actual->next != NULL)
1142 gfc_actual_arglist *arg, *var_arg;
1144 switch (expr2->value.function.isym->id)
1152 if (expr2->value.function.actual->next->next != NULL)
1154 gfc_error ("!$OMP ATOMIC assignment intrinsic IAND, IOR "
1155 "or IEOR must have two arguments at %L",
1161 gfc_error ("!$OMP ATOMIC assignment intrinsic must be "
1162 "MIN, MAX, IAND, IOR or IEOR at %L",
1168 for (arg = expr2->value.function.actual; arg; arg = arg->next)
1170 if ((arg == expr2->value.function.actual
1171 || (var_arg == NULL && arg->next == NULL))
1172 && arg->expr->expr_type == EXPR_VARIABLE
1173 && arg->expr->symtree != NULL
1174 && arg->expr->symtree->n.sym == var)
1176 else if (expr_references_sym (arg->expr, var, NULL))
1177 gfc_error ("!$OMP ATOMIC intrinsic arguments except one must not "
1178 "reference '%s' at %L", var->name, &arg->expr->where);
1179 if (arg->expr->rank != 0)
1180 gfc_error ("!$OMP ATOMIC intrinsic arguments must be scalar "
1181 "at %L", &arg->expr->where);
1184 if (var_arg == NULL)
1186 gfc_error ("First or last !$OMP ATOMIC intrinsic argument must "
1187 "be '%s' at %L", var->name, &expr2->where);
1191 if (var_arg != expr2->value.function.actual)
1193 /* Canonicalize, so that var comes first. */
1194 gcc_assert (var_arg->next == NULL);
1195 for (arg = expr2->value.function.actual;
1196 arg->next != var_arg; arg = arg->next)
1198 var_arg->next = expr2->value.function.actual;
1199 expr2->value.function.actual = var_arg;
1204 gfc_error ("!$OMP ATOMIC assignment must have an operator or intrinsic "
1205 "on right hand side at %L", &expr2->where);
1212 struct pointer_set_t *sharing_clauses;
1213 struct pointer_set_t *private_iterators;
1214 struct omp_context *previous;
1216 gfc_code *omp_current_do_code;
1220 gfc_resolve_omp_do_blocks (gfc_code *code, gfc_namespace *ns)
1222 if (code->block->next && code->block->next->op == EXEC_DO)
1223 omp_current_do_code = code->block->next;
1224 gfc_resolve_blocks (code->block, ns);
1229 gfc_resolve_omp_parallel_blocks (gfc_code *code, gfc_namespace *ns)
1231 struct omp_context ctx;
1232 gfc_omp_clauses *omp_clauses = code->ext.omp_clauses;
1237 ctx.sharing_clauses = pointer_set_create ();
1238 ctx.private_iterators = pointer_set_create ();
1239 ctx.previous = omp_current_ctx;
1240 omp_current_ctx = &ctx;
1242 for (list = 0; list < OMP_LIST_NUM; list++)
1243 for (n = omp_clauses->lists[list]; n; n = n->next)
1244 pointer_set_insert (ctx.sharing_clauses, n->sym);
1246 if (code->op == EXEC_OMP_PARALLEL_DO)
1247 gfc_resolve_omp_do_blocks (code, ns);
1249 gfc_resolve_blocks (code->block, ns);
1251 omp_current_ctx = ctx.previous;
1252 pointer_set_destroy (ctx.sharing_clauses);
1253 pointer_set_destroy (ctx.private_iterators);
1257 /* Note a DO iterator variable. This is special in !$omp parallel
1258 construct, where they are predetermined private. */
1261 gfc_resolve_do_iterator (gfc_code *code, gfc_symbol *sym)
1263 struct omp_context *ctx;
1265 if (sym->attr.threadprivate)
1268 /* !$omp do and !$omp parallel do iteration variable is predetermined
1269 private just in the !$omp do resp. !$omp parallel do construct,
1270 with no implications for the outer parallel constructs. */
1271 if (code == omp_current_do_code)
1274 for (ctx = omp_current_ctx; ctx; ctx = ctx->previous)
1276 if (pointer_set_contains (ctx->sharing_clauses, sym))
1279 if (! pointer_set_insert (ctx->private_iterators, sym))
1281 gfc_omp_clauses *omp_clauses = ctx->code->ext.omp_clauses;
1284 p = gfc_get_namelist ();
1286 p->next = omp_clauses->lists[OMP_LIST_PRIVATE];
1287 omp_clauses->lists[OMP_LIST_PRIVATE] = p;
1294 resolve_omp_do (gfc_code *code)
1301 if (code->ext.omp_clauses)
1302 resolve_omp_clauses (code);
1304 do_code = code->block->next;
1305 if (do_code->op == EXEC_DO_WHILE)
1306 gfc_error ("!$OMP DO cannot be a DO WHILE or DO without loop control "
1307 "at %L", &do_code->loc);
1310 gcc_assert (do_code->op == EXEC_DO);
1311 if (do_code->ext.iterator->var->ts.type != BT_INTEGER)
1312 gfc_error ("!$OMP DO iteration variable must be of type integer at %L",
1314 dovar = do_code->ext.iterator->var->symtree->n.sym;
1315 if (dovar->attr.threadprivate)
1316 gfc_error ("!$OMP DO iteration variable must not be THREADPRIVATE "
1317 "at %L", &do_code->loc);
1318 if (code->ext.omp_clauses)
1319 for (list = 0; list < OMP_LIST_NUM; list++)
1320 if (list != OMP_LIST_PRIVATE && list != OMP_LIST_LASTPRIVATE)
1321 for (n = code->ext.omp_clauses->lists[list]; n; n = n->next)
1322 if (dovar == n->sym)
1324 gfc_error ("!$OMP DO iteration variable present on clause "
1325 "other than PRIVATE or LASTPRIVATE at %L",
1333 /* Resolve OpenMP directive clauses and check various requirements
1334 of each directive. */
1337 gfc_resolve_omp_directive (gfc_code *code, gfc_namespace *ns ATTRIBUTE_UNUSED)
1342 case EXEC_OMP_PARALLEL_DO:
1343 resolve_omp_do (code);
1345 case EXEC_OMP_WORKSHARE:
1346 case EXEC_OMP_PARALLEL_WORKSHARE:
1347 case EXEC_OMP_PARALLEL:
1348 case EXEC_OMP_PARALLEL_SECTIONS:
1349 case EXEC_OMP_SECTIONS:
1350 case EXEC_OMP_SINGLE:
1351 if (code->ext.omp_clauses)
1352 resolve_omp_clauses (code);
1354 case EXEC_OMP_ATOMIC:
1355 resolve_omp_atomic (code);