1 /* OpenMP directive matching and resolving.
2 Copyright (C) 2005-2020 Free Software Foundation, Inc.
3 Contributed by Jakub Jelinek
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
23 #include "coretypes.h"
28 #include "diagnostic.h"
29 #include "gomp-constants.h"
31 /* Match an end of OpenMP directive. End of OpenMP directive is optional
32 whitespace, followed by '\n' or comment '!'. */
35 gfc_match_omp_eos (void)
40 old_loc
= gfc_current_locus
;
41 gfc_gobble_whitespace ();
43 c
= gfc_next_ascii_char ();
48 c
= gfc_next_ascii_char ();
56 gfc_current_locus
= old_loc
;
61 gfc_match_omp_eos_error (void)
63 if (gfc_match_omp_eos() == MATCH_YES
)
66 gfc_error ("Unexpected junk at %C");
71 /* Free an omp_clauses structure. */
74 gfc_free_omp_clauses (gfc_omp_clauses
*c
)
80 gfc_free_expr (c
->if_expr
);
81 gfc_free_expr (c
->final_expr
);
82 gfc_free_expr (c
->num_threads
);
83 gfc_free_expr (c
->chunk_size
);
84 gfc_free_expr (c
->safelen_expr
);
85 gfc_free_expr (c
->simdlen_expr
);
86 gfc_free_expr (c
->num_teams
);
87 gfc_free_expr (c
->device
);
88 gfc_free_expr (c
->thread_limit
);
89 gfc_free_expr (c
->dist_chunk_size
);
90 gfc_free_expr (c
->grainsize
);
91 gfc_free_expr (c
->hint
);
92 gfc_free_expr (c
->num_tasks
);
93 gfc_free_expr (c
->priority
);
94 for (i
= 0; i
< OMP_IF_LAST
; i
++)
95 gfc_free_expr (c
->if_exprs
[i
]);
96 gfc_free_expr (c
->async_expr
);
97 gfc_free_expr (c
->gang_num_expr
);
98 gfc_free_expr (c
->gang_static_expr
);
99 gfc_free_expr (c
->worker_expr
);
100 gfc_free_expr (c
->vector_expr
);
101 gfc_free_expr (c
->num_gangs_expr
);
102 gfc_free_expr (c
->num_workers_expr
);
103 gfc_free_expr (c
->vector_length_expr
);
104 for (i
= 0; i
< OMP_LIST_NUM
; i
++)
105 gfc_free_omp_namelist (c
->lists
[i
]);
106 gfc_free_expr_list (c
->wait_list
);
107 gfc_free_expr_list (c
->tile_list
);
108 free (CONST_CAST (char *, c
->critical_name
));
112 /* Free oacc_declare structures. */
115 gfc_free_oacc_declare_clauses (struct gfc_oacc_declare
*oc
)
117 struct gfc_oacc_declare
*decl
= oc
;
121 struct gfc_oacc_declare
*next
;
124 gfc_free_omp_clauses (decl
->clauses
);
131 /* Free expression list. */
133 gfc_free_expr_list (gfc_expr_list
*list
)
137 for (; list
; list
= n
)
144 /* Free an !$omp declare simd construct list. */
147 gfc_free_omp_declare_simd (gfc_omp_declare_simd
*ods
)
151 gfc_free_omp_clauses (ods
->clauses
);
157 gfc_free_omp_declare_simd_list (gfc_omp_declare_simd
*list
)
161 gfc_omp_declare_simd
*current
= list
;
163 gfc_free_omp_declare_simd (current
);
167 /* Free an !$omp declare reduction. */
170 gfc_free_omp_udr (gfc_omp_udr
*omp_udr
)
174 gfc_free_omp_udr (omp_udr
->next
);
175 gfc_free_namespace (omp_udr
->combiner_ns
);
176 if (omp_udr
->initializer_ns
)
177 gfc_free_namespace (omp_udr
->initializer_ns
);
184 gfc_find_omp_udr (gfc_namespace
*ns
, const char *name
, gfc_typespec
*ts
)
192 gfc_omp_udr
*omp_udr
;
194 st
= gfc_find_symtree (ns
->omp_udr_root
, name
);
197 for (omp_udr
= st
->n
.omp_udr
; omp_udr
; omp_udr
= omp_udr
->next
)
200 else if (gfc_compare_types (&omp_udr
->ts
, ts
))
202 if (ts
->type
== BT_CHARACTER
)
204 if (omp_udr
->ts
.u
.cl
->length
== NULL
)
206 if (ts
->u
.cl
->length
== NULL
)
208 if (gfc_compare_expr (omp_udr
->ts
.u
.cl
->length
,
217 /* Don't escape an interface block. */
218 if (ns
&& !ns
->has_import_set
219 && ns
->proc_name
&& ns
->proc_name
->attr
.if_source
== IFSRC_IFBODY
)
230 /* Match a variable/common block list and construct a namelist from it. */
233 gfc_match_omp_variable_list (const char *str
, gfc_omp_namelist
**list
,
234 bool allow_common
, bool *end_colon
= NULL
,
235 gfc_omp_namelist
***headp
= NULL
,
236 bool allow_sections
= false,
237 bool allow_derived
= false)
239 gfc_omp_namelist
*head
, *tail
, *p
;
240 locus old_loc
, cur_loc
;
241 char n
[GFC_MAX_SYMBOL_LEN
+1];
248 old_loc
= gfc_current_locus
;
256 cur_loc
= gfc_current_locus
;
257 m
= gfc_match_symbol (&sym
, 1);
263 if ((allow_sections
&& gfc_peek_ascii_char () == '(')
264 || (allow_derived
&& gfc_peek_ascii_char () == '%'))
266 gfc_current_locus
= cur_loc
;
267 m
= gfc_match_variable (&expr
, 0);
277 if (gfc_is_coindexed (expr
))
279 gfc_error ("List item shall not be coindexed at %C");
283 gfc_set_sym_referenced (sym
);
284 p
= gfc_get_omp_namelist ();
294 tail
->where
= cur_loc
;
305 m
= gfc_match (" / %n /", n
);
306 if (m
== MATCH_ERROR
)
311 st
= gfc_find_symtree (gfc_current_ns
->common_root
, n
);
314 gfc_error ("COMMON block /%s/ not found at %C", n
);
317 for (sym
= st
->n
.common
->head
; sym
; sym
= sym
->common_next
)
319 gfc_set_sym_referenced (sym
);
320 p
= gfc_get_omp_namelist ();
329 tail
->where
= cur_loc
;
333 if (end_colon
&& gfc_match_char (':') == MATCH_YES
)
338 if (gfc_match_char (')') == MATCH_YES
)
340 if (gfc_match_char (',') != MATCH_YES
)
345 list
= &(*list
)->next
;
353 gfc_error ("Syntax error in OpenMP variable list at %C");
356 gfc_free_omp_namelist (head
);
357 gfc_current_locus
= old_loc
;
361 /* Match a variable/procedure/common block list and construct a namelist
365 gfc_match_omp_to_link (const char *str
, gfc_omp_namelist
**list
)
367 gfc_omp_namelist
*head
, *tail
, *p
;
368 locus old_loc
, cur_loc
;
369 char n
[GFC_MAX_SYMBOL_LEN
+1];
376 old_loc
= gfc_current_locus
;
384 cur_loc
= gfc_current_locus
;
385 m
= gfc_match_symbol (&sym
, 1);
389 p
= gfc_get_omp_namelist ();
398 tail
->where
= cur_loc
;
406 m
= gfc_match (" / %n /", n
);
407 if (m
== MATCH_ERROR
)
412 st
= gfc_find_symtree (gfc_current_ns
->common_root
, n
);
415 gfc_error ("COMMON block /%s/ not found at %C", n
);
418 p
= gfc_get_omp_namelist ();
426 tail
->u
.common
= st
->n
.common
;
427 tail
->where
= cur_loc
;
430 if (gfc_match_char (')') == MATCH_YES
)
432 if (gfc_match_char (',') != MATCH_YES
)
437 list
= &(*list
)->next
;
443 gfc_error ("Syntax error in OpenMP variable list at %C");
446 gfc_free_omp_namelist (head
);
447 gfc_current_locus
= old_loc
;
451 /* Match depend(sink : ...) construct a namelist from it. */
454 gfc_match_omp_depend_sink (gfc_omp_namelist
**list
)
456 gfc_omp_namelist
*head
, *tail
, *p
;
457 locus old_loc
, cur_loc
;
462 old_loc
= gfc_current_locus
;
466 cur_loc
= gfc_current_locus
;
467 switch (gfc_match_symbol (&sym
, 1))
470 gfc_set_sym_referenced (sym
);
471 p
= gfc_get_omp_namelist ();
475 head
->u
.depend_op
= OMP_DEPEND_SINK_FIRST
;
481 tail
->u
.depend_op
= OMP_DEPEND_SINK
;
485 tail
->where
= cur_loc
;
486 if (gfc_match_char ('+') == MATCH_YES
)
488 if (gfc_match_literal_constant (&tail
->expr
, 0) != MATCH_YES
)
491 else if (gfc_match_char ('-') == MATCH_YES
)
493 if (gfc_match_literal_constant (&tail
->expr
, 0) != MATCH_YES
)
495 tail
->expr
= gfc_uminus (tail
->expr
);
504 if (gfc_match_char (')') == MATCH_YES
)
506 if (gfc_match_char (',') != MATCH_YES
)
511 list
= &(*list
)->next
;
517 gfc_error ("Syntax error in OpenMP DEPEND SINK list at %C");
520 gfc_free_omp_namelist (head
);
521 gfc_current_locus
= old_loc
;
526 match_oacc_expr_list (const char *str
, gfc_expr_list
**list
,
529 gfc_expr_list
*head
, *tail
, *p
;
536 old_loc
= gfc_current_locus
;
544 m
= gfc_match_expr (&expr
);
545 if (m
== MATCH_YES
|| allow_asterisk
)
547 p
= gfc_get_expr_list ();
557 else if (gfc_match (" *") != MATCH_YES
)
561 if (m
== MATCH_ERROR
)
566 if (gfc_match_char (')') == MATCH_YES
)
568 if (gfc_match_char (',') != MATCH_YES
)
573 list
= &(*list
)->next
;
579 gfc_error ("Syntax error in OpenACC expression list at %C");
582 gfc_free_expr_list (head
);
583 gfc_current_locus
= old_loc
;
588 match_oacc_clause_gwv (gfc_omp_clauses
*cp
, unsigned gwv
)
590 match ret
= MATCH_YES
;
592 if (gfc_match (" ( ") != MATCH_YES
)
595 if (gwv
== GOMP_DIM_GANG
)
597 /* The gang clause accepts two optional arguments, num and static.
598 The num argument may either be explicit (num: <val>) or
599 implicit without (<val> without num:). */
601 while (ret
== MATCH_YES
)
603 if (gfc_match (" static :") == MATCH_YES
)
608 cp
->gang_static
= true;
609 if (gfc_match_char ('*') == MATCH_YES
)
610 cp
->gang_static_expr
= NULL
;
611 else if (gfc_match (" %e ", &cp
->gang_static_expr
) != MATCH_YES
)
616 if (cp
->gang_num_expr
)
619 /* The 'num' argument is optional. */
620 gfc_match (" num :");
622 if (gfc_match (" %e ", &cp
->gang_num_expr
) != MATCH_YES
)
626 ret
= gfc_match (" , ");
629 else if (gwv
== GOMP_DIM_WORKER
)
631 /* The 'num' argument is optional. */
632 gfc_match (" num :");
634 if (gfc_match (" %e ", &cp
->worker_expr
) != MATCH_YES
)
637 else if (gwv
== GOMP_DIM_VECTOR
)
639 /* The 'length' argument is optional. */
640 gfc_match (" length :");
642 if (gfc_match (" %e ", &cp
->vector_expr
) != MATCH_YES
)
646 gfc_fatal_error ("Unexpected OpenACC parallelism.");
648 return gfc_match (" )");
652 gfc_match_oacc_clause_link (const char *str
, gfc_omp_namelist
**list
)
654 gfc_omp_namelist
*head
= NULL
;
655 gfc_omp_namelist
*tail
, *p
;
657 char n
[GFC_MAX_SYMBOL_LEN
+1];
662 old_loc
= gfc_current_locus
;
668 m
= gfc_match (" (");
672 m
= gfc_match_symbol (&sym
, 0);
676 if (sym
->attr
.in_common
)
678 gfc_error_now ("Variable at %C is an element of a COMMON block");
681 gfc_set_sym_referenced (sym
);
682 p
= gfc_get_omp_namelist ();
692 tail
->where
= gfc_current_locus
;
701 m
= gfc_match (" / %n /", n
);
702 if (m
== MATCH_ERROR
)
704 if (m
== MATCH_NO
|| n
[0] == '\0')
707 st
= gfc_find_symtree (gfc_current_ns
->common_root
, n
);
710 gfc_error ("COMMON block /%s/ not found at %C", n
);
714 for (sym
= st
->n
.common
->head
; sym
; sym
= sym
->common_next
)
716 gfc_set_sym_referenced (sym
);
717 p
= gfc_get_omp_namelist ();
726 tail
->where
= gfc_current_locus
;
730 if (gfc_match_char (')') == MATCH_YES
)
732 if (gfc_match_char (',') != MATCH_YES
)
736 if (gfc_match_omp_eos () != MATCH_YES
)
738 gfc_error ("Unexpected junk after !$ACC DECLARE at %C");
743 list
= &(*list
)->next
;
748 gfc_error ("Syntax error in !$ACC DECLARE list at %C");
751 gfc_current_locus
= old_loc
;
755 /* OpenMP 4.5 clauses. */
759 OMP_CLAUSE_FIRSTPRIVATE
,
760 OMP_CLAUSE_LASTPRIVATE
,
761 OMP_CLAUSE_COPYPRIVATE
,
764 OMP_CLAUSE_REDUCTION
,
766 OMP_CLAUSE_NUM_THREADS
,
774 OMP_CLAUSE_MERGEABLE
,
779 OMP_CLAUSE_NOTINBRANCH
,
780 OMP_CLAUSE_PROC_BIND
,
788 OMP_CLAUSE_NUM_TEAMS
,
789 OMP_CLAUSE_THREAD_LIMIT
,
790 OMP_CLAUSE_DIST_SCHEDULE
,
791 OMP_CLAUSE_DEFAULTMAP
,
792 OMP_CLAUSE_GRAINSIZE
,
794 OMP_CLAUSE_IS_DEVICE_PTR
,
797 OMP_CLAUSE_NOTEMPORAL
,
798 OMP_CLAUSE_NUM_TASKS
,
802 OMP_CLAUSE_USE_DEVICE_PTR
,
803 OMP_CLAUSE_USE_DEVICE_ADDR
, /* Actually, OpenMP 5.0. */
805 /* This must come last. */
809 /* OpenACC 2.0+ specific clauses. */
813 OMP_CLAUSE_NUM_GANGS
,
814 OMP_CLAUSE_NUM_WORKERS
,
815 OMP_CLAUSE_VECTOR_LENGTH
,
819 OMP_CLAUSE_NO_CREATE
,
821 OMP_CLAUSE_DEVICEPTR
,
826 OMP_CLAUSE_INDEPENDENT
,
827 OMP_CLAUSE_USE_DEVICE
,
828 OMP_CLAUSE_DEVICE_RESIDENT
,
829 OMP_CLAUSE_HOST_SELF
,
834 OMP_CLAUSE_IF_PRESENT
,
838 /* This must come last. */
844 /* Customized bitset for up to 128-bits.
845 The two enums above provide bit numbers to use, and which of the
846 two enums it is determines which of the two mask fields is used.
847 Supported operations are defining a mask, like:
848 #define XXX_CLAUSES \
849 (omp_mask (OMP_CLAUSE_XXX) | OMP_CLAUSE_YYY | OMP_CLAUSE_ZZZ)
850 oring such bitsets together or removing selected bits:
851 (XXX_CLAUSES | YYY_CLAUSES) & ~(omp_mask (OMP_CLAUSE_VVV))
852 and testing individual bits:
853 if (mask & OMP_CLAUSE_UUU) */
856 const uint64_t mask1
;
857 const uint64_t mask2
;
859 inline omp_mask (omp_mask1
);
860 inline omp_mask (omp_mask2
);
861 inline omp_mask (uint64_t, uint64_t);
862 inline omp_mask
operator| (omp_mask1
) const;
863 inline omp_mask
operator| (omp_mask2
) const;
864 inline omp_mask
operator| (omp_mask
) const;
865 inline omp_mask
operator& (const omp_inv_mask
&) const;
866 inline bool operator& (omp_mask1
) const;
867 inline bool operator& (omp_mask2
) const;
868 inline omp_inv_mask
operator~ () const;
871 struct omp_inv_mask
: public omp_mask
{
872 inline omp_inv_mask (const omp_mask
&);
875 omp_mask::omp_mask () : mask1 (0), mask2 (0)
879 omp_mask::omp_mask (omp_mask1 m
) : mask1 (((uint64_t) 1) << m
), mask2 (0)
883 omp_mask::omp_mask (omp_mask2 m
) : mask1 (0), mask2 (((uint64_t) 1) << m
)
887 omp_mask::omp_mask (uint64_t m1
, uint64_t m2
) : mask1 (m1
), mask2 (m2
)
892 omp_mask::operator| (omp_mask1 m
) const
894 return omp_mask (mask1
| (((uint64_t) 1) << m
), mask2
);
898 omp_mask::operator| (omp_mask2 m
) const
900 return omp_mask (mask1
, mask2
| (((uint64_t) 1) << m
));
904 omp_mask::operator| (omp_mask m
) const
906 return omp_mask (mask1
| m
.mask1
, mask2
| m
.mask2
);
910 omp_mask::operator& (const omp_inv_mask
&m
) const
912 return omp_mask (mask1
& ~m
.mask1
, mask2
& ~m
.mask2
);
916 omp_mask::operator& (omp_mask1 m
) const
918 return (mask1
& (((uint64_t) 1) << m
)) != 0;
922 omp_mask::operator& (omp_mask2 m
) const
924 return (mask2
& (((uint64_t) 1) << m
)) != 0;
928 omp_mask::operator~ () const
930 return omp_inv_mask (*this);
933 omp_inv_mask::omp_inv_mask (const omp_mask
&m
) : omp_mask (m
)
937 /* Helper function for OpenACC and OpenMP clauses involving memory
941 gfc_match_omp_map_clause (gfc_omp_namelist
**list
, gfc_omp_map_op map_op
,
942 bool allow_common
, bool allow_derived
)
944 gfc_omp_namelist
**head
= NULL
;
945 if (gfc_match_omp_variable_list ("", list
, allow_common
, NULL
, &head
, true,
950 for (n
= *head
; n
; n
= n
->next
)
951 n
->u
.map_op
= map_op
;
958 /* Match OpenMP and OpenACC directive clauses. MASK is a bitmask of
959 clauses that are allowed for a particular directive. */
962 gfc_match_omp_clauses (gfc_omp_clauses
**cp
, const omp_mask mask
,
963 bool first
= true, bool needs_space
= true,
964 bool openacc
= false)
966 gfc_omp_clauses
*c
= gfc_get_omp_clauses ();
968 /* Determine whether we're dealing with an OpenACC directive that permits
969 derived type member accesses. This in particular disallows
970 "!$acc declare" from using such accesses, because it's not clear if/how
972 bool allow_derived
= (openacc
973 && ((mask
& OMP_CLAUSE_ATTACH
)
974 || (mask
& OMP_CLAUSE_DETACH
)
975 || (mask
& OMP_CLAUSE_HOST_SELF
)));
977 gcc_checking_assert (OMP_MASK1_LAST
<= 64 && OMP_MASK2_LAST
<= 64);
981 if ((first
|| gfc_match_char (',') != MATCH_YES
)
982 && (needs_space
&& gfc_match_space () != MATCH_YES
))
986 gfc_gobble_whitespace ();
988 gfc_omp_namelist
**head
;
989 old_loc
= gfc_current_locus
;
990 char pc
= gfc_peek_ascii_char ();
996 if ((mask
& OMP_CLAUSE_ALIGNED
)
997 && gfc_match_omp_variable_list ("aligned (",
998 &c
->lists
[OMP_LIST_ALIGNED
],
1000 &head
) == MATCH_YES
)
1002 gfc_expr
*alignment
= NULL
;
1003 gfc_omp_namelist
*n
;
1005 if (end_colon
&& gfc_match (" %e )", &alignment
) != MATCH_YES
)
1007 gfc_free_omp_namelist (*head
);
1008 gfc_current_locus
= old_loc
;
1012 for (n
= *head
; n
; n
= n
->next
)
1013 if (n
->next
&& alignment
)
1014 n
->expr
= gfc_copy_expr (alignment
);
1016 n
->expr
= alignment
;
1019 if ((mask
& OMP_CLAUSE_ASYNC
)
1021 && gfc_match ("async") == MATCH_YES
)
1024 match m
= gfc_match (" ( %e )", &c
->async_expr
);
1025 if (m
== MATCH_ERROR
)
1027 gfc_current_locus
= old_loc
;
1030 else if (m
== MATCH_NO
)
1033 = gfc_get_constant_expr (BT_INTEGER
,
1034 gfc_default_integer_kind
,
1035 &gfc_current_locus
);
1036 mpz_set_si (c
->async_expr
->value
.integer
, GOMP_ASYNC_NOVAL
);
1041 if ((mask
& OMP_CLAUSE_AUTO
)
1043 && gfc_match ("auto") == MATCH_YES
)
1049 if ((mask
& OMP_CLAUSE_ATTACH
)
1050 && gfc_match ("attach ( ") == MATCH_YES
1051 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1052 OMP_MAP_ATTACH
, false,
1057 if ((mask
& OMP_CLAUSE_COLLAPSE
)
1060 gfc_expr
*cexpr
= NULL
;
1061 match m
= gfc_match ("collapse ( %e )", &cexpr
);
1066 if (gfc_extract_int (cexpr
, &collapse
, -1))
1068 else if (collapse
<= 0)
1070 gfc_error_now ("COLLAPSE clause argument not"
1071 " constant positive integer at %C");
1074 c
->collapse
= collapse
;
1075 gfc_free_expr (cexpr
);
1079 if ((mask
& OMP_CLAUSE_COPY
)
1080 && gfc_match ("copy ( ") == MATCH_YES
1081 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1082 OMP_MAP_TOFROM
, true,
1085 if (mask
& OMP_CLAUSE_COPYIN
)
1089 if (gfc_match ("copyin ( ") == MATCH_YES
1090 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1095 else if (gfc_match_omp_variable_list ("copyin (",
1096 &c
->lists
[OMP_LIST_COPYIN
],
1100 if ((mask
& OMP_CLAUSE_COPYOUT
)
1101 && gfc_match ("copyout ( ") == MATCH_YES
1102 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1103 OMP_MAP_FROM
, true, allow_derived
))
1105 if ((mask
& OMP_CLAUSE_COPYPRIVATE
)
1106 && gfc_match_omp_variable_list ("copyprivate (",
1107 &c
->lists
[OMP_LIST_COPYPRIVATE
],
1110 if ((mask
& OMP_CLAUSE_CREATE
)
1111 && gfc_match ("create ( ") == MATCH_YES
1112 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1113 OMP_MAP_ALLOC
, true, allow_derived
))
1117 if ((mask
& OMP_CLAUSE_DEFAULT
)
1118 && c
->default_sharing
== OMP_DEFAULT_UNKNOWN
)
1120 if (gfc_match ("default ( none )") == MATCH_YES
)
1121 c
->default_sharing
= OMP_DEFAULT_NONE
;
1124 if (gfc_match ("default ( present )") == MATCH_YES
)
1125 c
->default_sharing
= OMP_DEFAULT_PRESENT
;
1129 if (gfc_match ("default ( firstprivate )") == MATCH_YES
)
1130 c
->default_sharing
= OMP_DEFAULT_FIRSTPRIVATE
;
1131 else if (gfc_match ("default ( private )") == MATCH_YES
)
1132 c
->default_sharing
= OMP_DEFAULT_PRIVATE
;
1133 else if (gfc_match ("default ( shared )") == MATCH_YES
)
1134 c
->default_sharing
= OMP_DEFAULT_SHARED
;
1136 if (c
->default_sharing
!= OMP_DEFAULT_UNKNOWN
)
1139 if ((mask
& OMP_CLAUSE_DEFAULTMAP
)
1141 && gfc_match ("defaultmap ( tofrom : scalar )") == MATCH_YES
)
1143 c
->defaultmap
= true;
1146 if ((mask
& OMP_CLAUSE_DELETE
)
1147 && gfc_match ("delete ( ") == MATCH_YES
1148 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1149 OMP_MAP_RELEASE
, true,
1152 if ((mask
& OMP_CLAUSE_DEPEND
)
1153 && gfc_match ("depend ( ") == MATCH_YES
)
1155 match m
= MATCH_YES
;
1156 gfc_omp_depend_op depend_op
= OMP_DEPEND_OUT
;
1157 if (gfc_match ("inout") == MATCH_YES
)
1158 depend_op
= OMP_DEPEND_INOUT
;
1159 else if (gfc_match ("in") == MATCH_YES
)
1160 depend_op
= OMP_DEPEND_IN
;
1161 else if (gfc_match ("out") == MATCH_YES
)
1162 depend_op
= OMP_DEPEND_OUT
;
1163 else if (!c
->depend_source
1164 && gfc_match ("source )") == MATCH_YES
)
1166 c
->depend_source
= true;
1169 else if (gfc_match ("sink : ") == MATCH_YES
)
1171 if (gfc_match_omp_depend_sink (&c
->lists
[OMP_LIST_DEPEND
])
1180 && gfc_match_omp_variable_list (" : ",
1181 &c
->lists
[OMP_LIST_DEPEND
],
1185 gfc_omp_namelist
*n
;
1186 for (n
= *head
; n
; n
= n
->next
)
1187 n
->u
.depend_op
= depend_op
;
1191 gfc_current_locus
= old_loc
;
1193 if ((mask
& OMP_CLAUSE_DETACH
)
1194 && gfc_match ("detach ( ") == MATCH_YES
1195 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1196 OMP_MAP_DETACH
, false,
1199 if ((mask
& OMP_CLAUSE_DEVICE
)
1201 && c
->device
== NULL
1202 && gfc_match ("device ( %e )", &c
->device
) == MATCH_YES
)
1204 if ((mask
& OMP_CLAUSE_DEVICE
)
1206 && gfc_match ("device ( ") == MATCH_YES
1207 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1208 OMP_MAP_FORCE_TO
, true,
1211 if ((mask
& OMP_CLAUSE_DEVICEPTR
)
1212 && gfc_match ("deviceptr ( ") == MATCH_YES
1213 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1214 OMP_MAP_FORCE_DEVICEPTR
, false,
1217 if ((mask
& OMP_CLAUSE_DEVICE_RESIDENT
)
1218 && gfc_match_omp_variable_list
1219 ("device_resident (",
1220 &c
->lists
[OMP_LIST_DEVICE_RESIDENT
], true) == MATCH_YES
)
1222 if ((mask
& OMP_CLAUSE_DIST_SCHEDULE
)
1223 && c
->dist_sched_kind
== OMP_SCHED_NONE
1224 && gfc_match ("dist_schedule ( static") == MATCH_YES
)
1227 c
->dist_sched_kind
= OMP_SCHED_STATIC
;
1228 m
= gfc_match (" , %e )", &c
->dist_chunk_size
);
1230 m
= gfc_match_char (')');
1233 c
->dist_sched_kind
= OMP_SCHED_NONE
;
1234 gfc_current_locus
= old_loc
;
1241 if ((mask
& OMP_CLAUSE_FINAL
)
1242 && c
->final_expr
== NULL
1243 && gfc_match ("final ( %e )", &c
->final_expr
) == MATCH_YES
)
1245 if ((mask
& OMP_CLAUSE_FINALIZE
)
1247 && gfc_match ("finalize") == MATCH_YES
)
1253 if ((mask
& OMP_CLAUSE_FIRSTPRIVATE
)
1254 && gfc_match_omp_variable_list ("firstprivate (",
1255 &c
->lists
[OMP_LIST_FIRSTPRIVATE
],
1258 if ((mask
& OMP_CLAUSE_FROM
)
1259 && gfc_match_omp_variable_list ("from (",
1260 &c
->lists
[OMP_LIST_FROM
], false,
1261 NULL
, &head
, true) == MATCH_YES
)
1265 if ((mask
& OMP_CLAUSE_GANG
)
1267 && gfc_match ("gang") == MATCH_YES
)
1270 match m
= match_oacc_clause_gwv (c
, GOMP_DIM_GANG
);
1271 if (m
== MATCH_ERROR
)
1273 gfc_current_locus
= old_loc
;
1276 else if (m
== MATCH_NO
)
1280 if ((mask
& OMP_CLAUSE_GRAINSIZE
)
1281 && c
->grainsize
== NULL
1282 && gfc_match ("grainsize ( %e )", &c
->grainsize
) == MATCH_YES
)
1286 if ((mask
& OMP_CLAUSE_HINT
)
1288 && gfc_match ("hint ( %e )", &c
->hint
) == MATCH_YES
)
1290 if ((mask
& OMP_CLAUSE_HOST_SELF
)
1291 && gfc_match ("host ( ") == MATCH_YES
1292 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1293 OMP_MAP_FORCE_FROM
, true,
1298 if ((mask
& OMP_CLAUSE_IF
)
1299 && c
->if_expr
== NULL
1300 && gfc_match ("if ( ") == MATCH_YES
)
1302 if (gfc_match ("%e )", &c
->if_expr
) == MATCH_YES
)
1306 /* This should match the enum gfc_omp_if_kind order. */
1307 static const char *ifs
[OMP_IF_LAST
] = {
1314 " target data : %e )",
1315 " target update : %e )",
1316 " target enter data : %e )",
1317 " target exit data : %e )" };
1319 for (i
= 0; i
< OMP_IF_LAST
; i
++)
1320 if (c
->if_exprs
[i
] == NULL
1321 && gfc_match (ifs
[i
], &c
->if_exprs
[i
]) == MATCH_YES
)
1323 if (i
< OMP_IF_LAST
)
1326 gfc_current_locus
= old_loc
;
1328 if ((mask
& OMP_CLAUSE_IF_PRESENT
)
1330 && gfc_match ("if_present") == MATCH_YES
)
1332 c
->if_present
= true;
1336 if ((mask
& OMP_CLAUSE_INBRANCH
)
1339 && gfc_match ("inbranch") == MATCH_YES
)
1341 c
->inbranch
= needs_space
= true;
1344 if ((mask
& OMP_CLAUSE_INDEPENDENT
)
1346 && gfc_match ("independent") == MATCH_YES
)
1348 c
->independent
= true;
1352 if ((mask
& OMP_CLAUSE_IS_DEVICE_PTR
)
1353 && gfc_match_omp_variable_list
1355 &c
->lists
[OMP_LIST_IS_DEVICE_PTR
], false) == MATCH_YES
)
1359 if ((mask
& OMP_CLAUSE_LASTPRIVATE
)
1360 && gfc_match ("lastprivate ( ") == MATCH_YES
)
1362 bool conditional
= gfc_match ("conditional : ") == MATCH_YES
;
1364 if (gfc_match_omp_variable_list ("",
1365 &c
->lists
[OMP_LIST_LASTPRIVATE
],
1366 false, NULL
, &head
) == MATCH_YES
)
1368 gfc_omp_namelist
*n
;
1369 for (n
= *head
; n
; n
= n
->next
)
1370 n
->u
.lastprivate_conditional
= conditional
;
1373 gfc_current_locus
= old_loc
;
1378 if ((mask
& OMP_CLAUSE_LINEAR
)
1379 && gfc_match ("linear (") == MATCH_YES
)
1381 gfc_omp_linear_op linear_op
= OMP_LINEAR_DEFAULT
;
1382 gfc_expr
*step
= NULL
;
1384 if (gfc_match_omp_variable_list (" ref (",
1385 &c
->lists
[OMP_LIST_LINEAR
],
1388 linear_op
= OMP_LINEAR_REF
;
1389 else if (gfc_match_omp_variable_list (" val (",
1390 &c
->lists
[OMP_LIST_LINEAR
],
1393 linear_op
= OMP_LINEAR_VAL
;
1394 else if (gfc_match_omp_variable_list (" uval (",
1395 &c
->lists
[OMP_LIST_LINEAR
],
1398 linear_op
= OMP_LINEAR_UVAL
;
1399 else if (gfc_match_omp_variable_list ("",
1400 &c
->lists
[OMP_LIST_LINEAR
],
1401 false, &end_colon
, &head
)
1403 linear_op
= OMP_LINEAR_DEFAULT
;
1406 gfc_current_locus
= old_loc
;
1409 if (linear_op
!= OMP_LINEAR_DEFAULT
)
1411 if (gfc_match (" :") == MATCH_YES
)
1413 else if (gfc_match (" )") != MATCH_YES
)
1415 gfc_free_omp_namelist (*head
);
1416 gfc_current_locus
= old_loc
;
1421 if (end_colon
&& gfc_match (" %e )", &step
) != MATCH_YES
)
1423 gfc_free_omp_namelist (*head
);
1424 gfc_current_locus
= old_loc
;
1428 else if (!end_colon
)
1430 step
= gfc_get_constant_expr (BT_INTEGER
,
1431 gfc_default_integer_kind
,
1433 mpz_set_si (step
->value
.integer
, 1);
1435 (*head
)->expr
= step
;
1436 if (linear_op
!= OMP_LINEAR_DEFAULT
)
1437 for (gfc_omp_namelist
*n
= *head
; n
; n
= n
->next
)
1438 n
->u
.linear_op
= linear_op
;
1441 if ((mask
& OMP_CLAUSE_LINK
)
1443 && (gfc_match_oacc_clause_link ("link (",
1444 &c
->lists
[OMP_LIST_LINK
])
1447 else if ((mask
& OMP_CLAUSE_LINK
)
1449 && (gfc_match_omp_to_link ("link (",
1450 &c
->lists
[OMP_LIST_LINK
])
1455 if ((mask
& OMP_CLAUSE_MAP
)
1456 && gfc_match ("map ( ") == MATCH_YES
)
1458 locus old_loc2
= gfc_current_locus
;
1459 bool always
= false;
1460 gfc_omp_map_op map_op
= OMP_MAP_TOFROM
;
1461 if (gfc_match ("always , ") == MATCH_YES
)
1463 if (gfc_match ("alloc : ") == MATCH_YES
)
1464 map_op
= OMP_MAP_ALLOC
;
1465 else if (gfc_match ("tofrom : ") == MATCH_YES
)
1466 map_op
= always
? OMP_MAP_ALWAYS_TOFROM
: OMP_MAP_TOFROM
;
1467 else if (gfc_match ("to : ") == MATCH_YES
)
1468 map_op
= always
? OMP_MAP_ALWAYS_TO
: OMP_MAP_TO
;
1469 else if (gfc_match ("from : ") == MATCH_YES
)
1470 map_op
= always
? OMP_MAP_ALWAYS_FROM
: OMP_MAP_FROM
;
1471 else if (gfc_match ("release : ") == MATCH_YES
)
1472 map_op
= OMP_MAP_RELEASE
;
1473 else if (gfc_match ("delete : ") == MATCH_YES
)
1474 map_op
= OMP_MAP_DELETE
;
1477 gfc_current_locus
= old_loc2
;
1481 if (gfc_match_omp_variable_list ("", &c
->lists
[OMP_LIST_MAP
],
1483 true, true) == MATCH_YES
)
1485 gfc_omp_namelist
*n
;
1486 for (n
= *head
; n
; n
= n
->next
)
1487 n
->u
.map_op
= map_op
;
1491 gfc_current_locus
= old_loc
;
1493 if ((mask
& OMP_CLAUSE_MERGEABLE
) && !c
->mergeable
1494 && gfc_match ("mergeable") == MATCH_YES
)
1496 c
->mergeable
= needs_space
= true;
1501 if ((mask
& OMP_CLAUSE_NO_CREATE
)
1502 && gfc_match ("no_create ( ") == MATCH_YES
1503 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1504 OMP_MAP_IF_PRESENT
, true,
1507 if ((mask
& OMP_CLAUSE_NOGROUP
)
1509 && gfc_match ("nogroup") == MATCH_YES
)
1511 c
->nogroup
= needs_space
= true;
1514 if ((mask
& OMP_CLAUSE_NOTEMPORAL
)
1515 && gfc_match_omp_variable_list ("nontemporal (",
1516 &c
->lists
[OMP_LIST_NONTEMPORAL
],
1519 if ((mask
& OMP_CLAUSE_NOTINBRANCH
)
1522 && gfc_match ("notinbranch") == MATCH_YES
)
1524 c
->notinbranch
= needs_space
= true;
1527 if ((mask
& OMP_CLAUSE_NOWAIT
)
1529 && gfc_match ("nowait") == MATCH_YES
)
1531 c
->nowait
= needs_space
= true;
1534 if ((mask
& OMP_CLAUSE_NUM_GANGS
)
1535 && c
->num_gangs_expr
== NULL
1536 && gfc_match ("num_gangs ( %e )",
1537 &c
->num_gangs_expr
) == MATCH_YES
)
1539 if ((mask
& OMP_CLAUSE_NUM_TASKS
)
1540 && c
->num_tasks
== NULL
1541 && gfc_match ("num_tasks ( %e )", &c
->num_tasks
) == MATCH_YES
)
1543 if ((mask
& OMP_CLAUSE_NUM_TEAMS
)
1544 && c
->num_teams
== NULL
1545 && gfc_match ("num_teams ( %e )", &c
->num_teams
) == MATCH_YES
)
1547 if ((mask
& OMP_CLAUSE_NUM_THREADS
)
1548 && c
->num_threads
== NULL
1549 && (gfc_match ("num_threads ( %e )", &c
->num_threads
)
1552 if ((mask
& OMP_CLAUSE_NUM_WORKERS
)
1553 && c
->num_workers_expr
== NULL
1554 && gfc_match ("num_workers ( %e )",
1555 &c
->num_workers_expr
) == MATCH_YES
)
1559 if ((mask
& OMP_CLAUSE_ORDER
)
1560 && !c
->order_concurrent
1561 && gfc_match ("order ( concurrent )") == MATCH_YES
)
1563 c
->order_concurrent
= true;
1566 if ((mask
& OMP_CLAUSE_ORDERED
)
1568 && gfc_match ("ordered") == MATCH_YES
)
1570 gfc_expr
*cexpr
= NULL
;
1571 match m
= gfc_match (" ( %e )", &cexpr
);
1577 if (gfc_extract_int (cexpr
, &ordered
, -1))
1579 else if (ordered
<= 0)
1581 gfc_error_now ("ORDERED clause argument not"
1582 " constant positive integer at %C");
1585 c
->orderedc
= ordered
;
1586 gfc_free_expr (cexpr
);
1595 if ((mask
& OMP_CLAUSE_COPY
)
1596 && gfc_match ("pcopy ( ") == MATCH_YES
1597 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1598 OMP_MAP_TOFROM
, true, allow_derived
))
1600 if ((mask
& OMP_CLAUSE_COPYIN
)
1601 && gfc_match ("pcopyin ( ") == MATCH_YES
1602 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1603 OMP_MAP_TO
, true, allow_derived
))
1605 if ((mask
& OMP_CLAUSE_COPYOUT
)
1606 && gfc_match ("pcopyout ( ") == MATCH_YES
1607 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1608 OMP_MAP_FROM
, true, allow_derived
))
1610 if ((mask
& OMP_CLAUSE_CREATE
)
1611 && gfc_match ("pcreate ( ") == MATCH_YES
1612 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1613 OMP_MAP_ALLOC
, true, allow_derived
))
1615 if ((mask
& OMP_CLAUSE_PRESENT
)
1616 && gfc_match ("present ( ") == MATCH_YES
1617 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1618 OMP_MAP_FORCE_PRESENT
, false,
1621 if ((mask
& OMP_CLAUSE_COPY
)
1622 && gfc_match ("present_or_copy ( ") == MATCH_YES
1623 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1624 OMP_MAP_TOFROM
, true,
1627 if ((mask
& OMP_CLAUSE_COPYIN
)
1628 && gfc_match ("present_or_copyin ( ") == MATCH_YES
1629 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1630 OMP_MAP_TO
, true, allow_derived
))
1632 if ((mask
& OMP_CLAUSE_COPYOUT
)
1633 && gfc_match ("present_or_copyout ( ") == MATCH_YES
1634 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1635 OMP_MAP_FROM
, true, allow_derived
))
1637 if ((mask
& OMP_CLAUSE_CREATE
)
1638 && gfc_match ("present_or_create ( ") == MATCH_YES
1639 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1640 OMP_MAP_ALLOC
, true, allow_derived
))
1642 if ((mask
& OMP_CLAUSE_PRIORITY
)
1643 && c
->priority
== NULL
1644 && gfc_match ("priority ( %e )", &c
->priority
) == MATCH_YES
)
1646 if ((mask
& OMP_CLAUSE_PRIVATE
)
1647 && gfc_match_omp_variable_list ("private (",
1648 &c
->lists
[OMP_LIST_PRIVATE
],
1651 if ((mask
& OMP_CLAUSE_PROC_BIND
)
1652 && c
->proc_bind
== OMP_PROC_BIND_UNKNOWN
)
1654 if (gfc_match ("proc_bind ( master )") == MATCH_YES
)
1655 c
->proc_bind
= OMP_PROC_BIND_MASTER
;
1656 else if (gfc_match ("proc_bind ( spread )") == MATCH_YES
)
1657 c
->proc_bind
= OMP_PROC_BIND_SPREAD
;
1658 else if (gfc_match ("proc_bind ( close )") == MATCH_YES
)
1659 c
->proc_bind
= OMP_PROC_BIND_CLOSE
;
1660 if (c
->proc_bind
!= OMP_PROC_BIND_UNKNOWN
)
1665 if ((mask
& OMP_CLAUSE_REDUCTION
)
1666 && gfc_match ("reduction ( ") == MATCH_YES
)
1668 gfc_omp_reduction_op rop
= OMP_REDUCTION_NONE
;
1669 char buffer
[GFC_MAX_SYMBOL_LEN
+ 3];
1670 if (gfc_match_char ('+') == MATCH_YES
)
1671 rop
= OMP_REDUCTION_PLUS
;
1672 else if (gfc_match_char ('*') == MATCH_YES
)
1673 rop
= OMP_REDUCTION_TIMES
;
1674 else if (gfc_match_char ('-') == MATCH_YES
)
1675 rop
= OMP_REDUCTION_MINUS
;
1676 else if (gfc_match (".and.") == MATCH_YES
)
1677 rop
= OMP_REDUCTION_AND
;
1678 else if (gfc_match (".or.") == MATCH_YES
)
1679 rop
= OMP_REDUCTION_OR
;
1680 else if (gfc_match (".eqv.") == MATCH_YES
)
1681 rop
= OMP_REDUCTION_EQV
;
1682 else if (gfc_match (".neqv.") == MATCH_YES
)
1683 rop
= OMP_REDUCTION_NEQV
;
1684 if (rop
!= OMP_REDUCTION_NONE
)
1685 snprintf (buffer
, sizeof buffer
, "operator %s",
1686 gfc_op2string ((gfc_intrinsic_op
) rop
));
1687 else if (gfc_match_defined_op_name (buffer
+ 1, 1) == MATCH_YES
)
1690 strcat (buffer
, ".");
1692 else if (gfc_match_name (buffer
) == MATCH_YES
)
1695 const char *n
= buffer
;
1697 gfc_find_symbol (buffer
, NULL
, 1, &sym
);
1700 if (sym
->attr
.intrinsic
)
1702 else if ((sym
->attr
.flavor
!= FL_UNKNOWN
1703 && sym
->attr
.flavor
!= FL_PROCEDURE
)
1704 || sym
->attr
.external
1705 || sym
->attr
.generic
1709 || sym
->attr
.subroutine
1710 || sym
->attr
.pointer
1712 || sym
->attr
.cray_pointer
1713 || sym
->attr
.cray_pointee
1714 || (sym
->attr
.proc
!= PROC_UNKNOWN
1715 && sym
->attr
.proc
!= PROC_INTRINSIC
)
1716 || sym
->attr
.if_source
!= IFSRC_UNKNOWN
1717 || sym
== sym
->ns
->proc_name
)
1726 rop
= OMP_REDUCTION_NONE
;
1727 else if (strcmp (n
, "max") == 0)
1728 rop
= OMP_REDUCTION_MAX
;
1729 else if (strcmp (n
, "min") == 0)
1730 rop
= OMP_REDUCTION_MIN
;
1731 else if (strcmp (n
, "iand") == 0)
1732 rop
= OMP_REDUCTION_IAND
;
1733 else if (strcmp (n
, "ior") == 0)
1734 rop
= OMP_REDUCTION_IOR
;
1735 else if (strcmp (n
, "ieor") == 0)
1736 rop
= OMP_REDUCTION_IEOR
;
1737 if (rop
!= OMP_REDUCTION_NONE
1739 && ! sym
->attr
.intrinsic
1740 && ! sym
->attr
.use_assoc
1741 && ((sym
->attr
.flavor
== FL_UNKNOWN
1742 && !gfc_add_flavor (&sym
->attr
, FL_PROCEDURE
,
1744 || !gfc_add_intrinsic (&sym
->attr
, NULL
)))
1745 rop
= OMP_REDUCTION_NONE
;
1751 ? gfc_find_omp_udr (gfc_current_ns
, buffer
, NULL
) : NULL
);
1752 gfc_omp_namelist
**head
= NULL
;
1753 if (rop
== OMP_REDUCTION_NONE
&& udr
)
1754 rop
= OMP_REDUCTION_USER
;
1756 if (gfc_match_omp_variable_list (" :",
1757 &c
->lists
[OMP_LIST_REDUCTION
],
1758 false, NULL
, &head
, openacc
,
1759 allow_derived
) == MATCH_YES
)
1761 gfc_omp_namelist
*n
;
1762 if (rop
== OMP_REDUCTION_NONE
)
1766 gfc_error_now ("!$OMP DECLARE REDUCTION %s not found "
1767 "at %L", buffer
, &old_loc
);
1768 gfc_free_omp_namelist (n
);
1771 for (n
= *head
; n
; n
= n
->next
)
1773 n
->u
.reduction_op
= rop
;
1776 n
->udr
= gfc_get_omp_namelist_udr ();
1783 gfc_current_locus
= old_loc
;
1787 if ((mask
& OMP_CLAUSE_SAFELEN
)
1788 && c
->safelen_expr
== NULL
1789 && gfc_match ("safelen ( %e )", &c
->safelen_expr
) == MATCH_YES
)
1791 if ((mask
& OMP_CLAUSE_SCHEDULE
)
1792 && c
->sched_kind
== OMP_SCHED_NONE
1793 && gfc_match ("schedule ( ") == MATCH_YES
)
1796 locus old_loc2
= gfc_current_locus
;
1799 if (gfc_match ("simd") == MATCH_YES
)
1801 c
->sched_simd
= true;
1804 else if (gfc_match ("monotonic") == MATCH_YES
)
1806 c
->sched_monotonic
= true;
1809 else if (gfc_match ("nonmonotonic") == MATCH_YES
)
1811 c
->sched_nonmonotonic
= true;
1817 gfc_current_locus
= old_loc2
;
1821 && gfc_match (" , ") == MATCH_YES
)
1823 else if (gfc_match (" : ") == MATCH_YES
)
1825 gfc_current_locus
= old_loc2
;
1829 if (gfc_match ("static") == MATCH_YES
)
1830 c
->sched_kind
= OMP_SCHED_STATIC
;
1831 else if (gfc_match ("dynamic") == MATCH_YES
)
1832 c
->sched_kind
= OMP_SCHED_DYNAMIC
;
1833 else if (gfc_match ("guided") == MATCH_YES
)
1834 c
->sched_kind
= OMP_SCHED_GUIDED
;
1835 else if (gfc_match ("runtime") == MATCH_YES
)
1836 c
->sched_kind
= OMP_SCHED_RUNTIME
;
1837 else if (gfc_match ("auto") == MATCH_YES
)
1838 c
->sched_kind
= OMP_SCHED_AUTO
;
1839 if (c
->sched_kind
!= OMP_SCHED_NONE
)
1842 if (c
->sched_kind
!= OMP_SCHED_RUNTIME
1843 && c
->sched_kind
!= OMP_SCHED_AUTO
)
1844 m
= gfc_match (" , %e )", &c
->chunk_size
);
1846 m
= gfc_match_char (')');
1848 c
->sched_kind
= OMP_SCHED_NONE
;
1850 if (c
->sched_kind
!= OMP_SCHED_NONE
)
1853 gfc_current_locus
= old_loc
;
1855 if ((mask
& OMP_CLAUSE_HOST_SELF
)
1856 && gfc_match ("self ( ") == MATCH_YES
1857 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1858 OMP_MAP_FORCE_FROM
, true,
1861 if ((mask
& OMP_CLAUSE_SEQ
)
1863 && gfc_match ("seq") == MATCH_YES
)
1869 if ((mask
& OMP_CLAUSE_SHARED
)
1870 && gfc_match_omp_variable_list ("shared (",
1871 &c
->lists
[OMP_LIST_SHARED
],
1874 if ((mask
& OMP_CLAUSE_SIMDLEN
)
1875 && c
->simdlen_expr
== NULL
1876 && gfc_match ("simdlen ( %e )", &c
->simdlen_expr
) == MATCH_YES
)
1878 if ((mask
& OMP_CLAUSE_SIMD
)
1880 && gfc_match ("simd") == MATCH_YES
)
1882 c
->simd
= needs_space
= true;
1887 if ((mask
& OMP_CLAUSE_THREAD_LIMIT
)
1888 && c
->thread_limit
== NULL
1889 && gfc_match ("thread_limit ( %e )",
1890 &c
->thread_limit
) == MATCH_YES
)
1892 if ((mask
& OMP_CLAUSE_THREADS
)
1894 && gfc_match ("threads") == MATCH_YES
)
1896 c
->threads
= needs_space
= true;
1899 if ((mask
& OMP_CLAUSE_TILE
)
1901 && match_oacc_expr_list ("tile (", &c
->tile_list
,
1904 if ((mask
& OMP_CLAUSE_TO
) && (mask
& OMP_CLAUSE_LINK
))
1906 if (gfc_match_omp_to_link ("to (", &c
->lists
[OMP_LIST_TO
])
1910 else if ((mask
& OMP_CLAUSE_TO
)
1911 && gfc_match_omp_variable_list ("to (",
1912 &c
->lists
[OMP_LIST_TO
], false,
1913 NULL
, &head
, true) == MATCH_YES
)
1917 if ((mask
& OMP_CLAUSE_UNIFORM
)
1918 && gfc_match_omp_variable_list ("uniform (",
1919 &c
->lists
[OMP_LIST_UNIFORM
],
1920 false) == MATCH_YES
)
1922 if ((mask
& OMP_CLAUSE_UNTIED
)
1924 && gfc_match ("untied") == MATCH_YES
)
1926 c
->untied
= needs_space
= true;
1929 if ((mask
& OMP_CLAUSE_USE_DEVICE
)
1930 && gfc_match_omp_variable_list ("use_device (",
1931 &c
->lists
[OMP_LIST_USE_DEVICE
],
1934 if ((mask
& OMP_CLAUSE_USE_DEVICE_PTR
)
1935 && gfc_match_omp_variable_list
1936 ("use_device_ptr (",
1937 &c
->lists
[OMP_LIST_USE_DEVICE_PTR
], false) == MATCH_YES
)
1939 if ((mask
& OMP_CLAUSE_USE_DEVICE_ADDR
)
1940 && gfc_match_omp_variable_list
1941 ("use_device_addr (",
1942 &c
->lists
[OMP_LIST_USE_DEVICE_ADDR
], false) == MATCH_YES
)
1946 /* VECTOR_LENGTH must be matched before VECTOR, because the latter
1947 doesn't unconditionally match '('. */
1948 if ((mask
& OMP_CLAUSE_VECTOR_LENGTH
)
1949 && c
->vector_length_expr
== NULL
1950 && (gfc_match ("vector_length ( %e )", &c
->vector_length_expr
)
1953 if ((mask
& OMP_CLAUSE_VECTOR
)
1955 && gfc_match ("vector") == MATCH_YES
)
1958 match m
= match_oacc_clause_gwv (c
, GOMP_DIM_VECTOR
);
1959 if (m
== MATCH_ERROR
)
1961 gfc_current_locus
= old_loc
;
1970 if ((mask
& OMP_CLAUSE_WAIT
)
1971 && gfc_match ("wait") == MATCH_YES
)
1973 match m
= match_oacc_expr_list (" (", &c
->wait_list
, false);
1974 if (m
== MATCH_ERROR
)
1976 gfc_current_locus
= old_loc
;
1979 else if (m
== MATCH_NO
)
1982 = gfc_get_constant_expr (BT_INTEGER
,
1983 gfc_default_integer_kind
,
1984 &gfc_current_locus
);
1985 mpz_set_si (expr
->value
.integer
, GOMP_ASYNC_NOVAL
);
1986 gfc_expr_list
**expr_list
= &c
->wait_list
;
1988 expr_list
= &(*expr_list
)->next
;
1989 *expr_list
= gfc_get_expr_list ();
1990 (*expr_list
)->expr
= expr
;
1995 if ((mask
& OMP_CLAUSE_WORKER
)
1997 && gfc_match ("worker") == MATCH_YES
)
2000 match m
= match_oacc_clause_gwv (c
, GOMP_DIM_WORKER
);
2001 if (m
== MATCH_ERROR
)
2003 gfc_current_locus
= old_loc
;
2006 else if (m
== MATCH_NO
)
2015 if (gfc_match_omp_eos () != MATCH_YES
)
2017 if (!gfc_error_flag_test ())
2018 gfc_error ("Failed to match clause at %C");
2019 gfc_free_omp_clauses (c
);
2028 #define OACC_PARALLEL_CLAUSES \
2029 (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_NUM_GANGS \
2030 | OMP_CLAUSE_NUM_WORKERS | OMP_CLAUSE_VECTOR_LENGTH | OMP_CLAUSE_REDUCTION \
2031 | OMP_CLAUSE_COPY | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT \
2032 | OMP_CLAUSE_CREATE | OMP_CLAUSE_NO_CREATE | OMP_CLAUSE_PRESENT \
2033 | OMP_CLAUSE_DEVICEPTR | OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE \
2034 | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_WAIT | OMP_CLAUSE_ATTACH)
2035 #define OACC_KERNELS_CLAUSES \
2036 (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_NUM_GANGS \
2037 | OMP_CLAUSE_NUM_WORKERS | OMP_CLAUSE_VECTOR_LENGTH | OMP_CLAUSE_DEVICEPTR \
2038 | OMP_CLAUSE_COPY | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT \
2039 | OMP_CLAUSE_CREATE | OMP_CLAUSE_NO_CREATE | OMP_CLAUSE_PRESENT \
2040 | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_WAIT | OMP_CLAUSE_ATTACH)
2041 #define OACC_SERIAL_CLAUSES \
2042 (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_REDUCTION \
2043 | OMP_CLAUSE_COPY | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT \
2044 | OMP_CLAUSE_CREATE | OMP_CLAUSE_NO_CREATE | OMP_CLAUSE_PRESENT \
2045 | OMP_CLAUSE_DEVICEPTR | OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE \
2046 | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_WAIT | OMP_CLAUSE_ATTACH)
2047 #define OACC_DATA_CLAUSES \
2048 (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_DEVICEPTR | OMP_CLAUSE_COPY \
2049 | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT | OMP_CLAUSE_CREATE \
2050 | OMP_CLAUSE_NO_CREATE | OMP_CLAUSE_PRESENT | OMP_CLAUSE_ATTACH)
2051 #define OACC_LOOP_CLAUSES \
2052 (omp_mask (OMP_CLAUSE_COLLAPSE) | OMP_CLAUSE_GANG | OMP_CLAUSE_WORKER \
2053 | OMP_CLAUSE_VECTOR | OMP_CLAUSE_SEQ | OMP_CLAUSE_INDEPENDENT \
2054 | OMP_CLAUSE_PRIVATE | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_AUTO \
2056 #define OACC_PARALLEL_LOOP_CLAUSES \
2057 (OACC_LOOP_CLAUSES | OACC_PARALLEL_CLAUSES)
2058 #define OACC_KERNELS_LOOP_CLAUSES \
2059 (OACC_LOOP_CLAUSES | OACC_KERNELS_CLAUSES)
2060 #define OACC_SERIAL_LOOP_CLAUSES \
2061 (OACC_LOOP_CLAUSES | OACC_SERIAL_CLAUSES)
2062 #define OACC_HOST_DATA_CLAUSES \
2063 (omp_mask (OMP_CLAUSE_USE_DEVICE) \
2065 | OMP_CLAUSE_IF_PRESENT)
2066 #define OACC_DECLARE_CLAUSES \
2067 (omp_mask (OMP_CLAUSE_COPY) | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT \
2068 | OMP_CLAUSE_CREATE | OMP_CLAUSE_DEVICEPTR | OMP_CLAUSE_DEVICE_RESIDENT \
2069 | OMP_CLAUSE_PRESENT \
2071 #define OACC_UPDATE_CLAUSES \
2072 (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_HOST_SELF \
2073 | OMP_CLAUSE_DEVICE | OMP_CLAUSE_WAIT | OMP_CLAUSE_IF_PRESENT)
2074 #define OACC_ENTER_DATA_CLAUSES \
2075 (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_WAIT \
2076 | OMP_CLAUSE_COPYIN | OMP_CLAUSE_CREATE | OMP_CLAUSE_ATTACH)
2077 #define OACC_EXIT_DATA_CLAUSES \
2078 (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_WAIT \
2079 | OMP_CLAUSE_COPYOUT | OMP_CLAUSE_DELETE | OMP_CLAUSE_FINALIZE \
2080 | OMP_CLAUSE_DETACH)
2081 #define OACC_WAIT_CLAUSES \
2082 omp_mask (OMP_CLAUSE_ASYNC)
2083 #define OACC_ROUTINE_CLAUSES \
2084 (omp_mask (OMP_CLAUSE_GANG) | OMP_CLAUSE_WORKER | OMP_CLAUSE_VECTOR \
2089 match_acc (gfc_exec_op op
, const omp_mask mask
)
2092 if (gfc_match_omp_clauses (&c
, mask
, false, false, true) != MATCH_YES
)
2095 new_st
.ext
.omp_clauses
= c
;
2100 gfc_match_oacc_parallel_loop (void)
2102 return match_acc (EXEC_OACC_PARALLEL_LOOP
, OACC_PARALLEL_LOOP_CLAUSES
);
2107 gfc_match_oacc_parallel (void)
2109 return match_acc (EXEC_OACC_PARALLEL
, OACC_PARALLEL_CLAUSES
);
2114 gfc_match_oacc_kernels_loop (void)
2116 return match_acc (EXEC_OACC_KERNELS_LOOP
, OACC_KERNELS_LOOP_CLAUSES
);
2121 gfc_match_oacc_kernels (void)
2123 return match_acc (EXEC_OACC_KERNELS
, OACC_KERNELS_CLAUSES
);
2128 gfc_match_oacc_serial_loop (void)
2130 return match_acc (EXEC_OACC_SERIAL_LOOP
, OACC_SERIAL_LOOP_CLAUSES
);
2135 gfc_match_oacc_serial (void)
2137 return match_acc (EXEC_OACC_SERIAL
, OACC_SERIAL_CLAUSES
);
2142 gfc_match_oacc_data (void)
2144 return match_acc (EXEC_OACC_DATA
, OACC_DATA_CLAUSES
);
2149 gfc_match_oacc_host_data (void)
2151 return match_acc (EXEC_OACC_HOST_DATA
, OACC_HOST_DATA_CLAUSES
);
2156 gfc_match_oacc_loop (void)
2158 return match_acc (EXEC_OACC_LOOP
, OACC_LOOP_CLAUSES
);
2163 gfc_match_oacc_declare (void)
2166 gfc_omp_namelist
*n
;
2167 gfc_namespace
*ns
= gfc_current_ns
;
2168 gfc_oacc_declare
*new_oc
;
2169 bool module_var
= false;
2170 locus where
= gfc_current_locus
;
2172 if (gfc_match_omp_clauses (&c
, OACC_DECLARE_CLAUSES
, false, false, true)
2176 for (n
= c
->lists
[OMP_LIST_DEVICE_RESIDENT
]; n
!= NULL
; n
= n
->next
)
2177 n
->sym
->attr
.oacc_declare_device_resident
= 1;
2179 for (n
= c
->lists
[OMP_LIST_LINK
]; n
!= NULL
; n
= n
->next
)
2180 n
->sym
->attr
.oacc_declare_link
= 1;
2182 for (n
= c
->lists
[OMP_LIST_MAP
]; n
!= NULL
; n
= n
->next
)
2184 gfc_symbol
*s
= n
->sym
;
2186 if (gfc_current_ns
->proc_name
2187 && gfc_current_ns
->proc_name
->attr
.flavor
== FL_MODULE
)
2189 if (n
->u
.map_op
!= OMP_MAP_ALLOC
&& n
->u
.map_op
!= OMP_MAP_TO
)
2191 gfc_error ("Invalid clause in module with !$ACC DECLARE at %L",
2199 if (s
->attr
.use_assoc
)
2201 gfc_error ("Variable is USE-associated with !$ACC DECLARE at %L",
2206 if ((s
->result
== s
&& s
->ns
->contained
!= gfc_current_ns
)
2207 || ((s
->attr
.flavor
== FL_UNKNOWN
|| s
->attr
.flavor
== FL_VARIABLE
)
2208 && s
->ns
!= gfc_current_ns
))
2210 gfc_error ("Variable %qs shall be declared in the same scoping unit "
2211 "as !$ACC DECLARE at %L", s
->name
, &where
);
2215 if ((s
->attr
.dimension
|| s
->attr
.codimension
)
2216 && s
->attr
.dummy
&& s
->as
->type
!= AS_EXPLICIT
)
2218 gfc_error ("Assumed-size dummy array with !$ACC DECLARE at %L",
2223 switch (n
->u
.map_op
)
2225 case OMP_MAP_FORCE_ALLOC
:
2227 s
->attr
.oacc_declare_create
= 1;
2230 case OMP_MAP_FORCE_TO
:
2232 s
->attr
.oacc_declare_copyin
= 1;
2235 case OMP_MAP_FORCE_DEVICEPTR
:
2236 s
->attr
.oacc_declare_deviceptr
= 1;
2244 new_oc
= gfc_get_oacc_declare ();
2245 new_oc
->next
= ns
->oacc_declare
;
2246 new_oc
->module_var
= module_var
;
2247 new_oc
->clauses
= c
;
2248 new_oc
->loc
= gfc_current_locus
;
2249 ns
->oacc_declare
= new_oc
;
2256 gfc_match_oacc_update (void)
2259 locus here
= gfc_current_locus
;
2261 if (gfc_match_omp_clauses (&c
, OACC_UPDATE_CLAUSES
, false, false, true)
2265 if (!c
->lists
[OMP_LIST_MAP
])
2267 gfc_error ("%<acc update%> must contain at least one "
2268 "%<device%> or %<host%> or %<self%> clause at %L", &here
);
2272 new_st
.op
= EXEC_OACC_UPDATE
;
2273 new_st
.ext
.omp_clauses
= c
;
2279 gfc_match_oacc_enter_data (void)
2281 return match_acc (EXEC_OACC_ENTER_DATA
, OACC_ENTER_DATA_CLAUSES
);
2286 gfc_match_oacc_exit_data (void)
2288 return match_acc (EXEC_OACC_EXIT_DATA
, OACC_EXIT_DATA_CLAUSES
);
2293 gfc_match_oacc_wait (void)
2295 gfc_omp_clauses
*c
= gfc_get_omp_clauses ();
2296 gfc_expr_list
*wait_list
= NULL
, *el
;
2300 m
= match_oacc_expr_list (" (", &wait_list
, true);
2301 if (m
== MATCH_ERROR
)
2303 else if (m
== MATCH_YES
)
2306 if (gfc_match_omp_clauses (&c
, OACC_WAIT_CLAUSES
, space
, space
, true)
2311 for (el
= wait_list
; el
; el
= el
->next
)
2313 if (el
->expr
== NULL
)
2315 gfc_error ("Invalid argument to !$ACC WAIT at %C");
2319 if (!gfc_resolve_expr (el
->expr
)
2320 || el
->expr
->ts
.type
!= BT_INTEGER
|| el
->expr
->rank
!= 0)
2322 gfc_error ("WAIT clause at %L requires a scalar INTEGER expression",
2328 c
->wait_list
= wait_list
;
2329 new_st
.op
= EXEC_OACC_WAIT
;
2330 new_st
.ext
.omp_clauses
= c
;
2336 gfc_match_oacc_cache (void)
2338 gfc_omp_clauses
*c
= gfc_get_omp_clauses ();
2339 /* The OpenACC cache directive explicitly only allows "array elements or
2340 subarrays", which we're currently not checking here. Either check this
2341 after the call of gfc_match_omp_variable_list, or add something like a
2342 only_sections variant next to its allow_sections parameter. */
2343 match m
= gfc_match_omp_variable_list (" (",
2344 &c
->lists
[OMP_LIST_CACHE
], true,
2348 gfc_free_omp_clauses(c
);
2352 if (gfc_current_state() != COMP_DO
2353 && gfc_current_state() != COMP_DO_CONCURRENT
)
2355 gfc_error ("ACC CACHE directive must be inside of loop %C");
2356 gfc_free_omp_clauses(c
);
2360 new_st
.op
= EXEC_OACC_CACHE
;
2361 new_st
.ext
.omp_clauses
= c
;
2365 /* Determine the OpenACC 'routine' directive's level of parallelism. */
2367 static oacc_routine_lop
2368 gfc_oacc_routine_lop (gfc_omp_clauses
*clauses
)
2370 oacc_routine_lop ret
= OACC_ROUTINE_LOP_SEQ
;
2374 unsigned n_lop_clauses
= 0;
2379 ret
= OACC_ROUTINE_LOP_GANG
;
2381 if (clauses
->worker
)
2384 ret
= OACC_ROUTINE_LOP_WORKER
;
2386 if (clauses
->vector
)
2389 ret
= OACC_ROUTINE_LOP_VECTOR
;
2394 ret
= OACC_ROUTINE_LOP_SEQ
;
2397 if (n_lop_clauses
> 1)
2398 ret
= OACC_ROUTINE_LOP_ERROR
;
2405 gfc_match_oacc_routine (void)
2409 gfc_intrinsic_sym
*isym
= NULL
;
2410 gfc_symbol
*sym
= NULL
;
2411 gfc_omp_clauses
*c
= NULL
;
2412 gfc_oacc_routine_name
*n
= NULL
;
2413 oacc_routine_lop lop
= OACC_ROUTINE_LOP_NONE
;
2415 old_loc
= gfc_current_locus
;
2417 m
= gfc_match (" (");
2419 if (gfc_current_ns
->proc_name
2420 && gfc_current_ns
->proc_name
->attr
.if_source
== IFSRC_IFBODY
2423 gfc_error ("Only the !$ACC ROUTINE form without "
2424 "list is allowed in interface block at %C");
2430 char buffer
[GFC_MAX_SYMBOL_LEN
+ 1];
2432 m
= gfc_match_name (buffer
);
2435 gfc_symtree
*st
= NULL
;
2437 /* First look for an intrinsic symbol. */
2438 isym
= gfc_find_function (buffer
);
2440 isym
= gfc_find_subroutine (buffer
);
2441 /* If no intrinsic symbol found, search the current namespace. */
2443 st
= gfc_find_symtree (gfc_current_ns
->sym_root
, buffer
);
2447 /* If the name in a 'routine' directive refers to the containing
2448 subroutine or function, then make sure that we'll later handle
2449 this accordingly. */
2450 if (gfc_current_ns
->proc_name
!= NULL
2451 && strcmp (sym
->name
, gfc_current_ns
->proc_name
->name
) == 0)
2455 if (isym
== NULL
&& st
== NULL
)
2457 gfc_error ("Invalid NAME %qs in !$ACC ROUTINE ( NAME ) at %C",
2459 gfc_current_locus
= old_loc
;
2465 gfc_error ("Syntax error in !$ACC ROUTINE ( NAME ) at %C");
2466 gfc_current_locus
= old_loc
;
2470 if (gfc_match_char (')') != MATCH_YES
)
2472 gfc_error ("Syntax error in !$ACC ROUTINE ( NAME ) at %C, expecting"
2474 gfc_current_locus
= old_loc
;
2479 if (gfc_match_omp_eos () != MATCH_YES
2480 && (gfc_match_omp_clauses (&c
, OACC_ROUTINE_CLAUSES
, false, false, true)
2484 lop
= gfc_oacc_routine_lop (c
);
2485 if (lop
== OACC_ROUTINE_LOP_ERROR
)
2487 gfc_error ("Multiple loop axes specified for routine at %C");
2493 /* Diagnose any OpenACC 'routine' directive that doesn't match the
2494 (implicit) one with a 'seq' clause. */
2495 if (c
&& (c
->gang
|| c
->worker
|| c
->vector
))
2497 gfc_error ("Intrinsic symbol specified in !$ACC ROUTINE ( NAME )"
2498 " at %C marked with incompatible GANG, WORKER, or VECTOR"
2503 else if (sym
!= NULL
)
2507 /* For a repeated OpenACC 'routine' directive, diagnose if it doesn't
2508 match the first one. */
2509 for (gfc_oacc_routine_name
*n_p
= gfc_current_ns
->oacc_routine_names
;
2512 if (n_p
->sym
== sym
)
2515 if (lop
!= gfc_oacc_routine_lop (n_p
->clauses
))
2517 gfc_error ("!$ACC ROUTINE already applied at %C");
2524 sym
->attr
.oacc_routine_lop
= lop
;
2526 n
= gfc_get_oacc_routine_name ();
2529 n
->next
= gfc_current_ns
->oacc_routine_names
;
2531 gfc_current_ns
->oacc_routine_names
= n
;
2534 else if (gfc_current_ns
->proc_name
)
2536 /* For a repeated OpenACC 'routine' directive, diagnose if it doesn't
2537 match the first one. */
2538 oacc_routine_lop lop_p
= gfc_current_ns
->proc_name
->attr
.oacc_routine_lop
;
2539 if (lop_p
!= OACC_ROUTINE_LOP_NONE
2542 gfc_error ("!$ACC ROUTINE already applied at %C");
2546 if (!gfc_add_omp_declare_target (&gfc_current_ns
->proc_name
->attr
,
2547 gfc_current_ns
->proc_name
->name
,
2550 gfc_current_ns
->proc_name
->attr
.oacc_routine_lop
= lop
;
2553 /* Something has gone wrong, possibly a syntax error. */
2556 if (gfc_pure (NULL
) && c
&& (c
->gang
|| c
->worker
|| c
->vector
))
2558 gfc_error ("!$ACC ROUTINE with GANG, WORKER, or VECTOR clause is not "
2559 "permitted in PURE procedure at %C");
2566 else if (gfc_current_ns
->oacc_routine
)
2567 gfc_current_ns
->oacc_routine_clauses
= c
;
2569 new_st
.op
= EXEC_OACC_ROUTINE
;
2570 new_st
.ext
.omp_clauses
= c
;
2574 gfc_current_locus
= old_loc
;
2579 #define OMP_PARALLEL_CLAUSES \
2580 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \
2581 | OMP_CLAUSE_SHARED | OMP_CLAUSE_COPYIN | OMP_CLAUSE_REDUCTION \
2582 | OMP_CLAUSE_IF | OMP_CLAUSE_NUM_THREADS | OMP_CLAUSE_DEFAULT \
2583 | OMP_CLAUSE_PROC_BIND)
2584 #define OMP_DECLARE_SIMD_CLAUSES \
2585 (omp_mask (OMP_CLAUSE_SIMDLEN) | OMP_CLAUSE_LINEAR \
2586 | OMP_CLAUSE_UNIFORM | OMP_CLAUSE_ALIGNED | OMP_CLAUSE_INBRANCH \
2587 | OMP_CLAUSE_NOTINBRANCH)
2588 #define OMP_DO_CLAUSES \
2589 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \
2590 | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION \
2591 | OMP_CLAUSE_SCHEDULE | OMP_CLAUSE_ORDERED | OMP_CLAUSE_COLLAPSE \
2592 | OMP_CLAUSE_LINEAR | OMP_CLAUSE_ORDER)
2593 #define OMP_SECTIONS_CLAUSES \
2594 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \
2595 | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION)
2596 #define OMP_SIMD_CLAUSES \
2597 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_LASTPRIVATE \
2598 | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_SAFELEN \
2599 | OMP_CLAUSE_LINEAR | OMP_CLAUSE_ALIGNED | OMP_CLAUSE_SIMDLEN \
2600 | OMP_CLAUSE_IF | OMP_CLAUSE_ORDER | OMP_CLAUSE_NOTEMPORAL)
2601 #define OMP_TASK_CLAUSES \
2602 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \
2603 | OMP_CLAUSE_SHARED | OMP_CLAUSE_IF | OMP_CLAUSE_DEFAULT \
2604 | OMP_CLAUSE_UNTIED | OMP_CLAUSE_FINAL | OMP_CLAUSE_MERGEABLE \
2605 | OMP_CLAUSE_DEPEND | OMP_CLAUSE_PRIORITY)
2606 #define OMP_TASKLOOP_CLAUSES \
2607 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \
2608 | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_SHARED | OMP_CLAUSE_IF \
2609 | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_UNTIED | OMP_CLAUSE_FINAL \
2610 | OMP_CLAUSE_MERGEABLE | OMP_CLAUSE_PRIORITY | OMP_CLAUSE_GRAINSIZE \
2611 | OMP_CLAUSE_NUM_TASKS | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_NOGROUP)
2612 #define OMP_TARGET_CLAUSES \
2613 (omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF \
2614 | OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT | OMP_CLAUSE_PRIVATE \
2615 | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_DEFAULTMAP \
2616 | OMP_CLAUSE_IS_DEVICE_PTR)
2617 #define OMP_TARGET_DATA_CLAUSES \
2618 (omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF \
2619 | OMP_CLAUSE_USE_DEVICE_PTR | OMP_CLAUSE_USE_DEVICE_ADDR)
2620 #define OMP_TARGET_ENTER_DATA_CLAUSES \
2621 (omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF \
2622 | OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT)
2623 #define OMP_TARGET_EXIT_DATA_CLAUSES \
2624 (omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF \
2625 | OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT)
2626 #define OMP_TARGET_UPDATE_CLAUSES \
2627 (omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_IF | OMP_CLAUSE_TO \
2628 | OMP_CLAUSE_FROM | OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT)
2629 #define OMP_TEAMS_CLAUSES \
2630 (omp_mask (OMP_CLAUSE_NUM_TEAMS) | OMP_CLAUSE_THREAD_LIMIT \
2631 | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE \
2632 | OMP_CLAUSE_SHARED | OMP_CLAUSE_REDUCTION)
2633 #define OMP_DISTRIBUTE_CLAUSES \
2634 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \
2635 | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_DIST_SCHEDULE)
2636 #define OMP_SINGLE_CLAUSES \
2637 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE)
2638 #define OMP_ORDERED_CLAUSES \
2639 (omp_mask (OMP_CLAUSE_THREADS) | OMP_CLAUSE_SIMD)
2640 #define OMP_DECLARE_TARGET_CLAUSES \
2641 (omp_mask (OMP_CLAUSE_TO) | OMP_CLAUSE_LINK)
2645 match_omp (gfc_exec_op op
, const omp_mask mask
)
2648 if (gfc_match_omp_clauses (&c
, mask
) != MATCH_YES
)
2651 new_st
.ext
.omp_clauses
= c
;
2657 gfc_match_omp_critical (void)
2659 char n
[GFC_MAX_SYMBOL_LEN
+1];
2660 gfc_omp_clauses
*c
= NULL
;
2662 if (gfc_match (" ( %n )", n
) != MATCH_YES
)
2665 if (gfc_match_omp_clauses (&c
, omp_mask (OMP_CLAUSE_HINT
),
2666 /* first = */ n
[0] == '\0') != MATCH_YES
)
2669 new_st
.op
= EXEC_OMP_CRITICAL
;
2670 new_st
.ext
.omp_clauses
= c
;
2672 c
->critical_name
= xstrdup (n
);
2678 gfc_match_omp_end_critical (void)
2680 char n
[GFC_MAX_SYMBOL_LEN
+1];
2682 if (gfc_match (" ( %n )", n
) != MATCH_YES
)
2684 if (gfc_match_omp_eos () != MATCH_YES
)
2686 gfc_error ("Unexpected junk after $OMP CRITICAL statement at %C");
2690 new_st
.op
= EXEC_OMP_END_CRITICAL
;
2691 new_st
.ext
.omp_name
= n
[0] ? xstrdup (n
) : NULL
;
2697 gfc_match_omp_distribute (void)
2699 return match_omp (EXEC_OMP_DISTRIBUTE
, OMP_DISTRIBUTE_CLAUSES
);
2704 gfc_match_omp_distribute_parallel_do (void)
2706 return match_omp (EXEC_OMP_DISTRIBUTE_PARALLEL_DO
,
2707 (OMP_DISTRIBUTE_CLAUSES
| OMP_PARALLEL_CLAUSES
2709 & ~(omp_mask (OMP_CLAUSE_ORDERED
))
2710 & ~(omp_mask (OMP_CLAUSE_LINEAR
)));
2715 gfc_match_omp_distribute_parallel_do_simd (void)
2717 return match_omp (EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD
,
2718 (OMP_DISTRIBUTE_CLAUSES
| OMP_PARALLEL_CLAUSES
2719 | OMP_DO_CLAUSES
| OMP_SIMD_CLAUSES
)
2720 & ~(omp_mask (OMP_CLAUSE_ORDERED
)));
2725 gfc_match_omp_distribute_simd (void)
2727 return match_omp (EXEC_OMP_DISTRIBUTE_SIMD
,
2728 OMP_DISTRIBUTE_CLAUSES
| OMP_SIMD_CLAUSES
);
2733 gfc_match_omp_do (void)
2735 return match_omp (EXEC_OMP_DO
, OMP_DO_CLAUSES
);
2740 gfc_match_omp_do_simd (void)
2742 return match_omp (EXEC_OMP_DO_SIMD
, OMP_DO_CLAUSES
| OMP_SIMD_CLAUSES
);
2747 gfc_match_omp_flush (void)
2749 gfc_omp_namelist
*list
= NULL
;
2750 gfc_match_omp_variable_list (" (", &list
, true);
2751 if (gfc_match_omp_eos () != MATCH_YES
)
2753 gfc_error ("Unexpected junk after $OMP FLUSH statement at %C");
2754 gfc_free_omp_namelist (list
);
2757 new_st
.op
= EXEC_OMP_FLUSH
;
2758 new_st
.ext
.omp_namelist
= list
;
2764 gfc_match_omp_declare_simd (void)
2766 locus where
= gfc_current_locus
;
2767 gfc_symbol
*proc_name
;
2769 gfc_omp_declare_simd
*ods
;
2770 bool needs_space
= false;
2772 switch (gfc_match (" ( %s ) ", &proc_name
))
2774 case MATCH_YES
: break;
2775 case MATCH_NO
: proc_name
= NULL
; needs_space
= true; break;
2776 case MATCH_ERROR
: return MATCH_ERROR
;
2779 if (gfc_match_omp_clauses (&c
, OMP_DECLARE_SIMD_CLAUSES
, true,
2780 needs_space
) != MATCH_YES
)
2783 if (gfc_current_ns
->is_block_data
)
2785 gfc_free_omp_clauses (c
);
2789 ods
= gfc_get_omp_declare_simd ();
2791 ods
->proc_name
= proc_name
;
2793 ods
->next
= gfc_current_ns
->omp_declare_simd
;
2794 gfc_current_ns
->omp_declare_simd
= ods
;
2800 match_udr_expr (gfc_symtree
*omp_sym1
, gfc_symtree
*omp_sym2
)
2803 locus old_loc
= gfc_current_locus
;
2804 char sname
[GFC_MAX_SYMBOL_LEN
+ 1];
2806 gfc_namespace
*ns
= gfc_current_ns
;
2807 gfc_expr
*lvalue
= NULL
, *rvalue
= NULL
;
2809 gfc_actual_arglist
*arglist
;
2811 m
= gfc_match (" %v =", &lvalue
);
2813 gfc_current_locus
= old_loc
;
2816 m
= gfc_match (" %e )", &rvalue
);
2819 ns
->code
= gfc_get_code (EXEC_ASSIGN
);
2820 ns
->code
->expr1
= lvalue
;
2821 ns
->code
->expr2
= rvalue
;
2822 ns
->code
->loc
= old_loc
;
2826 gfc_current_locus
= old_loc
;
2827 gfc_free_expr (lvalue
);
2830 m
= gfc_match (" %n", sname
);
2834 if (strcmp (sname
, omp_sym1
->name
) == 0
2835 || strcmp (sname
, omp_sym2
->name
) == 0)
2838 gfc_current_ns
= ns
->parent
;
2839 if (gfc_get_ha_sym_tree (sname
, &st
))
2843 if (sym
->attr
.flavor
!= FL_PROCEDURE
2844 && sym
->attr
.flavor
!= FL_UNKNOWN
)
2847 if (!sym
->attr
.generic
2848 && !sym
->attr
.subroutine
2849 && !sym
->attr
.function
)
2851 if (!(sym
->attr
.external
&& !sym
->attr
.referenced
))
2853 /* ...create a symbol in this scope... */
2854 if (sym
->ns
!= gfc_current_ns
2855 && gfc_get_sym_tree (sname
, NULL
, &st
, false) == 1)
2858 if (sym
!= st
->n
.sym
)
2862 /* ...and then to try to make the symbol into a subroutine. */
2863 if (!gfc_add_subroutine (&sym
->attr
, sym
->name
, NULL
))
2867 gfc_set_sym_referenced (sym
);
2868 gfc_gobble_whitespace ();
2869 if (gfc_peek_ascii_char () != '(')
2872 gfc_current_ns
= ns
;
2873 m
= gfc_match_actual_arglist (1, &arglist
);
2877 if (gfc_match_char (')') != MATCH_YES
)
2880 ns
->code
= gfc_get_code (EXEC_CALL
);
2881 ns
->code
->symtree
= st
;
2882 ns
->code
->ext
.actual
= arglist
;
2883 ns
->code
->loc
= old_loc
;
2888 gfc_omp_udr_predef (gfc_omp_reduction_op rop
, const char *name
,
2889 gfc_typespec
*ts
, const char **n
)
2891 if (!gfc_numeric_ts (ts
) && ts
->type
!= BT_LOGICAL
)
2896 case OMP_REDUCTION_PLUS
:
2897 case OMP_REDUCTION_MINUS
:
2898 case OMP_REDUCTION_TIMES
:
2899 return ts
->type
!= BT_LOGICAL
;
2900 case OMP_REDUCTION_AND
:
2901 case OMP_REDUCTION_OR
:
2902 case OMP_REDUCTION_EQV
:
2903 case OMP_REDUCTION_NEQV
:
2904 return ts
->type
== BT_LOGICAL
;
2905 case OMP_REDUCTION_USER
:
2906 if (name
[0] != '.' && (ts
->type
== BT_INTEGER
|| ts
->type
== BT_REAL
))
2910 gfc_find_symbol (name
, NULL
, 1, &sym
);
2913 if (sym
->attr
.intrinsic
)
2915 else if ((sym
->attr
.flavor
!= FL_UNKNOWN
2916 && sym
->attr
.flavor
!= FL_PROCEDURE
)
2917 || sym
->attr
.external
2918 || sym
->attr
.generic
2922 || sym
->attr
.subroutine
2923 || sym
->attr
.pointer
2925 || sym
->attr
.cray_pointer
2926 || sym
->attr
.cray_pointee
2927 || (sym
->attr
.proc
!= PROC_UNKNOWN
2928 && sym
->attr
.proc
!= PROC_INTRINSIC
)
2929 || sym
->attr
.if_source
!= IFSRC_UNKNOWN
2930 || sym
== sym
->ns
->proc_name
)
2938 && (strcmp (*n
, "max") == 0 || strcmp (*n
, "min") == 0))
2941 && ts
->type
== BT_INTEGER
2942 && (strcmp (*n
, "iand") == 0
2943 || strcmp (*n
, "ior") == 0
2944 || strcmp (*n
, "ieor") == 0))
2955 gfc_omp_udr_find (gfc_symtree
*st
, gfc_typespec
*ts
)
2957 gfc_omp_udr
*omp_udr
;
2962 for (omp_udr
= st
->n
.omp_udr
; omp_udr
; omp_udr
= omp_udr
->next
)
2963 if (omp_udr
->ts
.type
== ts
->type
2964 || ((omp_udr
->ts
.type
== BT_DERIVED
|| omp_udr
->ts
.type
== BT_CLASS
)
2965 && (ts
->type
== BT_DERIVED
|| ts
->type
== BT_CLASS
)))
2967 if (omp_udr
->ts
.type
== BT_DERIVED
|| omp_udr
->ts
.type
== BT_CLASS
)
2969 if (strcmp (omp_udr
->ts
.u
.derived
->name
, ts
->u
.derived
->name
) == 0)
2972 else if (omp_udr
->ts
.kind
== ts
->kind
)
2974 if (omp_udr
->ts
.type
== BT_CHARACTER
)
2976 if (omp_udr
->ts
.u
.cl
->length
== NULL
2977 || ts
->u
.cl
->length
== NULL
)
2979 if (omp_udr
->ts
.u
.cl
->length
->expr_type
!= EXPR_CONSTANT
)
2981 if (ts
->u
.cl
->length
->expr_type
!= EXPR_CONSTANT
)
2983 if (omp_udr
->ts
.u
.cl
->length
->ts
.type
!= BT_INTEGER
)
2985 if (ts
->u
.cl
->length
->ts
.type
!= BT_INTEGER
)
2987 if (gfc_compare_expr (omp_udr
->ts
.u
.cl
->length
,
2988 ts
->u
.cl
->length
, INTRINSIC_EQ
) != 0)
2998 gfc_match_omp_declare_reduction (void)
3001 gfc_intrinsic_op op
;
3002 char name
[GFC_MAX_SYMBOL_LEN
+ 3];
3003 auto_vec
<gfc_typespec
, 5> tss
;
3007 locus where
= gfc_current_locus
;
3008 locus end_loc
= gfc_current_locus
;
3009 bool end_loc_set
= false;
3010 gfc_omp_reduction_op rop
= OMP_REDUCTION_NONE
;
3012 if (gfc_match_char ('(') != MATCH_YES
)
3015 m
= gfc_match (" %o : ", &op
);
3016 if (m
== MATCH_ERROR
)
3020 snprintf (name
, sizeof name
, "operator %s", gfc_op2string (op
));
3021 rop
= (gfc_omp_reduction_op
) op
;
3025 m
= gfc_match_defined_op_name (name
+ 1, 1);
3026 if (m
== MATCH_ERROR
)
3032 if (gfc_match (" : ") != MATCH_YES
)
3037 if (gfc_match (" %n : ", name
) != MATCH_YES
)
3040 rop
= OMP_REDUCTION_USER
;
3043 m
= gfc_match_type_spec (&ts
);
3046 /* Treat len=: the same as len=*. */
3047 if (ts
.type
== BT_CHARACTER
)
3048 ts
.deferred
= false;
3051 while (gfc_match_char (',') == MATCH_YES
)
3053 m
= gfc_match_type_spec (&ts
);
3058 if (gfc_match_char (':') != MATCH_YES
)
3061 st
= gfc_find_symtree (gfc_current_ns
->omp_udr_root
, name
);
3062 for (i
= 0; i
< tss
.length (); i
++)
3064 gfc_symtree
*omp_out
, *omp_in
;
3065 gfc_symtree
*omp_priv
= NULL
, *omp_orig
= NULL
;
3066 gfc_namespace
*combiner_ns
, *initializer_ns
= NULL
;
3067 gfc_omp_udr
*prev_udr
, *omp_udr
;
3068 const char *predef_name
= NULL
;
3070 omp_udr
= gfc_get_omp_udr ();
3071 omp_udr
->name
= gfc_get_string ("%s", name
);
3073 omp_udr
->ts
= tss
[i
];
3074 omp_udr
->where
= where
;
3076 gfc_current_ns
= combiner_ns
= gfc_get_namespace (gfc_current_ns
, 1);
3077 combiner_ns
->proc_name
= combiner_ns
->parent
->proc_name
;
3079 gfc_get_sym_tree ("omp_out", combiner_ns
, &omp_out
, false);
3080 gfc_get_sym_tree ("omp_in", combiner_ns
, &omp_in
, false);
3081 combiner_ns
->omp_udr_ns
= 1;
3082 omp_out
->n
.sym
->ts
= tss
[i
];
3083 omp_in
->n
.sym
->ts
= tss
[i
];
3084 omp_out
->n
.sym
->attr
.omp_udr_artificial_var
= 1;
3085 omp_in
->n
.sym
->attr
.omp_udr_artificial_var
= 1;
3086 omp_out
->n
.sym
->attr
.flavor
= FL_VARIABLE
;
3087 omp_in
->n
.sym
->attr
.flavor
= FL_VARIABLE
;
3088 gfc_commit_symbols ();
3089 omp_udr
->combiner_ns
= combiner_ns
;
3090 omp_udr
->omp_out
= omp_out
->n
.sym
;
3091 omp_udr
->omp_in
= omp_in
->n
.sym
;
3093 locus old_loc
= gfc_current_locus
;
3095 if (!match_udr_expr (omp_out
, omp_in
))
3098 gfc_current_locus
= old_loc
;
3099 gfc_current_ns
= combiner_ns
->parent
;
3100 gfc_undo_symbols ();
3101 gfc_free_omp_udr (omp_udr
);
3105 if (gfc_match (" initializer ( ") == MATCH_YES
)
3107 gfc_current_ns
= combiner_ns
->parent
;
3108 initializer_ns
= gfc_get_namespace (gfc_current_ns
, 1);
3109 gfc_current_ns
= initializer_ns
;
3110 initializer_ns
->proc_name
= initializer_ns
->parent
->proc_name
;
3112 gfc_get_sym_tree ("omp_priv", initializer_ns
, &omp_priv
, false);
3113 gfc_get_sym_tree ("omp_orig", initializer_ns
, &omp_orig
, false);
3114 initializer_ns
->omp_udr_ns
= 1;
3115 omp_priv
->n
.sym
->ts
= tss
[i
];
3116 omp_orig
->n
.sym
->ts
= tss
[i
];
3117 omp_priv
->n
.sym
->attr
.omp_udr_artificial_var
= 1;
3118 omp_orig
->n
.sym
->attr
.omp_udr_artificial_var
= 1;
3119 omp_priv
->n
.sym
->attr
.flavor
= FL_VARIABLE
;
3120 omp_orig
->n
.sym
->attr
.flavor
= FL_VARIABLE
;
3121 gfc_commit_symbols ();
3122 omp_udr
->initializer_ns
= initializer_ns
;
3123 omp_udr
->omp_priv
= omp_priv
->n
.sym
;
3124 omp_udr
->omp_orig
= omp_orig
->n
.sym
;
3126 if (!match_udr_expr (omp_priv
, omp_orig
))
3130 gfc_current_ns
= combiner_ns
->parent
;
3134 end_loc
= gfc_current_locus
;
3136 gfc_current_locus
= old_loc
;
3138 prev_udr
= gfc_omp_udr_find (st
, &tss
[i
]);
3139 if (gfc_omp_udr_predef (rop
, name
, &tss
[i
], &predef_name
)
3140 /* Don't error on !$omp declare reduction (min : integer : ...)
3141 just yet, there could be integer :: min afterwards,
3142 making it valid. When the UDR is resolved, we'll get
3144 && (rop
!= OMP_REDUCTION_USER
|| name
[0] == '.'))
3147 gfc_error_now ("Redefinition of predefined %s "
3148 "!$OMP DECLARE REDUCTION at %L",
3149 predef_name
, &where
);
3151 gfc_error_now ("Redefinition of predefined "
3152 "!$OMP DECLARE REDUCTION at %L", &where
);
3156 gfc_error_now ("Redefinition of !$OMP DECLARE REDUCTION at %L",
3158 gfc_error_now ("Previous !$OMP DECLARE REDUCTION at %L",
3163 omp_udr
->next
= st
->n
.omp_udr
;
3164 st
->n
.omp_udr
= omp_udr
;
3168 st
= gfc_new_symtree (&gfc_current_ns
->omp_udr_root
, name
);
3169 st
->n
.omp_udr
= omp_udr
;
3175 gfc_current_locus
= end_loc
;
3176 if (gfc_match_omp_eos () != MATCH_YES
)
3178 gfc_error ("Unexpected junk after !$OMP DECLARE REDUCTION at %C");
3179 gfc_current_locus
= where
;
3191 gfc_match_omp_declare_target (void)
3195 gfc_omp_clauses
*c
= NULL
;
3197 gfc_omp_namelist
*n
;
3200 old_loc
= gfc_current_locus
;
3202 if (gfc_current_ns
->proc_name
3203 && gfc_match_omp_eos () == MATCH_YES
)
3205 if (!gfc_add_omp_declare_target (&gfc_current_ns
->proc_name
->attr
,
3206 gfc_current_ns
->proc_name
->name
,
3212 if (gfc_current_ns
->proc_name
3213 && gfc_current_ns
->proc_name
->attr
.if_source
== IFSRC_IFBODY
)
3215 gfc_error ("Only the !$OMP DECLARE TARGET form without "
3216 "clauses is allowed in interface block at %C");
3220 m
= gfc_match (" (");
3223 c
= gfc_get_omp_clauses ();
3224 gfc_current_locus
= old_loc
;
3225 m
= gfc_match_omp_to_link (" (", &c
->lists
[OMP_LIST_TO
]);
3228 if (gfc_match_omp_eos () != MATCH_YES
)
3230 gfc_error ("Unexpected junk after !$OMP DECLARE TARGET at %C");
3234 else if (gfc_match_omp_clauses (&c
, OMP_DECLARE_TARGET_CLAUSES
) != MATCH_YES
)
3237 gfc_buffer_error (false);
3239 for (list
= OMP_LIST_TO
; list
!= OMP_LIST_NUM
;
3240 list
= (list
== OMP_LIST_TO
? OMP_LIST_LINK
: OMP_LIST_NUM
))
3241 for (n
= c
->lists
[list
]; n
; n
= n
->next
)
3244 else if (n
->u
.common
->head
)
3245 n
->u
.common
->head
->mark
= 0;
3247 for (list
= OMP_LIST_TO
; list
!= OMP_LIST_NUM
;
3248 list
= (list
== OMP_LIST_TO
? OMP_LIST_LINK
: OMP_LIST_NUM
))
3249 for (n
= c
->lists
[list
]; n
; n
= n
->next
)
3252 if (n
->sym
->attr
.in_common
)
3253 gfc_error_now ("OMP DECLARE TARGET variable at %L is an "
3254 "element of a COMMON block", &n
->where
);
3255 else if (n
->sym
->attr
.omp_declare_target
3256 && n
->sym
->attr
.omp_declare_target_link
3257 && list
!= OMP_LIST_LINK
)
3258 gfc_error_now ("OMP DECLARE TARGET variable at %L previously "
3259 "mentioned in LINK clause and later in TO clause",
3261 else if (n
->sym
->attr
.omp_declare_target
3262 && !n
->sym
->attr
.omp_declare_target_link
3263 && list
== OMP_LIST_LINK
)
3264 gfc_error_now ("OMP DECLARE TARGET variable at %L previously "
3265 "mentioned in TO clause and later in LINK clause",
3267 else if (n
->sym
->mark
)
3268 gfc_error_now ("Variable at %L mentioned multiple times in "
3269 "clauses of the same OMP DECLARE TARGET directive",
3271 else if (gfc_add_omp_declare_target (&n
->sym
->attr
, n
->sym
->name
,
3272 &n
->sym
->declared_at
))
3274 if (list
== OMP_LIST_LINK
)
3275 gfc_add_omp_declare_target_link (&n
->sym
->attr
, n
->sym
->name
,
3276 &n
->sym
->declared_at
);
3280 else if (n
->u
.common
->omp_declare_target
3281 && n
->u
.common
->omp_declare_target_link
3282 && list
!= OMP_LIST_LINK
)
3283 gfc_error_now ("OMP DECLARE TARGET COMMON at %L previously "
3284 "mentioned in LINK clause and later in TO clause",
3286 else if (n
->u
.common
->omp_declare_target
3287 && !n
->u
.common
->omp_declare_target_link
3288 && list
== OMP_LIST_LINK
)
3289 gfc_error_now ("OMP DECLARE TARGET COMMON at %L previously "
3290 "mentioned in TO clause and later in LINK clause",
3292 else if (n
->u
.common
->head
&& n
->u
.common
->head
->mark
)
3293 gfc_error_now ("COMMON at %L mentioned multiple times in "
3294 "clauses of the same OMP DECLARE TARGET directive",
3298 n
->u
.common
->omp_declare_target
= 1;
3299 n
->u
.common
->omp_declare_target_link
= (list
== OMP_LIST_LINK
);
3300 for (s
= n
->u
.common
->head
; s
; s
= s
->common_next
)
3303 if (gfc_add_omp_declare_target (&s
->attr
, s
->name
,
3306 if (list
== OMP_LIST_LINK
)
3307 gfc_add_omp_declare_target_link (&s
->attr
, s
->name
,
3313 gfc_buffer_error (true);
3316 gfc_free_omp_clauses (c
);
3320 gfc_error ("Syntax error in !$OMP DECLARE TARGET list at %C");
3323 gfc_current_locus
= old_loc
;
3325 gfc_free_omp_clauses (c
);
3331 gfc_match_omp_threadprivate (void)
3334 char n
[GFC_MAX_SYMBOL_LEN
+1];
3339 old_loc
= gfc_current_locus
;
3341 m
= gfc_match (" (");
3347 m
= gfc_match_symbol (&sym
, 0);
3351 if (sym
->attr
.in_common
)
3352 gfc_error_now ("Threadprivate variable at %C is an element of "
3354 else if (!gfc_add_threadprivate (&sym
->attr
, sym
->name
, &sym
->declared_at
))
3363 m
= gfc_match (" / %n /", n
);
3364 if (m
== MATCH_ERROR
)
3366 if (m
== MATCH_NO
|| n
[0] == '\0')
3369 st
= gfc_find_symtree (gfc_current_ns
->common_root
, n
);
3372 gfc_error ("COMMON block /%s/ not found at %C", n
);
3375 st
->n
.common
->threadprivate
= 1;
3376 for (sym
= st
->n
.common
->head
; sym
; sym
= sym
->common_next
)
3377 if (!gfc_add_threadprivate (&sym
->attr
, sym
->name
, &sym
->declared_at
))
3381 if (gfc_match_char (')') == MATCH_YES
)
3383 if (gfc_match_char (',') != MATCH_YES
)
3387 if (gfc_match_omp_eos () != MATCH_YES
)
3389 gfc_error ("Unexpected junk after OMP THREADPRIVATE at %C");
3396 gfc_error ("Syntax error in !$OMP THREADPRIVATE list at %C");
3399 gfc_current_locus
= old_loc
;
3405 gfc_match_omp_parallel (void)
3407 return match_omp (EXEC_OMP_PARALLEL
, OMP_PARALLEL_CLAUSES
);
3412 gfc_match_omp_parallel_do (void)
3414 return match_omp (EXEC_OMP_PARALLEL_DO
,
3415 OMP_PARALLEL_CLAUSES
| OMP_DO_CLAUSES
);
3420 gfc_match_omp_parallel_do_simd (void)
3422 return match_omp (EXEC_OMP_PARALLEL_DO_SIMD
,
3423 OMP_PARALLEL_CLAUSES
| OMP_DO_CLAUSES
| OMP_SIMD_CLAUSES
);
3428 gfc_match_omp_parallel_sections (void)
3430 return match_omp (EXEC_OMP_PARALLEL_SECTIONS
,
3431 OMP_PARALLEL_CLAUSES
| OMP_SECTIONS_CLAUSES
);
3436 gfc_match_omp_parallel_workshare (void)
3438 return match_omp (EXEC_OMP_PARALLEL_WORKSHARE
, OMP_PARALLEL_CLAUSES
);
3442 gfc_check_omp_requires (gfc_namespace
*ns
, int ref_omp_requires
)
3444 if (ns
->omp_target_seen
3445 && (ns
->omp_requires
& OMP_REQ_TARGET_MASK
)
3446 != (ref_omp_requires
& OMP_REQ_TARGET_MASK
))
3448 gcc_assert (ns
->proc_name
);
3449 if ((ref_omp_requires
& OMP_REQ_REVERSE_OFFLOAD
)
3450 && !(ns
->omp_requires
& OMP_REQ_REVERSE_OFFLOAD
))
3451 gfc_error ("Program unit at %L has OpenMP device constructs/routines "
3452 "but does not set !$OMP REQUIRES REVERSE_OFFSET but other "
3453 "program units do", &ns
->proc_name
->declared_at
);
3454 if ((ref_omp_requires
& OMP_REQ_UNIFIED_ADDRESS
)
3455 && !(ns
->omp_requires
& OMP_REQ_UNIFIED_ADDRESS
))
3456 gfc_error ("Program unit at %L has OpenMP device constructs/routines "
3457 "but does not set !$OMP REQUIRES UNIFIED_ADDRESS but other "
3458 "program units do", &ns
->proc_name
->declared_at
);
3459 if ((ref_omp_requires
& OMP_REQ_UNIFIED_SHARED_MEMORY
)
3460 && !(ns
->omp_requires
& OMP_REQ_UNIFIED_SHARED_MEMORY
))
3461 gfc_error ("Program unit at %L has OpenMP device constructs/routines "
3462 "but does not set !$OMP REQUIRES UNIFIED_SHARED_MEMORY but "
3463 "other program units do", &ns
->proc_name
->declared_at
);
3468 gfc_omp_requires_add_clause (gfc_omp_requires_kind clause
,
3469 const char *clause_name
, locus
*loc
,
3470 const char *module_name
)
3472 gfc_namespace
*prog_unit
= gfc_current_ns
;
3473 while (prog_unit
->parent
)
3475 if (gfc_state_stack
->previous
3476 && gfc_state_stack
->previous
->state
== COMP_INTERFACE
)
3478 prog_unit
= prog_unit
->parent
;
3481 /* Requires added after use. */
3482 if (prog_unit
->omp_target_seen
3483 && (clause
& OMP_REQ_TARGET_MASK
)
3484 && !(prog_unit
->omp_requires
& clause
))
3487 gfc_error ("!$OMP REQUIRES clause %qs specified via module %qs use "
3488 "at %L comes after using a device construct/routine",
3489 clause_name
, module_name
, loc
);
3491 gfc_error ("!$OMP REQUIRES clause %qs specified at %L comes after "
3492 "using a device construct/routine", clause_name
, loc
);
3496 /* Overriding atomic_default_mem_order clause value. */
3497 if ((clause
& OMP_REQ_ATOMIC_MEM_ORDER_MASK
)
3498 && (prog_unit
->omp_requires
& OMP_REQ_ATOMIC_MEM_ORDER_MASK
)
3499 && (prog_unit
->omp_requires
& OMP_REQ_ATOMIC_MEM_ORDER_MASK
)
3503 if (prog_unit
->omp_requires
& OMP_REQ_ATOMIC_MEM_ORDER_SEQ_CST
)
3505 else if (prog_unit
->omp_requires
& OMP_REQ_ATOMIC_MEM_ORDER_ACQ_REL
)
3507 else if (prog_unit
->omp_requires
& OMP_REQ_ATOMIC_MEM_ORDER_RELAXED
)
3513 gfc_error ("!$OMP REQUIRES clause %<atomic_default_mem_order(%s)%> "
3514 "specified via module %qs use at %L overrides a previous "
3515 "%<atomic_default_mem_order(%s)%> (which might be through "
3516 "using a module)", clause_name
, module_name
, loc
, other
);
3518 gfc_error ("!$OMP REQUIRES clause %<atomic_default_mem_order(%s)%> "
3519 "specified at %L overrides a previous "
3520 "%<atomic_default_mem_order(%s)%> (which might be through "
3521 "using a module)", clause_name
, loc
, other
);
3525 /* Requires via module not at program-unit level and not repeating clause. */
3526 if (prog_unit
!= gfc_current_ns
&& !(prog_unit
->omp_requires
& clause
))
3528 if (clause
& OMP_REQ_ATOMIC_MEM_ORDER_MASK
)
3529 gfc_error ("!$OMP REQUIRES clause %<atomic_default_mem_order(%s)%> "
3530 "specified via module %qs use at %L but same clause is "
3531 "not set at for the program unit", clause_name
, module_name
,
3534 gfc_error ("!$OMP REQUIRES clause %qs specified via module %qs use at "
3535 "%L but same clause is not set at for the program unit",
3536 clause_name
, module_name
, loc
);
3540 if (!gfc_state_stack
->previous
3541 || gfc_state_stack
->previous
->state
!= COMP_INTERFACE
)
3542 prog_unit
->omp_requires
|= clause
;
3547 gfc_match_omp_requires (void)
3549 static const char *clauses
[] = {"reverse_offload",
3551 "unified_shared_memory",
3552 "dynamic_allocators",
3554 const char *clause
= NULL
;
3555 int requires_clauses
= 0;
3559 if (gfc_current_ns
->parent
3560 && (!gfc_state_stack
->previous
3561 || gfc_state_stack
->previous
->state
!= COMP_INTERFACE
))
3563 gfc_error ("!$OMP REQUIRES at %C must appear in the specification part "
3564 "of a program unit");
3570 old_loc
= gfc_current_locus
;
3571 gfc_omp_requires_kind requires_clause
;
3572 if ((first
|| gfc_match_char (',') != MATCH_YES
)
3573 && (first
&& gfc_match_space () != MATCH_YES
))
3576 gfc_gobble_whitespace ();
3577 old_loc
= gfc_current_locus
;
3579 if (gfc_match_omp_eos () != MATCH_NO
)
3581 if (gfc_match (clauses
[0]) == MATCH_YES
)
3583 clause
= clauses
[0];
3584 requires_clause
= OMP_REQ_REVERSE_OFFLOAD
;
3585 if (requires_clauses
& OMP_REQ_REVERSE_OFFLOAD
)
3586 goto duplicate_clause
;
3588 else if (gfc_match (clauses
[1]) == MATCH_YES
)
3590 clause
= clauses
[1];
3591 requires_clause
= OMP_REQ_UNIFIED_ADDRESS
;
3592 if (requires_clauses
& OMP_REQ_UNIFIED_ADDRESS
)
3593 goto duplicate_clause
;
3595 else if (gfc_match (clauses
[2]) == MATCH_YES
)
3597 clause
= clauses
[2];
3598 requires_clause
= OMP_REQ_UNIFIED_SHARED_MEMORY
;
3599 if (requires_clauses
& OMP_REQ_UNIFIED_SHARED_MEMORY
)
3600 goto duplicate_clause
;
3602 else if (gfc_match (clauses
[3]) == MATCH_YES
)
3604 clause
= clauses
[3];
3605 requires_clause
= OMP_REQ_DYNAMIC_ALLOCATORS
;
3606 if (requires_clauses
& OMP_REQ_DYNAMIC_ALLOCATORS
)
3607 goto duplicate_clause
;
3609 else if (gfc_match ("atomic_default_mem_order (") == MATCH_YES
)
3611 clause
= clauses
[4];
3612 if (requires_clauses
& OMP_REQ_ATOMIC_MEM_ORDER_MASK
)
3613 goto duplicate_clause
;
3614 if (gfc_match (" seq_cst )") == MATCH_YES
)
3617 requires_clause
= OMP_REQ_ATOMIC_MEM_ORDER_SEQ_CST
;
3619 else if (gfc_match (" acq_rel )") == MATCH_YES
)
3622 requires_clause
= OMP_REQ_ATOMIC_MEM_ORDER_ACQ_REL
;
3624 else if (gfc_match (" relaxed )") == MATCH_YES
)
3627 requires_clause
= OMP_REQ_ATOMIC_MEM_ORDER_RELAXED
;
3631 gfc_error ("Expected SEQ_CST, ACQ_REL or RELAXED for "
3632 "ATOMIC_DEFAULT_MEM_ORDER clause at %C");
3639 if (requires_clause
& ~OMP_REQ_ATOMIC_MEM_ORDER_MASK
)
3640 gfc_error_now ("Sorry, %qs clause at %L on REQUIRES directive is not "
3641 "yet supported", clause
, &old_loc
);
3642 if (!gfc_omp_requires_add_clause (requires_clause
, clause
, &old_loc
, NULL
))
3644 requires_clauses
|= requires_clause
;
3647 if (requires_clauses
== 0)
3649 if (!gfc_error_flag_test ())
3650 gfc_error ("Clause expected at %C");
3656 gfc_error ("%qs clause at %L specified more than once", clause
, &old_loc
);
3658 if (!gfc_error_flag_test ())
3659 gfc_error ("Expected UNIFIED_ADDRESS, UNIFIED_SHARED_MEMORY, "
3660 "DYNAMIC_ALLOCATORS, REVERSE_OFFLOAD, or "
3661 "ATOMIC_DEFAULT_MEM_ORDER clause at %L", &old_loc
);
3667 gfc_match_omp_sections (void)
3669 return match_omp (EXEC_OMP_SECTIONS
, OMP_SECTIONS_CLAUSES
);
3674 gfc_match_omp_simd (void)
3676 return match_omp (EXEC_OMP_SIMD
, OMP_SIMD_CLAUSES
);
3681 gfc_match_omp_single (void)
3683 return match_omp (EXEC_OMP_SINGLE
, OMP_SINGLE_CLAUSES
);
3688 gfc_match_omp_target (void)
3690 return match_omp (EXEC_OMP_TARGET
, OMP_TARGET_CLAUSES
);
3695 gfc_match_omp_target_data (void)
3697 return match_omp (EXEC_OMP_TARGET_DATA
, OMP_TARGET_DATA_CLAUSES
);
3702 gfc_match_omp_target_enter_data (void)
3704 return match_omp (EXEC_OMP_TARGET_ENTER_DATA
, OMP_TARGET_ENTER_DATA_CLAUSES
);
3709 gfc_match_omp_target_exit_data (void)
3711 return match_omp (EXEC_OMP_TARGET_EXIT_DATA
, OMP_TARGET_EXIT_DATA_CLAUSES
);
3716 gfc_match_omp_target_parallel (void)
3718 return match_omp (EXEC_OMP_TARGET_PARALLEL
,
3719 (OMP_TARGET_CLAUSES
| OMP_PARALLEL_CLAUSES
)
3720 & ~(omp_mask (OMP_CLAUSE_COPYIN
)));
3725 gfc_match_omp_target_parallel_do (void)
3727 return match_omp (EXEC_OMP_TARGET_PARALLEL_DO
,
3728 (OMP_TARGET_CLAUSES
| OMP_PARALLEL_CLAUSES
3729 | OMP_DO_CLAUSES
) & ~(omp_mask (OMP_CLAUSE_COPYIN
)));
3734 gfc_match_omp_target_parallel_do_simd (void)
3736 return match_omp (EXEC_OMP_TARGET_PARALLEL_DO_SIMD
,
3737 (OMP_TARGET_CLAUSES
| OMP_PARALLEL_CLAUSES
| OMP_DO_CLAUSES
3738 | OMP_SIMD_CLAUSES
) & ~(omp_mask (OMP_CLAUSE_COPYIN
)));
3743 gfc_match_omp_target_simd (void)
3745 return match_omp (EXEC_OMP_TARGET_SIMD
,
3746 OMP_TARGET_CLAUSES
| OMP_SIMD_CLAUSES
);
3751 gfc_match_omp_target_teams (void)
3753 return match_omp (EXEC_OMP_TARGET_TEAMS
,
3754 OMP_TARGET_CLAUSES
| OMP_TEAMS_CLAUSES
);
3759 gfc_match_omp_target_teams_distribute (void)
3761 return match_omp (EXEC_OMP_TARGET_TEAMS_DISTRIBUTE
,
3762 OMP_TARGET_CLAUSES
| OMP_TEAMS_CLAUSES
3763 | OMP_DISTRIBUTE_CLAUSES
);
3768 gfc_match_omp_target_teams_distribute_parallel_do (void)
3770 return match_omp (EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO
,
3771 (OMP_TARGET_CLAUSES
| OMP_TEAMS_CLAUSES
3772 | OMP_DISTRIBUTE_CLAUSES
| OMP_PARALLEL_CLAUSES
3774 & ~(omp_mask (OMP_CLAUSE_ORDERED
))
3775 & ~(omp_mask (OMP_CLAUSE_LINEAR
)));
3780 gfc_match_omp_target_teams_distribute_parallel_do_simd (void)
3782 return match_omp (EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
,
3783 (OMP_TARGET_CLAUSES
| OMP_TEAMS_CLAUSES
3784 | OMP_DISTRIBUTE_CLAUSES
| OMP_PARALLEL_CLAUSES
3785 | OMP_DO_CLAUSES
| OMP_SIMD_CLAUSES
)
3786 & ~(omp_mask (OMP_CLAUSE_ORDERED
)));
3791 gfc_match_omp_target_teams_distribute_simd (void)
3793 return match_omp (EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD
,
3794 OMP_TARGET_CLAUSES
| OMP_TEAMS_CLAUSES
3795 | OMP_DISTRIBUTE_CLAUSES
| OMP_SIMD_CLAUSES
);
3800 gfc_match_omp_target_update (void)
3802 return match_omp (EXEC_OMP_TARGET_UPDATE
, OMP_TARGET_UPDATE_CLAUSES
);
3807 gfc_match_omp_task (void)
3809 return match_omp (EXEC_OMP_TASK
, OMP_TASK_CLAUSES
);
3814 gfc_match_omp_taskloop (void)
3816 return match_omp (EXEC_OMP_TASKLOOP
, OMP_TASKLOOP_CLAUSES
);
3821 gfc_match_omp_taskloop_simd (void)
3823 return match_omp (EXEC_OMP_TASKLOOP_SIMD
,
3824 (OMP_TASKLOOP_CLAUSES
| OMP_SIMD_CLAUSES
)
3825 & ~(omp_mask (OMP_CLAUSE_REDUCTION
)));
3830 gfc_match_omp_taskwait (void)
3832 if (gfc_match_omp_eos () != MATCH_YES
)
3834 gfc_error ("Unexpected junk after TASKWAIT clause at %C");
3837 new_st
.op
= EXEC_OMP_TASKWAIT
;
3838 new_st
.ext
.omp_clauses
= NULL
;
3844 gfc_match_omp_taskyield (void)
3846 if (gfc_match_omp_eos () != MATCH_YES
)
3848 gfc_error ("Unexpected junk after TASKYIELD clause at %C");
3851 new_st
.op
= EXEC_OMP_TASKYIELD
;
3852 new_st
.ext
.omp_clauses
= NULL
;
3858 gfc_match_omp_teams (void)
3860 return match_omp (EXEC_OMP_TEAMS
, OMP_TEAMS_CLAUSES
);
3865 gfc_match_omp_teams_distribute (void)
3867 return match_omp (EXEC_OMP_TEAMS_DISTRIBUTE
,
3868 OMP_TEAMS_CLAUSES
| OMP_DISTRIBUTE_CLAUSES
);
3873 gfc_match_omp_teams_distribute_parallel_do (void)
3875 return match_omp (EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO
,
3876 (OMP_TEAMS_CLAUSES
| OMP_DISTRIBUTE_CLAUSES
3877 | OMP_PARALLEL_CLAUSES
| OMP_DO_CLAUSES
)
3878 & ~(omp_mask (OMP_CLAUSE_ORDERED
))
3879 & ~(omp_mask (OMP_CLAUSE_LINEAR
)));
3884 gfc_match_omp_teams_distribute_parallel_do_simd (void)
3886 return match_omp (EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
,
3887 (OMP_TEAMS_CLAUSES
| OMP_DISTRIBUTE_CLAUSES
3888 | OMP_PARALLEL_CLAUSES
| OMP_DO_CLAUSES
3889 | OMP_SIMD_CLAUSES
) & ~(omp_mask (OMP_CLAUSE_ORDERED
)));
3894 gfc_match_omp_teams_distribute_simd (void)
3896 return match_omp (EXEC_OMP_TEAMS_DISTRIBUTE_SIMD
,
3897 OMP_TEAMS_CLAUSES
| OMP_DISTRIBUTE_CLAUSES
3898 | OMP_SIMD_CLAUSES
);
3903 gfc_match_omp_workshare (void)
3905 if (gfc_match_omp_eos () != MATCH_YES
)
3907 gfc_error ("Unexpected junk after $OMP WORKSHARE statement at %C");
3910 new_st
.op
= EXEC_OMP_WORKSHARE
;
3911 new_st
.ext
.omp_clauses
= gfc_get_omp_clauses ();
3917 gfc_match_omp_master (void)
3919 if (gfc_match_omp_eos () != MATCH_YES
)
3921 gfc_error ("Unexpected junk after $OMP MASTER statement at %C");
3924 new_st
.op
= EXEC_OMP_MASTER
;
3925 new_st
.ext
.omp_clauses
= NULL
;
3931 gfc_match_omp_ordered (void)
3933 return match_omp (EXEC_OMP_ORDERED
, OMP_ORDERED_CLAUSES
);
3938 gfc_match_omp_ordered_depend (void)
3940 return match_omp (EXEC_OMP_ORDERED
, omp_mask (OMP_CLAUSE_DEPEND
));
3945 gfc_match_omp_oacc_atomic (bool omp_p
)
3947 gfc_omp_atomic_op op
= GFC_OMP_ATOMIC_UPDATE
;
3949 if (gfc_match ("% seq_cst") == MATCH_YES
)
3951 locus old_loc
= gfc_current_locus
;
3952 if (seq_cst
&& gfc_match_char (',') == MATCH_YES
)
3955 || gfc_match_space () == MATCH_YES
)
3957 gfc_gobble_whitespace ();
3958 if (gfc_match ("update") == MATCH_YES
)
3959 op
= GFC_OMP_ATOMIC_UPDATE
;
3960 else if (gfc_match ("read") == MATCH_YES
)
3961 op
= GFC_OMP_ATOMIC_READ
;
3962 else if (gfc_match ("write") == MATCH_YES
)
3963 op
= GFC_OMP_ATOMIC_WRITE
;
3964 else if (gfc_match ("capture") == MATCH_YES
)
3965 op
= GFC_OMP_ATOMIC_CAPTURE
;
3969 gfc_current_locus
= old_loc
;
3973 && (gfc_match (", seq_cst") == MATCH_YES
3974 || gfc_match ("% seq_cst") == MATCH_YES
))
3978 if (gfc_match_omp_eos () != MATCH_YES
)
3980 gfc_error ("Unexpected junk after $OMP ATOMIC statement at %C");
3983 new_st
.op
= (omp_p
? EXEC_OMP_ATOMIC
: EXEC_OACC_ATOMIC
);
3985 op
= (gfc_omp_atomic_op
) (op
| GFC_OMP_ATOMIC_SEQ_CST
);
3988 gfc_namespace
*prog_unit
= gfc_current_ns
;
3989 while (prog_unit
->parent
)
3990 prog_unit
= prog_unit
->parent
;
3991 switch (prog_unit
->omp_requires
& OMP_REQ_ATOMIC_MEM_ORDER_MASK
)
3994 case OMP_REQ_ATOMIC_MEM_ORDER_RELAXED
:
3996 case OMP_REQ_ATOMIC_MEM_ORDER_SEQ_CST
:
3997 op
= (gfc_omp_atomic_op
) (op
| GFC_OMP_ATOMIC_SEQ_CST
);
3999 case OMP_REQ_ATOMIC_MEM_ORDER_ACQ_REL
:
4000 op
= (gfc_omp_atomic_op
) (op
| GFC_OMP_ATOMIC_ACQ_REL
);
4006 new_st
.ext
.omp_atomic
= op
;
4011 gfc_match_oacc_atomic (void)
4013 return gfc_match_omp_oacc_atomic (false);
4017 gfc_match_omp_atomic (void)
4019 return gfc_match_omp_oacc_atomic (true);
4023 gfc_match_omp_barrier (void)
4025 if (gfc_match_omp_eos () != MATCH_YES
)
4027 gfc_error ("Unexpected junk after $OMP BARRIER statement at %C");
4030 new_st
.op
= EXEC_OMP_BARRIER
;
4031 new_st
.ext
.omp_clauses
= NULL
;
4037 gfc_match_omp_taskgroup (void)
4039 if (gfc_match_omp_eos () != MATCH_YES
)
4041 gfc_error ("Unexpected junk after $OMP TASKGROUP statement at %C");
4044 new_st
.op
= EXEC_OMP_TASKGROUP
;
4049 static enum gfc_omp_cancel_kind
4050 gfc_match_omp_cancel_kind (void)
4052 if (gfc_match_space () != MATCH_YES
)
4053 return OMP_CANCEL_UNKNOWN
;
4054 if (gfc_match ("parallel") == MATCH_YES
)
4055 return OMP_CANCEL_PARALLEL
;
4056 if (gfc_match ("sections") == MATCH_YES
)
4057 return OMP_CANCEL_SECTIONS
;
4058 if (gfc_match ("do") == MATCH_YES
)
4059 return OMP_CANCEL_DO
;
4060 if (gfc_match ("taskgroup") == MATCH_YES
)
4061 return OMP_CANCEL_TASKGROUP
;
4062 return OMP_CANCEL_UNKNOWN
;
4067 gfc_match_omp_cancel (void)
4070 enum gfc_omp_cancel_kind kind
= gfc_match_omp_cancel_kind ();
4071 if (kind
== OMP_CANCEL_UNKNOWN
)
4073 if (gfc_match_omp_clauses (&c
, omp_mask (OMP_CLAUSE_IF
), false) != MATCH_YES
)
4076 new_st
.op
= EXEC_OMP_CANCEL
;
4077 new_st
.ext
.omp_clauses
= c
;
4083 gfc_match_omp_cancellation_point (void)
4086 enum gfc_omp_cancel_kind kind
= gfc_match_omp_cancel_kind ();
4087 if (kind
== OMP_CANCEL_UNKNOWN
)
4089 if (gfc_match_omp_eos () != MATCH_YES
)
4091 gfc_error ("Unexpected junk after $OMP CANCELLATION POINT statement "
4095 c
= gfc_get_omp_clauses ();
4097 new_st
.op
= EXEC_OMP_CANCELLATION_POINT
;
4098 new_st
.ext
.omp_clauses
= c
;
4104 gfc_match_omp_end_nowait (void)
4106 bool nowait
= false;
4107 if (gfc_match ("% nowait") == MATCH_YES
)
4109 if (gfc_match_omp_eos () != MATCH_YES
)
4111 gfc_error ("Unexpected junk after NOWAIT clause at %C");
4114 new_st
.op
= EXEC_OMP_END_NOWAIT
;
4115 new_st
.ext
.omp_bool
= nowait
;
4121 gfc_match_omp_end_single (void)
4124 if (gfc_match ("% nowait") == MATCH_YES
)
4126 new_st
.op
= EXEC_OMP_END_NOWAIT
;
4127 new_st
.ext
.omp_bool
= true;
4130 if (gfc_match_omp_clauses (&c
, omp_mask (OMP_CLAUSE_COPYPRIVATE
))
4133 new_st
.op
= EXEC_OMP_END_SINGLE
;
4134 new_st
.ext
.omp_clauses
= c
;
4140 oacc_is_loop (gfc_code
*code
)
4142 return code
->op
== EXEC_OACC_PARALLEL_LOOP
4143 || code
->op
== EXEC_OACC_KERNELS_LOOP
4144 || code
->op
== EXEC_OACC_SERIAL_LOOP
4145 || code
->op
== EXEC_OACC_LOOP
;
4149 resolve_scalar_int_expr (gfc_expr
*expr
, const char *clause
)
4151 if (!gfc_resolve_expr (expr
)
4152 || expr
->ts
.type
!= BT_INTEGER
4154 gfc_error ("%s clause at %L requires a scalar INTEGER expression",
4155 clause
, &expr
->where
);
4159 resolve_positive_int_expr (gfc_expr
*expr
, const char *clause
)
4161 resolve_scalar_int_expr (expr
, clause
);
4162 if (expr
->expr_type
== EXPR_CONSTANT
4163 && expr
->ts
.type
== BT_INTEGER
4164 && mpz_sgn (expr
->value
.integer
) <= 0)
4165 gfc_warning (0, "INTEGER expression of %s clause at %L must be positive",
4166 clause
, &expr
->where
);
4170 resolve_nonnegative_int_expr (gfc_expr
*expr
, const char *clause
)
4172 resolve_scalar_int_expr (expr
, clause
);
4173 if (expr
->expr_type
== EXPR_CONSTANT
4174 && expr
->ts
.type
== BT_INTEGER
4175 && mpz_sgn (expr
->value
.integer
) < 0)
4176 gfc_warning (0, "INTEGER expression of %s clause at %L must be "
4177 "non-negative", clause
, &expr
->where
);
4180 /* Emits error when symbol is pointer, cray pointer or cray pointee
4181 of derived of polymorphic type. */
4184 check_symbol_not_pointer (gfc_symbol
*sym
, locus loc
, const char *name
)
4186 if (sym
->ts
.type
== BT_DERIVED
&& sym
->attr
.cray_pointer
)
4187 gfc_error ("Cray pointer object %qs of derived type in %s clause at %L",
4188 sym
->name
, name
, &loc
);
4189 if (sym
->ts
.type
== BT_DERIVED
&& sym
->attr
.cray_pointee
)
4190 gfc_error ("Cray pointee object %qs of derived type in %s clause at %L",
4191 sym
->name
, name
, &loc
);
4193 if ((sym
->ts
.type
== BT_ASSUMED
&& sym
->attr
.pointer
)
4194 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
4195 && CLASS_DATA (sym
)->attr
.pointer
))
4196 gfc_error ("POINTER object %qs of polymorphic type in %s clause at %L",
4197 sym
->name
, name
, &loc
);
4198 if ((sym
->ts
.type
== BT_ASSUMED
&& sym
->attr
.cray_pointer
)
4199 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
4200 && CLASS_DATA (sym
)->attr
.cray_pointer
))
4201 gfc_error ("Cray pointer object %qs of polymorphic type in %s clause at %L",
4202 sym
->name
, name
, &loc
);
4203 if ((sym
->ts
.type
== BT_ASSUMED
&& sym
->attr
.cray_pointee
)
4204 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
4205 && CLASS_DATA (sym
)->attr
.cray_pointee
))
4206 gfc_error ("Cray pointee object %qs of polymorphic type in %s clause at %L",
4207 sym
->name
, name
, &loc
);
4210 /* Emits error when symbol represents assumed size/rank array. */
4213 check_array_not_assumed (gfc_symbol
*sym
, locus loc
, const char *name
)
4215 if (sym
->as
&& sym
->as
->type
== AS_ASSUMED_SIZE
)
4216 gfc_error ("Assumed size array %qs in %s clause at %L",
4217 sym
->name
, name
, &loc
);
4218 if (sym
->as
&& sym
->as
->type
== AS_ASSUMED_RANK
)
4219 gfc_error ("Assumed rank array %qs in %s clause at %L",
4220 sym
->name
, name
, &loc
);
4224 resolve_oacc_data_clauses (gfc_symbol
*sym
, locus loc
, const char *name
)
4226 check_array_not_assumed (sym
, loc
, name
);
4230 resolve_oacc_deviceptr_clause (gfc_symbol
*sym
, locus loc
, const char *name
)
4232 if (sym
->attr
.pointer
4233 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
4234 && CLASS_DATA (sym
)->attr
.class_pointer
))
4235 gfc_error ("POINTER object %qs in %s clause at %L",
4236 sym
->name
, name
, &loc
);
4237 if (sym
->attr
.cray_pointer
4238 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
4239 && CLASS_DATA (sym
)->attr
.cray_pointer
))
4240 gfc_error ("Cray pointer object %qs in %s clause at %L",
4241 sym
->name
, name
, &loc
);
4242 if (sym
->attr
.cray_pointee
4243 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
4244 && CLASS_DATA (sym
)->attr
.cray_pointee
))
4245 gfc_error ("Cray pointee object %qs in %s clause at %L",
4246 sym
->name
, name
, &loc
);
4247 if (sym
->attr
.allocatable
4248 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
4249 && CLASS_DATA (sym
)->attr
.allocatable
))
4250 gfc_error ("ALLOCATABLE object %qs in %s clause at %L",
4251 sym
->name
, name
, &loc
);
4252 if (sym
->attr
.value
)
4253 gfc_error ("VALUE object %qs in %s clause at %L",
4254 sym
->name
, name
, &loc
);
4255 check_array_not_assumed (sym
, loc
, name
);
4259 struct resolve_omp_udr_callback_data
4261 gfc_symbol
*sym1
, *sym2
;
4266 resolve_omp_udr_callback (gfc_expr
**e
, int *, void *data
)
4268 struct resolve_omp_udr_callback_data
*rcd
4269 = (struct resolve_omp_udr_callback_data
*) data
;
4270 if ((*e
)->expr_type
== EXPR_VARIABLE
4271 && ((*e
)->symtree
->n
.sym
== rcd
->sym1
4272 || (*e
)->symtree
->n
.sym
== rcd
->sym2
))
4274 gfc_ref
*ref
= gfc_get_ref ();
4275 ref
->type
= REF_ARRAY
;
4276 ref
->u
.ar
.where
= (*e
)->where
;
4277 ref
->u
.ar
.as
= (*e
)->symtree
->n
.sym
->as
;
4278 ref
->u
.ar
.type
= AR_FULL
;
4279 ref
->u
.ar
.dimen
= 0;
4280 ref
->next
= (*e
)->ref
;
4288 resolve_omp_udr_callback2 (gfc_expr
**e
, int *, void *)
4290 if ((*e
)->expr_type
== EXPR_FUNCTION
4291 && (*e
)->value
.function
.isym
== NULL
)
4293 gfc_symbol
*sym
= (*e
)->symtree
->n
.sym
;
4294 if (!sym
->attr
.intrinsic
4295 && sym
->attr
.if_source
== IFSRC_UNKNOWN
)
4296 gfc_error ("Implicitly declared function %s used in "
4297 "!$OMP DECLARE REDUCTION at %L", sym
->name
, &(*e
)->where
);
4304 resolve_omp_udr_clause (gfc_omp_namelist
*n
, gfc_namespace
*ns
,
4305 gfc_symbol
*sym1
, gfc_symbol
*sym2
)
4308 gfc_symbol sym1_copy
, sym2_copy
;
4310 if (ns
->code
->op
== EXEC_ASSIGN
)
4312 copy
= gfc_get_code (EXEC_ASSIGN
);
4313 copy
->expr1
= gfc_copy_expr (ns
->code
->expr1
);
4314 copy
->expr2
= gfc_copy_expr (ns
->code
->expr2
);
4318 copy
= gfc_get_code (EXEC_CALL
);
4319 copy
->symtree
= ns
->code
->symtree
;
4320 copy
->ext
.actual
= gfc_copy_actual_arglist (ns
->code
->ext
.actual
);
4322 copy
->loc
= ns
->code
->loc
;
4327 sym1
->name
= sym1_copy
.name
;
4328 sym2
->name
= sym2_copy
.name
;
4329 ns
->proc_name
= ns
->parent
->proc_name
;
4330 if (n
->sym
->attr
.dimension
)
4332 struct resolve_omp_udr_callback_data rcd
;
4335 gfc_code_walker (©
, gfc_dummy_code_callback
,
4336 resolve_omp_udr_callback
, &rcd
);
4338 gfc_resolve_code (copy
, gfc_current_ns
);
4339 if (copy
->op
== EXEC_CALL
&& copy
->resolved_isym
== NULL
)
4341 gfc_symbol
*sym
= copy
->resolved_sym
;
4343 && !sym
->attr
.intrinsic
4344 && sym
->attr
.if_source
== IFSRC_UNKNOWN
)
4345 gfc_error ("Implicitly declared subroutine %s used in "
4346 "!$OMP DECLARE REDUCTION at %L", sym
->name
,
4349 gfc_code_walker (©
, gfc_dummy_code_callback
,
4350 resolve_omp_udr_callback2
, NULL
);
4356 /* OpenMP directive resolving routines. */
4359 resolve_omp_clauses (gfc_code
*code
, gfc_omp_clauses
*omp_clauses
,
4360 gfc_namespace
*ns
, bool openacc
= false)
4362 gfc_omp_namelist
*n
;
4366 bool if_without_mod
= false;
4367 gfc_omp_linear_op linear_op
= OMP_LINEAR_DEFAULT
;
4368 static const char *clause_names
[]
4369 = { "PRIVATE", "FIRSTPRIVATE", "LASTPRIVATE", "COPYPRIVATE", "SHARED",
4370 "COPYIN", "UNIFORM", "ALIGNED", "LINEAR", "DEPEND", "MAP",
4371 "TO", "FROM", "REDUCTION", "DEVICE_RESIDENT", "LINK", "USE_DEVICE",
4372 "CACHE", "IS_DEVICE_PTR", "USE_DEVICE_PTR", "USE_DEVICE_ADDR",
4374 STATIC_ASSERT (ARRAY_SIZE (clause_names
) == OMP_LIST_NUM
);
4376 if (omp_clauses
== NULL
)
4379 if (omp_clauses
->orderedc
&& omp_clauses
->orderedc
< omp_clauses
->collapse
)
4380 gfc_error ("ORDERED clause parameter is less than COLLAPSE at %L",
4383 if (omp_clauses
->if_expr
)
4385 gfc_expr
*expr
= omp_clauses
->if_expr
;
4386 if (!gfc_resolve_expr (expr
)
4387 || expr
->ts
.type
!= BT_LOGICAL
|| expr
->rank
!= 0)
4388 gfc_error ("IF clause at %L requires a scalar LOGICAL expression",
4390 if_without_mod
= true;
4392 for (ifc
= 0; ifc
< OMP_IF_LAST
; ifc
++)
4393 if (omp_clauses
->if_exprs
[ifc
])
4395 gfc_expr
*expr
= omp_clauses
->if_exprs
[ifc
];
4397 if (!gfc_resolve_expr (expr
)
4398 || expr
->ts
.type
!= BT_LOGICAL
|| expr
->rank
!= 0)
4399 gfc_error ("IF clause at %L requires a scalar LOGICAL expression",
4401 else if (if_without_mod
)
4403 gfc_error ("IF clause without modifier at %L used together with "
4404 "IF clauses with modifiers",
4405 &omp_clauses
->if_expr
->where
);
4406 if_without_mod
= false;
4411 case EXEC_OMP_CANCEL
:
4412 ok
= ifc
== OMP_IF_CANCEL
;
4415 case EXEC_OMP_PARALLEL
:
4416 case EXEC_OMP_PARALLEL_DO
:
4417 case EXEC_OMP_PARALLEL_SECTIONS
:
4418 case EXEC_OMP_PARALLEL_WORKSHARE
:
4419 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO
:
4420 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO
:
4421 ok
= ifc
== OMP_IF_PARALLEL
;
4424 case EXEC_OMP_PARALLEL_DO_SIMD
:
4425 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD
:
4426 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
4427 ok
= ifc
== OMP_IF_PARALLEL
|| ifc
== OMP_IF_SIMD
;
4431 case EXEC_OMP_DO_SIMD
:
4432 case EXEC_OMP_DISTRIBUTE_SIMD
:
4433 case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD
:
4434 ok
= ifc
== OMP_IF_SIMD
;
4438 ok
= ifc
== OMP_IF_TASK
;
4441 case EXEC_OMP_TASKLOOP
:
4442 ok
= ifc
== OMP_IF_TASKLOOP
;
4445 case EXEC_OMP_TASKLOOP_SIMD
:
4446 ok
= ifc
== OMP_IF_TASKLOOP
|| ifc
== OMP_IF_SIMD
;
4449 case EXEC_OMP_TARGET
:
4450 case EXEC_OMP_TARGET_TEAMS
:
4451 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE
:
4452 ok
= ifc
== OMP_IF_TARGET
;
4455 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD
:
4456 case EXEC_OMP_TARGET_SIMD
:
4457 ok
= ifc
== OMP_IF_TARGET
|| ifc
== OMP_IF_SIMD
;
4460 case EXEC_OMP_TARGET_DATA
:
4461 ok
= ifc
== OMP_IF_TARGET_DATA
;
4464 case EXEC_OMP_TARGET_UPDATE
:
4465 ok
= ifc
== OMP_IF_TARGET_UPDATE
;
4468 case EXEC_OMP_TARGET_ENTER_DATA
:
4469 ok
= ifc
== OMP_IF_TARGET_ENTER_DATA
;
4472 case EXEC_OMP_TARGET_EXIT_DATA
:
4473 ok
= ifc
== OMP_IF_TARGET_EXIT_DATA
;
4476 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO
:
4477 case EXEC_OMP_TARGET_PARALLEL
:
4478 case EXEC_OMP_TARGET_PARALLEL_DO
:
4479 ok
= ifc
== OMP_IF_TARGET
|| ifc
== OMP_IF_PARALLEL
;
4482 case EXEC_OMP_TARGET_PARALLEL_DO_SIMD
:
4483 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
4484 ok
= (ifc
== OMP_IF_TARGET
4485 || ifc
== OMP_IF_PARALLEL
4486 || ifc
== OMP_IF_SIMD
);
4495 static const char *ifs
[] = {
4504 "TARGET ENTER DATA",
4507 gfc_error ("IF clause modifier %s at %L not appropriate for "
4508 "the current OpenMP construct", ifs
[ifc
], &expr
->where
);
4512 if (omp_clauses
->final_expr
)
4514 gfc_expr
*expr
= omp_clauses
->final_expr
;
4515 if (!gfc_resolve_expr (expr
)
4516 || expr
->ts
.type
!= BT_LOGICAL
|| expr
->rank
!= 0)
4517 gfc_error ("FINAL clause at %L requires a scalar LOGICAL expression",
4520 if (omp_clauses
->num_threads
)
4521 resolve_positive_int_expr (omp_clauses
->num_threads
, "NUM_THREADS");
4522 if (omp_clauses
->chunk_size
)
4524 gfc_expr
*expr
= omp_clauses
->chunk_size
;
4525 if (!gfc_resolve_expr (expr
)
4526 || expr
->ts
.type
!= BT_INTEGER
|| expr
->rank
!= 0)
4527 gfc_error ("SCHEDULE clause's chunk_size at %L requires "
4528 "a scalar INTEGER expression", &expr
->where
);
4529 else if (expr
->expr_type
== EXPR_CONSTANT
4530 && expr
->ts
.type
== BT_INTEGER
4531 && mpz_sgn (expr
->value
.integer
) <= 0)
4532 gfc_warning (0, "INTEGER expression of SCHEDULE clause's chunk_size "
4533 "at %L must be positive", &expr
->where
);
4535 if (omp_clauses
->sched_kind
!= OMP_SCHED_NONE
4536 && omp_clauses
->sched_nonmonotonic
)
4538 if (omp_clauses
->sched_kind
!= OMP_SCHED_DYNAMIC
4539 && omp_clauses
->sched_kind
!= OMP_SCHED_GUIDED
)
4542 switch (omp_clauses
->sched_kind
)
4544 case OMP_SCHED_STATIC
: p
= "STATIC"; break;
4545 case OMP_SCHED_RUNTIME
: p
= "RUNTIME"; break;
4546 case OMP_SCHED_AUTO
: p
= "AUTO"; break;
4547 default: gcc_unreachable ();
4549 gfc_error ("NONMONOTONIC modifier specified for %s schedule kind "
4550 "at %L", p
, &code
->loc
);
4552 else if (omp_clauses
->sched_monotonic
)
4553 gfc_error ("Both MONOTONIC and NONMONOTONIC schedule modifiers "
4554 "specified at %L", &code
->loc
);
4555 else if (omp_clauses
->ordered
)
4556 gfc_error ("NONMONOTONIC schedule modifier specified with ORDERED "
4557 "clause at %L", &code
->loc
);
4560 /* Check that no symbol appears on multiple clauses, except that
4561 a symbol can appear on both firstprivate and lastprivate. */
4562 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
4563 for (n
= omp_clauses
->lists
[list
]; n
; n
= n
->next
)
4566 n
->sym
->comp_mark
= 0;
4567 if (n
->sym
->attr
.flavor
== FL_VARIABLE
4568 || n
->sym
->attr
.proc_pointer
4569 || (!code
&& (!n
->sym
->attr
.dummy
|| n
->sym
->ns
!= ns
)))
4571 if (!code
&& (!n
->sym
->attr
.dummy
|| n
->sym
->ns
!= ns
))
4572 gfc_error ("Variable %qs is not a dummy argument at %L",
4573 n
->sym
->name
, &n
->where
);
4576 if (n
->sym
->attr
.flavor
== FL_PROCEDURE
4577 && n
->sym
->result
== n
->sym
4578 && n
->sym
->attr
.function
)
4580 if (gfc_current_ns
->proc_name
== n
->sym
4581 || (gfc_current_ns
->parent
4582 && gfc_current_ns
->parent
->proc_name
== n
->sym
))
4584 if (gfc_current_ns
->proc_name
->attr
.entry_master
)
4586 gfc_entry_list
*el
= gfc_current_ns
->entries
;
4587 for (; el
; el
= el
->next
)
4588 if (el
->sym
== n
->sym
)
4593 if (gfc_current_ns
->parent
4594 && gfc_current_ns
->parent
->proc_name
->attr
.entry_master
)
4596 gfc_entry_list
*el
= gfc_current_ns
->parent
->entries
;
4597 for (; el
; el
= el
->next
)
4598 if (el
->sym
== n
->sym
)
4604 if (list
== OMP_LIST_MAP
4605 && n
->sym
->attr
.flavor
== FL_PARAMETER
)
4608 gfc_error ("Object %qs is not a variable at %L; parameters"
4609 " cannot be and need not be copied", n
->sym
->name
,
4612 gfc_error ("Object %qs is not a variable at %L; parameters"
4613 " cannot be and need not be mapped", n
->sym
->name
,
4617 gfc_error ("Object %qs is not a variable at %L", n
->sym
->name
,
4621 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
4622 if (list
!= OMP_LIST_FIRSTPRIVATE
4623 && list
!= OMP_LIST_LASTPRIVATE
4624 && list
!= OMP_LIST_ALIGNED
4625 && list
!= OMP_LIST_DEPEND
4626 && (list
!= OMP_LIST_MAP
|| openacc
)
4627 && list
!= OMP_LIST_FROM
4628 && list
!= OMP_LIST_TO
4629 && (list
!= OMP_LIST_REDUCTION
|| !openacc
))
4630 for (n
= omp_clauses
->lists
[list
]; n
; n
= n
->next
)
4632 bool component_ref_p
= false;
4634 /* Allow multiple components of the same (e.g. derived-type)
4635 variable here. Duplicate components are detected elsewhere. */
4636 if (n
->expr
&& n
->expr
->expr_type
== EXPR_VARIABLE
)
4637 for (gfc_ref
*ref
= n
->expr
->ref
; ref
; ref
= ref
->next
)
4638 if (ref
->type
== REF_COMPONENT
)
4639 component_ref_p
= true;
4640 if ((!component_ref_p
&& n
->sym
->comp_mark
)
4641 || (component_ref_p
&& n
->sym
->mark
))
4642 gfc_error ("Symbol %qs has mixed component and non-component "
4643 "accesses at %L", n
->sym
->name
, &n
->where
);
4644 else if (n
->sym
->mark
)
4645 gfc_error ("Symbol %qs present on multiple clauses at %L",
4646 n
->sym
->name
, &n
->where
);
4649 if (component_ref_p
)
4650 n
->sym
->comp_mark
= 1;
4656 gcc_assert (OMP_LIST_LASTPRIVATE
== OMP_LIST_FIRSTPRIVATE
+ 1);
4657 for (list
= OMP_LIST_FIRSTPRIVATE
; list
<= OMP_LIST_LASTPRIVATE
; list
++)
4658 for (n
= omp_clauses
->lists
[list
]; n
; n
= n
->next
)
4661 gfc_error ("Symbol %qs present on multiple clauses at %L",
4662 n
->sym
->name
, &n
->where
);
4666 for (n
= omp_clauses
->lists
[OMP_LIST_FIRSTPRIVATE
]; n
; n
= n
->next
)
4669 gfc_error ("Symbol %qs present on multiple clauses at %L",
4670 n
->sym
->name
, &n
->where
);
4674 for (n
= omp_clauses
->lists
[OMP_LIST_LASTPRIVATE
]; n
; n
= n
->next
)
4677 for (n
= omp_clauses
->lists
[OMP_LIST_LASTPRIVATE
]; n
; n
= n
->next
)
4680 gfc_error ("Symbol %qs present on multiple clauses at %L",
4681 n
->sym
->name
, &n
->where
);
4686 for (n
= omp_clauses
->lists
[OMP_LIST_ALIGNED
]; n
; n
= n
->next
)
4689 for (n
= omp_clauses
->lists
[OMP_LIST_ALIGNED
]; n
; n
= n
->next
)
4692 gfc_error ("Symbol %qs present on multiple clauses at %L",
4693 n
->sym
->name
, &n
->where
);
4698 /* OpenACC reductions. */
4701 for (n
= omp_clauses
->lists
[OMP_LIST_REDUCTION
]; n
; n
= n
->next
)
4704 for (n
= omp_clauses
->lists
[OMP_LIST_REDUCTION
]; n
; n
= n
->next
)
4707 gfc_error ("Symbol %qs present on multiple clauses at %L",
4708 n
->sym
->name
, &n
->where
);
4712 /* OpenACC does not support reductions on arrays. */
4714 gfc_error ("Array %qs is not permitted in reduction at %L",
4715 n
->sym
->name
, &n
->where
);
4719 for (n
= omp_clauses
->lists
[OMP_LIST_TO
]; n
; n
= n
->next
)
4721 for (n
= omp_clauses
->lists
[OMP_LIST_FROM
]; n
; n
= n
->next
)
4722 if (n
->expr
== NULL
)
4724 for (n
= omp_clauses
->lists
[OMP_LIST_TO
]; n
; n
= n
->next
)
4726 if (n
->expr
== NULL
&& n
->sym
->mark
)
4727 gfc_error ("Symbol %qs present on both FROM and TO clauses at %L",
4728 n
->sym
->name
, &n
->where
);
4733 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
4734 if ((n
= omp_clauses
->lists
[list
]) != NULL
)
4736 const char *name
= clause_names
[list
];
4740 case OMP_LIST_COPYIN
:
4741 for (; n
!= NULL
; n
= n
->next
)
4743 if (!n
->sym
->attr
.threadprivate
)
4744 gfc_error ("Non-THREADPRIVATE object %qs in COPYIN clause"
4745 " at %L", n
->sym
->name
, &n
->where
);
4748 case OMP_LIST_COPYPRIVATE
:
4749 for (; n
!= NULL
; n
= n
->next
)
4751 if (n
->sym
->as
&& n
->sym
->as
->type
== AS_ASSUMED_SIZE
)
4752 gfc_error ("Assumed size array %qs in COPYPRIVATE clause "
4753 "at %L", n
->sym
->name
, &n
->where
);
4754 if (n
->sym
->attr
.pointer
&& n
->sym
->attr
.intent
== INTENT_IN
)
4755 gfc_error ("INTENT(IN) POINTER %qs in COPYPRIVATE clause "
4756 "at %L", n
->sym
->name
, &n
->where
);
4759 case OMP_LIST_SHARED
:
4760 for (; n
!= NULL
; n
= n
->next
)
4762 if (n
->sym
->attr
.threadprivate
)
4763 gfc_error ("THREADPRIVATE object %qs in SHARED clause at "
4764 "%L", n
->sym
->name
, &n
->where
);
4765 if (n
->sym
->attr
.cray_pointee
)
4766 gfc_error ("Cray pointee %qs in SHARED clause at %L",
4767 n
->sym
->name
, &n
->where
);
4768 if (n
->sym
->attr
.associate_var
)
4769 gfc_error ("ASSOCIATE name %qs in SHARED clause at %L",
4770 n
->sym
->name
, &n
->where
);
4773 case OMP_LIST_ALIGNED
:
4774 for (; n
!= NULL
; n
= n
->next
)
4776 if (!n
->sym
->attr
.pointer
4777 && !n
->sym
->attr
.allocatable
4778 && !n
->sym
->attr
.cray_pointer
4779 && (n
->sym
->ts
.type
!= BT_DERIVED
4780 || (n
->sym
->ts
.u
.derived
->from_intmod
4781 != INTMOD_ISO_C_BINDING
)
4782 || (n
->sym
->ts
.u
.derived
->intmod_sym_id
4783 != ISOCBINDING_PTR
)))
4784 gfc_error ("%qs in ALIGNED clause must be POINTER, "
4785 "ALLOCATABLE, Cray pointer or C_PTR at %L",
4786 n
->sym
->name
, &n
->where
);
4789 gfc_expr
*expr
= n
->expr
;
4791 if (!gfc_resolve_expr (expr
)
4792 || expr
->ts
.type
!= BT_INTEGER
4794 || gfc_extract_int (expr
, &alignment
)
4796 gfc_error ("%qs in ALIGNED clause at %L requires a scalar "
4797 "positive constant integer alignment "
4798 "expression", n
->sym
->name
, &n
->where
);
4802 case OMP_LIST_DEPEND
:
4806 case OMP_LIST_CACHE
:
4807 for (; n
!= NULL
; n
= n
->next
)
4809 if (list
== OMP_LIST_DEPEND
)
4811 if (n
->u
.depend_op
== OMP_DEPEND_SINK_FIRST
4812 || n
->u
.depend_op
== OMP_DEPEND_SINK
)
4814 if (code
->op
!= EXEC_OMP_ORDERED
)
4815 gfc_error ("SINK dependence type only allowed "
4816 "on ORDERED directive at %L", &n
->where
);
4817 else if (omp_clauses
->depend_source
)
4819 gfc_error ("DEPEND SINK used together with "
4820 "DEPEND SOURCE on the same construct "
4821 "at %L", &n
->where
);
4822 omp_clauses
->depend_source
= false;
4826 if (!gfc_resolve_expr (n
->expr
)
4827 || n
->expr
->ts
.type
!= BT_INTEGER
4828 || n
->expr
->rank
!= 0)
4829 gfc_error ("SINK addend not a constant integer "
4830 "at %L", &n
->where
);
4834 else if (code
->op
== EXEC_OMP_ORDERED
)
4835 gfc_error ("Only SOURCE or SINK dependence types "
4836 "are allowed on ORDERED directive at %L",
4839 gfc_ref
*array_ref
= NULL
;
4840 bool resolved
= false;
4843 array_ref
= n
->expr
->ref
;
4844 resolved
= gfc_resolve_expr (n
->expr
);
4846 /* Look through component refs to find last array
4850 /* The "!$acc cache" directive allows rectangular
4851 subarrays to be specified, with some restrictions
4852 on the form of bounds (not implemented).
4853 Only raise an error here if we're really sure the
4854 array isn't contiguous. An expression such as
4855 arr(-n:n,-n:n) could be contiguous even if it looks
4856 like it may not be. */
4857 if (list
!= OMP_LIST_CACHE
4858 && list
!= OMP_LIST_DEPEND
4859 && !gfc_is_simply_contiguous (n
->expr
, false, true)
4860 && gfc_is_not_contiguous (n
->expr
))
4861 gfc_error ("Array is not contiguous at %L",
4865 && (array_ref
->type
== REF_COMPONENT
4866 || (array_ref
->type
== REF_ARRAY
4868 && (array_ref
->next
->type
4869 == REF_COMPONENT
))))
4870 array_ref
= array_ref
->next
;
4875 && (!resolved
|| n
->expr
->expr_type
!= EXPR_VARIABLE
)))
4878 || n
->expr
->expr_type
!= EXPR_VARIABLE
4880 || array_ref
->type
!= REF_ARRAY
)
4881 gfc_error ("%qs in %s clause at %L is not a proper "
4882 "array section", n
->sym
->name
, name
,
4887 gfc_array_ref
*ar
= &array_ref
->u
.ar
;
4888 for (i
= 0; i
< ar
->dimen
; i
++)
4891 gfc_error ("Stride should not be specified for "
4892 "array section in %s clause at %L",
4896 else if (ar
->dimen_type
[i
] != DIMEN_ELEMENT
4897 && ar
->dimen_type
[i
] != DIMEN_RANGE
)
4899 gfc_error ("%qs in %s clause at %L is not a "
4900 "proper array section",
4901 n
->sym
->name
, name
, &n
->where
);
4904 else if (list
== OMP_LIST_DEPEND
4906 && ar
->start
[i
]->expr_type
== EXPR_CONSTANT
4908 && ar
->end
[i
]->expr_type
== EXPR_CONSTANT
4909 && mpz_cmp (ar
->start
[i
]->value
.integer
,
4910 ar
->end
[i
]->value
.integer
) > 0)
4912 gfc_error ("%qs in DEPEND clause at %L is a "
4913 "zero size array section",
4914 n
->sym
->name
, &n
->where
);
4921 if (list
== OMP_LIST_MAP
4922 && n
->u
.map_op
== OMP_MAP_FORCE_DEVICEPTR
)
4923 resolve_oacc_deviceptr_clause (n
->sym
, n
->where
, name
);
4925 resolve_oacc_data_clauses (n
->sym
, n
->where
, name
);
4927 else if (list
!= OMP_LIST_DEPEND
4929 && n
->sym
->as
->type
== AS_ASSUMED_SIZE
)
4930 gfc_error ("Assumed size array %qs in %s clause at %L",
4931 n
->sym
->name
, name
, &n
->where
);
4933 && list
== OMP_LIST_MAP
4934 && n
->sym
->ts
.type
== BT_DERIVED
4935 && n
->sym
->ts
.u
.derived
->attr
.alloc_comp
)
4936 gfc_error ("List item %qs with allocatable components is not "
4937 "permitted in map clause at %L", n
->sym
->name
,
4939 if (list
== OMP_LIST_MAP
&& !openacc
)
4942 case EXEC_OMP_TARGET
:
4943 case EXEC_OMP_TARGET_DATA
:
4944 switch (n
->u
.map_op
)
4947 case OMP_MAP_ALWAYS_TO
:
4949 case OMP_MAP_ALWAYS_FROM
:
4950 case OMP_MAP_TOFROM
:
4951 case OMP_MAP_ALWAYS_TOFROM
:
4955 gfc_error ("TARGET%s with map-type other than TO, "
4956 "FROM, TOFROM, or ALLOC on MAP clause "
4958 code
->op
== EXEC_OMP_TARGET
4959 ? "" : " DATA", &n
->where
);
4963 case EXEC_OMP_TARGET_ENTER_DATA
:
4964 switch (n
->u
.map_op
)
4967 case OMP_MAP_ALWAYS_TO
:
4971 gfc_error ("TARGET ENTER DATA with map-type other "
4972 "than TO, or ALLOC on MAP clause at %L",
4977 case EXEC_OMP_TARGET_EXIT_DATA
:
4978 switch (n
->u
.map_op
)
4981 case OMP_MAP_ALWAYS_FROM
:
4982 case OMP_MAP_RELEASE
:
4983 case OMP_MAP_DELETE
:
4986 gfc_error ("TARGET EXIT DATA with map-type other "
4987 "than FROM, RELEASE, or DELETE on MAP "
4988 "clause at %L", &n
->where
);
4997 if (list
!= OMP_LIST_DEPEND
)
4998 for (n
= omp_clauses
->lists
[list
]; n
!= NULL
; n
= n
->next
)
5000 n
->sym
->attr
.referenced
= 1;
5001 if (n
->sym
->attr
.threadprivate
)
5002 gfc_error ("THREADPRIVATE object %qs in %s clause at %L",
5003 n
->sym
->name
, name
, &n
->where
);
5004 if (n
->sym
->attr
.cray_pointee
)
5005 gfc_error ("Cray pointee %qs in %s clause at %L",
5006 n
->sym
->name
, name
, &n
->where
);
5009 case OMP_LIST_IS_DEVICE_PTR
:
5010 if (!n
->sym
->attr
.dummy
)
5011 gfc_error ("Non-dummy object %qs in %s clause at %L",
5012 n
->sym
->name
, name
, &n
->where
);
5013 if (n
->sym
->attr
.allocatable
5014 || (n
->sym
->ts
.type
== BT_CLASS
5015 && CLASS_DATA (n
->sym
)->attr
.allocatable
))
5016 gfc_error ("ALLOCATABLE object %qs in %s clause at %L",
5017 n
->sym
->name
, name
, &n
->where
);
5018 if (n
->sym
->attr
.pointer
5019 || (n
->sym
->ts
.type
== BT_CLASS
5020 && CLASS_DATA (n
->sym
)->attr
.pointer
))
5021 gfc_error ("POINTER object %qs in %s clause at %L",
5022 n
->sym
->name
, name
, &n
->where
);
5023 if (n
->sym
->attr
.value
)
5024 gfc_error ("VALUE object %qs in %s clause at %L",
5025 n
->sym
->name
, name
, &n
->where
);
5027 case OMP_LIST_USE_DEVICE_PTR
:
5028 case OMP_LIST_USE_DEVICE_ADDR
:
5029 /* FIXME: Handle OMP_LIST_USE_DEVICE_PTR. */
5032 for (; n
!= NULL
; n
= n
->next
)
5035 if (n
->sym
->attr
.threadprivate
)
5036 gfc_error ("THREADPRIVATE object %qs in %s clause at %L",
5037 n
->sym
->name
, name
, &n
->where
);
5038 if (n
->sym
->attr
.cray_pointee
)
5039 gfc_error ("Cray pointee %qs in %s clause at %L",
5040 n
->sym
->name
, name
, &n
->where
);
5041 if (n
->sym
->attr
.associate_var
)
5042 gfc_error ("ASSOCIATE name %qs in %s clause at %L",
5043 n
->sym
->name
, name
, &n
->where
);
5044 if (list
!= OMP_LIST_PRIVATE
)
5046 if (n
->sym
->attr
.proc_pointer
&& list
== OMP_LIST_REDUCTION
)
5047 gfc_error ("Procedure pointer %qs in %s clause at %L",
5048 n
->sym
->name
, name
, &n
->where
);
5049 if (n
->sym
->attr
.pointer
&& list
== OMP_LIST_REDUCTION
)
5050 gfc_error ("POINTER object %qs in %s clause at %L",
5051 n
->sym
->name
, name
, &n
->where
);
5052 if (n
->sym
->attr
.cray_pointer
&& list
== OMP_LIST_REDUCTION
)
5053 gfc_error ("Cray pointer %qs in %s clause at %L",
5054 n
->sym
->name
, name
, &n
->where
);
5057 && (oacc_is_loop (code
)
5058 || code
->op
== EXEC_OACC_PARALLEL
5059 || code
->op
== EXEC_OACC_SERIAL
))
5060 check_array_not_assumed (n
->sym
, n
->where
, name
);
5061 else if (n
->sym
->as
&& n
->sym
->as
->type
== AS_ASSUMED_SIZE
)
5062 gfc_error ("Assumed size array %qs in %s clause at %L",
5063 n
->sym
->name
, name
, &n
->where
);
5064 if (n
->sym
->attr
.in_namelist
&& list
!= OMP_LIST_REDUCTION
)
5065 gfc_error ("Variable %qs in %s clause is used in "
5066 "NAMELIST statement at %L",
5067 n
->sym
->name
, name
, &n
->where
);
5068 if (n
->sym
->attr
.pointer
&& n
->sym
->attr
.intent
== INTENT_IN
)
5071 case OMP_LIST_PRIVATE
:
5072 case OMP_LIST_LASTPRIVATE
:
5073 case OMP_LIST_LINEAR
:
5074 /* case OMP_LIST_REDUCTION: */
5075 gfc_error ("INTENT(IN) POINTER %qs in %s clause at %L",
5076 n
->sym
->name
, name
, &n
->where
);
5084 case OMP_LIST_REDUCTION
:
5085 switch (n
->u
.reduction_op
)
5087 case OMP_REDUCTION_PLUS
:
5088 case OMP_REDUCTION_TIMES
:
5089 case OMP_REDUCTION_MINUS
:
5090 if (!gfc_numeric_ts (&n
->sym
->ts
))
5093 case OMP_REDUCTION_AND
:
5094 case OMP_REDUCTION_OR
:
5095 case OMP_REDUCTION_EQV
:
5096 case OMP_REDUCTION_NEQV
:
5097 if (n
->sym
->ts
.type
!= BT_LOGICAL
)
5100 case OMP_REDUCTION_MAX
:
5101 case OMP_REDUCTION_MIN
:
5102 if (n
->sym
->ts
.type
!= BT_INTEGER
5103 && n
->sym
->ts
.type
!= BT_REAL
)
5106 case OMP_REDUCTION_IAND
:
5107 case OMP_REDUCTION_IOR
:
5108 case OMP_REDUCTION_IEOR
:
5109 if (n
->sym
->ts
.type
!= BT_INTEGER
)
5112 case OMP_REDUCTION_USER
:
5122 const char *udr_name
= NULL
;
5125 udr_name
= n
->udr
->udr
->name
;
5127 = gfc_find_omp_udr (NULL
, udr_name
,
5129 if (n
->udr
->udr
== NULL
)
5137 if (udr_name
== NULL
)
5138 switch (n
->u
.reduction_op
)
5140 case OMP_REDUCTION_PLUS
:
5141 case OMP_REDUCTION_TIMES
:
5142 case OMP_REDUCTION_MINUS
:
5143 case OMP_REDUCTION_AND
:
5144 case OMP_REDUCTION_OR
:
5145 case OMP_REDUCTION_EQV
:
5146 case OMP_REDUCTION_NEQV
:
5147 udr_name
= gfc_op2string ((gfc_intrinsic_op
)
5150 case OMP_REDUCTION_MAX
:
5153 case OMP_REDUCTION_MIN
:
5156 case OMP_REDUCTION_IAND
:
5159 case OMP_REDUCTION_IOR
:
5162 case OMP_REDUCTION_IEOR
:
5168 gfc_error ("!$OMP DECLARE REDUCTION %s not found "
5169 "for type %s at %L", udr_name
,
5170 gfc_typename (&n
->sym
->ts
), &n
->where
);
5174 gfc_omp_udr
*udr
= n
->udr
->udr
;
5175 n
->u
.reduction_op
= OMP_REDUCTION_USER
;
5177 = resolve_omp_udr_clause (n
, udr
->combiner_ns
,
5180 if (udr
->initializer_ns
)
5182 = resolve_omp_udr_clause (n
,
5183 udr
->initializer_ns
,
5189 case OMP_LIST_LINEAR
:
5191 && n
->u
.linear_op
!= OMP_LINEAR_DEFAULT
5192 && n
->u
.linear_op
!= linear_op
)
5194 gfc_error ("LINEAR clause modifier used on DO or SIMD"
5195 " construct at %L", &n
->where
);
5196 linear_op
= n
->u
.linear_op
;
5198 else if (omp_clauses
->orderedc
)
5199 gfc_error ("LINEAR clause specified together with "
5200 "ORDERED clause with argument at %L",
5202 else if (n
->u
.linear_op
!= OMP_LINEAR_REF
5203 && n
->sym
->ts
.type
!= BT_INTEGER
)
5204 gfc_error ("LINEAR variable %qs must be INTEGER "
5205 "at %L", n
->sym
->name
, &n
->where
);
5206 else if ((n
->u
.linear_op
== OMP_LINEAR_REF
5207 || n
->u
.linear_op
== OMP_LINEAR_UVAL
)
5208 && n
->sym
->attr
.value
)
5209 gfc_error ("LINEAR dummy argument %qs with VALUE "
5210 "attribute with %s modifier at %L",
5212 n
->u
.linear_op
== OMP_LINEAR_REF
5213 ? "REF" : "UVAL", &n
->where
);
5216 gfc_expr
*expr
= n
->expr
;
5217 if (!gfc_resolve_expr (expr
)
5218 || expr
->ts
.type
!= BT_INTEGER
5220 gfc_error ("%qs in LINEAR clause at %L requires "
5221 "a scalar integer linear-step expression",
5222 n
->sym
->name
, &n
->where
);
5223 else if (!code
&& expr
->expr_type
!= EXPR_CONSTANT
)
5225 if (expr
->expr_type
== EXPR_VARIABLE
5226 && expr
->symtree
->n
.sym
->attr
.dummy
5227 && expr
->symtree
->n
.sym
->ns
== ns
)
5229 gfc_omp_namelist
*n2
;
5230 for (n2
= omp_clauses
->lists
[OMP_LIST_UNIFORM
];
5232 if (n2
->sym
== expr
->symtree
->n
.sym
)
5237 gfc_error ("%qs in LINEAR clause at %L requires "
5238 "a constant integer linear-step "
5239 "expression or dummy argument "
5240 "specified in UNIFORM clause",
5241 n
->sym
->name
, &n
->where
);
5245 /* Workaround for PR middle-end/26316, nothing really needs
5246 to be done here for OMP_LIST_PRIVATE. */
5247 case OMP_LIST_PRIVATE
:
5248 gcc_assert (code
&& code
->op
!= EXEC_NOP
);
5250 case OMP_LIST_USE_DEVICE
:
5251 if (n
->sym
->attr
.allocatable
5252 || (n
->sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (n
->sym
)
5253 && CLASS_DATA (n
->sym
)->attr
.allocatable
))
5254 gfc_error ("ALLOCATABLE object %qs in %s clause at %L",
5255 n
->sym
->name
, name
, &n
->where
);
5256 if (n
->sym
->ts
.type
== BT_CLASS
5257 && CLASS_DATA (n
->sym
)
5258 && CLASS_DATA (n
->sym
)->attr
.class_pointer
)
5259 gfc_error ("POINTER object %qs of polymorphic type in "
5260 "%s clause at %L", n
->sym
->name
, name
,
5262 if (n
->sym
->attr
.cray_pointer
)
5263 gfc_error ("Cray pointer object %qs in %s clause at %L",
5264 n
->sym
->name
, name
, &n
->where
);
5265 else if (n
->sym
->attr
.cray_pointee
)
5266 gfc_error ("Cray pointee object %qs in %s clause at %L",
5267 n
->sym
->name
, name
, &n
->where
);
5268 else if (n
->sym
->attr
.flavor
== FL_VARIABLE
5270 && !n
->sym
->attr
.pointer
)
5271 gfc_error ("%s clause variable %qs at %L is neither "
5272 "a POINTER nor an array", name
,
5273 n
->sym
->name
, &n
->where
);
5275 case OMP_LIST_DEVICE_RESIDENT
:
5276 check_symbol_not_pointer (n
->sym
, n
->where
, name
);
5277 check_array_not_assumed (n
->sym
, n
->where
, name
);
5286 if (omp_clauses
->safelen_expr
)
5287 resolve_positive_int_expr (omp_clauses
->safelen_expr
, "SAFELEN");
5288 if (omp_clauses
->simdlen_expr
)
5289 resolve_positive_int_expr (omp_clauses
->simdlen_expr
, "SIMDLEN");
5290 if (omp_clauses
->num_teams
)
5291 resolve_positive_int_expr (omp_clauses
->num_teams
, "NUM_TEAMS");
5292 if (omp_clauses
->device
)
5293 resolve_nonnegative_int_expr (omp_clauses
->device
, "DEVICE");
5294 if (omp_clauses
->hint
)
5296 resolve_scalar_int_expr (omp_clauses
->hint
, "HINT");
5297 if (omp_clauses
->hint
->ts
.type
!= BT_INTEGER
5298 || omp_clauses
->hint
->expr_type
!= EXPR_CONSTANT
5299 || mpz_sgn (omp_clauses
->hint
->value
.integer
) < 0)
5300 gfc_error ("Value of HINT clause at %L shall be a valid "
5301 "constant hint expression", &omp_clauses
->hint
->where
);
5303 if (omp_clauses
->priority
)
5304 resolve_nonnegative_int_expr (omp_clauses
->priority
, "PRIORITY");
5305 if (omp_clauses
->dist_chunk_size
)
5307 gfc_expr
*expr
= omp_clauses
->dist_chunk_size
;
5308 if (!gfc_resolve_expr (expr
)
5309 || expr
->ts
.type
!= BT_INTEGER
|| expr
->rank
!= 0)
5310 gfc_error ("DIST_SCHEDULE clause's chunk_size at %L requires "
5311 "a scalar INTEGER expression", &expr
->where
);
5313 if (omp_clauses
->thread_limit
)
5314 resolve_positive_int_expr (omp_clauses
->thread_limit
, "THREAD_LIMIT");
5315 if (omp_clauses
->grainsize
)
5316 resolve_positive_int_expr (omp_clauses
->grainsize
, "GRAINSIZE");
5317 if (omp_clauses
->num_tasks
)
5318 resolve_positive_int_expr (omp_clauses
->num_tasks
, "NUM_TASKS");
5319 if (omp_clauses
->async
)
5320 if (omp_clauses
->async_expr
)
5321 resolve_scalar_int_expr (omp_clauses
->async_expr
, "ASYNC");
5322 if (omp_clauses
->num_gangs_expr
)
5323 resolve_positive_int_expr (omp_clauses
->num_gangs_expr
, "NUM_GANGS");
5324 if (omp_clauses
->num_workers_expr
)
5325 resolve_positive_int_expr (omp_clauses
->num_workers_expr
, "NUM_WORKERS");
5326 if (omp_clauses
->vector_length_expr
)
5327 resolve_positive_int_expr (omp_clauses
->vector_length_expr
,
5329 if (omp_clauses
->gang_num_expr
)
5330 resolve_positive_int_expr (omp_clauses
->gang_num_expr
, "GANG");
5331 if (omp_clauses
->gang_static_expr
)
5332 resolve_positive_int_expr (omp_clauses
->gang_static_expr
, "GANG");
5333 if (omp_clauses
->worker_expr
)
5334 resolve_positive_int_expr (omp_clauses
->worker_expr
, "WORKER");
5335 if (omp_clauses
->vector_expr
)
5336 resolve_positive_int_expr (omp_clauses
->vector_expr
, "VECTOR");
5337 for (el
= omp_clauses
->wait_list
; el
; el
= el
->next
)
5338 resolve_scalar_int_expr (el
->expr
, "WAIT");
5339 if (omp_clauses
->collapse
&& omp_clauses
->tile_list
)
5340 gfc_error ("Incompatible use of TILE and COLLAPSE at %L", &code
->loc
);
5341 if (omp_clauses
->depend_source
&& code
->op
!= EXEC_OMP_ORDERED
)
5342 gfc_error ("SOURCE dependence type only allowed "
5343 "on ORDERED directive at %L", &code
->loc
);
5346 && omp_clauses
->lists
[OMP_LIST_MAP
] == NULL
5347 && omp_clauses
->lists
[OMP_LIST_USE_DEVICE_PTR
] == NULL
5348 && omp_clauses
->lists
[OMP_LIST_USE_DEVICE_ADDR
] == NULL
)
5350 const char *p
= NULL
;
5353 case EXEC_OMP_TARGET_ENTER_DATA
: p
= "TARGET ENTER DATA"; break;
5354 case EXEC_OMP_TARGET_EXIT_DATA
: p
= "TARGET EXIT DATA"; break;
5357 if (code
->op
== EXEC_OMP_TARGET_DATA
)
5358 gfc_error ("TARGET DATA must contain at least one MAP, USE_DEVICE_PTR, "
5359 "or USE_DEVICE_ADDR clause at %L", &code
->loc
);
5361 gfc_error ("%s must contain at least one MAP clause at %L",
5367 /* Return true if SYM is ever referenced in EXPR except in the SE node. */
5370 expr_references_sym (gfc_expr
*e
, gfc_symbol
*s
, gfc_expr
*se
)
5372 gfc_actual_arglist
*arg
;
5373 if (e
== NULL
|| e
== se
)
5375 switch (e
->expr_type
)
5380 case EXPR_STRUCTURE
:
5382 if (e
->symtree
!= NULL
5383 && e
->symtree
->n
.sym
== s
)
5386 case EXPR_SUBSTRING
:
5388 && (expr_references_sym (e
->ref
->u
.ss
.start
, s
, se
)
5389 || expr_references_sym (e
->ref
->u
.ss
.end
, s
, se
)))
5393 if (expr_references_sym (e
->value
.op
.op2
, s
, se
))
5395 return expr_references_sym (e
->value
.op
.op1
, s
, se
);
5397 for (arg
= e
->value
.function
.actual
; arg
; arg
= arg
->next
)
5398 if (expr_references_sym (arg
->expr
, s
, se
))
5407 /* If EXPR is a conversion function that widens the type
5408 if WIDENING is true or narrows the type if WIDENING is false,
5409 return the inner expression, otherwise return NULL. */
5412 is_conversion (gfc_expr
*expr
, bool widening
)
5414 gfc_typespec
*ts1
, *ts2
;
5416 if (expr
->expr_type
!= EXPR_FUNCTION
5417 || expr
->value
.function
.isym
== NULL
5418 || expr
->value
.function
.esym
!= NULL
5419 || expr
->value
.function
.isym
->id
!= GFC_ISYM_CONVERSION
)
5425 ts2
= &expr
->value
.function
.actual
->expr
->ts
;
5429 ts1
= &expr
->value
.function
.actual
->expr
->ts
;
5433 if (ts1
->type
> ts2
->type
5434 || (ts1
->type
== ts2
->type
&& ts1
->kind
> ts2
->kind
))
5435 return expr
->value
.function
.actual
->expr
;
5442 resolve_omp_atomic (gfc_code
*code
)
5444 gfc_code
*atomic_code
= code
;
5446 gfc_expr
*expr2
, *expr2_tmp
;
5447 gfc_omp_atomic_op aop
5448 = (gfc_omp_atomic_op
) (atomic_code
->ext
.omp_atomic
& GFC_OMP_ATOMIC_MASK
);
5450 code
= code
->block
->next
;
5451 /* resolve_blocks asserts this is initially EXEC_ASSIGN.
5452 If it changed to EXEC_NOP, assume an error has been emitted already. */
5453 if (code
->op
== EXEC_NOP
)
5455 if (code
->op
!= EXEC_ASSIGN
)
5458 gfc_error ("unexpected !$OMP ATOMIC expression at %L", &code
->loc
);
5461 if (aop
!= GFC_OMP_ATOMIC_CAPTURE
)
5463 if (code
->next
!= NULL
)
5468 if (code
->next
== NULL
)
5470 if (code
->next
->op
== EXEC_NOP
)
5472 if (code
->next
->op
!= EXEC_ASSIGN
|| code
->next
->next
)
5479 if (code
->expr1
->expr_type
!= EXPR_VARIABLE
5480 || code
->expr1
->symtree
== NULL
5481 || code
->expr1
->rank
!= 0
5482 || (code
->expr1
->ts
.type
!= BT_INTEGER
5483 && code
->expr1
->ts
.type
!= BT_REAL
5484 && code
->expr1
->ts
.type
!= BT_COMPLEX
5485 && code
->expr1
->ts
.type
!= BT_LOGICAL
))
5487 gfc_error ("!$OMP ATOMIC statement must set a scalar variable of "
5488 "intrinsic type at %L", &code
->loc
);
5492 var
= code
->expr1
->symtree
->n
.sym
;
5493 expr2
= is_conversion (code
->expr2
, false);
5496 if (aop
== GFC_OMP_ATOMIC_READ
|| aop
== GFC_OMP_ATOMIC_WRITE
)
5497 expr2
= is_conversion (code
->expr2
, true);
5499 expr2
= code
->expr2
;
5504 case GFC_OMP_ATOMIC_READ
:
5505 if (expr2
->expr_type
!= EXPR_VARIABLE
5506 || expr2
->symtree
== NULL
5508 || (expr2
->ts
.type
!= BT_INTEGER
5509 && expr2
->ts
.type
!= BT_REAL
5510 && expr2
->ts
.type
!= BT_COMPLEX
5511 && expr2
->ts
.type
!= BT_LOGICAL
))
5512 gfc_error ("!$OMP ATOMIC READ statement must read from a scalar "
5513 "variable of intrinsic type at %L", &expr2
->where
);
5515 case GFC_OMP_ATOMIC_WRITE
:
5516 if (expr2
->rank
!= 0 || expr_references_sym (code
->expr2
, var
, NULL
))
5517 gfc_error ("expr in !$OMP ATOMIC WRITE assignment var = expr "
5518 "must be scalar and cannot reference var at %L",
5521 case GFC_OMP_ATOMIC_CAPTURE
:
5523 if (expr2
== code
->expr2
)
5525 expr2_tmp
= is_conversion (code
->expr2
, true);
5526 if (expr2_tmp
== NULL
)
5529 if (expr2_tmp
->expr_type
== EXPR_VARIABLE
)
5531 if (expr2_tmp
->symtree
== NULL
5532 || expr2_tmp
->rank
!= 0
5533 || (expr2_tmp
->ts
.type
!= BT_INTEGER
5534 && expr2_tmp
->ts
.type
!= BT_REAL
5535 && expr2_tmp
->ts
.type
!= BT_COMPLEX
5536 && expr2_tmp
->ts
.type
!= BT_LOGICAL
)
5537 || expr2_tmp
->symtree
->n
.sym
== var
)
5539 gfc_error ("!$OMP ATOMIC CAPTURE capture statement must read from "
5540 "a scalar variable of intrinsic type at %L",
5544 var
= expr2_tmp
->symtree
->n
.sym
;
5546 if (code
->expr1
->expr_type
!= EXPR_VARIABLE
5547 || code
->expr1
->symtree
== NULL
5548 || code
->expr1
->rank
!= 0
5549 || (code
->expr1
->ts
.type
!= BT_INTEGER
5550 && code
->expr1
->ts
.type
!= BT_REAL
5551 && code
->expr1
->ts
.type
!= BT_COMPLEX
5552 && code
->expr1
->ts
.type
!= BT_LOGICAL
))
5554 gfc_error ("!$OMP ATOMIC CAPTURE update statement must set "
5555 "a scalar variable of intrinsic type at %L",
5556 &code
->expr1
->where
);
5559 if (code
->expr1
->symtree
->n
.sym
!= var
)
5561 gfc_error ("!$OMP ATOMIC CAPTURE capture statement reads from "
5562 "different variable than update statement writes "
5563 "into at %L", &code
->expr1
->where
);
5566 expr2
= is_conversion (code
->expr2
, false);
5568 expr2
= code
->expr2
;
5575 if (gfc_expr_attr (code
->expr1
).allocatable
)
5577 gfc_error ("!$OMP ATOMIC with ALLOCATABLE variable at %L",
5582 if (aop
== GFC_OMP_ATOMIC_CAPTURE
5583 && code
->next
== NULL
5584 && code
->expr2
->rank
== 0
5585 && !expr_references_sym (code
->expr2
, var
, NULL
))
5586 atomic_code
->ext
.omp_atomic
5587 = (gfc_omp_atomic_op
) (atomic_code
->ext
.omp_atomic
5588 | GFC_OMP_ATOMIC_SWAP
);
5589 else if (expr2
->expr_type
== EXPR_OP
)
5591 gfc_expr
*v
= NULL
, *e
, *c
;
5592 gfc_intrinsic_op op
= expr2
->value
.op
.op
;
5593 gfc_intrinsic_op alt_op
= INTRINSIC_NONE
;
5597 case INTRINSIC_PLUS
:
5598 alt_op
= INTRINSIC_MINUS
;
5600 case INTRINSIC_TIMES
:
5601 alt_op
= INTRINSIC_DIVIDE
;
5603 case INTRINSIC_MINUS
:
5604 alt_op
= INTRINSIC_PLUS
;
5606 case INTRINSIC_DIVIDE
:
5607 alt_op
= INTRINSIC_TIMES
;
5613 alt_op
= INTRINSIC_NEQV
;
5615 case INTRINSIC_NEQV
:
5616 alt_op
= INTRINSIC_EQV
;
5619 gfc_error ("!$OMP ATOMIC assignment operator must be binary "
5620 "+, *, -, /, .AND., .OR., .EQV. or .NEQV. at %L",
5625 /* Check for var = var op expr resp. var = expr op var where
5626 expr doesn't reference var and var op expr is mathematically
5627 equivalent to var op (expr) resp. expr op var equivalent to
5628 (expr) op var. We rely here on the fact that the matcher
5629 for x op1 y op2 z where op1 and op2 have equal precedence
5630 returns (x op1 y) op2 z. */
5631 e
= expr2
->value
.op
.op2
;
5632 if (e
->expr_type
== EXPR_VARIABLE
5633 && e
->symtree
!= NULL
5634 && e
->symtree
->n
.sym
== var
)
5636 else if ((c
= is_conversion (e
, true)) != NULL
5637 && c
->expr_type
== EXPR_VARIABLE
5638 && c
->symtree
!= NULL
5639 && c
->symtree
->n
.sym
== var
)
5643 gfc_expr
**p
= NULL
, **q
;
5644 for (q
= &expr2
->value
.op
.op1
; (e
= *q
) != NULL
; )
5645 if (e
->expr_type
== EXPR_VARIABLE
5646 && e
->symtree
!= NULL
5647 && e
->symtree
->n
.sym
== var
)
5652 else if ((c
= is_conversion (e
, true)) != NULL
)
5653 q
= &e
->value
.function
.actual
->expr
;
5654 else if (e
->expr_type
!= EXPR_OP
5655 || (e
->value
.op
.op
!= op
5656 && e
->value
.op
.op
!= alt_op
)
5662 q
= &e
->value
.op
.op1
;
5667 gfc_error ("!$OMP ATOMIC assignment must be var = var op expr "
5668 "or var = expr op var at %L", &expr2
->where
);
5675 switch (e
->value
.op
.op
)
5677 case INTRINSIC_MINUS
:
5678 case INTRINSIC_DIVIDE
:
5680 case INTRINSIC_NEQV
:
5681 gfc_error ("!$OMP ATOMIC var = var op expr not "
5682 "mathematically equivalent to var = var op "
5683 "(expr) at %L", &expr2
->where
);
5689 /* Canonicalize into var = var op (expr). */
5690 *p
= e
->value
.op
.op2
;
5691 e
->value
.op
.op2
= expr2
;
5693 if (code
->expr2
== expr2
)
5694 code
->expr2
= expr2
= e
;
5696 code
->expr2
->value
.function
.actual
->expr
= expr2
= e
;
5698 if (!gfc_compare_types (&expr2
->value
.op
.op1
->ts
, &expr2
->ts
))
5700 for (p
= &expr2
->value
.op
.op1
; *p
!= v
;
5701 p
= &(*p
)->value
.function
.actual
->expr
)
5704 gfc_free_expr (expr2
->value
.op
.op1
);
5705 expr2
->value
.op
.op1
= v
;
5706 gfc_convert_type (v
, &expr2
->ts
, 2);
5711 if (e
->rank
!= 0 || expr_references_sym (code
->expr2
, var
, v
))
5713 gfc_error ("expr in !$OMP ATOMIC assignment var = var op expr "
5714 "must be scalar and cannot reference var at %L",
5719 else if (expr2
->expr_type
== EXPR_FUNCTION
5720 && expr2
->value
.function
.isym
!= NULL
5721 && expr2
->value
.function
.esym
== NULL
5722 && expr2
->value
.function
.actual
!= NULL
5723 && expr2
->value
.function
.actual
->next
!= NULL
)
5725 gfc_actual_arglist
*arg
, *var_arg
;
5727 switch (expr2
->value
.function
.isym
->id
)
5735 if (expr2
->value
.function
.actual
->next
->next
!= NULL
)
5737 gfc_error ("!$OMP ATOMIC assignment intrinsic IAND, IOR "
5738 "or IEOR must have two arguments at %L",
5744 gfc_error ("!$OMP ATOMIC assignment intrinsic must be "
5745 "MIN, MAX, IAND, IOR or IEOR at %L",
5751 for (arg
= expr2
->value
.function
.actual
; arg
; arg
= arg
->next
)
5753 if ((arg
== expr2
->value
.function
.actual
5754 || (var_arg
== NULL
&& arg
->next
== NULL
))
5755 && arg
->expr
->expr_type
== EXPR_VARIABLE
5756 && arg
->expr
->symtree
!= NULL
5757 && arg
->expr
->symtree
->n
.sym
== var
)
5759 else if (expr_references_sym (arg
->expr
, var
, NULL
))
5761 gfc_error ("!$OMP ATOMIC intrinsic arguments except one must "
5762 "not reference %qs at %L",
5763 var
->name
, &arg
->expr
->where
);
5766 if (arg
->expr
->rank
!= 0)
5768 gfc_error ("!$OMP ATOMIC intrinsic arguments must be scalar "
5769 "at %L", &arg
->expr
->where
);
5774 if (var_arg
== NULL
)
5776 gfc_error ("First or last !$OMP ATOMIC intrinsic argument must "
5777 "be %qs at %L", var
->name
, &expr2
->where
);
5781 if (var_arg
!= expr2
->value
.function
.actual
)
5783 /* Canonicalize, so that var comes first. */
5784 gcc_assert (var_arg
->next
== NULL
);
5785 for (arg
= expr2
->value
.function
.actual
;
5786 arg
->next
!= var_arg
; arg
= arg
->next
)
5788 var_arg
->next
= expr2
->value
.function
.actual
;
5789 expr2
->value
.function
.actual
= var_arg
;
5794 gfc_error ("!$OMP ATOMIC assignment must have an operator or "
5795 "intrinsic on right hand side at %L", &expr2
->where
);
5797 if (aop
== GFC_OMP_ATOMIC_CAPTURE
&& code
->next
)
5800 if (code
->expr1
->expr_type
!= EXPR_VARIABLE
5801 || code
->expr1
->symtree
== NULL
5802 || code
->expr1
->rank
!= 0
5803 || (code
->expr1
->ts
.type
!= BT_INTEGER
5804 && code
->expr1
->ts
.type
!= BT_REAL
5805 && code
->expr1
->ts
.type
!= BT_COMPLEX
5806 && code
->expr1
->ts
.type
!= BT_LOGICAL
))
5808 gfc_error ("!$OMP ATOMIC CAPTURE capture statement must set "
5809 "a scalar variable of intrinsic type at %L",
5810 &code
->expr1
->where
);
5814 expr2
= is_conversion (code
->expr2
, false);
5817 expr2
= is_conversion (code
->expr2
, true);
5819 expr2
= code
->expr2
;
5822 if (expr2
->expr_type
!= EXPR_VARIABLE
5823 || expr2
->symtree
== NULL
5825 || (expr2
->ts
.type
!= BT_INTEGER
5826 && expr2
->ts
.type
!= BT_REAL
5827 && expr2
->ts
.type
!= BT_COMPLEX
5828 && expr2
->ts
.type
!= BT_LOGICAL
))
5830 gfc_error ("!$OMP ATOMIC CAPTURE capture statement must read "
5831 "from a scalar variable of intrinsic type at %L",
5835 if (expr2
->symtree
->n
.sym
!= var
)
5837 gfc_error ("!$OMP ATOMIC CAPTURE capture statement reads from "
5838 "different variable than update statement writes "
5839 "into at %L", &expr2
->where
);
5846 static struct fortran_omp_context
5849 hash_set
<gfc_symbol
*> *sharing_clauses
;
5850 hash_set
<gfc_symbol
*> *private_iterators
;
5851 struct fortran_omp_context
*previous
;
5854 static gfc_code
*omp_current_do_code
;
5855 static int omp_current_do_collapse
;
5858 gfc_resolve_omp_do_blocks (gfc_code
*code
, gfc_namespace
*ns
)
5860 if (code
->block
->next
&& code
->block
->next
->op
== EXEC_DO
)
5865 omp_current_do_code
= code
->block
->next
;
5866 if (code
->ext
.omp_clauses
->orderedc
)
5867 omp_current_do_collapse
= code
->ext
.omp_clauses
->orderedc
;
5869 omp_current_do_collapse
= code
->ext
.omp_clauses
->collapse
;
5870 for (i
= 1, c
= omp_current_do_code
; i
< omp_current_do_collapse
; i
++)
5873 if (c
->op
!= EXEC_DO
|| c
->next
== NULL
)
5876 if (c
->op
!= EXEC_DO
)
5879 if (i
< omp_current_do_collapse
|| omp_current_do_collapse
<= 0)
5880 omp_current_do_collapse
= 1;
5882 gfc_resolve_blocks (code
->block
, ns
);
5883 omp_current_do_collapse
= 0;
5884 omp_current_do_code
= NULL
;
5889 gfc_resolve_omp_parallel_blocks (gfc_code
*code
, gfc_namespace
*ns
)
5891 struct fortran_omp_context ctx
;
5892 gfc_omp_clauses
*omp_clauses
= code
->ext
.omp_clauses
;
5893 gfc_omp_namelist
*n
;
5897 ctx
.sharing_clauses
= new hash_set
<gfc_symbol
*>;
5898 ctx
.private_iterators
= new hash_set
<gfc_symbol
*>;
5899 ctx
.previous
= omp_current_ctx
;
5900 ctx
.is_openmp
= true;
5901 omp_current_ctx
= &ctx
;
5903 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
5906 case OMP_LIST_SHARED
:
5907 case OMP_LIST_PRIVATE
:
5908 case OMP_LIST_FIRSTPRIVATE
:
5909 case OMP_LIST_LASTPRIVATE
:
5910 case OMP_LIST_REDUCTION
:
5911 case OMP_LIST_LINEAR
:
5912 for (n
= omp_clauses
->lists
[list
]; n
; n
= n
->next
)
5913 ctx
.sharing_clauses
->add (n
->sym
);
5921 case EXEC_OMP_PARALLEL_DO
:
5922 case EXEC_OMP_PARALLEL_DO_SIMD
:
5923 case EXEC_OMP_TARGET_PARALLEL_DO
:
5924 case EXEC_OMP_TARGET_PARALLEL_DO_SIMD
:
5925 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE
:
5926 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO
:
5927 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
5928 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD
:
5929 case EXEC_OMP_TASKLOOP
:
5930 case EXEC_OMP_TASKLOOP_SIMD
:
5931 case EXEC_OMP_TEAMS_DISTRIBUTE
:
5932 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO
:
5933 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
5934 case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD
:
5935 gfc_resolve_omp_do_blocks (code
, ns
);
5938 gfc_resolve_blocks (code
->block
, ns
);
5941 omp_current_ctx
= ctx
.previous
;
5942 delete ctx
.sharing_clauses
;
5943 delete ctx
.private_iterators
;
5947 /* Save and clear openmp.c private state. */
5950 gfc_omp_save_and_clear_state (struct gfc_omp_saved_state
*state
)
5952 state
->ptrs
[0] = omp_current_ctx
;
5953 state
->ptrs
[1] = omp_current_do_code
;
5954 state
->ints
[0] = omp_current_do_collapse
;
5955 omp_current_ctx
= NULL
;
5956 omp_current_do_code
= NULL
;
5957 omp_current_do_collapse
= 0;
5961 /* Restore openmp.c private state from the saved state. */
5964 gfc_omp_restore_state (struct gfc_omp_saved_state
*state
)
5966 omp_current_ctx
= (struct fortran_omp_context
*) state
->ptrs
[0];
5967 omp_current_do_code
= (gfc_code
*) state
->ptrs
[1];
5968 omp_current_do_collapse
= state
->ints
[0];
5972 /* Note a DO iterator variable. This is special in !$omp parallel
5973 construct, where they are predetermined private. */
5976 gfc_resolve_do_iterator (gfc_code
*code
, gfc_symbol
*sym
, bool add_clause
)
5978 if (omp_current_ctx
== NULL
)
5981 int i
= omp_current_do_collapse
;
5982 gfc_code
*c
= omp_current_do_code
;
5984 if (sym
->attr
.threadprivate
)
5987 /* !$omp do and !$omp parallel do iteration variable is predetermined
5988 private just in the !$omp do resp. !$omp parallel do construct,
5989 with no implications for the outer parallel constructs. */
5999 /* An openacc context may represent a data clause. Abort if so. */
6000 if (!omp_current_ctx
->is_openmp
&& !oacc_is_loop (omp_current_ctx
->code
))
6003 if (omp_current_ctx
->sharing_clauses
->contains (sym
))
6006 if (omp_current_ctx
->is_openmp
&& omp_current_ctx
->code
->block
)
6008 /* SIMD is handled differently and, hence, ignored here. */
6009 gfc_code
*omp_code
= omp_current_ctx
->code
->block
;
6010 for ( ; omp_code
->next
; omp_code
= omp_code
->next
)
6011 switch (omp_code
->op
)
6014 case EXEC_OMP_DO_SIMD
:
6015 case EXEC_OMP_PARALLEL_DO_SIMD
:
6016 case EXEC_OMP_DISTRIBUTE_SIMD
:
6017 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD
:
6018 case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD
:
6019 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD
:
6020 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
6021 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
6022 case EXEC_OMP_TARGET_PARALLEL_DO_SIMD
:
6023 case EXEC_OMP_TARGET_SIMD
:
6024 case EXEC_OMP_TASKLOOP_SIMD
:
6031 if (! omp_current_ctx
->private_iterators
->add (sym
) && add_clause
)
6033 gfc_omp_clauses
*omp_clauses
= omp_current_ctx
->code
->ext
.omp_clauses
;
6034 gfc_omp_namelist
*p
;
6036 p
= gfc_get_omp_namelist ();
6038 p
->next
= omp_clauses
->lists
[OMP_LIST_PRIVATE
];
6039 omp_clauses
->lists
[OMP_LIST_PRIVATE
] = p
;
6044 handle_local_var (gfc_symbol
*sym
)
6046 if (sym
->attr
.flavor
!= FL_VARIABLE
6048 || (sym
->ts
.type
!= BT_INTEGER
&& sym
->ts
.type
!= BT_REAL
))
6050 gfc_resolve_do_iterator (sym
->ns
->code
, sym
, false);
6054 gfc_resolve_omp_local_vars (gfc_namespace
*ns
)
6056 if (omp_current_ctx
)
6057 gfc_traverse_ns (ns
, handle_local_var
);
6061 resolve_omp_do (gfc_code
*code
)
6063 gfc_code
*do_code
, *c
;
6064 int list
, i
, collapse
;
6065 gfc_omp_namelist
*n
;
6068 bool is_simd
= false;
6072 case EXEC_OMP_DISTRIBUTE
: name
= "!$OMP DISTRIBUTE"; break;
6073 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO
:
6074 name
= "!$OMP DISTRIBUTE PARALLEL DO";
6076 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD
:
6077 name
= "!$OMP DISTRIBUTE PARALLEL DO SIMD";
6080 case EXEC_OMP_DISTRIBUTE_SIMD
:
6081 name
= "!$OMP DISTRIBUTE SIMD";
6084 case EXEC_OMP_DO
: name
= "!$OMP DO"; break;
6085 case EXEC_OMP_DO_SIMD
: name
= "!$OMP DO SIMD"; is_simd
= true; break;
6086 case EXEC_OMP_PARALLEL_DO
: name
= "!$OMP PARALLEL DO"; break;
6087 case EXEC_OMP_PARALLEL_DO_SIMD
:
6088 name
= "!$OMP PARALLEL DO SIMD";
6091 case EXEC_OMP_SIMD
: name
= "!$OMP SIMD"; is_simd
= true; break;
6092 case EXEC_OMP_TARGET_PARALLEL_DO
: name
= "!$OMP TARGET PARALLEL DO"; break;
6093 case EXEC_OMP_TARGET_PARALLEL_DO_SIMD
:
6094 name
= "!$OMP TARGET PARALLEL DO SIMD";
6097 case EXEC_OMP_TARGET_SIMD
:
6098 name
= "!$OMP TARGET SIMD";
6101 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE
:
6102 name
= "!$OMP TARGET TEAMS DISTRIBUTE";
6104 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO
:
6105 name
= "!$OMP TARGET TEAMS DISTRIBUTE PARALLEL DO";
6107 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
6108 name
= "!$OMP TARGET TEAMS DISTRIBUTE PARALLEL DO SIMD";
6111 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD
:
6112 name
= "!$OMP TARGET TEAMS DISTRIBUTE SIMD";
6115 case EXEC_OMP_TASKLOOP
: name
= "!$OMP TASKLOOP"; break;
6116 case EXEC_OMP_TASKLOOP_SIMD
:
6117 name
= "!$OMP TASKLOOP SIMD";
6120 case EXEC_OMP_TEAMS_DISTRIBUTE
: name
= "!$OMP TEAMS DISTRIBUTE"; break;
6121 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO
:
6122 name
= "!$OMP TEAMS DISTRIBUTE PARALLEL DO";
6124 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
6125 name
= "!$OMP TEAMS DISTRIBUTE PARALLEL DO SIMD";
6128 case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD
:
6129 name
= "!$OMP TEAMS DISTRIBUTE SIMD";
6132 default: gcc_unreachable ();
6135 if (code
->ext
.omp_clauses
)
6136 resolve_omp_clauses (code
, code
->ext
.omp_clauses
, NULL
);
6138 do_code
= code
->block
->next
;
6139 if (code
->ext
.omp_clauses
->orderedc
)
6140 collapse
= code
->ext
.omp_clauses
->orderedc
;
6143 collapse
= code
->ext
.omp_clauses
->collapse
;
6147 for (i
= 1; i
<= collapse
; i
++)
6149 if (do_code
->op
== EXEC_DO_WHILE
)
6151 gfc_error ("%s cannot be a DO WHILE or DO without loop control "
6152 "at %L", name
, &do_code
->loc
);
6155 if (do_code
->op
== EXEC_DO_CONCURRENT
)
6157 gfc_error ("%s cannot be a DO CONCURRENT loop at %L", name
,
6161 gcc_assert (do_code
->op
== EXEC_DO
);
6162 if (do_code
->ext
.iterator
->var
->ts
.type
!= BT_INTEGER
)
6163 gfc_error ("%s iteration variable must be of type integer at %L",
6164 name
, &do_code
->loc
);
6165 dovar
= do_code
->ext
.iterator
->var
->symtree
->n
.sym
;
6166 if (dovar
->attr
.threadprivate
)
6167 gfc_error ("%s iteration variable must not be THREADPRIVATE "
6168 "at %L", name
, &do_code
->loc
);
6169 if (code
->ext
.omp_clauses
)
6170 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
6171 if (!is_simd
|| code
->ext
.omp_clauses
->collapse
> 1
6172 ? (list
!= OMP_LIST_PRIVATE
&& list
!= OMP_LIST_LASTPRIVATE
)
6173 : (list
!= OMP_LIST_PRIVATE
&& list
!= OMP_LIST_LASTPRIVATE
6174 && list
!= OMP_LIST_LINEAR
))
6175 for (n
= code
->ext
.omp_clauses
->lists
[list
]; n
; n
= n
->next
)
6176 if (dovar
== n
->sym
)
6178 if (!is_simd
|| code
->ext
.omp_clauses
->collapse
> 1)
6179 gfc_error ("%s iteration variable present on clause "
6180 "other than PRIVATE or LASTPRIVATE at %L",
6181 name
, &do_code
->loc
);
6183 gfc_error ("%s iteration variable present on clause "
6184 "other than PRIVATE, LASTPRIVATE or "
6185 "LINEAR at %L", name
, &do_code
->loc
);
6190 gfc_code
*do_code2
= code
->block
->next
;
6193 for (j
= 1; j
< i
; j
++)
6195 gfc_symbol
*ivar
= do_code2
->ext
.iterator
->var
->symtree
->n
.sym
;
6197 || gfc_find_sym_in_expr (ivar
, do_code
->ext
.iterator
->start
)
6198 || gfc_find_sym_in_expr (ivar
, do_code
->ext
.iterator
->end
)
6199 || gfc_find_sym_in_expr (ivar
, do_code
->ext
.iterator
->step
))
6201 gfc_error ("%s collapsed loops don't form rectangular "
6202 "iteration space at %L", name
, &do_code
->loc
);
6205 do_code2
= do_code2
->block
->next
;
6208 for (c
= do_code
->next
; c
; c
= c
->next
)
6209 if (c
->op
!= EXEC_NOP
&& c
->op
!= EXEC_CONTINUE
)
6211 gfc_error ("collapsed %s loops not perfectly nested at %L",
6215 if (i
== collapse
|| c
)
6217 do_code
= do_code
->block
;
6218 if (do_code
->op
!= EXEC_DO
&& do_code
->op
!= EXEC_DO_WHILE
)
6220 gfc_error ("not enough DO loops for collapsed %s at %L",
6224 do_code
= do_code
->next
;
6226 || (do_code
->op
!= EXEC_DO
&& do_code
->op
!= EXEC_DO_WHILE
))
6228 gfc_error ("not enough DO loops for collapsed %s at %L",
6236 oacc_is_parallel (gfc_code
*code
)
6238 return code
->op
== EXEC_OACC_PARALLEL
|| code
->op
== EXEC_OACC_PARALLEL_LOOP
;
6241 static gfc_statement
6242 omp_code_to_statement (gfc_code
*code
)
6246 case EXEC_OMP_PARALLEL
:
6247 return ST_OMP_PARALLEL
;
6248 case EXEC_OMP_PARALLEL_SECTIONS
:
6249 return ST_OMP_PARALLEL_SECTIONS
;
6250 case EXEC_OMP_SECTIONS
:
6251 return ST_OMP_SECTIONS
;
6252 case EXEC_OMP_ORDERED
:
6253 return ST_OMP_ORDERED
;
6254 case EXEC_OMP_CRITICAL
:
6255 return ST_OMP_CRITICAL
;
6256 case EXEC_OMP_MASTER
:
6257 return ST_OMP_MASTER
;
6258 case EXEC_OMP_SINGLE
:
6259 return ST_OMP_SINGLE
;
6262 case EXEC_OMP_WORKSHARE
:
6263 return ST_OMP_WORKSHARE
;
6264 case EXEC_OMP_PARALLEL_WORKSHARE
:
6265 return ST_OMP_PARALLEL_WORKSHARE
;
6268 case EXEC_OMP_ATOMIC
:
6269 return ST_OMP_ATOMIC
;
6270 case EXEC_OMP_BARRIER
:
6271 return ST_OMP_BARRIER
;
6272 case EXEC_OMP_CANCEL
:
6273 return ST_OMP_CANCEL
;
6274 case EXEC_OMP_CANCELLATION_POINT
:
6275 return ST_OMP_CANCELLATION_POINT
;
6276 case EXEC_OMP_FLUSH
:
6277 return ST_OMP_FLUSH
;
6278 case EXEC_OMP_DISTRIBUTE
:
6279 return ST_OMP_DISTRIBUTE
;
6280 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO
:
6281 return ST_OMP_DISTRIBUTE_PARALLEL_DO
;
6282 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD
:
6283 return ST_OMP_DISTRIBUTE_PARALLEL_DO_SIMD
;
6284 case EXEC_OMP_DISTRIBUTE_SIMD
:
6285 return ST_OMP_DISTRIBUTE_SIMD
;
6286 case EXEC_OMP_DO_SIMD
:
6287 return ST_OMP_DO_SIMD
;
6290 case EXEC_OMP_TARGET
:
6291 return ST_OMP_TARGET
;
6292 case EXEC_OMP_TARGET_DATA
:
6293 return ST_OMP_TARGET_DATA
;
6294 case EXEC_OMP_TARGET_ENTER_DATA
:
6295 return ST_OMP_TARGET_ENTER_DATA
;
6296 case EXEC_OMP_TARGET_EXIT_DATA
:
6297 return ST_OMP_TARGET_EXIT_DATA
;
6298 case EXEC_OMP_TARGET_PARALLEL
:
6299 return ST_OMP_TARGET_PARALLEL
;
6300 case EXEC_OMP_TARGET_PARALLEL_DO
:
6301 return ST_OMP_TARGET_PARALLEL_DO
;
6302 case EXEC_OMP_TARGET_PARALLEL_DO_SIMD
:
6303 return ST_OMP_TARGET_PARALLEL_DO_SIMD
;
6304 case EXEC_OMP_TARGET_SIMD
:
6305 return ST_OMP_TARGET_SIMD
;
6306 case EXEC_OMP_TARGET_TEAMS
:
6307 return ST_OMP_TARGET_TEAMS
;
6308 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE
:
6309 return ST_OMP_TARGET_TEAMS_DISTRIBUTE
;
6310 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO
:
6311 return ST_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO
;
6312 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
6313 return ST_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
;
6314 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD
:
6315 return ST_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD
;
6316 case EXEC_OMP_TARGET_UPDATE
:
6317 return ST_OMP_TARGET_UPDATE
;
6318 case EXEC_OMP_TASKGROUP
:
6319 return ST_OMP_TASKGROUP
;
6320 case EXEC_OMP_TASKLOOP
:
6321 return ST_OMP_TASKLOOP
;
6322 case EXEC_OMP_TASKLOOP_SIMD
:
6323 return ST_OMP_TASKLOOP_SIMD
;
6324 case EXEC_OMP_TASKWAIT
:
6325 return ST_OMP_TASKWAIT
;
6326 case EXEC_OMP_TASKYIELD
:
6327 return ST_OMP_TASKYIELD
;
6328 case EXEC_OMP_TEAMS
:
6329 return ST_OMP_TEAMS
;
6330 case EXEC_OMP_TEAMS_DISTRIBUTE
:
6331 return ST_OMP_TEAMS_DISTRIBUTE
;
6332 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO
:
6333 return ST_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO
;
6334 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
6335 return ST_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
;
6336 case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD
:
6337 return ST_OMP_TEAMS_DISTRIBUTE_SIMD
;
6338 case EXEC_OMP_PARALLEL_DO
:
6339 return ST_OMP_PARALLEL_DO
;
6340 case EXEC_OMP_PARALLEL_DO_SIMD
:
6341 return ST_OMP_PARALLEL_DO_SIMD
;
6348 static gfc_statement
6349 oacc_code_to_statement (gfc_code
*code
)
6353 case EXEC_OACC_PARALLEL
:
6354 return ST_OACC_PARALLEL
;
6355 case EXEC_OACC_KERNELS
:
6356 return ST_OACC_KERNELS
;
6357 case EXEC_OACC_SERIAL
:
6358 return ST_OACC_SERIAL
;
6359 case EXEC_OACC_DATA
:
6360 return ST_OACC_DATA
;
6361 case EXEC_OACC_HOST_DATA
:
6362 return ST_OACC_HOST_DATA
;
6363 case EXEC_OACC_PARALLEL_LOOP
:
6364 return ST_OACC_PARALLEL_LOOP
;
6365 case EXEC_OACC_KERNELS_LOOP
:
6366 return ST_OACC_KERNELS_LOOP
;
6367 case EXEC_OACC_SERIAL_LOOP
:
6368 return ST_OACC_SERIAL_LOOP
;
6369 case EXEC_OACC_LOOP
:
6370 return ST_OACC_LOOP
;
6371 case EXEC_OACC_ATOMIC
:
6372 return ST_OACC_ATOMIC
;
6373 case EXEC_OACC_ROUTINE
:
6374 return ST_OACC_ROUTINE
;
6375 case EXEC_OACC_UPDATE
:
6376 return ST_OACC_UPDATE
;
6377 case EXEC_OACC_WAIT
:
6378 return ST_OACC_WAIT
;
6379 case EXEC_OACC_CACHE
:
6380 return ST_OACC_CACHE
;
6381 case EXEC_OACC_ENTER_DATA
:
6382 return ST_OACC_ENTER_DATA
;
6383 case EXEC_OACC_EXIT_DATA
:
6384 return ST_OACC_EXIT_DATA
;
6385 case EXEC_OACC_DECLARE
:
6386 return ST_OACC_DECLARE
;
6393 resolve_oacc_directive_inside_omp_region (gfc_code
*code
)
6395 if (omp_current_ctx
!= NULL
&& omp_current_ctx
->is_openmp
)
6397 gfc_statement st
= omp_code_to_statement (omp_current_ctx
->code
);
6398 gfc_statement oacc_st
= oacc_code_to_statement (code
);
6399 gfc_error ("The %s directive cannot be specified within "
6400 "a %s region at %L", gfc_ascii_statement (oacc_st
),
6401 gfc_ascii_statement (st
), &code
->loc
);
6406 resolve_omp_directive_inside_oacc_region (gfc_code
*code
)
6408 if (omp_current_ctx
!= NULL
&& !omp_current_ctx
->is_openmp
)
6410 gfc_statement st
= oacc_code_to_statement (omp_current_ctx
->code
);
6411 gfc_statement omp_st
= omp_code_to_statement (code
);
6412 gfc_error ("The %s directive cannot be specified within "
6413 "a %s region at %L", gfc_ascii_statement (omp_st
),
6414 gfc_ascii_statement (st
), &code
->loc
);
6420 resolve_oacc_nested_loops (gfc_code
*code
, gfc_code
* do_code
, int collapse
,
6427 for (i
= 1; i
<= collapse
; i
++)
6429 if (do_code
->op
== EXEC_DO_WHILE
)
6431 gfc_error ("!$ACC LOOP cannot be a DO WHILE or DO without loop control "
6432 "at %L", &do_code
->loc
);
6435 if (do_code
->op
== EXEC_DO_CONCURRENT
)
6437 gfc_error ("!$ACC LOOP cannot be a DO CONCURRENT loop at %L",
6441 gcc_assert (do_code
->op
== EXEC_DO
);
6442 if (do_code
->ext
.iterator
->var
->ts
.type
!= BT_INTEGER
)
6443 gfc_error ("!$ACC LOOP iteration variable must be of type integer at %L",
6445 dovar
= do_code
->ext
.iterator
->var
->symtree
->n
.sym
;
6448 gfc_code
*do_code2
= code
->block
->next
;
6451 for (j
= 1; j
< i
; j
++)
6453 gfc_symbol
*ivar
= do_code2
->ext
.iterator
->var
->symtree
->n
.sym
;
6455 || gfc_find_sym_in_expr (ivar
, do_code
->ext
.iterator
->start
)
6456 || gfc_find_sym_in_expr (ivar
, do_code
->ext
.iterator
->end
)
6457 || gfc_find_sym_in_expr (ivar
, do_code
->ext
.iterator
->step
))
6459 gfc_error ("!$ACC LOOP %s loops don't form rectangular "
6460 "iteration space at %L", clause
, &do_code
->loc
);
6463 do_code2
= do_code2
->block
->next
;
6468 for (c
= do_code
->next
; c
; c
= c
->next
)
6469 if (c
->op
!= EXEC_NOP
&& c
->op
!= EXEC_CONTINUE
)
6471 gfc_error ("%s !$ACC LOOP loops not perfectly nested at %L",
6477 do_code
= do_code
->block
;
6478 if (do_code
->op
!= EXEC_DO
&& do_code
->op
!= EXEC_DO_WHILE
6479 && do_code
->op
!= EXEC_DO_CONCURRENT
)
6481 gfc_error ("not enough DO loops for %s !$ACC LOOP at %L",
6482 clause
, &code
->loc
);
6485 do_code
= do_code
->next
;
6487 || (do_code
->op
!= EXEC_DO
&& do_code
->op
!= EXEC_DO_WHILE
6488 && do_code
->op
!= EXEC_DO_CONCURRENT
))
6490 gfc_error ("not enough DO loops for %s !$ACC LOOP at %L",
6491 clause
, &code
->loc
);
6499 resolve_oacc_params_in_parallel (gfc_code
*code
, const char *clause
,
6502 fortran_omp_context
*c
;
6504 if (oacc_is_parallel (code
))
6505 gfc_error ("!$ACC LOOP %s in PARALLEL region doesn't allow "
6506 "%s arguments at %L", clause
, arg
, &code
->loc
);
6507 for (c
= omp_current_ctx
; c
; c
= c
->previous
)
6509 if (oacc_is_loop (c
->code
))
6511 if (oacc_is_parallel (c
->code
))
6512 gfc_error ("!$ACC LOOP %s in PARALLEL region doesn't allow "
6513 "%s arguments at %L", clause
, arg
, &code
->loc
);
6519 resolve_oacc_loop_blocks (gfc_code
*code
)
6521 if (!oacc_is_loop (code
))
6524 if (code
->ext
.omp_clauses
->tile_list
&& code
->ext
.omp_clauses
->gang
6525 && code
->ext
.omp_clauses
->worker
&& code
->ext
.omp_clauses
->vector
)
6526 gfc_error ("Tiled loop cannot be parallelized across gangs, workers and "
6527 "vectors at the same time at %L", &code
->loc
);
6529 if (code
->ext
.omp_clauses
->gang
6530 && code
->ext
.omp_clauses
->gang_num_expr
)
6531 resolve_oacc_params_in_parallel (code
, "GANG", "num");
6533 if (code
->ext
.omp_clauses
->worker
6534 && code
->ext
.omp_clauses
->worker_expr
)
6535 resolve_oacc_params_in_parallel (code
, "WORKER", "num");
6537 if (code
->ext
.omp_clauses
->vector
6538 && code
->ext
.omp_clauses
->vector_expr
)
6539 resolve_oacc_params_in_parallel (code
, "VECTOR", "length");
6541 if (code
->ext
.omp_clauses
->tile_list
)
6544 for (el
= code
->ext
.omp_clauses
->tile_list
; el
; el
= el
->next
)
6546 if (el
->expr
== NULL
)
6548 /* NULL expressions are used to represent '*' arguments.
6549 Convert those to a 0 expressions. */
6550 el
->expr
= gfc_get_constant_expr (BT_INTEGER
,
6551 gfc_default_integer_kind
,
6553 mpz_set_si (el
->expr
->value
.integer
, 0);
6557 resolve_positive_int_expr (el
->expr
, "TILE");
6558 if (el
->expr
->expr_type
!= EXPR_CONSTANT
)
6559 gfc_error ("TILE requires constant expression at %L",
6568 gfc_resolve_oacc_blocks (gfc_code
*code
, gfc_namespace
*ns
)
6570 fortran_omp_context ctx
;
6571 gfc_omp_clauses
*omp_clauses
= code
->ext
.omp_clauses
;
6572 gfc_omp_namelist
*n
;
6575 resolve_oacc_loop_blocks (code
);
6578 ctx
.sharing_clauses
= new hash_set
<gfc_symbol
*>;
6579 ctx
.private_iterators
= new hash_set
<gfc_symbol
*>;
6580 ctx
.previous
= omp_current_ctx
;
6581 ctx
.is_openmp
= false;
6582 omp_current_ctx
= &ctx
;
6584 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
6587 case OMP_LIST_PRIVATE
:
6588 for (n
= omp_clauses
->lists
[list
]; n
; n
= n
->next
)
6589 ctx
.sharing_clauses
->add (n
->sym
);
6595 gfc_resolve_blocks (code
->block
, ns
);
6597 omp_current_ctx
= ctx
.previous
;
6598 delete ctx
.sharing_clauses
;
6599 delete ctx
.private_iterators
;
6604 resolve_oacc_loop (gfc_code
*code
)
6609 if (code
->ext
.omp_clauses
)
6610 resolve_omp_clauses (code
, code
->ext
.omp_clauses
, NULL
, true);
6612 do_code
= code
->block
->next
;
6613 collapse
= code
->ext
.omp_clauses
->collapse
;
6615 /* Both collapsed and tiled loops are lowered the same way, but are not
6616 compatible. In gfc_trans_omp_do, the tile is prioritized. */
6617 if (code
->ext
.omp_clauses
->tile_list
)
6621 for (el
= code
->ext
.omp_clauses
->tile_list
; el
; el
= el
->next
)
6623 resolve_oacc_nested_loops (code
, code
->block
->next
, num
, "tiled");
6629 resolve_oacc_nested_loops (code
, do_code
, collapse
, "collapsed");
6633 gfc_resolve_oacc_declare (gfc_namespace
*ns
)
6636 gfc_omp_namelist
*n
;
6637 gfc_oacc_declare
*oc
;
6639 if (ns
->oacc_declare
== NULL
)
6642 for (oc
= ns
->oacc_declare
; oc
; oc
= oc
->next
)
6644 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
6645 for (n
= oc
->clauses
->lists
[list
]; n
; n
= n
->next
)
6648 if (n
->sym
->attr
.flavor
!= FL_VARIABLE
6649 && (n
->sym
->attr
.flavor
!= FL_PROCEDURE
6650 || n
->sym
->result
!= n
->sym
))
6652 gfc_error ("Object %qs is not a variable at %L",
6653 n
->sym
->name
, &oc
->loc
);
6657 if (n
->expr
&& n
->expr
->ref
->type
== REF_ARRAY
)
6659 gfc_error ("Array sections: %qs not allowed in"
6660 " !$ACC DECLARE at %L", n
->sym
->name
, &oc
->loc
);
6665 for (n
= oc
->clauses
->lists
[OMP_LIST_DEVICE_RESIDENT
]; n
; n
= n
->next
)
6666 check_array_not_assumed (n
->sym
, oc
->loc
, "DEVICE_RESIDENT");
6669 for (oc
= ns
->oacc_declare
; oc
; oc
= oc
->next
)
6671 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
6672 for (n
= oc
->clauses
->lists
[list
]; n
; n
= n
->next
)
6676 gfc_error ("Symbol %qs present on multiple clauses at %L",
6677 n
->sym
->name
, &oc
->loc
);
6685 for (oc
= ns
->oacc_declare
; oc
; oc
= oc
->next
)
6687 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
6688 for (n
= oc
->clauses
->lists
[list
]; n
; n
= n
->next
)
6695 gfc_resolve_oacc_routines (gfc_namespace
*ns
)
6697 for (gfc_oacc_routine_name
*orn
= ns
->oacc_routine_names
;
6701 gfc_symbol
*sym
= orn
->sym
;
6702 if (!sym
->attr
.external
6703 && !sym
->attr
.function
6704 && !sym
->attr
.subroutine
)
6706 gfc_error ("NAME %qs does not refer to a subroutine or function"
6707 " in !$ACC ROUTINE ( NAME ) at %L", sym
->name
, &orn
->loc
);
6710 if (!gfc_add_omp_declare_target (&sym
->attr
, sym
->name
, &orn
->loc
))
6712 gfc_error ("NAME %qs invalid"
6713 " in !$ACC ROUTINE ( NAME ) at %L", sym
->name
, &orn
->loc
);
6721 gfc_resolve_oacc_directive (gfc_code
*code
, gfc_namespace
*ns ATTRIBUTE_UNUSED
)
6723 resolve_oacc_directive_inside_omp_region (code
);
6727 case EXEC_OACC_PARALLEL
:
6728 case EXEC_OACC_KERNELS
:
6729 case EXEC_OACC_SERIAL
:
6730 case EXEC_OACC_DATA
:
6731 case EXEC_OACC_HOST_DATA
:
6732 case EXEC_OACC_UPDATE
:
6733 case EXEC_OACC_ENTER_DATA
:
6734 case EXEC_OACC_EXIT_DATA
:
6735 case EXEC_OACC_WAIT
:
6736 case EXEC_OACC_CACHE
:
6737 resolve_omp_clauses (code
, code
->ext
.omp_clauses
, NULL
, true);
6739 case EXEC_OACC_PARALLEL_LOOP
:
6740 case EXEC_OACC_KERNELS_LOOP
:
6741 case EXEC_OACC_SERIAL_LOOP
:
6742 case EXEC_OACC_LOOP
:
6743 resolve_oacc_loop (code
);
6745 case EXEC_OACC_ATOMIC
:
6746 resolve_omp_atomic (code
);
6754 /* Resolve OpenMP directive clauses and check various requirements
6755 of each directive. */
6758 gfc_resolve_omp_directive (gfc_code
*code
, gfc_namespace
*ns ATTRIBUTE_UNUSED
)
6760 resolve_omp_directive_inside_oacc_region (code
);
6762 if (code
->op
!= EXEC_OMP_ATOMIC
)
6763 gfc_maybe_initialize_eh ();
6767 case EXEC_OMP_DISTRIBUTE
:
6768 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO
:
6769 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD
:
6770 case EXEC_OMP_DISTRIBUTE_SIMD
:
6772 case EXEC_OMP_DO_SIMD
:
6773 case EXEC_OMP_PARALLEL_DO
:
6774 case EXEC_OMP_PARALLEL_DO_SIMD
:
6776 case EXEC_OMP_TARGET_PARALLEL_DO
:
6777 case EXEC_OMP_TARGET_PARALLEL_DO_SIMD
:
6778 case EXEC_OMP_TARGET_SIMD
:
6779 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE
:
6780 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO
:
6781 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
6782 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD
:
6783 case EXEC_OMP_TASKLOOP
:
6784 case EXEC_OMP_TASKLOOP_SIMD
:
6785 case EXEC_OMP_TEAMS_DISTRIBUTE
:
6786 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO
:
6787 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
6788 case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD
:
6789 resolve_omp_do (code
);
6791 case EXEC_OMP_CANCEL
:
6792 case EXEC_OMP_PARALLEL_WORKSHARE
:
6793 case EXEC_OMP_PARALLEL
:
6794 case EXEC_OMP_PARALLEL_SECTIONS
:
6795 case EXEC_OMP_SECTIONS
:
6796 case EXEC_OMP_SINGLE
:
6797 case EXEC_OMP_TARGET
:
6798 case EXEC_OMP_TARGET_DATA
:
6799 case EXEC_OMP_TARGET_ENTER_DATA
:
6800 case EXEC_OMP_TARGET_EXIT_DATA
:
6801 case EXEC_OMP_TARGET_PARALLEL
:
6802 case EXEC_OMP_TARGET_TEAMS
:
6804 case EXEC_OMP_TEAMS
:
6805 case EXEC_OMP_WORKSHARE
:
6806 if (code
->ext
.omp_clauses
)
6807 resolve_omp_clauses (code
, code
->ext
.omp_clauses
, NULL
);
6809 case EXEC_OMP_TARGET_UPDATE
:
6810 if (code
->ext
.omp_clauses
)
6811 resolve_omp_clauses (code
, code
->ext
.omp_clauses
, NULL
);
6812 if (code
->ext
.omp_clauses
== NULL
6813 || (code
->ext
.omp_clauses
->lists
[OMP_LIST_TO
] == NULL
6814 && code
->ext
.omp_clauses
->lists
[OMP_LIST_FROM
] == NULL
))
6815 gfc_error ("OMP TARGET UPDATE at %L requires at least one TO or "
6816 "FROM clause", &code
->loc
);
6818 case EXEC_OMP_ATOMIC
:
6819 resolve_omp_atomic (code
);
6821 case EXEC_OMP_CRITICAL
:
6822 resolve_omp_clauses (code
, code
->ext
.omp_clauses
, NULL
);
6823 if (!code
->ext
.omp_clauses
->critical_name
6824 && code
->ext
.omp_clauses
->hint
6825 && code
->ext
.omp_clauses
->hint
->ts
.type
== BT_INTEGER
6826 && code
->ext
.omp_clauses
->hint
->expr_type
== EXPR_CONSTANT
6827 && mpz_sgn (code
->ext
.omp_clauses
->hint
->value
.integer
) != 0)
6828 gfc_error ("OMP CRITICAL at %L with HINT clause requires a NAME, "
6829 "except when omp_sync_hint_none is used", &code
->loc
);
6836 /* Resolve !$omp declare simd constructs in NS. */
6839 gfc_resolve_omp_declare_simd (gfc_namespace
*ns
)
6841 gfc_omp_declare_simd
*ods
;
6843 for (ods
= ns
->omp_declare_simd
; ods
; ods
= ods
->next
)
6845 if (ods
->proc_name
!= NULL
6846 && ods
->proc_name
!= ns
->proc_name
)
6847 gfc_error ("!$OMP DECLARE SIMD should refer to containing procedure "
6848 "%qs at %L", ns
->proc_name
->name
, &ods
->where
);
6850 resolve_omp_clauses (NULL
, ods
->clauses
, ns
);
6854 struct omp_udr_callback_data
6856 gfc_omp_udr
*omp_udr
;
6857 bool is_initializer
;
6861 omp_udr_callback (gfc_expr
**e
, int *walk_subtrees ATTRIBUTE_UNUSED
,
6864 struct omp_udr_callback_data
*cd
= (struct omp_udr_callback_data
*) data
;
6865 if ((*e
)->expr_type
== EXPR_VARIABLE
)
6867 if (cd
->is_initializer
)
6869 if ((*e
)->symtree
->n
.sym
!= cd
->omp_udr
->omp_priv
6870 && (*e
)->symtree
->n
.sym
!= cd
->omp_udr
->omp_orig
)
6871 gfc_error ("Variable other than OMP_PRIV or OMP_ORIG used in "
6872 "INITIALIZER clause of !$OMP DECLARE REDUCTION at %L",
6877 if ((*e
)->symtree
->n
.sym
!= cd
->omp_udr
->omp_out
6878 && (*e
)->symtree
->n
.sym
!= cd
->omp_udr
->omp_in
)
6879 gfc_error ("Variable other than OMP_OUT or OMP_IN used in "
6880 "combiner of !$OMP DECLARE REDUCTION at %L",
6887 /* Resolve !$omp declare reduction constructs. */
6890 gfc_resolve_omp_udr (gfc_omp_udr
*omp_udr
)
6892 gfc_actual_arglist
*a
;
6893 const char *predef_name
= NULL
;
6895 switch (omp_udr
->rop
)
6897 case OMP_REDUCTION_PLUS
:
6898 case OMP_REDUCTION_TIMES
:
6899 case OMP_REDUCTION_MINUS
:
6900 case OMP_REDUCTION_AND
:
6901 case OMP_REDUCTION_OR
:
6902 case OMP_REDUCTION_EQV
:
6903 case OMP_REDUCTION_NEQV
:
6904 case OMP_REDUCTION_MAX
:
6905 case OMP_REDUCTION_USER
:
6908 gfc_error ("Invalid operator for !$OMP DECLARE REDUCTION %s at %L",
6909 omp_udr
->name
, &omp_udr
->where
);
6913 if (gfc_omp_udr_predef (omp_udr
->rop
, omp_udr
->name
,
6914 &omp_udr
->ts
, &predef_name
))
6917 gfc_error_now ("Redefinition of predefined %s "
6918 "!$OMP DECLARE REDUCTION at %L",
6919 predef_name
, &omp_udr
->where
);
6921 gfc_error_now ("Redefinition of predefined "
6922 "!$OMP DECLARE REDUCTION at %L", &omp_udr
->where
);
6926 if (omp_udr
->ts
.type
== BT_CHARACTER
6927 && omp_udr
->ts
.u
.cl
->length
6928 && omp_udr
->ts
.u
.cl
->length
->expr_type
!= EXPR_CONSTANT
)
6930 gfc_error ("CHARACTER length in !$OMP DECLARE REDUCTION %s not "
6931 "constant at %L", omp_udr
->name
, &omp_udr
->where
);
6935 struct omp_udr_callback_data cd
;
6936 cd
.omp_udr
= omp_udr
;
6937 cd
.is_initializer
= false;
6938 gfc_code_walker (&omp_udr
->combiner_ns
->code
, gfc_dummy_code_callback
,
6939 omp_udr_callback
, &cd
);
6940 if (omp_udr
->combiner_ns
->code
->op
== EXEC_CALL
)
6942 for (a
= omp_udr
->combiner_ns
->code
->ext
.actual
; a
; a
= a
->next
)
6943 if (a
->expr
== NULL
)
6946 gfc_error ("Subroutine call with alternate returns in combiner "
6947 "of !$OMP DECLARE REDUCTION at %L",
6948 &omp_udr
->combiner_ns
->code
->loc
);
6950 if (omp_udr
->initializer_ns
)
6952 cd
.is_initializer
= true;
6953 gfc_code_walker (&omp_udr
->initializer_ns
->code
, gfc_dummy_code_callback
,
6954 omp_udr_callback
, &cd
);
6955 if (omp_udr
->initializer_ns
->code
->op
== EXEC_CALL
)
6957 for (a
= omp_udr
->initializer_ns
->code
->ext
.actual
; a
; a
= a
->next
)
6958 if (a
->expr
== NULL
)
6961 gfc_error ("Subroutine call with alternate returns in "
6962 "INITIALIZER clause of !$OMP DECLARE REDUCTION "
6963 "at %L", &omp_udr
->initializer_ns
->code
->loc
);
6964 for (a
= omp_udr
->initializer_ns
->code
->ext
.actual
; a
; a
= a
->next
)
6966 && a
->expr
->expr_type
== EXPR_VARIABLE
6967 && a
->expr
->symtree
->n
.sym
== omp_udr
->omp_priv
6968 && a
->expr
->ref
== NULL
)
6971 gfc_error ("One of actual subroutine arguments in INITIALIZER "
6972 "clause of !$OMP DECLARE REDUCTION must be OMP_PRIV "
6973 "at %L", &omp_udr
->initializer_ns
->code
->loc
);
6976 else if (omp_udr
->ts
.type
== BT_DERIVED
6977 && !gfc_has_default_initializer (omp_udr
->ts
.u
.derived
))
6979 gfc_error ("Missing INITIALIZER clause for !$OMP DECLARE REDUCTION "
6980 "of derived type without default initializer at %L",
6987 gfc_resolve_omp_udrs (gfc_symtree
*st
)
6989 gfc_omp_udr
*omp_udr
;
6993 gfc_resolve_omp_udrs (st
->left
);
6994 gfc_resolve_omp_udrs (st
->right
);
6995 for (omp_udr
= st
->n
.omp_udr
; omp_udr
; omp_udr
= omp_udr
->next
)
6996 gfc_resolve_omp_udr (omp_udr
);