+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.
+
2014-12-09 Richard Biener <rguenther@suse.de>
PR middle-end/64199
+2014-12-09 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/64193
+ * gcc.dg/tree-ssa/ssa-fre-43.c: New testcase.
+
2014-12-09 Richard Biener <rguenther@suse.de>
PR middle-end/64199
--- /dev/null
+/* 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" } } */
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;
else if (res != NULL)
break;
+ if (valueize)
+ vuse = valueize (vuse);
def_stmt = SSA_NAME_DEF_STMT (vuse);
if (gimple_nop_p (def_stmt))
break;
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 *),
&& 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;
*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);
}
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)
{