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
;
60 /* Free an omp_clauses structure. */
63 gfc_free_omp_clauses (gfc_omp_clauses
*c
)
69 gfc_free_expr (c
->if_expr
);
70 gfc_free_expr (c
->final_expr
);
71 gfc_free_expr (c
->num_threads
);
72 gfc_free_expr (c
->chunk_size
);
73 gfc_free_expr (c
->safelen_expr
);
74 gfc_free_expr (c
->simdlen_expr
);
75 gfc_free_expr (c
->num_teams
);
76 gfc_free_expr (c
->device
);
77 gfc_free_expr (c
->thread_limit
);
78 gfc_free_expr (c
->dist_chunk_size
);
79 gfc_free_expr (c
->grainsize
);
80 gfc_free_expr (c
->hint
);
81 gfc_free_expr (c
->num_tasks
);
82 gfc_free_expr (c
->priority
);
83 for (i
= 0; i
< OMP_IF_LAST
; i
++)
84 gfc_free_expr (c
->if_exprs
[i
]);
85 gfc_free_expr (c
->async_expr
);
86 gfc_free_expr (c
->gang_num_expr
);
87 gfc_free_expr (c
->gang_static_expr
);
88 gfc_free_expr (c
->worker_expr
);
89 gfc_free_expr (c
->vector_expr
);
90 gfc_free_expr (c
->num_gangs_expr
);
91 gfc_free_expr (c
->num_workers_expr
);
92 gfc_free_expr (c
->vector_length_expr
);
93 for (i
= 0; i
< OMP_LIST_NUM
; i
++)
94 gfc_free_omp_namelist (c
->lists
[i
]);
95 gfc_free_expr_list (c
->wait_list
);
96 gfc_free_expr_list (c
->tile_list
);
97 free (CONST_CAST (char *, c
->critical_name
));
101 /* Free oacc_declare structures. */
104 gfc_free_oacc_declare_clauses (struct gfc_oacc_declare
*oc
)
106 struct gfc_oacc_declare
*decl
= oc
;
110 struct gfc_oacc_declare
*next
;
113 gfc_free_omp_clauses (decl
->clauses
);
120 /* Free expression list. */
122 gfc_free_expr_list (gfc_expr_list
*list
)
126 for (; list
; list
= n
)
133 /* Free an !$omp declare simd construct list. */
136 gfc_free_omp_declare_simd (gfc_omp_declare_simd
*ods
)
140 gfc_free_omp_clauses (ods
->clauses
);
146 gfc_free_omp_declare_simd_list (gfc_omp_declare_simd
*list
)
150 gfc_omp_declare_simd
*current
= list
;
152 gfc_free_omp_declare_simd (current
);
156 /* Free an !$omp declare reduction. */
159 gfc_free_omp_udr (gfc_omp_udr
*omp_udr
)
163 gfc_free_omp_udr (omp_udr
->next
);
164 gfc_free_namespace (omp_udr
->combiner_ns
);
165 if (omp_udr
->initializer_ns
)
166 gfc_free_namespace (omp_udr
->initializer_ns
);
173 gfc_find_omp_udr (gfc_namespace
*ns
, const char *name
, gfc_typespec
*ts
)
181 gfc_omp_udr
*omp_udr
;
183 st
= gfc_find_symtree (ns
->omp_udr_root
, name
);
186 for (omp_udr
= st
->n
.omp_udr
; omp_udr
; omp_udr
= omp_udr
->next
)
189 else if (gfc_compare_types (&omp_udr
->ts
, ts
))
191 if (ts
->type
== BT_CHARACTER
)
193 if (omp_udr
->ts
.u
.cl
->length
== NULL
)
195 if (ts
->u
.cl
->length
== NULL
)
197 if (gfc_compare_expr (omp_udr
->ts
.u
.cl
->length
,
206 /* Don't escape an interface block. */
207 if (ns
&& !ns
->has_import_set
208 && ns
->proc_name
&& ns
->proc_name
->attr
.if_source
== IFSRC_IFBODY
)
219 /* Match a variable/common block list and construct a namelist from it. */
222 gfc_match_omp_variable_list (const char *str
, gfc_omp_namelist
**list
,
223 bool allow_common
, bool *end_colon
= NULL
,
224 gfc_omp_namelist
***headp
= NULL
,
225 bool allow_sections
= false)
227 gfc_omp_namelist
*head
, *tail
, *p
;
228 locus old_loc
, cur_loc
;
229 char n
[GFC_MAX_SYMBOL_LEN
+1];
236 old_loc
= gfc_current_locus
;
244 cur_loc
= gfc_current_locus
;
245 m
= gfc_match_symbol (&sym
, 1);
251 if (allow_sections
&& gfc_peek_ascii_char () == '(')
253 gfc_current_locus
= cur_loc
;
254 m
= gfc_match_variable (&expr
, 0);
265 gfc_set_sym_referenced (sym
);
266 p
= gfc_get_omp_namelist ();
276 tail
->where
= cur_loc
;
287 m
= gfc_match (" / %n /", n
);
288 if (m
== MATCH_ERROR
)
293 st
= gfc_find_symtree (gfc_current_ns
->common_root
, n
);
296 gfc_error ("COMMON block /%s/ not found at %C", n
);
299 for (sym
= st
->n
.common
->head
; sym
; sym
= sym
->common_next
)
301 gfc_set_sym_referenced (sym
);
302 p
= gfc_get_omp_namelist ();
311 tail
->where
= cur_loc
;
315 if (end_colon
&& gfc_match_char (':') == MATCH_YES
)
320 if (gfc_match_char (')') == MATCH_YES
)
322 if (gfc_match_char (',') != MATCH_YES
)
327 list
= &(*list
)->next
;
335 gfc_error ("Syntax error in OpenMP variable list at %C");
338 gfc_free_omp_namelist (head
);
339 gfc_current_locus
= old_loc
;
343 /* Match a variable/procedure/common block list and construct a namelist
347 gfc_match_omp_to_link (const char *str
, gfc_omp_namelist
**list
)
349 gfc_omp_namelist
*head
, *tail
, *p
;
350 locus old_loc
, cur_loc
;
351 char n
[GFC_MAX_SYMBOL_LEN
+1];
358 old_loc
= gfc_current_locus
;
366 cur_loc
= gfc_current_locus
;
367 m
= gfc_match_symbol (&sym
, 1);
371 p
= gfc_get_omp_namelist ();
380 tail
->where
= cur_loc
;
388 m
= gfc_match (" / %n /", n
);
389 if (m
== MATCH_ERROR
)
394 st
= gfc_find_symtree (gfc_current_ns
->common_root
, n
);
397 gfc_error ("COMMON block /%s/ not found at %C", n
);
400 p
= gfc_get_omp_namelist ();
408 tail
->u
.common
= st
->n
.common
;
409 tail
->where
= cur_loc
;
412 if (gfc_match_char (')') == MATCH_YES
)
414 if (gfc_match_char (',') != MATCH_YES
)
419 list
= &(*list
)->next
;
425 gfc_error ("Syntax error in OpenMP variable list at %C");
428 gfc_free_omp_namelist (head
);
429 gfc_current_locus
= old_loc
;
433 /* Match depend(sink : ...) construct a namelist from it. */
436 gfc_match_omp_depend_sink (gfc_omp_namelist
**list
)
438 gfc_omp_namelist
*head
, *tail
, *p
;
439 locus old_loc
, cur_loc
;
444 old_loc
= gfc_current_locus
;
448 cur_loc
= gfc_current_locus
;
449 switch (gfc_match_symbol (&sym
, 1))
452 gfc_set_sym_referenced (sym
);
453 p
= gfc_get_omp_namelist ();
457 head
->u
.depend_op
= OMP_DEPEND_SINK_FIRST
;
463 tail
->u
.depend_op
= OMP_DEPEND_SINK
;
467 tail
->where
= cur_loc
;
468 if (gfc_match_char ('+') == MATCH_YES
)
470 if (gfc_match_literal_constant (&tail
->expr
, 0) != MATCH_YES
)
473 else if (gfc_match_char ('-') == MATCH_YES
)
475 if (gfc_match_literal_constant (&tail
->expr
, 0) != MATCH_YES
)
477 tail
->expr
= gfc_uminus (tail
->expr
);
486 if (gfc_match_char (')') == MATCH_YES
)
488 if (gfc_match_char (',') != MATCH_YES
)
493 list
= &(*list
)->next
;
499 gfc_error ("Syntax error in OpenMP DEPEND SINK list at %C");
502 gfc_free_omp_namelist (head
);
503 gfc_current_locus
= old_loc
;
508 match_oacc_expr_list (const char *str
, gfc_expr_list
**list
,
511 gfc_expr_list
*head
, *tail
, *p
;
518 old_loc
= gfc_current_locus
;
526 m
= gfc_match_expr (&expr
);
527 if (m
== MATCH_YES
|| allow_asterisk
)
529 p
= gfc_get_expr_list ();
539 else if (gfc_match (" *") != MATCH_YES
)
543 if (m
== MATCH_ERROR
)
548 if (gfc_match_char (')') == MATCH_YES
)
550 if (gfc_match_char (',') != MATCH_YES
)
555 list
= &(*list
)->next
;
561 gfc_error ("Syntax error in OpenACC expression list at %C");
564 gfc_free_expr_list (head
);
565 gfc_current_locus
= old_loc
;
570 match_oacc_clause_gwv (gfc_omp_clauses
*cp
, unsigned gwv
)
572 match ret
= MATCH_YES
;
574 if (gfc_match (" ( ") != MATCH_YES
)
577 if (gwv
== GOMP_DIM_GANG
)
579 /* The gang clause accepts two optional arguments, num and static.
580 The num argument may either be explicit (num: <val>) or
581 implicit without (<val> without num:). */
583 while (ret
== MATCH_YES
)
585 if (gfc_match (" static :") == MATCH_YES
)
590 cp
->gang_static
= true;
591 if (gfc_match_char ('*') == MATCH_YES
)
592 cp
->gang_static_expr
= NULL
;
593 else if (gfc_match (" %e ", &cp
->gang_static_expr
) != MATCH_YES
)
598 if (cp
->gang_num_expr
)
601 /* The 'num' argument is optional. */
602 gfc_match (" num :");
604 if (gfc_match (" %e ", &cp
->gang_num_expr
) != MATCH_YES
)
608 ret
= gfc_match (" , ");
611 else if (gwv
== GOMP_DIM_WORKER
)
613 /* The 'num' argument is optional. */
614 gfc_match (" num :");
616 if (gfc_match (" %e ", &cp
->worker_expr
) != MATCH_YES
)
619 else if (gwv
== GOMP_DIM_VECTOR
)
621 /* The 'length' argument is optional. */
622 gfc_match (" length :");
624 if (gfc_match (" %e ", &cp
->vector_expr
) != MATCH_YES
)
628 gfc_fatal_error ("Unexpected OpenACC parallelism.");
630 return gfc_match (" )");
634 gfc_match_oacc_clause_link (const char *str
, gfc_omp_namelist
**list
)
636 gfc_omp_namelist
*head
= NULL
;
637 gfc_omp_namelist
*tail
, *p
;
639 char n
[GFC_MAX_SYMBOL_LEN
+1];
644 old_loc
= gfc_current_locus
;
650 m
= gfc_match (" (");
654 m
= gfc_match_symbol (&sym
, 0);
658 if (sym
->attr
.in_common
)
660 gfc_error_now ("Variable at %C is an element of a COMMON block");
663 gfc_set_sym_referenced (sym
);
664 p
= gfc_get_omp_namelist ();
674 tail
->where
= gfc_current_locus
;
683 m
= gfc_match (" / %n /", n
);
684 if (m
== MATCH_ERROR
)
686 if (m
== MATCH_NO
|| n
[0] == '\0')
689 st
= gfc_find_symtree (gfc_current_ns
->common_root
, n
);
692 gfc_error ("COMMON block /%s/ not found at %C", n
);
696 for (sym
= st
->n
.common
->head
; sym
; sym
= sym
->common_next
)
698 gfc_set_sym_referenced (sym
);
699 p
= gfc_get_omp_namelist ();
708 tail
->where
= gfc_current_locus
;
712 if (gfc_match_char (')') == MATCH_YES
)
714 if (gfc_match_char (',') != MATCH_YES
)
718 if (gfc_match_omp_eos () != MATCH_YES
)
720 gfc_error ("Unexpected junk after !$ACC DECLARE at %C");
725 list
= &(*list
)->next
;
730 gfc_error ("Syntax error in !$ACC DECLARE list at %C");
733 gfc_current_locus
= old_loc
;
737 /* OpenMP 4.5 clauses. */
741 OMP_CLAUSE_FIRSTPRIVATE
,
742 OMP_CLAUSE_LASTPRIVATE
,
743 OMP_CLAUSE_COPYPRIVATE
,
746 OMP_CLAUSE_REDUCTION
,
748 OMP_CLAUSE_NUM_THREADS
,
755 OMP_CLAUSE_MERGEABLE
,
760 OMP_CLAUSE_NOTINBRANCH
,
761 OMP_CLAUSE_PROC_BIND
,
769 OMP_CLAUSE_NUM_TEAMS
,
770 OMP_CLAUSE_THREAD_LIMIT
,
771 OMP_CLAUSE_DIST_SCHEDULE
,
772 OMP_CLAUSE_DEFAULTMAP
,
773 OMP_CLAUSE_GRAINSIZE
,
775 OMP_CLAUSE_IS_DEVICE_PTR
,
778 OMP_CLAUSE_NUM_TASKS
,
782 OMP_CLAUSE_USE_DEVICE_PTR
,
784 /* This must come last. */
788 /* OpenACC 2.0 specific clauses. */
792 OMP_CLAUSE_NUM_GANGS
,
793 OMP_CLAUSE_NUM_WORKERS
,
794 OMP_CLAUSE_VECTOR_LENGTH
,
799 OMP_CLAUSE_DEVICEPTR
,
804 OMP_CLAUSE_INDEPENDENT
,
805 OMP_CLAUSE_USE_DEVICE
,
806 OMP_CLAUSE_DEVICE_RESIDENT
,
807 OMP_CLAUSE_HOST_SELF
,
812 OMP_CLAUSE_IF_PRESENT
,
814 /* This must come last. */
820 /* Customized bitset for up to 128-bits.
821 The two enums above provide bit numbers to use, and which of the
822 two enums it is determines which of the two mask fields is used.
823 Supported operations are defining a mask, like:
824 #define XXX_CLAUSES \
825 (omp_mask (OMP_CLAUSE_XXX) | OMP_CLAUSE_YYY | OMP_CLAUSE_ZZZ)
826 oring such bitsets together or removing selected bits:
827 (XXX_CLAUSES | YYY_CLAUSES) & ~(omp_mask (OMP_CLAUSE_VVV))
828 and testing individual bits:
829 if (mask & OMP_CLAUSE_UUU) */
832 const uint64_t mask1
;
833 const uint64_t mask2
;
835 inline omp_mask (omp_mask1
);
836 inline omp_mask (omp_mask2
);
837 inline omp_mask (uint64_t, uint64_t);
838 inline omp_mask
operator| (omp_mask1
) const;
839 inline omp_mask
operator| (omp_mask2
) const;
840 inline omp_mask
operator| (omp_mask
) const;
841 inline omp_mask
operator& (const omp_inv_mask
&) const;
842 inline bool operator& (omp_mask1
) const;
843 inline bool operator& (omp_mask2
) const;
844 inline omp_inv_mask
operator~ () const;
847 struct omp_inv_mask
: public omp_mask
{
848 inline omp_inv_mask (const omp_mask
&);
851 omp_mask::omp_mask () : mask1 (0), mask2 (0)
855 omp_mask::omp_mask (omp_mask1 m
) : mask1 (((uint64_t) 1) << m
), mask2 (0)
859 omp_mask::omp_mask (omp_mask2 m
) : mask1 (0), mask2 (((uint64_t) 1) << m
)
863 omp_mask::omp_mask (uint64_t m1
, uint64_t m2
) : mask1 (m1
), mask2 (m2
)
868 omp_mask::operator| (omp_mask1 m
) const
870 return omp_mask (mask1
| (((uint64_t) 1) << m
), mask2
);
874 omp_mask::operator| (omp_mask2 m
) const
876 return omp_mask (mask1
, mask2
| (((uint64_t) 1) << m
));
880 omp_mask::operator| (omp_mask m
) const
882 return omp_mask (mask1
| m
.mask1
, mask2
| m
.mask2
);
886 omp_mask::operator& (const omp_inv_mask
&m
) const
888 return omp_mask (mask1
& ~m
.mask1
, mask2
& ~m
.mask2
);
892 omp_mask::operator& (omp_mask1 m
) const
894 return (mask1
& (((uint64_t) 1) << m
)) != 0;
898 omp_mask::operator& (omp_mask2 m
) const
900 return (mask2
& (((uint64_t) 1) << m
)) != 0;
904 omp_mask::operator~ () const
906 return omp_inv_mask (*this);
909 omp_inv_mask::omp_inv_mask (const omp_mask
&m
) : omp_mask (m
)
913 /* Helper function for OpenACC and OpenMP clauses involving memory
917 gfc_match_omp_map_clause (gfc_omp_namelist
**list
, gfc_omp_map_op map_op
)
919 gfc_omp_namelist
**head
= NULL
;
920 if (gfc_match_omp_variable_list ("", list
, false, NULL
, &head
, true)
924 for (n
= *head
; n
; n
= n
->next
)
925 n
->u
.map_op
= map_op
;
932 /* Match OpenMP and OpenACC directive clauses. MASK is a bitmask of
933 clauses that are allowed for a particular directive. */
936 gfc_match_omp_clauses (gfc_omp_clauses
**cp
, const omp_mask mask
,
937 bool first
= true, bool needs_space
= true,
938 bool openacc
= false)
940 gfc_omp_clauses
*c
= gfc_get_omp_clauses ();
943 gcc_checking_assert (OMP_MASK1_LAST
<= 64 && OMP_MASK2_LAST
<= 64);
947 if ((first
|| gfc_match_char (',') != MATCH_YES
)
948 && (needs_space
&& gfc_match_space () != MATCH_YES
))
952 gfc_gobble_whitespace ();
954 gfc_omp_namelist
**head
;
955 old_loc
= gfc_current_locus
;
956 char pc
= gfc_peek_ascii_char ();
962 if ((mask
& OMP_CLAUSE_ALIGNED
)
963 && gfc_match_omp_variable_list ("aligned (",
964 &c
->lists
[OMP_LIST_ALIGNED
],
968 gfc_expr
*alignment
= NULL
;
971 if (end_colon
&& gfc_match (" %e )", &alignment
) != MATCH_YES
)
973 gfc_free_omp_namelist (*head
);
974 gfc_current_locus
= old_loc
;
978 for (n
= *head
; n
; n
= n
->next
)
979 if (n
->next
&& alignment
)
980 n
->expr
= gfc_copy_expr (alignment
);
985 if ((mask
& OMP_CLAUSE_ASYNC
)
987 && gfc_match ("async") == MATCH_YES
)
990 match m
= gfc_match (" ( %e )", &c
->async_expr
);
991 if (m
== MATCH_ERROR
)
993 gfc_current_locus
= old_loc
;
996 else if (m
== MATCH_NO
)
999 = gfc_get_constant_expr (BT_INTEGER
,
1000 gfc_default_integer_kind
,
1001 &gfc_current_locus
);
1002 mpz_set_si (c
->async_expr
->value
.integer
, GOMP_ASYNC_NOVAL
);
1007 if ((mask
& OMP_CLAUSE_AUTO
)
1009 && gfc_match ("auto") == MATCH_YES
)
1017 if ((mask
& OMP_CLAUSE_COLLAPSE
)
1020 gfc_expr
*cexpr
= NULL
;
1021 match m
= gfc_match ("collapse ( %e )", &cexpr
);
1026 if (gfc_extract_int (cexpr
, &collapse
, -1))
1028 else if (collapse
<= 0)
1030 gfc_error_now ("COLLAPSE clause argument not"
1031 " constant positive integer at %C");
1034 c
->collapse
= collapse
;
1035 gfc_free_expr (cexpr
);
1039 if ((mask
& OMP_CLAUSE_COPY
)
1040 && gfc_match ("copy ( ") == MATCH_YES
1041 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1044 if (mask
& OMP_CLAUSE_COPYIN
)
1048 if (gfc_match ("copyin ( ") == MATCH_YES
1049 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1053 else if (gfc_match_omp_variable_list ("copyin (",
1054 &c
->lists
[OMP_LIST_COPYIN
],
1058 if ((mask
& OMP_CLAUSE_COPYOUT
)
1059 && gfc_match ("copyout ( ") == MATCH_YES
1060 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1063 if ((mask
& OMP_CLAUSE_COPYPRIVATE
)
1064 && gfc_match_omp_variable_list ("copyprivate (",
1065 &c
->lists
[OMP_LIST_COPYPRIVATE
],
1068 if ((mask
& OMP_CLAUSE_CREATE
)
1069 && gfc_match ("create ( ") == MATCH_YES
1070 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1075 if ((mask
& OMP_CLAUSE_DEFAULT
)
1076 && c
->default_sharing
== OMP_DEFAULT_UNKNOWN
)
1078 if (gfc_match ("default ( none )") == MATCH_YES
)
1079 c
->default_sharing
= OMP_DEFAULT_NONE
;
1082 if (gfc_match ("default ( present )") == MATCH_YES
)
1083 c
->default_sharing
= OMP_DEFAULT_PRESENT
;
1087 if (gfc_match ("default ( firstprivate )") == MATCH_YES
)
1088 c
->default_sharing
= OMP_DEFAULT_FIRSTPRIVATE
;
1089 else if (gfc_match ("default ( private )") == MATCH_YES
)
1090 c
->default_sharing
= OMP_DEFAULT_PRIVATE
;
1091 else if (gfc_match ("default ( shared )") == MATCH_YES
)
1092 c
->default_sharing
= OMP_DEFAULT_SHARED
;
1094 if (c
->default_sharing
!= OMP_DEFAULT_UNKNOWN
)
1097 if ((mask
& OMP_CLAUSE_DEFAULTMAP
)
1099 && gfc_match ("defaultmap ( tofrom : scalar )") == MATCH_YES
)
1101 c
->defaultmap
= true;
1104 if ((mask
& OMP_CLAUSE_DELETE
)
1105 && gfc_match ("delete ( ") == MATCH_YES
1106 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1109 if ((mask
& OMP_CLAUSE_DEPEND
)
1110 && gfc_match ("depend ( ") == MATCH_YES
)
1112 match m
= MATCH_YES
;
1113 gfc_omp_depend_op depend_op
= OMP_DEPEND_OUT
;
1114 if (gfc_match ("inout") == MATCH_YES
)
1115 depend_op
= OMP_DEPEND_INOUT
;
1116 else if (gfc_match ("in") == MATCH_YES
)
1117 depend_op
= OMP_DEPEND_IN
;
1118 else if (gfc_match ("out") == MATCH_YES
)
1119 depend_op
= OMP_DEPEND_OUT
;
1120 else if (!c
->depend_source
1121 && gfc_match ("source )") == MATCH_YES
)
1123 c
->depend_source
= true;
1126 else if (gfc_match ("sink : ") == MATCH_YES
)
1128 if (gfc_match_omp_depend_sink (&c
->lists
[OMP_LIST_DEPEND
])
1137 && gfc_match_omp_variable_list (" : ",
1138 &c
->lists
[OMP_LIST_DEPEND
],
1142 gfc_omp_namelist
*n
;
1143 for (n
= *head
; n
; n
= n
->next
)
1144 n
->u
.depend_op
= depend_op
;
1148 gfc_current_locus
= old_loc
;
1150 if ((mask
& OMP_CLAUSE_DEVICE
)
1152 && c
->device
== NULL
1153 && gfc_match ("device ( %e )", &c
->device
) == MATCH_YES
)
1155 if ((mask
& OMP_CLAUSE_DEVICE
)
1157 && gfc_match ("device ( ") == MATCH_YES
1158 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1161 if ((mask
& OMP_CLAUSE_DEVICEPTR
)
1162 && gfc_match ("deviceptr ( ") == MATCH_YES
1163 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1164 OMP_MAP_FORCE_DEVICEPTR
))
1166 if ((mask
& OMP_CLAUSE_DEVICE_RESIDENT
)
1167 && gfc_match_omp_variable_list
1168 ("device_resident (",
1169 &c
->lists
[OMP_LIST_DEVICE_RESIDENT
], true) == MATCH_YES
)
1171 if ((mask
& OMP_CLAUSE_DIST_SCHEDULE
)
1172 && c
->dist_sched_kind
== OMP_SCHED_NONE
1173 && gfc_match ("dist_schedule ( static") == MATCH_YES
)
1176 c
->dist_sched_kind
= OMP_SCHED_STATIC
;
1177 m
= gfc_match (" , %e )", &c
->dist_chunk_size
);
1179 m
= gfc_match_char (')');
1182 c
->dist_sched_kind
= OMP_SCHED_NONE
;
1183 gfc_current_locus
= old_loc
;
1190 if ((mask
& OMP_CLAUSE_FINAL
)
1191 && c
->final_expr
== NULL
1192 && gfc_match ("final ( %e )", &c
->final_expr
) == MATCH_YES
)
1194 if ((mask
& OMP_CLAUSE_FINALIZE
)
1196 && gfc_match ("finalize") == MATCH_YES
)
1202 if ((mask
& OMP_CLAUSE_FIRSTPRIVATE
)
1203 && gfc_match_omp_variable_list ("firstprivate (",
1204 &c
->lists
[OMP_LIST_FIRSTPRIVATE
],
1207 if ((mask
& OMP_CLAUSE_FROM
)
1208 && gfc_match_omp_variable_list ("from (",
1209 &c
->lists
[OMP_LIST_FROM
], false,
1210 NULL
, &head
, true) == MATCH_YES
)
1214 if ((mask
& OMP_CLAUSE_GANG
)
1216 && gfc_match ("gang") == MATCH_YES
)
1219 match m
= match_oacc_clause_gwv (c
, GOMP_DIM_GANG
);
1220 if (m
== MATCH_ERROR
)
1222 gfc_current_locus
= old_loc
;
1225 else if (m
== MATCH_NO
)
1229 if ((mask
& OMP_CLAUSE_GRAINSIZE
)
1230 && c
->grainsize
== NULL
1231 && gfc_match ("grainsize ( %e )", &c
->grainsize
) == MATCH_YES
)
1235 if ((mask
& OMP_CLAUSE_HINT
)
1237 && gfc_match ("hint ( %e )", &c
->hint
) == MATCH_YES
)
1239 if ((mask
& OMP_CLAUSE_HOST_SELF
)
1240 && gfc_match ("host ( ") == MATCH_YES
1241 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1242 OMP_MAP_FORCE_FROM
))
1246 if ((mask
& OMP_CLAUSE_IF
)
1247 && c
->if_expr
== NULL
1248 && gfc_match ("if ( ") == MATCH_YES
)
1250 if (gfc_match ("%e )", &c
->if_expr
) == MATCH_YES
)
1254 /* This should match the enum gfc_omp_if_kind order. */
1255 static const char *ifs
[OMP_IF_LAST
] = {
1260 " target data : %e )",
1261 " target update : %e )",
1262 " target enter data : %e )",
1263 " target exit data : %e )" };
1265 for (i
= 0; i
< OMP_IF_LAST
; i
++)
1266 if (c
->if_exprs
[i
] == NULL
1267 && gfc_match (ifs
[i
], &c
->if_exprs
[i
]) == MATCH_YES
)
1269 if (i
< OMP_IF_LAST
)
1272 gfc_current_locus
= old_loc
;
1274 if ((mask
& OMP_CLAUSE_IF_PRESENT
)
1276 && gfc_match ("if_present") == MATCH_YES
)
1278 c
->if_present
= true;
1282 if ((mask
& OMP_CLAUSE_INBRANCH
)
1285 && gfc_match ("inbranch") == MATCH_YES
)
1287 c
->inbranch
= needs_space
= true;
1290 if ((mask
& OMP_CLAUSE_INDEPENDENT
)
1292 && gfc_match ("independent") == MATCH_YES
)
1294 c
->independent
= true;
1298 if ((mask
& OMP_CLAUSE_IS_DEVICE_PTR
)
1299 && gfc_match_omp_variable_list
1301 &c
->lists
[OMP_LIST_IS_DEVICE_PTR
], false) == MATCH_YES
)
1305 if ((mask
& OMP_CLAUSE_LASTPRIVATE
)
1306 && gfc_match_omp_variable_list ("lastprivate (",
1307 &c
->lists
[OMP_LIST_LASTPRIVATE
],
1312 if ((mask
& OMP_CLAUSE_LINEAR
)
1313 && gfc_match ("linear (") == MATCH_YES
)
1315 gfc_omp_linear_op linear_op
= OMP_LINEAR_DEFAULT
;
1316 gfc_expr
*step
= NULL
;
1318 if (gfc_match_omp_variable_list (" ref (",
1319 &c
->lists
[OMP_LIST_LINEAR
],
1322 linear_op
= OMP_LINEAR_REF
;
1323 else if (gfc_match_omp_variable_list (" val (",
1324 &c
->lists
[OMP_LIST_LINEAR
],
1327 linear_op
= OMP_LINEAR_VAL
;
1328 else if (gfc_match_omp_variable_list (" uval (",
1329 &c
->lists
[OMP_LIST_LINEAR
],
1332 linear_op
= OMP_LINEAR_UVAL
;
1333 else if (gfc_match_omp_variable_list ("",
1334 &c
->lists
[OMP_LIST_LINEAR
],
1335 false, &end_colon
, &head
)
1337 linear_op
= OMP_LINEAR_DEFAULT
;
1340 gfc_current_locus
= old_loc
;
1343 if (linear_op
!= OMP_LINEAR_DEFAULT
)
1345 if (gfc_match (" :") == MATCH_YES
)
1347 else if (gfc_match (" )") != MATCH_YES
)
1349 gfc_free_omp_namelist (*head
);
1350 gfc_current_locus
= old_loc
;
1355 if (end_colon
&& gfc_match (" %e )", &step
) != MATCH_YES
)
1357 gfc_free_omp_namelist (*head
);
1358 gfc_current_locus
= old_loc
;
1362 else if (!end_colon
)
1364 step
= gfc_get_constant_expr (BT_INTEGER
,
1365 gfc_default_integer_kind
,
1367 mpz_set_si (step
->value
.integer
, 1);
1369 (*head
)->expr
= step
;
1370 if (linear_op
!= OMP_LINEAR_DEFAULT
)
1371 for (gfc_omp_namelist
*n
= *head
; n
; n
= n
->next
)
1372 n
->u
.linear_op
= linear_op
;
1375 if ((mask
& OMP_CLAUSE_LINK
)
1377 && (gfc_match_oacc_clause_link ("link (",
1378 &c
->lists
[OMP_LIST_LINK
])
1381 else if ((mask
& OMP_CLAUSE_LINK
)
1383 && (gfc_match_omp_to_link ("link (",
1384 &c
->lists
[OMP_LIST_LINK
])
1389 if ((mask
& OMP_CLAUSE_MAP
)
1390 && gfc_match ("map ( ") == MATCH_YES
)
1392 locus old_loc2
= gfc_current_locus
;
1393 bool always
= false;
1394 gfc_omp_map_op map_op
= OMP_MAP_TOFROM
;
1395 if (gfc_match ("always , ") == MATCH_YES
)
1397 if (gfc_match ("alloc : ") == MATCH_YES
)
1398 map_op
= OMP_MAP_ALLOC
;
1399 else if (gfc_match ("tofrom : ") == MATCH_YES
)
1400 map_op
= always
? OMP_MAP_ALWAYS_TOFROM
: OMP_MAP_TOFROM
;
1401 else if (gfc_match ("to : ") == MATCH_YES
)
1402 map_op
= always
? OMP_MAP_ALWAYS_TO
: OMP_MAP_TO
;
1403 else if (gfc_match ("from : ") == MATCH_YES
)
1404 map_op
= always
? OMP_MAP_ALWAYS_FROM
: OMP_MAP_FROM
;
1405 else if (gfc_match ("release : ") == MATCH_YES
)
1406 map_op
= OMP_MAP_RELEASE
;
1407 else if (gfc_match ("delete : ") == MATCH_YES
)
1408 map_op
= OMP_MAP_DELETE
;
1411 gfc_current_locus
= old_loc2
;
1415 if (gfc_match_omp_variable_list ("", &c
->lists
[OMP_LIST_MAP
],
1419 gfc_omp_namelist
*n
;
1420 for (n
= *head
; n
; n
= n
->next
)
1421 n
->u
.map_op
= map_op
;
1425 gfc_current_locus
= old_loc
;
1427 if ((mask
& OMP_CLAUSE_MERGEABLE
) && !c
->mergeable
1428 && gfc_match ("mergeable") == MATCH_YES
)
1430 c
->mergeable
= needs_space
= true;
1435 if ((mask
& OMP_CLAUSE_NOGROUP
)
1437 && gfc_match ("nogroup") == MATCH_YES
)
1439 c
->nogroup
= needs_space
= true;
1442 if ((mask
& OMP_CLAUSE_NOTINBRANCH
)
1445 && gfc_match ("notinbranch") == MATCH_YES
)
1447 c
->notinbranch
= needs_space
= true;
1450 if ((mask
& OMP_CLAUSE_NOWAIT
)
1452 && gfc_match ("nowait") == MATCH_YES
)
1454 c
->nowait
= needs_space
= true;
1457 if ((mask
& OMP_CLAUSE_NUM_GANGS
)
1458 && c
->num_gangs_expr
== NULL
1459 && gfc_match ("num_gangs ( %e )",
1460 &c
->num_gangs_expr
) == MATCH_YES
)
1462 if ((mask
& OMP_CLAUSE_NUM_TASKS
)
1463 && c
->num_tasks
== NULL
1464 && gfc_match ("num_tasks ( %e )", &c
->num_tasks
) == MATCH_YES
)
1466 if ((mask
& OMP_CLAUSE_NUM_TEAMS
)
1467 && c
->num_teams
== NULL
1468 && gfc_match ("num_teams ( %e )", &c
->num_teams
) == MATCH_YES
)
1470 if ((mask
& OMP_CLAUSE_NUM_THREADS
)
1471 && c
->num_threads
== NULL
1472 && (gfc_match ("num_threads ( %e )", &c
->num_threads
)
1475 if ((mask
& OMP_CLAUSE_NUM_WORKERS
)
1476 && c
->num_workers_expr
== NULL
1477 && gfc_match ("num_workers ( %e )",
1478 &c
->num_workers_expr
) == MATCH_YES
)
1482 if ((mask
& OMP_CLAUSE_ORDERED
)
1484 && gfc_match ("ordered") == MATCH_YES
)
1486 gfc_expr
*cexpr
= NULL
;
1487 match m
= gfc_match (" ( %e )", &cexpr
);
1493 if (gfc_extract_int (cexpr
, &ordered
, -1))
1495 else if (ordered
<= 0)
1497 gfc_error_now ("ORDERED clause argument not"
1498 " constant positive integer at %C");
1501 c
->orderedc
= ordered
;
1502 gfc_free_expr (cexpr
);
1511 if ((mask
& OMP_CLAUSE_COPY
)
1512 && gfc_match ("pcopy ( ") == MATCH_YES
1513 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1516 if ((mask
& OMP_CLAUSE_COPYIN
)
1517 && gfc_match ("pcopyin ( ") == MATCH_YES
1518 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1521 if ((mask
& OMP_CLAUSE_COPYOUT
)
1522 && gfc_match ("pcopyout ( ") == MATCH_YES
1523 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1526 if ((mask
& OMP_CLAUSE_CREATE
)
1527 && gfc_match ("pcreate ( ") == MATCH_YES
1528 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1531 if ((mask
& OMP_CLAUSE_PRESENT
)
1532 && gfc_match ("present ( ") == MATCH_YES
1533 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1534 OMP_MAP_FORCE_PRESENT
))
1536 if ((mask
& OMP_CLAUSE_COPY
)
1537 && gfc_match ("present_or_copy ( ") == MATCH_YES
1538 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1541 if ((mask
& OMP_CLAUSE_COPYIN
)
1542 && gfc_match ("present_or_copyin ( ") == MATCH_YES
1543 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1546 if ((mask
& OMP_CLAUSE_COPYOUT
)
1547 && gfc_match ("present_or_copyout ( ") == MATCH_YES
1548 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1551 if ((mask
& OMP_CLAUSE_CREATE
)
1552 && gfc_match ("present_or_create ( ") == MATCH_YES
1553 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1556 if ((mask
& OMP_CLAUSE_PRIORITY
)
1557 && c
->priority
== NULL
1558 && gfc_match ("priority ( %e )", &c
->priority
) == MATCH_YES
)
1560 if ((mask
& OMP_CLAUSE_PRIVATE
)
1561 && gfc_match_omp_variable_list ("private (",
1562 &c
->lists
[OMP_LIST_PRIVATE
],
1565 if ((mask
& OMP_CLAUSE_PROC_BIND
)
1566 && c
->proc_bind
== OMP_PROC_BIND_UNKNOWN
)
1568 if (gfc_match ("proc_bind ( master )") == MATCH_YES
)
1569 c
->proc_bind
= OMP_PROC_BIND_MASTER
;
1570 else if (gfc_match ("proc_bind ( spread )") == MATCH_YES
)
1571 c
->proc_bind
= OMP_PROC_BIND_SPREAD
;
1572 else if (gfc_match ("proc_bind ( close )") == MATCH_YES
)
1573 c
->proc_bind
= OMP_PROC_BIND_CLOSE
;
1574 if (c
->proc_bind
!= OMP_PROC_BIND_UNKNOWN
)
1579 if ((mask
& OMP_CLAUSE_REDUCTION
)
1580 && gfc_match ("reduction ( ") == MATCH_YES
)
1582 gfc_omp_reduction_op rop
= OMP_REDUCTION_NONE
;
1583 char buffer
[GFC_MAX_SYMBOL_LEN
+ 3];
1584 if (gfc_match_char ('+') == MATCH_YES
)
1585 rop
= OMP_REDUCTION_PLUS
;
1586 else if (gfc_match_char ('*') == MATCH_YES
)
1587 rop
= OMP_REDUCTION_TIMES
;
1588 else if (gfc_match_char ('-') == MATCH_YES
)
1589 rop
= OMP_REDUCTION_MINUS
;
1590 else if (gfc_match (".and.") == MATCH_YES
)
1591 rop
= OMP_REDUCTION_AND
;
1592 else if (gfc_match (".or.") == MATCH_YES
)
1593 rop
= OMP_REDUCTION_OR
;
1594 else if (gfc_match (".eqv.") == MATCH_YES
)
1595 rop
= OMP_REDUCTION_EQV
;
1596 else if (gfc_match (".neqv.") == MATCH_YES
)
1597 rop
= OMP_REDUCTION_NEQV
;
1598 if (rop
!= OMP_REDUCTION_NONE
)
1599 snprintf (buffer
, sizeof buffer
, "operator %s",
1600 gfc_op2string ((gfc_intrinsic_op
) rop
));
1601 else if (gfc_match_defined_op_name (buffer
+ 1, 1) == MATCH_YES
)
1604 strcat (buffer
, ".");
1606 else if (gfc_match_name (buffer
) == MATCH_YES
)
1609 const char *n
= buffer
;
1611 gfc_find_symbol (buffer
, NULL
, 1, &sym
);
1614 if (sym
->attr
.intrinsic
)
1616 else if ((sym
->attr
.flavor
!= FL_UNKNOWN
1617 && sym
->attr
.flavor
!= FL_PROCEDURE
)
1618 || sym
->attr
.external
1619 || sym
->attr
.generic
1623 || sym
->attr
.subroutine
1624 || sym
->attr
.pointer
1626 || sym
->attr
.cray_pointer
1627 || sym
->attr
.cray_pointee
1628 || (sym
->attr
.proc
!= PROC_UNKNOWN
1629 && sym
->attr
.proc
!= PROC_INTRINSIC
)
1630 || sym
->attr
.if_source
!= IFSRC_UNKNOWN
1631 || sym
== sym
->ns
->proc_name
)
1640 rop
= OMP_REDUCTION_NONE
;
1641 else if (strcmp (n
, "max") == 0)
1642 rop
= OMP_REDUCTION_MAX
;
1643 else if (strcmp (n
, "min") == 0)
1644 rop
= OMP_REDUCTION_MIN
;
1645 else if (strcmp (n
, "iand") == 0)
1646 rop
= OMP_REDUCTION_IAND
;
1647 else if (strcmp (n
, "ior") == 0)
1648 rop
= OMP_REDUCTION_IOR
;
1649 else if (strcmp (n
, "ieor") == 0)
1650 rop
= OMP_REDUCTION_IEOR
;
1651 if (rop
!= OMP_REDUCTION_NONE
1653 && ! sym
->attr
.intrinsic
1654 && ! sym
->attr
.use_assoc
1655 && ((sym
->attr
.flavor
== FL_UNKNOWN
1656 && !gfc_add_flavor (&sym
->attr
, FL_PROCEDURE
,
1658 || !gfc_add_intrinsic (&sym
->attr
, NULL
)))
1659 rop
= OMP_REDUCTION_NONE
;
1665 ? gfc_find_omp_udr (gfc_current_ns
, buffer
, NULL
) : NULL
);
1666 gfc_omp_namelist
**head
= NULL
;
1667 if (rop
== OMP_REDUCTION_NONE
&& udr
)
1668 rop
= OMP_REDUCTION_USER
;
1670 if (gfc_match_omp_variable_list (" :",
1671 &c
->lists
[OMP_LIST_REDUCTION
],
1673 openacc
) == MATCH_YES
)
1675 gfc_omp_namelist
*n
;
1676 if (rop
== OMP_REDUCTION_NONE
)
1680 gfc_error_now ("!$OMP DECLARE REDUCTION %s not found "
1681 "at %L", buffer
, &old_loc
);
1682 gfc_free_omp_namelist (n
);
1685 for (n
= *head
; n
; n
= n
->next
)
1687 n
->u
.reduction_op
= rop
;
1690 n
->udr
= gfc_get_omp_namelist_udr ();
1697 gfc_current_locus
= old_loc
;
1701 if ((mask
& OMP_CLAUSE_SAFELEN
)
1702 && c
->safelen_expr
== NULL
1703 && gfc_match ("safelen ( %e )", &c
->safelen_expr
) == MATCH_YES
)
1705 if ((mask
& OMP_CLAUSE_SCHEDULE
)
1706 && c
->sched_kind
== OMP_SCHED_NONE
1707 && gfc_match ("schedule ( ") == MATCH_YES
)
1710 locus old_loc2
= gfc_current_locus
;
1713 if (gfc_match ("simd") == MATCH_YES
)
1715 c
->sched_simd
= true;
1718 else if (gfc_match ("monotonic") == MATCH_YES
)
1720 c
->sched_monotonic
= true;
1723 else if (gfc_match ("nonmonotonic") == MATCH_YES
)
1725 c
->sched_nonmonotonic
= true;
1731 gfc_current_locus
= old_loc2
;
1735 && gfc_match (" , ") == MATCH_YES
)
1737 else if (gfc_match (" : ") == MATCH_YES
)
1739 gfc_current_locus
= old_loc2
;
1743 if (gfc_match ("static") == MATCH_YES
)
1744 c
->sched_kind
= OMP_SCHED_STATIC
;
1745 else if (gfc_match ("dynamic") == MATCH_YES
)
1746 c
->sched_kind
= OMP_SCHED_DYNAMIC
;
1747 else if (gfc_match ("guided") == MATCH_YES
)
1748 c
->sched_kind
= OMP_SCHED_GUIDED
;
1749 else if (gfc_match ("runtime") == MATCH_YES
)
1750 c
->sched_kind
= OMP_SCHED_RUNTIME
;
1751 else if (gfc_match ("auto") == MATCH_YES
)
1752 c
->sched_kind
= OMP_SCHED_AUTO
;
1753 if (c
->sched_kind
!= OMP_SCHED_NONE
)
1756 if (c
->sched_kind
!= OMP_SCHED_RUNTIME
1757 && c
->sched_kind
!= OMP_SCHED_AUTO
)
1758 m
= gfc_match (" , %e )", &c
->chunk_size
);
1760 m
= gfc_match_char (')');
1762 c
->sched_kind
= OMP_SCHED_NONE
;
1764 if (c
->sched_kind
!= OMP_SCHED_NONE
)
1767 gfc_current_locus
= old_loc
;
1769 if ((mask
& OMP_CLAUSE_HOST_SELF
)
1770 && gfc_match ("self ( ") == MATCH_YES
1771 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1772 OMP_MAP_FORCE_FROM
))
1774 if ((mask
& OMP_CLAUSE_SEQ
)
1776 && gfc_match ("seq") == MATCH_YES
)
1782 if ((mask
& OMP_CLAUSE_SHARED
)
1783 && gfc_match_omp_variable_list ("shared (",
1784 &c
->lists
[OMP_LIST_SHARED
],
1787 if ((mask
& OMP_CLAUSE_SIMDLEN
)
1788 && c
->simdlen_expr
== NULL
1789 && gfc_match ("simdlen ( %e )", &c
->simdlen_expr
) == MATCH_YES
)
1791 if ((mask
& OMP_CLAUSE_SIMD
)
1793 && gfc_match ("simd") == MATCH_YES
)
1795 c
->simd
= needs_space
= true;
1800 if ((mask
& OMP_CLAUSE_THREAD_LIMIT
)
1801 && c
->thread_limit
== NULL
1802 && gfc_match ("thread_limit ( %e )",
1803 &c
->thread_limit
) == MATCH_YES
)
1805 if ((mask
& OMP_CLAUSE_THREADS
)
1807 && gfc_match ("threads") == MATCH_YES
)
1809 c
->threads
= needs_space
= true;
1812 if ((mask
& OMP_CLAUSE_TILE
)
1814 && match_oacc_expr_list ("tile (", &c
->tile_list
,
1817 if ((mask
& OMP_CLAUSE_TO
) && (mask
& OMP_CLAUSE_LINK
))
1819 if (gfc_match_omp_to_link ("to (", &c
->lists
[OMP_LIST_TO
])
1823 else if ((mask
& OMP_CLAUSE_TO
)
1824 && gfc_match_omp_variable_list ("to (",
1825 &c
->lists
[OMP_LIST_TO
], false,
1826 NULL
, &head
, true) == MATCH_YES
)
1830 if ((mask
& OMP_CLAUSE_UNIFORM
)
1831 && gfc_match_omp_variable_list ("uniform (",
1832 &c
->lists
[OMP_LIST_UNIFORM
],
1833 false) == MATCH_YES
)
1835 if ((mask
& OMP_CLAUSE_UNTIED
)
1837 && gfc_match ("untied") == MATCH_YES
)
1839 c
->untied
= needs_space
= true;
1842 if ((mask
& OMP_CLAUSE_USE_DEVICE
)
1843 && gfc_match_omp_variable_list ("use_device (",
1844 &c
->lists
[OMP_LIST_USE_DEVICE
],
1847 if ((mask
& OMP_CLAUSE_USE_DEVICE_PTR
)
1848 && gfc_match_omp_variable_list
1849 ("use_device_ptr (",
1850 &c
->lists
[OMP_LIST_USE_DEVICE_PTR
], false) == MATCH_YES
)
1854 /* VECTOR_LENGTH must be matched before VECTOR, because the latter
1855 doesn't unconditionally match '('. */
1856 if ((mask
& OMP_CLAUSE_VECTOR_LENGTH
)
1857 && c
->vector_length_expr
== NULL
1858 && (gfc_match ("vector_length ( %e )", &c
->vector_length_expr
)
1861 if ((mask
& OMP_CLAUSE_VECTOR
)
1863 && gfc_match ("vector") == MATCH_YES
)
1866 match m
= match_oacc_clause_gwv (c
, GOMP_DIM_VECTOR
);
1867 if (m
== MATCH_ERROR
)
1869 gfc_current_locus
= old_loc
;
1878 if ((mask
& OMP_CLAUSE_WAIT
)
1879 && gfc_match ("wait") == MATCH_YES
)
1881 match m
= match_oacc_expr_list (" (", &c
->wait_list
, false);
1882 if (m
== MATCH_ERROR
)
1884 gfc_current_locus
= old_loc
;
1887 else if (m
== MATCH_NO
)
1890 = gfc_get_constant_expr (BT_INTEGER
,
1891 gfc_default_integer_kind
,
1892 &gfc_current_locus
);
1893 mpz_set_si (expr
->value
.integer
, GOMP_ASYNC_NOVAL
);
1894 gfc_expr_list
**expr_list
= &c
->wait_list
;
1896 expr_list
= &(*expr_list
)->next
;
1897 *expr_list
= gfc_get_expr_list ();
1898 (*expr_list
)->expr
= expr
;
1903 if ((mask
& OMP_CLAUSE_WORKER
)
1905 && gfc_match ("worker") == MATCH_YES
)
1908 match m
= match_oacc_clause_gwv (c
, GOMP_DIM_WORKER
);
1909 if (m
== MATCH_ERROR
)
1911 gfc_current_locus
= old_loc
;
1914 else if (m
== MATCH_NO
)
1923 if (gfc_match_omp_eos () != MATCH_YES
)
1925 gfc_free_omp_clauses (c
);
1934 #define OACC_PARALLEL_CLAUSES \
1935 (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_NUM_GANGS \
1936 | OMP_CLAUSE_NUM_WORKERS | OMP_CLAUSE_VECTOR_LENGTH | OMP_CLAUSE_REDUCTION \
1937 | OMP_CLAUSE_COPY | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT \
1938 | OMP_CLAUSE_CREATE | OMP_CLAUSE_PRESENT | OMP_CLAUSE_DEVICEPTR \
1939 | OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_DEFAULT \
1941 #define OACC_KERNELS_CLAUSES \
1942 (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_NUM_GANGS \
1943 | OMP_CLAUSE_NUM_WORKERS | OMP_CLAUSE_VECTOR_LENGTH | OMP_CLAUSE_DEVICEPTR \
1944 | OMP_CLAUSE_COPY | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT \
1945 | OMP_CLAUSE_CREATE | OMP_CLAUSE_PRESENT | OMP_CLAUSE_DEFAULT \
1947 #define OACC_DATA_CLAUSES \
1948 (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_DEVICEPTR | OMP_CLAUSE_COPY \
1949 | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT | OMP_CLAUSE_CREATE \
1950 | OMP_CLAUSE_PRESENT)
1951 #define OACC_LOOP_CLAUSES \
1952 (omp_mask (OMP_CLAUSE_COLLAPSE) | OMP_CLAUSE_GANG | OMP_CLAUSE_WORKER \
1953 | OMP_CLAUSE_VECTOR | OMP_CLAUSE_SEQ | OMP_CLAUSE_INDEPENDENT \
1954 | OMP_CLAUSE_PRIVATE | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_AUTO \
1956 #define OACC_PARALLEL_LOOP_CLAUSES \
1957 (OACC_LOOP_CLAUSES | OACC_PARALLEL_CLAUSES)
1958 #define OACC_KERNELS_LOOP_CLAUSES \
1959 (OACC_LOOP_CLAUSES | OACC_KERNELS_CLAUSES)
1960 #define OACC_HOST_DATA_CLAUSES omp_mask (OMP_CLAUSE_USE_DEVICE)
1961 #define OACC_DECLARE_CLAUSES \
1962 (omp_mask (OMP_CLAUSE_COPY) | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT \
1963 | OMP_CLAUSE_CREATE | OMP_CLAUSE_DEVICEPTR | OMP_CLAUSE_DEVICE_RESIDENT \
1964 | OMP_CLAUSE_PRESENT \
1966 #define OACC_UPDATE_CLAUSES \
1967 (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_HOST_SELF \
1968 | OMP_CLAUSE_DEVICE | OMP_CLAUSE_WAIT | OMP_CLAUSE_IF_PRESENT)
1969 #define OACC_ENTER_DATA_CLAUSES \
1970 (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_WAIT \
1971 | OMP_CLAUSE_COPYIN | OMP_CLAUSE_CREATE)
1972 #define OACC_EXIT_DATA_CLAUSES \
1973 (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_WAIT \
1974 | OMP_CLAUSE_COPYOUT | OMP_CLAUSE_DELETE | OMP_CLAUSE_FINALIZE)
1975 #define OACC_WAIT_CLAUSES \
1976 omp_mask (OMP_CLAUSE_ASYNC)
1977 #define OACC_ROUTINE_CLAUSES \
1978 (omp_mask (OMP_CLAUSE_GANG) | OMP_CLAUSE_WORKER | OMP_CLAUSE_VECTOR \
1983 match_acc (gfc_exec_op op
, const omp_mask mask
)
1986 if (gfc_match_omp_clauses (&c
, mask
, false, false, true) != MATCH_YES
)
1989 new_st
.ext
.omp_clauses
= c
;
1994 gfc_match_oacc_parallel_loop (void)
1996 return match_acc (EXEC_OACC_PARALLEL_LOOP
, OACC_PARALLEL_LOOP_CLAUSES
);
2001 gfc_match_oacc_parallel (void)
2003 return match_acc (EXEC_OACC_PARALLEL
, OACC_PARALLEL_CLAUSES
);
2008 gfc_match_oacc_kernels_loop (void)
2010 return match_acc (EXEC_OACC_KERNELS_LOOP
, OACC_KERNELS_LOOP_CLAUSES
);
2015 gfc_match_oacc_kernels (void)
2017 return match_acc (EXEC_OACC_KERNELS
, OACC_KERNELS_CLAUSES
);
2022 gfc_match_oacc_data (void)
2024 return match_acc (EXEC_OACC_DATA
, OACC_DATA_CLAUSES
);
2029 gfc_match_oacc_host_data (void)
2031 return match_acc (EXEC_OACC_HOST_DATA
, OACC_HOST_DATA_CLAUSES
);
2036 gfc_match_oacc_loop (void)
2038 return match_acc (EXEC_OACC_LOOP
, OACC_LOOP_CLAUSES
);
2043 gfc_match_oacc_declare (void)
2046 gfc_omp_namelist
*n
;
2047 gfc_namespace
*ns
= gfc_current_ns
;
2048 gfc_oacc_declare
*new_oc
;
2049 bool module_var
= false;
2050 locus where
= gfc_current_locus
;
2052 if (gfc_match_omp_clauses (&c
, OACC_DECLARE_CLAUSES
, false, false, true)
2056 for (n
= c
->lists
[OMP_LIST_DEVICE_RESIDENT
]; n
!= NULL
; n
= n
->next
)
2057 n
->sym
->attr
.oacc_declare_device_resident
= 1;
2059 for (n
= c
->lists
[OMP_LIST_LINK
]; n
!= NULL
; n
= n
->next
)
2060 n
->sym
->attr
.oacc_declare_link
= 1;
2062 for (n
= c
->lists
[OMP_LIST_MAP
]; n
!= NULL
; n
= n
->next
)
2064 gfc_symbol
*s
= n
->sym
;
2066 if (s
->ns
->proc_name
&& s
->ns
->proc_name
->attr
.proc
== PROC_MODULE
)
2068 if (n
->u
.map_op
!= OMP_MAP_ALLOC
&& n
->u
.map_op
!= OMP_MAP_TO
)
2070 gfc_error ("Invalid clause in module with !$ACC DECLARE at %L",
2078 if (s
->attr
.use_assoc
)
2080 gfc_error ("Variable is USE-associated with !$ACC DECLARE at %L",
2085 if ((s
->attr
.dimension
|| s
->attr
.codimension
)
2086 && s
->attr
.dummy
&& s
->as
->type
!= AS_EXPLICIT
)
2088 gfc_error ("Assumed-size dummy array with !$ACC DECLARE at %L",
2093 switch (n
->u
.map_op
)
2095 case OMP_MAP_FORCE_ALLOC
:
2097 s
->attr
.oacc_declare_create
= 1;
2100 case OMP_MAP_FORCE_TO
:
2102 s
->attr
.oacc_declare_copyin
= 1;
2105 case OMP_MAP_FORCE_DEVICEPTR
:
2106 s
->attr
.oacc_declare_deviceptr
= 1;
2114 new_oc
= gfc_get_oacc_declare ();
2115 new_oc
->next
= ns
->oacc_declare
;
2116 new_oc
->module_var
= module_var
;
2117 new_oc
->clauses
= c
;
2118 new_oc
->loc
= gfc_current_locus
;
2119 ns
->oacc_declare
= new_oc
;
2126 gfc_match_oacc_update (void)
2129 locus here
= gfc_current_locus
;
2131 if (gfc_match_omp_clauses (&c
, OACC_UPDATE_CLAUSES
, false, false, true)
2135 if (!c
->lists
[OMP_LIST_MAP
])
2137 gfc_error ("%<acc update%> must contain at least one "
2138 "%<device%> or %<host%> or %<self%> clause at %L", &here
);
2142 new_st
.op
= EXEC_OACC_UPDATE
;
2143 new_st
.ext
.omp_clauses
= c
;
2149 gfc_match_oacc_enter_data (void)
2151 return match_acc (EXEC_OACC_ENTER_DATA
, OACC_ENTER_DATA_CLAUSES
);
2156 gfc_match_oacc_exit_data (void)
2158 return match_acc (EXEC_OACC_EXIT_DATA
, OACC_EXIT_DATA_CLAUSES
);
2163 gfc_match_oacc_wait (void)
2165 gfc_omp_clauses
*c
= gfc_get_omp_clauses ();
2166 gfc_expr_list
*wait_list
= NULL
, *el
;
2170 m
= match_oacc_expr_list (" (", &wait_list
, true);
2171 if (m
== MATCH_ERROR
)
2173 else if (m
== MATCH_YES
)
2176 if (gfc_match_omp_clauses (&c
, OACC_WAIT_CLAUSES
, space
, space
, true)
2181 for (el
= wait_list
; el
; el
= el
->next
)
2183 if (el
->expr
== NULL
)
2185 gfc_error ("Invalid argument to !$ACC WAIT at %C");
2189 if (!gfc_resolve_expr (el
->expr
)
2190 || el
->expr
->ts
.type
!= BT_INTEGER
|| el
->expr
->rank
!= 0)
2192 gfc_error ("WAIT clause at %L requires a scalar INTEGER expression",
2198 c
->wait_list
= wait_list
;
2199 new_st
.op
= EXEC_OACC_WAIT
;
2200 new_st
.ext
.omp_clauses
= c
;
2206 gfc_match_oacc_cache (void)
2208 gfc_omp_clauses
*c
= gfc_get_omp_clauses ();
2209 /* The OpenACC cache directive explicitly only allows "array elements or
2210 subarrays", which we're currently not checking here. Either check this
2211 after the call of gfc_match_omp_variable_list, or add something like a
2212 only_sections variant next to its allow_sections parameter. */
2213 match m
= gfc_match_omp_variable_list (" (",
2214 &c
->lists
[OMP_LIST_CACHE
], true,
2218 gfc_free_omp_clauses(c
);
2222 if (gfc_current_state() != COMP_DO
2223 && gfc_current_state() != COMP_DO_CONCURRENT
)
2225 gfc_error ("ACC CACHE directive must be inside of loop %C");
2226 gfc_free_omp_clauses(c
);
2230 new_st
.op
= EXEC_OACC_CACHE
;
2231 new_st
.ext
.omp_clauses
= c
;
2235 /* Determine the OpenACC 'routine' directive's level of parallelism. */
2237 static oacc_routine_lop
2238 gfc_oacc_routine_lop (gfc_omp_clauses
*clauses
)
2240 oacc_routine_lop ret
= OACC_ROUTINE_LOP_SEQ
;
2244 unsigned n_lop_clauses
= 0;
2249 ret
= OACC_ROUTINE_LOP_GANG
;
2251 if (clauses
->worker
)
2254 ret
= OACC_ROUTINE_LOP_WORKER
;
2256 if (clauses
->vector
)
2259 ret
= OACC_ROUTINE_LOP_VECTOR
;
2264 ret
= OACC_ROUTINE_LOP_SEQ
;
2267 if (n_lop_clauses
> 1)
2268 ret
= OACC_ROUTINE_LOP_ERROR
;
2275 gfc_match_oacc_routine (void)
2279 gfc_intrinsic_sym
*isym
= NULL
;
2280 gfc_symbol
*sym
= NULL
;
2281 gfc_omp_clauses
*c
= NULL
;
2282 gfc_oacc_routine_name
*n
= NULL
;
2283 oacc_routine_lop lop
= OACC_ROUTINE_LOP_NONE
;
2285 old_loc
= gfc_current_locus
;
2287 m
= gfc_match (" (");
2289 if (gfc_current_ns
->proc_name
2290 && gfc_current_ns
->proc_name
->attr
.if_source
== IFSRC_IFBODY
2293 gfc_error ("Only the !$ACC ROUTINE form without "
2294 "list is allowed in interface block at %C");
2300 char buffer
[GFC_MAX_SYMBOL_LEN
+ 1];
2302 m
= gfc_match_name (buffer
);
2305 gfc_symtree
*st
= NULL
;
2307 /* First look for an intrinsic symbol. */
2308 isym
= gfc_find_function (buffer
);
2310 isym
= gfc_find_subroutine (buffer
);
2311 /* If no intrinsic symbol found, search the current namespace. */
2313 st
= gfc_find_symtree (gfc_current_ns
->sym_root
, buffer
);
2317 /* If the name in a 'routine' directive refers to the containing
2318 subroutine or function, then make sure that we'll later handle
2319 this accordingly. */
2320 if (gfc_current_ns
->proc_name
!= NULL
2321 && strcmp (sym
->name
, gfc_current_ns
->proc_name
->name
) == 0)
2325 if (isym
== NULL
&& st
== NULL
)
2327 gfc_error ("Invalid NAME %qs in !$ACC ROUTINE ( NAME ) at %C",
2329 gfc_current_locus
= old_loc
;
2335 gfc_error ("Syntax error in !$ACC ROUTINE ( NAME ) at %C");
2336 gfc_current_locus
= old_loc
;
2340 if (gfc_match_char (')') != MATCH_YES
)
2342 gfc_error ("Syntax error in !$ACC ROUTINE ( NAME ) at %C, expecting"
2344 gfc_current_locus
= old_loc
;
2349 if (gfc_match_omp_eos () != MATCH_YES
2350 && (gfc_match_omp_clauses (&c
, OACC_ROUTINE_CLAUSES
, false, false, true)
2354 lop
= gfc_oacc_routine_lop (c
);
2355 if (lop
== OACC_ROUTINE_LOP_ERROR
)
2357 gfc_error ("Multiple loop axes specified for routine at %C");
2363 /* Diagnose any OpenACC 'routine' directive that doesn't match the
2364 (implicit) one with a 'seq' clause. */
2365 if (c
&& (c
->gang
|| c
->worker
|| c
->vector
))
2367 gfc_error ("Intrinsic symbol specified in !$ACC ROUTINE ( NAME )"
2368 " at %C marked with incompatible GANG, WORKER, or VECTOR"
2373 else if (sym
!= NULL
)
2377 /* For a repeated OpenACC 'routine' directive, diagnose if it doesn't
2378 match the first one. */
2379 for (gfc_oacc_routine_name
*n_p
= gfc_current_ns
->oacc_routine_names
;
2382 if (n_p
->sym
== sym
)
2385 if (lop
!= gfc_oacc_routine_lop (n_p
->clauses
))
2387 gfc_error ("!$ACC ROUTINE already applied at %C");
2394 sym
->attr
.oacc_routine_lop
= lop
;
2396 n
= gfc_get_oacc_routine_name ();
2399 n
->next
= gfc_current_ns
->oacc_routine_names
;
2401 gfc_current_ns
->oacc_routine_names
= n
;
2404 else if (gfc_current_ns
->proc_name
)
2406 /* For a repeated OpenACC 'routine' directive, diagnose if it doesn't
2407 match the first one. */
2408 oacc_routine_lop lop_p
= gfc_current_ns
->proc_name
->attr
.oacc_routine_lop
;
2409 if (lop_p
!= OACC_ROUTINE_LOP_NONE
2412 gfc_error ("!$ACC ROUTINE already applied at %C");
2416 if (!gfc_add_omp_declare_target (&gfc_current_ns
->proc_name
->attr
,
2417 gfc_current_ns
->proc_name
->name
,
2420 gfc_current_ns
->proc_name
->attr
.oacc_routine_lop
= lop
;
2423 /* Something has gone wrong, possibly a syntax error. */
2428 else if (gfc_current_ns
->oacc_routine
)
2429 gfc_current_ns
->oacc_routine_clauses
= c
;
2431 new_st
.op
= EXEC_OACC_ROUTINE
;
2432 new_st
.ext
.omp_clauses
= c
;
2436 gfc_current_locus
= old_loc
;
2441 #define OMP_PARALLEL_CLAUSES \
2442 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \
2443 | OMP_CLAUSE_SHARED | OMP_CLAUSE_COPYIN | OMP_CLAUSE_REDUCTION \
2444 | OMP_CLAUSE_IF | OMP_CLAUSE_NUM_THREADS | OMP_CLAUSE_DEFAULT \
2445 | OMP_CLAUSE_PROC_BIND)
2446 #define OMP_DECLARE_SIMD_CLAUSES \
2447 (omp_mask (OMP_CLAUSE_SIMDLEN) | OMP_CLAUSE_LINEAR \
2448 | OMP_CLAUSE_UNIFORM | OMP_CLAUSE_ALIGNED | OMP_CLAUSE_INBRANCH \
2449 | OMP_CLAUSE_NOTINBRANCH)
2450 #define OMP_DO_CLAUSES \
2451 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \
2452 | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION \
2453 | OMP_CLAUSE_SCHEDULE | OMP_CLAUSE_ORDERED | OMP_CLAUSE_COLLAPSE \
2454 | OMP_CLAUSE_LINEAR)
2455 #define OMP_SECTIONS_CLAUSES \
2456 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \
2457 | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION)
2458 #define OMP_SIMD_CLAUSES \
2459 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_LASTPRIVATE \
2460 | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_SAFELEN \
2461 | OMP_CLAUSE_LINEAR | OMP_CLAUSE_ALIGNED | OMP_CLAUSE_SIMDLEN)
2462 #define OMP_TASK_CLAUSES \
2463 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \
2464 | OMP_CLAUSE_SHARED | OMP_CLAUSE_IF | OMP_CLAUSE_DEFAULT \
2465 | OMP_CLAUSE_UNTIED | OMP_CLAUSE_FINAL | OMP_CLAUSE_MERGEABLE \
2466 | OMP_CLAUSE_DEPEND | OMP_CLAUSE_PRIORITY)
2467 #define OMP_TASKLOOP_CLAUSES \
2468 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \
2469 | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_SHARED | OMP_CLAUSE_IF \
2470 | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_UNTIED | OMP_CLAUSE_FINAL \
2471 | OMP_CLAUSE_MERGEABLE | OMP_CLAUSE_PRIORITY | OMP_CLAUSE_GRAINSIZE \
2472 | OMP_CLAUSE_NUM_TASKS | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_NOGROUP)
2473 #define OMP_TARGET_CLAUSES \
2474 (omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF \
2475 | OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT | OMP_CLAUSE_PRIVATE \
2476 | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_DEFAULTMAP \
2477 | OMP_CLAUSE_IS_DEVICE_PTR)
2478 #define OMP_TARGET_DATA_CLAUSES \
2479 (omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF \
2480 | OMP_CLAUSE_USE_DEVICE_PTR)
2481 #define OMP_TARGET_ENTER_DATA_CLAUSES \
2482 (omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF \
2483 | OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT)
2484 #define OMP_TARGET_EXIT_DATA_CLAUSES \
2485 (omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF \
2486 | OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT)
2487 #define OMP_TARGET_UPDATE_CLAUSES \
2488 (omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_IF | OMP_CLAUSE_TO \
2489 | OMP_CLAUSE_FROM | OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT)
2490 #define OMP_TEAMS_CLAUSES \
2491 (omp_mask (OMP_CLAUSE_NUM_TEAMS) | OMP_CLAUSE_THREAD_LIMIT \
2492 | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE \
2493 | OMP_CLAUSE_SHARED | OMP_CLAUSE_REDUCTION)
2494 #define OMP_DISTRIBUTE_CLAUSES \
2495 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \
2496 | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_DIST_SCHEDULE)
2497 #define OMP_SINGLE_CLAUSES \
2498 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE)
2499 #define OMP_ORDERED_CLAUSES \
2500 (omp_mask (OMP_CLAUSE_THREADS) | OMP_CLAUSE_SIMD)
2501 #define OMP_DECLARE_TARGET_CLAUSES \
2502 (omp_mask (OMP_CLAUSE_TO) | OMP_CLAUSE_LINK)
2506 match_omp (gfc_exec_op op
, const omp_mask mask
)
2509 if (gfc_match_omp_clauses (&c
, mask
) != MATCH_YES
)
2512 new_st
.ext
.omp_clauses
= c
;
2518 gfc_match_omp_critical (void)
2520 char n
[GFC_MAX_SYMBOL_LEN
+1];
2521 gfc_omp_clauses
*c
= NULL
;
2523 if (gfc_match (" ( %n )", n
) != MATCH_YES
)
2526 if (gfc_match_omp_eos () != MATCH_YES
)
2528 gfc_error ("Unexpected junk after $OMP CRITICAL statement at %C");
2532 else if (gfc_match_omp_clauses (&c
, omp_mask (OMP_CLAUSE_HINT
)) != MATCH_YES
)
2535 new_st
.op
= EXEC_OMP_CRITICAL
;
2536 new_st
.ext
.omp_clauses
= c
;
2538 c
->critical_name
= xstrdup (n
);
2544 gfc_match_omp_end_critical (void)
2546 char n
[GFC_MAX_SYMBOL_LEN
+1];
2548 if (gfc_match (" ( %n )", n
) != MATCH_YES
)
2550 if (gfc_match_omp_eos () != MATCH_YES
)
2552 gfc_error ("Unexpected junk after $OMP CRITICAL statement at %C");
2556 new_st
.op
= EXEC_OMP_END_CRITICAL
;
2557 new_st
.ext
.omp_name
= n
[0] ? xstrdup (n
) : NULL
;
2563 gfc_match_omp_distribute (void)
2565 return match_omp (EXEC_OMP_DISTRIBUTE
, OMP_DISTRIBUTE_CLAUSES
);
2570 gfc_match_omp_distribute_parallel_do (void)
2572 return match_omp (EXEC_OMP_DISTRIBUTE_PARALLEL_DO
,
2573 (OMP_DISTRIBUTE_CLAUSES
| OMP_PARALLEL_CLAUSES
2575 & ~(omp_mask (OMP_CLAUSE_ORDERED
))
2576 & ~(omp_mask (OMP_CLAUSE_LINEAR
)));
2581 gfc_match_omp_distribute_parallel_do_simd (void)
2583 return match_omp (EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD
,
2584 (OMP_DISTRIBUTE_CLAUSES
| OMP_PARALLEL_CLAUSES
2585 | OMP_DO_CLAUSES
| OMP_SIMD_CLAUSES
)
2586 & ~(omp_mask (OMP_CLAUSE_ORDERED
)));
2591 gfc_match_omp_distribute_simd (void)
2593 return match_omp (EXEC_OMP_DISTRIBUTE_SIMD
,
2594 OMP_DISTRIBUTE_CLAUSES
| OMP_SIMD_CLAUSES
);
2599 gfc_match_omp_do (void)
2601 return match_omp (EXEC_OMP_DO
, OMP_DO_CLAUSES
);
2606 gfc_match_omp_do_simd (void)
2608 return match_omp (EXEC_OMP_DO_SIMD
, OMP_DO_CLAUSES
| OMP_SIMD_CLAUSES
);
2613 gfc_match_omp_flush (void)
2615 gfc_omp_namelist
*list
= NULL
;
2616 gfc_match_omp_variable_list (" (", &list
, true);
2617 if (gfc_match_omp_eos () != MATCH_YES
)
2619 gfc_error ("Unexpected junk after $OMP FLUSH statement at %C");
2620 gfc_free_omp_namelist (list
);
2623 new_st
.op
= EXEC_OMP_FLUSH
;
2624 new_st
.ext
.omp_namelist
= list
;
2630 gfc_match_omp_declare_simd (void)
2632 locus where
= gfc_current_locus
;
2633 gfc_symbol
*proc_name
;
2635 gfc_omp_declare_simd
*ods
;
2636 bool needs_space
= false;
2638 switch (gfc_match (" ( %s ) ", &proc_name
))
2640 case MATCH_YES
: break;
2641 case MATCH_NO
: proc_name
= NULL
; needs_space
= true; break;
2642 case MATCH_ERROR
: return MATCH_ERROR
;
2645 if (gfc_match_omp_clauses (&c
, OMP_DECLARE_SIMD_CLAUSES
, true,
2646 needs_space
) != MATCH_YES
)
2649 if (gfc_current_ns
->is_block_data
)
2651 gfc_free_omp_clauses (c
);
2655 ods
= gfc_get_omp_declare_simd ();
2657 ods
->proc_name
= proc_name
;
2659 ods
->next
= gfc_current_ns
->omp_declare_simd
;
2660 gfc_current_ns
->omp_declare_simd
= ods
;
2666 match_udr_expr (gfc_symtree
*omp_sym1
, gfc_symtree
*omp_sym2
)
2669 locus old_loc
= gfc_current_locus
;
2670 char sname
[GFC_MAX_SYMBOL_LEN
+ 1];
2672 gfc_namespace
*ns
= gfc_current_ns
;
2673 gfc_expr
*lvalue
= NULL
, *rvalue
= NULL
;
2675 gfc_actual_arglist
*arglist
;
2677 m
= gfc_match (" %v =", &lvalue
);
2679 gfc_current_locus
= old_loc
;
2682 m
= gfc_match (" %e )", &rvalue
);
2685 ns
->code
= gfc_get_code (EXEC_ASSIGN
);
2686 ns
->code
->expr1
= lvalue
;
2687 ns
->code
->expr2
= rvalue
;
2688 ns
->code
->loc
= old_loc
;
2692 gfc_current_locus
= old_loc
;
2693 gfc_free_expr (lvalue
);
2696 m
= gfc_match (" %n", sname
);
2700 if (strcmp (sname
, omp_sym1
->name
) == 0
2701 || strcmp (sname
, omp_sym2
->name
) == 0)
2704 gfc_current_ns
= ns
->parent
;
2705 if (gfc_get_ha_sym_tree (sname
, &st
))
2709 if (sym
->attr
.flavor
!= FL_PROCEDURE
2710 && sym
->attr
.flavor
!= FL_UNKNOWN
)
2713 if (!sym
->attr
.generic
2714 && !sym
->attr
.subroutine
2715 && !sym
->attr
.function
)
2717 if (!(sym
->attr
.external
&& !sym
->attr
.referenced
))
2719 /* ...create a symbol in this scope... */
2720 if (sym
->ns
!= gfc_current_ns
2721 && gfc_get_sym_tree (sname
, NULL
, &st
, false) == 1)
2724 if (sym
!= st
->n
.sym
)
2728 /* ...and then to try to make the symbol into a subroutine. */
2729 if (!gfc_add_subroutine (&sym
->attr
, sym
->name
, NULL
))
2733 gfc_set_sym_referenced (sym
);
2734 gfc_gobble_whitespace ();
2735 if (gfc_peek_ascii_char () != '(')
2738 gfc_current_ns
= ns
;
2739 m
= gfc_match_actual_arglist (1, &arglist
);
2743 if (gfc_match_char (')') != MATCH_YES
)
2746 ns
->code
= gfc_get_code (EXEC_CALL
);
2747 ns
->code
->symtree
= st
;
2748 ns
->code
->ext
.actual
= arglist
;
2749 ns
->code
->loc
= old_loc
;
2754 gfc_omp_udr_predef (gfc_omp_reduction_op rop
, const char *name
,
2755 gfc_typespec
*ts
, const char **n
)
2757 if (!gfc_numeric_ts (ts
) && ts
->type
!= BT_LOGICAL
)
2762 case OMP_REDUCTION_PLUS
:
2763 case OMP_REDUCTION_MINUS
:
2764 case OMP_REDUCTION_TIMES
:
2765 return ts
->type
!= BT_LOGICAL
;
2766 case OMP_REDUCTION_AND
:
2767 case OMP_REDUCTION_OR
:
2768 case OMP_REDUCTION_EQV
:
2769 case OMP_REDUCTION_NEQV
:
2770 return ts
->type
== BT_LOGICAL
;
2771 case OMP_REDUCTION_USER
:
2772 if (name
[0] != '.' && (ts
->type
== BT_INTEGER
|| ts
->type
== BT_REAL
))
2776 gfc_find_symbol (name
, NULL
, 1, &sym
);
2779 if (sym
->attr
.intrinsic
)
2781 else if ((sym
->attr
.flavor
!= FL_UNKNOWN
2782 && sym
->attr
.flavor
!= FL_PROCEDURE
)
2783 || sym
->attr
.external
2784 || sym
->attr
.generic
2788 || sym
->attr
.subroutine
2789 || sym
->attr
.pointer
2791 || sym
->attr
.cray_pointer
2792 || sym
->attr
.cray_pointee
2793 || (sym
->attr
.proc
!= PROC_UNKNOWN
2794 && sym
->attr
.proc
!= PROC_INTRINSIC
)
2795 || sym
->attr
.if_source
!= IFSRC_UNKNOWN
2796 || sym
== sym
->ns
->proc_name
)
2804 && (strcmp (*n
, "max") == 0 || strcmp (*n
, "min") == 0))
2807 && ts
->type
== BT_INTEGER
2808 && (strcmp (*n
, "iand") == 0
2809 || strcmp (*n
, "ior") == 0
2810 || strcmp (*n
, "ieor") == 0))
2821 gfc_omp_udr_find (gfc_symtree
*st
, gfc_typespec
*ts
)
2823 gfc_omp_udr
*omp_udr
;
2828 for (omp_udr
= st
->n
.omp_udr
; omp_udr
; omp_udr
= omp_udr
->next
)
2829 if (omp_udr
->ts
.type
== ts
->type
2830 || ((omp_udr
->ts
.type
== BT_DERIVED
|| omp_udr
->ts
.type
== BT_CLASS
)
2831 && (ts
->type
== BT_DERIVED
|| ts
->type
== BT_CLASS
)))
2833 if (omp_udr
->ts
.type
== BT_DERIVED
|| omp_udr
->ts
.type
== BT_CLASS
)
2835 if (strcmp (omp_udr
->ts
.u
.derived
->name
, ts
->u
.derived
->name
) == 0)
2838 else if (omp_udr
->ts
.kind
== ts
->kind
)
2840 if (omp_udr
->ts
.type
== BT_CHARACTER
)
2842 if (omp_udr
->ts
.u
.cl
->length
== NULL
2843 || ts
->u
.cl
->length
== NULL
)
2845 if (omp_udr
->ts
.u
.cl
->length
->expr_type
!= EXPR_CONSTANT
)
2847 if (ts
->u
.cl
->length
->expr_type
!= EXPR_CONSTANT
)
2849 if (omp_udr
->ts
.u
.cl
->length
->ts
.type
!= BT_INTEGER
)
2851 if (ts
->u
.cl
->length
->ts
.type
!= BT_INTEGER
)
2853 if (gfc_compare_expr (omp_udr
->ts
.u
.cl
->length
,
2854 ts
->u
.cl
->length
, INTRINSIC_EQ
) != 0)
2864 gfc_match_omp_declare_reduction (void)
2867 gfc_intrinsic_op op
;
2868 char name
[GFC_MAX_SYMBOL_LEN
+ 3];
2869 auto_vec
<gfc_typespec
, 5> tss
;
2873 locus where
= gfc_current_locus
;
2874 locus end_loc
= gfc_current_locus
;
2875 bool end_loc_set
= false;
2876 gfc_omp_reduction_op rop
= OMP_REDUCTION_NONE
;
2878 if (gfc_match_char ('(') != MATCH_YES
)
2881 m
= gfc_match (" %o : ", &op
);
2882 if (m
== MATCH_ERROR
)
2886 snprintf (name
, sizeof name
, "operator %s", gfc_op2string (op
));
2887 rop
= (gfc_omp_reduction_op
) op
;
2891 m
= gfc_match_defined_op_name (name
+ 1, 1);
2892 if (m
== MATCH_ERROR
)
2898 if (gfc_match (" : ") != MATCH_YES
)
2903 if (gfc_match (" %n : ", name
) != MATCH_YES
)
2906 rop
= OMP_REDUCTION_USER
;
2909 m
= gfc_match_type_spec (&ts
);
2912 /* Treat len=: the same as len=*. */
2913 if (ts
.type
== BT_CHARACTER
)
2914 ts
.deferred
= false;
2917 while (gfc_match_char (',') == MATCH_YES
)
2919 m
= gfc_match_type_spec (&ts
);
2924 if (gfc_match_char (':') != MATCH_YES
)
2927 st
= gfc_find_symtree (gfc_current_ns
->omp_udr_root
, name
);
2928 for (i
= 0; i
< tss
.length (); i
++)
2930 gfc_symtree
*omp_out
, *omp_in
;
2931 gfc_symtree
*omp_priv
= NULL
, *omp_orig
= NULL
;
2932 gfc_namespace
*combiner_ns
, *initializer_ns
= NULL
;
2933 gfc_omp_udr
*prev_udr
, *omp_udr
;
2934 const char *predef_name
= NULL
;
2936 omp_udr
= gfc_get_omp_udr ();
2937 omp_udr
->name
= gfc_get_string ("%s", name
);
2939 omp_udr
->ts
= tss
[i
];
2940 omp_udr
->where
= where
;
2942 gfc_current_ns
= combiner_ns
= gfc_get_namespace (gfc_current_ns
, 1);
2943 combiner_ns
->proc_name
= combiner_ns
->parent
->proc_name
;
2945 gfc_get_sym_tree ("omp_out", combiner_ns
, &omp_out
, false);
2946 gfc_get_sym_tree ("omp_in", combiner_ns
, &omp_in
, false);
2947 combiner_ns
->omp_udr_ns
= 1;
2948 omp_out
->n
.sym
->ts
= tss
[i
];
2949 omp_in
->n
.sym
->ts
= tss
[i
];
2950 omp_out
->n
.sym
->attr
.omp_udr_artificial_var
= 1;
2951 omp_in
->n
.sym
->attr
.omp_udr_artificial_var
= 1;
2952 omp_out
->n
.sym
->attr
.flavor
= FL_VARIABLE
;
2953 omp_in
->n
.sym
->attr
.flavor
= FL_VARIABLE
;
2954 gfc_commit_symbols ();
2955 omp_udr
->combiner_ns
= combiner_ns
;
2956 omp_udr
->omp_out
= omp_out
->n
.sym
;
2957 omp_udr
->omp_in
= omp_in
->n
.sym
;
2959 locus old_loc
= gfc_current_locus
;
2961 if (!match_udr_expr (omp_out
, omp_in
))
2964 gfc_current_locus
= old_loc
;
2965 gfc_current_ns
= combiner_ns
->parent
;
2966 gfc_undo_symbols ();
2967 gfc_free_omp_udr (omp_udr
);
2971 if (gfc_match (" initializer ( ") == MATCH_YES
)
2973 gfc_current_ns
= combiner_ns
->parent
;
2974 initializer_ns
= gfc_get_namespace (gfc_current_ns
, 1);
2975 gfc_current_ns
= initializer_ns
;
2976 initializer_ns
->proc_name
= initializer_ns
->parent
->proc_name
;
2978 gfc_get_sym_tree ("omp_priv", initializer_ns
, &omp_priv
, false);
2979 gfc_get_sym_tree ("omp_orig", initializer_ns
, &omp_orig
, false);
2980 initializer_ns
->omp_udr_ns
= 1;
2981 omp_priv
->n
.sym
->ts
= tss
[i
];
2982 omp_orig
->n
.sym
->ts
= tss
[i
];
2983 omp_priv
->n
.sym
->attr
.omp_udr_artificial_var
= 1;
2984 omp_orig
->n
.sym
->attr
.omp_udr_artificial_var
= 1;
2985 omp_priv
->n
.sym
->attr
.flavor
= FL_VARIABLE
;
2986 omp_orig
->n
.sym
->attr
.flavor
= FL_VARIABLE
;
2987 gfc_commit_symbols ();
2988 omp_udr
->initializer_ns
= initializer_ns
;
2989 omp_udr
->omp_priv
= omp_priv
->n
.sym
;
2990 omp_udr
->omp_orig
= omp_orig
->n
.sym
;
2992 if (!match_udr_expr (omp_priv
, omp_orig
))
2996 gfc_current_ns
= combiner_ns
->parent
;
3000 end_loc
= gfc_current_locus
;
3002 gfc_current_locus
= old_loc
;
3004 prev_udr
= gfc_omp_udr_find (st
, &tss
[i
]);
3005 if (gfc_omp_udr_predef (rop
, name
, &tss
[i
], &predef_name
)
3006 /* Don't error on !$omp declare reduction (min : integer : ...)
3007 just yet, there could be integer :: min afterwards,
3008 making it valid. When the UDR is resolved, we'll get
3010 && (rop
!= OMP_REDUCTION_USER
|| name
[0] == '.'))
3013 gfc_error_now ("Redefinition of predefined %s "
3014 "!$OMP DECLARE REDUCTION at %L",
3015 predef_name
, &where
);
3017 gfc_error_now ("Redefinition of predefined "
3018 "!$OMP DECLARE REDUCTION at %L", &where
);
3022 gfc_error_now ("Redefinition of !$OMP DECLARE REDUCTION at %L",
3024 gfc_error_now ("Previous !$OMP DECLARE REDUCTION at %L",
3029 omp_udr
->next
= st
->n
.omp_udr
;
3030 st
->n
.omp_udr
= omp_udr
;
3034 st
= gfc_new_symtree (&gfc_current_ns
->omp_udr_root
, name
);
3035 st
->n
.omp_udr
= omp_udr
;
3041 gfc_current_locus
= end_loc
;
3042 if (gfc_match_omp_eos () != MATCH_YES
)
3044 gfc_error ("Unexpected junk after !$OMP DECLARE REDUCTION at %C");
3045 gfc_current_locus
= where
;
3057 gfc_match_omp_declare_target (void)
3061 gfc_omp_clauses
*c
= NULL
;
3063 gfc_omp_namelist
*n
;
3066 old_loc
= gfc_current_locus
;
3068 if (gfc_current_ns
->proc_name
3069 && gfc_match_omp_eos () == MATCH_YES
)
3071 if (!gfc_add_omp_declare_target (&gfc_current_ns
->proc_name
->attr
,
3072 gfc_current_ns
->proc_name
->name
,
3078 if (gfc_current_ns
->proc_name
3079 && gfc_current_ns
->proc_name
->attr
.if_source
== IFSRC_IFBODY
)
3081 gfc_error ("Only the !$OMP DECLARE TARGET form without "
3082 "clauses is allowed in interface block at %C");
3086 m
= gfc_match (" (");
3089 c
= gfc_get_omp_clauses ();
3090 gfc_current_locus
= old_loc
;
3091 m
= gfc_match_omp_to_link (" (", &c
->lists
[OMP_LIST_TO
]);
3094 if (gfc_match_omp_eos () != MATCH_YES
)
3096 gfc_error ("Unexpected junk after !$OMP DECLARE TARGET at %C");
3100 else if (gfc_match_omp_clauses (&c
, OMP_DECLARE_TARGET_CLAUSES
) != MATCH_YES
)
3103 gfc_buffer_error (false);
3105 for (list
= OMP_LIST_TO
; list
!= OMP_LIST_NUM
;
3106 list
= (list
== OMP_LIST_TO
? OMP_LIST_LINK
: OMP_LIST_NUM
))
3107 for (n
= c
->lists
[list
]; n
; n
= n
->next
)
3110 else if (n
->u
.common
->head
)
3111 n
->u
.common
->head
->mark
= 0;
3113 for (list
= OMP_LIST_TO
; list
!= OMP_LIST_NUM
;
3114 list
= (list
== OMP_LIST_TO
? OMP_LIST_LINK
: OMP_LIST_NUM
))
3115 for (n
= c
->lists
[list
]; n
; n
= n
->next
)
3118 if (n
->sym
->attr
.in_common
)
3119 gfc_error_now ("OMP DECLARE TARGET variable at %L is an "
3120 "element of a COMMON block", &n
->where
);
3121 else if (n
->sym
->attr
.omp_declare_target
3122 && n
->sym
->attr
.omp_declare_target_link
3123 && list
!= OMP_LIST_LINK
)
3124 gfc_error_now ("OMP DECLARE TARGET variable at %L previously "
3125 "mentioned in LINK clause and later in TO clause",
3127 else if (n
->sym
->attr
.omp_declare_target
3128 && !n
->sym
->attr
.omp_declare_target_link
3129 && list
== OMP_LIST_LINK
)
3130 gfc_error_now ("OMP DECLARE TARGET variable at %L previously "
3131 "mentioned in TO clause and later in LINK clause",
3133 else if (n
->sym
->mark
)
3134 gfc_error_now ("Variable at %L mentioned multiple times in "
3135 "clauses of the same OMP DECLARE TARGET directive",
3137 else if (gfc_add_omp_declare_target (&n
->sym
->attr
, n
->sym
->name
,
3138 &n
->sym
->declared_at
))
3140 if (list
== OMP_LIST_LINK
)
3141 gfc_add_omp_declare_target_link (&n
->sym
->attr
, n
->sym
->name
,
3142 &n
->sym
->declared_at
);
3146 else if (n
->u
.common
->omp_declare_target
3147 && n
->u
.common
->omp_declare_target_link
3148 && list
!= OMP_LIST_LINK
)
3149 gfc_error_now ("OMP DECLARE TARGET COMMON at %L previously "
3150 "mentioned in LINK clause and later in TO clause",
3152 else if (n
->u
.common
->omp_declare_target
3153 && !n
->u
.common
->omp_declare_target_link
3154 && list
== OMP_LIST_LINK
)
3155 gfc_error_now ("OMP DECLARE TARGET COMMON at %L previously "
3156 "mentioned in TO clause and later in LINK clause",
3158 else if (n
->u
.common
->head
&& n
->u
.common
->head
->mark
)
3159 gfc_error_now ("COMMON at %L mentioned multiple times in "
3160 "clauses of the same OMP DECLARE TARGET directive",
3164 n
->u
.common
->omp_declare_target
= 1;
3165 n
->u
.common
->omp_declare_target_link
= (list
== OMP_LIST_LINK
);
3166 for (s
= n
->u
.common
->head
; s
; s
= s
->common_next
)
3169 if (gfc_add_omp_declare_target (&s
->attr
, s
->name
,
3172 if (list
== OMP_LIST_LINK
)
3173 gfc_add_omp_declare_target_link (&s
->attr
, s
->name
,
3179 gfc_buffer_error (true);
3182 gfc_free_omp_clauses (c
);
3186 gfc_error ("Syntax error in !$OMP DECLARE TARGET list at %C");
3189 gfc_current_locus
= old_loc
;
3191 gfc_free_omp_clauses (c
);
3197 gfc_match_omp_threadprivate (void)
3200 char n
[GFC_MAX_SYMBOL_LEN
+1];
3205 old_loc
= gfc_current_locus
;
3207 m
= gfc_match (" (");
3213 m
= gfc_match_symbol (&sym
, 0);
3217 if (sym
->attr
.in_common
)
3218 gfc_error_now ("Threadprivate variable at %C is an element of "
3220 else if (!gfc_add_threadprivate (&sym
->attr
, sym
->name
, &sym
->declared_at
))
3229 m
= gfc_match (" / %n /", n
);
3230 if (m
== MATCH_ERROR
)
3232 if (m
== MATCH_NO
|| n
[0] == '\0')
3235 st
= gfc_find_symtree (gfc_current_ns
->common_root
, n
);
3238 gfc_error ("COMMON block /%s/ not found at %C", n
);
3241 st
->n
.common
->threadprivate
= 1;
3242 for (sym
= st
->n
.common
->head
; sym
; sym
= sym
->common_next
)
3243 if (!gfc_add_threadprivate (&sym
->attr
, sym
->name
, &sym
->declared_at
))
3247 if (gfc_match_char (')') == MATCH_YES
)
3249 if (gfc_match_char (',') != MATCH_YES
)
3253 if (gfc_match_omp_eos () != MATCH_YES
)
3255 gfc_error ("Unexpected junk after OMP THREADPRIVATE at %C");
3262 gfc_error ("Syntax error in !$OMP THREADPRIVATE list at %C");
3265 gfc_current_locus
= old_loc
;
3271 gfc_match_omp_parallel (void)
3273 return match_omp (EXEC_OMP_PARALLEL
, OMP_PARALLEL_CLAUSES
);
3278 gfc_match_omp_parallel_do (void)
3280 return match_omp (EXEC_OMP_PARALLEL_DO
,
3281 OMP_PARALLEL_CLAUSES
| OMP_DO_CLAUSES
);
3286 gfc_match_omp_parallel_do_simd (void)
3288 return match_omp (EXEC_OMP_PARALLEL_DO_SIMD
,
3289 OMP_PARALLEL_CLAUSES
| OMP_DO_CLAUSES
| OMP_SIMD_CLAUSES
);
3294 gfc_match_omp_parallel_sections (void)
3296 return match_omp (EXEC_OMP_PARALLEL_SECTIONS
,
3297 OMP_PARALLEL_CLAUSES
| OMP_SECTIONS_CLAUSES
);
3302 gfc_match_omp_parallel_workshare (void)
3304 return match_omp (EXEC_OMP_PARALLEL_WORKSHARE
, OMP_PARALLEL_CLAUSES
);
3309 gfc_match_omp_sections (void)
3311 return match_omp (EXEC_OMP_SECTIONS
, OMP_SECTIONS_CLAUSES
);
3316 gfc_match_omp_simd (void)
3318 return match_omp (EXEC_OMP_SIMD
, OMP_SIMD_CLAUSES
);
3323 gfc_match_omp_single (void)
3325 return match_omp (EXEC_OMP_SINGLE
, OMP_SINGLE_CLAUSES
);
3330 gfc_match_omp_target (void)
3332 return match_omp (EXEC_OMP_TARGET
, OMP_TARGET_CLAUSES
);
3337 gfc_match_omp_target_data (void)
3339 return match_omp (EXEC_OMP_TARGET_DATA
, OMP_TARGET_DATA_CLAUSES
);
3344 gfc_match_omp_target_enter_data (void)
3346 return match_omp (EXEC_OMP_TARGET_ENTER_DATA
, OMP_TARGET_ENTER_DATA_CLAUSES
);
3351 gfc_match_omp_target_exit_data (void)
3353 return match_omp (EXEC_OMP_TARGET_EXIT_DATA
, OMP_TARGET_EXIT_DATA_CLAUSES
);
3358 gfc_match_omp_target_parallel (void)
3360 return match_omp (EXEC_OMP_TARGET_PARALLEL
,
3361 (OMP_TARGET_CLAUSES
| OMP_PARALLEL_CLAUSES
)
3362 & ~(omp_mask (OMP_CLAUSE_COPYIN
)));
3367 gfc_match_omp_target_parallel_do (void)
3369 return match_omp (EXEC_OMP_TARGET_PARALLEL_DO
,
3370 (OMP_TARGET_CLAUSES
| OMP_PARALLEL_CLAUSES
3371 | OMP_DO_CLAUSES
) & ~(omp_mask (OMP_CLAUSE_COPYIN
)));
3376 gfc_match_omp_target_parallel_do_simd (void)
3378 return match_omp (EXEC_OMP_TARGET_PARALLEL_DO_SIMD
,
3379 (OMP_TARGET_CLAUSES
| OMP_PARALLEL_CLAUSES
| OMP_DO_CLAUSES
3380 | OMP_SIMD_CLAUSES
) & ~(omp_mask (OMP_CLAUSE_COPYIN
)));
3385 gfc_match_omp_target_simd (void)
3387 return match_omp (EXEC_OMP_TARGET_SIMD
,
3388 OMP_TARGET_CLAUSES
| OMP_SIMD_CLAUSES
);
3393 gfc_match_omp_target_teams (void)
3395 return match_omp (EXEC_OMP_TARGET_TEAMS
,
3396 OMP_TARGET_CLAUSES
| OMP_TEAMS_CLAUSES
);
3401 gfc_match_omp_target_teams_distribute (void)
3403 return match_omp (EXEC_OMP_TARGET_TEAMS_DISTRIBUTE
,
3404 OMP_TARGET_CLAUSES
| OMP_TEAMS_CLAUSES
3405 | OMP_DISTRIBUTE_CLAUSES
);
3410 gfc_match_omp_target_teams_distribute_parallel_do (void)
3412 return match_omp (EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO
,
3413 (OMP_TARGET_CLAUSES
| OMP_TEAMS_CLAUSES
3414 | OMP_DISTRIBUTE_CLAUSES
| OMP_PARALLEL_CLAUSES
3416 & ~(omp_mask (OMP_CLAUSE_ORDERED
))
3417 & ~(omp_mask (OMP_CLAUSE_LINEAR
)));
3422 gfc_match_omp_target_teams_distribute_parallel_do_simd (void)
3424 return match_omp (EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
,
3425 (OMP_TARGET_CLAUSES
| OMP_TEAMS_CLAUSES
3426 | OMP_DISTRIBUTE_CLAUSES
| OMP_PARALLEL_CLAUSES
3427 | OMP_DO_CLAUSES
| OMP_SIMD_CLAUSES
)
3428 & ~(omp_mask (OMP_CLAUSE_ORDERED
)));
3433 gfc_match_omp_target_teams_distribute_simd (void)
3435 return match_omp (EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD
,
3436 OMP_TARGET_CLAUSES
| OMP_TEAMS_CLAUSES
3437 | OMP_DISTRIBUTE_CLAUSES
| OMP_SIMD_CLAUSES
);
3442 gfc_match_omp_target_update (void)
3444 return match_omp (EXEC_OMP_TARGET_UPDATE
, OMP_TARGET_UPDATE_CLAUSES
);
3449 gfc_match_omp_task (void)
3451 return match_omp (EXEC_OMP_TASK
, OMP_TASK_CLAUSES
);
3456 gfc_match_omp_taskloop (void)
3458 return match_omp (EXEC_OMP_TASKLOOP
, OMP_TASKLOOP_CLAUSES
);
3463 gfc_match_omp_taskloop_simd (void)
3465 return match_omp (EXEC_OMP_TASKLOOP_SIMD
,
3466 (OMP_TASKLOOP_CLAUSES
| OMP_SIMD_CLAUSES
)
3467 & ~(omp_mask (OMP_CLAUSE_REDUCTION
)));
3472 gfc_match_omp_taskwait (void)
3474 if (gfc_match_omp_eos () != MATCH_YES
)
3476 gfc_error ("Unexpected junk after TASKWAIT clause at %C");
3479 new_st
.op
= EXEC_OMP_TASKWAIT
;
3480 new_st
.ext
.omp_clauses
= NULL
;
3486 gfc_match_omp_taskyield (void)
3488 if (gfc_match_omp_eos () != MATCH_YES
)
3490 gfc_error ("Unexpected junk after TASKYIELD clause at %C");
3493 new_st
.op
= EXEC_OMP_TASKYIELD
;
3494 new_st
.ext
.omp_clauses
= NULL
;
3500 gfc_match_omp_teams (void)
3502 return match_omp (EXEC_OMP_TEAMS
, OMP_TEAMS_CLAUSES
);
3507 gfc_match_omp_teams_distribute (void)
3509 return match_omp (EXEC_OMP_TEAMS_DISTRIBUTE
,
3510 OMP_TEAMS_CLAUSES
| OMP_DISTRIBUTE_CLAUSES
);
3515 gfc_match_omp_teams_distribute_parallel_do (void)
3517 return match_omp (EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO
,
3518 (OMP_TEAMS_CLAUSES
| OMP_DISTRIBUTE_CLAUSES
3519 | OMP_PARALLEL_CLAUSES
| OMP_DO_CLAUSES
)
3520 & ~(omp_mask (OMP_CLAUSE_ORDERED
))
3521 & ~(omp_mask (OMP_CLAUSE_LINEAR
)));
3526 gfc_match_omp_teams_distribute_parallel_do_simd (void)
3528 return match_omp (EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
,
3529 (OMP_TEAMS_CLAUSES
| OMP_DISTRIBUTE_CLAUSES
3530 | OMP_PARALLEL_CLAUSES
| OMP_DO_CLAUSES
3531 | OMP_SIMD_CLAUSES
) & ~(omp_mask (OMP_CLAUSE_ORDERED
)));
3536 gfc_match_omp_teams_distribute_simd (void)
3538 return match_omp (EXEC_OMP_TEAMS_DISTRIBUTE_SIMD
,
3539 OMP_TEAMS_CLAUSES
| OMP_DISTRIBUTE_CLAUSES
3540 | OMP_SIMD_CLAUSES
);
3545 gfc_match_omp_workshare (void)
3547 if (gfc_match_omp_eos () != MATCH_YES
)
3549 gfc_error ("Unexpected junk after $OMP WORKSHARE statement at %C");
3552 new_st
.op
= EXEC_OMP_WORKSHARE
;
3553 new_st
.ext
.omp_clauses
= gfc_get_omp_clauses ();
3559 gfc_match_omp_master (void)
3561 if (gfc_match_omp_eos () != MATCH_YES
)
3563 gfc_error ("Unexpected junk after $OMP MASTER statement at %C");
3566 new_st
.op
= EXEC_OMP_MASTER
;
3567 new_st
.ext
.omp_clauses
= NULL
;
3573 gfc_match_omp_ordered (void)
3575 return match_omp (EXEC_OMP_ORDERED
, OMP_ORDERED_CLAUSES
);
3580 gfc_match_omp_ordered_depend (void)
3582 return match_omp (EXEC_OMP_ORDERED
, omp_mask (OMP_CLAUSE_DEPEND
));
3587 gfc_match_omp_oacc_atomic (bool omp_p
)
3589 gfc_omp_atomic_op op
= GFC_OMP_ATOMIC_UPDATE
;
3591 if (gfc_match ("% seq_cst") == MATCH_YES
)
3593 locus old_loc
= gfc_current_locus
;
3594 if (seq_cst
&& gfc_match_char (',') == MATCH_YES
)
3597 || gfc_match_space () == MATCH_YES
)
3599 gfc_gobble_whitespace ();
3600 if (gfc_match ("update") == MATCH_YES
)
3601 op
= GFC_OMP_ATOMIC_UPDATE
;
3602 else if (gfc_match ("read") == MATCH_YES
)
3603 op
= GFC_OMP_ATOMIC_READ
;
3604 else if (gfc_match ("write") == MATCH_YES
)
3605 op
= GFC_OMP_ATOMIC_WRITE
;
3606 else if (gfc_match ("capture") == MATCH_YES
)
3607 op
= GFC_OMP_ATOMIC_CAPTURE
;
3611 gfc_current_locus
= old_loc
;
3615 && (gfc_match (", seq_cst") == MATCH_YES
3616 || gfc_match ("% seq_cst") == MATCH_YES
))
3620 if (gfc_match_omp_eos () != MATCH_YES
)
3622 gfc_error ("Unexpected junk after $OMP ATOMIC statement at %C");
3625 new_st
.op
= (omp_p
? EXEC_OMP_ATOMIC
: EXEC_OACC_ATOMIC
);
3627 op
= (gfc_omp_atomic_op
) (op
| GFC_OMP_ATOMIC_SEQ_CST
);
3628 new_st
.ext
.omp_atomic
= op
;
3633 gfc_match_oacc_atomic (void)
3635 return gfc_match_omp_oacc_atomic (false);
3639 gfc_match_omp_atomic (void)
3641 return gfc_match_omp_oacc_atomic (true);
3645 gfc_match_omp_barrier (void)
3647 if (gfc_match_omp_eos () != MATCH_YES
)
3649 gfc_error ("Unexpected junk after $OMP BARRIER statement at %C");
3652 new_st
.op
= EXEC_OMP_BARRIER
;
3653 new_st
.ext
.omp_clauses
= NULL
;
3659 gfc_match_omp_taskgroup (void)
3661 if (gfc_match_omp_eos () != MATCH_YES
)
3663 gfc_error ("Unexpected junk after $OMP TASKGROUP statement at %C");
3666 new_st
.op
= EXEC_OMP_TASKGROUP
;
3671 static enum gfc_omp_cancel_kind
3672 gfc_match_omp_cancel_kind (void)
3674 if (gfc_match_space () != MATCH_YES
)
3675 return OMP_CANCEL_UNKNOWN
;
3676 if (gfc_match ("parallel") == MATCH_YES
)
3677 return OMP_CANCEL_PARALLEL
;
3678 if (gfc_match ("sections") == MATCH_YES
)
3679 return OMP_CANCEL_SECTIONS
;
3680 if (gfc_match ("do") == MATCH_YES
)
3681 return OMP_CANCEL_DO
;
3682 if (gfc_match ("taskgroup") == MATCH_YES
)
3683 return OMP_CANCEL_TASKGROUP
;
3684 return OMP_CANCEL_UNKNOWN
;
3689 gfc_match_omp_cancel (void)
3692 enum gfc_omp_cancel_kind kind
= gfc_match_omp_cancel_kind ();
3693 if (kind
== OMP_CANCEL_UNKNOWN
)
3695 if (gfc_match_omp_clauses (&c
, omp_mask (OMP_CLAUSE_IF
), false) != MATCH_YES
)
3698 new_st
.op
= EXEC_OMP_CANCEL
;
3699 new_st
.ext
.omp_clauses
= c
;
3705 gfc_match_omp_cancellation_point (void)
3708 enum gfc_omp_cancel_kind kind
= gfc_match_omp_cancel_kind ();
3709 if (kind
== OMP_CANCEL_UNKNOWN
)
3711 if (gfc_match_omp_eos () != MATCH_YES
)
3713 gfc_error ("Unexpected junk after $OMP CANCELLATION POINT statement "
3717 c
= gfc_get_omp_clauses ();
3719 new_st
.op
= EXEC_OMP_CANCELLATION_POINT
;
3720 new_st
.ext
.omp_clauses
= c
;
3726 gfc_match_omp_end_nowait (void)
3728 bool nowait
= false;
3729 if (gfc_match ("% nowait") == MATCH_YES
)
3731 if (gfc_match_omp_eos () != MATCH_YES
)
3733 gfc_error ("Unexpected junk after NOWAIT clause at %C");
3736 new_st
.op
= EXEC_OMP_END_NOWAIT
;
3737 new_st
.ext
.omp_bool
= nowait
;
3743 gfc_match_omp_end_single (void)
3746 if (gfc_match ("% nowait") == MATCH_YES
)
3748 new_st
.op
= EXEC_OMP_END_NOWAIT
;
3749 new_st
.ext
.omp_bool
= true;
3752 if (gfc_match_omp_clauses (&c
, omp_mask (OMP_CLAUSE_COPYPRIVATE
))
3755 new_st
.op
= EXEC_OMP_END_SINGLE
;
3756 new_st
.ext
.omp_clauses
= c
;
3762 oacc_is_loop (gfc_code
*code
)
3764 return code
->op
== EXEC_OACC_PARALLEL_LOOP
3765 || code
->op
== EXEC_OACC_KERNELS_LOOP
3766 || code
->op
== EXEC_OACC_LOOP
;
3770 resolve_scalar_int_expr (gfc_expr
*expr
, const char *clause
)
3772 if (!gfc_resolve_expr (expr
)
3773 || expr
->ts
.type
!= BT_INTEGER
3775 gfc_error ("%s clause at %L requires a scalar INTEGER expression",
3776 clause
, &expr
->where
);
3780 resolve_positive_int_expr (gfc_expr
*expr
, const char *clause
)
3782 resolve_scalar_int_expr (expr
, clause
);
3783 if (expr
->expr_type
== EXPR_CONSTANT
3784 && expr
->ts
.type
== BT_INTEGER
3785 && mpz_sgn (expr
->value
.integer
) <= 0)
3786 gfc_warning (0, "INTEGER expression of %s clause at %L must be positive",
3787 clause
, &expr
->where
);
3791 resolve_nonnegative_int_expr (gfc_expr
*expr
, const char *clause
)
3793 resolve_scalar_int_expr (expr
, clause
);
3794 if (expr
->expr_type
== EXPR_CONSTANT
3795 && expr
->ts
.type
== BT_INTEGER
3796 && mpz_sgn (expr
->value
.integer
) < 0)
3797 gfc_warning (0, "INTEGER expression of %s clause at %L must be "
3798 "non-negative", clause
, &expr
->where
);
3801 /* Emits error when symbol is pointer, cray pointer or cray pointee
3802 of derived of polymorphic type. */
3805 check_symbol_not_pointer (gfc_symbol
*sym
, locus loc
, const char *name
)
3807 if (sym
->ts
.type
== BT_DERIVED
&& sym
->attr
.pointer
)
3808 gfc_error ("POINTER object %qs of derived type in %s clause at %L",
3809 sym
->name
, name
, &loc
);
3810 if (sym
->ts
.type
== BT_DERIVED
&& sym
->attr
.cray_pointer
)
3811 gfc_error ("Cray pointer object %qs of derived type in %s clause at %L",
3812 sym
->name
, name
, &loc
);
3813 if (sym
->ts
.type
== BT_DERIVED
&& sym
->attr
.cray_pointee
)
3814 gfc_error ("Cray pointee object %qs of derived type in %s clause at %L",
3815 sym
->name
, name
, &loc
);
3817 if ((sym
->ts
.type
== BT_ASSUMED
&& sym
->attr
.pointer
)
3818 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
3819 && CLASS_DATA (sym
)->attr
.pointer
))
3820 gfc_error ("POINTER object %qs of polymorphic type in %s clause at %L",
3821 sym
->name
, name
, &loc
);
3822 if ((sym
->ts
.type
== BT_ASSUMED
&& sym
->attr
.cray_pointer
)
3823 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
3824 && CLASS_DATA (sym
)->attr
.cray_pointer
))
3825 gfc_error ("Cray pointer object %qs of polymorphic type in %s clause at %L",
3826 sym
->name
, name
, &loc
);
3827 if ((sym
->ts
.type
== BT_ASSUMED
&& sym
->attr
.cray_pointee
)
3828 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
3829 && CLASS_DATA (sym
)->attr
.cray_pointee
))
3830 gfc_error ("Cray pointee object %qs of polymorphic type in %s clause at %L",
3831 sym
->name
, name
, &loc
);
3834 /* Emits error when symbol represents assumed size/rank array. */
3837 check_array_not_assumed (gfc_symbol
*sym
, locus loc
, const char *name
)
3839 if (sym
->as
&& sym
->as
->type
== AS_ASSUMED_SIZE
)
3840 gfc_error ("Assumed size array %qs in %s clause at %L",
3841 sym
->name
, name
, &loc
);
3842 if (sym
->as
&& sym
->as
->type
== AS_ASSUMED_RANK
)
3843 gfc_error ("Assumed rank array %qs in %s clause at %L",
3844 sym
->name
, name
, &loc
);
3845 if (sym
->as
&& sym
->as
->type
== AS_DEFERRED
&& sym
->attr
.pointer
3846 && !sym
->attr
.contiguous
)
3847 gfc_error ("Noncontiguous deferred shape array %qs in %s clause at %L",
3848 sym
->name
, name
, &loc
);
3852 resolve_oacc_data_clauses (gfc_symbol
*sym
, locus loc
, const char *name
)
3854 if (sym
->ts
.type
== BT_DERIVED
&& sym
->attr
.allocatable
)
3855 gfc_error ("ALLOCATABLE object %qs of derived type in %s clause at %L",
3856 sym
->name
, name
, &loc
);
3857 if ((sym
->ts
.type
== BT_ASSUMED
&& sym
->attr
.allocatable
)
3858 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
3859 && CLASS_DATA (sym
)->attr
.allocatable
))
3860 gfc_error ("ALLOCATABLE object %qs of polymorphic type "
3861 "in %s clause at %L", sym
->name
, name
, &loc
);
3862 check_symbol_not_pointer (sym
, loc
, name
);
3863 check_array_not_assumed (sym
, loc
, name
);
3867 resolve_oacc_deviceptr_clause (gfc_symbol
*sym
, locus loc
, const char *name
)
3869 if (sym
->attr
.pointer
3870 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
3871 && CLASS_DATA (sym
)->attr
.class_pointer
))
3872 gfc_error ("POINTER object %qs in %s clause at %L",
3873 sym
->name
, name
, &loc
);
3874 if (sym
->attr
.cray_pointer
3875 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
3876 && CLASS_DATA (sym
)->attr
.cray_pointer
))
3877 gfc_error ("Cray pointer object %qs in %s clause at %L",
3878 sym
->name
, name
, &loc
);
3879 if (sym
->attr
.cray_pointee
3880 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
3881 && CLASS_DATA (sym
)->attr
.cray_pointee
))
3882 gfc_error ("Cray pointee object %qs in %s clause at %L",
3883 sym
->name
, name
, &loc
);
3884 if (sym
->attr
.allocatable
3885 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
3886 && CLASS_DATA (sym
)->attr
.allocatable
))
3887 gfc_error ("ALLOCATABLE object %qs in %s clause at %L",
3888 sym
->name
, name
, &loc
);
3889 if (sym
->attr
.value
)
3890 gfc_error ("VALUE object %qs in %s clause at %L",
3891 sym
->name
, name
, &loc
);
3892 check_array_not_assumed (sym
, loc
, name
);
3896 struct resolve_omp_udr_callback_data
3898 gfc_symbol
*sym1
, *sym2
;
3903 resolve_omp_udr_callback (gfc_expr
**e
, int *, void *data
)
3905 struct resolve_omp_udr_callback_data
*rcd
3906 = (struct resolve_omp_udr_callback_data
*) data
;
3907 if ((*e
)->expr_type
== EXPR_VARIABLE
3908 && ((*e
)->symtree
->n
.sym
== rcd
->sym1
3909 || (*e
)->symtree
->n
.sym
== rcd
->sym2
))
3911 gfc_ref
*ref
= gfc_get_ref ();
3912 ref
->type
= REF_ARRAY
;
3913 ref
->u
.ar
.where
= (*e
)->where
;
3914 ref
->u
.ar
.as
= (*e
)->symtree
->n
.sym
->as
;
3915 ref
->u
.ar
.type
= AR_FULL
;
3916 ref
->u
.ar
.dimen
= 0;
3917 ref
->next
= (*e
)->ref
;
3925 resolve_omp_udr_callback2 (gfc_expr
**e
, int *, void *)
3927 if ((*e
)->expr_type
== EXPR_FUNCTION
3928 && (*e
)->value
.function
.isym
== NULL
)
3930 gfc_symbol
*sym
= (*e
)->symtree
->n
.sym
;
3931 if (!sym
->attr
.intrinsic
3932 && sym
->attr
.if_source
== IFSRC_UNKNOWN
)
3933 gfc_error ("Implicitly declared function %s used in "
3934 "!$OMP DECLARE REDUCTION at %L", sym
->name
, &(*e
)->where
);
3941 resolve_omp_udr_clause (gfc_omp_namelist
*n
, gfc_namespace
*ns
,
3942 gfc_symbol
*sym1
, gfc_symbol
*sym2
)
3945 gfc_symbol sym1_copy
, sym2_copy
;
3947 if (ns
->code
->op
== EXEC_ASSIGN
)
3949 copy
= gfc_get_code (EXEC_ASSIGN
);
3950 copy
->expr1
= gfc_copy_expr (ns
->code
->expr1
);
3951 copy
->expr2
= gfc_copy_expr (ns
->code
->expr2
);
3955 copy
= gfc_get_code (EXEC_CALL
);
3956 copy
->symtree
= ns
->code
->symtree
;
3957 copy
->ext
.actual
= gfc_copy_actual_arglist (ns
->code
->ext
.actual
);
3959 copy
->loc
= ns
->code
->loc
;
3964 sym1
->name
= sym1_copy
.name
;
3965 sym2
->name
= sym2_copy
.name
;
3966 ns
->proc_name
= ns
->parent
->proc_name
;
3967 if (n
->sym
->attr
.dimension
)
3969 struct resolve_omp_udr_callback_data rcd
;
3972 gfc_code_walker (©
, gfc_dummy_code_callback
,
3973 resolve_omp_udr_callback
, &rcd
);
3975 gfc_resolve_code (copy
, gfc_current_ns
);
3976 if (copy
->op
== EXEC_CALL
&& copy
->resolved_isym
== NULL
)
3978 gfc_symbol
*sym
= copy
->resolved_sym
;
3980 && !sym
->attr
.intrinsic
3981 && sym
->attr
.if_source
== IFSRC_UNKNOWN
)
3982 gfc_error ("Implicitly declared subroutine %s used in "
3983 "!$OMP DECLARE REDUCTION at %L", sym
->name
,
3986 gfc_code_walker (©
, gfc_dummy_code_callback
,
3987 resolve_omp_udr_callback2
, NULL
);
3993 /* OpenMP directive resolving routines. */
3996 resolve_omp_clauses (gfc_code
*code
, gfc_omp_clauses
*omp_clauses
,
3997 gfc_namespace
*ns
, bool openacc
= false)
3999 gfc_omp_namelist
*n
;
4003 bool if_without_mod
= false;
4004 gfc_omp_linear_op linear_op
= OMP_LINEAR_DEFAULT
;
4005 static const char *clause_names
[]
4006 = { "PRIVATE", "FIRSTPRIVATE", "LASTPRIVATE", "COPYPRIVATE", "SHARED",
4007 "COPYIN", "UNIFORM", "ALIGNED", "LINEAR", "DEPEND", "MAP",
4008 "TO", "FROM", "REDUCTION", "DEVICE_RESIDENT", "LINK", "USE_DEVICE",
4009 "CACHE", "IS_DEVICE_PTR", "USE_DEVICE_PTR" };
4011 if (omp_clauses
== NULL
)
4014 if (omp_clauses
->orderedc
&& omp_clauses
->orderedc
< omp_clauses
->collapse
)
4015 gfc_error ("ORDERED clause parameter is less than COLLAPSE at %L",
4018 if (omp_clauses
->if_expr
)
4020 gfc_expr
*expr
= omp_clauses
->if_expr
;
4021 if (!gfc_resolve_expr (expr
)
4022 || expr
->ts
.type
!= BT_LOGICAL
|| expr
->rank
!= 0)
4023 gfc_error ("IF clause at %L requires a scalar LOGICAL expression",
4025 if_without_mod
= true;
4027 for (ifc
= 0; ifc
< OMP_IF_LAST
; ifc
++)
4028 if (omp_clauses
->if_exprs
[ifc
])
4030 gfc_expr
*expr
= omp_clauses
->if_exprs
[ifc
];
4032 if (!gfc_resolve_expr (expr
)
4033 || expr
->ts
.type
!= BT_LOGICAL
|| expr
->rank
!= 0)
4034 gfc_error ("IF clause at %L requires a scalar LOGICAL expression",
4036 else if (if_without_mod
)
4038 gfc_error ("IF clause without modifier at %L used together with "
4039 "IF clauses with modifiers",
4040 &omp_clauses
->if_expr
->where
);
4041 if_without_mod
= false;
4046 case EXEC_OMP_PARALLEL
:
4047 case EXEC_OMP_PARALLEL_DO
:
4048 case EXEC_OMP_PARALLEL_SECTIONS
:
4049 case EXEC_OMP_PARALLEL_WORKSHARE
:
4050 case EXEC_OMP_PARALLEL_DO_SIMD
:
4051 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO
:
4052 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD
:
4053 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO
:
4054 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
4055 ok
= ifc
== OMP_IF_PARALLEL
;
4059 ok
= ifc
== OMP_IF_TASK
;
4062 case EXEC_OMP_TASKLOOP
:
4063 case EXEC_OMP_TASKLOOP_SIMD
:
4064 ok
= ifc
== OMP_IF_TASKLOOP
;
4067 case EXEC_OMP_TARGET
:
4068 case EXEC_OMP_TARGET_TEAMS
:
4069 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE
:
4070 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD
:
4071 case EXEC_OMP_TARGET_SIMD
:
4072 ok
= ifc
== OMP_IF_TARGET
;
4075 case EXEC_OMP_TARGET_DATA
:
4076 ok
= ifc
== OMP_IF_TARGET_DATA
;
4079 case EXEC_OMP_TARGET_UPDATE
:
4080 ok
= ifc
== OMP_IF_TARGET_UPDATE
;
4083 case EXEC_OMP_TARGET_ENTER_DATA
:
4084 ok
= ifc
== OMP_IF_TARGET_ENTER_DATA
;
4087 case EXEC_OMP_TARGET_EXIT_DATA
:
4088 ok
= ifc
== OMP_IF_TARGET_EXIT_DATA
;
4091 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO
:
4092 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
4093 case EXEC_OMP_TARGET_PARALLEL
:
4094 case EXEC_OMP_TARGET_PARALLEL_DO
:
4095 case EXEC_OMP_TARGET_PARALLEL_DO_SIMD
:
4096 ok
= ifc
== OMP_IF_TARGET
|| ifc
== OMP_IF_PARALLEL
;
4105 static const char *ifs
[] = {
4112 "TARGET ENTER DATA",
4115 gfc_error ("IF clause modifier %s at %L not appropriate for "
4116 "the current OpenMP construct", ifs
[ifc
], &expr
->where
);
4120 if (omp_clauses
->final_expr
)
4122 gfc_expr
*expr
= omp_clauses
->final_expr
;
4123 if (!gfc_resolve_expr (expr
)
4124 || expr
->ts
.type
!= BT_LOGICAL
|| expr
->rank
!= 0)
4125 gfc_error ("FINAL clause at %L requires a scalar LOGICAL expression",
4128 if (omp_clauses
->num_threads
)
4129 resolve_positive_int_expr (omp_clauses
->num_threads
, "NUM_THREADS");
4130 if (omp_clauses
->chunk_size
)
4132 gfc_expr
*expr
= omp_clauses
->chunk_size
;
4133 if (!gfc_resolve_expr (expr
)
4134 || expr
->ts
.type
!= BT_INTEGER
|| expr
->rank
!= 0)
4135 gfc_error ("SCHEDULE clause's chunk_size at %L requires "
4136 "a scalar INTEGER expression", &expr
->where
);
4137 else if (expr
->expr_type
== EXPR_CONSTANT
4138 && expr
->ts
.type
== BT_INTEGER
4139 && mpz_sgn (expr
->value
.integer
) <= 0)
4140 gfc_warning (0, "INTEGER expression of SCHEDULE clause's chunk_size "
4141 "at %L must be positive", &expr
->where
);
4143 if (omp_clauses
->sched_kind
!= OMP_SCHED_NONE
4144 && omp_clauses
->sched_nonmonotonic
)
4146 if (omp_clauses
->sched_kind
!= OMP_SCHED_DYNAMIC
4147 && omp_clauses
->sched_kind
!= OMP_SCHED_GUIDED
)
4150 switch (omp_clauses
->sched_kind
)
4152 case OMP_SCHED_STATIC
: p
= "STATIC"; break;
4153 case OMP_SCHED_RUNTIME
: p
= "RUNTIME"; break;
4154 case OMP_SCHED_AUTO
: p
= "AUTO"; break;
4155 default: gcc_unreachable ();
4157 gfc_error ("NONMONOTONIC modifier specified for %s schedule kind "
4158 "at %L", p
, &code
->loc
);
4160 else if (omp_clauses
->sched_monotonic
)
4161 gfc_error ("Both MONOTONIC and NONMONOTONIC schedule modifiers "
4162 "specified at %L", &code
->loc
);
4163 else if (omp_clauses
->ordered
)
4164 gfc_error ("NONMONOTONIC schedule modifier specified with ORDERED "
4165 "clause at %L", &code
->loc
);
4168 /* Check that no symbol appears on multiple clauses, except that
4169 a symbol can appear on both firstprivate and lastprivate. */
4170 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
4171 for (n
= omp_clauses
->lists
[list
]; n
; n
= n
->next
)
4174 if (n
->sym
->attr
.flavor
== FL_VARIABLE
4175 || n
->sym
->attr
.proc_pointer
4176 || (!code
&& (!n
->sym
->attr
.dummy
|| n
->sym
->ns
!= ns
)))
4178 if (!code
&& (!n
->sym
->attr
.dummy
|| n
->sym
->ns
!= ns
))
4179 gfc_error ("Variable %qs is not a dummy argument at %L",
4180 n
->sym
->name
, &n
->where
);
4183 if (n
->sym
->attr
.flavor
== FL_PROCEDURE
4184 && n
->sym
->result
== n
->sym
4185 && n
->sym
->attr
.function
)
4187 if (gfc_current_ns
->proc_name
== n
->sym
4188 || (gfc_current_ns
->parent
4189 && gfc_current_ns
->parent
->proc_name
== n
->sym
))
4191 if (gfc_current_ns
->proc_name
->attr
.entry_master
)
4193 gfc_entry_list
*el
= gfc_current_ns
->entries
;
4194 for (; el
; el
= el
->next
)
4195 if (el
->sym
== n
->sym
)
4200 if (gfc_current_ns
->parent
4201 && gfc_current_ns
->parent
->proc_name
->attr
.entry_master
)
4203 gfc_entry_list
*el
= gfc_current_ns
->parent
->entries
;
4204 for (; el
; el
= el
->next
)
4205 if (el
->sym
== n
->sym
)
4211 gfc_error ("Object %qs is not a variable at %L", n
->sym
->name
,
4215 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
4216 if (list
!= OMP_LIST_FIRSTPRIVATE
4217 && list
!= OMP_LIST_LASTPRIVATE
4218 && list
!= OMP_LIST_ALIGNED
4219 && list
!= OMP_LIST_DEPEND
4220 && (list
!= OMP_LIST_MAP
|| openacc
)
4221 && list
!= OMP_LIST_FROM
4222 && list
!= OMP_LIST_TO
4223 && (list
!= OMP_LIST_REDUCTION
|| !openacc
))
4224 for (n
= omp_clauses
->lists
[list
]; n
; n
= n
->next
)
4227 gfc_error ("Symbol %qs present on multiple clauses at %L",
4228 n
->sym
->name
, &n
->where
);
4233 gcc_assert (OMP_LIST_LASTPRIVATE
== OMP_LIST_FIRSTPRIVATE
+ 1);
4234 for (list
= OMP_LIST_FIRSTPRIVATE
; list
<= OMP_LIST_LASTPRIVATE
; list
++)
4235 for (n
= omp_clauses
->lists
[list
]; n
; n
= n
->next
)
4238 gfc_error ("Symbol %qs present on multiple clauses at %L",
4239 n
->sym
->name
, &n
->where
);
4243 for (n
= omp_clauses
->lists
[OMP_LIST_FIRSTPRIVATE
]; n
; n
= n
->next
)
4246 gfc_error ("Symbol %qs present on multiple clauses at %L",
4247 n
->sym
->name
, &n
->where
);
4251 for (n
= omp_clauses
->lists
[OMP_LIST_LASTPRIVATE
]; n
; n
= n
->next
)
4254 for (n
= omp_clauses
->lists
[OMP_LIST_LASTPRIVATE
]; n
; n
= n
->next
)
4257 gfc_error ("Symbol %qs present on multiple clauses at %L",
4258 n
->sym
->name
, &n
->where
);
4263 for (n
= omp_clauses
->lists
[OMP_LIST_ALIGNED
]; n
; n
= n
->next
)
4266 for (n
= omp_clauses
->lists
[OMP_LIST_ALIGNED
]; n
; n
= n
->next
)
4269 gfc_error ("Symbol %qs present on multiple clauses at %L",
4270 n
->sym
->name
, &n
->where
);
4275 /* OpenACC reductions. */
4278 for (n
= omp_clauses
->lists
[OMP_LIST_REDUCTION
]; n
; n
= n
->next
)
4281 for (n
= omp_clauses
->lists
[OMP_LIST_REDUCTION
]; n
; n
= n
->next
)
4284 gfc_error ("Symbol %qs present on multiple clauses at %L",
4285 n
->sym
->name
, &n
->where
);
4289 /* OpenACC does not support reductions on arrays. */
4291 gfc_error ("Array %qs is not permitted in reduction at %L",
4292 n
->sym
->name
, &n
->where
);
4296 for (n
= omp_clauses
->lists
[OMP_LIST_TO
]; n
; n
= n
->next
)
4298 for (n
= omp_clauses
->lists
[OMP_LIST_FROM
]; n
; n
= n
->next
)
4299 if (n
->expr
== NULL
)
4301 for (n
= omp_clauses
->lists
[OMP_LIST_TO
]; n
; n
= n
->next
)
4303 if (n
->expr
== NULL
&& n
->sym
->mark
)
4304 gfc_error ("Symbol %qs present on both FROM and TO clauses at %L",
4305 n
->sym
->name
, &n
->where
);
4310 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
4311 if ((n
= omp_clauses
->lists
[list
]) != NULL
)
4315 if (list
< OMP_LIST_NUM
)
4316 name
= clause_names
[list
];
4322 case OMP_LIST_COPYIN
:
4323 for (; n
!= NULL
; n
= n
->next
)
4325 if (!n
->sym
->attr
.threadprivate
)
4326 gfc_error ("Non-THREADPRIVATE object %qs in COPYIN clause"
4327 " at %L", n
->sym
->name
, &n
->where
);
4330 case OMP_LIST_COPYPRIVATE
:
4331 for (; n
!= NULL
; n
= n
->next
)
4333 if (n
->sym
->as
&& n
->sym
->as
->type
== AS_ASSUMED_SIZE
)
4334 gfc_error ("Assumed size array %qs in COPYPRIVATE clause "
4335 "at %L", n
->sym
->name
, &n
->where
);
4336 if (n
->sym
->attr
.pointer
&& n
->sym
->attr
.intent
== INTENT_IN
)
4337 gfc_error ("INTENT(IN) POINTER %qs in COPYPRIVATE clause "
4338 "at %L", n
->sym
->name
, &n
->where
);
4341 case OMP_LIST_SHARED
:
4342 for (; n
!= NULL
; n
= n
->next
)
4344 if (n
->sym
->attr
.threadprivate
)
4345 gfc_error ("THREADPRIVATE object %qs in SHARED clause at "
4346 "%L", n
->sym
->name
, &n
->where
);
4347 if (n
->sym
->attr
.cray_pointee
)
4348 gfc_error ("Cray pointee %qs in SHARED clause at %L",
4349 n
->sym
->name
, &n
->where
);
4350 if (n
->sym
->attr
.associate_var
)
4351 gfc_error ("ASSOCIATE name %qs in SHARED clause at %L",
4352 n
->sym
->name
, &n
->where
);
4355 case OMP_LIST_ALIGNED
:
4356 for (; n
!= NULL
; n
= n
->next
)
4358 if (!n
->sym
->attr
.pointer
4359 && !n
->sym
->attr
.allocatable
4360 && !n
->sym
->attr
.cray_pointer
4361 && (n
->sym
->ts
.type
!= BT_DERIVED
4362 || (n
->sym
->ts
.u
.derived
->from_intmod
4363 != INTMOD_ISO_C_BINDING
)
4364 || (n
->sym
->ts
.u
.derived
->intmod_sym_id
4365 != ISOCBINDING_PTR
)))
4366 gfc_error ("%qs in ALIGNED clause must be POINTER, "
4367 "ALLOCATABLE, Cray pointer or C_PTR at %L",
4368 n
->sym
->name
, &n
->where
);
4371 gfc_expr
*expr
= n
->expr
;
4373 if (!gfc_resolve_expr (expr
)
4374 || expr
->ts
.type
!= BT_INTEGER
4376 || gfc_extract_int (expr
, &alignment
)
4378 gfc_error ("%qs in ALIGNED clause at %L requires a scalar "
4379 "positive constant integer alignment "
4380 "expression", n
->sym
->name
, &n
->where
);
4384 case OMP_LIST_DEPEND
:
4388 case OMP_LIST_CACHE
:
4389 for (; n
!= NULL
; n
= n
->next
)
4391 if (list
== OMP_LIST_DEPEND
)
4393 if (n
->u
.depend_op
== OMP_DEPEND_SINK_FIRST
4394 || n
->u
.depend_op
== OMP_DEPEND_SINK
)
4396 if (code
->op
!= EXEC_OMP_ORDERED
)
4397 gfc_error ("SINK dependence type only allowed "
4398 "on ORDERED directive at %L", &n
->where
);
4399 else if (omp_clauses
->depend_source
)
4401 gfc_error ("DEPEND SINK used together with "
4402 "DEPEND SOURCE on the same construct "
4403 "at %L", &n
->where
);
4404 omp_clauses
->depend_source
= false;
4408 if (!gfc_resolve_expr (n
->expr
)
4409 || n
->expr
->ts
.type
!= BT_INTEGER
4410 || n
->expr
->rank
!= 0)
4411 gfc_error ("SINK addend not a constant integer "
4412 "at %L", &n
->where
);
4416 else if (code
->op
== EXEC_OMP_ORDERED
)
4417 gfc_error ("Only SOURCE or SINK dependence types "
4418 "are allowed on ORDERED directive at %L",
4423 if (!gfc_resolve_expr (n
->expr
)
4424 || n
->expr
->expr_type
!= EXPR_VARIABLE
4425 || n
->expr
->ref
== NULL
4426 || n
->expr
->ref
->next
4427 || n
->expr
->ref
->type
!= REF_ARRAY
)
4428 gfc_error ("%qs in %s clause at %L is not a proper "
4429 "array section", n
->sym
->name
, name
,
4431 else if (n
->expr
->ref
->u
.ar
.codimen
)
4432 gfc_error ("Coarrays not supported in %s clause at %L",
4437 gfc_array_ref
*ar
= &n
->expr
->ref
->u
.ar
;
4438 for (i
= 0; i
< ar
->dimen
; i
++)
4441 gfc_error ("Stride should not be specified for "
4442 "array section in %s clause at %L",
4446 else if (ar
->dimen_type
[i
] != DIMEN_ELEMENT
4447 && ar
->dimen_type
[i
] != DIMEN_RANGE
)
4449 gfc_error ("%qs in %s clause at %L is not a "
4450 "proper array section",
4451 n
->sym
->name
, name
, &n
->where
);
4454 else if (list
== OMP_LIST_DEPEND
4456 && ar
->start
[i
]->expr_type
== EXPR_CONSTANT
4458 && ar
->end
[i
]->expr_type
== EXPR_CONSTANT
4459 && mpz_cmp (ar
->start
[i
]->value
.integer
,
4460 ar
->end
[i
]->value
.integer
) > 0)
4462 gfc_error ("%qs in DEPEND clause at %L is a "
4463 "zero size array section",
4464 n
->sym
->name
, &n
->where
);
4471 if (list
== OMP_LIST_MAP
4472 && n
->u
.map_op
== OMP_MAP_FORCE_DEVICEPTR
)
4473 resolve_oacc_deviceptr_clause (n
->sym
, n
->where
, name
);
4475 resolve_oacc_data_clauses (n
->sym
, n
->where
, name
);
4477 else if (list
!= OMP_LIST_DEPEND
4479 && n
->sym
->as
->type
== AS_ASSUMED_SIZE
)
4480 gfc_error ("Assumed size array %qs in %s clause at %L",
4481 n
->sym
->name
, name
, &n
->where
);
4482 if (list
== OMP_LIST_MAP
&& !openacc
)
4485 case EXEC_OMP_TARGET
:
4486 case EXEC_OMP_TARGET_DATA
:
4487 switch (n
->u
.map_op
)
4490 case OMP_MAP_ALWAYS_TO
:
4492 case OMP_MAP_ALWAYS_FROM
:
4493 case OMP_MAP_TOFROM
:
4494 case OMP_MAP_ALWAYS_TOFROM
:
4498 gfc_error ("TARGET%s with map-type other than TO, "
4499 "FROM, TOFROM, or ALLOC on MAP clause "
4501 code
->op
== EXEC_OMP_TARGET
4502 ? "" : " DATA", &n
->where
);
4506 case EXEC_OMP_TARGET_ENTER_DATA
:
4507 switch (n
->u
.map_op
)
4510 case OMP_MAP_ALWAYS_TO
:
4514 gfc_error ("TARGET ENTER DATA with map-type other "
4515 "than TO, or ALLOC on MAP clause at %L",
4520 case EXEC_OMP_TARGET_EXIT_DATA
:
4521 switch (n
->u
.map_op
)
4524 case OMP_MAP_ALWAYS_FROM
:
4525 case OMP_MAP_RELEASE
:
4526 case OMP_MAP_DELETE
:
4529 gfc_error ("TARGET EXIT DATA with map-type other "
4530 "than FROM, RELEASE, or DELETE on MAP "
4531 "clause at %L", &n
->where
);
4540 if (list
!= OMP_LIST_DEPEND
)
4541 for (n
= omp_clauses
->lists
[list
]; n
!= NULL
; n
= n
->next
)
4543 n
->sym
->attr
.referenced
= 1;
4544 if (n
->sym
->attr
.threadprivate
)
4545 gfc_error ("THREADPRIVATE object %qs in %s clause at %L",
4546 n
->sym
->name
, name
, &n
->where
);
4547 if (n
->sym
->attr
.cray_pointee
)
4548 gfc_error ("Cray pointee %qs in %s clause at %L",
4549 n
->sym
->name
, name
, &n
->where
);
4552 case OMP_LIST_IS_DEVICE_PTR
:
4553 case OMP_LIST_USE_DEVICE_PTR
:
4554 /* FIXME: Handle these. */
4557 for (; n
!= NULL
; n
= n
->next
)
4560 if (n
->sym
->attr
.threadprivate
)
4561 gfc_error ("THREADPRIVATE object %qs in %s clause at %L",
4562 n
->sym
->name
, name
, &n
->where
);
4563 if (n
->sym
->attr
.cray_pointee
)
4564 gfc_error ("Cray pointee %qs in %s clause at %L",
4565 n
->sym
->name
, name
, &n
->where
);
4566 if (n
->sym
->attr
.associate_var
)
4567 gfc_error ("ASSOCIATE name %qs in %s clause at %L",
4568 n
->sym
->name
, name
, &n
->where
);
4569 if (list
!= OMP_LIST_PRIVATE
)
4571 if (n
->sym
->attr
.proc_pointer
&& list
== OMP_LIST_REDUCTION
)
4572 gfc_error ("Procedure pointer %qs in %s clause at %L",
4573 n
->sym
->name
, name
, &n
->where
);
4574 if (n
->sym
->attr
.pointer
&& list
== OMP_LIST_REDUCTION
)
4575 gfc_error ("POINTER object %qs in %s clause at %L",
4576 n
->sym
->name
, name
, &n
->where
);
4577 if (n
->sym
->attr
.cray_pointer
&& list
== OMP_LIST_REDUCTION
)
4578 gfc_error ("Cray pointer %qs in %s clause at %L",
4579 n
->sym
->name
, name
, &n
->where
);
4582 && (oacc_is_loop (code
) || code
->op
== EXEC_OACC_PARALLEL
))
4583 check_array_not_assumed (n
->sym
, n
->where
, name
);
4584 else if (n
->sym
->as
&& n
->sym
->as
->type
== AS_ASSUMED_SIZE
)
4585 gfc_error ("Assumed size array %qs in %s clause at %L",
4586 n
->sym
->name
, name
, &n
->where
);
4587 if (n
->sym
->attr
.in_namelist
&& list
!= OMP_LIST_REDUCTION
)
4588 gfc_error ("Variable %qs in %s clause is used in "
4589 "NAMELIST statement at %L",
4590 n
->sym
->name
, name
, &n
->where
);
4591 if (n
->sym
->attr
.pointer
&& n
->sym
->attr
.intent
== INTENT_IN
)
4594 case OMP_LIST_PRIVATE
:
4595 case OMP_LIST_LASTPRIVATE
:
4596 case OMP_LIST_LINEAR
:
4597 /* case OMP_LIST_REDUCTION: */
4598 gfc_error ("INTENT(IN) POINTER %qs in %s clause at %L",
4599 n
->sym
->name
, name
, &n
->where
);
4607 case OMP_LIST_REDUCTION
:
4608 switch (n
->u
.reduction_op
)
4610 case OMP_REDUCTION_PLUS
:
4611 case OMP_REDUCTION_TIMES
:
4612 case OMP_REDUCTION_MINUS
:
4613 if (!gfc_numeric_ts (&n
->sym
->ts
))
4616 case OMP_REDUCTION_AND
:
4617 case OMP_REDUCTION_OR
:
4618 case OMP_REDUCTION_EQV
:
4619 case OMP_REDUCTION_NEQV
:
4620 if (n
->sym
->ts
.type
!= BT_LOGICAL
)
4623 case OMP_REDUCTION_MAX
:
4624 case OMP_REDUCTION_MIN
:
4625 if (n
->sym
->ts
.type
!= BT_INTEGER
4626 && n
->sym
->ts
.type
!= BT_REAL
)
4629 case OMP_REDUCTION_IAND
:
4630 case OMP_REDUCTION_IOR
:
4631 case OMP_REDUCTION_IEOR
:
4632 if (n
->sym
->ts
.type
!= BT_INTEGER
)
4635 case OMP_REDUCTION_USER
:
4645 const char *udr_name
= NULL
;
4648 udr_name
= n
->udr
->udr
->name
;
4650 = gfc_find_omp_udr (NULL
, udr_name
,
4652 if (n
->udr
->udr
== NULL
)
4660 if (udr_name
== NULL
)
4661 switch (n
->u
.reduction_op
)
4663 case OMP_REDUCTION_PLUS
:
4664 case OMP_REDUCTION_TIMES
:
4665 case OMP_REDUCTION_MINUS
:
4666 case OMP_REDUCTION_AND
:
4667 case OMP_REDUCTION_OR
:
4668 case OMP_REDUCTION_EQV
:
4669 case OMP_REDUCTION_NEQV
:
4670 udr_name
= gfc_op2string ((gfc_intrinsic_op
)
4673 case OMP_REDUCTION_MAX
:
4676 case OMP_REDUCTION_MIN
:
4679 case OMP_REDUCTION_IAND
:
4682 case OMP_REDUCTION_IOR
:
4685 case OMP_REDUCTION_IEOR
:
4691 gfc_error ("!$OMP DECLARE REDUCTION %s not found "
4692 "for type %s at %L", udr_name
,
4693 gfc_typename (&n
->sym
->ts
), &n
->where
);
4697 gfc_omp_udr
*udr
= n
->udr
->udr
;
4698 n
->u
.reduction_op
= OMP_REDUCTION_USER
;
4700 = resolve_omp_udr_clause (n
, udr
->combiner_ns
,
4703 if (udr
->initializer_ns
)
4705 = resolve_omp_udr_clause (n
,
4706 udr
->initializer_ns
,
4712 case OMP_LIST_LINEAR
:
4714 && n
->u
.linear_op
!= OMP_LINEAR_DEFAULT
4715 && n
->u
.linear_op
!= linear_op
)
4717 gfc_error ("LINEAR clause modifier used on DO or SIMD"
4718 " construct at %L", &n
->where
);
4719 linear_op
= n
->u
.linear_op
;
4721 else if (omp_clauses
->orderedc
)
4722 gfc_error ("LINEAR clause specified together with "
4723 "ORDERED clause with argument at %L",
4725 else if (n
->u
.linear_op
!= OMP_LINEAR_REF
4726 && n
->sym
->ts
.type
!= BT_INTEGER
)
4727 gfc_error ("LINEAR variable %qs must be INTEGER "
4728 "at %L", n
->sym
->name
, &n
->where
);
4729 else if ((n
->u
.linear_op
== OMP_LINEAR_REF
4730 || n
->u
.linear_op
== OMP_LINEAR_UVAL
)
4731 && n
->sym
->attr
.value
)
4732 gfc_error ("LINEAR dummy argument %qs with VALUE "
4733 "attribute with %s modifier at %L",
4735 n
->u
.linear_op
== OMP_LINEAR_REF
4736 ? "REF" : "UVAL", &n
->where
);
4739 gfc_expr
*expr
= n
->expr
;
4740 if (!gfc_resolve_expr (expr
)
4741 || expr
->ts
.type
!= BT_INTEGER
4743 gfc_error ("%qs in LINEAR clause at %L requires "
4744 "a scalar integer linear-step expression",
4745 n
->sym
->name
, &n
->where
);
4746 else if (!code
&& expr
->expr_type
!= EXPR_CONSTANT
)
4748 if (expr
->expr_type
== EXPR_VARIABLE
4749 && expr
->symtree
->n
.sym
->attr
.dummy
4750 && expr
->symtree
->n
.sym
->ns
== ns
)
4752 gfc_omp_namelist
*n2
;
4753 for (n2
= omp_clauses
->lists
[OMP_LIST_UNIFORM
];
4755 if (n2
->sym
== expr
->symtree
->n
.sym
)
4760 gfc_error ("%qs in LINEAR clause at %L requires "
4761 "a constant integer linear-step "
4762 "expression or dummy argument "
4763 "specified in UNIFORM clause",
4764 n
->sym
->name
, &n
->where
);
4768 /* Workaround for PR middle-end/26316, nothing really needs
4769 to be done here for OMP_LIST_PRIVATE. */
4770 case OMP_LIST_PRIVATE
:
4771 gcc_assert (code
&& code
->op
!= EXEC_NOP
);
4773 case OMP_LIST_USE_DEVICE
:
4774 if (n
->sym
->attr
.allocatable
4775 || (n
->sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (n
->sym
)
4776 && CLASS_DATA (n
->sym
)->attr
.allocatable
))
4777 gfc_error ("ALLOCATABLE object %qs in %s clause at %L",
4778 n
->sym
->name
, name
, &n
->where
);
4779 if (n
->sym
->ts
.type
== BT_CLASS
4780 && CLASS_DATA (n
->sym
)
4781 && CLASS_DATA (n
->sym
)->attr
.class_pointer
)
4782 gfc_error ("POINTER object %qs of polymorphic type in "
4783 "%s clause at %L", n
->sym
->name
, name
,
4785 if (n
->sym
->attr
.cray_pointer
)
4786 gfc_error ("Cray pointer object %qs in %s clause at %L",
4787 n
->sym
->name
, name
, &n
->where
);
4788 else if (n
->sym
->attr
.cray_pointee
)
4789 gfc_error ("Cray pointee object %qs in %s clause at %L",
4790 n
->sym
->name
, name
, &n
->where
);
4791 else if (n
->sym
->attr
.flavor
== FL_VARIABLE
4793 && !n
->sym
->attr
.pointer
)
4794 gfc_error ("%s clause variable %qs at %L is neither "
4795 "a POINTER nor an array", name
,
4796 n
->sym
->name
, &n
->where
);
4798 case OMP_LIST_DEVICE_RESIDENT
:
4799 check_symbol_not_pointer (n
->sym
, n
->where
, name
);
4800 check_array_not_assumed (n
->sym
, n
->where
, name
);
4809 if (omp_clauses
->safelen_expr
)
4810 resolve_positive_int_expr (omp_clauses
->safelen_expr
, "SAFELEN");
4811 if (omp_clauses
->simdlen_expr
)
4812 resolve_positive_int_expr (omp_clauses
->simdlen_expr
, "SIMDLEN");
4813 if (omp_clauses
->num_teams
)
4814 resolve_positive_int_expr (omp_clauses
->num_teams
, "NUM_TEAMS");
4815 if (omp_clauses
->device
)
4816 resolve_nonnegative_int_expr (omp_clauses
->device
, "DEVICE");
4817 if (omp_clauses
->hint
)
4818 resolve_scalar_int_expr (omp_clauses
->hint
, "HINT");
4819 if (omp_clauses
->priority
)
4820 resolve_nonnegative_int_expr (omp_clauses
->priority
, "PRIORITY");
4821 if (omp_clauses
->dist_chunk_size
)
4823 gfc_expr
*expr
= omp_clauses
->dist_chunk_size
;
4824 if (!gfc_resolve_expr (expr
)
4825 || expr
->ts
.type
!= BT_INTEGER
|| expr
->rank
!= 0)
4826 gfc_error ("DIST_SCHEDULE clause's chunk_size at %L requires "
4827 "a scalar INTEGER expression", &expr
->where
);
4829 if (omp_clauses
->thread_limit
)
4830 resolve_positive_int_expr (omp_clauses
->thread_limit
, "THREAD_LIMIT");
4831 if (omp_clauses
->grainsize
)
4832 resolve_positive_int_expr (omp_clauses
->grainsize
, "GRAINSIZE");
4833 if (omp_clauses
->num_tasks
)
4834 resolve_positive_int_expr (omp_clauses
->num_tasks
, "NUM_TASKS");
4835 if (omp_clauses
->async
)
4836 if (omp_clauses
->async_expr
)
4837 resolve_scalar_int_expr (omp_clauses
->async_expr
, "ASYNC");
4838 if (omp_clauses
->num_gangs_expr
)
4839 resolve_positive_int_expr (omp_clauses
->num_gangs_expr
, "NUM_GANGS");
4840 if (omp_clauses
->num_workers_expr
)
4841 resolve_positive_int_expr (omp_clauses
->num_workers_expr
, "NUM_WORKERS");
4842 if (omp_clauses
->vector_length_expr
)
4843 resolve_positive_int_expr (omp_clauses
->vector_length_expr
,
4845 if (omp_clauses
->gang_num_expr
)
4846 resolve_positive_int_expr (omp_clauses
->gang_num_expr
, "GANG");
4847 if (omp_clauses
->gang_static_expr
)
4848 resolve_positive_int_expr (omp_clauses
->gang_static_expr
, "GANG");
4849 if (omp_clauses
->worker_expr
)
4850 resolve_positive_int_expr (omp_clauses
->worker_expr
, "WORKER");
4851 if (omp_clauses
->vector_expr
)
4852 resolve_positive_int_expr (omp_clauses
->vector_expr
, "VECTOR");
4853 for (el
= omp_clauses
->wait_list
; el
; el
= el
->next
)
4854 resolve_scalar_int_expr (el
->expr
, "WAIT");
4855 if (omp_clauses
->collapse
&& omp_clauses
->tile_list
)
4856 gfc_error ("Incompatible use of TILE and COLLAPSE at %L", &code
->loc
);
4857 if (omp_clauses
->depend_source
&& code
->op
!= EXEC_OMP_ORDERED
)
4858 gfc_error ("SOURCE dependence type only allowed "
4859 "on ORDERED directive at %L", &code
->loc
);
4860 if (!openacc
&& code
&& omp_clauses
->lists
[OMP_LIST_MAP
] == NULL
)
4862 const char *p
= NULL
;
4865 case EXEC_OMP_TARGET_DATA
: p
= "TARGET DATA"; break;
4866 case EXEC_OMP_TARGET_ENTER_DATA
: p
= "TARGET ENTER DATA"; break;
4867 case EXEC_OMP_TARGET_EXIT_DATA
: p
= "TARGET EXIT DATA"; break;
4871 gfc_error ("%s must contain at least one MAP clause at %L",
4877 /* Return true if SYM is ever referenced in EXPR except in the SE node. */
4880 expr_references_sym (gfc_expr
*e
, gfc_symbol
*s
, gfc_expr
*se
)
4882 gfc_actual_arglist
*arg
;
4883 if (e
== NULL
|| e
== se
)
4885 switch (e
->expr_type
)
4890 case EXPR_STRUCTURE
:
4892 if (e
->symtree
!= NULL
4893 && e
->symtree
->n
.sym
== s
)
4896 case EXPR_SUBSTRING
:
4898 && (expr_references_sym (e
->ref
->u
.ss
.start
, s
, se
)
4899 || expr_references_sym (e
->ref
->u
.ss
.end
, s
, se
)))
4903 if (expr_references_sym (e
->value
.op
.op2
, s
, se
))
4905 return expr_references_sym (e
->value
.op
.op1
, s
, se
);
4907 for (arg
= e
->value
.function
.actual
; arg
; arg
= arg
->next
)
4908 if (expr_references_sym (arg
->expr
, s
, se
))
4917 /* If EXPR is a conversion function that widens the type
4918 if WIDENING is true or narrows the type if WIDENING is false,
4919 return the inner expression, otherwise return NULL. */
4922 is_conversion (gfc_expr
*expr
, bool widening
)
4924 gfc_typespec
*ts1
, *ts2
;
4926 if (expr
->expr_type
!= EXPR_FUNCTION
4927 || expr
->value
.function
.isym
== NULL
4928 || expr
->value
.function
.esym
!= NULL
4929 || expr
->value
.function
.isym
->id
!= GFC_ISYM_CONVERSION
)
4935 ts2
= &expr
->value
.function
.actual
->expr
->ts
;
4939 ts1
= &expr
->value
.function
.actual
->expr
->ts
;
4943 if (ts1
->type
> ts2
->type
4944 || (ts1
->type
== ts2
->type
&& ts1
->kind
> ts2
->kind
))
4945 return expr
->value
.function
.actual
->expr
;
4952 resolve_omp_atomic (gfc_code
*code
)
4954 gfc_code
*atomic_code
= code
;
4956 gfc_expr
*expr2
, *expr2_tmp
;
4957 gfc_omp_atomic_op aop
4958 = (gfc_omp_atomic_op
) (atomic_code
->ext
.omp_atomic
& GFC_OMP_ATOMIC_MASK
);
4960 code
= code
->block
->next
;
4961 /* resolve_blocks asserts this is initially EXEC_ASSIGN.
4962 If it changed to EXEC_NOP, assume an error has been emitted already. */
4963 if (code
->op
== EXEC_NOP
)
4965 if (code
->op
!= EXEC_ASSIGN
)
4968 gfc_error ("unexpected !$OMP ATOMIC expression at %L", &code
->loc
);
4971 if (aop
!= GFC_OMP_ATOMIC_CAPTURE
)
4973 if (code
->next
!= NULL
)
4978 if (code
->next
== NULL
)
4980 if (code
->next
->op
== EXEC_NOP
)
4982 if (code
->next
->op
!= EXEC_ASSIGN
|| code
->next
->next
)
4989 if (code
->expr1
->expr_type
!= EXPR_VARIABLE
4990 || code
->expr1
->symtree
== NULL
4991 || code
->expr1
->rank
!= 0
4992 || (code
->expr1
->ts
.type
!= BT_INTEGER
4993 && code
->expr1
->ts
.type
!= BT_REAL
4994 && code
->expr1
->ts
.type
!= BT_COMPLEX
4995 && code
->expr1
->ts
.type
!= BT_LOGICAL
))
4997 gfc_error ("!$OMP ATOMIC statement must set a scalar variable of "
4998 "intrinsic type at %L", &code
->loc
);
5002 var
= code
->expr1
->symtree
->n
.sym
;
5003 expr2
= is_conversion (code
->expr2
, false);
5006 if (aop
== GFC_OMP_ATOMIC_READ
|| aop
== GFC_OMP_ATOMIC_WRITE
)
5007 expr2
= is_conversion (code
->expr2
, true);
5009 expr2
= code
->expr2
;
5014 case GFC_OMP_ATOMIC_READ
:
5015 if (expr2
->expr_type
!= EXPR_VARIABLE
5016 || expr2
->symtree
== NULL
5018 || (expr2
->ts
.type
!= BT_INTEGER
5019 && expr2
->ts
.type
!= BT_REAL
5020 && expr2
->ts
.type
!= BT_COMPLEX
5021 && expr2
->ts
.type
!= BT_LOGICAL
))
5022 gfc_error ("!$OMP ATOMIC READ statement must read from a scalar "
5023 "variable of intrinsic type at %L", &expr2
->where
);
5025 case GFC_OMP_ATOMIC_WRITE
:
5026 if (expr2
->rank
!= 0 || expr_references_sym (code
->expr2
, var
, NULL
))
5027 gfc_error ("expr in !$OMP ATOMIC WRITE assignment var = expr "
5028 "must be scalar and cannot reference var at %L",
5031 case GFC_OMP_ATOMIC_CAPTURE
:
5033 if (expr2
== code
->expr2
)
5035 expr2_tmp
= is_conversion (code
->expr2
, true);
5036 if (expr2_tmp
== NULL
)
5039 if (expr2_tmp
->expr_type
== EXPR_VARIABLE
)
5041 if (expr2_tmp
->symtree
== NULL
5042 || expr2_tmp
->rank
!= 0
5043 || (expr2_tmp
->ts
.type
!= BT_INTEGER
5044 && expr2_tmp
->ts
.type
!= BT_REAL
5045 && expr2_tmp
->ts
.type
!= BT_COMPLEX
5046 && expr2_tmp
->ts
.type
!= BT_LOGICAL
)
5047 || expr2_tmp
->symtree
->n
.sym
== var
)
5049 gfc_error ("!$OMP ATOMIC CAPTURE capture statement must read from "
5050 "a scalar variable of intrinsic type at %L",
5054 var
= expr2_tmp
->symtree
->n
.sym
;
5056 if (code
->expr1
->expr_type
!= EXPR_VARIABLE
5057 || code
->expr1
->symtree
== NULL
5058 || code
->expr1
->rank
!= 0
5059 || (code
->expr1
->ts
.type
!= BT_INTEGER
5060 && code
->expr1
->ts
.type
!= BT_REAL
5061 && code
->expr1
->ts
.type
!= BT_COMPLEX
5062 && code
->expr1
->ts
.type
!= BT_LOGICAL
))
5064 gfc_error ("!$OMP ATOMIC CAPTURE update statement must set "
5065 "a scalar variable of intrinsic type at %L",
5066 &code
->expr1
->where
);
5069 if (code
->expr1
->symtree
->n
.sym
!= var
)
5071 gfc_error ("!$OMP ATOMIC CAPTURE capture statement reads from "
5072 "different variable than update statement writes "
5073 "into at %L", &code
->expr1
->where
);
5076 expr2
= is_conversion (code
->expr2
, false);
5078 expr2
= code
->expr2
;
5085 if (gfc_expr_attr (code
->expr1
).allocatable
)
5087 gfc_error ("!$OMP ATOMIC with ALLOCATABLE variable at %L",
5092 if (aop
== GFC_OMP_ATOMIC_CAPTURE
5093 && code
->next
== NULL
5094 && code
->expr2
->rank
== 0
5095 && !expr_references_sym (code
->expr2
, var
, NULL
))
5096 atomic_code
->ext
.omp_atomic
5097 = (gfc_omp_atomic_op
) (atomic_code
->ext
.omp_atomic
5098 | GFC_OMP_ATOMIC_SWAP
);
5099 else if (expr2
->expr_type
== EXPR_OP
)
5101 gfc_expr
*v
= NULL
, *e
, *c
;
5102 gfc_intrinsic_op op
= expr2
->value
.op
.op
;
5103 gfc_intrinsic_op alt_op
= INTRINSIC_NONE
;
5107 case INTRINSIC_PLUS
:
5108 alt_op
= INTRINSIC_MINUS
;
5110 case INTRINSIC_TIMES
:
5111 alt_op
= INTRINSIC_DIVIDE
;
5113 case INTRINSIC_MINUS
:
5114 alt_op
= INTRINSIC_PLUS
;
5116 case INTRINSIC_DIVIDE
:
5117 alt_op
= INTRINSIC_TIMES
;
5123 alt_op
= INTRINSIC_NEQV
;
5125 case INTRINSIC_NEQV
:
5126 alt_op
= INTRINSIC_EQV
;
5129 gfc_error ("!$OMP ATOMIC assignment operator must be binary "
5130 "+, *, -, /, .AND., .OR., .EQV. or .NEQV. at %L",
5135 /* Check for var = var op expr resp. var = expr op var where
5136 expr doesn't reference var and var op expr is mathematically
5137 equivalent to var op (expr) resp. expr op var equivalent to
5138 (expr) op var. We rely here on the fact that the matcher
5139 for x op1 y op2 z where op1 and op2 have equal precedence
5140 returns (x op1 y) op2 z. */
5141 e
= expr2
->value
.op
.op2
;
5142 if (e
->expr_type
== EXPR_VARIABLE
5143 && e
->symtree
!= NULL
5144 && e
->symtree
->n
.sym
== var
)
5146 else if ((c
= is_conversion (e
, true)) != NULL
5147 && c
->expr_type
== EXPR_VARIABLE
5148 && c
->symtree
!= NULL
5149 && c
->symtree
->n
.sym
== var
)
5153 gfc_expr
**p
= NULL
, **q
;
5154 for (q
= &expr2
->value
.op
.op1
; (e
= *q
) != NULL
; )
5155 if (e
->expr_type
== EXPR_VARIABLE
5156 && e
->symtree
!= NULL
5157 && e
->symtree
->n
.sym
== var
)
5162 else if ((c
= is_conversion (e
, true)) != NULL
)
5163 q
= &e
->value
.function
.actual
->expr
;
5164 else if (e
->expr_type
!= EXPR_OP
5165 || (e
->value
.op
.op
!= op
5166 && e
->value
.op
.op
!= alt_op
)
5172 q
= &e
->value
.op
.op1
;
5177 gfc_error ("!$OMP ATOMIC assignment must be var = var op expr "
5178 "or var = expr op var at %L", &expr2
->where
);
5185 switch (e
->value
.op
.op
)
5187 case INTRINSIC_MINUS
:
5188 case INTRINSIC_DIVIDE
:
5190 case INTRINSIC_NEQV
:
5191 gfc_error ("!$OMP ATOMIC var = var op expr not "
5192 "mathematically equivalent to var = var op "
5193 "(expr) at %L", &expr2
->where
);
5199 /* Canonicalize into var = var op (expr). */
5200 *p
= e
->value
.op
.op2
;
5201 e
->value
.op
.op2
= expr2
;
5203 if (code
->expr2
== expr2
)
5204 code
->expr2
= expr2
= e
;
5206 code
->expr2
->value
.function
.actual
->expr
= expr2
= e
;
5208 if (!gfc_compare_types (&expr2
->value
.op
.op1
->ts
, &expr2
->ts
))
5210 for (p
= &expr2
->value
.op
.op1
; *p
!= v
;
5211 p
= &(*p
)->value
.function
.actual
->expr
)
5214 gfc_free_expr (expr2
->value
.op
.op1
);
5215 expr2
->value
.op
.op1
= v
;
5216 gfc_convert_type (v
, &expr2
->ts
, 2);
5221 if (e
->rank
!= 0 || expr_references_sym (code
->expr2
, var
, v
))
5223 gfc_error ("expr in !$OMP ATOMIC assignment var = var op expr "
5224 "must be scalar and cannot reference var at %L",
5229 else if (expr2
->expr_type
== EXPR_FUNCTION
5230 && expr2
->value
.function
.isym
!= NULL
5231 && expr2
->value
.function
.esym
== NULL
5232 && expr2
->value
.function
.actual
!= NULL
5233 && expr2
->value
.function
.actual
->next
!= NULL
)
5235 gfc_actual_arglist
*arg
, *var_arg
;
5237 switch (expr2
->value
.function
.isym
->id
)
5245 if (expr2
->value
.function
.actual
->next
->next
!= NULL
)
5247 gfc_error ("!$OMP ATOMIC assignment intrinsic IAND, IOR "
5248 "or IEOR must have two arguments at %L",
5254 gfc_error ("!$OMP ATOMIC assignment intrinsic must be "
5255 "MIN, MAX, IAND, IOR or IEOR at %L",
5261 for (arg
= expr2
->value
.function
.actual
; arg
; arg
= arg
->next
)
5263 if ((arg
== expr2
->value
.function
.actual
5264 || (var_arg
== NULL
&& arg
->next
== NULL
))
5265 && arg
->expr
->expr_type
== EXPR_VARIABLE
5266 && arg
->expr
->symtree
!= NULL
5267 && arg
->expr
->symtree
->n
.sym
== var
)
5269 else if (expr_references_sym (arg
->expr
, var
, NULL
))
5271 gfc_error ("!$OMP ATOMIC intrinsic arguments except one must "
5272 "not reference %qs at %L",
5273 var
->name
, &arg
->expr
->where
);
5276 if (arg
->expr
->rank
!= 0)
5278 gfc_error ("!$OMP ATOMIC intrinsic arguments must be scalar "
5279 "at %L", &arg
->expr
->where
);
5284 if (var_arg
== NULL
)
5286 gfc_error ("First or last !$OMP ATOMIC intrinsic argument must "
5287 "be %qs at %L", var
->name
, &expr2
->where
);
5291 if (var_arg
!= expr2
->value
.function
.actual
)
5293 /* Canonicalize, so that var comes first. */
5294 gcc_assert (var_arg
->next
== NULL
);
5295 for (arg
= expr2
->value
.function
.actual
;
5296 arg
->next
!= var_arg
; arg
= arg
->next
)
5298 var_arg
->next
= expr2
->value
.function
.actual
;
5299 expr2
->value
.function
.actual
= var_arg
;
5304 gfc_error ("!$OMP ATOMIC assignment must have an operator or "
5305 "intrinsic on right hand side at %L", &expr2
->where
);
5307 if (aop
== GFC_OMP_ATOMIC_CAPTURE
&& code
->next
)
5310 if (code
->expr1
->expr_type
!= EXPR_VARIABLE
5311 || code
->expr1
->symtree
== NULL
5312 || code
->expr1
->rank
!= 0
5313 || (code
->expr1
->ts
.type
!= BT_INTEGER
5314 && code
->expr1
->ts
.type
!= BT_REAL
5315 && code
->expr1
->ts
.type
!= BT_COMPLEX
5316 && code
->expr1
->ts
.type
!= BT_LOGICAL
))
5318 gfc_error ("!$OMP ATOMIC CAPTURE capture statement must set "
5319 "a scalar variable of intrinsic type at %L",
5320 &code
->expr1
->where
);
5324 expr2
= is_conversion (code
->expr2
, false);
5327 expr2
= is_conversion (code
->expr2
, true);
5329 expr2
= code
->expr2
;
5332 if (expr2
->expr_type
!= EXPR_VARIABLE
5333 || expr2
->symtree
== NULL
5335 || (expr2
->ts
.type
!= BT_INTEGER
5336 && expr2
->ts
.type
!= BT_REAL
5337 && expr2
->ts
.type
!= BT_COMPLEX
5338 && expr2
->ts
.type
!= BT_LOGICAL
))
5340 gfc_error ("!$OMP ATOMIC CAPTURE capture statement must read "
5341 "from a scalar variable of intrinsic type at %L",
5345 if (expr2
->symtree
->n
.sym
!= var
)
5347 gfc_error ("!$OMP ATOMIC CAPTURE capture statement reads from "
5348 "different variable than update statement writes "
5349 "into at %L", &expr2
->where
);
5356 static struct fortran_omp_context
5359 hash_set
<gfc_symbol
*> *sharing_clauses
;
5360 hash_set
<gfc_symbol
*> *private_iterators
;
5361 struct fortran_omp_context
*previous
;
5364 static gfc_code
*omp_current_do_code
;
5365 static int omp_current_do_collapse
;
5368 gfc_resolve_omp_do_blocks (gfc_code
*code
, gfc_namespace
*ns
)
5370 if (code
->block
->next
&& code
->block
->next
->op
== EXEC_DO
)
5375 omp_current_do_code
= code
->block
->next
;
5376 if (code
->ext
.omp_clauses
->orderedc
)
5377 omp_current_do_collapse
= code
->ext
.omp_clauses
->orderedc
;
5379 omp_current_do_collapse
= code
->ext
.omp_clauses
->collapse
;
5380 for (i
= 1, c
= omp_current_do_code
; i
< omp_current_do_collapse
; i
++)
5383 if (c
->op
!= EXEC_DO
|| c
->next
== NULL
)
5386 if (c
->op
!= EXEC_DO
)
5389 if (i
< omp_current_do_collapse
|| omp_current_do_collapse
<= 0)
5390 omp_current_do_collapse
= 1;
5392 gfc_resolve_blocks (code
->block
, ns
);
5393 omp_current_do_collapse
= 0;
5394 omp_current_do_code
= NULL
;
5399 gfc_resolve_omp_parallel_blocks (gfc_code
*code
, gfc_namespace
*ns
)
5401 struct fortran_omp_context ctx
;
5402 gfc_omp_clauses
*omp_clauses
= code
->ext
.omp_clauses
;
5403 gfc_omp_namelist
*n
;
5407 ctx
.sharing_clauses
= new hash_set
<gfc_symbol
*>;
5408 ctx
.private_iterators
= new hash_set
<gfc_symbol
*>;
5409 ctx
.previous
= omp_current_ctx
;
5410 ctx
.is_openmp
= true;
5411 omp_current_ctx
= &ctx
;
5413 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
5416 case OMP_LIST_SHARED
:
5417 case OMP_LIST_PRIVATE
:
5418 case OMP_LIST_FIRSTPRIVATE
:
5419 case OMP_LIST_LASTPRIVATE
:
5420 case OMP_LIST_REDUCTION
:
5421 case OMP_LIST_LINEAR
:
5422 for (n
= omp_clauses
->lists
[list
]; n
; n
= n
->next
)
5423 ctx
.sharing_clauses
->add (n
->sym
);
5431 case EXEC_OMP_PARALLEL_DO
:
5432 case EXEC_OMP_PARALLEL_DO_SIMD
:
5433 case EXEC_OMP_TARGET_PARALLEL_DO
:
5434 case EXEC_OMP_TARGET_PARALLEL_DO_SIMD
:
5435 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE
:
5436 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO
:
5437 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
5438 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD
:
5439 case EXEC_OMP_TASKLOOP
:
5440 case EXEC_OMP_TASKLOOP_SIMD
:
5441 case EXEC_OMP_TEAMS_DISTRIBUTE
:
5442 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO
:
5443 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
5444 case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD
:
5445 gfc_resolve_omp_do_blocks (code
, ns
);
5448 gfc_resolve_blocks (code
->block
, ns
);
5451 omp_current_ctx
= ctx
.previous
;
5452 delete ctx
.sharing_clauses
;
5453 delete ctx
.private_iterators
;
5457 /* Save and clear openmp.c private state. */
5460 gfc_omp_save_and_clear_state (struct gfc_omp_saved_state
*state
)
5462 state
->ptrs
[0] = omp_current_ctx
;
5463 state
->ptrs
[1] = omp_current_do_code
;
5464 state
->ints
[0] = omp_current_do_collapse
;
5465 omp_current_ctx
= NULL
;
5466 omp_current_do_code
= NULL
;
5467 omp_current_do_collapse
= 0;
5471 /* Restore openmp.c private state from the saved state. */
5474 gfc_omp_restore_state (struct gfc_omp_saved_state
*state
)
5476 omp_current_ctx
= (struct fortran_omp_context
*) state
->ptrs
[0];
5477 omp_current_do_code
= (gfc_code
*) state
->ptrs
[1];
5478 omp_current_do_collapse
= state
->ints
[0];
5482 /* Note a DO iterator variable. This is special in !$omp parallel
5483 construct, where they are predetermined private. */
5486 gfc_resolve_do_iterator (gfc_code
*code
, gfc_symbol
*sym
, bool add_clause
)
5488 if (omp_current_ctx
== NULL
)
5491 int i
= omp_current_do_collapse
;
5492 gfc_code
*c
= omp_current_do_code
;
5494 if (sym
->attr
.threadprivate
)
5497 /* !$omp do and !$omp parallel do iteration variable is predetermined
5498 private just in the !$omp do resp. !$omp parallel do construct,
5499 with no implications for the outer parallel constructs. */
5509 /* An openacc context may represent a data clause. Abort if so. */
5510 if (!omp_current_ctx
->is_openmp
&& !oacc_is_loop (omp_current_ctx
->code
))
5513 if (omp_current_ctx
->is_openmp
5514 && omp_current_ctx
->sharing_clauses
->contains (sym
))
5517 if (! omp_current_ctx
->private_iterators
->add (sym
) && add_clause
)
5519 gfc_omp_clauses
*omp_clauses
= omp_current_ctx
->code
->ext
.omp_clauses
;
5520 gfc_omp_namelist
*p
;
5522 p
= gfc_get_omp_namelist ();
5524 p
->next
= omp_clauses
->lists
[OMP_LIST_PRIVATE
];
5525 omp_clauses
->lists
[OMP_LIST_PRIVATE
] = p
;
5530 handle_local_var (gfc_symbol
*sym
)
5532 if (sym
->attr
.flavor
!= FL_VARIABLE
5534 || (sym
->ts
.type
!= BT_INTEGER
&& sym
->ts
.type
!= BT_REAL
))
5536 gfc_resolve_do_iterator (sym
->ns
->code
, sym
, false);
5540 gfc_resolve_omp_local_vars (gfc_namespace
*ns
)
5542 if (omp_current_ctx
)
5543 gfc_traverse_ns (ns
, handle_local_var
);
5547 resolve_omp_do (gfc_code
*code
)
5549 gfc_code
*do_code
, *c
;
5550 int list
, i
, collapse
;
5551 gfc_omp_namelist
*n
;
5554 bool is_simd
= false;
5558 case EXEC_OMP_DISTRIBUTE
: name
= "!$OMP DISTRIBUTE"; break;
5559 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO
:
5560 name
= "!$OMP DISTRIBUTE PARALLEL DO";
5562 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD
:
5563 name
= "!$OMP DISTRIBUTE PARALLEL DO SIMD";
5566 case EXEC_OMP_DISTRIBUTE_SIMD
:
5567 name
= "!$OMP DISTRIBUTE SIMD";
5570 case EXEC_OMP_DO
: name
= "!$OMP DO"; break;
5571 case EXEC_OMP_DO_SIMD
: name
= "!$OMP DO SIMD"; is_simd
= true; break;
5572 case EXEC_OMP_PARALLEL_DO
: name
= "!$OMP PARALLEL DO"; break;
5573 case EXEC_OMP_PARALLEL_DO_SIMD
:
5574 name
= "!$OMP PARALLEL DO SIMD";
5577 case EXEC_OMP_SIMD
: name
= "!$OMP SIMD"; is_simd
= true; break;
5578 case EXEC_OMP_TARGET_PARALLEL_DO
: name
= "!$OMP TARGET PARALLEL DO"; break;
5579 case EXEC_OMP_TARGET_PARALLEL_DO_SIMD
:
5580 name
= "!$OMP TARGET PARALLEL DO SIMD";
5583 case EXEC_OMP_TARGET_SIMD
:
5584 name
= "!$OMP TARGET SIMD";
5587 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE
:
5588 name
= "!$OMP TARGET TEAMS DISTRIBUTE";
5590 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO
:
5591 name
= "!$OMP TARGET TEAMS DISTRIBUTE PARALLEL DO";
5593 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
5594 name
= "!$OMP TARGET TEAMS DISTRIBUTE PARALLEL DO SIMD";
5597 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD
:
5598 name
= "!$OMP TARGET TEAMS DISTRIBUTE SIMD";
5601 case EXEC_OMP_TASKLOOP
: name
= "!$OMP TASKLOOP"; break;
5602 case EXEC_OMP_TASKLOOP_SIMD
:
5603 name
= "!$OMP TASKLOOP SIMD";
5606 case EXEC_OMP_TEAMS_DISTRIBUTE
: name
= "!$OMP TEAMS DISTRIBUTE"; break;
5607 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO
:
5608 name
= "!$OMP TEAMS DISTRIBUTE PARALLEL DO";
5610 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
5611 name
= "!$OMP TEAMS DISTRIBUTE PARALLEL DO SIMD";
5614 case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD
:
5615 name
= "!$OMP TEAMS DISTRIBUTE SIMD";
5618 default: gcc_unreachable ();
5621 if (code
->ext
.omp_clauses
)
5622 resolve_omp_clauses (code
, code
->ext
.omp_clauses
, NULL
);
5624 do_code
= code
->block
->next
;
5625 if (code
->ext
.omp_clauses
->orderedc
)
5626 collapse
= code
->ext
.omp_clauses
->orderedc
;
5629 collapse
= code
->ext
.omp_clauses
->collapse
;
5633 for (i
= 1; i
<= collapse
; i
++)
5635 if (do_code
->op
== EXEC_DO_WHILE
)
5637 gfc_error ("%s cannot be a DO WHILE or DO without loop control "
5638 "at %L", name
, &do_code
->loc
);
5641 if (do_code
->op
== EXEC_DO_CONCURRENT
)
5643 gfc_error ("%s cannot be a DO CONCURRENT loop at %L", name
,
5647 gcc_assert (do_code
->op
== EXEC_DO
);
5648 if (do_code
->ext
.iterator
->var
->ts
.type
!= BT_INTEGER
)
5649 gfc_error ("%s iteration variable must be of type integer at %L",
5650 name
, &do_code
->loc
);
5651 dovar
= do_code
->ext
.iterator
->var
->symtree
->n
.sym
;
5652 if (dovar
->attr
.threadprivate
)
5653 gfc_error ("%s iteration variable must not be THREADPRIVATE "
5654 "at %L", name
, &do_code
->loc
);
5655 if (code
->ext
.omp_clauses
)
5656 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
5658 ? (list
!= OMP_LIST_PRIVATE
&& list
!= OMP_LIST_LASTPRIVATE
)
5659 : code
->ext
.omp_clauses
->collapse
> 1
5660 ? (list
!= OMP_LIST_LASTPRIVATE
)
5661 : (list
!= OMP_LIST_LINEAR
))
5662 for (n
= code
->ext
.omp_clauses
->lists
[list
]; n
; n
= n
->next
)
5663 if (dovar
== n
->sym
)
5666 gfc_error ("%s iteration variable present on clause "
5667 "other than PRIVATE or LASTPRIVATE at %L",
5668 name
, &do_code
->loc
);
5669 else if (code
->ext
.omp_clauses
->collapse
> 1)
5670 gfc_error ("%s iteration variable present on clause "
5671 "other than LASTPRIVATE at %L",
5672 name
, &do_code
->loc
);
5674 gfc_error ("%s iteration variable present on clause "
5675 "other than LINEAR at %L",
5676 name
, &do_code
->loc
);
5681 gfc_code
*do_code2
= code
->block
->next
;
5684 for (j
= 1; j
< i
; j
++)
5686 gfc_symbol
*ivar
= do_code2
->ext
.iterator
->var
->symtree
->n
.sym
;
5688 || gfc_find_sym_in_expr (ivar
, do_code
->ext
.iterator
->start
)
5689 || gfc_find_sym_in_expr (ivar
, do_code
->ext
.iterator
->end
)
5690 || gfc_find_sym_in_expr (ivar
, do_code
->ext
.iterator
->step
))
5692 gfc_error ("%s collapsed loops don't form rectangular "
5693 "iteration space at %L", name
, &do_code
->loc
);
5696 do_code2
= do_code2
->block
->next
;
5701 for (c
= do_code
->next
; c
; c
= c
->next
)
5702 if (c
->op
!= EXEC_NOP
&& c
->op
!= EXEC_CONTINUE
)
5704 gfc_error ("collapsed %s loops not perfectly nested at %L",
5710 do_code
= do_code
->block
;
5711 if (do_code
->op
!= EXEC_DO
&& do_code
->op
!= EXEC_DO_WHILE
)
5713 gfc_error ("not enough DO loops for collapsed %s at %L",
5717 do_code
= do_code
->next
;
5719 || (do_code
->op
!= EXEC_DO
&& do_code
->op
!= EXEC_DO_WHILE
))
5721 gfc_error ("not enough DO loops for collapsed %s at %L",
5729 oacc_is_parallel (gfc_code
*code
)
5731 return code
->op
== EXEC_OACC_PARALLEL
|| code
->op
== EXEC_OACC_PARALLEL_LOOP
;
5734 static gfc_statement
5735 omp_code_to_statement (gfc_code
*code
)
5739 case EXEC_OMP_PARALLEL
:
5740 return ST_OMP_PARALLEL
;
5741 case EXEC_OMP_PARALLEL_SECTIONS
:
5742 return ST_OMP_PARALLEL_SECTIONS
;
5743 case EXEC_OMP_SECTIONS
:
5744 return ST_OMP_SECTIONS
;
5745 case EXEC_OMP_ORDERED
:
5746 return ST_OMP_ORDERED
;
5747 case EXEC_OMP_CRITICAL
:
5748 return ST_OMP_CRITICAL
;
5749 case EXEC_OMP_MASTER
:
5750 return ST_OMP_MASTER
;
5751 case EXEC_OMP_SINGLE
:
5752 return ST_OMP_SINGLE
;
5755 case EXEC_OMP_WORKSHARE
:
5756 return ST_OMP_WORKSHARE
;
5757 case EXEC_OMP_PARALLEL_WORKSHARE
:
5758 return ST_OMP_PARALLEL_WORKSHARE
;
5766 static gfc_statement
5767 oacc_code_to_statement (gfc_code
*code
)
5771 case EXEC_OACC_PARALLEL
:
5772 return ST_OACC_PARALLEL
;
5773 case EXEC_OACC_KERNELS
:
5774 return ST_OACC_KERNELS
;
5775 case EXEC_OACC_DATA
:
5776 return ST_OACC_DATA
;
5777 case EXEC_OACC_HOST_DATA
:
5778 return ST_OACC_HOST_DATA
;
5779 case EXEC_OACC_PARALLEL_LOOP
:
5780 return ST_OACC_PARALLEL_LOOP
;
5781 case EXEC_OACC_KERNELS_LOOP
:
5782 return ST_OACC_KERNELS_LOOP
;
5783 case EXEC_OACC_LOOP
:
5784 return ST_OACC_LOOP
;
5785 case EXEC_OACC_ATOMIC
:
5786 return ST_OACC_ATOMIC
;
5793 resolve_oacc_directive_inside_omp_region (gfc_code
*code
)
5795 if (omp_current_ctx
!= NULL
&& omp_current_ctx
->is_openmp
)
5797 gfc_statement st
= omp_code_to_statement (omp_current_ctx
->code
);
5798 gfc_statement oacc_st
= oacc_code_to_statement (code
);
5799 gfc_error ("The %s directive cannot be specified within "
5800 "a %s region at %L", gfc_ascii_statement (oacc_st
),
5801 gfc_ascii_statement (st
), &code
->loc
);
5806 resolve_omp_directive_inside_oacc_region (gfc_code
*code
)
5808 if (omp_current_ctx
!= NULL
&& !omp_current_ctx
->is_openmp
)
5810 gfc_statement st
= oacc_code_to_statement (omp_current_ctx
->code
);
5811 gfc_statement omp_st
= omp_code_to_statement (code
);
5812 gfc_error ("The %s directive cannot be specified within "
5813 "a %s region at %L", gfc_ascii_statement (omp_st
),
5814 gfc_ascii_statement (st
), &code
->loc
);
5820 resolve_oacc_nested_loops (gfc_code
*code
, gfc_code
* do_code
, int collapse
,
5827 for (i
= 1; i
<= collapse
; i
++)
5829 if (do_code
->op
== EXEC_DO_WHILE
)
5831 gfc_error ("!$ACC LOOP cannot be a DO WHILE or DO without loop control "
5832 "at %L", &do_code
->loc
);
5835 if (do_code
->op
== EXEC_DO_CONCURRENT
)
5837 gfc_error ("!$ACC LOOP cannot be a DO CONCURRENT loop at %L",
5841 gcc_assert (do_code
->op
== EXEC_DO
);
5842 if (do_code
->ext
.iterator
->var
->ts
.type
!= BT_INTEGER
)
5843 gfc_error ("!$ACC LOOP iteration variable must be of type integer at %L",
5845 dovar
= do_code
->ext
.iterator
->var
->symtree
->n
.sym
;
5848 gfc_code
*do_code2
= code
->block
->next
;
5851 for (j
= 1; j
< i
; j
++)
5853 gfc_symbol
*ivar
= do_code2
->ext
.iterator
->var
->symtree
->n
.sym
;
5855 || gfc_find_sym_in_expr (ivar
, do_code
->ext
.iterator
->start
)
5856 || gfc_find_sym_in_expr (ivar
, do_code
->ext
.iterator
->end
)
5857 || gfc_find_sym_in_expr (ivar
, do_code
->ext
.iterator
->step
))
5859 gfc_error ("!$ACC LOOP %s loops don't form rectangular "
5860 "iteration space at %L", clause
, &do_code
->loc
);
5863 do_code2
= do_code2
->block
->next
;
5868 for (c
= do_code
->next
; c
; c
= c
->next
)
5869 if (c
->op
!= EXEC_NOP
&& c
->op
!= EXEC_CONTINUE
)
5871 gfc_error ("%s !$ACC LOOP loops not perfectly nested at %L",
5877 do_code
= do_code
->block
;
5878 if (do_code
->op
!= EXEC_DO
&& do_code
->op
!= EXEC_DO_WHILE
5879 && do_code
->op
!= EXEC_DO_CONCURRENT
)
5881 gfc_error ("not enough DO loops for %s !$ACC LOOP at %L",
5882 clause
, &code
->loc
);
5885 do_code
= do_code
->next
;
5887 || (do_code
->op
!= EXEC_DO
&& do_code
->op
!= EXEC_DO_WHILE
5888 && do_code
->op
!= EXEC_DO_CONCURRENT
))
5890 gfc_error ("not enough DO loops for %s !$ACC LOOP at %L",
5891 clause
, &code
->loc
);
5899 resolve_oacc_params_in_parallel (gfc_code
*code
, const char *clause
,
5902 fortran_omp_context
*c
;
5904 if (oacc_is_parallel (code
))
5905 gfc_error ("!$ACC LOOP %s in PARALLEL region doesn't allow "
5906 "%s arguments at %L", clause
, arg
, &code
->loc
);
5907 for (c
= omp_current_ctx
; c
; c
= c
->previous
)
5909 if (oacc_is_loop (c
->code
))
5911 if (oacc_is_parallel (c
->code
))
5912 gfc_error ("!$ACC LOOP %s in PARALLEL region doesn't allow "
5913 "%s arguments at %L", clause
, arg
, &code
->loc
);
5919 resolve_oacc_loop_blocks (gfc_code
*code
)
5921 if (!oacc_is_loop (code
))
5924 if (code
->ext
.omp_clauses
->tile_list
&& code
->ext
.omp_clauses
->gang
5925 && code
->ext
.omp_clauses
->worker
&& code
->ext
.omp_clauses
->vector
)
5926 gfc_error ("Tiled loop cannot be parallelized across gangs, workers and "
5927 "vectors at the same time at %L", &code
->loc
);
5929 if (code
->ext
.omp_clauses
->gang
5930 && code
->ext
.omp_clauses
->gang_num_expr
)
5931 resolve_oacc_params_in_parallel (code
, "GANG", "num");
5933 if (code
->ext
.omp_clauses
->worker
5934 && code
->ext
.omp_clauses
->worker_expr
)
5935 resolve_oacc_params_in_parallel (code
, "WORKER", "num");
5937 if (code
->ext
.omp_clauses
->vector
5938 && code
->ext
.omp_clauses
->vector_expr
)
5939 resolve_oacc_params_in_parallel (code
, "VECTOR", "length");
5941 if (code
->ext
.omp_clauses
->tile_list
)
5945 for (el
= code
->ext
.omp_clauses
->tile_list
; el
; el
= el
->next
)
5948 if (el
->expr
== NULL
)
5950 /* NULL expressions are used to represent '*' arguments.
5951 Convert those to a 0 expressions. */
5952 el
->expr
= gfc_get_constant_expr (BT_INTEGER
,
5953 gfc_default_integer_kind
,
5955 mpz_set_si (el
->expr
->value
.integer
, 0);
5959 resolve_positive_int_expr (el
->expr
, "TILE");
5960 if (el
->expr
->expr_type
!= EXPR_CONSTANT
)
5961 gfc_error ("TILE requires constant expression at %L",
5965 resolve_oacc_nested_loops (code
, code
->block
->next
, num
, "tiled");
5971 gfc_resolve_oacc_blocks (gfc_code
*code
, gfc_namespace
*ns
)
5973 fortran_omp_context ctx
;
5975 resolve_oacc_loop_blocks (code
);
5978 ctx
.sharing_clauses
= NULL
;
5979 ctx
.private_iterators
= new hash_set
<gfc_symbol
*>;
5980 ctx
.previous
= omp_current_ctx
;
5981 ctx
.is_openmp
= false;
5982 omp_current_ctx
= &ctx
;
5984 gfc_resolve_blocks (code
->block
, ns
);
5986 omp_current_ctx
= ctx
.previous
;
5987 delete ctx
.private_iterators
;
5992 resolve_oacc_loop (gfc_code
*code
)
5997 if (code
->ext
.omp_clauses
)
5998 resolve_omp_clauses (code
, code
->ext
.omp_clauses
, NULL
, true);
6000 do_code
= code
->block
->next
;
6001 collapse
= code
->ext
.omp_clauses
->collapse
;
6005 resolve_oacc_nested_loops (code
, do_code
, collapse
, "collapsed");
6009 gfc_resolve_oacc_declare (gfc_namespace
*ns
)
6012 gfc_omp_namelist
*n
;
6013 gfc_oacc_declare
*oc
;
6015 if (ns
->oacc_declare
== NULL
)
6018 for (oc
= ns
->oacc_declare
; oc
; oc
= oc
->next
)
6020 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
6021 for (n
= oc
->clauses
->lists
[list
]; n
; n
= n
->next
)
6024 if (n
->sym
->attr
.function
|| n
->sym
->attr
.subroutine
)
6026 gfc_error ("Object %qs is not a variable at %L",
6027 n
->sym
->name
, &oc
->loc
);
6030 if (n
->sym
->attr
.flavor
== FL_PARAMETER
)
6032 gfc_error ("PARAMETER object %qs is not allowed at %L",
6033 n
->sym
->name
, &oc
->loc
);
6037 if (n
->expr
&& n
->expr
->ref
->type
== REF_ARRAY
)
6039 gfc_error ("Array sections: %qs not allowed in"
6040 " !$ACC DECLARE at %L", n
->sym
->name
, &oc
->loc
);
6045 for (n
= oc
->clauses
->lists
[OMP_LIST_DEVICE_RESIDENT
]; n
; n
= n
->next
)
6046 check_array_not_assumed (n
->sym
, oc
->loc
, "DEVICE_RESIDENT");
6049 for (oc
= ns
->oacc_declare
; oc
; oc
= oc
->next
)
6051 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
6052 for (n
= oc
->clauses
->lists
[list
]; n
; n
= n
->next
)
6056 gfc_error ("Symbol %qs present on multiple clauses at %L",
6057 n
->sym
->name
, &oc
->loc
);
6065 for (oc
= ns
->oacc_declare
; oc
; oc
= oc
->next
)
6067 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
6068 for (n
= oc
->clauses
->lists
[list
]; n
; n
= n
->next
)
6075 gfc_resolve_oacc_routines (gfc_namespace
*ns
)
6077 for (gfc_oacc_routine_name
*orn
= ns
->oacc_routine_names
;
6081 gfc_symbol
*sym
= orn
->sym
;
6082 if (!sym
->attr
.external
6083 && !sym
->attr
.function
6084 && !sym
->attr
.subroutine
)
6086 gfc_error ("NAME %qs does not refer to a subroutine or function"
6087 " in !$ACC ROUTINE ( NAME ) at %L", sym
->name
, &orn
->loc
);
6090 if (!gfc_add_omp_declare_target (&sym
->attr
, sym
->name
, &orn
->loc
))
6092 gfc_error ("NAME %qs invalid"
6093 " in !$ACC ROUTINE ( NAME ) at %L", sym
->name
, &orn
->loc
);
6101 gfc_resolve_oacc_directive (gfc_code
*code
, gfc_namespace
*ns ATTRIBUTE_UNUSED
)
6103 resolve_oacc_directive_inside_omp_region (code
);
6107 case EXEC_OACC_PARALLEL
:
6108 case EXEC_OACC_KERNELS
:
6109 case EXEC_OACC_DATA
:
6110 case EXEC_OACC_HOST_DATA
:
6111 case EXEC_OACC_UPDATE
:
6112 case EXEC_OACC_ENTER_DATA
:
6113 case EXEC_OACC_EXIT_DATA
:
6114 case EXEC_OACC_WAIT
:
6115 case EXEC_OACC_CACHE
:
6116 resolve_omp_clauses (code
, code
->ext
.omp_clauses
, NULL
, true);
6118 case EXEC_OACC_PARALLEL_LOOP
:
6119 case EXEC_OACC_KERNELS_LOOP
:
6120 case EXEC_OACC_LOOP
:
6121 resolve_oacc_loop (code
);
6123 case EXEC_OACC_ATOMIC
:
6124 resolve_omp_atomic (code
);
6132 /* Resolve OpenMP directive clauses and check various requirements
6133 of each directive. */
6136 gfc_resolve_omp_directive (gfc_code
*code
, gfc_namespace
*ns ATTRIBUTE_UNUSED
)
6138 resolve_omp_directive_inside_oacc_region (code
);
6140 if (code
->op
!= EXEC_OMP_ATOMIC
)
6141 gfc_maybe_initialize_eh ();
6145 case EXEC_OMP_DISTRIBUTE
:
6146 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO
:
6147 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD
:
6148 case EXEC_OMP_DISTRIBUTE_SIMD
:
6150 case EXEC_OMP_DO_SIMD
:
6151 case EXEC_OMP_PARALLEL_DO
:
6152 case EXEC_OMP_PARALLEL_DO_SIMD
:
6154 case EXEC_OMP_TARGET_PARALLEL_DO
:
6155 case EXEC_OMP_TARGET_PARALLEL_DO_SIMD
:
6156 case EXEC_OMP_TARGET_SIMD
:
6157 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE
:
6158 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO
:
6159 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
6160 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD
:
6161 case EXEC_OMP_TASKLOOP
:
6162 case EXEC_OMP_TASKLOOP_SIMD
:
6163 case EXEC_OMP_TEAMS_DISTRIBUTE
:
6164 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO
:
6165 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
6166 case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD
:
6167 resolve_omp_do (code
);
6169 case EXEC_OMP_CANCEL
:
6170 case EXEC_OMP_PARALLEL_WORKSHARE
:
6171 case EXEC_OMP_PARALLEL
:
6172 case EXEC_OMP_PARALLEL_SECTIONS
:
6173 case EXEC_OMP_SECTIONS
:
6174 case EXEC_OMP_SINGLE
:
6175 case EXEC_OMP_TARGET
:
6176 case EXEC_OMP_TARGET_DATA
:
6177 case EXEC_OMP_TARGET_ENTER_DATA
:
6178 case EXEC_OMP_TARGET_EXIT_DATA
:
6179 case EXEC_OMP_TARGET_PARALLEL
:
6180 case EXEC_OMP_TARGET_TEAMS
:
6182 case EXEC_OMP_TEAMS
:
6183 case EXEC_OMP_WORKSHARE
:
6184 if (code
->ext
.omp_clauses
)
6185 resolve_omp_clauses (code
, code
->ext
.omp_clauses
, NULL
);
6187 case EXEC_OMP_TARGET_UPDATE
:
6188 if (code
->ext
.omp_clauses
)
6189 resolve_omp_clauses (code
, code
->ext
.omp_clauses
, NULL
);
6190 if (code
->ext
.omp_clauses
== NULL
6191 || (code
->ext
.omp_clauses
->lists
[OMP_LIST_TO
] == NULL
6192 && code
->ext
.omp_clauses
->lists
[OMP_LIST_FROM
] == NULL
))
6193 gfc_error ("OMP TARGET UPDATE at %L requires at least one TO or "
6194 "FROM clause", &code
->loc
);
6196 case EXEC_OMP_ATOMIC
:
6197 resolve_omp_atomic (code
);
6204 /* Resolve !$omp declare simd constructs in NS. */
6207 gfc_resolve_omp_declare_simd (gfc_namespace
*ns
)
6209 gfc_omp_declare_simd
*ods
;
6211 for (ods
= ns
->omp_declare_simd
; ods
; ods
= ods
->next
)
6213 if (ods
->proc_name
!= NULL
6214 && ods
->proc_name
!= ns
->proc_name
)
6215 gfc_error ("!$OMP DECLARE SIMD should refer to containing procedure "
6216 "%qs at %L", ns
->proc_name
->name
, &ods
->where
);
6218 resolve_omp_clauses (NULL
, ods
->clauses
, ns
);
6222 struct omp_udr_callback_data
6224 gfc_omp_udr
*omp_udr
;
6225 bool is_initializer
;
6229 omp_udr_callback (gfc_expr
**e
, int *walk_subtrees ATTRIBUTE_UNUSED
,
6232 struct omp_udr_callback_data
*cd
= (struct omp_udr_callback_data
*) data
;
6233 if ((*e
)->expr_type
== EXPR_VARIABLE
)
6235 if (cd
->is_initializer
)
6237 if ((*e
)->symtree
->n
.sym
!= cd
->omp_udr
->omp_priv
6238 && (*e
)->symtree
->n
.sym
!= cd
->omp_udr
->omp_orig
)
6239 gfc_error ("Variable other than OMP_PRIV or OMP_ORIG used in "
6240 "INITIALIZER clause of !$OMP DECLARE REDUCTION at %L",
6245 if ((*e
)->symtree
->n
.sym
!= cd
->omp_udr
->omp_out
6246 && (*e
)->symtree
->n
.sym
!= cd
->omp_udr
->omp_in
)
6247 gfc_error ("Variable other than OMP_OUT or OMP_IN used in "
6248 "combiner of !$OMP DECLARE REDUCTION at %L",
6255 /* Resolve !$omp declare reduction constructs. */
6258 gfc_resolve_omp_udr (gfc_omp_udr
*omp_udr
)
6260 gfc_actual_arglist
*a
;
6261 const char *predef_name
= NULL
;
6263 switch (omp_udr
->rop
)
6265 case OMP_REDUCTION_PLUS
:
6266 case OMP_REDUCTION_TIMES
:
6267 case OMP_REDUCTION_MINUS
:
6268 case OMP_REDUCTION_AND
:
6269 case OMP_REDUCTION_OR
:
6270 case OMP_REDUCTION_EQV
:
6271 case OMP_REDUCTION_NEQV
:
6272 case OMP_REDUCTION_MAX
:
6273 case OMP_REDUCTION_USER
:
6276 gfc_error ("Invalid operator for !$OMP DECLARE REDUCTION %s at %L",
6277 omp_udr
->name
, &omp_udr
->where
);
6281 if (gfc_omp_udr_predef (omp_udr
->rop
, omp_udr
->name
,
6282 &omp_udr
->ts
, &predef_name
))
6285 gfc_error_now ("Redefinition of predefined %s "
6286 "!$OMP DECLARE REDUCTION at %L",
6287 predef_name
, &omp_udr
->where
);
6289 gfc_error_now ("Redefinition of predefined "
6290 "!$OMP DECLARE REDUCTION at %L", &omp_udr
->where
);
6294 if (omp_udr
->ts
.type
== BT_CHARACTER
6295 && omp_udr
->ts
.u
.cl
->length
6296 && omp_udr
->ts
.u
.cl
->length
->expr_type
!= EXPR_CONSTANT
)
6298 gfc_error ("CHARACTER length in !$OMP DECLARE REDUCTION %s not "
6299 "constant at %L", omp_udr
->name
, &omp_udr
->where
);
6303 struct omp_udr_callback_data cd
;
6304 cd
.omp_udr
= omp_udr
;
6305 cd
.is_initializer
= false;
6306 gfc_code_walker (&omp_udr
->combiner_ns
->code
, gfc_dummy_code_callback
,
6307 omp_udr_callback
, &cd
);
6308 if (omp_udr
->combiner_ns
->code
->op
== EXEC_CALL
)
6310 for (a
= omp_udr
->combiner_ns
->code
->ext
.actual
; a
; a
= a
->next
)
6311 if (a
->expr
== NULL
)
6314 gfc_error ("Subroutine call with alternate returns in combiner "
6315 "of !$OMP DECLARE REDUCTION at %L",
6316 &omp_udr
->combiner_ns
->code
->loc
);
6318 if (omp_udr
->initializer_ns
)
6320 cd
.is_initializer
= true;
6321 gfc_code_walker (&omp_udr
->initializer_ns
->code
, gfc_dummy_code_callback
,
6322 omp_udr_callback
, &cd
);
6323 if (omp_udr
->initializer_ns
->code
->op
== EXEC_CALL
)
6325 for (a
= omp_udr
->initializer_ns
->code
->ext
.actual
; a
; a
= a
->next
)
6326 if (a
->expr
== NULL
)
6329 gfc_error ("Subroutine call with alternate returns in "
6330 "INITIALIZER clause of !$OMP DECLARE REDUCTION "
6331 "at %L", &omp_udr
->initializer_ns
->code
->loc
);
6332 for (a
= omp_udr
->initializer_ns
->code
->ext
.actual
; a
; a
= a
->next
)
6334 && a
->expr
->expr_type
== EXPR_VARIABLE
6335 && a
->expr
->symtree
->n
.sym
== omp_udr
->omp_priv
6336 && a
->expr
->ref
== NULL
)
6339 gfc_error ("One of actual subroutine arguments in INITIALIZER "
6340 "clause of !$OMP DECLARE REDUCTION must be OMP_PRIV "
6341 "at %L", &omp_udr
->initializer_ns
->code
->loc
);
6344 else if (omp_udr
->ts
.type
== BT_DERIVED
6345 && !gfc_has_default_initializer (omp_udr
->ts
.u
.derived
))
6347 gfc_error ("Missing INITIALIZER clause for !$OMP DECLARE REDUCTION "
6348 "of derived type without default initializer at %L",
6355 gfc_resolve_omp_udrs (gfc_symtree
*st
)
6357 gfc_omp_udr
*omp_udr
;
6361 gfc_resolve_omp_udrs (st
->left
);
6362 gfc_resolve_omp_udrs (st
->right
);
6363 for (omp_udr
= st
->n
.omp_udr
; omp_udr
; omp_udr
= omp_udr
->next
)
6364 gfc_resolve_omp_udr (omp_udr
);