2006-03-15 Paul Brook <paul@codesourcery.com>
[official-gcc.git] / gcc / fortran / openmp.c
blob09ec255974cc8f787fbdbe60964427264bed39ae
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
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 COPYING. If not, write to the Free
19 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301, USA. */
23 #include "config.h"
24 #include "system.h"
25 #include "flags.h"
26 #include "gfortran.h"
27 #include "match.h"
28 #include "parse.h"
29 #include "pointer-set.h"
30 #include "target.h"
31 #include "toplev.h"
33 /* Match an end of OpenMP directive. End of OpenMP directive is optional
34 whitespace, followed by '\n' or comment '!'. */
36 match
37 gfc_match_omp_eos (void)
39 locus old_loc;
40 int c;
42 old_loc = gfc_current_locus;
43 gfc_gobble_whitespace ();
45 c = gfc_next_char ();
46 switch (c)
48 case '!':
50 c = gfc_next_char ();
51 while (c != '\n');
52 /* Fall through */
54 case '\n':
55 return MATCH_YES;
58 gfc_current_locus = old_loc;
59 return MATCH_NO;
62 /* Free an omp_clauses structure. */
64 void
65 gfc_free_omp_clauses (gfc_omp_clauses *c)
67 int i;
68 if (c == NULL)
69 return;
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]);
76 gfc_free (c);
79 /* Match a variable/common block list and construct a namelist from it. */
81 static match
82 gfc_match_omp_variable_list (const char *str, gfc_namelist **list,
83 bool allow_common)
85 gfc_namelist *head, *tail, *p;
86 locus old_loc;
87 char n[GFC_MAX_SYMBOL_LEN+1];
88 gfc_symbol *sym;
89 match m;
90 gfc_symtree *st;
92 head = tail = NULL;
94 old_loc = gfc_current_locus;
96 m = gfc_match (str);
97 if (m != MATCH_YES)
98 return m;
100 for (;;)
102 m = gfc_match_symbol (&sym, 1);
103 switch (m)
105 case MATCH_YES:
106 gfc_set_sym_referenced (sym);
107 p = gfc_get_namelist ();
108 if (head == NULL)
109 head = tail = p;
110 else
112 tail->next = p;
113 tail = tail->next;
115 tail->sym = sym;
116 goto next_item;
117 case MATCH_NO:
118 break;
119 case MATCH_ERROR:
120 goto cleanup;
123 if (!allow_common)
124 goto syntax;
126 m = gfc_match (" / %n /", n);
127 if (m == MATCH_ERROR)
128 goto cleanup;
129 if (m == MATCH_NO)
130 goto syntax;
132 st = gfc_find_symtree (gfc_current_ns->common_root, n);
133 if (st == NULL)
135 gfc_error ("COMMON block /%s/ not found at %C", n);
136 goto cleanup;
138 for (sym = st->n.common->head; sym; sym = sym->common_next)
140 gfc_set_sym_referenced (sym);
141 p = gfc_get_namelist ();
142 if (head == NULL)
143 head = tail = p;
144 else
146 tail->next = p;
147 tail = tail->next;
149 tail->sym = sym;
152 next_item:
153 if (gfc_match_char (')') == MATCH_YES)
154 break;
155 if (gfc_match_char (',') != MATCH_YES)
156 goto syntax;
159 while (*list)
160 list = &(*list)->next;
162 *list = head;
163 return MATCH_YES;
165 syntax:
166 gfc_error ("Syntax error in OpenMP variable list at %C");
168 cleanup:
169 gfc_free_namelist (head);
170 gfc_current_locus = old_loc;
171 return MATCH_ERROR;
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. */
190 static match
191 gfc_match_omp_clauses (gfc_omp_clauses **cp, int mask)
193 gfc_omp_clauses *c = gfc_get_omp_clauses ();
194 locus old_loc;
195 bool needs_space = true, first = true;
197 *cp = NULL;
198 while (1)
200 if ((first || gfc_match_char (',') != MATCH_YES)
201 && (needs_space && gfc_match_space () != MATCH_YES))
202 break;
203 needs_space = false;
204 first = false;
205 gfc_gobble_whitespace ();
206 if ((mask & OMP_CLAUSE_IF) && c->if_expr == NULL
207 && gfc_match ("if ( %e )", &c->if_expr) == MATCH_YES)
208 continue;
209 if ((mask & OMP_CLAUSE_NUM_THREADS) && c->num_threads == NULL
210 && gfc_match ("num_threads ( %e )", &c->num_threads) == MATCH_YES)
211 continue;
212 if ((mask & OMP_CLAUSE_PRIVATE)
213 && gfc_match_omp_variable_list ("private (",
214 &c->lists[OMP_LIST_PRIVATE], true)
215 == MATCH_YES)
216 continue;
217 if ((mask & OMP_CLAUSE_FIRSTPRIVATE)
218 && gfc_match_omp_variable_list ("firstprivate (",
219 &c->lists[OMP_LIST_FIRSTPRIVATE],
220 true)
221 == MATCH_YES)
222 continue;
223 if ((mask & OMP_CLAUSE_LASTPRIVATE)
224 && gfc_match_omp_variable_list ("lastprivate (",
225 &c->lists[OMP_LIST_LASTPRIVATE],
226 true)
227 == MATCH_YES)
228 continue;
229 if ((mask & OMP_CLAUSE_COPYPRIVATE)
230 && gfc_match_omp_variable_list ("copyprivate (",
231 &c->lists[OMP_LIST_COPYPRIVATE],
232 true)
233 == MATCH_YES)
234 continue;
235 if ((mask & OMP_CLAUSE_SHARED)
236 && gfc_match_omp_variable_list ("shared (",
237 &c->lists[OMP_LIST_SHARED], true)
238 == MATCH_YES)
239 continue;
240 if ((mask & OMP_CLAUSE_COPYIN)
241 && gfc_match_omp_variable_list ("copyin (",
242 &c->lists[OMP_LIST_COPYIN], true)
243 == MATCH_YES)
244 continue;
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)
267 gfc_symbol *sym;
268 const char *n = buffer;
270 gfc_find_symbol (buffer, NULL, 1, &sym);
271 if (sym != NULL)
273 if (sym->attr.intrinsic)
274 n = sym->name;
275 else if ((sym->attr.flavor != FL_UNKNOWN
276 && sym->attr.flavor != FL_PROCEDURE)
277 || sym->attr.external
278 || sym->attr.generic
279 || sym->attr.entry
280 || sym->attr.result
281 || sym->attr.dummy
282 || sym->attr.subroutine
283 || sym->attr.pointer
284 || sym->attr.target
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 "
293 "at %C", buffer);
294 sym = NULL;
296 else
297 n = sym->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
310 && sym != NULL
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);
319 return MATCH_ERROR;
322 if (reduction != OMP_LIST_NUM
323 && gfc_match_omp_variable_list (" :", &c->lists[reduction],
324 false)
325 == MATCH_YES)
326 continue;
327 else
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)
340 continue;
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)
357 match m = MATCH_NO;
358 if (c->sched_kind != OMP_SCHED_RUNTIME)
359 m = gfc_match (" , %e )", &c->chunk_size);
360 if (m != MATCH_YES)
361 m = gfc_match_char (')');
362 if (m != MATCH_YES)
363 c->sched_kind = OMP_SCHED_NONE;
365 if (c->sched_kind != OMP_SCHED_NONE)
366 continue;
367 else
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;
374 continue;
377 break;
380 if (gfc_match_omp_eos () != MATCH_YES)
382 gfc_free_omp_clauses (c);
383 return MATCH_ERROR;
386 *cp = c;
387 return MATCH_YES;
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)
402 match
403 gfc_match_omp_parallel (void)
405 gfc_omp_clauses *c;
406 if (gfc_match_omp_clauses (&c, OMP_PARALLEL_CLAUSES) != MATCH_YES)
407 return MATCH_ERROR;
408 new_st.op = EXEC_OMP_PARALLEL;
409 new_st.ext.omp_clauses = c;
410 return MATCH_YES;
413 match
414 gfc_match_omp_critical (void)
416 char n[GFC_MAX_SYMBOL_LEN+1];
418 if (gfc_match (" ( %n )", n) != MATCH_YES)
419 n[0] = '\0';
420 if (gfc_match_omp_eos () != MATCH_YES)
421 return MATCH_ERROR;
422 new_st.op = EXEC_OMP_CRITICAL;
423 new_st.ext.omp_name = n[0] ? xstrdup (n) : NULL;
424 return MATCH_YES;
427 match
428 gfc_match_omp_do (void)
430 gfc_omp_clauses *c;
431 if (gfc_match_omp_clauses (&c, OMP_DO_CLAUSES) != MATCH_YES)
432 return MATCH_ERROR;
433 new_st.op = EXEC_OMP_DO;
434 new_st.ext.omp_clauses = c;
435 return MATCH_YES;
438 match
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);
446 return MATCH_ERROR;
448 new_st.op = EXEC_OMP_FLUSH;
449 new_st.ext.omp_namelist = list;
450 return MATCH_YES;
453 match
454 gfc_match_omp_threadprivate (void)
456 locus old_loc;
457 char n[GFC_MAX_SYMBOL_LEN+1];
458 gfc_symbol *sym;
459 match m;
460 gfc_symtree *st;
462 old_loc = gfc_current_locus;
464 m = gfc_match (" (");
465 if (m != MATCH_YES)
466 return m;
468 if (!targetm.have_tls)
470 sorry ("threadprivate variables not supported in this target");
471 goto cleanup;
474 for (;;)
476 m = gfc_match_symbol (&sym, 0);
477 switch (m)
479 case MATCH_YES:
480 if (sym->attr.in_common)
481 gfc_error_now ("Threadprivate variable at %C is an element of"
482 " a COMMON block");
483 else if (gfc_add_threadprivate (&sym->attr, sym->name,
484 &sym->declared_at) == FAILURE)
485 goto cleanup;
486 goto next_item;
487 case MATCH_NO:
488 break;
489 case MATCH_ERROR:
490 goto cleanup;
493 m = gfc_match (" / %n /", n);
494 if (m == MATCH_ERROR)
495 goto cleanup;
496 if (m == MATCH_NO || n[0] == '\0')
497 goto syntax;
499 st = gfc_find_symtree (gfc_current_ns->common_root, n);
500 if (st == NULL)
502 gfc_error ("COMMON block /%s/ not found at %C", n);
503 goto cleanup;
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)
509 goto cleanup;
511 next_item:
512 if (gfc_match_char (')') == MATCH_YES)
513 break;
514 if (gfc_match_char (',') != MATCH_YES)
515 goto syntax;
518 return MATCH_YES;
520 syntax:
521 gfc_error ("Syntax error in !$OMP THREADPRIVATE list at %C");
523 cleanup:
524 gfc_current_locus = old_loc;
525 return MATCH_ERROR;
528 match
529 gfc_match_omp_parallel_do (void)
531 gfc_omp_clauses *c;
532 if (gfc_match_omp_clauses (&c, OMP_PARALLEL_CLAUSES | OMP_DO_CLAUSES)
533 != MATCH_YES)
534 return MATCH_ERROR;
535 new_st.op = EXEC_OMP_PARALLEL_DO;
536 new_st.ext.omp_clauses = c;
537 return MATCH_YES;
540 match
541 gfc_match_omp_parallel_sections (void)
543 gfc_omp_clauses *c;
544 if (gfc_match_omp_clauses (&c, OMP_PARALLEL_CLAUSES | OMP_SECTIONS_CLAUSES)
545 != MATCH_YES)
546 return MATCH_ERROR;
547 new_st.op = EXEC_OMP_PARALLEL_SECTIONS;
548 new_st.ext.omp_clauses = c;
549 return MATCH_YES;
552 match
553 gfc_match_omp_parallel_workshare (void)
555 gfc_omp_clauses *c;
556 if (gfc_match_omp_clauses (&c, OMP_PARALLEL_CLAUSES) != MATCH_YES)
557 return MATCH_ERROR;
558 new_st.op = EXEC_OMP_PARALLEL_WORKSHARE;
559 new_st.ext.omp_clauses = c;
560 return MATCH_YES;
563 match
564 gfc_match_omp_sections (void)
566 gfc_omp_clauses *c;
567 if (gfc_match_omp_clauses (&c, OMP_SECTIONS_CLAUSES) != MATCH_YES)
568 return MATCH_ERROR;
569 new_st.op = EXEC_OMP_SECTIONS;
570 new_st.ext.omp_clauses = c;
571 return MATCH_YES;
574 match
575 gfc_match_omp_single (void)
577 gfc_omp_clauses *c;
578 if (gfc_match_omp_clauses (&c, OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE)
579 != MATCH_YES)
580 return MATCH_ERROR;
581 new_st.op = EXEC_OMP_SINGLE;
582 new_st.ext.omp_clauses = c;
583 return MATCH_YES;
586 match
587 gfc_match_omp_workshare (void)
589 if (gfc_match_omp_eos () != MATCH_YES)
590 return MATCH_ERROR;
591 new_st.op = EXEC_OMP_WORKSHARE;
592 new_st.ext.omp_clauses = gfc_get_omp_clauses ();
593 return MATCH_YES;
596 match
597 gfc_match_omp_master (void)
599 if (gfc_match_omp_eos () != MATCH_YES)
600 return MATCH_ERROR;
601 new_st.op = EXEC_OMP_MASTER;
602 new_st.ext.omp_clauses = NULL;
603 return MATCH_YES;
606 match
607 gfc_match_omp_ordered (void)
609 if (gfc_match_omp_eos () != MATCH_YES)
610 return MATCH_ERROR;
611 new_st.op = EXEC_OMP_ORDERED;
612 new_st.ext.omp_clauses = NULL;
613 return MATCH_YES;
616 match
617 gfc_match_omp_atomic (void)
619 if (gfc_match_omp_eos () != MATCH_YES)
620 return MATCH_ERROR;
621 new_st.op = EXEC_OMP_ATOMIC;
622 new_st.ext.omp_clauses = NULL;
623 return MATCH_YES;
626 match
627 gfc_match_omp_barrier (void)
629 if (gfc_match_omp_eos () != MATCH_YES)
630 return MATCH_ERROR;
631 new_st.op = EXEC_OMP_BARRIER;
632 new_st.ext.omp_clauses = NULL;
633 return MATCH_YES;
636 match
637 gfc_match_omp_end_nowait (void)
639 bool nowait = false;
640 if (gfc_match ("% nowait") == MATCH_YES)
641 nowait = true;
642 if (gfc_match_omp_eos () != MATCH_YES)
643 return MATCH_ERROR;
644 new_st.op = EXEC_OMP_END_NOWAIT;
645 new_st.ext.omp_bool = nowait;
646 return MATCH_YES;
649 match
650 gfc_match_omp_end_single (void)
652 gfc_omp_clauses *c;
653 if (gfc_match ("% nowait") == MATCH_YES)
655 new_st.op = EXEC_OMP_END_NOWAIT;
656 new_st.ext.omp_bool = true;
657 return MATCH_YES;
659 if (gfc_match_omp_clauses (&c, OMP_CLAUSE_COPYPRIVATE) != MATCH_YES)
660 return MATCH_ERROR;
661 new_st.op = EXEC_OMP_END_SINGLE;
662 new_st.ext.omp_clauses = c;
663 return MATCH_YES;
666 /* OpenMP directive resolving routines. */
668 static void
669 resolve_omp_clauses (gfc_code *code)
671 gfc_omp_clauses *omp_clauses = code->ext.omp_clauses;
672 gfc_namelist *n;
673 int list;
674 static const char *clause_names[]
675 = { "PRIVATE", "FIRSTPRIVATE", "LASTPRIVATE", "COPYPRIVATE", "SHARED",
676 "COPYIN", "REDUCTION" };
678 if (omp_clauses == NULL)
679 return;
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",
687 &expr->where);
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)
710 n->sym->mark = 0;
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)
715 if (n->sym->mark)
716 gfc_error ("Symbol '%s' present on multiple clauses at %L",
717 n->sym->name, &code->loc);
718 else
719 n->sym->mark = 1;
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)
724 if (n->sym->mark)
726 gfc_error ("Symbol '%s' present on multiple clauses at %L",
727 n->sym->name, &code->loc);
728 n->sym->mark = 0;
731 for (n = omp_clauses->lists[OMP_LIST_FIRSTPRIVATE]; n; n = n->next)
732 if (n->sym->mark)
733 gfc_error ("Symbol '%s' present on multiple clauses at %L",
734 n->sym->name, &code->loc);
735 else
736 n->sym->mark = 1;
738 for (n = omp_clauses->lists[OMP_LIST_LASTPRIVATE]; n; n = n->next)
739 n->sym->mark = 0;
741 for (n = omp_clauses->lists[OMP_LIST_LASTPRIVATE]; n; n = n->next)
742 if (n->sym->mark)
743 gfc_error ("Symbol '%s' present on multiple clauses at %L",
744 n->sym->name, &code->loc);
745 else
746 n->sym->mark = 1;
748 for (list = 0; list < OMP_LIST_NUM; list++)
749 if ((n = omp_clauses->lists[list]) != NULL)
751 const char *name;
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];
757 else
758 gcc_unreachable ();
760 switch (list)
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);
772 break;
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);
783 break;
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);
794 break;
795 default:
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);
825 switch (list)
827 case OMP_LIST_PLUS:
828 case OMP_LIST_MULT:
829 case OMP_LIST_SUB:
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),
835 &code->loc);
836 break;
837 case OMP_LIST_AND:
838 case OMP_LIST_OR:
839 case OMP_LIST_EQV:
840 case OMP_LIST_NEQV:
841 if (n->sym->ts.type != BT_LOGICAL)
842 gfc_error ("%s REDUCTION variable '%s' must be LOGICAL"
843 " at %L",
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);
848 break;
849 case OMP_LIST_MAX:
850 case OMP_LIST_MIN:
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);
857 break;
858 case OMP_LIST_IAND:
859 case OMP_LIST_IOR:
860 case OMP_LIST_IEOR:
861 if (n->sym->ts.type != BT_INTEGER)
862 gfc_error ("%s REDUCTION variable '%s' must be INTEGER"
863 " at %L",
864 list == OMP_LIST_IAND ? "IAND"
865 : list == OMP_LIST_MULT ? "IOR" : "IEOR",
866 n->sym->name, &code->loc);
867 break;
868 /* Workaround for PR middle-end/26316, nothing really needs
869 to be done here for OMP_LIST_PRIVATE. */
870 case OMP_LIST_PRIVATE:
871 gcc_assert (code->op != EXEC_NOP);
872 default:
873 break;
876 break;
881 /* Return true if SYM is ever referenced in EXPR except in the SE node. */
883 static bool
884 expr_references_sym (gfc_expr *e, gfc_symbol *s, gfc_expr *se)
886 gfc_actual_arglist *arg;
887 if (e == NULL || e == se)
888 return false;
889 switch (e->expr_type)
891 case EXPR_CONSTANT:
892 case EXPR_NULL:
893 case EXPR_VARIABLE:
894 case EXPR_STRUCTURE:
895 case EXPR_ARRAY:
896 if (e->symtree != NULL
897 && e->symtree->n.sym == s)
898 return true;
899 return false;
900 case EXPR_SUBSTRING:
901 if (e->ref != NULL
902 && (expr_references_sym (e->ref->u.ss.start, s, se)
903 || expr_references_sym (e->ref->u.ss.end, s, se)))
904 return true;
905 return false;
906 case EXPR_OP:
907 if (expr_references_sym (e->value.op.op2, s, se))
908 return true;
909 return expr_references_sym (e->value.op.op1, s, se);
910 case EXPR_FUNCTION:
911 for (arg = e->value.function.actual; arg; arg = arg->next)
912 if (expr_references_sym (arg->expr, s, se))
913 return true;
914 return false;
915 default:
916 gcc_unreachable ();
920 /* If EXPR is a conversion function that widens the type
921 if WIDENING is true or narrows the type if WIDENING is false,
922 return the inner expression, otherwise return NULL. */
924 static gfc_expr *
925 is_conversion (gfc_expr *expr, bool widening)
927 gfc_typespec *ts1, *ts2;
929 if (expr->expr_type != EXPR_FUNCTION
930 || expr->value.function.isym == NULL
931 || expr->value.function.esym != NULL
932 || expr->value.function.isym->generic_id != GFC_ISYM_CONVERSION)
933 return NULL;
935 if (widening)
937 ts1 = &expr->ts;
938 ts2 = &expr->value.function.actual->expr->ts;
940 else
942 ts1 = &expr->value.function.actual->expr->ts;
943 ts2 = &expr->ts;
946 if (ts1->type > ts2->type
947 || (ts1->type == ts2->type && ts1->kind > ts2->kind))
948 return expr->value.function.actual->expr;
950 return NULL;
953 static void
954 resolve_omp_atomic (gfc_code *code)
956 gfc_symbol *var;
957 gfc_expr *expr2;
959 code = code->block->next;
960 gcc_assert (code->op == EXEC_ASSIGN);
961 gcc_assert (code->next == NULL);
963 if (code->expr->expr_type != EXPR_VARIABLE
964 || code->expr->symtree == NULL
965 || code->expr->rank != 0
966 || (code->expr->ts.type != BT_INTEGER
967 && code->expr->ts.type != BT_REAL
968 && code->expr->ts.type != BT_COMPLEX
969 && code->expr->ts.type != BT_LOGICAL))
971 gfc_error ("!$OMP ATOMIC statement must set a scalar variable of"
972 " intrinsic type at %L", &code->loc);
973 return;
976 var = code->expr->symtree->n.sym;
977 expr2 = is_conversion (code->expr2, false);
978 if (expr2 == NULL)
979 expr2 = code->expr2;
981 if (expr2->expr_type == EXPR_OP)
983 gfc_expr *v = NULL, *e, *c;
984 gfc_intrinsic_op op = expr2->value.op.operator;
985 gfc_intrinsic_op alt_op = INTRINSIC_NONE;
987 switch (op)
989 case INTRINSIC_PLUS:
990 alt_op = INTRINSIC_MINUS;
991 break;
992 case INTRINSIC_TIMES:
993 alt_op = INTRINSIC_DIVIDE;
994 break;
995 case INTRINSIC_MINUS:
996 alt_op = INTRINSIC_PLUS;
997 break;
998 case INTRINSIC_DIVIDE:
999 alt_op = INTRINSIC_TIMES;
1000 break;
1001 case INTRINSIC_AND:
1002 case INTRINSIC_OR:
1003 break;
1004 case INTRINSIC_EQV:
1005 alt_op = INTRINSIC_NEQV;
1006 break;
1007 case INTRINSIC_NEQV:
1008 alt_op = INTRINSIC_EQV;
1009 break;
1010 default:
1011 gfc_error ("!$OMP ATOMIC assignment operator must be"
1012 " +, *, -, /, .AND., .OR., .EQV. or .NEQV. at %L",
1013 &expr2->where);
1014 return;
1017 /* Check for var = var op expr resp. var = expr op var where
1018 expr doesn't reference var and var op expr is mathematically
1019 equivalent to var op (expr) resp. expr op var equivalent to
1020 (expr) op var. We rely here on the fact that the matcher
1021 for x op1 y op2 z where op1 and op2 have equal precedence
1022 returns (x op1 y) op2 z. */
1023 e = expr2->value.op.op2;
1024 if (e->expr_type == EXPR_VARIABLE
1025 && e->symtree != NULL
1026 && e->symtree->n.sym == var)
1027 v = e;
1028 else if ((c = is_conversion (e, true)) != NULL
1029 && c->expr_type == EXPR_VARIABLE
1030 && c->symtree != NULL
1031 && c->symtree->n.sym == var)
1032 v = c;
1033 else
1035 gfc_expr **p = NULL, **q;
1036 for (q = &expr2->value.op.op1; (e = *q) != NULL; )
1037 if (e->expr_type == EXPR_VARIABLE
1038 && e->symtree != NULL
1039 && e->symtree->n.sym == var)
1041 v = e;
1042 break;
1044 else if ((c = is_conversion (e, true)) != NULL)
1045 q = &e->value.function.actual->expr;
1046 else if (e->expr_type != EXPR_OP
1047 || (e->value.op.operator != op
1048 && e->value.op.operator != alt_op)
1049 || e->rank != 0)
1050 break;
1051 else
1053 p = q;
1054 q = &e->value.op.op1;
1057 if (v == NULL)
1059 gfc_error ("!$OMP ATOMIC assignment must be var = var op expr"
1060 " or var = expr op var at %L", &expr2->where);
1061 return;
1064 if (p != NULL)
1066 e = *p;
1067 switch (e->value.op.operator)
1069 case INTRINSIC_MINUS:
1070 case INTRINSIC_DIVIDE:
1071 case INTRINSIC_EQV:
1072 case INTRINSIC_NEQV:
1073 gfc_error ("!$OMP ATOMIC var = var op expr not"
1074 " mathematically equivalent to var = var op"
1075 " (expr) at %L", &expr2->where);
1076 break;
1077 default:
1078 break;
1081 /* Canonicalize into var = var op (expr). */
1082 *p = e->value.op.op2;
1083 e->value.op.op2 = expr2;
1084 e->ts = expr2->ts;
1085 if (code->expr2 == expr2)
1086 code->expr2 = expr2 = e;
1087 else
1088 code->expr2->value.function.actual->expr = expr2 = e;
1090 if (!gfc_compare_types (&expr2->value.op.op1->ts, &expr2->ts))
1092 for (p = &expr2->value.op.op1; *p != v;
1093 p = &(*p)->value.function.actual->expr)
1095 *p = NULL;
1096 gfc_free_expr (expr2->value.op.op1);
1097 expr2->value.op.op1 = v;
1098 gfc_convert_type (v, &expr2->ts, 2);
1103 if (e->rank != 0 || expr_references_sym (code->expr2, var, v))
1105 gfc_error ("expr in !$OMP ATOMIC assignment var = var op expr"
1106 " must be scalar and cannot reference var at %L",
1107 &expr2->where);
1108 return;
1111 else if (expr2->expr_type == EXPR_FUNCTION
1112 && expr2->value.function.isym != NULL
1113 && expr2->value.function.esym == NULL
1114 && expr2->value.function.actual != NULL
1115 && expr2->value.function.actual->next != NULL)
1117 gfc_actual_arglist *arg, *var_arg;
1119 switch (expr2->value.function.isym->generic_id)
1121 case GFC_ISYM_MIN:
1122 case GFC_ISYM_MAX:
1123 break;
1124 case GFC_ISYM_IAND:
1125 case GFC_ISYM_IOR:
1126 case GFC_ISYM_IEOR:
1127 if (expr2->value.function.actual->next->next != NULL)
1129 gfc_error ("!$OMP ATOMIC assignment intrinsic IAND, IOR"
1130 "or IEOR must have two arguments at %L",
1131 &expr2->where);
1132 return;
1134 break;
1135 default:
1136 gfc_error ("!$OMP ATOMIC assignment intrinsic must be"
1137 " MIN, MAX, IAND, IOR or IEOR at %L",
1138 &expr2->where);
1139 return;
1142 var_arg = NULL;
1143 for (arg = expr2->value.function.actual; arg; arg = arg->next)
1145 if ((arg == expr2->value.function.actual
1146 || (var_arg == NULL && arg->next == NULL))
1147 && arg->expr->expr_type == EXPR_VARIABLE
1148 && arg->expr->symtree != NULL
1149 && arg->expr->symtree->n.sym == var)
1150 var_arg = arg;
1151 else if (expr_references_sym (arg->expr, var, NULL))
1152 gfc_error ("!$OMP ATOMIC intrinsic arguments except one must not"
1153 " reference '%s' at %L", var->name, &arg->expr->where);
1154 if (arg->expr->rank != 0)
1155 gfc_error ("!$OMP ATOMIC intrinsic arguments must be scalar"
1156 " at %L", &arg->expr->where);
1159 if (var_arg == NULL)
1161 gfc_error ("First or last !$OMP ATOMIC intrinsic argument must"
1162 " be '%s' at %L", var->name, &expr2->where);
1163 return;
1166 if (var_arg != expr2->value.function.actual)
1168 /* Canonicalize, so that var comes first. */
1169 gcc_assert (var_arg->next == NULL);
1170 for (arg = expr2->value.function.actual;
1171 arg->next != var_arg; arg = arg->next)
1173 var_arg->next = expr2->value.function.actual;
1174 expr2->value.function.actual = var_arg;
1175 arg->next = NULL;
1178 else
1179 gfc_error ("!$OMP ATOMIC assignment must have an operator or intrinsic"
1180 " on right hand side at %L", &expr2->where);
1183 struct omp_context
1185 gfc_code *code;
1186 struct pointer_set_t *sharing_clauses;
1187 struct pointer_set_t *private_iterators;
1188 struct omp_context *previous;
1189 } *omp_current_ctx;
1190 gfc_code *omp_current_do_code;
1192 void
1193 gfc_resolve_omp_do_blocks (gfc_code *code, gfc_namespace *ns)
1195 if (code->block->next && code->block->next->op == EXEC_DO)
1196 omp_current_do_code = code->block->next;
1197 gfc_resolve_blocks (code->block, ns);
1200 void
1201 gfc_resolve_omp_parallel_blocks (gfc_code *code, gfc_namespace *ns)
1203 struct omp_context ctx;
1204 gfc_omp_clauses *omp_clauses = code->ext.omp_clauses;
1205 gfc_namelist *n;
1206 int list;
1208 ctx.code = code;
1209 ctx.sharing_clauses = pointer_set_create ();
1210 ctx.private_iterators = pointer_set_create ();
1211 ctx.previous = omp_current_ctx;
1212 omp_current_ctx = &ctx;
1214 for (list = 0; list < OMP_LIST_NUM; list++)
1215 for (n = omp_clauses->lists[list]; n; n = n->next)
1216 pointer_set_insert (ctx.sharing_clauses, n->sym);
1218 if (code->op == EXEC_OMP_PARALLEL_DO)
1219 gfc_resolve_omp_do_blocks (code, ns);
1220 else
1221 gfc_resolve_blocks (code->block, ns);
1223 omp_current_ctx = ctx.previous;
1224 pointer_set_destroy (ctx.sharing_clauses);
1225 pointer_set_destroy (ctx.private_iterators);
1228 /* Note a DO iterator variable. This is special in !$omp parallel
1229 construct, where they are predetermined private. */
1231 void
1232 gfc_resolve_do_iterator (gfc_code *code, gfc_symbol *sym)
1234 struct omp_context *ctx;
1236 if (sym->attr.threadprivate)
1237 return;
1239 /* !$omp do and !$omp parallel do iteration variable is predetermined
1240 private just in the !$omp do resp. !$omp parallel do construct,
1241 with no implications for the outer parallel constructs. */
1242 if (code == omp_current_do_code)
1243 return;
1245 for (ctx = omp_current_ctx; ctx; ctx = ctx->previous)
1247 if (pointer_set_contains (ctx->sharing_clauses, sym))
1248 continue;
1250 if (! pointer_set_insert (ctx->private_iterators, sym))
1252 gfc_omp_clauses *omp_clauses = ctx->code->ext.omp_clauses;
1253 gfc_namelist *p;
1255 p = gfc_get_namelist ();
1256 p->sym = sym;
1257 p->next = omp_clauses->lists[OMP_LIST_PRIVATE];
1258 omp_clauses->lists[OMP_LIST_PRIVATE] = p;
1263 static void
1264 resolve_omp_do (gfc_code *code)
1266 gfc_code *do_code;
1267 int list;
1268 gfc_namelist *n;
1269 gfc_symbol *dovar;
1271 if (code->ext.omp_clauses)
1272 resolve_omp_clauses (code);
1274 do_code = code->block->next;
1275 if (do_code->op == EXEC_DO_WHILE)
1276 gfc_error ("!$OMP DO cannot be a DO WHILE or DO without loop control at %L",
1277 &do_code->loc);
1278 else
1280 gcc_assert (do_code->op == EXEC_DO);
1281 if (do_code->ext.iterator->var->ts.type != BT_INTEGER)
1282 gfc_error ("!$OMP DO iteration variable must be of type integer at %L",
1283 &do_code->loc);
1284 dovar = do_code->ext.iterator->var->symtree->n.sym;
1285 if (dovar->attr.threadprivate)
1286 gfc_error ("!$OMP DO iteration variable must not be THREADPRIVATE at %L",
1287 &do_code->loc);
1288 if (code->ext.omp_clauses)
1289 for (list = 0; list < OMP_LIST_NUM; list++)
1290 if (list != OMP_LIST_PRIVATE && list != OMP_LIST_LASTPRIVATE)
1291 for (n = code->ext.omp_clauses->lists[list]; n; n = n->next)
1292 if (dovar == n->sym)
1294 gfc_error ("!$OMP DO iteration variable present on clause"
1295 " other than PRIVATE or LASTPRIVATE at %L",
1296 &do_code->loc);
1297 break;
1302 /* Resolve OpenMP directive clauses and check various requirements
1303 of each directive. */
1305 void
1306 gfc_resolve_omp_directive (gfc_code *code, gfc_namespace *ns ATTRIBUTE_UNUSED)
1308 switch (code->op)
1310 case EXEC_OMP_DO:
1311 case EXEC_OMP_PARALLEL_DO:
1312 resolve_omp_do (code);
1313 break;
1314 case EXEC_OMP_WORKSHARE:
1315 case EXEC_OMP_PARALLEL_WORKSHARE:
1316 case EXEC_OMP_PARALLEL:
1317 case EXEC_OMP_PARALLEL_SECTIONS:
1318 case EXEC_OMP_SECTIONS:
1319 case EXEC_OMP_SINGLE:
1320 if (code->ext.omp_clauses)
1321 resolve_omp_clauses (code);
1322 break;
1323 case EXEC_OMP_ATOMIC:
1324 resolve_omp_atomic (code);
1325 break;
1326 default:
1327 break;