1 /* OpenMP directive matching and resolving.
2 Copyright (C) 2005, 2006, 2007, 2008, 2010, 2011
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
->final_expr
);
70 gfc_free_expr (c
->num_threads
);
71 gfc_free_expr (c
->chunk_size
);
72 for (i
= 0; i
< OMP_LIST_NUM
; i
++)
73 gfc_free_namelist (c
->lists
[i
]);
77 /* Match a variable/common block list and construct a namelist from it. */
80 gfc_match_omp_variable_list (const char *str
, gfc_namelist
**list
,
83 gfc_namelist
*head
, *tail
, *p
;
85 char n
[GFC_MAX_SYMBOL_LEN
+1];
92 old_loc
= gfc_current_locus
;
100 m
= gfc_match_symbol (&sym
, 1);
104 gfc_set_sym_referenced (sym
);
105 p
= gfc_get_namelist ();
124 m
= gfc_match (" / %n /", n
);
125 if (m
== MATCH_ERROR
)
130 st
= gfc_find_symtree (gfc_current_ns
->common_root
, n
);
133 gfc_error ("COMMON block /%s/ not found at %C", n
);
136 for (sym
= st
->n
.common
->head
; sym
; sym
= sym
->common_next
)
138 gfc_set_sym_referenced (sym
);
139 p
= gfc_get_namelist ();
151 if (gfc_match_char (')') == MATCH_YES
)
153 if (gfc_match_char (',') != MATCH_YES
)
158 list
= &(*list
)->next
;
164 gfc_error ("Syntax error in OpenMP variable list at %C");
167 gfc_free_namelist (head
);
168 gfc_current_locus
= old_loc
;
172 #define OMP_CLAUSE_PRIVATE (1 << 0)
173 #define OMP_CLAUSE_FIRSTPRIVATE (1 << 1)
174 #define OMP_CLAUSE_LASTPRIVATE (1 << 2)
175 #define OMP_CLAUSE_COPYPRIVATE (1 << 3)
176 #define OMP_CLAUSE_SHARED (1 << 4)
177 #define OMP_CLAUSE_COPYIN (1 << 5)
178 #define OMP_CLAUSE_REDUCTION (1 << 6)
179 #define OMP_CLAUSE_IF (1 << 7)
180 #define OMP_CLAUSE_NUM_THREADS (1 << 8)
181 #define OMP_CLAUSE_SCHEDULE (1 << 9)
182 #define OMP_CLAUSE_DEFAULT (1 << 10)
183 #define OMP_CLAUSE_ORDERED (1 << 11)
184 #define OMP_CLAUSE_COLLAPSE (1 << 12)
185 #define OMP_CLAUSE_UNTIED (1 << 13)
186 #define OMP_CLAUSE_FINAL (1 << 14)
187 #define OMP_CLAUSE_MERGEABLE (1 << 15)
189 /* Match OpenMP directive clauses. MASK is a bitmask of
190 clauses that are allowed for a particular directive. */
193 gfc_match_omp_clauses (gfc_omp_clauses
**cp
, int mask
)
195 gfc_omp_clauses
*c
= gfc_get_omp_clauses ();
197 bool needs_space
= true, first
= true;
202 if ((first
|| gfc_match_char (',') != MATCH_YES
)
203 && (needs_space
&& gfc_match_space () != MATCH_YES
))
207 gfc_gobble_whitespace ();
208 if ((mask
& OMP_CLAUSE_IF
) && c
->if_expr
== NULL
209 && gfc_match ("if ( %e )", &c
->if_expr
) == MATCH_YES
)
211 if ((mask
& OMP_CLAUSE_FINAL
) && c
->final_expr
== NULL
212 && gfc_match ("final ( %e )", &c
->final_expr
) == MATCH_YES
)
214 if ((mask
& OMP_CLAUSE_NUM_THREADS
) && c
->num_threads
== NULL
215 && gfc_match ("num_threads ( %e )", &c
->num_threads
) == MATCH_YES
)
217 if ((mask
& OMP_CLAUSE_PRIVATE
)
218 && gfc_match_omp_variable_list ("private (",
219 &c
->lists
[OMP_LIST_PRIVATE
], true)
222 if ((mask
& OMP_CLAUSE_FIRSTPRIVATE
)
223 && gfc_match_omp_variable_list ("firstprivate (",
224 &c
->lists
[OMP_LIST_FIRSTPRIVATE
],
228 if ((mask
& OMP_CLAUSE_LASTPRIVATE
)
229 && gfc_match_omp_variable_list ("lastprivate (",
230 &c
->lists
[OMP_LIST_LASTPRIVATE
],
234 if ((mask
& OMP_CLAUSE_COPYPRIVATE
)
235 && gfc_match_omp_variable_list ("copyprivate (",
236 &c
->lists
[OMP_LIST_COPYPRIVATE
],
240 if ((mask
& OMP_CLAUSE_SHARED
)
241 && gfc_match_omp_variable_list ("shared (",
242 &c
->lists
[OMP_LIST_SHARED
], true)
245 if ((mask
& OMP_CLAUSE_COPYIN
)
246 && gfc_match_omp_variable_list ("copyin (",
247 &c
->lists
[OMP_LIST_COPYIN
], true)
250 old_loc
= gfc_current_locus
;
251 if ((mask
& OMP_CLAUSE_REDUCTION
)
252 && gfc_match ("reduction ( ") == MATCH_YES
)
254 int reduction
= OMP_LIST_NUM
;
255 char buffer
[GFC_MAX_SYMBOL_LEN
+ 1];
256 if (gfc_match_char ('+') == MATCH_YES
)
257 reduction
= OMP_LIST_PLUS
;
258 else if (gfc_match_char ('*') == MATCH_YES
)
259 reduction
= OMP_LIST_MULT
;
260 else if (gfc_match_char ('-') == MATCH_YES
)
261 reduction
= OMP_LIST_SUB
;
262 else if (gfc_match (".and.") == MATCH_YES
)
263 reduction
= OMP_LIST_AND
;
264 else if (gfc_match (".or.") == MATCH_YES
)
265 reduction
= OMP_LIST_OR
;
266 else if (gfc_match (".eqv.") == MATCH_YES
)
267 reduction
= OMP_LIST_EQV
;
268 else if (gfc_match (".neqv.") == MATCH_YES
)
269 reduction
= OMP_LIST_NEQV
;
270 else if (gfc_match_name (buffer
) == MATCH_YES
)
273 const char *n
= buffer
;
275 gfc_find_symbol (buffer
, NULL
, 1, &sym
);
278 if (sym
->attr
.intrinsic
)
280 else if ((sym
->attr
.flavor
!= FL_UNKNOWN
281 && sym
->attr
.flavor
!= FL_PROCEDURE
)
282 || sym
->attr
.external
287 || sym
->attr
.subroutine
290 || sym
->attr
.cray_pointer
291 || sym
->attr
.cray_pointee
292 || (sym
->attr
.proc
!= PROC_UNKNOWN
293 && sym
->attr
.proc
!= PROC_INTRINSIC
)
294 || sym
->attr
.if_source
!= IFSRC_UNKNOWN
295 || sym
== sym
->ns
->proc_name
)
297 gfc_error_now ("%s is not INTRINSIC procedure name "
304 if (strcmp (n
, "max") == 0)
305 reduction
= OMP_LIST_MAX
;
306 else if (strcmp (n
, "min") == 0)
307 reduction
= OMP_LIST_MIN
;
308 else if (strcmp (n
, "iand") == 0)
309 reduction
= OMP_LIST_IAND
;
310 else if (strcmp (n
, "ior") == 0)
311 reduction
= OMP_LIST_IOR
;
312 else if (strcmp (n
, "ieor") == 0)
313 reduction
= OMP_LIST_IEOR
;
314 if (reduction
!= OMP_LIST_NUM
316 && ! sym
->attr
.intrinsic
317 && ! sym
->attr
.use_assoc
318 && ((sym
->attr
.flavor
== FL_UNKNOWN
319 && gfc_add_flavor (&sym
->attr
, FL_PROCEDURE
,
320 sym
->name
, NULL
) == FAILURE
)
321 || gfc_add_intrinsic (&sym
->attr
, NULL
) == FAILURE
))
323 gfc_free_omp_clauses (c
);
327 if (reduction
!= OMP_LIST_NUM
328 && gfc_match_omp_variable_list (" :", &c
->lists
[reduction
],
333 gfc_current_locus
= old_loc
;
335 if ((mask
& OMP_CLAUSE_DEFAULT
)
336 && c
->default_sharing
== OMP_DEFAULT_UNKNOWN
)
338 if (gfc_match ("default ( shared )") == MATCH_YES
)
339 c
->default_sharing
= OMP_DEFAULT_SHARED
;
340 else if (gfc_match ("default ( private )") == MATCH_YES
)
341 c
->default_sharing
= OMP_DEFAULT_PRIVATE
;
342 else if (gfc_match ("default ( none )") == MATCH_YES
)
343 c
->default_sharing
= OMP_DEFAULT_NONE
;
344 else if (gfc_match ("default ( firstprivate )") == MATCH_YES
)
345 c
->default_sharing
= OMP_DEFAULT_FIRSTPRIVATE
;
346 if (c
->default_sharing
!= OMP_DEFAULT_UNKNOWN
)
349 old_loc
= gfc_current_locus
;
350 if ((mask
& OMP_CLAUSE_SCHEDULE
)
351 && c
->sched_kind
== OMP_SCHED_NONE
352 && gfc_match ("schedule ( ") == MATCH_YES
)
354 if (gfc_match ("static") == MATCH_YES
)
355 c
->sched_kind
= OMP_SCHED_STATIC
;
356 else if (gfc_match ("dynamic") == MATCH_YES
)
357 c
->sched_kind
= OMP_SCHED_DYNAMIC
;
358 else if (gfc_match ("guided") == MATCH_YES
)
359 c
->sched_kind
= OMP_SCHED_GUIDED
;
360 else if (gfc_match ("runtime") == MATCH_YES
)
361 c
->sched_kind
= OMP_SCHED_RUNTIME
;
362 else if (gfc_match ("auto") == MATCH_YES
)
363 c
->sched_kind
= OMP_SCHED_AUTO
;
364 if (c
->sched_kind
!= OMP_SCHED_NONE
)
367 if (c
->sched_kind
!= OMP_SCHED_RUNTIME
368 && c
->sched_kind
!= OMP_SCHED_AUTO
)
369 m
= gfc_match (" , %e )", &c
->chunk_size
);
371 m
= gfc_match_char (')');
373 c
->sched_kind
= OMP_SCHED_NONE
;
375 if (c
->sched_kind
!= OMP_SCHED_NONE
)
378 gfc_current_locus
= old_loc
;
380 if ((mask
& OMP_CLAUSE_ORDERED
) && !c
->ordered
381 && gfc_match ("ordered") == MATCH_YES
)
383 c
->ordered
= needs_space
= true;
386 if ((mask
& OMP_CLAUSE_UNTIED
) && !c
->untied
387 && gfc_match ("untied") == MATCH_YES
)
389 c
->untied
= needs_space
= true;
392 if ((mask
& OMP_CLAUSE_MERGEABLE
) && !c
->mergeable
393 && gfc_match ("mergeable") == MATCH_YES
)
395 c
->mergeable
= needs_space
= true;
398 if ((mask
& OMP_CLAUSE_COLLAPSE
) && !c
->collapse
)
400 gfc_expr
*cexpr
= NULL
;
401 match m
= gfc_match ("collapse ( %e )", &cexpr
);
406 const char *p
= gfc_extract_int (cexpr
, &collapse
);
412 else if (collapse
<= 0)
414 gfc_error_now ("COLLAPSE clause argument not"
415 " constant positive integer at %C");
418 c
->collapse
= collapse
;
419 gfc_free_expr (cexpr
);
427 if (gfc_match_omp_eos () != MATCH_YES
)
429 gfc_free_omp_clauses (c
);
437 #define OMP_PARALLEL_CLAUSES \
438 (OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_SHARED \
439 | OMP_CLAUSE_COPYIN | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_IF \
440 | OMP_CLAUSE_NUM_THREADS | OMP_CLAUSE_DEFAULT)
441 #define OMP_DO_CLAUSES \
442 (OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE \
443 | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION \
444 | OMP_CLAUSE_SCHEDULE | OMP_CLAUSE_ORDERED | OMP_CLAUSE_COLLAPSE)
445 #define OMP_SECTIONS_CLAUSES \
446 (OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE \
447 | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION)
448 #define OMP_TASK_CLAUSES \
449 (OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_SHARED \
450 | OMP_CLAUSE_IF | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_UNTIED \
451 | OMP_CLAUSE_FINAL | OMP_CLAUSE_MERGEABLE)
454 gfc_match_omp_parallel (void)
457 if (gfc_match_omp_clauses (&c
, OMP_PARALLEL_CLAUSES
) != MATCH_YES
)
459 new_st
.op
= EXEC_OMP_PARALLEL
;
460 new_st
.ext
.omp_clauses
= c
;
466 gfc_match_omp_task (void)
469 if (gfc_match_omp_clauses (&c
, OMP_TASK_CLAUSES
) != MATCH_YES
)
471 new_st
.op
= EXEC_OMP_TASK
;
472 new_st
.ext
.omp_clauses
= c
;
478 gfc_match_omp_taskwait (void)
480 if (gfc_match_omp_eos () != MATCH_YES
)
482 gfc_error ("Unexpected junk after TASKWAIT clause at %C");
485 new_st
.op
= EXEC_OMP_TASKWAIT
;
486 new_st
.ext
.omp_clauses
= NULL
;
492 gfc_match_omp_taskyield (void)
494 if (gfc_match_omp_eos () != MATCH_YES
)
496 gfc_error ("Unexpected junk after TASKYIELD clause at %C");
499 new_st
.op
= EXEC_OMP_TASKYIELD
;
500 new_st
.ext
.omp_clauses
= NULL
;
506 gfc_match_omp_critical (void)
508 char n
[GFC_MAX_SYMBOL_LEN
+1];
510 if (gfc_match (" ( %n )", n
) != MATCH_YES
)
512 if (gfc_match_omp_eos () != MATCH_YES
)
514 gfc_error ("Unexpected junk after $OMP CRITICAL statement at %C");
517 new_st
.op
= EXEC_OMP_CRITICAL
;
518 new_st
.ext
.omp_name
= n
[0] ? xstrdup (n
) : NULL
;
524 gfc_match_omp_do (void)
527 if (gfc_match_omp_clauses (&c
, OMP_DO_CLAUSES
) != MATCH_YES
)
529 new_st
.op
= EXEC_OMP_DO
;
530 new_st
.ext
.omp_clauses
= c
;
536 gfc_match_omp_flush (void)
538 gfc_namelist
*list
= NULL
;
539 gfc_match_omp_variable_list (" (", &list
, true);
540 if (gfc_match_omp_eos () != MATCH_YES
)
542 gfc_error ("Unexpected junk after $OMP FLUSH statement at %C");
543 gfc_free_namelist (list
);
546 new_st
.op
= EXEC_OMP_FLUSH
;
547 new_st
.ext
.omp_namelist
= list
;
553 gfc_match_omp_threadprivate (void)
556 char n
[GFC_MAX_SYMBOL_LEN
+1];
561 old_loc
= gfc_current_locus
;
563 m
= gfc_match (" (");
569 m
= gfc_match_symbol (&sym
, 0);
573 if (sym
->attr
.in_common
)
574 gfc_error_now ("Threadprivate variable at %C is an element of "
576 else if (gfc_add_threadprivate (&sym
->attr
, sym
->name
,
577 &sym
->declared_at
) == FAILURE
)
586 m
= gfc_match (" / %n /", n
);
587 if (m
== MATCH_ERROR
)
589 if (m
== MATCH_NO
|| n
[0] == '\0')
592 st
= gfc_find_symtree (gfc_current_ns
->common_root
, n
);
595 gfc_error ("COMMON block /%s/ not found at %C", n
);
598 st
->n
.common
->threadprivate
= 1;
599 for (sym
= st
->n
.common
->head
; sym
; sym
= sym
->common_next
)
600 if (gfc_add_threadprivate (&sym
->attr
, sym
->name
,
601 &sym
->declared_at
) == FAILURE
)
605 if (gfc_match_char (')') == MATCH_YES
)
607 if (gfc_match_char (',') != MATCH_YES
)
614 gfc_error ("Syntax error in !$OMP THREADPRIVATE list at %C");
617 gfc_current_locus
= old_loc
;
623 gfc_match_omp_parallel_do (void)
626 if (gfc_match_omp_clauses (&c
, OMP_PARALLEL_CLAUSES
| OMP_DO_CLAUSES
)
629 new_st
.op
= EXEC_OMP_PARALLEL_DO
;
630 new_st
.ext
.omp_clauses
= c
;
636 gfc_match_omp_parallel_sections (void)
639 if (gfc_match_omp_clauses (&c
, OMP_PARALLEL_CLAUSES
| OMP_SECTIONS_CLAUSES
)
642 new_st
.op
= EXEC_OMP_PARALLEL_SECTIONS
;
643 new_st
.ext
.omp_clauses
= c
;
649 gfc_match_omp_parallel_workshare (void)
652 if (gfc_match_omp_clauses (&c
, OMP_PARALLEL_CLAUSES
) != MATCH_YES
)
654 new_st
.op
= EXEC_OMP_PARALLEL_WORKSHARE
;
655 new_st
.ext
.omp_clauses
= c
;
661 gfc_match_omp_sections (void)
664 if (gfc_match_omp_clauses (&c
, OMP_SECTIONS_CLAUSES
) != MATCH_YES
)
666 new_st
.op
= EXEC_OMP_SECTIONS
;
667 new_st
.ext
.omp_clauses
= c
;
673 gfc_match_omp_single (void)
676 if (gfc_match_omp_clauses (&c
, OMP_CLAUSE_PRIVATE
| OMP_CLAUSE_FIRSTPRIVATE
)
679 new_st
.op
= EXEC_OMP_SINGLE
;
680 new_st
.ext
.omp_clauses
= c
;
686 gfc_match_omp_workshare (void)
688 if (gfc_match_omp_eos () != MATCH_YES
)
690 gfc_error ("Unexpected junk after $OMP WORKSHARE statement at %C");
693 new_st
.op
= EXEC_OMP_WORKSHARE
;
694 new_st
.ext
.omp_clauses
= gfc_get_omp_clauses ();
700 gfc_match_omp_master (void)
702 if (gfc_match_omp_eos () != MATCH_YES
)
704 gfc_error ("Unexpected junk after $OMP MASTER statement at %C");
707 new_st
.op
= EXEC_OMP_MASTER
;
708 new_st
.ext
.omp_clauses
= NULL
;
714 gfc_match_omp_ordered (void)
716 if (gfc_match_omp_eos () != MATCH_YES
)
718 gfc_error ("Unexpected junk after $OMP ORDERED statement at %C");
721 new_st
.op
= EXEC_OMP_ORDERED
;
722 new_st
.ext
.omp_clauses
= NULL
;
728 gfc_match_omp_atomic (void)
730 gfc_omp_atomic_op op
= GFC_OMP_ATOMIC_UPDATE
;
731 if (gfc_match ("% update") == MATCH_YES
)
732 op
= GFC_OMP_ATOMIC_UPDATE
;
733 else if (gfc_match ("% read") == MATCH_YES
)
734 op
= GFC_OMP_ATOMIC_READ
;
735 else if (gfc_match ("% write") == MATCH_YES
)
736 op
= GFC_OMP_ATOMIC_WRITE
;
737 else if (gfc_match ("% capture") == MATCH_YES
)
738 op
= GFC_OMP_ATOMIC_CAPTURE
;
739 if (gfc_match_omp_eos () != MATCH_YES
)
741 gfc_error ("Unexpected junk after $OMP ATOMIC statement at %C");
744 new_st
.op
= EXEC_OMP_ATOMIC
;
745 new_st
.ext
.omp_atomic
= op
;
751 gfc_match_omp_barrier (void)
753 if (gfc_match_omp_eos () != MATCH_YES
)
755 gfc_error ("Unexpected junk after $OMP BARRIER statement at %C");
758 new_st
.op
= EXEC_OMP_BARRIER
;
759 new_st
.ext
.omp_clauses
= NULL
;
765 gfc_match_omp_end_nowait (void)
768 if (gfc_match ("% nowait") == MATCH_YES
)
770 if (gfc_match_omp_eos () != MATCH_YES
)
772 gfc_error ("Unexpected junk after NOWAIT clause at %C");
775 new_st
.op
= EXEC_OMP_END_NOWAIT
;
776 new_st
.ext
.omp_bool
= nowait
;
782 gfc_match_omp_end_single (void)
785 if (gfc_match ("% nowait") == MATCH_YES
)
787 new_st
.op
= EXEC_OMP_END_NOWAIT
;
788 new_st
.ext
.omp_bool
= true;
791 if (gfc_match_omp_clauses (&c
, OMP_CLAUSE_COPYPRIVATE
) != MATCH_YES
)
793 new_st
.op
= EXEC_OMP_END_SINGLE
;
794 new_st
.ext
.omp_clauses
= c
;
799 /* OpenMP directive resolving routines. */
802 resolve_omp_clauses (gfc_code
*code
)
804 gfc_omp_clauses
*omp_clauses
= code
->ext
.omp_clauses
;
807 static const char *clause_names
[]
808 = { "PRIVATE", "FIRSTPRIVATE", "LASTPRIVATE", "COPYPRIVATE", "SHARED",
809 "COPYIN", "REDUCTION" };
811 if (omp_clauses
== NULL
)
814 if (omp_clauses
->if_expr
)
816 gfc_expr
*expr
= omp_clauses
->if_expr
;
817 if (gfc_resolve_expr (expr
) == FAILURE
818 || expr
->ts
.type
!= BT_LOGICAL
|| expr
->rank
!= 0)
819 gfc_error ("IF clause at %L requires a scalar LOGICAL expression",
822 if (omp_clauses
->final_expr
)
824 gfc_expr
*expr
= omp_clauses
->final_expr
;
825 if (gfc_resolve_expr (expr
) == FAILURE
826 || expr
->ts
.type
!= BT_LOGICAL
|| expr
->rank
!= 0)
827 gfc_error ("FINAL clause at %L requires a scalar LOGICAL expression",
830 if (omp_clauses
->num_threads
)
832 gfc_expr
*expr
= omp_clauses
->num_threads
;
833 if (gfc_resolve_expr (expr
) == FAILURE
834 || expr
->ts
.type
!= BT_INTEGER
|| expr
->rank
!= 0)
835 gfc_error ("NUM_THREADS clause at %L requires a scalar "
836 "INTEGER expression", &expr
->where
);
838 if (omp_clauses
->chunk_size
)
840 gfc_expr
*expr
= omp_clauses
->chunk_size
;
841 if (gfc_resolve_expr (expr
) == FAILURE
842 || expr
->ts
.type
!= BT_INTEGER
|| expr
->rank
!= 0)
843 gfc_error ("SCHEDULE clause's chunk_size at %L requires "
844 "a scalar INTEGER expression", &expr
->where
);
847 /* Check that no symbol appears on multiple clauses, except that
848 a symbol can appear on both firstprivate and lastprivate. */
849 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
850 for (n
= omp_clauses
->lists
[list
]; n
; n
= n
->next
)
853 if (n
->sym
->attr
.flavor
== FL_VARIABLE
)
855 if (n
->sym
->attr
.flavor
== FL_PROCEDURE
856 && n
->sym
->result
== n
->sym
857 && n
->sym
->attr
.function
)
859 if (gfc_current_ns
->proc_name
== n
->sym
860 || (gfc_current_ns
->parent
861 && gfc_current_ns
->parent
->proc_name
== n
->sym
))
863 if (gfc_current_ns
->proc_name
->attr
.entry_master
)
865 gfc_entry_list
*el
= gfc_current_ns
->entries
;
866 for (; el
; el
= el
->next
)
867 if (el
->sym
== n
->sym
)
872 if (gfc_current_ns
->parent
873 && gfc_current_ns
->parent
->proc_name
->attr
.entry_master
)
875 gfc_entry_list
*el
= gfc_current_ns
->parent
->entries
;
876 for (; el
; el
= el
->next
)
877 if (el
->sym
== n
->sym
)
882 if (n
->sym
->attr
.proc_pointer
)
885 gfc_error ("Object '%s' is not a variable at %L", n
->sym
->name
,
889 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
890 if (list
!= OMP_LIST_FIRSTPRIVATE
&& list
!= OMP_LIST_LASTPRIVATE
)
891 for (n
= omp_clauses
->lists
[list
]; n
; n
= n
->next
)
894 gfc_error ("Symbol '%s' present on multiple clauses at %L",
895 n
->sym
->name
, &code
->loc
);
900 gcc_assert (OMP_LIST_LASTPRIVATE
== OMP_LIST_FIRSTPRIVATE
+ 1);
901 for (list
= OMP_LIST_FIRSTPRIVATE
; list
<= OMP_LIST_LASTPRIVATE
; list
++)
902 for (n
= omp_clauses
->lists
[list
]; n
; n
= n
->next
)
905 gfc_error ("Symbol '%s' present on multiple clauses at %L",
906 n
->sym
->name
, &code
->loc
);
910 for (n
= omp_clauses
->lists
[OMP_LIST_FIRSTPRIVATE
]; n
; n
= n
->next
)
913 gfc_error ("Symbol '%s' present on multiple clauses at %L",
914 n
->sym
->name
, &code
->loc
);
918 for (n
= omp_clauses
->lists
[OMP_LIST_LASTPRIVATE
]; n
; n
= n
->next
)
921 for (n
= omp_clauses
->lists
[OMP_LIST_LASTPRIVATE
]; n
; n
= n
->next
)
924 gfc_error ("Symbol '%s' present on multiple clauses at %L",
925 n
->sym
->name
, &code
->loc
);
929 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
930 if ((n
= omp_clauses
->lists
[list
]) != NULL
)
934 if (list
< OMP_LIST_REDUCTION_FIRST
)
935 name
= clause_names
[list
];
936 else if (list
<= OMP_LIST_REDUCTION_LAST
)
937 name
= clause_names
[OMP_LIST_REDUCTION_FIRST
];
943 case OMP_LIST_COPYIN
:
944 for (; n
!= NULL
; n
= n
->next
)
946 if (!n
->sym
->attr
.threadprivate
)
947 gfc_error ("Non-THREADPRIVATE object '%s' in COPYIN clause"
948 " at %L", n
->sym
->name
, &code
->loc
);
949 if (n
->sym
->ts
.type
== BT_DERIVED
&& n
->sym
->ts
.u
.derived
->attr
.alloc_comp
)
950 gfc_error ("COPYIN clause object '%s' at %L has ALLOCATABLE components",
951 n
->sym
->name
, &code
->loc
);
954 case OMP_LIST_COPYPRIVATE
:
955 for (; n
!= NULL
; n
= n
->next
)
957 if (n
->sym
->as
&& n
->sym
->as
->type
== AS_ASSUMED_SIZE
)
958 gfc_error ("Assumed size array '%s' in COPYPRIVATE clause "
959 "at %L", n
->sym
->name
, &code
->loc
);
960 if (n
->sym
->ts
.type
== BT_DERIVED
&& n
->sym
->ts
.u
.derived
->attr
.alloc_comp
)
961 gfc_error ("COPYPRIVATE clause object '%s' at %L has ALLOCATABLE components",
962 n
->sym
->name
, &code
->loc
);
965 case OMP_LIST_SHARED
:
966 for (; n
!= NULL
; n
= n
->next
)
968 if (n
->sym
->attr
.threadprivate
)
969 gfc_error ("THREADPRIVATE object '%s' in SHARED clause at "
970 "%L", n
->sym
->name
, &code
->loc
);
971 if (n
->sym
->attr
.cray_pointee
)
972 gfc_error ("Cray pointee '%s' in SHARED clause at %L",
973 n
->sym
->name
, &code
->loc
);
977 for (; n
!= NULL
; n
= n
->next
)
979 if (n
->sym
->attr
.threadprivate
)
980 gfc_error ("THREADPRIVATE object '%s' in %s clause at %L",
981 n
->sym
->name
, name
, &code
->loc
);
982 if (n
->sym
->attr
.cray_pointee
)
983 gfc_error ("Cray pointee '%s' in %s clause at %L",
984 n
->sym
->name
, name
, &code
->loc
);
985 if (list
!= OMP_LIST_PRIVATE
)
987 if (n
->sym
->attr
.pointer
988 && list
>= OMP_LIST_REDUCTION_FIRST
989 && list
<= OMP_LIST_REDUCTION_LAST
)
990 gfc_error ("POINTER object '%s' in %s clause at %L",
991 n
->sym
->name
, name
, &code
->loc
);
992 /* Variables in REDUCTION-clauses must be of intrinsic type (flagged below). */
993 if ((list
< OMP_LIST_REDUCTION_FIRST
|| list
> OMP_LIST_REDUCTION_LAST
)
994 && n
->sym
->ts
.type
== BT_DERIVED
995 && n
->sym
->ts
.u
.derived
->attr
.alloc_comp
)
996 gfc_error ("%s clause object '%s' has ALLOCATABLE components at %L",
997 name
, n
->sym
->name
, &code
->loc
);
998 if (n
->sym
->attr
.cray_pointer
999 && list
>= OMP_LIST_REDUCTION_FIRST
1000 && list
<= OMP_LIST_REDUCTION_LAST
)
1001 gfc_error ("Cray pointer '%s' in %s clause at %L",
1002 n
->sym
->name
, name
, &code
->loc
);
1004 if (n
->sym
->as
&& n
->sym
->as
->type
== AS_ASSUMED_SIZE
)
1005 gfc_error ("Assumed size array '%s' in %s clause at %L",
1006 n
->sym
->name
, name
, &code
->loc
);
1007 if (n
->sym
->attr
.in_namelist
1008 && (list
< OMP_LIST_REDUCTION_FIRST
1009 || list
> OMP_LIST_REDUCTION_LAST
))
1010 gfc_error ("Variable '%s' in %s clause is used in "
1011 "NAMELIST statement at %L",
1012 n
->sym
->name
, name
, &code
->loc
);
1018 if (!gfc_numeric_ts (&n
->sym
->ts
))
1019 gfc_error ("%c REDUCTION variable '%s' at %L must be of numeric type, got %s",
1020 list
== OMP_LIST_PLUS
? '+'
1021 : list
== OMP_LIST_MULT
? '*' : '-',
1022 n
->sym
->name
, &code
->loc
,
1023 gfc_typename (&n
->sym
->ts
));
1029 if (n
->sym
->ts
.type
!= BT_LOGICAL
)
1030 gfc_error ("%s REDUCTION variable '%s' must be LOGICAL "
1032 list
== OMP_LIST_AND
? ".AND."
1033 : list
== OMP_LIST_OR
? ".OR."
1034 : list
== OMP_LIST_EQV
? ".EQV." : ".NEQV.",
1035 n
->sym
->name
, &code
->loc
);
1039 if (n
->sym
->ts
.type
!= BT_INTEGER
1040 && n
->sym
->ts
.type
!= BT_REAL
)
1041 gfc_error ("%s REDUCTION variable '%s' must be "
1042 "INTEGER or REAL at %L",
1043 list
== OMP_LIST_MAX
? "MAX" : "MIN",
1044 n
->sym
->name
, &code
->loc
);
1049 if (n
->sym
->ts
.type
!= BT_INTEGER
)
1050 gfc_error ("%s REDUCTION variable '%s' must be INTEGER "
1052 list
== OMP_LIST_IAND
? "IAND"
1053 : list
== OMP_LIST_MULT
? "IOR" : "IEOR",
1054 n
->sym
->name
, &code
->loc
);
1056 /* Workaround for PR middle-end/26316, nothing really needs
1057 to be done here for OMP_LIST_PRIVATE. */
1058 case OMP_LIST_PRIVATE
:
1059 gcc_assert (code
->op
!= EXEC_NOP
);
1070 /* Return true if SYM is ever referenced in EXPR except in the SE node. */
1073 expr_references_sym (gfc_expr
*e
, gfc_symbol
*s
, gfc_expr
*se
)
1075 gfc_actual_arglist
*arg
;
1076 if (e
== NULL
|| e
== se
)
1078 switch (e
->expr_type
)
1083 case EXPR_STRUCTURE
:
1085 if (e
->symtree
!= NULL
1086 && e
->symtree
->n
.sym
== s
)
1089 case EXPR_SUBSTRING
:
1091 && (expr_references_sym (e
->ref
->u
.ss
.start
, s
, se
)
1092 || expr_references_sym (e
->ref
->u
.ss
.end
, s
, se
)))
1096 if (expr_references_sym (e
->value
.op
.op2
, s
, se
))
1098 return expr_references_sym (e
->value
.op
.op1
, s
, se
);
1100 for (arg
= e
->value
.function
.actual
; arg
; arg
= arg
->next
)
1101 if (expr_references_sym (arg
->expr
, s
, se
))
1110 /* If EXPR is a conversion function that widens the type
1111 if WIDENING is true or narrows the type if WIDENING is false,
1112 return the inner expression, otherwise return NULL. */
1115 is_conversion (gfc_expr
*expr
, bool widening
)
1117 gfc_typespec
*ts1
, *ts2
;
1119 if (expr
->expr_type
!= EXPR_FUNCTION
1120 || expr
->value
.function
.isym
== NULL
1121 || expr
->value
.function
.esym
!= NULL
1122 || expr
->value
.function
.isym
->id
!= GFC_ISYM_CONVERSION
)
1128 ts2
= &expr
->value
.function
.actual
->expr
->ts
;
1132 ts1
= &expr
->value
.function
.actual
->expr
->ts
;
1136 if (ts1
->type
> ts2
->type
1137 || (ts1
->type
== ts2
->type
&& ts1
->kind
> ts2
->kind
))
1138 return expr
->value
.function
.actual
->expr
;
1145 resolve_omp_atomic (gfc_code
*code
)
1147 gfc_code
*atomic_code
= code
;
1149 gfc_expr
*expr2
, *expr2_tmp
;
1151 code
= code
->block
->next
;
1152 gcc_assert (code
->op
== EXEC_ASSIGN
);
1153 gcc_assert ((atomic_code
->ext
.omp_atomic
!= GFC_OMP_ATOMIC_CAPTURE
1154 && code
->next
== NULL
)
1155 || (atomic_code
->ext
.omp_atomic
== GFC_OMP_ATOMIC_CAPTURE
1156 && code
->next
!= NULL
1157 && code
->next
->op
== EXEC_ASSIGN
1158 && code
->next
->next
== NULL
));
1160 if (code
->expr1
->expr_type
!= EXPR_VARIABLE
1161 || code
->expr1
->symtree
== NULL
1162 || code
->expr1
->rank
!= 0
1163 || (code
->expr1
->ts
.type
!= BT_INTEGER
1164 && code
->expr1
->ts
.type
!= BT_REAL
1165 && code
->expr1
->ts
.type
!= BT_COMPLEX
1166 && code
->expr1
->ts
.type
!= BT_LOGICAL
))
1168 gfc_error ("!$OMP ATOMIC statement must set a scalar variable of "
1169 "intrinsic type at %L", &code
->loc
);
1173 var
= code
->expr1
->symtree
->n
.sym
;
1174 expr2
= is_conversion (code
->expr2
, false);
1177 if (atomic_code
->ext
.omp_atomic
== GFC_OMP_ATOMIC_READ
1178 || atomic_code
->ext
.omp_atomic
== GFC_OMP_ATOMIC_WRITE
)
1179 expr2
= is_conversion (code
->expr2
, true);
1181 expr2
= code
->expr2
;
1184 switch (atomic_code
->ext
.omp_atomic
)
1186 case GFC_OMP_ATOMIC_READ
:
1187 if (expr2
->expr_type
!= EXPR_VARIABLE
1188 || expr2
->symtree
== NULL
1190 || (expr2
->ts
.type
!= BT_INTEGER
1191 && expr2
->ts
.type
!= BT_REAL
1192 && expr2
->ts
.type
!= BT_COMPLEX
1193 && expr2
->ts
.type
!= BT_LOGICAL
))
1194 gfc_error ("!$OMP ATOMIC READ statement must read from a scalar "
1195 "variable of intrinsic type at %L", &expr2
->where
);
1197 case GFC_OMP_ATOMIC_WRITE
:
1198 if (expr2
->rank
!= 0 || expr_references_sym (code
->expr2
, var
, NULL
))
1199 gfc_error ("expr in !$OMP ATOMIC WRITE assignment var = expr "
1200 "must be scalar and cannot reference var at %L",
1203 case GFC_OMP_ATOMIC_CAPTURE
:
1205 if (expr2
== code
->expr2
)
1207 expr2_tmp
= is_conversion (code
->expr2
, true);
1208 if (expr2_tmp
== NULL
)
1211 if (expr2_tmp
->expr_type
== EXPR_VARIABLE
)
1213 if (expr2_tmp
->symtree
== NULL
1214 || expr2_tmp
->rank
!= 0
1215 || (expr2_tmp
->ts
.type
!= BT_INTEGER
1216 && expr2_tmp
->ts
.type
!= BT_REAL
1217 && expr2_tmp
->ts
.type
!= BT_COMPLEX
1218 && expr2_tmp
->ts
.type
!= BT_LOGICAL
)
1219 || expr2_tmp
->symtree
->n
.sym
== var
)
1221 gfc_error ("!$OMP ATOMIC CAPTURE capture statement must read from "
1222 "a scalar variable of intrinsic type at %L",
1226 var
= expr2_tmp
->symtree
->n
.sym
;
1228 if (code
->expr1
->expr_type
!= EXPR_VARIABLE
1229 || code
->expr1
->symtree
== NULL
1230 || code
->expr1
->rank
!= 0
1231 || (code
->expr1
->ts
.type
!= BT_INTEGER
1232 && code
->expr1
->ts
.type
!= BT_REAL
1233 && code
->expr1
->ts
.type
!= BT_COMPLEX
1234 && code
->expr1
->ts
.type
!= BT_LOGICAL
))
1236 gfc_error ("!$OMP ATOMIC CAPTURE update statement must set "
1237 "a scalar variable of intrinsic type at %L",
1238 &code
->expr1
->where
);
1241 if (code
->expr1
->symtree
->n
.sym
!= var
)
1243 gfc_error ("!$OMP ATOMIC CAPTURE capture statement reads from "
1244 "different variable than update statement writes "
1245 "into at %L", &code
->expr1
->where
);
1248 expr2
= is_conversion (code
->expr2
, false);
1250 expr2
= code
->expr2
;
1257 if (expr2
->expr_type
== EXPR_OP
)
1259 gfc_expr
*v
= NULL
, *e
, *c
;
1260 gfc_intrinsic_op op
= expr2
->value
.op
.op
;
1261 gfc_intrinsic_op alt_op
= INTRINSIC_NONE
;
1265 case INTRINSIC_PLUS
:
1266 alt_op
= INTRINSIC_MINUS
;
1268 case INTRINSIC_TIMES
:
1269 alt_op
= INTRINSIC_DIVIDE
;
1271 case INTRINSIC_MINUS
:
1272 alt_op
= INTRINSIC_PLUS
;
1274 case INTRINSIC_DIVIDE
:
1275 alt_op
= INTRINSIC_TIMES
;
1281 alt_op
= INTRINSIC_NEQV
;
1283 case INTRINSIC_NEQV
:
1284 alt_op
= INTRINSIC_EQV
;
1287 gfc_error ("!$OMP ATOMIC assignment operator must be "
1288 "+, *, -, /, .AND., .OR., .EQV. or .NEQV. at %L",
1293 /* Check for var = var op expr resp. var = expr op var where
1294 expr doesn't reference var and var op expr is mathematically
1295 equivalent to var op (expr) resp. expr op var equivalent to
1296 (expr) op var. We rely here on the fact that the matcher
1297 for x op1 y op2 z where op1 and op2 have equal precedence
1298 returns (x op1 y) op2 z. */
1299 e
= expr2
->value
.op
.op2
;
1300 if (e
->expr_type
== EXPR_VARIABLE
1301 && e
->symtree
!= NULL
1302 && e
->symtree
->n
.sym
== var
)
1304 else if ((c
= is_conversion (e
, true)) != NULL
1305 && c
->expr_type
== EXPR_VARIABLE
1306 && c
->symtree
!= NULL
1307 && c
->symtree
->n
.sym
== var
)
1311 gfc_expr
**p
= NULL
, **q
;
1312 for (q
= &expr2
->value
.op
.op1
; (e
= *q
) != NULL
; )
1313 if (e
->expr_type
== EXPR_VARIABLE
1314 && e
->symtree
!= NULL
1315 && e
->symtree
->n
.sym
== var
)
1320 else if ((c
= is_conversion (e
, true)) != NULL
)
1321 q
= &e
->value
.function
.actual
->expr
;
1322 else if (e
->expr_type
!= EXPR_OP
1323 || (e
->value
.op
.op
!= op
1324 && e
->value
.op
.op
!= alt_op
)
1330 q
= &e
->value
.op
.op1
;
1335 gfc_error ("!$OMP ATOMIC assignment must be var = var op expr "
1336 "or var = expr op var at %L", &expr2
->where
);
1343 switch (e
->value
.op
.op
)
1345 case INTRINSIC_MINUS
:
1346 case INTRINSIC_DIVIDE
:
1348 case INTRINSIC_NEQV
:
1349 gfc_error ("!$OMP ATOMIC var = var op expr not "
1350 "mathematically equivalent to var = var op "
1351 "(expr) at %L", &expr2
->where
);
1357 /* Canonicalize into var = var op (expr). */
1358 *p
= e
->value
.op
.op2
;
1359 e
->value
.op
.op2
= expr2
;
1361 if (code
->expr2
== expr2
)
1362 code
->expr2
= expr2
= e
;
1364 code
->expr2
->value
.function
.actual
->expr
= expr2
= e
;
1366 if (!gfc_compare_types (&expr2
->value
.op
.op1
->ts
, &expr2
->ts
))
1368 for (p
= &expr2
->value
.op
.op1
; *p
!= v
;
1369 p
= &(*p
)->value
.function
.actual
->expr
)
1372 gfc_free_expr (expr2
->value
.op
.op1
);
1373 expr2
->value
.op
.op1
= v
;
1374 gfc_convert_type (v
, &expr2
->ts
, 2);
1379 if (e
->rank
!= 0 || expr_references_sym (code
->expr2
, var
, v
))
1381 gfc_error ("expr in !$OMP ATOMIC assignment var = var op expr "
1382 "must be scalar and cannot reference var at %L",
1387 else if (expr2
->expr_type
== EXPR_FUNCTION
1388 && expr2
->value
.function
.isym
!= NULL
1389 && expr2
->value
.function
.esym
== NULL
1390 && expr2
->value
.function
.actual
!= NULL
1391 && expr2
->value
.function
.actual
->next
!= NULL
)
1393 gfc_actual_arglist
*arg
, *var_arg
;
1395 switch (expr2
->value
.function
.isym
->id
)
1403 if (expr2
->value
.function
.actual
->next
->next
!= NULL
)
1405 gfc_error ("!$OMP ATOMIC assignment intrinsic IAND, IOR "
1406 "or IEOR must have two arguments at %L",
1412 gfc_error ("!$OMP ATOMIC assignment intrinsic must be "
1413 "MIN, MAX, IAND, IOR or IEOR at %L",
1419 for (arg
= expr2
->value
.function
.actual
; arg
; arg
= arg
->next
)
1421 if ((arg
== expr2
->value
.function
.actual
1422 || (var_arg
== NULL
&& arg
->next
== NULL
))
1423 && arg
->expr
->expr_type
== EXPR_VARIABLE
1424 && arg
->expr
->symtree
!= NULL
1425 && arg
->expr
->symtree
->n
.sym
== var
)
1427 else if (expr_references_sym (arg
->expr
, var
, NULL
))
1428 gfc_error ("!$OMP ATOMIC intrinsic arguments except one must not "
1429 "reference '%s' at %L", var
->name
, &arg
->expr
->where
);
1430 if (arg
->expr
->rank
!= 0)
1431 gfc_error ("!$OMP ATOMIC intrinsic arguments must be scalar "
1432 "at %L", &arg
->expr
->where
);
1435 if (var_arg
== NULL
)
1437 gfc_error ("First or last !$OMP ATOMIC intrinsic argument must "
1438 "be '%s' at %L", var
->name
, &expr2
->where
);
1442 if (var_arg
!= expr2
->value
.function
.actual
)
1444 /* Canonicalize, so that var comes first. */
1445 gcc_assert (var_arg
->next
== NULL
);
1446 for (arg
= expr2
->value
.function
.actual
;
1447 arg
->next
!= var_arg
; arg
= arg
->next
)
1449 var_arg
->next
= expr2
->value
.function
.actual
;
1450 expr2
->value
.function
.actual
= var_arg
;
1455 gfc_error ("!$OMP ATOMIC assignment must have an operator or intrinsic "
1456 "on right hand side at %L", &expr2
->where
);
1458 if (atomic_code
->ext
.omp_atomic
== GFC_OMP_ATOMIC_CAPTURE
&& code
->next
)
1461 if (code
->expr1
->expr_type
!= EXPR_VARIABLE
1462 || code
->expr1
->symtree
== NULL
1463 || code
->expr1
->rank
!= 0
1464 || (code
->expr1
->ts
.type
!= BT_INTEGER
1465 && code
->expr1
->ts
.type
!= BT_REAL
1466 && code
->expr1
->ts
.type
!= BT_COMPLEX
1467 && code
->expr1
->ts
.type
!= BT_LOGICAL
))
1469 gfc_error ("!$OMP ATOMIC CAPTURE capture statement must set "
1470 "a scalar variable of intrinsic type at %L",
1471 &code
->expr1
->where
);
1475 expr2
= is_conversion (code
->expr2
, false);
1478 expr2
= is_conversion (code
->expr2
, true);
1480 expr2
= code
->expr2
;
1483 if (expr2
->expr_type
!= EXPR_VARIABLE
1484 || expr2
->symtree
== NULL
1486 || (expr2
->ts
.type
!= BT_INTEGER
1487 && expr2
->ts
.type
!= BT_REAL
1488 && expr2
->ts
.type
!= BT_COMPLEX
1489 && expr2
->ts
.type
!= BT_LOGICAL
))
1491 gfc_error ("!$OMP ATOMIC CAPTURE capture statement must read "
1492 "from a scalar variable of intrinsic type at %L",
1496 if (expr2
->symtree
->n
.sym
!= var
)
1498 gfc_error ("!$OMP ATOMIC CAPTURE capture statement reads from "
1499 "different variable than update statement writes "
1500 "into at %L", &expr2
->where
);
1510 struct pointer_set_t
*sharing_clauses
;
1511 struct pointer_set_t
*private_iterators
;
1512 struct omp_context
*previous
;
1514 static gfc_code
*omp_current_do_code
;
1515 static int omp_current_do_collapse
;
1518 gfc_resolve_omp_do_blocks (gfc_code
*code
, gfc_namespace
*ns
)
1520 if (code
->block
->next
&& code
->block
->next
->op
== EXEC_DO
)
1525 omp_current_do_code
= code
->block
->next
;
1526 omp_current_do_collapse
= code
->ext
.omp_clauses
->collapse
;
1527 for (i
= 1, c
= omp_current_do_code
; i
< omp_current_do_collapse
; i
++)
1530 if (c
->op
!= EXEC_DO
|| c
->next
== NULL
)
1533 if (c
->op
!= EXEC_DO
)
1536 if (i
< omp_current_do_collapse
|| omp_current_do_collapse
<= 0)
1537 omp_current_do_collapse
= 1;
1539 gfc_resolve_blocks (code
->block
, ns
);
1540 omp_current_do_collapse
= 0;
1541 omp_current_do_code
= NULL
;
1546 gfc_resolve_omp_parallel_blocks (gfc_code
*code
, gfc_namespace
*ns
)
1548 struct omp_context ctx
;
1549 gfc_omp_clauses
*omp_clauses
= code
->ext
.omp_clauses
;
1554 ctx
.sharing_clauses
= pointer_set_create ();
1555 ctx
.private_iterators
= pointer_set_create ();
1556 ctx
.previous
= omp_current_ctx
;
1557 omp_current_ctx
= &ctx
;
1559 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
1560 for (n
= omp_clauses
->lists
[list
]; n
; n
= n
->next
)
1561 pointer_set_insert (ctx
.sharing_clauses
, n
->sym
);
1563 if (code
->op
== EXEC_OMP_PARALLEL_DO
)
1564 gfc_resolve_omp_do_blocks (code
, ns
);
1566 gfc_resolve_blocks (code
->block
, ns
);
1568 omp_current_ctx
= ctx
.previous
;
1569 pointer_set_destroy (ctx
.sharing_clauses
);
1570 pointer_set_destroy (ctx
.private_iterators
);
1574 /* Save and clear openmp.c private state. */
1577 gfc_omp_save_and_clear_state (struct gfc_omp_saved_state
*state
)
1579 state
->ptrs
[0] = omp_current_ctx
;
1580 state
->ptrs
[1] = omp_current_do_code
;
1581 state
->ints
[0] = omp_current_do_collapse
;
1582 omp_current_ctx
= NULL
;
1583 omp_current_do_code
= NULL
;
1584 omp_current_do_collapse
= 0;
1588 /* Restore openmp.c private state from the saved state. */
1591 gfc_omp_restore_state (struct gfc_omp_saved_state
*state
)
1593 omp_current_ctx
= (struct omp_context
*) state
->ptrs
[0];
1594 omp_current_do_code
= (gfc_code
*) state
->ptrs
[1];
1595 omp_current_do_collapse
= state
->ints
[0];
1599 /* Note a DO iterator variable. This is special in !$omp parallel
1600 construct, where they are predetermined private. */
1603 gfc_resolve_do_iterator (gfc_code
*code
, gfc_symbol
*sym
)
1605 int i
= omp_current_do_collapse
;
1606 gfc_code
*c
= omp_current_do_code
;
1608 if (sym
->attr
.threadprivate
)
1611 /* !$omp do and !$omp parallel do iteration variable is predetermined
1612 private just in the !$omp do resp. !$omp parallel do construct,
1613 with no implications for the outer parallel constructs. */
1623 if (omp_current_ctx
== NULL
)
1626 if (pointer_set_contains (omp_current_ctx
->sharing_clauses
, sym
))
1629 if (! pointer_set_insert (omp_current_ctx
->private_iterators
, sym
))
1631 gfc_omp_clauses
*omp_clauses
= omp_current_ctx
->code
->ext
.omp_clauses
;
1634 p
= gfc_get_namelist ();
1636 p
->next
= omp_clauses
->lists
[OMP_LIST_PRIVATE
];
1637 omp_clauses
->lists
[OMP_LIST_PRIVATE
] = p
;
1643 resolve_omp_do (gfc_code
*code
)
1645 gfc_code
*do_code
, *c
;
1646 int list
, i
, collapse
;
1650 if (code
->ext
.omp_clauses
)
1651 resolve_omp_clauses (code
);
1653 do_code
= code
->block
->next
;
1654 collapse
= code
->ext
.omp_clauses
->collapse
;
1657 for (i
= 1; i
<= collapse
; i
++)
1659 if (do_code
->op
== EXEC_DO_WHILE
)
1661 gfc_error ("!$OMP DO cannot be a DO WHILE or DO without loop control "
1662 "at %L", &do_code
->loc
);
1665 gcc_assert (do_code
->op
== EXEC_DO
);
1666 if (do_code
->ext
.iterator
->var
->ts
.type
!= BT_INTEGER
)
1667 gfc_error ("!$OMP DO iteration variable must be of type integer at %L",
1669 dovar
= do_code
->ext
.iterator
->var
->symtree
->n
.sym
;
1670 if (dovar
->attr
.threadprivate
)
1671 gfc_error ("!$OMP DO iteration variable must not be THREADPRIVATE "
1672 "at %L", &do_code
->loc
);
1673 if (code
->ext
.omp_clauses
)
1674 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
1675 if (list
!= OMP_LIST_PRIVATE
&& list
!= OMP_LIST_LASTPRIVATE
)
1676 for (n
= code
->ext
.omp_clauses
->lists
[list
]; n
; n
= n
->next
)
1677 if (dovar
== n
->sym
)
1679 gfc_error ("!$OMP DO iteration variable present on clause "
1680 "other than PRIVATE or LASTPRIVATE at %L",
1686 gfc_code
*do_code2
= code
->block
->next
;
1689 for (j
= 1; j
< i
; j
++)
1691 gfc_symbol
*ivar
= do_code2
->ext
.iterator
->var
->symtree
->n
.sym
;
1693 || gfc_find_sym_in_expr (ivar
, do_code
->ext
.iterator
->start
)
1694 || gfc_find_sym_in_expr (ivar
, do_code
->ext
.iterator
->end
)
1695 || gfc_find_sym_in_expr (ivar
, do_code
->ext
.iterator
->step
))
1697 gfc_error ("!$OMP DO collapsed loops don't form rectangular iteration space at %L",
1703 do_code2
= do_code2
->block
->next
;
1708 for (c
= do_code
->next
; c
; c
= c
->next
)
1709 if (c
->op
!= EXEC_NOP
&& c
->op
!= EXEC_CONTINUE
)
1711 gfc_error ("collapsed !$OMP DO loops not perfectly nested at %L",
1717 do_code
= do_code
->block
;
1718 if (do_code
->op
!= EXEC_DO
&& do_code
->op
!= EXEC_DO_WHILE
)
1720 gfc_error ("not enough DO loops for collapsed !$OMP DO at %L",
1724 do_code
= do_code
->next
;
1726 || (do_code
->op
!= EXEC_DO
&& do_code
->op
!= EXEC_DO_WHILE
))
1728 gfc_error ("not enough DO loops for collapsed !$OMP DO at %L",
1736 /* Resolve OpenMP directive clauses and check various requirements
1737 of each directive. */
1740 gfc_resolve_omp_directive (gfc_code
*code
, gfc_namespace
*ns ATTRIBUTE_UNUSED
)
1742 if (code
->op
!= EXEC_OMP_ATOMIC
)
1743 gfc_maybe_initialize_eh ();
1748 case EXEC_OMP_PARALLEL_DO
:
1749 resolve_omp_do (code
);
1751 case EXEC_OMP_WORKSHARE
:
1752 case EXEC_OMP_PARALLEL_WORKSHARE
:
1753 case EXEC_OMP_PARALLEL
:
1754 case EXEC_OMP_PARALLEL_SECTIONS
:
1755 case EXEC_OMP_SECTIONS
:
1756 case EXEC_OMP_SINGLE
:
1758 if (code
->ext
.omp_clauses
)
1759 resolve_omp_clauses (code
);
1761 case EXEC_OMP_ATOMIC
:
1762 resolve_omp_atomic (code
);