<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="generator" content="AsciiDoc 8.6.10">
<title>CallGraph</title>
<link rel="stylesheet" href="./asciidoc.css" type="text/css">
<link rel="stylesheet" href="./pygments.css" type="text/css">


<script type="text/javascript" src="./asciidoc.js"></script>
<script type="text/javascript">
/*<![CDATA[*/
asciidoc.install();
/*]]>*/
</script>
<link rel="stylesheet" href="./mlton.css" type="text/css">
</head>
<body class="article">
<div id="banner">
<div id="banner-home">
<a href="./Home">MLton 20201002</a>
</div>
</div>
<div id="header">
<h1>CallGraph</h1>
</div>
<div id="content">
<div id="preamble">
<div class="sectionbody">
<div class="paragraph"><p>For easier visualization of <a href="Profiling">profiling</a> data, <span class="monospaced">mlprof</span> can
create a call graph of the program in dot format, from which you can
use the <a href="http://www.research.att.com/sw/tools/graphviz/">graphviz</a>
software package to create a PostScript or PNG graph.  For example,</p></div>
<div class="listingblock">
<div class="content monospaced">
<pre>mlprof -call-graph foo.dot foo mlmon.out</pre>
</div></div>
<div class="paragraph"><p>will create <span class="monospaced">foo.dot</span> with a complete call graph.  For each source
function, there will be one node in the graph that contains the
function name (and source position with <span class="monospaced">-show-line true</span>), as
well as the percentage of ticks.  If you want to create a call graph
for your program without any profiling data, you can simply call
<span class="monospaced">mlprof</span> without any <span class="monospaced">mlmon.out</span> files, as in</p></div>
<div class="listingblock">
<div class="content monospaced">
<pre>mlprof -call-graph foo.dot foo</pre>
</div></div>
<div class="paragraph"><p>Because SML has higher-order functions, the call graph is is dependent
on MLton&#8217;s analysis of which functions call each other.  This analysis
depends on many implementation details and might display spurious
edges that a human could conclude are impossible.  However, in
practice, the call graphs tend to be very accurate.</p></div>
<div class="paragraph"><p>Because call graphs can get big, <span class="monospaced">mlprof</span> provides the <span class="monospaced">-keep</span> option
to specify the nodes that you would like to see.  This option also
controls which functions appear in the table that <span class="monospaced">mlprof</span> prints.
The argument to <span class="monospaced">-keep</span> is an expression describing a set of source
functions (i.e. graph nodes).  The expression <em>e</em> should be of the
following form.</p></div>
<div class="ulist"><ul>
<li>
<p>
<span class="monospaced">all</span>
</p>
</li>
<li>
<p>
<span class="monospaced">"<em>s</em>"</span>
</p>
</li>
<li>
<p>
<span class="monospaced">(and <em>e &#8230;</em>)</span>
</p>
</li>
<li>
<p>
<span class="monospaced">(from <em>e</em>)</span>
</p>
</li>
<li>
<p>
<span class="monospaced">(not <em>e</em>)</span>
</p>
</li>
<li>
<p>
<span class="monospaced">(or <em>e</em>)</span>
</p>
</li>
<li>
<p>
<span class="monospaced">(pred <em>e</em>)</span>
</p>
</li>
<li>
<p>
<span class="monospaced">(succ <em>e</em>)</span>
</p>
</li>
<li>
<p>
<span class="monospaced">(thresh <em>x</em>)</span>
</p>
</li>
<li>
<p>
<span class="monospaced">(thresh-gc <em>x</em>)</span>
</p>
</li>
<li>
<p>
<span class="monospaced">(thresh-stack <em>x</em>)</span>
</p>
</li>
<li>
<p>
<span class="monospaced">(to <em>e</em>)</span>
</p>
</li>
</ul></div>
<div class="paragraph"><p>In the grammar, <span class="monospaced">all</span> denotes the set of all nodes.  <span class="monospaced">"<em>s</em>"</span> is
a regular expression denoting the set of functions whose name
(followed by a space and the source position) has a prefix matching
the regexp.  The <span class="monospaced">and</span>, <span class="monospaced">not</span>, and <span class="monospaced">or</span> expressions denote
intersection, complement, and union, respectively.  The <span class="monospaced">pred</span> and
<span class="monospaced">succ</span> expressions add the set of immediate predecessors or successors
to their argument, respectively.  The <span class="monospaced">from</span> and <span class="monospaced">to</span> expressions
denote the set of nodes that have paths from or to the set of nodes
denoted by their arguments, respectively.  Finally, <span class="monospaced">thresh</span>,
<span class="monospaced">thresh-gc</span>, and <span class="monospaced">thresh-stack</span> denote the set of nodes whose
percentage of ticks, gc ticks, or stack ticks, respectively, is
greater than or equal to the real number <em>x</em>.</p></div>
<div class="paragraph"><p>For example, if you want to see the entire call graph for a program,
you can use <span class="monospaced">-keep all</span> (this is the default).  If you want to see
all nodes reachable from function <span class="monospaced">foo</span> in your program, you would
use <span class="monospaced">-keep '(from "foo")'</span>.  Or, if you want to see all the
functions defined in subdirectory <span class="monospaced">bar</span> of your project that used
at least 1% of the ticks, you would use</p></div>
<div class="listingblock">
<div class="content monospaced">
<pre>-keep '(and ".*/bar/" (thresh 1.0))'</pre>
</div></div>
<div class="paragraph"><p>To see all functions with ticks above a threshold, you can also use
<span class="monospaced">-thresh x</span>, which is an abbreviation for <span class="monospaced">-keep '(thresh x)'</span>.  You
can not use multiple <span class="monospaced">-keep</span> arguments or both <span class="monospaced">-keep</span> and <span class="monospaced">-thresh</span>.
When you use <span class="monospaced">-keep</span> to display a subset of the functions, <span class="monospaced">mlprof</span>
will add dashed edges to the call graph to indicate a path in the
original call graph from one function to another.</p></div>
<div class="paragraph"><p>When compiling with <span class="monospaced">-profile-stack true</span>, you can use <span class="monospaced">mlprof -gray
true</span> to make the nodes darker or lighter depending on whether their
stack percentage is higher or lower.</p></div>
<div class="paragraph"><p>MLton&#8217;s optimizer may duplicate source functions for any of a number
of reasons (functor duplication, monomorphisation, polyvariance,
inlining).  By default, all duplicates of a function are treated as
one.  If you would like to treat the duplicates separately, you can
use <span class="monospaced">mlprof -split <em>regexp</em></span>, which will cause all duplicates of
functions whose name has a prefix matching the regular expression to
be treated separately.  This can be especially useful for higher-order
utility functions like <span class="monospaced">General.o</span>.</p></div>
</div>
</div>
<div class="sect1">
<h2 id="_caveats">Caveats</h2>
<div class="sectionbody">
<div class="paragraph"><p>Technically speaking, <span class="monospaced">mlprof</span> produces a call-stack graph rather than
a call graph, because it describes the set of possible call stacks.
The difference is in how tail calls are displayed.  For example if <span class="monospaced">f</span>
nontail calls <span class="monospaced">g</span> and <span class="monospaced">g</span> tail calls <span class="monospaced">h</span>, then the call-stack graph
has edges from <span class="monospaced">f</span> to <span class="monospaced">g</span> and <span class="monospaced">f</span> to <span class="monospaced">h</span>, while the call graph has
edges from <span class="monospaced">f</span> to <span class="monospaced">g</span> and <span class="monospaced">g</span> to <span class="monospaced">h</span>.  That is, a tail call from <span class="monospaced">g</span>
to <span class="monospaced">h</span> removes <span class="monospaced">g</span> from the call stack and replaces it with <span class="monospaced">h</span>.</p></div>
</div>
</div>
</div>
<div id="footnotes"><hr></div>
<div id="footer">
<div id="footer-text">
</div>
<div id="footer-badges">
</div>
</div>
</body>
</html>
