1 /* OpenMP directive matching and resolving.
2 Copyright (C) 2005, 2006 Free Software Foundation, Inc.
3 Contributed by Jakub Jelinek
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 2, or (at your option) any later
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 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;
414 gfc_match_omp_critical (void)
416 char n[GFC_MAX_SYMBOL_LEN+1];
418 if (gfc_match (" ( %n )", n) != MATCH_YES)
420 if (gfc_match_omp_eos () != MATCH_YES)
422 new_st.op = EXEC_OMP_CRITICAL;
423 new_st.ext.omp_name = n[0] ? xstrdup (n) : NULL;
428 gfc_match_omp_do (void)
431 if (gfc_match_omp_clauses (&c, OMP_DO_CLAUSES) != MATCH_YES)
433 new_st.op = EXEC_OMP_DO;
434 new_st.ext.omp_clauses = c;
439 gfc_match_omp_flush (void)
441 gfc_namelist *list = NULL;
442 gfc_match_omp_variable_list (" (", &list, true);
443 if (gfc_match_omp_eos () != MATCH_YES)
445 gfc_free_namelist (list);
448 new_st.op = EXEC_OMP_FLUSH;
449 new_st.ext.omp_namelist = list;
454 gfc_match_omp_threadprivate (void)
457 char n[GFC_MAX_SYMBOL_LEN+1];
462 old_loc = gfc_current_locus;
464 m = gfc_match (" (");
468 if (!targetm.have_tls)
470 sorry ("threadprivate variables not supported in this target");
476 m = gfc_match_symbol (&sym, 0);
480 if (sym->attr.in_common)
481 gfc_error_now ("Threadprivate variable at %C is an element of"
483 else if (gfc_add_threadprivate (&sym->attr, sym->name,
484 &sym->declared_at) == FAILURE)
493 m = gfc_match (" / %n /", n);
494 if (m == MATCH_ERROR)
496 if (m == MATCH_NO || n[0] == '\0')
499 st = gfc_find_symtree (gfc_current_ns->common_root, n);
502 gfc_error ("COMMON block /%s/ not found at %C", n);
505 st->n.common->threadprivate = 1;
506 for (sym = st->n.common->head; sym; sym = sym->common_next)
507 if (gfc_add_threadprivate (&sym->attr, sym->name,
508 &sym->declared_at) == FAILURE)
512 if (gfc_match_char (')') == MATCH_YES)
514 if (gfc_match_char (',') != MATCH_YES)
521 gfc_error ("Syntax error in !$OMP THREADPRIVATE list at %C");
524 gfc_current_locus = old_loc;
529 gfc_match_omp_parallel_do (void)
532 if (gfc_match_omp_clauses (&c, OMP_PARALLEL_CLAUSES | OMP_DO_CLAUSES)
535 new_st.op = EXEC_OMP_PARALLEL_DO;
536 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;
553 gfc_match_omp_parallel_workshare (void)
556 if (gfc_match_omp_clauses (&c, OMP_PARALLEL_CLAUSES) != MATCH_YES)
558 new_st.op = EXEC_OMP_PARALLEL_WORKSHARE;
559 new_st.ext.omp_clauses = c;
564 gfc_match_omp_sections (void)
567 if (gfc_match_omp_clauses (&c, OMP_SECTIONS_CLAUSES) != MATCH_YES)
569 new_st.op = EXEC_OMP_SECTIONS;
570 new_st.ext.omp_clauses = c;
575 gfc_match_omp_single (void)
578 if (gfc_match_omp_clauses (&c, OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE)
581 new_st.op = EXEC_OMP_SINGLE;
582 new_st.ext.omp_clauses = c;
587 gfc_match_omp_workshare (void)
589 if (gfc_match_omp_eos () != MATCH_YES)
591 new_st.op = EXEC_OMP_WORKSHARE;
592 new_st.ext.omp_clauses = gfc_get_omp_clauses ();
597 gfc_match_omp_master (void)
599 if (gfc_match_omp_eos () != MATCH_YES)
601 new_st.op = EXEC_OMP_MASTER;
602 new_st.ext.omp_clauses = NULL;
607 gfc_match_omp_ordered (void)
609 if (gfc_match_omp_eos () != MATCH_YES)
611 new_st.op = EXEC_OMP_ORDERED;
612 new_st.ext.omp_clauses = NULL;
617 gfc_match_omp_atomic (void)
619 if (gfc_match_omp_eos () != MATCH_YES)
621 new_st.op = EXEC_OMP_ATOMIC;
622 new_st.ext.omp_clauses = NULL;
627 gfc_match_omp_barrier (void)
629 if (gfc_match_omp_eos () != MATCH_YES)
631 new_st.op = EXEC_OMP_BARRIER;
632 new_st.ext.omp_clauses = NULL;
637 gfc_match_omp_end_nowait (void)
640 if (gfc_match ("% nowait") == MATCH_YES)
642 if (gfc_match_omp_eos () != MATCH_YES)
644 new_st.op = EXEC_OMP_END_NOWAIT;
645 new_st.ext.omp_bool = nowait;
650 gfc_match_omp_end_single (void)
653 if (gfc_match ("% nowait") == MATCH_YES)
655 new_st.op = EXEC_OMP_END_NOWAIT;
656 new_st.ext.omp_bool = true;
659 if (gfc_match_omp_clauses (&c, OMP_CLAUSE_COPYPRIVATE) != MATCH_YES)
661 new_st.op = EXEC_OMP_END_SINGLE;
662 new_st.ext.omp_clauses = c;
666 /* OpenMP directive resolving routines. */
669 resolve_omp_clauses (gfc_code *code)
671 gfc_omp_clauses *omp_clauses = code->ext.omp_clauses;
674 static const char *clause_names[]
675 = { "PRIVATE", "FIRSTPRIVATE", "LASTPRIVATE", "COPYPRIVATE", "SHARED",
676 "COPYIN", "REDUCTION" };
678 if (omp_clauses == NULL)
681 if (omp_clauses->if_expr)
683 gfc_expr *expr = omp_clauses->if_expr;
684 if (gfc_resolve_expr (expr) == FAILURE
685 || expr->ts.type != BT_LOGICAL || expr->rank != 0)
686 gfc_error ("IF clause at %L requires a scalar LOGICAL expression",
689 if (omp_clauses->num_threads)
691 gfc_expr *expr = omp_clauses->num_threads;
692 if (gfc_resolve_expr (expr) == FAILURE
693 || expr->ts.type != BT_INTEGER || expr->rank != 0)
694 gfc_error ("NUM_THREADS clause at %L requires a scalar"
695 " INTEGER expression", &expr->where);
697 if (omp_clauses->chunk_size)
699 gfc_expr *expr = omp_clauses->chunk_size;
700 if (gfc_resolve_expr (expr) == FAILURE
701 || expr->ts.type != BT_INTEGER || expr->rank != 0)
702 gfc_error ("SCHEDULE clause's chunk_size at %L requires"
703 " a scalar INTEGER expression", &expr->where);
706 /* Check that no symbol appears on multiple clauses, except that
707 a symbol can appear on both firstprivate and lastprivate. */
708 for (list = 0; list < OMP_LIST_NUM; list++)
709 for (n = omp_clauses->lists[list]; n; n = n->next)
712 for (list = 0; list < OMP_LIST_NUM; list++)
713 if (list != OMP_LIST_FIRSTPRIVATE && list != OMP_LIST_LASTPRIVATE)
714 for (n = omp_clauses->lists[list]; n; n = n->next)
716 gfc_error ("Symbol '%s' present on multiple clauses at %L",
717 n->sym->name, &code->loc);
721 gcc_assert (OMP_LIST_LASTPRIVATE == OMP_LIST_FIRSTPRIVATE + 1);
722 for (list = OMP_LIST_FIRSTPRIVATE; list <= OMP_LIST_LASTPRIVATE; list++)
723 for (n = omp_clauses->lists[list]; n; n = n->next)
726 gfc_error ("Symbol '%s' present on multiple clauses at %L",
727 n->sym->name, &code->loc);
731 for (n = omp_clauses->lists[OMP_LIST_FIRSTPRIVATE]; n; n = n->next)
733 gfc_error ("Symbol '%s' present on multiple clauses at %L",
734 n->sym->name, &code->loc);
738 for (n = omp_clauses->lists[OMP_LIST_LASTPRIVATE]; n; n = n->next)
741 for (n = omp_clauses->lists[OMP_LIST_LASTPRIVATE]; n; n = n->next)
743 gfc_error ("Symbol '%s' present on multiple clauses at %L",
744 n->sym->name, &code->loc);
748 for (list = 0; list < OMP_LIST_NUM; list++)
749 if ((n = omp_clauses->lists[list]) != NULL)
753 if (list < OMP_LIST_REDUCTION_FIRST)
754 name = clause_names[list];
755 else if (list <= OMP_LIST_REDUCTION_LAST)
756 name = clause_names[OMP_LIST_REDUCTION_FIRST];
762 case OMP_LIST_COPYIN:
763 for (; n != NULL; n = n->next)
765 if (!n->sym->attr.threadprivate)
766 gfc_error ("Non-THREADPRIVATE object '%s' in COPYIN clause"
767 " at %L", n->sym->name, &code->loc);
768 if (n->sym->attr.allocatable)
769 gfc_error ("COPYIN clause object '%s' is ALLOCATABLE at %L",
770 n->sym->name, &code->loc);
773 case OMP_LIST_COPYPRIVATE:
774 for (; n != NULL; n = n->next)
776 if (n->sym->as && n->sym->as->type == AS_ASSUMED_SIZE)
777 gfc_error ("Assumed size array '%s' in COPYPRIVATE clause"
778 " at %L", n->sym->name, &code->loc);
779 if (n->sym->attr.allocatable)
780 gfc_error ("COPYPRIVATE clause object '%s' is ALLOCATABLE"
781 " at %L", n->sym->name, &code->loc);
784 case OMP_LIST_SHARED:
785 for (; n != NULL; n = n->next)
787 if (n->sym->attr.threadprivate)
788 gfc_error ("THREADPRIVATE object '%s' in SHARED clause at"
789 " %L", n->sym->name, &code->loc);
790 if (n->sym->attr.cray_pointee)
791 gfc_error ("Cray pointee '%s' in SHARED clause at %L",
792 n->sym->name, &code->loc);
796 for (; n != NULL; n = n->next)
798 if (n->sym->attr.threadprivate)
799 gfc_error ("THREADPRIVATE object '%s' in %s clause at %L",
800 n->sym->name, name, &code->loc);
801 if (n->sym->attr.cray_pointee)
802 gfc_error ("Cray pointee '%s' in %s clause at %L",
803 n->sym->name, name, &code->loc);
804 if (list != OMP_LIST_PRIVATE)
806 if (n->sym->attr.pointer)
807 gfc_error ("POINTER object '%s' in %s clause at %L",
808 n->sym->name, name, &code->loc);
809 if (n->sym->attr.allocatable)
810 gfc_error ("%s clause object '%s' is ALLOCATABLE at %L",
811 name, n->sym->name, &code->loc);
812 if (n->sym->attr.cray_pointer)
813 gfc_error ("Cray pointer '%s' in %s clause at %L",
814 n->sym->name, name, &code->loc);
816 if (n->sym->as && n->sym->as->type == AS_ASSUMED_SIZE)
817 gfc_error ("Assumed size array '%s' in %s clause at %L",
818 n->sym->name, name, &code->loc);
819 if (n->sym->attr.in_namelist
820 && (list < OMP_LIST_REDUCTION_FIRST
821 || list > OMP_LIST_REDUCTION_LAST))
822 gfc_error ("Variable '%s' in %s clause is used in"
823 " NAMELIST statement at %L",
824 n->sym->name, name, &code->loc);
830 if (!gfc_numeric_ts (&n->sym->ts))
831 gfc_error ("%c REDUCTION variable '%s' is %s at %L",
832 list == OMP_LIST_PLUS ? '+'
833 : list == OMP_LIST_MULT ? '*' : '-',
834 n->sym->name, gfc_typename (&n->sym->ts),
841 if (n->sym->ts.type != BT_LOGICAL)
842 gfc_error ("%s REDUCTION variable '%s' must be LOGICAL"
844 list == OMP_LIST_AND ? ".AND."
845 : list == OMP_LIST_OR ? ".OR."
846 : list == OMP_LIST_EQV ? ".EQV." : ".NEQV.",
847 n->sym->name, &code->loc);
851 if (n->sym->ts.type != BT_INTEGER
852 && n->sym->ts.type != BT_REAL)
853 gfc_error ("%s REDUCTION variable '%s' must be"
854 " INTEGER or REAL at %L",
855 list == OMP_LIST_MAX ? "MAX" : "MIN",
856 n->sym->name, &code->loc);
861 if (n->sym->ts.type != BT_INTEGER)
862 gfc_error ("%s REDUCTION variable '%s' must be INTEGER"
864 list == OMP_LIST_IAND ? "IAND"
865 : list == OMP_LIST_MULT ? "IOR" : "IEOR",
866 n->sym->name, &code->loc);
877 /* Return true if SYM is ever referenced in EXPR except in the SE node. */
880 expr_references_sym (gfc_expr *e, gfc_symbol *s, gfc_expr *se)
882 gfc_actual_arglist *arg;
883 if (e == NULL || e == se)
885 switch (e->expr_type)
892 if (e->symtree != NULL
893 && e->symtree->n.sym == s)
898 && (expr_references_sym (e->ref->u.ss.start, s, se)
899 || expr_references_sym (e->ref->u.ss.end, s, se)))
903 if (expr_references_sym (e->value.op.op2, s, se))
905 return expr_references_sym (e->value.op.op1, s, se);
907 for (arg = e->value.function.actual; arg; arg = arg->next)
908 if (expr_references_sym (arg->expr, s, se))
916 /* If EXPR is a conversion function that widens the type
917 if WIDENING is true or narrows the type if WIDENING is false,
918 return the inner expression, otherwise return NULL. */
921 is_conversion (gfc_expr *expr, bool widening)
923 gfc_typespec *ts1, *ts2;
925 if (expr->expr_type != EXPR_FUNCTION
926 || expr->value.function.isym == NULL
927 || expr->value.function.esym != NULL
928 || expr->value.function.isym->generic_id != GFC_ISYM_CONVERSION)
934 ts2 = &expr->value.function.actual->expr->ts;
938 ts1 = &expr->value.function.actual->expr->ts;
942 if (ts1->type > ts2->type
943 || (ts1->type == ts2->type && ts1->kind > ts2->kind))
944 return expr->value.function.actual->expr;
950 resolve_omp_atomic (gfc_code *code)
955 code = code->block->next;
956 gcc_assert (code->op == EXEC_ASSIGN);
957 gcc_assert (code->next == NULL);
959 if (code->expr->expr_type != EXPR_VARIABLE
960 || code->expr->symtree == NULL
961 || code->expr->rank != 0
962 || (code->expr->ts.type != BT_INTEGER
963 && code->expr->ts.type != BT_REAL
964 && code->expr->ts.type != BT_COMPLEX
965 && code->expr->ts.type != BT_LOGICAL))
967 gfc_error ("!$OMP ATOMIC statement must set a scalar variable of"
968 " intrinsic type at %L", &code->loc);
972 var = code->expr->symtree->n.sym;
973 expr2 = is_conversion (code->expr2, false);
977 if (expr2->expr_type == EXPR_OP)
979 gfc_expr *v = NULL, *e, *c;
980 gfc_intrinsic_op op = expr2->value.op.operator;
981 gfc_intrinsic_op alt_op = INTRINSIC_NONE;
986 alt_op = INTRINSIC_MINUS;
988 case INTRINSIC_TIMES:
989 alt_op = INTRINSIC_DIVIDE;
991 case INTRINSIC_MINUS:
992 alt_op = INTRINSIC_PLUS;
994 case INTRINSIC_DIVIDE:
995 alt_op = INTRINSIC_TIMES;
1001 alt_op = INTRINSIC_NEQV;
1003 case INTRINSIC_NEQV:
1004 alt_op = INTRINSIC_EQV;
1007 gfc_error ("!$OMP ATOMIC assignment operator must be"
1008 " +, *, -, /, .AND., .OR., .EQV. or .NEQV. at %L",
1013 /* Check for var = var op expr resp. var = expr op var where
1014 expr doesn't reference var and var op expr is mathematically
1015 equivalent to var op (expr) resp. expr op var equivalent to
1016 (expr) op var. We rely here on the fact that the matcher
1017 for x op1 y op2 z where op1 and op2 have equal precedence
1018 returns (x op1 y) op2 z. */
1019 e = expr2->value.op.op2;
1020 if (e->expr_type == EXPR_VARIABLE
1021 && e->symtree != NULL
1022 && e->symtree->n.sym == var)
1024 else if ((c = is_conversion (e, true)) != NULL
1025 && c->expr_type == EXPR_VARIABLE
1026 && c->symtree != NULL
1027 && c->symtree->n.sym == var)
1031 gfc_expr **p = NULL, **q;
1032 for (q = &expr2->value.op.op1; (e = *q) != NULL; )
1033 if (e->expr_type == EXPR_VARIABLE
1034 && e->symtree != NULL
1035 && e->symtree->n.sym == var)
1040 else if ((c = is_conversion (e, true)) != NULL)
1041 q = &e->value.function.actual->expr;
1042 else if (e->expr_type != EXPR_OP
1043 || (e->value.op.operator != op
1044 && e->value.op.operator != alt_op)
1050 q = &e->value.op.op1;
1055 gfc_error ("!$OMP ATOMIC assignment must be var = var op expr"
1056 " or var = expr op var at %L", &expr2->where);
1063 switch (e->value.op.operator)
1065 case INTRINSIC_MINUS:
1066 case INTRINSIC_DIVIDE:
1068 case INTRINSIC_NEQV:
1069 gfc_error ("!$OMP ATOMIC var = var op expr not"
1070 " mathematically equivalent to var = var op"
1071 " (expr) at %L", &expr2->where);
1077 /* Canonicalize into var = var op (expr). */
1078 *p = e->value.op.op2;
1079 e->value.op.op2 = expr2;
1081 if (code->expr2 == expr2)
1082 code->expr2 = expr2 = e;
1084 code->expr2->value.function.actual->expr = expr2 = e;
1086 if (!gfc_compare_types (&expr2->value.op.op1->ts, &expr2->ts))
1088 for (p = &expr2->value.op.op1; *p != v;
1089 p = &(*p)->value.function.actual->expr)
1092 gfc_free_expr (expr2->value.op.op1);
1093 expr2->value.op.op1 = v;
1094 gfc_convert_type (v, &expr2->ts, 2);
1099 if (e->rank != 0 || expr_references_sym (code->expr2, var, v))
1101 gfc_error ("expr in !$OMP ATOMIC assignment var = var op expr"
1102 " must be scalar and cannot reference var at %L",
1107 else if (expr2->expr_type == EXPR_FUNCTION
1108 && expr2->value.function.isym != NULL
1109 && expr2->value.function.esym == NULL
1110 && expr2->value.function.actual != NULL
1111 && expr2->value.function.actual->next != NULL)
1113 gfc_actual_arglist *arg, *var_arg;
1115 switch (expr2->value.function.isym->generic_id)
1123 if (expr2->value.function.actual->next->next != NULL)
1125 gfc_error ("!$OMP ATOMIC assignment intrinsic IAND, IOR"
1126 "or IEOR must have two arguments at %L",
1132 gfc_error ("!$OMP ATOMIC assignment intrinsic must be"
1133 " MIN, MAX, IAND, IOR or IEOR at %L",
1139 for (arg = expr2->value.function.actual; arg; arg = arg->next)
1141 if ((arg == expr2->value.function.actual
1142 || (var_arg == NULL && arg->next == NULL))
1143 && arg->expr->expr_type == EXPR_VARIABLE
1144 && arg->expr->symtree != NULL
1145 && arg->expr->symtree->n.sym == var)
1147 else if (expr_references_sym (arg->expr, var, NULL))
1148 gfc_error ("!$OMP ATOMIC intrinsic arguments except one must not"
1149 " reference '%s' at %L", var->name, &arg->expr->where);
1150 if (arg->expr->rank != 0)
1151 gfc_error ("!$OMP ATOMIC intrinsic arguments must be scalar"
1152 " at %L", &arg->expr->where);
1155 if (var_arg == NULL)
1157 gfc_error ("First or last !$OMP ATOMIC intrinsic argument must"
1158 " be '%s' at %L", var->name, &expr2->where);
1162 if (var_arg != expr2->value.function.actual)
1164 /* Canonicalize, so that var comes first. */
1165 gcc_assert (var_arg->next == NULL);
1166 for (arg = expr2->value.function.actual;
1167 arg->next != var_arg; arg = arg->next)
1169 var_arg->next = expr2->value.function.actual;
1170 expr2->value.function.actual = var_arg;
1175 gfc_error ("!$OMP ATOMIC assignment must have an operator or intrinsic"
1176 " on right hand side at %L", &expr2->where);
1182 struct pointer_set_t *sharing_clauses;
1183 struct pointer_set_t *private_iterators;
1184 struct omp_context *previous;
1186 gfc_code *omp_current_do_code;
1189 gfc_resolve_omp_do_blocks (gfc_code *code, gfc_namespace *ns)
1191 if (code->block->next && code->block->next->op == EXEC_DO)
1192 omp_current_do_code = code->block->next;
1193 gfc_resolve_blocks (code->block, ns);
1197 gfc_resolve_omp_parallel_blocks (gfc_code *code, gfc_namespace *ns)
1199 struct omp_context ctx;
1200 gfc_omp_clauses *omp_clauses = code->ext.omp_clauses;
1205 ctx.sharing_clauses = pointer_set_create ();
1206 ctx.private_iterators = pointer_set_create ();
1207 ctx.previous = omp_current_ctx;
1208 omp_current_ctx = &ctx;
1210 for (list = 0; list < OMP_LIST_NUM; list++)
1211 for (n = omp_clauses->lists[list]; n; n = n->next)
1212 pointer_set_insert (ctx.sharing_clauses, n->sym);
1214 if (code->op == EXEC_OMP_PARALLEL_DO)
1215 gfc_resolve_omp_do_blocks (code, ns);
1217 gfc_resolve_blocks (code->block, ns);
1219 omp_current_ctx = ctx.previous;
1220 pointer_set_destroy (ctx.sharing_clauses);
1221 pointer_set_destroy (ctx.private_iterators);
1224 /* Note a DO iterator variable. This is special in !$omp parallel
1225 construct, where they are predetermined private. */
1228 gfc_resolve_do_iterator (gfc_code *code, gfc_symbol *sym)
1230 struct omp_context *ctx;
1232 if (sym->attr.threadprivate)
1235 /* !$omp do and !$omp parallel do iteration variable is predetermined
1236 private just in the !$omp do resp. !$omp parallel do construct,
1237 with no implications for the outer parallel constructs. */
1238 if (code == omp_current_do_code)
1241 for (ctx = omp_current_ctx; ctx; ctx = ctx->previous)
1243 if (pointer_set_contains (ctx->sharing_clauses, sym))
1246 if (! pointer_set_insert (ctx->private_iterators, sym))
1248 gfc_omp_clauses *omp_clauses = ctx->code->ext.omp_clauses;
1251 p = gfc_get_namelist ();
1253 p->next = omp_clauses->lists[OMP_LIST_PRIVATE];
1254 omp_clauses->lists[OMP_LIST_PRIVATE] = p;
1260 resolve_omp_do (gfc_code *code)
1267 if (code->ext.omp_clauses)
1268 resolve_omp_clauses (code);
1270 do_code = code->block->next;
1271 if (do_code->op == EXEC_DO_WHILE)
1272 gfc_error ("!$OMP DO cannot be a DO WHILE or DO without loop control at %L",
1276 gcc_assert (do_code->op == EXEC_DO);
1277 if (do_code->ext.iterator->var->ts.type != BT_INTEGER)
1278 gfc_error ("!$OMP DO iteration variable must be of type integer at %L",
1280 dovar = do_code->ext.iterator->var->symtree->n.sym;
1281 if (dovar->attr.threadprivate)
1282 gfc_error ("!$OMP DO iteration variable must not be THREADPRIVATE at %L",
1284 if (code->ext.omp_clauses)
1285 for (list = 0; list < OMP_LIST_NUM; list++)
1286 if (list != OMP_LIST_PRIVATE && list != OMP_LIST_LASTPRIVATE)
1287 for (n = code->ext.omp_clauses->lists[list]; n; n = n->next)
1288 if (dovar == n->sym)
1290 gfc_error ("!$OMP DO iteration variable present on clause"
1291 " other than PRIVATE or LASTPRIVATE at %L",
1298 /* Resolve OpenMP directive clauses and check various requirements
1299 of each directive. */
1302 gfc_resolve_omp_directive (gfc_code *code, gfc_namespace *ns ATTRIBUTE_UNUSED)
1307 case EXEC_OMP_PARALLEL_DO:
1308 resolve_omp_do (code);
1310 case EXEC_OMP_WORKSHARE:
1311 case EXEC_OMP_PARALLEL_WORKSHARE:
1312 case EXEC_OMP_PARALLEL:
1313 case EXEC_OMP_PARALLEL_SECTIONS:
1314 case EXEC_OMP_SECTIONS:
1315 case EXEC_OMP_SINGLE:
1316 if (code->ext.omp_clauses)
1317 resolve_omp_clauses (code);
1319 case EXEC_OMP_ATOMIC:
1320 resolve_omp_atomic (code);