diff --git a/gcc/fortran/array.c b/gcc/fortran/array.c index 46642bb5d978a..dc1d272dd0af0 100644 --- a/gcc/fortran/array.c +++ b/gcc/fortran/array.c @@ -158,7 +158,8 @@ gfc_match_array_ref (gfc_array_ref *ar, gfc_array_spec *as, int init, bool matched_bracket = false; gfc_expr *tmp; bool stat_just_seen = false; - + bool team_just_seen = false; + memset (ar, '\0', sizeof (*ar)); ar->where = gfc_current_locus; @@ -230,7 +231,21 @@ gfc_match_array_ref (gfc_array_ref *ar, gfc_array_spec *as, int init, if (m == MATCH_ERROR) return MATCH_ERROR; + team_just_seen = false; stat_just_seen = false; + + if (gfc_match(" , team = %e",&tmp) == MATCH_YES && ar->stat == NULL) + { + ar->team = tmp; + team_just_seen = true; + } + + if (ar->team && !team_just_seen) + { + gfc_error ("TEAM= attribute in %C misplaced"); + return MATCH_ERROR; + } + if (gfc_match(" , stat = %e",&tmp) == MATCH_YES && ar->stat == NULL) { ar->stat = tmp; diff --git a/gcc/fortran/check.c b/gcc/fortran/check.c index e85e398cd4330..ab1985d8816c6 100644 --- a/gcc/fortran/check.c +++ b/gcc/fortran/check.c @@ -1213,6 +1213,20 @@ gfc_check_failed_or_stopped_images (gfc_expr *team, gfc_expr *kind) return true; } +bool +gfc_check_get_team (gfc_expr *level) +{ + if (level) + { + gfc_error ("%qs argument of %qs intrinsic at %L not yet supported", + gfc_current_intrinsic_arg[0]->name, gfc_current_intrinsic, + &level->where); + return false; + } + + return true; +} + bool gfc_check_atomic_cas (gfc_expr *atom, gfc_expr *old, gfc_expr *compare, diff --git a/gcc/fortran/dump-parse-tree.c b/gcc/fortran/dump-parse-tree.c index a0098d70743b8..f2c3cb82e8009 100644 --- a/gcc/fortran/dump-parse-tree.c +++ b/gcc/fortran/dump-parse-tree.c @@ -1860,6 +1860,22 @@ show_code_node (int level, gfc_code *c) fputs ("FAIL IMAGE ", dumpfile); break; + case EXEC_CHANGE_TEAM: + fputs ("CHANGE TEAM", dumpfile); + break; + + case EXEC_END_TEAM: + fputs ("END TEAM", dumpfile); + break; + + case EXEC_FORM_TEAM: + fputs ("FORM TEAM", dumpfile); + break; + + case EXEC_SYNC_TEAM: + fputs ("SYNC TEAM", dumpfile); + break; + case EXEC_SYNC_ALL: fputs ("SYNC ALL ", dumpfile); if (c->expr2 != NULL) diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c index bfbb19ee577fa..05b0b8286f09e 100644 --- a/gcc/fortran/expr.c +++ b/gcc/fortran/expr.c @@ -4974,6 +4974,24 @@ gfc_ref_this_image (gfc_ref *ref) return true; } +gfc_expr * +gfc_find_team_co(gfc_expr *e) +{ + gfc_ref *ref; + + for (ref = e->ref; ref; ref = ref->next) + if (ref->type == REF_ARRAY && ref->u.ar.codimen > 0) + return ref->u.ar.team; + + if (e->value.function.actual->expr) + for (ref = e->value.function.actual->expr->ref; ref; + ref = ref->next) + if (ref->type == REF_ARRAY && ref->u.ar.codimen > 0) + return ref->u.ar.team; + + return NULL; +} + gfc_expr * gfc_find_stat_co(gfc_expr *e) { diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index 18a534d3c9d6f..2fdc9ea047780 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -263,7 +263,8 @@ enum gfc_statement ST_OMP_TASKLOOP_SIMD, ST_OMP_END_TASKLOOP_SIMD, ST_OMP_ORDERED_DEPEND, ST_PROCEDURE, ST_GENERIC, ST_CRITICAL, ST_END_CRITICAL, ST_GET_FCN_CHARACTERISTICS, ST_LOCK, ST_UNLOCK, ST_EVENT_POST, - ST_EVENT_WAIT,ST_FAIL_IMAGE,ST_NONE + ST_EVENT_WAIT, ST_FAIL_IMAGE, ST_FORM_TEAM, ST_CHANGE_TEAM, + ST_END_TEAM, ST_SYNC_TEAM, ST_NONE }; /* Types of interfaces that we can have. Assignment interfaces are @@ -456,6 +457,7 @@ enum gfc_isym_id GFC_ISYM_GETLOG, GFC_ISYM_GETPID, GFC_ISYM_GETUID, + GFC_ISYM_GET_TEAM, GFC_ISYM_GMTIME, GFC_ISYM_HOSTNM, GFC_ISYM_HUGE, @@ -1913,6 +1915,7 @@ typedef struct gfc_array_ref int dimen; /* # of components in the reference */ int codimen; bool in_allocate; /* For coarray checks. */ + gfc_expr *team; gfc_expr *stat; locus where; gfc_array_spec *as; @@ -2488,6 +2491,7 @@ enum gfc_exec_op EXEC_OPEN, EXEC_CLOSE, EXEC_WAIT, EXEC_READ, EXEC_WRITE, EXEC_IOLENGTH, EXEC_TRANSFER, EXEC_DT_END, EXEC_BACKSPACE, EXEC_ENDFILE, EXEC_INQUIRE, EXEC_REWIND, EXEC_FLUSH, + EXEC_FORM_TEAM, EXEC_CHANGE_TEAM, EXEC_END_TEAM, EXEC_SYNC_TEAM, EXEC_LOCK, EXEC_UNLOCK, EXEC_EVENT_POST, EXEC_EVENT_WAIT, EXEC_FAIL_IMAGE, EXEC_OACC_KERNELS_LOOP, EXEC_OACC_PARALLEL_LOOP, EXEC_OACC_ROUTINE, EXEC_OACC_PARALLEL, EXEC_OACC_KERNELS, EXEC_OACC_DATA, EXEC_OACC_HOST_DATA, @@ -3190,6 +3194,7 @@ bool gfc_is_coarray (gfc_expr *); int gfc_get_corank (gfc_expr *); bool gfc_has_ultimate_allocatable (gfc_expr *); bool gfc_has_ultimate_pointer (gfc_expr *); +gfc_expr* gfc_find_team_co (gfc_expr *); gfc_expr* gfc_find_stat_co (gfc_expr *); gfc_expr* gfc_build_intrinsic_call (gfc_namespace *, gfc_isym_id, const char*, locus, unsigned, ...); diff --git a/gcc/fortran/intrinsic.c b/gcc/fortran/intrinsic.c index 8965d509882bc..a2bb0d97a20e9 100644 --- a/gcc/fortran/intrinsic.c +++ b/gcc/fortran/intrinsic.c @@ -1938,6 +1938,13 @@ add_functions (void) make_generic ("getpid", GFC_ISYM_GETPID, GFC_STD_GNU); + add_sym_1 ("get_team", GFC_ISYM_GET_TEAM, CLASS_TRANSFORMATIONAL, + ACTUAL_NO, BT_INTEGER, di, GFC_STD_F2008_TS, + gfc_check_get_team, + NULL, + gfc_resolve_get_team, + "level", BT_INTEGER, di, OPTIONAL); + add_sym_0 ("getuid", GFC_ISYM_GETUID, CLASS_IMPURE, ACTUAL_NO, BT_INTEGER, di, GFC_STD_GNU, NULL, NULL, gfc_resolve_getuid); diff --git a/gcc/fortran/intrinsic.h b/gcc/fortran/intrinsic.h index e8280f6f2ac38..89b34c0dd9d2c 100644 --- a/gcc/fortran/intrinsic.h +++ b/gcc/fortran/intrinsic.h @@ -83,6 +83,7 @@ bool gfc_check_fn_r (gfc_expr *); bool gfc_check_fn_rc (gfc_expr *); bool gfc_check_fn_rc2008 (gfc_expr *); bool gfc_check_fnum (gfc_expr *); +bool gfc_check_get_team (gfc_expr *); bool gfc_check_hostnm (gfc_expr *); bool gfc_check_huge (gfc_expr *); bool gfc_check_hypot (gfc_expr *, gfc_expr *); @@ -299,6 +300,7 @@ gfc_expr *gfc_simplify_float (gfc_expr *); gfc_expr *gfc_simplify_floor (gfc_expr *, gfc_expr *); gfc_expr *gfc_simplify_fraction (gfc_expr *); gfc_expr *gfc_simplify_gamma (gfc_expr *); +gfc_expr *gfc_simplify_get_team (gfc_expr *); gfc_expr *gfc_simplify_huge (gfc_expr *); gfc_expr *gfc_simplify_hypot (gfc_expr *, gfc_expr *); gfc_expr *gfc_simplify_iachar (gfc_expr *, gfc_expr *); @@ -493,6 +495,7 @@ void gfc_resolve_gamma (gfc_expr *, gfc_expr *); void gfc_resolve_getcwd (gfc_expr *, gfc_expr *); void gfc_resolve_getgid (gfc_expr *); void gfc_resolve_getpid (gfc_expr *); +void gfc_resolve_get_team (gfc_expr *, gfc_expr *); void gfc_resolve_getuid (gfc_expr *); void gfc_resolve_hostnm (gfc_expr *, gfc_expr *); void gfc_resolve_hypot (gfc_expr *, gfc_expr *, gfc_expr *); diff --git a/gcc/fortran/iresolve.c b/gcc/fortran/iresolve.c index b784ac339e964..4c3f6e3f6a9ba 100644 --- a/gcc/fortran/iresolve.c +++ b/gcc/fortran/iresolve.c @@ -2859,6 +2859,18 @@ gfc_resolve_image_status (gfc_expr *f, gfc_expr *image ATTRIBUTE_UNUSED, f->value.function.name = image_status; } +/* Resolve get_team (). */ + +void +gfc_resolve_get_team (gfc_expr *f, gfc_expr *level ATTRIBUTE_UNUSED) +{ + static char get_team[] = "_gfortran_caf_get_team"; + f->rank = 0; + f->ts.type = BT_INTEGER; + f->ts.kind = gfc_default_integer_kind; + f->value.function.name = get_team; +} + /* Resolve image_index (...). */ diff --git a/gcc/fortran/iso-fortran-env.def b/gcc/fortran/iso-fortran-env.def index 8e231a6330a8b..9a2df57c6c9a6 100644 --- a/gcc/fortran/iso-fortran-env.def +++ b/gcc/fortran/iso-fortran-env.def @@ -125,7 +125,12 @@ NAMED_DERIVED_TYPE (ISOFORTRAN_LOCK_TYPE, "lock_type", \ NAMED_DERIVED_TYPE (ISOFORTRAN_EVENT_TYPE, "event_type", \ flag_coarray == GFC_FCOARRAY_LIB - ? get_int_kind_from_node (ptr_type_node) + ? get_int_kind_from_node (ptr_type_node) + : gfc_default_integer_kind, GFC_STD_F2008_TS) + +NAMED_DERIVED_TYPE (ISOFORTRAN_TEAM_TYPE, "team_type", \ + flag_coarray == GFC_FCOARRAY_LIB + ? get_int_kind_from_node (ptr_type_node) : gfc_default_integer_kind, GFC_STD_F2008_TS) #undef NAMED_INTCST diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c index 4d657e0bc345c..fb20bcd1a3a78 100644 --- a/gcc/fortran/match.c +++ b/gcc/fortran/match.c @@ -1595,16 +1595,19 @@ gfc_match_if (gfc_statement *if_type) match ("assign", gfc_match_assign, ST_LABEL_ASSIGNMENT) match ("backspace", gfc_match_backspace, ST_BACKSPACE) match ("call", gfc_match_call, ST_CALL) + match ("change team", gfc_match_change_team, ST_CHANGE_TEAM) match ("close", gfc_match_close, ST_CLOSE) match ("continue", gfc_match_continue, ST_CONTINUE) match ("cycle", gfc_match_cycle, ST_CYCLE) match ("deallocate", gfc_match_deallocate, ST_DEALLOCATE) match ("end file", gfc_match_endfile, ST_END_FILE) + match ("end team", gfc_match_end_team, ST_END_TEAM) match ("error stop", gfc_match_error_stop, ST_ERROR_STOP) match ("event post", gfc_match_event_post, ST_EVENT_POST) match ("event wait", gfc_match_event_wait, ST_EVENT_WAIT) match ("exit", gfc_match_exit, ST_EXIT) match ("fail image", gfc_match_fail_image, ST_FAIL_IMAGE) + match ("form team", gfc_match_form_team, ST_FORM_TEAM) match ("flush", gfc_match_flush, ST_FLUSH) match ("forall", match_simple_forall, ST_FORALL) match ("go to", gfc_match_goto, ST_GOTO) @@ -1620,6 +1623,7 @@ gfc_match_if (gfc_statement *if_type) match ("rewind", gfc_match_rewind, ST_REWIND) match ("stop", gfc_match_stop, ST_STOP) match ("wait", gfc_match_wait, ST_WAIT) + match ("sync team", gfc_match_sync_team, ST_SYNC_TEAM) match ("sync all", gfc_match_sync_all, ST_SYNC_CALL); match ("sync images", gfc_match_sync_images, ST_SYNC_IMAGES); match ("sync memory", gfc_match_sync_memory, ST_SYNC_MEMORY); @@ -1659,7 +1663,6 @@ gfc_match_if (gfc_statement *if_type) gfc_free_expr (expr); return MATCH_ERROR; } - /* At this point, we've matched the single IF and the action clause is in new_st. Rearrange things so that the IF statement appears in new_st. */ @@ -3343,6 +3346,136 @@ gfc_match_fail_image (void) return MATCH_ERROR; } +/* Match a FORM TEAM statement. */ + +match +gfc_match_form_team (void) +{ + match m; + gfc_expr *teamid,*team; + + if (!gfc_notify_std (GFC_STD_F2008_TS, "FORM TEAM statement at %C")) + return MATCH_ERROR; + + if (gfc_match_char ('(') == MATCH_NO) + goto syntax; + + new_st.op = EXEC_FORM_TEAM; + + if (gfc_match ("%e", &teamid) != MATCH_YES) + goto syntax; + m = gfc_match_char (','); + if (m == MATCH_ERROR) + goto syntax; + if (gfc_match ("%e", &team) != MATCH_YES) + goto syntax; + + m = gfc_match_char (')'); + if (m == MATCH_NO) + goto syntax; + + new_st.expr1 = teamid; + new_st.expr2 = team; + + return MATCH_YES; + +syntax: + gfc_syntax_error (ST_FORM_TEAM); + + return MATCH_ERROR; +} + +/* Match a CHANGE TEAM statement. */ + +match +gfc_match_change_team (void) +{ + match m; + gfc_expr *team; + + if (!gfc_notify_std (GFC_STD_F2008_TS, "CHANGE TEAM statement at %C")) + return MATCH_ERROR; + + if (gfc_match_char ('(') == MATCH_NO) + goto syntax; + + new_st.op = EXEC_CHANGE_TEAM; + + /* if (gfc_match ("%e", &teamid) != MATCH_YES) */ + /* goto syntax; */ + /* m = gfc_match_char (','); */ + /* if (m == MATCH_ERROR) */ + /* goto syntax; */ + if (gfc_match ("%e", &team) != MATCH_YES) + goto syntax; + + m = gfc_match_char (')'); + if (m == MATCH_NO) + goto syntax; + + new_st.expr1 = team; + + return MATCH_YES; + +syntax: + gfc_syntax_error (ST_CHANGE_TEAM); + + return MATCH_ERROR; +} + +/* Match a END TEAM statement. */ + +match +gfc_match_end_team (void) +{ + if (!gfc_notify_std (GFC_STD_F2008_TS, "END TEAM statement at %C")) + return MATCH_ERROR; + + if (gfc_match_char ('(') == MATCH_YES) + goto syntax; + + new_st.op = EXEC_END_TEAM; + + return MATCH_YES; + +syntax: + gfc_syntax_error (ST_END_TEAM); + + return MATCH_ERROR; +} + +/* Match a SYNC TEAM statement. */ + +match +gfc_match_sync_team (void) +{ + match m; + gfc_expr *team; + + if (!gfc_notify_std (GFC_STD_F2008_TS, "SYNC TEAM statement at %C")) + return MATCH_ERROR; + + if (gfc_match_char ('(') == MATCH_NO) + goto syntax; + + new_st.op = EXEC_SYNC_TEAM; + + if (gfc_match ("%e", &team) != MATCH_YES) + goto syntax; + + m = gfc_match_char (')'); + if (m == MATCH_NO) + goto syntax; + + new_st.expr1 = team; + + return MATCH_YES; + +syntax: + gfc_syntax_error (ST_SYNC_TEAM); + + return MATCH_ERROR; +} /* Match LOCK/UNLOCK statement. Syntax: LOCK ( lock-variable [ , lock-stat-list ] ) diff --git a/gcc/fortran/match.h b/gcc/fortran/match.h index d6df349532c3b..4f8ba990b63cd 100644 --- a/gcc/fortran/match.h +++ b/gcc/fortran/match.h @@ -74,6 +74,10 @@ match gfc_match_event_post (void); match gfc_match_event_wait (void); match gfc_match_critical (void); match gfc_match_fail_image (void); +match gfc_match_change_team (void); +match gfc_match_end_team (void); +match gfc_match_form_team (void); +match gfc_match_sync_team (void); match gfc_match_block (void); match gfc_match_associate (void); match gfc_match_do (void); diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c index eb0f92e734b11..d65ca27b9ca57 100644 --- a/gcc/fortran/parse.c +++ b/gcc/fortran/parse.c @@ -451,6 +451,7 @@ decode_statement (void) case 'c': match ("call", gfc_match_call, ST_CALL); + match ("change team", gfc_match_change_team, ST_CHANGE_TEAM); match ("close", gfc_match_close, ST_CLOSE); match ("continue", gfc_match_continue, ST_CONTINUE); match ("contiguous", gfc_match_contiguous, ST_ATTR_DECL); @@ -470,6 +471,7 @@ decode_statement (void) case 'e': match ("end file", gfc_match_endfile, ST_END_FILE); + match ("end team", gfc_match_end_team, ST_END_TEAM); match ("exit", gfc_match_exit, ST_EXIT); match ("else", gfc_match_else, ST_ELSE); match ("else where", gfc_match_elsewhere, ST_ELSEWHERE); @@ -491,6 +493,7 @@ decode_statement (void) match ("fail image", gfc_match_fail_image, ST_FAIL_IMAGE); match ("final", gfc_match_final_decl, ST_FINAL); match ("flush", gfc_match_flush, ST_FLUSH); + match ("form team", gfc_match_form_team, ST_FORM_TEAM); match ("format", gfc_match_format, ST_FORMAT); break; @@ -558,6 +561,7 @@ decode_statement (void) match ("sync all", gfc_match_sync_all, ST_SYNC_ALL); match ("sync images", gfc_match_sync_images, ST_SYNC_IMAGES); match ("sync memory", gfc_match_sync_memory, ST_SYNC_MEMORY); + match ("sync team", gfc_match_sync_team, ST_SYNC_TEAM); break; case 't': @@ -587,7 +591,7 @@ decode_statement (void) if (!gfc_error_check ()) gfc_error_now ("Unclassifiable statement at %C"); - + reject_statement (); gfc_error_recovery (); @@ -1501,7 +1505,10 @@ next_statement (void) case ST_OMP_TARGET_UPDATE: case ST_OMP_TARGET_ENTER_DATA: \ case ST_OMP_TARGET_EXIT_DATA: case ST_OMP_ORDERED_DEPEND: \ case ST_ERROR_STOP: case ST_SYNC_ALL: \ - case ST_SYNC_IMAGES: case ST_SYNC_MEMORY: case ST_LOCK: case ST_UNLOCK: \ + case ST_SYNC_IMAGES: case ST_SYNC_MEMORY: \ + case ST_LOCK: case ST_UNLOCK: \ + case ST_FORM_TEAM: case ST_CHANGE_TEAM: \ + case ST_END_TEAM: case ST_SYNC_TEAM: \ case ST_EVENT_POST: case ST_EVENT_WAIT: case ST_FAIL_IMAGE: \ case ST_OACC_UPDATE: case ST_OACC_WAIT: case ST_OACC_CACHE: \ case ST_OACC_ENTER_DATA: case ST_OACC_EXIT_DATA @@ -1833,6 +1840,18 @@ gfc_ascii_statement (gfc_statement st) case ST_FAIL_IMAGE: p = "FAIL IMAGE"; break; + case ST_CHANGE_TEAM: + p = "CHANGE TEAM"; + break; + case ST_END_TEAM: + p = "END TEAM"; + break; + case ST_FORM_TEAM: + p = "FORM TEAM"; + break; + case ST_SYNC_TEAM: + p = "SYNC TEAM"; + break; case ST_END_ASSOCIATE: p = "END ASSOCIATE"; break; diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c index e6f95d513d34d..0a9811541ea2b 100644 --- a/gcc/fortran/resolve.c +++ b/gcc/fortran/resolve.c @@ -11001,6 +11001,18 @@ gfc_resolve_code (gfc_code *code, gfc_namespace *ns) case EXEC_FAIL_IMAGE: break; + case EXEC_FORM_TEAM: + break; + + case EXEC_CHANGE_TEAM: + break; + + case EXEC_END_TEAM: + break; + + case EXEC_SYNC_TEAM: + break; + case EXEC_ENTRY: /* Keep track of which entry we are up to. */ current_entry_id = code->ext.entry->id; diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c index 169aef1d89238..17d77e9a6c6ef 100644 --- a/gcc/fortran/simplify.c +++ b/gcc/fortran/simplify.c @@ -2495,6 +2495,28 @@ gfc_simplify_failed_or_stopped_images (gfc_expr *team ATTRIBUTE_UNUSED, return NULL; } +gfc_expr * +gfc_simplify_get_team (gfc_expr *level ATTRIBUTE_UNUSED) +{ + if (flag_coarray == GFC_FCOARRAY_NONE) + { + gfc_current_locus = *gfc_current_intrinsic_where; + gfc_fatal_error ("Coarrays disabled at %C, use %<-fcoarray=%> to enable"); + return &gfc_bad_expr; + } + + if (flag_coarray == GFC_FCOARRAY_SINGLE) + { + gfc_expr *result; + result = gfc_get_array_expr (BT_INTEGER, gfc_default_integer_kind, &gfc_current_locus); + result->rank = 0; + return result; + } + + /* For fcoarray = lib no simplification is possible, because it is not known + what images failed or are stopped at compile time. */ + return NULL; +} gfc_expr * gfc_simplify_float (gfc_expr *a) diff --git a/gcc/fortran/st.c b/gcc/fortran/st.c index bffe50df7b819..a2699b7a074fe 100644 --- a/gcc/fortran/st.c +++ b/gcc/fortran/st.c @@ -121,6 +121,10 @@ gfc_free_statement (gfc_code *p) case EXEC_EVENT_POST: case EXEC_EVENT_WAIT: case EXEC_FAIL_IMAGE: + case EXEC_CHANGE_TEAM: + case EXEC_END_TEAM: + case EXEC_FORM_TEAM: + case EXEC_SYNC_TEAM: break; case EXEC_BLOCK: diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c index b4f515f21d955..e0ff9e40abae6 100644 --- a/gcc/fortran/trans-decl.c +++ b/gcc/fortran/trans-decl.c @@ -157,6 +157,11 @@ tree gfor_fndecl_caf_fail_image; tree gfor_fndecl_caf_failed_images; tree gfor_fndecl_caf_image_status; tree gfor_fndecl_caf_stopped_images; +tree gfor_fndecl_caf_form_team; +tree gfor_fndecl_caf_change_team; +tree gfor_fndecl_caf_end_team; +tree gfor_fndecl_caf_sync_team; +tree gfor_fndecl_caf_get_team; tree gfor_fndecl_co_broadcast; tree gfor_fndecl_co_max; tree gfor_fndecl_co_min; @@ -3637,10 +3642,10 @@ gfc_build_builtin_function_decls (void) boolean_type_node, pint_type); gfor_fndecl_caf_send = gfc_build_library_function_decl_with_spec ( - get_identifier (PREFIX("caf_send")), ".R.RRRRRRW", void_type_node, 10, + get_identifier (PREFIX("caf_send")), ".R.RRRRRRWR", void_type_node, 11, pvoid_type_node, size_type_node, integer_type_node, pvoid_type_node, pvoid_type_node, pvoid_type_node, integer_type_node, integer_type_node, - boolean_type_node, pint_type); + boolean_type_node, pint_type, pvoid_type_node); gfor_fndecl_caf_sendget = gfc_build_library_function_decl_with_spec ( get_identifier (PREFIX("caf_sendget")), ".R.RRRR.RRRRRR", @@ -3764,6 +3769,33 @@ gfc_build_builtin_function_decls (void) void_type_node, 3, pvoid_type_node, ppvoid_type_node, integer_type_node); + gfor_fndecl_caf_form_team + = gfc_build_library_function_decl_with_spec ( + get_identifier (PREFIX("caf_form_team")), "RWR", + void_type_node, 3, integer_type_node, ppvoid_type_node, + integer_type_node); + + gfor_fndecl_caf_change_team + = gfc_build_library_function_decl_with_spec ( + get_identifier (PREFIX("caf_change_team")), "RR", + void_type_node, 2, ppvoid_type_node, + integer_type_node); + + gfor_fndecl_caf_end_team + = gfc_build_library_function_decl ( + get_identifier (PREFIX("caf_end_team")), void_type_node, 0); + + gfor_fndecl_caf_get_team + = gfc_build_library_function_decl_with_spec ( + get_identifier (PREFIX("caf_get_team")), "R", + void_type_node, 1, integer_type_node); + + gfor_fndecl_caf_sync_team + = gfc_build_library_function_decl_with_spec ( + get_identifier (PREFIX("caf_sync_team")), "RR", + void_type_node, 2, ppvoid_type_node, + integer_type_node); + gfor_fndecl_caf_image_status = gfc_build_library_function_decl_with_spec ( get_identifier (PREFIX("caf_image_status")), "RR", diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c index 9bc465e43d93d..0e3e3860fdbc3 100644 --- a/gcc/fortran/trans-intrinsic.c +++ b/gcc/fortran/trans-intrinsic.c @@ -842,6 +842,7 @@ gfc_conv_intrinsic_lib_function (gfc_se * se, gfc_expr * expr) gfc_isym_id id; id = expr->value.function.isym->id; + /* Find the entry for this function. */ for (m = gfc_intrinsic_map; m->id != GFC_ISYM_NONE || m->double_built_in != END_BUILTINS; m++) @@ -852,6 +853,7 @@ gfc_conv_intrinsic_lib_function (gfc_se * se, gfc_expr * expr) if (m->id == GFC_ISYM_NONE) { + printf("Id %d none %d\n",id,GFC_ISYM_NONE); gfc_internal_error ("Intrinsic function %qs (%d) not recognized", expr->value.function.name, id); } @@ -1846,11 +1848,11 @@ gfc_conv_intrinsic_caf_get (gfc_se *se, gfc_expr *expr, tree lhs, tree lhs_kind, static tree conv_caf_send (gfc_code *code) { - gfc_expr *lhs_expr, *rhs_expr, *tmp_stat; + gfc_expr *lhs_expr, *rhs_expr, *tmp_stat, *tmp_team; gfc_se lhs_se, rhs_se; stmtblock_t block; tree caf_decl, token, offset, image_index, tmp, lhs_kind, rhs_kind; - tree may_require_tmp, src_stat, dst_stat; + tree may_require_tmp, src_stat, dst_stat, dst_team, src_team; tree lhs_type = NULL_TREE; tree vec = null_pointer_node, rhs_vec = null_pointer_node; symbol_attribute lhs_caf_attr, rhs_caf_attr; @@ -1866,6 +1868,7 @@ conv_caf_send (gfc_code *code) { lhs_caf_attr = gfc_caf_attr (lhs_expr); rhs_caf_attr = gfc_caf_attr (rhs_expr); src_stat = dst_stat = null_pointer_node; + src_team = dst_team = null_pointer_node; /* LHS. */ gfc_init_se (&lhs_se, NULL); @@ -2068,6 +2071,18 @@ conv_caf_send (gfc_code *code) { gfc_add_block_to_block (&block, &stat_se.post); } + tmp_team = gfc_find_team_co (lhs_expr); + + if (tmp_team) + { + gfc_se team_se; + gfc_init_se (&team_se, NULL); + gfc_conv_expr_reference (&team_se, tmp_team); + dst_team = team_se.expr; + gfc_add_block_to_block (&block, &team_se.pre); + gfc_add_block_to_block (&block, &team_se.post); + } + if (!gfc_is_coindexed (rhs_expr)) { if (lhs_caf_attr.alloc_comp || lhs_caf_attr.pointer_comp) @@ -2083,10 +2098,10 @@ conv_caf_send (gfc_code *code) { may_require_tmp, dst_realloc, src_stat); } else - tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_send, 10, + tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_send, 11, token, offset, image_index, lhs_se.expr, vec, rhs_se.expr, lhs_kind, rhs_kind, - may_require_tmp, src_stat); + may_require_tmp, src_stat, dst_team); } else { @@ -9504,6 +9519,7 @@ gfc_is_intrinsic_libcall (gfc_expr * expr) case GFC_ISYM_CSHIFT: case GFC_ISYM_EOSHIFT: + case GFC_ISYM_GET_TEAM: case GFC_ISYM_FAILED_IMAGES: case GFC_ISYM_STOPPED_IMAGES: case GFC_ISYM_PACK: diff --git a/gcc/fortran/trans-stmt.c b/gcc/fortran/trans-stmt.c index 7a76b8ead3166..3de9124f19a3d 100644 --- a/gcc/fortran/trans-stmt.c +++ b/gcc/fortran/trans-stmt.c @@ -696,6 +696,115 @@ gfc_trans_fail_image (gfc_code *code ATTRIBUTE_UNUSED) } } +/* Translate the FORM TEAM statement. */ + +tree +gfc_trans_form_team (gfc_code *code) +{ + if (flag_coarray == GFC_FCOARRAY_LIB) + { + gfc_se argse; + tree team_id,team_type; + gfc_init_se (&argse, NULL); + gfc_conv_expr_val (&argse, code->expr1); + team_id = fold_convert (integer_type_node, argse.expr); + gfc_init_se (&argse, NULL); + gfc_conv_expr_val (&argse, code->expr2); + team_type = gfc_build_addr_expr (ppvoid_type_node, argse.expr); + + return build_call_expr_loc (input_location, + gfor_fndecl_caf_form_team, 3, + team_id, team_type, + build_int_cst (integer_type_node, 0)); + } + else + { + const char *name = gfc_get_string (PREFIX ("exit_i%d"), 4); + gfc_symbol *exsym = gfc_get_intrinsic_sub_symbol (name); + tree tmp = gfc_get_symbol_decl (exsym); + return build_call_expr_loc (input_location, tmp, 1, integer_zero_node); + } +} + +/* Translate the CHANGE TEAM statement. */ + +tree +gfc_trans_change_team (gfc_code *code) +{ + if (flag_coarray == GFC_FCOARRAY_LIB) + { + gfc_se argse; + tree team_type; + /* gfc_init_se (&argse, NULL); */ + /* gfc_conv_expr_val (&argse, code->expr1); */ + /* team_id = fold_convert (integer_type_node, argse.expr); */ + gfc_init_se (&argse, NULL); + gfc_conv_expr_val (&argse, code->expr1); + team_type = gfc_build_addr_expr (ppvoid_type_node, argse.expr); + + return build_call_expr_loc (input_location, + gfor_fndecl_caf_change_team, 2, + team_type, + build_int_cst (integer_type_node, 0)); + } + else + { + const char *name = gfc_get_string (PREFIX ("exit_i%d"), 4); + gfc_symbol *exsym = gfc_get_intrinsic_sub_symbol (name); + tree tmp = gfc_get_symbol_decl (exsym); + return build_call_expr_loc (input_location, tmp, 1, integer_zero_node); + } +} + +/* Translate the END TEAM statement. */ + +tree +gfc_trans_end_team (gfc_code *code ATTRIBUTE_UNUSED) +{ + if (flag_coarray == GFC_FCOARRAY_LIB) + { + return build_call_expr_loc (input_location, + gfor_fndecl_caf_end_team, 1, + build_int_cst (pchar_type_node, 0)); + } + else + { + const char *name = gfc_get_string (PREFIX ("exit_i%d"), 4); + gfc_symbol *exsym = gfc_get_intrinsic_sub_symbol (name); + tree tmp = gfc_get_symbol_decl (exsym); + return build_call_expr_loc (input_location, tmp, 1, integer_zero_node); + } +} + +/* Translate the SYNC TEAM statement. */ + +tree +gfc_trans_sync_team (gfc_code *code) +{ + if (flag_coarray == GFC_FCOARRAY_LIB) + { + gfc_se argse; + tree team_type; + /* gfc_init_se (&argse, NULL); */ + /* gfc_conv_expr_val (&argse, code->expr1); */ + /* team_id = fold_convert (integer_type_node, argse.expr); */ + gfc_init_se (&argse, NULL); + gfc_conv_expr_val (&argse, code->expr1); + team_type = gfc_build_addr_expr (ppvoid_type_node, argse.expr); + + return build_call_expr_loc (input_location, + gfor_fndecl_caf_sync_team, 2, + team_type, + build_int_cst (integer_type_node, 0)); + } + else + { + const char *name = gfc_get_string (PREFIX ("exit_i%d"), 4); + gfc_symbol *exsym = gfc_get_intrinsic_sub_symbol (name); + tree tmp = gfc_get_symbol_decl (exsym); + return build_call_expr_loc (input_location, tmp, 1, integer_zero_node); + } +} tree gfc_trans_lock_unlock (gfc_code *code, gfc_exec_op op) diff --git a/gcc/fortran/trans-stmt.h b/gcc/fortran/trans-stmt.h index 0a39e26c21889..80858a7429808 100644 --- a/gcc/fortran/trans-stmt.h +++ b/gcc/fortran/trans-stmt.h @@ -57,6 +57,10 @@ tree gfc_trans_sync (gfc_code *, gfc_exec_op); tree gfc_trans_lock_unlock (gfc_code *, gfc_exec_op); tree gfc_trans_event_post_wait (gfc_code *, gfc_exec_op); tree gfc_trans_fail_image (gfc_code *); +tree gfc_trans_form_team (gfc_code *); +tree gfc_trans_change_team (gfc_code *); +tree gfc_trans_end_team (gfc_code *); +tree gfc_trans_sync_team (gfc_code *); tree gfc_trans_forall (gfc_code *); tree gfc_trans_where (gfc_code *); tree gfc_trans_allocate (gfc_code *); diff --git a/gcc/fortran/trans-types.c b/gcc/fortran/trans-types.c index 78477a90f80c3..85386a81aef0a 100644 --- a/gcc/fortran/trans-types.c +++ b/gcc/fortran/trans-types.c @@ -2476,12 +2476,14 @@ gfc_get_derived_type (gfc_symbol * derived, int codimen) || (flag_coarray == GFC_FCOARRAY_LIB && derived->from_intmod == INTMOD_ISO_FORTRAN_ENV && (derived->intmod_sym_id == ISOFORTRAN_LOCK_TYPE - || derived->intmod_sym_id == ISOFORTRAN_EVENT_TYPE))) + || derived->intmod_sym_id == ISOFORTRAN_EVENT_TYPE + || derived->intmod_sym_id == ISOFORTRAN_TEAM_TYPE))) return ptr_type_node; if (flag_coarray != GFC_FCOARRAY_LIB && derived->from_intmod == INTMOD_ISO_FORTRAN_ENV - && derived->intmod_sym_id == ISOFORTRAN_EVENT_TYPE) + && (derived->intmod_sym_id == ISOFORTRAN_EVENT_TYPE + || derived->intmod_sym_id == ISOFORTRAN_TEAM_TYPE)) return gfc_get_int_type (gfc_default_integer_kind); if (derived && derived->attr.flavor == FL_PROCEDURE diff --git a/gcc/fortran/trans.c b/gcc/fortran/trans.c index 53bc4285c7889..5f3c4c95305d2 100644 --- a/gcc/fortran/trans.c +++ b/gcc/fortran/trans.c @@ -1968,6 +1968,22 @@ trans_code (gfc_code * code, tree cond) res = gfc_trans_forall (code); break; + case EXEC_FORM_TEAM: + res = gfc_trans_form_team (code); + break; + + case EXEC_CHANGE_TEAM: + res = gfc_trans_change_team (code); + break; + + case EXEC_END_TEAM: + res = gfc_trans_end_team (code); + break; + + case EXEC_SYNC_TEAM: + res = gfc_trans_sync_team (code); + break; + case EXEC_WHERE: res = gfc_trans_where (code); break; diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h index c970ace86f997..088348d410dcd 100644 --- a/gcc/fortran/trans.h +++ b/gcc/fortran/trans.h @@ -837,6 +837,11 @@ extern GTY(()) tree gfor_fndecl_caf_fail_image; extern GTY(()) tree gfor_fndecl_caf_failed_images; extern GTY(()) tree gfor_fndecl_caf_image_status; extern GTY(()) tree gfor_fndecl_caf_stopped_images; +extern GTY(()) tree gfor_fndecl_caf_form_team; +extern GTY(()) tree gfor_fndecl_caf_change_team; +extern GTY(()) tree gfor_fndecl_caf_end_team; +extern GTY(()) tree gfor_fndecl_caf_get_team; +extern GTY(()) tree gfor_fndecl_caf_sync_team; extern GTY(()) tree gfor_fndecl_co_broadcast; extern GTY(()) tree gfor_fndecl_co_max; extern GTY(()) tree gfor_fndecl_co_min;