On Tue, 2005-10-11 at 20:44 -0400, Diego Novillo wrote:
> On Tuesday 11 October 2005 20:30, Daniel Berlin wrote:
> 
> > BTW, you are also screwing up the upwards fud-chains in cases where it
> > really does clobber A, since you'll get the exact same as above, and
> > thus, A_1 won't be linked to the may-def at the clobber site, but to the
> > "real def" that last occurs.
> >
> No.  Without GV, there *will* be a VMD for A at the call to foo().

Uh, no, no there won't.
Look at get_call_expr_operands, at the not_read/not_written stuff.
The ipa-reference info will say it isn't clobbered by the call to foo.
Thus, we normally won't add a VMD for it.
You will get exactly the representation i sent you, without GV's.  I
checked it before i sent it to you :).  This is, after all, why the
static clobber avoidance stuff was implemented

Again, this is *already* on at O1+.  It's only "global" (IE externally
visible) variables that we know nothing about, and would get a VMD at
the call site.

Just to publicly followup on the original email, I think that for the PR
in question, The single var (IE just GV everywhere) scheme works better
than what you plan on, for the following reasons:

1. The single var scheme, while losing all optimization for global
variables, is correct in the FUD chains.  Every def is linked to the
nearest redef site, and if you walked them, they are conservatively
correct.

The take home point is that when you have 60000 globals and 236 function
calls, trying to do optimization on globals at all is a losing
proposition.  We should just give up and go home *entirely*, instead of
introducing something that could confuse people writing optimizers, is
hard to initially wrap your head around.

You could also use more than a single GV if you really cared.  You could
make up some equivalence sets and have 5 vars, or 10, or whatever.
They'll still all link up properly.

As for correctness, to sink statements, we only need to find the vuses
of the vmd's of a statement, and make sure we dominate them.  There are
rarely/never vuses on these statements, so we can safely ignore the
statements with both vuses/vdefs without really losing much
optimization.

In your scheme, since all global stores have GV VUSES, we have to find
the vuses of the vmd's, *and* the next vmd of the vuse (of gv), all the
time, and dominate that, or else we might cross a GV def.  This is
because ...

2. Your scheme is really assigning two versions to each global
variable : one version is changed at each def site of the variable (as
in normaly ssa), and one version is changed at each call site that
clobbers *any* global variable.  This is why you have VUSES on global
loads too.

Ie you are doing the equivalent of saying

A_2 (Global ver 1) = V_MUST_DEF <A_1 (GV1)>
A = 5 

B_3 (GV1) = V_MUST_DEF <B_2 (GV1)>
B = 6 

Z_5 (GV1) = V_MUST_DEF <Z_4 (GV1)>
VUSE<B_3 (GV1)>
VUSE<A_2 (GV1)>

Z = A + B

GV2 = V_MAY_DEF (GV1)
foo()

Z_6 (GV2) = V_MUST_DEF <Z_5 (GV2)>
VUSE<B_3 (GV2)>
VUSE<A_2 (GV2)>
Z = A + B

IE You end up having to check both the "regular" version number, and the
"global" version number, to determine whether a use of B_3 really is the
same B_3 that it's def links to (IE when the GV's are different, they
aren't).

This seems wonky, and is sure to confuse people :).

Also, since it's just the same as the above, why bother wasting memory
with more vuses?  You still need phis for the GV's in some cases, you
can't avoid that, but why not just add an extra int somewhere to
represent the global version number instead of a whole new vop per
statement?  Seems like if you are trying to make things save
memory/faster, that would be the way to go.




Reply via email to