[MLton-devel] New release of MLton: call-graphs

Matthew Fluet MLton@mlton.org
Thu, 3 Apr 2003 12:31:46 -0500 (EST)


> Comments on the new approach appreciated.

It all seems reasonable.

I guess my only qualm is that we are using an implementation detail to try
and capture an implementation independent fact: namely, that in the
following code:

val (op o) = fn (f, g) => fn x => f (g x)
local
val f1 = ...
val f2 = ...
val g1 = ...
val g2 = ...
in
val h1 = (f1 o g1)
val h2 = (f2 o g2)
end

all occurences of f1 on the call stack have a frame for o below them and a
frame for h1 below that and similarly for the other functions.  In
particular, that control flow realized by the program always has edges
from h1 to o to both f1 and g1 but never to f2 or g2, despite the fact
that clearly control can flow from from o to any of f1, f2, g1, g2, just
not arbitrarily.

The point being, that if I change the definition of o to

val (op o) = fn (f, g) => fn x => (print "Composed function called.\n";
                                   f (g x))

Then no amount of fiddling with mlprof (or mlton) parameters will recover
the mlprof graph that is drawn in the previous case, because the
implementation won't split the o function.

Anyways, I just don't want to give the impression that when someone
writes:

fun expensive(x) = ...

fun useA () = ... expensive(a) ...
fun useB () = ... expensive(b) ...

and sees lots of time spent in expensive, looks at the call graph and
thinks "I wonder if it is the call in useA that is time consuming or
the call in useB?  I know, I'll  -profile-split expensive, and looking at
the new call graph, I'll be able to tell which was more expensive."  This
won't work when expensive isn't actually split by the compiler.  Now, the
user should be able to figure this out by compiling with -profile-stack
true, and hopefully one of useA's or useB's stack time will give an
indication of which call to expensive was more time consuming.

> One other thing I'd like to point out is that I'm beginning to wonder
> about the necessity of -profile-split.  It was originally added to
> solve the problem where a utility function needed to be split so that
> when it was ignored by mlprof, spurious edges wouldn't be added.  With
> the new approach, this is no longer a problem since the split version
> of a function that is not -graph'ed will always be used.  So, the only
> remaining use of -profile-split is when the user wants to actually see
> a split function.  I suppose that could happen when you want to
> profile a library function, though.

Personally, I'm wary of using -profile-split, because my notion of a
utility function may be quite different from the compiler's notion of a
splittable function.  In particular, the graphs for programs with/without
debugging statements might be very different, even though my notion of a
utility function hasn't changed.


I guess all I'm saying is something that should always be said with
profiling: that the results need to be interpreted carefully.  The problem
is that when you allow compiler details to leak into the profiling info,
you make the interpretation that much more careful.



-------------------------------------------------------
This SF.net email is sponsored by: ValueWeb: 
Dedicated Hosting for just $79/mo with 500 GB of bandwidth! 
No other company gives more support or power for your dedicated server
http://click.atdmt.com/AFF/go/sdnxxaff00300020aff/direct/01/
_______________________________________________
MLton-devel mailing list
MLton-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mlton-devel