4.3 KiB
Handoff — one buffer for every lowering
Branch dev-loop, worktree agent-a9d4028fa5752ba39, from f772162.
spike/x86/dump.sh landed at f772162 and prints four lowerings of one function side by side: the LLVM IR
the frontend emits, what llc makes of it at -O0 and at -O2, and what the hand-written x86 backend emits.
Reading one against another is the only way to check a lowering by eye. A shell script that prints all four
into a scrollback is not how anyone reads them, though: three of the four are noise on any given day, and the
one that is not is the one you are elbow-deep in. So the same four go into an Emacs buffer with collapsible
sections, and the buffer remembers which of them you had open.
M-x flan-lowering, C-c C-l in flan-mode.
The three decisions
1. It compiles the file; it does not ask the daemon
flan-disassemble (C-c C-a) asks the running program what the body it is calling for a name actually came
out as. This asks a different question — what does this source compile to, through four different lowerings —
and the two cannot be merged, for a concrete reason rather than a stylistic one: the daemon has the
installed body's .ll and its .so, and neither llc -O2 nor the hand-written backend has ever been run
over it. There is no answer in the daemon to give. llc -O2 on the installed IR would be a fifth thing,
built here and never run anywhere, and the backend's output for an installed body does not exist at all
unless the daemon was started --x86.
So the two commands sit beside each other and each says which question it answers. flan-disassemble keeps
its header, whose showing line is the daemon's own account of how much its answer claims. This buffer's
header says the opposite thing just as plainly: it names the file and the compiler flags, and says the
listing is what the source on disk compiles to and not what the program is running. Both docstrings
cross-reference the other.
2. outline-minor-mode, not magit-section and not overlays of my own
Nothing under emacs/ requires a package that is not in Emacs — the whole client is subr-x, seq,
pcase, cl-lib, xref, eldoc, comint, imenu and its own files. Taking a dependency on Magit for a
four-section buffer would be the first, and it would be for folding, which Emacs has had since before Magit
existed.
outline-minor-mode on GNU Emacs 30.2.50 is the whole of what was asked for: outline-cycle is TAB on a
heading, outline-hide-body and outline-show-all collapse and expand everything, and
outline-next-visible-heading / outline-previous-visible-heading are n and p. Hand-rolling it would be
a hundred lines re-implementing that badly.
Headings are found by outline-search-function keyed to a text property this file puts on the four heading
lines, not by a regexp over the text. That is not fussiness: LLVM IR has ; comments, assembler output
has # and ; comments and lines that start with ., and objdump prints <flan.step>: label lines. Any
regexp loose enough to match four section headers matches inside three of the four bodies, and folding then
fragments in the middle of a listing.
3. The open/closed state is a global alist keyed by section, and nothing else
One defvar, four entries, alive for the Emacs session and no longer. Not persisted to disk: it is four
booleans, a preference file for it would one day have to be migrated, and nobody has ever wanted yesterday's
fold state back.
Keyed to the section, not to the function. The workflow is "I am working on the backend today", which is
a fact about the section and holds across every function the author looks at while he is doing it. Keyed to
the function it would forget on every M-x flan-lowering of a different name, which is exactly the thing he
asked not to happen.
The alist is the single source of truth. A toggle mutates it and then applies it to the buffer; a refresh applies it to the newly drawn buffer. Visibility is never read back out — that would couple this to whether outline folds with overlays or with text properties, which is a thing that has changed between Emacs versions and is none of this file's business.
Status
- Handoff stub, decisions fixed
emacs/flan-lower.el- Key in
flan-mode, autoloads - Tests in
emacs/test-flan-dev.el emacs/MANUAL.mddune test,@page,@cells