<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<p>Hi Diego,</p>
<p>Thank you very much for your work in this direction, it's sorely
needed.<br>
</p>
<p>I'm all for having proper roundtrip correctness for Cmm, but I am
not sure altering the parser is the way to go.<br>
In my opinion, GHC should produce valid textual Cmm, that can be
ingested by the parser at it is today.<br>
<br>
Have a nice day,<br>
Hécate<br>
</p>
<div class="moz-cite-prefix">Le 28/07/2025 à 02:16, Diego Antonio
Rosario Palomino a écrit :<br>
</div>
<blockquote type="cite"
cite="mid:CAONcbWLjEePZCQOzy9JPF1zp=MWAzxZXSn7L8Y8yGf7qC_sa9A@mail.gmail.com">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<div dir="ltr">
<p>Hello GHC devs,</p>
<p>I'm currently working on Cmm documentation and tooling
improvements as part of my Google Summer of Code project. One
of my core goals is to make Cmm roundtrip serializable.</p>
<p>Right now, the in-memory Cmm data structure—generated
programmatically (e.g., from STG via GHC)—can be
pretty-printed, and Cmm can also be parsed. However, the
pretty-printed version is not compatible with the parser. That
is, we cannot take the output of the pretty printer and feed
it directly back into the parser.</p>
<p>Example:</p>
<p>Parseable version:</p>
<pre><code>sum {
cr:
bits64 x;
x = R1 + R2;
R1 = x;
jump %ENTRY_CODE(Sp(0))[R1];
}
</code></pre>
<p>Pretty-printed version:</p>
<pre><code>sum() { // []
{ info_tbls: []
stack_info: arg_space: 8
}
{offset
cf: // global
_ce::I64 = R1 + R2;
R1 = _ce::I64;
call (I64[Sp + 0 * 8])(R1) args: 8, res: 0, upd: 8;
}
}
</code></pre>
<p>Another example:</p>
<p>Parseable version:</p>
<pre><code>simple_sum_4 { // [R2, R1]
cr: // global
bits64 _cq;
_cq = R2;
bits64 _cp;
_cp = R1;
R1 = _cq + _cp;
jump (bits64[Sp])[R1];
}
</code></pre>
<p>Pretty-printed version:</p>
<pre><code>simple_sum_4() { // []
{ info_tbls: []
stack_info: arg_space: 8
}
{offset
cs: // global
_cq::I64 = R2;
_cr::I64 = R1;
R1 = _cq::I64 + _cr::I64;
call (I64[Sp])(R1) args: 8, res: 0, upd: 8;
}
}
</code></pre>
<p>While it’s possible to write parseable Cmm that resembles the
pretty-printed version (and hence the internal ADT), they
don’t fully match—mainly because the parser inserts inferred
fields using convenience functions.</p>
<p>Proposal:</p>
<p>To make roundtrip serialization possible, I propose
supporting a new syntax that matches the pretty printer output
exactly.</p>
<p>There are a couple of design options:</p>
<ol>
<li>
<p>Create a separate parser that accepts the pretty-printed
syntax. Files could then use either the current parser or
the new strict one.</p>
</li>
<li>
<p>Extend the current parser with a dedicated block syntax
like:</p>
</li>
</ol>
<pre><code>low_level_unwrapped {
...
}
</code></pre>
<p>This second option is the one my mentor recommends, as it may
better reflect GHC developers' preferences. In this mode, the
parser would not insert any inferred data and would expect the
input to match the pretty-printed form exactly.</p>
<p>This would enable a true roundtrip:</p>
<ul>
<li>
<p>Compile Haskell to Cmm (in-memory AST)</p>
</li>
<li>
<p>Pretty-print and write it to disk (wrapped in
low_level_unwrapped { ... })</p>
</li>
<li>
<p>Later read it back using the parser and continue with
codegen</p>
</li>
</ul>
<p>Optional future direction:</p>
<p>As a side note: currently the parser has both a “high-level”
and a “low-level” mode. The low-level mode resembles the AST
more closely but still inserts some inferred data.</p>
<p>If we introduce this new “exact” low-level form, it's
possible the existing low-level mode could become redundant.
We might then have:</p>
<ul>
<li>
<p>High-level syntax</p>
</li>
<li>
<p>New low-level (exact)</p>
</li>
<li>
<p>And possibly deprecate the current low-level variant</p>
</li>
</ul>
<p>I’d be interested in your thoughts on whether that direction
makes sense.</p>
<p>Serialization libraries?</p>
<p>One technically possible—but likely unacceptable—alternative
would be to derive serialization via a library like <code>aeson</code>.
That would enable serializing and deserializing the Cmm AST
directly. However, I understand that <code>aeson</code> adds
a large dependency footprint, and likely wouldn't be suitable
for inclusion in GHC.</p>
<p>Final question:</p>
<p>Lastly—I’ve heard that parts of the Cmm pipeline may
currently be under refactoring. If that’s the case, could you
point me to which parts (parser, pretty printer, internal
representation, etc.) are being modified? I’d like to align my
efforts accordingly and avoid conflicts.</p>
<p>Thanks very much for your time and input! I'm happy to
iterate on this based on your feedback.</p>
<p>Best regards,<br>
Diego Antonio Rosario Palomino<br>
GSoC 2025 – Cmm Documentation & Tooling</p>
</div>
<br>
<fieldset class="moz-mime-attachment-header"></fieldset>
<pre wrap="" class="moz-quote-pre">_______________________________________________
ghc-devs mailing list
<a class="moz-txt-link-abbreviated" href="mailto:ghc-devs@haskell.org">ghc-devs@haskell.org</a>
<a class="moz-txt-link-freetext" href="http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs">http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs</a>
</pre>
</blockquote>
<pre class="moz-signature" cols="72">--
Hécate ✨
🐦: @TechnoEmpress
IRC: Hecate
WWW: <a class="moz-txt-link-freetext" href="https://glitchbra.in">https://glitchbra.in</a>
RUN: BSD</pre>
</body>
</html>