diff options
author | Tobias Burnus <tobias@codesourcery.com> | 2019-11-11 09:19:29 +0000 |
---|---|---|
committer | Tobias Burnus <burnus@gcc.gnu.org> | 2019-11-11 10:19:29 +0100 |
commit | a2c26c50310a336361d8129ecdd43d3001d6cb3a (patch) | |
tree | 652752017ebc9459258438136af1d92a63535d0d /gcc/fortran | |
parent | bfa1837b010feaa81a56cbc46ce7c17dc909c3bb (diff) | |
download | gcc-a2c26c50310a336361d8129ecdd43d3001d6cb3a.zip gcc-a2c26c50310a336361d8129ecdd43d3001d6cb3a.tar.gz gcc-a2c26c50310a336361d8129ecdd43d3001d6cb3a.tar.bz2 |
Fortran] Support absent optional args with use_device_{ptr,addr}
2019-11-11 Tobias Burnus <tobias@codesourcery.com>
Kwok Cheung Yeung <kcy@codesourcery.com>
gcc/
* langhooks-def.h (LANG_HOOKS_OMP_CHECK_OPTIONAL_ARGUMENT):
Renamed from LANG_HOOKS_OMP_IS_OPTIONAL_ARGUMENT; update define.
(LANG_HOOKS_DECLS): Rename also here.
* langhooks.h (lang_hooks_for_decls): Rename
omp_is_optional_argument to omp_check_optional_argument; take
additional bool argument.
* omp-general.h (omp_check_optional_argument): Likewise.
* omp-general.h (omp_check_optional_argument): Likewise.
* omp-low.c (lower_omp_target): Update calls; handle absent
Fortran optional arguments with USE_DEVICE_ADDR/USE_DEVICE_PTR.
gcc/fortran/
* trans-expr.c (gfc_conv_expr_present): Check for DECL_ARTIFICIAL
for the VALUE hidden argument avoiding -fallow-underscore issues.
* trans-decl.c (create_function_arglist): Also set
GFC_DECL_OPTIONAL_ARGUMENT for per-value arguments.
* f95-lang.c (LANG_HOOKS_OMP_CHECK_OPTIONAL_ARGUMENT):
Renamed from LANG_HOOKS_OMP_IS_OPTIONAL_ARGUMENT; point
to gfc_omp_check_optional_argument.
* trans.h (gfc_omp_check_optional_argument): Subsitutes
gfc_omp_is_optional_argument declaration.
* trans-openmp.c (gfc_omp_is_optional_argument): Make static.
(gfc_omp_check_optional_argument): New function.
libgomp/
* testsuite/libgomp.fortran/use_device_ptr-optional-1.f90: Extend.
* testsuite/libgomp.fortran/use_device_ptr-optional-2.f90: New.
Co-Authored-By: Kwok Cheung Yeung <kcy@codesourcery.com>
From-SVN: r278046
Diffstat (limited to 'gcc/fortran')
-rw-r--r-- | gcc/fortran/ChangeLog | 15 | ||||
-rw-r--r-- | gcc/fortran/f95-lang.c | 4 | ||||
-rw-r--r-- | gcc/fortran/trans-decl.c | 3 | ||||
-rw-r--r-- | gcc/fortran/trans-expr.c | 3 | ||||
-rw-r--r-- | gcc/fortran/trans-openmp.c | 63 | ||||
-rw-r--r-- | gcc/fortran/trans.h | 2 |
6 files changed, 79 insertions, 11 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 2031688..0a8efed 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,18 @@ +2019-11-11 Tobias Burnus <tobias@codesourcery.com> + Kwok Cheung Yeung <kcy@codesourcery.com> + + * trans-expr.c (gfc_conv_expr_present): Check for DECL_ARTIFICIAL + for the VALUE hidden argument avoiding -fallow-underscore issues. + * trans-decl.c (create_function_arglist): Also set + GFC_DECL_OPTIONAL_ARGUMENT for per-value arguments. + * f95-lang.c (LANG_HOOKS_OMP_CHECK_OPTIONAL_ARGUMENT): + Renamed from LANG_HOOKS_OMP_IS_OPTIONAL_ARGUMENT; point + to gfc_omp_check_optional_argument. + * trans.h (gfc_omp_check_optional_argument): Subsitutes + gfc_omp_is_optional_argument declaration. + * trans-openmp.c (gfc_omp_is_optional_argument): Make static. + (gfc_omp_check_optional_argument): New function. + 2019-11-10 Janne Blomqvist <jb@gcc.gnu.org> PR fortran/91413 diff --git a/gcc/fortran/f95-lang.c b/gcc/fortran/f95-lang.c index 0684c3b..c7b592d 100644 --- a/gcc/fortran/f95-lang.c +++ b/gcc/fortran/f95-lang.c @@ -115,7 +115,7 @@ static const struct attribute_spec gfc_attribute_table[] = #undef LANG_HOOKS_INIT_TS #undef LANG_HOOKS_OMP_ARRAY_DATA #undef LANG_HOOKS_OMP_IS_ALLOCATABLE_OR_PTR -#undef LANG_HOOKS_OMP_IS_OPTIONAL_ARGUMENT +#undef LANG_HOOKS_OMP_CHECK_OPTIONAL_ARGUMENT #undef LANG_HOOKS_OMP_PRIVATIZE_BY_REFERENCE #undef LANG_HOOKS_OMP_PREDETERMINED_SHARING #undef LANG_HOOKS_OMP_REPORT_DECL @@ -150,7 +150,7 @@ static const struct attribute_spec gfc_attribute_table[] = #define LANG_HOOKS_INIT_TS gfc_init_ts #define LANG_HOOKS_OMP_ARRAY_DATA gfc_omp_array_data #define LANG_HOOKS_OMP_IS_ALLOCATABLE_OR_PTR gfc_omp_is_allocatable_or_ptr -#define LANG_HOOKS_OMP_IS_OPTIONAL_ARGUMENT gfc_omp_is_optional_argument +#define LANG_HOOKS_OMP_CHECK_OPTIONAL_ARGUMENT gfc_omp_check_optional_argument #define LANG_HOOKS_OMP_PRIVATIZE_BY_REFERENCE gfc_omp_privatize_by_reference #define LANG_HOOKS_OMP_PREDETERMINED_SHARING gfc_omp_predetermined_sharing #define LANG_HOOKS_OMP_REPORT_DECL gfc_omp_report_decl diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c index 76e1c7a..e742447 100644 --- a/gcc/fortran/trans-decl.c +++ b/gcc/fortran/trans-decl.c @@ -2692,9 +2692,8 @@ create_function_arglist (gfc_symbol * sym) && (!f->sym->attr.proc_pointer && f->sym->attr.flavor != FL_PROCEDURE)) DECL_BY_REFERENCE (parm) = 1; - if (f->sym->attr.optional && !f->sym->attr.value) + if (f->sym->attr.optional) { - /* With value, the argument is passed as is. */ gfc_allocate_lang_decl (parm); GFC_DECL_OPTIONAL_ARGUMENT (parm) = 1; } diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c index f800faa..6355938 100644 --- a/gcc/fortran/trans-expr.c +++ b/gcc/fortran/trans-expr.c @@ -1725,7 +1725,8 @@ gfc_conv_expr_present (gfc_symbol * sym) /* Walk function argument list to find hidden arg. */ cond = DECL_ARGUMENTS (DECL_CONTEXT (decl)); for ( ; cond != NULL_TREE; cond = TREE_CHAIN (cond)) - if (DECL_NAME (cond) == tree_name) + if (DECL_NAME (cond) == tree_name + && DECL_ARTIFICIAL (cond)) break; gcc_assert (cond); diff --git a/gcc/fortran/trans-openmp.c b/gcc/fortran/trans-openmp.c index 14a3c3e..dee7cc2 100644 --- a/gcc/fortran/trans-openmp.c +++ b/gcc/fortran/trans-openmp.c @@ -58,19 +58,72 @@ gfc_omp_is_allocatable_or_ptr (const_tree decl) || GFC_DECL_GET_SCALAR_ALLOCATABLE (decl))); } -/* True if OpenMP should treat this DECL as an optional argument; note: for - arguments with VALUE attribute, the DECL is identical to nonoptional - arguments; hence, we return false here. To check whether the variable is - present, use the DECL which is passed as hidden argument. */ +/* True if the argument is an optional argument; except that false is also + returned for arguments with the value attribute (nonpointers) and for + assumed-shape variables (decl is a local variable containing arg->data). */ -bool +static bool gfc_omp_is_optional_argument (const_tree decl) { return (TREE_CODE (decl) == PARM_DECL && DECL_LANG_SPECIFIC (decl) + && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE && GFC_DECL_OPTIONAL_ARGUMENT (decl)); } +/* Check whether this DECL belongs to a Fortran optional argument. + With 'for_present_check' set to false, decls which are optional parameters + themselve are returned as tree - or a NULL_TREE otherwise. Those decls are + always pointers. With 'for_present_check' set to true, the decl for checking + whether an argument is present is returned; for arguments with value + attribute this is the hidden argument and of BOOLEAN_TYPE. If the decl is + unrelated to optional arguments, NULL_TREE is returned. */ + +tree +gfc_omp_check_optional_argument (tree decl, bool for_present_check) +{ + if (!for_present_check) + return gfc_omp_is_optional_argument (decl) ? decl : NULL_TREE; + + if (!DECL_LANG_SPECIFIC (decl)) + return NULL_TREE; + + /* For assumed-shape arrays, a local decl with arg->data is used. */ + if (TREE_CODE (decl) != PARM_DECL + && (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)) + || GFC_ARRAY_TYPE_P (TREE_TYPE (decl)))) + decl = GFC_DECL_SAVED_DESCRIPTOR (decl); + + if (TREE_CODE (decl) != PARM_DECL + || !DECL_LANG_SPECIFIC (decl) + || !GFC_DECL_OPTIONAL_ARGUMENT (decl)) + return NULL_TREE; + + /* For VALUE, the scalar variable is passed as is but a hidden argument + denotes the value. Cf. trans-expr.c. */ + if (TREE_CODE (TREE_TYPE (decl)) != POINTER_TYPE) + { + char name[GFC_MAX_SYMBOL_LEN + 2]; + tree tree_name; + + name[0] = '_'; + strcpy (&name[1], IDENTIFIER_POINTER (DECL_NAME (decl))); + tree_name = get_identifier (name); + + /* Walk function argument list to find the hidden arg. */ + decl = DECL_ARGUMENTS (DECL_CONTEXT (decl)); + for ( ; decl != NULL_TREE; decl = TREE_CHAIN (decl)) + if (DECL_NAME (decl) == tree_name + && DECL_ARTIFICIAL (decl)) + break; + + gcc_assert (decl); + return decl; + } + + return decl; +} + /* Returns tree with NULL if it is not an array descriptor and with the tree to access the 'data' component otherwise. With type_only = true, it returns the diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h index 364efe5..359c7a2 100644 --- a/gcc/fortran/trans.h +++ b/gcc/fortran/trans.h @@ -787,7 +787,7 @@ bool gfc_get_array_descr_info (const_tree, struct array_descr_info *); /* In trans-openmp.c */ bool gfc_omp_is_allocatable_or_ptr (const_tree); -bool gfc_omp_is_optional_argument (const_tree); +tree gfc_omp_check_optional_argument (tree, bool); tree gfc_omp_array_data (tree, bool); bool gfc_omp_privatize_by_reference (const_tree); enum omp_clause_default_kind gfc_omp_predetermined_sharing (tree); |