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 PR58459


After much thinking I settled on removing the restriction from
forwprop that avoids propagating non-invariant addresses into
loops.  As forwprop is mainly seen as a way to canonicalize the IL
and simplify it for further passes this seems like the correct thing
to do.  LIM and IVOPTs should undo any harm this causes, otherwise
I'll find another way to fix the fallout.

Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

Richard.

2013-09-26  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/58459
	* tree-ssa-forwprop.c (forward_propagate_addr_expr): Remove
	restriction not propagating into loops.

	* gcc.dg/tree-ssa/ssa-pre-31.c: New testcase.

Index: gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-31.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-31.c	(revision 0)
--- gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-31.c	(working copy)
***************
*** 0 ****
--- 1,47 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O2 -fdump-tree-pre" } */
+ 
+ typedef struct {
+     unsigned int key;
+ } S;
+ typedef struct s1  {
+     unsigned int key;
+     unsigned int bits;
+     struct s1 *left, *right;
+ }S1;
+ extern S a[1024];
+ static inline int bar( S* p, S1* n )
+ {
+   S1 *curr;
+   S1 *next;
+ 
+   if ( n->left == n )
+     return (int)(p->key == n->key);
+ 
+   curr = n;
+   next = n->left;
+ 
+   while (curr->bits > next->bits ) {
+       curr = next;
+       if (p->key & (1 << curr->bits))
+ 	next = curr->right;
+       else
+ 	next = curr->left;
+   }
+ 
+   return (int)(p->key == next->key);
+ 
+ }
+ 
+ int foo (S1 *root, int N)
+ {
+   volatile int r;
+   int i,j;
+   for (i=0; i<N; i++)
+     for (j=0;j<1024; j++)
+       r = bar(&a[j], root);
+   return 0;
+ } 
+ 
+ /* { dg-final { scan-tree-dump-times "key" 4 "pre" } } */
+ /* { dg-final { cleanup-tree-dump "pre" } } */
Index: gcc/tree-ssa-forwprop.c
===================================================================
*** gcc/tree-ssa-forwprop.c	(revision 202941)
--- gcc/tree-ssa-forwprop.c	(working copy)
*************** forward_propagate_addr_expr_1 (tree name
*** 1001,1007 ****
  static bool
  forward_propagate_addr_expr (tree name, tree rhs)
  {
-   int stmt_loop_depth = bb_loop_depth (gimple_bb (SSA_NAME_DEF_STMT (name)));
    imm_use_iterator iter;
    gimple use_stmt;
    bool all = true;
--- 1001,1006 ----
*************** forward_propagate_addr_expr (tree name,
*** 1014,1050 ****
  
        /* If the use is not in a simple assignment statement, then
  	 there is nothing we can do.  */
!       if (gimple_code (use_stmt) != GIMPLE_ASSIGN)
  	{
  	  if (!is_gimple_debug (use_stmt))
  	    all = false;
  	  continue;
  	}
  
!       /* If the use is in a deeper loop nest, then we do not want
! 	 to propagate non-invariant ADDR_EXPRs into the loop as that
! 	 is likely adding expression evaluations into the loop.  */
!       if (bb_loop_depth (gimple_bb (use_stmt)) > stmt_loop_depth
! 	  && !is_gimple_min_invariant (rhs))
  	{
! 	  all = false;
! 	  continue;
  	}
! 
!       {
! 	gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
! 	result = forward_propagate_addr_expr_1 (name, rhs, &gsi,
! 						single_use_p);
! 	/* If the use has moved to a different statement adjust
! 	   the update machinery for the old statement too.  */
! 	if (use_stmt != gsi_stmt (gsi))
! 	  {
! 	    update_stmt (use_stmt);
! 	    use_stmt = gsi_stmt (gsi);
! 	  }
! 
! 	update_stmt (use_stmt);
!       }
        all &= result;
  
        /* Remove intermediate now unused copy and conversion chains.  */
--- 1013,1036 ----
  
        /* If the use is not in a simple assignment statement, then
  	 there is nothing we can do.  */
!       if (!is_gimple_assign (use_stmt))
  	{
  	  if (!is_gimple_debug (use_stmt))
  	    all = false;
  	  continue;
  	}
  
!       gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
!       result = forward_propagate_addr_expr_1 (name, rhs, &gsi,
! 					      single_use_p);
!       /* If the use has moved to a different statement adjust
! 	 the update machinery for the old statement too.  */
!       if (use_stmt != gsi_stmt (gsi))
  	{
! 	  update_stmt (use_stmt);
! 	  use_stmt = gsi_stmt (gsi);
  	}
!       update_stmt (use_stmt);
        all &= result;
  
        /* Remove intermediate now unused copy and conversion chains.  */


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