What if we try a variation on this. Im not even sure how I feel about it since its even wonkier than what you suggest.
first, create a unique GV for each type, and implement a gatherer definition. Instead of individual VMAYDEFS for 3 variables, we have a gatherer which assigns them all to one global var. something like: > # GV_14 = V_KILL_ALL <x_2, y_4, z_6> > bar () then instead of using what would have been the new version of x, y or z, we use GV_14 for each of x, y, or z until it is redefined via another VMAYDEF. I know thats not very clear, so let me try to explain it more graphically with the virtual operands on the RHS of this listing: foo() { maps to: # X_2 = V_MUST_DEF <X_1> # X_2 = V_MUST_DEF <X_1> X = 3 # Y_4 = V_MUST_DEF <Y_12> # Y_4 = V_MUST_DEF <Y_12> Y = 1 # Z_6 = V_MUST_DEF <Z_11> # Z_6 = V_MUST_DEF <Z_11> # VUSE <X_2> Z = X + 1 # X_3 = V_MAY_DEF <X_2> # GV_13 = V_KILL_ALL <X_2, Y_4, Z_6> # Y_5 = V_MAY_DEF <Y_4> # Z_7 = V_MAY_DEF <Z_6> bar () # VUSE <X_3> # VUSE <GV_13> # Y_8 = V_MUST_DEF <Y_5> # Y_8 = V_MUST_DEF <GV_13> Y = X + 2 # VUSE <Y_8> # VUSE <Y_8> # VUSE <Z_7> # VUSE <GV_13> return Y + Z; } In effect, what we are doing is saying that at the call site every variable in the alias set for GV_13 has been MAYDEF'd. This means we dont know its value until its physically defined again, as Y is. Until then, we simply use the current GV variable instead of the individual variables. In into-ssa I guess this means the "current-def" would be set to the alias variable at these points. As I said, this looks pretty wonky, but I beleive it accurately represents reality. Other than the collector V_KILL_ALL, I dont think anything would change... would it? it looks a bit tricky to sort out bugs, especially in a large program with lots of variables. we might have to moidify the lister to add the variable names to the RHS when there is a reference to the GV to help. ie: # VUSE <X_3> # VUSE <GV_13 {X}> # Y_8 = V_MUST_DEF <Y_5> # Y_8 = V_MUST_DEF <GV_13 {Y}> Y = X + 2 # VUSE <Y_8> # VUSE <Y_8> # VUSE <Z_7> # VUSE <GV_13 {Z}> return Y + Z; It will be even more cryptic than this in reality. The VUSE of GV_13 is redundant, as it is mentioned in the RHS of the V_MUST_DEF, leaving us with: # Y_8 = V_MUST_DEF <GV_13> Y = X + 2 which looks even wonkyier. Its precise and efficient however. And will it cause an issue to have GV_13 in the RHS of a V_MUST_DEF and then be used later in a VUSE as in the return stmt? In *theory* it shouldnt, but I dont know if anyone has written code which assumes the RHS of a VMAYDEF is dead. I think all the PHI node issues work themselves out too, but you spend way more time thinking about PHI nodes than I do. maybe you see an issue. Alternatively, if this is either too out there, or I'm otherwise off my rocker for some reason Ive missed, we can visit a solution to the only real problem with the proposal: > > - If there are no uses of X, Y and Z after the call to bar, DCE will > think that those stores are dead. We would have to hack DCE to somehow > seeing the call to bar() as a user for those stores. This is really the only issue I see, and Im not sure of a decent way to deal with it. I'll think about it. Andrew