Arrays in fortran have a couple of internal variables associated with
them, e.g. stride, lbound, ubound, size, etc. Depending on how and where
the array was declared, these internal variables may be packed inside an
array descriptor represented by a struct or defined individually. The
major problem with this is that kernels and parallel regions with
default(none) will generate errors if those internal variables are
defined individually since the user has no way to add clauses to them. I
suspect this is also true for arrays inside omp target regions.
My fix for this involves two parts. First, I reinitialize those private
array variables which aren't associated with array descriptors at the
beginning of the parallel/kernels region they are used in. Second, I
added OMP_CLAUSE_PRIVATE for those internal variables.
I'll apply this patch to gomp-4_0-branch shortly.
Is there any reason why only certain arrays have array descriptors? The
arrays with descriptors don't have this problem. It's only the ones
without descriptors that leak new internal variables that cause errors
with default(none).
Cesar
2015-10-13 Cesar Philippidis
gcc/fortran/
* trans-array.c (gfc_trans_array_bounds): Add an INIT_VLA argument
to control whether VLAs should be initialized. Don't mark this
function as static.
(gfc_trans_auto_array_allocation): Update call to
gfc_trans_array_bounds.
(gfc_trans_g77_array): Likewise.
* trans-array.h: Declare gfc_trans_array_bounds.
* trans-openmp.c (gfc_scan_nodesc_arrays): New function.
(gfc_privatize_nodesc_arrays_1): New function.
(gfc_privatize_nodesc_arrays): New function.
(gfc_init_nodesc_arrays): New function.
(gfc_trans_oacc_construct): Initialize any internal variables for
arrays without array descriptors inside the offloaded parallel and
kernels region.
(gfc_trans_oacc_combined_directive): Likewise.
gcc/testsuite/
* gfortran.dg/goacc/default_none.f95: New test.
diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c
index a6b761b..86f983a 100644
--- a/gcc/fortran/trans-array.c
+++ b/gcc/fortran/trans-array.c
@@ -5709,9 +5709,9 @@ gfc_trans_array_cobounds (tree type, stmtblock_t * pblock,
/* Generate code to evaluate non-constant array bounds. Sets *poffset and
returns the size (in elements) of the array. */
-static tree
+tree
gfc_trans_array_bounds (tree type, gfc_symbol * sym, tree * poffset,
-stmtblock_t * pblock)
+stmtblock_t * pblock, bool init_vla)
{
gfc_array_spec *as;
tree size;
@@ -5788,7 +5788,9 @@ gfc_trans_array_bounds (tree type, gfc_symbol * sym, tree * poffset,
}
gfc_trans_array_cobounds (type, pblock, sym);
- gfc_trans_vla_type_sizes (sym, pblock);
+
+ if (init_vla)
+gfc_trans_vla_type_sizes (sym, pblock);
*poffset = offset;
return size;
@@ -5852,7 +5854,7 @@ gfc_trans_auto_array_allocation (tree decl, gfc_symbol * sym,
&& !INTEGER_CST_P (sym->ts.u.cl->backend_decl))
gfc_conv_string_length (sym->ts.u.cl, NULL, );
- size = gfc_trans_array_bounds (type, sym, , );
+ size = gfc_trans_array_bounds (type, sym, , , true);
/* Don't actually allocate space for Cray Pointees. */
if (sym->attr.cray_pointee)
@@ -5947,7 +5949,7 @@ gfc_trans_g77_array (gfc_symbol * sym, gfc_wrapped_block * block)
gfc_conv_string_length (sym->ts.u.cl, NULL, );
/* Evaluate the bounds of the array. */
- gfc_trans_array_bounds (type, sym, , );
+ gfc_trans_array_bounds (type, sym, , , true);
/* Set the offset. */
if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
diff --git a/gcc/fortran/trans-array.h b/gcc/fortran/trans-array.h
index 52f1c9a..8dbafb9 100644
--- a/gcc/fortran/trans-array.h
+++ b/gcc/fortran/trans-array.h
@@ -44,6 +44,8 @@ void gfc_trans_g77_array (gfc_symbol *, gfc_wrapped_block *);
/* Generate code to deallocate an array, if it is allocated. */
tree gfc_trans_dealloc_allocated (tree, bool, gfc_expr *);
+tree gfc_trans_array_bounds (tree, gfc_symbol *, tree *, stmtblock_t *, bool);
+
tree gfc_full_array_size (stmtblock_t *, tree, int);
tree gfc_duplicate_allocatable (tree, tree, tree, int, tree);
diff --git a/gcc/fortran/trans-openmp.c b/gcc/fortran/trans-openmp.c
index 8c1e897..f2e9803 100644
--- a/gcc/fortran/trans-openmp.c
+++ b/gcc/fortran/trans-openmp.c
@@ -39,6 +39,8 @@ along with GCC; see the file COPYING3. If not see
#include "arith.h"
#include "omp-low.h"
#include "gomp-constants.h"
+#include "hash-set.h"
+#include "tree-iterator.h"
int ompws_flags;
@@ -2716,22 +2718,157 @@ gfc_trans_omp_code (gfc_code *code, bool force_empty)
return stmt;
}
+void gfc_debug_expr (gfc_expr *);
+
+/* Add any array that does not have an array descriptor to the hash_set
+ pointed to by DATA. */
+
+static int
+gfc_scan_nodesc_arrays (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
+ void *data)
+{
+ hash_set *arrays = (hash_set *)data;
+
+ if ((*e)->expr_type ==