1 /* OpenMP directive matching and resolving.
2 Copyright (C) 2005-2019 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)
238 gfc_omp_namelist
*head
, *tail
, *p
;
239 locus old_loc
, cur_loc
;
240 char n
[GFC_MAX_SYMBOL_LEN
+1];
247 old_loc
= gfc_current_locus
;
255 cur_loc
= gfc_current_locus
;
256 m
= gfc_match_symbol (&sym
, 1);
262 if (allow_sections
&& gfc_peek_ascii_char () == '(')
264 gfc_current_locus
= cur_loc
;
265 m
= gfc_match_variable (&expr
, 0);
276 gfc_set_sym_referenced (sym
);
277 p
= gfc_get_omp_namelist ();
287 tail
->where
= cur_loc
;
298 m
= gfc_match (" / %n /", n
);
299 if (m
== MATCH_ERROR
)
304 st
= gfc_find_symtree (gfc_current_ns
->common_root
, n
);
307 gfc_error ("COMMON block /%s/ not found at %C", n
);
310 for (sym
= st
->n
.common
->head
; sym
; sym
= sym
->common_next
)
312 gfc_set_sym_referenced (sym
);
313 p
= gfc_get_omp_namelist ();
322 tail
->where
= cur_loc
;
326 if (end_colon
&& gfc_match_char (':') == MATCH_YES
)
331 if (gfc_match_char (')') == MATCH_YES
)
333 if (gfc_match_char (',') != MATCH_YES
)
338 list
= &(*list
)->next
;
346 gfc_error ("Syntax error in OpenMP variable list at %C");
349 gfc_free_omp_namelist (head
);
350 gfc_current_locus
= old_loc
;
354 /* Match a variable/procedure/common block list and construct a namelist
358 gfc_match_omp_to_link (const char *str
, gfc_omp_namelist
**list
)
360 gfc_omp_namelist
*head
, *tail
, *p
;
361 locus old_loc
, cur_loc
;
362 char n
[GFC_MAX_SYMBOL_LEN
+1];
369 old_loc
= gfc_current_locus
;
377 cur_loc
= gfc_current_locus
;
378 m
= gfc_match_symbol (&sym
, 1);
382 p
= gfc_get_omp_namelist ();
391 tail
->where
= cur_loc
;
399 m
= gfc_match (" / %n /", n
);
400 if (m
== MATCH_ERROR
)
405 st
= gfc_find_symtree (gfc_current_ns
->common_root
, n
);
408 gfc_error ("COMMON block /%s/ not found at %C", n
);
411 p
= gfc_get_omp_namelist ();
419 tail
->u
.common
= st
->n
.common
;
420 tail
->where
= cur_loc
;
423 if (gfc_match_char (')') == MATCH_YES
)
425 if (gfc_match_char (',') != MATCH_YES
)
430 list
= &(*list
)->next
;
436 gfc_error ("Syntax error in OpenMP variable list at %C");
439 gfc_free_omp_namelist (head
);
440 gfc_current_locus
= old_loc
;
444 /* Match depend(sink : ...) construct a namelist from it. */
447 gfc_match_omp_depend_sink (gfc_omp_namelist
**list
)
449 gfc_omp_namelist
*head
, *tail
, *p
;
450 locus old_loc
, cur_loc
;
455 old_loc
= gfc_current_locus
;
459 cur_loc
= gfc_current_locus
;
460 switch (gfc_match_symbol (&sym
, 1))
463 gfc_set_sym_referenced (sym
);
464 p
= gfc_get_omp_namelist ();
468 head
->u
.depend_op
= OMP_DEPEND_SINK_FIRST
;
474 tail
->u
.depend_op
= OMP_DEPEND_SINK
;
478 tail
->where
= cur_loc
;
479 if (gfc_match_char ('+') == MATCH_YES
)
481 if (gfc_match_literal_constant (&tail
->expr
, 0) != MATCH_YES
)
484 else if (gfc_match_char ('-') == MATCH_YES
)
486 if (gfc_match_literal_constant (&tail
->expr
, 0) != MATCH_YES
)
488 tail
->expr
= gfc_uminus (tail
->expr
);
497 if (gfc_match_char (')') == MATCH_YES
)
499 if (gfc_match_char (',') != MATCH_YES
)
504 list
= &(*list
)->next
;
510 gfc_error ("Syntax error in OpenMP DEPEND SINK list at %C");
513 gfc_free_omp_namelist (head
);
514 gfc_current_locus
= old_loc
;
519 match_oacc_expr_list (const char *str
, gfc_expr_list
**list
,
522 gfc_expr_list
*head
, *tail
, *p
;
529 old_loc
= gfc_current_locus
;
537 m
= gfc_match_expr (&expr
);
538 if (m
== MATCH_YES
|| allow_asterisk
)
540 p
= gfc_get_expr_list ();
550 else if (gfc_match (" *") != MATCH_YES
)
554 if (m
== MATCH_ERROR
)
559 if (gfc_match_char (')') == MATCH_YES
)
561 if (gfc_match_char (',') != MATCH_YES
)
566 list
= &(*list
)->next
;
572 gfc_error ("Syntax error in OpenACC expression list at %C");
575 gfc_free_expr_list (head
);
576 gfc_current_locus
= old_loc
;
581 match_oacc_clause_gwv (gfc_omp_clauses
*cp
, unsigned gwv
)
583 match ret
= MATCH_YES
;
585 if (gfc_match (" ( ") != MATCH_YES
)
588 if (gwv
== GOMP_DIM_GANG
)
590 /* The gang clause accepts two optional arguments, num and static.
591 The num argument may either be explicit (num: <val>) or
592 implicit without (<val> without num:). */
594 while (ret
== MATCH_YES
)
596 if (gfc_match (" static :") == MATCH_YES
)
601 cp
->gang_static
= true;
602 if (gfc_match_char ('*') == MATCH_YES
)
603 cp
->gang_static_expr
= NULL
;
604 else if (gfc_match (" %e ", &cp
->gang_static_expr
) != MATCH_YES
)
609 if (cp
->gang_num_expr
)
612 /* The 'num' argument is optional. */
613 gfc_match (" num :");
615 if (gfc_match (" %e ", &cp
->gang_num_expr
) != MATCH_YES
)
619 ret
= gfc_match (" , ");
622 else if (gwv
== GOMP_DIM_WORKER
)
624 /* The 'num' argument is optional. */
625 gfc_match (" num :");
627 if (gfc_match (" %e ", &cp
->worker_expr
) != MATCH_YES
)
630 else if (gwv
== GOMP_DIM_VECTOR
)
632 /* The 'length' argument is optional. */
633 gfc_match (" length :");
635 if (gfc_match (" %e ", &cp
->vector_expr
) != MATCH_YES
)
639 gfc_fatal_error ("Unexpected OpenACC parallelism.");
641 return gfc_match (" )");
645 gfc_match_oacc_clause_link (const char *str
, gfc_omp_namelist
**list
)
647 gfc_omp_namelist
*head
= NULL
;
648 gfc_omp_namelist
*tail
, *p
;
650 char n
[GFC_MAX_SYMBOL_LEN
+1];
655 old_loc
= gfc_current_locus
;
661 m
= gfc_match (" (");
665 m
= gfc_match_symbol (&sym
, 0);
669 if (sym
->attr
.in_common
)
671 gfc_error_now ("Variable at %C is an element of a COMMON block");
674 gfc_set_sym_referenced (sym
);
675 p
= gfc_get_omp_namelist ();
685 tail
->where
= gfc_current_locus
;
694 m
= gfc_match (" / %n /", n
);
695 if (m
== MATCH_ERROR
)
697 if (m
== MATCH_NO
|| n
[0] == '\0')
700 st
= gfc_find_symtree (gfc_current_ns
->common_root
, n
);
703 gfc_error ("COMMON block /%s/ not found at %C", n
);
707 for (sym
= st
->n
.common
->head
; sym
; sym
= sym
->common_next
)
709 gfc_set_sym_referenced (sym
);
710 p
= gfc_get_omp_namelist ();
719 tail
->where
= gfc_current_locus
;
723 if (gfc_match_char (')') == MATCH_YES
)
725 if (gfc_match_char (',') != MATCH_YES
)
729 if (gfc_match_omp_eos () != MATCH_YES
)
731 gfc_error ("Unexpected junk after !$ACC DECLARE at %C");
736 list
= &(*list
)->next
;
741 gfc_error ("Syntax error in !$ACC DECLARE list at %C");
744 gfc_current_locus
= old_loc
;
748 /* OpenMP 4.5 clauses. */
752 OMP_CLAUSE_FIRSTPRIVATE
,
753 OMP_CLAUSE_LASTPRIVATE
,
754 OMP_CLAUSE_COPYPRIVATE
,
757 OMP_CLAUSE_REDUCTION
,
759 OMP_CLAUSE_NUM_THREADS
,
766 OMP_CLAUSE_MERGEABLE
,
771 OMP_CLAUSE_NOTINBRANCH
,
772 OMP_CLAUSE_PROC_BIND
,
780 OMP_CLAUSE_NUM_TEAMS
,
781 OMP_CLAUSE_THREAD_LIMIT
,
782 OMP_CLAUSE_DIST_SCHEDULE
,
783 OMP_CLAUSE_DEFAULTMAP
,
784 OMP_CLAUSE_GRAINSIZE
,
786 OMP_CLAUSE_IS_DEVICE_PTR
,
789 OMP_CLAUSE_NUM_TASKS
,
793 OMP_CLAUSE_USE_DEVICE_PTR
,
794 OMP_CLAUSE_USE_DEVICE_ADDR
, /* Actually, OpenMP 5.0. */
796 /* This must come last. */
800 /* OpenACC 2.0 specific clauses. */
804 OMP_CLAUSE_NUM_GANGS
,
805 OMP_CLAUSE_NUM_WORKERS
,
806 OMP_CLAUSE_VECTOR_LENGTH
,
811 OMP_CLAUSE_DEVICEPTR
,
816 OMP_CLAUSE_INDEPENDENT
,
817 OMP_CLAUSE_USE_DEVICE
,
818 OMP_CLAUSE_DEVICE_RESIDENT
,
819 OMP_CLAUSE_HOST_SELF
,
824 OMP_CLAUSE_IF_PRESENT
,
826 /* This must come last. */
832 /* Customized bitset for up to 128-bits.
833 The two enums above provide bit numbers to use, and which of the
834 two enums it is determines which of the two mask fields is used.
835 Supported operations are defining a mask, like:
836 #define XXX_CLAUSES \
837 (omp_mask (OMP_CLAUSE_XXX) | OMP_CLAUSE_YYY | OMP_CLAUSE_ZZZ)
838 oring such bitsets together or removing selected bits:
839 (XXX_CLAUSES | YYY_CLAUSES) & ~(omp_mask (OMP_CLAUSE_VVV))
840 and testing individual bits:
841 if (mask & OMP_CLAUSE_UUU) */
844 const uint64_t mask1
;
845 const uint64_t mask2
;
847 inline omp_mask (omp_mask1
);
848 inline omp_mask (omp_mask2
);
849 inline omp_mask (uint64_t, uint64_t);
850 inline omp_mask
operator| (omp_mask1
) const;
851 inline omp_mask
operator| (omp_mask2
) const;
852 inline omp_mask
operator| (omp_mask
) const;
853 inline omp_mask
operator& (const omp_inv_mask
&) const;
854 inline bool operator& (omp_mask1
) const;
855 inline bool operator& (omp_mask2
) const;
856 inline omp_inv_mask
operator~ () const;
859 struct omp_inv_mask
: public omp_mask
{
860 inline omp_inv_mask (const omp_mask
&);
863 omp_mask::omp_mask () : mask1 (0), mask2 (0)
867 omp_mask::omp_mask (omp_mask1 m
) : mask1 (((uint64_t) 1) << m
), mask2 (0)
871 omp_mask::omp_mask (omp_mask2 m
) : mask1 (0), mask2 (((uint64_t) 1) << m
)
875 omp_mask::omp_mask (uint64_t m1
, uint64_t m2
) : mask1 (m1
), mask2 (m2
)
880 omp_mask::operator| (omp_mask1 m
) const
882 return omp_mask (mask1
| (((uint64_t) 1) << m
), mask2
);
886 omp_mask::operator| (omp_mask2 m
) const
888 return omp_mask (mask1
, mask2
| (((uint64_t) 1) << m
));
892 omp_mask::operator| (omp_mask m
) const
894 return omp_mask (mask1
| m
.mask1
, mask2
| m
.mask2
);
898 omp_mask::operator& (const omp_inv_mask
&m
) const
900 return omp_mask (mask1
& ~m
.mask1
, mask2
& ~m
.mask2
);
904 omp_mask::operator& (omp_mask1 m
) const
906 return (mask1
& (((uint64_t) 1) << m
)) != 0;
910 omp_mask::operator& (omp_mask2 m
) const
912 return (mask2
& (((uint64_t) 1) << m
)) != 0;
916 omp_mask::operator~ () const
918 return omp_inv_mask (*this);
921 omp_inv_mask::omp_inv_mask (const omp_mask
&m
) : omp_mask (m
)
925 /* Helper function for OpenACC and OpenMP clauses involving memory
929 gfc_match_omp_map_clause (gfc_omp_namelist
**list
, gfc_omp_map_op map_op
,
932 gfc_omp_namelist
**head
= NULL
;
933 if (gfc_match_omp_variable_list ("", list
, allow_common
, NULL
, &head
, true)
937 for (n
= *head
; n
; n
= n
->next
)
938 n
->u
.map_op
= map_op
;
945 /* Match OpenMP and OpenACC directive clauses. MASK is a bitmask of
946 clauses that are allowed for a particular directive. */
949 gfc_match_omp_clauses (gfc_omp_clauses
**cp
, const omp_mask mask
,
950 bool first
= true, bool needs_space
= true,
951 bool openacc
= false)
953 gfc_omp_clauses
*c
= gfc_get_omp_clauses ();
956 gcc_checking_assert (OMP_MASK1_LAST
<= 64 && OMP_MASK2_LAST
<= 64);
960 if ((first
|| gfc_match_char (',') != MATCH_YES
)
961 && (needs_space
&& gfc_match_space () != MATCH_YES
))
965 gfc_gobble_whitespace ();
967 gfc_omp_namelist
**head
;
968 old_loc
= gfc_current_locus
;
969 char pc
= gfc_peek_ascii_char ();
975 if ((mask
& OMP_CLAUSE_ALIGNED
)
976 && gfc_match_omp_variable_list ("aligned (",
977 &c
->lists
[OMP_LIST_ALIGNED
],
981 gfc_expr
*alignment
= NULL
;
984 if (end_colon
&& gfc_match (" %e )", &alignment
) != MATCH_YES
)
986 gfc_free_omp_namelist (*head
);
987 gfc_current_locus
= old_loc
;
991 for (n
= *head
; n
; n
= n
->next
)
992 if (n
->next
&& alignment
)
993 n
->expr
= gfc_copy_expr (alignment
);
998 if ((mask
& OMP_CLAUSE_ASYNC
)
1000 && gfc_match ("async") == MATCH_YES
)
1003 match m
= gfc_match (" ( %e )", &c
->async_expr
);
1004 if (m
== MATCH_ERROR
)
1006 gfc_current_locus
= old_loc
;
1009 else if (m
== MATCH_NO
)
1012 = gfc_get_constant_expr (BT_INTEGER
,
1013 gfc_default_integer_kind
,
1014 &gfc_current_locus
);
1015 mpz_set_si (c
->async_expr
->value
.integer
, GOMP_ASYNC_NOVAL
);
1020 if ((mask
& OMP_CLAUSE_AUTO
)
1022 && gfc_match ("auto") == MATCH_YES
)
1030 if ((mask
& OMP_CLAUSE_COLLAPSE
)
1033 gfc_expr
*cexpr
= NULL
;
1034 match m
= gfc_match ("collapse ( %e )", &cexpr
);
1039 if (gfc_extract_int (cexpr
, &collapse
, -1))
1041 else if (collapse
<= 0)
1043 gfc_error_now ("COLLAPSE clause argument not"
1044 " constant positive integer at %C");
1047 c
->collapse
= collapse
;
1048 gfc_free_expr (cexpr
);
1052 if ((mask
& OMP_CLAUSE_COPY
)
1053 && gfc_match ("copy ( ") == MATCH_YES
1054 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1055 OMP_MAP_TOFROM
, true))
1057 if (mask
& OMP_CLAUSE_COPYIN
)
1061 if (gfc_match ("copyin ( ") == MATCH_YES
1062 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1066 else if (gfc_match_omp_variable_list ("copyin (",
1067 &c
->lists
[OMP_LIST_COPYIN
],
1071 if ((mask
& OMP_CLAUSE_COPYOUT
)
1072 && gfc_match ("copyout ( ") == MATCH_YES
1073 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1074 OMP_MAP_FROM
, true))
1076 if ((mask
& OMP_CLAUSE_COPYPRIVATE
)
1077 && gfc_match_omp_variable_list ("copyprivate (",
1078 &c
->lists
[OMP_LIST_COPYPRIVATE
],
1081 if ((mask
& OMP_CLAUSE_CREATE
)
1082 && gfc_match ("create ( ") == MATCH_YES
1083 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1084 OMP_MAP_ALLOC
, true))
1088 if ((mask
& OMP_CLAUSE_DEFAULT
)
1089 && c
->default_sharing
== OMP_DEFAULT_UNKNOWN
)
1091 if (gfc_match ("default ( none )") == MATCH_YES
)
1092 c
->default_sharing
= OMP_DEFAULT_NONE
;
1095 if (gfc_match ("default ( present )") == MATCH_YES
)
1096 c
->default_sharing
= OMP_DEFAULT_PRESENT
;
1100 if (gfc_match ("default ( firstprivate )") == MATCH_YES
)
1101 c
->default_sharing
= OMP_DEFAULT_FIRSTPRIVATE
;
1102 else if (gfc_match ("default ( private )") == MATCH_YES
)
1103 c
->default_sharing
= OMP_DEFAULT_PRIVATE
;
1104 else if (gfc_match ("default ( shared )") == MATCH_YES
)
1105 c
->default_sharing
= OMP_DEFAULT_SHARED
;
1107 if (c
->default_sharing
!= OMP_DEFAULT_UNKNOWN
)
1110 if ((mask
& OMP_CLAUSE_DEFAULTMAP
)
1112 && gfc_match ("defaultmap ( tofrom : scalar )") == MATCH_YES
)
1114 c
->defaultmap
= true;
1117 if ((mask
& OMP_CLAUSE_DELETE
)
1118 && gfc_match ("delete ( ") == MATCH_YES
1119 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1120 OMP_MAP_RELEASE
, true))
1122 if ((mask
& OMP_CLAUSE_DEPEND
)
1123 && gfc_match ("depend ( ") == MATCH_YES
)
1125 match m
= MATCH_YES
;
1126 gfc_omp_depend_op depend_op
= OMP_DEPEND_OUT
;
1127 if (gfc_match ("inout") == MATCH_YES
)
1128 depend_op
= OMP_DEPEND_INOUT
;
1129 else if (gfc_match ("in") == MATCH_YES
)
1130 depend_op
= OMP_DEPEND_IN
;
1131 else if (gfc_match ("out") == MATCH_YES
)
1132 depend_op
= OMP_DEPEND_OUT
;
1133 else if (!c
->depend_source
1134 && gfc_match ("source )") == MATCH_YES
)
1136 c
->depend_source
= true;
1139 else if (gfc_match ("sink : ") == MATCH_YES
)
1141 if (gfc_match_omp_depend_sink (&c
->lists
[OMP_LIST_DEPEND
])
1150 && gfc_match_omp_variable_list (" : ",
1151 &c
->lists
[OMP_LIST_DEPEND
],
1155 gfc_omp_namelist
*n
;
1156 for (n
= *head
; n
; n
= n
->next
)
1157 n
->u
.depend_op
= depend_op
;
1161 gfc_current_locus
= old_loc
;
1163 if ((mask
& OMP_CLAUSE_DEVICE
)
1165 && c
->device
== NULL
1166 && gfc_match ("device ( %e )", &c
->device
) == MATCH_YES
)
1168 if ((mask
& OMP_CLAUSE_DEVICE
)
1170 && gfc_match ("device ( ") == MATCH_YES
1171 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1172 OMP_MAP_FORCE_TO
, true))
1174 if ((mask
& OMP_CLAUSE_DEVICEPTR
)
1175 && gfc_match ("deviceptr ( ") == MATCH_YES
1176 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1177 OMP_MAP_FORCE_DEVICEPTR
, false))
1179 if ((mask
& OMP_CLAUSE_DEVICE_RESIDENT
)
1180 && gfc_match_omp_variable_list
1181 ("device_resident (",
1182 &c
->lists
[OMP_LIST_DEVICE_RESIDENT
], true) == MATCH_YES
)
1184 if ((mask
& OMP_CLAUSE_DIST_SCHEDULE
)
1185 && c
->dist_sched_kind
== OMP_SCHED_NONE
1186 && gfc_match ("dist_schedule ( static") == MATCH_YES
)
1189 c
->dist_sched_kind
= OMP_SCHED_STATIC
;
1190 m
= gfc_match (" , %e )", &c
->dist_chunk_size
);
1192 m
= gfc_match_char (')');
1195 c
->dist_sched_kind
= OMP_SCHED_NONE
;
1196 gfc_current_locus
= old_loc
;
1203 if ((mask
& OMP_CLAUSE_FINAL
)
1204 && c
->final_expr
== NULL
1205 && gfc_match ("final ( %e )", &c
->final_expr
) == MATCH_YES
)
1207 if ((mask
& OMP_CLAUSE_FINALIZE
)
1209 && gfc_match ("finalize") == MATCH_YES
)
1215 if ((mask
& OMP_CLAUSE_FIRSTPRIVATE
)
1216 && gfc_match_omp_variable_list ("firstprivate (",
1217 &c
->lists
[OMP_LIST_FIRSTPRIVATE
],
1220 if ((mask
& OMP_CLAUSE_FROM
)
1221 && gfc_match_omp_variable_list ("from (",
1222 &c
->lists
[OMP_LIST_FROM
], false,
1223 NULL
, &head
, true) == MATCH_YES
)
1227 if ((mask
& OMP_CLAUSE_GANG
)
1229 && gfc_match ("gang") == MATCH_YES
)
1232 match m
= match_oacc_clause_gwv (c
, GOMP_DIM_GANG
);
1233 if (m
== MATCH_ERROR
)
1235 gfc_current_locus
= old_loc
;
1238 else if (m
== MATCH_NO
)
1242 if ((mask
& OMP_CLAUSE_GRAINSIZE
)
1243 && c
->grainsize
== NULL
1244 && gfc_match ("grainsize ( %e )", &c
->grainsize
) == MATCH_YES
)
1248 if ((mask
& OMP_CLAUSE_HINT
)
1250 && gfc_match ("hint ( %e )", &c
->hint
) == MATCH_YES
)
1252 if ((mask
& OMP_CLAUSE_HOST_SELF
)
1253 && gfc_match ("host ( ") == MATCH_YES
1254 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1255 OMP_MAP_FORCE_FROM
, true))
1259 if ((mask
& OMP_CLAUSE_IF
)
1260 && c
->if_expr
== NULL
1261 && gfc_match ("if ( ") == MATCH_YES
)
1263 if (gfc_match ("%e )", &c
->if_expr
) == MATCH_YES
)
1267 /* This should match the enum gfc_omp_if_kind order. */
1268 static const char *ifs
[OMP_IF_LAST
] = {
1273 " target data : %e )",
1274 " target update : %e )",
1275 " target enter data : %e )",
1276 " target exit data : %e )" };
1278 for (i
= 0; i
< OMP_IF_LAST
; i
++)
1279 if (c
->if_exprs
[i
] == NULL
1280 && gfc_match (ifs
[i
], &c
->if_exprs
[i
]) == MATCH_YES
)
1282 if (i
< OMP_IF_LAST
)
1285 gfc_current_locus
= old_loc
;
1287 if ((mask
& OMP_CLAUSE_IF_PRESENT
)
1289 && gfc_match ("if_present") == MATCH_YES
)
1291 c
->if_present
= true;
1295 if ((mask
& OMP_CLAUSE_INBRANCH
)
1298 && gfc_match ("inbranch") == MATCH_YES
)
1300 c
->inbranch
= needs_space
= true;
1303 if ((mask
& OMP_CLAUSE_INDEPENDENT
)
1305 && gfc_match ("independent") == MATCH_YES
)
1307 c
->independent
= true;
1311 if ((mask
& OMP_CLAUSE_IS_DEVICE_PTR
)
1312 && gfc_match_omp_variable_list
1314 &c
->lists
[OMP_LIST_IS_DEVICE_PTR
], false) == MATCH_YES
)
1318 if ((mask
& OMP_CLAUSE_LASTPRIVATE
)
1319 && gfc_match_omp_variable_list ("lastprivate (",
1320 &c
->lists
[OMP_LIST_LASTPRIVATE
],
1325 if ((mask
& OMP_CLAUSE_LINEAR
)
1326 && gfc_match ("linear (") == MATCH_YES
)
1328 gfc_omp_linear_op linear_op
= OMP_LINEAR_DEFAULT
;
1329 gfc_expr
*step
= NULL
;
1331 if (gfc_match_omp_variable_list (" ref (",
1332 &c
->lists
[OMP_LIST_LINEAR
],
1335 linear_op
= OMP_LINEAR_REF
;
1336 else if (gfc_match_omp_variable_list (" val (",
1337 &c
->lists
[OMP_LIST_LINEAR
],
1340 linear_op
= OMP_LINEAR_VAL
;
1341 else if (gfc_match_omp_variable_list (" uval (",
1342 &c
->lists
[OMP_LIST_LINEAR
],
1345 linear_op
= OMP_LINEAR_UVAL
;
1346 else if (gfc_match_omp_variable_list ("",
1347 &c
->lists
[OMP_LIST_LINEAR
],
1348 false, &end_colon
, &head
)
1350 linear_op
= OMP_LINEAR_DEFAULT
;
1353 gfc_current_locus
= old_loc
;
1356 if (linear_op
!= OMP_LINEAR_DEFAULT
)
1358 if (gfc_match (" :") == MATCH_YES
)
1360 else if (gfc_match (" )") != MATCH_YES
)
1362 gfc_free_omp_namelist (*head
);
1363 gfc_current_locus
= old_loc
;
1368 if (end_colon
&& gfc_match (" %e )", &step
) != MATCH_YES
)
1370 gfc_free_omp_namelist (*head
);
1371 gfc_current_locus
= old_loc
;
1375 else if (!end_colon
)
1377 step
= gfc_get_constant_expr (BT_INTEGER
,
1378 gfc_default_integer_kind
,
1380 mpz_set_si (step
->value
.integer
, 1);
1382 (*head
)->expr
= step
;
1383 if (linear_op
!= OMP_LINEAR_DEFAULT
)
1384 for (gfc_omp_namelist
*n
= *head
; n
; n
= n
->next
)
1385 n
->u
.linear_op
= linear_op
;
1388 if ((mask
& OMP_CLAUSE_LINK
)
1390 && (gfc_match_oacc_clause_link ("link (",
1391 &c
->lists
[OMP_LIST_LINK
])
1394 else if ((mask
& OMP_CLAUSE_LINK
)
1396 && (gfc_match_omp_to_link ("link (",
1397 &c
->lists
[OMP_LIST_LINK
])
1402 if ((mask
& OMP_CLAUSE_MAP
)
1403 && gfc_match ("map ( ") == MATCH_YES
)
1405 locus old_loc2
= gfc_current_locus
;
1406 bool always
= false;
1407 gfc_omp_map_op map_op
= OMP_MAP_TOFROM
;
1408 if (gfc_match ("always , ") == MATCH_YES
)
1410 if (gfc_match ("alloc : ") == MATCH_YES
)
1411 map_op
= OMP_MAP_ALLOC
;
1412 else if (gfc_match ("tofrom : ") == MATCH_YES
)
1413 map_op
= always
? OMP_MAP_ALWAYS_TOFROM
: OMP_MAP_TOFROM
;
1414 else if (gfc_match ("to : ") == MATCH_YES
)
1415 map_op
= always
? OMP_MAP_ALWAYS_TO
: OMP_MAP_TO
;
1416 else if (gfc_match ("from : ") == MATCH_YES
)
1417 map_op
= always
? OMP_MAP_ALWAYS_FROM
: OMP_MAP_FROM
;
1418 else if (gfc_match ("release : ") == MATCH_YES
)
1419 map_op
= OMP_MAP_RELEASE
;
1420 else if (gfc_match ("delete : ") == MATCH_YES
)
1421 map_op
= OMP_MAP_DELETE
;
1424 gfc_current_locus
= old_loc2
;
1428 if (gfc_match_omp_variable_list ("", &c
->lists
[OMP_LIST_MAP
],
1432 gfc_omp_namelist
*n
;
1433 for (n
= *head
; n
; n
= n
->next
)
1434 n
->u
.map_op
= map_op
;
1438 gfc_current_locus
= old_loc
;
1440 if ((mask
& OMP_CLAUSE_MERGEABLE
) && !c
->mergeable
1441 && gfc_match ("mergeable") == MATCH_YES
)
1443 c
->mergeable
= needs_space
= true;
1448 if ((mask
& OMP_CLAUSE_NOGROUP
)
1450 && gfc_match ("nogroup") == MATCH_YES
)
1452 c
->nogroup
= needs_space
= true;
1455 if ((mask
& OMP_CLAUSE_NOTINBRANCH
)
1458 && gfc_match ("notinbranch") == MATCH_YES
)
1460 c
->notinbranch
= needs_space
= true;
1463 if ((mask
& OMP_CLAUSE_NOWAIT
)
1465 && gfc_match ("nowait") == MATCH_YES
)
1467 c
->nowait
= needs_space
= true;
1470 if ((mask
& OMP_CLAUSE_NUM_GANGS
)
1471 && c
->num_gangs_expr
== NULL
1472 && gfc_match ("num_gangs ( %e )",
1473 &c
->num_gangs_expr
) == MATCH_YES
)
1475 if ((mask
& OMP_CLAUSE_NUM_TASKS
)
1476 && c
->num_tasks
== NULL
1477 && gfc_match ("num_tasks ( %e )", &c
->num_tasks
) == MATCH_YES
)
1479 if ((mask
& OMP_CLAUSE_NUM_TEAMS
)
1480 && c
->num_teams
== NULL
1481 && gfc_match ("num_teams ( %e )", &c
->num_teams
) == MATCH_YES
)
1483 if ((mask
& OMP_CLAUSE_NUM_THREADS
)
1484 && c
->num_threads
== NULL
1485 && (gfc_match ("num_threads ( %e )", &c
->num_threads
)
1488 if ((mask
& OMP_CLAUSE_NUM_WORKERS
)
1489 && c
->num_workers_expr
== NULL
1490 && gfc_match ("num_workers ( %e )",
1491 &c
->num_workers_expr
) == MATCH_YES
)
1495 if ((mask
& OMP_CLAUSE_ORDERED
)
1497 && gfc_match ("ordered") == MATCH_YES
)
1499 gfc_expr
*cexpr
= NULL
;
1500 match m
= gfc_match (" ( %e )", &cexpr
);
1506 if (gfc_extract_int (cexpr
, &ordered
, -1))
1508 else if (ordered
<= 0)
1510 gfc_error_now ("ORDERED clause argument not"
1511 " constant positive integer at %C");
1514 c
->orderedc
= ordered
;
1515 gfc_free_expr (cexpr
);
1524 if ((mask
& OMP_CLAUSE_COPY
)
1525 && gfc_match ("pcopy ( ") == MATCH_YES
1526 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1527 OMP_MAP_TOFROM
, true))
1529 if ((mask
& OMP_CLAUSE_COPYIN
)
1530 && gfc_match ("pcopyin ( ") == MATCH_YES
1531 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1534 if ((mask
& OMP_CLAUSE_COPYOUT
)
1535 && gfc_match ("pcopyout ( ") == MATCH_YES
1536 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1537 OMP_MAP_FROM
, true))
1539 if ((mask
& OMP_CLAUSE_CREATE
)
1540 && gfc_match ("pcreate ( ") == MATCH_YES
1541 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1542 OMP_MAP_ALLOC
, true))
1544 if ((mask
& OMP_CLAUSE_PRESENT
)
1545 && gfc_match ("present ( ") == MATCH_YES
1546 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1547 OMP_MAP_FORCE_PRESENT
, false))
1549 if ((mask
& OMP_CLAUSE_COPY
)
1550 && gfc_match ("present_or_copy ( ") == MATCH_YES
1551 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1552 OMP_MAP_TOFROM
, true))
1554 if ((mask
& OMP_CLAUSE_COPYIN
)
1555 && gfc_match ("present_or_copyin ( ") == MATCH_YES
1556 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1559 if ((mask
& OMP_CLAUSE_COPYOUT
)
1560 && gfc_match ("present_or_copyout ( ") == MATCH_YES
1561 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1562 OMP_MAP_FROM
, true))
1564 if ((mask
& OMP_CLAUSE_CREATE
)
1565 && gfc_match ("present_or_create ( ") == MATCH_YES
1566 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1567 OMP_MAP_ALLOC
, true))
1569 if ((mask
& OMP_CLAUSE_PRIORITY
)
1570 && c
->priority
== NULL
1571 && gfc_match ("priority ( %e )", &c
->priority
) == MATCH_YES
)
1573 if ((mask
& OMP_CLAUSE_PRIVATE
)
1574 && gfc_match_omp_variable_list ("private (",
1575 &c
->lists
[OMP_LIST_PRIVATE
],
1578 if ((mask
& OMP_CLAUSE_PROC_BIND
)
1579 && c
->proc_bind
== OMP_PROC_BIND_UNKNOWN
)
1581 if (gfc_match ("proc_bind ( master )") == MATCH_YES
)
1582 c
->proc_bind
= OMP_PROC_BIND_MASTER
;
1583 else if (gfc_match ("proc_bind ( spread )") == MATCH_YES
)
1584 c
->proc_bind
= OMP_PROC_BIND_SPREAD
;
1585 else if (gfc_match ("proc_bind ( close )") == MATCH_YES
)
1586 c
->proc_bind
= OMP_PROC_BIND_CLOSE
;
1587 if (c
->proc_bind
!= OMP_PROC_BIND_UNKNOWN
)
1592 if ((mask
& OMP_CLAUSE_REDUCTION
)
1593 && gfc_match ("reduction ( ") == MATCH_YES
)
1595 gfc_omp_reduction_op rop
= OMP_REDUCTION_NONE
;
1596 char buffer
[GFC_MAX_SYMBOL_LEN
+ 3];
1597 if (gfc_match_char ('+') == MATCH_YES
)
1598 rop
= OMP_REDUCTION_PLUS
;
1599 else if (gfc_match_char ('*') == MATCH_YES
)
1600 rop
= OMP_REDUCTION_TIMES
;
1601 else if (gfc_match_char ('-') == MATCH_YES
)
1602 rop
= OMP_REDUCTION_MINUS
;
1603 else if (gfc_match (".and.") == MATCH_YES
)
1604 rop
= OMP_REDUCTION_AND
;
1605 else if (gfc_match (".or.") == MATCH_YES
)
1606 rop
= OMP_REDUCTION_OR
;
1607 else if (gfc_match (".eqv.") == MATCH_YES
)
1608 rop
= OMP_REDUCTION_EQV
;
1609 else if (gfc_match (".neqv.") == MATCH_YES
)
1610 rop
= OMP_REDUCTION_NEQV
;
1611 if (rop
!= OMP_REDUCTION_NONE
)
1612 snprintf (buffer
, sizeof buffer
, "operator %s",
1613 gfc_op2string ((gfc_intrinsic_op
) rop
));
1614 else if (gfc_match_defined_op_name (buffer
+ 1, 1) == MATCH_YES
)
1617 strcat (buffer
, ".");
1619 else if (gfc_match_name (buffer
) == MATCH_YES
)
1622 const char *n
= buffer
;
1624 gfc_find_symbol (buffer
, NULL
, 1, &sym
);
1627 if (sym
->attr
.intrinsic
)
1629 else if ((sym
->attr
.flavor
!= FL_UNKNOWN
1630 && sym
->attr
.flavor
!= FL_PROCEDURE
)
1631 || sym
->attr
.external
1632 || sym
->attr
.generic
1636 || sym
->attr
.subroutine
1637 || sym
->attr
.pointer
1639 || sym
->attr
.cray_pointer
1640 || sym
->attr
.cray_pointee
1641 || (sym
->attr
.proc
!= PROC_UNKNOWN
1642 && sym
->attr
.proc
!= PROC_INTRINSIC
)
1643 || sym
->attr
.if_source
!= IFSRC_UNKNOWN
1644 || sym
== sym
->ns
->proc_name
)
1653 rop
= OMP_REDUCTION_NONE
;
1654 else if (strcmp (n
, "max") == 0)
1655 rop
= OMP_REDUCTION_MAX
;
1656 else if (strcmp (n
, "min") == 0)
1657 rop
= OMP_REDUCTION_MIN
;
1658 else if (strcmp (n
, "iand") == 0)
1659 rop
= OMP_REDUCTION_IAND
;
1660 else if (strcmp (n
, "ior") == 0)
1661 rop
= OMP_REDUCTION_IOR
;
1662 else if (strcmp (n
, "ieor") == 0)
1663 rop
= OMP_REDUCTION_IEOR
;
1664 if (rop
!= OMP_REDUCTION_NONE
1666 && ! sym
->attr
.intrinsic
1667 && ! sym
->attr
.use_assoc
1668 && ((sym
->attr
.flavor
== FL_UNKNOWN
1669 && !gfc_add_flavor (&sym
->attr
, FL_PROCEDURE
,
1671 || !gfc_add_intrinsic (&sym
->attr
, NULL
)))
1672 rop
= OMP_REDUCTION_NONE
;
1678 ? gfc_find_omp_udr (gfc_current_ns
, buffer
, NULL
) : NULL
);
1679 gfc_omp_namelist
**head
= NULL
;
1680 if (rop
== OMP_REDUCTION_NONE
&& udr
)
1681 rop
= OMP_REDUCTION_USER
;
1683 if (gfc_match_omp_variable_list (" :",
1684 &c
->lists
[OMP_LIST_REDUCTION
],
1686 openacc
) == MATCH_YES
)
1688 gfc_omp_namelist
*n
;
1689 if (rop
== OMP_REDUCTION_NONE
)
1693 gfc_error_now ("!$OMP DECLARE REDUCTION %s not found "
1694 "at %L", buffer
, &old_loc
);
1695 gfc_free_omp_namelist (n
);
1698 for (n
= *head
; n
; n
= n
->next
)
1700 n
->u
.reduction_op
= rop
;
1703 n
->udr
= gfc_get_omp_namelist_udr ();
1710 gfc_current_locus
= old_loc
;
1714 if ((mask
& OMP_CLAUSE_SAFELEN
)
1715 && c
->safelen_expr
== NULL
1716 && gfc_match ("safelen ( %e )", &c
->safelen_expr
) == MATCH_YES
)
1718 if ((mask
& OMP_CLAUSE_SCHEDULE
)
1719 && c
->sched_kind
== OMP_SCHED_NONE
1720 && gfc_match ("schedule ( ") == MATCH_YES
)
1723 locus old_loc2
= gfc_current_locus
;
1726 if (gfc_match ("simd") == MATCH_YES
)
1728 c
->sched_simd
= true;
1731 else if (gfc_match ("monotonic") == MATCH_YES
)
1733 c
->sched_monotonic
= true;
1736 else if (gfc_match ("nonmonotonic") == MATCH_YES
)
1738 c
->sched_nonmonotonic
= true;
1744 gfc_current_locus
= old_loc2
;
1748 && gfc_match (" , ") == MATCH_YES
)
1750 else if (gfc_match (" : ") == MATCH_YES
)
1752 gfc_current_locus
= old_loc2
;
1756 if (gfc_match ("static") == MATCH_YES
)
1757 c
->sched_kind
= OMP_SCHED_STATIC
;
1758 else if (gfc_match ("dynamic") == MATCH_YES
)
1759 c
->sched_kind
= OMP_SCHED_DYNAMIC
;
1760 else if (gfc_match ("guided") == MATCH_YES
)
1761 c
->sched_kind
= OMP_SCHED_GUIDED
;
1762 else if (gfc_match ("runtime") == MATCH_YES
)
1763 c
->sched_kind
= OMP_SCHED_RUNTIME
;
1764 else if (gfc_match ("auto") == MATCH_YES
)
1765 c
->sched_kind
= OMP_SCHED_AUTO
;
1766 if (c
->sched_kind
!= OMP_SCHED_NONE
)
1769 if (c
->sched_kind
!= OMP_SCHED_RUNTIME
1770 && c
->sched_kind
!= OMP_SCHED_AUTO
)
1771 m
= gfc_match (" , %e )", &c
->chunk_size
);
1773 m
= gfc_match_char (')');
1775 c
->sched_kind
= OMP_SCHED_NONE
;
1777 if (c
->sched_kind
!= OMP_SCHED_NONE
)
1780 gfc_current_locus
= old_loc
;
1782 if ((mask
& OMP_CLAUSE_HOST_SELF
)
1783 && gfc_match ("self ( ") == MATCH_YES
1784 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1785 OMP_MAP_FORCE_FROM
, true))
1787 if ((mask
& OMP_CLAUSE_SEQ
)
1789 && gfc_match ("seq") == MATCH_YES
)
1795 if ((mask
& OMP_CLAUSE_SHARED
)
1796 && gfc_match_omp_variable_list ("shared (",
1797 &c
->lists
[OMP_LIST_SHARED
],
1800 if ((mask
& OMP_CLAUSE_SIMDLEN
)
1801 && c
->simdlen_expr
== NULL
1802 && gfc_match ("simdlen ( %e )", &c
->simdlen_expr
) == MATCH_YES
)
1804 if ((mask
& OMP_CLAUSE_SIMD
)
1806 && gfc_match ("simd") == MATCH_YES
)
1808 c
->simd
= needs_space
= true;
1813 if ((mask
& OMP_CLAUSE_THREAD_LIMIT
)
1814 && c
->thread_limit
== NULL
1815 && gfc_match ("thread_limit ( %e )",
1816 &c
->thread_limit
) == MATCH_YES
)
1818 if ((mask
& OMP_CLAUSE_THREADS
)
1820 && gfc_match ("threads") == MATCH_YES
)
1822 c
->threads
= needs_space
= true;
1825 if ((mask
& OMP_CLAUSE_TILE
)
1827 && match_oacc_expr_list ("tile (", &c
->tile_list
,
1830 if ((mask
& OMP_CLAUSE_TO
) && (mask
& OMP_CLAUSE_LINK
))
1832 if (gfc_match_omp_to_link ("to (", &c
->lists
[OMP_LIST_TO
])
1836 else if ((mask
& OMP_CLAUSE_TO
)
1837 && gfc_match_omp_variable_list ("to (",
1838 &c
->lists
[OMP_LIST_TO
], false,
1839 NULL
, &head
, true) == MATCH_YES
)
1843 if ((mask
& OMP_CLAUSE_UNIFORM
)
1844 && gfc_match_omp_variable_list ("uniform (",
1845 &c
->lists
[OMP_LIST_UNIFORM
],
1846 false) == MATCH_YES
)
1848 if ((mask
& OMP_CLAUSE_UNTIED
)
1850 && gfc_match ("untied") == MATCH_YES
)
1852 c
->untied
= needs_space
= true;
1855 if ((mask
& OMP_CLAUSE_USE_DEVICE
)
1856 && gfc_match_omp_variable_list ("use_device (",
1857 &c
->lists
[OMP_LIST_USE_DEVICE
],
1860 if ((mask
& OMP_CLAUSE_USE_DEVICE_PTR
)
1861 && gfc_match_omp_variable_list
1862 ("use_device_ptr (",
1863 &c
->lists
[OMP_LIST_USE_DEVICE_PTR
], false) == MATCH_YES
)
1865 if ((mask
& OMP_CLAUSE_USE_DEVICE_ADDR
)
1866 && gfc_match_omp_variable_list
1867 ("use_device_addr (",
1868 &c
->lists
[OMP_LIST_USE_DEVICE_ADDR
], false) == MATCH_YES
)
1872 /* VECTOR_LENGTH must be matched before VECTOR, because the latter
1873 doesn't unconditionally match '('. */
1874 if ((mask
& OMP_CLAUSE_VECTOR_LENGTH
)
1875 && c
->vector_length_expr
== NULL
1876 && (gfc_match ("vector_length ( %e )", &c
->vector_length_expr
)
1879 if ((mask
& OMP_CLAUSE_VECTOR
)
1881 && gfc_match ("vector") == MATCH_YES
)
1884 match m
= match_oacc_clause_gwv (c
, GOMP_DIM_VECTOR
);
1885 if (m
== MATCH_ERROR
)
1887 gfc_current_locus
= old_loc
;
1896 if ((mask
& OMP_CLAUSE_WAIT
)
1897 && gfc_match ("wait") == MATCH_YES
)
1899 match m
= match_oacc_expr_list (" (", &c
->wait_list
, false);
1900 if (m
== MATCH_ERROR
)
1902 gfc_current_locus
= old_loc
;
1905 else if (m
== MATCH_NO
)
1908 = gfc_get_constant_expr (BT_INTEGER
,
1909 gfc_default_integer_kind
,
1910 &gfc_current_locus
);
1911 mpz_set_si (expr
->value
.integer
, GOMP_ASYNC_NOVAL
);
1912 gfc_expr_list
**expr_list
= &c
->wait_list
;
1914 expr_list
= &(*expr_list
)->next
;
1915 *expr_list
= gfc_get_expr_list ();
1916 (*expr_list
)->expr
= expr
;
1921 if ((mask
& OMP_CLAUSE_WORKER
)
1923 && gfc_match ("worker") == MATCH_YES
)
1926 match m
= match_oacc_clause_gwv (c
, GOMP_DIM_WORKER
);
1927 if (m
== MATCH_ERROR
)
1929 gfc_current_locus
= old_loc
;
1932 else if (m
== MATCH_NO
)
1941 if (gfc_match_omp_eos () != MATCH_YES
)
1943 if (!gfc_error_flag_test ())
1944 gfc_error ("Failed to match clause at %C");
1945 gfc_free_omp_clauses (c
);
1954 #define OACC_PARALLEL_CLAUSES \
1955 (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_NUM_GANGS \
1956 | OMP_CLAUSE_NUM_WORKERS | OMP_CLAUSE_VECTOR_LENGTH | OMP_CLAUSE_REDUCTION \
1957 | OMP_CLAUSE_COPY | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT \
1958 | OMP_CLAUSE_CREATE | OMP_CLAUSE_PRESENT | OMP_CLAUSE_DEVICEPTR \
1959 | OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_DEFAULT \
1961 #define OACC_KERNELS_CLAUSES \
1962 (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_NUM_GANGS \
1963 | OMP_CLAUSE_NUM_WORKERS | OMP_CLAUSE_VECTOR_LENGTH | OMP_CLAUSE_DEVICEPTR \
1964 | OMP_CLAUSE_COPY | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT \
1965 | OMP_CLAUSE_CREATE | OMP_CLAUSE_PRESENT | OMP_CLAUSE_DEFAULT \
1967 #define OACC_DATA_CLAUSES \
1968 (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_DEVICEPTR | OMP_CLAUSE_COPY \
1969 | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT | OMP_CLAUSE_CREATE \
1970 | OMP_CLAUSE_PRESENT)
1971 #define OACC_LOOP_CLAUSES \
1972 (omp_mask (OMP_CLAUSE_COLLAPSE) | OMP_CLAUSE_GANG | OMP_CLAUSE_WORKER \
1973 | OMP_CLAUSE_VECTOR | OMP_CLAUSE_SEQ | OMP_CLAUSE_INDEPENDENT \
1974 | OMP_CLAUSE_PRIVATE | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_AUTO \
1976 #define OACC_PARALLEL_LOOP_CLAUSES \
1977 (OACC_LOOP_CLAUSES | OACC_PARALLEL_CLAUSES)
1978 #define OACC_KERNELS_LOOP_CLAUSES \
1979 (OACC_LOOP_CLAUSES | OACC_KERNELS_CLAUSES)
1980 #define OACC_HOST_DATA_CLAUSES omp_mask (OMP_CLAUSE_USE_DEVICE)
1981 #define OACC_DECLARE_CLAUSES \
1982 (omp_mask (OMP_CLAUSE_COPY) | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT \
1983 | OMP_CLAUSE_CREATE | OMP_CLAUSE_DEVICEPTR | OMP_CLAUSE_DEVICE_RESIDENT \
1984 | OMP_CLAUSE_PRESENT \
1986 #define OACC_UPDATE_CLAUSES \
1987 (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_HOST_SELF \
1988 | OMP_CLAUSE_DEVICE | OMP_CLAUSE_WAIT | OMP_CLAUSE_IF_PRESENT)
1989 #define OACC_ENTER_DATA_CLAUSES \
1990 (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_WAIT \
1991 | OMP_CLAUSE_COPYIN | OMP_CLAUSE_CREATE)
1992 #define OACC_EXIT_DATA_CLAUSES \
1993 (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_WAIT \
1994 | OMP_CLAUSE_COPYOUT | OMP_CLAUSE_DELETE | OMP_CLAUSE_FINALIZE)
1995 #define OACC_WAIT_CLAUSES \
1996 omp_mask (OMP_CLAUSE_ASYNC)
1997 #define OACC_ROUTINE_CLAUSES \
1998 (omp_mask (OMP_CLAUSE_GANG) | OMP_CLAUSE_WORKER | OMP_CLAUSE_VECTOR \
2003 match_acc (gfc_exec_op op
, const omp_mask mask
)
2006 if (gfc_match_omp_clauses (&c
, mask
, false, false, true) != MATCH_YES
)
2009 new_st
.ext
.omp_clauses
= c
;
2014 gfc_match_oacc_parallel_loop (void)
2016 return match_acc (EXEC_OACC_PARALLEL_LOOP
, OACC_PARALLEL_LOOP_CLAUSES
);
2021 gfc_match_oacc_parallel (void)
2023 return match_acc (EXEC_OACC_PARALLEL
, OACC_PARALLEL_CLAUSES
);
2028 gfc_match_oacc_kernels_loop (void)
2030 return match_acc (EXEC_OACC_KERNELS_LOOP
, OACC_KERNELS_LOOP_CLAUSES
);
2035 gfc_match_oacc_kernels (void)
2037 return match_acc (EXEC_OACC_KERNELS
, OACC_KERNELS_CLAUSES
);
2042 gfc_match_oacc_data (void)
2044 return match_acc (EXEC_OACC_DATA
, OACC_DATA_CLAUSES
);
2049 gfc_match_oacc_host_data (void)
2051 return match_acc (EXEC_OACC_HOST_DATA
, OACC_HOST_DATA_CLAUSES
);
2056 gfc_match_oacc_loop (void)
2058 return match_acc (EXEC_OACC_LOOP
, OACC_LOOP_CLAUSES
);
2063 gfc_match_oacc_declare (void)
2066 gfc_omp_namelist
*n
;
2067 gfc_namespace
*ns
= gfc_current_ns
;
2068 gfc_oacc_declare
*new_oc
;
2069 bool module_var
= false;
2070 locus where
= gfc_current_locus
;
2072 if (gfc_match_omp_clauses (&c
, OACC_DECLARE_CLAUSES
, false, false, true)
2076 for (n
= c
->lists
[OMP_LIST_DEVICE_RESIDENT
]; n
!= NULL
; n
= n
->next
)
2077 n
->sym
->attr
.oacc_declare_device_resident
= 1;
2079 for (n
= c
->lists
[OMP_LIST_LINK
]; n
!= NULL
; n
= n
->next
)
2080 n
->sym
->attr
.oacc_declare_link
= 1;
2082 for (n
= c
->lists
[OMP_LIST_MAP
]; n
!= NULL
; n
= n
->next
)
2084 gfc_symbol
*s
= n
->sym
;
2086 if (s
->ns
->proc_name
&& s
->ns
->proc_name
->attr
.proc
== PROC_MODULE
)
2088 if (n
->u
.map_op
!= OMP_MAP_ALLOC
&& n
->u
.map_op
!= OMP_MAP_TO
)
2090 gfc_error ("Invalid clause in module with !$ACC DECLARE at %L",
2098 if (s
->attr
.use_assoc
)
2100 gfc_error ("Variable is USE-associated with !$ACC DECLARE at %L",
2105 if ((s
->attr
.dimension
|| s
->attr
.codimension
)
2106 && s
->attr
.dummy
&& s
->as
->type
!= AS_EXPLICIT
)
2108 gfc_error ("Assumed-size dummy array with !$ACC DECLARE at %L",
2113 switch (n
->u
.map_op
)
2115 case OMP_MAP_FORCE_ALLOC
:
2117 s
->attr
.oacc_declare_create
= 1;
2120 case OMP_MAP_FORCE_TO
:
2122 s
->attr
.oacc_declare_copyin
= 1;
2125 case OMP_MAP_FORCE_DEVICEPTR
:
2126 s
->attr
.oacc_declare_deviceptr
= 1;
2134 new_oc
= gfc_get_oacc_declare ();
2135 new_oc
->next
= ns
->oacc_declare
;
2136 new_oc
->module_var
= module_var
;
2137 new_oc
->clauses
= c
;
2138 new_oc
->loc
= gfc_current_locus
;
2139 ns
->oacc_declare
= new_oc
;
2146 gfc_match_oacc_update (void)
2149 locus here
= gfc_current_locus
;
2151 if (gfc_match_omp_clauses (&c
, OACC_UPDATE_CLAUSES
, false, false, true)
2155 if (!c
->lists
[OMP_LIST_MAP
])
2157 gfc_error ("%<acc update%> must contain at least one "
2158 "%<device%> or %<host%> or %<self%> clause at %L", &here
);
2162 new_st
.op
= EXEC_OACC_UPDATE
;
2163 new_st
.ext
.omp_clauses
= c
;
2169 gfc_match_oacc_enter_data (void)
2171 return match_acc (EXEC_OACC_ENTER_DATA
, OACC_ENTER_DATA_CLAUSES
);
2176 gfc_match_oacc_exit_data (void)
2178 return match_acc (EXEC_OACC_EXIT_DATA
, OACC_EXIT_DATA_CLAUSES
);
2183 gfc_match_oacc_wait (void)
2185 gfc_omp_clauses
*c
= gfc_get_omp_clauses ();
2186 gfc_expr_list
*wait_list
= NULL
, *el
;
2190 m
= match_oacc_expr_list (" (", &wait_list
, true);
2191 if (m
== MATCH_ERROR
)
2193 else if (m
== MATCH_YES
)
2196 if (gfc_match_omp_clauses (&c
, OACC_WAIT_CLAUSES
, space
, space
, true)
2201 for (el
= wait_list
; el
; el
= el
->next
)
2203 if (el
->expr
== NULL
)
2205 gfc_error ("Invalid argument to !$ACC WAIT at %C");
2209 if (!gfc_resolve_expr (el
->expr
)
2210 || el
->expr
->ts
.type
!= BT_INTEGER
|| el
->expr
->rank
!= 0)
2212 gfc_error ("WAIT clause at %L requires a scalar INTEGER expression",
2218 c
->wait_list
= wait_list
;
2219 new_st
.op
= EXEC_OACC_WAIT
;
2220 new_st
.ext
.omp_clauses
= c
;
2226 gfc_match_oacc_cache (void)
2228 gfc_omp_clauses
*c
= gfc_get_omp_clauses ();
2229 /* The OpenACC cache directive explicitly only allows "array elements or
2230 subarrays", which we're currently not checking here. Either check this
2231 after the call of gfc_match_omp_variable_list, or add something like a
2232 only_sections variant next to its allow_sections parameter. */
2233 match m
= gfc_match_omp_variable_list (" (",
2234 &c
->lists
[OMP_LIST_CACHE
], true,
2238 gfc_free_omp_clauses(c
);
2242 if (gfc_current_state() != COMP_DO
2243 && gfc_current_state() != COMP_DO_CONCURRENT
)
2245 gfc_error ("ACC CACHE directive must be inside of loop %C");
2246 gfc_free_omp_clauses(c
);
2250 new_st
.op
= EXEC_OACC_CACHE
;
2251 new_st
.ext
.omp_clauses
= c
;
2255 /* Determine the OpenACC 'routine' directive's level of parallelism. */
2257 static oacc_routine_lop
2258 gfc_oacc_routine_lop (gfc_omp_clauses
*clauses
)
2260 oacc_routine_lop ret
= OACC_ROUTINE_LOP_SEQ
;
2264 unsigned n_lop_clauses
= 0;
2269 ret
= OACC_ROUTINE_LOP_GANG
;
2271 if (clauses
->worker
)
2274 ret
= OACC_ROUTINE_LOP_WORKER
;
2276 if (clauses
->vector
)
2279 ret
= OACC_ROUTINE_LOP_VECTOR
;
2284 ret
= OACC_ROUTINE_LOP_SEQ
;
2287 if (n_lop_clauses
> 1)
2288 ret
= OACC_ROUTINE_LOP_ERROR
;
2295 gfc_match_oacc_routine (void)
2299 gfc_intrinsic_sym
*isym
= NULL
;
2300 gfc_symbol
*sym
= NULL
;
2301 gfc_omp_clauses
*c
= NULL
;
2302 gfc_oacc_routine_name
*n
= NULL
;
2303 oacc_routine_lop lop
= OACC_ROUTINE_LOP_NONE
;
2305 old_loc
= gfc_current_locus
;
2307 m
= gfc_match (" (");
2309 if (gfc_current_ns
->proc_name
2310 && gfc_current_ns
->proc_name
->attr
.if_source
== IFSRC_IFBODY
2313 gfc_error ("Only the !$ACC ROUTINE form without "
2314 "list is allowed in interface block at %C");
2320 char buffer
[GFC_MAX_SYMBOL_LEN
+ 1];
2322 m
= gfc_match_name (buffer
);
2325 gfc_symtree
*st
= NULL
;
2327 /* First look for an intrinsic symbol. */
2328 isym
= gfc_find_function (buffer
);
2330 isym
= gfc_find_subroutine (buffer
);
2331 /* If no intrinsic symbol found, search the current namespace. */
2333 st
= gfc_find_symtree (gfc_current_ns
->sym_root
, buffer
);
2337 /* If the name in a 'routine' directive refers to the containing
2338 subroutine or function, then make sure that we'll later handle
2339 this accordingly. */
2340 if (gfc_current_ns
->proc_name
!= NULL
2341 && strcmp (sym
->name
, gfc_current_ns
->proc_name
->name
) == 0)
2345 if (isym
== NULL
&& st
== NULL
)
2347 gfc_error ("Invalid NAME %qs in !$ACC ROUTINE ( NAME ) at %C",
2349 gfc_current_locus
= old_loc
;
2355 gfc_error ("Syntax error in !$ACC ROUTINE ( NAME ) at %C");
2356 gfc_current_locus
= old_loc
;
2360 if (gfc_match_char (')') != MATCH_YES
)
2362 gfc_error ("Syntax error in !$ACC ROUTINE ( NAME ) at %C, expecting"
2364 gfc_current_locus
= old_loc
;
2369 if (gfc_match_omp_eos () != MATCH_YES
2370 && (gfc_match_omp_clauses (&c
, OACC_ROUTINE_CLAUSES
, false, false, true)
2374 lop
= gfc_oacc_routine_lop (c
);
2375 if (lop
== OACC_ROUTINE_LOP_ERROR
)
2377 gfc_error ("Multiple loop axes specified for routine at %C");
2383 /* Diagnose any OpenACC 'routine' directive that doesn't match the
2384 (implicit) one with a 'seq' clause. */
2385 if (c
&& (c
->gang
|| c
->worker
|| c
->vector
))
2387 gfc_error ("Intrinsic symbol specified in !$ACC ROUTINE ( NAME )"
2388 " at %C marked with incompatible GANG, WORKER, or VECTOR"
2393 else if (sym
!= NULL
)
2397 /* For a repeated OpenACC 'routine' directive, diagnose if it doesn't
2398 match the first one. */
2399 for (gfc_oacc_routine_name
*n_p
= gfc_current_ns
->oacc_routine_names
;
2402 if (n_p
->sym
== sym
)
2405 if (lop
!= gfc_oacc_routine_lop (n_p
->clauses
))
2407 gfc_error ("!$ACC ROUTINE already applied at %C");
2414 sym
->attr
.oacc_routine_lop
= lop
;
2416 n
= gfc_get_oacc_routine_name ();
2419 n
->next
= gfc_current_ns
->oacc_routine_names
;
2421 gfc_current_ns
->oacc_routine_names
= n
;
2424 else if (gfc_current_ns
->proc_name
)
2426 /* For a repeated OpenACC 'routine' directive, diagnose if it doesn't
2427 match the first one. */
2428 oacc_routine_lop lop_p
= gfc_current_ns
->proc_name
->attr
.oacc_routine_lop
;
2429 if (lop_p
!= OACC_ROUTINE_LOP_NONE
2432 gfc_error ("!$ACC ROUTINE already applied at %C");
2436 if (!gfc_add_omp_declare_target (&gfc_current_ns
->proc_name
->attr
,
2437 gfc_current_ns
->proc_name
->name
,
2440 gfc_current_ns
->proc_name
->attr
.oacc_routine_lop
= lop
;
2443 /* Something has gone wrong, possibly a syntax error. */
2448 else if (gfc_current_ns
->oacc_routine
)
2449 gfc_current_ns
->oacc_routine_clauses
= c
;
2451 new_st
.op
= EXEC_OACC_ROUTINE
;
2452 new_st
.ext
.omp_clauses
= c
;
2456 gfc_current_locus
= old_loc
;
2461 #define OMP_PARALLEL_CLAUSES \
2462 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \
2463 | OMP_CLAUSE_SHARED | OMP_CLAUSE_COPYIN | OMP_CLAUSE_REDUCTION \
2464 | OMP_CLAUSE_IF | OMP_CLAUSE_NUM_THREADS | OMP_CLAUSE_DEFAULT \
2465 | OMP_CLAUSE_PROC_BIND)
2466 #define OMP_DECLARE_SIMD_CLAUSES \
2467 (omp_mask (OMP_CLAUSE_SIMDLEN) | OMP_CLAUSE_LINEAR \
2468 | OMP_CLAUSE_UNIFORM | OMP_CLAUSE_ALIGNED | OMP_CLAUSE_INBRANCH \
2469 | OMP_CLAUSE_NOTINBRANCH)
2470 #define OMP_DO_CLAUSES \
2471 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \
2472 | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION \
2473 | OMP_CLAUSE_SCHEDULE | OMP_CLAUSE_ORDERED | OMP_CLAUSE_COLLAPSE \
2474 | OMP_CLAUSE_LINEAR)
2475 #define OMP_SECTIONS_CLAUSES \
2476 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \
2477 | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION)
2478 #define OMP_SIMD_CLAUSES \
2479 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_LASTPRIVATE \
2480 | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_SAFELEN \
2481 | OMP_CLAUSE_LINEAR | OMP_CLAUSE_ALIGNED | OMP_CLAUSE_SIMDLEN)
2482 #define OMP_TASK_CLAUSES \
2483 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \
2484 | OMP_CLAUSE_SHARED | OMP_CLAUSE_IF | OMP_CLAUSE_DEFAULT \
2485 | OMP_CLAUSE_UNTIED | OMP_CLAUSE_FINAL | OMP_CLAUSE_MERGEABLE \
2486 | OMP_CLAUSE_DEPEND | OMP_CLAUSE_PRIORITY)
2487 #define OMP_TASKLOOP_CLAUSES \
2488 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \
2489 | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_SHARED | OMP_CLAUSE_IF \
2490 | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_UNTIED | OMP_CLAUSE_FINAL \
2491 | OMP_CLAUSE_MERGEABLE | OMP_CLAUSE_PRIORITY | OMP_CLAUSE_GRAINSIZE \
2492 | OMP_CLAUSE_NUM_TASKS | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_NOGROUP)
2493 #define OMP_TARGET_CLAUSES \
2494 (omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF \
2495 | OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT | OMP_CLAUSE_PRIVATE \
2496 | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_DEFAULTMAP \
2497 | OMP_CLAUSE_IS_DEVICE_PTR)
2498 #define OMP_TARGET_DATA_CLAUSES \
2499 (omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF \
2500 | OMP_CLAUSE_USE_DEVICE_PTR | OMP_CLAUSE_USE_DEVICE_ADDR)
2501 #define OMP_TARGET_ENTER_DATA_CLAUSES \
2502 (omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF \
2503 | OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT)
2504 #define OMP_TARGET_EXIT_DATA_CLAUSES \
2505 (omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF \
2506 | OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT)
2507 #define OMP_TARGET_UPDATE_CLAUSES \
2508 (omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_IF | OMP_CLAUSE_TO \
2509 | OMP_CLAUSE_FROM | OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT)
2510 #define OMP_TEAMS_CLAUSES \
2511 (omp_mask (OMP_CLAUSE_NUM_TEAMS) | OMP_CLAUSE_THREAD_LIMIT \
2512 | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE \
2513 | OMP_CLAUSE_SHARED | OMP_CLAUSE_REDUCTION)
2514 #define OMP_DISTRIBUTE_CLAUSES \
2515 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \
2516 | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_DIST_SCHEDULE)
2517 #define OMP_SINGLE_CLAUSES \
2518 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE)
2519 #define OMP_ORDERED_CLAUSES \
2520 (omp_mask (OMP_CLAUSE_THREADS) | OMP_CLAUSE_SIMD)
2521 #define OMP_DECLARE_TARGET_CLAUSES \
2522 (omp_mask (OMP_CLAUSE_TO) | OMP_CLAUSE_LINK)
2526 match_omp (gfc_exec_op op
, const omp_mask mask
)
2529 if (gfc_match_omp_clauses (&c
, mask
) != MATCH_YES
)
2532 new_st
.ext
.omp_clauses
= c
;
2538 gfc_match_omp_critical (void)
2540 char n
[GFC_MAX_SYMBOL_LEN
+1];
2541 gfc_omp_clauses
*c
= NULL
;
2543 if (gfc_match (" ( %n )", n
) != MATCH_YES
)
2546 if (gfc_match_omp_eos () != MATCH_YES
)
2548 gfc_error ("Unexpected junk after $OMP CRITICAL statement at %C");
2552 else if (gfc_match_omp_clauses (&c
, omp_mask (OMP_CLAUSE_HINT
)) != MATCH_YES
)
2555 new_st
.op
= EXEC_OMP_CRITICAL
;
2556 new_st
.ext
.omp_clauses
= c
;
2558 c
->critical_name
= xstrdup (n
);
2564 gfc_match_omp_end_critical (void)
2566 char n
[GFC_MAX_SYMBOL_LEN
+1];
2568 if (gfc_match (" ( %n )", n
) != MATCH_YES
)
2570 if (gfc_match_omp_eos () != MATCH_YES
)
2572 gfc_error ("Unexpected junk after $OMP CRITICAL statement at %C");
2576 new_st
.op
= EXEC_OMP_END_CRITICAL
;
2577 new_st
.ext
.omp_name
= n
[0] ? xstrdup (n
) : NULL
;
2583 gfc_match_omp_distribute (void)
2585 return match_omp (EXEC_OMP_DISTRIBUTE
, OMP_DISTRIBUTE_CLAUSES
);
2590 gfc_match_omp_distribute_parallel_do (void)
2592 return match_omp (EXEC_OMP_DISTRIBUTE_PARALLEL_DO
,
2593 (OMP_DISTRIBUTE_CLAUSES
| OMP_PARALLEL_CLAUSES
2595 & ~(omp_mask (OMP_CLAUSE_ORDERED
))
2596 & ~(omp_mask (OMP_CLAUSE_LINEAR
)));
2601 gfc_match_omp_distribute_parallel_do_simd (void)
2603 return match_omp (EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD
,
2604 (OMP_DISTRIBUTE_CLAUSES
| OMP_PARALLEL_CLAUSES
2605 | OMP_DO_CLAUSES
| OMP_SIMD_CLAUSES
)
2606 & ~(omp_mask (OMP_CLAUSE_ORDERED
)));
2611 gfc_match_omp_distribute_simd (void)
2613 return match_omp (EXEC_OMP_DISTRIBUTE_SIMD
,
2614 OMP_DISTRIBUTE_CLAUSES
| OMP_SIMD_CLAUSES
);
2619 gfc_match_omp_do (void)
2621 return match_omp (EXEC_OMP_DO
, OMP_DO_CLAUSES
);
2626 gfc_match_omp_do_simd (void)
2628 return match_omp (EXEC_OMP_DO_SIMD
, OMP_DO_CLAUSES
| OMP_SIMD_CLAUSES
);
2633 gfc_match_omp_flush (void)
2635 gfc_omp_namelist
*list
= NULL
;
2636 gfc_match_omp_variable_list (" (", &list
, true);
2637 if (gfc_match_omp_eos () != MATCH_YES
)
2639 gfc_error ("Unexpected junk after $OMP FLUSH statement at %C");
2640 gfc_free_omp_namelist (list
);
2643 new_st
.op
= EXEC_OMP_FLUSH
;
2644 new_st
.ext
.omp_namelist
= list
;
2650 gfc_match_omp_declare_simd (void)
2652 locus where
= gfc_current_locus
;
2653 gfc_symbol
*proc_name
;
2655 gfc_omp_declare_simd
*ods
;
2656 bool needs_space
= false;
2658 switch (gfc_match (" ( %s ) ", &proc_name
))
2660 case MATCH_YES
: break;
2661 case MATCH_NO
: proc_name
= NULL
; needs_space
= true; break;
2662 case MATCH_ERROR
: return MATCH_ERROR
;
2665 if (gfc_match_omp_clauses (&c
, OMP_DECLARE_SIMD_CLAUSES
, true,
2666 needs_space
) != MATCH_YES
)
2669 if (gfc_current_ns
->is_block_data
)
2671 gfc_free_omp_clauses (c
);
2675 ods
= gfc_get_omp_declare_simd ();
2677 ods
->proc_name
= proc_name
;
2679 ods
->next
= gfc_current_ns
->omp_declare_simd
;
2680 gfc_current_ns
->omp_declare_simd
= ods
;
2686 match_udr_expr (gfc_symtree
*omp_sym1
, gfc_symtree
*omp_sym2
)
2689 locus old_loc
= gfc_current_locus
;
2690 char sname
[GFC_MAX_SYMBOL_LEN
+ 1];
2692 gfc_namespace
*ns
= gfc_current_ns
;
2693 gfc_expr
*lvalue
= NULL
, *rvalue
= NULL
;
2695 gfc_actual_arglist
*arglist
;
2697 m
= gfc_match (" %v =", &lvalue
);
2699 gfc_current_locus
= old_loc
;
2702 m
= gfc_match (" %e )", &rvalue
);
2705 ns
->code
= gfc_get_code (EXEC_ASSIGN
);
2706 ns
->code
->expr1
= lvalue
;
2707 ns
->code
->expr2
= rvalue
;
2708 ns
->code
->loc
= old_loc
;
2712 gfc_current_locus
= old_loc
;
2713 gfc_free_expr (lvalue
);
2716 m
= gfc_match (" %n", sname
);
2720 if (strcmp (sname
, omp_sym1
->name
) == 0
2721 || strcmp (sname
, omp_sym2
->name
) == 0)
2724 gfc_current_ns
= ns
->parent
;
2725 if (gfc_get_ha_sym_tree (sname
, &st
))
2729 if (sym
->attr
.flavor
!= FL_PROCEDURE
2730 && sym
->attr
.flavor
!= FL_UNKNOWN
)
2733 if (!sym
->attr
.generic
2734 && !sym
->attr
.subroutine
2735 && !sym
->attr
.function
)
2737 if (!(sym
->attr
.external
&& !sym
->attr
.referenced
))
2739 /* ...create a symbol in this scope... */
2740 if (sym
->ns
!= gfc_current_ns
2741 && gfc_get_sym_tree (sname
, NULL
, &st
, false) == 1)
2744 if (sym
!= st
->n
.sym
)
2748 /* ...and then to try to make the symbol into a subroutine. */
2749 if (!gfc_add_subroutine (&sym
->attr
, sym
->name
, NULL
))
2753 gfc_set_sym_referenced (sym
);
2754 gfc_gobble_whitespace ();
2755 if (gfc_peek_ascii_char () != '(')
2758 gfc_current_ns
= ns
;
2759 m
= gfc_match_actual_arglist (1, &arglist
);
2763 if (gfc_match_char (')') != MATCH_YES
)
2766 ns
->code
= gfc_get_code (EXEC_CALL
);
2767 ns
->code
->symtree
= st
;
2768 ns
->code
->ext
.actual
= arglist
;
2769 ns
->code
->loc
= old_loc
;
2774 gfc_omp_udr_predef (gfc_omp_reduction_op rop
, const char *name
,
2775 gfc_typespec
*ts
, const char **n
)
2777 if (!gfc_numeric_ts (ts
) && ts
->type
!= BT_LOGICAL
)
2782 case OMP_REDUCTION_PLUS
:
2783 case OMP_REDUCTION_MINUS
:
2784 case OMP_REDUCTION_TIMES
:
2785 return ts
->type
!= BT_LOGICAL
;
2786 case OMP_REDUCTION_AND
:
2787 case OMP_REDUCTION_OR
:
2788 case OMP_REDUCTION_EQV
:
2789 case OMP_REDUCTION_NEQV
:
2790 return ts
->type
== BT_LOGICAL
;
2791 case OMP_REDUCTION_USER
:
2792 if (name
[0] != '.' && (ts
->type
== BT_INTEGER
|| ts
->type
== BT_REAL
))
2796 gfc_find_symbol (name
, NULL
, 1, &sym
);
2799 if (sym
->attr
.intrinsic
)
2801 else if ((sym
->attr
.flavor
!= FL_UNKNOWN
2802 && sym
->attr
.flavor
!= FL_PROCEDURE
)
2803 || sym
->attr
.external
2804 || sym
->attr
.generic
2808 || sym
->attr
.subroutine
2809 || sym
->attr
.pointer
2811 || sym
->attr
.cray_pointer
2812 || sym
->attr
.cray_pointee
2813 || (sym
->attr
.proc
!= PROC_UNKNOWN
2814 && sym
->attr
.proc
!= PROC_INTRINSIC
)
2815 || sym
->attr
.if_source
!= IFSRC_UNKNOWN
2816 || sym
== sym
->ns
->proc_name
)
2824 && (strcmp (*n
, "max") == 0 || strcmp (*n
, "min") == 0))
2827 && ts
->type
== BT_INTEGER
2828 && (strcmp (*n
, "iand") == 0
2829 || strcmp (*n
, "ior") == 0
2830 || strcmp (*n
, "ieor") == 0))
2841 gfc_omp_udr_find (gfc_symtree
*st
, gfc_typespec
*ts
)
2843 gfc_omp_udr
*omp_udr
;
2848 for (omp_udr
= st
->n
.omp_udr
; omp_udr
; omp_udr
= omp_udr
->next
)
2849 if (omp_udr
->ts
.type
== ts
->type
2850 || ((omp_udr
->ts
.type
== BT_DERIVED
|| omp_udr
->ts
.type
== BT_CLASS
)
2851 && (ts
->type
== BT_DERIVED
|| ts
->type
== BT_CLASS
)))
2853 if (omp_udr
->ts
.type
== BT_DERIVED
|| omp_udr
->ts
.type
== BT_CLASS
)
2855 if (strcmp (omp_udr
->ts
.u
.derived
->name
, ts
->u
.derived
->name
) == 0)
2858 else if (omp_udr
->ts
.kind
== ts
->kind
)
2860 if (omp_udr
->ts
.type
== BT_CHARACTER
)
2862 if (omp_udr
->ts
.u
.cl
->length
== NULL
2863 || ts
->u
.cl
->length
== NULL
)
2865 if (omp_udr
->ts
.u
.cl
->length
->expr_type
!= EXPR_CONSTANT
)
2867 if (ts
->u
.cl
->length
->expr_type
!= EXPR_CONSTANT
)
2869 if (omp_udr
->ts
.u
.cl
->length
->ts
.type
!= BT_INTEGER
)
2871 if (ts
->u
.cl
->length
->ts
.type
!= BT_INTEGER
)
2873 if (gfc_compare_expr (omp_udr
->ts
.u
.cl
->length
,
2874 ts
->u
.cl
->length
, INTRINSIC_EQ
) != 0)
2884 gfc_match_omp_declare_reduction (void)
2887 gfc_intrinsic_op op
;
2888 char name
[GFC_MAX_SYMBOL_LEN
+ 3];
2889 auto_vec
<gfc_typespec
, 5> tss
;
2893 locus where
= gfc_current_locus
;
2894 locus end_loc
= gfc_current_locus
;
2895 bool end_loc_set
= false;
2896 gfc_omp_reduction_op rop
= OMP_REDUCTION_NONE
;
2898 if (gfc_match_char ('(') != MATCH_YES
)
2901 m
= gfc_match (" %o : ", &op
);
2902 if (m
== MATCH_ERROR
)
2906 snprintf (name
, sizeof name
, "operator %s", gfc_op2string (op
));
2907 rop
= (gfc_omp_reduction_op
) op
;
2911 m
= gfc_match_defined_op_name (name
+ 1, 1);
2912 if (m
== MATCH_ERROR
)
2918 if (gfc_match (" : ") != MATCH_YES
)
2923 if (gfc_match (" %n : ", name
) != MATCH_YES
)
2926 rop
= OMP_REDUCTION_USER
;
2929 m
= gfc_match_type_spec (&ts
);
2932 /* Treat len=: the same as len=*. */
2933 if (ts
.type
== BT_CHARACTER
)
2934 ts
.deferred
= false;
2937 while (gfc_match_char (',') == MATCH_YES
)
2939 m
= gfc_match_type_spec (&ts
);
2944 if (gfc_match_char (':') != MATCH_YES
)
2947 st
= gfc_find_symtree (gfc_current_ns
->omp_udr_root
, name
);
2948 for (i
= 0; i
< tss
.length (); i
++)
2950 gfc_symtree
*omp_out
, *omp_in
;
2951 gfc_symtree
*omp_priv
= NULL
, *omp_orig
= NULL
;
2952 gfc_namespace
*combiner_ns
, *initializer_ns
= NULL
;
2953 gfc_omp_udr
*prev_udr
, *omp_udr
;
2954 const char *predef_name
= NULL
;
2956 omp_udr
= gfc_get_omp_udr ();
2957 omp_udr
->name
= gfc_get_string ("%s", name
);
2959 omp_udr
->ts
= tss
[i
];
2960 omp_udr
->where
= where
;
2962 gfc_current_ns
= combiner_ns
= gfc_get_namespace (gfc_current_ns
, 1);
2963 combiner_ns
->proc_name
= combiner_ns
->parent
->proc_name
;
2965 gfc_get_sym_tree ("omp_out", combiner_ns
, &omp_out
, false);
2966 gfc_get_sym_tree ("omp_in", combiner_ns
, &omp_in
, false);
2967 combiner_ns
->omp_udr_ns
= 1;
2968 omp_out
->n
.sym
->ts
= tss
[i
];
2969 omp_in
->n
.sym
->ts
= tss
[i
];
2970 omp_out
->n
.sym
->attr
.omp_udr_artificial_var
= 1;
2971 omp_in
->n
.sym
->attr
.omp_udr_artificial_var
= 1;
2972 omp_out
->n
.sym
->attr
.flavor
= FL_VARIABLE
;
2973 omp_in
->n
.sym
->attr
.flavor
= FL_VARIABLE
;
2974 gfc_commit_symbols ();
2975 omp_udr
->combiner_ns
= combiner_ns
;
2976 omp_udr
->omp_out
= omp_out
->n
.sym
;
2977 omp_udr
->omp_in
= omp_in
->n
.sym
;
2979 locus old_loc
= gfc_current_locus
;
2981 if (!match_udr_expr (omp_out
, omp_in
))
2984 gfc_current_locus
= old_loc
;
2985 gfc_current_ns
= combiner_ns
->parent
;
2986 gfc_undo_symbols ();
2987 gfc_free_omp_udr (omp_udr
);
2991 if (gfc_match (" initializer ( ") == MATCH_YES
)
2993 gfc_current_ns
= combiner_ns
->parent
;
2994 initializer_ns
= gfc_get_namespace (gfc_current_ns
, 1);
2995 gfc_current_ns
= initializer_ns
;
2996 initializer_ns
->proc_name
= initializer_ns
->parent
->proc_name
;
2998 gfc_get_sym_tree ("omp_priv", initializer_ns
, &omp_priv
, false);
2999 gfc_get_sym_tree ("omp_orig", initializer_ns
, &omp_orig
, false);
3000 initializer_ns
->omp_udr_ns
= 1;
3001 omp_priv
->n
.sym
->ts
= tss
[i
];
3002 omp_orig
->n
.sym
->ts
= tss
[i
];
3003 omp_priv
->n
.sym
->attr
.omp_udr_artificial_var
= 1;
3004 omp_orig
->n
.sym
->attr
.omp_udr_artificial_var
= 1;
3005 omp_priv
->n
.sym
->attr
.flavor
= FL_VARIABLE
;
3006 omp_orig
->n
.sym
->attr
.flavor
= FL_VARIABLE
;
3007 gfc_commit_symbols ();
3008 omp_udr
->initializer_ns
= initializer_ns
;
3009 omp_udr
->omp_priv
= omp_priv
->n
.sym
;
3010 omp_udr
->omp_orig
= omp_orig
->n
.sym
;
3012 if (!match_udr_expr (omp_priv
, omp_orig
))
3016 gfc_current_ns
= combiner_ns
->parent
;
3020 end_loc
= gfc_current_locus
;
3022 gfc_current_locus
= old_loc
;
3024 prev_udr
= gfc_omp_udr_find (st
, &tss
[i
]);
3025 if (gfc_omp_udr_predef (rop
, name
, &tss
[i
], &predef_name
)
3026 /* Don't error on !$omp declare reduction (min : integer : ...)
3027 just yet, there could be integer :: min afterwards,
3028 making it valid. When the UDR is resolved, we'll get
3030 && (rop
!= OMP_REDUCTION_USER
|| name
[0] == '.'))
3033 gfc_error_now ("Redefinition of predefined %s "
3034 "!$OMP DECLARE REDUCTION at %L",
3035 predef_name
, &where
);
3037 gfc_error_now ("Redefinition of predefined "
3038 "!$OMP DECLARE REDUCTION at %L", &where
);
3042 gfc_error_now ("Redefinition of !$OMP DECLARE REDUCTION at %L",
3044 gfc_error_now ("Previous !$OMP DECLARE REDUCTION at %L",
3049 omp_udr
->next
= st
->n
.omp_udr
;
3050 st
->n
.omp_udr
= omp_udr
;
3054 st
= gfc_new_symtree (&gfc_current_ns
->omp_udr_root
, name
);
3055 st
->n
.omp_udr
= omp_udr
;
3061 gfc_current_locus
= end_loc
;
3062 if (gfc_match_omp_eos () != MATCH_YES
)
3064 gfc_error ("Unexpected junk after !$OMP DECLARE REDUCTION at %C");
3065 gfc_current_locus
= where
;
3077 gfc_match_omp_declare_target (void)
3081 gfc_omp_clauses
*c
= NULL
;
3083 gfc_omp_namelist
*n
;
3086 old_loc
= gfc_current_locus
;
3088 if (gfc_current_ns
->proc_name
3089 && gfc_match_omp_eos () == MATCH_YES
)
3091 if (!gfc_add_omp_declare_target (&gfc_current_ns
->proc_name
->attr
,
3092 gfc_current_ns
->proc_name
->name
,
3098 if (gfc_current_ns
->proc_name
3099 && gfc_current_ns
->proc_name
->attr
.if_source
== IFSRC_IFBODY
)
3101 gfc_error ("Only the !$OMP DECLARE TARGET form without "
3102 "clauses is allowed in interface block at %C");
3106 m
= gfc_match (" (");
3109 c
= gfc_get_omp_clauses ();
3110 gfc_current_locus
= old_loc
;
3111 m
= gfc_match_omp_to_link (" (", &c
->lists
[OMP_LIST_TO
]);
3114 if (gfc_match_omp_eos () != MATCH_YES
)
3116 gfc_error ("Unexpected junk after !$OMP DECLARE TARGET at %C");
3120 else if (gfc_match_omp_clauses (&c
, OMP_DECLARE_TARGET_CLAUSES
) != MATCH_YES
)
3123 gfc_buffer_error (false);
3125 for (list
= OMP_LIST_TO
; list
!= OMP_LIST_NUM
;
3126 list
= (list
== OMP_LIST_TO
? OMP_LIST_LINK
: OMP_LIST_NUM
))
3127 for (n
= c
->lists
[list
]; n
; n
= n
->next
)
3130 else if (n
->u
.common
->head
)
3131 n
->u
.common
->head
->mark
= 0;
3133 for (list
= OMP_LIST_TO
; list
!= OMP_LIST_NUM
;
3134 list
= (list
== OMP_LIST_TO
? OMP_LIST_LINK
: OMP_LIST_NUM
))
3135 for (n
= c
->lists
[list
]; n
; n
= n
->next
)
3138 if (n
->sym
->attr
.in_common
)
3139 gfc_error_now ("OMP DECLARE TARGET variable at %L is an "
3140 "element of a COMMON block", &n
->where
);
3141 else if (n
->sym
->attr
.omp_declare_target
3142 && n
->sym
->attr
.omp_declare_target_link
3143 && list
!= OMP_LIST_LINK
)
3144 gfc_error_now ("OMP DECLARE TARGET variable at %L previously "
3145 "mentioned in LINK clause and later in TO clause",
3147 else if (n
->sym
->attr
.omp_declare_target
3148 && !n
->sym
->attr
.omp_declare_target_link
3149 && list
== OMP_LIST_LINK
)
3150 gfc_error_now ("OMP DECLARE TARGET variable at %L previously "
3151 "mentioned in TO clause and later in LINK clause",
3153 else if (n
->sym
->mark
)
3154 gfc_error_now ("Variable at %L mentioned multiple times in "
3155 "clauses of the same OMP DECLARE TARGET directive",
3157 else if (gfc_add_omp_declare_target (&n
->sym
->attr
, n
->sym
->name
,
3158 &n
->sym
->declared_at
))
3160 if (list
== OMP_LIST_LINK
)
3161 gfc_add_omp_declare_target_link (&n
->sym
->attr
, n
->sym
->name
,
3162 &n
->sym
->declared_at
);
3166 else if (n
->u
.common
->omp_declare_target
3167 && n
->u
.common
->omp_declare_target_link
3168 && list
!= OMP_LIST_LINK
)
3169 gfc_error_now ("OMP DECLARE TARGET COMMON at %L previously "
3170 "mentioned in LINK clause and later in TO clause",
3172 else if (n
->u
.common
->omp_declare_target
3173 && !n
->u
.common
->omp_declare_target_link
3174 && list
== OMP_LIST_LINK
)
3175 gfc_error_now ("OMP DECLARE TARGET COMMON at %L previously "
3176 "mentioned in TO clause and later in LINK clause",
3178 else if (n
->u
.common
->head
&& n
->u
.common
->head
->mark
)
3179 gfc_error_now ("COMMON at %L mentioned multiple times in "
3180 "clauses of the same OMP DECLARE TARGET directive",
3184 n
->u
.common
->omp_declare_target
= 1;
3185 n
->u
.common
->omp_declare_target_link
= (list
== OMP_LIST_LINK
);
3186 for (s
= n
->u
.common
->head
; s
; s
= s
->common_next
)
3189 if (gfc_add_omp_declare_target (&s
->attr
, s
->name
,
3192 if (list
== OMP_LIST_LINK
)
3193 gfc_add_omp_declare_target_link (&s
->attr
, s
->name
,
3199 gfc_buffer_error (true);
3202 gfc_free_omp_clauses (c
);
3206 gfc_error ("Syntax error in !$OMP DECLARE TARGET list at %C");
3209 gfc_current_locus
= old_loc
;
3211 gfc_free_omp_clauses (c
);
3217 gfc_match_omp_threadprivate (void)
3220 char n
[GFC_MAX_SYMBOL_LEN
+1];
3225 old_loc
= gfc_current_locus
;
3227 m
= gfc_match (" (");
3233 m
= gfc_match_symbol (&sym
, 0);
3237 if (sym
->attr
.in_common
)
3238 gfc_error_now ("Threadprivate variable at %C is an element of "
3240 else if (!gfc_add_threadprivate (&sym
->attr
, sym
->name
, &sym
->declared_at
))
3249 m
= gfc_match (" / %n /", n
);
3250 if (m
== MATCH_ERROR
)
3252 if (m
== MATCH_NO
|| n
[0] == '\0')
3255 st
= gfc_find_symtree (gfc_current_ns
->common_root
, n
);
3258 gfc_error ("COMMON block /%s/ not found at %C", n
);
3261 st
->n
.common
->threadprivate
= 1;
3262 for (sym
= st
->n
.common
->head
; sym
; sym
= sym
->common_next
)
3263 if (!gfc_add_threadprivate (&sym
->attr
, sym
->name
, &sym
->declared_at
))
3267 if (gfc_match_char (')') == MATCH_YES
)
3269 if (gfc_match_char (',') != MATCH_YES
)
3273 if (gfc_match_omp_eos () != MATCH_YES
)
3275 gfc_error ("Unexpected junk after OMP THREADPRIVATE at %C");
3282 gfc_error ("Syntax error in !$OMP THREADPRIVATE list at %C");
3285 gfc_current_locus
= old_loc
;
3291 gfc_match_omp_parallel (void)
3293 return match_omp (EXEC_OMP_PARALLEL
, OMP_PARALLEL_CLAUSES
);
3298 gfc_match_omp_parallel_do (void)
3300 return match_omp (EXEC_OMP_PARALLEL_DO
,
3301 OMP_PARALLEL_CLAUSES
| OMP_DO_CLAUSES
);
3306 gfc_match_omp_parallel_do_simd (void)
3308 return match_omp (EXEC_OMP_PARALLEL_DO_SIMD
,
3309 OMP_PARALLEL_CLAUSES
| OMP_DO_CLAUSES
| OMP_SIMD_CLAUSES
);
3314 gfc_match_omp_parallel_sections (void)
3316 return match_omp (EXEC_OMP_PARALLEL_SECTIONS
,
3317 OMP_PARALLEL_CLAUSES
| OMP_SECTIONS_CLAUSES
);
3322 gfc_match_omp_parallel_workshare (void)
3324 return match_omp (EXEC_OMP_PARALLEL_WORKSHARE
, OMP_PARALLEL_CLAUSES
);
3329 gfc_match_omp_sections (void)
3331 return match_omp (EXEC_OMP_SECTIONS
, OMP_SECTIONS_CLAUSES
);
3336 gfc_match_omp_simd (void)
3338 return match_omp (EXEC_OMP_SIMD
, OMP_SIMD_CLAUSES
);
3343 gfc_match_omp_single (void)
3345 return match_omp (EXEC_OMP_SINGLE
, OMP_SINGLE_CLAUSES
);
3350 gfc_match_omp_target (void)
3352 return match_omp (EXEC_OMP_TARGET
, OMP_TARGET_CLAUSES
);
3357 gfc_match_omp_target_data (void)
3359 return match_omp (EXEC_OMP_TARGET_DATA
, OMP_TARGET_DATA_CLAUSES
);
3364 gfc_match_omp_target_enter_data (void)
3366 return match_omp (EXEC_OMP_TARGET_ENTER_DATA
, OMP_TARGET_ENTER_DATA_CLAUSES
);
3371 gfc_match_omp_target_exit_data (void)
3373 return match_omp (EXEC_OMP_TARGET_EXIT_DATA
, OMP_TARGET_EXIT_DATA_CLAUSES
);
3378 gfc_match_omp_target_parallel (void)
3380 return match_omp (EXEC_OMP_TARGET_PARALLEL
,
3381 (OMP_TARGET_CLAUSES
| OMP_PARALLEL_CLAUSES
)
3382 & ~(omp_mask (OMP_CLAUSE_COPYIN
)));
3387 gfc_match_omp_target_parallel_do (void)
3389 return match_omp (EXEC_OMP_TARGET_PARALLEL_DO
,
3390 (OMP_TARGET_CLAUSES
| OMP_PARALLEL_CLAUSES
3391 | OMP_DO_CLAUSES
) & ~(omp_mask (OMP_CLAUSE_COPYIN
)));
3396 gfc_match_omp_target_parallel_do_simd (void)
3398 return match_omp (EXEC_OMP_TARGET_PARALLEL_DO_SIMD
,
3399 (OMP_TARGET_CLAUSES
| OMP_PARALLEL_CLAUSES
| OMP_DO_CLAUSES
3400 | OMP_SIMD_CLAUSES
) & ~(omp_mask (OMP_CLAUSE_COPYIN
)));
3405 gfc_match_omp_target_simd (void)
3407 return match_omp (EXEC_OMP_TARGET_SIMD
,
3408 OMP_TARGET_CLAUSES
| OMP_SIMD_CLAUSES
);
3413 gfc_match_omp_target_teams (void)
3415 return match_omp (EXEC_OMP_TARGET_TEAMS
,
3416 OMP_TARGET_CLAUSES
| OMP_TEAMS_CLAUSES
);
3421 gfc_match_omp_target_teams_distribute (void)
3423 return match_omp (EXEC_OMP_TARGET_TEAMS_DISTRIBUTE
,
3424 OMP_TARGET_CLAUSES
| OMP_TEAMS_CLAUSES
3425 | OMP_DISTRIBUTE_CLAUSES
);
3430 gfc_match_omp_target_teams_distribute_parallel_do (void)
3432 return match_omp (EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO
,
3433 (OMP_TARGET_CLAUSES
| OMP_TEAMS_CLAUSES
3434 | OMP_DISTRIBUTE_CLAUSES
| OMP_PARALLEL_CLAUSES
3436 & ~(omp_mask (OMP_CLAUSE_ORDERED
))
3437 & ~(omp_mask (OMP_CLAUSE_LINEAR
)));
3442 gfc_match_omp_target_teams_distribute_parallel_do_simd (void)
3444 return match_omp (EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
,
3445 (OMP_TARGET_CLAUSES
| OMP_TEAMS_CLAUSES
3446 | OMP_DISTRIBUTE_CLAUSES
| OMP_PARALLEL_CLAUSES
3447 | OMP_DO_CLAUSES
| OMP_SIMD_CLAUSES
)
3448 & ~(omp_mask (OMP_CLAUSE_ORDERED
)));
3453 gfc_match_omp_target_teams_distribute_simd (void)
3455 return match_omp (EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD
,
3456 OMP_TARGET_CLAUSES
| OMP_TEAMS_CLAUSES
3457 | OMP_DISTRIBUTE_CLAUSES
| OMP_SIMD_CLAUSES
);
3462 gfc_match_omp_target_update (void)
3464 return match_omp (EXEC_OMP_TARGET_UPDATE
, OMP_TARGET_UPDATE_CLAUSES
);
3469 gfc_match_omp_task (void)
3471 return match_omp (EXEC_OMP_TASK
, OMP_TASK_CLAUSES
);
3476 gfc_match_omp_taskloop (void)
3478 return match_omp (EXEC_OMP_TASKLOOP
, OMP_TASKLOOP_CLAUSES
);
3483 gfc_match_omp_taskloop_simd (void)
3485 return match_omp (EXEC_OMP_TASKLOOP_SIMD
,
3486 (OMP_TASKLOOP_CLAUSES
| OMP_SIMD_CLAUSES
)
3487 & ~(omp_mask (OMP_CLAUSE_REDUCTION
)));
3492 gfc_match_omp_taskwait (void)
3494 if (gfc_match_omp_eos () != MATCH_YES
)
3496 gfc_error ("Unexpected junk after TASKWAIT clause at %C");
3499 new_st
.op
= EXEC_OMP_TASKWAIT
;
3500 new_st
.ext
.omp_clauses
= NULL
;
3506 gfc_match_omp_taskyield (void)
3508 if (gfc_match_omp_eos () != MATCH_YES
)
3510 gfc_error ("Unexpected junk after TASKYIELD clause at %C");
3513 new_st
.op
= EXEC_OMP_TASKYIELD
;
3514 new_st
.ext
.omp_clauses
= NULL
;
3520 gfc_match_omp_teams (void)
3522 return match_omp (EXEC_OMP_TEAMS
, OMP_TEAMS_CLAUSES
);
3527 gfc_match_omp_teams_distribute (void)
3529 return match_omp (EXEC_OMP_TEAMS_DISTRIBUTE
,
3530 OMP_TEAMS_CLAUSES
| OMP_DISTRIBUTE_CLAUSES
);
3535 gfc_match_omp_teams_distribute_parallel_do (void)
3537 return match_omp (EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO
,
3538 (OMP_TEAMS_CLAUSES
| OMP_DISTRIBUTE_CLAUSES
3539 | OMP_PARALLEL_CLAUSES
| OMP_DO_CLAUSES
)
3540 & ~(omp_mask (OMP_CLAUSE_ORDERED
))
3541 & ~(omp_mask (OMP_CLAUSE_LINEAR
)));
3546 gfc_match_omp_teams_distribute_parallel_do_simd (void)
3548 return match_omp (EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
,
3549 (OMP_TEAMS_CLAUSES
| OMP_DISTRIBUTE_CLAUSES
3550 | OMP_PARALLEL_CLAUSES
| OMP_DO_CLAUSES
3551 | OMP_SIMD_CLAUSES
) & ~(omp_mask (OMP_CLAUSE_ORDERED
)));
3556 gfc_match_omp_teams_distribute_simd (void)
3558 return match_omp (EXEC_OMP_TEAMS_DISTRIBUTE_SIMD
,
3559 OMP_TEAMS_CLAUSES
| OMP_DISTRIBUTE_CLAUSES
3560 | OMP_SIMD_CLAUSES
);
3565 gfc_match_omp_workshare (void)
3567 if (gfc_match_omp_eos () != MATCH_YES
)
3569 gfc_error ("Unexpected junk after $OMP WORKSHARE statement at %C");
3572 new_st
.op
= EXEC_OMP_WORKSHARE
;
3573 new_st
.ext
.omp_clauses
= gfc_get_omp_clauses ();
3579 gfc_match_omp_master (void)
3581 if (gfc_match_omp_eos () != MATCH_YES
)
3583 gfc_error ("Unexpected junk after $OMP MASTER statement at %C");
3586 new_st
.op
= EXEC_OMP_MASTER
;
3587 new_st
.ext
.omp_clauses
= NULL
;
3593 gfc_match_omp_ordered (void)
3595 return match_omp (EXEC_OMP_ORDERED
, OMP_ORDERED_CLAUSES
);
3600 gfc_match_omp_ordered_depend (void)
3602 return match_omp (EXEC_OMP_ORDERED
, omp_mask (OMP_CLAUSE_DEPEND
));
3607 gfc_match_omp_oacc_atomic (bool omp_p
)
3609 gfc_omp_atomic_op op
= GFC_OMP_ATOMIC_UPDATE
;
3611 if (gfc_match ("% seq_cst") == MATCH_YES
)
3613 locus old_loc
= gfc_current_locus
;
3614 if (seq_cst
&& gfc_match_char (',') == MATCH_YES
)
3617 || gfc_match_space () == MATCH_YES
)
3619 gfc_gobble_whitespace ();
3620 if (gfc_match ("update") == MATCH_YES
)
3621 op
= GFC_OMP_ATOMIC_UPDATE
;
3622 else if (gfc_match ("read") == MATCH_YES
)
3623 op
= GFC_OMP_ATOMIC_READ
;
3624 else if (gfc_match ("write") == MATCH_YES
)
3625 op
= GFC_OMP_ATOMIC_WRITE
;
3626 else if (gfc_match ("capture") == MATCH_YES
)
3627 op
= GFC_OMP_ATOMIC_CAPTURE
;
3631 gfc_current_locus
= old_loc
;
3635 && (gfc_match (", seq_cst") == MATCH_YES
3636 || gfc_match ("% seq_cst") == MATCH_YES
))
3640 if (gfc_match_omp_eos () != MATCH_YES
)
3642 gfc_error ("Unexpected junk after $OMP ATOMIC statement at %C");
3645 new_st
.op
= (omp_p
? EXEC_OMP_ATOMIC
: EXEC_OACC_ATOMIC
);
3647 op
= (gfc_omp_atomic_op
) (op
| GFC_OMP_ATOMIC_SEQ_CST
);
3648 new_st
.ext
.omp_atomic
= op
;
3653 gfc_match_oacc_atomic (void)
3655 return gfc_match_omp_oacc_atomic (false);
3659 gfc_match_omp_atomic (void)
3661 return gfc_match_omp_oacc_atomic (true);
3665 gfc_match_omp_barrier (void)
3667 if (gfc_match_omp_eos () != MATCH_YES
)
3669 gfc_error ("Unexpected junk after $OMP BARRIER statement at %C");
3672 new_st
.op
= EXEC_OMP_BARRIER
;
3673 new_st
.ext
.omp_clauses
= NULL
;
3679 gfc_match_omp_taskgroup (void)
3681 if (gfc_match_omp_eos () != MATCH_YES
)
3683 gfc_error ("Unexpected junk after $OMP TASKGROUP statement at %C");
3686 new_st
.op
= EXEC_OMP_TASKGROUP
;
3691 static enum gfc_omp_cancel_kind
3692 gfc_match_omp_cancel_kind (void)
3694 if (gfc_match_space () != MATCH_YES
)
3695 return OMP_CANCEL_UNKNOWN
;
3696 if (gfc_match ("parallel") == MATCH_YES
)
3697 return OMP_CANCEL_PARALLEL
;
3698 if (gfc_match ("sections") == MATCH_YES
)
3699 return OMP_CANCEL_SECTIONS
;
3700 if (gfc_match ("do") == MATCH_YES
)
3701 return OMP_CANCEL_DO
;
3702 if (gfc_match ("taskgroup") == MATCH_YES
)
3703 return OMP_CANCEL_TASKGROUP
;
3704 return OMP_CANCEL_UNKNOWN
;
3709 gfc_match_omp_cancel (void)
3712 enum gfc_omp_cancel_kind kind
= gfc_match_omp_cancel_kind ();
3713 if (kind
== OMP_CANCEL_UNKNOWN
)
3715 if (gfc_match_omp_clauses (&c
, omp_mask (OMP_CLAUSE_IF
), false) != MATCH_YES
)
3718 new_st
.op
= EXEC_OMP_CANCEL
;
3719 new_st
.ext
.omp_clauses
= c
;
3725 gfc_match_omp_cancellation_point (void)
3728 enum gfc_omp_cancel_kind kind
= gfc_match_omp_cancel_kind ();
3729 if (kind
== OMP_CANCEL_UNKNOWN
)
3731 if (gfc_match_omp_eos () != MATCH_YES
)
3733 gfc_error ("Unexpected junk after $OMP CANCELLATION POINT statement "
3737 c
= gfc_get_omp_clauses ();
3739 new_st
.op
= EXEC_OMP_CANCELLATION_POINT
;
3740 new_st
.ext
.omp_clauses
= c
;
3746 gfc_match_omp_end_nowait (void)
3748 bool nowait
= false;
3749 if (gfc_match ("% nowait") == MATCH_YES
)
3751 if (gfc_match_omp_eos () != MATCH_YES
)
3753 gfc_error ("Unexpected junk after NOWAIT clause at %C");
3756 new_st
.op
= EXEC_OMP_END_NOWAIT
;
3757 new_st
.ext
.omp_bool
= nowait
;
3763 gfc_match_omp_end_single (void)
3766 if (gfc_match ("% nowait") == MATCH_YES
)
3768 new_st
.op
= EXEC_OMP_END_NOWAIT
;
3769 new_st
.ext
.omp_bool
= true;
3772 if (gfc_match_omp_clauses (&c
, omp_mask (OMP_CLAUSE_COPYPRIVATE
))
3775 new_st
.op
= EXEC_OMP_END_SINGLE
;
3776 new_st
.ext
.omp_clauses
= c
;
3782 oacc_is_loop (gfc_code
*code
)
3784 return code
->op
== EXEC_OACC_PARALLEL_LOOP
3785 || code
->op
== EXEC_OACC_KERNELS_LOOP
3786 || code
->op
== EXEC_OACC_LOOP
;
3790 resolve_scalar_int_expr (gfc_expr
*expr
, const char *clause
)
3792 if (!gfc_resolve_expr (expr
)
3793 || expr
->ts
.type
!= BT_INTEGER
3795 gfc_error ("%s clause at %L requires a scalar INTEGER expression",
3796 clause
, &expr
->where
);
3800 resolve_positive_int_expr (gfc_expr
*expr
, const char *clause
)
3802 resolve_scalar_int_expr (expr
, clause
);
3803 if (expr
->expr_type
== EXPR_CONSTANT
3804 && expr
->ts
.type
== BT_INTEGER
3805 && mpz_sgn (expr
->value
.integer
) <= 0)
3806 gfc_warning (0, "INTEGER expression of %s clause at %L must be positive",
3807 clause
, &expr
->where
);
3811 resolve_nonnegative_int_expr (gfc_expr
*expr
, const char *clause
)
3813 resolve_scalar_int_expr (expr
, clause
);
3814 if (expr
->expr_type
== EXPR_CONSTANT
3815 && expr
->ts
.type
== BT_INTEGER
3816 && mpz_sgn (expr
->value
.integer
) < 0)
3817 gfc_warning (0, "INTEGER expression of %s clause at %L must be "
3818 "non-negative", clause
, &expr
->where
);
3821 /* Emits error when symbol is pointer, cray pointer or cray pointee
3822 of derived of polymorphic type. */
3825 check_symbol_not_pointer (gfc_symbol
*sym
, locus loc
, const char *name
)
3827 if (sym
->ts
.type
== BT_DERIVED
&& sym
->attr
.pointer
)
3828 gfc_error ("POINTER object %qs of derived type in %s clause at %L",
3829 sym
->name
, name
, &loc
);
3830 if (sym
->ts
.type
== BT_DERIVED
&& sym
->attr
.cray_pointer
)
3831 gfc_error ("Cray pointer object %qs of derived type in %s clause at %L",
3832 sym
->name
, name
, &loc
);
3833 if (sym
->ts
.type
== BT_DERIVED
&& sym
->attr
.cray_pointee
)
3834 gfc_error ("Cray pointee object %qs of derived type in %s clause at %L",
3835 sym
->name
, name
, &loc
);
3837 if ((sym
->ts
.type
== BT_ASSUMED
&& sym
->attr
.pointer
)
3838 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
3839 && CLASS_DATA (sym
)->attr
.pointer
))
3840 gfc_error ("POINTER object %qs of polymorphic type in %s clause at %L",
3841 sym
->name
, name
, &loc
);
3842 if ((sym
->ts
.type
== BT_ASSUMED
&& sym
->attr
.cray_pointer
)
3843 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
3844 && CLASS_DATA (sym
)->attr
.cray_pointer
))
3845 gfc_error ("Cray pointer object %qs of polymorphic type in %s clause at %L",
3846 sym
->name
, name
, &loc
);
3847 if ((sym
->ts
.type
== BT_ASSUMED
&& sym
->attr
.cray_pointee
)
3848 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
3849 && CLASS_DATA (sym
)->attr
.cray_pointee
))
3850 gfc_error ("Cray pointee object %qs of polymorphic type in %s clause at %L",
3851 sym
->name
, name
, &loc
);
3854 /* Emits error when symbol represents assumed size/rank array. */
3857 check_array_not_assumed (gfc_symbol
*sym
, locus loc
, const char *name
)
3859 if (sym
->as
&& sym
->as
->type
== AS_ASSUMED_SIZE
)
3860 gfc_error ("Assumed size array %qs in %s clause at %L",
3861 sym
->name
, name
, &loc
);
3862 if (sym
->as
&& sym
->as
->type
== AS_ASSUMED_RANK
)
3863 gfc_error ("Assumed rank array %qs in %s clause at %L",
3864 sym
->name
, name
, &loc
);
3868 resolve_oacc_data_clauses (gfc_symbol
*sym
, locus loc
, const char *name
)
3870 if (sym
->ts
.type
== BT_DERIVED
&& sym
->attr
.allocatable
)
3871 gfc_error ("ALLOCATABLE object %qs of derived type in %s clause at %L",
3872 sym
->name
, name
, &loc
);
3873 if ((sym
->ts
.type
== BT_ASSUMED
&& sym
->attr
.allocatable
)
3874 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
3875 && CLASS_DATA (sym
)->attr
.allocatable
))
3876 gfc_error ("ALLOCATABLE object %qs of polymorphic type "
3877 "in %s clause at %L", sym
->name
, name
, &loc
);
3878 check_symbol_not_pointer (sym
, loc
, name
);
3879 check_array_not_assumed (sym
, loc
, name
);
3883 resolve_oacc_deviceptr_clause (gfc_symbol
*sym
, locus loc
, const char *name
)
3885 if (sym
->attr
.pointer
3886 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
3887 && CLASS_DATA (sym
)->attr
.class_pointer
))
3888 gfc_error ("POINTER object %qs in %s clause at %L",
3889 sym
->name
, name
, &loc
);
3890 if (sym
->attr
.cray_pointer
3891 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
3892 && CLASS_DATA (sym
)->attr
.cray_pointer
))
3893 gfc_error ("Cray pointer object %qs in %s clause at %L",
3894 sym
->name
, name
, &loc
);
3895 if (sym
->attr
.cray_pointee
3896 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
3897 && CLASS_DATA (sym
)->attr
.cray_pointee
))
3898 gfc_error ("Cray pointee object %qs in %s clause at %L",
3899 sym
->name
, name
, &loc
);
3900 if (sym
->attr
.allocatable
3901 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
3902 && CLASS_DATA (sym
)->attr
.allocatable
))
3903 gfc_error ("ALLOCATABLE object %qs in %s clause at %L",
3904 sym
->name
, name
, &loc
);
3905 if (sym
->attr
.value
)
3906 gfc_error ("VALUE object %qs in %s clause at %L",
3907 sym
->name
, name
, &loc
);
3908 check_array_not_assumed (sym
, loc
, name
);
3912 struct resolve_omp_udr_callback_data
3914 gfc_symbol
*sym1
, *sym2
;
3919 resolve_omp_udr_callback (gfc_expr
**e
, int *, void *data
)
3921 struct resolve_omp_udr_callback_data
*rcd
3922 = (struct resolve_omp_udr_callback_data
*) data
;
3923 if ((*e
)->expr_type
== EXPR_VARIABLE
3924 && ((*e
)->symtree
->n
.sym
== rcd
->sym1
3925 || (*e
)->symtree
->n
.sym
== rcd
->sym2
))
3927 gfc_ref
*ref
= gfc_get_ref ();
3928 ref
->type
= REF_ARRAY
;
3929 ref
->u
.ar
.where
= (*e
)->where
;
3930 ref
->u
.ar
.as
= (*e
)->symtree
->n
.sym
->as
;
3931 ref
->u
.ar
.type
= AR_FULL
;
3932 ref
->u
.ar
.dimen
= 0;
3933 ref
->next
= (*e
)->ref
;
3941 resolve_omp_udr_callback2 (gfc_expr
**e
, int *, void *)
3943 if ((*e
)->expr_type
== EXPR_FUNCTION
3944 && (*e
)->value
.function
.isym
== NULL
)
3946 gfc_symbol
*sym
= (*e
)->symtree
->n
.sym
;
3947 if (!sym
->attr
.intrinsic
3948 && sym
->attr
.if_source
== IFSRC_UNKNOWN
)
3949 gfc_error ("Implicitly declared function %s used in "
3950 "!$OMP DECLARE REDUCTION at %L", sym
->name
, &(*e
)->where
);
3957 resolve_omp_udr_clause (gfc_omp_namelist
*n
, gfc_namespace
*ns
,
3958 gfc_symbol
*sym1
, gfc_symbol
*sym2
)
3961 gfc_symbol sym1_copy
, sym2_copy
;
3963 if (ns
->code
->op
== EXEC_ASSIGN
)
3965 copy
= gfc_get_code (EXEC_ASSIGN
);
3966 copy
->expr1
= gfc_copy_expr (ns
->code
->expr1
);
3967 copy
->expr2
= gfc_copy_expr (ns
->code
->expr2
);
3971 copy
= gfc_get_code (EXEC_CALL
);
3972 copy
->symtree
= ns
->code
->symtree
;
3973 copy
->ext
.actual
= gfc_copy_actual_arglist (ns
->code
->ext
.actual
);
3975 copy
->loc
= ns
->code
->loc
;
3980 sym1
->name
= sym1_copy
.name
;
3981 sym2
->name
= sym2_copy
.name
;
3982 ns
->proc_name
= ns
->parent
->proc_name
;
3983 if (n
->sym
->attr
.dimension
)
3985 struct resolve_omp_udr_callback_data rcd
;
3988 gfc_code_walker (©
, gfc_dummy_code_callback
,
3989 resolve_omp_udr_callback
, &rcd
);
3991 gfc_resolve_code (copy
, gfc_current_ns
);
3992 if (copy
->op
== EXEC_CALL
&& copy
->resolved_isym
== NULL
)
3994 gfc_symbol
*sym
= copy
->resolved_sym
;
3996 && !sym
->attr
.intrinsic
3997 && sym
->attr
.if_source
== IFSRC_UNKNOWN
)
3998 gfc_error ("Implicitly declared subroutine %s used in "
3999 "!$OMP DECLARE REDUCTION at %L", sym
->name
,
4002 gfc_code_walker (©
, gfc_dummy_code_callback
,
4003 resolve_omp_udr_callback2
, NULL
);
4009 /* OpenMP directive resolving routines. */
4012 resolve_omp_clauses (gfc_code
*code
, gfc_omp_clauses
*omp_clauses
,
4013 gfc_namespace
*ns
, bool openacc
= false)
4015 gfc_omp_namelist
*n
;
4019 bool if_without_mod
= false;
4020 gfc_omp_linear_op linear_op
= OMP_LINEAR_DEFAULT
;
4021 static const char *clause_names
[]
4022 = { "PRIVATE", "FIRSTPRIVATE", "LASTPRIVATE", "COPYPRIVATE", "SHARED",
4023 "COPYIN", "UNIFORM", "ALIGNED", "LINEAR", "DEPEND", "MAP",
4024 "TO", "FROM", "REDUCTION", "DEVICE_RESIDENT", "LINK", "USE_DEVICE",
4025 "CACHE", "IS_DEVICE_PTR", "USE_DEVICE_PTR", "USE_DEVICE_ADDR" };
4027 if (omp_clauses
== NULL
)
4030 if (omp_clauses
->orderedc
&& omp_clauses
->orderedc
< omp_clauses
->collapse
)
4031 gfc_error ("ORDERED clause parameter is less than COLLAPSE at %L",
4034 if (omp_clauses
->if_expr
)
4036 gfc_expr
*expr
= omp_clauses
->if_expr
;
4037 if (!gfc_resolve_expr (expr
)
4038 || expr
->ts
.type
!= BT_LOGICAL
|| expr
->rank
!= 0)
4039 gfc_error ("IF clause at %L requires a scalar LOGICAL expression",
4041 if_without_mod
= true;
4043 for (ifc
= 0; ifc
< OMP_IF_LAST
; ifc
++)
4044 if (omp_clauses
->if_exprs
[ifc
])
4046 gfc_expr
*expr
= omp_clauses
->if_exprs
[ifc
];
4048 if (!gfc_resolve_expr (expr
)
4049 || expr
->ts
.type
!= BT_LOGICAL
|| expr
->rank
!= 0)
4050 gfc_error ("IF clause at %L requires a scalar LOGICAL expression",
4052 else if (if_without_mod
)
4054 gfc_error ("IF clause without modifier at %L used together with "
4055 "IF clauses with modifiers",
4056 &omp_clauses
->if_expr
->where
);
4057 if_without_mod
= false;
4062 case EXEC_OMP_PARALLEL
:
4063 case EXEC_OMP_PARALLEL_DO
:
4064 case EXEC_OMP_PARALLEL_SECTIONS
:
4065 case EXEC_OMP_PARALLEL_WORKSHARE
:
4066 case EXEC_OMP_PARALLEL_DO_SIMD
:
4067 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO
:
4068 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD
:
4069 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO
:
4070 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
4071 ok
= ifc
== OMP_IF_PARALLEL
;
4075 ok
= ifc
== OMP_IF_TASK
;
4078 case EXEC_OMP_TASKLOOP
:
4079 case EXEC_OMP_TASKLOOP_SIMD
:
4080 ok
= ifc
== OMP_IF_TASKLOOP
;
4083 case EXEC_OMP_TARGET
:
4084 case EXEC_OMP_TARGET_TEAMS
:
4085 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE
:
4086 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD
:
4087 case EXEC_OMP_TARGET_SIMD
:
4088 ok
= ifc
== OMP_IF_TARGET
;
4091 case EXEC_OMP_TARGET_DATA
:
4092 ok
= ifc
== OMP_IF_TARGET_DATA
;
4095 case EXEC_OMP_TARGET_UPDATE
:
4096 ok
= ifc
== OMP_IF_TARGET_UPDATE
;
4099 case EXEC_OMP_TARGET_ENTER_DATA
:
4100 ok
= ifc
== OMP_IF_TARGET_ENTER_DATA
;
4103 case EXEC_OMP_TARGET_EXIT_DATA
:
4104 ok
= ifc
== OMP_IF_TARGET_EXIT_DATA
;
4107 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO
:
4108 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
4109 case EXEC_OMP_TARGET_PARALLEL
:
4110 case EXEC_OMP_TARGET_PARALLEL_DO
:
4111 case EXEC_OMP_TARGET_PARALLEL_DO_SIMD
:
4112 ok
= ifc
== OMP_IF_TARGET
|| ifc
== OMP_IF_PARALLEL
;
4121 static const char *ifs
[] = {
4128 "TARGET ENTER DATA",
4131 gfc_error ("IF clause modifier %s at %L not appropriate for "
4132 "the current OpenMP construct", ifs
[ifc
], &expr
->where
);
4136 if (omp_clauses
->final_expr
)
4138 gfc_expr
*expr
= omp_clauses
->final_expr
;
4139 if (!gfc_resolve_expr (expr
)
4140 || expr
->ts
.type
!= BT_LOGICAL
|| expr
->rank
!= 0)
4141 gfc_error ("FINAL clause at %L requires a scalar LOGICAL expression",
4144 if (omp_clauses
->num_threads
)
4145 resolve_positive_int_expr (omp_clauses
->num_threads
, "NUM_THREADS");
4146 if (omp_clauses
->chunk_size
)
4148 gfc_expr
*expr
= omp_clauses
->chunk_size
;
4149 if (!gfc_resolve_expr (expr
)
4150 || expr
->ts
.type
!= BT_INTEGER
|| expr
->rank
!= 0)
4151 gfc_error ("SCHEDULE clause's chunk_size at %L requires "
4152 "a scalar INTEGER expression", &expr
->where
);
4153 else if (expr
->expr_type
== EXPR_CONSTANT
4154 && expr
->ts
.type
== BT_INTEGER
4155 && mpz_sgn (expr
->value
.integer
) <= 0)
4156 gfc_warning (0, "INTEGER expression of SCHEDULE clause's chunk_size "
4157 "at %L must be positive", &expr
->where
);
4159 if (omp_clauses
->sched_kind
!= OMP_SCHED_NONE
4160 && omp_clauses
->sched_nonmonotonic
)
4162 if (omp_clauses
->sched_kind
!= OMP_SCHED_DYNAMIC
4163 && omp_clauses
->sched_kind
!= OMP_SCHED_GUIDED
)
4166 switch (omp_clauses
->sched_kind
)
4168 case OMP_SCHED_STATIC
: p
= "STATIC"; break;
4169 case OMP_SCHED_RUNTIME
: p
= "RUNTIME"; break;
4170 case OMP_SCHED_AUTO
: p
= "AUTO"; break;
4171 default: gcc_unreachable ();
4173 gfc_error ("NONMONOTONIC modifier specified for %s schedule kind "
4174 "at %L", p
, &code
->loc
);
4176 else if (omp_clauses
->sched_monotonic
)
4177 gfc_error ("Both MONOTONIC and NONMONOTONIC schedule modifiers "
4178 "specified at %L", &code
->loc
);
4179 else if (omp_clauses
->ordered
)
4180 gfc_error ("NONMONOTONIC schedule modifier specified with ORDERED "
4181 "clause at %L", &code
->loc
);
4184 /* Check that no symbol appears on multiple clauses, except that
4185 a symbol can appear on both firstprivate and lastprivate. */
4186 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
4187 for (n
= omp_clauses
->lists
[list
]; n
; n
= n
->next
)
4190 if (n
->sym
->attr
.flavor
== FL_VARIABLE
4191 || n
->sym
->attr
.proc_pointer
4192 || (!code
&& (!n
->sym
->attr
.dummy
|| n
->sym
->ns
!= ns
)))
4194 if (!code
&& (!n
->sym
->attr
.dummy
|| n
->sym
->ns
!= ns
))
4195 gfc_error ("Variable %qs is not a dummy argument at %L",
4196 n
->sym
->name
, &n
->where
);
4199 if (n
->sym
->attr
.flavor
== FL_PROCEDURE
4200 && n
->sym
->result
== n
->sym
4201 && n
->sym
->attr
.function
)
4203 if (gfc_current_ns
->proc_name
== n
->sym
4204 || (gfc_current_ns
->parent
4205 && gfc_current_ns
->parent
->proc_name
== n
->sym
))
4207 if (gfc_current_ns
->proc_name
->attr
.entry_master
)
4209 gfc_entry_list
*el
= gfc_current_ns
->entries
;
4210 for (; el
; el
= el
->next
)
4211 if (el
->sym
== n
->sym
)
4216 if (gfc_current_ns
->parent
4217 && gfc_current_ns
->parent
->proc_name
->attr
.entry_master
)
4219 gfc_entry_list
*el
= gfc_current_ns
->parent
->entries
;
4220 for (; el
; el
= el
->next
)
4221 if (el
->sym
== n
->sym
)
4227 if (list
== OMP_LIST_MAP
4228 && n
->sym
->attr
.flavor
== FL_PARAMETER
)
4231 gfc_error ("Object %qs is not a variable at %L; parameters"
4232 " cannot be and need not be copied", n
->sym
->name
,
4235 gfc_error ("Object %qs is not a variable at %L; parameters"
4236 " cannot be and need not be mapped", n
->sym
->name
,
4240 gfc_error ("Object %qs is not a variable at %L", n
->sym
->name
,
4244 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
4245 if (list
!= OMP_LIST_FIRSTPRIVATE
4246 && list
!= OMP_LIST_LASTPRIVATE
4247 && list
!= OMP_LIST_ALIGNED
4248 && list
!= OMP_LIST_DEPEND
4249 && (list
!= OMP_LIST_MAP
|| openacc
)
4250 && list
!= OMP_LIST_FROM
4251 && list
!= OMP_LIST_TO
4252 && (list
!= OMP_LIST_REDUCTION
|| !openacc
))
4253 for (n
= omp_clauses
->lists
[list
]; n
; n
= n
->next
)
4256 gfc_error ("Symbol %qs present on multiple clauses at %L",
4257 n
->sym
->name
, &n
->where
);
4262 gcc_assert (OMP_LIST_LASTPRIVATE
== OMP_LIST_FIRSTPRIVATE
+ 1);
4263 for (list
= OMP_LIST_FIRSTPRIVATE
; list
<= OMP_LIST_LASTPRIVATE
; list
++)
4264 for (n
= omp_clauses
->lists
[list
]; n
; n
= n
->next
)
4267 gfc_error ("Symbol %qs present on multiple clauses at %L",
4268 n
->sym
->name
, &n
->where
);
4272 for (n
= omp_clauses
->lists
[OMP_LIST_FIRSTPRIVATE
]; n
; n
= n
->next
)
4275 gfc_error ("Symbol %qs present on multiple clauses at %L",
4276 n
->sym
->name
, &n
->where
);
4280 for (n
= omp_clauses
->lists
[OMP_LIST_LASTPRIVATE
]; n
; n
= n
->next
)
4283 for (n
= omp_clauses
->lists
[OMP_LIST_LASTPRIVATE
]; n
; n
= n
->next
)
4286 gfc_error ("Symbol %qs present on multiple clauses at %L",
4287 n
->sym
->name
, &n
->where
);
4292 for (n
= omp_clauses
->lists
[OMP_LIST_ALIGNED
]; n
; n
= n
->next
)
4295 for (n
= omp_clauses
->lists
[OMP_LIST_ALIGNED
]; n
; n
= n
->next
)
4298 gfc_error ("Symbol %qs present on multiple clauses at %L",
4299 n
->sym
->name
, &n
->where
);
4304 /* OpenACC reductions. */
4307 for (n
= omp_clauses
->lists
[OMP_LIST_REDUCTION
]; n
; n
= n
->next
)
4310 for (n
= omp_clauses
->lists
[OMP_LIST_REDUCTION
]; n
; n
= n
->next
)
4313 gfc_error ("Symbol %qs present on multiple clauses at %L",
4314 n
->sym
->name
, &n
->where
);
4318 /* OpenACC does not support reductions on arrays. */
4320 gfc_error ("Array %qs is not permitted in reduction at %L",
4321 n
->sym
->name
, &n
->where
);
4325 for (n
= omp_clauses
->lists
[OMP_LIST_TO
]; n
; n
= n
->next
)
4327 for (n
= omp_clauses
->lists
[OMP_LIST_FROM
]; n
; n
= n
->next
)
4328 if (n
->expr
== NULL
)
4330 for (n
= omp_clauses
->lists
[OMP_LIST_TO
]; n
; n
= n
->next
)
4332 if (n
->expr
== NULL
&& n
->sym
->mark
)
4333 gfc_error ("Symbol %qs present on both FROM and TO clauses at %L",
4334 n
->sym
->name
, &n
->where
);
4339 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
4340 if ((n
= omp_clauses
->lists
[list
]) != NULL
)
4344 if (list
< OMP_LIST_NUM
)
4345 name
= clause_names
[list
];
4351 case OMP_LIST_COPYIN
:
4352 for (; n
!= NULL
; n
= n
->next
)
4354 if (!n
->sym
->attr
.threadprivate
)
4355 gfc_error ("Non-THREADPRIVATE object %qs in COPYIN clause"
4356 " at %L", n
->sym
->name
, &n
->where
);
4359 case OMP_LIST_COPYPRIVATE
:
4360 for (; n
!= NULL
; n
= n
->next
)
4362 if (n
->sym
->as
&& n
->sym
->as
->type
== AS_ASSUMED_SIZE
)
4363 gfc_error ("Assumed size array %qs in COPYPRIVATE clause "
4364 "at %L", n
->sym
->name
, &n
->where
);
4365 if (n
->sym
->attr
.pointer
&& n
->sym
->attr
.intent
== INTENT_IN
)
4366 gfc_error ("INTENT(IN) POINTER %qs in COPYPRIVATE clause "
4367 "at %L", n
->sym
->name
, &n
->where
);
4370 case OMP_LIST_SHARED
:
4371 for (; n
!= NULL
; n
= n
->next
)
4373 if (n
->sym
->attr
.threadprivate
)
4374 gfc_error ("THREADPRIVATE object %qs in SHARED clause at "
4375 "%L", n
->sym
->name
, &n
->where
);
4376 if (n
->sym
->attr
.cray_pointee
)
4377 gfc_error ("Cray pointee %qs in SHARED clause at %L",
4378 n
->sym
->name
, &n
->where
);
4379 if (n
->sym
->attr
.associate_var
)
4380 gfc_error ("ASSOCIATE name %qs in SHARED clause at %L",
4381 n
->sym
->name
, &n
->where
);
4384 case OMP_LIST_ALIGNED
:
4385 for (; n
!= NULL
; n
= n
->next
)
4387 if (!n
->sym
->attr
.pointer
4388 && !n
->sym
->attr
.allocatable
4389 && !n
->sym
->attr
.cray_pointer
4390 && (n
->sym
->ts
.type
!= BT_DERIVED
4391 || (n
->sym
->ts
.u
.derived
->from_intmod
4392 != INTMOD_ISO_C_BINDING
)
4393 || (n
->sym
->ts
.u
.derived
->intmod_sym_id
4394 != ISOCBINDING_PTR
)))
4395 gfc_error ("%qs in ALIGNED clause must be POINTER, "
4396 "ALLOCATABLE, Cray pointer or C_PTR at %L",
4397 n
->sym
->name
, &n
->where
);
4400 gfc_expr
*expr
= n
->expr
;
4402 if (!gfc_resolve_expr (expr
)
4403 || expr
->ts
.type
!= BT_INTEGER
4405 || gfc_extract_int (expr
, &alignment
)
4407 gfc_error ("%qs in ALIGNED clause at %L requires a scalar "
4408 "positive constant integer alignment "
4409 "expression", n
->sym
->name
, &n
->where
);
4413 case OMP_LIST_DEPEND
:
4417 case OMP_LIST_CACHE
:
4418 for (; n
!= NULL
; n
= n
->next
)
4420 if (list
== OMP_LIST_DEPEND
)
4422 if (n
->u
.depend_op
== OMP_DEPEND_SINK_FIRST
4423 || n
->u
.depend_op
== OMP_DEPEND_SINK
)
4425 if (code
->op
!= EXEC_OMP_ORDERED
)
4426 gfc_error ("SINK dependence type only allowed "
4427 "on ORDERED directive at %L", &n
->where
);
4428 else if (omp_clauses
->depend_source
)
4430 gfc_error ("DEPEND SINK used together with "
4431 "DEPEND SOURCE on the same construct "
4432 "at %L", &n
->where
);
4433 omp_clauses
->depend_source
= false;
4437 if (!gfc_resolve_expr (n
->expr
)
4438 || n
->expr
->ts
.type
!= BT_INTEGER
4439 || n
->expr
->rank
!= 0)
4440 gfc_error ("SINK addend not a constant integer "
4441 "at %L", &n
->where
);
4445 else if (code
->op
== EXEC_OMP_ORDERED
)
4446 gfc_error ("Only SOURCE or SINK dependence types "
4447 "are allowed on ORDERED directive at %L",
4452 if (!gfc_resolve_expr (n
->expr
)
4453 || n
->expr
->expr_type
!= EXPR_VARIABLE
4454 || n
->expr
->ref
== NULL
4455 || n
->expr
->ref
->next
4456 || n
->expr
->ref
->type
!= REF_ARRAY
)
4457 gfc_error ("%qs in %s clause at %L is not a proper "
4458 "array section", n
->sym
->name
, name
,
4460 else if (n
->expr
->ref
->u
.ar
.codimen
)
4461 gfc_error ("Coarrays not supported in %s clause at %L",
4466 gfc_array_ref
*ar
= &n
->expr
->ref
->u
.ar
;
4467 for (i
= 0; i
< ar
->dimen
; i
++)
4470 gfc_error ("Stride should not be specified for "
4471 "array section in %s clause at %L",
4475 else if (ar
->dimen_type
[i
] != DIMEN_ELEMENT
4476 && ar
->dimen_type
[i
] != DIMEN_RANGE
)
4478 gfc_error ("%qs in %s clause at %L is not a "
4479 "proper array section",
4480 n
->sym
->name
, name
, &n
->where
);
4483 else if (list
== OMP_LIST_DEPEND
4485 && ar
->start
[i
]->expr_type
== EXPR_CONSTANT
4487 && ar
->end
[i
]->expr_type
== EXPR_CONSTANT
4488 && mpz_cmp (ar
->start
[i
]->value
.integer
,
4489 ar
->end
[i
]->value
.integer
) > 0)
4491 gfc_error ("%qs in DEPEND clause at %L is a "
4492 "zero size array section",
4493 n
->sym
->name
, &n
->where
);
4500 if (list
== OMP_LIST_MAP
4501 && n
->u
.map_op
== OMP_MAP_FORCE_DEVICEPTR
)
4502 resolve_oacc_deviceptr_clause (n
->sym
, n
->where
, name
);
4504 resolve_oacc_data_clauses (n
->sym
, n
->where
, name
);
4506 else if (list
!= OMP_LIST_DEPEND
4508 && n
->sym
->as
->type
== AS_ASSUMED_SIZE
)
4509 gfc_error ("Assumed size array %qs in %s clause at %L",
4510 n
->sym
->name
, name
, &n
->where
);
4511 if (list
== OMP_LIST_MAP
&& !openacc
)
4514 case EXEC_OMP_TARGET
:
4515 case EXEC_OMP_TARGET_DATA
:
4516 switch (n
->u
.map_op
)
4519 case OMP_MAP_ALWAYS_TO
:
4521 case OMP_MAP_ALWAYS_FROM
:
4522 case OMP_MAP_TOFROM
:
4523 case OMP_MAP_ALWAYS_TOFROM
:
4527 gfc_error ("TARGET%s with map-type other than TO, "
4528 "FROM, TOFROM, or ALLOC on MAP clause "
4530 code
->op
== EXEC_OMP_TARGET
4531 ? "" : " DATA", &n
->where
);
4535 case EXEC_OMP_TARGET_ENTER_DATA
:
4536 switch (n
->u
.map_op
)
4539 case OMP_MAP_ALWAYS_TO
:
4543 gfc_error ("TARGET ENTER DATA with map-type other "
4544 "than TO, or ALLOC on MAP clause at %L",
4549 case EXEC_OMP_TARGET_EXIT_DATA
:
4550 switch (n
->u
.map_op
)
4553 case OMP_MAP_ALWAYS_FROM
:
4554 case OMP_MAP_RELEASE
:
4555 case OMP_MAP_DELETE
:
4558 gfc_error ("TARGET EXIT DATA with map-type other "
4559 "than FROM, RELEASE, or DELETE on MAP "
4560 "clause at %L", &n
->where
);
4569 if (list
!= OMP_LIST_DEPEND
)
4570 for (n
= omp_clauses
->lists
[list
]; n
!= NULL
; n
= n
->next
)
4572 n
->sym
->attr
.referenced
= 1;
4573 if (n
->sym
->attr
.threadprivate
)
4574 gfc_error ("THREADPRIVATE object %qs in %s clause at %L",
4575 n
->sym
->name
, name
, &n
->where
);
4576 if (n
->sym
->attr
.cray_pointee
)
4577 gfc_error ("Cray pointee %qs in %s clause at %L",
4578 n
->sym
->name
, name
, &n
->where
);
4581 case OMP_LIST_IS_DEVICE_PTR
:
4582 if (!n
->sym
->attr
.dummy
)
4583 gfc_error ("Non-dummy object %qs in %s clause at %L",
4584 n
->sym
->name
, name
, &n
->where
);
4585 if (n
->sym
->attr
.allocatable
4586 || (n
->sym
->ts
.type
== BT_CLASS
4587 && CLASS_DATA (n
->sym
)->attr
.allocatable
))
4588 gfc_error ("ALLOCATABLE object %qs in %s clause at %L",
4589 n
->sym
->name
, name
, &n
->where
);
4590 if (n
->sym
->attr
.pointer
4591 || (n
->sym
->ts
.type
== BT_CLASS
4592 && CLASS_DATA (n
->sym
)->attr
.pointer
))
4593 gfc_error ("POINTER object %qs in %s clause at %L",
4594 n
->sym
->name
, name
, &n
->where
);
4595 if (n
->sym
->attr
.value
)
4596 gfc_error ("VALUE object %qs in %s clause at %L",
4597 n
->sym
->name
, name
, &n
->where
);
4599 case OMP_LIST_USE_DEVICE_PTR
:
4600 case OMP_LIST_USE_DEVICE_ADDR
:
4601 /* FIXME: Handle OMP_LIST_USE_DEVICE_PTR. */
4604 for (; n
!= NULL
; n
= n
->next
)
4607 if (n
->sym
->attr
.threadprivate
)
4608 gfc_error ("THREADPRIVATE object %qs in %s clause at %L",
4609 n
->sym
->name
, name
, &n
->where
);
4610 if (n
->sym
->attr
.cray_pointee
)
4611 gfc_error ("Cray pointee %qs in %s clause at %L",
4612 n
->sym
->name
, name
, &n
->where
);
4613 if (n
->sym
->attr
.associate_var
)
4614 gfc_error ("ASSOCIATE name %qs in %s clause at %L",
4615 n
->sym
->name
, name
, &n
->where
);
4616 if (list
!= OMP_LIST_PRIVATE
)
4618 if (n
->sym
->attr
.proc_pointer
&& list
== OMP_LIST_REDUCTION
)
4619 gfc_error ("Procedure pointer %qs in %s clause at %L",
4620 n
->sym
->name
, name
, &n
->where
);
4621 if (n
->sym
->attr
.pointer
&& list
== OMP_LIST_REDUCTION
)
4622 gfc_error ("POINTER object %qs in %s clause at %L",
4623 n
->sym
->name
, name
, &n
->where
);
4624 if (n
->sym
->attr
.cray_pointer
&& list
== OMP_LIST_REDUCTION
)
4625 gfc_error ("Cray pointer %qs in %s clause at %L",
4626 n
->sym
->name
, name
, &n
->where
);
4629 && (oacc_is_loop (code
) || code
->op
== EXEC_OACC_PARALLEL
))
4630 check_array_not_assumed (n
->sym
, n
->where
, name
);
4631 else if (n
->sym
->as
&& n
->sym
->as
->type
== AS_ASSUMED_SIZE
)
4632 gfc_error ("Assumed size array %qs in %s clause at %L",
4633 n
->sym
->name
, name
, &n
->where
);
4634 if (n
->sym
->attr
.in_namelist
&& list
!= OMP_LIST_REDUCTION
)
4635 gfc_error ("Variable %qs in %s clause is used in "
4636 "NAMELIST statement at %L",
4637 n
->sym
->name
, name
, &n
->where
);
4638 if (n
->sym
->attr
.pointer
&& n
->sym
->attr
.intent
== INTENT_IN
)
4641 case OMP_LIST_PRIVATE
:
4642 case OMP_LIST_LASTPRIVATE
:
4643 case OMP_LIST_LINEAR
:
4644 /* case OMP_LIST_REDUCTION: */
4645 gfc_error ("INTENT(IN) POINTER %qs in %s clause at %L",
4646 n
->sym
->name
, name
, &n
->where
);
4654 case OMP_LIST_REDUCTION
:
4655 switch (n
->u
.reduction_op
)
4657 case OMP_REDUCTION_PLUS
:
4658 case OMP_REDUCTION_TIMES
:
4659 case OMP_REDUCTION_MINUS
:
4660 if (!gfc_numeric_ts (&n
->sym
->ts
))
4663 case OMP_REDUCTION_AND
:
4664 case OMP_REDUCTION_OR
:
4665 case OMP_REDUCTION_EQV
:
4666 case OMP_REDUCTION_NEQV
:
4667 if (n
->sym
->ts
.type
!= BT_LOGICAL
)
4670 case OMP_REDUCTION_MAX
:
4671 case OMP_REDUCTION_MIN
:
4672 if (n
->sym
->ts
.type
!= BT_INTEGER
4673 && n
->sym
->ts
.type
!= BT_REAL
)
4676 case OMP_REDUCTION_IAND
:
4677 case OMP_REDUCTION_IOR
:
4678 case OMP_REDUCTION_IEOR
:
4679 if (n
->sym
->ts
.type
!= BT_INTEGER
)
4682 case OMP_REDUCTION_USER
:
4692 const char *udr_name
= NULL
;
4695 udr_name
= n
->udr
->udr
->name
;
4697 = gfc_find_omp_udr (NULL
, udr_name
,
4699 if (n
->udr
->udr
== NULL
)
4707 if (udr_name
== NULL
)
4708 switch (n
->u
.reduction_op
)
4710 case OMP_REDUCTION_PLUS
:
4711 case OMP_REDUCTION_TIMES
:
4712 case OMP_REDUCTION_MINUS
:
4713 case OMP_REDUCTION_AND
:
4714 case OMP_REDUCTION_OR
:
4715 case OMP_REDUCTION_EQV
:
4716 case OMP_REDUCTION_NEQV
:
4717 udr_name
= gfc_op2string ((gfc_intrinsic_op
)
4720 case OMP_REDUCTION_MAX
:
4723 case OMP_REDUCTION_MIN
:
4726 case OMP_REDUCTION_IAND
:
4729 case OMP_REDUCTION_IOR
:
4732 case OMP_REDUCTION_IEOR
:
4738 gfc_error ("!$OMP DECLARE REDUCTION %s not found "
4739 "for type %s at %L", udr_name
,
4740 gfc_typename (&n
->sym
->ts
), &n
->where
);
4744 gfc_omp_udr
*udr
= n
->udr
->udr
;
4745 n
->u
.reduction_op
= OMP_REDUCTION_USER
;
4747 = resolve_omp_udr_clause (n
, udr
->combiner_ns
,
4750 if (udr
->initializer_ns
)
4752 = resolve_omp_udr_clause (n
,
4753 udr
->initializer_ns
,
4759 case OMP_LIST_LINEAR
:
4761 && n
->u
.linear_op
!= OMP_LINEAR_DEFAULT
4762 && n
->u
.linear_op
!= linear_op
)
4764 gfc_error ("LINEAR clause modifier used on DO or SIMD"
4765 " construct at %L", &n
->where
);
4766 linear_op
= n
->u
.linear_op
;
4768 else if (omp_clauses
->orderedc
)
4769 gfc_error ("LINEAR clause specified together with "
4770 "ORDERED clause with argument at %L",
4772 else if (n
->u
.linear_op
!= OMP_LINEAR_REF
4773 && n
->sym
->ts
.type
!= BT_INTEGER
)
4774 gfc_error ("LINEAR variable %qs must be INTEGER "
4775 "at %L", n
->sym
->name
, &n
->where
);
4776 else if ((n
->u
.linear_op
== OMP_LINEAR_REF
4777 || n
->u
.linear_op
== OMP_LINEAR_UVAL
)
4778 && n
->sym
->attr
.value
)
4779 gfc_error ("LINEAR dummy argument %qs with VALUE "
4780 "attribute with %s modifier at %L",
4782 n
->u
.linear_op
== OMP_LINEAR_REF
4783 ? "REF" : "UVAL", &n
->where
);
4786 gfc_expr
*expr
= n
->expr
;
4787 if (!gfc_resolve_expr (expr
)
4788 || expr
->ts
.type
!= BT_INTEGER
4790 gfc_error ("%qs in LINEAR clause at %L requires "
4791 "a scalar integer linear-step expression",
4792 n
->sym
->name
, &n
->where
);
4793 else if (!code
&& expr
->expr_type
!= EXPR_CONSTANT
)
4795 if (expr
->expr_type
== EXPR_VARIABLE
4796 && expr
->symtree
->n
.sym
->attr
.dummy
4797 && expr
->symtree
->n
.sym
->ns
== ns
)
4799 gfc_omp_namelist
*n2
;
4800 for (n2
= omp_clauses
->lists
[OMP_LIST_UNIFORM
];
4802 if (n2
->sym
== expr
->symtree
->n
.sym
)
4807 gfc_error ("%qs in LINEAR clause at %L requires "
4808 "a constant integer linear-step "
4809 "expression or dummy argument "
4810 "specified in UNIFORM clause",
4811 n
->sym
->name
, &n
->where
);
4815 /* Workaround for PR middle-end/26316, nothing really needs
4816 to be done here for OMP_LIST_PRIVATE. */
4817 case OMP_LIST_PRIVATE
:
4818 gcc_assert (code
&& code
->op
!= EXEC_NOP
);
4820 case OMP_LIST_USE_DEVICE
:
4821 if (n
->sym
->attr
.allocatable
4822 || (n
->sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (n
->sym
)
4823 && CLASS_DATA (n
->sym
)->attr
.allocatable
))
4824 gfc_error ("ALLOCATABLE object %qs in %s clause at %L",
4825 n
->sym
->name
, name
, &n
->where
);
4826 if (n
->sym
->ts
.type
== BT_CLASS
4827 && CLASS_DATA (n
->sym
)
4828 && CLASS_DATA (n
->sym
)->attr
.class_pointer
)
4829 gfc_error ("POINTER object %qs of polymorphic type in "
4830 "%s clause at %L", n
->sym
->name
, name
,
4832 if (n
->sym
->attr
.cray_pointer
)
4833 gfc_error ("Cray pointer object %qs in %s clause at %L",
4834 n
->sym
->name
, name
, &n
->where
);
4835 else if (n
->sym
->attr
.cray_pointee
)
4836 gfc_error ("Cray pointee object %qs in %s clause at %L",
4837 n
->sym
->name
, name
, &n
->where
);
4838 else if (n
->sym
->attr
.flavor
== FL_VARIABLE
4840 && !n
->sym
->attr
.pointer
)
4841 gfc_error ("%s clause variable %qs at %L is neither "
4842 "a POINTER nor an array", name
,
4843 n
->sym
->name
, &n
->where
);
4845 case OMP_LIST_DEVICE_RESIDENT
:
4846 check_symbol_not_pointer (n
->sym
, n
->where
, name
);
4847 check_array_not_assumed (n
->sym
, n
->where
, name
);
4856 if (omp_clauses
->safelen_expr
)
4857 resolve_positive_int_expr (omp_clauses
->safelen_expr
, "SAFELEN");
4858 if (omp_clauses
->simdlen_expr
)
4859 resolve_positive_int_expr (omp_clauses
->simdlen_expr
, "SIMDLEN");
4860 if (omp_clauses
->num_teams
)
4861 resolve_positive_int_expr (omp_clauses
->num_teams
, "NUM_TEAMS");
4862 if (omp_clauses
->device
)
4863 resolve_nonnegative_int_expr (omp_clauses
->device
, "DEVICE");
4864 if (omp_clauses
->hint
)
4865 resolve_scalar_int_expr (omp_clauses
->hint
, "HINT");
4866 if (omp_clauses
->priority
)
4867 resolve_nonnegative_int_expr (omp_clauses
->priority
, "PRIORITY");
4868 if (omp_clauses
->dist_chunk_size
)
4870 gfc_expr
*expr
= omp_clauses
->dist_chunk_size
;
4871 if (!gfc_resolve_expr (expr
)
4872 || expr
->ts
.type
!= BT_INTEGER
|| expr
->rank
!= 0)
4873 gfc_error ("DIST_SCHEDULE clause's chunk_size at %L requires "
4874 "a scalar INTEGER expression", &expr
->where
);
4876 if (omp_clauses
->thread_limit
)
4877 resolve_positive_int_expr (omp_clauses
->thread_limit
, "THREAD_LIMIT");
4878 if (omp_clauses
->grainsize
)
4879 resolve_positive_int_expr (omp_clauses
->grainsize
, "GRAINSIZE");
4880 if (omp_clauses
->num_tasks
)
4881 resolve_positive_int_expr (omp_clauses
->num_tasks
, "NUM_TASKS");
4882 if (omp_clauses
->async
)
4883 if (omp_clauses
->async_expr
)
4884 resolve_scalar_int_expr (omp_clauses
->async_expr
, "ASYNC");
4885 if (omp_clauses
->num_gangs_expr
)
4886 resolve_positive_int_expr (omp_clauses
->num_gangs_expr
, "NUM_GANGS");
4887 if (omp_clauses
->num_workers_expr
)
4888 resolve_positive_int_expr (omp_clauses
->num_workers_expr
, "NUM_WORKERS");
4889 if (omp_clauses
->vector_length_expr
)
4890 resolve_positive_int_expr (omp_clauses
->vector_length_expr
,
4892 if (omp_clauses
->gang_num_expr
)
4893 resolve_positive_int_expr (omp_clauses
->gang_num_expr
, "GANG");
4894 if (omp_clauses
->gang_static_expr
)
4895 resolve_positive_int_expr (omp_clauses
->gang_static_expr
, "GANG");
4896 if (omp_clauses
->worker_expr
)
4897 resolve_positive_int_expr (omp_clauses
->worker_expr
, "WORKER");
4898 if (omp_clauses
->vector_expr
)
4899 resolve_positive_int_expr (omp_clauses
->vector_expr
, "VECTOR");
4900 for (el
= omp_clauses
->wait_list
; el
; el
= el
->next
)
4901 resolve_scalar_int_expr (el
->expr
, "WAIT");
4902 if (omp_clauses
->collapse
&& omp_clauses
->tile_list
)
4903 gfc_error ("Incompatible use of TILE and COLLAPSE at %L", &code
->loc
);
4904 if (omp_clauses
->depend_source
&& code
->op
!= EXEC_OMP_ORDERED
)
4905 gfc_error ("SOURCE dependence type only allowed "
4906 "on ORDERED directive at %L", &code
->loc
);
4907 if (!openacc
&& code
&& omp_clauses
->lists
[OMP_LIST_MAP
] == NULL
)
4909 const char *p
= NULL
;
4912 case EXEC_OMP_TARGET_DATA
: p
= "TARGET DATA"; break;
4913 case EXEC_OMP_TARGET_ENTER_DATA
: p
= "TARGET ENTER DATA"; break;
4914 case EXEC_OMP_TARGET_EXIT_DATA
: p
= "TARGET EXIT DATA"; break;
4918 gfc_error ("%s must contain at least one MAP clause at %L",
4924 /* Return true if SYM is ever referenced in EXPR except in the SE node. */
4927 expr_references_sym (gfc_expr
*e
, gfc_symbol
*s
, gfc_expr
*se
)
4929 gfc_actual_arglist
*arg
;
4930 if (e
== NULL
|| e
== se
)
4932 switch (e
->expr_type
)
4937 case EXPR_STRUCTURE
:
4939 if (e
->symtree
!= NULL
4940 && e
->symtree
->n
.sym
== s
)
4943 case EXPR_SUBSTRING
:
4945 && (expr_references_sym (e
->ref
->u
.ss
.start
, s
, se
)
4946 || expr_references_sym (e
->ref
->u
.ss
.end
, s
, se
)))
4950 if (expr_references_sym (e
->value
.op
.op2
, s
, se
))
4952 return expr_references_sym (e
->value
.op
.op1
, s
, se
);
4954 for (arg
= e
->value
.function
.actual
; arg
; arg
= arg
->next
)
4955 if (expr_references_sym (arg
->expr
, s
, se
))
4964 /* If EXPR is a conversion function that widens the type
4965 if WIDENING is true or narrows the type if WIDENING is false,
4966 return the inner expression, otherwise return NULL. */
4969 is_conversion (gfc_expr
*expr
, bool widening
)
4971 gfc_typespec
*ts1
, *ts2
;
4973 if (expr
->expr_type
!= EXPR_FUNCTION
4974 || expr
->value
.function
.isym
== NULL
4975 || expr
->value
.function
.esym
!= NULL
4976 || expr
->value
.function
.isym
->id
!= GFC_ISYM_CONVERSION
)
4982 ts2
= &expr
->value
.function
.actual
->expr
->ts
;
4986 ts1
= &expr
->value
.function
.actual
->expr
->ts
;
4990 if (ts1
->type
> ts2
->type
4991 || (ts1
->type
== ts2
->type
&& ts1
->kind
> ts2
->kind
))
4992 return expr
->value
.function
.actual
->expr
;
4999 resolve_omp_atomic (gfc_code
*code
)
5001 gfc_code
*atomic_code
= code
;
5003 gfc_expr
*expr2
, *expr2_tmp
;
5004 gfc_omp_atomic_op aop
5005 = (gfc_omp_atomic_op
) (atomic_code
->ext
.omp_atomic
& GFC_OMP_ATOMIC_MASK
);
5007 code
= code
->block
->next
;
5008 /* resolve_blocks asserts this is initially EXEC_ASSIGN.
5009 If it changed to EXEC_NOP, assume an error has been emitted already. */
5010 if (code
->op
== EXEC_NOP
)
5012 if (code
->op
!= EXEC_ASSIGN
)
5015 gfc_error ("unexpected !$OMP ATOMIC expression at %L", &code
->loc
);
5018 if (aop
!= GFC_OMP_ATOMIC_CAPTURE
)
5020 if (code
->next
!= NULL
)
5025 if (code
->next
== NULL
)
5027 if (code
->next
->op
== EXEC_NOP
)
5029 if (code
->next
->op
!= EXEC_ASSIGN
|| code
->next
->next
)
5036 if (code
->expr1
->expr_type
!= EXPR_VARIABLE
5037 || code
->expr1
->symtree
== NULL
5038 || code
->expr1
->rank
!= 0
5039 || (code
->expr1
->ts
.type
!= BT_INTEGER
5040 && code
->expr1
->ts
.type
!= BT_REAL
5041 && code
->expr1
->ts
.type
!= BT_COMPLEX
5042 && code
->expr1
->ts
.type
!= BT_LOGICAL
))
5044 gfc_error ("!$OMP ATOMIC statement must set a scalar variable of "
5045 "intrinsic type at %L", &code
->loc
);
5049 var
= code
->expr1
->symtree
->n
.sym
;
5050 expr2
= is_conversion (code
->expr2
, false);
5053 if (aop
== GFC_OMP_ATOMIC_READ
|| aop
== GFC_OMP_ATOMIC_WRITE
)
5054 expr2
= is_conversion (code
->expr2
, true);
5056 expr2
= code
->expr2
;
5061 case GFC_OMP_ATOMIC_READ
:
5062 if (expr2
->expr_type
!= EXPR_VARIABLE
5063 || expr2
->symtree
== NULL
5065 || (expr2
->ts
.type
!= BT_INTEGER
5066 && expr2
->ts
.type
!= BT_REAL
5067 && expr2
->ts
.type
!= BT_COMPLEX
5068 && expr2
->ts
.type
!= BT_LOGICAL
))
5069 gfc_error ("!$OMP ATOMIC READ statement must read from a scalar "
5070 "variable of intrinsic type at %L", &expr2
->where
);
5072 case GFC_OMP_ATOMIC_WRITE
:
5073 if (expr2
->rank
!= 0 || expr_references_sym (code
->expr2
, var
, NULL
))
5074 gfc_error ("expr in !$OMP ATOMIC WRITE assignment var = expr "
5075 "must be scalar and cannot reference var at %L",
5078 case GFC_OMP_ATOMIC_CAPTURE
:
5080 if (expr2
== code
->expr2
)
5082 expr2_tmp
= is_conversion (code
->expr2
, true);
5083 if (expr2_tmp
== NULL
)
5086 if (expr2_tmp
->expr_type
== EXPR_VARIABLE
)
5088 if (expr2_tmp
->symtree
== NULL
5089 || expr2_tmp
->rank
!= 0
5090 || (expr2_tmp
->ts
.type
!= BT_INTEGER
5091 && expr2_tmp
->ts
.type
!= BT_REAL
5092 && expr2_tmp
->ts
.type
!= BT_COMPLEX
5093 && expr2_tmp
->ts
.type
!= BT_LOGICAL
)
5094 || expr2_tmp
->symtree
->n
.sym
== var
)
5096 gfc_error ("!$OMP ATOMIC CAPTURE capture statement must read from "
5097 "a scalar variable of intrinsic type at %L",
5101 var
= expr2_tmp
->symtree
->n
.sym
;
5103 if (code
->expr1
->expr_type
!= EXPR_VARIABLE
5104 || code
->expr1
->symtree
== NULL
5105 || code
->expr1
->rank
!= 0
5106 || (code
->expr1
->ts
.type
!= BT_INTEGER
5107 && code
->expr1
->ts
.type
!= BT_REAL
5108 && code
->expr1
->ts
.type
!= BT_COMPLEX
5109 && code
->expr1
->ts
.type
!= BT_LOGICAL
))
5111 gfc_error ("!$OMP ATOMIC CAPTURE update statement must set "
5112 "a scalar variable of intrinsic type at %L",
5113 &code
->expr1
->where
);
5116 if (code
->expr1
->symtree
->n
.sym
!= var
)
5118 gfc_error ("!$OMP ATOMIC CAPTURE capture statement reads from "
5119 "different variable than update statement writes "
5120 "into at %L", &code
->expr1
->where
);
5123 expr2
= is_conversion (code
->expr2
, false);
5125 expr2
= code
->expr2
;
5132 if (gfc_expr_attr (code
->expr1
).allocatable
)
5134 gfc_error ("!$OMP ATOMIC with ALLOCATABLE variable at %L",
5139 if (aop
== GFC_OMP_ATOMIC_CAPTURE
5140 && code
->next
== NULL
5141 && code
->expr2
->rank
== 0
5142 && !expr_references_sym (code
->expr2
, var
, NULL
))
5143 atomic_code
->ext
.omp_atomic
5144 = (gfc_omp_atomic_op
) (atomic_code
->ext
.omp_atomic
5145 | GFC_OMP_ATOMIC_SWAP
);
5146 else if (expr2
->expr_type
== EXPR_OP
)
5148 gfc_expr
*v
= NULL
, *e
, *c
;
5149 gfc_intrinsic_op op
= expr2
->value
.op
.op
;
5150 gfc_intrinsic_op alt_op
= INTRINSIC_NONE
;
5154 case INTRINSIC_PLUS
:
5155 alt_op
= INTRINSIC_MINUS
;
5157 case INTRINSIC_TIMES
:
5158 alt_op
= INTRINSIC_DIVIDE
;
5160 case INTRINSIC_MINUS
:
5161 alt_op
= INTRINSIC_PLUS
;
5163 case INTRINSIC_DIVIDE
:
5164 alt_op
= INTRINSIC_TIMES
;
5170 alt_op
= INTRINSIC_NEQV
;
5172 case INTRINSIC_NEQV
:
5173 alt_op
= INTRINSIC_EQV
;
5176 gfc_error ("!$OMP ATOMIC assignment operator must be binary "
5177 "+, *, -, /, .AND., .OR., .EQV. or .NEQV. at %L",
5182 /* Check for var = var op expr resp. var = expr op var where
5183 expr doesn't reference var and var op expr is mathematically
5184 equivalent to var op (expr) resp. expr op var equivalent to
5185 (expr) op var. We rely here on the fact that the matcher
5186 for x op1 y op2 z where op1 and op2 have equal precedence
5187 returns (x op1 y) op2 z. */
5188 e
= expr2
->value
.op
.op2
;
5189 if (e
->expr_type
== EXPR_VARIABLE
5190 && e
->symtree
!= NULL
5191 && e
->symtree
->n
.sym
== var
)
5193 else if ((c
= is_conversion (e
, true)) != NULL
5194 && c
->expr_type
== EXPR_VARIABLE
5195 && c
->symtree
!= NULL
5196 && c
->symtree
->n
.sym
== var
)
5200 gfc_expr
**p
= NULL
, **q
;
5201 for (q
= &expr2
->value
.op
.op1
; (e
= *q
) != NULL
; )
5202 if (e
->expr_type
== EXPR_VARIABLE
5203 && e
->symtree
!= NULL
5204 && e
->symtree
->n
.sym
== var
)
5209 else if ((c
= is_conversion (e
, true)) != NULL
)
5210 q
= &e
->value
.function
.actual
->expr
;
5211 else if (e
->expr_type
!= EXPR_OP
5212 || (e
->value
.op
.op
!= op
5213 && e
->value
.op
.op
!= alt_op
)
5219 q
= &e
->value
.op
.op1
;
5224 gfc_error ("!$OMP ATOMIC assignment must be var = var op expr "
5225 "or var = expr op var at %L", &expr2
->where
);
5232 switch (e
->value
.op
.op
)
5234 case INTRINSIC_MINUS
:
5235 case INTRINSIC_DIVIDE
:
5237 case INTRINSIC_NEQV
:
5238 gfc_error ("!$OMP ATOMIC var = var op expr not "
5239 "mathematically equivalent to var = var op "
5240 "(expr) at %L", &expr2
->where
);
5246 /* Canonicalize into var = var op (expr). */
5247 *p
= e
->value
.op
.op2
;
5248 e
->value
.op
.op2
= expr2
;
5250 if (code
->expr2
== expr2
)
5251 code
->expr2
= expr2
= e
;
5253 code
->expr2
->value
.function
.actual
->expr
= expr2
= e
;
5255 if (!gfc_compare_types (&expr2
->value
.op
.op1
->ts
, &expr2
->ts
))
5257 for (p
= &expr2
->value
.op
.op1
; *p
!= v
;
5258 p
= &(*p
)->value
.function
.actual
->expr
)
5261 gfc_free_expr (expr2
->value
.op
.op1
);
5262 expr2
->value
.op
.op1
= v
;
5263 gfc_convert_type (v
, &expr2
->ts
, 2);
5268 if (e
->rank
!= 0 || expr_references_sym (code
->expr2
, var
, v
))
5270 gfc_error ("expr in !$OMP ATOMIC assignment var = var op expr "
5271 "must be scalar and cannot reference var at %L",
5276 else if (expr2
->expr_type
== EXPR_FUNCTION
5277 && expr2
->value
.function
.isym
!= NULL
5278 && expr2
->value
.function
.esym
== NULL
5279 && expr2
->value
.function
.actual
!= NULL
5280 && expr2
->value
.function
.actual
->next
!= NULL
)
5282 gfc_actual_arglist
*arg
, *var_arg
;
5284 switch (expr2
->value
.function
.isym
->id
)
5292 if (expr2
->value
.function
.actual
->next
->next
!= NULL
)
5294 gfc_error ("!$OMP ATOMIC assignment intrinsic IAND, IOR "
5295 "or IEOR must have two arguments at %L",
5301 gfc_error ("!$OMP ATOMIC assignment intrinsic must be "
5302 "MIN, MAX, IAND, IOR or IEOR at %L",
5308 for (arg
= expr2
->value
.function
.actual
; arg
; arg
= arg
->next
)
5310 if ((arg
== expr2
->value
.function
.actual
5311 || (var_arg
== NULL
&& arg
->next
== NULL
))
5312 && arg
->expr
->expr_type
== EXPR_VARIABLE
5313 && arg
->expr
->symtree
!= NULL
5314 && arg
->expr
->symtree
->n
.sym
== var
)
5316 else if (expr_references_sym (arg
->expr
, var
, NULL
))
5318 gfc_error ("!$OMP ATOMIC intrinsic arguments except one must "
5319 "not reference %qs at %L",
5320 var
->name
, &arg
->expr
->where
);
5323 if (arg
->expr
->rank
!= 0)
5325 gfc_error ("!$OMP ATOMIC intrinsic arguments must be scalar "
5326 "at %L", &arg
->expr
->where
);
5331 if (var_arg
== NULL
)
5333 gfc_error ("First or last !$OMP ATOMIC intrinsic argument must "
5334 "be %qs at %L", var
->name
, &expr2
->where
);
5338 if (var_arg
!= expr2
->value
.function
.actual
)
5340 /* Canonicalize, so that var comes first. */
5341 gcc_assert (var_arg
->next
== NULL
);
5342 for (arg
= expr2
->value
.function
.actual
;
5343 arg
->next
!= var_arg
; arg
= arg
->next
)
5345 var_arg
->next
= expr2
->value
.function
.actual
;
5346 expr2
->value
.function
.actual
= var_arg
;
5351 gfc_error ("!$OMP ATOMIC assignment must have an operator or "
5352 "intrinsic on right hand side at %L", &expr2
->where
);
5354 if (aop
== GFC_OMP_ATOMIC_CAPTURE
&& code
->next
)
5357 if (code
->expr1
->expr_type
!= EXPR_VARIABLE
5358 || code
->expr1
->symtree
== NULL
5359 || code
->expr1
->rank
!= 0
5360 || (code
->expr1
->ts
.type
!= BT_INTEGER
5361 && code
->expr1
->ts
.type
!= BT_REAL
5362 && code
->expr1
->ts
.type
!= BT_COMPLEX
5363 && code
->expr1
->ts
.type
!= BT_LOGICAL
))
5365 gfc_error ("!$OMP ATOMIC CAPTURE capture statement must set "
5366 "a scalar variable of intrinsic type at %L",
5367 &code
->expr1
->where
);
5371 expr2
= is_conversion (code
->expr2
, false);
5374 expr2
= is_conversion (code
->expr2
, true);
5376 expr2
= code
->expr2
;
5379 if (expr2
->expr_type
!= EXPR_VARIABLE
5380 || expr2
->symtree
== NULL
5382 || (expr2
->ts
.type
!= BT_INTEGER
5383 && expr2
->ts
.type
!= BT_REAL
5384 && expr2
->ts
.type
!= BT_COMPLEX
5385 && expr2
->ts
.type
!= BT_LOGICAL
))
5387 gfc_error ("!$OMP ATOMIC CAPTURE capture statement must read "
5388 "from a scalar variable of intrinsic type at %L",
5392 if (expr2
->symtree
->n
.sym
!= var
)
5394 gfc_error ("!$OMP ATOMIC CAPTURE capture statement reads from "
5395 "different variable than update statement writes "
5396 "into at %L", &expr2
->where
);
5403 static struct fortran_omp_context
5406 hash_set
<gfc_symbol
*> *sharing_clauses
;
5407 hash_set
<gfc_symbol
*> *private_iterators
;
5408 struct fortran_omp_context
*previous
;
5411 static gfc_code
*omp_current_do_code
;
5412 static int omp_current_do_collapse
;
5415 gfc_resolve_omp_do_blocks (gfc_code
*code
, gfc_namespace
*ns
)
5417 if (code
->block
->next
&& code
->block
->next
->op
== EXEC_DO
)
5422 omp_current_do_code
= code
->block
->next
;
5423 if (code
->ext
.omp_clauses
->orderedc
)
5424 omp_current_do_collapse
= code
->ext
.omp_clauses
->orderedc
;
5426 omp_current_do_collapse
= code
->ext
.omp_clauses
->collapse
;
5427 for (i
= 1, c
= omp_current_do_code
; i
< omp_current_do_collapse
; i
++)
5430 if (c
->op
!= EXEC_DO
|| c
->next
== NULL
)
5433 if (c
->op
!= EXEC_DO
)
5436 if (i
< omp_current_do_collapse
|| omp_current_do_collapse
<= 0)
5437 omp_current_do_collapse
= 1;
5439 gfc_resolve_blocks (code
->block
, ns
);
5440 omp_current_do_collapse
= 0;
5441 omp_current_do_code
= NULL
;
5446 gfc_resolve_omp_parallel_blocks (gfc_code
*code
, gfc_namespace
*ns
)
5448 struct fortran_omp_context ctx
;
5449 gfc_omp_clauses
*omp_clauses
= code
->ext
.omp_clauses
;
5450 gfc_omp_namelist
*n
;
5454 ctx
.sharing_clauses
= new hash_set
<gfc_symbol
*>;
5455 ctx
.private_iterators
= new hash_set
<gfc_symbol
*>;
5456 ctx
.previous
= omp_current_ctx
;
5457 ctx
.is_openmp
= true;
5458 omp_current_ctx
= &ctx
;
5460 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
5463 case OMP_LIST_SHARED
:
5464 case OMP_LIST_PRIVATE
:
5465 case OMP_LIST_FIRSTPRIVATE
:
5466 case OMP_LIST_LASTPRIVATE
:
5467 case OMP_LIST_REDUCTION
:
5468 case OMP_LIST_LINEAR
:
5469 for (n
= omp_clauses
->lists
[list
]; n
; n
= n
->next
)
5470 ctx
.sharing_clauses
->add (n
->sym
);
5478 case EXEC_OMP_PARALLEL_DO
:
5479 case EXEC_OMP_PARALLEL_DO_SIMD
:
5480 case EXEC_OMP_TARGET_PARALLEL_DO
:
5481 case EXEC_OMP_TARGET_PARALLEL_DO_SIMD
:
5482 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE
:
5483 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO
:
5484 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
5485 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD
:
5486 case EXEC_OMP_TASKLOOP
:
5487 case EXEC_OMP_TASKLOOP_SIMD
:
5488 case EXEC_OMP_TEAMS_DISTRIBUTE
:
5489 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO
:
5490 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
5491 case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD
:
5492 gfc_resolve_omp_do_blocks (code
, ns
);
5495 gfc_resolve_blocks (code
->block
, ns
);
5498 omp_current_ctx
= ctx
.previous
;
5499 delete ctx
.sharing_clauses
;
5500 delete ctx
.private_iterators
;
5504 /* Save and clear openmp.c private state. */
5507 gfc_omp_save_and_clear_state (struct gfc_omp_saved_state
*state
)
5509 state
->ptrs
[0] = omp_current_ctx
;
5510 state
->ptrs
[1] = omp_current_do_code
;
5511 state
->ints
[0] = omp_current_do_collapse
;
5512 omp_current_ctx
= NULL
;
5513 omp_current_do_code
= NULL
;
5514 omp_current_do_collapse
= 0;
5518 /* Restore openmp.c private state from the saved state. */
5521 gfc_omp_restore_state (struct gfc_omp_saved_state
*state
)
5523 omp_current_ctx
= (struct fortran_omp_context
*) state
->ptrs
[0];
5524 omp_current_do_code
= (gfc_code
*) state
->ptrs
[1];
5525 omp_current_do_collapse
= state
->ints
[0];
5529 /* Note a DO iterator variable. This is special in !$omp parallel
5530 construct, where they are predetermined private. */
5533 gfc_resolve_do_iterator (gfc_code
*code
, gfc_symbol
*sym
, bool add_clause
)
5535 if (omp_current_ctx
== NULL
)
5538 int i
= omp_current_do_collapse
;
5539 gfc_code
*c
= omp_current_do_code
;
5541 if (sym
->attr
.threadprivate
)
5544 /* !$omp do and !$omp parallel do iteration variable is predetermined
5545 private just in the !$omp do resp. !$omp parallel do construct,
5546 with no implications for the outer parallel constructs. */
5556 /* An openacc context may represent a data clause. Abort if so. */
5557 if (!omp_current_ctx
->is_openmp
&& !oacc_is_loop (omp_current_ctx
->code
))
5560 if (omp_current_ctx
->sharing_clauses
->contains (sym
))
5563 if (! omp_current_ctx
->private_iterators
->add (sym
) && add_clause
)
5565 gfc_omp_clauses
*omp_clauses
= omp_current_ctx
->code
->ext
.omp_clauses
;
5566 gfc_omp_namelist
*p
;
5568 p
= gfc_get_omp_namelist ();
5570 p
->next
= omp_clauses
->lists
[OMP_LIST_PRIVATE
];
5571 omp_clauses
->lists
[OMP_LIST_PRIVATE
] = p
;
5576 handle_local_var (gfc_symbol
*sym
)
5578 if (sym
->attr
.flavor
!= FL_VARIABLE
5580 || (sym
->ts
.type
!= BT_INTEGER
&& sym
->ts
.type
!= BT_REAL
))
5582 gfc_resolve_do_iterator (sym
->ns
->code
, sym
, false);
5586 gfc_resolve_omp_local_vars (gfc_namespace
*ns
)
5588 if (omp_current_ctx
)
5589 gfc_traverse_ns (ns
, handle_local_var
);
5593 resolve_omp_do (gfc_code
*code
)
5595 gfc_code
*do_code
, *c
;
5596 int list
, i
, collapse
;
5597 gfc_omp_namelist
*n
;
5600 bool is_simd
= false;
5604 case EXEC_OMP_DISTRIBUTE
: name
= "!$OMP DISTRIBUTE"; break;
5605 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO
:
5606 name
= "!$OMP DISTRIBUTE PARALLEL DO";
5608 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD
:
5609 name
= "!$OMP DISTRIBUTE PARALLEL DO SIMD";
5612 case EXEC_OMP_DISTRIBUTE_SIMD
:
5613 name
= "!$OMP DISTRIBUTE SIMD";
5616 case EXEC_OMP_DO
: name
= "!$OMP DO"; break;
5617 case EXEC_OMP_DO_SIMD
: name
= "!$OMP DO SIMD"; is_simd
= true; break;
5618 case EXEC_OMP_PARALLEL_DO
: name
= "!$OMP PARALLEL DO"; break;
5619 case EXEC_OMP_PARALLEL_DO_SIMD
:
5620 name
= "!$OMP PARALLEL DO SIMD";
5623 case EXEC_OMP_SIMD
: name
= "!$OMP SIMD"; is_simd
= true; break;
5624 case EXEC_OMP_TARGET_PARALLEL_DO
: name
= "!$OMP TARGET PARALLEL DO"; break;
5625 case EXEC_OMP_TARGET_PARALLEL_DO_SIMD
:
5626 name
= "!$OMP TARGET PARALLEL DO SIMD";
5629 case EXEC_OMP_TARGET_SIMD
:
5630 name
= "!$OMP TARGET SIMD";
5633 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE
:
5634 name
= "!$OMP TARGET TEAMS DISTRIBUTE";
5636 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO
:
5637 name
= "!$OMP TARGET TEAMS DISTRIBUTE PARALLEL DO";
5639 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
5640 name
= "!$OMP TARGET TEAMS DISTRIBUTE PARALLEL DO SIMD";
5643 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD
:
5644 name
= "!$OMP TARGET TEAMS DISTRIBUTE SIMD";
5647 case EXEC_OMP_TASKLOOP
: name
= "!$OMP TASKLOOP"; break;
5648 case EXEC_OMP_TASKLOOP_SIMD
:
5649 name
= "!$OMP TASKLOOP SIMD";
5652 case EXEC_OMP_TEAMS_DISTRIBUTE
: name
= "!$OMP TEAMS DISTRIBUTE"; break;
5653 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO
:
5654 name
= "!$OMP TEAMS DISTRIBUTE PARALLEL DO";
5656 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
5657 name
= "!$OMP TEAMS DISTRIBUTE PARALLEL DO SIMD";
5660 case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD
:
5661 name
= "!$OMP TEAMS DISTRIBUTE SIMD";
5664 default: gcc_unreachable ();
5667 if (code
->ext
.omp_clauses
)
5668 resolve_omp_clauses (code
, code
->ext
.omp_clauses
, NULL
);
5670 do_code
= code
->block
->next
;
5671 if (code
->ext
.omp_clauses
->orderedc
)
5672 collapse
= code
->ext
.omp_clauses
->orderedc
;
5675 collapse
= code
->ext
.omp_clauses
->collapse
;
5679 for (i
= 1; i
<= collapse
; i
++)
5681 if (do_code
->op
== EXEC_DO_WHILE
)
5683 gfc_error ("%s cannot be a DO WHILE or DO without loop control "
5684 "at %L", name
, &do_code
->loc
);
5687 if (do_code
->op
== EXEC_DO_CONCURRENT
)
5689 gfc_error ("%s cannot be a DO CONCURRENT loop at %L", name
,
5693 gcc_assert (do_code
->op
== EXEC_DO
);
5694 if (do_code
->ext
.iterator
->var
->ts
.type
!= BT_INTEGER
)
5695 gfc_error ("%s iteration variable must be of type integer at %L",
5696 name
, &do_code
->loc
);
5697 dovar
= do_code
->ext
.iterator
->var
->symtree
->n
.sym
;
5698 if (dovar
->attr
.threadprivate
)
5699 gfc_error ("%s iteration variable must not be THREADPRIVATE "
5700 "at %L", name
, &do_code
->loc
);
5701 if (code
->ext
.omp_clauses
)
5702 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
5704 ? (list
!= OMP_LIST_PRIVATE
&& list
!= OMP_LIST_LASTPRIVATE
)
5705 : code
->ext
.omp_clauses
->collapse
> 1
5706 ? (list
!= OMP_LIST_LASTPRIVATE
)
5707 : (list
!= OMP_LIST_LINEAR
))
5708 for (n
= code
->ext
.omp_clauses
->lists
[list
]; n
; n
= n
->next
)
5709 if (dovar
== n
->sym
)
5712 gfc_error ("%s iteration variable present on clause "
5713 "other than PRIVATE or LASTPRIVATE at %L",
5714 name
, &do_code
->loc
);
5715 else if (code
->ext
.omp_clauses
->collapse
> 1)
5716 gfc_error ("%s iteration variable present on clause "
5717 "other than LASTPRIVATE at %L",
5718 name
, &do_code
->loc
);
5720 gfc_error ("%s iteration variable present on clause "
5721 "other than LINEAR at %L",
5722 name
, &do_code
->loc
);
5727 gfc_code
*do_code2
= code
->block
->next
;
5730 for (j
= 1; j
< i
; j
++)
5732 gfc_symbol
*ivar
= do_code2
->ext
.iterator
->var
->symtree
->n
.sym
;
5734 || gfc_find_sym_in_expr (ivar
, do_code
->ext
.iterator
->start
)
5735 || gfc_find_sym_in_expr (ivar
, do_code
->ext
.iterator
->end
)
5736 || gfc_find_sym_in_expr (ivar
, do_code
->ext
.iterator
->step
))
5738 gfc_error ("%s collapsed loops don't form rectangular "
5739 "iteration space at %L", name
, &do_code
->loc
);
5742 do_code2
= do_code2
->block
->next
;
5747 for (c
= do_code
->next
; c
; c
= c
->next
)
5748 if (c
->op
!= EXEC_NOP
&& c
->op
!= EXEC_CONTINUE
)
5750 gfc_error ("collapsed %s loops not perfectly nested at %L",
5756 do_code
= do_code
->block
;
5757 if (do_code
->op
!= EXEC_DO
&& do_code
->op
!= EXEC_DO_WHILE
)
5759 gfc_error ("not enough DO loops for collapsed %s at %L",
5763 do_code
= do_code
->next
;
5765 || (do_code
->op
!= EXEC_DO
&& do_code
->op
!= EXEC_DO_WHILE
))
5767 gfc_error ("not enough DO loops for collapsed %s at %L",
5775 oacc_is_parallel (gfc_code
*code
)
5777 return code
->op
== EXEC_OACC_PARALLEL
|| code
->op
== EXEC_OACC_PARALLEL_LOOP
;
5780 static gfc_statement
5781 omp_code_to_statement (gfc_code
*code
)
5785 case EXEC_OMP_PARALLEL
:
5786 return ST_OMP_PARALLEL
;
5787 case EXEC_OMP_PARALLEL_SECTIONS
:
5788 return ST_OMP_PARALLEL_SECTIONS
;
5789 case EXEC_OMP_SECTIONS
:
5790 return ST_OMP_SECTIONS
;
5791 case EXEC_OMP_ORDERED
:
5792 return ST_OMP_ORDERED
;
5793 case EXEC_OMP_CRITICAL
:
5794 return ST_OMP_CRITICAL
;
5795 case EXEC_OMP_MASTER
:
5796 return ST_OMP_MASTER
;
5797 case EXEC_OMP_SINGLE
:
5798 return ST_OMP_SINGLE
;
5801 case EXEC_OMP_WORKSHARE
:
5802 return ST_OMP_WORKSHARE
;
5803 case EXEC_OMP_PARALLEL_WORKSHARE
:
5804 return ST_OMP_PARALLEL_WORKSHARE
;
5812 static gfc_statement
5813 oacc_code_to_statement (gfc_code
*code
)
5817 case EXEC_OACC_PARALLEL
:
5818 return ST_OACC_PARALLEL
;
5819 case EXEC_OACC_KERNELS
:
5820 return ST_OACC_KERNELS
;
5821 case EXEC_OACC_DATA
:
5822 return ST_OACC_DATA
;
5823 case EXEC_OACC_HOST_DATA
:
5824 return ST_OACC_HOST_DATA
;
5825 case EXEC_OACC_PARALLEL_LOOP
:
5826 return ST_OACC_PARALLEL_LOOP
;
5827 case EXEC_OACC_KERNELS_LOOP
:
5828 return ST_OACC_KERNELS_LOOP
;
5829 case EXEC_OACC_LOOP
:
5830 return ST_OACC_LOOP
;
5831 case EXEC_OACC_ATOMIC
:
5832 return ST_OACC_ATOMIC
;
5839 resolve_oacc_directive_inside_omp_region (gfc_code
*code
)
5841 if (omp_current_ctx
!= NULL
&& omp_current_ctx
->is_openmp
)
5843 gfc_statement st
= omp_code_to_statement (omp_current_ctx
->code
);
5844 gfc_statement oacc_st
= oacc_code_to_statement (code
);
5845 gfc_error ("The %s directive cannot be specified within "
5846 "a %s region at %L", gfc_ascii_statement (oacc_st
),
5847 gfc_ascii_statement (st
), &code
->loc
);
5852 resolve_omp_directive_inside_oacc_region (gfc_code
*code
)
5854 if (omp_current_ctx
!= NULL
&& !omp_current_ctx
->is_openmp
)
5856 gfc_statement st
= oacc_code_to_statement (omp_current_ctx
->code
);
5857 gfc_statement omp_st
= omp_code_to_statement (code
);
5858 gfc_error ("The %s directive cannot be specified within "
5859 "a %s region at %L", gfc_ascii_statement (omp_st
),
5860 gfc_ascii_statement (st
), &code
->loc
);
5866 resolve_oacc_nested_loops (gfc_code
*code
, gfc_code
* do_code
, int collapse
,
5873 for (i
= 1; i
<= collapse
; i
++)
5875 if (do_code
->op
== EXEC_DO_WHILE
)
5877 gfc_error ("!$ACC LOOP cannot be a DO WHILE or DO without loop control "
5878 "at %L", &do_code
->loc
);
5881 if (do_code
->op
== EXEC_DO_CONCURRENT
)
5883 gfc_error ("!$ACC LOOP cannot be a DO CONCURRENT loop at %L",
5887 gcc_assert (do_code
->op
== EXEC_DO
);
5888 if (do_code
->ext
.iterator
->var
->ts
.type
!= BT_INTEGER
)
5889 gfc_error ("!$ACC LOOP iteration variable must be of type integer at %L",
5891 dovar
= do_code
->ext
.iterator
->var
->symtree
->n
.sym
;
5894 gfc_code
*do_code2
= code
->block
->next
;
5897 for (j
= 1; j
< i
; j
++)
5899 gfc_symbol
*ivar
= do_code2
->ext
.iterator
->var
->symtree
->n
.sym
;
5901 || gfc_find_sym_in_expr (ivar
, do_code
->ext
.iterator
->start
)
5902 || gfc_find_sym_in_expr (ivar
, do_code
->ext
.iterator
->end
)
5903 || gfc_find_sym_in_expr (ivar
, do_code
->ext
.iterator
->step
))
5905 gfc_error ("!$ACC LOOP %s loops don't form rectangular "
5906 "iteration space at %L", clause
, &do_code
->loc
);
5909 do_code2
= do_code2
->block
->next
;
5914 for (c
= do_code
->next
; c
; c
= c
->next
)
5915 if (c
->op
!= EXEC_NOP
&& c
->op
!= EXEC_CONTINUE
)
5917 gfc_error ("%s !$ACC LOOP loops not perfectly nested at %L",
5923 do_code
= do_code
->block
;
5924 if (do_code
->op
!= EXEC_DO
&& do_code
->op
!= EXEC_DO_WHILE
5925 && do_code
->op
!= EXEC_DO_CONCURRENT
)
5927 gfc_error ("not enough DO loops for %s !$ACC LOOP at %L",
5928 clause
, &code
->loc
);
5931 do_code
= do_code
->next
;
5933 || (do_code
->op
!= EXEC_DO
&& do_code
->op
!= EXEC_DO_WHILE
5934 && do_code
->op
!= EXEC_DO_CONCURRENT
))
5936 gfc_error ("not enough DO loops for %s !$ACC LOOP at %L",
5937 clause
, &code
->loc
);
5945 resolve_oacc_params_in_parallel (gfc_code
*code
, const char *clause
,
5948 fortran_omp_context
*c
;
5950 if (oacc_is_parallel (code
))
5951 gfc_error ("!$ACC LOOP %s in PARALLEL region doesn't allow "
5952 "%s arguments at %L", clause
, arg
, &code
->loc
);
5953 for (c
= omp_current_ctx
; c
; c
= c
->previous
)
5955 if (oacc_is_loop (c
->code
))
5957 if (oacc_is_parallel (c
->code
))
5958 gfc_error ("!$ACC LOOP %s in PARALLEL region doesn't allow "
5959 "%s arguments at %L", clause
, arg
, &code
->loc
);
5965 resolve_oacc_loop_blocks (gfc_code
*code
)
5967 if (!oacc_is_loop (code
))
5970 if (code
->ext
.omp_clauses
->tile_list
&& code
->ext
.omp_clauses
->gang
5971 && code
->ext
.omp_clauses
->worker
&& code
->ext
.omp_clauses
->vector
)
5972 gfc_error ("Tiled loop cannot be parallelized across gangs, workers and "
5973 "vectors at the same time at %L", &code
->loc
);
5975 if (code
->ext
.omp_clauses
->gang
5976 && code
->ext
.omp_clauses
->gang_num_expr
)
5977 resolve_oacc_params_in_parallel (code
, "GANG", "num");
5979 if (code
->ext
.omp_clauses
->worker
5980 && code
->ext
.omp_clauses
->worker_expr
)
5981 resolve_oacc_params_in_parallel (code
, "WORKER", "num");
5983 if (code
->ext
.omp_clauses
->vector
5984 && code
->ext
.omp_clauses
->vector_expr
)
5985 resolve_oacc_params_in_parallel (code
, "VECTOR", "length");
5987 if (code
->ext
.omp_clauses
->tile_list
)
5991 for (el
= code
->ext
.omp_clauses
->tile_list
; el
; el
= el
->next
)
5994 if (el
->expr
== NULL
)
5996 /* NULL expressions are used to represent '*' arguments.
5997 Convert those to a 0 expressions. */
5998 el
->expr
= gfc_get_constant_expr (BT_INTEGER
,
5999 gfc_default_integer_kind
,
6001 mpz_set_si (el
->expr
->value
.integer
, 0);
6005 resolve_positive_int_expr (el
->expr
, "TILE");
6006 if (el
->expr
->expr_type
!= EXPR_CONSTANT
)
6007 gfc_error ("TILE requires constant expression at %L",
6011 resolve_oacc_nested_loops (code
, code
->block
->next
, num
, "tiled");
6017 gfc_resolve_oacc_blocks (gfc_code
*code
, gfc_namespace
*ns
)
6019 fortran_omp_context ctx
;
6020 gfc_omp_clauses
*omp_clauses
= code
->ext
.omp_clauses
;
6021 gfc_omp_namelist
*n
;
6024 resolve_oacc_loop_blocks (code
);
6027 ctx
.sharing_clauses
= new hash_set
<gfc_symbol
*>;
6028 ctx
.private_iterators
= new hash_set
<gfc_symbol
*>;
6029 ctx
.previous
= omp_current_ctx
;
6030 ctx
.is_openmp
= false;
6031 omp_current_ctx
= &ctx
;
6033 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
6036 case OMP_LIST_PRIVATE
:
6037 for (n
= omp_clauses
->lists
[list
]; n
; n
= n
->next
)
6038 ctx
.sharing_clauses
->add (n
->sym
);
6044 gfc_resolve_blocks (code
->block
, ns
);
6046 omp_current_ctx
= ctx
.previous
;
6047 delete ctx
.sharing_clauses
;
6048 delete ctx
.private_iterators
;
6053 resolve_oacc_loop (gfc_code
*code
)
6058 if (code
->ext
.omp_clauses
)
6059 resolve_omp_clauses (code
, code
->ext
.omp_clauses
, NULL
, true);
6061 do_code
= code
->block
->next
;
6062 collapse
= code
->ext
.omp_clauses
->collapse
;
6066 resolve_oacc_nested_loops (code
, do_code
, collapse
, "collapsed");
6070 gfc_resolve_oacc_declare (gfc_namespace
*ns
)
6073 gfc_omp_namelist
*n
;
6074 gfc_oacc_declare
*oc
;
6076 if (ns
->oacc_declare
== NULL
)
6079 for (oc
= ns
->oacc_declare
; oc
; oc
= oc
->next
)
6081 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
6082 for (n
= oc
->clauses
->lists
[list
]; n
; n
= n
->next
)
6085 if (n
->sym
->attr
.flavor
!= FL_VARIABLE
6086 && (n
->sym
->attr
.flavor
!= FL_PROCEDURE
6087 || n
->sym
->result
!= n
->sym
))
6089 gfc_error ("Object %qs is not a variable at %L",
6090 n
->sym
->name
, &oc
->loc
);
6094 if (n
->expr
&& n
->expr
->ref
->type
== REF_ARRAY
)
6096 gfc_error ("Array sections: %qs not allowed in"
6097 " !$ACC DECLARE at %L", n
->sym
->name
, &oc
->loc
);
6102 for (n
= oc
->clauses
->lists
[OMP_LIST_DEVICE_RESIDENT
]; n
; n
= n
->next
)
6103 check_array_not_assumed (n
->sym
, oc
->loc
, "DEVICE_RESIDENT");
6106 for (oc
= ns
->oacc_declare
; oc
; oc
= oc
->next
)
6108 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
6109 for (n
= oc
->clauses
->lists
[list
]; n
; n
= n
->next
)
6113 gfc_error ("Symbol %qs present on multiple clauses at %L",
6114 n
->sym
->name
, &oc
->loc
);
6122 for (oc
= ns
->oacc_declare
; oc
; oc
= oc
->next
)
6124 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
6125 for (n
= oc
->clauses
->lists
[list
]; n
; n
= n
->next
)
6132 gfc_resolve_oacc_routines (gfc_namespace
*ns
)
6134 for (gfc_oacc_routine_name
*orn
= ns
->oacc_routine_names
;
6138 gfc_symbol
*sym
= orn
->sym
;
6139 if (!sym
->attr
.external
6140 && !sym
->attr
.function
6141 && !sym
->attr
.subroutine
)
6143 gfc_error ("NAME %qs does not refer to a subroutine or function"
6144 " in !$ACC ROUTINE ( NAME ) at %L", sym
->name
, &orn
->loc
);
6147 if (!gfc_add_omp_declare_target (&sym
->attr
, sym
->name
, &orn
->loc
))
6149 gfc_error ("NAME %qs invalid"
6150 " in !$ACC ROUTINE ( NAME ) at %L", sym
->name
, &orn
->loc
);
6158 gfc_resolve_oacc_directive (gfc_code
*code
, gfc_namespace
*ns ATTRIBUTE_UNUSED
)
6160 resolve_oacc_directive_inside_omp_region (code
);
6164 case EXEC_OACC_PARALLEL
:
6165 case EXEC_OACC_KERNELS
:
6166 case EXEC_OACC_DATA
:
6167 case EXEC_OACC_HOST_DATA
:
6168 case EXEC_OACC_UPDATE
:
6169 case EXEC_OACC_ENTER_DATA
:
6170 case EXEC_OACC_EXIT_DATA
:
6171 case EXEC_OACC_WAIT
:
6172 case EXEC_OACC_CACHE
:
6173 resolve_omp_clauses (code
, code
->ext
.omp_clauses
, NULL
, true);
6175 case EXEC_OACC_PARALLEL_LOOP
:
6176 case EXEC_OACC_KERNELS_LOOP
:
6177 case EXEC_OACC_LOOP
:
6178 resolve_oacc_loop (code
);
6180 case EXEC_OACC_ATOMIC
:
6181 resolve_omp_atomic (code
);
6189 /* Resolve OpenMP directive clauses and check various requirements
6190 of each directive. */
6193 gfc_resolve_omp_directive (gfc_code
*code
, gfc_namespace
*ns ATTRIBUTE_UNUSED
)
6195 resolve_omp_directive_inside_oacc_region (code
);
6197 if (code
->op
!= EXEC_OMP_ATOMIC
)
6198 gfc_maybe_initialize_eh ();
6202 case EXEC_OMP_DISTRIBUTE
:
6203 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO
:
6204 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD
:
6205 case EXEC_OMP_DISTRIBUTE_SIMD
:
6207 case EXEC_OMP_DO_SIMD
:
6208 case EXEC_OMP_PARALLEL_DO
:
6209 case EXEC_OMP_PARALLEL_DO_SIMD
:
6211 case EXEC_OMP_TARGET_PARALLEL_DO
:
6212 case EXEC_OMP_TARGET_PARALLEL_DO_SIMD
:
6213 case EXEC_OMP_TARGET_SIMD
:
6214 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE
:
6215 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO
:
6216 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
6217 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD
:
6218 case EXEC_OMP_TASKLOOP
:
6219 case EXEC_OMP_TASKLOOP_SIMD
:
6220 case EXEC_OMP_TEAMS_DISTRIBUTE
:
6221 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO
:
6222 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
6223 case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD
:
6224 resolve_omp_do (code
);
6226 case EXEC_OMP_CANCEL
:
6227 case EXEC_OMP_PARALLEL_WORKSHARE
:
6228 case EXEC_OMP_PARALLEL
:
6229 case EXEC_OMP_PARALLEL_SECTIONS
:
6230 case EXEC_OMP_SECTIONS
:
6231 case EXEC_OMP_SINGLE
:
6232 case EXEC_OMP_TARGET
:
6233 case EXEC_OMP_TARGET_DATA
:
6234 case EXEC_OMP_TARGET_ENTER_DATA
:
6235 case EXEC_OMP_TARGET_EXIT_DATA
:
6236 case EXEC_OMP_TARGET_PARALLEL
:
6237 case EXEC_OMP_TARGET_TEAMS
:
6239 case EXEC_OMP_TEAMS
:
6240 case EXEC_OMP_WORKSHARE
:
6241 if (code
->ext
.omp_clauses
)
6242 resolve_omp_clauses (code
, code
->ext
.omp_clauses
, NULL
);
6244 case EXEC_OMP_TARGET_UPDATE
:
6245 if (code
->ext
.omp_clauses
)
6246 resolve_omp_clauses (code
, code
->ext
.omp_clauses
, NULL
);
6247 if (code
->ext
.omp_clauses
== NULL
6248 || (code
->ext
.omp_clauses
->lists
[OMP_LIST_TO
] == NULL
6249 && code
->ext
.omp_clauses
->lists
[OMP_LIST_FROM
] == NULL
))
6250 gfc_error ("OMP TARGET UPDATE at %L requires at least one TO or "
6251 "FROM clause", &code
->loc
);
6253 case EXEC_OMP_ATOMIC
:
6254 resolve_omp_atomic (code
);
6261 /* Resolve !$omp declare simd constructs in NS. */
6264 gfc_resolve_omp_declare_simd (gfc_namespace
*ns
)
6266 gfc_omp_declare_simd
*ods
;
6268 for (ods
= ns
->omp_declare_simd
; ods
; ods
= ods
->next
)
6270 if (ods
->proc_name
!= NULL
6271 && ods
->proc_name
!= ns
->proc_name
)
6272 gfc_error ("!$OMP DECLARE SIMD should refer to containing procedure "
6273 "%qs at %L", ns
->proc_name
->name
, &ods
->where
);
6275 resolve_omp_clauses (NULL
, ods
->clauses
, ns
);
6279 struct omp_udr_callback_data
6281 gfc_omp_udr
*omp_udr
;
6282 bool is_initializer
;
6286 omp_udr_callback (gfc_expr
**e
, int *walk_subtrees ATTRIBUTE_UNUSED
,
6289 struct omp_udr_callback_data
*cd
= (struct omp_udr_callback_data
*) data
;
6290 if ((*e
)->expr_type
== EXPR_VARIABLE
)
6292 if (cd
->is_initializer
)
6294 if ((*e
)->symtree
->n
.sym
!= cd
->omp_udr
->omp_priv
6295 && (*e
)->symtree
->n
.sym
!= cd
->omp_udr
->omp_orig
)
6296 gfc_error ("Variable other than OMP_PRIV or OMP_ORIG used in "
6297 "INITIALIZER clause of !$OMP DECLARE REDUCTION at %L",
6302 if ((*e
)->symtree
->n
.sym
!= cd
->omp_udr
->omp_out
6303 && (*e
)->symtree
->n
.sym
!= cd
->omp_udr
->omp_in
)
6304 gfc_error ("Variable other than OMP_OUT or OMP_IN used in "
6305 "combiner of !$OMP DECLARE REDUCTION at %L",
6312 /* Resolve !$omp declare reduction constructs. */
6315 gfc_resolve_omp_udr (gfc_omp_udr
*omp_udr
)
6317 gfc_actual_arglist
*a
;
6318 const char *predef_name
= NULL
;
6320 switch (omp_udr
->rop
)
6322 case OMP_REDUCTION_PLUS
:
6323 case OMP_REDUCTION_TIMES
:
6324 case OMP_REDUCTION_MINUS
:
6325 case OMP_REDUCTION_AND
:
6326 case OMP_REDUCTION_OR
:
6327 case OMP_REDUCTION_EQV
:
6328 case OMP_REDUCTION_NEQV
:
6329 case OMP_REDUCTION_MAX
:
6330 case OMP_REDUCTION_USER
:
6333 gfc_error ("Invalid operator for !$OMP DECLARE REDUCTION %s at %L",
6334 omp_udr
->name
, &omp_udr
->where
);
6338 if (gfc_omp_udr_predef (omp_udr
->rop
, omp_udr
->name
,
6339 &omp_udr
->ts
, &predef_name
))
6342 gfc_error_now ("Redefinition of predefined %s "
6343 "!$OMP DECLARE REDUCTION at %L",
6344 predef_name
, &omp_udr
->where
);
6346 gfc_error_now ("Redefinition of predefined "
6347 "!$OMP DECLARE REDUCTION at %L", &omp_udr
->where
);
6351 if (omp_udr
->ts
.type
== BT_CHARACTER
6352 && omp_udr
->ts
.u
.cl
->length
6353 && omp_udr
->ts
.u
.cl
->length
->expr_type
!= EXPR_CONSTANT
)
6355 gfc_error ("CHARACTER length in !$OMP DECLARE REDUCTION %s not "
6356 "constant at %L", omp_udr
->name
, &omp_udr
->where
);
6360 struct omp_udr_callback_data cd
;
6361 cd
.omp_udr
= omp_udr
;
6362 cd
.is_initializer
= false;
6363 gfc_code_walker (&omp_udr
->combiner_ns
->code
, gfc_dummy_code_callback
,
6364 omp_udr_callback
, &cd
);
6365 if (omp_udr
->combiner_ns
->code
->op
== EXEC_CALL
)
6367 for (a
= omp_udr
->combiner_ns
->code
->ext
.actual
; a
; a
= a
->next
)
6368 if (a
->expr
== NULL
)
6371 gfc_error ("Subroutine call with alternate returns in combiner "
6372 "of !$OMP DECLARE REDUCTION at %L",
6373 &omp_udr
->combiner_ns
->code
->loc
);
6375 if (omp_udr
->initializer_ns
)
6377 cd
.is_initializer
= true;
6378 gfc_code_walker (&omp_udr
->initializer_ns
->code
, gfc_dummy_code_callback
,
6379 omp_udr_callback
, &cd
);
6380 if (omp_udr
->initializer_ns
->code
->op
== EXEC_CALL
)
6382 for (a
= omp_udr
->initializer_ns
->code
->ext
.actual
; a
; a
= a
->next
)
6383 if (a
->expr
== NULL
)
6386 gfc_error ("Subroutine call with alternate returns in "
6387 "INITIALIZER clause of !$OMP DECLARE REDUCTION "
6388 "at %L", &omp_udr
->initializer_ns
->code
->loc
);
6389 for (a
= omp_udr
->initializer_ns
->code
->ext
.actual
; a
; a
= a
->next
)
6391 && a
->expr
->expr_type
== EXPR_VARIABLE
6392 && a
->expr
->symtree
->n
.sym
== omp_udr
->omp_priv
6393 && a
->expr
->ref
== NULL
)
6396 gfc_error ("One of actual subroutine arguments in INITIALIZER "
6397 "clause of !$OMP DECLARE REDUCTION must be OMP_PRIV "
6398 "at %L", &omp_udr
->initializer_ns
->code
->loc
);
6401 else if (omp_udr
->ts
.type
== BT_DERIVED
6402 && !gfc_has_default_initializer (omp_udr
->ts
.u
.derived
))
6404 gfc_error ("Missing INITIALIZER clause for !$OMP DECLARE REDUCTION "
6405 "of derived type without default initializer at %L",
6412 gfc_resolve_omp_udrs (gfc_symtree
*st
)
6414 gfc_omp_udr
*omp_udr
;
6418 gfc_resolve_omp_udrs (st
->left
);
6419 gfc_resolve_omp_udrs (st
->right
);
6420 for (omp_udr
= st
->n
.omp_udr
; omp_udr
; omp_udr
= omp_udr
->next
)
6421 gfc_resolve_omp_udr (omp_udr
);