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 PR64191, 2nd part


This fixes DCE to remove pointless clobbers which then enables to
DCE empty loops (with just clobbers).  This is IMHO important
to get rid of empty constructor calling loops which are not uncommon.

The way this now works is to treat clobbers as not necessary - but
avoid removing them if required uses are not DCEd.  Thus they get
treated similar to debug stmts.

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

Richard.

2014-12-10  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/64191
	* tree-ssa-dce.c (mark_stmt_if_obviously_necessary): Do not
	mark clobbers as necessary.
	(eliminate_unnecessary_stmts): Keep clobbers live if we can.

	* g++.dg/pr64191.C: Make sure we can DCE empty loops with
	indirect clobbers.

Index: gcc/tree-ssa-dce.c
===================================================================
--- gcc/tree-ssa-dce.c	(revision 218479)
+++ gcc/tree-ssa-dce.c	(working copy)
@@ -292,8 +292,7 @@ mark_stmt_if_obviously_necessary (gimple
       break;
 
     case GIMPLE_ASSIGN:
-      if (TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME
-	  && TREE_CLOBBER_P (gimple_assign_rhs1 (stmt)))
+      if (gimple_clobber_p (stmt))
 	return;
       break;
 
@@ -1362,6 +1361,25 @@ eliminate_unnecessary_stmts (void)
 	  /* If GSI is not necessary then remove it.  */
 	  if (!gimple_plf (stmt, STMT_NECESSARY))
 	    {
+	      /* Keep clobbers that we can keep live live.  */
+	      if (gimple_clobber_p (stmt))
+		{
+		  ssa_op_iter iter;
+		  use_operand_p use_p;
+		  bool dead = false;
+		  FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
+		    {
+		      tree name = USE_FROM_PTR (use_p);
+		      if (!SSA_NAME_IS_DEFAULT_DEF (name)
+			  && !bitmap_bit_p (processed, SSA_NAME_VERSION (name)))
+			{
+			  dead = true;
+			  break;
+			}
+		    }
+		  if (!dead)
+		    continue;
+		}
 	      if (!is_gimple_debug (stmt))
 		something_changed = true;
 	      remove_dead_stmt (&gsi, bb);
Index: gcc/testsuite/g++.dg/pr64191.C
===================================================================
--- gcc/testsuite/g++.dg/pr64191.C	(revision 0)
+++ gcc/testsuite/g++.dg/pr64191.C	(working copy)
@@ -0,0 +1,25 @@
+// { dg-do compile }
+// { dg-options "-O2 -fdump-tree-cddce1" }
+
+struct Bar
+{
+  int i;
+  ~Bar() { }
+};
+void bar_dtor_loop(Bar* p, unsigned int n)
+{
+  if (p) {
+      Bar* e = p + n;
+      while (e > p) {
+	  --e;
+	  e->~Bar();
+      }
+  }
+}
+
+// The clobber in ~Bar should persist but those inlined into
+// bar_dtor_loop not, nor should the loop therein
+
+// { dg-final { scan-tree-dump-times "CLOBBER" 1 "cddce1" } }
+// { dg-final { scan-tree-dump-times "if" 0 "cddce1" } }
+// { dg-final { cleanup-tree-dump "cddce1" } }


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