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