Patchwork Tidy replace_uses_by

login
register
mail settings
Submitter Richard Guenther
Date Dec. 13, 2011, 4:06 p.m.
Message ID <alpine.LNX.2.00.1112131703571.4527@zhemvz.fhfr.qr>
Download mbox | patch
Permalink /patch/131126/
State New
Headers show

Comments

Richard Guenther - Dec. 13, 2011, 4:06 p.m.
After fixing PR51481 I noticed replace_uses_by does quite some
unnecessary work despite being (one of) the core propagator routine(s).
The following patch cleans it up to avoid doing useless work.

LTO bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

I'll apply this tomorrow.

Thanks,
Richard.

2011-12-13  Richard Guenther  <rguenther@suse.de>

	* tree-cfg.c (replace_uses_by): Only mark blocks altered
	that will make a difference.  Only recompute ADDR_EXPR
	invariantness if it could possibly have changed.  Do so
	before folding the statement.

Patch

Index: gcc/tree-cfg.c
===================================================================
--- gcc/tree-cfg.c	(revision 182285)
+++ gcc/tree-cfg.c	(working copy)
@@ -1592,7 +1596,7 @@  replace_uses_by (tree name, tree val)
 		  /* This can only occur for virtual operands, since
 		     for the real ones SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name))
 		     would prevent replacement.  */
-		  gcc_assert (!is_gimple_reg (name));
+		  gcc_checking_assert (!is_gimple_reg (name));
 		  SSA_NAME_OCCURS_IN_ABNORMAL_PHI (val) = 1;
 		}
 	    }
@@ -1604,28 +1608,37 @@  replace_uses_by (tree name, tree val)
 	  gimple orig_stmt = stmt;
 	  size_t i;
 
-	  fold_stmt (&gsi);
-	  stmt = gsi_stmt (gsi);
-	  if (cfgcleanup_altered_bbs && !is_gimple_debug (stmt))
+	  /* Mark the block if we changed the last stmt in it.  */
+	  if (cfgcleanup_altered_bbs
+	      && stmt_ends_bb_p (stmt))
 	    bitmap_set_bit (cfgcleanup_altered_bbs, gimple_bb (stmt)->index);
 
-	  /* FIXME.  This should go in update_stmt.  */
-	  for (i = 0; i < gimple_num_ops (stmt); i++)
+	  /* FIXME.  It shouldn't be required to keep TREE_CONSTANT
+	     on ADDR_EXPRs up-to-date on GIMPLE.  Propagation will
+	     only change sth from non-invariant to invariant, and only
+	     when propagating integer constants.  */
+	  if (TREE_CODE (val) == INTEGER_CST)
+	    for (i = 0; i < gimple_num_ops (stmt); i++)
+	      {
+		tree op = gimple_op (stmt, i);
+		/* Operands may be empty here.  For example, the labels
+		   of a GIMPLE_COND are nulled out following the creation
+		   of the corresponding CFG edges.  */
+		if (op && TREE_CODE (op) == ADDR_EXPR)
+		  recompute_tree_invariant_for_addr_expr (op);
+	      }
+
+	  if (fold_stmt (&gsi))
 	    {
-	      tree op = gimple_op (stmt, i);
-              /* Operands may be empty here.  For example, the labels
-                 of a GIMPLE_COND are nulled out following the creation
-                 of the corresponding CFG edges.  */
-	      if (op && TREE_CODE (op) == ADDR_EXPR)
-		recompute_tree_invariant_for_addr_expr (op);
+	      stmt = gsi_stmt (gsi);
+	      maybe_clean_or_replace_eh_stmt (orig_stmt, stmt);
 	    }
 
-	  maybe_clean_or_replace_eh_stmt (orig_stmt, stmt);
 	  update_stmt (stmt);
 	}
     }
 
-  gcc_assert (has_zero_uses (name));
+  gcc_checking_assert (has_zero_uses (name));
 
   /* Also update the trees stored in loop structures.  */
   if (current_loops)