[PATCH, PR 41112] Another attempt to deal with variable bounded arrays in SRA

Richard Guenther rguenther@suse.de
Fri Sep 4 09:24:00 GMT 2009


On Thu, 3 Sep 2009, Martin Jambor wrote:

> Hi,
> 
> after Richi said he did not want to disqualify whole aggregates if
> only a part of them are variable bounded arrays, I have come up with
> the following approach which scans the access expressions for such
> ARRAY_REFs when analyzing the access tree.
> 
> While testing this I ran into the problem with
> duplicate_expr_for_different_base and so this patch needs to go on top
> of the one removing it.
> 
> Bootstrapped and regression-tested on x86_64-linux, both n a revision
> before and after the patch turning SRA down.
> 
> OK for trunk?

Ok.

Thanks,
Richard.

> Thanks,
> 
> Martin
> 
> 
> 2009-09-03  Martin Jambor  <mjambor@suse.cz>
> 
> 	PR tree-optimization/41112
> 	* tree-sra.c (build_ref_for_offset_1): Signal that we cannot
> 	handle varibale-bounded arrays.
> 	(expr_with_var_bounded_array_refs_p): New function.
> 	(analyze_access_subtree): Call expr_with_var_bounded_array_refs_p.
> 
> 	* testsuite/gnat.dg/array8.adb: New test.
> 
> 
> Index: mine/gcc/tree-sra.c
> ===================================================================
> --- mine.orig/gcc/tree-sra.c
> +++ mine/gcc/tree-sra.c
> @@ -1039,7 +1039,7 @@ build_ref_for_offset_1 (tree *res, tree
>    while (1)
>      {
>        tree fld;
> -      tree tr_size, index;
> +      tree tr_size, index, minidx;
>        HOST_WIDE_INT el_size;
>  
>        if (offset == 0 && exp_type
> @@ -1090,13 +1090,14 @@ build_ref_for_offset_1 (tree *res, tree
>  	    return false;
>  	  el_size = tree_low_cst (tr_size, 1);
>  
> +	  minidx = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
> +	  if (TREE_CODE (minidx) != INTEGER_CST)
> +	    return false;
>  	  if (res)
>  	    {
>  	      index = build_int_cst (TYPE_DOMAIN (type), offset / el_size);
> -	      if (!integer_zerop (TYPE_MIN_VALUE (TYPE_DOMAIN (type))))
> -		index = int_const_binop (PLUS_EXPR, index,
> -					 TYPE_MIN_VALUE (TYPE_DOMAIN (type)),
> -					 0);
> +	      if (!integer_zerop (minidx))
> +		index = int_const_binop (PLUS_EXPR, index, minidx, 0);
>  	      *res = build4 (ARRAY_REF, TREE_TYPE (type), *res, index,
>  			     NULL_TREE, NULL_TREE);
>  	    }
> @@ -1378,6 +1379,22 @@ build_access_trees (struct access *acces
>      }
>  }
>  
> +/* Return true if expr contains some ARRAY_REFs into a variable bounded
> +   array.  */
> +
> +static bool
> +expr_with_var_bounded_array_refs_p (tree expr)
> +{
> +  while (handled_component_p (expr))
> +    {
> +      if (TREE_CODE (expr) == ARRAY_REF
> +	  && !host_integerp (array_ref_low_bound (expr), 0))
> +	return true;
> +      expr = TREE_OPERAND (expr, 0);
> +    }
> +  return false;
> +}
> +
>  /* Analyze the subtree of accesses rooted in ROOT, scheduling replacements when
>     both seeming beneficial and when ALLOW_REPLACEMENTS allows it.  Also set
>     all sorts of access flags appropriately along the way, notably always ser
> @@ -1407,6 +1424,9 @@ analyze_access_subtree (struct access *r
>    if (root->grp_unscalarizable_region)
>      allow_replacements = false;
>  
> +  if (allow_replacements && expr_with_var_bounded_array_refs_p (root->expr))
> +    allow_replacements = false;
> +
>    for (child = root->first_child; child; child = child->next_sibling)
>      {
>        if (!hole && child->offset < covered_to)
> Index: mine/gcc/testsuite/gnat.dg/array8.adb
> ===================================================================
> --- /dev/null
> +++ mine/gcc/testsuite/gnat.dg/array8.adb
> @@ -0,0 +1,34 @@
> +-- { dg-do compile }
> +-- { dg-options "-O2" }
> +
> +PROCEDURE Array8 IS
> +
> +  function ID (I : Integer) return Integer is
> +  begin
> +    return I;
> +  end;
> +
> +  SUBTYPE STB IS INTEGER RANGE ID(-8) .. -5;
> +
> +  TYPE TB IS ARRAY (STB RANGE <>) OF INTEGER;
> +
> +  GENERIC
> +    B1 : TB;
> +  PROCEDURE PROC1;
> +
> +  PROCEDURE PROC1 IS
> +  BEGIN
> +    IF B1'FIRST /= -8 THEN
> +      raise Program_Error;
> +    ELSIF B1'LAST /= ID(-5) THEN
> +      raise Program_Error;
> +    ELSIF B1 /= (7, 6, 5, 4) THEN
> +      raise Program_Error;
> +    END IF;
> +  END;
> +
> +  PROCEDURE PROC2 IS NEW PROC1 ((7, 6, ID(5), 4));
> +
> +BEGIN
> +  PROC2;
> +END;
> 
> 

-- 
Richard Guenther <rguenther@suse.de>
Novell / SUSE Labs
SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746 - GF: Markus Rex



More information about the Gcc-patches mailing list