1 /* OpenMP directive matching and resolving.
2 Copyright (C) 2005-2018 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
;
1714 && gfc_match ("simd") == MATCH_YES
)
1716 c
->sched_simd
= true;
1719 else if (!c
->sched_monotonic
1720 && !c
->sched_nonmonotonic
1721 && gfc_match ("monotonic") == MATCH_YES
)
1723 c
->sched_monotonic
= true;
1726 else if (!c
->sched_monotonic
1727 && !c
->sched_nonmonotonic
1728 && gfc_match ("nonmonotonic") == MATCH_YES
)
1730 c
->sched_nonmonotonic
= true;
1736 gfc_current_locus
= old_loc2
;
1740 && gfc_match (" , ") == MATCH_YES
)
1742 else if (gfc_match (" : ") == MATCH_YES
)
1744 gfc_current_locus
= old_loc2
;
1748 if (gfc_match ("static") == MATCH_YES
)
1749 c
->sched_kind
= OMP_SCHED_STATIC
;
1750 else if (gfc_match ("dynamic") == MATCH_YES
)
1751 c
->sched_kind
= OMP_SCHED_DYNAMIC
;
1752 else if (gfc_match ("guided") == MATCH_YES
)
1753 c
->sched_kind
= OMP_SCHED_GUIDED
;
1754 else if (gfc_match ("runtime") == MATCH_YES
)
1755 c
->sched_kind
= OMP_SCHED_RUNTIME
;
1756 else if (gfc_match ("auto") == MATCH_YES
)
1757 c
->sched_kind
= OMP_SCHED_AUTO
;
1758 if (c
->sched_kind
!= OMP_SCHED_NONE
)
1761 if (c
->sched_kind
!= OMP_SCHED_RUNTIME
1762 && c
->sched_kind
!= OMP_SCHED_AUTO
)
1763 m
= gfc_match (" , %e )", &c
->chunk_size
);
1765 m
= gfc_match_char (')');
1767 c
->sched_kind
= OMP_SCHED_NONE
;
1769 if (c
->sched_kind
!= OMP_SCHED_NONE
)
1772 gfc_current_locus
= old_loc
;
1774 if ((mask
& OMP_CLAUSE_HOST_SELF
)
1775 && gfc_match ("self ( ") == MATCH_YES
1776 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1777 OMP_MAP_FORCE_FROM
))
1779 if ((mask
& OMP_CLAUSE_SEQ
)
1781 && gfc_match ("seq") == MATCH_YES
)
1787 if ((mask
& OMP_CLAUSE_SHARED
)
1788 && gfc_match_omp_variable_list ("shared (",
1789 &c
->lists
[OMP_LIST_SHARED
],
1792 if ((mask
& OMP_CLAUSE_SIMDLEN
)
1793 && c
->simdlen_expr
== NULL
1794 && gfc_match ("simdlen ( %e )", &c
->simdlen_expr
) == MATCH_YES
)
1796 if ((mask
& OMP_CLAUSE_SIMD
)
1798 && gfc_match ("simd") == MATCH_YES
)
1800 c
->simd
= needs_space
= true;
1805 if ((mask
& OMP_CLAUSE_THREAD_LIMIT
)
1806 && c
->thread_limit
== NULL
1807 && gfc_match ("thread_limit ( %e )",
1808 &c
->thread_limit
) == MATCH_YES
)
1810 if ((mask
& OMP_CLAUSE_THREADS
)
1812 && gfc_match ("threads") == MATCH_YES
)
1814 c
->threads
= needs_space
= true;
1817 if ((mask
& OMP_CLAUSE_TILE
)
1819 && match_oacc_expr_list ("tile (", &c
->tile_list
,
1822 if ((mask
& OMP_CLAUSE_TO
) && (mask
& OMP_CLAUSE_LINK
))
1824 if (gfc_match_omp_to_link ("to (", &c
->lists
[OMP_LIST_TO
])
1828 else if ((mask
& OMP_CLAUSE_TO
)
1829 && gfc_match_omp_variable_list ("to (",
1830 &c
->lists
[OMP_LIST_TO
], false,
1831 NULL
, &head
, true) == MATCH_YES
)
1835 if ((mask
& OMP_CLAUSE_UNIFORM
)
1836 && gfc_match_omp_variable_list ("uniform (",
1837 &c
->lists
[OMP_LIST_UNIFORM
],
1838 false) == MATCH_YES
)
1840 if ((mask
& OMP_CLAUSE_UNTIED
)
1842 && gfc_match ("untied") == MATCH_YES
)
1844 c
->untied
= needs_space
= true;
1847 if ((mask
& OMP_CLAUSE_USE_DEVICE
)
1848 && gfc_match_omp_variable_list ("use_device (",
1849 &c
->lists
[OMP_LIST_USE_DEVICE
],
1852 if ((mask
& OMP_CLAUSE_USE_DEVICE_PTR
)
1853 && gfc_match_omp_variable_list
1854 ("use_device_ptr (",
1855 &c
->lists
[OMP_LIST_USE_DEVICE_PTR
], false) == MATCH_YES
)
1859 /* VECTOR_LENGTH must be matched before VECTOR, because the latter
1860 doesn't unconditionally match '('. */
1861 if ((mask
& OMP_CLAUSE_VECTOR_LENGTH
)
1862 && c
->vector_length_expr
== NULL
1863 && (gfc_match ("vector_length ( %e )", &c
->vector_length_expr
)
1866 if ((mask
& OMP_CLAUSE_VECTOR
)
1868 && gfc_match ("vector") == MATCH_YES
)
1871 match m
= match_oacc_clause_gwv (c
, GOMP_DIM_VECTOR
);
1872 if (m
== MATCH_ERROR
)
1874 gfc_current_locus
= old_loc
;
1883 if ((mask
& OMP_CLAUSE_WAIT
)
1885 && gfc_match ("wait") == MATCH_YES
)
1888 match m
= match_oacc_expr_list (" (", &c
->wait_list
, false);
1889 if (m
== MATCH_ERROR
)
1891 gfc_current_locus
= old_loc
;
1894 else if (m
== MATCH_NO
)
1898 if ((mask
& OMP_CLAUSE_WORKER
)
1900 && gfc_match ("worker") == MATCH_YES
)
1903 match m
= match_oacc_clause_gwv (c
, GOMP_DIM_WORKER
);
1904 if (m
== MATCH_ERROR
)
1906 gfc_current_locus
= old_loc
;
1909 else if (m
== MATCH_NO
)
1918 if (gfc_match_omp_eos () != MATCH_YES
)
1920 gfc_free_omp_clauses (c
);
1929 #define OACC_PARALLEL_CLAUSES \
1930 (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_NUM_GANGS \
1931 | OMP_CLAUSE_NUM_WORKERS | OMP_CLAUSE_VECTOR_LENGTH | OMP_CLAUSE_REDUCTION \
1932 | OMP_CLAUSE_COPY | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT \
1933 | OMP_CLAUSE_CREATE | OMP_CLAUSE_PRESENT | OMP_CLAUSE_DEVICEPTR \
1934 | OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_DEFAULT \
1936 #define OACC_KERNELS_CLAUSES \
1937 (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_NUM_GANGS \
1938 | OMP_CLAUSE_NUM_WORKERS | OMP_CLAUSE_VECTOR_LENGTH | OMP_CLAUSE_DEVICEPTR \
1939 | OMP_CLAUSE_COPY | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT \
1940 | OMP_CLAUSE_CREATE | OMP_CLAUSE_PRESENT | OMP_CLAUSE_DEFAULT \
1942 #define OACC_DATA_CLAUSES \
1943 (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_DEVICEPTR | OMP_CLAUSE_COPY \
1944 | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT | OMP_CLAUSE_CREATE \
1945 | OMP_CLAUSE_PRESENT)
1946 #define OACC_LOOP_CLAUSES \
1947 (omp_mask (OMP_CLAUSE_COLLAPSE) | OMP_CLAUSE_GANG | OMP_CLAUSE_WORKER \
1948 | OMP_CLAUSE_VECTOR | OMP_CLAUSE_SEQ | OMP_CLAUSE_INDEPENDENT \
1949 | OMP_CLAUSE_PRIVATE | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_AUTO \
1951 #define OACC_PARALLEL_LOOP_CLAUSES \
1952 (OACC_LOOP_CLAUSES | OACC_PARALLEL_CLAUSES)
1953 #define OACC_KERNELS_LOOP_CLAUSES \
1954 (OACC_LOOP_CLAUSES | OACC_KERNELS_CLAUSES)
1955 #define OACC_HOST_DATA_CLAUSES omp_mask (OMP_CLAUSE_USE_DEVICE)
1956 #define OACC_DECLARE_CLAUSES \
1957 (omp_mask (OMP_CLAUSE_COPY) | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT \
1958 | OMP_CLAUSE_CREATE | OMP_CLAUSE_DEVICEPTR | OMP_CLAUSE_DEVICE_RESIDENT \
1959 | OMP_CLAUSE_PRESENT \
1961 #define OACC_UPDATE_CLAUSES \
1962 (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_HOST_SELF \
1963 | OMP_CLAUSE_DEVICE | OMP_CLAUSE_WAIT | OMP_CLAUSE_IF_PRESENT)
1964 #define OACC_ENTER_DATA_CLAUSES \
1965 (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_WAIT \
1966 | OMP_CLAUSE_COPYIN | OMP_CLAUSE_CREATE)
1967 #define OACC_EXIT_DATA_CLAUSES \
1968 (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_WAIT \
1969 | OMP_CLAUSE_COPYOUT | OMP_CLAUSE_DELETE | OMP_CLAUSE_FINALIZE)
1970 #define OACC_WAIT_CLAUSES \
1971 omp_mask (OMP_CLAUSE_ASYNC)
1972 #define OACC_ROUTINE_CLAUSES \
1973 (omp_mask (OMP_CLAUSE_GANG) | OMP_CLAUSE_WORKER | OMP_CLAUSE_VECTOR \
1978 match_acc (gfc_exec_op op
, const omp_mask mask
)
1981 if (gfc_match_omp_clauses (&c
, mask
, false, false, true) != MATCH_YES
)
1984 new_st
.ext
.omp_clauses
= c
;
1989 gfc_match_oacc_parallel_loop (void)
1991 return match_acc (EXEC_OACC_PARALLEL_LOOP
, OACC_PARALLEL_LOOP_CLAUSES
);
1996 gfc_match_oacc_parallel (void)
1998 return match_acc (EXEC_OACC_PARALLEL
, OACC_PARALLEL_CLAUSES
);
2003 gfc_match_oacc_kernels_loop (void)
2005 return match_acc (EXEC_OACC_KERNELS_LOOP
, OACC_KERNELS_LOOP_CLAUSES
);
2010 gfc_match_oacc_kernels (void)
2012 return match_acc (EXEC_OACC_KERNELS
, OACC_KERNELS_CLAUSES
);
2017 gfc_match_oacc_data (void)
2019 return match_acc (EXEC_OACC_DATA
, OACC_DATA_CLAUSES
);
2024 gfc_match_oacc_host_data (void)
2026 return match_acc (EXEC_OACC_HOST_DATA
, OACC_HOST_DATA_CLAUSES
);
2031 gfc_match_oacc_loop (void)
2033 return match_acc (EXEC_OACC_LOOP
, OACC_LOOP_CLAUSES
);
2038 gfc_match_oacc_declare (void)
2041 gfc_omp_namelist
*n
;
2042 gfc_namespace
*ns
= gfc_current_ns
;
2043 gfc_oacc_declare
*new_oc
;
2044 bool module_var
= false;
2045 locus where
= gfc_current_locus
;
2047 if (gfc_match_omp_clauses (&c
, OACC_DECLARE_CLAUSES
, false, false, true)
2051 for (n
= c
->lists
[OMP_LIST_DEVICE_RESIDENT
]; n
!= NULL
; n
= n
->next
)
2052 n
->sym
->attr
.oacc_declare_device_resident
= 1;
2054 for (n
= c
->lists
[OMP_LIST_LINK
]; n
!= NULL
; n
= n
->next
)
2055 n
->sym
->attr
.oacc_declare_link
= 1;
2057 for (n
= c
->lists
[OMP_LIST_MAP
]; n
!= NULL
; n
= n
->next
)
2059 gfc_symbol
*s
= n
->sym
;
2061 if (s
->ns
->proc_name
&& s
->ns
->proc_name
->attr
.proc
== PROC_MODULE
)
2063 if (n
->u
.map_op
!= OMP_MAP_ALLOC
&& n
->u
.map_op
!= OMP_MAP_TO
)
2065 gfc_error ("Invalid clause in module with !$ACC DECLARE at %L",
2073 if (ns
->proc_name
->attr
.oacc_function
)
2075 gfc_error ("Invalid declare in routine with $!ACC DECLARE at %L",
2080 if (s
->attr
.use_assoc
)
2082 gfc_error ("Variable is USE-associated with !$ACC DECLARE at %L",
2087 if ((s
->attr
.dimension
|| s
->attr
.codimension
)
2088 && s
->attr
.dummy
&& s
->as
->type
!= AS_EXPLICIT
)
2090 gfc_error ("Assumed-size dummy array with !$ACC DECLARE at %L",
2095 switch (n
->u
.map_op
)
2097 case OMP_MAP_FORCE_ALLOC
:
2099 s
->attr
.oacc_declare_create
= 1;
2102 case OMP_MAP_FORCE_TO
:
2104 s
->attr
.oacc_declare_copyin
= 1;
2107 case OMP_MAP_FORCE_DEVICEPTR
:
2108 s
->attr
.oacc_declare_deviceptr
= 1;
2116 new_oc
= gfc_get_oacc_declare ();
2117 new_oc
->next
= ns
->oacc_declare
;
2118 new_oc
->module_var
= module_var
;
2119 new_oc
->clauses
= c
;
2120 new_oc
->loc
= gfc_current_locus
;
2121 ns
->oacc_declare
= new_oc
;
2128 gfc_match_oacc_update (void)
2131 locus here
= gfc_current_locus
;
2133 if (gfc_match_omp_clauses (&c
, OACC_UPDATE_CLAUSES
, false, false, true)
2137 if (!c
->lists
[OMP_LIST_MAP
])
2139 gfc_error ("%<acc update%> must contain at least one "
2140 "%<device%> or %<host%> or %<self%> clause at %L", &here
);
2144 new_st
.op
= EXEC_OACC_UPDATE
;
2145 new_st
.ext
.omp_clauses
= c
;
2151 gfc_match_oacc_enter_data (void)
2153 return match_acc (EXEC_OACC_ENTER_DATA
, OACC_ENTER_DATA_CLAUSES
);
2158 gfc_match_oacc_exit_data (void)
2160 return match_acc (EXEC_OACC_EXIT_DATA
, OACC_EXIT_DATA_CLAUSES
);
2165 gfc_match_oacc_wait (void)
2167 gfc_omp_clauses
*c
= gfc_get_omp_clauses ();
2168 gfc_expr_list
*wait_list
= NULL
, *el
;
2172 m
= match_oacc_expr_list (" (", &wait_list
, true);
2173 if (m
== MATCH_ERROR
)
2175 else if (m
== MATCH_YES
)
2178 if (gfc_match_omp_clauses (&c
, OACC_WAIT_CLAUSES
, space
, space
, true)
2183 for (el
= wait_list
; el
; el
= el
->next
)
2185 if (el
->expr
== NULL
)
2187 gfc_error ("Invalid argument to !$ACC WAIT at %C");
2191 if (!gfc_resolve_expr (el
->expr
)
2192 || el
->expr
->ts
.type
!= BT_INTEGER
|| el
->expr
->rank
!= 0)
2194 gfc_error ("WAIT clause at %L requires a scalar INTEGER expression",
2200 c
->wait_list
= wait_list
;
2201 new_st
.op
= EXEC_OACC_WAIT
;
2202 new_st
.ext
.omp_clauses
= c
;
2208 gfc_match_oacc_cache (void)
2210 gfc_omp_clauses
*c
= gfc_get_omp_clauses ();
2211 /* The OpenACC cache directive explicitly only allows "array elements or
2212 subarrays", which we're currently not checking here. Either check this
2213 after the call of gfc_match_omp_variable_list, or add something like a
2214 only_sections variant next to its allow_sections parameter. */
2215 match m
= gfc_match_omp_variable_list (" (",
2216 &c
->lists
[OMP_LIST_CACHE
], true,
2220 gfc_free_omp_clauses(c
);
2224 if (gfc_current_state() != COMP_DO
2225 && gfc_current_state() != COMP_DO_CONCURRENT
)
2227 gfc_error ("ACC CACHE directive must be inside of loop %C");
2228 gfc_free_omp_clauses(c
);
2232 new_st
.op
= EXEC_OACC_CACHE
;
2233 new_st
.ext
.omp_clauses
= c
;
2237 /* Determine the loop level for a routine. */
2240 gfc_oacc_routine_dims (gfc_omp_clauses
*clauses
)
2249 level
= GOMP_DIM_GANG
, mask
|= GOMP_DIM_MASK (level
);
2250 if (clauses
->worker
)
2251 level
= GOMP_DIM_WORKER
, mask
|= GOMP_DIM_MASK (level
);
2252 if (clauses
->vector
)
2253 level
= GOMP_DIM_VECTOR
, mask
|= GOMP_DIM_MASK (level
);
2255 level
= GOMP_DIM_MAX
, mask
|= GOMP_DIM_MASK (level
);
2257 if (mask
!= (mask
& -mask
))
2258 gfc_error ("Multiple loop axes specified for routine");
2262 level
= GOMP_DIM_MAX
;
2268 gfc_match_oacc_routine (void)
2271 gfc_symbol
*sym
= NULL
;
2273 gfc_omp_clauses
*c
= NULL
;
2274 gfc_oacc_routine_name
*n
= NULL
;
2276 old_loc
= gfc_current_locus
;
2278 m
= gfc_match (" (");
2280 if (gfc_current_ns
->proc_name
2281 && gfc_current_ns
->proc_name
->attr
.if_source
== IFSRC_IFBODY
2284 gfc_error ("Only the !$ACC ROUTINE form without "
2285 "list is allowed in interface block at %C");
2291 char buffer
[GFC_MAX_SYMBOL_LEN
+ 1];
2294 m
= gfc_match_name (buffer
);
2297 st
= gfc_find_symtree (gfc_current_ns
->sym_root
, buffer
);
2301 if (gfc_current_ns
->proc_name
!= NULL
2302 && strcmp (sym
->name
, gfc_current_ns
->proc_name
->name
) == 0)
2308 && !sym
->attr
.external
2309 && !sym
->attr
.function
2310 && !sym
->attr
.subroutine
))
2312 gfc_error ("Syntax error in !$ACC ROUTINE ( NAME ) at %C, "
2313 "invalid function name %s",
2314 (sym
) ? sym
->name
: buffer
);
2315 gfc_current_locus
= old_loc
;
2321 gfc_error ("Syntax error in !$ACC ROUTINE ( NAME ) at %C");
2322 gfc_current_locus
= old_loc
;
2326 if (gfc_match_char (')') != MATCH_YES
)
2328 gfc_error ("Syntax error in !$ACC ROUTINE ( NAME ) at %C, expecting"
2330 gfc_current_locus
= old_loc
;
2335 if (gfc_match_omp_eos () != MATCH_YES
2336 && (gfc_match_omp_clauses (&c
, OACC_ROUTINE_CLAUSES
, false, false, true)
2342 n
= gfc_get_oacc_routine_name ();
2346 if (gfc_current_ns
->oacc_routine_names
!= NULL
)
2347 n
->next
= gfc_current_ns
->oacc_routine_names
;
2349 gfc_current_ns
->oacc_routine_names
= n
;
2351 else if (gfc_current_ns
->proc_name
)
2353 if (!gfc_add_omp_declare_target (&gfc_current_ns
->proc_name
->attr
,
2354 gfc_current_ns
->proc_name
->name
,
2357 gfc_current_ns
->proc_name
->attr
.oacc_function
2358 = gfc_oacc_routine_dims (c
) + 1;
2363 else if (gfc_current_ns
->oacc_routine
)
2364 gfc_current_ns
->oacc_routine_clauses
= c
;
2366 new_st
.op
= EXEC_OACC_ROUTINE
;
2367 new_st
.ext
.omp_clauses
= c
;
2371 gfc_current_locus
= old_loc
;
2376 #define OMP_PARALLEL_CLAUSES \
2377 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \
2378 | OMP_CLAUSE_SHARED | OMP_CLAUSE_COPYIN | OMP_CLAUSE_REDUCTION \
2379 | OMP_CLAUSE_IF | OMP_CLAUSE_NUM_THREADS | OMP_CLAUSE_DEFAULT \
2380 | OMP_CLAUSE_PROC_BIND)
2381 #define OMP_DECLARE_SIMD_CLAUSES \
2382 (omp_mask (OMP_CLAUSE_SIMDLEN) | OMP_CLAUSE_LINEAR \
2383 | OMP_CLAUSE_UNIFORM | OMP_CLAUSE_ALIGNED | OMP_CLAUSE_INBRANCH \
2384 | OMP_CLAUSE_NOTINBRANCH)
2385 #define OMP_DO_CLAUSES \
2386 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \
2387 | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION \
2388 | OMP_CLAUSE_SCHEDULE | OMP_CLAUSE_ORDERED | OMP_CLAUSE_COLLAPSE \
2389 | OMP_CLAUSE_LINEAR)
2390 #define OMP_SECTIONS_CLAUSES \
2391 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \
2392 | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION)
2393 #define OMP_SIMD_CLAUSES \
2394 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_LASTPRIVATE \
2395 | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_SAFELEN \
2396 | OMP_CLAUSE_LINEAR | OMP_CLAUSE_ALIGNED | OMP_CLAUSE_SIMDLEN)
2397 #define OMP_TASK_CLAUSES \
2398 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \
2399 | OMP_CLAUSE_SHARED | OMP_CLAUSE_IF | OMP_CLAUSE_DEFAULT \
2400 | OMP_CLAUSE_UNTIED | OMP_CLAUSE_FINAL | OMP_CLAUSE_MERGEABLE \
2401 | OMP_CLAUSE_DEPEND | OMP_CLAUSE_PRIORITY)
2402 #define OMP_TASKLOOP_CLAUSES \
2403 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \
2404 | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_SHARED | OMP_CLAUSE_IF \
2405 | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_UNTIED | OMP_CLAUSE_FINAL \
2406 | OMP_CLAUSE_MERGEABLE | OMP_CLAUSE_PRIORITY | OMP_CLAUSE_GRAINSIZE \
2407 | OMP_CLAUSE_NUM_TASKS | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_NOGROUP)
2408 #define OMP_TARGET_CLAUSES \
2409 (omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF \
2410 | OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT | OMP_CLAUSE_PRIVATE \
2411 | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_DEFAULTMAP \
2412 | OMP_CLAUSE_IS_DEVICE_PTR)
2413 #define OMP_TARGET_DATA_CLAUSES \
2414 (omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF \
2415 | OMP_CLAUSE_USE_DEVICE_PTR)
2416 #define OMP_TARGET_ENTER_DATA_CLAUSES \
2417 (omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF \
2418 | OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT)
2419 #define OMP_TARGET_EXIT_DATA_CLAUSES \
2420 (omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF \
2421 | OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT)
2422 #define OMP_TARGET_UPDATE_CLAUSES \
2423 (omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_IF | OMP_CLAUSE_TO \
2424 | OMP_CLAUSE_FROM | OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT)
2425 #define OMP_TEAMS_CLAUSES \
2426 (omp_mask (OMP_CLAUSE_NUM_TEAMS) | OMP_CLAUSE_THREAD_LIMIT \
2427 | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE \
2428 | OMP_CLAUSE_SHARED | OMP_CLAUSE_REDUCTION)
2429 #define OMP_DISTRIBUTE_CLAUSES \
2430 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \
2431 | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_DIST_SCHEDULE)
2432 #define OMP_SINGLE_CLAUSES \
2433 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE)
2434 #define OMP_ORDERED_CLAUSES \
2435 (omp_mask (OMP_CLAUSE_THREADS) | OMP_CLAUSE_SIMD)
2436 #define OMP_DECLARE_TARGET_CLAUSES \
2437 (omp_mask (OMP_CLAUSE_TO) | OMP_CLAUSE_LINK)
2441 match_omp (gfc_exec_op op
, const omp_mask mask
)
2444 if (gfc_match_omp_clauses (&c
, mask
) != MATCH_YES
)
2447 new_st
.ext
.omp_clauses
= c
;
2453 gfc_match_omp_critical (void)
2455 char n
[GFC_MAX_SYMBOL_LEN
+1];
2456 gfc_omp_clauses
*c
= NULL
;
2458 if (gfc_match (" ( %n )", n
) != MATCH_YES
)
2461 if (gfc_match_omp_eos () != MATCH_YES
)
2463 gfc_error ("Unexpected junk after $OMP CRITICAL statement at %C");
2467 else if (gfc_match_omp_clauses (&c
, omp_mask (OMP_CLAUSE_HINT
)) != MATCH_YES
)
2470 new_st
.op
= EXEC_OMP_CRITICAL
;
2471 new_st
.ext
.omp_clauses
= c
;
2473 c
->critical_name
= xstrdup (n
);
2479 gfc_match_omp_end_critical (void)
2481 char n
[GFC_MAX_SYMBOL_LEN
+1];
2483 if (gfc_match (" ( %n )", n
) != MATCH_YES
)
2485 if (gfc_match_omp_eos () != MATCH_YES
)
2487 gfc_error ("Unexpected junk after $OMP CRITICAL statement at %C");
2491 new_st
.op
= EXEC_OMP_END_CRITICAL
;
2492 new_st
.ext
.omp_name
= n
[0] ? xstrdup (n
) : NULL
;
2498 gfc_match_omp_distribute (void)
2500 return match_omp (EXEC_OMP_DISTRIBUTE
, OMP_DISTRIBUTE_CLAUSES
);
2505 gfc_match_omp_distribute_parallel_do (void)
2507 return match_omp (EXEC_OMP_DISTRIBUTE_PARALLEL_DO
,
2508 (OMP_DISTRIBUTE_CLAUSES
| OMP_PARALLEL_CLAUSES
2510 & ~(omp_mask (OMP_CLAUSE_ORDERED
))
2511 & ~(omp_mask (OMP_CLAUSE_LINEAR
)));
2516 gfc_match_omp_distribute_parallel_do_simd (void)
2518 return match_omp (EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD
,
2519 (OMP_DISTRIBUTE_CLAUSES
| OMP_PARALLEL_CLAUSES
2520 | OMP_DO_CLAUSES
| OMP_SIMD_CLAUSES
)
2521 & ~(omp_mask (OMP_CLAUSE_ORDERED
)));
2526 gfc_match_omp_distribute_simd (void)
2528 return match_omp (EXEC_OMP_DISTRIBUTE_SIMD
,
2529 OMP_DISTRIBUTE_CLAUSES
| OMP_SIMD_CLAUSES
);
2534 gfc_match_omp_do (void)
2536 return match_omp (EXEC_OMP_DO
, OMP_DO_CLAUSES
);
2541 gfc_match_omp_do_simd (void)
2543 return match_omp (EXEC_OMP_DO_SIMD
, OMP_DO_CLAUSES
| OMP_SIMD_CLAUSES
);
2548 gfc_match_omp_flush (void)
2550 gfc_omp_namelist
*list
= NULL
;
2551 gfc_match_omp_variable_list (" (", &list
, true);
2552 if (gfc_match_omp_eos () != MATCH_YES
)
2554 gfc_error ("Unexpected junk after $OMP FLUSH statement at %C");
2555 gfc_free_omp_namelist (list
);
2558 new_st
.op
= EXEC_OMP_FLUSH
;
2559 new_st
.ext
.omp_namelist
= list
;
2565 gfc_match_omp_declare_simd (void)
2567 locus where
= gfc_current_locus
;
2568 gfc_symbol
*proc_name
;
2570 gfc_omp_declare_simd
*ods
;
2571 bool needs_space
= false;
2573 switch (gfc_match (" ( %s ) ", &proc_name
))
2575 case MATCH_YES
: break;
2576 case MATCH_NO
: proc_name
= NULL
; needs_space
= true; break;
2577 case MATCH_ERROR
: return MATCH_ERROR
;
2580 if (gfc_match_omp_clauses (&c
, OMP_DECLARE_SIMD_CLAUSES
, true,
2581 needs_space
) != MATCH_YES
)
2584 if (gfc_current_ns
->is_block_data
)
2586 gfc_free_omp_clauses (c
);
2590 ods
= gfc_get_omp_declare_simd ();
2592 ods
->proc_name
= proc_name
;
2594 ods
->next
= gfc_current_ns
->omp_declare_simd
;
2595 gfc_current_ns
->omp_declare_simd
= ods
;
2601 match_udr_expr (gfc_symtree
*omp_sym1
, gfc_symtree
*omp_sym2
)
2604 locus old_loc
= gfc_current_locus
;
2605 char sname
[GFC_MAX_SYMBOL_LEN
+ 1];
2607 gfc_namespace
*ns
= gfc_current_ns
;
2608 gfc_expr
*lvalue
= NULL
, *rvalue
= NULL
;
2610 gfc_actual_arglist
*arglist
;
2612 m
= gfc_match (" %v =", &lvalue
);
2614 gfc_current_locus
= old_loc
;
2617 m
= gfc_match (" %e )", &rvalue
);
2620 ns
->code
= gfc_get_code (EXEC_ASSIGN
);
2621 ns
->code
->expr1
= lvalue
;
2622 ns
->code
->expr2
= rvalue
;
2623 ns
->code
->loc
= old_loc
;
2627 gfc_current_locus
= old_loc
;
2628 gfc_free_expr (lvalue
);
2631 m
= gfc_match (" %n", sname
);
2635 if (strcmp (sname
, omp_sym1
->name
) == 0
2636 || strcmp (sname
, omp_sym2
->name
) == 0)
2639 gfc_current_ns
= ns
->parent
;
2640 if (gfc_get_ha_sym_tree (sname
, &st
))
2644 if (sym
->attr
.flavor
!= FL_PROCEDURE
2645 && sym
->attr
.flavor
!= FL_UNKNOWN
)
2648 if (!sym
->attr
.generic
2649 && !sym
->attr
.subroutine
2650 && !sym
->attr
.function
)
2652 if (!(sym
->attr
.external
&& !sym
->attr
.referenced
))
2654 /* ...create a symbol in this scope... */
2655 if (sym
->ns
!= gfc_current_ns
2656 && gfc_get_sym_tree (sname
, NULL
, &st
, false) == 1)
2659 if (sym
!= st
->n
.sym
)
2663 /* ...and then to try to make the symbol into a subroutine. */
2664 if (!gfc_add_subroutine (&sym
->attr
, sym
->name
, NULL
))
2668 gfc_set_sym_referenced (sym
);
2669 gfc_gobble_whitespace ();
2670 if (gfc_peek_ascii_char () != '(')
2673 gfc_current_ns
= ns
;
2674 m
= gfc_match_actual_arglist (1, &arglist
);
2678 if (gfc_match_char (')') != MATCH_YES
)
2681 ns
->code
= gfc_get_code (EXEC_CALL
);
2682 ns
->code
->symtree
= st
;
2683 ns
->code
->ext
.actual
= arglist
;
2684 ns
->code
->loc
= old_loc
;
2689 gfc_omp_udr_predef (gfc_omp_reduction_op rop
, const char *name
,
2690 gfc_typespec
*ts
, const char **n
)
2692 if (!gfc_numeric_ts (ts
) && ts
->type
!= BT_LOGICAL
)
2697 case OMP_REDUCTION_PLUS
:
2698 case OMP_REDUCTION_MINUS
:
2699 case OMP_REDUCTION_TIMES
:
2700 return ts
->type
!= BT_LOGICAL
;
2701 case OMP_REDUCTION_AND
:
2702 case OMP_REDUCTION_OR
:
2703 case OMP_REDUCTION_EQV
:
2704 case OMP_REDUCTION_NEQV
:
2705 return ts
->type
== BT_LOGICAL
;
2706 case OMP_REDUCTION_USER
:
2707 if (name
[0] != '.' && (ts
->type
== BT_INTEGER
|| ts
->type
== BT_REAL
))
2711 gfc_find_symbol (name
, NULL
, 1, &sym
);
2714 if (sym
->attr
.intrinsic
)
2716 else if ((sym
->attr
.flavor
!= FL_UNKNOWN
2717 && sym
->attr
.flavor
!= FL_PROCEDURE
)
2718 || sym
->attr
.external
2719 || sym
->attr
.generic
2723 || sym
->attr
.subroutine
2724 || sym
->attr
.pointer
2726 || sym
->attr
.cray_pointer
2727 || sym
->attr
.cray_pointee
2728 || (sym
->attr
.proc
!= PROC_UNKNOWN
2729 && sym
->attr
.proc
!= PROC_INTRINSIC
)
2730 || sym
->attr
.if_source
!= IFSRC_UNKNOWN
2731 || sym
== sym
->ns
->proc_name
)
2739 && (strcmp (*n
, "max") == 0 || strcmp (*n
, "min") == 0))
2742 && ts
->type
== BT_INTEGER
2743 && (strcmp (*n
, "iand") == 0
2744 || strcmp (*n
, "ior") == 0
2745 || strcmp (*n
, "ieor") == 0))
2756 gfc_omp_udr_find (gfc_symtree
*st
, gfc_typespec
*ts
)
2758 gfc_omp_udr
*omp_udr
;
2763 for (omp_udr
= st
->n
.omp_udr
; omp_udr
; omp_udr
= omp_udr
->next
)
2764 if (omp_udr
->ts
.type
== ts
->type
2765 || ((omp_udr
->ts
.type
== BT_DERIVED
|| omp_udr
->ts
.type
== BT_CLASS
)
2766 && (ts
->type
== BT_DERIVED
|| ts
->type
== BT_CLASS
)))
2768 if (omp_udr
->ts
.type
== BT_DERIVED
|| omp_udr
->ts
.type
== BT_CLASS
)
2770 if (strcmp (omp_udr
->ts
.u
.derived
->name
, ts
->u
.derived
->name
) == 0)
2773 else if (omp_udr
->ts
.kind
== ts
->kind
)
2775 if (omp_udr
->ts
.type
== BT_CHARACTER
)
2777 if (omp_udr
->ts
.u
.cl
->length
== NULL
2778 || ts
->u
.cl
->length
== NULL
)
2780 if (omp_udr
->ts
.u
.cl
->length
->expr_type
!= EXPR_CONSTANT
)
2782 if (ts
->u
.cl
->length
->expr_type
!= EXPR_CONSTANT
)
2784 if (omp_udr
->ts
.u
.cl
->length
->ts
.type
!= BT_INTEGER
)
2786 if (ts
->u
.cl
->length
->ts
.type
!= BT_INTEGER
)
2788 if (gfc_compare_expr (omp_udr
->ts
.u
.cl
->length
,
2789 ts
->u
.cl
->length
, INTRINSIC_EQ
) != 0)
2799 gfc_match_omp_declare_reduction (void)
2802 gfc_intrinsic_op op
;
2803 char name
[GFC_MAX_SYMBOL_LEN
+ 3];
2804 auto_vec
<gfc_typespec
, 5> tss
;
2808 locus where
= gfc_current_locus
;
2809 locus end_loc
= gfc_current_locus
;
2810 bool end_loc_set
= false;
2811 gfc_omp_reduction_op rop
= OMP_REDUCTION_NONE
;
2813 if (gfc_match_char ('(') != MATCH_YES
)
2816 m
= gfc_match (" %o : ", &op
);
2817 if (m
== MATCH_ERROR
)
2821 snprintf (name
, sizeof name
, "operator %s", gfc_op2string (op
));
2822 rop
= (gfc_omp_reduction_op
) op
;
2826 m
= gfc_match_defined_op_name (name
+ 1, 1);
2827 if (m
== MATCH_ERROR
)
2833 if (gfc_match (" : ") != MATCH_YES
)
2838 if (gfc_match (" %n : ", name
) != MATCH_YES
)
2841 rop
= OMP_REDUCTION_USER
;
2844 m
= gfc_match_type_spec (&ts
);
2847 /* Treat len=: the same as len=*. */
2848 if (ts
.type
== BT_CHARACTER
)
2849 ts
.deferred
= false;
2852 while (gfc_match_char (',') == MATCH_YES
)
2854 m
= gfc_match_type_spec (&ts
);
2859 if (gfc_match_char (':') != MATCH_YES
)
2862 st
= gfc_find_symtree (gfc_current_ns
->omp_udr_root
, name
);
2863 for (i
= 0; i
< tss
.length (); i
++)
2865 gfc_symtree
*omp_out
, *omp_in
;
2866 gfc_symtree
*omp_priv
= NULL
, *omp_orig
= NULL
;
2867 gfc_namespace
*combiner_ns
, *initializer_ns
= NULL
;
2868 gfc_omp_udr
*prev_udr
, *omp_udr
;
2869 const char *predef_name
= NULL
;
2871 omp_udr
= gfc_get_omp_udr ();
2872 omp_udr
->name
= gfc_get_string ("%s", name
);
2874 omp_udr
->ts
= tss
[i
];
2875 omp_udr
->where
= where
;
2877 gfc_current_ns
= combiner_ns
= gfc_get_namespace (gfc_current_ns
, 1);
2878 combiner_ns
->proc_name
= combiner_ns
->parent
->proc_name
;
2880 gfc_get_sym_tree ("omp_out", combiner_ns
, &omp_out
, false);
2881 gfc_get_sym_tree ("omp_in", combiner_ns
, &omp_in
, false);
2882 combiner_ns
->omp_udr_ns
= 1;
2883 omp_out
->n
.sym
->ts
= tss
[i
];
2884 omp_in
->n
.sym
->ts
= tss
[i
];
2885 omp_out
->n
.sym
->attr
.omp_udr_artificial_var
= 1;
2886 omp_in
->n
.sym
->attr
.omp_udr_artificial_var
= 1;
2887 omp_out
->n
.sym
->attr
.flavor
= FL_VARIABLE
;
2888 omp_in
->n
.sym
->attr
.flavor
= FL_VARIABLE
;
2889 gfc_commit_symbols ();
2890 omp_udr
->combiner_ns
= combiner_ns
;
2891 omp_udr
->omp_out
= omp_out
->n
.sym
;
2892 omp_udr
->omp_in
= omp_in
->n
.sym
;
2894 locus old_loc
= gfc_current_locus
;
2896 if (!match_udr_expr (omp_out
, omp_in
))
2899 gfc_current_locus
= old_loc
;
2900 gfc_current_ns
= combiner_ns
->parent
;
2901 gfc_undo_symbols ();
2902 gfc_free_omp_udr (omp_udr
);
2906 if (gfc_match (" initializer ( ") == MATCH_YES
)
2908 gfc_current_ns
= combiner_ns
->parent
;
2909 initializer_ns
= gfc_get_namespace (gfc_current_ns
, 1);
2910 gfc_current_ns
= initializer_ns
;
2911 initializer_ns
->proc_name
= initializer_ns
->parent
->proc_name
;
2913 gfc_get_sym_tree ("omp_priv", initializer_ns
, &omp_priv
, false);
2914 gfc_get_sym_tree ("omp_orig", initializer_ns
, &omp_orig
, false);
2915 initializer_ns
->omp_udr_ns
= 1;
2916 omp_priv
->n
.sym
->ts
= tss
[i
];
2917 omp_orig
->n
.sym
->ts
= tss
[i
];
2918 omp_priv
->n
.sym
->attr
.omp_udr_artificial_var
= 1;
2919 omp_orig
->n
.sym
->attr
.omp_udr_artificial_var
= 1;
2920 omp_priv
->n
.sym
->attr
.flavor
= FL_VARIABLE
;
2921 omp_orig
->n
.sym
->attr
.flavor
= FL_VARIABLE
;
2922 gfc_commit_symbols ();
2923 omp_udr
->initializer_ns
= initializer_ns
;
2924 omp_udr
->omp_priv
= omp_priv
->n
.sym
;
2925 omp_udr
->omp_orig
= omp_orig
->n
.sym
;
2927 if (!match_udr_expr (omp_priv
, omp_orig
))
2931 gfc_current_ns
= combiner_ns
->parent
;
2935 end_loc
= gfc_current_locus
;
2937 gfc_current_locus
= old_loc
;
2939 prev_udr
= gfc_omp_udr_find (st
, &tss
[i
]);
2940 if (gfc_omp_udr_predef (rop
, name
, &tss
[i
], &predef_name
)
2941 /* Don't error on !$omp declare reduction (min : integer : ...)
2942 just yet, there could be integer :: min afterwards,
2943 making it valid. When the UDR is resolved, we'll get
2945 && (rop
!= OMP_REDUCTION_USER
|| name
[0] == '.'))
2948 gfc_error_now ("Redefinition of predefined %s "
2949 "!$OMP DECLARE REDUCTION at %L",
2950 predef_name
, &where
);
2952 gfc_error_now ("Redefinition of predefined "
2953 "!$OMP DECLARE REDUCTION at %L", &where
);
2957 gfc_error_now ("Redefinition of !$OMP DECLARE REDUCTION at %L",
2959 gfc_error_now ("Previous !$OMP DECLARE REDUCTION at %L",
2964 omp_udr
->next
= st
->n
.omp_udr
;
2965 st
->n
.omp_udr
= omp_udr
;
2969 st
= gfc_new_symtree (&gfc_current_ns
->omp_udr_root
, name
);
2970 st
->n
.omp_udr
= omp_udr
;
2976 gfc_current_locus
= end_loc
;
2977 if (gfc_match_omp_eos () != MATCH_YES
)
2979 gfc_error ("Unexpected junk after !$OMP DECLARE REDUCTION at %C");
2980 gfc_current_locus
= where
;
2992 gfc_match_omp_declare_target (void)
2996 gfc_omp_clauses
*c
= NULL
;
2998 gfc_omp_namelist
*n
;
3001 old_loc
= gfc_current_locus
;
3003 if (gfc_current_ns
->proc_name
3004 && gfc_match_omp_eos () == MATCH_YES
)
3006 if (!gfc_add_omp_declare_target (&gfc_current_ns
->proc_name
->attr
,
3007 gfc_current_ns
->proc_name
->name
,
3013 if (gfc_current_ns
->proc_name
3014 && gfc_current_ns
->proc_name
->attr
.if_source
== IFSRC_IFBODY
)
3016 gfc_error ("Only the !$OMP DECLARE TARGET form without "
3017 "clauses is allowed in interface block at %C");
3021 m
= gfc_match (" (");
3024 c
= gfc_get_omp_clauses ();
3025 gfc_current_locus
= old_loc
;
3026 m
= gfc_match_omp_to_link (" (", &c
->lists
[OMP_LIST_TO
]);
3029 if (gfc_match_omp_eos () != MATCH_YES
)
3031 gfc_error ("Unexpected junk after !$OMP DECLARE TARGET at %C");
3035 else if (gfc_match_omp_clauses (&c
, OMP_DECLARE_TARGET_CLAUSES
) != MATCH_YES
)
3038 gfc_buffer_error (false);
3040 for (list
= OMP_LIST_TO
; list
!= OMP_LIST_NUM
;
3041 list
= (list
== OMP_LIST_TO
? OMP_LIST_LINK
: OMP_LIST_NUM
))
3042 for (n
= c
->lists
[list
]; n
; n
= n
->next
)
3045 else if (n
->u
.common
->head
)
3046 n
->u
.common
->head
->mark
= 0;
3048 for (list
= OMP_LIST_TO
; list
!= OMP_LIST_NUM
;
3049 list
= (list
== OMP_LIST_TO
? OMP_LIST_LINK
: OMP_LIST_NUM
))
3050 for (n
= c
->lists
[list
]; n
; n
= n
->next
)
3053 if (n
->sym
->attr
.in_common
)
3054 gfc_error_now ("OMP DECLARE TARGET variable at %L is an "
3055 "element of a COMMON block", &n
->where
);
3056 else if (n
->sym
->attr
.omp_declare_target
3057 && n
->sym
->attr
.omp_declare_target_link
3058 && list
!= OMP_LIST_LINK
)
3059 gfc_error_now ("OMP DECLARE TARGET variable at %L previously "
3060 "mentioned in LINK clause and later in TO clause",
3062 else if (n
->sym
->attr
.omp_declare_target
3063 && !n
->sym
->attr
.omp_declare_target_link
3064 && list
== OMP_LIST_LINK
)
3065 gfc_error_now ("OMP DECLARE TARGET variable at %L previously "
3066 "mentioned in TO clause and later in LINK clause",
3068 else if (n
->sym
->mark
)
3069 gfc_error_now ("Variable at %L mentioned multiple times in "
3070 "clauses of the same OMP DECLARE TARGET directive",
3072 else if (gfc_add_omp_declare_target (&n
->sym
->attr
, n
->sym
->name
,
3073 &n
->sym
->declared_at
))
3075 if (list
== OMP_LIST_LINK
)
3076 gfc_add_omp_declare_target_link (&n
->sym
->attr
, n
->sym
->name
,
3077 &n
->sym
->declared_at
);
3081 else if (n
->u
.common
->omp_declare_target
3082 && n
->u
.common
->omp_declare_target_link
3083 && list
!= OMP_LIST_LINK
)
3084 gfc_error_now ("OMP DECLARE TARGET COMMON at %L previously "
3085 "mentioned in LINK clause and later in TO clause",
3087 else if (n
->u
.common
->omp_declare_target
3088 && !n
->u
.common
->omp_declare_target_link
3089 && list
== OMP_LIST_LINK
)
3090 gfc_error_now ("OMP DECLARE TARGET COMMON at %L previously "
3091 "mentioned in TO clause and later in LINK clause",
3093 else if (n
->u
.common
->head
&& n
->u
.common
->head
->mark
)
3094 gfc_error_now ("COMMON at %L mentioned multiple times in "
3095 "clauses of the same OMP DECLARE TARGET directive",
3099 n
->u
.common
->omp_declare_target
= 1;
3100 n
->u
.common
->omp_declare_target_link
= (list
== OMP_LIST_LINK
);
3101 for (s
= n
->u
.common
->head
; s
; s
= s
->common_next
)
3104 if (gfc_add_omp_declare_target (&s
->attr
, s
->name
,
3107 if (list
== OMP_LIST_LINK
)
3108 gfc_add_omp_declare_target_link (&s
->attr
, s
->name
,
3114 gfc_buffer_error (true);
3117 gfc_free_omp_clauses (c
);
3121 gfc_error ("Syntax error in !$OMP DECLARE TARGET list at %C");
3124 gfc_current_locus
= old_loc
;
3126 gfc_free_omp_clauses (c
);
3132 gfc_match_omp_threadprivate (void)
3135 char n
[GFC_MAX_SYMBOL_LEN
+1];
3140 old_loc
= gfc_current_locus
;
3142 m
= gfc_match (" (");
3148 m
= gfc_match_symbol (&sym
, 0);
3152 if (sym
->attr
.in_common
)
3153 gfc_error_now ("Threadprivate variable at %C is an element of "
3155 else if (!gfc_add_threadprivate (&sym
->attr
, sym
->name
, &sym
->declared_at
))
3164 m
= gfc_match (" / %n /", n
);
3165 if (m
== MATCH_ERROR
)
3167 if (m
== MATCH_NO
|| n
[0] == '\0')
3170 st
= gfc_find_symtree (gfc_current_ns
->common_root
, n
);
3173 gfc_error ("COMMON block /%s/ not found at %C", n
);
3176 st
->n
.common
->threadprivate
= 1;
3177 for (sym
= st
->n
.common
->head
; sym
; sym
= sym
->common_next
)
3178 if (!gfc_add_threadprivate (&sym
->attr
, sym
->name
, &sym
->declared_at
))
3182 if (gfc_match_char (')') == MATCH_YES
)
3184 if (gfc_match_char (',') != MATCH_YES
)
3188 if (gfc_match_omp_eos () != MATCH_YES
)
3190 gfc_error ("Unexpected junk after OMP THREADPRIVATE at %C");
3197 gfc_error ("Syntax error in !$OMP THREADPRIVATE list at %C");
3200 gfc_current_locus
= old_loc
;
3206 gfc_match_omp_parallel (void)
3208 return match_omp (EXEC_OMP_PARALLEL
, OMP_PARALLEL_CLAUSES
);
3213 gfc_match_omp_parallel_do (void)
3215 return match_omp (EXEC_OMP_PARALLEL_DO
,
3216 OMP_PARALLEL_CLAUSES
| OMP_DO_CLAUSES
);
3221 gfc_match_omp_parallel_do_simd (void)
3223 return match_omp (EXEC_OMP_PARALLEL_DO_SIMD
,
3224 OMP_PARALLEL_CLAUSES
| OMP_DO_CLAUSES
| OMP_SIMD_CLAUSES
);
3229 gfc_match_omp_parallel_sections (void)
3231 return match_omp (EXEC_OMP_PARALLEL_SECTIONS
,
3232 OMP_PARALLEL_CLAUSES
| OMP_SECTIONS_CLAUSES
);
3237 gfc_match_omp_parallel_workshare (void)
3239 return match_omp (EXEC_OMP_PARALLEL_WORKSHARE
, OMP_PARALLEL_CLAUSES
);
3244 gfc_match_omp_sections (void)
3246 return match_omp (EXEC_OMP_SECTIONS
, OMP_SECTIONS_CLAUSES
);
3251 gfc_match_omp_simd (void)
3253 return match_omp (EXEC_OMP_SIMD
, OMP_SIMD_CLAUSES
);
3258 gfc_match_omp_single (void)
3260 return match_omp (EXEC_OMP_SINGLE
, OMP_SINGLE_CLAUSES
);
3265 gfc_match_omp_target (void)
3267 return match_omp (EXEC_OMP_TARGET
, OMP_TARGET_CLAUSES
);
3272 gfc_match_omp_target_data (void)
3274 return match_omp (EXEC_OMP_TARGET_DATA
, OMP_TARGET_DATA_CLAUSES
);
3279 gfc_match_omp_target_enter_data (void)
3281 return match_omp (EXEC_OMP_TARGET_ENTER_DATA
, OMP_TARGET_ENTER_DATA_CLAUSES
);
3286 gfc_match_omp_target_exit_data (void)
3288 return match_omp (EXEC_OMP_TARGET_EXIT_DATA
, OMP_TARGET_EXIT_DATA_CLAUSES
);
3293 gfc_match_omp_target_parallel (void)
3295 return match_omp (EXEC_OMP_TARGET_PARALLEL
,
3296 (OMP_TARGET_CLAUSES
| OMP_PARALLEL_CLAUSES
)
3297 & ~(omp_mask (OMP_CLAUSE_COPYIN
)));
3302 gfc_match_omp_target_parallel_do (void)
3304 return match_omp (EXEC_OMP_TARGET_PARALLEL_DO
,
3305 (OMP_TARGET_CLAUSES
| OMP_PARALLEL_CLAUSES
3306 | OMP_DO_CLAUSES
) & ~(omp_mask (OMP_CLAUSE_COPYIN
)));
3311 gfc_match_omp_target_parallel_do_simd (void)
3313 return match_omp (EXEC_OMP_TARGET_PARALLEL_DO_SIMD
,
3314 (OMP_TARGET_CLAUSES
| OMP_PARALLEL_CLAUSES
| OMP_DO_CLAUSES
3315 | OMP_SIMD_CLAUSES
) & ~(omp_mask (OMP_CLAUSE_COPYIN
)));
3320 gfc_match_omp_target_simd (void)
3322 return match_omp (EXEC_OMP_TARGET_SIMD
,
3323 OMP_TARGET_CLAUSES
| OMP_SIMD_CLAUSES
);
3328 gfc_match_omp_target_teams (void)
3330 return match_omp (EXEC_OMP_TARGET_TEAMS
,
3331 OMP_TARGET_CLAUSES
| OMP_TEAMS_CLAUSES
);
3336 gfc_match_omp_target_teams_distribute (void)
3338 return match_omp (EXEC_OMP_TARGET_TEAMS_DISTRIBUTE
,
3339 OMP_TARGET_CLAUSES
| OMP_TEAMS_CLAUSES
3340 | OMP_DISTRIBUTE_CLAUSES
);
3345 gfc_match_omp_target_teams_distribute_parallel_do (void)
3347 return match_omp (EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO
,
3348 (OMP_TARGET_CLAUSES
| OMP_TEAMS_CLAUSES
3349 | OMP_DISTRIBUTE_CLAUSES
| OMP_PARALLEL_CLAUSES
3351 & ~(omp_mask (OMP_CLAUSE_ORDERED
))
3352 & ~(omp_mask (OMP_CLAUSE_LINEAR
)));
3357 gfc_match_omp_target_teams_distribute_parallel_do_simd (void)
3359 return match_omp (EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
,
3360 (OMP_TARGET_CLAUSES
| OMP_TEAMS_CLAUSES
3361 | OMP_DISTRIBUTE_CLAUSES
| OMP_PARALLEL_CLAUSES
3362 | OMP_DO_CLAUSES
| OMP_SIMD_CLAUSES
)
3363 & ~(omp_mask (OMP_CLAUSE_ORDERED
)));
3368 gfc_match_omp_target_teams_distribute_simd (void)
3370 return match_omp (EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD
,
3371 OMP_TARGET_CLAUSES
| OMP_TEAMS_CLAUSES
3372 | OMP_DISTRIBUTE_CLAUSES
| OMP_SIMD_CLAUSES
);
3377 gfc_match_omp_target_update (void)
3379 return match_omp (EXEC_OMP_TARGET_UPDATE
, OMP_TARGET_UPDATE_CLAUSES
);
3384 gfc_match_omp_task (void)
3386 return match_omp (EXEC_OMP_TASK
, OMP_TASK_CLAUSES
);
3391 gfc_match_omp_taskloop (void)
3393 return match_omp (EXEC_OMP_TASKLOOP
, OMP_TASKLOOP_CLAUSES
);
3398 gfc_match_omp_taskloop_simd (void)
3400 return match_omp (EXEC_OMP_TASKLOOP_SIMD
,
3401 (OMP_TASKLOOP_CLAUSES
| OMP_SIMD_CLAUSES
)
3402 & ~(omp_mask (OMP_CLAUSE_REDUCTION
)));
3407 gfc_match_omp_taskwait (void)
3409 if (gfc_match_omp_eos () != MATCH_YES
)
3411 gfc_error ("Unexpected junk after TASKWAIT clause at %C");
3414 new_st
.op
= EXEC_OMP_TASKWAIT
;
3415 new_st
.ext
.omp_clauses
= NULL
;
3421 gfc_match_omp_taskyield (void)
3423 if (gfc_match_omp_eos () != MATCH_YES
)
3425 gfc_error ("Unexpected junk after TASKYIELD clause at %C");
3428 new_st
.op
= EXEC_OMP_TASKYIELD
;
3429 new_st
.ext
.omp_clauses
= NULL
;
3435 gfc_match_omp_teams (void)
3437 return match_omp (EXEC_OMP_TEAMS
, OMP_TEAMS_CLAUSES
);
3442 gfc_match_omp_teams_distribute (void)
3444 return match_omp (EXEC_OMP_TEAMS_DISTRIBUTE
,
3445 OMP_TEAMS_CLAUSES
| OMP_DISTRIBUTE_CLAUSES
);
3450 gfc_match_omp_teams_distribute_parallel_do (void)
3452 return match_omp (EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO
,
3453 (OMP_TEAMS_CLAUSES
| OMP_DISTRIBUTE_CLAUSES
3454 | OMP_PARALLEL_CLAUSES
| OMP_DO_CLAUSES
)
3455 & ~(omp_mask (OMP_CLAUSE_ORDERED
))
3456 & ~(omp_mask (OMP_CLAUSE_LINEAR
)));
3461 gfc_match_omp_teams_distribute_parallel_do_simd (void)
3463 return match_omp (EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
,
3464 (OMP_TEAMS_CLAUSES
| OMP_DISTRIBUTE_CLAUSES
3465 | OMP_PARALLEL_CLAUSES
| OMP_DO_CLAUSES
3466 | OMP_SIMD_CLAUSES
) & ~(omp_mask (OMP_CLAUSE_ORDERED
)));
3471 gfc_match_omp_teams_distribute_simd (void)
3473 return match_omp (EXEC_OMP_TEAMS_DISTRIBUTE_SIMD
,
3474 OMP_TEAMS_CLAUSES
| OMP_DISTRIBUTE_CLAUSES
3475 | OMP_SIMD_CLAUSES
);
3480 gfc_match_omp_workshare (void)
3482 if (gfc_match_omp_eos () != MATCH_YES
)
3484 gfc_error ("Unexpected junk after $OMP WORKSHARE statement at %C");
3487 new_st
.op
= EXEC_OMP_WORKSHARE
;
3488 new_st
.ext
.omp_clauses
= gfc_get_omp_clauses ();
3494 gfc_match_omp_master (void)
3496 if (gfc_match_omp_eos () != MATCH_YES
)
3498 gfc_error ("Unexpected junk after $OMP MASTER statement at %C");
3501 new_st
.op
= EXEC_OMP_MASTER
;
3502 new_st
.ext
.omp_clauses
= NULL
;
3508 gfc_match_omp_ordered (void)
3510 return match_omp (EXEC_OMP_ORDERED
, OMP_ORDERED_CLAUSES
);
3515 gfc_match_omp_ordered_depend (void)
3517 return match_omp (EXEC_OMP_ORDERED
, omp_mask (OMP_CLAUSE_DEPEND
));
3522 gfc_match_omp_oacc_atomic (bool omp_p
)
3524 gfc_omp_atomic_op op
= GFC_OMP_ATOMIC_UPDATE
;
3526 if (gfc_match ("% seq_cst") == MATCH_YES
)
3528 locus old_loc
= gfc_current_locus
;
3529 if (seq_cst
&& gfc_match_char (',') == MATCH_YES
)
3532 || gfc_match_space () == MATCH_YES
)
3534 gfc_gobble_whitespace ();
3535 if (gfc_match ("update") == MATCH_YES
)
3536 op
= GFC_OMP_ATOMIC_UPDATE
;
3537 else if (gfc_match ("read") == MATCH_YES
)
3538 op
= GFC_OMP_ATOMIC_READ
;
3539 else if (gfc_match ("write") == MATCH_YES
)
3540 op
= GFC_OMP_ATOMIC_WRITE
;
3541 else if (gfc_match ("capture") == MATCH_YES
)
3542 op
= GFC_OMP_ATOMIC_CAPTURE
;
3546 gfc_current_locus
= old_loc
;
3550 && (gfc_match (", seq_cst") == MATCH_YES
3551 || gfc_match ("% seq_cst") == MATCH_YES
))
3555 if (gfc_match_omp_eos () != MATCH_YES
)
3557 gfc_error ("Unexpected junk after $OMP ATOMIC statement at %C");
3560 new_st
.op
= (omp_p
? EXEC_OMP_ATOMIC
: EXEC_OACC_ATOMIC
);
3562 op
= (gfc_omp_atomic_op
) (op
| GFC_OMP_ATOMIC_SEQ_CST
);
3563 new_st
.ext
.omp_atomic
= op
;
3568 gfc_match_oacc_atomic (void)
3570 return gfc_match_omp_oacc_atomic (false);
3574 gfc_match_omp_atomic (void)
3576 return gfc_match_omp_oacc_atomic (true);
3580 gfc_match_omp_barrier (void)
3582 if (gfc_match_omp_eos () != MATCH_YES
)
3584 gfc_error ("Unexpected junk after $OMP BARRIER statement at %C");
3587 new_st
.op
= EXEC_OMP_BARRIER
;
3588 new_st
.ext
.omp_clauses
= NULL
;
3594 gfc_match_omp_taskgroup (void)
3596 if (gfc_match_omp_eos () != MATCH_YES
)
3598 gfc_error ("Unexpected junk after $OMP TASKGROUP statement at %C");
3601 new_st
.op
= EXEC_OMP_TASKGROUP
;
3606 static enum gfc_omp_cancel_kind
3607 gfc_match_omp_cancel_kind (void)
3609 if (gfc_match_space () != MATCH_YES
)
3610 return OMP_CANCEL_UNKNOWN
;
3611 if (gfc_match ("parallel") == MATCH_YES
)
3612 return OMP_CANCEL_PARALLEL
;
3613 if (gfc_match ("sections") == MATCH_YES
)
3614 return OMP_CANCEL_SECTIONS
;
3615 if (gfc_match ("do") == MATCH_YES
)
3616 return OMP_CANCEL_DO
;
3617 if (gfc_match ("taskgroup") == MATCH_YES
)
3618 return OMP_CANCEL_TASKGROUP
;
3619 return OMP_CANCEL_UNKNOWN
;
3624 gfc_match_omp_cancel (void)
3627 enum gfc_omp_cancel_kind kind
= gfc_match_omp_cancel_kind ();
3628 if (kind
== OMP_CANCEL_UNKNOWN
)
3630 if (gfc_match_omp_clauses (&c
, omp_mask (OMP_CLAUSE_IF
), false) != MATCH_YES
)
3633 new_st
.op
= EXEC_OMP_CANCEL
;
3634 new_st
.ext
.omp_clauses
= c
;
3640 gfc_match_omp_cancellation_point (void)
3643 enum gfc_omp_cancel_kind kind
= gfc_match_omp_cancel_kind ();
3644 if (kind
== OMP_CANCEL_UNKNOWN
)
3646 if (gfc_match_omp_eos () != MATCH_YES
)
3648 gfc_error ("Unexpected junk after $OMP CANCELLATION POINT statement "
3652 c
= gfc_get_omp_clauses ();
3654 new_st
.op
= EXEC_OMP_CANCELLATION_POINT
;
3655 new_st
.ext
.omp_clauses
= c
;
3661 gfc_match_omp_end_nowait (void)
3663 bool nowait
= false;
3664 if (gfc_match ("% nowait") == MATCH_YES
)
3666 if (gfc_match_omp_eos () != MATCH_YES
)
3668 gfc_error ("Unexpected junk after NOWAIT clause at %C");
3671 new_st
.op
= EXEC_OMP_END_NOWAIT
;
3672 new_st
.ext
.omp_bool
= nowait
;
3678 gfc_match_omp_end_single (void)
3681 if (gfc_match ("% nowait") == MATCH_YES
)
3683 new_st
.op
= EXEC_OMP_END_NOWAIT
;
3684 new_st
.ext
.omp_bool
= true;
3687 if (gfc_match_omp_clauses (&c
, omp_mask (OMP_CLAUSE_COPYPRIVATE
))
3690 new_st
.op
= EXEC_OMP_END_SINGLE
;
3691 new_st
.ext
.omp_clauses
= c
;
3697 oacc_is_loop (gfc_code
*code
)
3699 return code
->op
== EXEC_OACC_PARALLEL_LOOP
3700 || code
->op
== EXEC_OACC_KERNELS_LOOP
3701 || code
->op
== EXEC_OACC_LOOP
;
3705 resolve_scalar_int_expr (gfc_expr
*expr
, const char *clause
)
3707 if (!gfc_resolve_expr (expr
)
3708 || expr
->ts
.type
!= BT_INTEGER
3710 gfc_error ("%s clause at %L requires a scalar INTEGER expression",
3711 clause
, &expr
->where
);
3715 resolve_positive_int_expr (gfc_expr
*expr
, const char *clause
)
3717 resolve_scalar_int_expr (expr
, clause
);
3718 if (expr
->expr_type
== EXPR_CONSTANT
3719 && expr
->ts
.type
== BT_INTEGER
3720 && mpz_sgn (expr
->value
.integer
) <= 0)
3721 gfc_warning (0, "INTEGER expression of %s clause at %L must be positive",
3722 clause
, &expr
->where
);
3726 resolve_nonnegative_int_expr (gfc_expr
*expr
, const char *clause
)
3728 resolve_scalar_int_expr (expr
, clause
);
3729 if (expr
->expr_type
== EXPR_CONSTANT
3730 && expr
->ts
.type
== BT_INTEGER
3731 && mpz_sgn (expr
->value
.integer
) < 0)
3732 gfc_warning (0, "INTEGER expression of %s clause at %L must be "
3733 "non-negative", clause
, &expr
->where
);
3736 /* Emits error when symbol is pointer, cray pointer or cray pointee
3737 of derived of polymorphic type. */
3740 check_symbol_not_pointer (gfc_symbol
*sym
, locus loc
, const char *name
)
3742 if (sym
->ts
.type
== BT_DERIVED
&& sym
->attr
.pointer
)
3743 gfc_error ("POINTER object %qs of derived type in %s clause at %L",
3744 sym
->name
, name
, &loc
);
3745 if (sym
->ts
.type
== BT_DERIVED
&& sym
->attr
.cray_pointer
)
3746 gfc_error ("Cray pointer object %qs of derived type in %s clause at %L",
3747 sym
->name
, name
, &loc
);
3748 if (sym
->ts
.type
== BT_DERIVED
&& sym
->attr
.cray_pointee
)
3749 gfc_error ("Cray pointee object %qs of derived type in %s clause at %L",
3750 sym
->name
, name
, &loc
);
3752 if ((sym
->ts
.type
== BT_ASSUMED
&& sym
->attr
.pointer
)
3753 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
3754 && CLASS_DATA (sym
)->attr
.pointer
))
3755 gfc_error ("POINTER object %qs of polymorphic type in %s clause at %L",
3756 sym
->name
, name
, &loc
);
3757 if ((sym
->ts
.type
== BT_ASSUMED
&& sym
->attr
.cray_pointer
)
3758 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
3759 && CLASS_DATA (sym
)->attr
.cray_pointer
))
3760 gfc_error ("Cray pointer object %qs of polymorphic type in %s clause at %L",
3761 sym
->name
, name
, &loc
);
3762 if ((sym
->ts
.type
== BT_ASSUMED
&& sym
->attr
.cray_pointee
)
3763 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
3764 && CLASS_DATA (sym
)->attr
.cray_pointee
))
3765 gfc_error ("Cray pointee object %qs of polymorphic type in %s clause at %L",
3766 sym
->name
, name
, &loc
);
3769 /* Emits error when symbol represents assumed size/rank array. */
3772 check_array_not_assumed (gfc_symbol
*sym
, locus loc
, const char *name
)
3774 if (sym
->as
&& sym
->as
->type
== AS_ASSUMED_SIZE
)
3775 gfc_error ("Assumed size array %qs in %s clause at %L",
3776 sym
->name
, name
, &loc
);
3777 if (sym
->as
&& sym
->as
->type
== AS_ASSUMED_RANK
)
3778 gfc_error ("Assumed rank array %qs in %s clause at %L",
3779 sym
->name
, name
, &loc
);
3780 if (sym
->as
&& sym
->as
->type
== AS_DEFERRED
&& sym
->attr
.pointer
3781 && !sym
->attr
.contiguous
)
3782 gfc_error ("Noncontiguous deferred shape array %qs in %s clause at %L",
3783 sym
->name
, name
, &loc
);
3787 resolve_oacc_data_clauses (gfc_symbol
*sym
, locus loc
, const char *name
)
3789 if (sym
->ts
.type
== BT_DERIVED
&& sym
->attr
.allocatable
)
3790 gfc_error ("ALLOCATABLE object %qs of derived type in %s clause at %L",
3791 sym
->name
, name
, &loc
);
3792 if ((sym
->ts
.type
== BT_ASSUMED
&& sym
->attr
.allocatable
)
3793 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
3794 && CLASS_DATA (sym
)->attr
.allocatable
))
3795 gfc_error ("ALLOCATABLE object %qs of polymorphic type "
3796 "in %s clause at %L", sym
->name
, name
, &loc
);
3797 check_symbol_not_pointer (sym
, loc
, name
);
3798 check_array_not_assumed (sym
, loc
, name
);
3802 resolve_oacc_deviceptr_clause (gfc_symbol
*sym
, locus loc
, const char *name
)
3804 if (sym
->attr
.pointer
3805 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
3806 && CLASS_DATA (sym
)->attr
.class_pointer
))
3807 gfc_error ("POINTER object %qs in %s clause at %L",
3808 sym
->name
, name
, &loc
);
3809 if (sym
->attr
.cray_pointer
3810 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
3811 && CLASS_DATA (sym
)->attr
.cray_pointer
))
3812 gfc_error ("Cray pointer object %qs in %s clause at %L",
3813 sym
->name
, name
, &loc
);
3814 if (sym
->attr
.cray_pointee
3815 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
3816 && CLASS_DATA (sym
)->attr
.cray_pointee
))
3817 gfc_error ("Cray pointee object %qs in %s clause at %L",
3818 sym
->name
, name
, &loc
);
3819 if (sym
->attr
.allocatable
3820 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
3821 && CLASS_DATA (sym
)->attr
.allocatable
))
3822 gfc_error ("ALLOCATABLE object %qs in %s clause at %L",
3823 sym
->name
, name
, &loc
);
3824 if (sym
->attr
.value
)
3825 gfc_error ("VALUE object %qs in %s clause at %L",
3826 sym
->name
, name
, &loc
);
3827 check_array_not_assumed (sym
, loc
, name
);
3831 struct resolve_omp_udr_callback_data
3833 gfc_symbol
*sym1
, *sym2
;
3838 resolve_omp_udr_callback (gfc_expr
**e
, int *, void *data
)
3840 struct resolve_omp_udr_callback_data
*rcd
3841 = (struct resolve_omp_udr_callback_data
*) data
;
3842 if ((*e
)->expr_type
== EXPR_VARIABLE
3843 && ((*e
)->symtree
->n
.sym
== rcd
->sym1
3844 || (*e
)->symtree
->n
.sym
== rcd
->sym2
))
3846 gfc_ref
*ref
= gfc_get_ref ();
3847 ref
->type
= REF_ARRAY
;
3848 ref
->u
.ar
.where
= (*e
)->where
;
3849 ref
->u
.ar
.as
= (*e
)->symtree
->n
.sym
->as
;
3850 ref
->u
.ar
.type
= AR_FULL
;
3851 ref
->u
.ar
.dimen
= 0;
3852 ref
->next
= (*e
)->ref
;
3860 resolve_omp_udr_callback2 (gfc_expr
**e
, int *, void *)
3862 if ((*e
)->expr_type
== EXPR_FUNCTION
3863 && (*e
)->value
.function
.isym
== NULL
)
3865 gfc_symbol
*sym
= (*e
)->symtree
->n
.sym
;
3866 if (!sym
->attr
.intrinsic
3867 && sym
->attr
.if_source
== IFSRC_UNKNOWN
)
3868 gfc_error ("Implicitly declared function %s used in "
3869 "!$OMP DECLARE REDUCTION at %L", sym
->name
, &(*e
)->where
);
3876 resolve_omp_udr_clause (gfc_omp_namelist
*n
, gfc_namespace
*ns
,
3877 gfc_symbol
*sym1
, gfc_symbol
*sym2
)
3880 gfc_symbol sym1_copy
, sym2_copy
;
3882 if (ns
->code
->op
== EXEC_ASSIGN
)
3884 copy
= gfc_get_code (EXEC_ASSIGN
);
3885 copy
->expr1
= gfc_copy_expr (ns
->code
->expr1
);
3886 copy
->expr2
= gfc_copy_expr (ns
->code
->expr2
);
3890 copy
= gfc_get_code (EXEC_CALL
);
3891 copy
->symtree
= ns
->code
->symtree
;
3892 copy
->ext
.actual
= gfc_copy_actual_arglist (ns
->code
->ext
.actual
);
3894 copy
->loc
= ns
->code
->loc
;
3899 sym1
->name
= sym1_copy
.name
;
3900 sym2
->name
= sym2_copy
.name
;
3901 ns
->proc_name
= ns
->parent
->proc_name
;
3902 if (n
->sym
->attr
.dimension
)
3904 struct resolve_omp_udr_callback_data rcd
;
3907 gfc_code_walker (©
, gfc_dummy_code_callback
,
3908 resolve_omp_udr_callback
, &rcd
);
3910 gfc_resolve_code (copy
, gfc_current_ns
);
3911 if (copy
->op
== EXEC_CALL
&& copy
->resolved_isym
== NULL
)
3913 gfc_symbol
*sym
= copy
->resolved_sym
;
3915 && !sym
->attr
.intrinsic
3916 && sym
->attr
.if_source
== IFSRC_UNKNOWN
)
3917 gfc_error ("Implicitly declared subroutine %s used in "
3918 "!$OMP DECLARE REDUCTION at %L", sym
->name
,
3921 gfc_code_walker (©
, gfc_dummy_code_callback
,
3922 resolve_omp_udr_callback2
, NULL
);
3928 /* OpenMP directive resolving routines. */
3931 resolve_omp_clauses (gfc_code
*code
, gfc_omp_clauses
*omp_clauses
,
3932 gfc_namespace
*ns
, bool openacc
= false)
3934 gfc_omp_namelist
*n
;
3938 bool if_without_mod
= false;
3939 gfc_omp_linear_op linear_op
= OMP_LINEAR_DEFAULT
;
3940 static const char *clause_names
[]
3941 = { "PRIVATE", "FIRSTPRIVATE", "LASTPRIVATE", "COPYPRIVATE", "SHARED",
3942 "COPYIN", "UNIFORM", "ALIGNED", "LINEAR", "DEPEND", "MAP",
3943 "TO", "FROM", "REDUCTION", "DEVICE_RESIDENT", "LINK", "USE_DEVICE",
3944 "CACHE", "IS_DEVICE_PTR", "USE_DEVICE_PTR" };
3946 if (omp_clauses
== NULL
)
3949 if (omp_clauses
->orderedc
&& omp_clauses
->orderedc
< omp_clauses
->collapse
)
3950 gfc_error ("ORDERED clause parameter is less than COLLAPSE at %L",
3953 if (omp_clauses
->if_expr
)
3955 gfc_expr
*expr
= omp_clauses
->if_expr
;
3956 if (!gfc_resolve_expr (expr
)
3957 || expr
->ts
.type
!= BT_LOGICAL
|| expr
->rank
!= 0)
3958 gfc_error ("IF clause at %L requires a scalar LOGICAL expression",
3960 if_without_mod
= true;
3962 for (ifc
= 0; ifc
< OMP_IF_LAST
; ifc
++)
3963 if (omp_clauses
->if_exprs
[ifc
])
3965 gfc_expr
*expr
= omp_clauses
->if_exprs
[ifc
];
3967 if (!gfc_resolve_expr (expr
)
3968 || expr
->ts
.type
!= BT_LOGICAL
|| expr
->rank
!= 0)
3969 gfc_error ("IF clause at %L requires a scalar LOGICAL expression",
3971 else if (if_without_mod
)
3973 gfc_error ("IF clause without modifier at %L used together with "
3974 "IF clauses with modifiers",
3975 &omp_clauses
->if_expr
->where
);
3976 if_without_mod
= false;
3981 case EXEC_OMP_PARALLEL
:
3982 case EXEC_OMP_PARALLEL_DO
:
3983 case EXEC_OMP_PARALLEL_SECTIONS
:
3984 case EXEC_OMP_PARALLEL_WORKSHARE
:
3985 case EXEC_OMP_PARALLEL_DO_SIMD
:
3986 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO
:
3987 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD
:
3988 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO
:
3989 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
3990 ok
= ifc
== OMP_IF_PARALLEL
;
3994 ok
= ifc
== OMP_IF_TASK
;
3997 case EXEC_OMP_TASKLOOP
:
3998 case EXEC_OMP_TASKLOOP_SIMD
:
3999 ok
= ifc
== OMP_IF_TASKLOOP
;
4002 case EXEC_OMP_TARGET
:
4003 case EXEC_OMP_TARGET_TEAMS
:
4004 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE
:
4005 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD
:
4006 case EXEC_OMP_TARGET_SIMD
:
4007 ok
= ifc
== OMP_IF_TARGET
;
4010 case EXEC_OMP_TARGET_DATA
:
4011 ok
= ifc
== OMP_IF_TARGET_DATA
;
4014 case EXEC_OMP_TARGET_UPDATE
:
4015 ok
= ifc
== OMP_IF_TARGET_UPDATE
;
4018 case EXEC_OMP_TARGET_ENTER_DATA
:
4019 ok
= ifc
== OMP_IF_TARGET_ENTER_DATA
;
4022 case EXEC_OMP_TARGET_EXIT_DATA
:
4023 ok
= ifc
== OMP_IF_TARGET_EXIT_DATA
;
4026 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO
:
4027 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
4028 case EXEC_OMP_TARGET_PARALLEL
:
4029 case EXEC_OMP_TARGET_PARALLEL_DO
:
4030 case EXEC_OMP_TARGET_PARALLEL_DO_SIMD
:
4031 ok
= ifc
== OMP_IF_TARGET
|| ifc
== OMP_IF_PARALLEL
;
4040 static const char *ifs
[] = {
4047 "TARGET ENTER DATA",
4050 gfc_error ("IF clause modifier %s at %L not appropriate for "
4051 "the current OpenMP construct", ifs
[ifc
], &expr
->where
);
4055 if (omp_clauses
->final_expr
)
4057 gfc_expr
*expr
= omp_clauses
->final_expr
;
4058 if (!gfc_resolve_expr (expr
)
4059 || expr
->ts
.type
!= BT_LOGICAL
|| expr
->rank
!= 0)
4060 gfc_error ("FINAL clause at %L requires a scalar LOGICAL expression",
4063 if (omp_clauses
->num_threads
)
4064 resolve_positive_int_expr (omp_clauses
->num_threads
, "NUM_THREADS");
4065 if (omp_clauses
->chunk_size
)
4067 gfc_expr
*expr
= omp_clauses
->chunk_size
;
4068 if (!gfc_resolve_expr (expr
)
4069 || expr
->ts
.type
!= BT_INTEGER
|| expr
->rank
!= 0)
4070 gfc_error ("SCHEDULE clause's chunk_size at %L requires "
4071 "a scalar INTEGER expression", &expr
->where
);
4072 else if (expr
->expr_type
== EXPR_CONSTANT
4073 && expr
->ts
.type
== BT_INTEGER
4074 && mpz_sgn (expr
->value
.integer
) <= 0)
4075 gfc_warning (0, "INTEGER expression of SCHEDULE clause's chunk_size "
4076 "at %L must be positive", &expr
->where
);
4079 /* Check that no symbol appears on multiple clauses, except that
4080 a symbol can appear on both firstprivate and lastprivate. */
4081 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
4082 for (n
= omp_clauses
->lists
[list
]; n
; n
= n
->next
)
4085 if (n
->sym
->attr
.flavor
== FL_VARIABLE
4086 || n
->sym
->attr
.proc_pointer
4087 || (!code
&& (!n
->sym
->attr
.dummy
|| n
->sym
->ns
!= ns
)))
4089 if (!code
&& (!n
->sym
->attr
.dummy
|| n
->sym
->ns
!= ns
))
4090 gfc_error ("Variable %qs is not a dummy argument at %L",
4091 n
->sym
->name
, &n
->where
);
4094 if (n
->sym
->attr
.flavor
== FL_PROCEDURE
4095 && n
->sym
->result
== n
->sym
4096 && n
->sym
->attr
.function
)
4098 if (gfc_current_ns
->proc_name
== n
->sym
4099 || (gfc_current_ns
->parent
4100 && gfc_current_ns
->parent
->proc_name
== n
->sym
))
4102 if (gfc_current_ns
->proc_name
->attr
.entry_master
)
4104 gfc_entry_list
*el
= gfc_current_ns
->entries
;
4105 for (; el
; el
= el
->next
)
4106 if (el
->sym
== n
->sym
)
4111 if (gfc_current_ns
->parent
4112 && gfc_current_ns
->parent
->proc_name
->attr
.entry_master
)
4114 gfc_entry_list
*el
= gfc_current_ns
->parent
->entries
;
4115 for (; el
; el
= el
->next
)
4116 if (el
->sym
== n
->sym
)
4122 gfc_error ("Object %qs is not a variable at %L", n
->sym
->name
,
4126 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
4127 if (list
!= OMP_LIST_FIRSTPRIVATE
4128 && list
!= OMP_LIST_LASTPRIVATE
4129 && list
!= OMP_LIST_ALIGNED
4130 && list
!= OMP_LIST_DEPEND
4131 && (list
!= OMP_LIST_MAP
|| openacc
)
4132 && list
!= OMP_LIST_FROM
4133 && list
!= OMP_LIST_TO
4134 && (list
!= OMP_LIST_REDUCTION
|| !openacc
))
4135 for (n
= omp_clauses
->lists
[list
]; n
; n
= n
->next
)
4138 gfc_error ("Symbol %qs present on multiple clauses at %L",
4139 n
->sym
->name
, &n
->where
);
4144 gcc_assert (OMP_LIST_LASTPRIVATE
== OMP_LIST_FIRSTPRIVATE
+ 1);
4145 for (list
= OMP_LIST_FIRSTPRIVATE
; list
<= OMP_LIST_LASTPRIVATE
; list
++)
4146 for (n
= omp_clauses
->lists
[list
]; n
; n
= n
->next
)
4149 gfc_error ("Symbol %qs present on multiple clauses at %L",
4150 n
->sym
->name
, &n
->where
);
4154 for (n
= omp_clauses
->lists
[OMP_LIST_FIRSTPRIVATE
]; n
; n
= n
->next
)
4157 gfc_error ("Symbol %qs present on multiple clauses at %L",
4158 n
->sym
->name
, &n
->where
);
4162 for (n
= omp_clauses
->lists
[OMP_LIST_LASTPRIVATE
]; n
; n
= n
->next
)
4165 for (n
= omp_clauses
->lists
[OMP_LIST_LASTPRIVATE
]; n
; n
= n
->next
)
4168 gfc_error ("Symbol %qs present on multiple clauses at %L",
4169 n
->sym
->name
, &n
->where
);
4174 for (n
= omp_clauses
->lists
[OMP_LIST_ALIGNED
]; n
; n
= n
->next
)
4177 for (n
= omp_clauses
->lists
[OMP_LIST_ALIGNED
]; n
; n
= n
->next
)
4180 gfc_error ("Symbol %qs present on multiple clauses at %L",
4181 n
->sym
->name
, &n
->where
);
4186 /* OpenACC reductions. */
4189 for (n
= omp_clauses
->lists
[OMP_LIST_REDUCTION
]; n
; n
= n
->next
)
4192 for (n
= omp_clauses
->lists
[OMP_LIST_REDUCTION
]; n
; n
= n
->next
)
4195 gfc_error ("Symbol %qs present on multiple clauses at %L",
4196 n
->sym
->name
, &n
->where
);
4200 /* OpenACC does not support reductions on arrays. */
4202 gfc_error ("Array %qs is not permitted in reduction at %L",
4203 n
->sym
->name
, &n
->where
);
4207 for (n
= omp_clauses
->lists
[OMP_LIST_TO
]; n
; n
= n
->next
)
4209 for (n
= omp_clauses
->lists
[OMP_LIST_FROM
]; n
; n
= n
->next
)
4210 if (n
->expr
== NULL
)
4212 for (n
= omp_clauses
->lists
[OMP_LIST_TO
]; n
; n
= n
->next
)
4214 if (n
->expr
== NULL
&& n
->sym
->mark
)
4215 gfc_error ("Symbol %qs present on both FROM and TO clauses at %L",
4216 n
->sym
->name
, &n
->where
);
4221 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
4222 if ((n
= omp_clauses
->lists
[list
]) != NULL
)
4226 if (list
< OMP_LIST_NUM
)
4227 name
= clause_names
[list
];
4233 case OMP_LIST_COPYIN
:
4234 for (; n
!= NULL
; n
= n
->next
)
4236 if (!n
->sym
->attr
.threadprivate
)
4237 gfc_error ("Non-THREADPRIVATE object %qs in COPYIN clause"
4238 " at %L", n
->sym
->name
, &n
->where
);
4241 case OMP_LIST_COPYPRIVATE
:
4242 for (; n
!= NULL
; n
= n
->next
)
4244 if (n
->sym
->as
&& n
->sym
->as
->type
== AS_ASSUMED_SIZE
)
4245 gfc_error ("Assumed size array %qs in COPYPRIVATE clause "
4246 "at %L", n
->sym
->name
, &n
->where
);
4247 if (n
->sym
->attr
.pointer
&& n
->sym
->attr
.intent
== INTENT_IN
)
4248 gfc_error ("INTENT(IN) POINTER %qs in COPYPRIVATE clause "
4249 "at %L", n
->sym
->name
, &n
->where
);
4252 case OMP_LIST_SHARED
:
4253 for (; n
!= NULL
; n
= n
->next
)
4255 if (n
->sym
->attr
.threadprivate
)
4256 gfc_error ("THREADPRIVATE object %qs in SHARED clause at "
4257 "%L", n
->sym
->name
, &n
->where
);
4258 if (n
->sym
->attr
.cray_pointee
)
4259 gfc_error ("Cray pointee %qs in SHARED clause at %L",
4260 n
->sym
->name
, &n
->where
);
4261 if (n
->sym
->attr
.associate_var
)
4262 gfc_error ("ASSOCIATE name %qs in SHARED clause at %L",
4263 n
->sym
->name
, &n
->where
);
4266 case OMP_LIST_ALIGNED
:
4267 for (; n
!= NULL
; n
= n
->next
)
4269 if (!n
->sym
->attr
.pointer
4270 && !n
->sym
->attr
.allocatable
4271 && !n
->sym
->attr
.cray_pointer
4272 && (n
->sym
->ts
.type
!= BT_DERIVED
4273 || (n
->sym
->ts
.u
.derived
->from_intmod
4274 != INTMOD_ISO_C_BINDING
)
4275 || (n
->sym
->ts
.u
.derived
->intmod_sym_id
4276 != ISOCBINDING_PTR
)))
4277 gfc_error ("%qs in ALIGNED clause must be POINTER, "
4278 "ALLOCATABLE, Cray pointer or C_PTR at %L",
4279 n
->sym
->name
, &n
->where
);
4282 gfc_expr
*expr
= n
->expr
;
4284 if (!gfc_resolve_expr (expr
)
4285 || expr
->ts
.type
!= BT_INTEGER
4287 || gfc_extract_int (expr
, &alignment
)
4289 gfc_error ("%qs in ALIGNED clause at %L requires a scalar "
4290 "positive constant integer alignment "
4291 "expression", n
->sym
->name
, &n
->where
);
4295 case OMP_LIST_DEPEND
:
4299 case OMP_LIST_CACHE
:
4300 for (; n
!= NULL
; n
= n
->next
)
4302 if (list
== OMP_LIST_DEPEND
)
4304 if (n
->u
.depend_op
== OMP_DEPEND_SINK_FIRST
4305 || n
->u
.depend_op
== OMP_DEPEND_SINK
)
4307 if (code
->op
!= EXEC_OMP_ORDERED
)
4308 gfc_error ("SINK dependence type only allowed "
4309 "on ORDERED directive at %L", &n
->where
);
4310 else if (omp_clauses
->depend_source
)
4312 gfc_error ("DEPEND SINK used together with "
4313 "DEPEND SOURCE on the same construct "
4314 "at %L", &n
->where
);
4315 omp_clauses
->depend_source
= false;
4319 if (!gfc_resolve_expr (n
->expr
)
4320 || n
->expr
->ts
.type
!= BT_INTEGER
4321 || n
->expr
->rank
!= 0)
4322 gfc_error ("SINK addend not a constant integer "
4323 "at %L", &n
->where
);
4327 else if (code
->op
== EXEC_OMP_ORDERED
)
4328 gfc_error ("Only SOURCE or SINK dependence types "
4329 "are allowed on ORDERED directive at %L",
4334 if (!gfc_resolve_expr (n
->expr
)
4335 || n
->expr
->expr_type
!= EXPR_VARIABLE
4336 || n
->expr
->ref
== NULL
4337 || n
->expr
->ref
->next
4338 || n
->expr
->ref
->type
!= REF_ARRAY
)
4339 gfc_error ("%qs in %s clause at %L is not a proper "
4340 "array section", n
->sym
->name
, name
,
4342 else if (n
->expr
->ref
->u
.ar
.codimen
)
4343 gfc_error ("Coarrays not supported in %s clause at %L",
4348 gfc_array_ref
*ar
= &n
->expr
->ref
->u
.ar
;
4349 for (i
= 0; i
< ar
->dimen
; i
++)
4352 gfc_error ("Stride should not be specified for "
4353 "array section in %s clause at %L",
4357 else if (ar
->dimen_type
[i
] != DIMEN_ELEMENT
4358 && ar
->dimen_type
[i
] != DIMEN_RANGE
)
4360 gfc_error ("%qs in %s clause at %L is not a "
4361 "proper array section",
4362 n
->sym
->name
, name
, &n
->where
);
4365 else if (list
== OMP_LIST_DEPEND
4367 && ar
->start
[i
]->expr_type
== EXPR_CONSTANT
4369 && ar
->end
[i
]->expr_type
== EXPR_CONSTANT
4370 && mpz_cmp (ar
->start
[i
]->value
.integer
,
4371 ar
->end
[i
]->value
.integer
) > 0)
4373 gfc_error ("%qs in DEPEND clause at %L is a "
4374 "zero size array section",
4375 n
->sym
->name
, &n
->where
);
4382 if (list
== OMP_LIST_MAP
4383 && n
->u
.map_op
== OMP_MAP_FORCE_DEVICEPTR
)
4384 resolve_oacc_deviceptr_clause (n
->sym
, n
->where
, name
);
4386 resolve_oacc_data_clauses (n
->sym
, n
->where
, name
);
4388 else if (list
!= OMP_LIST_DEPEND
4390 && n
->sym
->as
->type
== AS_ASSUMED_SIZE
)
4391 gfc_error ("Assumed size array %qs in %s clause at %L",
4392 n
->sym
->name
, name
, &n
->where
);
4393 if (list
== OMP_LIST_MAP
&& !openacc
)
4396 case EXEC_OMP_TARGET
:
4397 case EXEC_OMP_TARGET_DATA
:
4398 switch (n
->u
.map_op
)
4401 case OMP_MAP_ALWAYS_TO
:
4403 case OMP_MAP_ALWAYS_FROM
:
4404 case OMP_MAP_TOFROM
:
4405 case OMP_MAP_ALWAYS_TOFROM
:
4409 gfc_error ("TARGET%s with map-type other than TO, "
4410 "FROM, TOFROM, or ALLOC on MAP clause "
4412 code
->op
== EXEC_OMP_TARGET
4413 ? "" : " DATA", &n
->where
);
4417 case EXEC_OMP_TARGET_ENTER_DATA
:
4418 switch (n
->u
.map_op
)
4421 case OMP_MAP_ALWAYS_TO
:
4425 gfc_error ("TARGET ENTER DATA with map-type other "
4426 "than TO, or ALLOC on MAP clause at %L",
4431 case EXEC_OMP_TARGET_EXIT_DATA
:
4432 switch (n
->u
.map_op
)
4435 case OMP_MAP_ALWAYS_FROM
:
4436 case OMP_MAP_RELEASE
:
4437 case OMP_MAP_DELETE
:
4440 gfc_error ("TARGET EXIT DATA with map-type other "
4441 "than FROM, RELEASE, or DELETE on MAP "
4442 "clause at %L", &n
->where
);
4451 if (list
!= OMP_LIST_DEPEND
)
4452 for (n
= omp_clauses
->lists
[list
]; n
!= NULL
; n
= n
->next
)
4454 n
->sym
->attr
.referenced
= 1;
4455 if (n
->sym
->attr
.threadprivate
)
4456 gfc_error ("THREADPRIVATE object %qs in %s clause at %L",
4457 n
->sym
->name
, name
, &n
->where
);
4458 if (n
->sym
->attr
.cray_pointee
)
4459 gfc_error ("Cray pointee %qs in %s clause at %L",
4460 n
->sym
->name
, name
, &n
->where
);
4463 case OMP_LIST_IS_DEVICE_PTR
:
4464 case OMP_LIST_USE_DEVICE_PTR
:
4465 /* FIXME: Handle these. */
4468 for (; n
!= NULL
; n
= n
->next
)
4471 if (n
->sym
->attr
.threadprivate
)
4472 gfc_error ("THREADPRIVATE object %qs in %s clause at %L",
4473 n
->sym
->name
, name
, &n
->where
);
4474 if (n
->sym
->attr
.cray_pointee
)
4475 gfc_error ("Cray pointee %qs in %s clause at %L",
4476 n
->sym
->name
, name
, &n
->where
);
4477 if (n
->sym
->attr
.associate_var
)
4478 gfc_error ("ASSOCIATE name %qs in %s clause at %L",
4479 n
->sym
->name
, name
, &n
->where
);
4480 if (list
!= OMP_LIST_PRIVATE
)
4482 if (n
->sym
->attr
.proc_pointer
&& list
== OMP_LIST_REDUCTION
)
4483 gfc_error ("Procedure pointer %qs in %s clause at %L",
4484 n
->sym
->name
, name
, &n
->where
);
4485 if (n
->sym
->attr
.pointer
&& list
== OMP_LIST_REDUCTION
)
4486 gfc_error ("POINTER object %qs in %s clause at %L",
4487 n
->sym
->name
, name
, &n
->where
);
4488 if (n
->sym
->attr
.cray_pointer
&& list
== OMP_LIST_REDUCTION
)
4489 gfc_error ("Cray pointer %qs in %s clause at %L",
4490 n
->sym
->name
, name
, &n
->where
);
4493 && (oacc_is_loop (code
) || code
->op
== EXEC_OACC_PARALLEL
))
4494 check_array_not_assumed (n
->sym
, n
->where
, name
);
4495 else if (n
->sym
->as
&& n
->sym
->as
->type
== AS_ASSUMED_SIZE
)
4496 gfc_error ("Assumed size array %qs in %s clause at %L",
4497 n
->sym
->name
, name
, &n
->where
);
4498 if (n
->sym
->attr
.in_namelist
&& list
!= OMP_LIST_REDUCTION
)
4499 gfc_error ("Variable %qs in %s clause is used in "
4500 "NAMELIST statement at %L",
4501 n
->sym
->name
, name
, &n
->where
);
4502 if (n
->sym
->attr
.pointer
&& n
->sym
->attr
.intent
== INTENT_IN
)
4505 case OMP_LIST_PRIVATE
:
4506 case OMP_LIST_LASTPRIVATE
:
4507 case OMP_LIST_LINEAR
:
4508 /* case OMP_LIST_REDUCTION: */
4509 gfc_error ("INTENT(IN) POINTER %qs in %s clause at %L",
4510 n
->sym
->name
, name
, &n
->where
);
4518 case OMP_LIST_REDUCTION
:
4519 switch (n
->u
.reduction_op
)
4521 case OMP_REDUCTION_PLUS
:
4522 case OMP_REDUCTION_TIMES
:
4523 case OMP_REDUCTION_MINUS
:
4524 if (!gfc_numeric_ts (&n
->sym
->ts
))
4527 case OMP_REDUCTION_AND
:
4528 case OMP_REDUCTION_OR
:
4529 case OMP_REDUCTION_EQV
:
4530 case OMP_REDUCTION_NEQV
:
4531 if (n
->sym
->ts
.type
!= BT_LOGICAL
)
4534 case OMP_REDUCTION_MAX
:
4535 case OMP_REDUCTION_MIN
:
4536 if (n
->sym
->ts
.type
!= BT_INTEGER
4537 && n
->sym
->ts
.type
!= BT_REAL
)
4540 case OMP_REDUCTION_IAND
:
4541 case OMP_REDUCTION_IOR
:
4542 case OMP_REDUCTION_IEOR
:
4543 if (n
->sym
->ts
.type
!= BT_INTEGER
)
4546 case OMP_REDUCTION_USER
:
4556 const char *udr_name
= NULL
;
4559 udr_name
= n
->udr
->udr
->name
;
4561 = gfc_find_omp_udr (NULL
, udr_name
,
4563 if (n
->udr
->udr
== NULL
)
4571 if (udr_name
== NULL
)
4572 switch (n
->u
.reduction_op
)
4574 case OMP_REDUCTION_PLUS
:
4575 case OMP_REDUCTION_TIMES
:
4576 case OMP_REDUCTION_MINUS
:
4577 case OMP_REDUCTION_AND
:
4578 case OMP_REDUCTION_OR
:
4579 case OMP_REDUCTION_EQV
:
4580 case OMP_REDUCTION_NEQV
:
4581 udr_name
= gfc_op2string ((gfc_intrinsic_op
)
4584 case OMP_REDUCTION_MAX
:
4587 case OMP_REDUCTION_MIN
:
4590 case OMP_REDUCTION_IAND
:
4593 case OMP_REDUCTION_IOR
:
4596 case OMP_REDUCTION_IEOR
:
4602 gfc_error ("!$OMP DECLARE REDUCTION %s not found "
4603 "for type %s at %L", udr_name
,
4604 gfc_typename (&n
->sym
->ts
), &n
->where
);
4608 gfc_omp_udr
*udr
= n
->udr
->udr
;
4609 n
->u
.reduction_op
= OMP_REDUCTION_USER
;
4611 = resolve_omp_udr_clause (n
, udr
->combiner_ns
,
4614 if (udr
->initializer_ns
)
4616 = resolve_omp_udr_clause (n
,
4617 udr
->initializer_ns
,
4623 case OMP_LIST_LINEAR
:
4625 && n
->u
.linear_op
!= OMP_LINEAR_DEFAULT
4626 && n
->u
.linear_op
!= linear_op
)
4628 gfc_error ("LINEAR clause modifier used on DO or SIMD"
4629 " construct at %L", &n
->where
);
4630 linear_op
= n
->u
.linear_op
;
4632 else if (omp_clauses
->orderedc
)
4633 gfc_error ("LINEAR clause specified together with "
4634 "ORDERED clause with argument at %L",
4636 else if (n
->u
.linear_op
!= OMP_LINEAR_REF
4637 && n
->sym
->ts
.type
!= BT_INTEGER
)
4638 gfc_error ("LINEAR variable %qs must be INTEGER "
4639 "at %L", n
->sym
->name
, &n
->where
);
4640 else if ((n
->u
.linear_op
== OMP_LINEAR_REF
4641 || n
->u
.linear_op
== OMP_LINEAR_UVAL
)
4642 && n
->sym
->attr
.value
)
4643 gfc_error ("LINEAR dummy argument %qs with VALUE "
4644 "attribute with %s modifier at %L",
4646 n
->u
.linear_op
== OMP_LINEAR_REF
4647 ? "REF" : "UVAL", &n
->where
);
4650 gfc_expr
*expr
= n
->expr
;
4651 if (!gfc_resolve_expr (expr
)
4652 || expr
->ts
.type
!= BT_INTEGER
4654 gfc_error ("%qs in LINEAR clause at %L requires "
4655 "a scalar integer linear-step expression",
4656 n
->sym
->name
, &n
->where
);
4657 else if (!code
&& expr
->expr_type
!= EXPR_CONSTANT
)
4659 if (expr
->expr_type
== EXPR_VARIABLE
4660 && expr
->symtree
->n
.sym
->attr
.dummy
4661 && expr
->symtree
->n
.sym
->ns
== ns
)
4663 gfc_omp_namelist
*n2
;
4664 for (n2
= omp_clauses
->lists
[OMP_LIST_UNIFORM
];
4666 if (n2
->sym
== expr
->symtree
->n
.sym
)
4671 gfc_error ("%qs in LINEAR clause at %L requires "
4672 "a constant integer linear-step "
4673 "expression or dummy argument "
4674 "specified in UNIFORM clause",
4675 n
->sym
->name
, &n
->where
);
4679 /* Workaround for PR middle-end/26316, nothing really needs
4680 to be done here for OMP_LIST_PRIVATE. */
4681 case OMP_LIST_PRIVATE
:
4682 gcc_assert (code
&& code
->op
!= EXEC_NOP
);
4684 case OMP_LIST_USE_DEVICE
:
4685 if (n
->sym
->attr
.allocatable
4686 || (n
->sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (n
->sym
)
4687 && CLASS_DATA (n
->sym
)->attr
.allocatable
))
4688 gfc_error ("ALLOCATABLE object %qs in %s clause at %L",
4689 n
->sym
->name
, name
, &n
->where
);
4690 if (n
->sym
->ts
.type
== BT_CLASS
4691 && CLASS_DATA (n
->sym
)
4692 && CLASS_DATA (n
->sym
)->attr
.class_pointer
)
4693 gfc_error ("POINTER object %qs of polymorphic type in "
4694 "%s clause at %L", n
->sym
->name
, name
,
4696 if (n
->sym
->attr
.cray_pointer
)
4697 gfc_error ("Cray pointer object %qs in %s clause at %L",
4698 n
->sym
->name
, name
, &n
->where
);
4699 else if (n
->sym
->attr
.cray_pointee
)
4700 gfc_error ("Cray pointee object %qs in %s clause at %L",
4701 n
->sym
->name
, name
, &n
->where
);
4702 else if (n
->sym
->attr
.flavor
== FL_VARIABLE
4704 && !n
->sym
->attr
.pointer
)
4705 gfc_error ("%s clause variable %qs at %L is neither "
4706 "a POINTER nor an array", name
,
4707 n
->sym
->name
, &n
->where
);
4709 case OMP_LIST_DEVICE_RESIDENT
:
4710 check_symbol_not_pointer (n
->sym
, n
->where
, name
);
4711 check_array_not_assumed (n
->sym
, n
->where
, name
);
4720 if (omp_clauses
->safelen_expr
)
4721 resolve_positive_int_expr (omp_clauses
->safelen_expr
, "SAFELEN");
4722 if (omp_clauses
->simdlen_expr
)
4723 resolve_positive_int_expr (omp_clauses
->simdlen_expr
, "SIMDLEN");
4724 if (omp_clauses
->num_teams
)
4725 resolve_positive_int_expr (omp_clauses
->num_teams
, "NUM_TEAMS");
4726 if (omp_clauses
->device
)
4727 resolve_nonnegative_int_expr (omp_clauses
->device
, "DEVICE");
4728 if (omp_clauses
->hint
)
4729 resolve_scalar_int_expr (omp_clauses
->hint
, "HINT");
4730 if (omp_clauses
->priority
)
4731 resolve_nonnegative_int_expr (omp_clauses
->priority
, "PRIORITY");
4732 if (omp_clauses
->dist_chunk_size
)
4734 gfc_expr
*expr
= omp_clauses
->dist_chunk_size
;
4735 if (!gfc_resolve_expr (expr
)
4736 || expr
->ts
.type
!= BT_INTEGER
|| expr
->rank
!= 0)
4737 gfc_error ("DIST_SCHEDULE clause's chunk_size at %L requires "
4738 "a scalar INTEGER expression", &expr
->where
);
4740 if (omp_clauses
->thread_limit
)
4741 resolve_positive_int_expr (omp_clauses
->thread_limit
, "THREAD_LIMIT");
4742 if (omp_clauses
->grainsize
)
4743 resolve_positive_int_expr (omp_clauses
->grainsize
, "GRAINSIZE");
4744 if (omp_clauses
->num_tasks
)
4745 resolve_positive_int_expr (omp_clauses
->num_tasks
, "NUM_TASKS");
4746 if (omp_clauses
->async
)
4747 if (omp_clauses
->async_expr
)
4748 resolve_scalar_int_expr (omp_clauses
->async_expr
, "ASYNC");
4749 if (omp_clauses
->num_gangs_expr
)
4750 resolve_positive_int_expr (omp_clauses
->num_gangs_expr
, "NUM_GANGS");
4751 if (omp_clauses
->num_workers_expr
)
4752 resolve_positive_int_expr (omp_clauses
->num_workers_expr
, "NUM_WORKERS");
4753 if (omp_clauses
->vector_length_expr
)
4754 resolve_positive_int_expr (omp_clauses
->vector_length_expr
,
4756 if (omp_clauses
->gang_num_expr
)
4757 resolve_positive_int_expr (omp_clauses
->gang_num_expr
, "GANG");
4758 if (omp_clauses
->gang_static_expr
)
4759 resolve_positive_int_expr (omp_clauses
->gang_static_expr
, "GANG");
4760 if (omp_clauses
->worker_expr
)
4761 resolve_positive_int_expr (omp_clauses
->worker_expr
, "WORKER");
4762 if (omp_clauses
->vector_expr
)
4763 resolve_positive_int_expr (omp_clauses
->vector_expr
, "VECTOR");
4764 if (omp_clauses
->wait
)
4765 if (omp_clauses
->wait_list
)
4766 for (el
= omp_clauses
->wait_list
; el
; el
= el
->next
)
4767 resolve_scalar_int_expr (el
->expr
, "WAIT");
4768 if (omp_clauses
->collapse
&& omp_clauses
->tile_list
)
4769 gfc_error ("Incompatible use of TILE and COLLAPSE at %L", &code
->loc
);
4770 if (omp_clauses
->depend_source
&& code
->op
!= EXEC_OMP_ORDERED
)
4771 gfc_error ("SOURCE dependence type only allowed "
4772 "on ORDERED directive at %L", &code
->loc
);
4773 if (!openacc
&& code
&& omp_clauses
->lists
[OMP_LIST_MAP
] == NULL
)
4775 const char *p
= NULL
;
4778 case EXEC_OMP_TARGET_DATA
: p
= "TARGET DATA"; break;
4779 case EXEC_OMP_TARGET_ENTER_DATA
: p
= "TARGET ENTER DATA"; break;
4780 case EXEC_OMP_TARGET_EXIT_DATA
: p
= "TARGET EXIT DATA"; break;
4784 gfc_error ("%s must contain at least one MAP clause at %L",
4790 /* Return true if SYM is ever referenced in EXPR except in the SE node. */
4793 expr_references_sym (gfc_expr
*e
, gfc_symbol
*s
, gfc_expr
*se
)
4795 gfc_actual_arglist
*arg
;
4796 if (e
== NULL
|| e
== se
)
4798 switch (e
->expr_type
)
4803 case EXPR_STRUCTURE
:
4805 if (e
->symtree
!= NULL
4806 && e
->symtree
->n
.sym
== s
)
4809 case EXPR_SUBSTRING
:
4811 && (expr_references_sym (e
->ref
->u
.ss
.start
, s
, se
)
4812 || expr_references_sym (e
->ref
->u
.ss
.end
, s
, se
)))
4816 if (expr_references_sym (e
->value
.op
.op2
, s
, se
))
4818 return expr_references_sym (e
->value
.op
.op1
, s
, se
);
4820 for (arg
= e
->value
.function
.actual
; arg
; arg
= arg
->next
)
4821 if (expr_references_sym (arg
->expr
, s
, se
))
4830 /* If EXPR is a conversion function that widens the type
4831 if WIDENING is true or narrows the type if WIDENING is false,
4832 return the inner expression, otherwise return NULL. */
4835 is_conversion (gfc_expr
*expr
, bool widening
)
4837 gfc_typespec
*ts1
, *ts2
;
4839 if (expr
->expr_type
!= EXPR_FUNCTION
4840 || expr
->value
.function
.isym
== NULL
4841 || expr
->value
.function
.esym
!= NULL
4842 || expr
->value
.function
.isym
->id
!= GFC_ISYM_CONVERSION
)
4848 ts2
= &expr
->value
.function
.actual
->expr
->ts
;
4852 ts1
= &expr
->value
.function
.actual
->expr
->ts
;
4856 if (ts1
->type
> ts2
->type
4857 || (ts1
->type
== ts2
->type
&& ts1
->kind
> ts2
->kind
))
4858 return expr
->value
.function
.actual
->expr
;
4865 resolve_omp_atomic (gfc_code
*code
)
4867 gfc_code
*atomic_code
= code
;
4869 gfc_expr
*expr2
, *expr2_tmp
;
4870 gfc_omp_atomic_op aop
4871 = (gfc_omp_atomic_op
) (atomic_code
->ext
.omp_atomic
& GFC_OMP_ATOMIC_MASK
);
4873 code
= code
->block
->next
;
4874 /* resolve_blocks asserts this is initially EXEC_ASSIGN.
4875 If it changed to EXEC_NOP, assume an error has been emitted already. */
4876 if (code
->op
== EXEC_NOP
)
4878 if (code
->op
!= EXEC_ASSIGN
)
4881 gfc_error ("unexpected !$OMP ATOMIC expression at %L", &code
->loc
);
4884 if (aop
!= GFC_OMP_ATOMIC_CAPTURE
)
4886 if (code
->next
!= NULL
)
4891 if (code
->next
== NULL
)
4893 if (code
->next
->op
== EXEC_NOP
)
4895 if (code
->next
->op
!= EXEC_ASSIGN
|| code
->next
->next
)
4902 if (code
->expr1
->expr_type
!= EXPR_VARIABLE
4903 || code
->expr1
->symtree
== NULL
4904 || code
->expr1
->rank
!= 0
4905 || (code
->expr1
->ts
.type
!= BT_INTEGER
4906 && code
->expr1
->ts
.type
!= BT_REAL
4907 && code
->expr1
->ts
.type
!= BT_COMPLEX
4908 && code
->expr1
->ts
.type
!= BT_LOGICAL
))
4910 gfc_error ("!$OMP ATOMIC statement must set a scalar variable of "
4911 "intrinsic type at %L", &code
->loc
);
4915 var
= code
->expr1
->symtree
->n
.sym
;
4916 expr2
= is_conversion (code
->expr2
, false);
4919 if (aop
== GFC_OMP_ATOMIC_READ
|| aop
== GFC_OMP_ATOMIC_WRITE
)
4920 expr2
= is_conversion (code
->expr2
, true);
4922 expr2
= code
->expr2
;
4927 case GFC_OMP_ATOMIC_READ
:
4928 if (expr2
->expr_type
!= EXPR_VARIABLE
4929 || expr2
->symtree
== NULL
4931 || (expr2
->ts
.type
!= BT_INTEGER
4932 && expr2
->ts
.type
!= BT_REAL
4933 && expr2
->ts
.type
!= BT_COMPLEX
4934 && expr2
->ts
.type
!= BT_LOGICAL
))
4935 gfc_error ("!$OMP ATOMIC READ statement must read from a scalar "
4936 "variable of intrinsic type at %L", &expr2
->where
);
4938 case GFC_OMP_ATOMIC_WRITE
:
4939 if (expr2
->rank
!= 0 || expr_references_sym (code
->expr2
, var
, NULL
))
4940 gfc_error ("expr in !$OMP ATOMIC WRITE assignment var = expr "
4941 "must be scalar and cannot reference var at %L",
4944 case GFC_OMP_ATOMIC_CAPTURE
:
4946 if (expr2
== code
->expr2
)
4948 expr2_tmp
= is_conversion (code
->expr2
, true);
4949 if (expr2_tmp
== NULL
)
4952 if (expr2_tmp
->expr_type
== EXPR_VARIABLE
)
4954 if (expr2_tmp
->symtree
== NULL
4955 || expr2_tmp
->rank
!= 0
4956 || (expr2_tmp
->ts
.type
!= BT_INTEGER
4957 && expr2_tmp
->ts
.type
!= BT_REAL
4958 && expr2_tmp
->ts
.type
!= BT_COMPLEX
4959 && expr2_tmp
->ts
.type
!= BT_LOGICAL
)
4960 || expr2_tmp
->symtree
->n
.sym
== var
)
4962 gfc_error ("!$OMP ATOMIC CAPTURE capture statement must read from "
4963 "a scalar variable of intrinsic type at %L",
4967 var
= expr2_tmp
->symtree
->n
.sym
;
4969 if (code
->expr1
->expr_type
!= EXPR_VARIABLE
4970 || code
->expr1
->symtree
== NULL
4971 || code
->expr1
->rank
!= 0
4972 || (code
->expr1
->ts
.type
!= BT_INTEGER
4973 && code
->expr1
->ts
.type
!= BT_REAL
4974 && code
->expr1
->ts
.type
!= BT_COMPLEX
4975 && code
->expr1
->ts
.type
!= BT_LOGICAL
))
4977 gfc_error ("!$OMP ATOMIC CAPTURE update statement must set "
4978 "a scalar variable of intrinsic type at %L",
4979 &code
->expr1
->where
);
4982 if (code
->expr1
->symtree
->n
.sym
!= var
)
4984 gfc_error ("!$OMP ATOMIC CAPTURE capture statement reads from "
4985 "different variable than update statement writes "
4986 "into at %L", &code
->expr1
->where
);
4989 expr2
= is_conversion (code
->expr2
, false);
4991 expr2
= code
->expr2
;
4998 if (gfc_expr_attr (code
->expr1
).allocatable
)
5000 gfc_error ("!$OMP ATOMIC with ALLOCATABLE variable at %L",
5005 if (aop
== GFC_OMP_ATOMIC_CAPTURE
5006 && code
->next
== NULL
5007 && code
->expr2
->rank
== 0
5008 && !expr_references_sym (code
->expr2
, var
, NULL
))
5009 atomic_code
->ext
.omp_atomic
5010 = (gfc_omp_atomic_op
) (atomic_code
->ext
.omp_atomic
5011 | GFC_OMP_ATOMIC_SWAP
);
5012 else if (expr2
->expr_type
== EXPR_OP
)
5014 gfc_expr
*v
= NULL
, *e
, *c
;
5015 gfc_intrinsic_op op
= expr2
->value
.op
.op
;
5016 gfc_intrinsic_op alt_op
= INTRINSIC_NONE
;
5020 case INTRINSIC_PLUS
:
5021 alt_op
= INTRINSIC_MINUS
;
5023 case INTRINSIC_TIMES
:
5024 alt_op
= INTRINSIC_DIVIDE
;
5026 case INTRINSIC_MINUS
:
5027 alt_op
= INTRINSIC_PLUS
;
5029 case INTRINSIC_DIVIDE
:
5030 alt_op
= INTRINSIC_TIMES
;
5036 alt_op
= INTRINSIC_NEQV
;
5038 case INTRINSIC_NEQV
:
5039 alt_op
= INTRINSIC_EQV
;
5042 gfc_error ("!$OMP ATOMIC assignment operator must be binary "
5043 "+, *, -, /, .AND., .OR., .EQV. or .NEQV. at %L",
5048 /* Check for var = var op expr resp. var = expr op var where
5049 expr doesn't reference var and var op expr is mathematically
5050 equivalent to var op (expr) resp. expr op var equivalent to
5051 (expr) op var. We rely here on the fact that the matcher
5052 for x op1 y op2 z where op1 and op2 have equal precedence
5053 returns (x op1 y) op2 z. */
5054 e
= expr2
->value
.op
.op2
;
5055 if (e
->expr_type
== EXPR_VARIABLE
5056 && e
->symtree
!= NULL
5057 && e
->symtree
->n
.sym
== var
)
5059 else if ((c
= is_conversion (e
, true)) != NULL
5060 && c
->expr_type
== EXPR_VARIABLE
5061 && c
->symtree
!= NULL
5062 && c
->symtree
->n
.sym
== var
)
5066 gfc_expr
**p
= NULL
, **q
;
5067 for (q
= &expr2
->value
.op
.op1
; (e
= *q
) != NULL
; )
5068 if (e
->expr_type
== EXPR_VARIABLE
5069 && e
->symtree
!= NULL
5070 && e
->symtree
->n
.sym
== var
)
5075 else if ((c
= is_conversion (e
, true)) != NULL
)
5076 q
= &e
->value
.function
.actual
->expr
;
5077 else if (e
->expr_type
!= EXPR_OP
5078 || (e
->value
.op
.op
!= op
5079 && e
->value
.op
.op
!= alt_op
)
5085 q
= &e
->value
.op
.op1
;
5090 gfc_error ("!$OMP ATOMIC assignment must be var = var op expr "
5091 "or var = expr op var at %L", &expr2
->where
);
5098 switch (e
->value
.op
.op
)
5100 case INTRINSIC_MINUS
:
5101 case INTRINSIC_DIVIDE
:
5103 case INTRINSIC_NEQV
:
5104 gfc_error ("!$OMP ATOMIC var = var op expr not "
5105 "mathematically equivalent to var = var op "
5106 "(expr) at %L", &expr2
->where
);
5112 /* Canonicalize into var = var op (expr). */
5113 *p
= e
->value
.op
.op2
;
5114 e
->value
.op
.op2
= expr2
;
5116 if (code
->expr2
== expr2
)
5117 code
->expr2
= expr2
= e
;
5119 code
->expr2
->value
.function
.actual
->expr
= expr2
= e
;
5121 if (!gfc_compare_types (&expr2
->value
.op
.op1
->ts
, &expr2
->ts
))
5123 for (p
= &expr2
->value
.op
.op1
; *p
!= v
;
5124 p
= &(*p
)->value
.function
.actual
->expr
)
5127 gfc_free_expr (expr2
->value
.op
.op1
);
5128 expr2
->value
.op
.op1
= v
;
5129 gfc_convert_type (v
, &expr2
->ts
, 2);
5134 if (e
->rank
!= 0 || expr_references_sym (code
->expr2
, var
, v
))
5136 gfc_error ("expr in !$OMP ATOMIC assignment var = var op expr "
5137 "must be scalar and cannot reference var at %L",
5142 else if (expr2
->expr_type
== EXPR_FUNCTION
5143 && expr2
->value
.function
.isym
!= NULL
5144 && expr2
->value
.function
.esym
== NULL
5145 && expr2
->value
.function
.actual
!= NULL
5146 && expr2
->value
.function
.actual
->next
!= NULL
)
5148 gfc_actual_arglist
*arg
, *var_arg
;
5150 switch (expr2
->value
.function
.isym
->id
)
5158 if (expr2
->value
.function
.actual
->next
->next
!= NULL
)
5160 gfc_error ("!$OMP ATOMIC assignment intrinsic IAND, IOR "
5161 "or IEOR must have two arguments at %L",
5167 gfc_error ("!$OMP ATOMIC assignment intrinsic must be "
5168 "MIN, MAX, IAND, IOR or IEOR at %L",
5174 for (arg
= expr2
->value
.function
.actual
; arg
; arg
= arg
->next
)
5176 if ((arg
== expr2
->value
.function
.actual
5177 || (var_arg
== NULL
&& arg
->next
== NULL
))
5178 && arg
->expr
->expr_type
== EXPR_VARIABLE
5179 && arg
->expr
->symtree
!= NULL
5180 && arg
->expr
->symtree
->n
.sym
== var
)
5182 else if (expr_references_sym (arg
->expr
, var
, NULL
))
5184 gfc_error ("!$OMP ATOMIC intrinsic arguments except one must "
5185 "not reference %qs at %L",
5186 var
->name
, &arg
->expr
->where
);
5189 if (arg
->expr
->rank
!= 0)
5191 gfc_error ("!$OMP ATOMIC intrinsic arguments must be scalar "
5192 "at %L", &arg
->expr
->where
);
5197 if (var_arg
== NULL
)
5199 gfc_error ("First or last !$OMP ATOMIC intrinsic argument must "
5200 "be %qs at %L", var
->name
, &expr2
->where
);
5204 if (var_arg
!= expr2
->value
.function
.actual
)
5206 /* Canonicalize, so that var comes first. */
5207 gcc_assert (var_arg
->next
== NULL
);
5208 for (arg
= expr2
->value
.function
.actual
;
5209 arg
->next
!= var_arg
; arg
= arg
->next
)
5211 var_arg
->next
= expr2
->value
.function
.actual
;
5212 expr2
->value
.function
.actual
= var_arg
;
5217 gfc_error ("!$OMP ATOMIC assignment must have an operator or "
5218 "intrinsic on right hand side at %L", &expr2
->where
);
5220 if (aop
== GFC_OMP_ATOMIC_CAPTURE
&& code
->next
)
5223 if (code
->expr1
->expr_type
!= EXPR_VARIABLE
5224 || code
->expr1
->symtree
== NULL
5225 || code
->expr1
->rank
!= 0
5226 || (code
->expr1
->ts
.type
!= BT_INTEGER
5227 && code
->expr1
->ts
.type
!= BT_REAL
5228 && code
->expr1
->ts
.type
!= BT_COMPLEX
5229 && code
->expr1
->ts
.type
!= BT_LOGICAL
))
5231 gfc_error ("!$OMP ATOMIC CAPTURE capture statement must set "
5232 "a scalar variable of intrinsic type at %L",
5233 &code
->expr1
->where
);
5237 expr2
= is_conversion (code
->expr2
, false);
5240 expr2
= is_conversion (code
->expr2
, true);
5242 expr2
= code
->expr2
;
5245 if (expr2
->expr_type
!= EXPR_VARIABLE
5246 || expr2
->symtree
== NULL
5248 || (expr2
->ts
.type
!= BT_INTEGER
5249 && expr2
->ts
.type
!= BT_REAL
5250 && expr2
->ts
.type
!= BT_COMPLEX
5251 && expr2
->ts
.type
!= BT_LOGICAL
))
5253 gfc_error ("!$OMP ATOMIC CAPTURE capture statement must read "
5254 "from a scalar variable of intrinsic type at %L",
5258 if (expr2
->symtree
->n
.sym
!= var
)
5260 gfc_error ("!$OMP ATOMIC CAPTURE capture statement reads from "
5261 "different variable than update statement writes "
5262 "into at %L", &expr2
->where
);
5269 static struct fortran_omp_context
5272 hash_set
<gfc_symbol
*> *sharing_clauses
;
5273 hash_set
<gfc_symbol
*> *private_iterators
;
5274 struct fortran_omp_context
*previous
;
5277 static gfc_code
*omp_current_do_code
;
5278 static int omp_current_do_collapse
;
5281 gfc_resolve_omp_do_blocks (gfc_code
*code
, gfc_namespace
*ns
)
5283 if (code
->block
->next
&& code
->block
->next
->op
== EXEC_DO
)
5288 omp_current_do_code
= code
->block
->next
;
5289 if (code
->ext
.omp_clauses
->orderedc
)
5290 omp_current_do_collapse
= code
->ext
.omp_clauses
->orderedc
;
5292 omp_current_do_collapse
= code
->ext
.omp_clauses
->collapse
;
5293 for (i
= 1, c
= omp_current_do_code
; i
< omp_current_do_collapse
; i
++)
5296 if (c
->op
!= EXEC_DO
|| c
->next
== NULL
)
5299 if (c
->op
!= EXEC_DO
)
5302 if (i
< omp_current_do_collapse
|| omp_current_do_collapse
<= 0)
5303 omp_current_do_collapse
= 1;
5305 gfc_resolve_blocks (code
->block
, ns
);
5306 omp_current_do_collapse
= 0;
5307 omp_current_do_code
= NULL
;
5312 gfc_resolve_omp_parallel_blocks (gfc_code
*code
, gfc_namespace
*ns
)
5314 struct fortran_omp_context ctx
;
5315 gfc_omp_clauses
*omp_clauses
= code
->ext
.omp_clauses
;
5316 gfc_omp_namelist
*n
;
5320 ctx
.sharing_clauses
= new hash_set
<gfc_symbol
*>;
5321 ctx
.private_iterators
= new hash_set
<gfc_symbol
*>;
5322 ctx
.previous
= omp_current_ctx
;
5323 ctx
.is_openmp
= true;
5324 omp_current_ctx
= &ctx
;
5326 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
5329 case OMP_LIST_SHARED
:
5330 case OMP_LIST_PRIVATE
:
5331 case OMP_LIST_FIRSTPRIVATE
:
5332 case OMP_LIST_LASTPRIVATE
:
5333 case OMP_LIST_REDUCTION
:
5334 case OMP_LIST_LINEAR
:
5335 for (n
= omp_clauses
->lists
[list
]; n
; n
= n
->next
)
5336 ctx
.sharing_clauses
->add (n
->sym
);
5344 case EXEC_OMP_PARALLEL_DO
:
5345 case EXEC_OMP_PARALLEL_DO_SIMD
:
5346 case EXEC_OMP_TARGET_PARALLEL_DO
:
5347 case EXEC_OMP_TARGET_PARALLEL_DO_SIMD
:
5348 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE
:
5349 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO
:
5350 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
5351 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD
:
5352 case EXEC_OMP_TASKLOOP
:
5353 case EXEC_OMP_TASKLOOP_SIMD
:
5354 case EXEC_OMP_TEAMS_DISTRIBUTE
:
5355 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO
:
5356 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
5357 case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD
:
5358 gfc_resolve_omp_do_blocks (code
, ns
);
5361 gfc_resolve_blocks (code
->block
, ns
);
5364 omp_current_ctx
= ctx
.previous
;
5365 delete ctx
.sharing_clauses
;
5366 delete ctx
.private_iterators
;
5370 /* Save and clear openmp.c private state. */
5373 gfc_omp_save_and_clear_state (struct gfc_omp_saved_state
*state
)
5375 state
->ptrs
[0] = omp_current_ctx
;
5376 state
->ptrs
[1] = omp_current_do_code
;
5377 state
->ints
[0] = omp_current_do_collapse
;
5378 omp_current_ctx
= NULL
;
5379 omp_current_do_code
= NULL
;
5380 omp_current_do_collapse
= 0;
5384 /* Restore openmp.c private state from the saved state. */
5387 gfc_omp_restore_state (struct gfc_omp_saved_state
*state
)
5389 omp_current_ctx
= (struct fortran_omp_context
*) state
->ptrs
[0];
5390 omp_current_do_code
= (gfc_code
*) state
->ptrs
[1];
5391 omp_current_do_collapse
= state
->ints
[0];
5395 /* Note a DO iterator variable. This is special in !$omp parallel
5396 construct, where they are predetermined private. */
5399 gfc_resolve_do_iterator (gfc_code
*code
, gfc_symbol
*sym
, bool add_clause
)
5401 if (omp_current_ctx
== NULL
)
5404 int i
= omp_current_do_collapse
;
5405 gfc_code
*c
= omp_current_do_code
;
5407 if (sym
->attr
.threadprivate
)
5410 /* !$omp do and !$omp parallel do iteration variable is predetermined
5411 private just in the !$omp do resp. !$omp parallel do construct,
5412 with no implications for the outer parallel constructs. */
5422 /* An openacc context may represent a data clause. Abort if so. */
5423 if (!omp_current_ctx
->is_openmp
&& !oacc_is_loop (omp_current_ctx
->code
))
5426 if (omp_current_ctx
->is_openmp
5427 && omp_current_ctx
->sharing_clauses
->contains (sym
))
5430 if (! omp_current_ctx
->private_iterators
->add (sym
) && add_clause
)
5432 gfc_omp_clauses
*omp_clauses
= omp_current_ctx
->code
->ext
.omp_clauses
;
5433 gfc_omp_namelist
*p
;
5435 p
= gfc_get_omp_namelist ();
5437 p
->next
= omp_clauses
->lists
[OMP_LIST_PRIVATE
];
5438 omp_clauses
->lists
[OMP_LIST_PRIVATE
] = p
;
5443 handle_local_var (gfc_symbol
*sym
)
5445 if (sym
->attr
.flavor
!= FL_VARIABLE
5447 || (sym
->ts
.type
!= BT_INTEGER
&& sym
->ts
.type
!= BT_REAL
))
5449 gfc_resolve_do_iterator (sym
->ns
->code
, sym
, false);
5453 gfc_resolve_omp_local_vars (gfc_namespace
*ns
)
5455 if (omp_current_ctx
)
5456 gfc_traverse_ns (ns
, handle_local_var
);
5460 resolve_omp_do (gfc_code
*code
)
5462 gfc_code
*do_code
, *c
;
5463 int list
, i
, collapse
;
5464 gfc_omp_namelist
*n
;
5467 bool is_simd
= false;
5471 case EXEC_OMP_DISTRIBUTE
: name
= "!$OMP DISTRIBUTE"; break;
5472 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO
:
5473 name
= "!$OMP DISTRIBUTE PARALLEL DO";
5475 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD
:
5476 name
= "!$OMP DISTRIBUTE PARALLEL DO SIMD";
5479 case EXEC_OMP_DISTRIBUTE_SIMD
:
5480 name
= "!$OMP DISTRIBUTE SIMD";
5483 case EXEC_OMP_DO
: name
= "!$OMP DO"; break;
5484 case EXEC_OMP_DO_SIMD
: name
= "!$OMP DO SIMD"; is_simd
= true; break;
5485 case EXEC_OMP_PARALLEL_DO
: name
= "!$OMP PARALLEL DO"; break;
5486 case EXEC_OMP_PARALLEL_DO_SIMD
:
5487 name
= "!$OMP PARALLEL DO SIMD";
5490 case EXEC_OMP_SIMD
: name
= "!$OMP SIMD"; is_simd
= true; break;
5491 case EXEC_OMP_TARGET_PARALLEL_DO
: name
= "!$OMP TARGET PARALLEL DO"; break;
5492 case EXEC_OMP_TARGET_PARALLEL_DO_SIMD
:
5493 name
= "!$OMP TARGET PARALLEL DO SIMD";
5496 case EXEC_OMP_TARGET_SIMD
:
5497 name
= "!$OMP TARGET SIMD";
5500 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE
:
5501 name
= "!$OMP TARGET TEAMS DISTRIBUTE";
5503 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO
:
5504 name
= "!$OMP TARGET TEAMS DISTRIBUTE PARALLEL DO";
5506 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
5507 name
= "!$OMP TARGET TEAMS DISTRIBUTE PARALLEL DO SIMD";
5510 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD
:
5511 name
= "!$OMP TARGET TEAMS DISTRIBUTE SIMD";
5514 case EXEC_OMP_TASKLOOP
: name
= "!$OMP TASKLOOP"; break;
5515 case EXEC_OMP_TASKLOOP_SIMD
:
5516 name
= "!$OMP TASKLOOP SIMD";
5519 case EXEC_OMP_TEAMS_DISTRIBUTE
: name
= "!$OMP TEAMS DISTRIBUTE"; break;
5520 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO
:
5521 name
= "!$OMP TEAMS DISTRIBUTE PARALLEL DO";
5523 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
5524 name
= "!$OMP TEAMS DISTRIBUTE PARALLEL DO SIMD";
5527 case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD
:
5528 name
= "!$OMP TEAMS DISTRIBUTE SIMD";
5531 default: gcc_unreachable ();
5534 if (code
->ext
.omp_clauses
)
5535 resolve_omp_clauses (code
, code
->ext
.omp_clauses
, NULL
);
5537 do_code
= code
->block
->next
;
5538 if (code
->ext
.omp_clauses
->orderedc
)
5539 collapse
= code
->ext
.omp_clauses
->orderedc
;
5542 collapse
= code
->ext
.omp_clauses
->collapse
;
5546 for (i
= 1; i
<= collapse
; i
++)
5548 if (do_code
->op
== EXEC_DO_WHILE
)
5550 gfc_error ("%s cannot be a DO WHILE or DO without loop control "
5551 "at %L", name
, &do_code
->loc
);
5554 if (do_code
->op
== EXEC_DO_CONCURRENT
)
5556 gfc_error ("%s cannot be a DO CONCURRENT loop at %L", name
,
5560 gcc_assert (do_code
->op
== EXEC_DO
);
5561 if (do_code
->ext
.iterator
->var
->ts
.type
!= BT_INTEGER
)
5562 gfc_error ("%s iteration variable must be of type integer at %L",
5563 name
, &do_code
->loc
);
5564 dovar
= do_code
->ext
.iterator
->var
->symtree
->n
.sym
;
5565 if (dovar
->attr
.threadprivate
)
5566 gfc_error ("%s iteration variable must not be THREADPRIVATE "
5567 "at %L", name
, &do_code
->loc
);
5568 if (code
->ext
.omp_clauses
)
5569 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
5571 ? (list
!= OMP_LIST_PRIVATE
&& list
!= OMP_LIST_LASTPRIVATE
)
5572 : code
->ext
.omp_clauses
->collapse
> 1
5573 ? (list
!= OMP_LIST_LASTPRIVATE
)
5574 : (list
!= OMP_LIST_LINEAR
))
5575 for (n
= code
->ext
.omp_clauses
->lists
[list
]; n
; n
= n
->next
)
5576 if (dovar
== n
->sym
)
5579 gfc_error ("%s iteration variable present on clause "
5580 "other than PRIVATE or LASTPRIVATE at %L",
5581 name
, &do_code
->loc
);
5582 else if (code
->ext
.omp_clauses
->collapse
> 1)
5583 gfc_error ("%s iteration variable present on clause "
5584 "other than LASTPRIVATE at %L",
5585 name
, &do_code
->loc
);
5587 gfc_error ("%s iteration variable present on clause "
5588 "other than LINEAR at %L",
5589 name
, &do_code
->loc
);
5594 gfc_code
*do_code2
= code
->block
->next
;
5597 for (j
= 1; j
< i
; j
++)
5599 gfc_symbol
*ivar
= do_code2
->ext
.iterator
->var
->symtree
->n
.sym
;
5601 || gfc_find_sym_in_expr (ivar
, do_code
->ext
.iterator
->start
)
5602 || gfc_find_sym_in_expr (ivar
, do_code
->ext
.iterator
->end
)
5603 || gfc_find_sym_in_expr (ivar
, do_code
->ext
.iterator
->step
))
5605 gfc_error ("%s collapsed loops don't form rectangular "
5606 "iteration space at %L", name
, &do_code
->loc
);
5609 do_code2
= do_code2
->block
->next
;
5614 for (c
= do_code
->next
; c
; c
= c
->next
)
5615 if (c
->op
!= EXEC_NOP
&& c
->op
!= EXEC_CONTINUE
)
5617 gfc_error ("collapsed %s loops not perfectly nested at %L",
5623 do_code
= do_code
->block
;
5624 if (do_code
->op
!= EXEC_DO
&& do_code
->op
!= EXEC_DO_WHILE
)
5626 gfc_error ("not enough DO loops for collapsed %s at %L",
5630 do_code
= do_code
->next
;
5632 || (do_code
->op
!= EXEC_DO
&& do_code
->op
!= EXEC_DO_WHILE
))
5634 gfc_error ("not enough DO loops for collapsed %s at %L",
5642 oacc_is_parallel (gfc_code
*code
)
5644 return code
->op
== EXEC_OACC_PARALLEL
|| code
->op
== EXEC_OACC_PARALLEL_LOOP
;
5648 oacc_is_kernels (gfc_code
*code
)
5650 return code
->op
== EXEC_OACC_KERNELS
|| code
->op
== EXEC_OACC_KERNELS_LOOP
;
5653 static gfc_statement
5654 omp_code_to_statement (gfc_code
*code
)
5658 case EXEC_OMP_PARALLEL
:
5659 return ST_OMP_PARALLEL
;
5660 case EXEC_OMP_PARALLEL_SECTIONS
:
5661 return ST_OMP_PARALLEL_SECTIONS
;
5662 case EXEC_OMP_SECTIONS
:
5663 return ST_OMP_SECTIONS
;
5664 case EXEC_OMP_ORDERED
:
5665 return ST_OMP_ORDERED
;
5666 case EXEC_OMP_CRITICAL
:
5667 return ST_OMP_CRITICAL
;
5668 case EXEC_OMP_MASTER
:
5669 return ST_OMP_MASTER
;
5670 case EXEC_OMP_SINGLE
:
5671 return ST_OMP_SINGLE
;
5674 case EXEC_OMP_WORKSHARE
:
5675 return ST_OMP_WORKSHARE
;
5676 case EXEC_OMP_PARALLEL_WORKSHARE
:
5677 return ST_OMP_PARALLEL_WORKSHARE
;
5685 static gfc_statement
5686 oacc_code_to_statement (gfc_code
*code
)
5690 case EXEC_OACC_PARALLEL
:
5691 return ST_OACC_PARALLEL
;
5692 case EXEC_OACC_KERNELS
:
5693 return ST_OACC_KERNELS
;
5694 case EXEC_OACC_DATA
:
5695 return ST_OACC_DATA
;
5696 case EXEC_OACC_HOST_DATA
:
5697 return ST_OACC_HOST_DATA
;
5698 case EXEC_OACC_PARALLEL_LOOP
:
5699 return ST_OACC_PARALLEL_LOOP
;
5700 case EXEC_OACC_KERNELS_LOOP
:
5701 return ST_OACC_KERNELS_LOOP
;
5702 case EXEC_OACC_LOOP
:
5703 return ST_OACC_LOOP
;
5704 case EXEC_OACC_ATOMIC
:
5705 return ST_OACC_ATOMIC
;
5712 resolve_oacc_directive_inside_omp_region (gfc_code
*code
)
5714 if (omp_current_ctx
!= NULL
&& omp_current_ctx
->is_openmp
)
5716 gfc_statement st
= omp_code_to_statement (omp_current_ctx
->code
);
5717 gfc_statement oacc_st
= oacc_code_to_statement (code
);
5718 gfc_error ("The %s directive cannot be specified within "
5719 "a %s region at %L", gfc_ascii_statement (oacc_st
),
5720 gfc_ascii_statement (st
), &code
->loc
);
5725 resolve_omp_directive_inside_oacc_region (gfc_code
*code
)
5727 if (omp_current_ctx
!= NULL
&& !omp_current_ctx
->is_openmp
)
5729 gfc_statement st
= oacc_code_to_statement (omp_current_ctx
->code
);
5730 gfc_statement omp_st
= omp_code_to_statement (code
);
5731 gfc_error ("The %s directive cannot be specified within "
5732 "a %s region at %L", gfc_ascii_statement (omp_st
),
5733 gfc_ascii_statement (st
), &code
->loc
);
5739 resolve_oacc_nested_loops (gfc_code
*code
, gfc_code
* do_code
, int collapse
,
5746 for (i
= 1; i
<= collapse
; i
++)
5748 if (do_code
->op
== EXEC_DO_WHILE
)
5750 gfc_error ("!$ACC LOOP cannot be a DO WHILE or DO without loop control "
5751 "at %L", &do_code
->loc
);
5754 gcc_assert (do_code
->op
== EXEC_DO
|| do_code
->op
== EXEC_DO_CONCURRENT
);
5755 if (do_code
->ext
.iterator
->var
->ts
.type
!= BT_INTEGER
)
5756 gfc_error ("!$ACC LOOP iteration variable must be of type integer at %L",
5758 dovar
= do_code
->ext
.iterator
->var
->symtree
->n
.sym
;
5761 gfc_code
*do_code2
= code
->block
->next
;
5764 for (j
= 1; j
< i
; j
++)
5766 gfc_symbol
*ivar
= do_code2
->ext
.iterator
->var
->symtree
->n
.sym
;
5768 || gfc_find_sym_in_expr (ivar
, do_code
->ext
.iterator
->start
)
5769 || gfc_find_sym_in_expr (ivar
, do_code
->ext
.iterator
->end
)
5770 || gfc_find_sym_in_expr (ivar
, do_code
->ext
.iterator
->step
))
5772 gfc_error ("!$ACC LOOP %s loops don't form rectangular "
5773 "iteration space at %L", clause
, &do_code
->loc
);
5776 do_code2
= do_code2
->block
->next
;
5781 for (c
= do_code
->next
; c
; c
= c
->next
)
5782 if (c
->op
!= EXEC_NOP
&& c
->op
!= EXEC_CONTINUE
)
5784 gfc_error ("%s !$ACC LOOP loops not perfectly nested at %L",
5790 do_code
= do_code
->block
;
5791 if (do_code
->op
!= EXEC_DO
&& do_code
->op
!= EXEC_DO_WHILE
5792 && do_code
->op
!= EXEC_DO_CONCURRENT
)
5794 gfc_error ("not enough DO loops for %s !$ACC LOOP at %L",
5795 clause
, &code
->loc
);
5798 do_code
= do_code
->next
;
5800 || (do_code
->op
!= EXEC_DO
&& do_code
->op
!= EXEC_DO_WHILE
5801 && do_code
->op
!= EXEC_DO_CONCURRENT
))
5803 gfc_error ("not enough DO loops for %s !$ACC LOOP at %L",
5804 clause
, &code
->loc
);
5812 resolve_oacc_params_in_parallel (gfc_code
*code
, const char *clause
,
5815 fortran_omp_context
*c
;
5817 if (oacc_is_parallel (code
))
5818 gfc_error ("!$ACC LOOP %s in PARALLEL region doesn't allow "
5819 "%s arguments at %L", clause
, arg
, &code
->loc
);
5820 for (c
= omp_current_ctx
; c
; c
= c
->previous
)
5822 if (oacc_is_loop (c
->code
))
5824 if (oacc_is_parallel (c
->code
))
5825 gfc_error ("!$ACC LOOP %s in PARALLEL region doesn't allow "
5826 "%s arguments at %L", clause
, arg
, &code
->loc
);
5832 resolve_oacc_loop_blocks (gfc_code
*code
)
5834 fortran_omp_context
*c
;
5836 if (!oacc_is_loop (code
))
5839 if (code
->op
== EXEC_OACC_LOOP
)
5840 for (c
= omp_current_ctx
; c
; c
= c
->previous
)
5842 if (oacc_is_loop (c
->code
))
5844 if (code
->ext
.omp_clauses
->gang
)
5846 if (c
->code
->ext
.omp_clauses
->gang
)
5847 gfc_error ("Loop parallelized across gangs is not allowed "
5848 "inside another loop parallelized across gangs at %L",
5850 if (c
->code
->ext
.omp_clauses
->worker
)
5851 gfc_error ("Loop parallelized across gangs is not allowed "
5852 "inside loop parallelized across workers at %L",
5854 if (c
->code
->ext
.omp_clauses
->vector
)
5855 gfc_error ("Loop parallelized across gangs is not allowed "
5856 "inside loop parallelized across vectors at %L",
5859 if (code
->ext
.omp_clauses
->worker
)
5861 if (c
->code
->ext
.omp_clauses
->worker
)
5862 gfc_error ("Loop parallelized across workers is not allowed "
5863 "inside another loop parallelized across workers at %L",
5865 if (c
->code
->ext
.omp_clauses
->vector
)
5866 gfc_error ("Loop parallelized across workers is not allowed "
5867 "inside another loop parallelized across vectors at %L",
5870 if (code
->ext
.omp_clauses
->vector
)
5871 if (c
->code
->ext
.omp_clauses
->vector
)
5872 gfc_error ("Loop parallelized across vectors is not allowed "
5873 "inside another loop parallelized across vectors at %L",
5877 if (oacc_is_parallel (c
->code
) || oacc_is_kernels (c
->code
))
5881 if (code
->ext
.omp_clauses
->seq
)
5883 if (code
->ext
.omp_clauses
->independent
)
5884 gfc_error ("Clause SEQ conflicts with INDEPENDENT at %L", &code
->loc
);
5885 if (code
->ext
.omp_clauses
->gang
)
5886 gfc_error ("Clause SEQ conflicts with GANG at %L", &code
->loc
);
5887 if (code
->ext
.omp_clauses
->worker
)
5888 gfc_error ("Clause SEQ conflicts with WORKER at %L", &code
->loc
);
5889 if (code
->ext
.omp_clauses
->vector
)
5890 gfc_error ("Clause SEQ conflicts with VECTOR at %L", &code
->loc
);
5891 if (code
->ext
.omp_clauses
->par_auto
)
5892 gfc_error ("Clause SEQ conflicts with AUTO at %L", &code
->loc
);
5894 if (code
->ext
.omp_clauses
->par_auto
)
5896 if (code
->ext
.omp_clauses
->gang
)
5897 gfc_error ("Clause AUTO conflicts with GANG at %L", &code
->loc
);
5898 if (code
->ext
.omp_clauses
->worker
)
5899 gfc_error ("Clause AUTO conflicts with WORKER at %L", &code
->loc
);
5900 if (code
->ext
.omp_clauses
->vector
)
5901 gfc_error ("Clause AUTO conflicts with VECTOR at %L", &code
->loc
);
5903 if (code
->ext
.omp_clauses
->tile_list
&& code
->ext
.omp_clauses
->gang
5904 && code
->ext
.omp_clauses
->worker
&& code
->ext
.omp_clauses
->vector
)
5905 gfc_error ("Tiled loop cannot be parallelized across gangs, workers and "
5906 "vectors at the same time at %L", &code
->loc
);
5908 if (code
->ext
.omp_clauses
->gang
5909 && code
->ext
.omp_clauses
->gang_num_expr
)
5910 resolve_oacc_params_in_parallel (code
, "GANG", "num");
5912 if (code
->ext
.omp_clauses
->worker
5913 && code
->ext
.omp_clauses
->worker_expr
)
5914 resolve_oacc_params_in_parallel (code
, "WORKER", "num");
5916 if (code
->ext
.omp_clauses
->vector
5917 && code
->ext
.omp_clauses
->vector_expr
)
5918 resolve_oacc_params_in_parallel (code
, "VECTOR", "length");
5920 if (code
->ext
.omp_clauses
->tile_list
)
5924 for (el
= code
->ext
.omp_clauses
->tile_list
; el
; el
= el
->next
)
5927 if (el
->expr
== NULL
)
5929 /* NULL expressions are used to represent '*' arguments.
5930 Convert those to a 0 expressions. */
5931 el
->expr
= gfc_get_constant_expr (BT_INTEGER
,
5932 gfc_default_integer_kind
,
5934 mpz_set_si (el
->expr
->value
.integer
, 0);
5938 resolve_positive_int_expr (el
->expr
, "TILE");
5939 if (el
->expr
->expr_type
!= EXPR_CONSTANT
)
5940 gfc_error ("TILE requires constant expression at %L",
5944 resolve_oacc_nested_loops (code
, code
->block
->next
, num
, "tiled");
5950 gfc_resolve_oacc_blocks (gfc_code
*code
, gfc_namespace
*ns
)
5952 fortran_omp_context ctx
;
5954 resolve_oacc_loop_blocks (code
);
5957 ctx
.sharing_clauses
= NULL
;
5958 ctx
.private_iterators
= new hash_set
<gfc_symbol
*>;
5959 ctx
.previous
= omp_current_ctx
;
5960 ctx
.is_openmp
= false;
5961 omp_current_ctx
= &ctx
;
5963 gfc_resolve_blocks (code
->block
, ns
);
5965 omp_current_ctx
= ctx
.previous
;
5966 delete ctx
.private_iterators
;
5971 resolve_oacc_loop (gfc_code
*code
)
5976 if (code
->ext
.omp_clauses
)
5977 resolve_omp_clauses (code
, code
->ext
.omp_clauses
, NULL
, true);
5979 do_code
= code
->block
->next
;
5980 collapse
= code
->ext
.omp_clauses
->collapse
;
5984 resolve_oacc_nested_loops (code
, do_code
, collapse
, "collapsed");
5988 gfc_resolve_oacc_declare (gfc_namespace
*ns
)
5991 gfc_omp_namelist
*n
;
5992 gfc_oacc_declare
*oc
;
5994 if (ns
->oacc_declare
== NULL
)
5997 for (oc
= ns
->oacc_declare
; oc
; oc
= oc
->next
)
5999 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
6000 for (n
= oc
->clauses
->lists
[list
]; n
; n
= n
->next
)
6003 if (n
->sym
->attr
.function
|| n
->sym
->attr
.subroutine
)
6005 gfc_error ("Object %qs is not a variable at %L",
6006 n
->sym
->name
, &oc
->loc
);
6009 if (n
->sym
->attr
.flavor
== FL_PARAMETER
)
6011 gfc_error ("PARAMETER object %qs is not allowed at %L",
6012 n
->sym
->name
, &oc
->loc
);
6016 if (n
->expr
&& n
->expr
->ref
->type
== REF_ARRAY
)
6018 gfc_error ("Array sections: %qs not allowed in"
6019 " !$ACC DECLARE at %L", n
->sym
->name
, &oc
->loc
);
6024 for (n
= oc
->clauses
->lists
[OMP_LIST_DEVICE_RESIDENT
]; n
; n
= n
->next
)
6025 check_array_not_assumed (n
->sym
, oc
->loc
, "DEVICE_RESIDENT");
6028 for (oc
= ns
->oacc_declare
; oc
; oc
= oc
->next
)
6030 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
6031 for (n
= oc
->clauses
->lists
[list
]; n
; n
= n
->next
)
6035 gfc_error ("Symbol %qs present on multiple clauses at %L",
6036 n
->sym
->name
, &oc
->loc
);
6044 for (oc
= ns
->oacc_declare
; oc
; oc
= oc
->next
)
6046 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
6047 for (n
= oc
->clauses
->lists
[list
]; n
; n
= n
->next
)
6053 gfc_resolve_oacc_directive (gfc_code
*code
, gfc_namespace
*ns ATTRIBUTE_UNUSED
)
6055 resolve_oacc_directive_inside_omp_region (code
);
6059 case EXEC_OACC_PARALLEL
:
6060 case EXEC_OACC_KERNELS
:
6061 case EXEC_OACC_DATA
:
6062 case EXEC_OACC_HOST_DATA
:
6063 case EXEC_OACC_UPDATE
:
6064 case EXEC_OACC_ENTER_DATA
:
6065 case EXEC_OACC_EXIT_DATA
:
6066 case EXEC_OACC_WAIT
:
6067 case EXEC_OACC_CACHE
:
6068 resolve_omp_clauses (code
, code
->ext
.omp_clauses
, NULL
, true);
6070 case EXEC_OACC_PARALLEL_LOOP
:
6071 case EXEC_OACC_KERNELS_LOOP
:
6072 case EXEC_OACC_LOOP
:
6073 resolve_oacc_loop (code
);
6075 case EXEC_OACC_ATOMIC
:
6076 resolve_omp_atomic (code
);
6084 /* Resolve OpenMP directive clauses and check various requirements
6085 of each directive. */
6088 gfc_resolve_omp_directive (gfc_code
*code
, gfc_namespace
*ns ATTRIBUTE_UNUSED
)
6090 resolve_omp_directive_inside_oacc_region (code
);
6092 if (code
->op
!= EXEC_OMP_ATOMIC
)
6093 gfc_maybe_initialize_eh ();
6097 case EXEC_OMP_DISTRIBUTE
:
6098 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO
:
6099 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD
:
6100 case EXEC_OMP_DISTRIBUTE_SIMD
:
6102 case EXEC_OMP_DO_SIMD
:
6103 case EXEC_OMP_PARALLEL_DO
:
6104 case EXEC_OMP_PARALLEL_DO_SIMD
:
6106 case EXEC_OMP_TARGET_PARALLEL_DO
:
6107 case EXEC_OMP_TARGET_PARALLEL_DO_SIMD
:
6108 case EXEC_OMP_TARGET_SIMD
:
6109 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE
:
6110 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO
:
6111 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
6112 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD
:
6113 case EXEC_OMP_TASKLOOP
:
6114 case EXEC_OMP_TASKLOOP_SIMD
:
6115 case EXEC_OMP_TEAMS_DISTRIBUTE
:
6116 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO
:
6117 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
6118 case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD
:
6119 resolve_omp_do (code
);
6121 case EXEC_OMP_CANCEL
:
6122 case EXEC_OMP_PARALLEL_WORKSHARE
:
6123 case EXEC_OMP_PARALLEL
:
6124 case EXEC_OMP_PARALLEL_SECTIONS
:
6125 case EXEC_OMP_SECTIONS
:
6126 case EXEC_OMP_SINGLE
:
6127 case EXEC_OMP_TARGET
:
6128 case EXEC_OMP_TARGET_DATA
:
6129 case EXEC_OMP_TARGET_ENTER_DATA
:
6130 case EXEC_OMP_TARGET_EXIT_DATA
:
6131 case EXEC_OMP_TARGET_PARALLEL
:
6132 case EXEC_OMP_TARGET_TEAMS
:
6134 case EXEC_OMP_TEAMS
:
6135 case EXEC_OMP_WORKSHARE
:
6136 if (code
->ext
.omp_clauses
)
6137 resolve_omp_clauses (code
, code
->ext
.omp_clauses
, NULL
);
6139 case EXEC_OMP_TARGET_UPDATE
:
6140 if (code
->ext
.omp_clauses
)
6141 resolve_omp_clauses (code
, code
->ext
.omp_clauses
, NULL
);
6142 if (code
->ext
.omp_clauses
== NULL
6143 || (code
->ext
.omp_clauses
->lists
[OMP_LIST_TO
] == NULL
6144 && code
->ext
.omp_clauses
->lists
[OMP_LIST_FROM
] == NULL
))
6145 gfc_error ("OMP TARGET UPDATE at %L requires at least one TO or "
6146 "FROM clause", &code
->loc
);
6148 case EXEC_OMP_ATOMIC
:
6149 resolve_omp_atomic (code
);
6156 /* Resolve !$omp declare simd constructs in NS. */
6159 gfc_resolve_omp_declare_simd (gfc_namespace
*ns
)
6161 gfc_omp_declare_simd
*ods
;
6163 for (ods
= ns
->omp_declare_simd
; ods
; ods
= ods
->next
)
6165 if (ods
->proc_name
!= NULL
6166 && ods
->proc_name
!= ns
->proc_name
)
6167 gfc_error ("!$OMP DECLARE SIMD should refer to containing procedure "
6168 "%qs at %L", ns
->proc_name
->name
, &ods
->where
);
6170 resolve_omp_clauses (NULL
, ods
->clauses
, ns
);
6174 struct omp_udr_callback_data
6176 gfc_omp_udr
*omp_udr
;
6177 bool is_initializer
;
6181 omp_udr_callback (gfc_expr
**e
, int *walk_subtrees ATTRIBUTE_UNUSED
,
6184 struct omp_udr_callback_data
*cd
= (struct omp_udr_callback_data
*) data
;
6185 if ((*e
)->expr_type
== EXPR_VARIABLE
)
6187 if (cd
->is_initializer
)
6189 if ((*e
)->symtree
->n
.sym
!= cd
->omp_udr
->omp_priv
6190 && (*e
)->symtree
->n
.sym
!= cd
->omp_udr
->omp_orig
)
6191 gfc_error ("Variable other than OMP_PRIV or OMP_ORIG used in "
6192 "INITIALIZER clause of !$OMP DECLARE REDUCTION at %L",
6197 if ((*e
)->symtree
->n
.sym
!= cd
->omp_udr
->omp_out
6198 && (*e
)->symtree
->n
.sym
!= cd
->omp_udr
->omp_in
)
6199 gfc_error ("Variable other than OMP_OUT or OMP_IN used in "
6200 "combiner of !$OMP DECLARE REDUCTION at %L",
6207 /* Resolve !$omp declare reduction constructs. */
6210 gfc_resolve_omp_udr (gfc_omp_udr
*omp_udr
)
6212 gfc_actual_arglist
*a
;
6213 const char *predef_name
= NULL
;
6215 switch (omp_udr
->rop
)
6217 case OMP_REDUCTION_PLUS
:
6218 case OMP_REDUCTION_TIMES
:
6219 case OMP_REDUCTION_MINUS
:
6220 case OMP_REDUCTION_AND
:
6221 case OMP_REDUCTION_OR
:
6222 case OMP_REDUCTION_EQV
:
6223 case OMP_REDUCTION_NEQV
:
6224 case OMP_REDUCTION_MAX
:
6225 case OMP_REDUCTION_USER
:
6228 gfc_error ("Invalid operator for !$OMP DECLARE REDUCTION %s at %L",
6229 omp_udr
->name
, &omp_udr
->where
);
6233 if (gfc_omp_udr_predef (omp_udr
->rop
, omp_udr
->name
,
6234 &omp_udr
->ts
, &predef_name
))
6237 gfc_error_now ("Redefinition of predefined %s "
6238 "!$OMP DECLARE REDUCTION at %L",
6239 predef_name
, &omp_udr
->where
);
6241 gfc_error_now ("Redefinition of predefined "
6242 "!$OMP DECLARE REDUCTION at %L", &omp_udr
->where
);
6246 if (omp_udr
->ts
.type
== BT_CHARACTER
6247 && omp_udr
->ts
.u
.cl
->length
6248 && omp_udr
->ts
.u
.cl
->length
->expr_type
!= EXPR_CONSTANT
)
6250 gfc_error ("CHARACTER length in !$OMP DECLARE REDUCTION %s not "
6251 "constant at %L", omp_udr
->name
, &omp_udr
->where
);
6255 struct omp_udr_callback_data cd
;
6256 cd
.omp_udr
= omp_udr
;
6257 cd
.is_initializer
= false;
6258 gfc_code_walker (&omp_udr
->combiner_ns
->code
, gfc_dummy_code_callback
,
6259 omp_udr_callback
, &cd
);
6260 if (omp_udr
->combiner_ns
->code
->op
== EXEC_CALL
)
6262 for (a
= omp_udr
->combiner_ns
->code
->ext
.actual
; a
; a
= a
->next
)
6263 if (a
->expr
== NULL
)
6266 gfc_error ("Subroutine call with alternate returns in combiner "
6267 "of !$OMP DECLARE REDUCTION at %L",
6268 &omp_udr
->combiner_ns
->code
->loc
);
6270 if (omp_udr
->initializer_ns
)
6272 cd
.is_initializer
= true;
6273 gfc_code_walker (&omp_udr
->initializer_ns
->code
, gfc_dummy_code_callback
,
6274 omp_udr_callback
, &cd
);
6275 if (omp_udr
->initializer_ns
->code
->op
== EXEC_CALL
)
6277 for (a
= omp_udr
->initializer_ns
->code
->ext
.actual
; a
; a
= a
->next
)
6278 if (a
->expr
== NULL
)
6281 gfc_error ("Subroutine call with alternate returns in "
6282 "INITIALIZER clause of !$OMP DECLARE REDUCTION "
6283 "at %L", &omp_udr
->initializer_ns
->code
->loc
);
6284 for (a
= omp_udr
->initializer_ns
->code
->ext
.actual
; a
; a
= a
->next
)
6286 && a
->expr
->expr_type
== EXPR_VARIABLE
6287 && a
->expr
->symtree
->n
.sym
== omp_udr
->omp_priv
6288 && a
->expr
->ref
== NULL
)
6291 gfc_error ("One of actual subroutine arguments in INITIALIZER "
6292 "clause of !$OMP DECLARE REDUCTION must be OMP_PRIV "
6293 "at %L", &omp_udr
->initializer_ns
->code
->loc
);
6296 else if (omp_udr
->ts
.type
== BT_DERIVED
6297 && !gfc_has_default_initializer (omp_udr
->ts
.u
.derived
))
6299 gfc_error ("Missing INITIALIZER clause for !$OMP DECLARE REDUCTION "
6300 "of derived type without default initializer at %L",
6307 gfc_resolve_omp_udrs (gfc_symtree
*st
)
6309 gfc_omp_udr
*omp_udr
;
6313 gfc_resolve_omp_udrs (st
->left
);
6314 gfc_resolve_omp_udrs (st
->right
);
6315 for (omp_udr
= st
->n
.omp_udr
; omp_udr
; omp_udr
= omp_udr
->next
)
6316 gfc_resolve_omp_udr (omp_udr
);