[MLton] modifying flatten.fun to always flatten

Stephen Weeks MLton@mlton.org
Thu, 15 Jan 2004 10:00:25 -0800


> As I understand it, the first part of the flatten.fun file extracts
> all the needed information to correctly fillout the two-point
> lattice, where top signifies that the tupple will not be flattened
> and bottom that it can be flattened.  The rest of the program checks
> the lattice and either flattenes or does not flatten depending on
> the value.

Yes.

> The initial idea to accomplish this was to modify the if then else
> branches in the flattening function as well the utility functions
> defined within it (IE doitArgs).

I think it would be better to modify the transformation as little as
possible, and instead to change the analysis to say "always flatten"
and then let the transformation do its thing.

> The initial idea was to have all functions default to the flatten
> case.

This is the right idea, except the way to achieve it is to make the
Rep.t's be flat.

> However, I have run into complications with the doitCaseCon function
> in which such a simple approach does not work.  For doitCaseCon I
> removed the tupple reconstruction, but also to no avail.

I would hope that you do not need to modify doitCaseCon -- once
everything is flattened it shouldn't have to do any coercions (line
298).

> One of the problem I am running into, is the diachotomy being
> created between what the tupples I am trying to flatten and the
> two-point lattice. Should I have to worry about the values in the
> two-point lattice?  For that matter, should I simply set them to
> bottom, or do I even need to do anything with the lattice?

Yes, you should use the lattice.  The default lattice value, bottom,
means flatten, which is what we want.  There are two places that the
value can be changed to top, via the makeTop function.  First, if a
type is not a tuple type, then we use makeTop.  This makes sense and
should be left alone, since non-tuples cannot be flattened.  Second,
the tuplize function, which is used in only one place, makes variables
top if they aren't explicitly bound to a tuple in doitStatement.  This
needs to be changed.  The easiest thing would be to add a flag

	val flattenAll: bool = ...

and to condition then call to tuplize on the flag

	if flattenAll then () else Rep.tuplize r

> When I attempt to fixpoint I am recieving the detupple message,
> which is generated if Tycons are not equal in the case of a tupple,
> whenever the function detuple is called.

I suspect this is happening because you are trying to flatten things
that aren't tuples.  This would happen if you blindly always follow
the Rep.isFlat case.

Once the analysis says to flatten all tuples, there is the problem
that the transformation will expect the tuple components to be there.
Specifically, the call to varTuple (line 232) will expect to get the
variables that make up the tuple.  While these will exist for
explicitly constructed tuples and for the flattened formals of blocks
and functions (created by doitArgs), they will not exist for tuples
that come from other places, e.g. Select expresssions (there may be
other places -- I'm not sure).  To fix that, you need to modify the
transformation to insert statements to select components of a tuples
that are needed by the flattens function.  You could either do it on
demand when varTuple is called, or just always generate the selects so
that varTuple always returns SOME, and let the shrinker later clean up
any unneeded selects.  The latter seems easier to me.  (Of course
these selects and any other modifications to the transformation should
be conditioned on flattenAll.)

Hopefully this makes sense.  Please followup when it works or you get
stuck.  If it starts to be more than ~50 lines of code, you're
probably headed down the wrong path (or have run into something I
didn't foresee :-).