Commit 45ce6084 by Richard Guenther Committed by Richard Biener

re PR tree-optimization/50204 (Missed fully redundant load found in crafty (SPEC 2k))

2011-10-11  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/50204
	* tree-ssa-alias.c (get_continuation_for_phi_1): Split out
	two argument handling from ...
	(get_continuation_for_phi): ... here.  Handle arbitrary number
	of PHI args.

	* gcc.dg/tree-ssa/ssa-fre-36.c: New testcase.

From-SVN: r179799
parent 12d31b36
2011-10-11 Richard Guenther <rguenther@suse.de>
PR tree-optimization/50204
* tree-ssa-alias.c (get_continuation_for_phi_1): Split out
two argument handling from ...
(get_continuation_for_phi): ... here. Handle arbitrary number
of PHI args.
2011-10-11 Paolo Carlini <paolo.carlini@oracle.com> 2011-10-11 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/33067 PR c++/33067
2011-10-11 Richard Guenther <rguenther@suse.de>
PR tree-optimization/50204
* gcc.dg/tree-ssa/ssa-fre-36.c: New testcase.
2011-10-11 Andreas Krebbel <Andreas.Krebbel@de.ibm.com> 2011-10-11 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
* gcc.target/s390/20090223-1.c: Add -Wno-attributes. * gcc.target/s390/20090223-1.c: Add -Wno-attributes.
......
/* { dg-do compile } */
/* { dg-options "-O -fdump-tree-fre1-details" } */
extern int opening;
extern int middle_game;
int s;
extern int d[1];
void PreEvaluate(int wtm)
{
int i, j;
if (opening) {
d[0]=1;
}
else if (middle_game) {
d[0]=-1;
}
if (4 != opening) {
return;
}
s = 1;
}
/* We should be able to CSE the second load of opening. */
/* { dg-final { scan-tree-dump "Replaced opening" "fre1" } } */
/* { dg-final { cleanup-tree-dump "fre1" } } */
...@@ -1875,6 +1875,60 @@ maybe_skip_until (gimple phi, tree target, ao_ref *ref, ...@@ -1875,6 +1875,60 @@ maybe_skip_until (gimple phi, tree target, ao_ref *ref,
return true; return true;
} }
/* For two PHI arguments ARG0 and ARG1 try to skip non-aliasing code
until we hit the phi argument definition that dominates the other one.
Return that, or NULL_TREE if there is no such definition. */
static tree
get_continuation_for_phi_1 (gimple phi, tree arg0, tree arg1,
ao_ref *ref, bitmap *visited)
{
gimple def0 = SSA_NAME_DEF_STMT (arg0);
gimple def1 = SSA_NAME_DEF_STMT (arg1);
tree common_vuse;
if (arg0 == arg1)
return arg0;
else if (gimple_nop_p (def0)
|| (!gimple_nop_p (def1)
&& dominated_by_p (CDI_DOMINATORS,
gimple_bb (def1), gimple_bb (def0))))
{
if (maybe_skip_until (phi, arg0, ref, arg1, visited))
return arg0;
}
else if (gimple_nop_p (def1)
|| dominated_by_p (CDI_DOMINATORS,
gimple_bb (def0), gimple_bb (def1)))
{
if (maybe_skip_until (phi, arg1, ref, arg0, visited))
return arg1;
}
/* Special case of a diamond:
MEM_1 = ...
goto (cond) ? L1 : L2
L1: store1 = ... #MEM_2 = vuse(MEM_1)
goto L3
L2: store2 = ... #MEM_3 = vuse(MEM_1)
L3: MEM_4 = PHI<MEM_2, MEM_3>
We were called with the PHI at L3, MEM_2 and MEM_3 don't
dominate each other, but still we can easily skip this PHI node
if we recognize that the vuse MEM operand is the same for both,
and that we can skip both statements (they don't clobber us).
This is still linear. Don't use maybe_skip_until, that might
potentially be slow. */
else if ((common_vuse = gimple_vuse (def0))
&& common_vuse == gimple_vuse (def1))
{
if (!stmt_may_clobber_ref_p_1 (def0, ref)
&& !stmt_may_clobber_ref_p_1 (def1, ref))
return common_vuse;
}
return NULL_TREE;
}
/* Starting from a PHI node for the virtual operand of the memory reference /* Starting from a PHI node for the virtual operand of the memory reference
REF find a continuation virtual operand that allows to continue walking REF find a continuation virtual operand that allows to continue walking
statements dominating PHI skipping only statements that cannot possibly statements dominating PHI skipping only statements that cannot possibly
...@@ -1890,53 +1944,24 @@ get_continuation_for_phi (gimple phi, ao_ref *ref, bitmap *visited) ...@@ -1890,53 +1944,24 @@ get_continuation_for_phi (gimple phi, ao_ref *ref, bitmap *visited)
if (nargs == 1) if (nargs == 1)
return PHI_ARG_DEF (phi, 0); return PHI_ARG_DEF (phi, 0);
/* For two arguments try to skip non-aliasing code until we hit /* For two or more arguments try to pairwise skip non-aliasing code
the phi argument definition that dominates the other one. */ until we hit the phi argument definition that dominates the other one. */
if (nargs == 2) else if (nargs >= 2)
{ {
tree arg0 = PHI_ARG_DEF (phi, 0); tree arg0 = PHI_ARG_DEF (phi, 0);
tree arg1 = PHI_ARG_DEF (phi, 1); tree arg1;
gimple def0 = SSA_NAME_DEF_STMT (arg0); unsigned i = 1;
gimple def1 = SSA_NAME_DEF_STMT (arg1); do
tree common_vuse;
if (arg0 == arg1)
return arg0;
else if (gimple_nop_p (def0)
|| (!gimple_nop_p (def1)
&& dominated_by_p (CDI_DOMINATORS,
gimple_bb (def1), gimple_bb (def0))))
{
if (maybe_skip_until (phi, arg0, ref, arg1, visited))
return arg0;
}
else if (gimple_nop_p (def1)
|| dominated_by_p (CDI_DOMINATORS,
gimple_bb (def0), gimple_bb (def1)))
{
if (maybe_skip_until (phi, arg1, ref, arg0, visited))
return arg1;
}
/* Special case of a diamond:
MEM_1 = ...
goto (cond) ? L1 : L2
L1: store1 = ... #MEM_2 = vuse(MEM_1)
goto L3
L2: store2 = ... #MEM_3 = vuse(MEM_1)
L3: MEM_4 = PHI<MEM_2, MEM_3>
We were called with the PHI at L3, MEM_2 and MEM_3 don't
dominate each other, but still we can easily skip this PHI node
if we recognize that the vuse MEM operand is the same for both,
and that we can skip both statements (they don't clobber us).
This is still linear. Don't use maybe_skip_until, that might
potentially be slow. */
else if ((common_vuse = gimple_vuse (def0))
&& common_vuse == gimple_vuse (def1))
{ {
if (!stmt_may_clobber_ref_p_1 (def0, ref) arg1 = PHI_ARG_DEF (phi, i);
&& !stmt_may_clobber_ref_p_1 (def1, ref)) arg0 = get_continuation_for_phi_1 (phi, arg0, arg1, ref, visited);
return common_vuse; if (!arg0)
return NULL_TREE;
} }
while (++i < nargs);
return arg0;
} }
return NULL_TREE; return NULL_TREE;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment