This is the mail archive of the
fortran@gcc.gnu.org
mailing list for the GNU Fortran project.
[Fortran-Dev, committed] Fix SIZE call - and, hence, 3 regressions
- From: Tobias Burnus <burnus at net-b dot de>
- To: gfortran <fortran at gcc dot gnu dot org>, gcc patches <gcc-patches at gcc dot gnu dot org>
- Date: Tue, 07 May 2013 18:53:48 +0200
- Subject: [Fortran-Dev, committed] Fix SIZE call - and, hence, 3 regressions
This is another trivial patch, which fixes three regressions. The
following four regressions remain:
gfortran.dg/mvbits_7.f90
gfortran.dg/mvbits_8.f90
gfortran.dg/subref_array_pointer_2.f90
gfortran.dg/unlimited_polymorphic_1.f03
Committed as Rev. 198688 - after building and regtesting on
x86-64-gnu-linux.
(Actually, that's not quite true: The last merge from the trunk also
imported some
regressions:http://gcc.gnu.org/ml/gcc-patches/2013-05/msg00352.html -
but ignoring those, there are only 4 regression left on the branch :-)
* * *
I think the mvbits regressions are related to elem_len != sm, i.e. since
dtype's size (now: elem_len) no longer matches stride multiplier, it
fails. But maybe that's the wrong assessment.
TODO:
- Fix the 4 regressions
- Remove the "offset" field/component from the descriptor
- Set lower_bound == 0 for the args to a nonpointer/nonalloc dummy argument.
- Handle elem_len != n*stride throughout the code
- Audit the use of elem_len, stride/sm, ubound, type, attribute for
correctness and performance optimization (e.g. making use of the
lower_bound==0 knowledge)
Tobias
Index: gcc/fortran/ChangeLog.fortran-dev
===================================================================
--- gcc/fortran/ChangeLog.fortran-dev (Revision 198687)
+++ gcc/fortran/ChangeLog.fortran-dev (Arbeitskopie)
@@ -1,5 +1,10 @@
2013-05-07 Tobias Burnus <burnus@net-b.de>
+ * trans-intrinsic.c (gfc_conv_intrinsic_bound,
+ gfc_conv_intrinsic_size): Set argse.data_not_needed.
+
+2013-05-07 Tobias Burnus <burnus@net-b.de>
+
* trans-array.c (gfc_conv_descriptor_stride_get,
gfc_conv_descriptor_stride_set): Use elem_len, unless it is
a nonstring intrinsic type for which size_in_bytes is used.
Index: gcc/fortran/trans-intrinsic.c
===================================================================
--- gcc/fortran/trans-intrinsic.c (Revision 198687)
+++ gcc/fortran/trans-intrinsic.c (Arbeitskopie)
@@ -1334,6 +1334,7 @@ gfc_conv_intrinsic_bound (gfc_se * se, gfc_expr *
/* TODO: don't re-evaluate the descriptor on each iteration. */
/* Get a descriptor for the first parameter. */
gfc_init_se (&argse, NULL);
+ argse.data_not_needed = 1;
gfc_conv_expr_descriptor (&argse, arg->expr);
gfc_add_block_to_block (&se->pre, &argse.pre);
gfc_add_block_to_block (&se->post, &argse.post);
@@ -5091,6 +5092,7 @@ gfc_conv_intrinsic_size (gfc_se * se, gfc_expr * e
/* TODO: don't re-evaluate the descriptor on each iteration. */
/* Get a descriptor for the first parameter. */
gfc_init_se (&argse, NULL);
+ argse.data_not_needed = 1;
gfc_conv_expr_descriptor (&argse, arg->expr);
gfc_add_block_to_block (&se->pre, &argse.pre);
gfc_add_block_to_block (&se->post, &argse.post);
2013-05-07 Tobias Burnus <burnus@net-b.de>
* trans-array.c (gfc_conv_descriptor_stride_get,
gfc_conv_descriptor_stride_set): Use elem_len, unless it is
a nonstring intrinsic type for which size_in_bytes is used.
(gfc_array_init_size): Set elem_len before handling the
strides.
* trans-expr.c (gfc_conv_subref_array_arg): Remove no-op
extent shifting code.
diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c
index 08f12aa..db8de69 100644
--- a/gcc/fortran/trans-array.c
+++ b/gcc/fortran/trans-array.c
@@ -422,7 +422,11 @@ gfc_conv_descriptor_stride_get (tree desc, tree dim)
return gfc_index_one_node;
tmp = gfc_get_element_type (type);
- size = size_in_bytes (tmp);
+ if (TREE_CODE (tmp) != RECORD_TYPE && !TYPE_STRING_FLAG (tmp))
+ size = size_in_bytes (tmp);
+ else
+ size = gfc_conv_descriptor_elem_len_get (desc);
+
size = fold_convert (gfc_array_index_type, size);
tmp = fold_build2_loc (input_location, FLOOR_DIV_EXPR, gfc_array_index_type,
gfc_conv_descriptor_sm_get (desc, dim), size);
@@ -440,7 +444,11 @@ gfc_conv_descriptor_stride_set (stmtblock_t *block, tree desc,
{
tree tmp;
tmp = gfc_get_element_type (TREE_TYPE (desc));
- tmp = size_in_bytes (tmp);
+ if (TREE_CODE (tmp) != RECORD_TYPE && !TYPE_STRING_FLAG (tmp))
+ tmp = size_in_bytes (tmp);
+ else
+ tmp = gfc_conv_descriptor_elem_len_get (desc);
+
tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
fold_convert (gfc_array_index_type, value),
fold_convert (gfc_array_index_type, tmp));
@@ -5117,6 +5125,34 @@ gfc_array_init_size (tree descriptor, gfc_typespec *ts,
tmp = gfc_conv_descriptor_dtype (descriptor);
gfc_add_modify (descriptor_block, tmp, gfc_get_dtype (ts));
+ if (expr3_elem_size != NULL_TREE)
+ tmp = expr3_elem_size;
+ else if (expr3 != NULL)
+ {
+ if (expr3->ts.type == BT_CLASS)
+ {
+ gfc_se se_sz;
+ gfc_expr *sz = gfc_copy_expr (expr3);
+ gfc_add_vptr_component (sz);
+ gfc_add_size_component (sz);
+ gfc_init_se (&se_sz, NULL);
+ gfc_conv_expr (&se_sz, sz);
+ gfc_free_expr (sz);
+ tmp = se_sz.expr;
+ }
+ else
+ {
+ tmp = gfc_typenode_for_spec (&expr3->ts);
+ tmp = TYPE_SIZE_UNIT (tmp);
+ }
+ }
+ else
+ tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
+
+ /* Convert to size_t. */
+ element_size = fold_convert (size_type_node, tmp);
+ gfc_conv_descriptor_elem_len_set (descriptor_block, descriptor, element_size);
+
or_expr = boolean_false_node;
for (n = 0; n < rank; n++)
@@ -5249,36 +5285,6 @@ gfc_array_init_size (tree descriptor, gfc_typespec *ts,
}
}
- /* The stride is the number of elements in the array, so multiply by the
- size of an element to get the total size. Obviously, if there is a
- SOURCE expression (expr3) we must use its element size. */
- if (expr3_elem_size != NULL_TREE)
- tmp = expr3_elem_size;
- else if (expr3 != NULL)
- {
- if (expr3->ts.type == BT_CLASS)
- {
- gfc_se se_sz;
- gfc_expr *sz = gfc_copy_expr (expr3);
- gfc_add_vptr_component (sz);
- gfc_add_size_component (sz);
- gfc_init_se (&se_sz, NULL);
- gfc_conv_expr (&se_sz, sz);
- gfc_free_expr (sz);
- tmp = se_sz.expr;
- }
- else
- {
- tmp = gfc_typenode_for_spec (&expr3->ts);
- tmp = TYPE_SIZE_UNIT (tmp);
- }
- }
- else
- tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
-
- /* Convert to size_t. */
- element_size = fold_convert (size_type_node, tmp);
-
if (rank == 0)
return element_size;
diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
index 2370f44..07f3ead 100644
--- a/gcc/fortran/trans-expr.c
+++ b/gcc/fortran/trans-expr.c
@@ -3772,12 +3772,6 @@ gfc_conv_subref_array_arg (gfc_se * parmse, gfc_expr * expr, int g77,
offset = gfc_index_zero_node;
for (n = 0; n < dimen; n++)
{
- tmp = gfc_conv_descriptor_extent_get (parmse->expr,
- gfc_rank_cst[n]);
- gfc_conv_descriptor_ubound_set (&parmse->pre,
- parmse->expr,
- gfc_rank_cst[n],
- tmp);
gfc_conv_descriptor_lbound_set (&parmse->pre,
parmse->expr,
gfc_rank_cst[n],