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



Reply via email to