1 /* OpenMP directive matching and resolving.
2 Copyright (C) 2005-2016 Free Software Foundation, Inc.
3 Contributed by Jakub Jelinek
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
23 #include "coretypes.h"
28 #include "diagnostic.h"
29 #include "gomp-constants.h"
31 /* Match an end of OpenMP directive. End of OpenMP directive is optional
32 whitespace, followed by '\n' or comment '!'. */
35 gfc_match_omp_eos (void)
40 old_loc
= gfc_current_locus
;
41 gfc_gobble_whitespace ();
43 c
= gfc_next_ascii_char ();
48 c
= gfc_next_ascii_char ();
56 gfc_current_locus
= old_loc
;
60 /* Free an omp_clauses structure. */
63 gfc_free_omp_clauses (gfc_omp_clauses
*c
)
69 gfc_free_expr (c
->if_expr
);
70 gfc_free_expr (c
->final_expr
);
71 gfc_free_expr (c
->num_threads
);
72 gfc_free_expr (c
->chunk_size
);
73 gfc_free_expr (c
->safelen_expr
);
74 gfc_free_expr (c
->simdlen_expr
);
75 gfc_free_expr (c
->num_teams
);
76 gfc_free_expr (c
->device
);
77 gfc_free_expr (c
->thread_limit
);
78 gfc_free_expr (c
->dist_chunk_size
);
79 gfc_free_expr (c
->async_expr
);
80 gfc_free_expr (c
->gang_num_expr
);
81 gfc_free_expr (c
->gang_static_expr
);
82 gfc_free_expr (c
->worker_expr
);
83 gfc_free_expr (c
->vector_expr
);
84 gfc_free_expr (c
->num_gangs_expr
);
85 gfc_free_expr (c
->num_workers_expr
);
86 gfc_free_expr (c
->vector_length_expr
);
87 for (i
= 0; i
< OMP_LIST_NUM
; i
++)
88 gfc_free_omp_namelist (c
->lists
[i
]);
89 gfc_free_expr_list (c
->wait_list
);
90 gfc_free_expr_list (c
->tile_list
);
94 /* Free oacc_declare structures. */
97 gfc_free_oacc_declare_clauses (struct gfc_oacc_declare
*oc
)
99 struct gfc_oacc_declare
*decl
= oc
;
103 struct gfc_oacc_declare
*next
;
106 gfc_free_omp_clauses (decl
->clauses
);
113 /* Free expression list. */
115 gfc_free_expr_list (gfc_expr_list
*list
)
119 for (; list
; list
= n
)
126 /* Free an !$omp declare simd construct list. */
129 gfc_free_omp_declare_simd (gfc_omp_declare_simd
*ods
)
133 gfc_free_omp_clauses (ods
->clauses
);
139 gfc_free_omp_declare_simd_list (gfc_omp_declare_simd
*list
)
143 gfc_omp_declare_simd
*current
= list
;
145 gfc_free_omp_declare_simd (current
);
149 /* Free an !$omp declare reduction. */
152 gfc_free_omp_udr (gfc_omp_udr
*omp_udr
)
156 gfc_free_omp_udr (omp_udr
->next
);
157 gfc_free_namespace (omp_udr
->combiner_ns
);
158 if (omp_udr
->initializer_ns
)
159 gfc_free_namespace (omp_udr
->initializer_ns
);
166 gfc_find_omp_udr (gfc_namespace
*ns
, const char *name
, gfc_typespec
*ts
)
174 gfc_omp_udr
*omp_udr
;
176 st
= gfc_find_symtree (ns
->omp_udr_root
, name
);
179 for (omp_udr
= st
->n
.omp_udr
; omp_udr
; omp_udr
= omp_udr
->next
)
182 else if (gfc_compare_types (&omp_udr
->ts
, ts
))
184 if (ts
->type
== BT_CHARACTER
)
186 if (omp_udr
->ts
.u
.cl
->length
== NULL
)
188 if (ts
->u
.cl
->length
== NULL
)
190 if (gfc_compare_expr (omp_udr
->ts
.u
.cl
->length
,
199 /* Don't escape an interface block. */
200 if (ns
&& !ns
->has_import_set
201 && ns
->proc_name
&& ns
->proc_name
->attr
.if_source
== IFSRC_IFBODY
)
212 /* Match a variable/common block list and construct a namelist from it. */
215 gfc_match_omp_variable_list (const char *str
, gfc_omp_namelist
**list
,
216 bool allow_common
, bool *end_colon
= NULL
,
217 gfc_omp_namelist
***headp
= NULL
,
218 bool allow_sections
= false)
220 gfc_omp_namelist
*head
, *tail
, *p
;
221 locus old_loc
, cur_loc
;
222 char n
[GFC_MAX_SYMBOL_LEN
+1];
229 old_loc
= gfc_current_locus
;
237 cur_loc
= gfc_current_locus
;
238 m
= gfc_match_symbol (&sym
, 1);
244 if (allow_sections
&& gfc_peek_ascii_char () == '(')
246 gfc_current_locus
= cur_loc
;
247 m
= gfc_match_variable (&expr
, 0);
258 gfc_set_sym_referenced (sym
);
259 p
= gfc_get_omp_namelist ();
269 tail
->where
= cur_loc
;
280 m
= gfc_match (" / %n /", n
);
281 if (m
== MATCH_ERROR
)
286 st
= gfc_find_symtree (gfc_current_ns
->common_root
, n
);
289 gfc_error ("COMMON block /%s/ not found at %C", n
);
292 for (sym
= st
->n
.common
->head
; sym
; sym
= sym
->common_next
)
294 gfc_set_sym_referenced (sym
);
295 p
= gfc_get_omp_namelist ();
304 tail
->where
= cur_loc
;
308 if (end_colon
&& gfc_match_char (':') == MATCH_YES
)
313 if (gfc_match_char (')') == MATCH_YES
)
315 if (gfc_match_char (',') != MATCH_YES
)
320 list
= &(*list
)->next
;
328 gfc_error ("Syntax error in OpenMP variable list at %C");
331 gfc_free_omp_namelist (head
);
332 gfc_current_locus
= old_loc
;
337 match_oacc_expr_list (const char *str
, gfc_expr_list
**list
,
340 gfc_expr_list
*head
, *tail
, *p
;
347 old_loc
= gfc_current_locus
;
355 m
= gfc_match_expr (&expr
);
356 if (m
== MATCH_YES
|| allow_asterisk
)
358 p
= gfc_get_expr_list ();
368 else if (gfc_match (" *") != MATCH_YES
)
372 if (m
== MATCH_ERROR
)
377 if (gfc_match_char (')') == MATCH_YES
)
379 if (gfc_match_char (',') != MATCH_YES
)
384 list
= &(*list
)->next
;
390 gfc_error ("Syntax error in OpenACC expression list at %C");
393 gfc_free_expr_list (head
);
394 gfc_current_locus
= old_loc
;
399 match_oacc_clause_gang (gfc_omp_clauses
*cp
)
401 match ret
= MATCH_YES
;
403 if (gfc_match (" ( ") != MATCH_YES
)
406 /* The gang clause accepts two optional arguments, num and static.
407 The num argument may either be explicit (num: <val>) or
408 implicit without (<val> without num:). */
410 while (ret
== MATCH_YES
)
412 if (gfc_match (" static :") == MATCH_YES
)
417 cp
->gang_static
= true;
418 if (gfc_match_char ('*') == MATCH_YES
)
419 cp
->gang_static_expr
= NULL
;
420 else if (gfc_match (" %e ", &cp
->gang_static_expr
) != MATCH_YES
)
425 /* This is optional. */
426 if (cp
->gang_num_expr
|| gfc_match (" num :") == MATCH_ERROR
)
428 else if (gfc_match (" %e ", &cp
->gang_num_expr
) != MATCH_YES
)
432 ret
= gfc_match (" , ");
435 return gfc_match (" ) ");
439 gfc_match_oacc_clause_link (const char *str
, gfc_omp_namelist
**list
)
441 gfc_omp_namelist
*head
= NULL
;
442 gfc_omp_namelist
*tail
, *p
;
444 char n
[GFC_MAX_SYMBOL_LEN
+1];
449 old_loc
= gfc_current_locus
;
455 m
= gfc_match (" (");
459 m
= gfc_match_symbol (&sym
, 0);
463 if (sym
->attr
.in_common
)
465 gfc_error_now ("Variable at %C is an element of a COMMON block");
468 gfc_set_sym_referenced (sym
);
469 p
= gfc_get_omp_namelist ();
479 tail
->where
= gfc_current_locus
;
488 m
= gfc_match (" / %n /", n
);
489 if (m
== MATCH_ERROR
)
491 if (m
== MATCH_NO
|| n
[0] == '\0')
494 st
= gfc_find_symtree (gfc_current_ns
->common_root
, n
);
497 gfc_error ("COMMON block /%s/ not found at %C", n
);
501 for (sym
= st
->n
.common
->head
; sym
; sym
= sym
->common_next
)
503 gfc_set_sym_referenced (sym
);
504 p
= gfc_get_omp_namelist ();
513 tail
->where
= gfc_current_locus
;
517 if (gfc_match_char (')') == MATCH_YES
)
519 if (gfc_match_char (',') != MATCH_YES
)
523 if (gfc_match_omp_eos () != MATCH_YES
)
525 gfc_error ("Unexpected junk after !$ACC DECLARE at %C");
530 list
= &(*list
)->next
;
535 gfc_error ("Syntax error in !$ACC DECLARE list at %C");
538 gfc_current_locus
= old_loc
;
542 #define OMP_CLAUSE_PRIVATE ((uint64_t) 1 << 0)
543 #define OMP_CLAUSE_FIRSTPRIVATE ((uint64_t) 1 << 1)
544 #define OMP_CLAUSE_LASTPRIVATE ((uint64_t) 1 << 2)
545 #define OMP_CLAUSE_COPYPRIVATE ((uint64_t) 1 << 3)
546 #define OMP_CLAUSE_SHARED ((uint64_t) 1 << 4)
547 #define OMP_CLAUSE_COPYIN ((uint64_t) 1 << 5)
548 #define OMP_CLAUSE_REDUCTION ((uint64_t) 1 << 6)
549 #define OMP_CLAUSE_IF ((uint64_t) 1 << 7)
550 #define OMP_CLAUSE_NUM_THREADS ((uint64_t) 1 << 8)
551 #define OMP_CLAUSE_SCHEDULE ((uint64_t) 1 << 9)
552 #define OMP_CLAUSE_DEFAULT ((uint64_t) 1 << 10)
553 #define OMP_CLAUSE_ORDERED ((uint64_t) 1 << 11)
554 #define OMP_CLAUSE_COLLAPSE ((uint64_t) 1 << 12)
555 #define OMP_CLAUSE_UNTIED ((uint64_t) 1 << 13)
556 #define OMP_CLAUSE_FINAL ((uint64_t) 1 << 14)
557 #define OMP_CLAUSE_MERGEABLE ((uint64_t) 1 << 15)
558 #define OMP_CLAUSE_ALIGNED ((uint64_t) 1 << 16)
559 #define OMP_CLAUSE_DEPEND ((uint64_t) 1 << 17)
560 #define OMP_CLAUSE_INBRANCH ((uint64_t) 1 << 18)
561 #define OMP_CLAUSE_LINEAR ((uint64_t) 1 << 19)
562 #define OMP_CLAUSE_NOTINBRANCH ((uint64_t) 1 << 20)
563 #define OMP_CLAUSE_PROC_BIND ((uint64_t) 1 << 21)
564 #define OMP_CLAUSE_SAFELEN ((uint64_t) 1 << 22)
565 #define OMP_CLAUSE_SIMDLEN ((uint64_t) 1 << 23)
566 #define OMP_CLAUSE_UNIFORM ((uint64_t) 1 << 24)
567 #define OMP_CLAUSE_DEVICE ((uint64_t) 1 << 25)
568 #define OMP_CLAUSE_MAP ((uint64_t) 1 << 26)
569 #define OMP_CLAUSE_TO ((uint64_t) 1 << 27)
570 #define OMP_CLAUSE_FROM ((uint64_t) 1 << 28)
571 #define OMP_CLAUSE_NUM_TEAMS ((uint64_t) 1 << 29)
572 #define OMP_CLAUSE_THREAD_LIMIT ((uint64_t) 1 << 30)
573 #define OMP_CLAUSE_DIST_SCHEDULE ((uint64_t) 1 << 31)
575 /* OpenACC 2.0 clauses. */
576 #define OMP_CLAUSE_ASYNC ((uint64_t) 1 << 32)
577 #define OMP_CLAUSE_NUM_GANGS ((uint64_t) 1 << 33)
578 #define OMP_CLAUSE_NUM_WORKERS ((uint64_t) 1 << 34)
579 #define OMP_CLAUSE_VECTOR_LENGTH ((uint64_t) 1 << 35)
580 #define OMP_CLAUSE_COPY ((uint64_t) 1 << 36)
581 #define OMP_CLAUSE_COPYOUT ((uint64_t) 1 << 37)
582 #define OMP_CLAUSE_CREATE ((uint64_t) 1 << 38)
583 #define OMP_CLAUSE_PRESENT ((uint64_t) 1 << 39)
584 #define OMP_CLAUSE_PRESENT_OR_COPY ((uint64_t) 1 << 40)
585 #define OMP_CLAUSE_PRESENT_OR_COPYIN ((uint64_t) 1 << 41)
586 #define OMP_CLAUSE_PRESENT_OR_COPYOUT ((uint64_t) 1 << 42)
587 #define OMP_CLAUSE_PRESENT_OR_CREATE ((uint64_t) 1 << 43)
588 #define OMP_CLAUSE_DEVICEPTR ((uint64_t) 1 << 44)
589 #define OMP_CLAUSE_GANG ((uint64_t) 1 << 45)
590 #define OMP_CLAUSE_WORKER ((uint64_t) 1 << 46)
591 #define OMP_CLAUSE_VECTOR ((uint64_t) 1 << 47)
592 #define OMP_CLAUSE_SEQ ((uint64_t) 1 << 48)
593 #define OMP_CLAUSE_INDEPENDENT ((uint64_t) 1 << 49)
594 #define OMP_CLAUSE_USE_DEVICE ((uint64_t) 1 << 50)
595 #define OMP_CLAUSE_DEVICE_RESIDENT ((uint64_t) 1 << 51)
596 #define OMP_CLAUSE_HOST_SELF ((uint64_t) 1 << 52)
597 #define OMP_CLAUSE_OACC_DEVICE ((uint64_t) 1 << 53)
598 #define OMP_CLAUSE_WAIT ((uint64_t) 1 << 54)
599 #define OMP_CLAUSE_DELETE ((uint64_t) 1 << 55)
600 #define OMP_CLAUSE_AUTO ((uint64_t) 1 << 56)
601 #define OMP_CLAUSE_TILE ((uint64_t) 1 << 57)
602 #define OMP_CLAUSE_LINK ((uint64_t) 1 << 58)
604 /* Helper function for OpenACC and OpenMP clauses involving memory
608 gfc_match_omp_map_clause (gfc_omp_namelist
**list
, gfc_omp_map_op map_op
)
610 gfc_omp_namelist
**head
= NULL
;
611 if (gfc_match_omp_variable_list ("", list
, false, NULL
, &head
, true)
615 for (n
= *head
; n
; n
= n
->next
)
616 n
->u
.map_op
= map_op
;
623 /* Match OpenMP and OpenACC directive clauses. MASK is a bitmask of
624 clauses that are allowed for a particular directive. */
627 gfc_match_omp_clauses (gfc_omp_clauses
**cp
, uint64_t mask
,
628 bool first
= true, bool needs_space
= true,
629 bool openacc
= false)
631 gfc_omp_clauses
*c
= gfc_get_omp_clauses ();
637 if ((first
|| gfc_match_char (',') != MATCH_YES
)
638 && (needs_space
&& gfc_match_space () != MATCH_YES
))
642 gfc_gobble_whitespace ();
644 gfc_omp_namelist
**head
;
645 old_loc
= gfc_current_locus
;
646 char pc
= gfc_peek_ascii_char ();
652 if ((mask
& OMP_CLAUSE_ALIGNED
)
653 && gfc_match_omp_variable_list ("aligned (",
654 &c
->lists
[OMP_LIST_ALIGNED
],
658 gfc_expr
*alignment
= NULL
;
661 if (end_colon
&& gfc_match (" %e )", &alignment
) != MATCH_YES
)
663 gfc_free_omp_namelist (*head
);
664 gfc_current_locus
= old_loc
;
668 for (n
= *head
; n
; n
= n
->next
)
669 if (n
->next
&& alignment
)
670 n
->expr
= gfc_copy_expr (alignment
);
675 if ((mask
& OMP_CLAUSE_ASYNC
)
677 && gfc_match ("async") == MATCH_YES
)
681 if (gfc_match (" ( %e )", &c
->async_expr
) != MATCH_YES
)
684 = gfc_get_constant_expr (BT_INTEGER
,
685 gfc_default_integer_kind
,
687 mpz_set_si (c
->async_expr
->value
.integer
, GOMP_ASYNC_NOVAL
);
691 if ((mask
& OMP_CLAUSE_AUTO
)
693 && gfc_match ("auto") == MATCH_YES
)
701 if ((mask
& OMP_CLAUSE_COLLAPSE
)
704 gfc_expr
*cexpr
= NULL
;
705 match m
= gfc_match ("collapse ( %e )", &cexpr
);
710 const char *p
= gfc_extract_int (cexpr
, &collapse
);
716 else if (collapse
<= 0)
718 gfc_error_now ("COLLAPSE clause argument not"
719 " constant positive integer at %C");
722 c
->collapse
= collapse
;
723 gfc_free_expr (cexpr
);
727 if ((mask
& OMP_CLAUSE_COPY
)
728 && gfc_match ("copy ( ") == MATCH_YES
729 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
730 OMP_MAP_FORCE_TOFROM
))
732 if (mask
& OMP_CLAUSE_COPYIN
)
736 if (gfc_match ("copyin ( ") == MATCH_YES
737 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
741 else if (gfc_match_omp_variable_list ("copyin (",
742 &c
->lists
[OMP_LIST_COPYIN
],
746 if ((mask
& OMP_CLAUSE_COPYOUT
)
747 && gfc_match ("copyout ( ") == MATCH_YES
748 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
751 if ((mask
& OMP_CLAUSE_COPYPRIVATE
)
752 && gfc_match_omp_variable_list ("copyprivate (",
753 &c
->lists
[OMP_LIST_COPYPRIVATE
],
756 if ((mask
& OMP_CLAUSE_CREATE
)
757 && gfc_match ("create ( ") == MATCH_YES
758 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
759 OMP_MAP_FORCE_ALLOC
))
763 if ((mask
& OMP_CLAUSE_DELETE
)
764 && gfc_match ("delete ( ") == MATCH_YES
765 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
768 if ((mask
& OMP_CLAUSE_DEFAULT
)
769 && c
->default_sharing
== OMP_DEFAULT_UNKNOWN
)
771 if (gfc_match ("default ( none )") == MATCH_YES
)
772 c
->default_sharing
= OMP_DEFAULT_NONE
;
774 /* c->default_sharing = OMP_DEFAULT_UNKNOWN */;
775 else if (gfc_match ("default ( shared )") == MATCH_YES
)
776 c
->default_sharing
= OMP_DEFAULT_SHARED
;
777 else if (gfc_match ("default ( private )") == MATCH_YES
)
778 c
->default_sharing
= OMP_DEFAULT_PRIVATE
;
779 else if (gfc_match ("default ( firstprivate )") == MATCH_YES
)
780 c
->default_sharing
= OMP_DEFAULT_FIRSTPRIVATE
;
781 if (c
->default_sharing
!= OMP_DEFAULT_UNKNOWN
)
784 if ((mask
& OMP_CLAUSE_DEPEND
)
785 && gfc_match ("depend ( ") == MATCH_YES
)
788 gfc_omp_depend_op depend_op
= OMP_DEPEND_OUT
;
789 if (gfc_match ("inout") == MATCH_YES
)
790 depend_op
= OMP_DEPEND_INOUT
;
791 else if (gfc_match ("in") == MATCH_YES
)
792 depend_op
= OMP_DEPEND_IN
;
793 else if (gfc_match ("out") == MATCH_YES
)
794 depend_op
= OMP_DEPEND_OUT
;
799 && gfc_match_omp_variable_list (" : ",
800 &c
->lists
[OMP_LIST_DEPEND
],
805 for (n
= *head
; n
; n
= n
->next
)
806 n
->u
.depend_op
= depend_op
;
810 gfc_current_locus
= old_loc
;
812 if ((mask
& OMP_CLAUSE_DEVICE
)
814 && gfc_match ("device ( %e )", &c
->device
) == MATCH_YES
)
816 if ((mask
& OMP_CLAUSE_OACC_DEVICE
)
817 && gfc_match ("device ( ") == MATCH_YES
818 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
821 if ((mask
& OMP_CLAUSE_DEVICEPTR
)
822 && gfc_match ("deviceptr ( ") == MATCH_YES
)
824 gfc_omp_namelist
**list
= &c
->lists
[OMP_LIST_MAP
];
825 gfc_omp_namelist
**head
= NULL
;
826 if (gfc_match_omp_variable_list ("", list
, true, NULL
,
827 &head
, false) == MATCH_YES
)
830 for (n
= *head
; n
; n
= n
->next
)
831 n
->u
.map_op
= OMP_MAP_FORCE_DEVICEPTR
;
835 if ((mask
& OMP_CLAUSE_DEVICE_RESIDENT
)
836 && gfc_match_omp_variable_list
837 ("device_resident (",
838 &c
->lists
[OMP_LIST_DEVICE_RESIDENT
], true) == MATCH_YES
)
840 if ((mask
& OMP_CLAUSE_DIST_SCHEDULE
)
841 && c
->dist_sched_kind
== OMP_SCHED_NONE
842 && gfc_match ("dist_schedule ( static") == MATCH_YES
)
845 c
->dist_sched_kind
= OMP_SCHED_STATIC
;
846 m
= gfc_match (" , %e )", &c
->dist_chunk_size
);
848 m
= gfc_match_char (')');
851 c
->dist_sched_kind
= OMP_SCHED_NONE
;
852 gfc_current_locus
= old_loc
;
859 if ((mask
& OMP_CLAUSE_FINAL
)
860 && c
->final_expr
== NULL
861 && gfc_match ("final ( %e )", &c
->final_expr
) == MATCH_YES
)
863 if ((mask
& OMP_CLAUSE_FIRSTPRIVATE
)
864 && gfc_match_omp_variable_list ("firstprivate (",
865 &c
->lists
[OMP_LIST_FIRSTPRIVATE
],
868 if ((mask
& OMP_CLAUSE_FROM
)
869 && gfc_match_omp_variable_list ("from (",
870 &c
->lists
[OMP_LIST_FROM
], false,
871 NULL
, &head
, true) == MATCH_YES
)
875 if ((mask
& OMP_CLAUSE_GANG
)
877 && gfc_match ("gang") == MATCH_YES
)
880 if (match_oacc_clause_gang(c
) == MATCH_YES
)
888 if ((mask
& OMP_CLAUSE_HOST_SELF
)
889 && gfc_match ("host ( ") == MATCH_YES
890 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
895 if ((mask
& OMP_CLAUSE_IF
)
896 && c
->if_expr
== NULL
897 && gfc_match ("if ( %e )", &c
->if_expr
) == MATCH_YES
)
899 if ((mask
& OMP_CLAUSE_INBRANCH
)
902 && gfc_match ("inbranch") == MATCH_YES
)
904 c
->inbranch
= needs_space
= true;
907 if ((mask
& OMP_CLAUSE_INDEPENDENT
)
909 && gfc_match ("independent") == MATCH_YES
)
911 c
->independent
= true;
917 if ((mask
& OMP_CLAUSE_LASTPRIVATE
)
918 && gfc_match_omp_variable_list ("lastprivate (",
919 &c
->lists
[OMP_LIST_LASTPRIVATE
],
924 if ((mask
& OMP_CLAUSE_LINEAR
)
925 && gfc_match_omp_variable_list ("linear (",
926 &c
->lists
[OMP_LIST_LINEAR
],
930 gfc_expr
*step
= NULL
;
932 if (end_colon
&& gfc_match (" %e )", &step
) != MATCH_YES
)
934 gfc_free_omp_namelist (*head
);
935 gfc_current_locus
= old_loc
;
941 step
= gfc_get_constant_expr (BT_INTEGER
,
942 gfc_default_integer_kind
,
944 mpz_set_si (step
->value
.integer
, 1);
946 (*head
)->expr
= step
;
949 if ((mask
& OMP_CLAUSE_LINK
)
950 && (gfc_match_oacc_clause_link ("link (",
951 &c
->lists
[OMP_LIST_LINK
])
956 if ((mask
& OMP_CLAUSE_MAP
)
957 && gfc_match ("map ( ") == MATCH_YES
)
959 gfc_omp_map_op map_op
= OMP_MAP_TOFROM
;
960 if (gfc_match ("alloc : ") == MATCH_YES
)
961 map_op
= OMP_MAP_ALLOC
;
962 else if (gfc_match ("tofrom : ") == MATCH_YES
)
963 map_op
= OMP_MAP_TOFROM
;
964 else if (gfc_match ("to : ") == MATCH_YES
)
966 else if (gfc_match ("from : ") == MATCH_YES
)
967 map_op
= OMP_MAP_FROM
;
969 if (gfc_match_omp_variable_list ("", &c
->lists
[OMP_LIST_MAP
],
974 for (n
= *head
; n
; n
= n
->next
)
975 n
->u
.map_op
= map_op
;
979 gfc_current_locus
= old_loc
;
981 if ((mask
& OMP_CLAUSE_MERGEABLE
) && !c
->mergeable
982 && gfc_match ("mergeable") == MATCH_YES
)
984 c
->mergeable
= needs_space
= true;
989 if ((mask
& OMP_CLAUSE_NOTINBRANCH
)
992 && gfc_match ("notinbranch") == MATCH_YES
)
994 c
->notinbranch
= needs_space
= true;
997 if ((mask
& OMP_CLAUSE_NUM_GANGS
)
998 && c
->num_gangs_expr
== NULL
999 && gfc_match ("num_gangs ( %e )",
1000 &c
->num_gangs_expr
) == MATCH_YES
)
1002 if ((mask
& OMP_CLAUSE_NUM_TEAMS
)
1003 && c
->num_teams
== NULL
1004 && gfc_match ("num_teams ( %e )", &c
->num_teams
) == MATCH_YES
)
1006 if ((mask
& OMP_CLAUSE_NUM_THREADS
)
1007 && c
->num_threads
== NULL
1008 && (gfc_match ("num_threads ( %e )", &c
->num_threads
)
1011 if ((mask
& OMP_CLAUSE_NUM_WORKERS
)
1012 && c
->num_workers_expr
== NULL
1013 && gfc_match ("num_workers ( %e )",
1014 &c
->num_workers_expr
) == MATCH_YES
)
1018 if ((mask
& OMP_CLAUSE_ORDERED
)
1020 && gfc_match ("ordered") == MATCH_YES
)
1022 c
->ordered
= needs_space
= true;
1027 if ((mask
& OMP_CLAUSE_PRESENT_OR_COPY
)
1028 && gfc_match ("pcopy ( ") == MATCH_YES
1029 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1032 if ((mask
& OMP_CLAUSE_PRESENT_OR_COPYIN
)
1033 && gfc_match ("pcopyin ( ") == MATCH_YES
1034 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1037 if ((mask
& OMP_CLAUSE_PRESENT_OR_COPYOUT
)
1038 && gfc_match ("pcopyout ( ") == MATCH_YES
1039 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1042 if ((mask
& OMP_CLAUSE_PRESENT_OR_CREATE
)
1043 && gfc_match ("pcreate ( ") == MATCH_YES
1044 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1047 if ((mask
& OMP_CLAUSE_PRESENT
)
1048 && gfc_match ("present ( ") == MATCH_YES
1049 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1050 OMP_MAP_FORCE_PRESENT
))
1052 if ((mask
& OMP_CLAUSE_PRESENT_OR_COPY
)
1053 && gfc_match ("present_or_copy ( ") == MATCH_YES
1054 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1057 if ((mask
& OMP_CLAUSE_PRESENT_OR_COPYIN
)
1058 && gfc_match ("present_or_copyin ( ") == MATCH_YES
1059 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1062 if ((mask
& OMP_CLAUSE_PRESENT_OR_COPYOUT
)
1063 && gfc_match ("present_or_copyout ( ") == MATCH_YES
1064 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1067 if ((mask
& OMP_CLAUSE_PRESENT_OR_CREATE
)
1068 && gfc_match ("present_or_create ( ") == MATCH_YES
1069 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1072 if ((mask
& OMP_CLAUSE_PRIVATE
)
1073 && gfc_match_omp_variable_list ("private (",
1074 &c
->lists
[OMP_LIST_PRIVATE
],
1077 if ((mask
& OMP_CLAUSE_PROC_BIND
)
1078 && c
->proc_bind
== OMP_PROC_BIND_UNKNOWN
)
1080 if (gfc_match ("proc_bind ( master )") == MATCH_YES
)
1081 c
->proc_bind
= OMP_PROC_BIND_MASTER
;
1082 else if (gfc_match ("proc_bind ( spread )") == MATCH_YES
)
1083 c
->proc_bind
= OMP_PROC_BIND_SPREAD
;
1084 else if (gfc_match ("proc_bind ( close )") == MATCH_YES
)
1085 c
->proc_bind
= OMP_PROC_BIND_CLOSE
;
1086 if (c
->proc_bind
!= OMP_PROC_BIND_UNKNOWN
)
1091 if ((mask
& OMP_CLAUSE_REDUCTION
)
1092 && gfc_match ("reduction ( ") == MATCH_YES
)
1094 gfc_omp_reduction_op rop
= OMP_REDUCTION_NONE
;
1095 char buffer
[GFC_MAX_SYMBOL_LEN
+ 3];
1096 if (gfc_match_char ('+') == MATCH_YES
)
1097 rop
= OMP_REDUCTION_PLUS
;
1098 else if (gfc_match_char ('*') == MATCH_YES
)
1099 rop
= OMP_REDUCTION_TIMES
;
1100 else if (gfc_match_char ('-') == MATCH_YES
)
1101 rop
= OMP_REDUCTION_MINUS
;
1102 else if (gfc_match (".and.") == MATCH_YES
)
1103 rop
= OMP_REDUCTION_AND
;
1104 else if (gfc_match (".or.") == MATCH_YES
)
1105 rop
= OMP_REDUCTION_OR
;
1106 else if (gfc_match (".eqv.") == MATCH_YES
)
1107 rop
= OMP_REDUCTION_EQV
;
1108 else if (gfc_match (".neqv.") == MATCH_YES
)
1109 rop
= OMP_REDUCTION_NEQV
;
1110 if (rop
!= OMP_REDUCTION_NONE
)
1111 snprintf (buffer
, sizeof buffer
, "operator %s",
1112 gfc_op2string ((gfc_intrinsic_op
) rop
));
1113 else if (gfc_match_defined_op_name (buffer
+ 1, 1) == MATCH_YES
)
1116 strcat (buffer
, ".");
1118 else if (gfc_match_name (buffer
) == MATCH_YES
)
1121 const char *n
= buffer
;
1123 gfc_find_symbol (buffer
, NULL
, 1, &sym
);
1126 if (sym
->attr
.intrinsic
)
1128 else if ((sym
->attr
.flavor
!= FL_UNKNOWN
1129 && sym
->attr
.flavor
!= FL_PROCEDURE
)
1130 || sym
->attr
.external
1131 || sym
->attr
.generic
1135 || sym
->attr
.subroutine
1136 || sym
->attr
.pointer
1138 || sym
->attr
.cray_pointer
1139 || sym
->attr
.cray_pointee
1140 || (sym
->attr
.proc
!= PROC_UNKNOWN
1141 && sym
->attr
.proc
!= PROC_INTRINSIC
)
1142 || sym
->attr
.if_source
!= IFSRC_UNKNOWN
1143 || sym
== sym
->ns
->proc_name
)
1152 rop
= OMP_REDUCTION_NONE
;
1153 else if (strcmp (n
, "max") == 0)
1154 rop
= OMP_REDUCTION_MAX
;
1155 else if (strcmp (n
, "min") == 0)
1156 rop
= OMP_REDUCTION_MIN
;
1157 else if (strcmp (n
, "iand") == 0)
1158 rop
= OMP_REDUCTION_IAND
;
1159 else if (strcmp (n
, "ior") == 0)
1160 rop
= OMP_REDUCTION_IOR
;
1161 else if (strcmp (n
, "ieor") == 0)
1162 rop
= OMP_REDUCTION_IEOR
;
1163 if (rop
!= OMP_REDUCTION_NONE
1165 && ! sym
->attr
.intrinsic
1166 && ! sym
->attr
.use_assoc
1167 && ((sym
->attr
.flavor
== FL_UNKNOWN
1168 && !gfc_add_flavor (&sym
->attr
, FL_PROCEDURE
,
1170 || !gfc_add_intrinsic (&sym
->attr
, NULL
)))
1171 rop
= OMP_REDUCTION_NONE
;
1177 ? gfc_find_omp_udr (gfc_current_ns
, buffer
, NULL
) : NULL
);
1178 gfc_omp_namelist
**head
= NULL
;
1179 if (rop
== OMP_REDUCTION_NONE
&& udr
)
1180 rop
= OMP_REDUCTION_USER
;
1182 if (gfc_match_omp_variable_list (" :",
1183 &c
->lists
[OMP_LIST_REDUCTION
],
1185 openacc
) == MATCH_YES
)
1187 gfc_omp_namelist
*n
;
1188 if (rop
== OMP_REDUCTION_NONE
)
1192 gfc_error_now ("!$OMP DECLARE REDUCTION %s not found "
1193 "at %L", buffer
, &old_loc
);
1194 gfc_free_omp_namelist (n
);
1197 for (n
= *head
; n
; n
= n
->next
)
1199 n
->u
.reduction_op
= rop
;
1202 n
->udr
= gfc_get_omp_namelist_udr ();
1209 gfc_current_locus
= old_loc
;
1213 if ((mask
& OMP_CLAUSE_SAFELEN
)
1214 && c
->safelen_expr
== NULL
1215 && gfc_match ("safelen ( %e )", &c
->safelen_expr
) == MATCH_YES
)
1217 if ((mask
& OMP_CLAUSE_SCHEDULE
)
1218 && c
->sched_kind
== OMP_SCHED_NONE
1219 && gfc_match ("schedule ( ") == MATCH_YES
)
1221 if (gfc_match ("static") == MATCH_YES
)
1222 c
->sched_kind
= OMP_SCHED_STATIC
;
1223 else if (gfc_match ("dynamic") == MATCH_YES
)
1224 c
->sched_kind
= OMP_SCHED_DYNAMIC
;
1225 else if (gfc_match ("guided") == MATCH_YES
)
1226 c
->sched_kind
= OMP_SCHED_GUIDED
;
1227 else if (gfc_match ("runtime") == MATCH_YES
)
1228 c
->sched_kind
= OMP_SCHED_RUNTIME
;
1229 else if (gfc_match ("auto") == MATCH_YES
)
1230 c
->sched_kind
= OMP_SCHED_AUTO
;
1231 if (c
->sched_kind
!= OMP_SCHED_NONE
)
1234 if (c
->sched_kind
!= OMP_SCHED_RUNTIME
1235 && c
->sched_kind
!= OMP_SCHED_AUTO
)
1236 m
= gfc_match (" , %e )", &c
->chunk_size
);
1238 m
= gfc_match_char (')');
1240 c
->sched_kind
= OMP_SCHED_NONE
;
1242 if (c
->sched_kind
!= OMP_SCHED_NONE
)
1245 gfc_current_locus
= old_loc
;
1247 if ((mask
& OMP_CLAUSE_HOST_SELF
)
1248 && gfc_match ("self ( ") == MATCH_YES
1249 && gfc_match_omp_map_clause (&c
->lists
[OMP_LIST_MAP
],
1250 OMP_MAP_FORCE_FROM
))
1252 if ((mask
& OMP_CLAUSE_SEQ
)
1254 && gfc_match ("seq") == MATCH_YES
)
1260 if ((mask
& OMP_CLAUSE_SHARED
)
1261 && gfc_match_omp_variable_list ("shared (",
1262 &c
->lists
[OMP_LIST_SHARED
],
1265 if ((mask
& OMP_CLAUSE_SIMDLEN
)
1266 && c
->simdlen_expr
== NULL
1267 && gfc_match ("simdlen ( %e )", &c
->simdlen_expr
) == MATCH_YES
)
1271 if ((mask
& OMP_CLAUSE_THREAD_LIMIT
)
1272 && c
->thread_limit
== NULL
1273 && gfc_match ("thread_limit ( %e )",
1274 &c
->thread_limit
) == MATCH_YES
)
1276 if ((mask
& OMP_CLAUSE_TILE
)
1278 && match_oacc_expr_list ("tile (", &c
->tile_list
,
1281 if ((mask
& OMP_CLAUSE_TO
)
1282 && gfc_match_omp_variable_list ("to (",
1283 &c
->lists
[OMP_LIST_TO
], false,
1284 NULL
, &head
, true) == MATCH_YES
)
1288 if ((mask
& OMP_CLAUSE_UNIFORM
)
1289 && gfc_match_omp_variable_list ("uniform (",
1290 &c
->lists
[OMP_LIST_UNIFORM
],
1291 false) == MATCH_YES
)
1293 if ((mask
& OMP_CLAUSE_UNTIED
)
1295 && gfc_match ("untied") == MATCH_YES
)
1297 c
->untied
= needs_space
= true;
1300 if ((mask
& OMP_CLAUSE_USE_DEVICE
)
1301 && gfc_match_omp_variable_list ("use_device (",
1302 &c
->lists
[OMP_LIST_USE_DEVICE
],
1307 if ((mask
& OMP_CLAUSE_VECTOR
)
1309 && gfc_match ("vector") == MATCH_YES
)
1312 if (gfc_match (" ( length : %e )", &c
->vector_expr
) == MATCH_YES
1313 || gfc_match (" ( %e )", &c
->vector_expr
) == MATCH_YES
)
1314 needs_space
= false;
1319 if ((mask
& OMP_CLAUSE_VECTOR_LENGTH
)
1320 && c
->vector_length_expr
== NULL
1321 && (gfc_match ("vector_length ( %e )", &c
->vector_length_expr
)
1326 if ((mask
& OMP_CLAUSE_WAIT
)
1328 && gfc_match ("wait") == MATCH_YES
)
1331 match_oacc_expr_list (" (", &c
->wait_list
, false);
1334 if ((mask
& OMP_CLAUSE_WORKER
)
1336 && gfc_match ("worker") == MATCH_YES
)
1339 if (gfc_match (" ( num : %e )", &c
->worker_expr
) == MATCH_YES
1340 || gfc_match (" ( %e )", &c
->worker_expr
) == MATCH_YES
)
1341 needs_space
= false;
1351 if (gfc_match_omp_eos () != MATCH_YES
)
1353 gfc_free_omp_clauses (c
);
1362 #define OACC_PARALLEL_CLAUSES \
1363 (OMP_CLAUSE_IF | OMP_CLAUSE_ASYNC | OMP_CLAUSE_NUM_GANGS \
1364 | OMP_CLAUSE_NUM_WORKERS | OMP_CLAUSE_VECTOR_LENGTH | OMP_CLAUSE_REDUCTION \
1365 | OMP_CLAUSE_COPY | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT \
1366 | OMP_CLAUSE_CREATE | OMP_CLAUSE_PRESENT | OMP_CLAUSE_PRESENT_OR_COPY \
1367 | OMP_CLAUSE_PRESENT_OR_COPYIN | OMP_CLAUSE_PRESENT_OR_COPYOUT \
1368 | OMP_CLAUSE_PRESENT_OR_CREATE | OMP_CLAUSE_DEVICEPTR | OMP_CLAUSE_PRIVATE \
1369 | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_WAIT)
1370 #define OACC_KERNELS_CLAUSES \
1371 (OMP_CLAUSE_IF | OMP_CLAUSE_ASYNC | OMP_CLAUSE_DEVICEPTR \
1372 | OMP_CLAUSE_COPY | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT \
1373 | OMP_CLAUSE_CREATE | OMP_CLAUSE_PRESENT | OMP_CLAUSE_PRESENT_OR_COPY \
1374 | OMP_CLAUSE_PRESENT_OR_COPYIN | OMP_CLAUSE_PRESENT_OR_COPYOUT \
1375 | OMP_CLAUSE_PRESENT_OR_CREATE | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_WAIT)
1376 #define OACC_DATA_CLAUSES \
1377 (OMP_CLAUSE_IF | OMP_CLAUSE_DEVICEPTR | OMP_CLAUSE_COPY \
1378 | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT | OMP_CLAUSE_CREATE \
1379 | OMP_CLAUSE_PRESENT | OMP_CLAUSE_PRESENT_OR_COPY \
1380 | OMP_CLAUSE_PRESENT_OR_COPYIN | OMP_CLAUSE_PRESENT_OR_COPYOUT \
1381 | OMP_CLAUSE_PRESENT_OR_CREATE)
1382 #define OACC_LOOP_CLAUSES \
1383 (OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_GANG | OMP_CLAUSE_WORKER \
1384 | OMP_CLAUSE_VECTOR | OMP_CLAUSE_SEQ | OMP_CLAUSE_INDEPENDENT \
1385 | OMP_CLAUSE_PRIVATE | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_AUTO \
1387 #define OACC_PARALLEL_LOOP_CLAUSES \
1388 (OACC_LOOP_CLAUSES | OACC_PARALLEL_CLAUSES)
1389 #define OACC_KERNELS_LOOP_CLAUSES \
1390 (OACC_LOOP_CLAUSES | OACC_KERNELS_CLAUSES)
1391 #define OACC_HOST_DATA_CLAUSES OMP_CLAUSE_USE_DEVICE
1392 #define OACC_DECLARE_CLAUSES \
1393 (OMP_CLAUSE_COPY | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT \
1394 | OMP_CLAUSE_CREATE | OMP_CLAUSE_DEVICEPTR | OMP_CLAUSE_DEVICE_RESIDENT \
1395 | OMP_CLAUSE_PRESENT | OMP_CLAUSE_PRESENT_OR_COPY \
1396 | OMP_CLAUSE_PRESENT_OR_COPYIN | OMP_CLAUSE_PRESENT_OR_COPYOUT \
1397 | OMP_CLAUSE_PRESENT_OR_CREATE | OMP_CLAUSE_LINK)
1398 #define OACC_UPDATE_CLAUSES \
1399 (OMP_CLAUSE_IF | OMP_CLAUSE_ASYNC | OMP_CLAUSE_HOST_SELF \
1400 | OMP_CLAUSE_OACC_DEVICE | OMP_CLAUSE_WAIT)
1401 #define OACC_ENTER_DATA_CLAUSES \
1402 (OMP_CLAUSE_IF | OMP_CLAUSE_ASYNC | OMP_CLAUSE_WAIT | OMP_CLAUSE_COPYIN \
1403 | OMP_CLAUSE_CREATE | OMP_CLAUSE_PRESENT_OR_COPYIN \
1404 | OMP_CLAUSE_PRESENT_OR_CREATE)
1405 #define OACC_EXIT_DATA_CLAUSES \
1406 (OMP_CLAUSE_IF | OMP_CLAUSE_ASYNC | OMP_CLAUSE_WAIT | OMP_CLAUSE_COPYOUT \
1407 | OMP_CLAUSE_DELETE)
1408 #define OACC_WAIT_CLAUSES \
1410 #define OACC_ROUTINE_CLAUSES \
1411 (OMP_CLAUSE_GANG | OMP_CLAUSE_WORKER | OMP_CLAUSE_VECTOR | OMP_CLAUSE_SEQ)
1415 match_acc (gfc_exec_op op
, uint64_t mask
)
1418 if (gfc_match_omp_clauses (&c
, mask
, false, false, true) != MATCH_YES
)
1421 new_st
.ext
.omp_clauses
= c
;
1426 gfc_match_oacc_parallel_loop (void)
1428 return match_acc (EXEC_OACC_PARALLEL_LOOP
, OACC_PARALLEL_LOOP_CLAUSES
);
1433 gfc_match_oacc_parallel (void)
1435 return match_acc (EXEC_OACC_PARALLEL
, OACC_PARALLEL_CLAUSES
);
1440 gfc_match_oacc_kernels_loop (void)
1442 return match_acc (EXEC_OACC_KERNELS_LOOP
, OACC_KERNELS_LOOP_CLAUSES
);
1447 gfc_match_oacc_kernels (void)
1449 return match_acc (EXEC_OACC_KERNELS
, OACC_KERNELS_CLAUSES
);
1454 gfc_match_oacc_data (void)
1456 return match_acc (EXEC_OACC_DATA
, OACC_DATA_CLAUSES
);
1461 gfc_match_oacc_host_data (void)
1463 return match_acc (EXEC_OACC_HOST_DATA
, OACC_HOST_DATA_CLAUSES
);
1468 gfc_match_oacc_loop (void)
1470 return match_acc (EXEC_OACC_LOOP
, OACC_LOOP_CLAUSES
);
1475 gfc_match_oacc_declare (void)
1478 gfc_omp_namelist
*n
;
1479 gfc_namespace
*ns
= gfc_current_ns
;
1480 gfc_oacc_declare
*new_oc
;
1481 bool module_var
= false;
1482 locus where
= gfc_current_locus
;
1484 if (gfc_match_omp_clauses (&c
, OACC_DECLARE_CLAUSES
, false, false, true)
1488 for (n
= c
->lists
[OMP_LIST_DEVICE_RESIDENT
]; n
!= NULL
; n
= n
->next
)
1489 n
->sym
->attr
.oacc_declare_device_resident
= 1;
1491 for (n
= c
->lists
[OMP_LIST_LINK
]; n
!= NULL
; n
= n
->next
)
1492 n
->sym
->attr
.oacc_declare_link
= 1;
1494 for (n
= c
->lists
[OMP_LIST_MAP
]; n
!= NULL
; n
= n
->next
)
1496 gfc_symbol
*s
= n
->sym
;
1498 if (s
->ns
->proc_name
&& s
->ns
->proc_name
->attr
.proc
== PROC_MODULE
)
1500 if (n
->u
.map_op
!= OMP_MAP_FORCE_ALLOC
1501 && n
->u
.map_op
!= OMP_MAP_FORCE_TO
)
1503 gfc_error ("Invalid clause in module with $!ACC DECLARE at %L",
1511 if (s
->attr
.use_assoc
)
1513 gfc_error ("Variable is USE-associated with $!ACC DECLARE at %L",
1518 if ((s
->attr
.dimension
|| s
->attr
.codimension
)
1519 && s
->attr
.dummy
&& s
->as
->type
!= AS_EXPLICIT
)
1521 gfc_error ("Assumed-size dummy array with $!ACC DECLARE at %L",
1526 switch (n
->u
.map_op
)
1528 case OMP_MAP_FORCE_ALLOC
:
1529 s
->attr
.oacc_declare_create
= 1;
1532 case OMP_MAP_FORCE_TO
:
1533 s
->attr
.oacc_declare_copyin
= 1;
1536 case OMP_MAP_FORCE_DEVICEPTR
:
1537 s
->attr
.oacc_declare_deviceptr
= 1;
1545 new_oc
= gfc_get_oacc_declare ();
1546 new_oc
->next
= ns
->oacc_declare
;
1547 new_oc
->module_var
= module_var
;
1548 new_oc
->clauses
= c
;
1549 new_oc
->loc
= gfc_current_locus
;
1550 ns
->oacc_declare
= new_oc
;
1557 gfc_match_oacc_update (void)
1560 locus here
= gfc_current_locus
;
1562 if (gfc_match_omp_clauses (&c
, OACC_UPDATE_CLAUSES
, false, false, true)
1566 if (!c
->lists
[OMP_LIST_MAP
])
1568 gfc_error ("%<acc update%> must contain at least one "
1569 "%<device%> or %<host%> or %<self%> clause at %L", &here
);
1573 new_st
.op
= EXEC_OACC_UPDATE
;
1574 new_st
.ext
.omp_clauses
= c
;
1580 gfc_match_oacc_enter_data (void)
1582 return match_acc (EXEC_OACC_ENTER_DATA
, OACC_ENTER_DATA_CLAUSES
);
1587 gfc_match_oacc_exit_data (void)
1589 return match_acc (EXEC_OACC_EXIT_DATA
, OACC_EXIT_DATA_CLAUSES
);
1594 gfc_match_oacc_wait (void)
1596 gfc_omp_clauses
*c
= gfc_get_omp_clauses ();
1597 gfc_expr_list
*wait_list
= NULL
, *el
;
1599 match_oacc_expr_list (" (", &wait_list
, true);
1600 gfc_match_omp_clauses (&c
, OACC_WAIT_CLAUSES
, false, false, true);
1602 if (gfc_match_omp_eos () != MATCH_YES
)
1604 gfc_error ("Unexpected junk in !$ACC WAIT at %C");
1609 for (el
= wait_list
; el
; el
= el
->next
)
1611 if (el
->expr
== NULL
)
1613 gfc_error ("Invalid argument to $!ACC WAIT at %L",
1614 &wait_list
->expr
->where
);
1618 if (!gfc_resolve_expr (el
->expr
)
1619 || el
->expr
->ts
.type
!= BT_INTEGER
|| el
->expr
->rank
!= 0
1620 || el
->expr
->expr_type
!= EXPR_CONSTANT
)
1622 gfc_error ("WAIT clause at %L requires a scalar INTEGER expression",
1628 c
->wait_list
= wait_list
;
1629 new_st
.op
= EXEC_OACC_WAIT
;
1630 new_st
.ext
.omp_clauses
= c
;
1636 gfc_match_oacc_cache (void)
1638 gfc_omp_clauses
*c
= gfc_get_omp_clauses ();
1639 /* The OpenACC cache directive explicitly only allows "array elements or
1640 subarrays", which we're currently not checking here. Either check this
1641 after the call of gfc_match_omp_variable_list, or add something like a
1642 only_sections variant next to its allow_sections parameter. */
1643 match m
= gfc_match_omp_variable_list (" (",
1644 &c
->lists
[OMP_LIST_CACHE
], true,
1648 gfc_free_omp_clauses(c
);
1652 if (gfc_current_state() != COMP_DO
1653 && gfc_current_state() != COMP_DO_CONCURRENT
)
1655 gfc_error ("ACC CACHE directive must be inside of loop %C");
1656 gfc_free_omp_clauses(c
);
1660 new_st
.op
= EXEC_OACC_CACHE
;
1661 new_st
.ext
.omp_clauses
= c
;
1665 /* Determine the loop level for a routine. */
1668 gfc_oacc_routine_dims (gfc_omp_clauses
*clauses
)
1677 level
= GOMP_DIM_GANG
, mask
|= GOMP_DIM_MASK (level
);
1678 if (clauses
->worker
)
1679 level
= GOMP_DIM_WORKER
, mask
|= GOMP_DIM_MASK (level
);
1680 if (clauses
->vector
)
1681 level
= GOMP_DIM_VECTOR
, mask
|= GOMP_DIM_MASK (level
);
1683 level
= GOMP_DIM_MAX
, mask
|= GOMP_DIM_MASK (level
);
1685 if (mask
!= (mask
& -mask
))
1686 gfc_error ("Multiple loop axes specified for routine");
1690 level
= GOMP_DIM_MAX
;
1696 gfc_match_oacc_routine (void)
1699 gfc_symbol
*sym
= NULL
;
1701 gfc_omp_clauses
*c
= NULL
;
1702 gfc_oacc_routine_name
*n
= NULL
;
1704 old_loc
= gfc_current_locus
;
1706 m
= gfc_match (" (");
1708 if (gfc_current_ns
->proc_name
1709 && gfc_current_ns
->proc_name
->attr
.if_source
== IFSRC_IFBODY
1712 gfc_error ("Only the !$ACC ROUTINE form without "
1713 "list is allowed in interface block at %C");
1719 char buffer
[GFC_MAX_SYMBOL_LEN
+ 1];
1722 m
= gfc_match_name (buffer
);
1725 st
= gfc_find_symtree (gfc_current_ns
->sym_root
, buffer
);
1729 if (strcmp (sym
->name
, gfc_current_ns
->proc_name
->name
) == 0)
1735 && !sym
->attr
.external
1736 && !sym
->attr
.function
1737 && !sym
->attr
.subroutine
))
1739 gfc_error ("Syntax error in !$ACC ROUTINE ( NAME ) at %C, "
1740 "invalid function name %s",
1741 (sym
) ? sym
->name
: buffer
);
1742 gfc_current_locus
= old_loc
;
1748 gfc_error ("Syntax error in !$ACC ROUTINE ( NAME ) at %C");
1749 gfc_current_locus
= old_loc
;
1753 if (gfc_match_char (')') != MATCH_YES
)
1755 gfc_error ("Syntax error in !$ACC ROUTINE ( NAME ) at %C, expecting"
1757 gfc_current_locus
= old_loc
;
1762 if (gfc_match_omp_eos () != MATCH_YES
1763 && (gfc_match_omp_clauses (&c
, OACC_ROUTINE_CLAUSES
, false, false, true)
1769 n
= gfc_get_oacc_routine_name ();
1773 if (gfc_current_ns
->oacc_routine_names
!= NULL
)
1774 n
->next
= gfc_current_ns
->oacc_routine_names
;
1776 gfc_current_ns
->oacc_routine_names
= n
;
1778 else if (gfc_current_ns
->proc_name
)
1780 if (!gfc_add_omp_declare_target (&gfc_current_ns
->proc_name
->attr
,
1781 gfc_current_ns
->proc_name
->name
,
1784 gfc_current_ns
->proc_name
->attr
.oacc_function
1785 = gfc_oacc_routine_dims (c
) + 1;
1790 else if (gfc_current_ns
->oacc_routine
)
1791 gfc_current_ns
->oacc_routine_clauses
= c
;
1793 new_st
.op
= EXEC_OACC_ROUTINE
;
1794 new_st
.ext
.omp_clauses
= c
;
1798 gfc_current_locus
= old_loc
;
1803 #define OMP_PARALLEL_CLAUSES \
1804 (OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_SHARED \
1805 | OMP_CLAUSE_COPYIN | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_IF \
1806 | OMP_CLAUSE_NUM_THREADS | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_PROC_BIND)
1807 #define OMP_DECLARE_SIMD_CLAUSES \
1808 (OMP_CLAUSE_SIMDLEN | OMP_CLAUSE_LINEAR | OMP_CLAUSE_UNIFORM \
1809 | OMP_CLAUSE_ALIGNED | OMP_CLAUSE_INBRANCH | OMP_CLAUSE_NOTINBRANCH)
1810 #define OMP_DO_CLAUSES \
1811 (OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE \
1812 | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION \
1813 | OMP_CLAUSE_SCHEDULE | OMP_CLAUSE_ORDERED | OMP_CLAUSE_COLLAPSE)
1814 #define OMP_SECTIONS_CLAUSES \
1815 (OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE \
1816 | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION)
1817 #define OMP_SIMD_CLAUSES \
1818 (OMP_CLAUSE_PRIVATE | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION \
1819 | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_SAFELEN | OMP_CLAUSE_LINEAR \
1820 | OMP_CLAUSE_ALIGNED)
1821 #define OMP_TASK_CLAUSES \
1822 (OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_SHARED \
1823 | OMP_CLAUSE_IF | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_UNTIED \
1824 | OMP_CLAUSE_FINAL | OMP_CLAUSE_MERGEABLE | OMP_CLAUSE_DEPEND)
1825 #define OMP_TARGET_CLAUSES \
1826 (OMP_CLAUSE_DEVICE | OMP_CLAUSE_MAP | OMP_CLAUSE_IF)
1827 #define OMP_TARGET_DATA_CLAUSES \
1828 (OMP_CLAUSE_DEVICE | OMP_CLAUSE_MAP | OMP_CLAUSE_IF)
1829 #define OMP_TARGET_UPDATE_CLAUSES \
1830 (OMP_CLAUSE_DEVICE | OMP_CLAUSE_IF | OMP_CLAUSE_TO | OMP_CLAUSE_FROM)
1831 #define OMP_TEAMS_CLAUSES \
1832 (OMP_CLAUSE_NUM_TEAMS | OMP_CLAUSE_THREAD_LIMIT | OMP_CLAUSE_DEFAULT \
1833 | OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_SHARED \
1834 | OMP_CLAUSE_REDUCTION)
1835 #define OMP_DISTRIBUTE_CLAUSES \
1836 (OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_COLLAPSE \
1837 | OMP_CLAUSE_DIST_SCHEDULE)
1841 match_omp (gfc_exec_op op
, unsigned int mask
)
1844 if (gfc_match_omp_clauses (&c
, mask
) != MATCH_YES
)
1847 new_st
.ext
.omp_clauses
= c
;
1853 gfc_match_omp_critical (void)
1855 char n
[GFC_MAX_SYMBOL_LEN
+1];
1857 if (gfc_match (" ( %n )", n
) != MATCH_YES
)
1859 if (gfc_match_omp_eos () != MATCH_YES
)
1861 gfc_error ("Unexpected junk after $OMP CRITICAL statement at %C");
1864 new_st
.op
= EXEC_OMP_CRITICAL
;
1865 new_st
.ext
.omp_name
= n
[0] ? xstrdup (n
) : NULL
;
1871 gfc_match_omp_distribute (void)
1873 return match_omp (EXEC_OMP_DISTRIBUTE
, OMP_DISTRIBUTE_CLAUSES
);
1878 gfc_match_omp_distribute_parallel_do (void)
1880 return match_omp (EXEC_OMP_DISTRIBUTE_PARALLEL_DO
,
1881 OMP_DISTRIBUTE_CLAUSES
| OMP_PARALLEL_CLAUSES
1887 gfc_match_omp_distribute_parallel_do_simd (void)
1889 return match_omp (EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD
,
1890 (OMP_DISTRIBUTE_CLAUSES
| OMP_PARALLEL_CLAUSES
1891 | OMP_DO_CLAUSES
| OMP_SIMD_CLAUSES
)
1892 & ~OMP_CLAUSE_ORDERED
);
1897 gfc_match_omp_distribute_simd (void)
1899 return match_omp (EXEC_OMP_DISTRIBUTE_SIMD
,
1900 OMP_DISTRIBUTE_CLAUSES
| OMP_SIMD_CLAUSES
);
1905 gfc_match_omp_do (void)
1907 return match_omp (EXEC_OMP_DO
, OMP_DO_CLAUSES
);
1912 gfc_match_omp_do_simd (void)
1914 return match_omp (EXEC_OMP_DO_SIMD
, ((OMP_DO_CLAUSES
| OMP_SIMD_CLAUSES
)
1915 & ~OMP_CLAUSE_ORDERED
));
1920 gfc_match_omp_flush (void)
1922 gfc_omp_namelist
*list
= NULL
;
1923 gfc_match_omp_variable_list (" (", &list
, true);
1924 if (gfc_match_omp_eos () != MATCH_YES
)
1926 gfc_error ("Unexpected junk after $OMP FLUSH statement at %C");
1927 gfc_free_omp_namelist (list
);
1930 new_st
.op
= EXEC_OMP_FLUSH
;
1931 new_st
.ext
.omp_namelist
= list
;
1937 gfc_match_omp_declare_simd (void)
1939 locus where
= gfc_current_locus
;
1940 gfc_symbol
*proc_name
;
1942 gfc_omp_declare_simd
*ods
;
1944 if (gfc_match (" ( %s ) ", &proc_name
) != MATCH_YES
)
1947 if (gfc_match_omp_clauses (&c
, OMP_DECLARE_SIMD_CLAUSES
, true,
1948 false) != MATCH_YES
)
1951 ods
= gfc_get_omp_declare_simd ();
1953 ods
->proc_name
= proc_name
;
1955 ods
->next
= gfc_current_ns
->omp_declare_simd
;
1956 gfc_current_ns
->omp_declare_simd
= ods
;
1962 match_udr_expr (gfc_symtree
*omp_sym1
, gfc_symtree
*omp_sym2
)
1965 locus old_loc
= gfc_current_locus
;
1966 char sname
[GFC_MAX_SYMBOL_LEN
+ 1];
1968 gfc_namespace
*ns
= gfc_current_ns
;
1969 gfc_expr
*lvalue
= NULL
, *rvalue
= NULL
;
1971 gfc_actual_arglist
*arglist
;
1973 m
= gfc_match (" %v =", &lvalue
);
1975 gfc_current_locus
= old_loc
;
1978 m
= gfc_match (" %e )", &rvalue
);
1981 ns
->code
= gfc_get_code (EXEC_ASSIGN
);
1982 ns
->code
->expr1
= lvalue
;
1983 ns
->code
->expr2
= rvalue
;
1984 ns
->code
->loc
= old_loc
;
1988 gfc_current_locus
= old_loc
;
1989 gfc_free_expr (lvalue
);
1992 m
= gfc_match (" %n", sname
);
1996 if (strcmp (sname
, omp_sym1
->name
) == 0
1997 || strcmp (sname
, omp_sym2
->name
) == 0)
2000 gfc_current_ns
= ns
->parent
;
2001 if (gfc_get_ha_sym_tree (sname
, &st
))
2005 if (sym
->attr
.flavor
!= FL_PROCEDURE
2006 && sym
->attr
.flavor
!= FL_UNKNOWN
)
2009 if (!sym
->attr
.generic
2010 && !sym
->attr
.subroutine
2011 && !sym
->attr
.function
)
2013 if (!(sym
->attr
.external
&& !sym
->attr
.referenced
))
2015 /* ...create a symbol in this scope... */
2016 if (sym
->ns
!= gfc_current_ns
2017 && gfc_get_sym_tree (sname
, NULL
, &st
, false) == 1)
2020 if (sym
!= st
->n
.sym
)
2024 /* ...and then to try to make the symbol into a subroutine. */
2025 if (!gfc_add_subroutine (&sym
->attr
, sym
->name
, NULL
))
2029 gfc_set_sym_referenced (sym
);
2030 gfc_gobble_whitespace ();
2031 if (gfc_peek_ascii_char () != '(')
2034 gfc_current_ns
= ns
;
2035 m
= gfc_match_actual_arglist (1, &arglist
);
2039 if (gfc_match_char (')') != MATCH_YES
)
2042 ns
->code
= gfc_get_code (EXEC_CALL
);
2043 ns
->code
->symtree
= st
;
2044 ns
->code
->ext
.actual
= arglist
;
2045 ns
->code
->loc
= old_loc
;
2050 gfc_omp_udr_predef (gfc_omp_reduction_op rop
, const char *name
,
2051 gfc_typespec
*ts
, const char **n
)
2053 if (!gfc_numeric_ts (ts
) && ts
->type
!= BT_LOGICAL
)
2058 case OMP_REDUCTION_PLUS
:
2059 case OMP_REDUCTION_MINUS
:
2060 case OMP_REDUCTION_TIMES
:
2061 return ts
->type
!= BT_LOGICAL
;
2062 case OMP_REDUCTION_AND
:
2063 case OMP_REDUCTION_OR
:
2064 case OMP_REDUCTION_EQV
:
2065 case OMP_REDUCTION_NEQV
:
2066 return ts
->type
== BT_LOGICAL
;
2067 case OMP_REDUCTION_USER
:
2068 if (name
[0] != '.' && (ts
->type
== BT_INTEGER
|| ts
->type
== BT_REAL
))
2072 gfc_find_symbol (name
, NULL
, 1, &sym
);
2075 if (sym
->attr
.intrinsic
)
2077 else if ((sym
->attr
.flavor
!= FL_UNKNOWN
2078 && sym
->attr
.flavor
!= FL_PROCEDURE
)
2079 || sym
->attr
.external
2080 || sym
->attr
.generic
2084 || sym
->attr
.subroutine
2085 || sym
->attr
.pointer
2087 || sym
->attr
.cray_pointer
2088 || sym
->attr
.cray_pointee
2089 || (sym
->attr
.proc
!= PROC_UNKNOWN
2090 && sym
->attr
.proc
!= PROC_INTRINSIC
)
2091 || sym
->attr
.if_source
!= IFSRC_UNKNOWN
2092 || sym
== sym
->ns
->proc_name
)
2100 && (strcmp (*n
, "max") == 0 || strcmp (*n
, "min") == 0))
2103 && ts
->type
== BT_INTEGER
2104 && (strcmp (*n
, "iand") == 0
2105 || strcmp (*n
, "ior") == 0
2106 || strcmp (*n
, "ieor") == 0))
2117 gfc_omp_udr_find (gfc_symtree
*st
, gfc_typespec
*ts
)
2119 gfc_omp_udr
*omp_udr
;
2124 for (omp_udr
= st
->n
.omp_udr
; omp_udr
; omp_udr
= omp_udr
->next
)
2125 if (omp_udr
->ts
.type
== ts
->type
2126 || ((omp_udr
->ts
.type
== BT_DERIVED
|| omp_udr
->ts
.type
== BT_CLASS
)
2127 && (ts
->type
== BT_DERIVED
|| ts
->type
== BT_CLASS
)))
2129 if (omp_udr
->ts
.type
== BT_DERIVED
|| omp_udr
->ts
.type
== BT_CLASS
)
2131 if (strcmp (omp_udr
->ts
.u
.derived
->name
, ts
->u
.derived
->name
) == 0)
2134 else if (omp_udr
->ts
.kind
== ts
->kind
)
2136 if (omp_udr
->ts
.type
== BT_CHARACTER
)
2138 if (omp_udr
->ts
.u
.cl
->length
== NULL
2139 || ts
->u
.cl
->length
== NULL
)
2141 if (omp_udr
->ts
.u
.cl
->length
->expr_type
!= EXPR_CONSTANT
)
2143 if (ts
->u
.cl
->length
->expr_type
!= EXPR_CONSTANT
)
2145 if (omp_udr
->ts
.u
.cl
->length
->ts
.type
!= BT_INTEGER
)
2147 if (ts
->u
.cl
->length
->ts
.type
!= BT_INTEGER
)
2149 if (gfc_compare_expr (omp_udr
->ts
.u
.cl
->length
,
2150 ts
->u
.cl
->length
, INTRINSIC_EQ
) != 0)
2160 gfc_match_omp_declare_reduction (void)
2163 gfc_intrinsic_op op
;
2164 char name
[GFC_MAX_SYMBOL_LEN
+ 3];
2165 auto_vec
<gfc_typespec
, 5> tss
;
2169 locus where
= gfc_current_locus
;
2170 locus end_loc
= gfc_current_locus
;
2171 bool end_loc_set
= false;
2172 gfc_omp_reduction_op rop
= OMP_REDUCTION_NONE
;
2174 if (gfc_match_char ('(') != MATCH_YES
)
2177 m
= gfc_match (" %o : ", &op
);
2178 if (m
== MATCH_ERROR
)
2182 snprintf (name
, sizeof name
, "operator %s", gfc_op2string (op
));
2183 rop
= (gfc_omp_reduction_op
) op
;
2187 m
= gfc_match_defined_op_name (name
+ 1, 1);
2188 if (m
== MATCH_ERROR
)
2194 if (gfc_match (" : ") != MATCH_YES
)
2199 if (gfc_match (" %n : ", name
) != MATCH_YES
)
2202 rop
= OMP_REDUCTION_USER
;
2205 m
= gfc_match_type_spec (&ts
);
2208 /* Treat len=: the same as len=*. */
2209 if (ts
.type
== BT_CHARACTER
)
2210 ts
.deferred
= false;
2213 while (gfc_match_char (',') == MATCH_YES
)
2215 m
= gfc_match_type_spec (&ts
);
2220 if (gfc_match_char (':') != MATCH_YES
)
2223 st
= gfc_find_symtree (gfc_current_ns
->omp_udr_root
, name
);
2224 for (i
= 0; i
< tss
.length (); i
++)
2226 gfc_symtree
*omp_out
, *omp_in
;
2227 gfc_symtree
*omp_priv
= NULL
, *omp_orig
= NULL
;
2228 gfc_namespace
*combiner_ns
, *initializer_ns
= NULL
;
2229 gfc_omp_udr
*prev_udr
, *omp_udr
;
2230 const char *predef_name
= NULL
;
2232 omp_udr
= gfc_get_omp_udr ();
2233 omp_udr
->name
= gfc_get_string (name
);
2235 omp_udr
->ts
= tss
[i
];
2236 omp_udr
->where
= where
;
2238 gfc_current_ns
= combiner_ns
= gfc_get_namespace (gfc_current_ns
, 1);
2239 combiner_ns
->proc_name
= combiner_ns
->parent
->proc_name
;
2241 gfc_get_sym_tree ("omp_out", combiner_ns
, &omp_out
, false);
2242 gfc_get_sym_tree ("omp_in", combiner_ns
, &omp_in
, false);
2243 combiner_ns
->omp_udr_ns
= 1;
2244 omp_out
->n
.sym
->ts
= tss
[i
];
2245 omp_in
->n
.sym
->ts
= tss
[i
];
2246 omp_out
->n
.sym
->attr
.omp_udr_artificial_var
= 1;
2247 omp_in
->n
.sym
->attr
.omp_udr_artificial_var
= 1;
2248 omp_out
->n
.sym
->attr
.flavor
= FL_VARIABLE
;
2249 omp_in
->n
.sym
->attr
.flavor
= FL_VARIABLE
;
2250 gfc_commit_symbols ();
2251 omp_udr
->combiner_ns
= combiner_ns
;
2252 omp_udr
->omp_out
= omp_out
->n
.sym
;
2253 omp_udr
->omp_in
= omp_in
->n
.sym
;
2255 locus old_loc
= gfc_current_locus
;
2257 if (!match_udr_expr (omp_out
, omp_in
))
2260 gfc_current_locus
= old_loc
;
2261 gfc_current_ns
= combiner_ns
->parent
;
2262 gfc_undo_symbols ();
2263 gfc_free_omp_udr (omp_udr
);
2267 if (gfc_match (" initializer ( ") == MATCH_YES
)
2269 gfc_current_ns
= combiner_ns
->parent
;
2270 initializer_ns
= gfc_get_namespace (gfc_current_ns
, 1);
2271 gfc_current_ns
= initializer_ns
;
2272 initializer_ns
->proc_name
= initializer_ns
->parent
->proc_name
;
2274 gfc_get_sym_tree ("omp_priv", initializer_ns
, &omp_priv
, false);
2275 gfc_get_sym_tree ("omp_orig", initializer_ns
, &omp_orig
, false);
2276 initializer_ns
->omp_udr_ns
= 1;
2277 omp_priv
->n
.sym
->ts
= tss
[i
];
2278 omp_orig
->n
.sym
->ts
= tss
[i
];
2279 omp_priv
->n
.sym
->attr
.omp_udr_artificial_var
= 1;
2280 omp_orig
->n
.sym
->attr
.omp_udr_artificial_var
= 1;
2281 omp_priv
->n
.sym
->attr
.flavor
= FL_VARIABLE
;
2282 omp_orig
->n
.sym
->attr
.flavor
= FL_VARIABLE
;
2283 gfc_commit_symbols ();
2284 omp_udr
->initializer_ns
= initializer_ns
;
2285 omp_udr
->omp_priv
= omp_priv
->n
.sym
;
2286 omp_udr
->omp_orig
= omp_orig
->n
.sym
;
2288 if (!match_udr_expr (omp_priv
, omp_orig
))
2292 gfc_current_ns
= combiner_ns
->parent
;
2296 end_loc
= gfc_current_locus
;
2298 gfc_current_locus
= old_loc
;
2300 prev_udr
= gfc_omp_udr_find (st
, &tss
[i
]);
2301 if (gfc_omp_udr_predef (rop
, name
, &tss
[i
], &predef_name
)
2302 /* Don't error on !$omp declare reduction (min : integer : ...)
2303 just yet, there could be integer :: min afterwards,
2304 making it valid. When the UDR is resolved, we'll get
2306 && (rop
!= OMP_REDUCTION_USER
|| name
[0] == '.'))
2309 gfc_error_now ("Redefinition of predefined %s "
2310 "!$OMP DECLARE REDUCTION at %L",
2311 predef_name
, &where
);
2313 gfc_error_now ("Redefinition of predefined "
2314 "!$OMP DECLARE REDUCTION at %L", &where
);
2318 gfc_error_now ("Redefinition of !$OMP DECLARE REDUCTION at %L",
2320 gfc_error_now ("Previous !$OMP DECLARE REDUCTION at %L",
2325 omp_udr
->next
= st
->n
.omp_udr
;
2326 st
->n
.omp_udr
= omp_udr
;
2330 st
= gfc_new_symtree (&gfc_current_ns
->omp_udr_root
, name
);
2331 st
->n
.omp_udr
= omp_udr
;
2337 gfc_current_locus
= end_loc
;
2338 if (gfc_match_omp_eos () != MATCH_YES
)
2340 gfc_error ("Unexpected junk after !$OMP DECLARE REDUCTION at %C");
2341 gfc_current_locus
= where
;
2353 gfc_match_omp_declare_target (void)
2356 char n
[GFC_MAX_SYMBOL_LEN
+1];
2361 old_loc
= gfc_current_locus
;
2363 m
= gfc_match (" (");
2365 if (gfc_current_ns
->proc_name
2366 && gfc_current_ns
->proc_name
->attr
.if_source
== IFSRC_IFBODY
2369 gfc_error ("Only the !$OMP DECLARE TARGET form without "
2370 "list is allowed in interface block at %C");
2375 && gfc_current_ns
->proc_name
2376 && gfc_match_omp_eos () == MATCH_YES
)
2378 if (!gfc_add_omp_declare_target (&gfc_current_ns
->proc_name
->attr
,
2379 gfc_current_ns
->proc_name
->name
,
2390 m
= gfc_match_symbol (&sym
, 0);
2394 if (sym
->attr
.in_common
)
2395 gfc_error_now ("OMP DECLARE TARGET on a variable at %C is an "
2396 "element of a COMMON block");
2397 else if (!gfc_add_omp_declare_target (&sym
->attr
, sym
->name
,
2407 m
= gfc_match (" / %n /", n
);
2408 if (m
== MATCH_ERROR
)
2410 if (m
== MATCH_NO
|| n
[0] == '\0')
2413 st
= gfc_find_symtree (gfc_current_ns
->common_root
, n
);
2416 gfc_error ("COMMON block /%s/ not found at %C", n
);
2419 st
->n
.common
->omp_declare_target
= 1;
2420 for (sym
= st
->n
.common
->head
; sym
; sym
= sym
->common_next
)
2421 if (!gfc_add_omp_declare_target (&sym
->attr
, sym
->name
,
2426 if (gfc_match_char (')') == MATCH_YES
)
2428 if (gfc_match_char (',') != MATCH_YES
)
2432 if (gfc_match_omp_eos () != MATCH_YES
)
2434 gfc_error ("Unexpected junk after !$OMP DECLARE TARGET at %C");
2440 gfc_error ("Syntax error in !$OMP DECLARE TARGET list at %C");
2443 gfc_current_locus
= old_loc
;
2449 gfc_match_omp_threadprivate (void)
2452 char n
[GFC_MAX_SYMBOL_LEN
+1];
2457 old_loc
= gfc_current_locus
;
2459 m
= gfc_match (" (");
2465 m
= gfc_match_symbol (&sym
, 0);
2469 if (sym
->attr
.in_common
)
2470 gfc_error_now ("Threadprivate variable at %C is an element of "
2472 else if (!gfc_add_threadprivate (&sym
->attr
, sym
->name
, &sym
->declared_at
))
2481 m
= gfc_match (" / %n /", n
);
2482 if (m
== MATCH_ERROR
)
2484 if (m
== MATCH_NO
|| n
[0] == '\0')
2487 st
= gfc_find_symtree (gfc_current_ns
->common_root
, n
);
2490 gfc_error ("COMMON block /%s/ not found at %C", n
);
2493 st
->n
.common
->threadprivate
= 1;
2494 for (sym
= st
->n
.common
->head
; sym
; sym
= sym
->common_next
)
2495 if (!gfc_add_threadprivate (&sym
->attr
, sym
->name
, &sym
->declared_at
))
2499 if (gfc_match_char (')') == MATCH_YES
)
2501 if (gfc_match_char (',') != MATCH_YES
)
2505 if (gfc_match_omp_eos () != MATCH_YES
)
2507 gfc_error ("Unexpected junk after OMP THREADPRIVATE at %C");
2514 gfc_error ("Syntax error in !$OMP THREADPRIVATE list at %C");
2517 gfc_current_locus
= old_loc
;
2523 gfc_match_omp_parallel (void)
2525 return match_omp (EXEC_OMP_PARALLEL
, OMP_PARALLEL_CLAUSES
);
2530 gfc_match_omp_parallel_do (void)
2532 return match_omp (EXEC_OMP_PARALLEL_DO
,
2533 OMP_PARALLEL_CLAUSES
| OMP_DO_CLAUSES
);
2538 gfc_match_omp_parallel_do_simd (void)
2540 return match_omp (EXEC_OMP_PARALLEL_DO_SIMD
,
2541 (OMP_PARALLEL_CLAUSES
| OMP_DO_CLAUSES
| OMP_SIMD_CLAUSES
)
2542 & ~OMP_CLAUSE_ORDERED
);
2547 gfc_match_omp_parallel_sections (void)
2549 return match_omp (EXEC_OMP_PARALLEL_SECTIONS
,
2550 OMP_PARALLEL_CLAUSES
| OMP_SECTIONS_CLAUSES
);
2555 gfc_match_omp_parallel_workshare (void)
2557 return match_omp (EXEC_OMP_PARALLEL_WORKSHARE
, OMP_PARALLEL_CLAUSES
);
2562 gfc_match_omp_sections (void)
2564 return match_omp (EXEC_OMP_SECTIONS
, OMP_SECTIONS_CLAUSES
);
2569 gfc_match_omp_simd (void)
2571 return match_omp (EXEC_OMP_SIMD
, OMP_SIMD_CLAUSES
);
2576 gfc_match_omp_single (void)
2578 return match_omp (EXEC_OMP_SINGLE
,
2579 OMP_CLAUSE_PRIVATE
| OMP_CLAUSE_FIRSTPRIVATE
);
2584 gfc_match_omp_task (void)
2586 return match_omp (EXEC_OMP_TASK
, OMP_TASK_CLAUSES
);
2591 gfc_match_omp_taskwait (void)
2593 if (gfc_match_omp_eos () != MATCH_YES
)
2595 gfc_error ("Unexpected junk after TASKWAIT clause at %C");
2598 new_st
.op
= EXEC_OMP_TASKWAIT
;
2599 new_st
.ext
.omp_clauses
= NULL
;
2605 gfc_match_omp_taskyield (void)
2607 if (gfc_match_omp_eos () != MATCH_YES
)
2609 gfc_error ("Unexpected junk after TASKYIELD clause at %C");
2612 new_st
.op
= EXEC_OMP_TASKYIELD
;
2613 new_st
.ext
.omp_clauses
= NULL
;
2619 gfc_match_omp_target (void)
2621 return match_omp (EXEC_OMP_TARGET
, OMP_TARGET_CLAUSES
);
2626 gfc_match_omp_target_data (void)
2628 return match_omp (EXEC_OMP_TARGET_DATA
, OMP_TARGET_DATA_CLAUSES
);
2633 gfc_match_omp_target_teams (void)
2635 return match_omp (EXEC_OMP_TARGET_TEAMS
,
2636 OMP_TARGET_CLAUSES
| OMP_TEAMS_CLAUSES
);
2641 gfc_match_omp_target_teams_distribute (void)
2643 return match_omp (EXEC_OMP_TARGET_TEAMS_DISTRIBUTE
,
2644 OMP_TARGET_CLAUSES
| OMP_TEAMS_CLAUSES
2645 | OMP_DISTRIBUTE_CLAUSES
);
2650 gfc_match_omp_target_teams_distribute_parallel_do (void)
2652 return match_omp (EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO
,
2653 OMP_TARGET_CLAUSES
| OMP_TEAMS_CLAUSES
2654 | OMP_DISTRIBUTE_CLAUSES
| OMP_PARALLEL_CLAUSES
2660 gfc_match_omp_target_teams_distribute_parallel_do_simd (void)
2662 return match_omp (EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
,
2663 (OMP_TARGET_CLAUSES
| OMP_TEAMS_CLAUSES
2664 | OMP_DISTRIBUTE_CLAUSES
| OMP_PARALLEL_CLAUSES
2665 | OMP_DO_CLAUSES
| OMP_SIMD_CLAUSES
)
2666 & ~OMP_CLAUSE_ORDERED
);
2671 gfc_match_omp_target_teams_distribute_simd (void)
2673 return match_omp (EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD
,
2674 OMP_TARGET_CLAUSES
| OMP_TEAMS_CLAUSES
2675 | OMP_DISTRIBUTE_CLAUSES
| OMP_SIMD_CLAUSES
);
2680 gfc_match_omp_target_update (void)
2682 return match_omp (EXEC_OMP_TARGET_UPDATE
, OMP_TARGET_UPDATE_CLAUSES
);
2687 gfc_match_omp_teams (void)
2689 return match_omp (EXEC_OMP_TEAMS
, OMP_TEAMS_CLAUSES
);
2694 gfc_match_omp_teams_distribute (void)
2696 return match_omp (EXEC_OMP_TEAMS_DISTRIBUTE
,
2697 OMP_TEAMS_CLAUSES
| OMP_DISTRIBUTE_CLAUSES
);
2702 gfc_match_omp_teams_distribute_parallel_do (void)
2704 return match_omp (EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO
,
2705 OMP_TEAMS_CLAUSES
| OMP_DISTRIBUTE_CLAUSES
2706 | OMP_PARALLEL_CLAUSES
| OMP_DO_CLAUSES
);
2711 gfc_match_omp_teams_distribute_parallel_do_simd (void)
2713 return match_omp (EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
,
2714 (OMP_TEAMS_CLAUSES
| OMP_DISTRIBUTE_CLAUSES
2715 | OMP_PARALLEL_CLAUSES
| OMP_DO_CLAUSES
2716 | OMP_SIMD_CLAUSES
) & ~OMP_CLAUSE_ORDERED
);
2721 gfc_match_omp_teams_distribute_simd (void)
2723 return match_omp (EXEC_OMP_TEAMS_DISTRIBUTE_SIMD
,
2724 OMP_TEAMS_CLAUSES
| OMP_DISTRIBUTE_CLAUSES
2725 | OMP_SIMD_CLAUSES
);
2730 gfc_match_omp_workshare (void)
2732 if (gfc_match_omp_eos () != MATCH_YES
)
2734 gfc_error ("Unexpected junk after $OMP WORKSHARE statement at %C");
2737 new_st
.op
= EXEC_OMP_WORKSHARE
;
2738 new_st
.ext
.omp_clauses
= gfc_get_omp_clauses ();
2744 gfc_match_omp_master (void)
2746 if (gfc_match_omp_eos () != MATCH_YES
)
2748 gfc_error ("Unexpected junk after $OMP MASTER statement at %C");
2751 new_st
.op
= EXEC_OMP_MASTER
;
2752 new_st
.ext
.omp_clauses
= NULL
;
2758 gfc_match_omp_ordered (void)
2760 if (gfc_match_omp_eos () != MATCH_YES
)
2762 gfc_error ("Unexpected junk after $OMP ORDERED statement at %C");
2765 new_st
.op
= EXEC_OMP_ORDERED
;
2766 new_st
.ext
.omp_clauses
= NULL
;
2772 gfc_match_omp_oacc_atomic (bool omp_p
)
2774 gfc_omp_atomic_op op
= GFC_OMP_ATOMIC_UPDATE
;
2776 if (gfc_match ("% seq_cst") == MATCH_YES
)
2778 locus old_loc
= gfc_current_locus
;
2779 if (seq_cst
&& gfc_match_char (',') == MATCH_YES
)
2782 || gfc_match_space () == MATCH_YES
)
2784 gfc_gobble_whitespace ();
2785 if (gfc_match ("update") == MATCH_YES
)
2786 op
= GFC_OMP_ATOMIC_UPDATE
;
2787 else if (gfc_match ("read") == MATCH_YES
)
2788 op
= GFC_OMP_ATOMIC_READ
;
2789 else if (gfc_match ("write") == MATCH_YES
)
2790 op
= GFC_OMP_ATOMIC_WRITE
;
2791 else if (gfc_match ("capture") == MATCH_YES
)
2792 op
= GFC_OMP_ATOMIC_CAPTURE
;
2796 gfc_current_locus
= old_loc
;
2800 && (gfc_match (", seq_cst") == MATCH_YES
2801 || gfc_match ("% seq_cst") == MATCH_YES
))
2805 if (gfc_match_omp_eos () != MATCH_YES
)
2807 gfc_error ("Unexpected junk after $OMP ATOMIC statement at %C");
2810 new_st
.op
= (omp_p
? EXEC_OMP_ATOMIC
: EXEC_OACC_ATOMIC
);
2812 op
= (gfc_omp_atomic_op
) (op
| GFC_OMP_ATOMIC_SEQ_CST
);
2813 new_st
.ext
.omp_atomic
= op
;
2818 gfc_match_oacc_atomic (void)
2820 return gfc_match_omp_oacc_atomic (false);
2824 gfc_match_omp_atomic (void)
2826 return gfc_match_omp_oacc_atomic (true);
2830 gfc_match_omp_barrier (void)
2832 if (gfc_match_omp_eos () != MATCH_YES
)
2834 gfc_error ("Unexpected junk after $OMP BARRIER statement at %C");
2837 new_st
.op
= EXEC_OMP_BARRIER
;
2838 new_st
.ext
.omp_clauses
= NULL
;
2844 gfc_match_omp_taskgroup (void)
2846 if (gfc_match_omp_eos () != MATCH_YES
)
2848 gfc_error ("Unexpected junk after $OMP TASKGROUP statement at %C");
2851 new_st
.op
= EXEC_OMP_TASKGROUP
;
2856 static enum gfc_omp_cancel_kind
2857 gfc_match_omp_cancel_kind (void)
2859 if (gfc_match_space () != MATCH_YES
)
2860 return OMP_CANCEL_UNKNOWN
;
2861 if (gfc_match ("parallel") == MATCH_YES
)
2862 return OMP_CANCEL_PARALLEL
;
2863 if (gfc_match ("sections") == MATCH_YES
)
2864 return OMP_CANCEL_SECTIONS
;
2865 if (gfc_match ("do") == MATCH_YES
)
2866 return OMP_CANCEL_DO
;
2867 if (gfc_match ("taskgroup") == MATCH_YES
)
2868 return OMP_CANCEL_TASKGROUP
;
2869 return OMP_CANCEL_UNKNOWN
;
2874 gfc_match_omp_cancel (void)
2877 enum gfc_omp_cancel_kind kind
= gfc_match_omp_cancel_kind ();
2878 if (kind
== OMP_CANCEL_UNKNOWN
)
2880 if (gfc_match_omp_clauses (&c
, OMP_CLAUSE_IF
, false) != MATCH_YES
)
2883 new_st
.op
= EXEC_OMP_CANCEL
;
2884 new_st
.ext
.omp_clauses
= c
;
2890 gfc_match_omp_cancellation_point (void)
2893 enum gfc_omp_cancel_kind kind
= gfc_match_omp_cancel_kind ();
2894 if (kind
== OMP_CANCEL_UNKNOWN
)
2896 if (gfc_match_omp_eos () != MATCH_YES
)
2898 gfc_error ("Unexpected junk after $OMP CANCELLATION POINT statement "
2902 c
= gfc_get_omp_clauses ();
2904 new_st
.op
= EXEC_OMP_CANCELLATION_POINT
;
2905 new_st
.ext
.omp_clauses
= c
;
2911 gfc_match_omp_end_nowait (void)
2913 bool nowait
= false;
2914 if (gfc_match ("% nowait") == MATCH_YES
)
2916 if (gfc_match_omp_eos () != MATCH_YES
)
2918 gfc_error ("Unexpected junk after NOWAIT clause at %C");
2921 new_st
.op
= EXEC_OMP_END_NOWAIT
;
2922 new_st
.ext
.omp_bool
= nowait
;
2928 gfc_match_omp_end_single (void)
2931 if (gfc_match ("% nowait") == MATCH_YES
)
2933 new_st
.op
= EXEC_OMP_END_NOWAIT
;
2934 new_st
.ext
.omp_bool
= true;
2937 if (gfc_match_omp_clauses (&c
, OMP_CLAUSE_COPYPRIVATE
) != MATCH_YES
)
2939 new_st
.op
= EXEC_OMP_END_SINGLE
;
2940 new_st
.ext
.omp_clauses
= c
;
2946 oacc_is_loop (gfc_code
*code
)
2948 return code
->op
== EXEC_OACC_PARALLEL_LOOP
2949 || code
->op
== EXEC_OACC_KERNELS_LOOP
2950 || code
->op
== EXEC_OACC_LOOP
;
2954 resolve_oacc_scalar_int_expr (gfc_expr
*expr
, const char *clause
)
2956 if (!gfc_resolve_expr (expr
)
2957 || expr
->ts
.type
!= BT_INTEGER
|| expr
->rank
!= 0)
2958 gfc_error ("%s clause at %L requires a scalar INTEGER expression",
2959 clause
, &expr
->where
);
2964 resolve_oacc_positive_int_expr (gfc_expr
*expr
, const char *clause
)
2966 resolve_oacc_scalar_int_expr (expr
, clause
);
2967 if (expr
->expr_type
== EXPR_CONSTANT
&& expr
->ts
.type
== BT_INTEGER
2968 && mpz_sgn(expr
->value
.integer
) <= 0)
2969 gfc_warning (0, "INTEGER expression of %s clause at %L must be positive",
2970 clause
, &expr
->where
);
2973 /* Emits error when symbol is pointer, cray pointer or cray pointee
2974 of derived of polymorphic type. */
2977 check_symbol_not_pointer (gfc_symbol
*sym
, locus loc
, const char *name
)
2979 if (sym
->ts
.type
== BT_DERIVED
&& sym
->attr
.pointer
)
2980 gfc_error ("POINTER object %qs of derived type in %s clause at %L",
2981 sym
->name
, name
, &loc
);
2982 if (sym
->ts
.type
== BT_DERIVED
&& sym
->attr
.cray_pointer
)
2983 gfc_error ("Cray pointer object of derived type %qs in %s clause at %L",
2984 sym
->name
, name
, &loc
);
2985 if (sym
->ts
.type
== BT_DERIVED
&& sym
->attr
.cray_pointee
)
2986 gfc_error ("Cray pointee object of derived type %qs in %s clause at %L",
2987 sym
->name
, name
, &loc
);
2989 if ((sym
->ts
.type
== BT_ASSUMED
&& sym
->attr
.pointer
)
2990 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
2991 && CLASS_DATA (sym
)->attr
.pointer
))
2992 gfc_error ("POINTER object %qs of polymorphic type in %s clause at %L",
2993 sym
->name
, name
, &loc
);
2994 if ((sym
->ts
.type
== BT_ASSUMED
&& sym
->attr
.cray_pointer
)
2995 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
2996 && CLASS_DATA (sym
)->attr
.cray_pointer
))
2997 gfc_error ("Cray pointer object of polymorphic type %qs in %s clause at %L",
2998 sym
->name
, name
, &loc
);
2999 if ((sym
->ts
.type
== BT_ASSUMED
&& sym
->attr
.cray_pointee
)
3000 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
3001 && CLASS_DATA (sym
)->attr
.cray_pointee
))
3002 gfc_error ("Cray pointee object of polymorphic type %qs in %s clause at %L",
3003 sym
->name
, name
, &loc
);
3006 /* Emits error when symbol represents assumed size/rank array. */
3009 check_array_not_assumed (gfc_symbol
*sym
, locus loc
, const char *name
)
3011 if (sym
->as
&& sym
->as
->type
== AS_ASSUMED_SIZE
)
3012 gfc_error ("Assumed size array %qs in %s clause at %L",
3013 sym
->name
, name
, &loc
);
3014 if (sym
->as
&& sym
->as
->type
== AS_ASSUMED_RANK
)
3015 gfc_error ("Assumed rank array %qs in %s clause at %L",
3016 sym
->name
, name
, &loc
);
3017 if (sym
->as
&& sym
->as
->type
== AS_DEFERRED
&& sym
->attr
.pointer
3018 && !sym
->attr
.contiguous
)
3019 gfc_error ("Noncontiguous deferred shape array %qs in %s clause at %L",
3020 sym
->name
, name
, &loc
);
3024 resolve_oacc_data_clauses (gfc_symbol
*sym
, locus loc
, const char *name
)
3026 if (sym
->ts
.type
== BT_DERIVED
&& sym
->attr
.allocatable
)
3027 gfc_error ("ALLOCATABLE object %qs of derived type in %s clause at %L",
3028 sym
->name
, name
, &loc
);
3029 if ((sym
->ts
.type
== BT_ASSUMED
&& sym
->attr
.allocatable
)
3030 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
3031 && CLASS_DATA (sym
)->attr
.allocatable
))
3032 gfc_error ("ALLOCATABLE object %qs of polymorphic type "
3033 "in %s clause at %L", sym
->name
, name
, &loc
);
3034 check_symbol_not_pointer (sym
, loc
, name
);
3035 check_array_not_assumed (sym
, loc
, name
);
3039 resolve_oacc_deviceptr_clause (gfc_symbol
*sym
, locus loc
, const char *name
)
3041 if (sym
->attr
.pointer
3042 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
3043 && CLASS_DATA (sym
)->attr
.class_pointer
))
3044 gfc_error ("POINTER object %qs in %s clause at %L",
3045 sym
->name
, name
, &loc
);
3046 if (sym
->attr
.cray_pointer
3047 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
3048 && CLASS_DATA (sym
)->attr
.cray_pointer
))
3049 gfc_error ("Cray pointer object %qs in %s clause at %L",
3050 sym
->name
, name
, &loc
);
3051 if (sym
->attr
.cray_pointee
3052 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
3053 && CLASS_DATA (sym
)->attr
.cray_pointee
))
3054 gfc_error ("Cray pointee object %qs in %s clause at %L",
3055 sym
->name
, name
, &loc
);
3056 if (sym
->attr
.allocatable
3057 || (sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (sym
)
3058 && CLASS_DATA (sym
)->attr
.allocatable
))
3059 gfc_error ("ALLOCATABLE object %qs in %s clause at %L",
3060 sym
->name
, name
, &loc
);
3061 if (sym
->attr
.value
)
3062 gfc_error ("VALUE object %qs in %s clause at %L",
3063 sym
->name
, name
, &loc
);
3064 check_array_not_assumed (sym
, loc
, name
);
3068 struct resolve_omp_udr_callback_data
3070 gfc_symbol
*sym1
, *sym2
;
3075 resolve_omp_udr_callback (gfc_expr
**e
, int *, void *data
)
3077 struct resolve_omp_udr_callback_data
*rcd
3078 = (struct resolve_omp_udr_callback_data
*) data
;
3079 if ((*e
)->expr_type
== EXPR_VARIABLE
3080 && ((*e
)->symtree
->n
.sym
== rcd
->sym1
3081 || (*e
)->symtree
->n
.sym
== rcd
->sym2
))
3083 gfc_ref
*ref
= gfc_get_ref ();
3084 ref
->type
= REF_ARRAY
;
3085 ref
->u
.ar
.where
= (*e
)->where
;
3086 ref
->u
.ar
.as
= (*e
)->symtree
->n
.sym
->as
;
3087 ref
->u
.ar
.type
= AR_FULL
;
3088 ref
->u
.ar
.dimen
= 0;
3089 ref
->next
= (*e
)->ref
;
3097 resolve_omp_udr_callback2 (gfc_expr
**e
, int *, void *)
3099 if ((*e
)->expr_type
== EXPR_FUNCTION
3100 && (*e
)->value
.function
.isym
== NULL
)
3102 gfc_symbol
*sym
= (*e
)->symtree
->n
.sym
;
3103 if (!sym
->attr
.intrinsic
3104 && sym
->attr
.if_source
== IFSRC_UNKNOWN
)
3105 gfc_error ("Implicitly declared function %s used in "
3106 "!$OMP DECLARE REDUCTION at %L ", sym
->name
, &(*e
)->where
);
3113 resolve_omp_udr_clause (gfc_omp_namelist
*n
, gfc_namespace
*ns
,
3114 gfc_symbol
*sym1
, gfc_symbol
*sym2
)
3117 gfc_symbol sym1_copy
, sym2_copy
;
3119 if (ns
->code
->op
== EXEC_ASSIGN
)
3121 copy
= gfc_get_code (EXEC_ASSIGN
);
3122 copy
->expr1
= gfc_copy_expr (ns
->code
->expr1
);
3123 copy
->expr2
= gfc_copy_expr (ns
->code
->expr2
);
3127 copy
= gfc_get_code (EXEC_CALL
);
3128 copy
->symtree
= ns
->code
->symtree
;
3129 copy
->ext
.actual
= gfc_copy_actual_arglist (ns
->code
->ext
.actual
);
3131 copy
->loc
= ns
->code
->loc
;
3136 sym1
->name
= sym1_copy
.name
;
3137 sym2
->name
= sym2_copy
.name
;
3138 ns
->proc_name
= ns
->parent
->proc_name
;
3139 if (n
->sym
->attr
.dimension
)
3141 struct resolve_omp_udr_callback_data rcd
;
3144 gfc_code_walker (©
, gfc_dummy_code_callback
,
3145 resolve_omp_udr_callback
, &rcd
);
3147 gfc_resolve_code (copy
, gfc_current_ns
);
3148 if (copy
->op
== EXEC_CALL
&& copy
->resolved_isym
== NULL
)
3150 gfc_symbol
*sym
= copy
->resolved_sym
;
3152 && !sym
->attr
.intrinsic
3153 && sym
->attr
.if_source
== IFSRC_UNKNOWN
)
3154 gfc_error ("Implicitly declared subroutine %s used in "
3155 "!$OMP DECLARE REDUCTION at %L ", sym
->name
,
3158 gfc_code_walker (©
, gfc_dummy_code_callback
,
3159 resolve_omp_udr_callback2
, NULL
);
3165 /* OpenMP directive resolving routines. */
3168 resolve_omp_clauses (gfc_code
*code
, gfc_omp_clauses
*omp_clauses
,
3169 gfc_namespace
*ns
, bool openacc
= false)
3171 gfc_omp_namelist
*n
;
3174 static const char *clause_names
[]
3175 = { "PRIVATE", "FIRSTPRIVATE", "LASTPRIVATE", "COPYPRIVATE", "SHARED",
3176 "COPYIN", "UNIFORM", "ALIGNED", "LINEAR", "DEPEND", "MAP",
3177 "TO", "FROM", "REDUCTION", "DEVICE_RESIDENT", "LINK", "USE_DEVICE",
3180 if (omp_clauses
== NULL
)
3183 if (omp_clauses
->if_expr
)
3185 gfc_expr
*expr
= omp_clauses
->if_expr
;
3186 if (!gfc_resolve_expr (expr
)
3187 || expr
->ts
.type
!= BT_LOGICAL
|| expr
->rank
!= 0)
3188 gfc_error ("IF clause at %L requires a scalar LOGICAL expression",
3191 if (omp_clauses
->final_expr
)
3193 gfc_expr
*expr
= omp_clauses
->final_expr
;
3194 if (!gfc_resolve_expr (expr
)
3195 || expr
->ts
.type
!= BT_LOGICAL
|| expr
->rank
!= 0)
3196 gfc_error ("FINAL clause at %L requires a scalar LOGICAL expression",
3199 if (omp_clauses
->num_threads
)
3201 gfc_expr
*expr
= omp_clauses
->num_threads
;
3202 if (!gfc_resolve_expr (expr
)
3203 || expr
->ts
.type
!= BT_INTEGER
|| expr
->rank
!= 0)
3204 gfc_error ("NUM_THREADS clause at %L requires a scalar "
3205 "INTEGER expression", &expr
->where
);
3207 if (omp_clauses
->chunk_size
)
3209 gfc_expr
*expr
= omp_clauses
->chunk_size
;
3210 if (!gfc_resolve_expr (expr
)
3211 || expr
->ts
.type
!= BT_INTEGER
|| expr
->rank
!= 0)
3212 gfc_error ("SCHEDULE clause's chunk_size at %L requires "
3213 "a scalar INTEGER expression", &expr
->where
);
3214 else if (expr
->expr_type
== EXPR_CONSTANT
3215 && expr
->ts
.type
== BT_INTEGER
3216 && mpz_sgn (expr
->value
.integer
) <= 0)
3217 gfc_warning (0, "INTEGER expression of SCHEDULE clause's chunk_size "
3218 "at %L must be positive", &expr
->where
);
3221 /* Check that no symbol appears on multiple clauses, except that
3222 a symbol can appear on both firstprivate and lastprivate. */
3223 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
3224 for (n
= omp_clauses
->lists
[list
]; n
; n
= n
->next
)
3227 if (n
->sym
->attr
.flavor
== FL_VARIABLE
3228 || n
->sym
->attr
.proc_pointer
3229 || (!code
&& (!n
->sym
->attr
.dummy
|| n
->sym
->ns
!= ns
)))
3231 if (!code
&& (!n
->sym
->attr
.dummy
|| n
->sym
->ns
!= ns
))
3232 gfc_error ("Variable %qs is not a dummy argument at %L",
3233 n
->sym
->name
, &n
->where
);
3236 if (n
->sym
->attr
.flavor
== FL_PROCEDURE
3237 && n
->sym
->result
== n
->sym
3238 && n
->sym
->attr
.function
)
3240 if (gfc_current_ns
->proc_name
== n
->sym
3241 || (gfc_current_ns
->parent
3242 && gfc_current_ns
->parent
->proc_name
== n
->sym
))
3244 if (gfc_current_ns
->proc_name
->attr
.entry_master
)
3246 gfc_entry_list
*el
= gfc_current_ns
->entries
;
3247 for (; el
; el
= el
->next
)
3248 if (el
->sym
== n
->sym
)
3253 if (gfc_current_ns
->parent
3254 && gfc_current_ns
->parent
->proc_name
->attr
.entry_master
)
3256 gfc_entry_list
*el
= gfc_current_ns
->parent
->entries
;
3257 for (; el
; el
= el
->next
)
3258 if (el
->sym
== n
->sym
)
3264 gfc_error ("Object %qs is not a variable at %L", n
->sym
->name
,
3268 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
3269 if (list
!= OMP_LIST_FIRSTPRIVATE
3270 && list
!= OMP_LIST_LASTPRIVATE
3271 && list
!= OMP_LIST_ALIGNED
3272 && list
!= OMP_LIST_DEPEND
3273 && (list
!= OMP_LIST_MAP
|| openacc
)
3274 && list
!= OMP_LIST_FROM
3275 && list
!= OMP_LIST_TO
3276 && (list
!= OMP_LIST_REDUCTION
|| !openacc
))
3277 for (n
= omp_clauses
->lists
[list
]; n
; n
= n
->next
)
3280 gfc_error ("Symbol %qs present on multiple clauses at %L",
3281 n
->sym
->name
, &n
->where
);
3286 gcc_assert (OMP_LIST_LASTPRIVATE
== OMP_LIST_FIRSTPRIVATE
+ 1);
3287 for (list
= OMP_LIST_FIRSTPRIVATE
; list
<= OMP_LIST_LASTPRIVATE
; list
++)
3288 for (n
= omp_clauses
->lists
[list
]; n
; n
= n
->next
)
3291 gfc_error ("Symbol %qs present on multiple clauses at %L",
3292 n
->sym
->name
, &n
->where
);
3296 for (n
= omp_clauses
->lists
[OMP_LIST_FIRSTPRIVATE
]; n
; n
= n
->next
)
3299 gfc_error ("Symbol %qs present on multiple clauses at %L",
3300 n
->sym
->name
, &n
->where
);
3304 for (n
= omp_clauses
->lists
[OMP_LIST_LASTPRIVATE
]; n
; n
= n
->next
)
3307 for (n
= omp_clauses
->lists
[OMP_LIST_LASTPRIVATE
]; n
; n
= n
->next
)
3310 gfc_error ("Symbol %qs present on multiple clauses at %L",
3311 n
->sym
->name
, &n
->where
);
3316 for (n
= omp_clauses
->lists
[OMP_LIST_ALIGNED
]; n
; n
= n
->next
)
3319 for (n
= omp_clauses
->lists
[OMP_LIST_ALIGNED
]; n
; n
= n
->next
)
3322 gfc_error ("Symbol %qs present on multiple clauses at %L",
3323 n
->sym
->name
, &n
->where
);
3328 /* OpenACC reductions. */
3331 for (n
= omp_clauses
->lists
[OMP_LIST_REDUCTION
]; n
; n
= n
->next
)
3334 for (n
= omp_clauses
->lists
[OMP_LIST_REDUCTION
]; n
; n
= n
->next
)
3337 gfc_error ("Symbol %qs present on multiple clauses at %L",
3338 n
->sym
->name
, &n
->where
);
3342 /* OpenACC does not support reductions on arrays. */
3344 gfc_error ("Array %qs is not permitted in reduction at %L",
3345 n
->sym
->name
, &n
->where
);
3349 for (n
= omp_clauses
->lists
[OMP_LIST_TO
]; n
; n
= n
->next
)
3351 for (n
= omp_clauses
->lists
[OMP_LIST_FROM
]; n
; n
= n
->next
)
3352 if (n
->expr
== NULL
)
3354 for (n
= omp_clauses
->lists
[OMP_LIST_TO
]; n
; n
= n
->next
)
3356 if (n
->expr
== NULL
&& n
->sym
->mark
)
3357 gfc_error ("Symbol %qs present on both FROM and TO clauses at %L",
3358 n
->sym
->name
, &n
->where
);
3363 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
3364 if ((n
= omp_clauses
->lists
[list
]) != NULL
)
3368 if (list
< OMP_LIST_NUM
)
3369 name
= clause_names
[list
];
3375 case OMP_LIST_COPYIN
:
3376 for (; n
!= NULL
; n
= n
->next
)
3378 if (!n
->sym
->attr
.threadprivate
)
3379 gfc_error ("Non-THREADPRIVATE object %qs in COPYIN clause"
3380 " at %L", n
->sym
->name
, &n
->where
);
3383 case OMP_LIST_COPYPRIVATE
:
3384 for (; n
!= NULL
; n
= n
->next
)
3386 if (n
->sym
->as
&& n
->sym
->as
->type
== AS_ASSUMED_SIZE
)
3387 gfc_error ("Assumed size array %qs in COPYPRIVATE clause "
3388 "at %L", n
->sym
->name
, &n
->where
);
3389 if (n
->sym
->attr
.pointer
&& n
->sym
->attr
.intent
== INTENT_IN
)
3390 gfc_error ("INTENT(IN) POINTER %qs in COPYPRIVATE clause "
3391 "at %L", n
->sym
->name
, &n
->where
);
3394 case OMP_LIST_SHARED
:
3395 for (; n
!= NULL
; n
= n
->next
)
3397 if (n
->sym
->attr
.threadprivate
)
3398 gfc_error ("THREADPRIVATE object %qs in SHARED clause at "
3399 "%L", n
->sym
->name
, &n
->where
);
3400 if (n
->sym
->attr
.cray_pointee
)
3401 gfc_error ("Cray pointee %qs in SHARED clause at %L",
3402 n
->sym
->name
, &n
->where
);
3403 if (n
->sym
->attr
.associate_var
)
3404 gfc_error ("ASSOCIATE name %qs in SHARED clause at %L",
3405 n
->sym
->name
, &n
->where
);
3408 case OMP_LIST_ALIGNED
:
3409 for (; n
!= NULL
; n
= n
->next
)
3411 if (!n
->sym
->attr
.pointer
3412 && !n
->sym
->attr
.allocatable
3413 && !n
->sym
->attr
.cray_pointer
3414 && (n
->sym
->ts
.type
!= BT_DERIVED
3415 || (n
->sym
->ts
.u
.derived
->from_intmod
3416 != INTMOD_ISO_C_BINDING
)
3417 || (n
->sym
->ts
.u
.derived
->intmod_sym_id
3418 != ISOCBINDING_PTR
)))
3419 gfc_error ("%qs in ALIGNED clause must be POINTER, "
3420 "ALLOCATABLE, Cray pointer or C_PTR at %L",
3421 n
->sym
->name
, &n
->where
);
3424 gfc_expr
*expr
= n
->expr
;
3426 if (!gfc_resolve_expr (expr
)
3427 || expr
->ts
.type
!= BT_INTEGER
3429 || gfc_extract_int (expr
, &alignment
)
3431 gfc_error ("%qs in ALIGNED clause at %L requires a scalar "
3432 "positive constant integer alignment "
3433 "expression", n
->sym
->name
, &n
->where
);
3437 case OMP_LIST_DEPEND
:
3441 case OMP_LIST_CACHE
:
3442 for (; n
!= NULL
; n
= n
->next
)
3446 if (!gfc_resolve_expr (n
->expr
)
3447 || n
->expr
->expr_type
!= EXPR_VARIABLE
3448 || n
->expr
->ref
== NULL
3449 || n
->expr
->ref
->next
3450 || n
->expr
->ref
->type
!= REF_ARRAY
)
3451 gfc_error ("%qs in %s clause at %L is not a proper "
3452 "array section", n
->sym
->name
, name
,
3454 else if (n
->expr
->ref
->u
.ar
.codimen
)
3455 gfc_error ("Coarrays not supported in %s clause at %L",
3460 gfc_array_ref
*ar
= &n
->expr
->ref
->u
.ar
;
3461 for (i
= 0; i
< ar
->dimen
; i
++)
3464 gfc_error ("Stride should not be specified for "
3465 "array section in %s clause at %L",
3469 else if (ar
->dimen_type
[i
] != DIMEN_ELEMENT
3470 && ar
->dimen_type
[i
] != DIMEN_RANGE
)
3472 gfc_error ("%qs in %s clause at %L is not a "
3473 "proper array section",
3474 n
->sym
->name
, name
, &n
->where
);
3477 else if (list
== OMP_LIST_DEPEND
3479 && ar
->start
[i
]->expr_type
== EXPR_CONSTANT
3481 && ar
->end
[i
]->expr_type
== EXPR_CONSTANT
3482 && mpz_cmp (ar
->start
[i
]->value
.integer
,
3483 ar
->end
[i
]->value
.integer
) > 0)
3485 gfc_error ("%qs in DEPEND clause at %L is a "
3486 "zero size array section",
3487 n
->sym
->name
, &n
->where
);
3494 if (list
== OMP_LIST_MAP
3495 && n
->u
.map_op
== OMP_MAP_FORCE_DEVICEPTR
)
3496 resolve_oacc_deviceptr_clause (n
->sym
, n
->where
, name
);
3498 resolve_oacc_data_clauses (n
->sym
, n
->where
, name
);
3502 if (list
!= OMP_LIST_DEPEND
)
3503 for (n
= omp_clauses
->lists
[list
]; n
!= NULL
; n
= n
->next
)
3505 n
->sym
->attr
.referenced
= 1;
3506 if (n
->sym
->attr
.threadprivate
)
3507 gfc_error ("THREADPRIVATE object %qs in %s clause at %L",
3508 n
->sym
->name
, name
, &n
->where
);
3509 if (n
->sym
->attr
.cray_pointee
)
3510 gfc_error ("Cray pointee %qs in %s clause at %L",
3511 n
->sym
->name
, name
, &n
->where
);
3515 for (; n
!= NULL
; n
= n
->next
)
3518 if (n
->sym
->attr
.threadprivate
)
3519 gfc_error ("THREADPRIVATE object %qs in %s clause at %L",
3520 n
->sym
->name
, name
, &n
->where
);
3521 if (n
->sym
->attr
.cray_pointee
)
3522 gfc_error ("Cray pointee %qs in %s clause at %L",
3523 n
->sym
->name
, name
, &n
->where
);
3524 if (n
->sym
->attr
.associate_var
)
3525 gfc_error ("ASSOCIATE name %qs in %s clause at %L",
3526 n
->sym
->name
, name
, &n
->where
);
3527 if (list
!= OMP_LIST_PRIVATE
)
3529 if (n
->sym
->attr
.proc_pointer
&& list
== OMP_LIST_REDUCTION
)
3530 gfc_error ("Procedure pointer %qs in %s clause at %L",
3531 n
->sym
->name
, name
, &n
->where
);
3532 if (n
->sym
->attr
.pointer
&& list
== OMP_LIST_REDUCTION
)
3533 gfc_error ("POINTER object %qs in %s clause at %L",
3534 n
->sym
->name
, name
, &n
->where
);
3535 if (n
->sym
->attr
.cray_pointer
&& list
== OMP_LIST_REDUCTION
)
3536 gfc_error ("Cray pointer %qs in %s clause at %L",
3537 n
->sym
->name
, name
, &n
->where
);
3540 && (oacc_is_loop (code
) || code
->op
== EXEC_OACC_PARALLEL
))
3541 check_array_not_assumed (n
->sym
, n
->where
, name
);
3542 else if (n
->sym
->as
&& n
->sym
->as
->type
== AS_ASSUMED_SIZE
)
3543 gfc_error ("Assumed size array %qs in %s clause at %L",
3544 n
->sym
->name
, name
, &n
->where
);
3545 if (n
->sym
->attr
.in_namelist
&& list
!= OMP_LIST_REDUCTION
)
3546 gfc_error ("Variable %qs in %s clause is used in "
3547 "NAMELIST statement at %L",
3548 n
->sym
->name
, name
, &n
->where
);
3549 if (n
->sym
->attr
.pointer
&& n
->sym
->attr
.intent
== INTENT_IN
)
3552 case OMP_LIST_PRIVATE
:
3553 case OMP_LIST_LASTPRIVATE
:
3554 case OMP_LIST_LINEAR
:
3555 /* case OMP_LIST_REDUCTION: */
3556 gfc_error ("INTENT(IN) POINTER %qs in %s clause at %L",
3557 n
->sym
->name
, name
, &n
->where
);
3565 case OMP_LIST_REDUCTION
:
3566 switch (n
->u
.reduction_op
)
3568 case OMP_REDUCTION_PLUS
:
3569 case OMP_REDUCTION_TIMES
:
3570 case OMP_REDUCTION_MINUS
:
3571 if (!gfc_numeric_ts (&n
->sym
->ts
))
3574 case OMP_REDUCTION_AND
:
3575 case OMP_REDUCTION_OR
:
3576 case OMP_REDUCTION_EQV
:
3577 case OMP_REDUCTION_NEQV
:
3578 if (n
->sym
->ts
.type
!= BT_LOGICAL
)
3581 case OMP_REDUCTION_MAX
:
3582 case OMP_REDUCTION_MIN
:
3583 if (n
->sym
->ts
.type
!= BT_INTEGER
3584 && n
->sym
->ts
.type
!= BT_REAL
)
3587 case OMP_REDUCTION_IAND
:
3588 case OMP_REDUCTION_IOR
:
3589 case OMP_REDUCTION_IEOR
:
3590 if (n
->sym
->ts
.type
!= BT_INTEGER
)
3593 case OMP_REDUCTION_USER
:
3603 const char *udr_name
= NULL
;
3606 udr_name
= n
->udr
->udr
->name
;
3608 = gfc_find_omp_udr (NULL
, udr_name
,
3610 if (n
->udr
->udr
== NULL
)
3618 if (udr_name
== NULL
)
3619 switch (n
->u
.reduction_op
)
3621 case OMP_REDUCTION_PLUS
:
3622 case OMP_REDUCTION_TIMES
:
3623 case OMP_REDUCTION_MINUS
:
3624 case OMP_REDUCTION_AND
:
3625 case OMP_REDUCTION_OR
:
3626 case OMP_REDUCTION_EQV
:
3627 case OMP_REDUCTION_NEQV
:
3628 udr_name
= gfc_op2string ((gfc_intrinsic_op
)
3631 case OMP_REDUCTION_MAX
:
3634 case OMP_REDUCTION_MIN
:
3637 case OMP_REDUCTION_IAND
:
3640 case OMP_REDUCTION_IOR
:
3643 case OMP_REDUCTION_IEOR
:
3649 gfc_error ("!$OMP DECLARE REDUCTION %s not found "
3650 "for type %s at %L", udr_name
,
3651 gfc_typename (&n
->sym
->ts
), &n
->where
);
3655 gfc_omp_udr
*udr
= n
->udr
->udr
;
3656 n
->u
.reduction_op
= OMP_REDUCTION_USER
;
3658 = resolve_omp_udr_clause (n
, udr
->combiner_ns
,
3661 if (udr
->initializer_ns
)
3663 = resolve_omp_udr_clause (n
,
3664 udr
->initializer_ns
,
3670 case OMP_LIST_LINEAR
:
3671 if (n
->sym
->ts
.type
!= BT_INTEGER
)
3672 gfc_error ("LINEAR variable %qs must be INTEGER "
3673 "at %L", n
->sym
->name
, &n
->where
);
3674 else if (!code
&& !n
->sym
->attr
.value
)
3675 gfc_error ("LINEAR dummy argument %qs must have VALUE "
3676 "attribute at %L", n
->sym
->name
, &n
->where
);
3679 gfc_expr
*expr
= n
->expr
;
3680 if (!gfc_resolve_expr (expr
)
3681 || expr
->ts
.type
!= BT_INTEGER
3683 gfc_error ("%qs in LINEAR clause at %L requires "
3684 "a scalar integer linear-step expression",
3685 n
->sym
->name
, &n
->where
);
3686 else if (!code
&& expr
->expr_type
!= EXPR_CONSTANT
)
3687 gfc_error ("%qs in LINEAR clause at %L requires "
3688 "a constant integer linear-step expression",
3689 n
->sym
->name
, &n
->where
);
3692 /* Workaround for PR middle-end/26316, nothing really needs
3693 to be done here for OMP_LIST_PRIVATE. */
3694 case OMP_LIST_PRIVATE
:
3695 gcc_assert (code
&& code
->op
!= EXEC_NOP
);
3697 case OMP_LIST_USE_DEVICE
:
3698 if (n
->sym
->attr
.allocatable
3699 || (n
->sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (n
->sym
)
3700 && CLASS_DATA (n
->sym
)->attr
.allocatable
))
3701 gfc_error ("ALLOCATABLE object %qs in %s clause at %L",
3702 n
->sym
->name
, name
, &n
->where
);
3703 if (n
->sym
->attr
.pointer
3704 || (n
->sym
->ts
.type
== BT_CLASS
&& CLASS_DATA (n
->sym
)
3705 && CLASS_DATA (n
->sym
)->attr
.class_pointer
))
3706 gfc_error ("POINTER object %qs in %s clause at %L",
3707 n
->sym
->name
, name
, &n
->where
);
3708 if (n
->sym
->attr
.cray_pointer
)
3709 gfc_error ("Cray pointer object %qs in %s clause at %L",
3710 n
->sym
->name
, name
, &n
->where
);
3711 if (n
->sym
->attr
.cray_pointee
)
3712 gfc_error ("Cray pointee object %qs in %s clause at %L",
3713 n
->sym
->name
, name
, &n
->where
);
3715 case OMP_LIST_DEVICE_RESIDENT
:
3716 check_symbol_not_pointer (n
->sym
, n
->where
, name
);
3717 check_array_not_assumed (n
->sym
, n
->where
, name
);
3726 if (omp_clauses
->safelen_expr
)
3728 gfc_expr
*expr
= omp_clauses
->safelen_expr
;
3729 if (!gfc_resolve_expr (expr
)
3730 || expr
->ts
.type
!= BT_INTEGER
|| expr
->rank
!= 0)
3731 gfc_error ("SAFELEN clause at %L requires a scalar "
3732 "INTEGER expression", &expr
->where
);
3734 if (omp_clauses
->simdlen_expr
)
3736 gfc_expr
*expr
= omp_clauses
->simdlen_expr
;
3737 if (!gfc_resolve_expr (expr
)
3738 || expr
->ts
.type
!= BT_INTEGER
|| expr
->rank
!= 0)
3739 gfc_error ("SIMDLEN clause at %L requires a scalar "
3740 "INTEGER expression", &expr
->where
);
3742 if (omp_clauses
->num_teams
)
3744 gfc_expr
*expr
= omp_clauses
->num_teams
;
3745 if (!gfc_resolve_expr (expr
)
3746 || expr
->ts
.type
!= BT_INTEGER
|| expr
->rank
!= 0)
3747 gfc_error ("NUM_TEAMS clause at %L requires a scalar "
3748 "INTEGER expression", &expr
->where
);
3750 if (omp_clauses
->device
)
3752 gfc_expr
*expr
= omp_clauses
->device
;
3753 if (!gfc_resolve_expr (expr
)
3754 || expr
->ts
.type
!= BT_INTEGER
|| expr
->rank
!= 0)
3755 gfc_error ("DEVICE clause at %L requires a scalar "
3756 "INTEGER expression", &expr
->where
);
3758 if (omp_clauses
->dist_chunk_size
)
3760 gfc_expr
*expr
= omp_clauses
->dist_chunk_size
;
3761 if (!gfc_resolve_expr (expr
)
3762 || expr
->ts
.type
!= BT_INTEGER
|| expr
->rank
!= 0)
3763 gfc_error ("DIST_SCHEDULE clause's chunk_size at %L requires "
3764 "a scalar INTEGER expression", &expr
->where
);
3766 if (omp_clauses
->thread_limit
)
3768 gfc_expr
*expr
= omp_clauses
->thread_limit
;
3769 if (!gfc_resolve_expr (expr
)
3770 || expr
->ts
.type
!= BT_INTEGER
|| expr
->rank
!= 0)
3771 gfc_error ("THREAD_LIMIT clause at %L requires a scalar "
3772 "INTEGER expression", &expr
->where
);
3774 if (omp_clauses
->async
)
3775 if (omp_clauses
->async_expr
)
3776 resolve_oacc_scalar_int_expr (omp_clauses
->async_expr
, "ASYNC");
3777 if (omp_clauses
->num_gangs_expr
)
3778 resolve_oacc_positive_int_expr (omp_clauses
->num_gangs_expr
, "NUM_GANGS");
3779 if (omp_clauses
->num_workers_expr
)
3780 resolve_oacc_positive_int_expr (omp_clauses
->num_workers_expr
,
3782 if (omp_clauses
->vector_length_expr
)
3783 resolve_oacc_positive_int_expr (omp_clauses
->vector_length_expr
,
3785 if (omp_clauses
->gang_num_expr
)
3786 resolve_oacc_positive_int_expr (omp_clauses
->gang_num_expr
, "GANG");
3787 if (omp_clauses
->gang_static_expr
)
3788 resolve_oacc_positive_int_expr (omp_clauses
->gang_static_expr
, "GANG");
3789 if (omp_clauses
->worker_expr
)
3790 resolve_oacc_positive_int_expr (omp_clauses
->worker_expr
, "WORKER");
3791 if (omp_clauses
->vector_expr
)
3792 resolve_oacc_positive_int_expr (omp_clauses
->vector_expr
, "VECTOR");
3793 if (omp_clauses
->wait
)
3794 if (omp_clauses
->wait_list
)
3795 for (el
= omp_clauses
->wait_list
; el
; el
= el
->next
)
3796 resolve_oacc_scalar_int_expr (el
->expr
, "WAIT");
3800 /* Return true if SYM is ever referenced in EXPR except in the SE node. */
3803 expr_references_sym (gfc_expr
*e
, gfc_symbol
*s
, gfc_expr
*se
)
3805 gfc_actual_arglist
*arg
;
3806 if (e
== NULL
|| e
== se
)
3808 switch (e
->expr_type
)
3813 case EXPR_STRUCTURE
:
3815 if (e
->symtree
!= NULL
3816 && e
->symtree
->n
.sym
== s
)
3819 case EXPR_SUBSTRING
:
3821 && (expr_references_sym (e
->ref
->u
.ss
.start
, s
, se
)
3822 || expr_references_sym (e
->ref
->u
.ss
.end
, s
, se
)))
3826 if (expr_references_sym (e
->value
.op
.op2
, s
, se
))
3828 return expr_references_sym (e
->value
.op
.op1
, s
, se
);
3830 for (arg
= e
->value
.function
.actual
; arg
; arg
= arg
->next
)
3831 if (expr_references_sym (arg
->expr
, s
, se
))
3840 /* If EXPR is a conversion function that widens the type
3841 if WIDENING is true or narrows the type if WIDENING is false,
3842 return the inner expression, otherwise return NULL. */
3845 is_conversion (gfc_expr
*expr
, bool widening
)
3847 gfc_typespec
*ts1
, *ts2
;
3849 if (expr
->expr_type
!= EXPR_FUNCTION
3850 || expr
->value
.function
.isym
== NULL
3851 || expr
->value
.function
.esym
!= NULL
3852 || expr
->value
.function
.isym
->id
!= GFC_ISYM_CONVERSION
)
3858 ts2
= &expr
->value
.function
.actual
->expr
->ts
;
3862 ts1
= &expr
->value
.function
.actual
->expr
->ts
;
3866 if (ts1
->type
> ts2
->type
3867 || (ts1
->type
== ts2
->type
&& ts1
->kind
> ts2
->kind
))
3868 return expr
->value
.function
.actual
->expr
;
3875 resolve_omp_atomic (gfc_code
*code
)
3877 gfc_code
*atomic_code
= code
;
3879 gfc_expr
*expr2
, *expr2_tmp
;
3880 gfc_omp_atomic_op aop
3881 = (gfc_omp_atomic_op
) (atomic_code
->ext
.omp_atomic
& GFC_OMP_ATOMIC_MASK
);
3883 code
= code
->block
->next
;
3884 gcc_assert (code
->op
== EXEC_ASSIGN
);
3885 gcc_assert (((aop
!= GFC_OMP_ATOMIC_CAPTURE
) && code
->next
== NULL
)
3886 || ((aop
== GFC_OMP_ATOMIC_CAPTURE
)
3887 && code
->next
!= NULL
3888 && code
->next
->op
== EXEC_ASSIGN
3889 && code
->next
->next
== NULL
));
3891 if (code
->expr1
->expr_type
!= EXPR_VARIABLE
3892 || code
->expr1
->symtree
== NULL
3893 || code
->expr1
->rank
!= 0
3894 || (code
->expr1
->ts
.type
!= BT_INTEGER
3895 && code
->expr1
->ts
.type
!= BT_REAL
3896 && code
->expr1
->ts
.type
!= BT_COMPLEX
3897 && code
->expr1
->ts
.type
!= BT_LOGICAL
))
3899 gfc_error ("!$OMP ATOMIC statement must set a scalar variable of "
3900 "intrinsic type at %L", &code
->loc
);
3904 var
= code
->expr1
->symtree
->n
.sym
;
3905 expr2
= is_conversion (code
->expr2
, false);
3908 if (aop
== GFC_OMP_ATOMIC_READ
|| aop
== GFC_OMP_ATOMIC_WRITE
)
3909 expr2
= is_conversion (code
->expr2
, true);
3911 expr2
= code
->expr2
;
3916 case GFC_OMP_ATOMIC_READ
:
3917 if (expr2
->expr_type
!= EXPR_VARIABLE
3918 || expr2
->symtree
== NULL
3920 || (expr2
->ts
.type
!= BT_INTEGER
3921 && expr2
->ts
.type
!= BT_REAL
3922 && expr2
->ts
.type
!= BT_COMPLEX
3923 && expr2
->ts
.type
!= BT_LOGICAL
))
3924 gfc_error ("!$OMP ATOMIC READ statement must read from a scalar "
3925 "variable of intrinsic type at %L", &expr2
->where
);
3927 case GFC_OMP_ATOMIC_WRITE
:
3928 if (expr2
->rank
!= 0 || expr_references_sym (code
->expr2
, var
, NULL
))
3929 gfc_error ("expr in !$OMP ATOMIC WRITE assignment var = expr "
3930 "must be scalar and cannot reference var at %L",
3933 case GFC_OMP_ATOMIC_CAPTURE
:
3935 if (expr2
== code
->expr2
)
3937 expr2_tmp
= is_conversion (code
->expr2
, true);
3938 if (expr2_tmp
== NULL
)
3941 if (expr2_tmp
->expr_type
== EXPR_VARIABLE
)
3943 if (expr2_tmp
->symtree
== NULL
3944 || expr2_tmp
->rank
!= 0
3945 || (expr2_tmp
->ts
.type
!= BT_INTEGER
3946 && expr2_tmp
->ts
.type
!= BT_REAL
3947 && expr2_tmp
->ts
.type
!= BT_COMPLEX
3948 && expr2_tmp
->ts
.type
!= BT_LOGICAL
)
3949 || expr2_tmp
->symtree
->n
.sym
== var
)
3951 gfc_error ("!$OMP ATOMIC CAPTURE capture statement must read from "
3952 "a scalar variable of intrinsic type at %L",
3956 var
= expr2_tmp
->symtree
->n
.sym
;
3958 if (code
->expr1
->expr_type
!= EXPR_VARIABLE
3959 || code
->expr1
->symtree
== NULL
3960 || code
->expr1
->rank
!= 0
3961 || (code
->expr1
->ts
.type
!= BT_INTEGER
3962 && code
->expr1
->ts
.type
!= BT_REAL
3963 && code
->expr1
->ts
.type
!= BT_COMPLEX
3964 && code
->expr1
->ts
.type
!= BT_LOGICAL
))
3966 gfc_error ("!$OMP ATOMIC CAPTURE update statement must set "
3967 "a scalar variable of intrinsic type at %L",
3968 &code
->expr1
->where
);
3971 if (code
->expr1
->symtree
->n
.sym
!= var
)
3973 gfc_error ("!$OMP ATOMIC CAPTURE capture statement reads from "
3974 "different variable than update statement writes "
3975 "into at %L", &code
->expr1
->where
);
3978 expr2
= is_conversion (code
->expr2
, false);
3980 expr2
= code
->expr2
;
3987 if (gfc_expr_attr (code
->expr1
).allocatable
)
3989 gfc_error ("!$OMP ATOMIC with ALLOCATABLE variable at %L",
3994 if (aop
== GFC_OMP_ATOMIC_CAPTURE
3995 && code
->next
== NULL
3996 && code
->expr2
->rank
== 0
3997 && !expr_references_sym (code
->expr2
, var
, NULL
))
3998 atomic_code
->ext
.omp_atomic
3999 = (gfc_omp_atomic_op
) (atomic_code
->ext
.omp_atomic
4000 | GFC_OMP_ATOMIC_SWAP
);
4001 else if (expr2
->expr_type
== EXPR_OP
)
4003 gfc_expr
*v
= NULL
, *e
, *c
;
4004 gfc_intrinsic_op op
= expr2
->value
.op
.op
;
4005 gfc_intrinsic_op alt_op
= INTRINSIC_NONE
;
4009 case INTRINSIC_PLUS
:
4010 alt_op
= INTRINSIC_MINUS
;
4012 case INTRINSIC_TIMES
:
4013 alt_op
= INTRINSIC_DIVIDE
;
4015 case INTRINSIC_MINUS
:
4016 alt_op
= INTRINSIC_PLUS
;
4018 case INTRINSIC_DIVIDE
:
4019 alt_op
= INTRINSIC_TIMES
;
4025 alt_op
= INTRINSIC_NEQV
;
4027 case INTRINSIC_NEQV
:
4028 alt_op
= INTRINSIC_EQV
;
4031 gfc_error ("!$OMP ATOMIC assignment operator must be binary "
4032 "+, *, -, /, .AND., .OR., .EQV. or .NEQV. at %L",
4037 /* Check for var = var op expr resp. var = expr op var where
4038 expr doesn't reference var and var op expr is mathematically
4039 equivalent to var op (expr) resp. expr op var equivalent to
4040 (expr) op var. We rely here on the fact that the matcher
4041 for x op1 y op2 z where op1 and op2 have equal precedence
4042 returns (x op1 y) op2 z. */
4043 e
= expr2
->value
.op
.op2
;
4044 if (e
->expr_type
== EXPR_VARIABLE
4045 && e
->symtree
!= NULL
4046 && e
->symtree
->n
.sym
== var
)
4048 else if ((c
= is_conversion (e
, true)) != NULL
4049 && c
->expr_type
== EXPR_VARIABLE
4050 && c
->symtree
!= NULL
4051 && c
->symtree
->n
.sym
== var
)
4055 gfc_expr
**p
= NULL
, **q
;
4056 for (q
= &expr2
->value
.op
.op1
; (e
= *q
) != NULL
; )
4057 if (e
->expr_type
== EXPR_VARIABLE
4058 && e
->symtree
!= NULL
4059 && e
->symtree
->n
.sym
== var
)
4064 else if ((c
= is_conversion (e
, true)) != NULL
)
4065 q
= &e
->value
.function
.actual
->expr
;
4066 else if (e
->expr_type
!= EXPR_OP
4067 || (e
->value
.op
.op
!= op
4068 && e
->value
.op
.op
!= alt_op
)
4074 q
= &e
->value
.op
.op1
;
4079 gfc_error ("!$OMP ATOMIC assignment must be var = var op expr "
4080 "or var = expr op var at %L", &expr2
->where
);
4087 switch (e
->value
.op
.op
)
4089 case INTRINSIC_MINUS
:
4090 case INTRINSIC_DIVIDE
:
4092 case INTRINSIC_NEQV
:
4093 gfc_error ("!$OMP ATOMIC var = var op expr not "
4094 "mathematically equivalent to var = var op "
4095 "(expr) at %L", &expr2
->where
);
4101 /* Canonicalize into var = var op (expr). */
4102 *p
= e
->value
.op
.op2
;
4103 e
->value
.op
.op2
= expr2
;
4105 if (code
->expr2
== expr2
)
4106 code
->expr2
= expr2
= e
;
4108 code
->expr2
->value
.function
.actual
->expr
= expr2
= e
;
4110 if (!gfc_compare_types (&expr2
->value
.op
.op1
->ts
, &expr2
->ts
))
4112 for (p
= &expr2
->value
.op
.op1
; *p
!= v
;
4113 p
= &(*p
)->value
.function
.actual
->expr
)
4116 gfc_free_expr (expr2
->value
.op
.op1
);
4117 expr2
->value
.op
.op1
= v
;
4118 gfc_convert_type (v
, &expr2
->ts
, 2);
4123 if (e
->rank
!= 0 || expr_references_sym (code
->expr2
, var
, v
))
4125 gfc_error ("expr in !$OMP ATOMIC assignment var = var op expr "
4126 "must be scalar and cannot reference var at %L",
4131 else if (expr2
->expr_type
== EXPR_FUNCTION
4132 && expr2
->value
.function
.isym
!= NULL
4133 && expr2
->value
.function
.esym
== NULL
4134 && expr2
->value
.function
.actual
!= NULL
4135 && expr2
->value
.function
.actual
->next
!= NULL
)
4137 gfc_actual_arglist
*arg
, *var_arg
;
4139 switch (expr2
->value
.function
.isym
->id
)
4147 if (expr2
->value
.function
.actual
->next
->next
!= NULL
)
4149 gfc_error ("!$OMP ATOMIC assignment intrinsic IAND, IOR "
4150 "or IEOR must have two arguments at %L",
4156 gfc_error ("!$OMP ATOMIC assignment intrinsic must be "
4157 "MIN, MAX, IAND, IOR or IEOR at %L",
4163 for (arg
= expr2
->value
.function
.actual
; arg
; arg
= arg
->next
)
4165 if ((arg
== expr2
->value
.function
.actual
4166 || (var_arg
== NULL
&& arg
->next
== NULL
))
4167 && arg
->expr
->expr_type
== EXPR_VARIABLE
4168 && arg
->expr
->symtree
!= NULL
4169 && arg
->expr
->symtree
->n
.sym
== var
)
4171 else if (expr_references_sym (arg
->expr
, var
, NULL
))
4173 gfc_error ("!$OMP ATOMIC intrinsic arguments except one must "
4174 "not reference %qs at %L",
4175 var
->name
, &arg
->expr
->where
);
4178 if (arg
->expr
->rank
!= 0)
4180 gfc_error ("!$OMP ATOMIC intrinsic arguments must be scalar "
4181 "at %L", &arg
->expr
->where
);
4186 if (var_arg
== NULL
)
4188 gfc_error ("First or last !$OMP ATOMIC intrinsic argument must "
4189 "be %qs at %L", var
->name
, &expr2
->where
);
4193 if (var_arg
!= expr2
->value
.function
.actual
)
4195 /* Canonicalize, so that var comes first. */
4196 gcc_assert (var_arg
->next
== NULL
);
4197 for (arg
= expr2
->value
.function
.actual
;
4198 arg
->next
!= var_arg
; arg
= arg
->next
)
4200 var_arg
->next
= expr2
->value
.function
.actual
;
4201 expr2
->value
.function
.actual
= var_arg
;
4206 gfc_error ("!$OMP ATOMIC assignment must have an operator or "
4207 "intrinsic on right hand side at %L", &expr2
->where
);
4209 if (aop
== GFC_OMP_ATOMIC_CAPTURE
&& code
->next
)
4212 if (code
->expr1
->expr_type
!= EXPR_VARIABLE
4213 || code
->expr1
->symtree
== NULL
4214 || code
->expr1
->rank
!= 0
4215 || (code
->expr1
->ts
.type
!= BT_INTEGER
4216 && code
->expr1
->ts
.type
!= BT_REAL
4217 && code
->expr1
->ts
.type
!= BT_COMPLEX
4218 && code
->expr1
->ts
.type
!= BT_LOGICAL
))
4220 gfc_error ("!$OMP ATOMIC CAPTURE capture statement must set "
4221 "a scalar variable of intrinsic type at %L",
4222 &code
->expr1
->where
);
4226 expr2
= is_conversion (code
->expr2
, false);
4229 expr2
= is_conversion (code
->expr2
, true);
4231 expr2
= code
->expr2
;
4234 if (expr2
->expr_type
!= EXPR_VARIABLE
4235 || expr2
->symtree
== NULL
4237 || (expr2
->ts
.type
!= BT_INTEGER
4238 && expr2
->ts
.type
!= BT_REAL
4239 && expr2
->ts
.type
!= BT_COMPLEX
4240 && expr2
->ts
.type
!= BT_LOGICAL
))
4242 gfc_error ("!$OMP ATOMIC CAPTURE capture statement must read "
4243 "from a scalar variable of intrinsic type at %L",
4247 if (expr2
->symtree
->n
.sym
!= var
)
4249 gfc_error ("!$OMP ATOMIC CAPTURE capture statement reads from "
4250 "different variable than update statement writes "
4251 "into at %L", &expr2
->where
);
4258 struct fortran_omp_context
4261 hash_set
<gfc_symbol
*> *sharing_clauses
;
4262 hash_set
<gfc_symbol
*> *private_iterators
;
4263 struct fortran_omp_context
*previous
;
4266 static gfc_code
*omp_current_do_code
;
4267 static int omp_current_do_collapse
;
4270 gfc_resolve_omp_do_blocks (gfc_code
*code
, gfc_namespace
*ns
)
4272 if (code
->block
->next
&& code
->block
->next
->op
== EXEC_DO
)
4277 omp_current_do_code
= code
->block
->next
;
4278 omp_current_do_collapse
= code
->ext
.omp_clauses
->collapse
;
4279 for (i
= 1, c
= omp_current_do_code
; i
< omp_current_do_collapse
; i
++)
4282 if (c
->op
!= EXEC_DO
|| c
->next
== NULL
)
4285 if (c
->op
!= EXEC_DO
)
4288 if (i
< omp_current_do_collapse
|| omp_current_do_collapse
<= 0)
4289 omp_current_do_collapse
= 1;
4291 gfc_resolve_blocks (code
->block
, ns
);
4292 omp_current_do_collapse
= 0;
4293 omp_current_do_code
= NULL
;
4298 gfc_resolve_omp_parallel_blocks (gfc_code
*code
, gfc_namespace
*ns
)
4300 struct fortran_omp_context ctx
;
4301 gfc_omp_clauses
*omp_clauses
= code
->ext
.omp_clauses
;
4302 gfc_omp_namelist
*n
;
4306 ctx
.sharing_clauses
= new hash_set
<gfc_symbol
*>;
4307 ctx
.private_iterators
= new hash_set
<gfc_symbol
*>;
4308 ctx
.previous
= omp_current_ctx
;
4309 ctx
.is_openmp
= true;
4310 omp_current_ctx
= &ctx
;
4312 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
4315 case OMP_LIST_SHARED
:
4316 case OMP_LIST_PRIVATE
:
4317 case OMP_LIST_FIRSTPRIVATE
:
4318 case OMP_LIST_LASTPRIVATE
:
4319 case OMP_LIST_REDUCTION
:
4320 case OMP_LIST_LINEAR
:
4321 for (n
= omp_clauses
->lists
[list
]; n
; n
= n
->next
)
4322 ctx
.sharing_clauses
->add (n
->sym
);
4330 case EXEC_OMP_PARALLEL_DO
:
4331 case EXEC_OMP_PARALLEL_DO_SIMD
:
4332 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE
:
4333 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO
:
4334 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
4335 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD
:
4336 case EXEC_OMP_TEAMS_DISTRIBUTE
:
4337 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO
:
4338 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
4339 case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD
:
4340 gfc_resolve_omp_do_blocks (code
, ns
);
4343 gfc_resolve_blocks (code
->block
, ns
);
4346 omp_current_ctx
= ctx
.previous
;
4347 delete ctx
.sharing_clauses
;
4348 delete ctx
.private_iterators
;
4352 /* Save and clear openmp.c private state. */
4355 gfc_omp_save_and_clear_state (struct gfc_omp_saved_state
*state
)
4357 state
->ptrs
[0] = omp_current_ctx
;
4358 state
->ptrs
[1] = omp_current_do_code
;
4359 state
->ints
[0] = omp_current_do_collapse
;
4360 omp_current_ctx
= NULL
;
4361 omp_current_do_code
= NULL
;
4362 omp_current_do_collapse
= 0;
4366 /* Restore openmp.c private state from the saved state. */
4369 gfc_omp_restore_state (struct gfc_omp_saved_state
*state
)
4371 omp_current_ctx
= (struct fortran_omp_context
*) state
->ptrs
[0];
4372 omp_current_do_code
= (gfc_code
*) state
->ptrs
[1];
4373 omp_current_do_collapse
= state
->ints
[0];
4377 /* Note a DO iterator variable. This is special in !$omp parallel
4378 construct, where they are predetermined private. */
4381 gfc_resolve_do_iterator (gfc_code
*code
, gfc_symbol
*sym
)
4383 int i
= omp_current_do_collapse
;
4384 gfc_code
*c
= omp_current_do_code
;
4386 if (sym
->attr
.threadprivate
)
4389 /* !$omp do and !$omp parallel do iteration variable is predetermined
4390 private just in the !$omp do resp. !$omp parallel do construct,
4391 with no implications for the outer parallel constructs. */
4401 if (omp_current_ctx
== NULL
)
4404 /* An openacc context may represent a data clause. Abort if so. */
4405 if (!omp_current_ctx
->is_openmp
&& !oacc_is_loop (omp_current_ctx
->code
))
4408 if (omp_current_ctx
->is_openmp
4409 && omp_current_ctx
->sharing_clauses
->contains (sym
))
4412 if (! omp_current_ctx
->private_iterators
->add (sym
))
4414 gfc_omp_clauses
*omp_clauses
= omp_current_ctx
->code
->ext
.omp_clauses
;
4415 gfc_omp_namelist
*p
;
4417 p
= gfc_get_omp_namelist ();
4419 p
->next
= omp_clauses
->lists
[OMP_LIST_PRIVATE
];
4420 omp_clauses
->lists
[OMP_LIST_PRIVATE
] = p
;
4426 resolve_omp_do (gfc_code
*code
)
4428 gfc_code
*do_code
, *c
;
4429 int list
, i
, collapse
;
4430 gfc_omp_namelist
*n
;
4433 bool is_simd
= false;
4437 case EXEC_OMP_DISTRIBUTE
: name
= "!$OMP DISTRIBUTE"; break;
4438 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO
:
4439 name
= "!$OMP DISTRIBUTE PARALLEL DO";
4441 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD
:
4442 name
= "!$OMP DISTRIBUTE PARALLEL DO SIMD";
4445 case EXEC_OMP_DISTRIBUTE_SIMD
:
4446 name
= "!$OMP DISTRIBUTE SIMD";
4449 case EXEC_OMP_DO
: name
= "!$OMP DO"; break;
4450 case EXEC_OMP_DO_SIMD
: name
= "!$OMP DO SIMD"; is_simd
= true; break;
4451 case EXEC_OMP_PARALLEL_DO
: name
= "!$OMP PARALLEL DO"; break;
4452 case EXEC_OMP_PARALLEL_DO_SIMD
:
4453 name
= "!$OMP PARALLEL DO SIMD";
4456 case EXEC_OMP_SIMD
: name
= "!$OMP SIMD"; is_simd
= true; break;
4457 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE
:
4458 name
= "!$OMP TARGET TEAMS_DISTRIBUTE";
4460 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO
:
4461 name
= "!$OMP TARGET TEAMS DISTRIBUTE PARALLEL DO";
4463 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
4464 name
= "!$OMP TARGET TEAMS DISTRIBUTE PARALLEL DO SIMD";
4467 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD
:
4468 name
= "!$OMP TARGET TEAMS DISTRIBUTE SIMD";
4471 case EXEC_OMP_TEAMS_DISTRIBUTE
: name
= "!$OMP TEAMS_DISTRIBUTE"; break;
4472 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO
:
4473 name
= "!$OMP TEAMS DISTRIBUTE PARALLEL DO";
4475 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
4476 name
= "!$OMP TEAMS DISTRIBUTE PARALLEL DO SIMD";
4479 case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD
:
4480 name
= "!$OMP TEAMS DISTRIBUTE SIMD";
4483 default: gcc_unreachable ();
4486 if (code
->ext
.omp_clauses
)
4487 resolve_omp_clauses (code
, code
->ext
.omp_clauses
, NULL
);
4489 do_code
= code
->block
->next
;
4490 collapse
= code
->ext
.omp_clauses
->collapse
;
4493 for (i
= 1; i
<= collapse
; i
++)
4495 if (do_code
->op
== EXEC_DO_WHILE
)
4497 gfc_error ("%s cannot be a DO WHILE or DO without loop control "
4498 "at %L", name
, &do_code
->loc
);
4501 if (do_code
->op
== EXEC_DO_CONCURRENT
)
4503 gfc_error ("%s cannot be a DO CONCURRENT loop at %L", name
,
4507 gcc_assert (do_code
->op
== EXEC_DO
);
4508 if (do_code
->ext
.iterator
->var
->ts
.type
!= BT_INTEGER
)
4509 gfc_error ("%s iteration variable must be of type integer at %L",
4510 name
, &do_code
->loc
);
4511 dovar
= do_code
->ext
.iterator
->var
->symtree
->n
.sym
;
4512 if (dovar
->attr
.threadprivate
)
4513 gfc_error ("%s iteration variable must not be THREADPRIVATE "
4514 "at %L", name
, &do_code
->loc
);
4515 if (code
->ext
.omp_clauses
)
4516 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
4518 ? (list
!= OMP_LIST_PRIVATE
&& list
!= OMP_LIST_LASTPRIVATE
)
4519 : code
->ext
.omp_clauses
->collapse
> 1
4520 ? (list
!= OMP_LIST_LASTPRIVATE
)
4521 : (list
!= OMP_LIST_LINEAR
))
4522 for (n
= code
->ext
.omp_clauses
->lists
[list
]; n
; n
= n
->next
)
4523 if (dovar
== n
->sym
)
4526 gfc_error ("%s iteration variable present on clause "
4527 "other than PRIVATE or LASTPRIVATE at %L",
4528 name
, &do_code
->loc
);
4529 else if (code
->ext
.omp_clauses
->collapse
> 1)
4530 gfc_error ("%s iteration variable present on clause "
4531 "other than LASTPRIVATE at %L",
4532 name
, &do_code
->loc
);
4534 gfc_error ("%s iteration variable present on clause "
4535 "other than LINEAR at %L",
4536 name
, &do_code
->loc
);
4541 gfc_code
*do_code2
= code
->block
->next
;
4544 for (j
= 1; j
< i
; j
++)
4546 gfc_symbol
*ivar
= do_code2
->ext
.iterator
->var
->symtree
->n
.sym
;
4548 || gfc_find_sym_in_expr (ivar
, do_code
->ext
.iterator
->start
)
4549 || gfc_find_sym_in_expr (ivar
, do_code
->ext
.iterator
->end
)
4550 || gfc_find_sym_in_expr (ivar
, do_code
->ext
.iterator
->step
))
4552 gfc_error ("%s collapsed loops don't form rectangular "
4553 "iteration space at %L", name
, &do_code
->loc
);
4558 do_code2
= do_code2
->block
->next
;
4563 for (c
= do_code
->next
; c
; c
= c
->next
)
4564 if (c
->op
!= EXEC_NOP
&& c
->op
!= EXEC_CONTINUE
)
4566 gfc_error ("collapsed %s loops not perfectly nested at %L",
4572 do_code
= do_code
->block
;
4573 if (do_code
->op
!= EXEC_DO
&& do_code
->op
!= EXEC_DO_WHILE
)
4575 gfc_error ("not enough DO loops for collapsed %s at %L",
4579 do_code
= do_code
->next
;
4581 || (do_code
->op
!= EXEC_DO
&& do_code
->op
!= EXEC_DO_WHILE
))
4583 gfc_error ("not enough DO loops for collapsed %s at %L",
4591 oacc_is_parallel (gfc_code
*code
)
4593 return code
->op
== EXEC_OACC_PARALLEL
|| code
->op
== EXEC_OACC_PARALLEL_LOOP
;
4597 oacc_is_kernels (gfc_code
*code
)
4599 return code
->op
== EXEC_OACC_KERNELS
|| code
->op
== EXEC_OACC_KERNELS_LOOP
;
4602 static gfc_statement
4603 omp_code_to_statement (gfc_code
*code
)
4607 case EXEC_OMP_PARALLEL
:
4608 return ST_OMP_PARALLEL
;
4609 case EXEC_OMP_PARALLEL_SECTIONS
:
4610 return ST_OMP_PARALLEL_SECTIONS
;
4611 case EXEC_OMP_SECTIONS
:
4612 return ST_OMP_SECTIONS
;
4613 case EXEC_OMP_ORDERED
:
4614 return ST_OMP_ORDERED
;
4615 case EXEC_OMP_CRITICAL
:
4616 return ST_OMP_CRITICAL
;
4617 case EXEC_OMP_MASTER
:
4618 return ST_OMP_MASTER
;
4619 case EXEC_OMP_SINGLE
:
4620 return ST_OMP_SINGLE
;
4623 case EXEC_OMP_WORKSHARE
:
4624 return ST_OMP_WORKSHARE
;
4625 case EXEC_OMP_PARALLEL_WORKSHARE
:
4626 return ST_OMP_PARALLEL_WORKSHARE
;
4634 static gfc_statement
4635 oacc_code_to_statement (gfc_code
*code
)
4639 case EXEC_OACC_PARALLEL
:
4640 return ST_OACC_PARALLEL
;
4641 case EXEC_OACC_KERNELS
:
4642 return ST_OACC_KERNELS
;
4643 case EXEC_OACC_DATA
:
4644 return ST_OACC_DATA
;
4645 case EXEC_OACC_HOST_DATA
:
4646 return ST_OACC_HOST_DATA
;
4647 case EXEC_OACC_PARALLEL_LOOP
:
4648 return ST_OACC_PARALLEL_LOOP
;
4649 case EXEC_OACC_KERNELS_LOOP
:
4650 return ST_OACC_KERNELS_LOOP
;
4651 case EXEC_OACC_LOOP
:
4652 return ST_OACC_LOOP
;
4653 case EXEC_OACC_ATOMIC
:
4654 return ST_OACC_ATOMIC
;
4661 resolve_oacc_directive_inside_omp_region (gfc_code
*code
)
4663 if (omp_current_ctx
!= NULL
&& omp_current_ctx
->is_openmp
)
4665 gfc_statement st
= omp_code_to_statement (omp_current_ctx
->code
);
4666 gfc_statement oacc_st
= oacc_code_to_statement (code
);
4667 gfc_error ("The %s directive cannot be specified within "
4668 "a %s region at %L", gfc_ascii_statement (oacc_st
),
4669 gfc_ascii_statement (st
), &code
->loc
);
4674 resolve_omp_directive_inside_oacc_region (gfc_code
*code
)
4676 if (omp_current_ctx
!= NULL
&& !omp_current_ctx
->is_openmp
)
4678 gfc_statement st
= oacc_code_to_statement (omp_current_ctx
->code
);
4679 gfc_statement omp_st
= omp_code_to_statement (code
);
4680 gfc_error ("The %s directive cannot be specified within "
4681 "a %s region at %L", gfc_ascii_statement (omp_st
),
4682 gfc_ascii_statement (st
), &code
->loc
);
4688 resolve_oacc_nested_loops (gfc_code
*code
, gfc_code
* do_code
, int collapse
,
4695 for (i
= 1; i
<= collapse
; i
++)
4697 if (do_code
->op
== EXEC_DO_WHILE
)
4699 gfc_error ("!$ACC LOOP cannot be a DO WHILE or DO without loop control "
4700 "at %L", &do_code
->loc
);
4703 gcc_assert (do_code
->op
== EXEC_DO
|| do_code
->op
== EXEC_DO_CONCURRENT
);
4704 if (do_code
->ext
.iterator
->var
->ts
.type
!= BT_INTEGER
)
4705 gfc_error ("!$ACC LOOP iteration variable must be of type integer at %L",
4707 dovar
= do_code
->ext
.iterator
->var
->symtree
->n
.sym
;
4710 gfc_code
*do_code2
= code
->block
->next
;
4713 for (j
= 1; j
< i
; j
++)
4715 gfc_symbol
*ivar
= do_code2
->ext
.iterator
->var
->symtree
->n
.sym
;
4717 || gfc_find_sym_in_expr (ivar
, do_code
->ext
.iterator
->start
)
4718 || gfc_find_sym_in_expr (ivar
, do_code
->ext
.iterator
->end
)
4719 || gfc_find_sym_in_expr (ivar
, do_code
->ext
.iterator
->step
))
4721 gfc_error ("!$ACC LOOP %s loops don't form rectangular iteration space at %L",
4722 clause
, &do_code
->loc
);
4727 do_code2
= do_code2
->block
->next
;
4732 for (c
= do_code
->next
; c
; c
= c
->next
)
4733 if (c
->op
!= EXEC_NOP
&& c
->op
!= EXEC_CONTINUE
)
4735 gfc_error ("%s !$ACC LOOP loops not perfectly nested at %L",
4741 do_code
= do_code
->block
;
4742 if (do_code
->op
!= EXEC_DO
&& do_code
->op
!= EXEC_DO_WHILE
4743 && do_code
->op
!= EXEC_DO_CONCURRENT
)
4745 gfc_error ("not enough DO loops for %s !$ACC LOOP at %L",
4746 clause
, &code
->loc
);
4749 do_code
= do_code
->next
;
4751 || (do_code
->op
!= EXEC_DO
&& do_code
->op
!= EXEC_DO_WHILE
4752 && do_code
->op
!= EXEC_DO_CONCURRENT
))
4754 gfc_error ("not enough DO loops for %s !$ACC LOOP at %L",
4755 clause
, &code
->loc
);
4763 resolve_oacc_params_in_parallel (gfc_code
*code
, const char *clause
,
4766 fortran_omp_context
*c
;
4768 if (oacc_is_parallel (code
))
4769 gfc_error ("!$ACC LOOP %s in PARALLEL region doesn't allow "
4770 "%s arguments at %L", clause
, arg
, &code
->loc
);
4771 for (c
= omp_current_ctx
; c
; c
= c
->previous
)
4773 if (oacc_is_loop (c
->code
))
4775 if (oacc_is_parallel (c
->code
))
4776 gfc_error ("!$ACC LOOP %s in PARALLEL region doesn't allow "
4777 "%s arguments at %L", clause
, arg
, &code
->loc
);
4783 resolve_oacc_loop_blocks (gfc_code
*code
)
4785 fortran_omp_context
*c
;
4787 if (!oacc_is_loop (code
))
4790 if (code
->op
== EXEC_OACC_LOOP
)
4791 for (c
= omp_current_ctx
; c
; c
= c
->previous
)
4793 if (oacc_is_loop (c
->code
))
4795 if (code
->ext
.omp_clauses
->gang
)
4797 if (c
->code
->ext
.omp_clauses
->gang
)
4798 gfc_error ("Loop parallelized across gangs is not allowed "
4799 "inside another loop parallelized across gangs at %L",
4801 if (c
->code
->ext
.omp_clauses
->worker
)
4802 gfc_error ("Loop parallelized across gangs is not allowed "
4803 "inside loop parallelized across workers at %L",
4805 if (c
->code
->ext
.omp_clauses
->vector
)
4806 gfc_error ("Loop parallelized across gangs is not allowed "
4807 "inside loop parallelized across workers at %L",
4810 if (code
->ext
.omp_clauses
->worker
)
4812 if (c
->code
->ext
.omp_clauses
->worker
)
4813 gfc_error ("Loop parallelized across workers is not allowed "
4814 "inside another loop parallelized across workers at %L",
4816 if (c
->code
->ext
.omp_clauses
->vector
)
4817 gfc_error ("Loop parallelized across workers is not allowed "
4818 "inside another loop parallelized across vectors at %L",
4821 if (code
->ext
.omp_clauses
->vector
)
4822 if (c
->code
->ext
.omp_clauses
->vector
)
4823 gfc_error ("Loop parallelized across vectors is not allowed "
4824 "inside another loop parallelized across vectors at %L",
4828 if (oacc_is_parallel (c
->code
) || oacc_is_kernels (c
->code
))
4832 if (code
->ext
.omp_clauses
->seq
)
4834 if (code
->ext
.omp_clauses
->independent
)
4835 gfc_error ("Clause SEQ conflicts with INDEPENDENT at %L", &code
->loc
);
4836 if (code
->ext
.omp_clauses
->gang
)
4837 gfc_error ("Clause SEQ conflicts with GANG at %L", &code
->loc
);
4838 if (code
->ext
.omp_clauses
->worker
)
4839 gfc_error ("Clause SEQ conflicts with WORKER at %L", &code
->loc
);
4840 if (code
->ext
.omp_clauses
->vector
)
4841 gfc_error ("Clause SEQ conflicts with VECTOR at %L", &code
->loc
);
4842 if (code
->ext
.omp_clauses
->par_auto
)
4843 gfc_error ("Clause SEQ conflicts with AUTO at %L", &code
->loc
);
4845 if (code
->ext
.omp_clauses
->par_auto
)
4847 if (code
->ext
.omp_clauses
->gang
)
4848 gfc_error ("Clause AUTO conflicts with GANG at %L", &code
->loc
);
4849 if (code
->ext
.omp_clauses
->worker
)
4850 gfc_error ("Clause AUTO conflicts with WORKER at %L", &code
->loc
);
4851 if (code
->ext
.omp_clauses
->vector
)
4852 gfc_error ("Clause AUTO conflicts with VECTOR at %L", &code
->loc
);
4854 if (code
->ext
.omp_clauses
->tile_list
&& code
->ext
.omp_clauses
->gang
4855 && code
->ext
.omp_clauses
->worker
&& code
->ext
.omp_clauses
->vector
)
4856 gfc_error ("Tiled loop cannot be parallelized across gangs, workers and "
4857 "vectors at the same time at %L", &code
->loc
);
4859 if (code
->ext
.omp_clauses
->gang
4860 && code
->ext
.omp_clauses
->gang_num_expr
)
4861 resolve_oacc_params_in_parallel (code
, "GANG", "num");
4863 if (code
->ext
.omp_clauses
->worker
4864 && code
->ext
.omp_clauses
->worker_expr
)
4865 resolve_oacc_params_in_parallel (code
, "WORKER", "num");
4867 if (code
->ext
.omp_clauses
->vector
4868 && code
->ext
.omp_clauses
->vector_expr
)
4869 resolve_oacc_params_in_parallel (code
, "VECTOR", "length");
4871 if (code
->ext
.omp_clauses
->tile_list
)
4875 for (el
= code
->ext
.omp_clauses
->tile_list
; el
; el
= el
->next
)
4878 if (el
->expr
== NULL
)
4880 /* NULL expressions are used to represent '*' arguments.
4881 Convert those to a -1 expressions. */
4882 el
->expr
= gfc_get_constant_expr (BT_INTEGER
,
4883 gfc_default_integer_kind
,
4885 mpz_set_si (el
->expr
->value
.integer
, -1);
4889 resolve_oacc_positive_int_expr (el
->expr
, "TILE");
4890 if (el
->expr
->expr_type
!= EXPR_CONSTANT
)
4891 gfc_error ("TILE requires constant expression at %L",
4895 resolve_oacc_nested_loops (code
, code
->block
->next
, num
, "tiled");
4901 gfc_resolve_oacc_blocks (gfc_code
*code
, gfc_namespace
*ns
)
4903 fortran_omp_context ctx
;
4905 resolve_oacc_loop_blocks (code
);
4908 ctx
.sharing_clauses
= NULL
;
4909 ctx
.private_iterators
= new hash_set
<gfc_symbol
*>;
4910 ctx
.previous
= omp_current_ctx
;
4911 ctx
.is_openmp
= false;
4912 omp_current_ctx
= &ctx
;
4914 gfc_resolve_blocks (code
->block
, ns
);
4916 omp_current_ctx
= ctx
.previous
;
4917 delete ctx
.private_iterators
;
4922 resolve_oacc_loop (gfc_code
*code
)
4927 if (code
->ext
.omp_clauses
)
4928 resolve_omp_clauses (code
, code
->ext
.omp_clauses
, NULL
, true);
4930 do_code
= code
->block
->next
;
4931 collapse
= code
->ext
.omp_clauses
->collapse
;
4935 resolve_oacc_nested_loops (code
, do_code
, collapse
, "collapsed");
4939 gfc_resolve_oacc_declare (gfc_namespace
*ns
)
4942 gfc_omp_namelist
*n
;
4943 gfc_oacc_declare
*oc
;
4945 if (ns
->oacc_declare
== NULL
)
4948 for (oc
= ns
->oacc_declare
; oc
; oc
= oc
->next
)
4950 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
4951 for (n
= oc
->clauses
->lists
[list
]; n
; n
= n
->next
)
4954 if (n
->sym
->attr
.flavor
== FL_PARAMETER
)
4956 gfc_error ("PARAMETER object %qs is not allowed at %L",
4957 n
->sym
->name
, &oc
->loc
);
4961 if (n
->expr
&& n
->expr
->ref
->type
== REF_ARRAY
)
4963 gfc_error ("Array sections: %qs not allowed in"
4964 " $!ACC DECLARE at %L", n
->sym
->name
, &oc
->loc
);
4969 for (n
= oc
->clauses
->lists
[OMP_LIST_DEVICE_RESIDENT
]; n
; n
= n
->next
)
4970 check_array_not_assumed (n
->sym
, oc
->loc
, "DEVICE_RESIDENT");
4973 for (oc
= ns
->oacc_declare
; oc
; oc
= oc
->next
)
4975 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
4976 for (n
= oc
->clauses
->lists
[list
]; n
; n
= n
->next
)
4980 gfc_error ("Symbol %qs present on multiple clauses at %L",
4981 n
->sym
->name
, &oc
->loc
);
4989 for (oc
= ns
->oacc_declare
; oc
; oc
= oc
->next
)
4991 for (list
= 0; list
< OMP_LIST_NUM
; list
++)
4992 for (n
= oc
->clauses
->lists
[list
]; n
; n
= n
->next
)
4998 gfc_resolve_oacc_directive (gfc_code
*code
, gfc_namespace
*ns ATTRIBUTE_UNUSED
)
5000 resolve_oacc_directive_inside_omp_region (code
);
5004 case EXEC_OACC_PARALLEL
:
5005 case EXEC_OACC_KERNELS
:
5006 case EXEC_OACC_DATA
:
5007 case EXEC_OACC_HOST_DATA
:
5008 case EXEC_OACC_UPDATE
:
5009 case EXEC_OACC_ENTER_DATA
:
5010 case EXEC_OACC_EXIT_DATA
:
5011 case EXEC_OACC_WAIT
:
5012 case EXEC_OACC_CACHE
:
5013 resolve_omp_clauses (code
, code
->ext
.omp_clauses
, NULL
, true);
5015 case EXEC_OACC_PARALLEL_LOOP
:
5016 case EXEC_OACC_KERNELS_LOOP
:
5017 case EXEC_OACC_LOOP
:
5018 resolve_oacc_loop (code
);
5020 case EXEC_OACC_ATOMIC
:
5021 resolve_omp_atomic (code
);
5029 /* Resolve OpenMP directive clauses and check various requirements
5030 of each directive. */
5033 gfc_resolve_omp_directive (gfc_code
*code
, gfc_namespace
*ns ATTRIBUTE_UNUSED
)
5035 resolve_omp_directive_inside_oacc_region (code
);
5037 if (code
->op
!= EXEC_OMP_ATOMIC
)
5038 gfc_maybe_initialize_eh ();
5042 case EXEC_OMP_DISTRIBUTE
:
5043 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO
:
5044 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD
:
5045 case EXEC_OMP_DISTRIBUTE_SIMD
:
5047 case EXEC_OMP_DO_SIMD
:
5048 case EXEC_OMP_PARALLEL_DO
:
5049 case EXEC_OMP_PARALLEL_DO_SIMD
:
5051 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE
:
5052 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO
:
5053 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
5054 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD
:
5055 case EXEC_OMP_TEAMS_DISTRIBUTE
:
5056 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO
:
5057 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
5058 case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD
:
5059 resolve_omp_do (code
);
5061 case EXEC_OMP_CANCEL
:
5062 case EXEC_OMP_PARALLEL_WORKSHARE
:
5063 case EXEC_OMP_PARALLEL
:
5064 case EXEC_OMP_PARALLEL_SECTIONS
:
5065 case EXEC_OMP_SECTIONS
:
5066 case EXEC_OMP_SINGLE
:
5067 case EXEC_OMP_TARGET
:
5068 case EXEC_OMP_TARGET_DATA
:
5069 case EXEC_OMP_TARGET_TEAMS
:
5071 case EXEC_OMP_TEAMS
:
5072 case EXEC_OMP_WORKSHARE
:
5073 if (code
->ext
.omp_clauses
)
5074 resolve_omp_clauses (code
, code
->ext
.omp_clauses
, NULL
);
5076 case EXEC_OMP_TARGET_UPDATE
:
5077 if (code
->ext
.omp_clauses
)
5078 resolve_omp_clauses (code
, code
->ext
.omp_clauses
, NULL
);
5079 if (code
->ext
.omp_clauses
== NULL
5080 || (code
->ext
.omp_clauses
->lists
[OMP_LIST_TO
] == NULL
5081 && code
->ext
.omp_clauses
->lists
[OMP_LIST_FROM
] == NULL
))
5082 gfc_error ("OMP TARGET UPDATE at %L requires at least one TO or "
5083 "FROM clause", &code
->loc
);
5085 case EXEC_OMP_ATOMIC
:
5086 resolve_omp_atomic (code
);
5093 /* Resolve !$omp declare simd constructs in NS. */
5096 gfc_resolve_omp_declare_simd (gfc_namespace
*ns
)
5098 gfc_omp_declare_simd
*ods
;
5100 for (ods
= ns
->omp_declare_simd
; ods
; ods
= ods
->next
)
5102 if (ods
->proc_name
!= ns
->proc_name
)
5103 gfc_error ("!$OMP DECLARE SIMD should refer to containing procedure "
5104 "%qs at %L", ns
->proc_name
->name
, &ods
->where
);
5106 resolve_omp_clauses (NULL
, ods
->clauses
, ns
);
5110 struct omp_udr_callback_data
5112 gfc_omp_udr
*omp_udr
;
5113 bool is_initializer
;
5117 omp_udr_callback (gfc_expr
**e
, int *walk_subtrees ATTRIBUTE_UNUSED
,
5120 struct omp_udr_callback_data
*cd
= (struct omp_udr_callback_data
*) data
;
5121 if ((*e
)->expr_type
== EXPR_VARIABLE
)
5123 if (cd
->is_initializer
)
5125 if ((*e
)->symtree
->n
.sym
!= cd
->omp_udr
->omp_priv
5126 && (*e
)->symtree
->n
.sym
!= cd
->omp_udr
->omp_orig
)
5127 gfc_error ("Variable other than OMP_PRIV or OMP_ORIG used in "
5128 "INITIALIZER clause of !$OMP DECLARE REDUCTION at %L",
5133 if ((*e
)->symtree
->n
.sym
!= cd
->omp_udr
->omp_out
5134 && (*e
)->symtree
->n
.sym
!= cd
->omp_udr
->omp_in
)
5135 gfc_error ("Variable other than OMP_OUT or OMP_IN used in "
5136 "combiner of !$OMP DECLARE REDUCTION at %L",
5143 /* Resolve !$omp declare reduction constructs. */
5146 gfc_resolve_omp_udr (gfc_omp_udr
*omp_udr
)
5148 gfc_actual_arglist
*a
;
5149 const char *predef_name
= NULL
;
5151 switch (omp_udr
->rop
)
5153 case OMP_REDUCTION_PLUS
:
5154 case OMP_REDUCTION_TIMES
:
5155 case OMP_REDUCTION_MINUS
:
5156 case OMP_REDUCTION_AND
:
5157 case OMP_REDUCTION_OR
:
5158 case OMP_REDUCTION_EQV
:
5159 case OMP_REDUCTION_NEQV
:
5160 case OMP_REDUCTION_MAX
:
5161 case OMP_REDUCTION_USER
:
5164 gfc_error ("Invalid operator for !$OMP DECLARE REDUCTION %s at %L",
5165 omp_udr
->name
, &omp_udr
->where
);
5169 if (gfc_omp_udr_predef (omp_udr
->rop
, omp_udr
->name
,
5170 &omp_udr
->ts
, &predef_name
))
5173 gfc_error_now ("Redefinition of predefined %s "
5174 "!$OMP DECLARE REDUCTION at %L",
5175 predef_name
, &omp_udr
->where
);
5177 gfc_error_now ("Redefinition of predefined "
5178 "!$OMP DECLARE REDUCTION at %L", &omp_udr
->where
);
5182 if (omp_udr
->ts
.type
== BT_CHARACTER
5183 && omp_udr
->ts
.u
.cl
->length
5184 && omp_udr
->ts
.u
.cl
->length
->expr_type
!= EXPR_CONSTANT
)
5186 gfc_error ("CHARACTER length in !$OMP DECLARE REDUCTION %s not "
5187 "constant at %L", omp_udr
->name
, &omp_udr
->where
);
5191 struct omp_udr_callback_data cd
;
5192 cd
.omp_udr
= omp_udr
;
5193 cd
.is_initializer
= false;
5194 gfc_code_walker (&omp_udr
->combiner_ns
->code
, gfc_dummy_code_callback
,
5195 omp_udr_callback
, &cd
);
5196 if (omp_udr
->combiner_ns
->code
->op
== EXEC_CALL
)
5198 for (a
= omp_udr
->combiner_ns
->code
->ext
.actual
; a
; a
= a
->next
)
5199 if (a
->expr
== NULL
)
5202 gfc_error ("Subroutine call with alternate returns in combiner "
5203 "of !$OMP DECLARE REDUCTION at %L",
5204 &omp_udr
->combiner_ns
->code
->loc
);
5206 if (omp_udr
->initializer_ns
)
5208 cd
.is_initializer
= true;
5209 gfc_code_walker (&omp_udr
->initializer_ns
->code
, gfc_dummy_code_callback
,
5210 omp_udr_callback
, &cd
);
5211 if (omp_udr
->initializer_ns
->code
->op
== EXEC_CALL
)
5213 for (a
= omp_udr
->initializer_ns
->code
->ext
.actual
; a
; a
= a
->next
)
5214 if (a
->expr
== NULL
)
5217 gfc_error ("Subroutine call with alternate returns in "
5218 "INITIALIZER clause of !$OMP DECLARE REDUCTION "
5219 "at %L", &omp_udr
->initializer_ns
->code
->loc
);
5220 for (a
= omp_udr
->initializer_ns
->code
->ext
.actual
; a
; a
= a
->next
)
5222 && a
->expr
->expr_type
== EXPR_VARIABLE
5223 && a
->expr
->symtree
->n
.sym
== omp_udr
->omp_priv
5224 && a
->expr
->ref
== NULL
)
5227 gfc_error ("One of actual subroutine arguments in INITIALIZER "
5228 "clause of !$OMP DECLARE REDUCTION must be OMP_PRIV "
5229 "at %L", &omp_udr
->initializer_ns
->code
->loc
);
5232 else if (omp_udr
->ts
.type
== BT_DERIVED
5233 && !gfc_has_default_initializer (omp_udr
->ts
.u
.derived
))
5235 gfc_error ("Missing INITIALIZER clause for !$OMP DECLARE REDUCTION "
5236 "of derived type without default initializer at %L",
5243 gfc_resolve_omp_udrs (gfc_symtree
*st
)
5245 gfc_omp_udr
*omp_udr
;
5249 gfc_resolve_omp_udrs (st
->left
);
5250 gfc_resolve_omp_udrs (st
->right
);
5251 for (omp_udr
= st
->n
.omp_udr
; omp_udr
; omp_udr
= omp_udr
->next
)
5252 gfc_resolve_omp_udr (omp_udr
);