diff mbox

Fix PR64193

Message ID alpine.LSU.2.11.1412091444340.8254@zhemvz.fhfr.qr
State New
Headers show

Commit Message

Richard Biener Dec. 9, 2014, 1:47 p.m. UTC
The following patch restores proper CSE by FRE/PRE when doing
optimistic value-numbering of stores/loads.  In that case we
may end up value-numbering a virtual operand to the only executable
edge value of a PHI - but as the alias walker doesn't know this
it fails to handle the PHI which results in inconsistent virtual
operand being used for the entry in the hashtable.  Since
r173250 we refuse to value-number to sth non-VARYING in the 2nd
iteration if the 1st iteration computed VARYING (which is correct).

The fix is to tell the alias walker about this optimistic handling.

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

Richard.

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

	PR tree-optimization/64193
	* tree-ssa-alias.c (walk_non_aliased_vuses): Add valueize parameter
	and valueize the VUSE before looking up the def stmt.
	* tree-ssa-alias.h (walk_non_aliased_vuses): Adjust prototype.
	* tree-ssa-sccvn.c (vn_reference_lookup_pieces): Pass vn_valueize
	to walk_non_aliased_vuses.
	(vn_reference_lookup): Likewise.
	* tree-ssa-dom.c (lookup_avail_expr): Pass NULL as valueize
	callback to walk_non_aliased_vuses.

	* gcc.dg/tree-ssa/ssa-fre-43.c: New testcase.
diff mbox

Patch

Index: gcc/tree-ssa-alias.c
===================================================================
--- gcc/tree-ssa-alias.c	(revision 218479)
+++ gcc/tree-ssa-alias.c	(working copy)
@@ -2632,12 +2632,18 @@  get_continuation_for_phi (gimple phi, ao
    If TRANSLATE returns NULL the walk continues and TRANSLATE is supposed
    to adjust REF and *DATA to make that valid.
 
+   VALUEIZE if non-NULL is called with the next VUSE that is considered
+   and return value is substituted for that.  This can be used to
+   implement optimistic value-numbering for example.  Note that the
+   VUSE argument is assumed to be valueized already.
+
    TODO: Cache the vector of equivalent vuses per ref, vuse pair.  */
 
 void *
 walk_non_aliased_vuses (ao_ref *ref, tree vuse,
 			void *(*walker)(ao_ref *, tree, unsigned int, void *),
 			void *(*translate)(ao_ref *, tree, void *, bool),
+			tree (*valueize)(tree),
 			void *data)
 {
   bitmap visited = NULL;
@@ -2663,6 +2669,8 @@  walk_non_aliased_vuses (ao_ref *ref, tre
       else if (res != NULL)
 	break;
 
+      if (valueize)
+	vuse = valueize (vuse);
       def_stmt = SSA_NAME_DEF_STMT (vuse);
       if (gimple_nop_p (def_stmt))
 	break;
Index: gcc/tree-ssa-alias.h
===================================================================
--- gcc/tree-ssa-alias.h	(revision 218479)
+++ gcc/tree-ssa-alias.h	(working copy)
@@ -124,6 +124,7 @@  extern void *walk_non_aliased_vuses (ao_
 				     void *(*)(ao_ref *, tree,
 					       unsigned int, void *),
 				     void *(*)(ao_ref *, tree, void *, bool),
+				     tree (*)(tree),
 				     void *);
 extern unsigned int walk_aliased_vdefs (ao_ref *, tree,
 					bool (*)(ao_ref *, tree, void *),
Index: gcc/tree-ssa-sccvn.c
===================================================================
--- gcc/tree-ssa-sccvn.c	(revision 218479)
+++ gcc/tree-ssa-sccvn.c	(working copy)
@@ -2160,7 +2176,8 @@  vn_reference_lookup_pieces (tree vuse, a
 	*vnresult =
 	  (vn_reference_t)walk_non_aliased_vuses (&r, vr1.vuse,
 						  vn_reference_lookup_2,
-						  vn_reference_lookup_3, &vr1);
+						  vn_reference_lookup_3,
+						  vn_valueize, &vr1);
       gcc_checking_assert (vr1.operands == shared_lookup_references);
     }
 
@@ -2212,7 +2229,8 @@  vn_reference_lookup (tree op, tree vuse,
       wvnresult =
 	(vn_reference_t)walk_non_aliased_vuses (&r, vr1.vuse,
 						vn_reference_lookup_2,
-						vn_reference_lookup_3, &vr1);
+						vn_reference_lookup_3,
+						vn_valueize, &vr1);
       gcc_checking_assert (vr1.operands == shared_lookup_references);
       if (wvnresult)
 	{
Index: gcc/tree-ssa-dom.c
===================================================================
--- gcc/tree-ssa-dom.c	(revision 218479)
+++ gcc/tree-ssa-dom.c	(working copy)
@@ -2635,7 +2635,7 @@  lookup_avail_expr (gimple stmt, bool ins
 	    && TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME
 	    && (ao_ref_init (&ref, gimple_assign_rhs1 (stmt)), true)
 	    && walk_non_aliased_vuses (&ref, vuse2,
-				       vuse_eq, NULL, vuse1) != NULL))
+				       vuse_eq, NULL, NULL, vuse1) != NULL))
 	{
 	  struct expr_hash_elt *element2 = XNEW (struct expr_hash_elt);
 	  *element2 = element;
Index: gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-43.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-43.c	(revision 0)
+++ gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-43.c	(working copy)
@@ -0,0 +1,29 @@ 
+/* PR tree-optimization/64193 */
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-fre1-details" } */
+
+double T,T2,E1[5];
+int J;
+
+void
+PA(double E[])
+{
+ J = 0;
+
+L10:
+ E[1] = ( E[1] + E[2] + E[3] - E[4]) * T;
+ E[2] = ( E[1] + E[2] - E[3] + E[4]) * T;
+ E[3] = ( E[1] - E[2] + E[3] + E[4]) * T;
+ E[4] = (-E[1] + E[2] + E[3] + E[4]) / T2;
+ J += 1;
+
+ if (J < 6)
+  goto L10;
+}
+
+/* We should remove 15 dead loads, fully propagating their replacements
+   with exactly 4 loads and 4 stores from/to E remaining.  */
+
+/* { dg-final { scan-tree-dump-times "Removing dead stmt" 15 "fre1" } } */
+/* { dg-final { scan-tree-dump-not "Not changing value number" "fre1" } } */
+/* { dg-final { cleanup-tree-dump "fre1" } } */