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] Fix PR47426


This fixes IPA-PTA to properly make things escape through externally
visible function returns.  Avoid doing it for main() to avoid
testsuite churn, also avoid the usual anything constraints from
truth valued expressions for the same reason.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Richard.

2011-01-25  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/47426
	* tree-ssa-structalias.c (ipa_pta_execute): Make externally
	visible functions results escape.

	* gcc.dg/torture/pr47426-1.c: New testcase.
	* gcc.dg/torture/pr47426-2.c: Likewise.

Index: gcc/tree-ssa-structalias.c
===================================================================
*** gcc/tree-ssa-structalias.c	(revision 169225)
--- gcc/tree-ssa-structalias.c	(working copy)
*************** find_func_aliases (gimple origt)
*** 4435,4446 ****
  	do_structure_copy (lhsop, rhsop);
        else
  	{
  	  get_constraint_for (lhsop, &lhsc);
  
! 	  if (gimple_assign_rhs_code (t) == POINTER_PLUS_EXPR)
  	    get_constraint_for_ptr_offset (gimple_assign_rhs1 (t),
  					   gimple_assign_rhs2 (t), &rhsc);
! 	  else if (gimple_assign_rhs_code (t) == BIT_AND_EXPR
  		   && TREE_CODE (gimple_assign_rhs2 (t)) == INTEGER_CST)
  	    {
  	      /* Aligning a pointer via a BIT_AND_EXPR is offsetting
--- 4454,4467 ----
  	do_structure_copy (lhsop, rhsop);
        else
  	{
+ 	  enum tree_code code = gimple_assign_rhs_code (t);
+ 
  	  get_constraint_for (lhsop, &lhsc);
  
! 	  if (code == POINTER_PLUS_EXPR)
  	    get_constraint_for_ptr_offset (gimple_assign_rhs1 (t),
  					   gimple_assign_rhs2 (t), &rhsc);
! 	  else if (code == BIT_AND_EXPR
  		   && TREE_CODE (gimple_assign_rhs2 (t)) == INTEGER_CST)
  	    {
  	      /* Aligning a pointer via a BIT_AND_EXPR is offsetting
*************** find_func_aliases (gimple origt)
*** 4448,4458 ****
  	      get_constraint_for_ptr_offset (gimple_assign_rhs1 (t),
  					     NULL_TREE, &rhsc);
  	    }
! 	  else if ((CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (t))
  		    && !(POINTER_TYPE_P (gimple_expr_type (t))
  			 && !POINTER_TYPE_P (TREE_TYPE (rhsop))))
  		   || gimple_assign_single_p (t))
  	    get_constraint_for_rhs (rhsop, &rhsc);
  	  else
  	    {
  	      /* All other operations are merges.  */
--- 4469,4483 ----
  	      get_constraint_for_ptr_offset (gimple_assign_rhs1 (t),
  					     NULL_TREE, &rhsc);
  	    }
! 	  else if ((CONVERT_EXPR_CODE_P (code)
  		    && !(POINTER_TYPE_P (gimple_expr_type (t))
  			 && !POINTER_TYPE_P (TREE_TYPE (rhsop))))
  		   || gimple_assign_single_p (t))
  	    get_constraint_for_rhs (rhsop, &rhsc);
+ 	  else if (truth_value_p (code))
+ 	    /* Truth value results are not pointer (parts).  Or at least
+ 	       very very unreasonable obfuscation of a part.  */
+ 	    ;
  	  else
  	    {
  	      /* All other operations are merges.  */
*************** ipa_pta_execute (void)
*** 6827,6837 ****
        push_cfun (func);
        current_function_decl = node->decl;
  
-       /* For externally visible functions use local constraints for
- 	 their arguments.  For local functions we see all callers
- 	 and thus do not need initial constraints for parameters.  */
        if (node->local.externally_visible)
! 	intra_create_variable_infos ();
  
        /* Build constriants for the function body.  */
        FOR_EACH_BB_FN (bb, func)
--- 6853,6886 ----
        push_cfun (func);
        current_function_decl = node->decl;
  
        if (node->local.externally_visible)
! 	{
! 	  /* For externally visible functions use local constraints for
! 	     their arguments.  For local functions we see all callers
! 	     and thus do not need initial constraints for parameters.  */
! 	  intra_create_variable_infos ();
! 
! 	  /* We also need to make function return values escape.  Nothing
! 	     escapes by returning from main though.  */
! 	  if (!MAIN_NAME_P (DECL_NAME (node->decl)))
! 	    {
! 	      varinfo_t fi, rvi;
! 	      fi = lookup_vi_for_tree (node->decl);
! 	      rvi = first_vi_for_offset (fi, fi_result);
! 	      if (rvi && rvi->offset == fi_result)
! 		{
! 		  struct constraint_expr includes;
! 		  struct constraint_expr var;
! 		  includes.var = escaped_id;
! 		  includes.offset = 0;
! 		  includes.type = SCALAR;
! 		  var.var = rvi->id;
! 		  var.offset = 0;
! 		  var.type = SCALAR;
! 		  process_constraint (new_constraint (includes, var));
! 		}
! 	    }
! 	}
  
        /* Build constriants for the function body.  */
        FOR_EACH_BB_FN (bb, func)
Index: gcc/testsuite/gcc.dg/torture/pr47426-1.c
===================================================================
*** gcc/testsuite/gcc.dg/torture/pr47426-1.c	(revision 0)
--- gcc/testsuite/gcc.dg/torture/pr47426-1.c	(revision 0)
***************
*** 0 ****
--- 1,23 ----
+ /* { dg-do run } */
+ /* { dg-options "-fipa-pta" } */
+ /* { dg-additional-sources "pr47426-2.c" } */
+ 
+ void bar (int *i);
+ 
+ static void
+ foo (int *i)
+ {
+   if (*i)
+     bar (i);
+   if (*i)
+     __builtin_abort();
+ }
+ 
+ typedef void tfoo (int *);
+ 
+ tfoo *
+ getfoo (void)
+ {
+   return &foo;
+ }
+ 
Index: gcc/testsuite/gcc.dg/torture/pr47426-2.c
===================================================================
*** gcc/testsuite/gcc.dg/torture/pr47426-2.c	(revision 0)
--- gcc/testsuite/gcc.dg/torture/pr47426-2.c	(revision 0)
***************
*** 0 ****
--- 1,19 ----
+ typedef void tfoo (int *);
+ tfoo *getfoo (void);
+ 
+ void
+ bar (int *i)
+ {
+   (*i)--;
+ }
+ 
+ int
+ main ()
+ {
+   int i = 1;
+   getfoo ()(&i);
+   if (i)
+     __builtin_abort ();
+   return 0;
+ }
+ 


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