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 some missed forwprop optimization after tuplification


We no longer were forward propagating (int *)&a into the load for

int b;
unsigned a;

void test1(void)
{
  int *p, *q = (int *)&a;
  a = 1;
  p = q;
  b = *q;

because the code handling copy-chains was too conservative.

Fixed with the following patch which also adjusts 
gcc.dg/tree-ssa/forwprop-9.c to make sure the transformation happens
early (and not only if we have a second DOM pass).

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

Richard.

2008-08-20  Richard Guenther  <rguenther@suse.de>

	* tree-ssa-forwprop.c (forward_propagate_addr_expr_1): More
	properly handle conversion/copy chains after tuplification.

	* gcc.dg/tree-ssa/forwprop-9.c: Scan FRE dump as well.
	* gcc.dg/tree-ssa/forwprop-10.c: New testcase.

Index: gcc/tree-ssa-forwprop.c
===================================================================
*** gcc/tree-ssa-forwprop.c	(revision 139265)
--- gcc/tree-ssa-forwprop.c	(working copy)
*************** forward_propagate_addr_expr_1 (tree name
*** 689,703 ****
       a conversion to def_rhs type separate, though.  */
    if (TREE_CODE (lhs) == SSA_NAME
        && ((rhs_code == SSA_NAME && rhs == name)
! 	  || CONVERT_EXPR_CODE_P (rhs_code))
!       && useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (def_rhs)))
      {
!       /* Only recurse if we don't deal with a single use.  */
!       if (!single_use_p)
  	return forward_propagate_addr_expr (lhs, def_rhs);
  
        gimple_assign_set_rhs1 (use_stmt, unshare_expr (def_rhs));
!       gimple_assign_set_rhs_code (use_stmt, TREE_CODE (def_rhs));
        return true;
      }
  
--- 692,713 ----
       a conversion to def_rhs type separate, though.  */
    if (TREE_CODE (lhs) == SSA_NAME
        && ((rhs_code == SSA_NAME && rhs == name)
! 	  || CONVERT_EXPR_CODE_P (rhs_code)))
      {
!       /* Only recurse if we don't deal with a single use or we cannot
! 	 do the propagation to the current statement.  In particular
! 	 we can end up with a conversion needed for a non-invariant
! 	 address which we cannot do in a single statement.  */
!       if (!single_use_p
! 	  || (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (def_rhs))
! 	      && !is_gimple_min_invariant (def_rhs)))
  	return forward_propagate_addr_expr (lhs, def_rhs);
  
        gimple_assign_set_rhs1 (use_stmt, unshare_expr (def_rhs));
!       if (useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (def_rhs)))
! 	gimple_assign_set_rhs_code (use_stmt, TREE_CODE (def_rhs));
!       else
! 	gimple_assign_set_rhs_code (use_stmt, NOP_EXPR);
        return true;
      }
  
Index: gcc/testsuite/gcc.dg/tree-ssa/forwprop-9.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/forwprop-9.c	(revision 139265)
--- gcc/testsuite/gcc.dg/tree-ssa/forwprop-9.c	(working copy)
***************
*** 1,6 ****
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-final_cleanup -W -Wall -fno-early-inlining" } */
! 
  
  int b;
  unsigned a;
--- 1,5 ----
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-final_cleanup -fdump-tree-fre -W -Wall -fno-early-inlining" } */
  
  int b;
  unsigned a;
*************** void f(void)
*** 13,18 ****
  {
     b = *g(); 
  }
! /* We should have converted the assignments to two = 1. */
  /* { dg-final { scan-tree-dump-times " = 1" 2 "final_cleanup"} } */
  /* { dg-final { cleanup-tree-dump "final_cleanup" } } */
--- 12,21 ----
  {
     b = *g(); 
  }
! 
! /* We should have converted the assignments to two = 1.  FRE does this.  */
! 
  /* { dg-final { scan-tree-dump-times " = 1" 2 "final_cleanup"} } */
+ /* { dg-final { scan-tree-dump-not " = a;" "fre"} } */
+ /* { dg-final { cleanup-tree-dump "fre" } } */
  /* { dg-final { cleanup-tree-dump "final_cleanup" } } */
Index: gcc/testsuite/gcc.dg/tree-ssa/forwprop-10.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/forwprop-10.c	(revision 0)
--- gcc/testsuite/gcc.dg/tree-ssa/forwprop-10.c	(revision 0)
***************
*** 0 ****
--- 1,23 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O -fdump-tree-forwprop1" } */
+ 
+ int b;
+ unsigned a;
+ 
+ static inline int *g(void)
+ {
+   a = 1;
+   return (int*)&a;
+ }
+ void test2(void)
+ {
+   b = *g();
+ }
+ 
+ /* The indirect load should be replaced by a load from a and a
+    conversion to int.  */
+ 
+ /* { dg-final { scan-tree-dump "= a;" "forwprop1" } } */
+ /* { dg-final { scan-tree-dump "= \\\(int\\\) " "forwprop1" } } */
+ /* { dg-final { scan-tree-dump-not "= \\\*" "forwprop1" } } */
+ /* { dg-final { cleanup-tree-dump "forwprop1" } } */


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