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.