mirror of
https://github.com/c-cube/moonpool.git
synced 2025-12-16 15:56:21 -05:00
23 lines
No EOL
3.1 KiB
HTML
23 lines
No EOL
3.1 KiB
HTML
<!DOCTYPE html>
|
||
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>Tmc (ocaml.Tmc)</title><link rel="stylesheet" href="../../_odoc-theme/odoc.css"/><meta charset="utf-8"/><meta name="generator" content="odoc 2.2.1"/><meta name="viewport" content="width=device-width,initial-scale=1.0"/><script src="../../highlight.pack.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body class="odoc"><nav class="odoc-nav"><a href="../index.html">Up</a> – <a href="../index.html">ocaml</a> » Tmc</nav><header class="odoc-preamble"><h1>Module <code><span>Tmc</span></code></h1><p>Tail-modulo-cons optimization.</p><p><b>Warning:</b> this module is unstable and part of <span class="xref-unresolved">compiler-libs</span>.</p></header><div class="odoc-content"><p>TMC (Tail Modulo Cons) is a code transformation that rewrites transformed functions in destination-passing-style, in such a way that certain calls that were not in tail position in the original program become tail-calls in the transformed program.</p><p>As a classic example, the following program <code>|
|
||
let[@tail_mod_cons] rec map f = function
|
||
| [] -> []
|
||
| x :: xs ->
|
||
let y = f x in
|
||
y :: map f xs
|
||
|</code> becomes (expressed in almost-source-form; the translation is in fact at the Lambda-level) <code>|
|
||
let rec map f = function
|
||
| [] -> []
|
||
| x :: xs ->
|
||
let y = f x in
|
||
let dst = y :: Placeholder in
|
||
map_dps dst 1 f xs; dst
|
||
and map_dps dst offset f = function
|
||
| [] ->
|
||
dst.offset <- []
|
||
| x :: xs ->
|
||
let y = f x in
|
||
let dst' = y :: Placeholder in
|
||
dst.offset <- dst';
|
||
map_dps dst 1 f fx
|
||
|</code></p><p>In this example, the expression (y :: map f xs) had a call in non-tail-position, and it gets rewritten into tail-calls. TMC handles all such cases where the continuation of the call (what needs to be done after the return) is a "construction", the creation of a (possibly nested) data block.</p><p>The code transformation generates two versions of the input function, the "direct" version with the same type and behavior as the original one (here just <code>map</code>), and the "destination-passing-style" version (here <code>map_dps</code>).</p><p>Any call to the original function from outside the let..rec declaration gets transformed into a call into the direct version, which will itself call the destination-passing-style versions on recursive calls that may benefit from it (they are in tail-position modulo constructors).</p><p>Because of this inherent code duplication, the transformation may not always improve performance. In this implementation, TMC is opt-in, we only transform functions that the user has annotated with an attribute to request the transformation.</p><div class="odoc-spec"><div class="spec value anchored" id="val-rewrite"><a href="#val-rewrite" class="anchor"></a><code><span><span class="keyword">val</span> rewrite : <span><a href="../Lambda/index.html#type-lambda">Lambda.lambda</a> <span class="arrow">-></span></span> <a href="../Lambda/index.html#type-lambda">Lambda.lambda</a></span></code></div></div></div></body></html> |