[PR49888,VTA] don't keep VALUEs bound to modified MEMs

Message ID ork3ytbxq8.fsf@livre.localdomain
State New
Headers show

Commit Message

Alexandre Oliva June 26, 2012, 8:54 p.m.
On Jun 14, 2012, "H.J. Lu" <hjl.tools@gmail.com> wrote:

> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53671

These two patches cure the two remaining problems.

Basically, we have a problem of tracking equivalent FP-relative
addresses across basic blocks when SP varies.  Once we lost track of SP,
pushing an argument for a call (without any MEM_EXPRs) was regarded as
aliasing an incoming argument, so we removed the argument binding from
the var tracking table.

This patch is a bit kludgy in that, in a perfect world, we'd be able to
recognize a broader set of equivalent incoming expressions at dataflow
confluences, taking both static and dynamic sets into account.
Currently, we only take the dynamic set into account, and don't
recognize as equivalent arithmetically equivalent expressions that
aren't isomorphic.

Fixing the more general problem is more than I can tackle right now, in
part because I don't have an efficient algorithm in mind and I'm
concerned a brute-force approach may be far too expensive in terms of
CPU and memory.  In fact, this is *the* main open problem in VTA, that
I'd like to discuss at the Cauldron with interested parties.

So I put in a kludge that tries to canonicalize incoming SPs and, if
they match, record that the merged SP holds the same canonical
representation.  It solves one of the regressions, but it will *not*
solve the general problem: AFAICT, a function that calls alloca,
especially if it calls it in a loop, will not get a proper relationship
between SP and FP so as to enable alias analysis to tell that a stack
push for an outgoing argument doesn't alias an FP-relative incoming

Perhaps defining separate alias sets for the various portions of the
stack frame, and annotating pushes that save registers and pushes of
outgoing arguments with these alias sets might help, but I haven't tried

The second patch simply adjusts a testcase to account for an
optimization possibility I hadn't taken into account that happened to be
exposed by the initial PR49888 patch, and the change happens to hide the
failure caused by a variant of the alias analysis problem described
above: we have an incoming pointer and a register-saving stack push that
must not alias because the incoming pointer couldn't possibly point to
the register-save area of a callee in a well-defined program, but alias
analysis can't figure that out.

Both patches were regstrapped on x86_64-linux-gnu and i686-linux-gnu.


Richard Henderson June 27, 2012, 7 p.m. | #1
On 06/26/2012 01:54 PM, Alexandre Oliva wrote:
> +  track_stack_pointer (dst, src1, src2);

Why does this function return a value then?

Alexandre Oliva June 28, 2012, 7:15 a.m. | #2
On Jun 27, 2012, Richard Henderson <rth@redhat.com> wrote:

> On 06/26/2012 01:54 PM, Alexandre Oliva wrote:
>> +  track_stack_pointer (dst, src1, src2);

> Why does this function return a value then?

During testing, I used an assert on the return value to catch cases that
couldn't be handled.  The comments before that function say:

+   ??? The return value, that was useful during testing, ended up
+   unused, but this single-use static function will be inlined, and
+   then the return value computation will be optimized out, so I'm
+   leaving it in.


for  gcc/testsuite/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	PR debug/53671
	PR debug/49888
	* gcc.dg/guality/pr49888.c: Account for the possibility that
	the variable is optimized out at the first test.

Index: gcc/testsuite/gcc.dg/guality/pr49888.c
--- gcc/testsuite/gcc.dg/guality/pr49888.c.orig	2012-06-25 20:55:13.465033665 -0300
+++ gcc/testsuite/gcc.dg/guality/pr49888.c	2012-06-25 21:33:00.035392709 -0300
@@ -9,12 +9,13 @@  f (int *p)
   int c = *p;
   v = c;
-  *p = 1; /* { dg-final { gdb-test 12 "c" "0" } } */
+  *p = 1; /* { dg-final { gdb-test 12 "!!c" "0" } } */
   /* c may very well be optimized out at this point, so we test !c,
      which will evaluate to the expected value.  We just want to make
      sure it doesn't remain bound to *p as it did before, in which
-     case !c would evaluate to 0.  */
-  v = 0; /* { dg-final { gdb-test 17 "!c" "1" } } */
+     case !c would evaluate to 0.  *p may also be regarded as aliasing
+     register saves, thus the !!c above.  */
+  v = 0; /* { dg-final { gdb-test 18 "!c" "1" } } */
 main ()