mirror of git://gcc.gnu.org/git/gcc.git
trans-decl.c (gfc_build_builtin_function_decls): Add may_require_tmp dummy argument.
2014-08-31 Tobias Burnus <burnus@net-b.de>
gcc/fortran/
* trans-decl.c (gfc_build_builtin_function_decls): Add
may_require_tmp dummy argument.
* trans-intrinsic.c (gfc_conv_intrinsic_caf_get,
conv_caf_send): Handle may_require_tmp argument.
(gfc_conv_intrinsic_function): Update call.
* gfortran.texi (_gfortran_caf_send, _gfortran_caf_get,
_gfortran_caf_sendget): Update interface description.
gcc/testsuite/
* gfortran.dg/coarray_lib_comm_1.f90: New.
libgfortran/
* caf/libcaf.h (_gfortran_caf_send, _gfortran_caf_get,
_gfortran_caf_sendget): Update prototype.
* caf/single.c (_gfortran_caf_send, _gfortran_caf_get,
_gfortran_caf_sendget): Handle may_require_tmp.
From-SVN: r214764
This commit is contained in:
parent
5c535ce216
commit
93e2e0465e
|
|
@ -1,3 +1,13 @@
|
||||||
|
2014-08-31 Tobias Burnus <burnus@net-b.de>
|
||||||
|
|
||||||
|
* trans-decl.c (gfc_build_builtin_function_decls): Add
|
||||||
|
may_require_tmp dummy argument.
|
||||||
|
* trans-intrinsic.c (gfc_conv_intrinsic_caf_get,
|
||||||
|
conv_caf_send): Handle may_require_tmp argument.
|
||||||
|
(gfc_conv_intrinsic_function): Update call.
|
||||||
|
* gfortran.texi (_gfortran_caf_send, _gfortran_caf_get,
|
||||||
|
_gfortran_caf_sendget): Update interface description.
|
||||||
|
|
||||||
2014-08-30 Tobias Burnus <burnus@net-b.de>
|
2014-08-30 Tobias Burnus <burnus@net-b.de>
|
||||||
|
|
||||||
* trans.h (gfc_caf_get_image_index,
|
* trans.h (gfc_caf_get_image_index,
|
||||||
|
|
|
||||||
|
|
@ -3448,7 +3448,7 @@ to a remote image identified by the image_index.
|
||||||
@item @emph{Syntax}:
|
@item @emph{Syntax}:
|
||||||
@code{void _gfortran_caf_send (caf_token_t token, size_t offset,
|
@code{void _gfortran_caf_send (caf_token_t token, size_t offset,
|
||||||
int image_index, gfc_descriptor_t *dest, caf_vector_t *dst_vector,
|
int image_index, gfc_descriptor_t *dest, caf_vector_t *dst_vector,
|
||||||
gfc_descriptor_t *src, int dst_kind, int src_kind)}
|
gfc_descriptor_t *src, int dst_kind, int src_kind, bool may_require_tmp)}
|
||||||
|
|
||||||
@item @emph{Arguments}:
|
@item @emph{Arguments}:
|
||||||
@multitable @columnfractions .15 .70
|
@multitable @columnfractions .15 .70
|
||||||
|
|
@ -3466,15 +3466,26 @@ triplet of the dest argument.
|
||||||
transferred to the remote image
|
transferred to the remote image
|
||||||
@item @var{dst_kind} @tab Kind of the destination argument
|
@item @var{dst_kind} @tab Kind of the destination argument
|
||||||
@item @var{src_kind} @tab Kind of the source argument
|
@item @var{src_kind} @tab Kind of the source argument
|
||||||
|
@item @var{may_require_tmp} @tab The variable is false it is known at compile
|
||||||
|
time that the @var{dest} and @var{src} either cannot overlap or overlap (fully
|
||||||
|
or partially) such that walking @var{src} and @var{dest} in element wise
|
||||||
|
element order (honoring the stride value) will not lead to wrong results.
|
||||||
|
Otherwise, the value is true.
|
||||||
@end multitable
|
@end multitable
|
||||||
|
|
||||||
@item @emph{NOTES}
|
@item @emph{NOTES}
|
||||||
It is permitted to have image_id equal the current image; the memory of the
|
It is permitted to have image_id equal the current image; the memory of the
|
||||||
send-to and the send-from might (partially) overlap in that case. The
|
send-to and the send-from might (partially) overlap in that case. The
|
||||||
implementation has to take care that it handles this case. Note that the
|
implementation has to take care that it handles this case, e.g. using
|
||||||
assignment of a scalar to an array is permitted. In addition, the library has
|
@code{memmove} which handles (partially) overlapping memory. If
|
||||||
to handle numeric-type conversion and for strings, padding and different
|
@var{may_require_tmp} is true, the library might additionally create a
|
||||||
character kinds.
|
temporary variable, unless additional checks show that this is not required
|
||||||
|
(e.g. because walking backward is possible or because both arrays are
|
||||||
|
contiguous and @code{memmove} takes care of overlap issues).
|
||||||
|
|
||||||
|
Note that the assignment of a scalar to an array is permitted. In addition,
|
||||||
|
the library has to handle numeric-type conversion and for strings, padding
|
||||||
|
and different character kinds.
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -3490,7 +3501,7 @@ image identified by the image_index.
|
||||||
@item @emph{Syntax}:
|
@item @emph{Syntax}:
|
||||||
@code{void _gfortran_caf_get_desc (caf_token_t token, size_t offset,
|
@code{void _gfortran_caf_get_desc (caf_token_t token, size_t offset,
|
||||||
int image_index, gfc_descriptor_t *src, caf_vector_t *src_vector,
|
int image_index, gfc_descriptor_t *src, caf_vector_t *src_vector,
|
||||||
gfc_descriptor_t *dest, int src_kind, int dst_kind)}
|
gfc_descriptor_t *dest, int src_kind, int dst_kind, bool may_require_tmp)}
|
||||||
|
|
||||||
@item @emph{Arguments}:
|
@item @emph{Arguments}:
|
||||||
@multitable @columnfractions .15 .70
|
@multitable @columnfractions .15 .70
|
||||||
|
|
@ -3508,14 +3519,25 @@ subscript of the destination array; the values are relative to the dimension
|
||||||
triplet of the dest argument.
|
triplet of the dest argument.
|
||||||
@item @var{dst_kind} @tab Kind of the destination argument
|
@item @var{dst_kind} @tab Kind of the destination argument
|
||||||
@item @var{src_kind} @tab Kind of the source argument
|
@item @var{src_kind} @tab Kind of the source argument
|
||||||
|
@item @var{may_require_tmp} @tab The variable is false it is known at compile
|
||||||
|
time that the @var{dest} and @var{src} either cannot overlap or overlap (fully
|
||||||
|
or partially) such that walking @var{src} and @var{dest} in element wise
|
||||||
|
element order (honoring the stride value) will not lead to wrong results.
|
||||||
|
Otherwise, the value is true.
|
||||||
@end multitable
|
@end multitable
|
||||||
|
|
||||||
@item @emph{NOTES}
|
@item @emph{NOTES}
|
||||||
It is permitted to have image_id equal the current image; the memory of the
|
It is permitted to have image_id equal the current image; the memory of the
|
||||||
send-to and the send-from might (partially) overlap in that case. The
|
send-to and the send-from might (partially) overlap in that case. The
|
||||||
implementation has to take care that it handles this case. Note that the
|
implementation has to take care that it handles this case, e.g. using
|
||||||
library has to handle numeric-type conversion and for strings, padding
|
@code{memmove} which handles (partially) overlapping memory. If
|
||||||
and different character kinds.
|
@var{may_require_tmp} is true, the library might additionally create a
|
||||||
|
temporary variable, unless additional checks show that this is not required
|
||||||
|
(e.g. because walking backward is possible or because both arrays are
|
||||||
|
contiguous and @code{memmove} takes care of overlap issues).
|
||||||
|
|
||||||
|
Note that the library has to handle numeric-type conversion and for strings,
|
||||||
|
padding and different character kinds.
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -3533,7 +3555,8 @@ dst_image_index.
|
||||||
@code{void _gfortran_caf_sendget (caf_token_t dst_token, size_t dst_offset,
|
@code{void _gfortran_caf_sendget (caf_token_t dst_token, size_t dst_offset,
|
||||||
int dst_image_index, gfc_descriptor_t *dest, caf_vector_t *dst_vector,
|
int dst_image_index, gfc_descriptor_t *dest, caf_vector_t *dst_vector,
|
||||||
caf_token_t src_token, size_t src_offset, int src_image_index,
|
caf_token_t src_token, size_t src_offset, int src_image_index,
|
||||||
gfc_descriptor_t *src, caf_vector_t *src_vector, int dst_kind, int src_kind)}
|
gfc_descriptor_t *src, caf_vector_t *src_vector, int dst_kind, int src_kind,
|
||||||
|
bool may_require_tmp)}
|
||||||
|
|
||||||
@item @emph{Arguments}:
|
@item @emph{Arguments}:
|
||||||
@multitable @columnfractions .15 .70
|
@multitable @columnfractions .15 .70
|
||||||
|
|
@ -3543,7 +3566,7 @@ destination coarray.
|
||||||
shifted compared to the base address of the destination coarray.
|
shifted compared to the base address of the destination coarray.
|
||||||
@item @var{dst_image_index} @tab The ID of the destination remote image; must
|
@item @var{dst_image_index} @tab The ID of the destination remote image; must
|
||||||
be a positive number.
|
be a positive number.
|
||||||
@item @var{dst_dest} @tab intent(in) Array descriptor for the destination
|
@item @var{dest} @tab intent(in) Array descriptor for the destination
|
||||||
remote image for the bounds and the size. The base_addr shall not be accessed.
|
remote image for the bounds and the size. The base_addr shall not be accessed.
|
||||||
@item @var{dst_vector} @tab intent(int) If not NULL, it contains the vector
|
@item @var{dst_vector} @tab intent(int) If not NULL, it contains the vector
|
||||||
subscript of the destination array; the values are relative to the dimension
|
subscript of the destination array; the values are relative to the dimension
|
||||||
|
|
@ -3553,21 +3576,31 @@ triplet of the dest argument.
|
||||||
compared to the base address of the source coarray.
|
compared to the base address of the source coarray.
|
||||||
@item @var{src_image_index} @tab The ID of the source remote image; must be a
|
@item @var{src_image_index} @tab The ID of the source remote image; must be a
|
||||||
positive number.
|
positive number.
|
||||||
@item @var{src_dest} @tab intent(in) Array descriptor of the local array to be
|
@item @var{src} @tab intent(in) Array descriptor of the local array to be
|
||||||
transferred to the remote image.
|
transferred to the remote image.
|
||||||
@item @var{src_vector} @tab intent(in) Array descriptor of the local array to
|
@item @var{src_vector} @tab intent(in) Array descriptor of the local array to
|
||||||
be transferred to the remote image
|
be transferred to the remote image
|
||||||
@item @var{dst_kind} @tab Kind of the destination argument
|
@item @var{dst_kind} @tab Kind of the destination argument
|
||||||
@item @var{src_kind} @tab Kind of the source argument
|
@item @var{src_kind} @tab Kind of the source argument
|
||||||
|
@item @var{may_require_tmp} @tab The variable is false it is known at compile
|
||||||
|
time that the @var{dest} and @var{src} either cannot overlap or overlap (fully
|
||||||
|
or partially) such that walking @var{src} and @var{dest} in element wise
|
||||||
|
element order (honoring the stride value) will not lead to wrong results.
|
||||||
|
Otherwise, the value is true.
|
||||||
@end multitable
|
@end multitable
|
||||||
|
|
||||||
@item @emph{NOTES}
|
@item @emph{NOTES}
|
||||||
It is permitted to have image_id equal the current image; the memory of the
|
It is permitted to have image_ids equal; the memory of the send-to and the
|
||||||
send-to and the send-from might (partially) overlap in that case. The
|
send-from might (partially) overlap in that case. The implementation has to
|
||||||
implementation has to take care that it handles this case. Note that the
|
take care that it handles this case, e.g. using @code{memmove} which handles
|
||||||
assignment of a scalar to an array is permitted. In addition, the library has
|
(partially) overlapping memory. If @var{may_require_tmp} is true, the library
|
||||||
to handle numeric-type conversion and for strings, padding and different
|
might additionally create a temporary variable, unless additional checks show
|
||||||
character kinds.
|
that this is not required (e.g. because walking backward is possible or because
|
||||||
|
both arrays are contiguous and @code{memmove} takes care of overlap issues).
|
||||||
|
|
||||||
|
Note that the assignment of a scalar to an array is permitted. In addition,
|
||||||
|
the library has to handle numeric-type conversion and for strings, padding and
|
||||||
|
different character kinds.
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3353,20 +3353,23 @@ gfc_build_builtin_function_decls (void)
|
||||||
ppvoid_type_node, pint_type, pchar_type_node, integer_type_node);
|
ppvoid_type_node, pint_type, pchar_type_node, integer_type_node);
|
||||||
|
|
||||||
gfor_fndecl_caf_get = gfc_build_library_function_decl_with_spec (
|
gfor_fndecl_caf_get = gfc_build_library_function_decl_with_spec (
|
||||||
get_identifier (PREFIX("caf_get")), ".R.RRRW", void_type_node, 8,
|
get_identifier (PREFIX("caf_get")), ".R.RRRW", void_type_node, 9,
|
||||||
pvoid_type_node, size_type_node, integer_type_node, pvoid_type_node,
|
pvoid_type_node, size_type_node, integer_type_node, pvoid_type_node,
|
||||||
pvoid_type_node, pvoid_type_node, integer_type_node, integer_type_node);
|
pvoid_type_node, pvoid_type_node, integer_type_node, integer_type_node,
|
||||||
|
boolean_type_node);
|
||||||
|
|
||||||
gfor_fndecl_caf_send = gfc_build_library_function_decl_with_spec (
|
gfor_fndecl_caf_send = gfc_build_library_function_decl_with_spec (
|
||||||
get_identifier (PREFIX("caf_send")), ".R.RRRR", void_type_node, 8,
|
get_identifier (PREFIX("caf_send")), ".R.RRRR", void_type_node, 9,
|
||||||
pvoid_type_node, size_type_node, integer_type_node, pvoid_type_node,
|
pvoid_type_node, size_type_node, integer_type_node, pvoid_type_node,
|
||||||
pvoid_type_node, pvoid_type_node, integer_type_node, integer_type_node);
|
pvoid_type_node, pvoid_type_node, integer_type_node, integer_type_node,
|
||||||
|
boolean_type_node);
|
||||||
|
|
||||||
gfor_fndecl_caf_sendget = gfc_build_library_function_decl_with_spec (
|
gfor_fndecl_caf_sendget = gfc_build_library_function_decl_with_spec (
|
||||||
get_identifier (PREFIX("caf_sendget")), ".R.RRRR.RRR", void_type_node,
|
get_identifier (PREFIX("caf_sendget")), ".R.RRRR.RRR", void_type_node,
|
||||||
12, pvoid_type_node, size_type_node, integer_type_node, pvoid_type_node,
|
13, pvoid_type_node, size_type_node, integer_type_node, pvoid_type_node,
|
||||||
pvoid_type_node, pvoid_type_node, size_type_node, integer_type_node,
|
pvoid_type_node, pvoid_type_node, size_type_node, integer_type_node,
|
||||||
pvoid_type_node, pvoid_type_node, integer_type_node, integer_type_node);
|
pvoid_type_node, pvoid_type_node, integer_type_node, integer_type_node,
|
||||||
|
boolean_type_node);
|
||||||
|
|
||||||
gfor_fndecl_caf_sync_all = gfc_build_library_function_decl_with_spec (
|
gfor_fndecl_caf_sync_all = gfc_build_library_function_decl_with_spec (
|
||||||
get_identifier (PREFIX("caf_sync_all")), ".WW", void_type_node,
|
get_identifier (PREFIX("caf_sync_all")), ".WW", void_type_node,
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@ along with GCC; see the file COPYING3. If not see
|
||||||
#include "trans-const.h"
|
#include "trans-const.h"
|
||||||
#include "trans-types.h"
|
#include "trans-types.h"
|
||||||
#include "trans-array.h"
|
#include "trans-array.h"
|
||||||
|
#include "dependency.h" /* For CAF array alias analysis. */
|
||||||
/* Only for gfc_trans_assign and gfc_trans_pointer_assign. */
|
/* Only for gfc_trans_assign and gfc_trans_pointer_assign. */
|
||||||
#include "trans-stmt.h"
|
#include "trans-stmt.h"
|
||||||
#include "tree-nested.h"
|
#include "tree-nested.h"
|
||||||
|
|
@ -1086,7 +1087,8 @@ conv_caf_vector_subscript (stmtblock_t *block, tree desc, gfc_array_ref *ar)
|
||||||
/* Get data from a remote coarray. */
|
/* Get data from a remote coarray. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gfc_conv_intrinsic_caf_get (gfc_se *se, gfc_expr *expr, tree lhs, tree lhs_kind)
|
gfc_conv_intrinsic_caf_get (gfc_se *se, gfc_expr *expr, tree lhs, tree lhs_kind,
|
||||||
|
tree may_require_tmp)
|
||||||
{
|
{
|
||||||
gfc_expr *array_expr;
|
gfc_expr *array_expr;
|
||||||
gfc_se argse;
|
gfc_se argse;
|
||||||
|
|
@ -1193,9 +1195,13 @@ gfc_conv_intrinsic_caf_get (gfc_se *se, gfc_expr *expr, tree lhs, tree lhs_kind)
|
||||||
image_index = gfc_caf_get_image_index (&se->pre, array_expr, caf_decl);
|
image_index = gfc_caf_get_image_index (&se->pre, array_expr, caf_decl);
|
||||||
gfc_get_caf_token_offset (&token, &offset, caf_decl, argse.expr, array_expr);
|
gfc_get_caf_token_offset (&token, &offset, caf_decl, argse.expr, array_expr);
|
||||||
|
|
||||||
tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_get, 8,
|
/* No overlap possible as we have generated a temporary. */
|
||||||
|
if (lhs == NULL_TREE)
|
||||||
|
may_require_tmp = boolean_false_node;
|
||||||
|
|
||||||
|
tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_get, 9,
|
||||||
token, offset, image_index, argse.expr, vec,
|
token, offset, image_index, argse.expr, vec,
|
||||||
dst_var, kind, lhs_kind);
|
dst_var, kind, lhs_kind, may_require_tmp);
|
||||||
gfc_add_expr_to_block (&se->pre, tmp);
|
gfc_add_expr_to_block (&se->pre, tmp);
|
||||||
|
|
||||||
if (se->ss)
|
if (se->ss)
|
||||||
|
|
@ -1215,6 +1221,7 @@ conv_caf_send (gfc_code *code) {
|
||||||
gfc_se lhs_se, rhs_se;
|
gfc_se lhs_se, rhs_se;
|
||||||
stmtblock_t block;
|
stmtblock_t block;
|
||||||
tree caf_decl, token, offset, image_index, tmp, lhs_kind, rhs_kind;
|
tree caf_decl, token, offset, image_index, tmp, lhs_kind, rhs_kind;
|
||||||
|
tree may_require_tmp;
|
||||||
tree lhs_type = NULL_TREE;
|
tree lhs_type = NULL_TREE;
|
||||||
tree vec = null_pointer_node, rhs_vec = null_pointer_node;
|
tree vec = null_pointer_node, rhs_vec = null_pointer_node;
|
||||||
|
|
||||||
|
|
@ -1222,6 +1229,8 @@ conv_caf_send (gfc_code *code) {
|
||||||
|
|
||||||
lhs_expr = code->ext.actual->expr;
|
lhs_expr = code->ext.actual->expr;
|
||||||
rhs_expr = code->ext.actual->next->expr;
|
rhs_expr = code->ext.actual->next->expr;
|
||||||
|
may_require_tmp = gfc_check_dependency (lhs_expr, rhs_expr, false) == 0
|
||||||
|
? boolean_false_node : boolean_true_node;
|
||||||
gfc_init_block (&block);
|
gfc_init_block (&block);
|
||||||
|
|
||||||
/* LHS. */
|
/* LHS. */
|
||||||
|
|
@ -1275,7 +1284,8 @@ conv_caf_send (gfc_code *code) {
|
||||||
{
|
{
|
||||||
gcc_assert (gfc_is_coindexed (rhs_expr));
|
gcc_assert (gfc_is_coindexed (rhs_expr));
|
||||||
gfc_init_se (&rhs_se, NULL);
|
gfc_init_se (&rhs_se, NULL);
|
||||||
gfc_conv_intrinsic_caf_get (&rhs_se, rhs_expr, lhs_se.expr, lhs_kind);
|
gfc_conv_intrinsic_caf_get (&rhs_se, rhs_expr, lhs_se.expr, lhs_kind,
|
||||||
|
may_require_tmp);
|
||||||
gfc_add_block_to_block (&block, &rhs_se.pre);
|
gfc_add_block_to_block (&block, &rhs_se.pre);
|
||||||
gfc_add_block_to_block (&block, &rhs_se.post);
|
gfc_add_block_to_block (&block, &rhs_se.post);
|
||||||
gfc_add_block_to_block (&block, &lhs_se.post);
|
gfc_add_block_to_block (&block, &lhs_se.post);
|
||||||
|
|
@ -1342,9 +1352,9 @@ conv_caf_send (gfc_code *code) {
|
||||||
rhs_kind = build_int_cst (integer_type_node, rhs_expr->ts.kind);
|
rhs_kind = build_int_cst (integer_type_node, rhs_expr->ts.kind);
|
||||||
|
|
||||||
if (!gfc_is_coindexed (rhs_expr))
|
if (!gfc_is_coindexed (rhs_expr))
|
||||||
tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_send, 8, token,
|
tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_send, 9, token,
|
||||||
offset, image_index, lhs_se.expr, vec,
|
offset, image_index, lhs_se.expr, vec,
|
||||||
rhs_se.expr, lhs_kind, rhs_kind);
|
rhs_se.expr, lhs_kind, rhs_kind, may_require_tmp);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tree rhs_token, rhs_offset, rhs_image_index;
|
tree rhs_token, rhs_offset, rhs_image_index;
|
||||||
|
|
@ -1355,10 +1365,11 @@ conv_caf_send (gfc_code *code) {
|
||||||
rhs_image_index = gfc_caf_get_image_index (&block, rhs_expr, caf_decl);
|
rhs_image_index = gfc_caf_get_image_index (&block, rhs_expr, caf_decl);
|
||||||
gfc_get_caf_token_offset (&rhs_token, &rhs_offset, caf_decl, rhs_se.expr,
|
gfc_get_caf_token_offset (&rhs_token, &rhs_offset, caf_decl, rhs_se.expr,
|
||||||
rhs_expr);
|
rhs_expr);
|
||||||
tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sendget, 12,
|
tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sendget, 13,
|
||||||
token, offset, image_index, lhs_se.expr, vec,
|
token, offset, image_index, lhs_se.expr, vec,
|
||||||
rhs_token, rhs_offset, rhs_image_index,
|
rhs_token, rhs_offset, rhs_image_index,
|
||||||
rhs_se.expr, rhs_vec, lhs_kind, rhs_kind);
|
rhs_se.expr, rhs_vec, lhs_kind, rhs_kind,
|
||||||
|
may_require_tmp);
|
||||||
}
|
}
|
||||||
gfc_add_expr_to_block (&block, tmp);
|
gfc_add_expr_to_block (&block, tmp);
|
||||||
gfc_add_block_to_block (&block, &lhs_se.post);
|
gfc_add_block_to_block (&block, &lhs_se.post);
|
||||||
|
|
@ -7383,7 +7394,7 @@ gfc_conv_intrinsic_function (gfc_se * se, gfc_expr * expr)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GFC_ISYM_CAF_GET:
|
case GFC_ISYM_CAF_GET:
|
||||||
gfc_conv_intrinsic_caf_get (se, expr, NULL_TREE, NULL_TREE);
|
gfc_conv_intrinsic_caf_get (se, expr, NULL_TREE, NULL_TREE, NULL_TREE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GFC_ISYM_CMPLX:
|
case GFC_ISYM_CMPLX:
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
2014-08-31 Tobias Burnus <burnus@net-b.de>
|
||||||
|
|
||||||
|
* gfortran.dg/coarray_lib_comm_1.f90: New.
|
||||||
|
|
||||||
2014-08-30 Andrew Pinski <apinski@cavium.com>
|
2014-08-30 Andrew Pinski <apinski@cavium.com>
|
||||||
|
|
||||||
* gcc.c-torture/execute/20140828-1.c: New testcase.
|
* gcc.c-torture/execute/20140828-1.c: New testcase.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
! { dg-do run }
|
||||||
|
! { dg-options "-fdump-tree-original -fcoarray=lib -lcaf_single" }
|
||||||
|
!
|
||||||
|
! Some dependency-analysis check for coarray communication
|
||||||
|
!
|
||||||
|
integer, target, save :: A(10)[*]
|
||||||
|
integer, pointer :: P(:)
|
||||||
|
integer, save :: B(10)[*]
|
||||||
|
|
||||||
|
A = [1,2,3,4,5,6,7,8,9,10]
|
||||||
|
B = [1,2,3,4,5,6,7,8,9,10]
|
||||||
|
A(10:2:-1) = A(9:1:-1)[1] ! 0
|
||||||
|
B(10:2:-1) = B(9:1:-1)
|
||||||
|
if (any (A-B /= 0)) call abort
|
||||||
|
|
||||||
|
A = [1,2,3,4,5,6,7,8,9,10]
|
||||||
|
B = [1,2,3,4,5,6,7,8,9,10]
|
||||||
|
A(9:1:-1) = A(10:2:-1)[1] ! 1
|
||||||
|
B(9:1:-1) = B(10:2:-1)
|
||||||
|
if (any (A-B /= 0)) call abort
|
||||||
|
|
||||||
|
A = [1,2,3,4,5,6,7,8,9,10]
|
||||||
|
B = [1,2,3,4,5,6,7,8,9,10]
|
||||||
|
allocate(P(10))
|
||||||
|
P(:) = A(:)[1] ! 1
|
||||||
|
if (any (A-B /= 0)) call abort
|
||||||
|
|
||||||
|
A = [1,2,3,4,5,6,7,8,9,10]
|
||||||
|
B = [1,2,3,4,5,6,7,8,9,10]
|
||||||
|
allocate(P(10))
|
||||||
|
P(:) = B(:)[1] ! 0
|
||||||
|
|
||||||
|
A = [1,2,3,4,5,6,7,8,9,10]
|
||||||
|
B = [1,2,3,4,5,6,7,8,9,10]
|
||||||
|
A(1:5)[1] = A(3:7)[1] ! 1
|
||||||
|
B(1:5) = B(3:7)
|
||||||
|
if (any (A-B /= 0)) call abort
|
||||||
|
end
|
||||||
|
|
||||||
|
! { dg-final { scan-tree-dump-times "_gfortran_caf_get \\\(caf_token.0, \\\(integer\\\(kind=\[48\]\\\)\\\) parm.\[0-9\]+.data - \\\(integer\\\(kind=\[48\]\\\)\\\) a, 1, &parm.\[0-9\]+, 0B, &parm.\[0-9\]+, 4, 4, 0\\\);" 1 "original" } }
|
||||||
|
! { dg-final { scan-tree-dump-times "_gfortran_caf_get \\\(caf_token.0, \\\(integer\\\(kind=\[48\]\\\)\\\) parm.\[0-9\]+.data - \\\(integer\\\(kind=\[48\]\\\)\\\) a, 1, &parm.\[0-9\]+, 0B, &parm.\[0-9\]+, 4, 4, 1\\\);" 1 "original" } }
|
||||||
|
! { dg-final { scan-tree-dump-times "_gfortran_caf_get \\\(caf_token.0, \\\(integer\\\(kind=\[48\]\\\)\\\) parm.\[0-9\]+.data - \\\(integer\\\(kind=\[48\]\\\)\\\) a, 1, &parm.\[0-9\]+, 0B, &p, 4, 4, 1\\\);" 1 "original" } }
|
||||||
|
! { dg-final { scan-tree-dump-times "_gfortran_caf_get \\\(caf_token.1, \\\(integer\\\(kind=\[48\]\\\)\\\) parm.\[0-9\]+.data - \\\(integer\\\(kind=\[48\]\\\)\\\) b, 1, &parm.\[0-9\]+, 0B, &p, 4, 4, 0\\\);" 1 "original" } }
|
||||||
|
! { dg-final { scan-tree-dump-times "_gfortran_caf_sendget \\\(caf_token.0, \\\(integer\\\(kind=\[48\]\\\)\\\) parm.\[0-9\]+.data - \\\(integer\\\(kind=\[48\]\\\)\\\) a, 1, &parm.\[0-9\]+, 0B, caf_token.0, \\\(integer\\\(kind=\[48\]\\\)\\\) parm.\[0-9\]+.data - \\\(integer\\\(kind=\[48\]\\\)\\\) a, 1, &parm.\[0-9\]+, 0B, 4, 4, 0\\\);" 1 "original" } }
|
||||||
|
|
||||||
|
! { dg-final { cleanup-tree-dump "original" } }
|
||||||
|
|
@ -1,3 +1,10 @@
|
||||||
|
2014-08-31 Tobias Burnus <burnus@net-b.de>
|
||||||
|
|
||||||
|
* caf/libcaf.h (_gfortran_caf_send, _gfortran_caf_get,
|
||||||
|
_gfortran_caf_sendget): Update prototype.
|
||||||
|
* caf/single.c (_gfortran_caf_send, _gfortran_caf_get,
|
||||||
|
_gfortran_caf_sendget): Handle may_require_tmp.
|
||||||
|
|
||||||
2014-08-20 Steven G. Kargl <kargl@gcc.gnu.org>
|
2014-08-20 Steven G. Kargl <kargl@gcc.gnu.org>
|
||||||
|
|
||||||
PR libgfortran/62188
|
PR libgfortran/62188
|
||||||
|
|
|
||||||
|
|
@ -114,12 +114,12 @@ void _gfortran_caf_co_max (gfc_descriptor_t *, int, int *, char *,
|
||||||
int, int);
|
int, int);
|
||||||
|
|
||||||
void _gfortran_caf_get (caf_token_t, size_t, int, gfc_descriptor_t *,
|
void _gfortran_caf_get (caf_token_t, size_t, int, gfc_descriptor_t *,
|
||||||
caf_vector_t *, gfc_descriptor_t *, int, int);
|
caf_vector_t *, gfc_descriptor_t *, int, int, bool);
|
||||||
void _gfortran_caf_send (caf_token_t, size_t, int, gfc_descriptor_t *,
|
void _gfortran_caf_send (caf_token_t, size_t, int, gfc_descriptor_t *,
|
||||||
caf_vector_t *, gfc_descriptor_t *, int, int);
|
caf_vector_t *, gfc_descriptor_t *, int, int, bool);
|
||||||
void _gfortran_caf_sendget (caf_token_t, size_t, int, gfc_descriptor_t *,
|
void _gfortran_caf_sendget (caf_token_t, size_t, int, gfc_descriptor_t *,
|
||||||
caf_vector_t *, caf_token_t, size_t, int,
|
caf_vector_t *, caf_token_t, size_t, int,
|
||||||
gfc_descriptor_t *, caf_vector_t *, int, int);
|
gfc_descriptor_t *, caf_vector_t *, int, int, bool);
|
||||||
|
|
||||||
void _gfortran_caf_atomic_define (caf_token_t, size_t, int, void *, int *,
|
void _gfortran_caf_atomic_define (caf_token_t, size_t, int, void *, int *,
|
||||||
int, int);
|
int, int);
|
||||||
|
|
|
||||||
|
|
@ -533,7 +533,8 @@ _gfortran_caf_get (caf_token_t token, size_t offset,
|
||||||
int image_index __attribute__ ((unused)),
|
int image_index __attribute__ ((unused)),
|
||||||
gfc_descriptor_t *src,
|
gfc_descriptor_t *src,
|
||||||
caf_vector_t *src_vector __attribute__ ((unused)),
|
caf_vector_t *src_vector __attribute__ ((unused)),
|
||||||
gfc_descriptor_t *dest, int src_kind, int dst_kind)
|
gfc_descriptor_t *dest, int src_kind, int dst_kind,
|
||||||
|
bool may_require_tmp)
|
||||||
{
|
{
|
||||||
/* FIXME: Handle vector subscripts. */
|
/* FIXME: Handle vector subscripts. */
|
||||||
size_t i, k, size;
|
size_t i, k, size;
|
||||||
|
|
@ -584,6 +585,82 @@ _gfortran_caf_get (caf_token_t token, size_t offset,
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (may_require_tmp)
|
||||||
|
{
|
||||||
|
ptrdiff_t array_offset_sr, array_offset_dst;
|
||||||
|
void *tmp = malloc (size*src_size);
|
||||||
|
|
||||||
|
array_offset_dst = 0;
|
||||||
|
for (i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
ptrdiff_t array_offset_sr = 0;
|
||||||
|
ptrdiff_t stride = 1;
|
||||||
|
ptrdiff_t extent = 1;
|
||||||
|
for (j = 0; j < GFC_DESCRIPTOR_RANK (src)-1; j++)
|
||||||
|
{
|
||||||
|
array_offset_sr += ((i / (extent*stride))
|
||||||
|
% (src->dim[j]._ubound
|
||||||
|
- src->dim[j].lower_bound + 1))
|
||||||
|
* src->dim[j]._stride;
|
||||||
|
extent = (src->dim[j]._ubound - src->dim[j].lower_bound + 1);
|
||||||
|
stride = src->dim[j]._stride;
|
||||||
|
}
|
||||||
|
array_offset_sr += (i / extent) * src->dim[rank-1]._stride;
|
||||||
|
void *sr = (void *)((char *) TOKEN (token) + offset
|
||||||
|
+ array_offset_sr*GFC_DESCRIPTOR_SIZE (src));
|
||||||
|
memcpy ((void *) ((char *) tmp + array_offset_dst), sr, src_size);
|
||||||
|
array_offset_dst += src_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
array_offset_sr = 0;
|
||||||
|
for (i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
ptrdiff_t array_offset_dst = 0;
|
||||||
|
ptrdiff_t stride = 1;
|
||||||
|
ptrdiff_t extent = 1;
|
||||||
|
for (j = 0; j < rank-1; j++)
|
||||||
|
{
|
||||||
|
array_offset_dst += ((i / (extent*stride))
|
||||||
|
% (dest->dim[j]._ubound
|
||||||
|
- dest->dim[j].lower_bound + 1))
|
||||||
|
* dest->dim[j]._stride;
|
||||||
|
extent = (dest->dim[j]._ubound - dest->dim[j].lower_bound + 1);
|
||||||
|
stride = dest->dim[j]._stride;
|
||||||
|
}
|
||||||
|
array_offset_dst += (i / extent) * dest->dim[rank-1]._stride;
|
||||||
|
void *dst = dest->base_addr
|
||||||
|
+ array_offset_dst*GFC_DESCRIPTOR_SIZE (dest);
|
||||||
|
void *sr = tmp + array_offset_sr;
|
||||||
|
|
||||||
|
if (GFC_DESCRIPTOR_TYPE (dest) == GFC_DESCRIPTOR_TYPE (src)
|
||||||
|
&& dst_kind == src_kind)
|
||||||
|
{
|
||||||
|
memmove (dst, sr, dst_size > src_size ? src_size : dst_size);
|
||||||
|
if (GFC_DESCRIPTOR_TYPE (dest) == BT_CHARACTER
|
||||||
|
&& dst_size > src_size)
|
||||||
|
{
|
||||||
|
if (dst_kind == 1)
|
||||||
|
memset ((void*)(char*) dst + src_size, ' ',
|
||||||
|
dst_size-src_size);
|
||||||
|
else /* dst_kind == 4. */
|
||||||
|
for (k = src_size/4; k < dst_size/4; k++)
|
||||||
|
((int32_t*) dst)[k] = (int32_t) ' ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (GFC_DESCRIPTOR_TYPE (dest) == BT_CHARACTER && dst_kind == 1)
|
||||||
|
assign_char1_from_char4 (dst_size, src_size, dst, sr);
|
||||||
|
else if (GFC_DESCRIPTOR_TYPE (dest) == BT_CHARACTER)
|
||||||
|
assign_char4_from_char1 (dst_size, src_size, dst, sr);
|
||||||
|
else
|
||||||
|
convert_type (dst, GFC_DESCRIPTOR_TYPE (dest), dst_kind,
|
||||||
|
sr, GFC_DESCRIPTOR_TYPE (src), src_kind);
|
||||||
|
array_offset_sr += src_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
free (tmp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < size; i++)
|
for (i = 0; i < size; i++)
|
||||||
{
|
{
|
||||||
ptrdiff_t array_offset_dst = 0;
|
ptrdiff_t array_offset_dst = 0;
|
||||||
|
|
@ -646,7 +723,8 @@ _gfortran_caf_send (caf_token_t token, size_t offset,
|
||||||
int image_index __attribute__ ((unused)),
|
int image_index __attribute__ ((unused)),
|
||||||
gfc_descriptor_t *dest,
|
gfc_descriptor_t *dest,
|
||||||
caf_vector_t *dst_vector __attribute__ ((unused)),
|
caf_vector_t *dst_vector __attribute__ ((unused)),
|
||||||
gfc_descriptor_t *src, int dst_kind, int src_kind)
|
gfc_descriptor_t *src, int dst_kind, int src_kind,
|
||||||
|
bool may_require_tmp)
|
||||||
{
|
{
|
||||||
/* FIXME: Handle vector subscripts. */
|
/* FIXME: Handle vector subscripts. */
|
||||||
size_t i, k, size;
|
size_t i, k, size;
|
||||||
|
|
@ -697,6 +775,91 @@ _gfortran_caf_send (caf_token_t token, size_t offset,
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (may_require_tmp)
|
||||||
|
{
|
||||||
|
ptrdiff_t array_offset_sr, array_offset_dst;
|
||||||
|
void *tmp;
|
||||||
|
|
||||||
|
if (GFC_DESCRIPTOR_RANK (src) == 0)
|
||||||
|
{
|
||||||
|
tmp = malloc (src_size);
|
||||||
|
memcpy (tmp, GFC_DESCRIPTOR_DATA (src), src_size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tmp = malloc (size*src_size);
|
||||||
|
array_offset_dst = 0;
|
||||||
|
for (i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
ptrdiff_t array_offset_sr = 0;
|
||||||
|
ptrdiff_t stride = 1;
|
||||||
|
ptrdiff_t extent = 1;
|
||||||
|
for (j = 0; j < GFC_DESCRIPTOR_RANK (src)-1; j++)
|
||||||
|
{
|
||||||
|
array_offset_sr += ((i / (extent*stride))
|
||||||
|
% (src->dim[j]._ubound
|
||||||
|
- src->dim[j].lower_bound + 1))
|
||||||
|
* src->dim[j]._stride;
|
||||||
|
extent = (src->dim[j]._ubound - src->dim[j].lower_bound + 1);
|
||||||
|
stride = src->dim[j]._stride;
|
||||||
|
}
|
||||||
|
array_offset_sr += (i / extent) * src->dim[rank-1]._stride;
|
||||||
|
void *sr = (void *) ((char *) src->base_addr
|
||||||
|
+ array_offset_sr*GFC_DESCRIPTOR_SIZE (src));
|
||||||
|
memcpy ((void *) ((char *) tmp + array_offset_dst), sr, src_size);
|
||||||
|
array_offset_dst += src_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
array_offset_sr = 0;
|
||||||
|
for (i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
ptrdiff_t array_offset_dst = 0;
|
||||||
|
ptrdiff_t stride = 1;
|
||||||
|
ptrdiff_t extent = 1;
|
||||||
|
for (j = 0; j < rank-1; j++)
|
||||||
|
{
|
||||||
|
array_offset_dst += ((i / (extent*stride))
|
||||||
|
% (dest->dim[j]._ubound
|
||||||
|
- dest->dim[j].lower_bound + 1))
|
||||||
|
* dest->dim[j]._stride;
|
||||||
|
extent = (dest->dim[j]._ubound - dest->dim[j].lower_bound + 1);
|
||||||
|
stride = dest->dim[j]._stride;
|
||||||
|
}
|
||||||
|
array_offset_dst += (i / extent) * dest->dim[rank-1]._stride;
|
||||||
|
void *dst = (void *)((char *) TOKEN (token) + offset
|
||||||
|
+ array_offset_dst*GFC_DESCRIPTOR_SIZE (dest));
|
||||||
|
void *sr = tmp + array_offset_sr;
|
||||||
|
if (GFC_DESCRIPTOR_TYPE (dest) == GFC_DESCRIPTOR_TYPE (src)
|
||||||
|
&& dst_kind == src_kind)
|
||||||
|
{
|
||||||
|
memmove (dst, sr,
|
||||||
|
dst_size > src_size ? src_size : dst_size);
|
||||||
|
if (GFC_DESCRIPTOR_TYPE (dest) == BT_CHARACTER
|
||||||
|
&& dst_size > src_size)
|
||||||
|
{
|
||||||
|
if (dst_kind == 1)
|
||||||
|
memset ((void*)(char*) dst + src_size, ' ',
|
||||||
|
dst_size-src_size);
|
||||||
|
else /* dst_kind == 4. */
|
||||||
|
for (k = src_size/4; k < dst_size/4; k++)
|
||||||
|
((int32_t*) dst)[k] = (int32_t) ' ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (GFC_DESCRIPTOR_TYPE (dest) == BT_CHARACTER && dst_kind == 1)
|
||||||
|
assign_char1_from_char4 (dst_size, src_size, dst, sr);
|
||||||
|
else if (GFC_DESCRIPTOR_TYPE (dest) == BT_CHARACTER)
|
||||||
|
assign_char4_from_char1 (dst_size, src_size, dst, sr);
|
||||||
|
else
|
||||||
|
convert_type (dst, GFC_DESCRIPTOR_TYPE (dest), dst_kind,
|
||||||
|
sr, GFC_DESCRIPTOR_TYPE (src), src_kind);
|
||||||
|
if (GFC_DESCRIPTOR_RANK (src))
|
||||||
|
array_offset_sr += src_size;
|
||||||
|
}
|
||||||
|
free (tmp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < size; i++)
|
for (i = 0; i < size; i++)
|
||||||
{
|
{
|
||||||
ptrdiff_t array_offset_dst = 0;
|
ptrdiff_t array_offset_dst = 0;
|
||||||
|
|
@ -769,7 +932,7 @@ _gfortran_caf_sendget (caf_token_t dst_token, size_t dst_offset,
|
||||||
int src_image_index __attribute__ ((unused)),
|
int src_image_index __attribute__ ((unused)),
|
||||||
gfc_descriptor_t *src,
|
gfc_descriptor_t *src,
|
||||||
caf_vector_t *src_vector __attribute__ ((unused)),
|
caf_vector_t *src_vector __attribute__ ((unused)),
|
||||||
int dst_kind, int src_kind)
|
int dst_kind, int src_kind, bool may_require_tmp)
|
||||||
{
|
{
|
||||||
/* FIXME: Handle vector subscript of 'src_vector'. */
|
/* FIXME: Handle vector subscript of 'src_vector'. */
|
||||||
/* For a single image, src->base_addr should be the same as src_token + offset
|
/* For a single image, src->base_addr should be the same as src_token + offset
|
||||||
|
|
@ -777,7 +940,7 @@ _gfortran_caf_sendget (caf_token_t dst_token, size_t dst_offset,
|
||||||
void *src_base = GFC_DESCRIPTOR_DATA (src);
|
void *src_base = GFC_DESCRIPTOR_DATA (src);
|
||||||
GFC_DESCRIPTOR_DATA (src) = (void *) ((char *) TOKEN (src_token) + src_offset);
|
GFC_DESCRIPTOR_DATA (src) = (void *) ((char *) TOKEN (src_token) + src_offset);
|
||||||
_gfortran_caf_send (dst_token, dst_offset, dst_image_index, dest, dst_vector,
|
_gfortran_caf_send (dst_token, dst_offset, dst_image_index, dest, dst_vector,
|
||||||
src, dst_kind, src_kind);
|
src, dst_kind, src_kind, may_require_tmp);
|
||||||
GFC_DESCRIPTOR_DATA (src) = src_base;
|
GFC_DESCRIPTOR_DATA (src) = src_base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue