aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/trans-openmp.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/fortran/trans-openmp.cc')
-rw-r--r--gcc/fortran/trans-openmp.cc53
1 files changed, 43 insertions, 10 deletions
diff --git a/gcc/fortran/trans-openmp.cc b/gcc/fortran/trans-openmp.cc
index e1907a4..bfd24f9 100644
--- a/gcc/fortran/trans-openmp.cc
+++ b/gcc/fortran/trans-openmp.cc
@@ -169,6 +169,48 @@ gfc_omp_array_data (tree decl, bool type_only)
return decl;
}
+/* Return the byte-size of the passed array descriptor. */
+
+tree
+gfc_omp_array_size (tree decl, gimple_seq *pre_p)
+{
+ stmtblock_t block;
+ if (POINTER_TYPE_P (TREE_TYPE (decl)))
+ decl = build_fold_indirect_ref (decl);
+ tree type = TREE_TYPE (decl);
+ gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
+ bool allocatable = (GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_ALLOCATABLE
+ || GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_POINTER
+ || GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_POINTER_CONT);
+ gfc_init_block (&block);
+ tree size = gfc_full_array_size (&block, decl,
+ GFC_TYPE_ARRAY_RANK (TREE_TYPE (decl)));
+ size = fold_convert (size_type_node, size);
+ tree elemsz = gfc_get_element_type (TREE_TYPE (decl));
+ if (TREE_CODE (elemsz) == ARRAY_TYPE && TYPE_STRING_FLAG (elemsz))
+ elemsz = gfc_conv_descriptor_elem_len (decl);
+ else
+ elemsz = TYPE_SIZE_UNIT (elemsz);
+ size = fold_build2 (MULT_EXPR, size_type_node, size, elemsz);
+ if (!allocatable)
+ gimplify_and_add (gfc_finish_block (&block), pre_p);
+ else
+ {
+ tree var = create_tmp_var (size_type_node);
+ gfc_add_expr_to_block (&block, build2 (MODIFY_EXPR, sizetype, var, size));
+ tree tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
+ gfc_conv_descriptor_data_get (decl),
+ null_pointer_node);
+ tmp = build3_loc (input_location, COND_EXPR, void_type_node, tmp,
+ gfc_finish_block (&block),
+ build2 (MODIFY_EXPR, sizetype, var, size_zero_node));
+ gimplify_and_add (tmp, pre_p);
+ size = var;
+ }
+ return size;
+}
+
+
/* True if OpenMP should privatize what this DECL points to rather
than the DECL itself. */
@@ -1922,16 +1964,7 @@ gfc_trans_omp_variable_list (enum omp_clause_code code,
if (t != error_mark_node)
{
tree node;
- /* For HAS_DEVICE_ADDR of an array descriptor, firstprivatize the
- descriptor such that the bounds are available; its data component
- is unmodified; it is handled as device address inside target. */
- if (code == OMP_CLAUSE_HAS_DEVICE_ADDR
- && (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (t))
- || (POINTER_TYPE_P (TREE_TYPE (t))
- && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (t))))))
- node = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
- else
- node = build_omp_clause (input_location, code);
+ node = build_omp_clause (input_location, code);
OMP_CLAUSE_DECL (node) = t;
list = gfc_trans_add_clause (node, list);