Patchwork [fortran] LBOUND/UBOUND/SHAPE assumed rank support

login
register
mail settings
Submitter Mikael Morin
Date Aug. 2, 2012, 2:17 p.m.
Message ID <501A8BE9.9090008@sfr.fr>
Download mbox | patch
Permalink /patch/174764/
State New
Headers show

Comments

Mikael Morin - Aug. 2, 2012, 2:17 p.m.
Hello,

as promised, I submit the patch (split to 5 pieces) adding support for
assumed rank actual arguments to the LBOUND/UBOUND/SHAPE intrinsics in
the non-scalar case (without the DIM argument).

Patch 1: Disable shape setting and simplification for assumed rank.
Patch 2: Move and rename get_rank_from_desc to gfc_conv_descriptor_rank.
Patch 3: Fix set_loop_bounds #1 (optional).
Patch 4: Fix set_loop_bounds #2.
Patch 5: Properly setup the scalarizer in the {l,u}bound(assumed_rank)
cases.

More details in the patch files.

Regression tested on x86_64-unknown-linux-gnu. OK for trunk?

Mikael
Tobias Burnus - Aug. 2, 2012, 2:48 p.m.
Hello Mikael,

thanks for your patch series, which not only implements missing parts of 
the assumed-rank support but also fixes some buglets such as the 
set_loop_bounds setting or the shape setting for assumed ranks. The 
patch is okay.

Tobias

On 08/02/2012 04:17 PM, Mikael Morin wrote:
> Hello,
>
> as promised, I submit the patch (split to 5 pieces) adding support for
> assumed rank actual arguments to the LBOUND/UBOUND/SHAPE intrinsics in
> the non-scalar case (without the DIM argument).
>
> Patch 1: Disable shape setting and simplification for assumed rank.
> Patch 2: Move and rename get_rank_from_desc to gfc_conv_descriptor_rank.
> Patch 3: Fix set_loop_bounds #1 (optional).
> Patch 4: Fix set_loop_bounds #2.
> Patch 5: Properly setup the scalarizer in the {l,u}bound(assumed_rank)
> cases.
>
> More details in the patch files.
>
> Regression tested on x86_64-unknown-linux-gnu. OK for trunk?
>
> Mikael
>
>
>
>
>

Patch

This part finally uses the rank to setup the intrinsic boundspec in
gfc_conv_ss_startstride and uses the intrinsic boundspec to set the
upper bound in set_loop_bounds.

There is no additional code; with this the scalarizer is properly setup
and calls appropriately the code previously modified by Tobias to handle
the DIM= version of the {l,u}bound and shape intrinsics.


2012-08-02  Mikael Morin  <mikael@gcc.gnu.org>

	* trans-array.c (gfc_conv_ss_startstride): Set the intrinsic
	result's lower and upper bounds according to the rank.
	(set_loop_bounds): Set the loop upper bound in the intrinsic case.

diff --git a/trans-array.c b/trans-array.c
index b799e24..187eab0 100644
--- a/trans-array.c
+++ b/trans-array.c
@@ -3808,6 +3808,40 @@  done:
 	    /* Fall through to supply start and stride.  */
 	    case GFC_ISYM_LBOUND:
 	    case GFC_ISYM_UBOUND:
+	      {
+		gfc_expr *arg;
+
+		/* This is the variant without DIM=...  */
+		gcc_assert (expr->value.function.actual->next->expr == NULL);
+
+		arg = expr->value.function.actual->expr;
+		if (arg->rank == -1)
+		  {
+		    gfc_se se;
+		    tree rank, tmp;
+
+		    /* The rank (hence the return value's shape) is unknown,
+		       we have to retrieve it.  */
+		    gfc_init_se (&se, NULL);
+		    se.descriptor_only = 1;
+		    gfc_conv_expr (&se, arg);
+		    /* This is a bare variable, so there is no preliminary
+		       or cleanup code.  */
+		    gcc_assert (se.pre.head == NULL_TREE
+				&& se.post.head == NULL_TREE);
+		    rank = gfc_conv_descriptor_rank (se.expr);
+		    tmp = fold_build2_loc (input_location, MINUS_EXPR,
+					   gfc_array_index_type,
+					   fold_convert (gfc_array_index_type,
+							 rank),
+					   gfc_index_one_node);
+		    info->end[0] = gfc_evaluate_now (tmp, &loop->pre);
+		    info->start[0] = gfc_index_zero_node;
+		    info->stride[0] = gfc_index_one_node;
+		    continue;
+		  }
+		  /* Otherwise fall through GFC_SS_FUNCTION.  */
+	      }
 	    case GFC_ISYM_LCOBOUND:
 	    case GFC_ISYM_UCOBOUND:
 	    case GFC_ISYM_THIS_IMAGE:
@@ -4526,6 +4560,20 @@  set_loop_bounds (gfc_loopinfo *loop)
 	      gcc_assert (loop->to[n] == NULL_TREE);
 	      break;
 
+	    case GFC_SS_INTRINSIC:
+	      {
+		gfc_expr *expr = loopspec[n]->info->expr;
+
+		/* The {l,u}bound of an assumed rank.  */
+		gcc_assert ((expr->value.function.isym->id == GFC_ISYM_LBOUND
+			     || expr->value.function.isym->id == GFC_ISYM_UBOUND)
+			     && expr->value.function.actual->next->expr == NULL
+			     && expr->value.function.actual->expr->rank == -1);
+
+		loop->to[n] = info->end[dim];
+		break;
+	      }
+
 	    default:
 	      gcc_unreachable ();
 	    }