Merged with mainline at revision 128810.
[official-gcc.git] / gcc / fortran / openmp.c
blob5c45343007c6af58a4d7f8bf48f169077423b73c
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 3, 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 COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
22 #include "config.h"
23 #include "system.h"
24 #include "flags.h"
25 #include "gfortran.h"
26 #include "match.h"
27 #include "parse.h"
28 #include "pointer-set.h"
29 #include "target.h"
30 #include "toplev.h"
32 /* Match an end of OpenMP directive. End of OpenMP directive is optional
33 whitespace, followed by '\n' or comment '!'. */
35 match
36 gfc_match_omp_eos (void)
38 locus old_loc;
39 int c;
41 old_loc = gfc_current_locus;
42 gfc_gobble_whitespace ();
44 c = gfc_next_char ();
45 switch (c)
47 case '!':
49 c = gfc_next_char ();
50 while (c != '\n');
51 /* Fall through */
53 case '\n':
54 return MATCH_YES;
57 gfc_current_locus = old_loc;
58 return MATCH_NO;
61 /* Free an omp_clauses structure. */
63 void
64 gfc_free_omp_clauses (gfc_omp_clauses *c)
66 int i;
67 if (c == NULL)
68 return;
70 gfc_free_expr (c->if_expr);
71 gfc_free_expr (c->num_threads);
72 gfc_free_expr (c->chunk_size);
73 for (i = 0; i < OMP_LIST_NUM; i++)
74 gfc_free_namelist (c->lists[i]);
75 gfc_free (c);
78 /* Match a variable/common block list and construct a namelist from it. */
80 static match
81 gfc_match_omp_variable_list (const char *str, gfc_namelist **list,
82 bool allow_common)
84 gfc_namelist *head, *tail, *p;
85 locus old_loc;
86 char n[GFC_MAX_SYMBOL_LEN+1];
87 gfc_symbol *sym;
88 match m;
89 gfc_symtree *st;
91 head = tail = NULL;
93 old_loc = gfc_current_locus;
95 m = gfc_match (str);
96 if (m != MATCH_YES)
97 return m;
99 for (;;)
101 m = gfc_match_symbol (&sym, 1);
102 switch (m)
104 case MATCH_YES:
105 gfc_set_sym_referenced (sym);
106 p = gfc_get_namelist ();
107 if (head == NULL)
108 head = tail = p;
109 else
111 tail->next = p;
112 tail = tail->next;
114 tail->sym = sym;
115 goto next_item;
116 case MATCH_NO:
117 break;
118 case MATCH_ERROR:
119 goto cleanup;
122 if (!allow_common)
123 goto syntax;
125 m = gfc_match (" / %n /", n);
126 if (m == MATCH_ERROR)
127 goto cleanup;
128 if (m == MATCH_NO)
129 goto syntax;
131 st = gfc_find_symtree (gfc_current_ns->common_root, n);
132 if (st == NULL)
134 gfc_error ("COMMON block /%s/ not found at %C", n);
135 goto cleanup;
137 for (sym = st->n.common->head; sym; sym = sym->common_next)
139 gfc_set_sym_referenced (sym);
140 p = gfc_get_namelist ();
141 if (head == NULL)
142 head = tail = p;
143 else
145 tail->next = p;
146 tail = tail->next;
148 tail->sym = sym;
151 next_item:
152 if (gfc_match_char (')') == MATCH_YES)
153 break;
154 if (gfc_match_char (',') != MATCH_YES)
155 goto syntax;
158 while (*list)
159 list = &(*list)->next;
161 *list = head;
162 return MATCH_YES;
164 syntax:
165 gfc_error ("Syntax error in OpenMP variable list at %C");
167 cleanup:
168 gfc_free_namelist (head);
169 gfc_current_locus = old_loc;
170 return MATCH_ERROR;
173 #define OMP_CLAUSE_PRIVATE (1 << 0)
174 #define OMP_CLAUSE_FIRSTPRIVATE (1 << 1)
175 #define OMP_CLAUSE_LASTPRIVATE (1 << 2)
176 #define OMP_CLAUSE_COPYPRIVATE (1 << 3)
177 #define OMP_CLAUSE_SHARED (1 << 4)
178 #define OMP_CLAUSE_COPYIN (1 << 5)
179 #define OMP_CLAUSE_REDUCTION (1 << 6)
180 #define OMP_CLAUSE_IF (1 << 7)
181 #define OMP_CLAUSE_NUM_THREADS (1 << 8)
182 #define OMP_CLAUSE_SCHEDULE (1 << 9)
183 #define OMP_CLAUSE_DEFAULT (1 << 10)
184 #define OMP_CLAUSE_ORDERED (1 << 11)
186 /* Match OpenMP directive clauses. MASK is a bitmask of
187 clauses that are allowed for a particular directive. */
189 static match
190 gfc_match_omp_clauses (gfc_omp_clauses **cp, int mask)
192 gfc_omp_clauses *c = gfc_get_omp_clauses ();
193 locus old_loc;
194 bool needs_space = true, first = true;
196 *cp = NULL;
197 while (1)
199 if ((first || gfc_match_char (',') != MATCH_YES)
200 && (needs_space && gfc_match_space () != MATCH_YES))
201 break;
202 needs_space = false;
203 first = false;
204 gfc_gobble_whitespace ();
205 if ((mask & OMP_CLAUSE_IF) && c->if_expr == NULL
206 && gfc_match ("if ( %e )", &c->if_expr) == MATCH_YES)
207 continue;
208 if ((mask & OMP_CLAUSE_NUM_THREADS) && c->num_threads == NULL
209 && gfc_match ("num_threads ( %e )", &c->num_threads) == MATCH_YES)
210 continue;
211 if ((mask & OMP_CLAUSE_PRIVATE)
212 && gfc_match_omp_variable_list ("private (",
213 &c->lists[OMP_LIST_PRIVATE], true)
214 == MATCH_YES)
215 continue;
216 if ((mask & OMP_CLAUSE_FIRSTPRIVATE)
217 && gfc_match_omp_variable_list ("firstprivate (",
218 &c->lists[OMP_LIST_FIRSTPRIVATE],
219 true)
220 == MATCH_YES)
221 continue;
222 if ((mask & OMP_CLAUSE_LASTPRIVATE)
223 && gfc_match_omp_variable_list ("lastprivate (",
224 &c->lists[OMP_LIST_LASTPRIVATE],
225 true)
226 == MATCH_YES)
227 continue;
228 if ((mask & OMP_CLAUSE_COPYPRIVATE)
229 && gfc_match_omp_variable_list ("copyprivate (",
230 &c->lists[OMP_LIST_COPYPRIVATE],
231 true)
232 == MATCH_YES)
233 continue;
234 if ((mask & OMP_CLAUSE_SHARED)
235 && gfc_match_omp_variable_list ("shared (",
236 &c->lists[OMP_LIST_SHARED], true)
237 == MATCH_YES)
238 continue;
239 if ((mask & OMP_CLAUSE_COPYIN)
240 && gfc_match_omp_variable_list ("copyin (",
241 &c->lists[OMP_LIST_COPYIN], true)
242 == MATCH_YES)
243 continue;
244 old_loc = gfc_current_locus;
245 if ((mask & OMP_CLAUSE_REDUCTION)
246 && gfc_match ("reduction ( ") == MATCH_YES)
248 int reduction = OMP_LIST_NUM;
249 char buffer[GFC_MAX_SYMBOL_LEN + 1];
250 if (gfc_match_char ('+') == MATCH_YES)
251 reduction = OMP_LIST_PLUS;
252 else if (gfc_match_char ('*') == MATCH_YES)
253 reduction = OMP_LIST_MULT;
254 else if (gfc_match_char ('-') == MATCH_YES)
255 reduction = OMP_LIST_SUB;
256 else if (gfc_match (".and.") == MATCH_YES)
257 reduction = OMP_LIST_AND;
258 else if (gfc_match (".or.") == MATCH_YES)
259 reduction = OMP_LIST_OR;
260 else if (gfc_match (".eqv.") == MATCH_YES)
261 reduction = OMP_LIST_EQV;
262 else if (gfc_match (".neqv.") == MATCH_YES)
263 reduction = OMP_LIST_NEQV;
264 else if (gfc_match_name (buffer) == MATCH_YES)
266 gfc_symbol *sym;
267 const char *n = buffer;
269 gfc_find_symbol (buffer, NULL, 1, &sym);
270 if (sym != NULL)
272 if (sym->attr.intrinsic)
273 n = sym->name;
274 else if ((sym->attr.flavor != FL_UNKNOWN
275 && sym->attr.flavor != FL_PROCEDURE)
276 || sym->attr.external
277 || sym->attr.generic
278 || sym->attr.entry
279 || sym->attr.result
280 || sym->attr.dummy
281 || sym->attr.subroutine
282 || sym->attr.pointer
283 || sym->attr.target
284 || sym->attr.cray_pointer
285 || sym->attr.cray_pointee
286 || (sym->attr.proc != PROC_UNKNOWN
287 && sym->attr.proc != PROC_INTRINSIC)
288 || sym->attr.if_source != IFSRC_UNKNOWN
289 || sym == sym->ns->proc_name)
291 gfc_error_now ("%s is not INTRINSIC procedure name "
292 "at %C", buffer);
293 sym = NULL;
295 else
296 n = sym->name;
298 if (strcmp (n, "max") == 0)
299 reduction = OMP_LIST_MAX;
300 else if (strcmp (n, "min") == 0)
301 reduction = OMP_LIST_MIN;
302 else if (strcmp (n, "iand") == 0)
303 reduction = OMP_LIST_IAND;
304 else if (strcmp (n, "ior") == 0)
305 reduction = OMP_LIST_IOR;
306 else if (strcmp (n, "ieor") == 0)
307 reduction = OMP_LIST_IEOR;
308 if (reduction != OMP_LIST_NUM
309 && sym != NULL
310 && ! sym->attr.intrinsic
311 && ! sym->attr.use_assoc
312 && ((sym->attr.flavor == FL_UNKNOWN
313 && gfc_add_flavor (&sym->attr, FL_PROCEDURE,
314 sym->name, NULL) == FAILURE)
315 || gfc_add_intrinsic (&sym->attr, NULL) == FAILURE))
317 gfc_free_omp_clauses (c);
318 return MATCH_ERROR;
321 if (reduction != OMP_LIST_NUM
322 && gfc_match_omp_variable_list (" :", &c->lists[reduction],
323 false)
324 == MATCH_YES)
325 continue;
326 else
327 gfc_current_locus = old_loc;
329 if ((mask & OMP_CLAUSE_DEFAULT)
330 && c->default_sharing == OMP_DEFAULT_UNKNOWN)
332 if (gfc_match ("default ( shared )") == MATCH_YES)
333 c->default_sharing = OMP_DEFAULT_SHARED;
334 else if (gfc_match ("default ( private )") == MATCH_YES)
335 c->default_sharing = OMP_DEFAULT_PRIVATE;
336 else if (gfc_match ("default ( none )") == MATCH_YES)
337 c->default_sharing = OMP_DEFAULT_NONE;
338 if (c->default_sharing != OMP_DEFAULT_UNKNOWN)
339 continue;
341 old_loc = gfc_current_locus;
342 if ((mask & OMP_CLAUSE_SCHEDULE)
343 && c->sched_kind == OMP_SCHED_NONE
344 && gfc_match ("schedule ( ") == MATCH_YES)
346 if (gfc_match ("static") == MATCH_YES)
347 c->sched_kind = OMP_SCHED_STATIC;
348 else if (gfc_match ("dynamic") == MATCH_YES)
349 c->sched_kind = OMP_SCHED_DYNAMIC;
350 else if (gfc_match ("guided") == MATCH_YES)
351 c->sched_kind = OMP_SCHED_GUIDED;
352 else if (gfc_match ("runtime") == MATCH_YES)
353 c->sched_kind = OMP_SCHED_RUNTIME;
354 if (c->sched_kind != OMP_SCHED_NONE)
356 match m = MATCH_NO;
357 if (c->sched_kind != OMP_SCHED_RUNTIME)
358 m = gfc_match (" , %e )", &c->chunk_size);
359 if (m != MATCH_YES)
360 m = gfc_match_char (')');
361 if (m != MATCH_YES)
362 c->sched_kind = OMP_SCHED_NONE;
364 if (c->sched_kind != OMP_SCHED_NONE)
365 continue;
366 else
367 gfc_current_locus = old_loc;
369 if ((mask & OMP_CLAUSE_ORDERED) && !c->ordered
370 && gfc_match ("ordered") == MATCH_YES)
372 c->ordered = needs_space = true;
373 continue;
376 break;
379 if (gfc_match_omp_eos () != MATCH_YES)
381 gfc_free_omp_clauses (c);
382 return MATCH_ERROR;
385 *cp = c;
386 return MATCH_YES;
389 #define OMP_PARALLEL_CLAUSES \
390 (OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_SHARED \
391 | OMP_CLAUSE_COPYIN | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_IF \
392 | OMP_CLAUSE_NUM_THREADS | OMP_CLAUSE_DEFAULT)
393 #define OMP_DO_CLAUSES \
394 (OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE \
395 | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION \
396 | OMP_CLAUSE_SCHEDULE | OMP_CLAUSE_ORDERED)
397 #define OMP_SECTIONS_CLAUSES \
398 (OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE \
399 | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION)
401 match
402 gfc_match_omp_parallel (void)
404 gfc_omp_clauses *c;
405 if (gfc_match_omp_clauses (&c, OMP_PARALLEL_CLAUSES) != MATCH_YES)
406 return MATCH_ERROR;
407 new_st.op = EXEC_OMP_PARALLEL;
408 new_st.ext.omp_clauses = c;
409 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;
428 match
429 gfc_match_omp_do (void)
431 gfc_omp_clauses *c;
432 if (gfc_match_omp_clauses (&c, OMP_DO_CLAUSES) != MATCH_YES)
433 return MATCH_ERROR;
434 new_st.op = EXEC_OMP_DO;
435 new_st.ext.omp_clauses = c;
436 return MATCH_YES;
440 match
441 gfc_match_omp_flush (void)
443 gfc_namelist *list = NULL;
444 gfc_match_omp_variable_list (" (", &list, true);
445 if (gfc_match_omp_eos () != MATCH_YES)
447 gfc_free_namelist (list);
448 return MATCH_ERROR;
450 new_st.op = EXEC_OMP_FLUSH;
451 new_st.ext.omp_namelist = list;
452 return MATCH_YES;
456 match
457 gfc_match_omp_threadprivate (void)
459 locus old_loc;
460 char n[GFC_MAX_SYMBOL_LEN+1];
461 gfc_symbol *sym;
462 match m;
463 gfc_symtree *st;
465 old_loc = gfc_current_locus;
467 m = gfc_match (" (");
468 if (m != MATCH_YES)
469 return m;
471 for (;;)
473 m = gfc_match_symbol (&sym, 0);
474 switch (m)
476 case MATCH_YES:
477 if (sym->attr.in_common)
478 gfc_error_now ("Threadprivate variable at %C is an element of "
479 "a COMMON block");
480 else if (gfc_add_threadprivate (&sym->attr, sym->name,
481 &sym->declared_at) == FAILURE)
482 goto cleanup;
483 goto next_item;
484 case MATCH_NO:
485 break;
486 case MATCH_ERROR:
487 goto cleanup;
490 m = gfc_match (" / %n /", n);
491 if (m == MATCH_ERROR)
492 goto cleanup;
493 if (m == MATCH_NO || n[0] == '\0')
494 goto syntax;
496 st = gfc_find_symtree (gfc_current_ns->common_root, n);
497 if (st == NULL)
499 gfc_error ("COMMON block /%s/ not found at %C", n);
500 goto cleanup;
502 st->n.common->threadprivate = 1;
503 for (sym = st->n.common->head; sym; sym = sym->common_next)
504 if (gfc_add_threadprivate (&sym->attr, sym->name,
505 &sym->declared_at) == FAILURE)
506 goto cleanup;
508 next_item:
509 if (gfc_match_char (')') == MATCH_YES)
510 break;
511 if (gfc_match_char (',') != MATCH_YES)
512 goto syntax;
515 return MATCH_YES;
517 syntax:
518 gfc_error ("Syntax error in !$OMP THREADPRIVATE list at %C");
520 cleanup:
521 gfc_current_locus = old_loc;
522 return MATCH_ERROR;
526 match
527 gfc_match_omp_parallel_do (void)
529 gfc_omp_clauses *c;
530 if (gfc_match_omp_clauses (&c, OMP_PARALLEL_CLAUSES | OMP_DO_CLAUSES)
531 != MATCH_YES)
532 return MATCH_ERROR;
533 new_st.op = EXEC_OMP_PARALLEL_DO;
534 new_st.ext.omp_clauses = c;
535 return MATCH_YES;
539 match
540 gfc_match_omp_parallel_sections (void)
542 gfc_omp_clauses *c;
543 if (gfc_match_omp_clauses (&c, OMP_PARALLEL_CLAUSES | OMP_SECTIONS_CLAUSES)
544 != MATCH_YES)
545 return MATCH_ERROR;
546 new_st.op = EXEC_OMP_PARALLEL_SECTIONS;
547 new_st.ext.omp_clauses = c;
548 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;
564 match
565 gfc_match_omp_sections (void)
567 gfc_omp_clauses *c;
568 if (gfc_match_omp_clauses (&c, OMP_SECTIONS_CLAUSES) != MATCH_YES)
569 return MATCH_ERROR;
570 new_st.op = EXEC_OMP_SECTIONS;
571 new_st.ext.omp_clauses = c;
572 return MATCH_YES;
576 match
577 gfc_match_omp_single (void)
579 gfc_omp_clauses *c;
580 if (gfc_match_omp_clauses (&c, OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE)
581 != MATCH_YES)
582 return MATCH_ERROR;
583 new_st.op = EXEC_OMP_SINGLE;
584 new_st.ext.omp_clauses = c;
585 return MATCH_YES;
589 match
590 gfc_match_omp_workshare (void)
592 if (gfc_match_omp_eos () != MATCH_YES)
593 return MATCH_ERROR;
594 new_st.op = EXEC_OMP_WORKSHARE;
595 new_st.ext.omp_clauses = gfc_get_omp_clauses ();
596 return MATCH_YES;
600 match
601 gfc_match_omp_master (void)
603 if (gfc_match_omp_eos () != MATCH_YES)
604 return MATCH_ERROR;
605 new_st.op = EXEC_OMP_MASTER;
606 new_st.ext.omp_clauses = NULL;
607 return MATCH_YES;
611 match
612 gfc_match_omp_ordered (void)
614 if (gfc_match_omp_eos () != MATCH_YES)
615 return MATCH_ERROR;
616 new_st.op = EXEC_OMP_ORDERED;
617 new_st.ext.omp_clauses = NULL;
618 return MATCH_YES;
622 match
623 gfc_match_omp_atomic (void)
625 if (gfc_match_omp_eos () != MATCH_YES)
626 return MATCH_ERROR;
627 new_st.op = EXEC_OMP_ATOMIC;
628 new_st.ext.omp_clauses = NULL;
629 return MATCH_YES;
633 match
634 gfc_match_omp_barrier (void)
636 if (gfc_match_omp_eos () != MATCH_YES)
637 return MATCH_ERROR;
638 new_st.op = EXEC_OMP_BARRIER;
639 new_st.ext.omp_clauses = NULL;
640 return MATCH_YES;
644 match
645 gfc_match_omp_end_nowait (void)
647 bool nowait = false;
648 if (gfc_match ("% nowait") == MATCH_YES)
649 nowait = true;
650 if (gfc_match_omp_eos () != MATCH_YES)
651 return MATCH_ERROR;
652 new_st.op = EXEC_OMP_END_NOWAIT;
653 new_st.ext.omp_bool = nowait;
654 return MATCH_YES;
658 match
659 gfc_match_omp_end_single (void)
661 gfc_omp_clauses *c;
662 if (gfc_match ("% nowait") == MATCH_YES)
664 new_st.op = EXEC_OMP_END_NOWAIT;
665 new_st.ext.omp_bool = true;
666 return MATCH_YES;
668 if (gfc_match_omp_clauses (&c, OMP_CLAUSE_COPYPRIVATE) != MATCH_YES)
669 return MATCH_ERROR;
670 new_st.op = EXEC_OMP_END_SINGLE;
671 new_st.ext.omp_clauses = c;
672 return MATCH_YES;
676 /* OpenMP directive resolving routines. */
678 static void
679 resolve_omp_clauses (gfc_code *code)
681 gfc_omp_clauses *omp_clauses = code->ext.omp_clauses;
682 gfc_namelist *n;
683 int list;
684 static const char *clause_names[]
685 = { "PRIVATE", "FIRSTPRIVATE", "LASTPRIVATE", "COPYPRIVATE", "SHARED",
686 "COPYIN", "REDUCTION" };
688 if (omp_clauses == NULL)
689 return;
691 if (omp_clauses->if_expr)
693 gfc_expr *expr = omp_clauses->if_expr;
694 if (gfc_resolve_expr (expr) == FAILURE
695 || expr->ts.type != BT_LOGICAL || expr->rank != 0)
696 gfc_error ("IF clause at %L requires a scalar LOGICAL expression",
697 &expr->where);
699 if (omp_clauses->num_threads)
701 gfc_expr *expr = omp_clauses->num_threads;
702 if (gfc_resolve_expr (expr) == FAILURE
703 || expr->ts.type != BT_INTEGER || expr->rank != 0)
704 gfc_error ("NUM_THREADS clause at %L requires a scalar "
705 "INTEGER expression", &expr->where);
707 if (omp_clauses->chunk_size)
709 gfc_expr *expr = omp_clauses->chunk_size;
710 if (gfc_resolve_expr (expr) == FAILURE
711 || expr->ts.type != BT_INTEGER || expr->rank != 0)
712 gfc_error ("SCHEDULE clause's chunk_size at %L requires "
713 "a scalar INTEGER expression", &expr->where);
716 /* Check that no symbol appears on multiple clauses, except that
717 a symbol can appear on both firstprivate and lastprivate. */
718 for (list = 0; list < OMP_LIST_NUM; list++)
719 for (n = omp_clauses->lists[list]; n; n = n->next)
720 n->sym->mark = 0;
722 for (list = 0; list < OMP_LIST_NUM; list++)
723 if (list != OMP_LIST_FIRSTPRIVATE && list != OMP_LIST_LASTPRIVATE)
724 for (n = omp_clauses->lists[list]; n; n = n->next)
725 if (n->sym->mark)
726 gfc_error ("Symbol '%s' present on multiple clauses at %L",
727 n->sym->name, &code->loc);
728 else
729 n->sym->mark = 1;
731 gcc_assert (OMP_LIST_LASTPRIVATE == OMP_LIST_FIRSTPRIVATE + 1);
732 for (list = OMP_LIST_FIRSTPRIVATE; list <= OMP_LIST_LASTPRIVATE; list++)
733 for (n = omp_clauses->lists[list]; n; n = n->next)
734 if (n->sym->mark)
736 gfc_error ("Symbol '%s' present on multiple clauses at %L",
737 n->sym->name, &code->loc);
738 n->sym->mark = 0;
741 for (n = omp_clauses->lists[OMP_LIST_FIRSTPRIVATE]; 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 (n = omp_clauses->lists[OMP_LIST_LASTPRIVATE]; n; n = n->next)
749 n->sym->mark = 0;
751 for (n = omp_clauses->lists[OMP_LIST_LASTPRIVATE]; n; n = n->next)
752 if (n->sym->mark)
753 gfc_error ("Symbol '%s' present on multiple clauses at %L",
754 n->sym->name, &code->loc);
755 else
756 n->sym->mark = 1;
758 for (list = 0; list < OMP_LIST_NUM; list++)
759 if ((n = omp_clauses->lists[list]) != NULL)
761 const char *name;
763 if (list < OMP_LIST_REDUCTION_FIRST)
764 name = clause_names[list];
765 else if (list <= OMP_LIST_REDUCTION_LAST)
766 name = clause_names[OMP_LIST_REDUCTION_FIRST];
767 else
768 gcc_unreachable ();
770 switch (list)
772 case OMP_LIST_COPYIN:
773 for (; n != NULL; n = n->next)
775 if (!n->sym->attr.threadprivate)
776 gfc_error ("Non-THREADPRIVATE object '%s' in COPYIN clause"
777 " at %L", n->sym->name, &code->loc);
778 if (n->sym->attr.allocatable)
779 gfc_error ("COPYIN clause object '%s' is ALLOCATABLE at %L",
780 n->sym->name, &code->loc);
781 if (n->sym->ts.type == BT_DERIVED && n->sym->ts.derived->attr.alloc_comp)
782 gfc_error ("COPYIN clause object '%s' at %L has ALLOCATABLE components",
783 n->sym->name, &code->loc);
785 break;
786 case OMP_LIST_COPYPRIVATE:
787 for (; n != NULL; n = n->next)
789 if (n->sym->as && n->sym->as->type == AS_ASSUMED_SIZE)
790 gfc_error ("Assumed size array '%s' in COPYPRIVATE clause "
791 "at %L", n->sym->name, &code->loc);
792 if (n->sym->attr.allocatable)
793 gfc_error ("COPYPRIVATE clause object '%s' is ALLOCATABLE "
794 "at %L", n->sym->name, &code->loc);
795 if (n->sym->ts.type == BT_DERIVED && n->sym->ts.derived->attr.alloc_comp)
796 gfc_error ("COPYPRIVATE clause object '%s' at %L has ALLOCATABLE components",
797 n->sym->name, &code->loc);
799 break;
800 case OMP_LIST_SHARED:
801 for (; n != NULL; n = n->next)
803 if (n->sym->attr.threadprivate)
804 gfc_error ("THREADPRIVATE object '%s' in SHARED clause at "
805 "%L", n->sym->name, &code->loc);
806 if (n->sym->attr.cray_pointee)
807 gfc_error ("Cray pointee '%s' in SHARED clause at %L",
808 n->sym->name, &code->loc);
810 break;
811 default:
812 for (; n != NULL; n = n->next)
814 if (n->sym->attr.threadprivate)
815 gfc_error ("THREADPRIVATE object '%s' in %s clause at %L",
816 n->sym->name, name, &code->loc);
817 if (n->sym->attr.cray_pointee)
818 gfc_error ("Cray pointee '%s' in %s clause at %L",
819 n->sym->name, name, &code->loc);
820 if (list != OMP_LIST_PRIVATE)
822 if (n->sym->attr.pointer)
823 gfc_error ("POINTER object '%s' in %s clause at %L",
824 n->sym->name, name, &code->loc);
825 if (n->sym->attr.allocatable)
826 gfc_error ("%s clause object '%s' is ALLOCATABLE at %L",
827 name, n->sym->name, &code->loc);
828 /* Variables in REDUCTION-clauses must be of intrinsic type (flagged below). */
829 if ((list < OMP_LIST_REDUCTION_FIRST || list > OMP_LIST_REDUCTION_LAST) &&
830 n->sym->ts.type == BT_DERIVED && n->sym->ts.derived->attr.alloc_comp)
831 gfc_error ("%s clause object '%s' has ALLOCATABLE components at %L",
832 name, n->sym->name, &code->loc);
833 if (n->sym->attr.cray_pointer)
834 gfc_error ("Cray pointer '%s' in %s clause at %L",
835 n->sym->name, name, &code->loc);
837 if (n->sym->as && n->sym->as->type == AS_ASSUMED_SIZE)
838 gfc_error ("Assumed size array '%s' in %s clause at %L",
839 n->sym->name, name, &code->loc);
840 if (n->sym->attr.in_namelist
841 && (list < OMP_LIST_REDUCTION_FIRST
842 || list > OMP_LIST_REDUCTION_LAST))
843 gfc_error ("Variable '%s' in %s clause is used in "
844 "NAMELIST statement at %L",
845 n->sym->name, name, &code->loc);
846 switch (list)
848 case OMP_LIST_PLUS:
849 case OMP_LIST_MULT:
850 case OMP_LIST_SUB:
851 if (!gfc_numeric_ts (&n->sym->ts))
852 gfc_error ("%c REDUCTION variable '%s' at %L must be of numeric type, got %s",
853 list == OMP_LIST_PLUS ? '+'
854 : list == OMP_LIST_MULT ? '*' : '-',
855 n->sym->name, &code->loc,
856 gfc_typename (&n->sym->ts));
857 break;
858 case OMP_LIST_AND:
859 case OMP_LIST_OR:
860 case OMP_LIST_EQV:
861 case OMP_LIST_NEQV:
862 if (n->sym->ts.type != BT_LOGICAL)
863 gfc_error ("%s REDUCTION variable '%s' must be LOGICAL "
864 "at %L",
865 list == OMP_LIST_AND ? ".AND."
866 : list == OMP_LIST_OR ? ".OR."
867 : list == OMP_LIST_EQV ? ".EQV." : ".NEQV.",
868 n->sym->name, &code->loc);
869 break;
870 case OMP_LIST_MAX:
871 case OMP_LIST_MIN:
872 if (n->sym->ts.type != BT_INTEGER
873 && n->sym->ts.type != BT_REAL)
874 gfc_error ("%s REDUCTION variable '%s' must be "
875 "INTEGER or REAL at %L",
876 list == OMP_LIST_MAX ? "MAX" : "MIN",
877 n->sym->name, &code->loc);
878 break;
879 case OMP_LIST_IAND:
880 case OMP_LIST_IOR:
881 case OMP_LIST_IEOR:
882 if (n->sym->ts.type != BT_INTEGER)
883 gfc_error ("%s REDUCTION variable '%s' must be INTEGER "
884 "at %L",
885 list == OMP_LIST_IAND ? "IAND"
886 : list == OMP_LIST_MULT ? "IOR" : "IEOR",
887 n->sym->name, &code->loc);
888 break;
889 /* Workaround for PR middle-end/26316, nothing really needs
890 to be done here for OMP_LIST_PRIVATE. */
891 case OMP_LIST_PRIVATE:
892 gcc_assert (code->op != EXEC_NOP);
893 default:
894 break;
897 break;
903 /* Return true if SYM is ever referenced in EXPR except in the SE node. */
905 static bool
906 expr_references_sym (gfc_expr *e, gfc_symbol *s, gfc_expr *se)
908 gfc_actual_arglist *arg;
909 if (e == NULL || e == se)
910 return false;
911 switch (e->expr_type)
913 case EXPR_CONSTANT:
914 case EXPR_NULL:
915 case EXPR_VARIABLE:
916 case EXPR_STRUCTURE:
917 case EXPR_ARRAY:
918 if (e->symtree != NULL
919 && e->symtree->n.sym == s)
920 return true;
921 return false;
922 case EXPR_SUBSTRING:
923 if (e->ref != NULL
924 && (expr_references_sym (e->ref->u.ss.start, s, se)
925 || expr_references_sym (e->ref->u.ss.end, s, se)))
926 return true;
927 return false;
928 case EXPR_OP:
929 if (expr_references_sym (e->value.op.op2, s, se))
930 return true;
931 return expr_references_sym (e->value.op.op1, s, se);
932 case EXPR_FUNCTION:
933 for (arg = e->value.function.actual; arg; arg = arg->next)
934 if (expr_references_sym (arg->expr, s, se))
935 return true;
936 return false;
937 default:
938 gcc_unreachable ();
943 /* If EXPR is a conversion function that widens the type
944 if WIDENING is true or narrows the type if WIDENING is false,
945 return the inner expression, otherwise return NULL. */
947 static gfc_expr *
948 is_conversion (gfc_expr *expr, bool widening)
950 gfc_typespec *ts1, *ts2;
952 if (expr->expr_type != EXPR_FUNCTION
953 || expr->value.function.isym == NULL
954 || expr->value.function.esym != NULL
955 || expr->value.function.isym->id != GFC_ISYM_CONVERSION)
956 return NULL;
958 if (widening)
960 ts1 = &expr->ts;
961 ts2 = &expr->value.function.actual->expr->ts;
963 else
965 ts1 = &expr->value.function.actual->expr->ts;
966 ts2 = &expr->ts;
969 if (ts1->type > ts2->type
970 || (ts1->type == ts2->type && ts1->kind > ts2->kind))
971 return expr->value.function.actual->expr;
973 return NULL;
977 static void
978 resolve_omp_atomic (gfc_code *code)
980 gfc_symbol *var;
981 gfc_expr *expr2;
983 code = code->block->next;
984 gcc_assert (code->op == EXEC_ASSIGN);
985 gcc_assert (code->next == NULL);
987 if (code->expr->expr_type != EXPR_VARIABLE
988 || code->expr->symtree == NULL
989 || code->expr->rank != 0
990 || (code->expr->ts.type != BT_INTEGER
991 && code->expr->ts.type != BT_REAL
992 && code->expr->ts.type != BT_COMPLEX
993 && code->expr->ts.type != BT_LOGICAL))
995 gfc_error ("!$OMP ATOMIC statement must set a scalar variable of "
996 "intrinsic type at %L", &code->loc);
997 return;
1000 var = code->expr->symtree->n.sym;
1001 expr2 = is_conversion (code->expr2, false);
1002 if (expr2 == NULL)
1003 expr2 = code->expr2;
1005 if (expr2->expr_type == EXPR_OP)
1007 gfc_expr *v = NULL, *e, *c;
1008 gfc_intrinsic_op op = expr2->value.op.operator;
1009 gfc_intrinsic_op alt_op = INTRINSIC_NONE;
1011 switch (op)
1013 case INTRINSIC_PLUS:
1014 alt_op = INTRINSIC_MINUS;
1015 break;
1016 case INTRINSIC_TIMES:
1017 alt_op = INTRINSIC_DIVIDE;
1018 break;
1019 case INTRINSIC_MINUS:
1020 alt_op = INTRINSIC_PLUS;
1021 break;
1022 case INTRINSIC_DIVIDE:
1023 alt_op = INTRINSIC_TIMES;
1024 break;
1025 case INTRINSIC_AND:
1026 case INTRINSIC_OR:
1027 break;
1028 case INTRINSIC_EQV:
1029 alt_op = INTRINSIC_NEQV;
1030 break;
1031 case INTRINSIC_NEQV:
1032 alt_op = INTRINSIC_EQV;
1033 break;
1034 default:
1035 gfc_error ("!$OMP ATOMIC assignment operator must be "
1036 "+, *, -, /, .AND., .OR., .EQV. or .NEQV. at %L",
1037 &expr2->where);
1038 return;
1041 /* Check for var = var op expr resp. var = expr op var where
1042 expr doesn't reference var and var op expr is mathematically
1043 equivalent to var op (expr) resp. expr op var equivalent to
1044 (expr) op var. We rely here on the fact that the matcher
1045 for x op1 y op2 z where op1 and op2 have equal precedence
1046 returns (x op1 y) op2 z. */
1047 e = expr2->value.op.op2;
1048 if (e->expr_type == EXPR_VARIABLE
1049 && e->symtree != NULL
1050 && e->symtree->n.sym == var)
1051 v = e;
1052 else if ((c = is_conversion (e, true)) != NULL
1053 && c->expr_type == EXPR_VARIABLE
1054 && c->symtree != NULL
1055 && c->symtree->n.sym == var)
1056 v = c;
1057 else
1059 gfc_expr **p = NULL, **q;
1060 for (q = &expr2->value.op.op1; (e = *q) != NULL; )
1061 if (e->expr_type == EXPR_VARIABLE
1062 && e->symtree != NULL
1063 && e->symtree->n.sym == var)
1065 v = e;
1066 break;
1068 else if ((c = is_conversion (e, true)) != NULL)
1069 q = &e->value.function.actual->expr;
1070 else if (e->expr_type != EXPR_OP
1071 || (e->value.op.operator != op
1072 && e->value.op.operator != alt_op)
1073 || e->rank != 0)
1074 break;
1075 else
1077 p = q;
1078 q = &e->value.op.op1;
1081 if (v == NULL)
1083 gfc_error ("!$OMP ATOMIC assignment must be var = var op expr "
1084 "or var = expr op var at %L", &expr2->where);
1085 return;
1088 if (p != NULL)
1090 e = *p;
1091 switch (e->value.op.operator)
1093 case INTRINSIC_MINUS:
1094 case INTRINSIC_DIVIDE:
1095 case INTRINSIC_EQV:
1096 case INTRINSIC_NEQV:
1097 gfc_error ("!$OMP ATOMIC var = var op expr not "
1098 "mathematically equivalent to var = var op "
1099 "(expr) at %L", &expr2->where);
1100 break;
1101 default:
1102 break;
1105 /* Canonicalize into var = var op (expr). */
1106 *p = e->value.op.op2;
1107 e->value.op.op2 = expr2;
1108 e->ts = expr2->ts;
1109 if (code->expr2 == expr2)
1110 code->expr2 = expr2 = e;
1111 else
1112 code->expr2->value.function.actual->expr = expr2 = e;
1114 if (!gfc_compare_types (&expr2->value.op.op1->ts, &expr2->ts))
1116 for (p = &expr2->value.op.op1; *p != v;
1117 p = &(*p)->value.function.actual->expr)
1119 *p = NULL;
1120 gfc_free_expr (expr2->value.op.op1);
1121 expr2->value.op.op1 = v;
1122 gfc_convert_type (v, &expr2->ts, 2);
1127 if (e->rank != 0 || expr_references_sym (code->expr2, var, v))
1129 gfc_error ("expr in !$OMP ATOMIC assignment var = var op expr "
1130 "must be scalar and cannot reference var at %L",
1131 &expr2->where);
1132 return;
1135 else if (expr2->expr_type == EXPR_FUNCTION
1136 && expr2->value.function.isym != NULL
1137 && expr2->value.function.esym == NULL
1138 && expr2->value.function.actual != NULL
1139 && expr2->value.function.actual->next != NULL)
1141 gfc_actual_arglist *arg, *var_arg;
1143 switch (expr2->value.function.isym->id)
1145 case GFC_ISYM_MIN:
1146 case GFC_ISYM_MAX:
1147 break;
1148 case GFC_ISYM_IAND:
1149 case GFC_ISYM_IOR:
1150 case GFC_ISYM_IEOR:
1151 if (expr2->value.function.actual->next->next != NULL)
1153 gfc_error ("!$OMP ATOMIC assignment intrinsic IAND, IOR "
1154 "or IEOR must have two arguments at %L",
1155 &expr2->where);
1156 return;
1158 break;
1159 default:
1160 gfc_error ("!$OMP ATOMIC assignment intrinsic must be "
1161 "MIN, MAX, IAND, IOR or IEOR at %L",
1162 &expr2->where);
1163 return;
1166 var_arg = NULL;
1167 for (arg = expr2->value.function.actual; arg; arg = arg->next)
1169 if ((arg == expr2->value.function.actual
1170 || (var_arg == NULL && arg->next == NULL))
1171 && arg->expr->expr_type == EXPR_VARIABLE
1172 && arg->expr->symtree != NULL
1173 && arg->expr->symtree->n.sym == var)
1174 var_arg = arg;
1175 else if (expr_references_sym (arg->expr, var, NULL))
1176 gfc_error ("!$OMP ATOMIC intrinsic arguments except one must not "
1177 "reference '%s' at %L", var->name, &arg->expr->where);
1178 if (arg->expr->rank != 0)
1179 gfc_error ("!$OMP ATOMIC intrinsic arguments must be scalar "
1180 "at %L", &arg->expr->where);
1183 if (var_arg == NULL)
1185 gfc_error ("First or last !$OMP ATOMIC intrinsic argument must "
1186 "be '%s' at %L", var->name, &expr2->where);
1187 return;
1190 if (var_arg != expr2->value.function.actual)
1192 /* Canonicalize, so that var comes first. */
1193 gcc_assert (var_arg->next == NULL);
1194 for (arg = expr2->value.function.actual;
1195 arg->next != var_arg; arg = arg->next)
1197 var_arg->next = expr2->value.function.actual;
1198 expr2->value.function.actual = var_arg;
1199 arg->next = NULL;
1202 else
1203 gfc_error ("!$OMP ATOMIC assignment must have an operator or intrinsic "
1204 "on right hand side at %L", &expr2->where);
1208 struct omp_context
1210 gfc_code *code;
1211 struct pointer_set_t *sharing_clauses;
1212 struct pointer_set_t *private_iterators;
1213 struct omp_context *previous;
1214 } *omp_current_ctx;
1215 gfc_code *omp_current_do_code;
1218 void
1219 gfc_resolve_omp_do_blocks (gfc_code *code, gfc_namespace *ns)
1221 if (code->block->next && code->block->next->op == EXEC_DO)
1222 omp_current_do_code = code->block->next;
1223 gfc_resolve_blocks (code->block, ns);
1227 void
1228 gfc_resolve_omp_parallel_blocks (gfc_code *code, gfc_namespace *ns)
1230 struct omp_context ctx;
1231 gfc_omp_clauses *omp_clauses = code->ext.omp_clauses;
1232 gfc_namelist *n;
1233 int list;
1235 ctx.code = code;
1236 ctx.sharing_clauses = pointer_set_create ();
1237 ctx.private_iterators = pointer_set_create ();
1238 ctx.previous = omp_current_ctx;
1239 omp_current_ctx = &ctx;
1241 for (list = 0; list < OMP_LIST_NUM; list++)
1242 for (n = omp_clauses->lists[list]; n; n = n->next)
1243 pointer_set_insert (ctx.sharing_clauses, n->sym);
1245 if (code->op == EXEC_OMP_PARALLEL_DO)
1246 gfc_resolve_omp_do_blocks (code, ns);
1247 else
1248 gfc_resolve_blocks (code->block, ns);
1250 omp_current_ctx = ctx.previous;
1251 pointer_set_destroy (ctx.sharing_clauses);
1252 pointer_set_destroy (ctx.private_iterators);
1256 /* Note a DO iterator variable. This is special in !$omp parallel
1257 construct, where they are predetermined private. */
1259 void
1260 gfc_resolve_do_iterator (gfc_code *code, gfc_symbol *sym)
1262 struct omp_context *ctx;
1264 if (sym->attr.threadprivate)
1265 return;
1267 /* !$omp do and !$omp parallel do iteration variable is predetermined
1268 private just in the !$omp do resp. !$omp parallel do construct,
1269 with no implications for the outer parallel constructs. */
1270 if (code == omp_current_do_code)
1271 return;
1273 for (ctx = omp_current_ctx; ctx; ctx = ctx->previous)
1275 if (pointer_set_contains (ctx->sharing_clauses, sym))
1276 continue;
1278 if (! pointer_set_insert (ctx->private_iterators, sym))
1280 gfc_omp_clauses *omp_clauses = ctx->code->ext.omp_clauses;
1281 gfc_namelist *p;
1283 p = gfc_get_namelist ();
1284 p->sym = sym;
1285 p->next = omp_clauses->lists[OMP_LIST_PRIVATE];
1286 omp_clauses->lists[OMP_LIST_PRIVATE] = p;
1292 static void
1293 resolve_omp_do (gfc_code *code)
1295 gfc_code *do_code;
1296 int list;
1297 gfc_namelist *n;
1298 gfc_symbol *dovar;
1300 if (code->ext.omp_clauses)
1301 resolve_omp_clauses (code);
1303 do_code = code->block->next;
1304 if (do_code->op == EXEC_DO_WHILE)
1305 gfc_error ("!$OMP DO cannot be a DO WHILE or DO without loop control "
1306 "at %L", &do_code->loc);
1307 else
1309 gcc_assert (do_code->op == EXEC_DO);
1310 if (do_code->ext.iterator->var->ts.type != BT_INTEGER)
1311 gfc_error ("!$OMP DO iteration variable must be of type integer at %L",
1312 &do_code->loc);
1313 dovar = do_code->ext.iterator->var->symtree->n.sym;
1314 if (dovar->attr.threadprivate)
1315 gfc_error ("!$OMP DO iteration variable must not be THREADPRIVATE "
1316 "at %L", &do_code->loc);
1317 if (code->ext.omp_clauses)
1318 for (list = 0; list < OMP_LIST_NUM; list++)
1319 if (list != OMP_LIST_PRIVATE && list != OMP_LIST_LASTPRIVATE)
1320 for (n = code->ext.omp_clauses->lists[list]; n; n = n->next)
1321 if (dovar == n->sym)
1323 gfc_error ("!$OMP DO iteration variable present on clause "
1324 "other than PRIVATE or LASTPRIVATE at %L",
1325 &do_code->loc);
1326 break;
1332 /* Resolve OpenMP directive clauses and check various requirements
1333 of each directive. */
1335 void
1336 gfc_resolve_omp_directive (gfc_code *code, gfc_namespace *ns ATTRIBUTE_UNUSED)
1338 switch (code->op)
1340 case EXEC_OMP_DO:
1341 case EXEC_OMP_PARALLEL_DO:
1342 resolve_omp_do (code);
1343 break;
1344 case EXEC_OMP_WORKSHARE:
1345 case EXEC_OMP_PARALLEL_WORKSHARE:
1346 case EXEC_OMP_PARALLEL:
1347 case EXEC_OMP_PARALLEL_SECTIONS:
1348 case EXEC_OMP_SECTIONS:
1349 case EXEC_OMP_SINGLE:
1350 if (code->ext.omp_clauses)
1351 resolve_omp_clauses (code);
1352 break;
1353 case EXEC_OMP_ATOMIC:
1354 resolve_omp_atomic (code);
1355 break;
1356 default:
1357 break;