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 endless loop in forwprop (PR tree-optimization/53226)


Hi!

The attached testcase loops endlessly, using more and more memory.
The problem is that the prev stmt iterator sometimes references stmts that
remove_prop_source_from_use decides to remove, and since Michael's
gimple seq changes that seems to be fatal.

Fixed by not keeping an iterator, but instead marking stmts that don't need
revisiting and restarting with first stmt that needs revisiting.  This
assumes that new stmts will have uid 0, but I believe that is the case.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2012-05-08  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/53226
	* tree-ssa-forwprop.c (ssa_forward_propagate_and_combine): Remove
	prev and prev_initialized vars, gimple_set_uid (stmt, 0) before
	processing it and gimple_set_uid (stmt, 1) if it doesn't need to be
	revisited, look for earliest stmt with uid 0 if something changed.

	* gcc.c-torture/compile/pr53226.c: New test.

--- gcc/tree-ssa-forwprop.c.jj	2012-05-03 08:35:52.000000000 +0200
+++ gcc/tree-ssa-forwprop.c	2012-05-08 18:10:19.662061709 +0200
@@ -2677,8 +2677,7 @@ ssa_forward_propagate_and_combine (void)
 
   FOR_EACH_BB (bb)
     {
-      gimple_stmt_iterator gsi, prev;
-      bool prev_initialized;
+      gimple_stmt_iterator gsi;
 
       /* Apply forward propagation to all stmts in the basic-block.
 	 Note we update GSI within the loop as necessary.  */
@@ -2771,12 +2770,14 @@ ssa_forward_propagate_and_combine (void)
 
       /* Combine stmts with the stmts defining their operands.
 	 Note we update GSI within the loop as necessary.  */
-      prev_initialized = false;
       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
 	{
 	  gimple stmt = gsi_stmt (gsi);
 	  bool changed = false;
 
+	  /* Mark stmt as potentially needing revisiting.  */
+	  gimple_set_uid (stmt, 0);
+
 	  switch (gimple_code (stmt))
 	    {
 	    case GIMPLE_ASSIGN:
@@ -2856,18 +2857,18 @@ ssa_forward_propagate_and_combine (void)
 	    {
 	      /* If the stmt changed then re-visit it and the statements
 		 inserted before it.  */
-	      if (!prev_initialized)
+	      for (; !gsi_end_p (gsi); gsi_prev (&gsi))
+		if (gimple_uid (gsi_stmt (gsi)))
+		  break;
+	      if (gsi_end_p (gsi))
 		gsi = gsi_start_bb (bb);
 	      else
-		{
-		  gsi = prev;
-		  gsi_next (&gsi);
-		}
+		gsi_next (&gsi);
 	    }
 	  else
 	    {
-	      prev = gsi;
-	      prev_initialized = true;
+	      /* Stmt no longer needs to be revisited.  */
+	      gimple_set_uid (stmt, 1);
 	      gsi_next (&gsi);
 	    }
 	}
--- gcc/testsuite/gcc.c-torture/compile/pr53226.c.jj	2012-05-08 18:07:40.007000510 +0200
+++ gcc/testsuite/gcc.c-torture/compile/pr53226.c	2012-05-08 18:07:35.071029578 +0200
@@ -0,0 +1,13 @@
+/* PR tree-optimization/53226 */
+
+void
+foo (unsigned long *x, char y, char z)
+{
+  int i;
+  for (i = y; i < z; ++i)
+    {
+      unsigned long a = ((unsigned char) i) & 63UL;
+      unsigned long b = 1ULL << a;
+      *x |= b;
+    }
+}

	Jakub


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