1 /* OpenMP directive matching and resolving.
2 Copyright (C) 2005, 2006, 2007, 2008, 2010
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
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
28 #include "pointer-set.h"
30 /* Match an end of OpenMP directive. End of OpenMP directive is optional
31 whitespace, followed by '\n' or comment '!'. */
34 gfc_match_omp_eos (void)
39 old_loc
= gfc_current_locus
;
40 gfc_gobble_whitespace ();
42 c
= gfc_next_ascii_char ();
47 c
= gfc_next_ascii_char ();
55 gfc_current_locus
= old_loc
;
59 /* Free an omp_clauses structure. */
62 gfc_free_omp_clauses (gfc_omp_clauses
*c
)
68 gfc_free_expr (c
->if_expr
);
69 gfc_free_expr (c
->num_threads
);
70 gfc_free_expr (c
->chunk_size
);
71 for (i
= 0; i
< OMP_LIST_NUM
; i
++)
72 gfc_free_namelist (c
->lists
[i
]);
76 /* Match a variable/common block list and construct a namelist from it. */
79 gfc_match_omp_variable_list (const char *str
, gfc_namelist
**list
,
82 gfc_namelist
*head
, *tail
, *p
;
84 char n
[GFC_MAX_SYMBOL_LEN
+1];
91 old_loc
= gfc_current_locus
;
99 m
= gfc_match_symbol (&sym
, 1);
103 gfc_set_sym_referenced (sym
);
104 p
= gfc_get_namelist ();
123 m
= gfc_match (" / %n /", n
);
124 if (m
== MATCH_ERROR
)
129 st
= gfc_find_symtree (gfc_current_ns
->common_root
, n
);
132 gfc_error ("COMMON block /%s/ not found at %C", n
);
135 for (sym
= st
->n
.common
->head
; sym
; sym
= sym
->common_next
)
137 gfc_set_sym_referenced (sym
);
138 p
= gfc_get_namelist ();
150 if (gfc_match_char (')') == MATCH_YES
)
152 if (gfc_match_char (',') != MATCH_YES
)
157 list
= &(*list
)->next
;
163 gfc_error ("Syntax error in OpenMP variable list at %C");
166 gfc_free_namelist (head
);
167 gfc_current_locus
= old_loc
;
171 #define OMP_CLAUSE_PRIVATE (1 << 0)
172 #define OMP_CLAUSE_FIRSTPRIVATE (1 << 1)
173 #define OMP_CLAUSE_LASTPRIVATE (1 << 2)
174 #define OMP_CLAUSE_COPYPRIVATE (1 << 3)
175 #define OMP_CLAUSE_SHARED (1 << 4)
176 #define OMP_CLAUSE_COPYIN (1 << 5)
177 #define OMP_CLAUSE_REDUCTION (1 << 6)
178 #define OMP_CLAUSE_IF (1 << 7)
179 #define OMP_CLAUSE_NUM_THREADS (1 << 8)
180 #define OMP_CLAUSE_SCHEDULE (1 << 9)
181 #define OMP_CLAUSE_DEFAULT (1 << 10)
182 #define OMP_CLAUSE_ORDERED (1 << 11)
183 #define OMP_CLAUSE_COLLAPSE (1 << 12)
184 #define OMP_CLAUSE_UNTIED (1 << 13)
186 /* Match OpenMP directive clauses. MASK is a bitmask of
187 clauses that are allowed for a particular directive. */
190 gfc_match_omp_clauses (gfc_omp_clauses
**cp
, int mask
)
192 gfc_omp_clauses
*c
= gfc_get_omp_clauses ();
194 bool needs_space
= true, first
= true;
199 if ((first
|| gfc_match_char (',') != MATCH_YES
)
200 && (needs_space
&& gfc_match_space () != MATCH_YES
))
204 gfc_gobble_whitespace ();
205 if ((mask
& OMP_CLAUSE_IF
) && c
->if_expr
== NULL
206 && gfc_match ("if ( %e )", &c
->if_expr
) == MATCH_YES
)
208 if ((mask
& OMP_CLAUSE_NUM_THREADS
) && c
->num_threads
== NULL
209 && gfc_match ("num_threads ( %e )", &c
->num_threads
) == MATCH_YES
)
211 if ((mask
& OMP_CLAUSE_PRIVATE
)
212 && gfc_match_omp_variable_list ("private (",
213 &c
->lists
[OMP_LIST_PRIVATE
], true)
216 if ((mask
& OMP_CLAUSE_FIRSTPRIVATE
)
217 && gfc_match_omp_variable_list ("firstprivate (",
218 &c
->lists
[OMP_LIST_FIRSTPRIVATE
],
222 if ((mask
& OMP_CLAUSE_LASTPRIVATE
)
223 && gfc_match_omp_variable_list ("lastprivate (",
224 &c
->lists
[OMP_LIST_LASTPRIVATE
],
228 if ((mask
& OMP_CLAUSE_COPYPRIVATE
)
229 && gfc_match_omp_variable_list ("copyprivate (",
230 &c
->lists
[OMP_LIST_COPYPRIVATE
],
234 if ((mask
& OMP_CLAUSE_SHARED
)
235 && gfc_match_omp_variable_list ("shared (",
236 &c
->lists
[OMP_LIST_SHARED
], true)
239 if ((mask
& OMP_CLAUSE_COPYIN
)
240 && gfc_match_omp_variable_list ("copyin (",
241 &c
->lists
[OMP_LIST_COPYIN
], true)
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
)
267 const char *n
= buffer
;
269 gfc_find_symbol (buffer
, NULL
, 1, &sym
);
272 if (sym
->attr
.intrinsic
)
274 else if ((sym
->attr
.flavor
!= FL_UNKNOWN
275 && sym
->attr
.flavor
!= FL_PROCEDURE
)
276 || sym
->attr
.external
281 || sym
->attr
.subroutine
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 "
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
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
);
321 if (reduction
!= OMP_LIST_NUM
322 && gfc_match_omp_variable_list (" :", &c
->lists
[reduction
],
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 else if (gfc_match ("default ( firstprivate )") == MATCH_YES
)
339 c
->default_sharing
= OMP_DEFAULT_FIRSTPRIVATE
;
340 if (c
->default_sharing
!= OMP_DEFAULT_UNKNOWN
)
343 old_loc
= gfc_current_locus
;
344 if ((mask
& OMP_CLAUSE_SCHEDULE
)
345 && c
->sched_kind
== OMP_SCHED_NONE
346 && gfc_match ("schedule ( ") == MATCH_YES
)
348 if (gfc_match ("static") == MATCH_YES
)
349 c
->sched_kind
= OMP_SCHED_STATIC
;
350 else if (gfc_match ("dynamic") == MATCH_YES
)
351 c
->sched_kind
= OMP_SCHED_DYNAMIC
;
352 else if (gfc_match ("guided") == MATCH_YES
)
353 c
->sched_kind
= OMP_SCHED_GUIDED
;
354 else if (gfc_match ("runtime") == MATCH_YES
)
355 c
->sched_kind
= OMP_SCHED_RUNTIME
;
356 else if (gfc_match ("auto") == MATCH_YES
)
357 c
->sched_kind
= OMP_SCHED_AUTO
;
358 if (c
->sched_kind
!= OMP_SCHED_NONE
)
361 if (c
->sched_kind
!= OMP_SCHED_RUNTIME
362 && c
->sched_kind
!= OMP_SCHED_AUTO
)
363 m
= gfc_match (" , %e )", &c
->chunk_size
);
365 m
= gfc_match_char (')');
367 c
->sched_kind
= OMP_SCHED_NONE
;
369 if (c
->sched_kind
!= OMP_SCHED_NONE
)
372 gfc_current_locus
= old_loc
;
374 if ((mask
& OMP_CLAUSE_ORDERED
) && !c
->ordered
375 && gfc_match ("ordered") == MATCH_YES
)
377 c
->ordered
= needs_space
= true;
380 if ((mask
& OMP_CLAUSE_UNTIED
) && !c
->untied
381 && gfc_match ("untied") == MATCH_YES
)
383 c
->untied
= needs_space
= true;
386 if ((mask
& OMP_CLAUSE_COLLAPSE
) && !c
->collapse
)
388 gfc_expr
*cexpr
= NULL
;
389 match m
= gfc_match ("collapse ( %e )", &cexpr
);
394 const char *p
= gfc_extract_int (cexpr
, &collapse
);
400 else if (collapse
<= 0)
402 gfc_error_now ("COLLAPSE clause argument not"
403 " constant positive integer at %C");
406 c
->collapse
= collapse
;
407 gfc_free_expr (cexpr
);
415 if (gfc_match_omp_eos () != MATCH_YES
)
417 gfc_free_omp_clauses (c
);
425 #define OMP_PARALLEL_CLAUSES \
426 (OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_SHARED \
427 | OMP_CLAUSE_COPYIN | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_IF \
428 | OMP_CLAUSE_NUM_THREADS | OMP_CLAUSE_DEFAULT)
429 #define OMP_DO_CLAUSES \
430 (OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE \
431 | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION \
432 | OMP_CLAUSE_SCHEDULE | OMP_CLAUSE_ORDERED | OMP_CLAUSE_COLLAPSE)
433 #define OMP_SECTIONS_CLAUSES \
434 (OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE \
435 | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION)
436 #define OMP_TASK_CLAUSES \
437 (OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_SHARED \
438 | OMP_CLAUSE_IF | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_UNTIED)
441 gfc_match_omp_parallel (void)
444 if (gfc_match_omp_clauses (&c
, OMP_PARALLEL_CLAUSES
) != MATCH_YES
)
446 new_st
.op
= EXEC_OMP_PARALLEL
;
447 new_st
.ext
.omp_clauses
= c
;
453 gfc_match_omp_task (void)
456 if (gfc_match_omp_clauses (&c
, OMP_TASK_CLAUSES
) != MATCH_YES
)
458 new_st
.op
= EXEC_OMP_TASK
;
459 new_st
.ext
.omp_clauses
= c
;
465 gfc_match_omp_taskwait (void)
467 if (gfc_match_omp_eos () != MATCH_YES
)
469 gfc_error ("Unexpected junk after TASKWAIT clause at %C");
472 new_st
.op
= EXEC_OMP_TASKWAIT
;
473 new_st
.ext
.omp_clauses
= NULL
;
479 gfc_match_omp_critical (void)
481 char n
[GFC_MAX_SYMBOL_LEN
+1];
483 if (gfc_match (" ( %n )", n
) != MATCH_YES
)
485 if (gfc_match_omp_eos () != MATCH_YES
)
487 gfc_error ("Unexpected junk after $OMP CRITICAL statement at %C");
490 new_st
.op
= EXEC_OMP_CRITICAL
;
491 new_st
.ext
.omp_name
= n
[0] ? xstrdup (n
) : NULL
;
497 gfc_match_omp_do (void)
500 if (gfc_match_omp_clauses (&c
, OMP_DO_CLAUSES
) != MATCH_YES
)
502 new_st
.op
= EXEC_OMP_DO
;
503 new_st
.ext
.omp_clauses
= c
;
509 gfc_match_omp_flush (void)
511 gfc_namelist
*list
= NULL
;
512 gfc_match_omp_variable_list (" (", &list
, true);
513 if (gfc_match_omp_eos () != MATCH_YES
)
515 gfc_error ("Unexpected junk after $OMP FLUSH statement at %C");
516 gfc_free_namelist (list
);
519 new_st
.op
= EXEC_OMP_FLUSH
;
520 new_st
.ext
.omp_namelist
= list
;
526 gfc_match_omp_threadprivate (void)
529 char n
[GFC_MAX_SYMBOL_LEN
+1];
534 old_loc
= gfc_current_locus
;
536 m
= gfc_match (" (");
542 m
= gfc_match_symbol (&sym
, 0);
546 if (sym
->attr
.in_common
)
547 gfc_error_now ("Threadprivate variable at %C is an element of "
549 else if (gfc_add_threadprivate (&sym
->attr
, sym
->name
,
550 &sym
->declared_at
) == FAILURE
)
559 m
= gfc_match (" / %n /", n
);
560 if (m
== MATCH_ERROR
)
562 if (m
== MATCH_NO
|| n
[0] == '\0')
565 st
= gfc_find_symtree (gfc_current_ns
->common_root
, n
);
568 gfc_error ("COMMON block /%s/ not found at %C", n
);
571 st
->n
.common
->threadprivate
= 1;
572 for (sym
= st
->n
.common
->head
; sym
; sym
= sym
->common_next
)
573 if (gfc_add_threadprivate (&sym
->attr
, sym
->name
,
574 &sym
->declared_at
) == FAILURE
)
578 if (gfc_match_char (')') == MATCH_YES
)
580 if (gfc_match_char (',') != MATCH_YES
)
587 gfc_error ("Syntax error in !$OMP THREADPRIVATE list at %C");
590 gfc_current_locus
= old_loc
;
596 gfc_match_omp_parallel_do (void)
599 if (gfc_match_omp_clauses (&c
, OMP_PARALLEL_CLAUSES
| OMP_DO_CLAUSES
)
602 new_st
.op
= EXEC_OMP_PARALLEL_DO
;
603 new_st
.ext
.omp_clauses
= c
;
609 gfc_match_omp_parallel_sections (void)
612 if (gfc_match_omp_clauses (&c
, OMP_PARALLEL_CLAUSES
| OMP_SECTIONS_CLAUSES
)
615 new_st
.op
= EXEC_OMP_PARALLEL_SECTIONS
;
616 new_st
.ext
.omp_clauses
= c
;
622 gfc_match_omp_parallel_workshare (void)
625 if (gfc_match_omp_clauses (&c
, OMP_PARALLEL_CLAUSES
) != MATCH_YES
)
627 new_st
.op
= EXEC_OMP_PARALLEL_WORKSHARE
;
628 new_st
.ext
.omp_clauses
= c
;
634 gfc_match_omp_sections (void)
637 if (gfc_match_omp_clauses (&c
, OMP_SECTIONS_CLAUSES
) != MATCH_YES
)
639 new_st
.op
= EXEC_OMP_SECTIONS
;
640 new_st
.ext
.omp_clauses
= c
;
646 gfc_match_omp_single (void)
649 if (gfc_match_omp_clauses (&c
, OMP_CLAUSE_PRIVATE
| OMP_CLAUSE_FIRSTPRIVATE
)
652 new_st
.op
= EXEC_OMP_SINGLE
;
653 new_st
.ext
.omp_clauses
= c
;
659 gfc_match_omp_workshare (void)
661 if (gfc_match_omp_eos () != MATCH_YES
)
663 gfc_error ("Unexpected junk after $OMP WORKSHARE statement at %C");
666 new_st
.op
= EXEC_OMP_WORKSHARE
;
667 new_st
.ext
.omp_clauses
= gfc_get_omp_clauses ();
673 gfc_match_omp_master (void)
675 if (gfc_match_omp_eos () != MATCH_YES
)
677 gfc_error ("Unexpected junk after $OMP MASTER statement at %C");
680 new_st
.op
= EXEC_OMP_MASTER
;
681 new_st
.ext
.omp_clauses
= NULL
;
687 gfc_match_omp_ordered (void)
689 if (gfc_match_omp_eos () != MATCH_YES
)
691 gfc_error ("Unexpected junk after $OMP ORDERED statement at %C");
694 new_st
.op
= EXEC_OMP_ORDERED
;
695 new_st
.ext
.omp_clauses
= NULL
;
701 gfc_match_omp_atomic (void)
703 if (gfc_match_omp_eos () != MATCH_YES
)
705 gfc_error ("Unexpected junk after $OMP ATOMIC statement at %C");
708 new_st
.op
= EXEC_OMP_ATOMIC
;
709 new_st
.ext
.omp_clauses
= NULL
;
715 gfc_match_omp_barrier (void)
717 if (gfc_match_omp_eos () != MATCH_YES
)
719 gfc_error ("Unexpected junk after $OMP BARRIER statement at %C");
722 new_st
.op
= EXEC_OMP_BARRIER
;
723 new_st
.ext
.omp_clauses
= NULL
;
729 gfc_match_omp_end_nowait (void)
732 if (gfc_match ("% nowait") == MATCH_YES
)
734 if (gfc_match_omp_eos () != MATCH_YES
)
736 gfc_error ("Unexpected junk after NOWAIT clause at %C");
739 new_st
.op
= EXEC_OMP_END_NOWAIT
;
740 new_st
.ext
.omp_bool
= nowait
;
746 gfc_match_omp_end_single (void)
749 if (gfc_match ("% nowait") == MATCH_YES
)
751 new_st
.op
= EXEC_OMP_END_NOWAIT
;
752 new_st
.ext
.omp_bool
= true;
755 if (gfc_match_omp_clauses (&c
, OMP_CLAUSE_COPYPRIVATE
) != MATCH_YES
)
757 new_st
.op
= EXEC_OMP_END_SINGLE
;
758 new_st
.ext
.omp_clauses
= c
;
763 /* OpenMP directive resolving routines. */
766 resolve_omp_clauses (gfc_code
*code
)
768 gfc_omp_clauses
*omp_clauses
= code
->ext
.omp_clauses
;
771 static const char *clause_names
[]
772 = { "PRIVATE", "FIRSTPRIVATE", "LASTPRIVATE", "COPYPRIVATE", "SHARED",
773 "COPYIN", "REDUCTION" };
775 if (omp_clauses
== NULL
)
778 if (omp_clauses
->if_expr
)
780 gfc_expr
*expr
= omp_clauses
->if_expr
;
781 if (gfc_resolve_expr (expr
) == FAILURE
782 || expr
->ts
.type
!= BT_LOGICAL
|| expr
->rank
!= 0)
783 gfc_error ("IF clause at %L requires a scalar LOGICAL expression",
786 if (omp_clauses
->num_threads
)
788 gfc_expr
*expr
= omp_clauses
->num_threads
;
789 if (gfc_resolve_expr (expr
) == FAILURE
790 || expr
->ts
.type
!= BT_INTEGER
|| expr
->rank
!= 0)
791 gfc_error ("NUM_THREADS clause at %L requires a scalar "
792 "INTEGER expression", &expr
->where
);
794 if (omp_clauses
->chunk_size
)
796 gfc_expr
*expr
= omp_clauses
->chunk_size
;
797 if (gfc_resolve_expr (expr
) == FAILURE
798 || expr
->ts
.type
!= BT_INTEGER
|| expr
->rank
!= 0)
799 gfc_error ("SCHEDULE clause's chunk_size at %L requires "
800 "a scalar INTEGER expression", &expr
->where
);
803 /* Check that no symbol appears on multiple clauses, except that
804 a symbol can appear on both firstprivate and lastprivate. */
805 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
806 for (n
= omp_clauses
->lists
[list
]; n
; n
= n
->next
)
809 if (n
->sym
->attr
.flavor
== FL_VARIABLE
)
811 if (n
->sym
->attr
.flavor
== FL_PROCEDURE
812 && n
->sym
->result
== n
->sym
813 && n
->sym
->attr
.function
)
815 if (gfc_current_ns
->proc_name
== n
->sym
816 || (gfc_current_ns
->parent
817 && gfc_current_ns
->parent
->proc_name
== n
->sym
))
819 if (gfc_current_ns
->proc_name
->attr
.entry_master
)
821 gfc_entry_list
*el
= gfc_current_ns
->entries
;
822 for (; el
; el
= el
->next
)
823 if (el
->sym
== n
->sym
)
828 if (gfc_current_ns
->parent
829 && gfc_current_ns
->parent
->proc_name
->attr
.entry_master
)
831 gfc_entry_list
*el
= gfc_current_ns
->parent
->entries
;
832 for (; el
; el
= el
->next
)
833 if (el
->sym
== n
->sym
)
838 if (n
->sym
->attr
.proc_pointer
)
841 gfc_error ("Object '%s' is not a variable at %L", n
->sym
->name
,
845 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
846 if (list
!= OMP_LIST_FIRSTPRIVATE
&& list
!= OMP_LIST_LASTPRIVATE
)
847 for (n
= omp_clauses
->lists
[list
]; n
; n
= n
->next
)
850 gfc_error ("Symbol '%s' present on multiple clauses at %L",
851 n
->sym
->name
, &code
->loc
);
856 gcc_assert (OMP_LIST_LASTPRIVATE
== OMP_LIST_FIRSTPRIVATE
+ 1);
857 for (list
= OMP_LIST_FIRSTPRIVATE
; list
<= OMP_LIST_LASTPRIVATE
; list
++)
858 for (n
= omp_clauses
->lists
[list
]; n
; n
= n
->next
)
861 gfc_error ("Symbol '%s' present on multiple clauses at %L",
862 n
->sym
->name
, &code
->loc
);
866 for (n
= omp_clauses
->lists
[OMP_LIST_FIRSTPRIVATE
]; n
; n
= n
->next
)
869 gfc_error ("Symbol '%s' present on multiple clauses at %L",
870 n
->sym
->name
, &code
->loc
);
874 for (n
= omp_clauses
->lists
[OMP_LIST_LASTPRIVATE
]; n
; n
= n
->next
)
877 for (n
= omp_clauses
->lists
[OMP_LIST_LASTPRIVATE
]; n
; n
= n
->next
)
880 gfc_error ("Symbol '%s' present on multiple clauses at %L",
881 n
->sym
->name
, &code
->loc
);
885 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
886 if ((n
= omp_clauses
->lists
[list
]) != NULL
)
890 if (list
< OMP_LIST_REDUCTION_FIRST
)
891 name
= clause_names
[list
];
892 else if (list
<= OMP_LIST_REDUCTION_LAST
)
893 name
= clause_names
[OMP_LIST_REDUCTION_FIRST
];
899 case OMP_LIST_COPYIN
:
900 for (; n
!= NULL
; n
= n
->next
)
902 if (!n
->sym
->attr
.threadprivate
)
903 gfc_error ("Non-THREADPRIVATE object '%s' in COPYIN clause"
904 " at %L", n
->sym
->name
, &code
->loc
);
905 if (n
->sym
->ts
.type
== BT_DERIVED
&& n
->sym
->ts
.u
.derived
->attr
.alloc_comp
)
906 gfc_error ("COPYIN clause object '%s' at %L has ALLOCATABLE components",
907 n
->sym
->name
, &code
->loc
);
910 case OMP_LIST_COPYPRIVATE
:
911 for (; n
!= NULL
; n
= n
->next
)
913 if (n
->sym
->as
&& n
->sym
->as
->type
== AS_ASSUMED_SIZE
)
914 gfc_error ("Assumed size array '%s' in COPYPRIVATE clause "
915 "at %L", n
->sym
->name
, &code
->loc
);
916 if (n
->sym
->ts
.type
== BT_DERIVED
&& n
->sym
->ts
.u
.derived
->attr
.alloc_comp
)
917 gfc_error ("COPYPRIVATE clause object '%s' at %L has ALLOCATABLE components",
918 n
->sym
->name
, &code
->loc
);
921 case OMP_LIST_SHARED
:
922 for (; n
!= NULL
; n
= n
->next
)
924 if (n
->sym
->attr
.threadprivate
)
925 gfc_error ("THREADPRIVATE object '%s' in SHARED clause at "
926 "%L", n
->sym
->name
, &code
->loc
);
927 if (n
->sym
->attr
.cray_pointee
)
928 gfc_error ("Cray pointee '%s' in SHARED clause at %L",
929 n
->sym
->name
, &code
->loc
);
933 for (; n
!= NULL
; n
= n
->next
)
935 if (n
->sym
->attr
.threadprivate
)
936 gfc_error ("THREADPRIVATE object '%s' in %s clause at %L",
937 n
->sym
->name
, name
, &code
->loc
);
938 if (n
->sym
->attr
.cray_pointee
)
939 gfc_error ("Cray pointee '%s' in %s clause at %L",
940 n
->sym
->name
, name
, &code
->loc
);
941 if (list
!= OMP_LIST_PRIVATE
)
943 if (n
->sym
->attr
.pointer
)
944 gfc_error ("POINTER object '%s' in %s clause at %L",
945 n
->sym
->name
, name
, &code
->loc
);
946 /* Variables in REDUCTION-clauses must be of intrinsic type (flagged below). */
947 if ((list
< OMP_LIST_REDUCTION_FIRST
|| list
> OMP_LIST_REDUCTION_LAST
) &&
948 n
->sym
->ts
.type
== BT_DERIVED
&& n
->sym
->ts
.u
.derived
->attr
.alloc_comp
)
949 gfc_error ("%s clause object '%s' has ALLOCATABLE components at %L",
950 name
, n
->sym
->name
, &code
->loc
);
951 if (n
->sym
->attr
.cray_pointer
)
952 gfc_error ("Cray pointer '%s' in %s clause at %L",
953 n
->sym
->name
, name
, &code
->loc
);
955 if (n
->sym
->as
&& n
->sym
->as
->type
== AS_ASSUMED_SIZE
)
956 gfc_error ("Assumed size array '%s' in %s clause at %L",
957 n
->sym
->name
, name
, &code
->loc
);
958 if (n
->sym
->attr
.in_namelist
959 && (list
< OMP_LIST_REDUCTION_FIRST
960 || list
> OMP_LIST_REDUCTION_LAST
))
961 gfc_error ("Variable '%s' in %s clause is used in "
962 "NAMELIST statement at %L",
963 n
->sym
->name
, name
, &code
->loc
);
969 if (!gfc_numeric_ts (&n
->sym
->ts
))
970 gfc_error ("%c REDUCTION variable '%s' at %L must be of numeric type, got %s",
971 list
== OMP_LIST_PLUS
? '+'
972 : list
== OMP_LIST_MULT
? '*' : '-',
973 n
->sym
->name
, &code
->loc
,
974 gfc_typename (&n
->sym
->ts
));
980 if (n
->sym
->ts
.type
!= BT_LOGICAL
)
981 gfc_error ("%s REDUCTION variable '%s' must be LOGICAL "
983 list
== OMP_LIST_AND
? ".AND."
984 : list
== OMP_LIST_OR
? ".OR."
985 : list
== OMP_LIST_EQV
? ".EQV." : ".NEQV.",
986 n
->sym
->name
, &code
->loc
);
990 if (n
->sym
->ts
.type
!= BT_INTEGER
991 && n
->sym
->ts
.type
!= BT_REAL
)
992 gfc_error ("%s REDUCTION variable '%s' must be "
993 "INTEGER or REAL at %L",
994 list
== OMP_LIST_MAX
? "MAX" : "MIN",
995 n
->sym
->name
, &code
->loc
);
1000 if (n
->sym
->ts
.type
!= BT_INTEGER
)
1001 gfc_error ("%s REDUCTION variable '%s' must be INTEGER "
1003 list
== OMP_LIST_IAND
? "IAND"
1004 : list
== OMP_LIST_MULT
? "IOR" : "IEOR",
1005 n
->sym
->name
, &code
->loc
);
1007 /* Workaround for PR middle-end/26316, nothing really needs
1008 to be done here for OMP_LIST_PRIVATE. */
1009 case OMP_LIST_PRIVATE
:
1010 gcc_assert (code
->op
!= EXEC_NOP
);
1021 /* Return true if SYM is ever referenced in EXPR except in the SE node. */
1024 expr_references_sym (gfc_expr
*e
, gfc_symbol
*s
, gfc_expr
*se
)
1026 gfc_actual_arglist
*arg
;
1027 if (e
== NULL
|| e
== se
)
1029 switch (e
->expr_type
)
1034 case EXPR_STRUCTURE
:
1036 if (e
->symtree
!= NULL
1037 && e
->symtree
->n
.sym
== s
)
1040 case EXPR_SUBSTRING
:
1042 && (expr_references_sym (e
->ref
->u
.ss
.start
, s
, se
)
1043 || expr_references_sym (e
->ref
->u
.ss
.end
, s
, se
)))
1047 if (expr_references_sym (e
->value
.op
.op2
, s
, se
))
1049 return expr_references_sym (e
->value
.op
.op1
, s
, se
);
1051 for (arg
= e
->value
.function
.actual
; arg
; arg
= arg
->next
)
1052 if (expr_references_sym (arg
->expr
, s
, se
))
1061 /* If EXPR is a conversion function that widens the type
1062 if WIDENING is true or narrows the type if WIDENING is false,
1063 return the inner expression, otherwise return NULL. */
1066 is_conversion (gfc_expr
*expr
, bool widening
)
1068 gfc_typespec
*ts1
, *ts2
;
1070 if (expr
->expr_type
!= EXPR_FUNCTION
1071 || expr
->value
.function
.isym
== NULL
1072 || expr
->value
.function
.esym
!= NULL
1073 || expr
->value
.function
.isym
->id
!= GFC_ISYM_CONVERSION
)
1079 ts2
= &expr
->value
.function
.actual
->expr
->ts
;
1083 ts1
= &expr
->value
.function
.actual
->expr
->ts
;
1087 if (ts1
->type
> ts2
->type
1088 || (ts1
->type
== ts2
->type
&& ts1
->kind
> ts2
->kind
))
1089 return expr
->value
.function
.actual
->expr
;
1096 resolve_omp_atomic (gfc_code
*code
)
1101 code
= code
->block
->next
;
1102 gcc_assert (code
->op
== EXEC_ASSIGN
);
1103 gcc_assert (code
->next
== NULL
);
1105 if (code
->expr1
->expr_type
!= EXPR_VARIABLE
1106 || code
->expr1
->symtree
== NULL
1107 || code
->expr1
->rank
!= 0
1108 || (code
->expr1
->ts
.type
!= BT_INTEGER
1109 && code
->expr1
->ts
.type
!= BT_REAL
1110 && code
->expr1
->ts
.type
!= BT_COMPLEX
1111 && code
->expr1
->ts
.type
!= BT_LOGICAL
))
1113 gfc_error ("!$OMP ATOMIC statement must set a scalar variable of "
1114 "intrinsic type at %L", &code
->loc
);
1118 var
= code
->expr1
->symtree
->n
.sym
;
1119 expr2
= is_conversion (code
->expr2
, false);
1121 expr2
= code
->expr2
;
1123 if (expr2
->expr_type
== EXPR_OP
)
1125 gfc_expr
*v
= NULL
, *e
, *c
;
1126 gfc_intrinsic_op op
= expr2
->value
.op
.op
;
1127 gfc_intrinsic_op alt_op
= INTRINSIC_NONE
;
1131 case INTRINSIC_PLUS
:
1132 alt_op
= INTRINSIC_MINUS
;
1134 case INTRINSIC_TIMES
:
1135 alt_op
= INTRINSIC_DIVIDE
;
1137 case INTRINSIC_MINUS
:
1138 alt_op
= INTRINSIC_PLUS
;
1140 case INTRINSIC_DIVIDE
:
1141 alt_op
= INTRINSIC_TIMES
;
1147 alt_op
= INTRINSIC_NEQV
;
1149 case INTRINSIC_NEQV
:
1150 alt_op
= INTRINSIC_EQV
;
1153 gfc_error ("!$OMP ATOMIC assignment operator must be "
1154 "+, *, -, /, .AND., .OR., .EQV. or .NEQV. at %L",
1159 /* Check for var = var op expr resp. var = expr op var where
1160 expr doesn't reference var and var op expr is mathematically
1161 equivalent to var op (expr) resp. expr op var equivalent to
1162 (expr) op var. We rely here on the fact that the matcher
1163 for x op1 y op2 z where op1 and op2 have equal precedence
1164 returns (x op1 y) op2 z. */
1165 e
= expr2
->value
.op
.op2
;
1166 if (e
->expr_type
== EXPR_VARIABLE
1167 && e
->symtree
!= NULL
1168 && e
->symtree
->n
.sym
== var
)
1170 else if ((c
= is_conversion (e
, true)) != NULL
1171 && c
->expr_type
== EXPR_VARIABLE
1172 && c
->symtree
!= NULL
1173 && c
->symtree
->n
.sym
== var
)
1177 gfc_expr
**p
= NULL
, **q
;
1178 for (q
= &expr2
->value
.op
.op1
; (e
= *q
) != NULL
; )
1179 if (e
->expr_type
== EXPR_VARIABLE
1180 && e
->symtree
!= NULL
1181 && e
->symtree
->n
.sym
== var
)
1186 else if ((c
= is_conversion (e
, true)) != NULL
)
1187 q
= &e
->value
.function
.actual
->expr
;
1188 else if (e
->expr_type
!= EXPR_OP
1189 || (e
->value
.op
.op
!= op
1190 && e
->value
.op
.op
!= alt_op
)
1196 q
= &e
->value
.op
.op1
;
1201 gfc_error ("!$OMP ATOMIC assignment must be var = var op expr "
1202 "or var = expr op var at %L", &expr2
->where
);
1209 switch (e
->value
.op
.op
)
1211 case INTRINSIC_MINUS
:
1212 case INTRINSIC_DIVIDE
:
1214 case INTRINSIC_NEQV
:
1215 gfc_error ("!$OMP ATOMIC var = var op expr not "
1216 "mathematically equivalent to var = var op "
1217 "(expr) at %L", &expr2
->where
);
1223 /* Canonicalize into var = var op (expr). */
1224 *p
= e
->value
.op
.op2
;
1225 e
->value
.op
.op2
= expr2
;
1227 if (code
->expr2
== expr2
)
1228 code
->expr2
= expr2
= e
;
1230 code
->expr2
->value
.function
.actual
->expr
= expr2
= e
;
1232 if (!gfc_compare_types (&expr2
->value
.op
.op1
->ts
, &expr2
->ts
))
1234 for (p
= &expr2
->value
.op
.op1
; *p
!= v
;
1235 p
= &(*p
)->value
.function
.actual
->expr
)
1238 gfc_free_expr (expr2
->value
.op
.op1
);
1239 expr2
->value
.op
.op1
= v
;
1240 gfc_convert_type (v
, &expr2
->ts
, 2);
1245 if (e
->rank
!= 0 || expr_references_sym (code
->expr2
, var
, v
))
1247 gfc_error ("expr in !$OMP ATOMIC assignment var = var op expr "
1248 "must be scalar and cannot reference var at %L",
1253 else if (expr2
->expr_type
== EXPR_FUNCTION
1254 && expr2
->value
.function
.isym
!= NULL
1255 && expr2
->value
.function
.esym
== NULL
1256 && expr2
->value
.function
.actual
!= NULL
1257 && expr2
->value
.function
.actual
->next
!= NULL
)
1259 gfc_actual_arglist
*arg
, *var_arg
;
1261 switch (expr2
->value
.function
.isym
->id
)
1269 if (expr2
->value
.function
.actual
->next
->next
!= NULL
)
1271 gfc_error ("!$OMP ATOMIC assignment intrinsic IAND, IOR "
1272 "or IEOR must have two arguments at %L",
1278 gfc_error ("!$OMP ATOMIC assignment intrinsic must be "
1279 "MIN, MAX, IAND, IOR or IEOR at %L",
1285 for (arg
= expr2
->value
.function
.actual
; arg
; arg
= arg
->next
)
1287 if ((arg
== expr2
->value
.function
.actual
1288 || (var_arg
== NULL
&& arg
->next
== NULL
))
1289 && arg
->expr
->expr_type
== EXPR_VARIABLE
1290 && arg
->expr
->symtree
!= NULL
1291 && arg
->expr
->symtree
->n
.sym
== var
)
1293 else if (expr_references_sym (arg
->expr
, var
, NULL
))
1294 gfc_error ("!$OMP ATOMIC intrinsic arguments except one must not "
1295 "reference '%s' at %L", var
->name
, &arg
->expr
->where
);
1296 if (arg
->expr
->rank
!= 0)
1297 gfc_error ("!$OMP ATOMIC intrinsic arguments must be scalar "
1298 "at %L", &arg
->expr
->where
);
1301 if (var_arg
== NULL
)
1303 gfc_error ("First or last !$OMP ATOMIC intrinsic argument must "
1304 "be '%s' at %L", var
->name
, &expr2
->where
);
1308 if (var_arg
!= expr2
->value
.function
.actual
)
1310 /* Canonicalize, so that var comes first. */
1311 gcc_assert (var_arg
->next
== NULL
);
1312 for (arg
= expr2
->value
.function
.actual
;
1313 arg
->next
!= var_arg
; arg
= arg
->next
)
1315 var_arg
->next
= expr2
->value
.function
.actual
;
1316 expr2
->value
.function
.actual
= var_arg
;
1321 gfc_error ("!$OMP ATOMIC assignment must have an operator or intrinsic "
1322 "on right hand side at %L", &expr2
->where
);
1329 struct pointer_set_t
*sharing_clauses
;
1330 struct pointer_set_t
*private_iterators
;
1331 struct omp_context
*previous
;
1333 static gfc_code
*omp_current_do_code
;
1334 static int omp_current_do_collapse
;
1337 gfc_resolve_omp_do_blocks (gfc_code
*code
, gfc_namespace
*ns
)
1339 if (code
->block
->next
&& code
->block
->next
->op
== EXEC_DO
)
1344 omp_current_do_code
= code
->block
->next
;
1345 omp_current_do_collapse
= code
->ext
.omp_clauses
->collapse
;
1346 for (i
= 1, c
= omp_current_do_code
; i
< omp_current_do_collapse
; i
++)
1349 if (c
->op
!= EXEC_DO
|| c
->next
== NULL
)
1352 if (c
->op
!= EXEC_DO
)
1355 if (i
< omp_current_do_collapse
|| omp_current_do_collapse
<= 0)
1356 omp_current_do_collapse
= 1;
1358 gfc_resolve_blocks (code
->block
, ns
);
1359 omp_current_do_collapse
= 0;
1360 omp_current_do_code
= NULL
;
1365 gfc_resolve_omp_parallel_blocks (gfc_code
*code
, gfc_namespace
*ns
)
1367 struct omp_context ctx
;
1368 gfc_omp_clauses
*omp_clauses
= code
->ext
.omp_clauses
;
1373 ctx
.sharing_clauses
= pointer_set_create ();
1374 ctx
.private_iterators
= pointer_set_create ();
1375 ctx
.previous
= omp_current_ctx
;
1376 omp_current_ctx
= &ctx
;
1378 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
1379 for (n
= omp_clauses
->lists
[list
]; n
; n
= n
->next
)
1380 pointer_set_insert (ctx
.sharing_clauses
, n
->sym
);
1382 if (code
->op
== EXEC_OMP_PARALLEL_DO
)
1383 gfc_resolve_omp_do_blocks (code
, ns
);
1385 gfc_resolve_blocks (code
->block
, ns
);
1387 omp_current_ctx
= ctx
.previous
;
1388 pointer_set_destroy (ctx
.sharing_clauses
);
1389 pointer_set_destroy (ctx
.private_iterators
);
1393 /* Save and clear openmp.c private state. */
1396 gfc_omp_save_and_clear_state (struct gfc_omp_saved_state
*state
)
1398 state
->ptrs
[0] = omp_current_ctx
;
1399 state
->ptrs
[1] = omp_current_do_code
;
1400 state
->ints
[0] = omp_current_do_collapse
;
1401 omp_current_ctx
= NULL
;
1402 omp_current_do_code
= NULL
;
1403 omp_current_do_collapse
= 0;
1407 /* Restore openmp.c private state from the saved state. */
1410 gfc_omp_restore_state (struct gfc_omp_saved_state
*state
)
1412 omp_current_ctx
= (struct omp_context
*) state
->ptrs
[0];
1413 omp_current_do_code
= (gfc_code
*) state
->ptrs
[1];
1414 omp_current_do_collapse
= state
->ints
[0];
1418 /* Note a DO iterator variable. This is special in !$omp parallel
1419 construct, where they are predetermined private. */
1422 gfc_resolve_do_iterator (gfc_code
*code
, gfc_symbol
*sym
)
1424 int i
= omp_current_do_collapse
;
1425 gfc_code
*c
= omp_current_do_code
;
1427 if (sym
->attr
.threadprivate
)
1430 /* !$omp do and !$omp parallel do iteration variable is predetermined
1431 private just in the !$omp do resp. !$omp parallel do construct,
1432 with no implications for the outer parallel constructs. */
1442 if (omp_current_ctx
== NULL
)
1445 if (pointer_set_contains (omp_current_ctx
->sharing_clauses
, sym
))
1448 if (! pointer_set_insert (omp_current_ctx
->private_iterators
, sym
))
1450 gfc_omp_clauses
*omp_clauses
= omp_current_ctx
->code
->ext
.omp_clauses
;
1453 p
= gfc_get_namelist ();
1455 p
->next
= omp_clauses
->lists
[OMP_LIST_PRIVATE
];
1456 omp_clauses
->lists
[OMP_LIST_PRIVATE
] = p
;
1462 resolve_omp_do (gfc_code
*code
)
1464 gfc_code
*do_code
, *c
;
1465 int list
, i
, collapse
;
1469 if (code
->ext
.omp_clauses
)
1470 resolve_omp_clauses (code
);
1472 do_code
= code
->block
->next
;
1473 collapse
= code
->ext
.omp_clauses
->collapse
;
1476 for (i
= 1; i
<= collapse
; i
++)
1478 if (do_code
->op
== EXEC_DO_WHILE
)
1480 gfc_error ("!$OMP DO cannot be a DO WHILE or DO without loop control "
1481 "at %L", &do_code
->loc
);
1484 gcc_assert (do_code
->op
== EXEC_DO
);
1485 if (do_code
->ext
.iterator
->var
->ts
.type
!= BT_INTEGER
)
1486 gfc_error ("!$OMP DO iteration variable must be of type integer at %L",
1488 dovar
= do_code
->ext
.iterator
->var
->symtree
->n
.sym
;
1489 if (dovar
->attr
.threadprivate
)
1490 gfc_error ("!$OMP DO iteration variable must not be THREADPRIVATE "
1491 "at %L", &do_code
->loc
);
1492 if (code
->ext
.omp_clauses
)
1493 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
1494 if (list
!= OMP_LIST_PRIVATE
&& list
!= OMP_LIST_LASTPRIVATE
)
1495 for (n
= code
->ext
.omp_clauses
->lists
[list
]; n
; n
= n
->next
)
1496 if (dovar
== n
->sym
)
1498 gfc_error ("!$OMP DO iteration variable present on clause "
1499 "other than PRIVATE or LASTPRIVATE at %L",
1505 gfc_code
*do_code2
= code
->block
->next
;
1508 for (j
= 1; j
< i
; j
++)
1510 gfc_symbol
*ivar
= do_code2
->ext
.iterator
->var
->symtree
->n
.sym
;
1512 || gfc_find_sym_in_expr (ivar
, do_code
->ext
.iterator
->start
)
1513 || gfc_find_sym_in_expr (ivar
, do_code
->ext
.iterator
->end
)
1514 || gfc_find_sym_in_expr (ivar
, do_code
->ext
.iterator
->step
))
1516 gfc_error ("!$OMP DO collapsed loops don't form rectangular iteration space at %L",
1522 do_code2
= do_code2
->block
->next
;
1527 for (c
= do_code
->next
; c
; c
= c
->next
)
1528 if (c
->op
!= EXEC_NOP
&& c
->op
!= EXEC_CONTINUE
)
1530 gfc_error ("collapsed !$OMP DO loops not perfectly nested at %L",
1536 do_code
= do_code
->block
;
1537 if (do_code
->op
!= EXEC_DO
&& do_code
->op
!= EXEC_DO_WHILE
)
1539 gfc_error ("not enough DO loops for collapsed !$OMP DO at %L",
1543 do_code
= do_code
->next
;
1545 || (do_code
->op
!= EXEC_DO
&& do_code
->op
!= EXEC_DO_WHILE
))
1547 gfc_error ("not enough DO loops for collapsed !$OMP DO at %L",
1555 /* Resolve OpenMP directive clauses and check various requirements
1556 of each directive. */
1559 gfc_resolve_omp_directive (gfc_code
*code
, gfc_namespace
*ns ATTRIBUTE_UNUSED
)
1561 if (code
->op
!= EXEC_OMP_ATOMIC
)
1562 gfc_maybe_initialize_eh ();
1567 case EXEC_OMP_PARALLEL_DO
:
1568 resolve_omp_do (code
);
1570 case EXEC_OMP_WORKSHARE
:
1571 case EXEC_OMP_PARALLEL_WORKSHARE
:
1572 case EXEC_OMP_PARALLEL
:
1573 case EXEC_OMP_PARALLEL_SECTIONS
:
1574 case EXEC_OMP_SECTIONS
:
1575 case EXEC_OMP_SINGLE
:
1577 if (code
->ext
.omp_clauses
)
1578 resolve_omp_clauses (code
);
1580 case EXEC_OMP_ATOMIC
:
1581 resolve_omp_atomic (code
);