contification paper
   
    Stephen Weeks
     
    MLton@sourcelight.com
       
    Fri, 16 Feb 2001 14:46:38 -0800 (PST)
    
    
  
> Looking at the outline, I think we'll be good on length without bringing
> in handlers.  And, they are completely transparent to the analyses, so I
> don't think they add much in this context.
Agreed.
> On the other hand, we really should be a little more precise about cycles.
> For example, we could have the following:
> 
> fun fm () = ...
> fun f () = ... K (g) ...
> fun g () = ... f () ...
> 
> and A(f) = g, A(g) = K is safe, although not minimal, and not "acyclic" in
> the sense that the transformation can't be performed.  I'll think a little
> more about this and see if I can't hammer out something more precise.
How about we just use Reach in the definition of safety.  I.E.
	* if not(Reach(f)) then A(f) = Uncalled
After all, reachability is a trivial concept and any sane analysis would do this 
(okok I know an old implementation of the contifier didn't :-).
If we do this, we can get rid of acyclicity in the definition of safety,
although we may need to prove it later anyways since we need it for the
transformation.
> > Maybe type correctness of resulting program.
> 
> I thought about this, but this will mean complicating the CPS IL a little.
> On the other hand, it probably won't be too hard; a function contified in
> another function doesn't change types at all; a function contified at a
> continuation changes it's return type, but corresponding calls also
> change.
It hadn't even occurred to me that we could present the CPS IL without the type
system.  But I see it doesn't really matter for this optimization.  However, in
the interest of staying closer to MLton and the fact that typed ILs are popular,
I think I'd like to present the IL as typed, at least in the grammar.  We can
mostly elide the types later.
> > Maybe the right thing to compare is the five analyses
> > 
> > 	none	call	cont	call+cont	dom
> > 
> > I'm wavering on including call+cont.
> 
> I agree.  The results there aren't much different than anywhere else.
So we go with none, call, cont, dom and either present run times as a ratio
relative to none or relative to dom, I'm not sure which.
> > Is this for the dom based on A*/parent, right?  Should we instead report the
> > dom based on ancestor, with a note that it's actually weaker due to the mutual
> > recursion problem?
> Yes, it is based on A*/parent.  The fact that the transformation accepts
> any A* safe analysis doesn't affect the transformation that's done when
> the dominator analysis uses ancestor (i.e., we won't be able to contify
> those two functions in logic).  It's a trivial change to run the parent
> analysis (I should just extend the contifyStrategy control) and get the
> numbers there.
You mean "change to run the ancestor analysis", right?  I assume so.  Anyways,
the run times should be based on ancestor since that conforms to the safety
definition in the paper.
Hmmm.  I just thought of another possibility.  What if we use the A* safety
definition, the parent analysis, and your latest transformation, but still
pretend we have mutual recursion.  Maybe that's not too complicated.
> I'll make one other comment.  When run with the call analysis, the new
> transformation is not identical to the old transformation.  Essentially,
> this is another nesting issue: 
..
> Essentially, the old transformation just found the one outside call and
> dropped the definition in the closest set of definitions.  The new
> transformation know that g is to be contified in f, so it's added before
> the original local functions of f.  There's no difference in runtimes
> between the old and new transformations, and virtually no difference in
> code size.
Good.  So we can stick with the one transformation that works for any safe
analysis.  I think it's ok to present a slightly historically inaccurate call
analysis, possibly with an incomprehensibly vague note about nesting.