* match.c (gfc_match_name): Expanded comment.
[official-gcc.git] / gcc / fortran / openmp.c
blob42b5aa15dba7453ffcc71ea0d388f0e07a4554ef
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
11 version.
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
16 for more details.
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
21 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;
414 match
415 gfc_match_omp_critical (void)
417 char n[GFC_MAX_SYMBOL_LEN+1];
419 if (gfc_match (" ( %n )", n) != MATCH_YES)
420 n[0] = '\0';
421 if (gfc_match_omp_eos () != MATCH_YES)
422 return MATCH_ERROR;
423 new_st.op = EXEC_OMP_CRITICAL;
424 new_st.ext.omp_name = n[0] ? xstrdup (n) : NULL;
425 return MATCH_YES;
429 match
430 gfc_match_omp_do (void)
432 gfc_omp_clauses *c;
433 if (gfc_match_omp_clauses (&c, OMP_DO_CLAUSES) != MATCH_YES)
434 return MATCH_ERROR;
435 new_st.op = EXEC_OMP_DO;
436 new_st.ext.omp_clauses = c;
437 return MATCH_YES;
441 match
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);
449 return MATCH_ERROR;
451 new_st.op = EXEC_OMP_FLUSH;
452 new_st.ext.omp_namelist = list;
453 return MATCH_YES;
457 match
458 gfc_match_omp_threadprivate (void)
460 locus old_loc;
461 char n[GFC_MAX_SYMBOL_LEN+1];
462 gfc_symbol *sym;
463 match m;
464 gfc_symtree *st;
466 old_loc = gfc_current_locus;
468 m = gfc_match (" (");
469 if (m != MATCH_YES)
470 return m;
472 for (;;)
474 m = gfc_match_symbol (&sym, 0);
475 switch (m)
477 case MATCH_YES:
478 if (sym->attr.in_common)
479 gfc_error_now ("Threadprivate variable at %C is an element of "
480 "a COMMON block");
481 else if (gfc_add_threadprivate (&sym->attr, sym->name,
482 &sym->declared_at) == FAILURE)
483 goto cleanup;
484 goto next_item;
485 case MATCH_NO:
486 break;
487 case MATCH_ERROR:
488 goto cleanup;
491 m = gfc_match (" / %n /", n);
492 if (m == MATCH_ERROR)
493 goto cleanup;
494 if (m == MATCH_NO || n[0] == '\0')
495 goto syntax;
497 st = gfc_find_symtree (gfc_current_ns->common_root, n);
498 if (st == NULL)
500 gfc_error ("COMMON block /%s/ not found at %C", n);
501 goto cleanup;
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)
507 goto cleanup;
509 next_item:
510 if (gfc_match_char (')') == MATCH_YES)
511 break;
512 if (gfc_match_char (',') != MATCH_YES)
513 goto syntax;
516 return MATCH_YES;
518 syntax:
519 gfc_error ("Syntax error in !$OMP THREADPRIVATE list at %C");
521 cleanup:
522 gfc_current_locus = old_loc;
523 return MATCH_ERROR;
527 match
528 gfc_match_omp_parallel_do (void)
530 gfc_omp_clauses *c;
531 if (gfc_match_omp_clauses (&c, OMP_PARALLEL_CLAUSES | OMP_DO_CLAUSES)
532 != MATCH_YES)
533 return MATCH_ERROR;
534 new_st.op = EXEC_OMP_PARALLEL_DO;
535 new_st.ext.omp_clauses = c;
536 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;
553 match
554 gfc_match_omp_parallel_workshare (void)
556 gfc_omp_clauses *c;
557 if (gfc_match_omp_clauses (&c, OMP_PARALLEL_CLAUSES) != MATCH_YES)
558 return MATCH_ERROR;
559 new_st.op = EXEC_OMP_PARALLEL_WORKSHARE;
560 new_st.ext.omp_clauses = c;
561 return MATCH_YES;
565 match
566 gfc_match_omp_sections (void)
568 gfc_omp_clauses *c;
569 if (gfc_match_omp_clauses (&c, OMP_SECTIONS_CLAUSES) != MATCH_YES)
570 return MATCH_ERROR;
571 new_st.op = EXEC_OMP_SECTIONS;
572 new_st.ext.omp_clauses = c;
573 return MATCH_YES;
577 match
578 gfc_match_omp_single (void)
580 gfc_omp_clauses *c;
581 if (gfc_match_omp_clauses (&c, OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE)
582 != MATCH_YES)
583 return MATCH_ERROR;
584 new_st.op = EXEC_OMP_SINGLE;
585 new_st.ext.omp_clauses = c;
586 return MATCH_YES;
590 match
591 gfc_match_omp_workshare (void)
593 if (gfc_match_omp_eos () != MATCH_YES)
594 return MATCH_ERROR;
595 new_st.op = EXEC_OMP_WORKSHARE;
596 new_st.ext.omp_clauses = gfc_get_omp_clauses ();
597 return MATCH_YES;
601 match
602 gfc_match_omp_master (void)
604 if (gfc_match_omp_eos () != MATCH_YES)
605 return MATCH_ERROR;
606 new_st.op = EXEC_OMP_MASTER;
607 new_st.ext.omp_clauses = NULL;
608 return MATCH_YES;
612 match
613 gfc_match_omp_ordered (void)
615 if (gfc_match_omp_eos () != MATCH_YES)
616 return MATCH_ERROR;
617 new_st.op = EXEC_OMP_ORDERED;
618 new_st.ext.omp_clauses = NULL;
619 return MATCH_YES;
623 match
624 gfc_match_omp_atomic (void)
626 if (gfc_match_omp_eos () != MATCH_YES)
627 return MATCH_ERROR;
628 new_st.op = EXEC_OMP_ATOMIC;
629 new_st.ext.omp_clauses = NULL;
630 return MATCH_YES;
634 match
635 gfc_match_omp_barrier (void)
637 if (gfc_match_omp_eos () != MATCH_YES)
638 return MATCH_ERROR;
639 new_st.op = EXEC_OMP_BARRIER;
640 new_st.ext.omp_clauses = NULL;
641 return MATCH_YES;
645 match
646 gfc_match_omp_end_nowait (void)
648 bool nowait = false;
649 if (gfc_match ("% nowait") == MATCH_YES)
650 nowait = true;
651 if (gfc_match_omp_eos () != MATCH_YES)
652 return MATCH_ERROR;
653 new_st.op = EXEC_OMP_END_NOWAIT;
654 new_st.ext.omp_bool = nowait;
655 return MATCH_YES;
659 match
660 gfc_match_omp_end_single (void)
662 gfc_omp_clauses *c;
663 if (gfc_match ("% nowait") == MATCH_YES)
665 new_st.op = EXEC_OMP_END_NOWAIT;
666 new_st.ext.omp_bool = true;
667 return MATCH_YES;
669 if (gfc_match_omp_clauses (&c, OMP_CLAUSE_COPYPRIVATE) != MATCH_YES)
670 return MATCH_ERROR;
671 new_st.op = EXEC_OMP_END_SINGLE;
672 new_st.ext.omp_clauses = c;
673 return MATCH_YES;
677 /* OpenMP directive resolving routines. */
679 static void
680 resolve_omp_clauses (gfc_code *code)
682 gfc_omp_clauses *omp_clauses = code->ext.omp_clauses;
683 gfc_namelist *n;
684 int list;
685 static const char *clause_names[]
686 = { "PRIVATE", "FIRSTPRIVATE", "LASTPRIVATE", "COPYPRIVATE", "SHARED",
687 "COPYIN", "REDUCTION" };
689 if (omp_clauses == NULL)
690 return;
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",
698 &expr->where);
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)
721 n->sym->mark = 0;
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)
726 if (n->sym->mark)
727 gfc_error ("Symbol '%s' present on multiple clauses at %L",
728 n->sym->name, &code->loc);
729 else
730 n->sym->mark = 1;
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)
735 if (n->sym->mark)
737 gfc_error ("Symbol '%s' present on multiple clauses at %L",
738 n->sym->name, &code->loc);
739 n->sym->mark = 0;
742 for (n = omp_clauses->lists[OMP_LIST_FIRSTPRIVATE]; n; n = n->next)
743 if (n->sym->mark)
744 gfc_error ("Symbol '%s' present on multiple clauses at %L",
745 n->sym->name, &code->loc);
746 else
747 n->sym->mark = 1;
749 for (n = omp_clauses->lists[OMP_LIST_LASTPRIVATE]; n; n = n->next)
750 n->sym->mark = 0;
752 for (n = omp_clauses->lists[OMP_LIST_LASTPRIVATE]; n; n = n->next)
753 if (n->sym->mark)
754 gfc_error ("Symbol '%s' present on multiple clauses at %L",
755 n->sym->name, &code->loc);
756 else
757 n->sym->mark = 1;
759 for (list = 0; list < OMP_LIST_NUM; list++)
760 if ((n = omp_clauses->lists[list]) != NULL)
762 const char *name;
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];
768 else
769 gcc_unreachable ();
771 switch (list)
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);
783 break;
784 case OMP_LIST_COPYPRIVATE:
785 for (; n != NULL; n = n->next)
787 if (n->sym->as && n->sym->as->type == AS_ASSUMED_SIZE)
788 gfc_error ("Assumed size array '%s' in COPYPRIVATE clause "
789 "at %L", n->sym->name, &code->loc);
790 if (n->sym->attr.allocatable)
791 gfc_error ("COPYPRIVATE clause object '%s' is ALLOCATABLE "
792 "at %L", n->sym->name, &code->loc);
794 break;
795 case OMP_LIST_SHARED:
796 for (; n != NULL; n = n->next)
798 if (n->sym->attr.threadprivate)
799 gfc_error ("THREADPRIVATE object '%s' in SHARED clause at "
800 "%L", n->sym->name, &code->loc);
801 if (n->sym->attr.cray_pointee)
802 gfc_error ("Cray pointee '%s' in SHARED clause at %L",
803 n->sym->name, &code->loc);
805 break;
806 default:
807 for (; n != NULL; n = n->next)
809 if (n->sym->attr.threadprivate)
810 gfc_error ("THREADPRIVATE object '%s' in %s clause at %L",
811 n->sym->name, name, &code->loc);
812 if (n->sym->attr.cray_pointee)
813 gfc_error ("Cray pointee '%s' in %s clause at %L",
814 n->sym->name, name, &code->loc);
815 if (list != OMP_LIST_PRIVATE)
817 if (n->sym->attr.pointer)
818 gfc_error ("POINTER object '%s' in %s clause at %L",
819 n->sym->name, name, &code->loc);
820 if (n->sym->attr.allocatable)
821 gfc_error ("%s clause object '%s' is ALLOCATABLE at %L",
822 name, n->sym->name, &code->loc);
823 if (n->sym->attr.cray_pointer)
824 gfc_error ("Cray pointer '%s' in %s clause at %L",
825 n->sym->name, name, &code->loc);
827 if (n->sym->as && n->sym->as->type == AS_ASSUMED_SIZE)
828 gfc_error ("Assumed size array '%s' in %s clause at %L",
829 n->sym->name, name, &code->loc);
830 if (n->sym->attr.in_namelist
831 && (list < OMP_LIST_REDUCTION_FIRST
832 || list > OMP_LIST_REDUCTION_LAST))
833 gfc_error ("Variable '%s' in %s clause is used in "
834 "NAMELIST statement at %L",
835 n->sym->name, name, &code->loc);
836 switch (list)
838 case OMP_LIST_PLUS:
839 case OMP_LIST_MULT:
840 case OMP_LIST_SUB:
841 if (!gfc_numeric_ts (&n->sym->ts))
842 gfc_error ("%c REDUCTION variable '%s' is %s at %L",
843 list == OMP_LIST_PLUS ? '+'
844 : list == OMP_LIST_MULT ? '*' : '-',
845 n->sym->name, gfc_typename (&n->sym->ts),
846 &code->loc);
847 break;
848 case OMP_LIST_AND:
849 case OMP_LIST_OR:
850 case OMP_LIST_EQV:
851 case OMP_LIST_NEQV:
852 if (n->sym->ts.type != BT_LOGICAL)
853 gfc_error ("%s REDUCTION variable '%s' must be LOGICAL "
854 "at %L",
855 list == OMP_LIST_AND ? ".AND."
856 : list == OMP_LIST_OR ? ".OR."
857 : list == OMP_LIST_EQV ? ".EQV." : ".NEQV.",
858 n->sym->name, &code->loc);
859 break;
860 case OMP_LIST_MAX:
861 case OMP_LIST_MIN:
862 if (n->sym->ts.type != BT_INTEGER
863 && n->sym->ts.type != BT_REAL)
864 gfc_error ("%s REDUCTION variable '%s' must be "
865 "INTEGER or REAL at %L",
866 list == OMP_LIST_MAX ? "MAX" : "MIN",
867 n->sym->name, &code->loc);
868 break;
869 case OMP_LIST_IAND:
870 case OMP_LIST_IOR:
871 case OMP_LIST_IEOR:
872 if (n->sym->ts.type != BT_INTEGER)
873 gfc_error ("%s REDUCTION variable '%s' must be INTEGER "
874 "at %L",
875 list == OMP_LIST_IAND ? "IAND"
876 : list == OMP_LIST_MULT ? "IOR" : "IEOR",
877 n->sym->name, &code->loc);
878 break;
879 /* Workaround for PR middle-end/26316, nothing really needs
880 to be done here for OMP_LIST_PRIVATE. */
881 case OMP_LIST_PRIVATE:
882 gcc_assert (code->op != EXEC_NOP);
883 default:
884 break;
887 break;
893 /* Return true if SYM is ever referenced in EXPR except in the SE node. */
895 static bool
896 expr_references_sym (gfc_expr *e, gfc_symbol *s, gfc_expr *se)
898 gfc_actual_arglist *arg;
899 if (e == NULL || e == se)
900 return false;
901 switch (e->expr_type)
903 case EXPR_CONSTANT:
904 case EXPR_NULL:
905 case EXPR_VARIABLE:
906 case EXPR_STRUCTURE:
907 case EXPR_ARRAY:
908 if (e->symtree != NULL
909 && e->symtree->n.sym == s)
910 return true;
911 return false;
912 case EXPR_SUBSTRING:
913 if (e->ref != NULL
914 && (expr_references_sym (e->ref->u.ss.start, s, se)
915 || expr_references_sym (e->ref->u.ss.end, s, se)))
916 return true;
917 return false;
918 case EXPR_OP:
919 if (expr_references_sym (e->value.op.op2, s, se))
920 return true;
921 return expr_references_sym (e->value.op.op1, s, se);
922 case EXPR_FUNCTION:
923 for (arg = e->value.function.actual; arg; arg = arg->next)
924 if (expr_references_sym (arg->expr, s, se))
925 return true;
926 return false;
927 default:
928 gcc_unreachable ();
933 /* If EXPR is a conversion function that widens the type
934 if WIDENING is true or narrows the type if WIDENING is false,
935 return the inner expression, otherwise return NULL. */
937 static gfc_expr *
938 is_conversion (gfc_expr *expr, bool widening)
940 gfc_typespec *ts1, *ts2;
942 if (expr->expr_type != EXPR_FUNCTION
943 || expr->value.function.isym == NULL
944 || expr->value.function.esym != NULL
945 || expr->value.function.isym->generic_id != GFC_ISYM_CONVERSION)
946 return NULL;
948 if (widening)
950 ts1 = &expr->ts;
951 ts2 = &expr->value.function.actual->expr->ts;
953 else
955 ts1 = &expr->value.function.actual->expr->ts;
956 ts2 = &expr->ts;
959 if (ts1->type > ts2->type
960 || (ts1->type == ts2->type && ts1->kind > ts2->kind))
961 return expr->value.function.actual->expr;
963 return NULL;
967 static void
968 resolve_omp_atomic (gfc_code *code)
970 gfc_symbol *var;
971 gfc_expr *expr2;
973 code = code->block->next;
974 gcc_assert (code->op == EXEC_ASSIGN);
975 gcc_assert (code->next == NULL);
977 if (code->expr->expr_type != EXPR_VARIABLE
978 || code->expr->symtree == NULL
979 || code->expr->rank != 0
980 || (code->expr->ts.type != BT_INTEGER
981 && code->expr->ts.type != BT_REAL
982 && code->expr->ts.type != BT_COMPLEX
983 && code->expr->ts.type != BT_LOGICAL))
985 gfc_error ("!$OMP ATOMIC statement must set a scalar variable of "
986 "intrinsic type at %L", &code->loc);
987 return;
990 var = code->expr->symtree->n.sym;
991 expr2 = is_conversion (code->expr2, false);
992 if (expr2 == NULL)
993 expr2 = code->expr2;
995 if (expr2->expr_type == EXPR_OP)
997 gfc_expr *v = NULL, *e, *c;
998 gfc_intrinsic_op op = expr2->value.op.operator;
999 gfc_intrinsic_op alt_op = INTRINSIC_NONE;
1001 switch (op)
1003 case INTRINSIC_PLUS:
1004 alt_op = INTRINSIC_MINUS;
1005 break;
1006 case INTRINSIC_TIMES:
1007 alt_op = INTRINSIC_DIVIDE;
1008 break;
1009 case INTRINSIC_MINUS:
1010 alt_op = INTRINSIC_PLUS;
1011 break;
1012 case INTRINSIC_DIVIDE:
1013 alt_op = INTRINSIC_TIMES;
1014 break;
1015 case INTRINSIC_AND:
1016 case INTRINSIC_OR:
1017 break;
1018 case INTRINSIC_EQV:
1019 alt_op = INTRINSIC_NEQV;
1020 break;
1021 case INTRINSIC_NEQV:
1022 alt_op = INTRINSIC_EQV;
1023 break;
1024 default:
1025 gfc_error ("!$OMP ATOMIC assignment operator must be "
1026 "+, *, -, /, .AND., .OR., .EQV. or .NEQV. at %L",
1027 &expr2->where);
1028 return;
1031 /* Check for var = var op expr resp. var = expr op var where
1032 expr doesn't reference var and var op expr is mathematically
1033 equivalent to var op (expr) resp. expr op var equivalent to
1034 (expr) op var. We rely here on the fact that the matcher
1035 for x op1 y op2 z where op1 and op2 have equal precedence
1036 returns (x op1 y) op2 z. */
1037 e = expr2->value.op.op2;
1038 if (e->expr_type == EXPR_VARIABLE
1039 && e->symtree != NULL
1040 && e->symtree->n.sym == var)
1041 v = e;
1042 else if ((c = is_conversion (e, true)) != NULL
1043 && c->expr_type == EXPR_VARIABLE
1044 && c->symtree != NULL
1045 && c->symtree->n.sym == var)
1046 v = c;
1047 else
1049 gfc_expr **p = NULL, **q;
1050 for (q = &expr2->value.op.op1; (e = *q) != NULL; )
1051 if (e->expr_type == EXPR_VARIABLE
1052 && e->symtree != NULL
1053 && e->symtree->n.sym == var)
1055 v = e;
1056 break;
1058 else if ((c = is_conversion (e, true)) != NULL)
1059 q = &e->value.function.actual->expr;
1060 else if (e->expr_type != EXPR_OP
1061 || (e->value.op.operator != op
1062 && e->value.op.operator != alt_op)
1063 || e->rank != 0)
1064 break;
1065 else
1067 p = q;
1068 q = &e->value.op.op1;
1071 if (v == NULL)
1073 gfc_error ("!$OMP ATOMIC assignment must be var = var op expr "
1074 "or var = expr op var at %L", &expr2->where);
1075 return;
1078 if (p != NULL)
1080 e = *p;
1081 switch (e->value.op.operator)
1083 case INTRINSIC_MINUS:
1084 case INTRINSIC_DIVIDE:
1085 case INTRINSIC_EQV:
1086 case INTRINSIC_NEQV:
1087 gfc_error ("!$OMP ATOMIC var = var op expr not "
1088 "mathematically equivalent to var = var op "
1089 "(expr) at %L", &expr2->where);
1090 break;
1091 default:
1092 break;
1095 /* Canonicalize into var = var op (expr). */
1096 *p = e->value.op.op2;
1097 e->value.op.op2 = expr2;
1098 e->ts = expr2->ts;
1099 if (code->expr2 == expr2)
1100 code->expr2 = expr2 = e;
1101 else
1102 code->expr2->value.function.actual->expr = expr2 = e;
1104 if (!gfc_compare_types (&expr2->value.op.op1->ts, &expr2->ts))
1106 for (p = &expr2->value.op.op1; *p != v;
1107 p = &(*p)->value.function.actual->expr)
1109 *p = NULL;
1110 gfc_free_expr (expr2->value.op.op1);
1111 expr2->value.op.op1 = v;
1112 gfc_convert_type (v, &expr2->ts, 2);
1117 if (e->rank != 0 || expr_references_sym (code->expr2, var, v))
1119 gfc_error ("expr in !$OMP ATOMIC assignment var = var op expr "
1120 "must be scalar and cannot reference var at %L",
1121 &expr2->where);
1122 return;
1125 else if (expr2->expr_type == EXPR_FUNCTION
1126 && expr2->value.function.isym != NULL
1127 && expr2->value.function.esym == NULL
1128 && expr2->value.function.actual != NULL
1129 && expr2->value.function.actual->next != NULL)
1131 gfc_actual_arglist *arg, *var_arg;
1133 switch (expr2->value.function.isym->generic_id)
1135 case GFC_ISYM_MIN:
1136 case GFC_ISYM_MAX:
1137 break;
1138 case GFC_ISYM_IAND:
1139 case GFC_ISYM_IOR:
1140 case GFC_ISYM_IEOR:
1141 if (expr2->value.function.actual->next->next != NULL)
1143 gfc_error ("!$OMP ATOMIC assignment intrinsic IAND, IOR "
1144 "or IEOR must have two arguments at %L",
1145 &expr2->where);
1146 return;
1148 break;
1149 default:
1150 gfc_error ("!$OMP ATOMIC assignment intrinsic must be "
1151 "MIN, MAX, IAND, IOR or IEOR at %L",
1152 &expr2->where);
1153 return;
1156 var_arg = NULL;
1157 for (arg = expr2->value.function.actual; arg; arg = arg->next)
1159 if ((arg == expr2->value.function.actual
1160 || (var_arg == NULL && arg->next == NULL))
1161 && arg->expr->expr_type == EXPR_VARIABLE
1162 && arg->expr->symtree != NULL
1163 && arg->expr->symtree->n.sym == var)
1164 var_arg = arg;
1165 else if (expr_references_sym (arg->expr, var, NULL))
1166 gfc_error ("!$OMP ATOMIC intrinsic arguments except one must not "
1167 "reference '%s' at %L", var->name, &arg->expr->where);
1168 if (arg->expr->rank != 0)
1169 gfc_error ("!$OMP ATOMIC intrinsic arguments must be scalar "
1170 "at %L", &arg->expr->where);
1173 if (var_arg == NULL)
1175 gfc_error ("First or last !$OMP ATOMIC intrinsic argument must "
1176 "be '%s' at %L", var->name, &expr2->where);
1177 return;
1180 if (var_arg != expr2->value.function.actual)
1182 /* Canonicalize, so that var comes first. */
1183 gcc_assert (var_arg->next == NULL);
1184 for (arg = expr2->value.function.actual;
1185 arg->next != var_arg; arg = arg->next)
1187 var_arg->next = expr2->value.function.actual;
1188 expr2->value.function.actual = var_arg;
1189 arg->next = NULL;
1192 else
1193 gfc_error ("!$OMP ATOMIC assignment must have an operator or intrinsic "
1194 "on right hand side at %L", &expr2->where);
1198 struct omp_context
1200 gfc_code *code;
1201 struct pointer_set_t *sharing_clauses;
1202 struct pointer_set_t *private_iterators;
1203 struct omp_context *previous;
1204 } *omp_current_ctx;
1205 gfc_code *omp_current_do_code;
1208 void
1209 gfc_resolve_omp_do_blocks (gfc_code *code, gfc_namespace *ns)
1211 if (code->block->next && code->block->next->op == EXEC_DO)
1212 omp_current_do_code = code->block->next;
1213 gfc_resolve_blocks (code->block, ns);
1217 void
1218 gfc_resolve_omp_parallel_blocks (gfc_code *code, gfc_namespace *ns)
1220 struct omp_context ctx;
1221 gfc_omp_clauses *omp_clauses = code->ext.omp_clauses;
1222 gfc_namelist *n;
1223 int list;
1225 ctx.code = code;
1226 ctx.sharing_clauses = pointer_set_create ();
1227 ctx.private_iterators = pointer_set_create ();
1228 ctx.previous = omp_current_ctx;
1229 omp_current_ctx = &ctx;
1231 for (list = 0; list < OMP_LIST_NUM; list++)
1232 for (n = omp_clauses->lists[list]; n; n = n->next)
1233 pointer_set_insert (ctx.sharing_clauses, n->sym);
1235 if (code->op == EXEC_OMP_PARALLEL_DO)
1236 gfc_resolve_omp_do_blocks (code, ns);
1237 else
1238 gfc_resolve_blocks (code->block, ns);
1240 omp_current_ctx = ctx.previous;
1241 pointer_set_destroy (ctx.sharing_clauses);
1242 pointer_set_destroy (ctx.private_iterators);
1246 /* Note a DO iterator variable. This is special in !$omp parallel
1247 construct, where they are predetermined private. */
1249 void
1250 gfc_resolve_do_iterator (gfc_code *code, gfc_symbol *sym)
1252 struct omp_context *ctx;
1254 if (sym->attr.threadprivate)
1255 return;
1257 /* !$omp do and !$omp parallel do iteration variable is predetermined
1258 private just in the !$omp do resp. !$omp parallel do construct,
1259 with no implications for the outer parallel constructs. */
1260 if (code == omp_current_do_code)
1261 return;
1263 for (ctx = omp_current_ctx; ctx; ctx = ctx->previous)
1265 if (pointer_set_contains (ctx->sharing_clauses, sym))
1266 continue;
1268 if (! pointer_set_insert (ctx->private_iterators, sym))
1270 gfc_omp_clauses *omp_clauses = ctx->code->ext.omp_clauses;
1271 gfc_namelist *p;
1273 p = gfc_get_namelist ();
1274 p->sym = sym;
1275 p->next = omp_clauses->lists[OMP_LIST_PRIVATE];
1276 omp_clauses->lists[OMP_LIST_PRIVATE] = p;
1282 static void
1283 resolve_omp_do (gfc_code *code)
1285 gfc_code *do_code;
1286 int list;
1287 gfc_namelist *n;
1288 gfc_symbol *dovar;
1290 if (code->ext.omp_clauses)
1291 resolve_omp_clauses (code);
1293 do_code = code->block->next;
1294 if (do_code->op == EXEC_DO_WHILE)
1295 gfc_error ("!$OMP DO cannot be a DO WHILE or DO without loop control "
1296 "at %L", &do_code->loc);
1297 else
1299 gcc_assert (do_code->op == EXEC_DO);
1300 if (do_code->ext.iterator->var->ts.type != BT_INTEGER)
1301 gfc_error ("!$OMP DO iteration variable must be of type integer at %L",
1302 &do_code->loc);
1303 dovar = do_code->ext.iterator->var->symtree->n.sym;
1304 if (dovar->attr.threadprivate)
1305 gfc_error ("!$OMP DO iteration variable must not be THREADPRIVATE "
1306 "at %L", &do_code->loc);
1307 if (code->ext.omp_clauses)
1308 for (list = 0; list < OMP_LIST_NUM; list++)
1309 if (list != OMP_LIST_PRIVATE && list != OMP_LIST_LASTPRIVATE)
1310 for (n = code->ext.omp_clauses->lists[list]; n; n = n->next)
1311 if (dovar == n->sym)
1313 gfc_error ("!$OMP DO iteration variable present on clause "
1314 "other than PRIVATE or LASTPRIVATE at %L",
1315 &do_code->loc);
1316 break;
1322 /* Resolve OpenMP directive clauses and check various requirements
1323 of each directive. */
1325 void
1326 gfc_resolve_omp_directive (gfc_code *code, gfc_namespace *ns ATTRIBUTE_UNUSED)
1328 switch (code->op)
1330 case EXEC_OMP_DO:
1331 case EXEC_OMP_PARALLEL_DO:
1332 resolve_omp_do (code);
1333 break;
1334 case EXEC_OMP_WORKSHARE:
1335 case EXEC_OMP_PARALLEL_WORKSHARE:
1336 case EXEC_OMP_PARALLEL:
1337 case EXEC_OMP_PARALLEL_SECTIONS:
1338 case EXEC_OMP_SECTIONS:
1339 case EXEC_OMP_SINGLE:
1340 if (code->ext.omp_clauses)
1341 resolve_omp_clauses (code);
1342 break;
1343 case EXEC_OMP_ATOMIC:
1344 resolve_omp_atomic (code);
1345 break;
1346 default:
1347 break;