<!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta name="generator" content="AsciiDoc 8.6.8"> <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 20130715</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’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 …</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’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>