This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH][improved-aliasing] Don't give up on struct-aliasing if weencounter arrays


This is the struct-aliasing improvement part that makes us create
subfields even for structures containing arrays.

This was bootstrapped and regtested on mainline with 
x86_64-unknown-linux-gnu and i686-pc-linux-gnu.

Ok for improved-aliasing-branch?

Thanks,
Richard.


2005-08-11  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/22555
	* tree-dfa.c (okay_component_ref_for_subvars): Do not give up,
	if one structure field is an array.
	* tree-ssa-alias.c (create_overlap_variables_for): Likewise.
	* tree-ssa-structalias.c (create_variable_info_for): Likewise.
	(get_constraint_for_component_ref): Do not assert we can not
	only be accessing padding.
	* tree-ssa-loop-ivopts.c (get_ref_tag): Handle subvars.
	(rewrite_use): Mark new vars in stmt for renaming.
	* tree-ssa-loop.c (pass_iv_optimize): Schedule TODO_update_ssa.
	* tree-ssa-operands.c (get_expr_operands): Continue scanning
	operands even if we found a subvar, but ignore VOPs in this
	case.

	* gcc.dg/tree-ssa/alias-3.c: New testcase.

Index: tree-dfa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-dfa.c,v
retrieving revision 2.61
diff -c -3 -p -r2.61 tree-dfa.c
*** tree-dfa.c	16 Jul 2005 18:56:52 -0000	2.61
--- tree-dfa.c	21 Jul 2005 12:21:55 -0000
*************** okay_component_ref_for_subvars (tree ref
*** 807,814 ****
    *poffset = 0;  
    *psize = (unsigned int) -1;
    
-   if (ref_contains_array_ref (ref))
-     return result;
    ref = get_inner_reference (ref, &bitsize, &bitpos, &offset, &mode,
  			     &unsignedp, &volatilep, false);
    if (TREE_CODE (ref) == INDIRECT_REF)
--- 810,815 ----
Index: tree-ssa-alias.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-alias.c,v
retrieving revision 2.105
diff -c -3 -p -r2.105 tree-ssa-alias.c
*** tree-ssa-alias.c	19 Jul 2005 03:36:13 -0000	2.105
--- tree-ssa-alias.c	21 Jul 2005 12:21:55 -0000
*************** create_overlap_variables_for (tree var)
*** 2536,2542 ****
  	{
  	  if (!DECL_SIZE (fo->field) 
  	      || TREE_CODE (DECL_SIZE (fo->field)) != INTEGER_CST
- 	      || TREE_CODE (TREE_TYPE (fo->field)) == ARRAY_TYPE
  	      || fo->offset < 0)
  	    {
  	      notokay = true;
--- 2536,2541 ----
Index: tree-ssa-structalias.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-structalias.c,v
retrieving revision 2.26
diff -c -3 -p -r2.26 tree-ssa-structalias.c
*** tree-ssa-structalias.c	6 Aug 2005 13:25:58 -0000	2.26
--- tree-ssa-structalias.c	11 Aug 2005 11:33:15 -0000
*************** get_constraint_for_component_ref (tree t
*** 2075,2082 ****
  	    }
  	  /* assert that we found *some* field there. The user couldn't be
  	     accessing *only* padding.  */
! 	     
! 	  gcc_assert (curr);
  	}
        else
  	if (dump_file && (dump_flags & TDF_DETAILS))
--- 2075,2083 ----
  	    }
  	  /* assert that we found *some* field there. The user couldn't be
  	     accessing *only* padding.  */
! 	  /* Still the user could access one past the end of an array
! 	     embedded in a struct resulting in accessing *only* padding.  */
! 	  /* gcc_assert (curr); */
  	}
        else
  	if (dump_file && (dump_flags & TDF_DETAILS))
*************** create_variable_info_for (tree decl, con
*** 3060,3066 ****
    vi->has_union = hasunion;
    if (!TYPE_SIZE (decltype) 
        || TREE_CODE (TYPE_SIZE (decltype)) != INTEGER_CST
-       || TREE_CODE (decltype) == ARRAY_TYPE
        || TREE_CODE (decltype) == UNION_TYPE
        || TREE_CODE (decltype) == QUAL_UNION_TYPE)
      {
--- 3061,3066 ----
*************** create_variable_info_for (tree decl, con
*** 3094,3100 ****
  	{
  	  if (!DECL_SIZE (fo->field) 
  	      || TREE_CODE (DECL_SIZE (fo->field)) != INTEGER_CST
- 	      || TREE_CODE (TREE_TYPE (fo->field)) == ARRAY_TYPE
  	      || fo->offset < 0)
  	    {
  	      notokay = true;
--- 3094,3099 ----
Index: tree-ssa-loop-ivopts.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-loop-ivopts.c,v
retrieving revision 2.84
diff -c -3 -p -r2.84 tree-ssa-loop-ivopts.c
*** tree-ssa-loop-ivopts.c	11 Jul 2005 23:59:11 -0000	2.84
--- tree-ssa-loop-ivopts.c	21 Jul 2005 12:21:55 -0000
*************** unshare_and_remove_ssa_names (tree ref)
*** 5427,5437 ****
     and extracts this single useful piece of information.  */
  
  static tree
! get_ref_tag (tree ref)
  {
!   tree var = get_base_address (ref);
    tree tag;
  
    if (!var)
      return NULL_TREE;
  
--- 5427,5452 ----
     and extracts this single useful piece of information.  */
  
  static tree
! get_ref_tag (tree ref_)
  {
!   tree var = get_base_address (ref_);
!   unsigned HOST_WIDE_INT offset, size;
!   tree ref = okay_component_ref_for_subvars (ref_, &offset, &size);
    tree tag;
  
+   if (ref)
+     {
+       subvar_t svars = get_subvars_for_var (ref);
+       subvar_t sv;
+       for (sv = svars; sv; sv = sv->next)
+         {
+           bool exact;
+           if (overlap_subvar (offset, size, sv, &exact)
+ 	      && exact)
+ 	    return sv->var;
+         }
+     }
+ 
    if (!var)
      return NULL_TREE;
  
*************** rewrite_use (struct ivopts_data *data,
*** 5745,5750 ****
--- 5760,5766 ----
  	gcc_unreachable ();
      }
    update_stmt (use->stmt);
+   mark_new_vars_to_rename (use->stmt);
  }
  
  /* Rewrite the uses using the selected induction variables.  */
Index: tree-ssa-loop.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-loop.c,v
retrieving revision 2.33
diff -c -3 -p -r2.33 tree-ssa-loop.c
*** tree-ssa-loop.c	19 Jul 2005 00:44:45 -0000	2.33
--- tree-ssa-loop.c	21 Jul 2005 13:13:45 -0000
*************** struct tree_opt_pass pass_iv_optimize =
*** 435,441 ****
    0,					/* properties_provided */
    0,					/* properties_destroyed */
    0,					/* todo_flags_start */
!   TODO_dump_func | TODO_verify_loops,	/* todo_flags_finish */
    0					/* letter */
  };
  
--- 460,466 ----
    0,					/* properties_provided */
    0,					/* properties_destroyed */
    0,					/* todo_flags_start */
!   TODO_dump_func | TODO_verify_loops | TODO_update_ssa,	/* todo_flags_finish */
    0					/* letter */
  };
  
Index: tree-ssa-operands.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-operands.c,v
retrieving revision 2.100
diff -c -3 -p -r2.100 tree-ssa-operands.c
*** tree-ssa-operands.c	2 Aug 2005 11:46:44 -0000	2.100
--- tree-ssa-operands.c	11 Aug 2005 08:28:05 -0000
*************** get_expr_operands (tree stmt, tree *expr
*** 1311,1316 ****
--- 1311,1317 ----
        {
  	tree ref;
  	unsigned HOST_WIDE_INT offset, size;
+ 	bool none = true;
   	/* This component ref becomes an access to all of the subvariables
  	   it can touch,  if we can determine that, but *NOT* the real one.
  	   If we can't determine which fields we could touch, the recursion
*************** get_expr_operands (tree stmt, tree *expr
*** 1328,1342 ****
  		if (overlap_subvar (offset, size, sv, &exact))
  		  {
  	            int subvar_flags = flags;
  		    if (!exact)
  		      subvar_flags &= ~opf_kill_def;
  		    add_stmt_operand (&sv->var, s_ann, subvar_flags);
  		  }
  	      }
  	  }
! 	else
! 	  get_expr_operands (stmt, &TREE_OPERAND (expr, 0), 
! 			     flags & ~opf_kill_def);
  	
  	if (code == COMPONENT_REF)
  	  {
--- 1329,1345 ----
  		if (overlap_subvar (offset, size, sv, &exact))
  		  {
  	            int subvar_flags = flags;
+ 		    none = false;
  		    if (!exact)
  		      subvar_flags &= ~opf_kill_def;
  		    add_stmt_operand (&sv->var, s_ann, subvar_flags);
  		  }
  	      }
+ 	    if (!none)
+ 	      flags |= opf_no_vops;
  	  }
! 	get_expr_operands (stmt, &TREE_OPERAND (expr, 0), 
! 			   flags & ~opf_kill_def);
  	
  	if (code == COMPONENT_REF)
  	  {



/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-vars" } */

struct {
	int i;
	int j;
	int x[2];
} a;

int foo(void)
{
	a.i = 1;
	a.j = 0;
	a.x[0] = 0;
	return a.i + a.j;
}

/* { dg-final { scan-tree-dump "return 1;" "vars" } } */
/* { dg-final { cleanup-tree-dump "vars" } } */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]