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][1/2] Improve DSE


This first patch improves DSE by improving the handling of
references with non-invariant addresses such as 
a->b[i].c in stmt_kills_ref_p_1.

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

Richard.

2014-06-04  Richard Biener  <rguenther@suse.de>

	* tree-ssa-alias.c (stmt_may_clobber_ref_p): Improve handling
	of accesses with non-invariant address.

	* gcc.dg/tree-ssa/ssa-dse-16.c: New testcase.

Index: gcc/tree-ssa-alias.c
===================================================================
*** gcc/tree-ssa-alias.c	(revision 211213)
--- gcc/tree-ssa-alias.c	(working copy)
*************** stmt_may_clobber_ref_p (gimple stmt, tre
*** 2174,2184 ****
  static bool
  stmt_kills_ref_p_1 (gimple stmt, ao_ref *ref)
  {
!   /* For a must-alias check we need to be able to constrain
!      the access properly.
!      FIXME: except for BUILTIN_FREE.  */
!   if (!ao_ref_base (ref)
!       || ref->max_size == -1)
      return false;
  
    if (gimple_has_lhs (stmt)
--- 2174,2180 ----
  static bool
  stmt_kills_ref_p_1 (gimple stmt, ao_ref *ref)
  {
!   if (!ao_ref_base (ref))
      return false;
  
    if (gimple_has_lhs (stmt)
*************** stmt_kills_ref_p_1 (gimple stmt, ao_ref
*** 2191,2199 ****
  	 might throw as well.  */
        && !stmt_can_throw_internal (stmt))
      {
!       tree base, lhs = gimple_get_lhs (stmt);
        HOST_WIDE_INT size, offset, max_size, ref_offset = ref->offset;
!       base = get_ref_base_and_extent (lhs, &offset, &size, &max_size);
        /* We can get MEM[symbol: sZ, index: D.8862_1] here,
  	 so base == ref->base does not always hold.  */
        if (base != ref->base)
--- 2187,2237 ----
  	 might throw as well.  */
        && !stmt_can_throw_internal (stmt))
      {
!       tree lhs = gimple_get_lhs (stmt);
!       /* If LHS is literally a base of the access we are done.  */
!       if (ref->ref)
! 	{
! 	  tree base = ref->ref;
! 	  if (handled_component_p (base))
! 	    {
! 	      tree saved_lhs0 = NULL_TREE;
! 	      if (handled_component_p (lhs))
! 		{
! 		  saved_lhs0 = TREE_OPERAND (lhs, 0);
! 		  TREE_OPERAND (lhs, 0) = integer_zero_node;
! 		}
! 	      do
! 		{
! 		  /* Just compare the outermost handled component, if
! 		     they are equal we have found a possible common
! 		     base.  */
! 		  tree saved_base0 = TREE_OPERAND (base, 0);
! 		  TREE_OPERAND (base, 0) = integer_zero_node;
! 		  bool res = operand_equal_p (lhs, base, 0);
! 		  TREE_OPERAND (base, 0) = saved_base0;
! 		  if (res)
! 		    break;
! 		  /* Otherwise drop handled components of the access.  */
! 		  base = saved_base0;
! 		}
! 	      while (handled_component_p (base));
! 	      if (saved_lhs0)
! 		TREE_OPERAND (lhs, 0) = saved_lhs0;
! 	    }
! 	  /* Finally check if lhs is equal or equal to the base candidate
! 	     of the access.  */
! 	  if (operand_equal_p (lhs, base, 0))
! 	    return true;
! 	}
! 
!       /* Now look for non-literal equal bases with the restriction of
!          handling constant offset and size.  */
!       /* For a must-alias check we need to be able to constrain
! 	 the access properly.  */
!       if (ref->max_size == -1)
! 	return false;
        HOST_WIDE_INT size, offset, max_size, ref_offset = ref->offset;
!       tree base = get_ref_base_and_extent (lhs, &offset, &size, &max_size);
        /* We can get MEM[symbol: sZ, index: D.8862_1] here,
  	 so base == ref->base does not always hold.  */
        if (base != ref->base)
*************** stmt_kills_ref_p_1 (gimple stmt, ao_ref
*** 2261,2266 ****
--- 2299,2308 ----
  	  case BUILT_IN_MEMMOVE_CHK:
  	  case BUILT_IN_MEMSET_CHK:
  	    {
+ 	      /* For a must-alias check we need to be able to constrain
+ 		 the access properly.  */
+ 	      if (ref->max_size == -1)
+ 		return false;
  	      tree dest = gimple_call_arg (stmt, 0);
  	      tree len = gimple_call_arg (stmt, 2);
  	      if (!tree_fits_shwi_p (len))
Index: gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-16.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-16.c	(revision 0)
+++ gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-16.c	(working copy)
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-dse1-details" } */
+
+struct X { struct A { int a[2]; } b[10]; };
+void foo (struct X *x, int i)
+{
+  struct A a;
+ /* Confuse SRA here with using a variable index, otherwise it will mess
+    with the IL too much.  */
+  a.a[i] = 3;
+  a.a[1] = 0;
+  /* The following store is dead.  */
+  x->b[i].a[0] = 1;
+  x->b[i] = a;
+}
+
+/* { dg-final { scan-tree-dump "Deleted dead store" "dse1" } } */
+/* { dg-final { cleanup-tree-dump "dse1" } } */


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