Patchwork Make IPA-SRA propagate reference_alias_ptr_types to the caller

login
register
mail settings
Submitter Martin Jambor
Date Dec. 9, 2010, 10:34 a.m.
Message ID <20101209103435.GB10989@virgil.arch.suse.de>
Download mbox | patch
Permalink /patch/74872/
State New
Headers show

Comments

Martin Jambor - Dec. 9, 2010, 10:34 a.m.
Hi,

the correct thing way of providing types to MEM_REFs created in the
caller by IPA-SRA (and avoid issues like PR 45687) is to propagate
them from the caller.

The patch below does this.  For each new parameter IPA-SRA produces,
it first checks, whether reference_alias_ptr_type of the expressions
that would access them are the same.  If they are not, the original
parameter it "comes from" is not considered for IPA-SRA any more.
Later when creating the adjustment structure describing the new
parameter, we store the result of reference_alias_ptr_type into it too
and then use it when building the MEM_REF in the caller (in all
cases).

I hope this is the correct thing to do (and I would like to get this
in the stage 3 although there is no known bug caused by this).  The
patch bootstrapped and tested fine on x86_64-linux (but there were
failures when I made a mistake when writing this).  I'll be happy to
address any comments.

The patch is meant to be applied on top of the fix for PR 46734 I have
just posted.

Thanks,

Martin



2010-12-08 Martin Jambor <mjambor@suse.cz>

	* ipa-prop.h (struct ipa_parm_adjustment): New field alias_ptr_type.
	* ipa-prop.c (ipa_modify_call_arguments): Use it.
	* tree-sra.c (splice_param_accesses): Test that all accesses have the
	same alias reference type.
	(turn_representatives_into_adjustments): Set alias_ptr_type of the
	adjustment.
Richard Guenther - Dec. 9, 2010, 12:09 p.m.
On Thu, 9 Dec 2010, Martin Jambor wrote:

> Hi,
> 
> the correct thing way of providing types to MEM_REFs created in the
> caller by IPA-SRA (and avoid issues like PR 45687) is to propagate
> them from the caller.
> 
> The patch below does this.  For each new parameter IPA-SRA produces,
> it first checks, whether reference_alias_ptr_type of the expressions
> that would access them are the same.  If they are not, the original
> parameter it "comes from" is not considered for IPA-SRA any more.
> Later when creating the adjustment structure describing the new
> parameter, we store the result of reference_alias_ptr_type into it too
> and then use it when building the MEM_REF in the caller (in all
> cases).
> 
> I hope this is the correct thing to do (and I would like to get this
> in the stage 3 although there is no known bug caused by this).  The
> patch bootstrapped and tested fine on x86_64-linux (but there were
> failures when I made a mistake when writing this).  I'll be happy to
> address any comments.
> 
> The patch is meant to be applied on top of the fix for PR 46734 I have
> just posted.

Ok.

Thanks,
Richard.

> Thanks,
> 
> Martin
> 
> 
> 
> 2010-12-08 Martin Jambor <mjambor@suse.cz>
> 
> 	* ipa-prop.h (struct ipa_parm_adjustment): New field alias_ptr_type.
> 	* ipa-prop.c (ipa_modify_call_arguments): Use it.
> 	* tree-sra.c (splice_param_accesses): Test that all accesses have the
> 	same alias reference type.
> 	(turn_representatives_into_adjustments): Set alias_ptr_type of the
> 	adjustment.
> 
> 
> Index: mine/gcc/ipa-prop.c
> ===================================================================
> --- mine.orig/gcc/ipa-prop.c
> +++ mine/gcc/ipa-prop.c
> @@ -2210,13 +2210,10 @@ ipa_modify_call_arguments (struct cgraph
>  	  base = gimple_call_arg (stmt, adj->base_index);
>  	  loc = EXPR_LOCATION (base);
>  
> -	  if (TREE_CODE (base) == ADDR_EXPR
> -	      && DECL_P (TREE_OPERAND (base, 0)))
> -	    off = build_int_cst (TREE_TYPE (base),
> +	  if (TREE_CODE (base) != ADDR_EXPR
> +	      && POINTER_TYPE_P (TREE_TYPE (base)))
> +	    off = build_int_cst (adj->alias_ptr_type,
>  				 adj->offset / BITS_PER_UNIT);
> -	  else if (TREE_CODE (base) != ADDR_EXPR
> -		   && POINTER_TYPE_P (TREE_TYPE (base)))
> -	    off = build_int_cst (TREE_TYPE (base), adj->offset / BITS_PER_UNIT);
>  	  else
>  	    {
>  	      HOST_WIDE_INT base_offset;
> @@ -2230,12 +2227,12 @@ ipa_modify_call_arguments (struct cgraph
>  	      if (!base)
>  		{
>  		  base = build_fold_addr_expr (prev_base);
> -		  off = build_int_cst (reference_alias_ptr_type (prev_base),
> +		  off = build_int_cst (adj->alias_ptr_type,
>  				       adj->offset / BITS_PER_UNIT);
>  		}
>  	      else if (TREE_CODE (base) == MEM_REF)
>  		{
> -		  off = build_int_cst (TREE_TYPE (TREE_OPERAND (base, 1)),
> +		  off = build_int_cst (adj->alias_ptr_type,
>  				       base_offset
>  				       + adj->offset / BITS_PER_UNIT);
>  		  off = int_const_binop (PLUS_EXPR, TREE_OPERAND (base, 1),
> @@ -2244,7 +2241,7 @@ ipa_modify_call_arguments (struct cgraph
>  		}
>  	      else
>  		{
> -		  off = build_int_cst (reference_alias_ptr_type (prev_base),
> +		  off = build_int_cst (adj->alias_ptr_type,
>  				       base_offset
>  				       + adj->offset / BITS_PER_UNIT);
>  		  base = build_fold_addr_expr (base);
> Index: mine/gcc/ipa-prop.h
> ===================================================================
> --- mine.orig/gcc/ipa-prop.h
> +++ mine/gcc/ipa-prop.h
> @@ -458,6 +458,10 @@ struct ipa_parm_adjustment
>       be a pointer to this type.  */
>    tree type;
>  
> +  /* Alias refrerence type to be used in MEM_REFs when adjusting caller
> +     arguments.  */
> +  tree alias_ptr_type;
> +
>    /* The new declaration when creating/replacing a parameter.  Created by
>       ipa_modify_formal_parameters, useful for functions modifying the body
>       accordingly. */
> Index: mine/gcc/tree-sra.c
> ===================================================================
> --- mine.orig/gcc/tree-sra.c
> +++ mine/gcc/tree-sra.c
> @@ -3563,10 +3563,12 @@ splice_param_accesses (tree parm, bool *
>    while (i < access_count)
>      {
>        bool modification;
> +      tree a1_alias_type;
>        access = VEC_index (access_p, access_vec, i);
>        modification = access->write;
>        if (access_precludes_ipa_sra_p (access))
>  	return NULL;
> +      a1_alias_type = reference_alias_ptr_type (access->expr);
>  
>        /* Access is about to become group representative unless we find some
>  	 nasty overlap which would preclude us from breaking this parameter
> @@ -3590,7 +3592,8 @@ splice_param_accesses (tree parm, bool *
>  	  if (access_precludes_ipa_sra_p (ac2)
>  	      || (ac2->type != access->type
>  		  && (TREE_ADDRESSABLE (ac2->type)
> -		      || TREE_ADDRESSABLE (access->type))))
> +		      || TREE_ADDRESSABLE (access->type)))
> +	      || (reference_alias_ptr_type (ac2->expr) != a1_alias_type))
>  	    return NULL;
>  
>  	  modification |= ac2->write;
> @@ -3825,6 +3828,7 @@ turn_representatives_into_adjustments (V
>  	      adj->base_index = index;
>  	      adj->base = repr->base;
>  	      adj->type = repr->type;
> +	      adj->alias_ptr_type = reference_alias_ptr_type (repr->expr);
>  	      adj->offset = repr->offset;
>  	      adj->by_ref = (POINTER_TYPE_P (TREE_TYPE (repr->base))
>  			     && (repr->grp_maybe_modified
> 
>

Patch

Index: mine/gcc/ipa-prop.c
===================================================================
--- mine.orig/gcc/ipa-prop.c
+++ mine/gcc/ipa-prop.c
@@ -2210,13 +2210,10 @@  ipa_modify_call_arguments (struct cgraph
 	  base = gimple_call_arg (stmt, adj->base_index);
 	  loc = EXPR_LOCATION (base);
 
-	  if (TREE_CODE (base) == ADDR_EXPR
-	      && DECL_P (TREE_OPERAND (base, 0)))
-	    off = build_int_cst (TREE_TYPE (base),
+	  if (TREE_CODE (base) != ADDR_EXPR
+	      && POINTER_TYPE_P (TREE_TYPE (base)))
+	    off = build_int_cst (adj->alias_ptr_type,
 				 adj->offset / BITS_PER_UNIT);
-	  else if (TREE_CODE (base) != ADDR_EXPR
-		   && POINTER_TYPE_P (TREE_TYPE (base)))
-	    off = build_int_cst (TREE_TYPE (base), adj->offset / BITS_PER_UNIT);
 	  else
 	    {
 	      HOST_WIDE_INT base_offset;
@@ -2230,12 +2227,12 @@  ipa_modify_call_arguments (struct cgraph
 	      if (!base)
 		{
 		  base = build_fold_addr_expr (prev_base);
-		  off = build_int_cst (reference_alias_ptr_type (prev_base),
+		  off = build_int_cst (adj->alias_ptr_type,
 				       adj->offset / BITS_PER_UNIT);
 		}
 	      else if (TREE_CODE (base) == MEM_REF)
 		{
-		  off = build_int_cst (TREE_TYPE (TREE_OPERAND (base, 1)),
+		  off = build_int_cst (adj->alias_ptr_type,
 				       base_offset
 				       + adj->offset / BITS_PER_UNIT);
 		  off = int_const_binop (PLUS_EXPR, TREE_OPERAND (base, 1),
@@ -2244,7 +2241,7 @@  ipa_modify_call_arguments (struct cgraph
 		}
 	      else
 		{
-		  off = build_int_cst (reference_alias_ptr_type (prev_base),
+		  off = build_int_cst (adj->alias_ptr_type,
 				       base_offset
 				       + adj->offset / BITS_PER_UNIT);
 		  base = build_fold_addr_expr (base);
Index: mine/gcc/ipa-prop.h
===================================================================
--- mine.orig/gcc/ipa-prop.h
+++ mine/gcc/ipa-prop.h
@@ -458,6 +458,10 @@  struct ipa_parm_adjustment
      be a pointer to this type.  */
   tree type;
 
+  /* Alias refrerence type to be used in MEM_REFs when adjusting caller
+     arguments.  */
+  tree alias_ptr_type;
+
   /* The new declaration when creating/replacing a parameter.  Created by
      ipa_modify_formal_parameters, useful for functions modifying the body
      accordingly. */
Index: mine/gcc/tree-sra.c
===================================================================
--- mine.orig/gcc/tree-sra.c
+++ mine/gcc/tree-sra.c
@@ -3563,10 +3563,12 @@  splice_param_accesses (tree parm, bool *
   while (i < access_count)
     {
       bool modification;
+      tree a1_alias_type;
       access = VEC_index (access_p, access_vec, i);
       modification = access->write;
       if (access_precludes_ipa_sra_p (access))
 	return NULL;
+      a1_alias_type = reference_alias_ptr_type (access->expr);
 
       /* Access is about to become group representative unless we find some
 	 nasty overlap which would preclude us from breaking this parameter
@@ -3590,7 +3592,8 @@  splice_param_accesses (tree parm, bool *
 	  if (access_precludes_ipa_sra_p (ac2)
 	      || (ac2->type != access->type
 		  && (TREE_ADDRESSABLE (ac2->type)
-		      || TREE_ADDRESSABLE (access->type))))
+		      || TREE_ADDRESSABLE (access->type)))
+	      || (reference_alias_ptr_type (ac2->expr) != a1_alias_type))
 	    return NULL;
 
 	  modification |= ac2->write;
@@ -3825,6 +3828,7 @@  turn_representatives_into_adjustments (V
 	      adj->base_index = index;
 	      adj->base = repr->base;
 	      adj->type = repr->type;
+	      adj->alias_ptr_type = reference_alias_ptr_type (repr->expr);
 	      adj->offset = repr->offset;
 	      adj->by_ref = (POINTER_TYPE_P (TREE_TYPE (repr->base))
 			     && (repr->grp_maybe_modified