1 /* OpenMP directive matching and resolving.
2 Copyright (C) 2005-2021 Free Software Foundation, Inc.
3 Contributed by Jakub Jelinek
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
23 #include "coretypes.h"
28 #include "diagnostic.h"
29 #include "gomp-constants.h"
31 /* Match an end of OpenMP directive. End of OpenMP directive is optional
32 whitespace, followed by '\n' or comment '!'. */
35 gfc_match_omp_eos (void)
40 old_loc
= gfc_current_locus
;
41 gfc_gobble_whitespace ();
43 c
= gfc_next_ascii_char ();
48 c
= gfc_next_ascii_char ();
56 gfc_current_locus
= old_loc
;
61 gfc_match_omp_eos_error (void)
63 if (gfc_match_omp_eos() == MATCH_YES
)
66 gfc_error ("Unexpected junk at %C");
71 /* Free an omp_clauses structure. */
74 gfc_free_omp_clauses (gfc_omp_clauses
*c
)
80 gfc_free_expr (c
->if_expr
);
81 gfc_free_expr (c
->final_expr
);
82 gfc_free_expr (c
->num_threads
);
83 gfc_free_expr (c
->chunk_size
);
84 gfc_free_expr (c
->safelen_expr
);
85 gfc_free_expr (c
->simdlen_expr
);
86 gfc_free_expr (c
->num_teams
);
87 gfc_free_expr (c
->device
);
88 gfc_free_expr (c
->thread_limit
);
89 gfc_free_expr (c
->dist_chunk_size
);
90 gfc_free_expr (c
->grainsize
);
91 gfc_free_expr (c
->hint
);
92 gfc_free_expr (c
->num_tasks
);
93 gfc_free_expr (c
->priority
);
94 gfc_free_expr (c
->detach
);
95 for (i
= 0; i
< OMP_IF_LAST
; i
++)
96 gfc_free_expr (c
->if_exprs
[i
]);
97 gfc_free_expr (c
->async_expr
);
98 gfc_free_expr (c
->gang_num_expr
);
99 gfc_free_expr (c
->gang_static_expr
);
100 gfc_free_expr (c
->worker_expr
);
101 gfc_free_expr (c
->vector_expr
);
102 gfc_free_expr (c
->num_gangs_expr
);
103 gfc_free_expr (c
->num_workers_expr
);
104 gfc_free_expr (c
->vector_length_expr
);
105 for (i
= 0; i
< OMP_LIST_NUM
; i
++)
106 gfc_free_omp_namelist (c
->lists
[i
]);
107 gfc_free_expr_list (c
->wait_list
);
108 gfc_free_expr_list (c
->tile_list
);
109 free (CONST_CAST (char *, c
->critical_name
));
113 /* Free oacc_declare structures. */
116 gfc_free_oacc_declare_clauses (struct gfc_oacc_declare
*oc
)
118 struct gfc_oacc_declare
*decl
= oc
;
122 struct gfc_oacc_declare
*next
;
125 gfc_free_omp_clauses (decl
->clauses
);
132 /* Free expression list. */
134 gfc_free_expr_list (gfc_expr_list
*list
)
138 for (; list
; list
= n
)
145 /* Free an !$omp declare simd construct list. */
148 gfc_free_omp_declare_simd (gfc_omp_declare_simd
*ods
)
152 gfc_free_omp_clauses (ods
->clauses
);
158 gfc_free_omp_declare_simd_list (gfc_omp_declare_simd
*list
)
162 gfc_omp_declare_simd
*current
= list
;
164 gfc_free_omp_declare_simd (current
);
168 /* Free an !$omp declare reduction. */
171 gfc_free_omp_udr (gfc_omp_udr
*omp_udr
)
175 gfc_free_omp_udr (omp_udr
->next
);
176 gfc_free_namespace (omp_udr
->combiner_ns
);
177 if (omp_udr
->initializer_ns
)
178 gfc_free_namespace (omp_udr
->initializer_ns
);
185 gfc_find_omp_udr (gfc_namespace
*ns
, const char *name
, gfc_typespec
*ts
)
193 gfc_omp_udr
*omp_udr
;
195 st
= gfc_find_symtree (ns
->omp_udr_root
, name
);
198 for (omp_udr
= st
->n
.omp_udr
; omp_udr
; omp_udr
= omp_udr
->next
)
201 else if (gfc_compare_types (&omp_udr
->ts
, ts
))
203 if (ts
->type
== BT_CHARACTER
)
205 if (omp_udr
->ts
.u
.cl
->length
== NULL
)
207 if (ts
->u
.cl
->length
== NULL
)
209 if (gfc_compare_expr (omp_udr
->ts
.u
.cl
->length
,
218 /* Don't escape an interface block. */
219 if (ns
&& !ns
->has_import_set
220 && ns
->proc_name
&& ns
->proc_name
->attr
.if_source
== IFSRC_IFBODY
)
231 /* Match a variable/common block list and construct a namelist from it. */
234 gfc_match_omp_variable_list (const char *str
, gfc_omp_namelist
**list
,
235 bool allow_common
, bool *end_colon
= NULL
,
236 gfc_omp_namelist
***headp
= NULL
,
237 bool allow_sections
= false,
238 bool allow_derived
= false)
240 gfc_omp_namelist
*head
, *tail
, *p
;
241 locus old_loc
, cur_loc
;
242 char n
[GFC_MAX_SYMBOL_LEN
+1];
249 old_loc
= gfc_current_locus
;
257 cur_loc
= gfc_current_locus
;
258 m
= gfc_match_symbol (&sym
, 1);
264 if ((allow_sections
&& gfc_peek_ascii_char () == '(')
265 || (allow_derived
&& gfc_peek_ascii_char () == '%'))
267 gfc_current_locus
= cur_loc
;
268 m
= gfc_match_variable (&expr
, 0);
278 if (gfc_is_coindexed (expr
))
280 gfc_error ("List item shall not be coindexed at %C");
284 gfc_set_sym_referenced (sym
);
285 p
= gfc_get_omp_namelist ();
295 tail
->where
= cur_loc
;
306 m
= gfc_match (" / %n /", n
);
307 if (m
== MATCH_ERROR
)
312 st
= gfc_find_symtree (gfc_current_ns
->common_root
, n
);
315 gfc_error ("COMMON block /%s/ not found at %C", n
);
318 for (sym
= st
->n
.common
->head
; sym
; sym
= sym
->common_next
)
320 gfc_set_sym_referenced (sym
);
321 p
= gfc_get_omp_namelist ();
330 tail
->where
= cur_loc
;
334 if (end_colon
&& gfc_match_char (':') == MATCH_YES
)
339 if (gfc_match_char (')') == MATCH_YES
)
341 if (gfc_match_char (',') != MATCH_YES
)
346 list
= &(*list
)->next
;
354 gfc_error ("Syntax error in OpenMP variable list at %C");
357 gfc_free_omp_namelist (head
);
358 gfc_current_locus
= old_loc
;
362 /* Match a variable/procedure/common block list and construct a namelist
366 gfc_match_omp_to_link (const char *str
, gfc_omp_namelist
**list
)
368 gfc_omp_namelist
*head
, *tail
, *p
;
369 locus old_loc
, cur_loc
;
370 char n
[GFC_MAX_SYMBOL_LEN
+1];
377 old_loc
= gfc_current_locus
;
385 cur_loc
= gfc_current_locus
;
386 m
= gfc_match_symbol (&sym
, 1);
390 p
= gfc_get_omp_namelist ();
399 tail
->where
= cur_loc
;
407 m
= gfc_match (" / %n /", n
);
408 if (m
== MATCH_ERROR
)
413 st
= gfc_find_symtree (gfc_current_ns
->common_root
, n
);
416 gfc_error ("COMMON block /%s/ not found at %C", n
);
419 p
= gfc_get_omp_namelist ();
427 tail
->u
.common
= st
->n
.common
;
428 tail
->where
= cur_loc
;
431 if (gfc_match_char (')') == MATCH_YES
)
433 if (gfc_match_char (',') != MATCH_YES
)
438 list
= &(*list
)->next
;
444 gfc_error ("Syntax error in OpenMP variable list at %C");
447 gfc_free_omp_namelist (head
);
448 gfc_current_locus
= old_loc
;
452 /* Match detach(event-handle). */
455 gfc_match_omp_detach (gfc_expr
**expr
)
457 locus old_loc
= gfc_current_locus
;
459 if (gfc_match ("detach ( ") != MATCH_YES
)
462 if (gfc_match_variable (expr
, 0) != MATCH_YES
)
465 if ((*expr
)->ts
.type
!= BT_INTEGER
|| (*expr
)->ts
.kind
!= gfc_c_intptr_kind
)
467 gfc_error ("%qs at %L should be of type "
468 "integer(kind=omp_event_handle_kind)",
469 (*expr
)->symtree
->n
.sym
->name
, &(*expr
)->where
);
473 if (gfc_match_char (')') != MATCH_YES
)
479 gfc_error ("Syntax error in OpenMP detach clause at %C");
480 gfc_current_locus
= old_loc
;
485 /* Match depend(sink : ...) construct a namelist from it. */
488 gfc_match_omp_depend_sink (gfc_omp_namelist
**list
)
490 gfc_omp_namelist
*head
, *tail
, *p
;
491 locus old_loc
, cur_loc
;
496 old_loc
= gfc_current_locus
;
500 cur_loc
= gfc_current_locus
;
501 switch (gfc_match_symbol (&sym
, 1))
504 gfc_set_sym_referenced (sym
);
505 p
= gfc_get_omp_namelist ();
509 head
->u
.depend_op
= OMP_DEPEND_SINK_FIRST
;
515 tail
->u
.depend_op
= OMP_DEPEND_SINK
;
519 tail
->where
= cur_loc
;
520 if (gfc_match_char ('+') == MATCH_YES
)
522 if (gfc_match_literal_constant (&tail
->expr
, 0) != MATCH_YES
)
525 else if (gfc_match_char ('-') == MATCH_YES
)
527 if (gfc_match_literal_constant (&tail
->expr
, 0) != MATCH_YES
)
529 tail
->expr
= gfc_uminus (tail
->expr
);
538 if (gfc_match_char (')') == MATCH_YES
)
540 if (gfc_match_char (',') != MATCH_YES
)
545 list
= &(*list
)->next
;
551 gfc_error ("Syntax error in OpenMP DEPEND SINK list at %C");
554 gfc_free_omp_namelist (head
);
555 gfc_current_locus
= old_loc
;
560 match_oacc_expr_list (const char *str
, gfc_expr_list
**list
,
563 gfc_expr_list
*head
, *tail
, *p
;
570 old_loc
= gfc_current_locus
;
578 m
= gfc_match_expr (&expr
);
579 if (m
== MATCH_YES
|| allow_asterisk
)
581 p
= gfc_get_expr_list ();
591 else if (gfc_match (" *") != MATCH_YES
)
595 if (m
== MATCH_ERROR
)
600 if (gfc_match_char (')') == MATCH_YES
)
602 if (gfc_match_char (',') != MATCH_YES
)
607 list
= &(*list
)->next
;
613 gfc_error ("Syntax error in OpenACC expression list at %C");
616 gfc_free_expr_list (head
);
617 gfc_current_locus
= old_loc
;
622 match_oacc_clause_gwv (gfc_omp_clauses
*cp
, unsigned gwv
)
624 match ret
= MATCH_YES
;
626 if (gfc_match (" ( ") != MATCH_YES
)
629 if (gwv
== GOMP_DIM_GANG
)
631 /* The gang clause accepts two optional arguments, num and static.
632 The num argument may either be explicit (num: <val>) or
633 implicit without (<val> without num:). */
635 while (ret
== MATCH_YES
)
637 if (gfc_match (" static :") == MATCH_YES
)
642 cp
->gang_static
= true;
643 if (gfc_match_char ('*') == MATCH_YES
)
644 cp
->gang_static_expr
= NULL
;
645 else if (gfc_match (" %e ", &cp
->gang_static_expr
) != MATCH_YES
)
650 if (cp
->gang_num_expr
)
653 /* The 'num' argument is optional. */
654 gfc_match (" num :");
656 if (gfc_match (" %e ", &cp
->gang_num_expr
) != MATCH_YES
)
660 ret
= gfc_match (" , ");
663 else if (gwv
== GOMP_DIM_WORKER
)
665 /* The 'num' argument is optional. */
666 gfc_match (" num :");
668 if (gfc_match (" %e ", &cp
->worker_expr
) != MATCH_YES
)
671 else if (gwv
== GOMP_DIM_VECTOR
)
673 /* The 'length' argument is optional. */
674 gfc_match (" length :");
676 if (gfc_match (" %e ", &cp
->vector_expr
) != MATCH_YES
)
680 gfc_fatal_error ("Unexpected OpenACC parallelism.");
682 return gfc_match (" )");
686 gfc_match_oacc_clause_link (const char *str
, gfc_omp_namelist
**list
)
688 gfc_omp_namelist
*head
= NULL
;
689 gfc_omp_namelist
*tail
, *p
;
691 char n
[GFC_MAX_SYMBOL_LEN
+1];
696 old_loc
= gfc_current_locus
;
702 m
= gfc_match (" (");
706 m
= gfc_match_symbol (&sym
, 0);
710 if (sym
->attr
.in_common
)
712 gfc_error_now ("Variable at %C is an element of a COMMON block");
715 gfc_set_sym_referenced (sym
);
716 p
= gfc_get_omp_namelist ();
726 tail
->where
= gfc_current_locus
;
735 m
= gfc_match (" / %n /", n
);
736 if (m
== MATCH_ERROR
)
738 if (m
== MATCH_NO
|| n
[0] == '\0')
741 st
= gfc_find_symtree (gfc_current_ns
->common_root
, n
);
744 gfc_error ("COMMON block /%s/ not found at %C", n
);
748 for (sym
= st
->n
.common
->head
; sym
; sym
= sym
->common_next
)
750 gfc_set_sym_referenced (sym
);
751 p
= gfc_get_omp_namelist ();
760 tail
->where
= gfc_current_locus
;
764 if (gfc_match_char (')') == MATCH_YES
)
766 if (gfc_match_char (',') != MATCH_YES
)
770 if (gfc_match_omp_eos () != MATCH_YES
)
772 gfc_error ("Unexpected junk after !$ACC DECLARE at %C");
777 list
= &(*list
)->next
;
782 gfc_error ("Syntax error in !$ACC DECLARE list at %C");
785 gfc_current_locus
= old_loc
;
789 /* OpenMP clauses. */
793 OMP_CLAUSE_FIRSTPRIVATE
,
794 OMP_CLAUSE_LASTPRIVATE
,
795 OMP_CLAUSE_COPYPRIVATE
,
798 OMP_CLAUSE_REDUCTION
,
799 OMP_CLAUSE_IN_REDUCTION
,
800 OMP_CLAUSE_TASK_REDUCTION
,
802 OMP_CLAUSE_NUM_THREADS
,
810 OMP_CLAUSE_MERGEABLE
,
815 OMP_CLAUSE_NOTINBRANCH
,
816 OMP_CLAUSE_PROC_BIND
,
824 OMP_CLAUSE_NUM_TEAMS
,
825 OMP_CLAUSE_THREAD_LIMIT
,
826 OMP_CLAUSE_DIST_SCHEDULE
,
827 OMP_CLAUSE_DEFAULTMAP
,
828 OMP_CLAUSE_GRAINSIZE
,
830 OMP_CLAUSE_IS_DEVICE_PTR
,
833 OMP_CLAUSE_NOTEMPORAL
,
834 OMP_CLAUSE_NUM_TASKS
,
838 OMP_CLAUSE_USE_DEVICE_PTR
,
839 OMP_CLAUSE_USE_DEVICE_ADDR
, /* OpenMP 5.0. */
840 OMP_CLAUSE_DEVICE_TYPE
, /* OpenMP 5.0. */
841 OMP_CLAUSE_ATOMIC
, /* OpenMP 5.0. */
842 OMP_CLAUSE_CAPTURE
, /* OpenMP 5.0. */
843 OMP_CLAUSE_MEMORDER
, /* OpenMP 5.0. */
844 OMP_CLAUSE_DETACH
, /* OpenMP 5.0. */
846 /* This must come last. */
850 /* OpenACC 2.0+ specific clauses. */
854 OMP_CLAUSE_NUM_GANGS
,
855 OMP_CLAUSE_NUM_WORKERS
,
856 OMP_CLAUSE_VECTOR_LENGTH
,
860 OMP_CLAUSE_NO_CREATE
,
862 OMP_CLAUSE_DEVICEPTR
,
867 OMP_CLAUSE_INDEPENDENT
,
868 OMP_CLAUSE_USE_DEVICE
,
869 OMP_CLAUSE_DEVICE_RESIDENT
,
870 OMP_CLAUSE_HOST_SELF
,
875 OMP_CLAUSE_IF_PRESENT
,
878 /* This must come last. */
884 /* Customized bitset for up to 128-bits.
885 The two enums above provide bit numbers to use, and which of the
886 two enums it is determines which of the two mask fields is used.
887 Supported operations are defining a mask, like:
888 #define XXX_CLAUSES \
889 (omp_mask (OMP_CLAUSE_XXX) | OMP_CLAUSE_YYY | OMP_CLAUSE_ZZZ)
890 oring such bitsets together or removing selected bits:
891 (XXX_CLAUSES | YYY_CLAUSES) & ~(omp_mask (OMP_CLAUSE_VVV))
892 and testing individual bits:
893 if (mask & OMP_CLAUSE_UUU) */
896 const uint64_t mask1
;
897 const uint64_t mask2
;
899 inline omp_mask (omp_mask1
);
900 inline omp_mask (omp_mask2
);
901 inline omp_mask (uint64_t, uint64_t);
902 inline omp_mask
operator| (omp_mask1
) const;
903 inline omp_mask
operator| (omp_mask2
) const;
904 inline omp_mask
operator| (omp_mask
) const;
905 inline omp_mask
operator& (const omp_inv_mask
&) const;
906 inline bool operator& (omp_mask1
) const;
907 inline bool operator& (omp_mask2
) const;
908 inline omp_inv_mask
operator~ () const;
911 struct omp_inv_mask
: public omp_mask
{
912 inline omp_inv_mask (const omp_mask
&);
915 omp_mask::omp_mask () : mask1 (0), mask2 (0)
919 omp_mask::omp_mask (omp_mask1 m
) : mask1 (((uint64_t) 1) << m
), mask2 (0)
923 omp_mask::omp_mask (omp_mask2 m
) : mask1 (0), mask2 (((uint64_t) 1) << m
)
927 omp_mask::omp_mask (uint64_t m1
, uint64_t m2
) : mask1 (m1
), mask2 (m2
)
932 omp_mask::operator| (omp_mask1 m
) const
934 return omp_mask (mask1
| (((uint64_t) 1) << m
), mask2
);
938 omp_mask::operator| (omp_mask2 m
) const
940 return omp_mask (mask1
, mask2
| (((uint64_t) 1) << m
));
944 omp_mask::operator| (omp_mask m
) const
946 return omp_mask (mask1
| m
.mask1
, mask2
| m
.mask2
);
950 omp_mask::operator& (const omp_inv_mask
&m
) const
952 return omp_mask (mask1
& ~m
.mask1
, mask2
& ~m
.mask2
);
956 omp_mask::operator& (omp_mask1 m
) const
958 return (mask1
& (((uint64_t) 1) << m
)) != 0;
962 omp_mask::operator& (omp_mask2 m
) const
964 return (mask2
& (((uint64_t) 1) << m
)) != 0;
968 omp_mask::operator~ () const
970 return omp_inv_mask (*this);
973 omp_inv_mask::omp_inv_mask (const omp_mask
&m
) : omp_mask (m
)
977 /* Helper function for OpenACC and OpenMP clauses involving memory
981 gfc_match_omp_map_clause (gfc_omp_namelist
**list
, gfc_omp_map_op map_op
,
982 bool allow_common
, bool allow_derived
)
984 gfc_omp_namelist
**head
= NULL
;
985 if (gfc_match_omp_variable_list ("", list
, allow_common
, NULL
, &head
, true,
990 for (n
= *head
; n
; n
= n
->next
)
991 n
->u
.map_op
= map_op
;
998 /* reduction ( reduction-modifier, reduction-operator : variable-list )
999 in_reduction ( reduction-operator : variable-list )
1000 task_reduction ( reduction-operator : variable-list ) */
1003 gfc_match_omp_clause_reduction (char pc
, gfc_omp_clauses
*c
, bool openacc
,
1006 if (pc
== 'r' && gfc_match ("reduction ( ") != MATCH_YES
)
1008 else if (pc
== 'i' && gfc_match ("in_reduction ( ") != MATCH_YES
)
1010 else if (pc
== 't' && gfc_match ("task_reduction ( ") != MATCH_YES
)
1013 locus old_loc
= gfc_current_locus
;
1016 if (pc
== 'r' && !openacc
)
1018 if (gfc_match ("inscan") == MATCH_YES
)
1019 list_idx
= OMP_LIST_REDUCTION_INSCAN
;
1020 else if (gfc_match ("task") == MATCH_YES
)
1021 list_idx
= OMP_LIST_REDUCTION_TASK
;
1022 else if (gfc_match ("default") == MATCH_YES
)
1023 list_idx
= OMP_LIST_REDUCTION
;
1024 if (list_idx
!= 0 && gfc_match (", ") != MATCH_YES
)
1026 gfc_error ("Comma expected at %C");
1027 gfc_current_locus
= old_loc
;
1031 list_idx
= OMP_LIST_REDUCTION
;
1034 list_idx
= OMP_LIST_IN_REDUCTION
;
1036 list_idx
= OMP_LIST_TASK_REDUCTION
;
1038 list_idx
= OMP_LIST_REDUCTION
;
1040 gfc_omp_reduction_op rop
= OMP_REDUCTION_NONE
;
1041 char buffer
[GFC_MAX_SYMBOL_LEN
+ 3];
1042 if (gfc_match_char ('+') == MATCH_YES
)
1043 rop
= OMP_REDUCTION_PLUS
;
1044 else if (gfc_match_char ('*') == MATCH_YES
)
1045 rop
= OMP_REDUCTION_TIMES
;
1046 else if (gfc_match_char ('-') == MATCH_YES
)
1047 rop
= OMP_REDUCTION_MINUS
;
1048 else if (gfc_match (".and.") == MATCH_YES
)
1049 rop
= OMP_REDUCTION_AND
;
1050 else if (gfc_match (".or.") == MATCH_YES
)
1051 rop
= OMP_REDUCTION_OR
;
1052 else if (gfc_match (".eqv.") == MATCH_YES
)
1053 rop
= OMP_REDUCTION_EQV
;
1054 else if (gfc_match (".neqv.") == MATCH_YES
)
1055 rop
= OMP_REDUCTION_NEQV
;
1056 if (rop
!= OMP_REDUCTION_NONE
)
1057 snprintf (buffer
, sizeof buffer
, "operator %s",
1058 gfc_op2string ((gfc_intrinsic_op
) rop
));
1059 else if (gfc_match_defined_op_name (buffer
+ 1, 1) == MATCH_YES
)
1062 strcat (buffer
, ".");
1064 else if (gfc_match_name (buffer
) == MATCH_YES
)
1067 const char *n
= buffer
;
1069 gfc_find_symbol (buffer
, NULL
, 1, &sym
);
1072 if (sym
->attr
.intrinsic
)
1074 else if ((sym
->attr
.flavor
!= FL_UNKNOWN
1075 && sym
->attr
.flavor
!= FL_PROCEDURE
)
1076 || sym
->attr
.external
1077 || sym
->attr
.generic
1081 || sym
->attr
.subroutine
1082 || sym
->attr
.pointer
1084 || sym
->attr
.cray_pointer
1085 || sym
->attr
.cray_pointee
1086 || (sym
->attr
.proc
!= PROC_UNKNOWN
1087 && sym
->attr
.proc
!= PROC_INTRINSIC
)
1088 || sym
->attr
.if_source
!= IFSRC_UNKNOWN
1089 || sym
== sym
->ns
->proc_name
)
1098 rop
= OMP_REDUCTION_NONE
;
1099 else if (strcmp (n
, "max") == 0)
1100 rop
= OMP_REDUCTION_MAX
;
1101 else if (strcmp (n
, "min") == 0)
1102 rop
= OMP_REDUCTION_MIN
;
1103 else if (strcmp (n
, "iand") == 0)
1104 rop
= OMP_REDUCTION_IAND
;
1105 else if (strcmp (n
, "ior") == 0)
1106 rop
= OMP_REDUCTION_IOR
;
1107 else if (strcmp (n
, "ieor") == 0)
1108 rop
= OMP_REDUCTION_IEOR
;
1109 if (rop
!= OMP_REDUCTION_NONE
1111 && ! sym
->attr
.intrinsic
1112 && ! sym
->attr
.use_assoc
1113 && ((sym
->attr
.flavor
== FL_UNKNOWN
1114 && !gfc_add_flavor (&sym
->attr
, FL_PROCEDURE
,
1116 || !gfc_add_intrinsic (&sym
->attr
, NULL
)))
1117 rop
= OMP_REDUCTION_NONE
;
1121 gfc_omp_udr
*udr
= (buffer
[0] ? gfc_find_omp_udr (gfc_current_ns
, buffer
, NULL
)
1123 gfc_omp_namelist
**head
= NULL
;
1124 if (rop
== OMP_REDUCTION_NONE
&& udr
)
1125 rop
= OMP_REDUCTION_USER
;
1127 if (gfc_match_omp_variable_list (" :", &c
->lists
[list_idx
], false, NULL
,
1128 &head
, openacc
, allow_derived
) != MATCH_YES
)
1130 gfc_current_locus
= old_loc
;
1133 gfc_omp_namelist
*n
;
1134 if (rop
== OMP_REDUCTION_NONE
)
1138 gfc_error_now ("!$OMP DECLARE REDUCTION %s not found at %L",
1140 gfc_free_omp_namelist (n
);
1143 for (n
= *head
; n
; n
= n
->next
)
1145 n
->u
.reduction_op
= rop
;
1148 n
->udr
= gfc_get_omp_namelist_udr ();
1155 /* Match OpenMP and OpenACC directive clauses. MASK is a bitmask of
1156 clauses that are allowed for a particular directive. */
1159 gfc_match_omp_clauses (gfc_omp_clauses
**cp
, const omp_mask mask
,
1160 bool first
= true, bool needs_space
= true,
1161 bool openacc
= false)
1163 gfc_omp_clauses
*c
= gfc_get_omp_clauses ();
1165 /* Determine whether we're dealing with an OpenACC directive that permits
1166 derived type member accesses. This in particular disallows
1167 "!$acc declare" from using such accesses, because it's not clear if/how
1168 that should work. */
1169 bool allow_derived
= (openacc
1170 && ((mask
& OMP_CLAUSE_ATTACH
)
1171 || (mask
& OMP_CLAUSE_DETACH
)
1172 || (mask
& OMP_CLAUSE_HOST_SELF
)));
1174 gcc_checking_assert (OMP_MASK1_LAST
<= 64 && OMP_MASK2_LAST
<= 64);
1178 if ((first
|| gfc_match_char (',') != MATCH_YES
)
1179 && (needs_space
&& gfc_match_space () != MATCH_YES
))
1181 needs_space
= false;
1183 gfc_gobble_whitespace ();
1185 gfc_omp_namelist
**head
;
1186 old_loc
= gfc_current_locus
;
1187 char pc
= gfc_peek_ascii_char ();
1193 if ((mask
& OMP_CLAUSE_ALIGNED
)
1194 && gfc_match_omp_variable_list ("aligned (",
1195 &c
->lists
[OMP_LIST_ALIGNED
],
1197 &head
) == MATCH_YES
)
1199 gfc_expr
*alignment
= NULL
;
1200 gfc_omp_namelist
*n
;
1202 if (end_colon
&& gfc_match (" %e )", &alignment
) != MATCH_YES
)
1204 gfc_free_omp_namelist (*head
);
1205 gfc_current_locus
= old_loc
;
1209 for (n
= *head
; n
; n
= n
->next
)
1210 if (n
->next
&& alignment
)
1211 n
->expr
= gfc_copy_expr (alignment
);
1213 n
->expr
= alignment
;
1216 if ((mask
& OMP_CLAUSE_MEMORDER
)
1217 && c
->memorder
== OMP_MEMORDER_UNSET
1218 && gfc_match ("acq_rel") == MATCH_YES
)
1220 c
->memorder
= OMP_MEMORDER_ACQ_REL
;
1224 if ((mask
& OMP_CLAUSE_MEMORDER
)
1225 && c
->memorder
== OMP_MEMORDER_UNSET
1226 && gfc_match ("acquire") == MATCH_YES
)
1228 c
->memorder
= OMP_MEMORDER_ACQUIRE
;
1232 if ((mask
& OMP_CLAUSE_ASYNC
)
1234 && gfc_match ("async") == MATCH_YES
)
1237 match m
= gfc_match (" ( %e )", &c
->async_expr
);
1238 if (m
== MATCH_ERROR
)
1240 gfc_current_locus
= old_loc
;
1243 else if (m
== MATCH_NO
)
1246 = gfc_get_constant_expr (BT_INTEGER
,
1247 gfc_default_integer_kind
,
1248 &gfc_current_locus
);
1249 mpz_set_si (c
->async_expr
->value
.integer
, GOMP_ASYNC_NOVAL
);
1254 if ((mask
& OMP_CLAUSE_AUTO
)
1256 && gfc_match ("auto") == MATCH_YES
)
1262 if ((mask
& OMP_CLAUSE_ATTACH
)
1263 && gfc_match ("attach ( ") == MATCH_YES
1264 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1265 OMP_MAP_ATTACH
, false,
1270 if ((mask
& OMP_CLAUSE_CAPTURE
)
1272 && gfc_match ("capture") == MATCH_YES
)
1278 if ((mask
& OMP_CLAUSE_COLLAPSE
)
1281 gfc_expr
*cexpr
= NULL
;
1282 match m
= gfc_match ("collapse ( %e )", &cexpr
);
1287 if (gfc_extract_int (cexpr
, &collapse
, -1))
1289 else if (collapse
<= 0)
1291 gfc_error_now ("COLLAPSE clause argument not"
1292 " constant positive integer at %C");
1295 c
->collapse
= collapse
;
1296 gfc_free_expr (cexpr
);
1300 if ((mask
& OMP_CLAUSE_COPY
)
1301 && gfc_match ("copy ( ") == MATCH_YES
1302 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1303 OMP_MAP_TOFROM
, true,
1306 if (mask
& OMP_CLAUSE_COPYIN
)
1310 if (gfc_match ("copyin ( ") == MATCH_YES
1311 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1316 else if (gfc_match_omp_variable_list ("copyin (",
1317 &c
->lists
[OMP_LIST_COPYIN
],
1321 if ((mask
& OMP_CLAUSE_COPYOUT
)
1322 && gfc_match ("copyout ( ") == MATCH_YES
1323 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1324 OMP_MAP_FROM
, true, allow_derived
))
1326 if ((mask
& OMP_CLAUSE_COPYPRIVATE
)
1327 && gfc_match_omp_variable_list ("copyprivate (",
1328 &c
->lists
[OMP_LIST_COPYPRIVATE
],
1331 if ((mask
& OMP_CLAUSE_CREATE
)
1332 && gfc_match ("create ( ") == MATCH_YES
1333 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1334 OMP_MAP_ALLOC
, true, allow_derived
))
1338 if ((mask
& OMP_CLAUSE_DEFAULT
)
1339 && c
->default_sharing
== OMP_DEFAULT_UNKNOWN
)
1341 if (gfc_match ("default ( none )") == MATCH_YES
)
1342 c
->default_sharing
= OMP_DEFAULT_NONE
;
1345 if (gfc_match ("default ( present )") == MATCH_YES
)
1346 c
->default_sharing
= OMP_DEFAULT_PRESENT
;
1350 if (gfc_match ("default ( firstprivate )") == MATCH_YES
)
1351 c
->default_sharing
= OMP_DEFAULT_FIRSTPRIVATE
;
1352 else if (gfc_match ("default ( private )") == MATCH_YES
)
1353 c
->default_sharing
= OMP_DEFAULT_PRIVATE
;
1354 else if (gfc_match ("default ( shared )") == MATCH_YES
)
1355 c
->default_sharing
= OMP_DEFAULT_SHARED
;
1357 if (c
->default_sharing
!= OMP_DEFAULT_UNKNOWN
)
1360 if ((mask
& OMP_CLAUSE_DEFAULTMAP
)
1362 && gfc_match ("defaultmap ( tofrom : scalar )") == MATCH_YES
)
1364 c
->defaultmap
= true;
1367 if ((mask
& OMP_CLAUSE_DELETE
)
1368 && gfc_match ("delete ( ") == MATCH_YES
1369 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1370 OMP_MAP_RELEASE
, true,
1373 if ((mask
& OMP_CLAUSE_DEPEND
)
1374 && gfc_match ("depend ( ") == MATCH_YES
)
1376 match m
= MATCH_YES
;
1377 gfc_omp_depend_op depend_op
= OMP_DEPEND_OUT
;
1378 if (gfc_match ("inout") == MATCH_YES
)
1379 depend_op
= OMP_DEPEND_INOUT
;
1380 else if (gfc_match ("in") == MATCH_YES
)
1381 depend_op
= OMP_DEPEND_IN
;
1382 else if (gfc_match ("out") == MATCH_YES
)
1383 depend_op
= OMP_DEPEND_OUT
;
1384 else if (!c
->depend_source
1385 && gfc_match ("source )") == MATCH_YES
)
1387 c
->depend_source
= true;
1390 else if (gfc_match ("sink : ") == MATCH_YES
)
1392 if (gfc_match_omp_depend_sink (&c
->lists
[OMP_LIST_DEPEND
])
1401 && gfc_match_omp_variable_list (" : ",
1402 &c
->lists
[OMP_LIST_DEPEND
],
1406 gfc_omp_namelist
*n
;
1407 for (n
= *head
; n
; n
= n
->next
)
1408 n
->u
.depend_op
= depend_op
;
1412 gfc_current_locus
= old_loc
;
1414 if ((mask
& OMP_CLAUSE_DETACH
)
1417 && gfc_match_omp_detach (&c
->detach
) == MATCH_YES
)
1419 if ((mask
& OMP_CLAUSE_DETACH
)
1421 && gfc_match ("detach ( ") == MATCH_YES
1422 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1423 OMP_MAP_DETACH
, false,
1426 if ((mask
& OMP_CLAUSE_DEVICE
)
1428 && c
->device
== NULL
1429 && gfc_match ("device ( %e )", &c
->device
) == MATCH_YES
)
1431 if ((mask
& OMP_CLAUSE_DEVICE
)
1433 && gfc_match ("device ( ") == MATCH_YES
1434 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1435 OMP_MAP_FORCE_TO
, true,
1438 if ((mask
& OMP_CLAUSE_DEVICEPTR
)
1439 && gfc_match ("deviceptr ( ") == MATCH_YES
1440 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1441 OMP_MAP_FORCE_DEVICEPTR
, false,
1444 if ((mask
& OMP_CLAUSE_DEVICE_TYPE
)
1445 && gfc_match ("device_type ( ") == MATCH_YES
)
1447 if (gfc_match ("host") == MATCH_YES
)
1448 c
->device_type
= OMP_DEVICE_TYPE_HOST
;
1449 else if (gfc_match ("nohost") == MATCH_YES
)
1450 c
->device_type
= OMP_DEVICE_TYPE_NOHOST
;
1451 else if (gfc_match ("any") == MATCH_YES
)
1452 c
->device_type
= OMP_DEVICE_TYPE_ANY
;
1455 gfc_error ("Expected HOST, NOHOST or ANY at %C");
1458 if (gfc_match (" )") != MATCH_YES
)
1462 if ((mask
& OMP_CLAUSE_DEVICE_RESIDENT
)
1463 && gfc_match_omp_variable_list
1464 ("device_resident (",
1465 &c
->lists
[OMP_LIST_DEVICE_RESIDENT
], true) == MATCH_YES
)
1467 if ((mask
& OMP_CLAUSE_DIST_SCHEDULE
)
1468 && c
->dist_sched_kind
== OMP_SCHED_NONE
1469 && gfc_match ("dist_schedule ( static") == MATCH_YES
)
1472 c
->dist_sched_kind
= OMP_SCHED_STATIC
;
1473 m
= gfc_match (" , %e )", &c
->dist_chunk_size
);
1475 m
= gfc_match_char (')');
1478 c
->dist_sched_kind
= OMP_SCHED_NONE
;
1479 gfc_current_locus
= old_loc
;
1486 if ((mask
& OMP_CLAUSE_FINAL
)
1487 && c
->final_expr
== NULL
1488 && gfc_match ("final ( %e )", &c
->final_expr
) == MATCH_YES
)
1490 if ((mask
& OMP_CLAUSE_FINALIZE
)
1492 && gfc_match ("finalize") == MATCH_YES
)
1498 if ((mask
& OMP_CLAUSE_FIRSTPRIVATE
)
1499 && gfc_match_omp_variable_list ("firstprivate (",
1500 &c
->lists
[OMP_LIST_FIRSTPRIVATE
],
1503 if ((mask
& OMP_CLAUSE_FROM
)
1504 && gfc_match_omp_variable_list ("from (",
1505 &c
->lists
[OMP_LIST_FROM
], false,
1506 NULL
, &head
, true) == MATCH_YES
)
1510 if ((mask
& OMP_CLAUSE_GANG
)
1512 && gfc_match ("gang") == MATCH_YES
)
1515 match m
= match_oacc_clause_gwv (c
, GOMP_DIM_GANG
);
1516 if (m
== MATCH_ERROR
)
1518 gfc_current_locus
= old_loc
;
1521 else if (m
== MATCH_NO
)
1525 if ((mask
& OMP_CLAUSE_GRAINSIZE
)
1526 && c
->grainsize
== NULL
1527 && gfc_match ("grainsize ( %e )", &c
->grainsize
) == MATCH_YES
)
1531 if ((mask
& OMP_CLAUSE_HINT
)
1533 && gfc_match ("hint ( %e )", &c
->hint
) == MATCH_YES
)
1535 if ((mask
& OMP_CLAUSE_HOST_SELF
)
1536 && gfc_match ("host ( ") == MATCH_YES
1537 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1538 OMP_MAP_FORCE_FROM
, true,
1543 if ((mask
& OMP_CLAUSE_IF
)
1544 && c
->if_expr
== NULL
1545 && gfc_match ("if ( ") == MATCH_YES
)
1549 /* This should match the enum gfc_omp_if_kind order. */
1550 static const char *ifs
[OMP_IF_LAST
] = {
1557 " target data : %e )",
1558 " target update : %e )",
1559 " target enter data : %e )",
1560 " target exit data : %e )" };
1562 for (i
= 0; i
< OMP_IF_LAST
; i
++)
1563 if (c
->if_exprs
[i
] == NULL
1564 && gfc_match (ifs
[i
], &c
->if_exprs
[i
]) == MATCH_YES
)
1566 if (i
< OMP_IF_LAST
)
1569 if (gfc_match ("%e )", &c
->if_expr
) == MATCH_YES
)
1571 gfc_current_locus
= old_loc
;
1573 if ((mask
& OMP_CLAUSE_IF_PRESENT
)
1575 && gfc_match ("if_present") == MATCH_YES
)
1577 c
->if_present
= true;
1581 if ((mask
& OMP_CLAUSE_IN_REDUCTION
)
1582 && gfc_match_omp_clause_reduction (pc
, c
, openacc
,
1583 allow_derived
) == MATCH_YES
)
1585 if ((mask
& OMP_CLAUSE_INBRANCH
)
1588 && gfc_match ("inbranch") == MATCH_YES
)
1590 c
->inbranch
= needs_space
= true;
1593 if ((mask
& OMP_CLAUSE_INDEPENDENT
)
1595 && gfc_match ("independent") == MATCH_YES
)
1597 c
->independent
= true;
1601 if ((mask
& OMP_CLAUSE_IS_DEVICE_PTR
)
1602 && gfc_match_omp_variable_list
1604 &c
->lists
[OMP_LIST_IS_DEVICE_PTR
], false) == MATCH_YES
)
1608 if ((mask
& OMP_CLAUSE_LASTPRIVATE
)
1609 && gfc_match ("lastprivate ( ") == MATCH_YES
)
1611 bool conditional
= gfc_match ("conditional : ") == MATCH_YES
;
1613 if (gfc_match_omp_variable_list ("",
1614 &c
->lists
[OMP_LIST_LASTPRIVATE
],
1615 false, NULL
, &head
) == MATCH_YES
)
1617 gfc_omp_namelist
*n
;
1618 for (n
= *head
; n
; n
= n
->next
)
1619 n
->u
.lastprivate_conditional
= conditional
;
1622 gfc_current_locus
= old_loc
;
1627 if ((mask
& OMP_CLAUSE_LINEAR
)
1628 && gfc_match ("linear (") == MATCH_YES
)
1630 gfc_omp_linear_op linear_op
= OMP_LINEAR_DEFAULT
;
1631 gfc_expr
*step
= NULL
;
1633 if (gfc_match_omp_variable_list (" ref (",
1634 &c
->lists
[OMP_LIST_LINEAR
],
1637 linear_op
= OMP_LINEAR_REF
;
1638 else if (gfc_match_omp_variable_list (" val (",
1639 &c
->lists
[OMP_LIST_LINEAR
],
1642 linear_op
= OMP_LINEAR_VAL
;
1643 else if (gfc_match_omp_variable_list (" uval (",
1644 &c
->lists
[OMP_LIST_LINEAR
],
1647 linear_op
= OMP_LINEAR_UVAL
;
1648 else if (gfc_match_omp_variable_list ("",
1649 &c
->lists
[OMP_LIST_LINEAR
],
1650 false, &end_colon
, &head
)
1652 linear_op
= OMP_LINEAR_DEFAULT
;
1655 gfc_current_locus
= old_loc
;
1658 if (linear_op
!= OMP_LINEAR_DEFAULT
)
1660 if (gfc_match (" :") == MATCH_YES
)
1662 else if (gfc_match (" )") != MATCH_YES
)
1664 gfc_free_omp_namelist (*head
);
1665 gfc_current_locus
= old_loc
;
1670 if (end_colon
&& gfc_match (" %e )", &step
) != MATCH_YES
)
1672 gfc_free_omp_namelist (*head
);
1673 gfc_current_locus
= old_loc
;
1677 else if (!end_colon
)
1679 step
= gfc_get_constant_expr (BT_INTEGER
,
1680 gfc_default_integer_kind
,
1682 mpz_set_si (step
->value
.integer
, 1);
1684 (*head
)->expr
= step
;
1685 if (linear_op
!= OMP_LINEAR_DEFAULT
)
1686 for (gfc_omp_namelist
*n
= *head
; n
; n
= n
->next
)
1687 n
->u
.linear_op
= linear_op
;
1690 if ((mask
& OMP_CLAUSE_LINK
)
1692 && (gfc_match_oacc_clause_link ("link (",
1693 &c
->lists
[OMP_LIST_LINK
])
1696 else if ((mask
& OMP_CLAUSE_LINK
)
1698 && (gfc_match_omp_to_link ("link (",
1699 &c
->lists
[OMP_LIST_LINK
])
1704 if ((mask
& OMP_CLAUSE_MAP
)
1705 && gfc_match ("map ( ") == MATCH_YES
)
1707 locus old_loc2
= gfc_current_locus
;
1708 bool always
= false;
1709 gfc_omp_map_op map_op
= OMP_MAP_TOFROM
;
1710 if (gfc_match ("always , ") == MATCH_YES
)
1712 if (gfc_match ("alloc : ") == MATCH_YES
)
1713 map_op
= OMP_MAP_ALLOC
;
1714 else if (gfc_match ("tofrom : ") == MATCH_YES
)
1715 map_op
= always
? OMP_MAP_ALWAYS_TOFROM
: OMP_MAP_TOFROM
;
1716 else if (gfc_match ("to : ") == MATCH_YES
)
1717 map_op
= always
? OMP_MAP_ALWAYS_TO
: OMP_MAP_TO
;
1718 else if (gfc_match ("from : ") == MATCH_YES
)
1719 map_op
= always
? OMP_MAP_ALWAYS_FROM
: OMP_MAP_FROM
;
1720 else if (gfc_match ("release : ") == MATCH_YES
)
1721 map_op
= OMP_MAP_RELEASE
;
1722 else if (gfc_match ("delete : ") == MATCH_YES
)
1723 map_op
= OMP_MAP_DELETE
;
1726 gfc_current_locus
= old_loc2
;
1730 if (gfc_match_omp_variable_list ("", &c
->lists
[OMP_LIST_MAP
],
1732 true, true) == MATCH_YES
)
1734 gfc_omp_namelist
*n
;
1735 for (n
= *head
; n
; n
= n
->next
)
1736 n
->u
.map_op
= map_op
;
1740 gfc_current_locus
= old_loc
;
1742 if ((mask
& OMP_CLAUSE_MERGEABLE
) && !c
->mergeable
1743 && gfc_match ("mergeable") == MATCH_YES
)
1745 c
->mergeable
= needs_space
= true;
1750 if ((mask
& OMP_CLAUSE_NO_CREATE
)
1751 && gfc_match ("no_create ( ") == MATCH_YES
1752 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1753 OMP_MAP_IF_PRESENT
, true,
1756 if ((mask
& OMP_CLAUSE_NOGROUP
)
1758 && gfc_match ("nogroup") == MATCH_YES
)
1760 c
->nogroup
= needs_space
= true;
1763 if ((mask
& OMP_CLAUSE_NOTEMPORAL
)
1764 && gfc_match_omp_variable_list ("nontemporal (",
1765 &c
->lists
[OMP_LIST_NONTEMPORAL
],
1768 if ((mask
& OMP_CLAUSE_NOTINBRANCH
)
1771 && gfc_match ("notinbranch") == MATCH_YES
)
1773 c
->notinbranch
= needs_space
= true;
1776 if ((mask
& OMP_CLAUSE_NOWAIT
)
1778 && gfc_match ("nowait") == MATCH_YES
)
1780 c
->nowait
= needs_space
= true;
1783 if ((mask
& OMP_CLAUSE_NUM_GANGS
)
1784 && c
->num_gangs_expr
== NULL
1785 && gfc_match ("num_gangs ( %e )",
1786 &c
->num_gangs_expr
) == MATCH_YES
)
1788 if ((mask
& OMP_CLAUSE_NUM_TASKS
)
1789 && c
->num_tasks
== NULL
1790 && gfc_match ("num_tasks ( %e )", &c
->num_tasks
) == MATCH_YES
)
1792 if ((mask
& OMP_CLAUSE_NUM_TEAMS
)
1793 && c
->num_teams
== NULL
1794 && gfc_match ("num_teams ( %e )", &c
->num_teams
) == MATCH_YES
)
1796 if ((mask
& OMP_CLAUSE_NUM_THREADS
)
1797 && c
->num_threads
== NULL
1798 && (gfc_match ("num_threads ( %e )", &c
->num_threads
)
1801 if ((mask
& OMP_CLAUSE_NUM_WORKERS
)
1802 && c
->num_workers_expr
== NULL
1803 && gfc_match ("num_workers ( %e )",
1804 &c
->num_workers_expr
) == MATCH_YES
)
1808 if ((mask
& OMP_CLAUSE_ORDER
)
1809 && !c
->order_concurrent
1810 && gfc_match ("order ( concurrent )") == MATCH_YES
)
1812 c
->order_concurrent
= true;
1815 if ((mask
& OMP_CLAUSE_ORDERED
)
1817 && gfc_match ("ordered") == MATCH_YES
)
1819 gfc_expr
*cexpr
= NULL
;
1820 match m
= gfc_match (" ( %e )", &cexpr
);
1826 if (gfc_extract_int (cexpr
, &ordered
, -1))
1828 else if (ordered
<= 0)
1830 gfc_error_now ("ORDERED clause argument not"
1831 " constant positive integer at %C");
1834 c
->orderedc
= ordered
;
1835 gfc_free_expr (cexpr
);
1844 if ((mask
& OMP_CLAUSE_COPY
)
1845 && gfc_match ("pcopy ( ") == MATCH_YES
1846 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1847 OMP_MAP_TOFROM
, true, allow_derived
))
1849 if ((mask
& OMP_CLAUSE_COPYIN
)
1850 && gfc_match ("pcopyin ( ") == MATCH_YES
1851 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1852 OMP_MAP_TO
, true, allow_derived
))
1854 if ((mask
& OMP_CLAUSE_COPYOUT
)
1855 && gfc_match ("pcopyout ( ") == MATCH_YES
1856 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1857 OMP_MAP_FROM
, true, allow_derived
))
1859 if ((mask
& OMP_CLAUSE_CREATE
)
1860 && gfc_match ("pcreate ( ") == MATCH_YES
1861 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1862 OMP_MAP_ALLOC
, true, allow_derived
))
1864 if ((mask
& OMP_CLAUSE_PRESENT
)
1865 && gfc_match ("present ( ") == MATCH_YES
1866 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1867 OMP_MAP_FORCE_PRESENT
, false,
1870 if ((mask
& OMP_CLAUSE_COPY
)
1871 && gfc_match ("present_or_copy ( ") == MATCH_YES
1872 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1873 OMP_MAP_TOFROM
, true,
1876 if ((mask
& OMP_CLAUSE_COPYIN
)
1877 && gfc_match ("present_or_copyin ( ") == MATCH_YES
1878 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1879 OMP_MAP_TO
, true, allow_derived
))
1881 if ((mask
& OMP_CLAUSE_COPYOUT
)
1882 && gfc_match ("present_or_copyout ( ") == MATCH_YES
1883 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1884 OMP_MAP_FROM
, true, allow_derived
))
1886 if ((mask
& OMP_CLAUSE_CREATE
)
1887 && gfc_match ("present_or_create ( ") == MATCH_YES
1888 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1889 OMP_MAP_ALLOC
, true, allow_derived
))
1891 if ((mask
& OMP_CLAUSE_PRIORITY
)
1892 && c
->priority
== NULL
1893 && gfc_match ("priority ( %e )", &c
->priority
) == MATCH_YES
)
1895 if ((mask
& OMP_CLAUSE_PRIVATE
)
1896 && gfc_match_omp_variable_list ("private (",
1897 &c
->lists
[OMP_LIST_PRIVATE
],
1900 if ((mask
& OMP_CLAUSE_PROC_BIND
)
1901 && c
->proc_bind
== OMP_PROC_BIND_UNKNOWN
)
1903 if (gfc_match ("proc_bind ( master )") == MATCH_YES
)
1904 c
->proc_bind
= OMP_PROC_BIND_MASTER
;
1905 else if (gfc_match ("proc_bind ( spread )") == MATCH_YES
)
1906 c
->proc_bind
= OMP_PROC_BIND_SPREAD
;
1907 else if (gfc_match ("proc_bind ( close )") == MATCH_YES
)
1908 c
->proc_bind
= OMP_PROC_BIND_CLOSE
;
1909 if (c
->proc_bind
!= OMP_PROC_BIND_UNKNOWN
)
1914 if ((mask
& OMP_CLAUSE_ATOMIC
)
1915 && c
->atomic_op
== GFC_OMP_ATOMIC_UNSET
1916 && gfc_match ("read") == MATCH_YES
)
1918 c
->atomic_op
= GFC_OMP_ATOMIC_READ
;
1922 if ((mask
& OMP_CLAUSE_REDUCTION
)
1923 && gfc_match_omp_clause_reduction (pc
, c
, openacc
,
1924 allow_derived
) == MATCH_YES
)
1926 if ((mask
& OMP_CLAUSE_MEMORDER
)
1927 && c
->memorder
== OMP_MEMORDER_UNSET
1928 && gfc_match ("relaxed") == MATCH_YES
)
1930 c
->memorder
= OMP_MEMORDER_RELAXED
;
1934 if ((mask
& OMP_CLAUSE_MEMORDER
)
1935 && c
->memorder
== OMP_MEMORDER_UNSET
1936 && gfc_match ("release") == MATCH_YES
)
1938 c
->memorder
= OMP_MEMORDER_RELEASE
;
1942 if ((mask
& OMP_CLAUSE_MEMORDER
)
1943 && c
->memorder
== OMP_MEMORDER_UNSET
1944 && gfc_match ("relaxed") == MATCH_YES
)
1946 c
->memorder
= OMP_MEMORDER_RELAXED
;
1950 if ((mask
& OMP_CLAUSE_MEMORDER
)
1951 && c
->memorder
== OMP_MEMORDER_UNSET
1952 && gfc_match ("release") == MATCH_YES
)
1954 c
->memorder
= OMP_MEMORDER_RELEASE
;
1960 if ((mask
& OMP_CLAUSE_SAFELEN
)
1961 && c
->safelen_expr
== NULL
1962 && gfc_match ("safelen ( %e )", &c
->safelen_expr
) == MATCH_YES
)
1964 if ((mask
& OMP_CLAUSE_SCHEDULE
)
1965 && c
->sched_kind
== OMP_SCHED_NONE
1966 && gfc_match ("schedule ( ") == MATCH_YES
)
1969 locus old_loc2
= gfc_current_locus
;
1972 if (gfc_match ("simd") == MATCH_YES
)
1974 c
->sched_simd
= true;
1977 else if (gfc_match ("monotonic") == MATCH_YES
)
1979 c
->sched_monotonic
= true;
1982 else if (gfc_match ("nonmonotonic") == MATCH_YES
)
1984 c
->sched_nonmonotonic
= true;
1990 gfc_current_locus
= old_loc2
;
1994 && gfc_match (" , ") == MATCH_YES
)
1996 else if (gfc_match (" : ") == MATCH_YES
)
1998 gfc_current_locus
= old_loc2
;
2002 if (gfc_match ("static") == MATCH_YES
)
2003 c
->sched_kind
= OMP_SCHED_STATIC
;
2004 else if (gfc_match ("dynamic") == MATCH_YES
)
2005 c
->sched_kind
= OMP_SCHED_DYNAMIC
;
2006 else if (gfc_match ("guided") == MATCH_YES
)
2007 c
->sched_kind
= OMP_SCHED_GUIDED
;
2008 else if (gfc_match ("runtime") == MATCH_YES
)
2009 c
->sched_kind
= OMP_SCHED_RUNTIME
;
2010 else if (gfc_match ("auto") == MATCH_YES
)
2011 c
->sched_kind
= OMP_SCHED_AUTO
;
2012 if (c
->sched_kind
!= OMP_SCHED_NONE
)
2015 if (c
->sched_kind
!= OMP_SCHED_RUNTIME
2016 && c
->sched_kind
!= OMP_SCHED_AUTO
)
2017 m
= gfc_match (" , %e )", &c
->chunk_size
);
2019 m
= gfc_match_char (')');
2021 c
->sched_kind
= OMP_SCHED_NONE
;
2023 if (c
->sched_kind
!= OMP_SCHED_NONE
)
2026 gfc_current_locus
= old_loc
;
2028 if ((mask
& OMP_CLAUSE_HOST_SELF
)
2029 && gfc_match ("self ( ") == MATCH_YES
2030 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
2031 OMP_MAP_FORCE_FROM
, true,
2034 if ((mask
& OMP_CLAUSE_SEQ
)
2036 && gfc_match ("seq") == MATCH_YES
)
2042 if ((mask
& OMP_CLAUSE_MEMORDER
)
2043 && c
->memorder
== OMP_MEMORDER_UNSET
2044 && gfc_match ("seq_cst") == MATCH_YES
)
2046 c
->memorder
= OMP_MEMORDER_SEQ_CST
;
2050 if ((mask
& OMP_CLAUSE_SHARED
)
2051 && gfc_match_omp_variable_list ("shared (",
2052 &c
->lists
[OMP_LIST_SHARED
],
2055 if ((mask
& OMP_CLAUSE_SIMDLEN
)
2056 && c
->simdlen_expr
== NULL
2057 && gfc_match ("simdlen ( %e )", &c
->simdlen_expr
) == MATCH_YES
)
2059 if ((mask
& OMP_CLAUSE_SIMD
)
2061 && gfc_match ("simd") == MATCH_YES
)
2063 c
->simd
= needs_space
= true;
2068 if ((mask
& OMP_CLAUSE_TASK_REDUCTION
)
2069 && gfc_match_omp_clause_reduction (pc
, c
, openacc
,
2070 allow_derived
) == MATCH_YES
)
2072 if ((mask
& OMP_CLAUSE_THREAD_LIMIT
)
2073 && c
->thread_limit
== NULL
2074 && gfc_match ("thread_limit ( %e )",
2075 &c
->thread_limit
) == MATCH_YES
)
2077 if ((mask
& OMP_CLAUSE_THREADS
)
2079 && gfc_match ("threads") == MATCH_YES
)
2081 c
->threads
= needs_space
= true;
2084 if ((mask
& OMP_CLAUSE_TILE
)
2086 && match_oacc_expr_list ("tile (", &c
->tile_list
,
2089 if ((mask
& OMP_CLAUSE_TO
) && (mask
& OMP_CLAUSE_LINK
))
2091 if (gfc_match_omp_to_link ("to (", &c
->lists
[OMP_LIST_TO
])
2095 else if ((mask
& OMP_CLAUSE_TO
)
2096 && gfc_match_omp_variable_list ("to (",
2097 &c
->lists
[OMP_LIST_TO
], false,
2098 NULL
, &head
, true) == MATCH_YES
)
2102 if ((mask
& OMP_CLAUSE_UNIFORM
)
2103 && gfc_match_omp_variable_list ("uniform (",
2104 &c
->lists
[OMP_LIST_UNIFORM
],
2105 false) == MATCH_YES
)
2107 if ((mask
& OMP_CLAUSE_UNTIED
)
2109 && gfc_match ("untied") == MATCH_YES
)
2111 c
->untied
= needs_space
= true;
2114 if ((mask
& OMP_CLAUSE_ATOMIC
)
2115 && c
->atomic_op
== GFC_OMP_ATOMIC_UNSET
2116 && gfc_match ("update") == MATCH_YES
)
2118 c
->atomic_op
= GFC_OMP_ATOMIC_UPDATE
;
2122 if ((mask
& OMP_CLAUSE_USE_DEVICE
)
2123 && gfc_match_omp_variable_list ("use_device (",
2124 &c
->lists
[OMP_LIST_USE_DEVICE
],
2127 if ((mask
& OMP_CLAUSE_USE_DEVICE_PTR
)
2128 && gfc_match_omp_variable_list
2129 ("use_device_ptr (",
2130 &c
->lists
[OMP_LIST_USE_DEVICE_PTR
], false) == MATCH_YES
)
2132 if ((mask
& OMP_CLAUSE_USE_DEVICE_ADDR
)
2133 && gfc_match_omp_variable_list
2134 ("use_device_addr (",
2135 &c
->lists
[OMP_LIST_USE_DEVICE_ADDR
], false) == MATCH_YES
)
2139 /* VECTOR_LENGTH must be matched before VECTOR, because the latter
2140 doesn't unconditionally match '('. */
2141 if ((mask
& OMP_CLAUSE_VECTOR_LENGTH
)
2142 && c
->vector_length_expr
== NULL
2143 && (gfc_match ("vector_length ( %e )", &c
->vector_length_expr
)
2146 if ((mask
& OMP_CLAUSE_VECTOR
)
2148 && gfc_match ("vector") == MATCH_YES
)
2151 match m
= match_oacc_clause_gwv (c
, GOMP_DIM_VECTOR
);
2152 if (m
== MATCH_ERROR
)
2154 gfc_current_locus
= old_loc
;
2163 if ((mask
& OMP_CLAUSE_WAIT
)
2164 && gfc_match ("wait") == MATCH_YES
)
2166 match m
= match_oacc_expr_list (" (", &c
->wait_list
, false);
2167 if (m
== MATCH_ERROR
)
2169 gfc_current_locus
= old_loc
;
2172 else if (m
== MATCH_NO
)
2175 = gfc_get_constant_expr (BT_INTEGER
,
2176 gfc_default_integer_kind
,
2177 &gfc_current_locus
);
2178 mpz_set_si (expr
->value
.integer
, GOMP_ASYNC_NOVAL
);
2179 gfc_expr_list
**expr_list
= &c
->wait_list
;
2181 expr_list
= &(*expr_list
)->next
;
2182 *expr_list
= gfc_get_expr_list ();
2183 (*expr_list
)->expr
= expr
;
2188 if ((mask
& OMP_CLAUSE_WORKER
)
2190 && gfc_match ("worker") == MATCH_YES
)
2193 match m
= match_oacc_clause_gwv (c
, GOMP_DIM_WORKER
);
2194 if (m
== MATCH_ERROR
)
2196 gfc_current_locus
= old_loc
;
2199 else if (m
== MATCH_NO
)
2203 if ((mask
& OMP_CLAUSE_ATOMIC
)
2204 && c
->atomic_op
== GFC_OMP_ATOMIC_UNSET
2205 && gfc_match ("write") == MATCH_YES
)
2207 c
->atomic_op
= GFC_OMP_ATOMIC_WRITE
;
2216 if (gfc_match_omp_eos () != MATCH_YES
)
2218 if (!gfc_error_flag_test ())
2219 gfc_error ("Failed to match clause at %C");
2220 gfc_free_omp_clauses (c
);
2229 #define OACC_PARALLEL_CLAUSES \
2230 (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_NUM_GANGS \
2231 | OMP_CLAUSE_NUM_WORKERS | OMP_CLAUSE_VECTOR_LENGTH | OMP_CLAUSE_REDUCTION \
2232 | OMP_CLAUSE_COPY | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT \
2233 | OMP_CLAUSE_CREATE | OMP_CLAUSE_NO_CREATE | OMP_CLAUSE_PRESENT \
2234 | OMP_CLAUSE_DEVICEPTR | OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE \
2235 | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_WAIT | OMP_CLAUSE_ATTACH)
2236 #define OACC_KERNELS_CLAUSES \
2237 (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_NUM_GANGS \
2238 | OMP_CLAUSE_NUM_WORKERS | OMP_CLAUSE_VECTOR_LENGTH | OMP_CLAUSE_DEVICEPTR \
2239 | OMP_CLAUSE_COPY | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT \
2240 | OMP_CLAUSE_CREATE | OMP_CLAUSE_NO_CREATE | OMP_CLAUSE_PRESENT \
2241 | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_WAIT | OMP_CLAUSE_ATTACH)
2242 #define OACC_SERIAL_CLAUSES \
2243 (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_REDUCTION \
2244 | OMP_CLAUSE_COPY | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT \
2245 | OMP_CLAUSE_CREATE | OMP_CLAUSE_NO_CREATE | OMP_CLAUSE_PRESENT \
2246 | OMP_CLAUSE_DEVICEPTR | OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE \
2247 | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_WAIT | OMP_CLAUSE_ATTACH)
2248 #define OACC_DATA_CLAUSES \
2249 (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_DEVICEPTR | OMP_CLAUSE_COPY \
2250 | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT | OMP_CLAUSE_CREATE \
2251 | OMP_CLAUSE_NO_CREATE | OMP_CLAUSE_PRESENT | OMP_CLAUSE_ATTACH)
2252 #define OACC_LOOP_CLAUSES \
2253 (omp_mask (OMP_CLAUSE_COLLAPSE) | OMP_CLAUSE_GANG | OMP_CLAUSE_WORKER \
2254 | OMP_CLAUSE_VECTOR | OMP_CLAUSE_SEQ | OMP_CLAUSE_INDEPENDENT \
2255 | OMP_CLAUSE_PRIVATE | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_AUTO \
2257 #define OACC_PARALLEL_LOOP_CLAUSES \
2258 (OACC_LOOP_CLAUSES | OACC_PARALLEL_CLAUSES)
2259 #define OACC_KERNELS_LOOP_CLAUSES \
2260 (OACC_LOOP_CLAUSES | OACC_KERNELS_CLAUSES)
2261 #define OACC_SERIAL_LOOP_CLAUSES \
2262 (OACC_LOOP_CLAUSES | OACC_SERIAL_CLAUSES)
2263 #define OACC_HOST_DATA_CLAUSES \
2264 (omp_mask (OMP_CLAUSE_USE_DEVICE) \
2266 | OMP_CLAUSE_IF_PRESENT)
2267 #define OACC_DECLARE_CLAUSES \
2268 (omp_mask (OMP_CLAUSE_COPY) | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT \
2269 | OMP_CLAUSE_CREATE | OMP_CLAUSE_DEVICEPTR | OMP_CLAUSE_DEVICE_RESIDENT \
2270 | OMP_CLAUSE_PRESENT \
2272 #define OACC_UPDATE_CLAUSES \
2273 (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_HOST_SELF \
2274 | OMP_CLAUSE_DEVICE | OMP_CLAUSE_WAIT | OMP_CLAUSE_IF_PRESENT)
2275 #define OACC_ENTER_DATA_CLAUSES \
2276 (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_WAIT \
2277 | OMP_CLAUSE_COPYIN | OMP_CLAUSE_CREATE | OMP_CLAUSE_ATTACH)
2278 #define OACC_EXIT_DATA_CLAUSES \
2279 (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_ASYNC | OMP_CLAUSE_WAIT \
2280 | OMP_CLAUSE_COPYOUT | OMP_CLAUSE_DELETE | OMP_CLAUSE_FINALIZE \
2281 | OMP_CLAUSE_DETACH)
2282 #define OACC_WAIT_CLAUSES \
2283 omp_mask (OMP_CLAUSE_ASYNC)
2284 #define OACC_ROUTINE_CLAUSES \
2285 (omp_mask (OMP_CLAUSE_GANG) | OMP_CLAUSE_WORKER | OMP_CLAUSE_VECTOR \
2290 match_acc (gfc_exec_op op
, const omp_mask mask
)
2293 if (gfc_match_omp_clauses (&c
, mask
, false, false, true) != MATCH_YES
)
2296 new_st
.ext
.omp_clauses
= c
;
2301 gfc_match_oacc_parallel_loop (void)
2303 return match_acc (EXEC_OACC_PARALLEL_LOOP
, OACC_PARALLEL_LOOP_CLAUSES
);
2308 gfc_match_oacc_parallel (void)
2310 return match_acc (EXEC_OACC_PARALLEL
, OACC_PARALLEL_CLAUSES
);
2315 gfc_match_oacc_kernels_loop (void)
2317 return match_acc (EXEC_OACC_KERNELS_LOOP
, OACC_KERNELS_LOOP_CLAUSES
);
2322 gfc_match_oacc_kernels (void)
2324 return match_acc (EXEC_OACC_KERNELS
, OACC_KERNELS_CLAUSES
);
2329 gfc_match_oacc_serial_loop (void)
2331 return match_acc (EXEC_OACC_SERIAL_LOOP
, OACC_SERIAL_LOOP_CLAUSES
);
2336 gfc_match_oacc_serial (void)
2338 return match_acc (EXEC_OACC_SERIAL
, OACC_SERIAL_CLAUSES
);
2343 gfc_match_oacc_data (void)
2345 return match_acc (EXEC_OACC_DATA
, OACC_DATA_CLAUSES
);
2350 gfc_match_oacc_host_data (void)
2352 return match_acc (EXEC_OACC_HOST_DATA
, OACC_HOST_DATA_CLAUSES
);
2357 gfc_match_oacc_loop (void)
2359 return match_acc (EXEC_OACC_LOOP
, OACC_LOOP_CLAUSES
);
2364 gfc_match_oacc_declare (void)
2367 gfc_omp_namelist
*n
;
2368 gfc_namespace
*ns
= gfc_current_ns
;
2369 gfc_oacc_declare
*new_oc
;
2370 bool module_var
= false;
2371 locus where
= gfc_current_locus
;
2373 if (gfc_match_omp_clauses (&c
, OACC_DECLARE_CLAUSES
, false, false, true)
2377 for (n
= c
->lists
[OMP_LIST_DEVICE_RESIDENT
]; n
!= NULL
; n
= n
->next
)
2378 n
->sym
->attr
.oacc_declare_device_resident
= 1;
2380 for (n
= c
->lists
[OMP_LIST_LINK
]; n
!= NULL
; n
= n
->next
)
2381 n
->sym
->attr
.oacc_declare_link
= 1;
2383 for (n
= c
->lists
[OMP_LIST_MAP
]; n
!= NULL
; n
= n
->next
)
2385 gfc_symbol
*s
= n
->sym
;
2387 if (gfc_current_ns
->proc_name
2388 && gfc_current_ns
->proc_name
->attr
.flavor
== FL_MODULE
)
2390 if (n
->u
.map_op
!= OMP_MAP_ALLOC
&& n
->u
.map_op
!= OMP_MAP_TO
)
2392 gfc_error ("Invalid clause in module with !$ACC DECLARE at %L",
2400 if (s
->attr
.use_assoc
)
2402 gfc_error ("Variable is USE-associated with !$ACC DECLARE at %L",
2407 if ((s
->result
== s
&& s
->ns
->contained
!= gfc_current_ns
)
2408 || ((s
->attr
.flavor
== FL_UNKNOWN
|| s
->attr
.flavor
== FL_VARIABLE
)
2409 && s
->ns
!= gfc_current_ns
))
2411 gfc_error ("Variable %qs shall be declared in the same scoping unit "
2412 "as !$ACC DECLARE at %L", s
->name
, &where
);
2416 if ((s
->attr
.dimension
|| s
->attr
.codimension
)
2417 && s
->attr
.dummy
&& s
->as
->type
!= AS_EXPLICIT
)
2419 gfc_error ("Assumed-size dummy array with !$ACC DECLARE at %L",
2424 switch (n
->u
.map_op
)
2426 case OMP_MAP_FORCE_ALLOC
:
2428 s
->attr
.oacc_declare_create
= 1;
2431 case OMP_MAP_FORCE_TO
:
2433 s
->attr
.oacc_declare_copyin
= 1;
2436 case OMP_MAP_FORCE_DEVICEPTR
:
2437 s
->attr
.oacc_declare_deviceptr
= 1;
2445 new_oc
= gfc_get_oacc_declare ();
2446 new_oc
->next
= ns
->oacc_declare
;
2447 new_oc
->module_var
= module_var
;
2448 new_oc
->clauses
= c
;
2449 new_oc
->loc
= gfc_current_locus
;
2450 ns
->oacc_declare
= new_oc
;
2457 gfc_match_oacc_update (void)
2460 locus here
= gfc_current_locus
;
2462 if (gfc_match_omp_clauses (&c
, OACC_UPDATE_CLAUSES
, false, false, true)
2466 if (!c
->lists
[OMP_LIST_MAP
])
2468 gfc_error ("%<acc update%> must contain at least one "
2469 "%<device%> or %<host%> or %<self%> clause at %L", &here
);
2473 new_st
.op
= EXEC_OACC_UPDATE
;
2474 new_st
.ext
.omp_clauses
= c
;
2480 gfc_match_oacc_enter_data (void)
2482 return match_acc (EXEC_OACC_ENTER_DATA
, OACC_ENTER_DATA_CLAUSES
);
2487 gfc_match_oacc_exit_data (void)
2489 return match_acc (EXEC_OACC_EXIT_DATA
, OACC_EXIT_DATA_CLAUSES
);
2494 gfc_match_oacc_wait (void)
2496 gfc_omp_clauses
*c
= gfc_get_omp_clauses ();
2497 gfc_expr_list
*wait_list
= NULL
, *el
;
2501 m
= match_oacc_expr_list (" (", &wait_list
, true);
2502 if (m
== MATCH_ERROR
)
2504 else if (m
== MATCH_YES
)
2507 if (gfc_match_omp_clauses (&c
, OACC_WAIT_CLAUSES
, space
, space
, true)
2512 for (el
= wait_list
; el
; el
= el
->next
)
2514 if (el
->expr
== NULL
)
2516 gfc_error ("Invalid argument to !$ACC WAIT at %C");
2520 if (!gfc_resolve_expr (el
->expr
)
2521 || el
->expr
->ts
.type
!= BT_INTEGER
|| el
->expr
->rank
!= 0)
2523 gfc_error ("WAIT clause at %L requires a scalar INTEGER expression",
2529 c
->wait_list
= wait_list
;
2530 new_st
.op
= EXEC_OACC_WAIT
;
2531 new_st
.ext
.omp_clauses
= c
;
2537 gfc_match_oacc_cache (void)
2539 gfc_omp_clauses
*c
= gfc_get_omp_clauses ();
2540 /* The OpenACC cache directive explicitly only allows "array elements or
2541 subarrays", which we're currently not checking here. Either check this
2542 after the call of gfc_match_omp_variable_list, or add something like a
2543 only_sections variant next to its allow_sections parameter. */
2544 match m
= gfc_match_omp_variable_list (" (",
2545 &c
->lists
[OMP_LIST_CACHE
], true,
2549 gfc_free_omp_clauses(c
);
2553 if (gfc_current_state() != COMP_DO
2554 && gfc_current_state() != COMP_DO_CONCURRENT
)
2556 gfc_error ("ACC CACHE directive must be inside of loop %C");
2557 gfc_free_omp_clauses(c
);
2561 new_st
.op
= EXEC_OACC_CACHE
;
2562 new_st
.ext
.omp_clauses
= c
;
2566 /* Determine the OpenACC 'routine' directive's level of parallelism. */
2568 static oacc_routine_lop
2569 gfc_oacc_routine_lop (gfc_omp_clauses
*clauses
)
2571 oacc_routine_lop ret
= OACC_ROUTINE_LOP_SEQ
;
2575 unsigned n_lop_clauses
= 0;
2580 ret
= OACC_ROUTINE_LOP_GANG
;
2582 if (clauses
->worker
)
2585 ret
= OACC_ROUTINE_LOP_WORKER
;
2587 if (clauses
->vector
)
2590 ret
= OACC_ROUTINE_LOP_VECTOR
;
2595 ret
= OACC_ROUTINE_LOP_SEQ
;
2598 if (n_lop_clauses
> 1)
2599 ret
= OACC_ROUTINE_LOP_ERROR
;
2606 gfc_match_oacc_routine (void)
2610 gfc_intrinsic_sym
*isym
= NULL
;
2611 gfc_symbol
*sym
= NULL
;
2612 gfc_omp_clauses
*c
= NULL
;
2613 gfc_oacc_routine_name
*n
= NULL
;
2614 oacc_routine_lop lop
= OACC_ROUTINE_LOP_NONE
;
2616 old_loc
= gfc_current_locus
;
2618 m
= gfc_match (" (");
2620 if (gfc_current_ns
->proc_name
2621 && gfc_current_ns
->proc_name
->attr
.if_source
== IFSRC_IFBODY
2624 gfc_error ("Only the !$ACC ROUTINE form without "
2625 "list is allowed in interface block at %C");
2631 char buffer
[GFC_MAX_SYMBOL_LEN
+ 1];
2633 m
= gfc_match_name (buffer
);
2636 gfc_symtree
*st
= NULL
;
2638 /* First look for an intrinsic symbol. */
2639 isym
= gfc_find_function (buffer
);
2641 isym
= gfc_find_subroutine (buffer
);
2642 /* If no intrinsic symbol found, search the current namespace. */
2644 st
= gfc_find_symtree (gfc_current_ns
->sym_root
, buffer
);
2648 /* If the name in a 'routine' directive refers to the containing
2649 subroutine or function, then make sure that we'll later handle
2650 this accordingly. */
2651 if (gfc_current_ns
->proc_name
!= NULL
2652 && strcmp (sym
->name
, gfc_current_ns
->proc_name
->name
) == 0)
2656 if (isym
== NULL
&& st
== NULL
)
2658 gfc_error ("Invalid NAME %qs in !$ACC ROUTINE ( NAME ) at %C",
2660 gfc_current_locus
= old_loc
;
2666 gfc_error ("Syntax error in !$ACC ROUTINE ( NAME ) at %C");
2667 gfc_current_locus
= old_loc
;
2671 if (gfc_match_char (')') != MATCH_YES
)
2673 gfc_error ("Syntax error in !$ACC ROUTINE ( NAME ) at %C, expecting"
2675 gfc_current_locus
= old_loc
;
2680 if (gfc_match_omp_eos () != MATCH_YES
2681 && (gfc_match_omp_clauses (&c
, OACC_ROUTINE_CLAUSES
, false, false, true)
2685 lop
= gfc_oacc_routine_lop (c
);
2686 if (lop
== OACC_ROUTINE_LOP_ERROR
)
2688 gfc_error ("Multiple loop axes specified for routine at %C");
2694 /* Diagnose any OpenACC 'routine' directive that doesn't match the
2695 (implicit) one with a 'seq' clause. */
2696 if (c
&& (c
->gang
|| c
->worker
|| c
->vector
))
2698 gfc_error ("Intrinsic symbol specified in !$ACC ROUTINE ( NAME )"
2699 " at %C marked with incompatible GANG, WORKER, or VECTOR"
2704 else if (sym
!= NULL
)
2708 /* For a repeated OpenACC 'routine' directive, diagnose if it doesn't
2709 match the first one. */
2710 for (gfc_oacc_routine_name
*n_p
= gfc_current_ns
->oacc_routine_names
;
2713 if (n_p
->sym
== sym
)
2716 if (lop
!= gfc_oacc_routine_lop (n_p
->clauses
))
2718 gfc_error ("!$ACC ROUTINE already applied at %C");
2725 sym
->attr
.oacc_routine_lop
= lop
;
2727 n
= gfc_get_oacc_routine_name ();
2730 n
->next
= gfc_current_ns
->oacc_routine_names
;
2732 gfc_current_ns
->oacc_routine_names
= n
;
2735 else if (gfc_current_ns
->proc_name
)
2737 /* For a repeated OpenACC 'routine' directive, diagnose if it doesn't
2738 match the first one. */
2739 oacc_routine_lop lop_p
= gfc_current_ns
->proc_name
->attr
.oacc_routine_lop
;
2740 if (lop_p
!= OACC_ROUTINE_LOP_NONE
2743 gfc_error ("!$ACC ROUTINE already applied at %C");
2747 if (!gfc_add_omp_declare_target (&gfc_current_ns
->proc_name
->attr
,
2748 gfc_current_ns
->proc_name
->name
,
2751 gfc_current_ns
->proc_name
->attr
.oacc_routine_lop
= lop
;
2754 /* Something has gone wrong, possibly a syntax error. */
2757 if (gfc_pure (NULL
) && c
&& (c
->gang
|| c
->worker
|| c
->vector
))
2759 gfc_error ("!$ACC ROUTINE with GANG, WORKER, or VECTOR clause is not "
2760 "permitted in PURE procedure at %C");
2767 else if (gfc_current_ns
->oacc_routine
)
2768 gfc_current_ns
->oacc_routine_clauses
= c
;
2770 new_st
.op
= EXEC_OACC_ROUTINE
;
2771 new_st
.ext
.omp_clauses
= c
;
2775 gfc_current_locus
= old_loc
;
2780 #define OMP_PARALLEL_CLAUSES \
2781 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \
2782 | OMP_CLAUSE_SHARED | OMP_CLAUSE_COPYIN | OMP_CLAUSE_REDUCTION \
2783 | OMP_CLAUSE_IF | OMP_CLAUSE_NUM_THREADS | OMP_CLAUSE_DEFAULT \
2784 | OMP_CLAUSE_PROC_BIND)
2785 #define OMP_DECLARE_SIMD_CLAUSES \
2786 (omp_mask (OMP_CLAUSE_SIMDLEN) | OMP_CLAUSE_LINEAR \
2787 | OMP_CLAUSE_UNIFORM | OMP_CLAUSE_ALIGNED | OMP_CLAUSE_INBRANCH \
2788 | OMP_CLAUSE_NOTINBRANCH)
2789 #define OMP_DO_CLAUSES \
2790 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \
2791 | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION \
2792 | OMP_CLAUSE_SCHEDULE | OMP_CLAUSE_ORDERED | OMP_CLAUSE_COLLAPSE \
2793 | OMP_CLAUSE_LINEAR | OMP_CLAUSE_ORDER)
2794 #define OMP_SECTIONS_CLAUSES \
2795 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \
2796 | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION)
2797 #define OMP_SIMD_CLAUSES \
2798 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_LASTPRIVATE \
2799 | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_SAFELEN \
2800 | OMP_CLAUSE_LINEAR | OMP_CLAUSE_ALIGNED | OMP_CLAUSE_SIMDLEN \
2801 | OMP_CLAUSE_IF | OMP_CLAUSE_ORDER | OMP_CLAUSE_NOTEMPORAL)
2802 #define OMP_TASK_CLAUSES \
2803 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \
2804 | OMP_CLAUSE_SHARED | OMP_CLAUSE_IF | OMP_CLAUSE_DEFAULT \
2805 | OMP_CLAUSE_UNTIED | OMP_CLAUSE_FINAL | OMP_CLAUSE_MERGEABLE \
2806 | OMP_CLAUSE_DEPEND | OMP_CLAUSE_PRIORITY | OMP_CLAUSE_IN_REDUCTION \
2807 | OMP_CLAUSE_DETACH)
2808 #define OMP_TASKLOOP_CLAUSES \
2809 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \
2810 | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_SHARED | OMP_CLAUSE_IF \
2811 | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_UNTIED | OMP_CLAUSE_FINAL \
2812 | OMP_CLAUSE_MERGEABLE | OMP_CLAUSE_PRIORITY | OMP_CLAUSE_GRAINSIZE \
2813 | OMP_CLAUSE_NUM_TASKS | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_NOGROUP \
2814 | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_IN_REDUCTION)
2815 #define OMP_TARGET_CLAUSES \
2816 (omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF \
2817 | OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT | OMP_CLAUSE_PRIVATE \
2818 | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_DEFAULTMAP \
2819 | OMP_CLAUSE_IS_DEVICE_PTR | OMP_CLAUSE_IN_REDUCTION)
2820 #define OMP_TARGET_DATA_CLAUSES \
2821 (omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF \
2822 | OMP_CLAUSE_USE_DEVICE_PTR | OMP_CLAUSE_USE_DEVICE_ADDR)
2823 #define OMP_TARGET_ENTER_DATA_CLAUSES \
2824 (omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF \
2825 | OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT)
2826 #define OMP_TARGET_EXIT_DATA_CLAUSES \
2827 (omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF \
2828 | OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT)
2829 #define OMP_TARGET_UPDATE_CLAUSES \
2830 (omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_IF | OMP_CLAUSE_TO \
2831 | OMP_CLAUSE_FROM | OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT)
2832 #define OMP_TEAMS_CLAUSES \
2833 (omp_mask (OMP_CLAUSE_NUM_TEAMS) | OMP_CLAUSE_THREAD_LIMIT \
2834 | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE \
2835 | OMP_CLAUSE_SHARED | OMP_CLAUSE_REDUCTION)
2836 #define OMP_DISTRIBUTE_CLAUSES \
2837 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \
2838 | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_DIST_SCHEDULE)
2839 #define OMP_SINGLE_CLAUSES \
2840 (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE)
2841 #define OMP_ORDERED_CLAUSES \
2842 (omp_mask (OMP_CLAUSE_THREADS) | OMP_CLAUSE_SIMD)
2843 #define OMP_DECLARE_TARGET_CLAUSES \
2844 (omp_mask (OMP_CLAUSE_TO) | OMP_CLAUSE_LINK | OMP_CLAUSE_DEVICE_TYPE)
2845 #define OMP_ATOMIC_CLAUSES \
2846 (omp_mask (OMP_CLAUSE_ATOMIC) | OMP_CLAUSE_CAPTURE | OMP_CLAUSE_HINT \
2847 | OMP_CLAUSE_MEMORDER)
2851 match_omp (gfc_exec_op op
, const omp_mask mask
)
2854 if (gfc_match_omp_clauses (&c
, mask
) != MATCH_YES
)
2857 new_st
.ext
.omp_clauses
= c
;
2863 gfc_match_omp_critical (void)
2865 char n
[GFC_MAX_SYMBOL_LEN
+1];
2866 gfc_omp_clauses
*c
= NULL
;
2868 if (gfc_match (" ( %n )", n
) != MATCH_YES
)
2871 if (gfc_match_omp_clauses (&c
, omp_mask (OMP_CLAUSE_HINT
),
2872 /* first = */ n
[0] == '\0') != MATCH_YES
)
2875 new_st
.op
= EXEC_OMP_CRITICAL
;
2876 new_st
.ext
.omp_clauses
= c
;
2878 c
->critical_name
= xstrdup (n
);
2884 gfc_match_omp_end_critical (void)
2886 char n
[GFC_MAX_SYMBOL_LEN
+1];
2888 if (gfc_match (" ( %n )", n
) != MATCH_YES
)
2890 if (gfc_match_omp_eos () != MATCH_YES
)
2892 gfc_error ("Unexpected junk after $OMP CRITICAL statement at %C");
2896 new_st
.op
= EXEC_OMP_END_CRITICAL
;
2897 new_st
.ext
.omp_name
= n
[0] ? xstrdup (n
) : NULL
;
2903 gfc_match_omp_distribute (void)
2905 return match_omp (EXEC_OMP_DISTRIBUTE
, OMP_DISTRIBUTE_CLAUSES
);
2910 gfc_match_omp_distribute_parallel_do (void)
2912 return match_omp (EXEC_OMP_DISTRIBUTE_PARALLEL_DO
,
2913 (OMP_DISTRIBUTE_CLAUSES
| OMP_PARALLEL_CLAUSES
2915 & ~(omp_mask (OMP_CLAUSE_ORDERED
))
2916 & ~(omp_mask (OMP_CLAUSE_LINEAR
)));
2921 gfc_match_omp_distribute_parallel_do_simd (void)
2923 return match_omp (EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD
,
2924 (OMP_DISTRIBUTE_CLAUSES
| OMP_PARALLEL_CLAUSES
2925 | OMP_DO_CLAUSES
| OMP_SIMD_CLAUSES
)
2926 & ~(omp_mask (OMP_CLAUSE_ORDERED
)));
2931 gfc_match_omp_distribute_simd (void)
2933 return match_omp (EXEC_OMP_DISTRIBUTE_SIMD
,
2934 OMP_DISTRIBUTE_CLAUSES
| OMP_SIMD_CLAUSES
);
2939 gfc_match_omp_do (void)
2941 return match_omp (EXEC_OMP_DO
, OMP_DO_CLAUSES
);
2946 gfc_match_omp_do_simd (void)
2948 return match_omp (EXEC_OMP_DO_SIMD
, OMP_DO_CLAUSES
| OMP_SIMD_CLAUSES
);
2953 gfc_match_omp_flush (void)
2955 gfc_omp_namelist
*list
= NULL
;
2956 gfc_omp_clauses
*c
= NULL
;
2957 gfc_gobble_whitespace ();
2958 enum gfc_omp_memorder mo
= OMP_MEMORDER_UNSET
;
2959 if (gfc_match_omp_eos () == MATCH_NO
&& gfc_peek_ascii_char () != '(')
2961 if (gfc_match ("acq_rel") == MATCH_YES
)
2962 mo
= OMP_MEMORDER_ACQ_REL
;
2963 else if (gfc_match ("release") == MATCH_YES
)
2964 mo
= OMP_MEMORDER_RELEASE
;
2965 else if (gfc_match ("acquire") == MATCH_YES
)
2966 mo
= OMP_MEMORDER_ACQUIRE
;
2969 gfc_error ("Expected AQC_REL, RELEASE, or ACQUIRE at %C");
2972 c
= gfc_get_omp_clauses ();
2975 gfc_match_omp_variable_list (" (", &list
, true);
2976 if (list
&& mo
!= OMP_MEMORDER_UNSET
)
2978 gfc_error ("List specified together with memory order clause in FLUSH "
2980 gfc_free_omp_namelist (list
);
2981 gfc_free_omp_clauses (c
);
2984 if (gfc_match_omp_eos () != MATCH_YES
)
2986 gfc_error ("Unexpected junk after $OMP FLUSH statement at %C");
2987 gfc_free_omp_namelist (list
);
2988 gfc_free_omp_clauses (c
);
2991 new_st
.op
= EXEC_OMP_FLUSH
;
2992 new_st
.ext
.omp_namelist
= list
;
2993 new_st
.ext
.omp_clauses
= c
;
2999 gfc_match_omp_declare_simd (void)
3001 locus where
= gfc_current_locus
;
3002 gfc_symbol
*proc_name
;
3004 gfc_omp_declare_simd
*ods
;
3005 bool needs_space
= false;
3007 switch (gfc_match (" ( %s ) ", &proc_name
))
3009 case MATCH_YES
: break;
3010 case MATCH_NO
: proc_name
= NULL
; needs_space
= true; break;
3011 case MATCH_ERROR
: return MATCH_ERROR
;
3014 if (gfc_match_omp_clauses (&c
, OMP_DECLARE_SIMD_CLAUSES
, true,
3015 needs_space
) != MATCH_YES
)
3018 if (gfc_current_ns
->is_block_data
)
3020 gfc_free_omp_clauses (c
);
3024 ods
= gfc_get_omp_declare_simd ();
3026 ods
->proc_name
= proc_name
;
3028 ods
->next
= gfc_current_ns
->omp_declare_simd
;
3029 gfc_current_ns
->omp_declare_simd
= ods
;
3035 match_udr_expr (gfc_symtree
*omp_sym1
, gfc_symtree
*omp_sym2
)
3038 locus old_loc
= gfc_current_locus
;
3039 char sname
[GFC_MAX_SYMBOL_LEN
+ 1];
3041 gfc_namespace
*ns
= gfc_current_ns
;
3042 gfc_expr
*lvalue
= NULL
, *rvalue
= NULL
;
3044 gfc_actual_arglist
*arglist
;
3046 m
= gfc_match (" %v =", &lvalue
);
3048 gfc_current_locus
= old_loc
;
3051 m
= gfc_match (" %e )", &rvalue
);
3054 ns
->code
= gfc_get_code (EXEC_ASSIGN
);
3055 ns
->code
->expr1
= lvalue
;
3056 ns
->code
->expr2
= rvalue
;
3057 ns
->code
->loc
= old_loc
;
3061 gfc_current_locus
= old_loc
;
3062 gfc_free_expr (lvalue
);
3065 m
= gfc_match (" %n", sname
);
3069 if (strcmp (sname
, omp_sym1
->name
) == 0
3070 || strcmp (sname
, omp_sym2
->name
) == 0)
3073 gfc_current_ns
= ns
->parent
;
3074 if (gfc_get_ha_sym_tree (sname
, &st
))
3078 if (sym
->attr
.flavor
!= FL_PROCEDURE
3079 && sym
->attr
.flavor
!= FL_UNKNOWN
)
3082 if (!sym
->attr
.generic
3083 && !sym
->attr
.subroutine
3084 && !sym
->attr
.function
)
3086 if (!(sym
->attr
.external
&& !sym
->attr
.referenced
))
3088 /* ...create a symbol in this scope... */
3089 if (sym
->ns
!= gfc_current_ns
3090 && gfc_get_sym_tree (sname
, NULL
, &st
, false) == 1)
3093 if (sym
!= st
->n
.sym
)
3097 /* ...and then to try to make the symbol into a subroutine. */
3098 if (!gfc_add_subroutine (&sym
->attr
, sym
->name
, NULL
))
3102 gfc_set_sym_referenced (sym
);
3103 gfc_gobble_whitespace ();
3104 if (gfc_peek_ascii_char () != '(')
3107 gfc_current_ns
= ns
;
3108 m
= gfc_match_actual_arglist (1, &arglist
);
3112 if (gfc_match_char (')') != MATCH_YES
)
3115 ns
->code
= gfc_get_code (EXEC_CALL
);
3116 ns
->code
->symtree
= st
;
3117 ns
->code
->ext
.actual
= arglist
;
3118 ns
->code
->loc
= old_loc
;
3123 gfc_omp_udr_predef (gfc_omp_reduction_op rop
, const char *name
,
3124 gfc_typespec
*ts
, const char **n
)
3126 if (!gfc_numeric_ts (ts
) && ts
->type
!= BT_LOGICAL
)
3131 case OMP_REDUCTION_PLUS
:
3132 case OMP_REDUCTION_MINUS
:
3133 case OMP_REDUCTION_TIMES
:
3134 return ts
->type
!= BT_LOGICAL
;
3135 case OMP_REDUCTION_AND
:
3136 case OMP_REDUCTION_OR
:
3137 case OMP_REDUCTION_EQV
:
3138 case OMP_REDUCTION_NEQV
:
3139 return ts
->type
== BT_LOGICAL
;
3140 case OMP_REDUCTION_USER
:
3141 if (name
[0] != '.' && (ts
->type
== BT_INTEGER
|| ts
->type
== BT_REAL
))
3145 gfc_find_symbol (name
, NULL
, 1, &sym
);
3148 if (sym
->attr
.intrinsic
)
3150 else if ((sym
->attr
.flavor
!= FL_UNKNOWN
3151 && sym
->attr
.flavor
!= FL_PROCEDURE
)
3152 || sym
->attr
.external
3153 || sym
->attr
.generic
3157 || sym
->attr
.subroutine
3158 || sym
->attr
.pointer
3160 || sym
->attr
.cray_pointer
3161 || sym
->attr
.cray_pointee
3162 || (sym
->attr
.proc
!= PROC_UNKNOWN
3163 && sym
->attr
.proc
!= PROC_INTRINSIC
)
3164 || sym
->attr
.if_source
!= IFSRC_UNKNOWN
3165 || sym
== sym
->ns
->proc_name
)
3173 && (strcmp (*n
, "max") == 0 || strcmp (*n
, "min") == 0))
3176 && ts
->type
== BT_INTEGER
3177 && (strcmp (*n
, "iand") == 0
3178 || strcmp (*n
, "ior") == 0
3179 || strcmp (*n
, "ieor") == 0))
3190 gfc_omp_udr_find (gfc_symtree
*st
, gfc_typespec
*ts
)
3192 gfc_omp_udr
*omp_udr
;
3197 for (omp_udr
= st
->n
.omp_udr
; omp_udr
; omp_udr
= omp_udr
->next
)
3198 if (omp_udr
->ts
.type
== ts
->type
3199 || ((omp_udr
->ts
.type
== BT_DERIVED
|| omp_udr
->ts
.type
== BT_CLASS
)
3200 && (ts
->type
== BT_DERIVED
|| ts
->type
== BT_CLASS
)))
3202 if (omp_udr
->ts
.type
== BT_DERIVED
|| omp_udr
->ts
.type
== BT_CLASS
)
3204 if (strcmp (omp_udr
->ts
.u
.derived
->name
, ts
->u
.derived
->name
) == 0)
3207 else if (omp_udr
->ts
.kind
== ts
->kind
)
3209 if (omp_udr
->ts
.type
== BT_CHARACTER
)
3211 if (omp_udr
->ts
.u
.cl
->length
== NULL
3212 || ts
->u
.cl
->length
== NULL
)
3214 if (omp_udr
->ts
.u
.cl
->length
->expr_type
!= EXPR_CONSTANT
)
3216 if (ts
->u
.cl
->length
->expr_type
!= EXPR_CONSTANT
)
3218 if (omp_udr
->ts
.u
.cl
->length
->ts
.type
!= BT_INTEGER
)
3220 if (ts
->u
.cl
->length
->ts
.type
!= BT_INTEGER
)
3222 if (gfc_compare_expr (omp_udr
->ts
.u
.cl
->length
,
3223 ts
->u
.cl
->length
, INTRINSIC_EQ
) != 0)
3233 gfc_match_omp_declare_reduction (void)
3236 gfc_intrinsic_op op
;
3237 char name
[GFC_MAX_SYMBOL_LEN
+ 3];
3238 auto_vec
<gfc_typespec
, 5> tss
;
3242 locus where
= gfc_current_locus
;
3243 locus end_loc
= gfc_current_locus
;
3244 bool end_loc_set
= false;
3245 gfc_omp_reduction_op rop
= OMP_REDUCTION_NONE
;
3247 if (gfc_match_char ('(') != MATCH_YES
)
3250 m
= gfc_match (" %o : ", &op
);
3251 if (m
== MATCH_ERROR
)
3255 snprintf (name
, sizeof name
, "operator %s", gfc_op2string (op
));
3256 rop
= (gfc_omp_reduction_op
) op
;
3260 m
= gfc_match_defined_op_name (name
+ 1, 1);
3261 if (m
== MATCH_ERROR
)
3267 if (gfc_match (" : ") != MATCH_YES
)
3272 if (gfc_match (" %n : ", name
) != MATCH_YES
)
3275 rop
= OMP_REDUCTION_USER
;
3278 m
= gfc_match_type_spec (&ts
);
3281 /* Treat len=: the same as len=*. */
3282 if (ts
.type
== BT_CHARACTER
)
3283 ts
.deferred
= false;
3286 while (gfc_match_char (',') == MATCH_YES
)
3288 m
= gfc_match_type_spec (&ts
);
3293 if (gfc_match_char (':') != MATCH_YES
)
3296 st
= gfc_find_symtree (gfc_current_ns
->omp_udr_root
, name
);
3297 for (i
= 0; i
< tss
.length (); i
++)
3299 gfc_symtree
*omp_out
, *omp_in
;
3300 gfc_symtree
*omp_priv
= NULL
, *omp_orig
= NULL
;
3301 gfc_namespace
*combiner_ns
, *initializer_ns
= NULL
;
3302 gfc_omp_udr
*prev_udr
, *omp_udr
;
3303 const char *predef_name
= NULL
;
3305 omp_udr
= gfc_get_omp_udr ();
3306 omp_udr
->name
= gfc_get_string ("%s", name
);
3308 omp_udr
->ts
= tss
[i
];
3309 omp_udr
->where
= where
;
3311 gfc_current_ns
= combiner_ns
= gfc_get_namespace (gfc_current_ns
, 1);
3312 combiner_ns
->proc_name
= combiner_ns
->parent
->proc_name
;
3314 gfc_get_sym_tree ("omp_out", combiner_ns
, &omp_out
, false);
3315 gfc_get_sym_tree ("omp_in", combiner_ns
, &omp_in
, false);
3316 combiner_ns
->omp_udr_ns
= 1;
3317 omp_out
->n
.sym
->ts
= tss
[i
];
3318 omp_in
->n
.sym
->ts
= tss
[i
];
3319 omp_out
->n
.sym
->attr
.omp_udr_artificial_var
= 1;
3320 omp_in
->n
.sym
->attr
.omp_udr_artificial_var
= 1;
3321 omp_out
->n
.sym
->attr
.flavor
= FL_VARIABLE
;
3322 omp_in
->n
.sym
->attr
.flavor
= FL_VARIABLE
;
3323 gfc_commit_symbols ();
3324 omp_udr
->combiner_ns
= combiner_ns
;
3325 omp_udr
->omp_out
= omp_out
->n
.sym
;
3326 omp_udr
->omp_in
= omp_in
->n
.sym
;
3328 locus old_loc
= gfc_current_locus
;
3330 if (!match_udr_expr (omp_out
, omp_in
))
3333 gfc_current_locus
= old_loc
;
3334 gfc_current_ns
= combiner_ns
->parent
;
3335 gfc_undo_symbols ();
3336 gfc_free_omp_udr (omp_udr
);
3340 if (gfc_match (" initializer ( ") == MATCH_YES
)
3342 gfc_current_ns
= combiner_ns
->parent
;
3343 initializer_ns
= gfc_get_namespace (gfc_current_ns
, 1);
3344 gfc_current_ns
= initializer_ns
;
3345 initializer_ns
->proc_name
= initializer_ns
->parent
->proc_name
;
3347 gfc_get_sym_tree ("omp_priv", initializer_ns
, &omp_priv
, false);
3348 gfc_get_sym_tree ("omp_orig", initializer_ns
, &omp_orig
, false);
3349 initializer_ns
->omp_udr_ns
= 1;
3350 omp_priv
->n
.sym
->ts
= tss
[i
];
3351 omp_orig
->n
.sym
->ts
= tss
[i
];
3352 omp_priv
->n
.sym
->attr
.omp_udr_artificial_var
= 1;
3353 omp_orig
->n
.sym
->attr
.omp_udr_artificial_var
= 1;
3354 omp_priv
->n
.sym
->attr
.flavor
= FL_VARIABLE
;
3355 omp_orig
->n
.sym
->attr
.flavor
= FL_VARIABLE
;
3356 gfc_commit_symbols ();
3357 omp_udr
->initializer_ns
= initializer_ns
;
3358 omp_udr
->omp_priv
= omp_priv
->n
.sym
;
3359 omp_udr
->omp_orig
= omp_orig
->n
.sym
;
3361 if (!match_udr_expr (omp_priv
, omp_orig
))
3365 gfc_current_ns
= combiner_ns
->parent
;
3369 end_loc
= gfc_current_locus
;
3371 gfc_current_locus
= old_loc
;
3373 prev_udr
= gfc_omp_udr_find (st
, &tss
[i
]);
3374 if (gfc_omp_udr_predef (rop
, name
, &tss
[i
], &predef_name
)
3375 /* Don't error on !$omp declare reduction (min : integer : ...)
3376 just yet, there could be integer :: min afterwards,
3377 making it valid. When the UDR is resolved, we'll get
3379 && (rop
!= OMP_REDUCTION_USER
|| name
[0] == '.'))
3382 gfc_error_now ("Redefinition of predefined %s "
3383 "!$OMP DECLARE REDUCTION at %L",
3384 predef_name
, &where
);
3386 gfc_error_now ("Redefinition of predefined "
3387 "!$OMP DECLARE REDUCTION at %L", &where
);
3391 gfc_error_now ("Redefinition of !$OMP DECLARE REDUCTION at %L",
3393 gfc_error_now ("Previous !$OMP DECLARE REDUCTION at %L",
3398 omp_udr
->next
= st
->n
.omp_udr
;
3399 st
->n
.omp_udr
= omp_udr
;
3403 st
= gfc_new_symtree (&gfc_current_ns
->omp_udr_root
, name
);
3404 st
->n
.omp_udr
= omp_udr
;
3410 gfc_current_locus
= end_loc
;
3411 if (gfc_match_omp_eos () != MATCH_YES
)
3413 gfc_error ("Unexpected junk after !$OMP DECLARE REDUCTION at %C");
3414 gfc_current_locus
= where
;
3426 gfc_match_omp_declare_target (void)
3430 gfc_omp_clauses
*c
= NULL
;
3432 gfc_omp_namelist
*n
;
3435 old_loc
= gfc_current_locus
;
3437 if (gfc_current_ns
->proc_name
3438 && gfc_match_omp_eos () == MATCH_YES
)
3440 if (!gfc_add_omp_declare_target (&gfc_current_ns
->proc_name
->attr
,
3441 gfc_current_ns
->proc_name
->name
,
3447 if (gfc_current_ns
->proc_name
3448 && gfc_current_ns
->proc_name
->attr
.if_source
== IFSRC_IFBODY
)
3450 gfc_error ("Only the !$OMP DECLARE TARGET form without "
3451 "clauses is allowed in interface block at %C");
3455 m
= gfc_match (" (");
3458 c
= gfc_get_omp_clauses ();
3459 gfc_current_locus
= old_loc
;
3460 m
= gfc_match_omp_to_link (" (", &c
->lists
[OMP_LIST_TO
]);
3463 if (gfc_match_omp_eos () != MATCH_YES
)
3465 gfc_error ("Unexpected junk after !$OMP DECLARE TARGET at %C");
3469 else if (gfc_match_omp_clauses (&c
, OMP_DECLARE_TARGET_CLAUSES
) != MATCH_YES
)
3472 gfc_buffer_error (false);
3474 for (list
= OMP_LIST_TO
; list
!= OMP_LIST_NUM
;
3475 list
= (list
== OMP_LIST_TO
? OMP_LIST_LINK
: OMP_LIST_NUM
))
3476 for (n
= c
->lists
[list
]; n
; n
= n
->next
)
3479 else if (n
->u
.common
->head
)
3480 n
->u
.common
->head
->mark
= 0;
3482 for (list
= OMP_LIST_TO
; list
!= OMP_LIST_NUM
;
3483 list
= (list
== OMP_LIST_TO
? OMP_LIST_LINK
: OMP_LIST_NUM
))
3484 for (n
= c
->lists
[list
]; n
; n
= n
->next
)
3487 if (n
->sym
->attr
.in_common
)
3488 gfc_error_now ("OMP DECLARE TARGET variable at %L is an "
3489 "element of a COMMON block", &n
->where
);
3490 else if (n
->sym
->attr
.omp_declare_target
3491 && n
->sym
->attr
.omp_declare_target_link
3492 && list
!= OMP_LIST_LINK
)
3493 gfc_error_now ("OMP DECLARE TARGET variable at %L previously "
3494 "mentioned in LINK clause and later in TO clause",
3496 else if (n
->sym
->attr
.omp_declare_target
3497 && !n
->sym
->attr
.omp_declare_target_link
3498 && list
== OMP_LIST_LINK
)
3499 gfc_error_now ("OMP DECLARE TARGET variable at %L previously "
3500 "mentioned in TO clause and later in LINK clause",
3502 else if (n
->sym
->mark
)
3503 gfc_error_now ("Variable at %L mentioned multiple times in "
3504 "clauses of the same OMP DECLARE TARGET directive",
3506 else if (gfc_add_omp_declare_target (&n
->sym
->attr
, n
->sym
->name
,
3507 &n
->sym
->declared_at
))
3509 if (list
== OMP_LIST_LINK
)
3510 gfc_add_omp_declare_target_link (&n
->sym
->attr
, n
->sym
->name
,
3511 &n
->sym
->declared_at
);
3513 if (c
->device_type
!= OMP_DEVICE_TYPE_UNSET
)
3515 if (n
->sym
->attr
.omp_device_type
!= OMP_DEVICE_TYPE_UNSET
3516 && n
->sym
->attr
.omp_device_type
!= c
->device_type
)
3517 gfc_error_now ("List item %qs at %L set in previous OMP DECLARE "
3518 "TARGET directive to a different DEVICE_TYPE",
3519 n
->sym
->name
, &n
->where
);
3520 n
->sym
->attr
.omp_device_type
= c
->device_type
;
3524 else if (n
->u
.common
->omp_declare_target
3525 && n
->u
.common
->omp_declare_target_link
3526 && list
!= OMP_LIST_LINK
)
3527 gfc_error_now ("OMP DECLARE TARGET COMMON at %L previously "
3528 "mentioned in LINK clause and later in TO clause",
3530 else if (n
->u
.common
->omp_declare_target
3531 && !n
->u
.common
->omp_declare_target_link
3532 && list
== OMP_LIST_LINK
)
3533 gfc_error_now ("OMP DECLARE TARGET COMMON at %L previously "
3534 "mentioned in TO clause and later in LINK clause",
3536 else if (n
->u
.common
->head
&& n
->u
.common
->head
->mark
)
3537 gfc_error_now ("COMMON at %L mentioned multiple times in "
3538 "clauses of the same OMP DECLARE TARGET directive",
3542 n
->u
.common
->omp_declare_target
= 1;
3543 n
->u
.common
->omp_declare_target_link
= (list
== OMP_LIST_LINK
);
3544 if (n
->u
.common
->omp_device_type
!= OMP_DEVICE_TYPE_UNSET
3545 && n
->u
.common
->omp_device_type
!= c
->device_type
)
3546 gfc_error_now ("COMMON at %L set in previous OMP DECLARE "
3547 "TARGET directive to a different DEVICE_TYPE",
3549 n
->u
.common
->omp_device_type
= c
->device_type
;
3551 for (s
= n
->u
.common
->head
; s
; s
= s
->common_next
)
3554 if (gfc_add_omp_declare_target (&s
->attr
, s
->name
,
3557 if (list
== OMP_LIST_LINK
)
3558 gfc_add_omp_declare_target_link (&s
->attr
, s
->name
,
3561 if (s
->attr
.omp_device_type
!= OMP_DEVICE_TYPE_UNSET
3562 && s
->attr
.omp_device_type
!= c
->device_type
)
3563 gfc_error_now ("List item %qs at %L set in previous OMP DECLARE"
3564 " TARGET directive to a different DEVICE_TYPE",
3565 s
->name
, &n
->where
);
3566 s
->attr
.omp_device_type
= c
->device_type
;
3569 if (c
->device_type
&& !c
->lists
[OMP_LIST_TO
] && !c
->lists
[OMP_LIST_LINK
])
3570 gfc_warning_now (0, "OMP DECLARE TARGET directive at %L with only "
3571 "DEVICE_TYPE clause is ignored", &old_loc
);
3573 gfc_buffer_error (true);
3576 gfc_free_omp_clauses (c
);
3580 gfc_error ("Syntax error in !$OMP DECLARE TARGET list at %C");
3583 gfc_current_locus
= old_loc
;
3585 gfc_free_omp_clauses (c
);
3591 gfc_match_omp_threadprivate (void)
3594 char n
[GFC_MAX_SYMBOL_LEN
+1];
3599 old_loc
= gfc_current_locus
;
3601 m
= gfc_match (" (");
3607 m
= gfc_match_symbol (&sym
, 0);
3611 if (sym
->attr
.in_common
)
3612 gfc_error_now ("Threadprivate variable at %C is an element of "
3614 else if (!gfc_add_threadprivate (&sym
->attr
, sym
->name
, &sym
->declared_at
))
3623 m
= gfc_match (" / %n /", n
);
3624 if (m
== MATCH_ERROR
)
3626 if (m
== MATCH_NO
|| n
[0] == '\0')
3629 st
= gfc_find_symtree (gfc_current_ns
->common_root
, n
);
3632 gfc_error ("COMMON block /%s/ not found at %C", n
);
3635 st
->n
.common
->threadprivate
= 1;
3636 for (sym
= st
->n
.common
->head
; sym
; sym
= sym
->common_next
)
3637 if (!gfc_add_threadprivate (&sym
->attr
, sym
->name
, &sym
->declared_at
))
3641 if (gfc_match_char (')') == MATCH_YES
)
3643 if (gfc_match_char (',') != MATCH_YES
)
3647 if (gfc_match_omp_eos () != MATCH_YES
)
3649 gfc_error ("Unexpected junk after OMP THREADPRIVATE at %C");
3656 gfc_error ("Syntax error in !$OMP THREADPRIVATE list at %C");
3659 gfc_current_locus
= old_loc
;
3665 gfc_match_omp_parallel (void)
3667 return match_omp (EXEC_OMP_PARALLEL
, OMP_PARALLEL_CLAUSES
);
3672 gfc_match_omp_parallel_do (void)
3674 return match_omp (EXEC_OMP_PARALLEL_DO
,
3675 OMP_PARALLEL_CLAUSES
| OMP_DO_CLAUSES
);
3680 gfc_match_omp_parallel_do_simd (void)
3682 return match_omp (EXEC_OMP_PARALLEL_DO_SIMD
,
3683 OMP_PARALLEL_CLAUSES
| OMP_DO_CLAUSES
| OMP_SIMD_CLAUSES
);
3688 gfc_match_omp_parallel_sections (void)
3690 return match_omp (EXEC_OMP_PARALLEL_SECTIONS
,
3691 OMP_PARALLEL_CLAUSES
| OMP_SECTIONS_CLAUSES
);
3696 gfc_match_omp_parallel_workshare (void)
3698 return match_omp (EXEC_OMP_PARALLEL_WORKSHARE
, OMP_PARALLEL_CLAUSES
);
3702 gfc_check_omp_requires (gfc_namespace
*ns
, int ref_omp_requires
)
3704 if (ns
->omp_target_seen
3705 && (ns
->omp_requires
& OMP_REQ_TARGET_MASK
)
3706 != (ref_omp_requires
& OMP_REQ_TARGET_MASK
))
3708 gcc_assert (ns
->proc_name
);
3709 if ((ref_omp_requires
& OMP_REQ_REVERSE_OFFLOAD
)
3710 && !(ns
->omp_requires
& OMP_REQ_REVERSE_OFFLOAD
))
3711 gfc_error ("Program unit at %L has OpenMP device constructs/routines "
3712 "but does not set !$OMP REQUIRES REVERSE_OFFSET but other "
3713 "program units do", &ns
->proc_name
->declared_at
);
3714 if ((ref_omp_requires
& OMP_REQ_UNIFIED_ADDRESS
)
3715 && !(ns
->omp_requires
& OMP_REQ_UNIFIED_ADDRESS
))
3716 gfc_error ("Program unit at %L has OpenMP device constructs/routines "
3717 "but does not set !$OMP REQUIRES UNIFIED_ADDRESS but other "
3718 "program units do", &ns
->proc_name
->declared_at
);
3719 if ((ref_omp_requires
& OMP_REQ_UNIFIED_SHARED_MEMORY
)
3720 && !(ns
->omp_requires
& OMP_REQ_UNIFIED_SHARED_MEMORY
))
3721 gfc_error ("Program unit at %L has OpenMP device constructs/routines "
3722 "but does not set !$OMP REQUIRES UNIFIED_SHARED_MEMORY but "
3723 "other program units do", &ns
->proc_name
->declared_at
);
3728 gfc_omp_requires_add_clause (gfc_omp_requires_kind clause
,
3729 const char *clause_name
, locus
*loc
,
3730 const char *module_name
)
3732 gfc_namespace
*prog_unit
= gfc_current_ns
;
3733 while (prog_unit
->parent
)
3735 if (gfc_state_stack
->previous
3736 && gfc_state_stack
->previous
->state
== COMP_INTERFACE
)
3738 prog_unit
= prog_unit
->parent
;
3741 /* Requires added after use. */
3742 if (prog_unit
->omp_target_seen
3743 && (clause
& OMP_REQ_TARGET_MASK
)
3744 && !(prog_unit
->omp_requires
& clause
))
3747 gfc_error ("!$OMP REQUIRES clause %qs specified via module %qs use "
3748 "at %L comes after using a device construct/routine",
3749 clause_name
, module_name
, loc
);
3751 gfc_error ("!$OMP REQUIRES clause %qs specified at %L comes after "
3752 "using a device construct/routine", clause_name
, loc
);
3756 /* Overriding atomic_default_mem_order clause value. */
3757 if ((clause
& OMP_REQ_ATOMIC_MEM_ORDER_MASK
)
3758 && (prog_unit
->omp_requires
& OMP_REQ_ATOMIC_MEM_ORDER_MASK
)
3759 && (prog_unit
->omp_requires
& OMP_REQ_ATOMIC_MEM_ORDER_MASK
)
3763 if (prog_unit
->omp_requires
& OMP_REQ_ATOMIC_MEM_ORDER_SEQ_CST
)
3765 else if (prog_unit
->omp_requires
& OMP_REQ_ATOMIC_MEM_ORDER_ACQ_REL
)
3767 else if (prog_unit
->omp_requires
& OMP_REQ_ATOMIC_MEM_ORDER_RELAXED
)
3773 gfc_error ("!$OMP REQUIRES clause %<atomic_default_mem_order(%s)%> "
3774 "specified via module %qs use at %L overrides a previous "
3775 "%<atomic_default_mem_order(%s)%> (which might be through "
3776 "using a module)", clause_name
, module_name
, loc
, other
);
3778 gfc_error ("!$OMP REQUIRES clause %<atomic_default_mem_order(%s)%> "
3779 "specified at %L overrides a previous "
3780 "%<atomic_default_mem_order(%s)%> (which might be through "
3781 "using a module)", clause_name
, loc
, other
);
3785 /* Requires via module not at program-unit level and not repeating clause. */
3786 if (prog_unit
!= gfc_current_ns
&& !(prog_unit
->omp_requires
& clause
))
3788 if (clause
& OMP_REQ_ATOMIC_MEM_ORDER_MASK
)
3789 gfc_error ("!$OMP REQUIRES clause %<atomic_default_mem_order(%s)%> "
3790 "specified via module %qs use at %L but same clause is "
3791 "not set at for the program unit", clause_name
, module_name
,
3794 gfc_error ("!$OMP REQUIRES clause %qs specified via module %qs use at "
3795 "%L but same clause is not set at for the program unit",
3796 clause_name
, module_name
, loc
);
3800 if (!gfc_state_stack
->previous
3801 || gfc_state_stack
->previous
->state
!= COMP_INTERFACE
)
3802 prog_unit
->omp_requires
|= clause
;
3807 gfc_match_omp_requires (void)
3809 static const char *clauses
[] = {"reverse_offload",
3811 "unified_shared_memory",
3812 "dynamic_allocators",
3814 const char *clause
= NULL
;
3815 int requires_clauses
= 0;
3819 if (gfc_current_ns
->parent
3820 && (!gfc_state_stack
->previous
3821 || gfc_state_stack
->previous
->state
!= COMP_INTERFACE
))
3823 gfc_error ("!$OMP REQUIRES at %C must appear in the specification part "
3824 "of a program unit");
3830 old_loc
= gfc_current_locus
;
3831 gfc_omp_requires_kind requires_clause
;
3832 if ((first
|| gfc_match_char (',') != MATCH_YES
)
3833 && (first
&& gfc_match_space () != MATCH_YES
))
3836 gfc_gobble_whitespace ();
3837 old_loc
= gfc_current_locus
;
3839 if (gfc_match_omp_eos () != MATCH_NO
)
3841 if (gfc_match (clauses
[0]) == MATCH_YES
)
3843 clause
= clauses
[0];
3844 requires_clause
= OMP_REQ_REVERSE_OFFLOAD
;
3845 if (requires_clauses
& OMP_REQ_REVERSE_OFFLOAD
)
3846 goto duplicate_clause
;
3848 else if (gfc_match (clauses
[1]) == MATCH_YES
)
3850 clause
= clauses
[1];
3851 requires_clause
= OMP_REQ_UNIFIED_ADDRESS
;
3852 if (requires_clauses
& OMP_REQ_UNIFIED_ADDRESS
)
3853 goto duplicate_clause
;
3855 else if (gfc_match (clauses
[2]) == MATCH_YES
)
3857 clause
= clauses
[2];
3858 requires_clause
= OMP_REQ_UNIFIED_SHARED_MEMORY
;
3859 if (requires_clauses
& OMP_REQ_UNIFIED_SHARED_MEMORY
)
3860 goto duplicate_clause
;
3862 else if (gfc_match (clauses
[3]) == MATCH_YES
)
3864 clause
= clauses
[3];
3865 requires_clause
= OMP_REQ_DYNAMIC_ALLOCATORS
;
3866 if (requires_clauses
& OMP_REQ_DYNAMIC_ALLOCATORS
)
3867 goto duplicate_clause
;
3869 else if (gfc_match ("atomic_default_mem_order (") == MATCH_YES
)
3871 clause
= clauses
[4];
3872 if (requires_clauses
& OMP_REQ_ATOMIC_MEM_ORDER_MASK
)
3873 goto duplicate_clause
;
3874 if (gfc_match (" seq_cst )") == MATCH_YES
)
3877 requires_clause
= OMP_REQ_ATOMIC_MEM_ORDER_SEQ_CST
;
3879 else if (gfc_match (" acq_rel )") == MATCH_YES
)
3882 requires_clause
= OMP_REQ_ATOMIC_MEM_ORDER_ACQ_REL
;
3884 else if (gfc_match (" relaxed )") == MATCH_YES
)
3887 requires_clause
= OMP_REQ_ATOMIC_MEM_ORDER_RELAXED
;
3891 gfc_error ("Expected SEQ_CST, ACQ_REL or RELAXED for "
3892 "ATOMIC_DEFAULT_MEM_ORDER clause at %C");
3899 if (requires_clause
& ~OMP_REQ_ATOMIC_MEM_ORDER_MASK
)
3900 gfc_error_now ("Sorry, %qs clause at %L on REQUIRES directive is not "
3901 "yet supported", clause
, &old_loc
);
3902 if (!gfc_omp_requires_add_clause (requires_clause
, clause
, &old_loc
, NULL
))
3904 requires_clauses
|= requires_clause
;
3907 if (requires_clauses
== 0)
3909 if (!gfc_error_flag_test ())
3910 gfc_error ("Clause expected at %C");
3916 gfc_error ("%qs clause at %L specified more than once", clause
, &old_loc
);
3918 if (!gfc_error_flag_test ())
3919 gfc_error ("Expected UNIFIED_ADDRESS, UNIFIED_SHARED_MEMORY, "
3920 "DYNAMIC_ALLOCATORS, REVERSE_OFFLOAD, or "
3921 "ATOMIC_DEFAULT_MEM_ORDER clause at %L", &old_loc
);
3927 gfc_match_omp_scan (void)
3930 gfc_omp_clauses
*c
= gfc_get_omp_clauses ();
3931 gfc_gobble_whitespace ();
3932 if ((incl
= (gfc_match ("inclusive") == MATCH_YES
))
3933 || gfc_match ("exclusive") == MATCH_YES
)
3935 if (gfc_match_omp_variable_list (" (", &c
->lists
[incl
? OMP_LIST_SCAN_IN
3936 : OMP_LIST_SCAN_EX
],
3937 false) != MATCH_YES
)
3939 gfc_free_omp_clauses (c
);
3945 gfc_error ("Expected INCLUSIVE or EXCLUSIVE clause at %C");
3946 gfc_free_omp_clauses (c
);
3949 if (gfc_match_omp_eos () != MATCH_YES
)
3951 gfc_error ("Unexpected junk after !$OMP SCAN at %C");
3952 gfc_free_omp_clauses (c
);
3956 new_st
.op
= EXEC_OMP_SCAN
;
3957 new_st
.ext
.omp_clauses
= c
;
3963 gfc_match_omp_sections (void)
3965 return match_omp (EXEC_OMP_SECTIONS
, OMP_SECTIONS_CLAUSES
);
3970 gfc_match_omp_simd (void)
3972 return match_omp (EXEC_OMP_SIMD
, OMP_SIMD_CLAUSES
);
3977 gfc_match_omp_single (void)
3979 return match_omp (EXEC_OMP_SINGLE
, OMP_SINGLE_CLAUSES
);
3984 gfc_match_omp_target (void)
3986 return match_omp (EXEC_OMP_TARGET
, OMP_TARGET_CLAUSES
);
3991 gfc_match_omp_target_data (void)
3993 return match_omp (EXEC_OMP_TARGET_DATA
, OMP_TARGET_DATA_CLAUSES
);
3998 gfc_match_omp_target_enter_data (void)
4000 return match_omp (EXEC_OMP_TARGET_ENTER_DATA
, OMP_TARGET_ENTER_DATA_CLAUSES
);
4005 gfc_match_omp_target_exit_data (void)
4007 return match_omp (EXEC_OMP_TARGET_EXIT_DATA
, OMP_TARGET_EXIT_DATA_CLAUSES
);
4012 gfc_match_omp_target_parallel (void)
4014 return match_omp (EXEC_OMP_TARGET_PARALLEL
,
4015 (OMP_TARGET_CLAUSES
| OMP_PARALLEL_CLAUSES
)
4016 & ~(omp_mask (OMP_CLAUSE_COPYIN
)));
4021 gfc_match_omp_target_parallel_do (void)
4023 return match_omp (EXEC_OMP_TARGET_PARALLEL_DO
,
4024 (OMP_TARGET_CLAUSES
| OMP_PARALLEL_CLAUSES
4025 | OMP_DO_CLAUSES
) & ~(omp_mask (OMP_CLAUSE_COPYIN
)));
4030 gfc_match_omp_target_parallel_do_simd (void)
4032 return match_omp (EXEC_OMP_TARGET_PARALLEL_DO_SIMD
,
4033 (OMP_TARGET_CLAUSES
| OMP_PARALLEL_CLAUSES
| OMP_DO_CLAUSES
4034 | OMP_SIMD_CLAUSES
) & ~(omp_mask (OMP_CLAUSE_COPYIN
)));
4039 gfc_match_omp_target_simd (void)
4041 return match_omp (EXEC_OMP_TARGET_SIMD
,
4042 OMP_TARGET_CLAUSES
| OMP_SIMD_CLAUSES
);
4047 gfc_match_omp_target_teams (void)
4049 return match_omp (EXEC_OMP_TARGET_TEAMS
,
4050 OMP_TARGET_CLAUSES
| OMP_TEAMS_CLAUSES
);
4055 gfc_match_omp_target_teams_distribute (void)
4057 return match_omp (EXEC_OMP_TARGET_TEAMS_DISTRIBUTE
,
4058 OMP_TARGET_CLAUSES
| OMP_TEAMS_CLAUSES
4059 | OMP_DISTRIBUTE_CLAUSES
);
4064 gfc_match_omp_target_teams_distribute_parallel_do (void)
4066 return match_omp (EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO
,
4067 (OMP_TARGET_CLAUSES
| OMP_TEAMS_CLAUSES
4068 | OMP_DISTRIBUTE_CLAUSES
| OMP_PARALLEL_CLAUSES
4070 & ~(omp_mask (OMP_CLAUSE_ORDERED
))
4071 & ~(omp_mask (OMP_CLAUSE_LINEAR
)));
4076 gfc_match_omp_target_teams_distribute_parallel_do_simd (void)
4078 return match_omp (EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
,
4079 (OMP_TARGET_CLAUSES
| OMP_TEAMS_CLAUSES
4080 | OMP_DISTRIBUTE_CLAUSES
| OMP_PARALLEL_CLAUSES
4081 | OMP_DO_CLAUSES
| OMP_SIMD_CLAUSES
)
4082 & ~(omp_mask (OMP_CLAUSE_ORDERED
)));
4087 gfc_match_omp_target_teams_distribute_simd (void)
4089 return match_omp (EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD
,
4090 OMP_TARGET_CLAUSES
| OMP_TEAMS_CLAUSES
4091 | OMP_DISTRIBUTE_CLAUSES
| OMP_SIMD_CLAUSES
);
4096 gfc_match_omp_target_update (void)
4098 return match_omp (EXEC_OMP_TARGET_UPDATE
, OMP_TARGET_UPDATE_CLAUSES
);
4103 gfc_match_omp_task (void)
4105 return match_omp (EXEC_OMP_TASK
, OMP_TASK_CLAUSES
);
4110 gfc_match_omp_taskloop (void)
4112 return match_omp (EXEC_OMP_TASKLOOP
, OMP_TASKLOOP_CLAUSES
);
4117 gfc_match_omp_taskloop_simd (void)
4119 return match_omp (EXEC_OMP_TASKLOOP_SIMD
,
4120 (OMP_TASKLOOP_CLAUSES
| OMP_SIMD_CLAUSES
)
4121 & ~(omp_mask (OMP_CLAUSE_REDUCTION
)));
4126 gfc_match_omp_taskwait (void)
4128 if (gfc_match_omp_eos () != MATCH_YES
)
4130 gfc_error ("Unexpected junk after TASKWAIT clause at %C");
4133 new_st
.op
= EXEC_OMP_TASKWAIT
;
4134 new_st
.ext
.omp_clauses
= NULL
;
4140 gfc_match_omp_taskyield (void)
4142 if (gfc_match_omp_eos () != MATCH_YES
)
4144 gfc_error ("Unexpected junk after TASKYIELD clause at %C");
4147 new_st
.op
= EXEC_OMP_TASKYIELD
;
4148 new_st
.ext
.omp_clauses
= NULL
;
4154 gfc_match_omp_teams (void)
4156 return match_omp (EXEC_OMP_TEAMS
, OMP_TEAMS_CLAUSES
);
4161 gfc_match_omp_teams_distribute (void)
4163 return match_omp (EXEC_OMP_TEAMS_DISTRIBUTE
,
4164 OMP_TEAMS_CLAUSES
| OMP_DISTRIBUTE_CLAUSES
);
4169 gfc_match_omp_teams_distribute_parallel_do (void)
4171 return match_omp (EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO
,
4172 (OMP_TEAMS_CLAUSES
| OMP_DISTRIBUTE_CLAUSES
4173 | OMP_PARALLEL_CLAUSES
| OMP_DO_CLAUSES
)
4174 & ~(omp_mask (OMP_CLAUSE_ORDERED
))
4175 & ~(omp_mask (OMP_CLAUSE_LINEAR
)));
4180 gfc_match_omp_teams_distribute_parallel_do_simd (void)
4182 return match_omp (EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
,
4183 (OMP_TEAMS_CLAUSES
| OMP_DISTRIBUTE_CLAUSES
4184 | OMP_PARALLEL_CLAUSES
| OMP_DO_CLAUSES
4185 | OMP_SIMD_CLAUSES
) & ~(omp_mask (OMP_CLAUSE_ORDERED
)));
4190 gfc_match_omp_teams_distribute_simd (void)
4192 return match_omp (EXEC_OMP_TEAMS_DISTRIBUTE_SIMD
,
4193 OMP_TEAMS_CLAUSES
| OMP_DISTRIBUTE_CLAUSES
4194 | OMP_SIMD_CLAUSES
);
4199 gfc_match_omp_workshare (void)
4201 if (gfc_match_omp_eos () != MATCH_YES
)
4203 gfc_error ("Unexpected junk after $OMP WORKSHARE statement at %C");
4206 new_st
.op
= EXEC_OMP_WORKSHARE
;
4207 new_st
.ext
.omp_clauses
= gfc_get_omp_clauses ();
4213 gfc_match_omp_master (void)
4215 if (gfc_match_omp_eos () != MATCH_YES
)
4217 gfc_error ("Unexpected junk after $OMP MASTER statement at %C");
4220 new_st
.op
= EXEC_OMP_MASTER
;
4221 new_st
.ext
.omp_clauses
= NULL
;
4227 gfc_match_omp_ordered (void)
4229 return match_omp (EXEC_OMP_ORDERED
, OMP_ORDERED_CLAUSES
);
4234 gfc_match_omp_ordered_depend (void)
4236 return match_omp (EXEC_OMP_ORDERED
, omp_mask (OMP_CLAUSE_DEPEND
));
4240 /* omp atomic [clause-list]
4241 - atomic-clause: read | write | update
4243 - memory-order-clause: seq_cst | acq_rel | release | acquire | relaxed
4248 gfc_match_omp_atomic (void)
4251 locus loc
= gfc_current_locus
;
4253 if (gfc_match_omp_clauses (&c
, OMP_ATOMIC_CLAUSES
, true, true) != MATCH_YES
)
4256 if (c
->capture
&& c
->atomic_op
!= GFC_OMP_ATOMIC_UNSET
)
4257 gfc_error ("OMP ATOMIC at %L with multiple atomic clauses", &loc
);
4259 if (c
->atomic_op
== GFC_OMP_ATOMIC_UNSET
)
4260 c
->atomic_op
= GFC_OMP_ATOMIC_UPDATE
;
4262 if (c
->memorder
== OMP_MEMORDER_UNSET
)
4264 gfc_namespace
*prog_unit
= gfc_current_ns
;
4265 while (prog_unit
->parent
)
4266 prog_unit
= prog_unit
->parent
;
4267 switch (prog_unit
->omp_requires
& OMP_REQ_ATOMIC_MEM_ORDER_MASK
)
4270 case OMP_REQ_ATOMIC_MEM_ORDER_RELAXED
:
4271 c
->memorder
= OMP_MEMORDER_RELAXED
;
4273 case OMP_REQ_ATOMIC_MEM_ORDER_SEQ_CST
:
4274 c
->memorder
= OMP_MEMORDER_SEQ_CST
;
4276 case OMP_REQ_ATOMIC_MEM_ORDER_ACQ_REL
:
4278 c
->memorder
= OMP_MEMORDER_ACQ_REL
;
4279 else if (c
->atomic_op
== GFC_OMP_ATOMIC_READ
)
4280 c
->memorder
= OMP_MEMORDER_ACQUIRE
;
4282 c
->memorder
= OMP_MEMORDER_RELEASE
;
4289 switch (c
->atomic_op
)
4291 case GFC_OMP_ATOMIC_READ
:
4292 if (c
->memorder
== OMP_MEMORDER_ACQ_REL
4293 || c
->memorder
== OMP_MEMORDER_RELEASE
)
4295 gfc_error ("!$OMP ATOMIC READ at %L incompatible with "
4296 "ACQ_REL or RELEASE clauses", &loc
);
4297 c
->memorder
= OMP_MEMORDER_SEQ_CST
;
4300 case GFC_OMP_ATOMIC_WRITE
:
4301 if (c
->memorder
== OMP_MEMORDER_ACQ_REL
4302 || c
->memorder
== OMP_MEMORDER_ACQUIRE
)
4304 gfc_error ("!$OMP ATOMIC WRITE at %L incompatible with "
4305 "ACQ_REL or ACQUIRE clauses", &loc
);
4306 c
->memorder
= OMP_MEMORDER_SEQ_CST
;
4309 case GFC_OMP_ATOMIC_UPDATE
:
4310 if ((c
->memorder
== OMP_MEMORDER_ACQ_REL
4311 || c
->memorder
== OMP_MEMORDER_ACQUIRE
)
4314 gfc_error ("!$OMP ATOMIC UPDATE at %L incompatible with "
4315 "ACQ_REL or ACQUIRE clauses", &loc
);
4316 c
->memorder
= OMP_MEMORDER_SEQ_CST
;
4323 new_st
.ext
.omp_clauses
= c
;
4324 new_st
.op
= EXEC_OMP_ATOMIC
;
4329 /* acc atomic [ read | write | update | capture] */
4332 gfc_match_oacc_atomic (void)
4334 gfc_omp_clauses
*c
= gfc_get_omp_clauses ();
4335 c
->atomic_op
= GFC_OMP_ATOMIC_UPDATE
;
4336 c
->memorder
= OMP_MEMORDER_RELAXED
;
4337 gfc_gobble_whitespace ();
4338 if (gfc_match ("update") == MATCH_YES
)
4340 else if (gfc_match ("read") == MATCH_YES
)
4341 c
->atomic_op
= GFC_OMP_ATOMIC_READ
;
4342 else if (gfc_match ("write") == MATCH_YES
)
4343 c
->atomic_op
= GFC_OMP_ATOMIC_WRITE
;
4344 else if (gfc_match ("capture") == MATCH_YES
)
4346 gfc_gobble_whitespace ();
4347 if (gfc_match_omp_eos () != MATCH_YES
)
4349 gfc_error ("Unexpected junk after !$ACC ATOMIC statement at %C");
4350 gfc_free_omp_clauses (c
);
4353 new_st
.ext
.omp_clauses
= c
;
4354 new_st
.op
= EXEC_OACC_ATOMIC
;
4360 gfc_match_omp_barrier (void)
4362 if (gfc_match_omp_eos () != MATCH_YES
)
4364 gfc_error ("Unexpected junk after $OMP BARRIER statement at %C");
4367 new_st
.op
= EXEC_OMP_BARRIER
;
4368 new_st
.ext
.omp_clauses
= NULL
;
4374 gfc_match_omp_taskgroup (void)
4376 return match_omp (EXEC_OMP_TASKGROUP
, OMP_CLAUSE_TASK_REDUCTION
);
4380 static enum gfc_omp_cancel_kind
4381 gfc_match_omp_cancel_kind (void)
4383 if (gfc_match_space () != MATCH_YES
)
4384 return OMP_CANCEL_UNKNOWN
;
4385 if (gfc_match ("parallel") == MATCH_YES
)
4386 return OMP_CANCEL_PARALLEL
;
4387 if (gfc_match ("sections") == MATCH_YES
)
4388 return OMP_CANCEL_SECTIONS
;
4389 if (gfc_match ("do") == MATCH_YES
)
4390 return OMP_CANCEL_DO
;
4391 if (gfc_match ("taskgroup") == MATCH_YES
)
4392 return OMP_CANCEL_TASKGROUP
;
4393 return OMP_CANCEL_UNKNOWN
;
4398 gfc_match_omp_cancel (void)
4401 enum gfc_omp_cancel_kind kind
= gfc_match_omp_cancel_kind ();
4402 if (kind
== OMP_CANCEL_UNKNOWN
)
4404 if (gfc_match_omp_clauses (&c
, omp_mask (OMP_CLAUSE_IF
), false) != MATCH_YES
)
4407 new_st
.op
= EXEC_OMP_CANCEL
;
4408 new_st
.ext
.omp_clauses
= c
;
4414 gfc_match_omp_cancellation_point (void)
4417 enum gfc_omp_cancel_kind kind
= gfc_match_omp_cancel_kind ();
4418 if (kind
== OMP_CANCEL_UNKNOWN
)
4420 if (gfc_match_omp_eos () != MATCH_YES
)
4422 gfc_error ("Unexpected junk after $OMP CANCELLATION POINT statement "
4426 c
= gfc_get_omp_clauses ();
4428 new_st
.op
= EXEC_OMP_CANCELLATION_POINT
;
4429 new_st
.ext
.omp_clauses
= c
;
4435 gfc_match_omp_end_nowait (void)
4437 bool nowait
= false;
4438 if (gfc_match ("% nowait") == MATCH_YES
)
4440 if (gfc_match_omp_eos () != MATCH_YES
)
4442 gfc_error ("Unexpected junk after NOWAIT clause at %C");
4445 new_st
.op
= EXEC_OMP_END_NOWAIT
;
4446 new_st
.ext
.omp_bool
= nowait
;
4452 gfc_match_omp_end_single (void)
4455 if (gfc_match ("% nowait") == MATCH_YES
)
4457 new_st
.op
= EXEC_OMP_END_NOWAIT
;
4458 new_st
.ext
.omp_bool
= true;
4461 if (gfc_match_omp_clauses (&c
, omp_mask (OMP_CLAUSE_COPYPRIVATE
))
4464 new_st
.op
= EXEC_OMP_END_SINGLE
;
4465 new_st
.ext
.omp_clauses
= c
;
4471 oacc_is_loop (gfc_code
*code
)
4473 return code
->op
== EXEC_OACC_PARALLEL_LOOP
4474 || code
->op
== EXEC_OACC_KERNELS_LOOP
4475 || code
->op
== EXEC_OACC_SERIAL_LOOP
4476 || code
->op
== EXEC_OACC_LOOP
;
4480 resolve_scalar_int_expr (gfc_expr
*expr
, const char *clause
)
4482 if (!gfc_resolve_expr (expr
)
4483 || expr
->ts
.type
!= BT_INTEGER
4485 gfc_error ("%s clause at %L requires a scalar INTEGER expression",
4486 clause
, &expr
->where
);
4490 resolve_positive_int_expr (gfc_expr
*expr
, const char *clause
)
4492 resolve_scalar_int_expr (expr
, clause
);
4493 if (expr
->expr_type
== EXPR_CONSTANT
4494 && expr
->ts
.type
== BT_INTEGER
4495 && mpz_sgn (expr
->value
.integer
) <= 0)
4496 gfc_warning (0, "INTEGER expression of %s clause at %L must be positive",
4497 clause
, &expr
->where
);
4501 resolve_nonnegative_int_expr (gfc_expr
*expr
, const char *clause
)
4503 resolve_scalar_int_expr (expr
, clause
);
4504 if (expr
->expr_type
== EXPR_CONSTANT
4505 && expr
->ts
.type
== BT_INTEGER
4506 && mpz_sgn (expr
->value
.integer
) < 0)
4507 gfc_warning (0, "INTEGER expression of %s clause at %L must be "
4508 "non-negative", clause
, &expr
->where
);
4511 /* Emits error when symbol is pointer, cray pointer or cray pointee
4512 of derived of polymorphic type. */
4515 check_symbol_not_pointer (gfc_symbol
*sym
, locus loc
, const char *name
)
4517 if (sym
->ts
.type
== BT_DERIVED
&& sym
->attr
.cray_pointer
)
4518 gfc_error ("Cray pointer object %qs of derived type in %s clause at %L",
4519 sym
->name
, name
, &loc
);
4520 if (sym
->ts
.type
== BT_DERIVED
&& sym
->attr
.cray_pointee
)
4521 gfc_error ("Cray pointee object %qs of derived type in %s clause at %L",
4522 sym
->name
, name
, &loc
);
4524 if ((sym
->ts
.type
== BT_ASSUMED
&& sym
->attr
.pointer
)
4525 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
4526 && CLASS_DATA (sym
)->attr
.pointer
))
4527 gfc_error ("POINTER object %qs of polymorphic type in %s clause at %L",
4528 sym
->name
, name
, &loc
);
4529 if ((sym
->ts
.type
== BT_ASSUMED
&& sym
->attr
.cray_pointer
)
4530 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
4531 && CLASS_DATA (sym
)->attr
.cray_pointer
))
4532 gfc_error ("Cray pointer object %qs of polymorphic type in %s clause at %L",
4533 sym
->name
, name
, &loc
);
4534 if ((sym
->ts
.type
== BT_ASSUMED
&& sym
->attr
.cray_pointee
)
4535 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
4536 && CLASS_DATA (sym
)->attr
.cray_pointee
))
4537 gfc_error ("Cray pointee object %qs of polymorphic type in %s clause at %L",
4538 sym
->name
, name
, &loc
);
4541 /* Emits error when symbol represents assumed size/rank array. */
4544 check_array_not_assumed (gfc_symbol
*sym
, locus loc
, const char *name
)
4546 if (sym
->as
&& sym
->as
->type
== AS_ASSUMED_SIZE
)
4547 gfc_error ("Assumed size array %qs in %s clause at %L",
4548 sym
->name
, name
, &loc
);
4549 if (sym
->as
&& sym
->as
->type
== AS_ASSUMED_RANK
)
4550 gfc_error ("Assumed rank array %qs in %s clause at %L",
4551 sym
->name
, name
, &loc
);
4555 resolve_oacc_data_clauses (gfc_symbol
*sym
, locus loc
, const char *name
)
4557 check_array_not_assumed (sym
, loc
, name
);
4561 resolve_oacc_deviceptr_clause (gfc_symbol
*sym
, locus loc
, const char *name
)
4563 if (sym
->attr
.pointer
4564 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
4565 && CLASS_DATA (sym
)->attr
.class_pointer
))
4566 gfc_error ("POINTER object %qs in %s clause at %L",
4567 sym
->name
, name
, &loc
);
4568 if (sym
->attr
.cray_pointer
4569 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
4570 && CLASS_DATA (sym
)->attr
.cray_pointer
))
4571 gfc_error ("Cray pointer object %qs in %s clause at %L",
4572 sym
->name
, name
, &loc
);
4573 if (sym
->attr
.cray_pointee
4574 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
4575 && CLASS_DATA (sym
)->attr
.cray_pointee
))
4576 gfc_error ("Cray pointee object %qs in %s clause at %L",
4577 sym
->name
, name
, &loc
);
4578 if (sym
->attr
.allocatable
4579 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
4580 && CLASS_DATA (sym
)->attr
.allocatable
))
4581 gfc_error ("ALLOCATABLE object %qs in %s clause at %L",
4582 sym
->name
, name
, &loc
);
4583 if (sym
->attr
.value
)
4584 gfc_error ("VALUE object %qs in %s clause at %L",
4585 sym
->name
, name
, &loc
);
4586 check_array_not_assumed (sym
, loc
, name
);
4590 struct resolve_omp_udr_callback_data
4592 gfc_symbol
*sym1
, *sym2
;
4597 resolve_omp_udr_callback (gfc_expr
**e
, int *, void *data
)
4599 struct resolve_omp_udr_callback_data
*rcd
4600 = (struct resolve_omp_udr_callback_data
*) data
;
4601 if ((*e
)->expr_type
== EXPR_VARIABLE
4602 && ((*e
)->symtree
->n
.sym
== rcd
->sym1
4603 || (*e
)->symtree
->n
.sym
== rcd
->sym2
))
4605 gfc_ref
*ref
= gfc_get_ref ();
4606 ref
->type
= REF_ARRAY
;
4607 ref
->u
.ar
.where
= (*e
)->where
;
4608 ref
->u
.ar
.as
= (*e
)->symtree
->n
.sym
->as
;
4609 ref
->u
.ar
.type
= AR_FULL
;
4610 ref
->u
.ar
.dimen
= 0;
4611 ref
->next
= (*e
)->ref
;
4619 resolve_omp_udr_callback2 (gfc_expr
**e
, int *, void *)
4621 if ((*e
)->expr_type
== EXPR_FUNCTION
4622 && (*e
)->value
.function
.isym
== NULL
)
4624 gfc_symbol
*sym
= (*e
)->symtree
->n
.sym
;
4625 if (!sym
->attr
.intrinsic
4626 && sym
->attr
.if_source
== IFSRC_UNKNOWN
)
4627 gfc_error ("Implicitly declared function %s used in "
4628 "!$OMP DECLARE REDUCTION at %L", sym
->name
, &(*e
)->where
);
4635 resolve_omp_udr_clause (gfc_omp_namelist
*n
, gfc_namespace
*ns
,
4636 gfc_symbol
*sym1
, gfc_symbol
*sym2
)
4639 gfc_symbol sym1_copy
, sym2_copy
;
4641 if (ns
->code
->op
== EXEC_ASSIGN
)
4643 copy
= gfc_get_code (EXEC_ASSIGN
);
4644 copy
->expr1
= gfc_copy_expr (ns
->code
->expr1
);
4645 copy
->expr2
= gfc_copy_expr (ns
->code
->expr2
);
4649 copy
= gfc_get_code (EXEC_CALL
);
4650 copy
->symtree
= ns
->code
->symtree
;
4651 copy
->ext
.actual
= gfc_copy_actual_arglist (ns
->code
->ext
.actual
);
4653 copy
->loc
= ns
->code
->loc
;
4658 sym1
->name
= sym1_copy
.name
;
4659 sym2
->name
= sym2_copy
.name
;
4660 ns
->proc_name
= ns
->parent
->proc_name
;
4661 if (n
->sym
->attr
.dimension
)
4663 struct resolve_omp_udr_callback_data rcd
;
4666 gfc_code_walker (©
, gfc_dummy_code_callback
,
4667 resolve_omp_udr_callback
, &rcd
);
4669 gfc_resolve_code (copy
, gfc_current_ns
);
4670 if (copy
->op
== EXEC_CALL
&& copy
->resolved_isym
== NULL
)
4672 gfc_symbol
*sym
= copy
->resolved_sym
;
4674 && !sym
->attr
.intrinsic
4675 && sym
->attr
.if_source
== IFSRC_UNKNOWN
)
4676 gfc_error ("Implicitly declared subroutine %s used in "
4677 "!$OMP DECLARE REDUCTION at %L", sym
->name
,
4680 gfc_code_walker (©
, gfc_dummy_code_callback
,
4681 resolve_omp_udr_callback2
, NULL
);
4687 /* OpenMP directive resolving routines. */
4690 resolve_omp_clauses (gfc_code
*code
, gfc_omp_clauses
*omp_clauses
,
4691 gfc_namespace
*ns
, bool openacc
= false)
4693 gfc_omp_namelist
*n
;
4697 bool if_without_mod
= false;
4698 gfc_omp_linear_op linear_op
= OMP_LINEAR_DEFAULT
;
4699 static const char *clause_names
[]
4700 = { "PRIVATE", "FIRSTPRIVATE", "LASTPRIVATE", "COPYPRIVATE", "SHARED",
4701 "COPYIN", "UNIFORM", "ALIGNED", "LINEAR", "DEPEND", "MAP",
4702 "TO", "FROM", "INCLUSIVE", "EXCLUSIVE",
4703 "REDUCTION", "REDUCTION" /*inscan*/, "REDUCTION" /*task*/,
4704 "IN_REDUCTION", "TASK_REDUCTION",
4705 "DEVICE_RESIDENT", "LINK", "USE_DEVICE",
4706 "CACHE", "IS_DEVICE_PTR", "USE_DEVICE_PTR", "USE_DEVICE_ADDR",
4708 STATIC_ASSERT (ARRAY_SIZE (clause_names
) == OMP_LIST_NUM
);
4710 if (omp_clauses
== NULL
)
4713 if (omp_clauses
->orderedc
&& omp_clauses
->orderedc
< omp_clauses
->collapse
)
4714 gfc_error ("ORDERED clause parameter is less than COLLAPSE at %L",
4717 if (omp_clauses
->if_expr
)
4719 gfc_expr
*expr
= omp_clauses
->if_expr
;
4720 if (!gfc_resolve_expr (expr
)
4721 || expr
->ts
.type
!= BT_LOGICAL
|| expr
->rank
!= 0)
4722 gfc_error ("IF clause at %L requires a scalar LOGICAL expression",
4724 if_without_mod
= true;
4726 for (ifc
= 0; ifc
< OMP_IF_LAST
; ifc
++)
4727 if (omp_clauses
->if_exprs
[ifc
])
4729 gfc_expr
*expr
= omp_clauses
->if_exprs
[ifc
];
4731 if (!gfc_resolve_expr (expr
)
4732 || expr
->ts
.type
!= BT_LOGICAL
|| expr
->rank
!= 0)
4733 gfc_error ("IF clause at %L requires a scalar LOGICAL expression",
4735 else if (if_without_mod
)
4737 gfc_error ("IF clause without modifier at %L used together with "
4738 "IF clauses with modifiers",
4739 &omp_clauses
->if_expr
->where
);
4740 if_without_mod
= false;
4745 case EXEC_OMP_CANCEL
:
4746 ok
= ifc
== OMP_IF_CANCEL
;
4749 case EXEC_OMP_PARALLEL
:
4750 case EXEC_OMP_PARALLEL_DO
:
4751 case EXEC_OMP_PARALLEL_SECTIONS
:
4752 case EXEC_OMP_PARALLEL_WORKSHARE
:
4753 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO
:
4754 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO
:
4755 ok
= ifc
== OMP_IF_PARALLEL
;
4758 case EXEC_OMP_PARALLEL_DO_SIMD
:
4759 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD
:
4760 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
4761 ok
= ifc
== OMP_IF_PARALLEL
|| ifc
== OMP_IF_SIMD
;
4765 case EXEC_OMP_DO_SIMD
:
4766 case EXEC_OMP_DISTRIBUTE_SIMD
:
4767 case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD
:
4768 ok
= ifc
== OMP_IF_SIMD
;
4772 ok
= ifc
== OMP_IF_TASK
;
4775 case EXEC_OMP_TASKLOOP
:
4776 ok
= ifc
== OMP_IF_TASKLOOP
;
4779 case EXEC_OMP_TASKLOOP_SIMD
:
4780 ok
= ifc
== OMP_IF_TASKLOOP
|| ifc
== OMP_IF_SIMD
;
4783 case EXEC_OMP_TARGET
:
4784 case EXEC_OMP_TARGET_TEAMS
:
4785 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE
:
4786 ok
= ifc
== OMP_IF_TARGET
;
4789 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD
:
4790 case EXEC_OMP_TARGET_SIMD
:
4791 ok
= ifc
== OMP_IF_TARGET
|| ifc
== OMP_IF_SIMD
;
4794 case EXEC_OMP_TARGET_DATA
:
4795 ok
= ifc
== OMP_IF_TARGET_DATA
;
4798 case EXEC_OMP_TARGET_UPDATE
:
4799 ok
= ifc
== OMP_IF_TARGET_UPDATE
;
4802 case EXEC_OMP_TARGET_ENTER_DATA
:
4803 ok
= ifc
== OMP_IF_TARGET_ENTER_DATA
;
4806 case EXEC_OMP_TARGET_EXIT_DATA
:
4807 ok
= ifc
== OMP_IF_TARGET_EXIT_DATA
;
4810 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO
:
4811 case EXEC_OMP_TARGET_PARALLEL
:
4812 case EXEC_OMP_TARGET_PARALLEL_DO
:
4813 ok
= ifc
== OMP_IF_TARGET
|| ifc
== OMP_IF_PARALLEL
;
4816 case EXEC_OMP_TARGET_PARALLEL_DO_SIMD
:
4817 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
4818 ok
= (ifc
== OMP_IF_TARGET
4819 || ifc
== OMP_IF_PARALLEL
4820 || ifc
== OMP_IF_SIMD
);
4829 static const char *ifs
[] = {
4838 "TARGET ENTER DATA",
4841 gfc_error ("IF clause modifier %s at %L not appropriate for "
4842 "the current OpenMP construct", ifs
[ifc
], &expr
->where
);
4846 if (omp_clauses
->final_expr
)
4848 gfc_expr
*expr
= omp_clauses
->final_expr
;
4849 if (!gfc_resolve_expr (expr
)
4850 || expr
->ts
.type
!= BT_LOGICAL
|| expr
->rank
!= 0)
4851 gfc_error ("FINAL clause at %L requires a scalar LOGICAL expression",
4854 if (omp_clauses
->num_threads
)
4855 resolve_positive_int_expr (omp_clauses
->num_threads
, "NUM_THREADS");
4856 if (omp_clauses
->chunk_size
)
4858 gfc_expr
*expr
= omp_clauses
->chunk_size
;
4859 if (!gfc_resolve_expr (expr
)
4860 || expr
->ts
.type
!= BT_INTEGER
|| expr
->rank
!= 0)
4861 gfc_error ("SCHEDULE clause's chunk_size at %L requires "
4862 "a scalar INTEGER expression", &expr
->where
);
4863 else if (expr
->expr_type
== EXPR_CONSTANT
4864 && expr
->ts
.type
== BT_INTEGER
4865 && mpz_sgn (expr
->value
.integer
) <= 0)
4866 gfc_warning (0, "INTEGER expression of SCHEDULE clause's chunk_size "
4867 "at %L must be positive", &expr
->where
);
4869 if (omp_clauses
->sched_kind
!= OMP_SCHED_NONE
4870 && omp_clauses
->sched_nonmonotonic
)
4872 if (omp_clauses
->sched_monotonic
)
4873 gfc_error ("Both MONOTONIC and NONMONOTONIC schedule modifiers "
4874 "specified at %L", &code
->loc
);
4875 else if (omp_clauses
->ordered
)
4876 gfc_error ("NONMONOTONIC schedule modifier specified with ORDERED "
4877 "clause at %L", &code
->loc
);
4880 /* Check that no symbol appears on multiple clauses, except that
4881 a symbol can appear on both firstprivate and lastprivate. */
4882 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
4883 for (n
= omp_clauses
->lists
[list
]; n
; n
= n
->next
)
4886 n
->sym
->comp_mark
= 0;
4887 if (n
->sym
->attr
.flavor
== FL_VARIABLE
4888 || n
->sym
->attr
.proc_pointer
4889 || (!code
&& (!n
->sym
->attr
.dummy
|| n
->sym
->ns
!= ns
)))
4891 if (!code
&& (!n
->sym
->attr
.dummy
|| n
->sym
->ns
!= ns
))
4892 gfc_error ("Variable %qs is not a dummy argument at %L",
4893 n
->sym
->name
, &n
->where
);
4896 if (n
->sym
->attr
.flavor
== FL_PROCEDURE
4897 && n
->sym
->result
== n
->sym
4898 && n
->sym
->attr
.function
)
4900 if (gfc_current_ns
->proc_name
== n
->sym
4901 || (gfc_current_ns
->parent
4902 && gfc_current_ns
->parent
->proc_name
== n
->sym
))
4904 if (gfc_current_ns
->proc_name
->attr
.entry_master
)
4906 gfc_entry_list
*el
= gfc_current_ns
->entries
;
4907 for (; el
; el
= el
->next
)
4908 if (el
->sym
== n
->sym
)
4913 if (gfc_current_ns
->parent
4914 && gfc_current_ns
->parent
->proc_name
->attr
.entry_master
)
4916 gfc_entry_list
*el
= gfc_current_ns
->parent
->entries
;
4917 for (; el
; el
= el
->next
)
4918 if (el
->sym
== n
->sym
)
4924 if (list
== OMP_LIST_MAP
4925 && n
->sym
->attr
.flavor
== FL_PARAMETER
)
4928 gfc_error ("Object %qs is not a variable at %L; parameters"
4929 " cannot be and need not be copied", n
->sym
->name
,
4932 gfc_error ("Object %qs is not a variable at %L; parameters"
4933 " cannot be and need not be mapped", n
->sym
->name
,
4937 gfc_error ("Object %qs is not a variable at %L", n
->sym
->name
,
4940 if (omp_clauses
->lists
[OMP_LIST_REDUCTION_INSCAN
]
4941 && code
->op
!= EXEC_OMP_DO
4942 && code
->op
!= EXEC_OMP_SIMD
4943 && code
->op
!= EXEC_OMP_DO_SIMD
4944 && code
->op
!= EXEC_OMP_PARALLEL_DO
4945 && code
->op
!= EXEC_OMP_PARALLEL_DO_SIMD
)
4946 gfc_error ("%<inscan%> REDUCTION clause on construct other than DO, SIMD, "
4947 "DO SIMD, PARALLEL DO, PARALLEL DO SIMD at %L",
4948 &omp_clauses
->lists
[OMP_LIST_REDUCTION_INSCAN
]->where
);
4950 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
4951 if (list
!= OMP_LIST_FIRSTPRIVATE
4952 && list
!= OMP_LIST_LASTPRIVATE
4953 && list
!= OMP_LIST_ALIGNED
4954 && list
!= OMP_LIST_DEPEND
4955 && (list
!= OMP_LIST_MAP
|| openacc
)
4956 && list
!= OMP_LIST_FROM
4957 && list
!= OMP_LIST_TO
4958 && (list
!= OMP_LIST_REDUCTION
|| !openacc
)
4959 && list
!= OMP_LIST_REDUCTION_INSCAN
4960 && list
!= OMP_LIST_REDUCTION_TASK
4961 && list
!= OMP_LIST_IN_REDUCTION
4962 && list
!= OMP_LIST_TASK_REDUCTION
)
4963 for (n
= omp_clauses
->lists
[list
]; n
; n
= n
->next
)
4965 bool component_ref_p
= false;
4967 /* Allow multiple components of the same (e.g. derived-type)
4968 variable here. Duplicate components are detected elsewhere. */
4969 if (n
->expr
&& n
->expr
->expr_type
== EXPR_VARIABLE
)
4970 for (gfc_ref
*ref
= n
->expr
->ref
; ref
; ref
= ref
->next
)
4971 if (ref
->type
== REF_COMPONENT
)
4972 component_ref_p
= true;
4973 if ((!component_ref_p
&& n
->sym
->comp_mark
)
4974 || (component_ref_p
&& n
->sym
->mark
))
4975 gfc_error ("Symbol %qs has mixed component and non-component "
4976 "accesses at %L", n
->sym
->name
, &n
->where
);
4977 else if (n
->sym
->mark
)
4978 gfc_error ("Symbol %qs present on multiple clauses at %L",
4979 n
->sym
->name
, &n
->where
);
4982 if (component_ref_p
)
4983 n
->sym
->comp_mark
= 1;
4989 gcc_assert (OMP_LIST_LASTPRIVATE
== OMP_LIST_FIRSTPRIVATE
+ 1);
4990 for (list
= OMP_LIST_FIRSTPRIVATE
; list
<= OMP_LIST_LASTPRIVATE
; list
++)
4991 for (n
= omp_clauses
->lists
[list
]; n
; n
= n
->next
)
4994 gfc_error ("Symbol %qs present on multiple clauses at %L",
4995 n
->sym
->name
, &n
->where
);
4999 for (n
= omp_clauses
->lists
[OMP_LIST_FIRSTPRIVATE
]; n
; n
= n
->next
)
5002 gfc_error ("Symbol %qs present on multiple clauses at %L",
5003 n
->sym
->name
, &n
->where
);
5007 for (n
= omp_clauses
->lists
[OMP_LIST_LASTPRIVATE
]; n
; n
= n
->next
)
5010 for (n
= omp_clauses
->lists
[OMP_LIST_LASTPRIVATE
]; n
; n
= n
->next
)
5013 gfc_error ("Symbol %qs present on multiple clauses at %L",
5014 n
->sym
->name
, &n
->where
);
5019 for (n
= omp_clauses
->lists
[OMP_LIST_ALIGNED
]; n
; n
= n
->next
)
5022 for (n
= omp_clauses
->lists
[OMP_LIST_ALIGNED
]; n
; n
= n
->next
)
5025 gfc_error ("Symbol %qs present on multiple clauses at %L",
5026 n
->sym
->name
, &n
->where
);
5031 /* OpenACC reductions. */
5034 for (n
= omp_clauses
->lists
[OMP_LIST_REDUCTION
]; n
; n
= n
->next
)
5037 for (n
= omp_clauses
->lists
[OMP_LIST_REDUCTION
]; n
; n
= n
->next
)
5040 gfc_error ("Symbol %qs present on multiple clauses at %L",
5041 n
->sym
->name
, &n
->where
);
5045 /* OpenACC does not support reductions on arrays. */
5047 gfc_error ("Array %qs is not permitted in reduction at %L",
5048 n
->sym
->name
, &n
->where
);
5052 for (n
= omp_clauses
->lists
[OMP_LIST_TO
]; n
; n
= n
->next
)
5054 for (n
= omp_clauses
->lists
[OMP_LIST_FROM
]; n
; n
= n
->next
)
5055 if (n
->expr
== NULL
)
5057 for (n
= omp_clauses
->lists
[OMP_LIST_TO
]; n
; n
= n
->next
)
5059 if (n
->expr
== NULL
&& n
->sym
->mark
)
5060 gfc_error ("Symbol %qs present on both FROM and TO clauses at %L",
5061 n
->sym
->name
, &n
->where
);
5066 bool has_inscan
= false, has_notinscan
= false;
5067 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
5068 if ((n
= omp_clauses
->lists
[list
]) != NULL
)
5070 const char *name
= clause_names
[list
];
5074 case OMP_LIST_COPYIN
:
5075 for (; n
!= NULL
; n
= n
->next
)
5077 if (!n
->sym
->attr
.threadprivate
)
5078 gfc_error ("Non-THREADPRIVATE object %qs in COPYIN clause"
5079 " at %L", n
->sym
->name
, &n
->where
);
5082 case OMP_LIST_COPYPRIVATE
:
5083 for (; n
!= NULL
; n
= n
->next
)
5085 if (n
->sym
->as
&& n
->sym
->as
->type
== AS_ASSUMED_SIZE
)
5086 gfc_error ("Assumed size array %qs in COPYPRIVATE clause "
5087 "at %L", n
->sym
->name
, &n
->where
);
5088 if (n
->sym
->attr
.pointer
&& n
->sym
->attr
.intent
== INTENT_IN
)
5089 gfc_error ("INTENT(IN) POINTER %qs in COPYPRIVATE clause "
5090 "at %L", n
->sym
->name
, &n
->where
);
5093 case OMP_LIST_SHARED
:
5094 for (; n
!= NULL
; n
= n
->next
)
5096 if (n
->sym
->attr
.threadprivate
)
5097 gfc_error ("THREADPRIVATE object %qs in SHARED clause at "
5098 "%L", n
->sym
->name
, &n
->where
);
5099 if (n
->sym
->attr
.cray_pointee
)
5100 gfc_error ("Cray pointee %qs in SHARED clause at %L",
5101 n
->sym
->name
, &n
->where
);
5102 if (n
->sym
->attr
.associate_var
)
5103 gfc_error ("ASSOCIATE name %qs in SHARED clause at %L",
5104 n
->sym
->name
, &n
->where
);
5105 if (omp_clauses
->detach
5106 && n
->sym
== omp_clauses
->detach
->symtree
->n
.sym
)
5107 gfc_error ("DETACH event handle %qs in SHARED clause at %L",
5108 n
->sym
->name
, &n
->where
);
5111 case OMP_LIST_ALIGNED
:
5112 for (; n
!= NULL
; n
= n
->next
)
5114 if (!n
->sym
->attr
.pointer
5115 && !n
->sym
->attr
.allocatable
5116 && !n
->sym
->attr
.cray_pointer
5117 && (n
->sym
->ts
.type
!= BT_DERIVED
5118 || (n
->sym
->ts
.u
.derived
->from_intmod
5119 != INTMOD_ISO_C_BINDING
)
5120 || (n
->sym
->ts
.u
.derived
->intmod_sym_id
5121 != ISOCBINDING_PTR
)))
5122 gfc_error ("%qs in ALIGNED clause must be POINTER, "
5123 "ALLOCATABLE, Cray pointer or C_PTR at %L",
5124 n
->sym
->name
, &n
->where
);
5127 gfc_expr
*expr
= n
->expr
;
5129 if (!gfc_resolve_expr (expr
)
5130 || expr
->ts
.type
!= BT_INTEGER
5132 || gfc_extract_int (expr
, &alignment
)
5134 gfc_error ("%qs in ALIGNED clause at %L requires a scalar "
5135 "positive constant integer alignment "
5136 "expression", n
->sym
->name
, &n
->where
);
5140 case OMP_LIST_DEPEND
:
5144 case OMP_LIST_CACHE
:
5145 for (; n
!= NULL
; n
= n
->next
)
5147 if (list
== OMP_LIST_DEPEND
)
5149 if (n
->u
.depend_op
== OMP_DEPEND_SINK_FIRST
5150 || n
->u
.depend_op
== OMP_DEPEND_SINK
)
5152 if (code
->op
!= EXEC_OMP_ORDERED
)
5153 gfc_error ("SINK dependence type only allowed "
5154 "on ORDERED directive at %L", &n
->where
);
5155 else if (omp_clauses
->depend_source
)
5157 gfc_error ("DEPEND SINK used together with "
5158 "DEPEND SOURCE on the same construct "
5159 "at %L", &n
->where
);
5160 omp_clauses
->depend_source
= false;
5164 if (!gfc_resolve_expr (n
->expr
)
5165 || n
->expr
->ts
.type
!= BT_INTEGER
5166 || n
->expr
->rank
!= 0)
5167 gfc_error ("SINK addend not a constant integer "
5168 "at %L", &n
->where
);
5172 else if (code
->op
== EXEC_OMP_ORDERED
)
5173 gfc_error ("Only SOURCE or SINK dependence types "
5174 "are allowed on ORDERED directive at %L",
5177 gfc_ref
*array_ref
= NULL
;
5178 bool resolved
= false;
5181 array_ref
= n
->expr
->ref
;
5182 resolved
= gfc_resolve_expr (n
->expr
);
5184 /* Look through component refs to find last array
5188 /* The "!$acc cache" directive allows rectangular
5189 subarrays to be specified, with some restrictions
5190 on the form of bounds (not implemented).
5191 Only raise an error here if we're really sure the
5192 array isn't contiguous. An expression such as
5193 arr(-n:n,-n:n) could be contiguous even if it looks
5194 like it may not be. */
5195 if (list
!= OMP_LIST_CACHE
5196 && list
!= OMP_LIST_DEPEND
5197 && !gfc_is_simply_contiguous (n
->expr
, false, true)
5198 && gfc_is_not_contiguous (n
->expr
))
5199 gfc_error ("Array is not contiguous at %L",
5203 && (array_ref
->type
== REF_COMPONENT
5204 || (array_ref
->type
== REF_ARRAY
5206 && (array_ref
->next
->type
5207 == REF_COMPONENT
))))
5208 array_ref
= array_ref
->next
;
5213 && (!resolved
|| n
->expr
->expr_type
!= EXPR_VARIABLE
)))
5216 || n
->expr
->expr_type
!= EXPR_VARIABLE
5218 || array_ref
->type
!= REF_ARRAY
)
5219 gfc_error ("%qs in %s clause at %L is not a proper "
5220 "array section", n
->sym
->name
, name
,
5225 gfc_array_ref
*ar
= &array_ref
->u
.ar
;
5226 for (i
= 0; i
< ar
->dimen
; i
++)
5229 gfc_error ("Stride should not be specified for "
5230 "array section in %s clause at %L",
5234 else if (ar
->dimen_type
[i
] != DIMEN_ELEMENT
5235 && ar
->dimen_type
[i
] != DIMEN_RANGE
)
5237 gfc_error ("%qs in %s clause at %L is not a "
5238 "proper array section",
5239 n
->sym
->name
, name
, &n
->where
);
5242 else if (list
== OMP_LIST_DEPEND
5244 && ar
->start
[i
]->expr_type
== EXPR_CONSTANT
5246 && ar
->end
[i
]->expr_type
== EXPR_CONSTANT
5247 && mpz_cmp (ar
->start
[i
]->value
.integer
,
5248 ar
->end
[i
]->value
.integer
) > 0)
5250 gfc_error ("%qs in DEPEND clause at %L is a "
5251 "zero size array section",
5252 n
->sym
->name
, &n
->where
);
5259 if (list
== OMP_LIST_MAP
5260 && n
->u
.map_op
== OMP_MAP_FORCE_DEVICEPTR
)
5261 resolve_oacc_deviceptr_clause (n
->sym
, n
->where
, name
);
5263 resolve_oacc_data_clauses (n
->sym
, n
->where
, name
);
5265 else if (list
!= OMP_LIST_DEPEND
5267 && n
->sym
->as
->type
== AS_ASSUMED_SIZE
)
5268 gfc_error ("Assumed size array %qs in %s clause at %L",
5269 n
->sym
->name
, name
, &n
->where
);
5271 && list
== OMP_LIST_MAP
5272 && n
->sym
->ts
.type
== BT_DERIVED
5273 && n
->sym
->ts
.u
.derived
->attr
.alloc_comp
)
5274 gfc_error ("List item %qs with allocatable components is not "
5275 "permitted in map clause at %L", n
->sym
->name
,
5277 if (list
== OMP_LIST_MAP
&& !openacc
)
5280 case EXEC_OMP_TARGET
:
5281 case EXEC_OMP_TARGET_DATA
:
5282 switch (n
->u
.map_op
)
5285 case OMP_MAP_ALWAYS_TO
:
5287 case OMP_MAP_ALWAYS_FROM
:
5288 case OMP_MAP_TOFROM
:
5289 case OMP_MAP_ALWAYS_TOFROM
:
5293 gfc_error ("TARGET%s with map-type other than TO, "
5294 "FROM, TOFROM, or ALLOC on MAP clause "
5296 code
->op
== EXEC_OMP_TARGET
5297 ? "" : " DATA", &n
->where
);
5301 case EXEC_OMP_TARGET_ENTER_DATA
:
5302 switch (n
->u
.map_op
)
5305 case OMP_MAP_ALWAYS_TO
:
5309 gfc_error ("TARGET ENTER DATA with map-type other "
5310 "than TO, or ALLOC on MAP clause at %L",
5315 case EXEC_OMP_TARGET_EXIT_DATA
:
5316 switch (n
->u
.map_op
)
5319 case OMP_MAP_ALWAYS_FROM
:
5320 case OMP_MAP_RELEASE
:
5321 case OMP_MAP_DELETE
:
5324 gfc_error ("TARGET EXIT DATA with map-type other "
5325 "than FROM, RELEASE, or DELETE on MAP "
5326 "clause at %L", &n
->where
);
5335 if (list
!= OMP_LIST_DEPEND
)
5336 for (n
= omp_clauses
->lists
[list
]; n
!= NULL
; n
= n
->next
)
5338 n
->sym
->attr
.referenced
= 1;
5339 if (n
->sym
->attr
.threadprivate
)
5340 gfc_error ("THREADPRIVATE object %qs in %s clause at %L",
5341 n
->sym
->name
, name
, &n
->where
);
5342 if (n
->sym
->attr
.cray_pointee
)
5343 gfc_error ("Cray pointee %qs in %s clause at %L",
5344 n
->sym
->name
, name
, &n
->where
);
5347 case OMP_LIST_IS_DEVICE_PTR
:
5348 if (!n
->sym
->attr
.dummy
)
5349 gfc_error ("Non-dummy object %qs in %s clause at %L",
5350 n
->sym
->name
, name
, &n
->where
);
5351 if (n
->sym
->attr
.allocatable
5352 || (n
->sym
->ts
.type
== BT_CLASS
5353 && CLASS_DATA (n
->sym
)->attr
.allocatable
))
5354 gfc_error ("ALLOCATABLE object %qs in %s clause at %L",
5355 n
->sym
->name
, name
, &n
->where
);
5356 if (n
->sym
->attr
.pointer
5357 || (n
->sym
->ts
.type
== BT_CLASS
5358 && CLASS_DATA (n
->sym
)->attr
.pointer
))
5359 gfc_error ("POINTER object %qs in %s clause at %L",
5360 n
->sym
->name
, name
, &n
->where
);
5361 if (n
->sym
->attr
.value
)
5362 gfc_error ("VALUE object %qs in %s clause at %L",
5363 n
->sym
->name
, name
, &n
->where
);
5365 case OMP_LIST_USE_DEVICE_PTR
:
5366 case OMP_LIST_USE_DEVICE_ADDR
:
5367 /* FIXME: Handle OMP_LIST_USE_DEVICE_PTR. */
5370 for (; n
!= NULL
; n
= n
->next
)
5373 bool is_reduction
= (list
== OMP_LIST_REDUCTION
5374 || list
== OMP_LIST_REDUCTION_INSCAN
5375 || list
== OMP_LIST_REDUCTION_TASK
5376 || list
== OMP_LIST_IN_REDUCTION
5377 || list
== OMP_LIST_TASK_REDUCTION
);
5378 if (list
== OMP_LIST_REDUCTION_INSCAN
)
5380 else if (is_reduction
)
5381 has_notinscan
= true;
5382 if (has_inscan
&& has_notinscan
&& is_reduction
)
5384 gfc_error ("%<inscan%> and non-%<inscan%> %<reduction%> "
5385 "clauses on the same construct %L",
5389 if (n
->sym
->attr
.threadprivate
)
5390 gfc_error ("THREADPRIVATE object %qs in %s clause at %L",
5391 n
->sym
->name
, name
, &n
->where
);
5392 if (n
->sym
->attr
.cray_pointee
)
5393 gfc_error ("Cray pointee %qs in %s clause at %L",
5394 n
->sym
->name
, name
, &n
->where
);
5395 if (n
->sym
->attr
.associate_var
)
5396 gfc_error ("ASSOCIATE name %qs in %s clause at %L",
5397 n
->sym
->name
, name
, &n
->where
);
5398 if (list
!= OMP_LIST_PRIVATE
&& is_reduction
)
5400 if (n
->sym
->attr
.proc_pointer
)
5401 gfc_error ("Procedure pointer %qs in %s clause at %L",
5402 n
->sym
->name
, name
, &n
->where
);
5403 if (n
->sym
->attr
.pointer
)
5404 gfc_error ("POINTER object %qs in %s clause at %L",
5405 n
->sym
->name
, name
, &n
->where
);
5406 if (n
->sym
->attr
.cray_pointer
)
5407 gfc_error ("Cray pointer %qs in %s clause at %L",
5408 n
->sym
->name
, name
, &n
->where
);
5411 && (oacc_is_loop (code
)
5412 || code
->op
== EXEC_OACC_PARALLEL
5413 || code
->op
== EXEC_OACC_SERIAL
))
5414 check_array_not_assumed (n
->sym
, n
->where
, name
);
5415 else if (n
->sym
->as
&& n
->sym
->as
->type
== AS_ASSUMED_SIZE
)
5416 gfc_error ("Assumed size array %qs in %s clause at %L",
5417 n
->sym
->name
, name
, &n
->where
);
5418 if (n
->sym
->attr
.in_namelist
&& !is_reduction
)
5419 gfc_error ("Variable %qs in %s clause is used in "
5420 "NAMELIST statement at %L",
5421 n
->sym
->name
, name
, &n
->where
);
5422 if (n
->sym
->attr
.pointer
&& n
->sym
->attr
.intent
== INTENT_IN
)
5425 case OMP_LIST_PRIVATE
:
5426 case OMP_LIST_LASTPRIVATE
:
5427 case OMP_LIST_LINEAR
:
5428 /* case OMP_LIST_REDUCTION: */
5429 gfc_error ("INTENT(IN) POINTER %qs in %s clause at %L",
5430 n
->sym
->name
, name
, &n
->where
);
5435 if (omp_clauses
->detach
5436 && (list
== OMP_LIST_PRIVATE
5437 || list
== OMP_LIST_FIRSTPRIVATE
5438 || list
== OMP_LIST_LASTPRIVATE
)
5439 && n
->sym
== omp_clauses
->detach
->symtree
->n
.sym
)
5440 gfc_error ("DETACH event handle %qs in %s clause at %L",
5441 n
->sym
->name
, name
, &n
->where
);
5444 case OMP_LIST_REDUCTION_INSCAN
:
5445 case OMP_LIST_REDUCTION_TASK
:
5446 if (code
&& (code
->op
== EXEC_OMP_TASKLOOP
5447 || code
->op
== EXEC_OMP_TEAMS
5448 || code
->op
== EXEC_OMP_TEAMS_DISTRIBUTE
))
5450 gfc_error ("Only DEFAULT permitted as reduction-"
5451 "modifier in REDUCTION clause at %L",
5456 case OMP_LIST_REDUCTION
:
5457 case OMP_LIST_IN_REDUCTION
:
5458 case OMP_LIST_TASK_REDUCTION
:
5459 switch (n
->u
.reduction_op
)
5461 case OMP_REDUCTION_PLUS
:
5462 case OMP_REDUCTION_TIMES
:
5463 case OMP_REDUCTION_MINUS
:
5464 if (!gfc_numeric_ts (&n
->sym
->ts
))
5467 case OMP_REDUCTION_AND
:
5468 case OMP_REDUCTION_OR
:
5469 case OMP_REDUCTION_EQV
:
5470 case OMP_REDUCTION_NEQV
:
5471 if (n
->sym
->ts
.type
!= BT_LOGICAL
)
5474 case OMP_REDUCTION_MAX
:
5475 case OMP_REDUCTION_MIN
:
5476 if (n
->sym
->ts
.type
!= BT_INTEGER
5477 && n
->sym
->ts
.type
!= BT_REAL
)
5480 case OMP_REDUCTION_IAND
:
5481 case OMP_REDUCTION_IOR
:
5482 case OMP_REDUCTION_IEOR
:
5483 if (n
->sym
->ts
.type
!= BT_INTEGER
)
5486 case OMP_REDUCTION_USER
:
5496 const char *udr_name
= NULL
;
5499 udr_name
= n
->udr
->udr
->name
;
5501 = gfc_find_omp_udr (NULL
, udr_name
,
5503 if (n
->udr
->udr
== NULL
)
5511 if (udr_name
== NULL
)
5512 switch (n
->u
.reduction_op
)
5514 case OMP_REDUCTION_PLUS
:
5515 case OMP_REDUCTION_TIMES
:
5516 case OMP_REDUCTION_MINUS
:
5517 case OMP_REDUCTION_AND
:
5518 case OMP_REDUCTION_OR
:
5519 case OMP_REDUCTION_EQV
:
5520 case OMP_REDUCTION_NEQV
:
5521 udr_name
= gfc_op2string ((gfc_intrinsic_op
)
5524 case OMP_REDUCTION_MAX
:
5527 case OMP_REDUCTION_MIN
:
5530 case OMP_REDUCTION_IAND
:
5533 case OMP_REDUCTION_IOR
:
5536 case OMP_REDUCTION_IEOR
:
5542 gfc_error ("!$OMP DECLARE REDUCTION %s not found "
5543 "for type %s at %L", udr_name
,
5544 gfc_typename (&n
->sym
->ts
), &n
->where
);
5548 gfc_omp_udr
*udr
= n
->udr
->udr
;
5549 n
->u
.reduction_op
= OMP_REDUCTION_USER
;
5551 = resolve_omp_udr_clause (n
, udr
->combiner_ns
,
5554 if (udr
->initializer_ns
)
5556 = resolve_omp_udr_clause (n
,
5557 udr
->initializer_ns
,
5563 case OMP_LIST_LINEAR
:
5565 && n
->u
.linear_op
!= OMP_LINEAR_DEFAULT
5566 && n
->u
.linear_op
!= linear_op
)
5568 gfc_error ("LINEAR clause modifier used on DO or SIMD"
5569 " construct at %L", &n
->where
);
5570 linear_op
= n
->u
.linear_op
;
5572 else if (omp_clauses
->orderedc
)
5573 gfc_error ("LINEAR clause specified together with "
5574 "ORDERED clause with argument at %L",
5576 else if (n
->u
.linear_op
!= OMP_LINEAR_REF
5577 && n
->sym
->ts
.type
!= BT_INTEGER
)
5578 gfc_error ("LINEAR variable %qs must be INTEGER "
5579 "at %L", n
->sym
->name
, &n
->where
);
5580 else if ((n
->u
.linear_op
== OMP_LINEAR_REF
5581 || n
->u
.linear_op
== OMP_LINEAR_UVAL
)
5582 && n
->sym
->attr
.value
)
5583 gfc_error ("LINEAR dummy argument %qs with VALUE "
5584 "attribute with %s modifier at %L",
5586 n
->u
.linear_op
== OMP_LINEAR_REF
5587 ? "REF" : "UVAL", &n
->where
);
5590 gfc_expr
*expr
= n
->expr
;
5591 if (!gfc_resolve_expr (expr
)
5592 || expr
->ts
.type
!= BT_INTEGER
5594 gfc_error ("%qs in LINEAR clause at %L requires "
5595 "a scalar integer linear-step expression",
5596 n
->sym
->name
, &n
->where
);
5597 else if (!code
&& expr
->expr_type
!= EXPR_CONSTANT
)
5599 if (expr
->expr_type
== EXPR_VARIABLE
5600 && expr
->symtree
->n
.sym
->attr
.dummy
5601 && expr
->symtree
->n
.sym
->ns
== ns
)
5603 gfc_omp_namelist
*n2
;
5604 for (n2
= omp_clauses
->lists
[OMP_LIST_UNIFORM
];
5606 if (n2
->sym
== expr
->symtree
->n
.sym
)
5611 gfc_error ("%qs in LINEAR clause at %L requires "
5612 "a constant integer linear-step "
5613 "expression or dummy argument "
5614 "specified in UNIFORM clause",
5615 n
->sym
->name
, &n
->where
);
5619 /* Workaround for PR middle-end/26316, nothing really needs
5620 to be done here for OMP_LIST_PRIVATE. */
5621 case OMP_LIST_PRIVATE
:
5622 gcc_assert (code
&& code
->op
!= EXEC_NOP
);
5624 case OMP_LIST_USE_DEVICE
:
5625 if (n
->sym
->attr
.allocatable
5626 || (n
->sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (n
->sym
)
5627 && CLASS_DATA (n
->sym
)->attr
.allocatable
))
5628 gfc_error ("ALLOCATABLE object %qs in %s clause at %L",
5629 n
->sym
->name
, name
, &n
->where
);
5630 if (n
->sym
->ts
.type
== BT_CLASS
5631 && CLASS_DATA (n
->sym
)
5632 && CLASS_DATA (n
->sym
)->attr
.class_pointer
)
5633 gfc_error ("POINTER object %qs of polymorphic type in "
5634 "%s clause at %L", n
->sym
->name
, name
,
5636 if (n
->sym
->attr
.cray_pointer
)
5637 gfc_error ("Cray pointer object %qs in %s clause at %L",
5638 n
->sym
->name
, name
, &n
->where
);
5639 else if (n
->sym
->attr
.cray_pointee
)
5640 gfc_error ("Cray pointee object %qs in %s clause at %L",
5641 n
->sym
->name
, name
, &n
->where
);
5642 else if (n
->sym
->attr
.flavor
== FL_VARIABLE
5644 && !n
->sym
->attr
.pointer
)
5645 gfc_error ("%s clause variable %qs at %L is neither "
5646 "a POINTER nor an array", name
,
5647 n
->sym
->name
, &n
->where
);
5649 case OMP_LIST_DEVICE_RESIDENT
:
5650 check_symbol_not_pointer (n
->sym
, n
->where
, name
);
5651 check_array_not_assumed (n
->sym
, n
->where
, name
);
5660 if (omp_clauses
->safelen_expr
)
5661 resolve_positive_int_expr (omp_clauses
->safelen_expr
, "SAFELEN");
5662 if (omp_clauses
->simdlen_expr
)
5663 resolve_positive_int_expr (omp_clauses
->simdlen_expr
, "SIMDLEN");
5664 if (omp_clauses
->num_teams
)
5665 resolve_positive_int_expr (omp_clauses
->num_teams
, "NUM_TEAMS");
5666 if (omp_clauses
->device
)
5667 resolve_nonnegative_int_expr (omp_clauses
->device
, "DEVICE");
5668 if (omp_clauses
->hint
)
5670 resolve_scalar_int_expr (omp_clauses
->hint
, "HINT");
5671 if (omp_clauses
->hint
->ts
.type
!= BT_INTEGER
5672 || omp_clauses
->hint
->expr_type
!= EXPR_CONSTANT
5673 || mpz_sgn (omp_clauses
->hint
->value
.integer
) < 0)
5674 gfc_error ("Value of HINT clause at %L shall be a valid "
5675 "constant hint expression", &omp_clauses
->hint
->where
);
5677 if (omp_clauses
->priority
)
5678 resolve_nonnegative_int_expr (omp_clauses
->priority
, "PRIORITY");
5679 if (omp_clauses
->dist_chunk_size
)
5681 gfc_expr
*expr
= omp_clauses
->dist_chunk_size
;
5682 if (!gfc_resolve_expr (expr
)
5683 || expr
->ts
.type
!= BT_INTEGER
|| expr
->rank
!= 0)
5684 gfc_error ("DIST_SCHEDULE clause's chunk_size at %L requires "
5685 "a scalar INTEGER expression", &expr
->where
);
5687 if (omp_clauses
->thread_limit
)
5688 resolve_positive_int_expr (omp_clauses
->thread_limit
, "THREAD_LIMIT");
5689 if (omp_clauses
->grainsize
)
5690 resolve_positive_int_expr (omp_clauses
->grainsize
, "GRAINSIZE");
5691 if (omp_clauses
->num_tasks
)
5692 resolve_positive_int_expr (omp_clauses
->num_tasks
, "NUM_TASKS");
5693 if (omp_clauses
->async
)
5694 if (omp_clauses
->async_expr
)
5695 resolve_scalar_int_expr (omp_clauses
->async_expr
, "ASYNC");
5696 if (omp_clauses
->num_gangs_expr
)
5697 resolve_positive_int_expr (omp_clauses
->num_gangs_expr
, "NUM_GANGS");
5698 if (omp_clauses
->num_workers_expr
)
5699 resolve_positive_int_expr (omp_clauses
->num_workers_expr
, "NUM_WORKERS");
5700 if (omp_clauses
->vector_length_expr
)
5701 resolve_positive_int_expr (omp_clauses
->vector_length_expr
,
5703 if (omp_clauses
->gang_num_expr
)
5704 resolve_positive_int_expr (omp_clauses
->gang_num_expr
, "GANG");
5705 if (omp_clauses
->gang_static_expr
)
5706 resolve_positive_int_expr (omp_clauses
->gang_static_expr
, "GANG");
5707 if (omp_clauses
->worker_expr
)
5708 resolve_positive_int_expr (omp_clauses
->worker_expr
, "WORKER");
5709 if (omp_clauses
->vector_expr
)
5710 resolve_positive_int_expr (omp_clauses
->vector_expr
, "VECTOR");
5711 for (el
= omp_clauses
->wait_list
; el
; el
= el
->next
)
5712 resolve_scalar_int_expr (el
->expr
, "WAIT");
5713 if (omp_clauses
->collapse
&& omp_clauses
->tile_list
)
5714 gfc_error ("Incompatible use of TILE and COLLAPSE at %L", &code
->loc
);
5715 if (omp_clauses
->depend_source
&& code
->op
!= EXEC_OMP_ORDERED
)
5716 gfc_error ("SOURCE dependence type only allowed "
5717 "on ORDERED directive at %L", &code
->loc
);
5720 && omp_clauses
->lists
[OMP_LIST_MAP
] == NULL
5721 && omp_clauses
->lists
[OMP_LIST_USE_DEVICE_PTR
] == NULL
5722 && omp_clauses
->lists
[OMP_LIST_USE_DEVICE_ADDR
] == NULL
)
5724 const char *p
= NULL
;
5727 case EXEC_OMP_TARGET_ENTER_DATA
: p
= "TARGET ENTER DATA"; break;
5728 case EXEC_OMP_TARGET_EXIT_DATA
: p
= "TARGET EXIT DATA"; break;
5731 if (code
->op
== EXEC_OMP_TARGET_DATA
)
5732 gfc_error ("TARGET DATA must contain at least one MAP, USE_DEVICE_PTR, "
5733 "or USE_DEVICE_ADDR clause at %L", &code
->loc
);
5735 gfc_error ("%s must contain at least one MAP clause at %L",
5738 if (!openacc
&& omp_clauses
->mergeable
&& omp_clauses
->detach
)
5739 gfc_error ("%<DETACH%> clause at %L must not be used together with "
5740 "%<MERGEABLE%> clause", &omp_clauses
->detach
->where
);
5744 /* Return true if SYM is ever referenced in EXPR except in the SE node. */
5747 expr_references_sym (gfc_expr
*e
, gfc_symbol
*s
, gfc_expr
*se
)
5749 gfc_actual_arglist
*arg
;
5750 if (e
== NULL
|| e
== se
)
5752 switch (e
->expr_type
)
5757 case EXPR_STRUCTURE
:
5759 if (e
->symtree
!= NULL
5760 && e
->symtree
->n
.sym
== s
)
5763 case EXPR_SUBSTRING
:
5765 && (expr_references_sym (e
->ref
->u
.ss
.start
, s
, se
)
5766 || expr_references_sym (e
->ref
->u
.ss
.end
, s
, se
)))
5770 if (expr_references_sym (e
->value
.op
.op2
, s
, se
))
5772 return expr_references_sym (e
->value
.op
.op1
, s
, se
);
5774 for (arg
= e
->value
.function
.actual
; arg
; arg
= arg
->next
)
5775 if (expr_references_sym (arg
->expr
, s
, se
))
5784 /* If EXPR is a conversion function that widens the type
5785 if WIDENING is true or narrows the type if WIDENING is false,
5786 return the inner expression, otherwise return NULL. */
5789 is_conversion (gfc_expr
*expr
, bool widening
)
5791 gfc_typespec
*ts1
, *ts2
;
5793 if (expr
->expr_type
!= EXPR_FUNCTION
5794 || expr
->value
.function
.isym
== NULL
5795 || expr
->value
.function
.esym
!= NULL
5796 || expr
->value
.function
.isym
->id
!= GFC_ISYM_CONVERSION
)
5802 ts2
= &expr
->value
.function
.actual
->expr
->ts
;
5806 ts1
= &expr
->value
.function
.actual
->expr
->ts
;
5810 if (ts1
->type
> ts2
->type
5811 || (ts1
->type
== ts2
->type
&& ts1
->kind
> ts2
->kind
))
5812 return expr
->value
.function
.actual
->expr
;
5819 resolve_omp_atomic (gfc_code
*code
)
5821 gfc_code
*atomic_code
= code
->block
;
5823 gfc_expr
*expr2
, *expr2_tmp
;
5824 gfc_omp_atomic_op aop
5825 = (gfc_omp_atomic_op
) (atomic_code
->ext
.omp_clauses
->atomic_op
5826 & GFC_OMP_ATOMIC_MASK
);
5828 code
= code
->block
->next
;
5829 /* resolve_blocks asserts this is initially EXEC_ASSIGN.
5830 If it changed to EXEC_NOP, assume an error has been emitted already. */
5831 if (code
->op
== EXEC_NOP
)
5833 if (code
->op
!= EXEC_ASSIGN
)
5836 gfc_error ("unexpected !$OMP ATOMIC expression at %L", &code
->loc
);
5839 if (!atomic_code
->ext
.omp_clauses
->capture
)
5841 if (code
->next
!= NULL
)
5846 if (code
->next
== NULL
)
5848 if (code
->next
->op
== EXEC_NOP
)
5850 if (code
->next
->op
!= EXEC_ASSIGN
|| code
->next
->next
)
5857 if (code
->expr1
->expr_type
!= EXPR_VARIABLE
5858 || code
->expr1
->symtree
== NULL
5859 || code
->expr1
->rank
!= 0
5860 || (code
->expr1
->ts
.type
!= BT_INTEGER
5861 && code
->expr1
->ts
.type
!= BT_REAL
5862 && code
->expr1
->ts
.type
!= BT_COMPLEX
5863 && code
->expr1
->ts
.type
!= BT_LOGICAL
))
5865 gfc_error ("!$OMP ATOMIC statement must set a scalar variable of "
5866 "intrinsic type at %L", &code
->loc
);
5870 var
= code
->expr1
->symtree
->n
.sym
;
5871 expr2
= is_conversion (code
->expr2
, false);
5874 if (aop
== GFC_OMP_ATOMIC_READ
|| aop
== GFC_OMP_ATOMIC_WRITE
)
5875 expr2
= is_conversion (code
->expr2
, true);
5877 expr2
= code
->expr2
;
5882 case GFC_OMP_ATOMIC_READ
:
5883 if (expr2
->expr_type
!= EXPR_VARIABLE
5884 || expr2
->symtree
== NULL
5886 || (expr2
->ts
.type
!= BT_INTEGER
5887 && expr2
->ts
.type
!= BT_REAL
5888 && expr2
->ts
.type
!= BT_COMPLEX
5889 && expr2
->ts
.type
!= BT_LOGICAL
))
5890 gfc_error ("!$OMP ATOMIC READ statement must read from a scalar "
5891 "variable of intrinsic type at %L", &expr2
->where
);
5893 case GFC_OMP_ATOMIC_WRITE
:
5894 if (expr2
->rank
!= 0 || expr_references_sym (code
->expr2
, var
, NULL
))
5895 gfc_error ("expr in !$OMP ATOMIC WRITE assignment var = expr "
5896 "must be scalar and cannot reference var at %L",
5902 if (atomic_code
->ext
.omp_clauses
->capture
)
5905 if (expr2
== code
->expr2
)
5907 expr2_tmp
= is_conversion (code
->expr2
, true);
5908 if (expr2_tmp
== NULL
)
5911 if (expr2_tmp
->expr_type
== EXPR_VARIABLE
)
5913 if (expr2_tmp
->symtree
== NULL
5914 || expr2_tmp
->rank
!= 0
5915 || (expr2_tmp
->ts
.type
!= BT_INTEGER
5916 && expr2_tmp
->ts
.type
!= BT_REAL
5917 && expr2_tmp
->ts
.type
!= BT_COMPLEX
5918 && expr2_tmp
->ts
.type
!= BT_LOGICAL
)
5919 || expr2_tmp
->symtree
->n
.sym
== var
)
5921 gfc_error ("!$OMP ATOMIC CAPTURE capture statement must read from "
5922 "a scalar variable of intrinsic type at %L",
5926 var
= expr2_tmp
->symtree
->n
.sym
;
5928 if (code
->expr1
->expr_type
!= EXPR_VARIABLE
5929 || code
->expr1
->symtree
== NULL
5930 || code
->expr1
->rank
!= 0
5931 || (code
->expr1
->ts
.type
!= BT_INTEGER
5932 && code
->expr1
->ts
.type
!= BT_REAL
5933 && code
->expr1
->ts
.type
!= BT_COMPLEX
5934 && code
->expr1
->ts
.type
!= BT_LOGICAL
))
5936 gfc_error ("!$OMP ATOMIC CAPTURE update statement must set "
5937 "a scalar variable of intrinsic type at %L",
5938 &code
->expr1
->where
);
5941 if (code
->expr1
->symtree
->n
.sym
!= var
)
5943 gfc_error ("!$OMP ATOMIC CAPTURE capture statement reads from "
5944 "different variable than update statement writes "
5945 "into at %L", &code
->expr1
->where
);
5948 expr2
= is_conversion (code
->expr2
, false);
5950 expr2
= code
->expr2
;
5954 if (gfc_expr_attr (code
->expr1
).allocatable
)
5956 gfc_error ("!$OMP ATOMIC with ALLOCATABLE variable at %L",
5961 if (atomic_code
->ext
.omp_clauses
->capture
5962 && code
->next
== NULL
5963 && code
->expr2
->rank
== 0
5964 && !expr_references_sym (code
->expr2
, var
, NULL
))
5965 atomic_code
->ext
.omp_clauses
->atomic_op
5966 = (gfc_omp_atomic_op
) (atomic_code
->ext
.omp_clauses
->atomic_op
5967 | GFC_OMP_ATOMIC_SWAP
);
5968 else if (expr2
->expr_type
== EXPR_OP
)
5970 gfc_expr
*v
= NULL
, *e
, *c
;
5971 gfc_intrinsic_op op
= expr2
->value
.op
.op
;
5972 gfc_intrinsic_op alt_op
= INTRINSIC_NONE
;
5976 case INTRINSIC_PLUS
:
5977 alt_op
= INTRINSIC_MINUS
;
5979 case INTRINSIC_TIMES
:
5980 alt_op
= INTRINSIC_DIVIDE
;
5982 case INTRINSIC_MINUS
:
5983 alt_op
= INTRINSIC_PLUS
;
5985 case INTRINSIC_DIVIDE
:
5986 alt_op
= INTRINSIC_TIMES
;
5992 alt_op
= INTRINSIC_NEQV
;
5994 case INTRINSIC_NEQV
:
5995 alt_op
= INTRINSIC_EQV
;
5998 gfc_error ("!$OMP ATOMIC assignment operator must be binary "
5999 "+, *, -, /, .AND., .OR., .EQV. or .NEQV. at %L",
6004 /* Check for var = var op expr resp. var = expr op var where
6005 expr doesn't reference var and var op expr is mathematically
6006 equivalent to var op (expr) resp. expr op var equivalent to
6007 (expr) op var. We rely here on the fact that the matcher
6008 for x op1 y op2 z where op1 and op2 have equal precedence
6009 returns (x op1 y) op2 z. */
6010 e
= expr2
->value
.op
.op2
;
6011 if (e
->expr_type
== EXPR_VARIABLE
6012 && e
->symtree
!= NULL
6013 && e
->symtree
->n
.sym
== var
)
6015 else if ((c
= is_conversion (e
, true)) != NULL
6016 && c
->expr_type
== EXPR_VARIABLE
6017 && c
->symtree
!= NULL
6018 && c
->symtree
->n
.sym
== var
)
6022 gfc_expr
**p
= NULL
, **q
;
6023 for (q
= &expr2
->value
.op
.op1
; (e
= *q
) != NULL
; )
6024 if (e
->expr_type
== EXPR_VARIABLE
6025 && e
->symtree
!= NULL
6026 && e
->symtree
->n
.sym
== var
)
6031 else if ((c
= is_conversion (e
, true)) != NULL
)
6032 q
= &e
->value
.function
.actual
->expr
;
6033 else if (e
->expr_type
!= EXPR_OP
6034 || (e
->value
.op
.op
!= op
6035 && e
->value
.op
.op
!= alt_op
)
6041 q
= &e
->value
.op
.op1
;
6046 gfc_error ("!$OMP ATOMIC assignment must be var = var op expr "
6047 "or var = expr op var at %L", &expr2
->where
);
6054 switch (e
->value
.op
.op
)
6056 case INTRINSIC_MINUS
:
6057 case INTRINSIC_DIVIDE
:
6059 case INTRINSIC_NEQV
:
6060 gfc_error ("!$OMP ATOMIC var = var op expr not "
6061 "mathematically equivalent to var = var op "
6062 "(expr) at %L", &expr2
->where
);
6068 /* Canonicalize into var = var op (expr). */
6069 *p
= e
->value
.op
.op2
;
6070 e
->value
.op
.op2
= expr2
;
6072 if (code
->expr2
== expr2
)
6073 code
->expr2
= expr2
= e
;
6075 code
->expr2
->value
.function
.actual
->expr
= expr2
= e
;
6077 if (!gfc_compare_types (&expr2
->value
.op
.op1
->ts
, &expr2
->ts
))
6079 for (p
= &expr2
->value
.op
.op1
; *p
!= v
;
6080 p
= &(*p
)->value
.function
.actual
->expr
)
6083 gfc_free_expr (expr2
->value
.op
.op1
);
6084 expr2
->value
.op
.op1
= v
;
6085 gfc_convert_type (v
, &expr2
->ts
, 2);
6090 if (e
->rank
!= 0 || expr_references_sym (code
->expr2
, var
, v
))
6092 gfc_error ("expr in !$OMP ATOMIC assignment var = var op expr "
6093 "must be scalar and cannot reference var at %L",
6098 else if (expr2
->expr_type
== EXPR_FUNCTION
6099 && expr2
->value
.function
.isym
!= NULL
6100 && expr2
->value
.function
.esym
== NULL
6101 && expr2
->value
.function
.actual
!= NULL
6102 && expr2
->value
.function
.actual
->next
!= NULL
)
6104 gfc_actual_arglist
*arg
, *var_arg
;
6106 switch (expr2
->value
.function
.isym
->id
)
6114 if (expr2
->value
.function
.actual
->next
->next
!= NULL
)
6116 gfc_error ("!$OMP ATOMIC assignment intrinsic IAND, IOR "
6117 "or IEOR must have two arguments at %L",
6123 gfc_error ("!$OMP ATOMIC assignment intrinsic must be "
6124 "MIN, MAX, IAND, IOR or IEOR at %L",
6130 for (arg
= expr2
->value
.function
.actual
; arg
; arg
= arg
->next
)
6132 if ((arg
== expr2
->value
.function
.actual
6133 || (var_arg
== NULL
&& arg
->next
== NULL
))
6134 && arg
->expr
->expr_type
== EXPR_VARIABLE
6135 && arg
->expr
->symtree
!= NULL
6136 && arg
->expr
->symtree
->n
.sym
== var
)
6138 else if (expr_references_sym (arg
->expr
, var
, NULL
))
6140 gfc_error ("!$OMP ATOMIC intrinsic arguments except one must "
6141 "not reference %qs at %L",
6142 var
->name
, &arg
->expr
->where
);
6145 if (arg
->expr
->rank
!= 0)
6147 gfc_error ("!$OMP ATOMIC intrinsic arguments must be scalar "
6148 "at %L", &arg
->expr
->where
);
6153 if (var_arg
== NULL
)
6155 gfc_error ("First or last !$OMP ATOMIC intrinsic argument must "
6156 "be %qs at %L", var
->name
, &expr2
->where
);
6160 if (var_arg
!= expr2
->value
.function
.actual
)
6162 /* Canonicalize, so that var comes first. */
6163 gcc_assert (var_arg
->next
== NULL
);
6164 for (arg
= expr2
->value
.function
.actual
;
6165 arg
->next
!= var_arg
; arg
= arg
->next
)
6167 var_arg
->next
= expr2
->value
.function
.actual
;
6168 expr2
->value
.function
.actual
= var_arg
;
6173 gfc_error ("!$OMP ATOMIC assignment must have an operator or "
6174 "intrinsic on right hand side at %L", &expr2
->where
);
6176 if (atomic_code
->ext
.omp_clauses
->capture
&& code
->next
)
6179 if (code
->expr1
->expr_type
!= EXPR_VARIABLE
6180 || code
->expr1
->symtree
== NULL
6181 || code
->expr1
->rank
!= 0
6182 || (code
->expr1
->ts
.type
!= BT_INTEGER
6183 && code
->expr1
->ts
.type
!= BT_REAL
6184 && code
->expr1
->ts
.type
!= BT_COMPLEX
6185 && code
->expr1
->ts
.type
!= BT_LOGICAL
))
6187 gfc_error ("!$OMP ATOMIC CAPTURE capture statement must set "
6188 "a scalar variable of intrinsic type at %L",
6189 &code
->expr1
->where
);
6193 expr2
= is_conversion (code
->expr2
, false);
6196 expr2
= is_conversion (code
->expr2
, true);
6198 expr2
= code
->expr2
;
6201 if (expr2
->expr_type
!= EXPR_VARIABLE
6202 || expr2
->symtree
== NULL
6204 || (expr2
->ts
.type
!= BT_INTEGER
6205 && expr2
->ts
.type
!= BT_REAL
6206 && expr2
->ts
.type
!= BT_COMPLEX
6207 && expr2
->ts
.type
!= BT_LOGICAL
))
6209 gfc_error ("!$OMP ATOMIC CAPTURE capture statement must read "
6210 "from a scalar variable of intrinsic type at %L",
6214 if (expr2
->symtree
->n
.sym
!= var
)
6216 gfc_error ("!$OMP ATOMIC CAPTURE capture statement reads from "
6217 "different variable than update statement writes "
6218 "into at %L", &expr2
->where
);
6225 static struct fortran_omp_context
6228 hash_set
<gfc_symbol
*> *sharing_clauses
;
6229 hash_set
<gfc_symbol
*> *private_iterators
;
6230 struct fortran_omp_context
*previous
;
6233 static gfc_code
*omp_current_do_code
;
6234 static int omp_current_do_collapse
;
6237 gfc_resolve_omp_do_blocks (gfc_code
*code
, gfc_namespace
*ns
)
6239 if (code
->block
->next
&& code
->block
->next
->op
== EXEC_DO
)
6244 omp_current_do_code
= code
->block
->next
;
6245 if (code
->ext
.omp_clauses
->orderedc
)
6246 omp_current_do_collapse
= code
->ext
.omp_clauses
->orderedc
;
6248 omp_current_do_collapse
= code
->ext
.omp_clauses
->collapse
;
6249 for (i
= 1, c
= omp_current_do_code
; i
< omp_current_do_collapse
; i
++)
6252 if (c
->op
!= EXEC_DO
|| c
->next
== NULL
)
6255 if (c
->op
!= EXEC_DO
)
6258 if (i
< omp_current_do_collapse
|| omp_current_do_collapse
<= 0)
6259 omp_current_do_collapse
= 1;
6260 if (code
->ext
.omp_clauses
->lists
[OMP_LIST_REDUCTION_INSCAN
])
6263 = &code
->ext
.omp_clauses
->lists
[OMP_LIST_REDUCTION_INSCAN
]->where
;
6264 if (code
->ext
.omp_clauses
->ordered
)
6265 gfc_error ("ORDERED clause specified together with %<inscan%> "
6266 "REDUCTION clause at %L", loc
);
6267 if (code
->ext
.omp_clauses
->sched_kind
!= OMP_SCHED_NONE
)
6268 gfc_error ("SCHEDULE clause specified together with %<inscan%> "
6269 "REDUCTION clause at %L", loc
);
6272 || !c
->block
->next
->next
6273 || c
->block
->next
->next
->op
!= EXEC_OMP_SCAN
6274 || !c
->block
->next
->next
->next
6275 || c
->block
->next
->next
->next
->next
)
6276 gfc_error ("With INSCAN at %L, expected loop body with !$OMP SCAN "
6277 "between two structured-block-sequences", loc
);
6279 /* Mark as checked; flag will be unset later. */
6280 c
->block
->next
->next
->ext
.omp_clauses
->if_present
= true;
6283 gfc_resolve_blocks (code
->block
, ns
);
6284 omp_current_do_collapse
= 0;
6285 omp_current_do_code
= NULL
;
6290 gfc_resolve_omp_parallel_blocks (gfc_code
*code
, gfc_namespace
*ns
)
6292 struct fortran_omp_context ctx
;
6293 gfc_omp_clauses
*omp_clauses
= code
->ext
.omp_clauses
;
6294 gfc_omp_namelist
*n
;
6298 ctx
.sharing_clauses
= new hash_set
<gfc_symbol
*>;
6299 ctx
.private_iterators
= new hash_set
<gfc_symbol
*>;
6300 ctx
.previous
= omp_current_ctx
;
6301 ctx
.is_openmp
= true;
6302 omp_current_ctx
= &ctx
;
6304 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
6307 case OMP_LIST_SHARED
:
6308 case OMP_LIST_PRIVATE
:
6309 case OMP_LIST_FIRSTPRIVATE
:
6310 case OMP_LIST_LASTPRIVATE
:
6311 case OMP_LIST_REDUCTION
:
6312 case OMP_LIST_REDUCTION_INSCAN
:
6313 case OMP_LIST_REDUCTION_TASK
:
6314 case OMP_LIST_IN_REDUCTION
:
6315 case OMP_LIST_TASK_REDUCTION
:
6316 case OMP_LIST_LINEAR
:
6317 for (n
= omp_clauses
->lists
[list
]; n
; n
= n
->next
)
6318 ctx
.sharing_clauses
->add (n
->sym
);
6326 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO
:
6327 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD
:
6328 case EXEC_OMP_PARALLEL_DO
:
6329 case EXEC_OMP_PARALLEL_DO_SIMD
:
6330 case EXEC_OMP_TARGET_PARALLEL_DO
:
6331 case EXEC_OMP_TARGET_PARALLEL_DO_SIMD
:
6332 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE
:
6333 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO
:
6334 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
6335 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD
:
6336 case EXEC_OMP_TASKLOOP
:
6337 case EXEC_OMP_TASKLOOP_SIMD
:
6338 case EXEC_OMP_TEAMS_DISTRIBUTE
:
6339 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO
:
6340 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
6341 case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD
:
6342 gfc_resolve_omp_do_blocks (code
, ns
);
6345 gfc_resolve_blocks (code
->block
, ns
);
6348 omp_current_ctx
= ctx
.previous
;
6349 delete ctx
.sharing_clauses
;
6350 delete ctx
.private_iterators
;
6354 /* Save and clear openmp.c private state. */
6357 gfc_omp_save_and_clear_state (struct gfc_omp_saved_state
*state
)
6359 state
->ptrs
[0] = omp_current_ctx
;
6360 state
->ptrs
[1] = omp_current_do_code
;
6361 state
->ints
[0] = omp_current_do_collapse
;
6362 omp_current_ctx
= NULL
;
6363 omp_current_do_code
= NULL
;
6364 omp_current_do_collapse
= 0;
6368 /* Restore openmp.c private state from the saved state. */
6371 gfc_omp_restore_state (struct gfc_omp_saved_state
*state
)
6373 omp_current_ctx
= (struct fortran_omp_context
*) state
->ptrs
[0];
6374 omp_current_do_code
= (gfc_code
*) state
->ptrs
[1];
6375 omp_current_do_collapse
= state
->ints
[0];
6379 /* Note a DO iterator variable. This is special in !$omp parallel
6380 construct, where they are predetermined private. */
6383 gfc_resolve_do_iterator (gfc_code
*code
, gfc_symbol
*sym
, bool add_clause
)
6385 if (omp_current_ctx
== NULL
)
6388 int i
= omp_current_do_collapse
;
6389 gfc_code
*c
= omp_current_do_code
;
6391 if (sym
->attr
.threadprivate
)
6394 /* !$omp do and !$omp parallel do iteration variable is predetermined
6395 private just in the !$omp do resp. !$omp parallel do construct,
6396 with no implications for the outer parallel constructs. */
6406 /* An openacc context may represent a data clause. Abort if so. */
6407 if (!omp_current_ctx
->is_openmp
&& !oacc_is_loop (omp_current_ctx
->code
))
6410 if (omp_current_ctx
->sharing_clauses
->contains (sym
))
6413 if (! omp_current_ctx
->private_iterators
->add (sym
) && add_clause
)
6415 gfc_omp_clauses
*omp_clauses
= omp_current_ctx
->code
->ext
.omp_clauses
;
6416 gfc_omp_namelist
*p
;
6418 p
= gfc_get_omp_namelist ();
6420 p
->next
= omp_clauses
->lists
[OMP_LIST_PRIVATE
];
6421 omp_clauses
->lists
[OMP_LIST_PRIVATE
] = p
;
6426 handle_local_var (gfc_symbol
*sym
)
6428 if (sym
->attr
.flavor
!= FL_VARIABLE
6430 || (sym
->ts
.type
!= BT_INTEGER
&& sym
->ts
.type
!= BT_REAL
))
6432 gfc_resolve_do_iterator (sym
->ns
->code
, sym
, false);
6436 gfc_resolve_omp_local_vars (gfc_namespace
*ns
)
6438 if (omp_current_ctx
)
6439 gfc_traverse_ns (ns
, handle_local_var
);
6443 resolve_omp_do (gfc_code
*code
)
6445 gfc_code
*do_code
, *c
;
6446 int list
, i
, collapse
;
6447 gfc_omp_namelist
*n
;
6450 bool is_simd
= false;
6454 case EXEC_OMP_DISTRIBUTE
: name
= "!$OMP DISTRIBUTE"; break;
6455 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO
:
6456 name
= "!$OMP DISTRIBUTE PARALLEL DO";
6458 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD
:
6459 name
= "!$OMP DISTRIBUTE PARALLEL DO SIMD";
6462 case EXEC_OMP_DISTRIBUTE_SIMD
:
6463 name
= "!$OMP DISTRIBUTE SIMD";
6466 case EXEC_OMP_DO
: name
= "!$OMP DO"; break;
6467 case EXEC_OMP_DO_SIMD
: name
= "!$OMP DO SIMD"; is_simd
= true; break;
6468 case EXEC_OMP_PARALLEL_DO
: name
= "!$OMP PARALLEL DO"; break;
6469 case EXEC_OMP_PARALLEL_DO_SIMD
:
6470 name
= "!$OMP PARALLEL DO SIMD";
6473 case EXEC_OMP_SIMD
: name
= "!$OMP SIMD"; is_simd
= true; break;
6474 case EXEC_OMP_TARGET_PARALLEL_DO
: name
= "!$OMP TARGET PARALLEL DO"; break;
6475 case EXEC_OMP_TARGET_PARALLEL_DO_SIMD
:
6476 name
= "!$OMP TARGET PARALLEL DO SIMD";
6479 case EXEC_OMP_TARGET_SIMD
:
6480 name
= "!$OMP TARGET SIMD";
6483 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE
:
6484 name
= "!$OMP TARGET TEAMS DISTRIBUTE";
6486 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO
:
6487 name
= "!$OMP TARGET TEAMS DISTRIBUTE PARALLEL DO";
6489 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
6490 name
= "!$OMP TARGET TEAMS DISTRIBUTE PARALLEL DO SIMD";
6493 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD
:
6494 name
= "!$OMP TARGET TEAMS DISTRIBUTE SIMD";
6497 case EXEC_OMP_TASKLOOP
: name
= "!$OMP TASKLOOP"; break;
6498 case EXEC_OMP_TASKLOOP_SIMD
:
6499 name
= "!$OMP TASKLOOP SIMD";
6502 case EXEC_OMP_TEAMS_DISTRIBUTE
: name
= "!$OMP TEAMS DISTRIBUTE"; break;
6503 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO
:
6504 name
= "!$OMP TEAMS DISTRIBUTE PARALLEL DO";
6506 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
6507 name
= "!$OMP TEAMS DISTRIBUTE PARALLEL DO SIMD";
6510 case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD
:
6511 name
= "!$OMP TEAMS DISTRIBUTE SIMD";
6514 default: gcc_unreachable ();
6517 if (code
->ext
.omp_clauses
)
6518 resolve_omp_clauses (code
, code
->ext
.omp_clauses
, NULL
);
6520 do_code
= code
->block
->next
;
6521 if (code
->ext
.omp_clauses
->orderedc
)
6522 collapse
= code
->ext
.omp_clauses
->orderedc
;
6525 collapse
= code
->ext
.omp_clauses
->collapse
;
6529 for (i
= 1; i
<= collapse
; i
++)
6531 if (do_code
->op
== EXEC_DO_WHILE
)
6533 gfc_error ("%s cannot be a DO WHILE or DO without loop control "
6534 "at %L", name
, &do_code
->loc
);
6537 if (do_code
->op
== EXEC_DO_CONCURRENT
)
6539 gfc_error ("%s cannot be a DO CONCURRENT loop at %L", name
,
6543 gcc_assert (do_code
->op
== EXEC_DO
);
6544 if (do_code
->ext
.iterator
->var
->ts
.type
!= BT_INTEGER
)
6545 gfc_error ("%s iteration variable must be of type integer at %L",
6546 name
, &do_code
->loc
);
6547 dovar
= do_code
->ext
.iterator
->var
->symtree
->n
.sym
;
6548 if (dovar
->attr
.threadprivate
)
6549 gfc_error ("%s iteration variable must not be THREADPRIVATE "
6550 "at %L", name
, &do_code
->loc
);
6551 if (code
->ext
.omp_clauses
)
6552 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
6553 if (!is_simd
|| code
->ext
.omp_clauses
->collapse
> 1
6554 ? (list
!= OMP_LIST_PRIVATE
&& list
!= OMP_LIST_LASTPRIVATE
)
6555 : (list
!= OMP_LIST_PRIVATE
&& list
!= OMP_LIST_LASTPRIVATE
6556 && list
!= OMP_LIST_LINEAR
))
6557 for (n
= code
->ext
.omp_clauses
->lists
[list
]; n
; n
= n
->next
)
6558 if (dovar
== n
->sym
)
6560 if (!is_simd
|| code
->ext
.omp_clauses
->collapse
> 1)
6561 gfc_error ("%s iteration variable present on clause "
6562 "other than PRIVATE or LASTPRIVATE at %L",
6563 name
, &do_code
->loc
);
6565 gfc_error ("%s iteration variable present on clause "
6566 "other than PRIVATE, LASTPRIVATE or "
6567 "LINEAR at %L", name
, &do_code
->loc
);
6572 gfc_code
*do_code2
= code
->block
->next
;
6575 for (j
= 1; j
< i
; j
++)
6577 gfc_symbol
*ivar
= do_code2
->ext
.iterator
->var
->symtree
->n
.sym
;
6579 || gfc_find_sym_in_expr (ivar
, do_code
->ext
.iterator
->start
)
6580 || gfc_find_sym_in_expr (ivar
, do_code
->ext
.iterator
->end
)
6581 || gfc_find_sym_in_expr (ivar
, do_code
->ext
.iterator
->step
))
6583 gfc_error ("%s collapsed loops don't form rectangular "
6584 "iteration space at %L", name
, &do_code
->loc
);
6587 do_code2
= do_code2
->block
->next
;
6590 for (c
= do_code
->next
; c
; c
= c
->next
)
6591 if (c
->op
!= EXEC_NOP
&& c
->op
!= EXEC_CONTINUE
)
6593 gfc_error ("collapsed %s loops not perfectly nested at %L",
6597 if (i
== collapse
|| c
)
6599 do_code
= do_code
->block
;
6600 if (do_code
->op
!= EXEC_DO
&& do_code
->op
!= EXEC_DO_WHILE
)
6602 gfc_error ("not enough DO loops for collapsed %s at %L",
6606 do_code
= do_code
->next
;
6608 || (do_code
->op
!= EXEC_DO
&& do_code
->op
!= EXEC_DO_WHILE
))
6610 gfc_error ("not enough DO loops for collapsed %s at %L",
6618 static gfc_statement
6619 omp_code_to_statement (gfc_code
*code
)
6623 case EXEC_OMP_PARALLEL
:
6624 return ST_OMP_PARALLEL
;
6625 case EXEC_OMP_PARALLEL_SECTIONS
:
6626 return ST_OMP_PARALLEL_SECTIONS
;
6627 case EXEC_OMP_SECTIONS
:
6628 return ST_OMP_SECTIONS
;
6629 case EXEC_OMP_ORDERED
:
6630 return ST_OMP_ORDERED
;
6631 case EXEC_OMP_CRITICAL
:
6632 return ST_OMP_CRITICAL
;
6633 case EXEC_OMP_MASTER
:
6634 return ST_OMP_MASTER
;
6635 case EXEC_OMP_SINGLE
:
6636 return ST_OMP_SINGLE
;
6639 case EXEC_OMP_WORKSHARE
:
6640 return ST_OMP_WORKSHARE
;
6641 case EXEC_OMP_PARALLEL_WORKSHARE
:
6642 return ST_OMP_PARALLEL_WORKSHARE
;
6645 case EXEC_OMP_ATOMIC
:
6646 return ST_OMP_ATOMIC
;
6647 case EXEC_OMP_BARRIER
:
6648 return ST_OMP_BARRIER
;
6649 case EXEC_OMP_CANCEL
:
6650 return ST_OMP_CANCEL
;
6651 case EXEC_OMP_CANCELLATION_POINT
:
6652 return ST_OMP_CANCELLATION_POINT
;
6653 case EXEC_OMP_FLUSH
:
6654 return ST_OMP_FLUSH
;
6655 case EXEC_OMP_DISTRIBUTE
:
6656 return ST_OMP_DISTRIBUTE
;
6657 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO
:
6658 return ST_OMP_DISTRIBUTE_PARALLEL_DO
;
6659 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD
:
6660 return ST_OMP_DISTRIBUTE_PARALLEL_DO_SIMD
;
6661 case EXEC_OMP_DISTRIBUTE_SIMD
:
6662 return ST_OMP_DISTRIBUTE_SIMD
;
6663 case EXEC_OMP_DO_SIMD
:
6664 return ST_OMP_DO_SIMD
;
6669 case EXEC_OMP_TARGET
:
6670 return ST_OMP_TARGET
;
6671 case EXEC_OMP_TARGET_DATA
:
6672 return ST_OMP_TARGET_DATA
;
6673 case EXEC_OMP_TARGET_ENTER_DATA
:
6674 return ST_OMP_TARGET_ENTER_DATA
;
6675 case EXEC_OMP_TARGET_EXIT_DATA
:
6676 return ST_OMP_TARGET_EXIT_DATA
;
6677 case EXEC_OMP_TARGET_PARALLEL
:
6678 return ST_OMP_TARGET_PARALLEL
;
6679 case EXEC_OMP_TARGET_PARALLEL_DO
:
6680 return ST_OMP_TARGET_PARALLEL_DO
;
6681 case EXEC_OMP_TARGET_PARALLEL_DO_SIMD
:
6682 return ST_OMP_TARGET_PARALLEL_DO_SIMD
;
6683 case EXEC_OMP_TARGET_SIMD
:
6684 return ST_OMP_TARGET_SIMD
;
6685 case EXEC_OMP_TARGET_TEAMS
:
6686 return ST_OMP_TARGET_TEAMS
;
6687 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE
:
6688 return ST_OMP_TARGET_TEAMS_DISTRIBUTE
;
6689 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO
:
6690 return ST_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO
;
6691 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
6692 return ST_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
;
6693 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD
:
6694 return ST_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD
;
6695 case EXEC_OMP_TARGET_UPDATE
:
6696 return ST_OMP_TARGET_UPDATE
;
6697 case EXEC_OMP_TASKGROUP
:
6698 return ST_OMP_TASKGROUP
;
6699 case EXEC_OMP_TASKLOOP
:
6700 return ST_OMP_TASKLOOP
;
6701 case EXEC_OMP_TASKLOOP_SIMD
:
6702 return ST_OMP_TASKLOOP_SIMD
;
6703 case EXEC_OMP_TASKWAIT
:
6704 return ST_OMP_TASKWAIT
;
6705 case EXEC_OMP_TASKYIELD
:
6706 return ST_OMP_TASKYIELD
;
6707 case EXEC_OMP_TEAMS
:
6708 return ST_OMP_TEAMS
;
6709 case EXEC_OMP_TEAMS_DISTRIBUTE
:
6710 return ST_OMP_TEAMS_DISTRIBUTE
;
6711 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO
:
6712 return ST_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO
;
6713 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
6714 return ST_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
;
6715 case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD
:
6716 return ST_OMP_TEAMS_DISTRIBUTE_SIMD
;
6717 case EXEC_OMP_PARALLEL_DO
:
6718 return ST_OMP_PARALLEL_DO
;
6719 case EXEC_OMP_PARALLEL_DO_SIMD
:
6720 return ST_OMP_PARALLEL_DO_SIMD
;
6727 static gfc_statement
6728 oacc_code_to_statement (gfc_code
*code
)
6732 case EXEC_OACC_PARALLEL
:
6733 return ST_OACC_PARALLEL
;
6734 case EXEC_OACC_KERNELS
:
6735 return ST_OACC_KERNELS
;
6736 case EXEC_OACC_SERIAL
:
6737 return ST_OACC_SERIAL
;
6738 case EXEC_OACC_DATA
:
6739 return ST_OACC_DATA
;
6740 case EXEC_OACC_HOST_DATA
:
6741 return ST_OACC_HOST_DATA
;
6742 case EXEC_OACC_PARALLEL_LOOP
:
6743 return ST_OACC_PARALLEL_LOOP
;
6744 case EXEC_OACC_KERNELS_LOOP
:
6745 return ST_OACC_KERNELS_LOOP
;
6746 case EXEC_OACC_SERIAL_LOOP
:
6747 return ST_OACC_SERIAL_LOOP
;
6748 case EXEC_OACC_LOOP
:
6749 return ST_OACC_LOOP
;
6750 case EXEC_OACC_ATOMIC
:
6751 return ST_OACC_ATOMIC
;
6752 case EXEC_OACC_ROUTINE
:
6753 return ST_OACC_ROUTINE
;
6754 case EXEC_OACC_UPDATE
:
6755 return ST_OACC_UPDATE
;
6756 case EXEC_OACC_WAIT
:
6757 return ST_OACC_WAIT
;
6758 case EXEC_OACC_CACHE
:
6759 return ST_OACC_CACHE
;
6760 case EXEC_OACC_ENTER_DATA
:
6761 return ST_OACC_ENTER_DATA
;
6762 case EXEC_OACC_EXIT_DATA
:
6763 return ST_OACC_EXIT_DATA
;
6764 case EXEC_OACC_DECLARE
:
6765 return ST_OACC_DECLARE
;
6772 resolve_oacc_directive_inside_omp_region (gfc_code
*code
)
6774 if (omp_current_ctx
!= NULL
&& omp_current_ctx
->is_openmp
)
6776 gfc_statement st
= omp_code_to_statement (omp_current_ctx
->code
);
6777 gfc_statement oacc_st
= oacc_code_to_statement (code
);
6778 gfc_error ("The %s directive cannot be specified within "
6779 "a %s region at %L", gfc_ascii_statement (oacc_st
),
6780 gfc_ascii_statement (st
), &code
->loc
);
6785 resolve_omp_directive_inside_oacc_region (gfc_code
*code
)
6787 if (omp_current_ctx
!= NULL
&& !omp_current_ctx
->is_openmp
)
6789 gfc_statement st
= oacc_code_to_statement (omp_current_ctx
->code
);
6790 gfc_statement omp_st
= omp_code_to_statement (code
);
6791 gfc_error ("The %s directive cannot be specified within "
6792 "a %s region at %L", gfc_ascii_statement (omp_st
),
6793 gfc_ascii_statement (st
), &code
->loc
);
6799 resolve_oacc_nested_loops (gfc_code
*code
, gfc_code
* do_code
, int collapse
,
6806 for (i
= 1; i
<= collapse
; i
++)
6808 if (do_code
->op
== EXEC_DO_WHILE
)
6810 gfc_error ("!$ACC LOOP cannot be a DO WHILE or DO without loop control "
6811 "at %L", &do_code
->loc
);
6814 if (do_code
->op
== EXEC_DO_CONCURRENT
)
6816 gfc_error ("!$ACC LOOP cannot be a DO CONCURRENT loop at %L",
6820 gcc_assert (do_code
->op
== EXEC_DO
);
6821 if (do_code
->ext
.iterator
->var
->ts
.type
!= BT_INTEGER
)
6822 gfc_error ("!$ACC LOOP iteration variable must be of type integer at %L",
6824 dovar
= do_code
->ext
.iterator
->var
->symtree
->n
.sym
;
6827 gfc_code
*do_code2
= code
->block
->next
;
6830 for (j
= 1; j
< i
; j
++)
6832 gfc_symbol
*ivar
= do_code2
->ext
.iterator
->var
->symtree
->n
.sym
;
6834 || gfc_find_sym_in_expr (ivar
, do_code
->ext
.iterator
->start
)
6835 || gfc_find_sym_in_expr (ivar
, do_code
->ext
.iterator
->end
)
6836 || gfc_find_sym_in_expr (ivar
, do_code
->ext
.iterator
->step
))
6838 gfc_error ("!$ACC LOOP %s loops don't form rectangular "
6839 "iteration space at %L", clause
, &do_code
->loc
);
6842 do_code2
= do_code2
->block
->next
;
6847 for (c
= do_code
->next
; c
; c
= c
->next
)
6848 if (c
->op
!= EXEC_NOP
&& c
->op
!= EXEC_CONTINUE
)
6850 gfc_error ("%s !$ACC LOOP loops not perfectly nested at %L",
6856 do_code
= do_code
->block
;
6857 if (do_code
->op
!= EXEC_DO
&& do_code
->op
!= EXEC_DO_WHILE
6858 && do_code
->op
!= EXEC_DO_CONCURRENT
)
6860 gfc_error ("not enough DO loops for %s !$ACC LOOP at %L",
6861 clause
, &code
->loc
);
6864 do_code
= do_code
->next
;
6866 || (do_code
->op
!= EXEC_DO
&& do_code
->op
!= EXEC_DO_WHILE
6867 && do_code
->op
!= EXEC_DO_CONCURRENT
))
6869 gfc_error ("not enough DO loops for %s !$ACC LOOP at %L",
6870 clause
, &code
->loc
);
6878 resolve_oacc_loop_blocks (gfc_code
*code
)
6880 if (!oacc_is_loop (code
))
6883 if (code
->ext
.omp_clauses
->tile_list
&& code
->ext
.omp_clauses
->gang
6884 && code
->ext
.omp_clauses
->worker
&& code
->ext
.omp_clauses
->vector
)
6885 gfc_error ("Tiled loop cannot be parallelized across gangs, workers and "
6886 "vectors at the same time at %L", &code
->loc
);
6888 if (code
->ext
.omp_clauses
->tile_list
)
6891 for (el
= code
->ext
.omp_clauses
->tile_list
; el
; el
= el
->next
)
6893 if (el
->expr
== NULL
)
6895 /* NULL expressions are used to represent '*' arguments.
6896 Convert those to a 0 expressions. */
6897 el
->expr
= gfc_get_constant_expr (BT_INTEGER
,
6898 gfc_default_integer_kind
,
6900 mpz_set_si (el
->expr
->value
.integer
, 0);
6904 resolve_positive_int_expr (el
->expr
, "TILE");
6905 if (el
->expr
->expr_type
!= EXPR_CONSTANT
)
6906 gfc_error ("TILE requires constant expression at %L",
6915 gfc_resolve_oacc_blocks (gfc_code
*code
, gfc_namespace
*ns
)
6917 fortran_omp_context ctx
;
6918 gfc_omp_clauses
*omp_clauses
= code
->ext
.omp_clauses
;
6919 gfc_omp_namelist
*n
;
6922 resolve_oacc_loop_blocks (code
);
6925 ctx
.sharing_clauses
= new hash_set
<gfc_symbol
*>;
6926 ctx
.private_iterators
= new hash_set
<gfc_symbol
*>;
6927 ctx
.previous
= omp_current_ctx
;
6928 ctx
.is_openmp
= false;
6929 omp_current_ctx
= &ctx
;
6931 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
6934 case OMP_LIST_PRIVATE
:
6935 for (n
= omp_clauses
->lists
[list
]; n
; n
= n
->next
)
6936 ctx
.sharing_clauses
->add (n
->sym
);
6942 gfc_resolve_blocks (code
->block
, ns
);
6944 omp_current_ctx
= ctx
.previous
;
6945 delete ctx
.sharing_clauses
;
6946 delete ctx
.private_iterators
;
6951 resolve_oacc_loop (gfc_code
*code
)
6956 if (code
->ext
.omp_clauses
)
6957 resolve_omp_clauses (code
, code
->ext
.omp_clauses
, NULL
, true);
6959 do_code
= code
->block
->next
;
6960 collapse
= code
->ext
.omp_clauses
->collapse
;
6962 /* Both collapsed and tiled loops are lowered the same way, but are not
6963 compatible. In gfc_trans_omp_do, the tile is prioritized. */
6964 if (code
->ext
.omp_clauses
->tile_list
)
6968 for (el
= code
->ext
.omp_clauses
->tile_list
; el
; el
= el
->next
)
6970 resolve_oacc_nested_loops (code
, code
->block
->next
, num
, "tiled");
6976 resolve_oacc_nested_loops (code
, do_code
, collapse
, "collapsed");
6980 gfc_resolve_oacc_declare (gfc_namespace
*ns
)
6983 gfc_omp_namelist
*n
;
6984 gfc_oacc_declare
*oc
;
6986 if (ns
->oacc_declare
== NULL
)
6989 for (oc
= ns
->oacc_declare
; oc
; oc
= oc
->next
)
6991 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
6992 for (n
= oc
->clauses
->lists
[list
]; n
; n
= n
->next
)
6995 if (n
->sym
->attr
.flavor
!= FL_VARIABLE
6996 && (n
->sym
->attr
.flavor
!= FL_PROCEDURE
6997 || n
->sym
->result
!= n
->sym
))
6999 gfc_error ("Object %qs is not a variable at %L",
7000 n
->sym
->name
, &oc
->loc
);
7004 if (n
->expr
&& n
->expr
->ref
->type
== REF_ARRAY
)
7006 gfc_error ("Array sections: %qs not allowed in"
7007 " !$ACC DECLARE at %L", n
->sym
->name
, &oc
->loc
);
7012 for (n
= oc
->clauses
->lists
[OMP_LIST_DEVICE_RESIDENT
]; n
; n
= n
->next
)
7013 check_array_not_assumed (n
->sym
, oc
->loc
, "DEVICE_RESIDENT");
7016 for (oc
= ns
->oacc_declare
; oc
; oc
= oc
->next
)
7018 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
7019 for (n
= oc
->clauses
->lists
[list
]; n
; n
= n
->next
)
7023 gfc_error ("Symbol %qs present on multiple clauses at %L",
7024 n
->sym
->name
, &oc
->loc
);
7032 for (oc
= ns
->oacc_declare
; oc
; oc
= oc
->next
)
7034 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
7035 for (n
= oc
->clauses
->lists
[list
]; n
; n
= n
->next
)
7042 gfc_resolve_oacc_routines (gfc_namespace
*ns
)
7044 for (gfc_oacc_routine_name
*orn
= ns
->oacc_routine_names
;
7048 gfc_symbol
*sym
= orn
->sym
;
7049 if (!sym
->attr
.external
7050 && !sym
->attr
.function
7051 && !sym
->attr
.subroutine
)
7053 gfc_error ("NAME %qs does not refer to a subroutine or function"
7054 " in !$ACC ROUTINE ( NAME ) at %L", sym
->name
, &orn
->loc
);
7057 if (!gfc_add_omp_declare_target (&sym
->attr
, sym
->name
, &orn
->loc
))
7059 gfc_error ("NAME %qs invalid"
7060 " in !$ACC ROUTINE ( NAME ) at %L", sym
->name
, &orn
->loc
);
7068 gfc_resolve_oacc_directive (gfc_code
*code
, gfc_namespace
*ns ATTRIBUTE_UNUSED
)
7070 resolve_oacc_directive_inside_omp_region (code
);
7074 case EXEC_OACC_PARALLEL
:
7075 case EXEC_OACC_KERNELS
:
7076 case EXEC_OACC_SERIAL
:
7077 case EXEC_OACC_DATA
:
7078 case EXEC_OACC_HOST_DATA
:
7079 case EXEC_OACC_UPDATE
:
7080 case EXEC_OACC_ENTER_DATA
:
7081 case EXEC_OACC_EXIT_DATA
:
7082 case EXEC_OACC_WAIT
:
7083 case EXEC_OACC_CACHE
:
7084 resolve_omp_clauses (code
, code
->ext
.omp_clauses
, NULL
, true);
7086 case EXEC_OACC_PARALLEL_LOOP
:
7087 case EXEC_OACC_KERNELS_LOOP
:
7088 case EXEC_OACC_SERIAL_LOOP
:
7089 case EXEC_OACC_LOOP
:
7090 resolve_oacc_loop (code
);
7092 case EXEC_OACC_ATOMIC
:
7093 resolve_omp_atomic (code
);
7101 /* Resolve OpenMP directive clauses and check various requirements
7102 of each directive. */
7105 gfc_resolve_omp_directive (gfc_code
*code
, gfc_namespace
*ns
)
7107 resolve_omp_directive_inside_oacc_region (code
);
7109 if (code
->op
!= EXEC_OMP_ATOMIC
)
7110 gfc_maybe_initialize_eh ();
7114 case EXEC_OMP_DISTRIBUTE
:
7115 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO
:
7116 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD
:
7117 case EXEC_OMP_DISTRIBUTE_SIMD
:
7119 case EXEC_OMP_DO_SIMD
:
7120 case EXEC_OMP_PARALLEL_DO
:
7121 case EXEC_OMP_PARALLEL_DO_SIMD
:
7123 case EXEC_OMP_TARGET_PARALLEL_DO
:
7124 case EXEC_OMP_TARGET_PARALLEL_DO_SIMD
:
7125 case EXEC_OMP_TARGET_SIMD
:
7126 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE
:
7127 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO
:
7128 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
7129 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD
:
7130 case EXEC_OMP_TASKLOOP
:
7131 case EXEC_OMP_TASKLOOP_SIMD
:
7132 case EXEC_OMP_TEAMS_DISTRIBUTE
:
7133 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO
:
7134 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
7135 case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD
:
7136 resolve_omp_do (code
);
7138 case EXEC_OMP_CANCEL
:
7139 case EXEC_OMP_PARALLEL_WORKSHARE
:
7140 case EXEC_OMP_PARALLEL
:
7141 case EXEC_OMP_PARALLEL_SECTIONS
:
7142 case EXEC_OMP_SECTIONS
:
7143 case EXEC_OMP_SINGLE
:
7144 case EXEC_OMP_TARGET
:
7145 case EXEC_OMP_TARGET_DATA
:
7146 case EXEC_OMP_TARGET_ENTER_DATA
:
7147 case EXEC_OMP_TARGET_EXIT_DATA
:
7148 case EXEC_OMP_TARGET_PARALLEL
:
7149 case EXEC_OMP_TARGET_TEAMS
:
7151 case EXEC_OMP_TEAMS
:
7152 case EXEC_OMP_WORKSHARE
:
7153 if (code
->ext
.omp_clauses
)
7154 resolve_omp_clauses (code
, code
->ext
.omp_clauses
, NULL
);
7156 case EXEC_OMP_TARGET_UPDATE
:
7157 if (code
->ext
.omp_clauses
)
7158 resolve_omp_clauses (code
, code
->ext
.omp_clauses
, NULL
);
7159 if (code
->ext
.omp_clauses
== NULL
7160 || (code
->ext
.omp_clauses
->lists
[OMP_LIST_TO
] == NULL
7161 && code
->ext
.omp_clauses
->lists
[OMP_LIST_FROM
] == NULL
))
7162 gfc_error ("OMP TARGET UPDATE at %L requires at least one TO or "
7163 "FROM clause", &code
->loc
);
7165 case EXEC_OMP_ATOMIC
:
7166 resolve_omp_clauses (code
, code
->block
->ext
.omp_clauses
, NULL
);
7167 resolve_omp_atomic (code
);
7169 case EXEC_OMP_CRITICAL
:
7170 resolve_omp_clauses (code
, code
->ext
.omp_clauses
, NULL
);
7171 if (!code
->ext
.omp_clauses
->critical_name
7172 && code
->ext
.omp_clauses
->hint
7173 && code
->ext
.omp_clauses
->hint
->ts
.type
== BT_INTEGER
7174 && code
->ext
.omp_clauses
->hint
->expr_type
== EXPR_CONSTANT
7175 && mpz_sgn (code
->ext
.omp_clauses
->hint
->value
.integer
) != 0)
7176 gfc_error ("OMP CRITICAL at %L with HINT clause requires a NAME, "
7177 "except when omp_sync_hint_none is used", &code
->loc
);
7180 /* Flag is only used to checking, hence, it is unset afterwards. */
7181 if (!code
->ext
.omp_clauses
->if_present
)
7182 gfc_error ("Unexpected !$OMP SCAN at %L outside loop construct with "
7183 "%<inscan%> REDUCTION clause", &code
->loc
);
7184 code
->ext
.omp_clauses
->if_present
= false;
7185 resolve_omp_clauses (code
, code
->ext
.omp_clauses
, ns
);
7192 /* Resolve !$omp declare simd constructs in NS. */
7195 gfc_resolve_omp_declare_simd (gfc_namespace
*ns
)
7197 gfc_omp_declare_simd
*ods
;
7199 for (ods
= ns
->omp_declare_simd
; ods
; ods
= ods
->next
)
7201 if (ods
->proc_name
!= NULL
7202 && ods
->proc_name
!= ns
->proc_name
)
7203 gfc_error ("!$OMP DECLARE SIMD should refer to containing procedure "
7204 "%qs at %L", ns
->proc_name
->name
, &ods
->where
);
7206 resolve_omp_clauses (NULL
, ods
->clauses
, ns
);
7210 struct omp_udr_callback_data
7212 gfc_omp_udr
*omp_udr
;
7213 bool is_initializer
;
7217 omp_udr_callback (gfc_expr
**e
, int *walk_subtrees ATTRIBUTE_UNUSED
,
7220 struct omp_udr_callback_data
*cd
= (struct omp_udr_callback_data
*) data
;
7221 if ((*e
)->expr_type
== EXPR_VARIABLE
)
7223 if (cd
->is_initializer
)
7225 if ((*e
)->symtree
->n
.sym
!= cd
->omp_udr
->omp_priv
7226 && (*e
)->symtree
->n
.sym
!= cd
->omp_udr
->omp_orig
)
7227 gfc_error ("Variable other than OMP_PRIV or OMP_ORIG used in "
7228 "INITIALIZER clause of !$OMP DECLARE REDUCTION at %L",
7233 if ((*e
)->symtree
->n
.sym
!= cd
->omp_udr
->omp_out
7234 && (*e
)->symtree
->n
.sym
!= cd
->omp_udr
->omp_in
)
7235 gfc_error ("Variable other than OMP_OUT or OMP_IN used in "
7236 "combiner of !$OMP DECLARE REDUCTION at %L",
7243 /* Resolve !$omp declare reduction constructs. */
7246 gfc_resolve_omp_udr (gfc_omp_udr
*omp_udr
)
7248 gfc_actual_arglist
*a
;
7249 const char *predef_name
= NULL
;
7251 switch (omp_udr
->rop
)
7253 case OMP_REDUCTION_PLUS
:
7254 case OMP_REDUCTION_TIMES
:
7255 case OMP_REDUCTION_MINUS
:
7256 case OMP_REDUCTION_AND
:
7257 case OMP_REDUCTION_OR
:
7258 case OMP_REDUCTION_EQV
:
7259 case OMP_REDUCTION_NEQV
:
7260 case OMP_REDUCTION_MAX
:
7261 case OMP_REDUCTION_USER
:
7264 gfc_error ("Invalid operator for !$OMP DECLARE REDUCTION %s at %L",
7265 omp_udr
->name
, &omp_udr
->where
);
7269 if (gfc_omp_udr_predef (omp_udr
->rop
, omp_udr
->name
,
7270 &omp_udr
->ts
, &predef_name
))
7273 gfc_error_now ("Redefinition of predefined %s "
7274 "!$OMP DECLARE REDUCTION at %L",
7275 predef_name
, &omp_udr
->where
);
7277 gfc_error_now ("Redefinition of predefined "
7278 "!$OMP DECLARE REDUCTION at %L", &omp_udr
->where
);
7282 if (omp_udr
->ts
.type
== BT_CHARACTER
7283 && omp_udr
->ts
.u
.cl
->length
7284 && omp_udr
->ts
.u
.cl
->length
->expr_type
!= EXPR_CONSTANT
)
7286 gfc_error ("CHARACTER length in !$OMP DECLARE REDUCTION %s not "
7287 "constant at %L", omp_udr
->name
, &omp_udr
->where
);
7291 struct omp_udr_callback_data cd
;
7292 cd
.omp_udr
= omp_udr
;
7293 cd
.is_initializer
= false;
7294 gfc_code_walker (&omp_udr
->combiner_ns
->code
, gfc_dummy_code_callback
,
7295 omp_udr_callback
, &cd
);
7296 if (omp_udr
->combiner_ns
->code
->op
== EXEC_CALL
)
7298 for (a
= omp_udr
->combiner_ns
->code
->ext
.actual
; a
; a
= a
->next
)
7299 if (a
->expr
== NULL
)
7302 gfc_error ("Subroutine call with alternate returns in combiner "
7303 "of !$OMP DECLARE REDUCTION at %L",
7304 &omp_udr
->combiner_ns
->code
->loc
);
7306 if (omp_udr
->initializer_ns
)
7308 cd
.is_initializer
= true;
7309 gfc_code_walker (&omp_udr
->initializer_ns
->code
, gfc_dummy_code_callback
,
7310 omp_udr_callback
, &cd
);
7311 if (omp_udr
->initializer_ns
->code
->op
== EXEC_CALL
)
7313 for (a
= omp_udr
->initializer_ns
->code
->ext
.actual
; a
; a
= a
->next
)
7314 if (a
->expr
== NULL
)
7317 gfc_error ("Subroutine call with alternate returns in "
7318 "INITIALIZER clause of !$OMP DECLARE REDUCTION "
7319 "at %L", &omp_udr
->initializer_ns
->code
->loc
);
7320 for (a
= omp_udr
->initializer_ns
->code
->ext
.actual
; a
; a
= a
->next
)
7322 && a
->expr
->expr_type
== EXPR_VARIABLE
7323 && a
->expr
->symtree
->n
.sym
== omp_udr
->omp_priv
7324 && a
->expr
->ref
== NULL
)
7327 gfc_error ("One of actual subroutine arguments in INITIALIZER "
7328 "clause of !$OMP DECLARE REDUCTION must be OMP_PRIV "
7329 "at %L", &omp_udr
->initializer_ns
->code
->loc
);
7332 else if (omp_udr
->ts
.type
== BT_DERIVED
7333 && !gfc_has_default_initializer (omp_udr
->ts
.u
.derived
))
7335 gfc_error ("Missing INITIALIZER clause for !$OMP DECLARE REDUCTION "
7336 "of derived type without default initializer at %L",
7343 gfc_resolve_omp_udrs (gfc_symtree
*st
)
7345 gfc_omp_udr
*omp_udr
;
7349 gfc_resolve_omp_udrs (st
->left
);
7350 gfc_resolve_omp_udrs (st
->right
);
7351 for (omp_udr
= st
->n
.omp_udr
; omp_udr
; omp_udr
= omp_udr
->next
)
7352 gfc_resolve_omp_udr (omp_udr
);