Patchwork [Fortran-Dev,committed] Fix SIZE call - and, hence, 3 regressions

login
register
mail settings
Submitter Tobias Burnus
Date May 7, 2013, 4:53 p.m.
Message ID <5189319C.3080700@net-b.de>
Download mbox | patch
Permalink /patch/242414/
State New
Headers show

Comments

Tobias Burnus - May 7, 2013, 4:53 p.m.
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

Patch

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],