diff --git a/web/index.html b/web/index.html index 1b77603..3ac93c3 100644 --- a/web/index.html +++ b/web/index.html @@ -328,17 +328,30 @@ $ ./_build/default/bin/main.exe run calc-me.flan "1 + 2 * (3 - 0.5) / 2"
$ flan
 usage: flan (read|parse|check|emit|shim) <file.flan>...
+       flan emit <file.flan> [--x86] [--dev] [--debug] [--no-bounds-checks]
        flan import-c <header.h> [package.flan...] [clang flags...]
        flan generate-c <package-dir>
        flan build <file.flan> [-o out] [--no-bounds-checks] [--dev] [--debug] [--sanitize] [--x86] [--target=wasm32-wasi|web]
        flan run <file.flan> [args...]
-       flan reload <program.flan> <forms.flan> [-o out.so]
-       flan dev <program.flan> [-s socket]
+ flan reload <program.flan> <forms.flan> [-o out.so] [--x86] + flan dev <program.flan> [-s socket] [--x86]

read, parse, check, emit and shim each stop the pipeline one stage further along and print what it produced. run builds to a temporary file and execs it.

+

flan emit --x86 prints the hand-written backend's assembly where plain +emit prints LLVM IR, and it is annotated: each run of bytes is +headed by the Flan form that produced it and its source position, and each function by a +map of its frame saying which displacement is which parameter, which is a named local, +and below which offset everything is a reusable temporary. Reading a listing of this +backend without that map is reading -0x20(%rbp) with no key. The comments +cost nothing in the object — the assembler discards them — but they are +emitted only by emit, never by a build, so the assembly a build hands to +clang is the same text it always was. spike/x86/dump.sh puts all +four lowerings of one function side by side, which is what C-c C-l shows in +the editor.

+

The smallest program:

(defn main [] ()
@@ -1734,6 +1747,7 @@ something surprising.

C-c C-iinspect a value, navigating into its fields C-c C-mwhat the macro call at point expands to, one step; C-u first for all the way C-c C-adisassemble a function; C-u first for its LLVM IR +C-c C-levery lowering of a function at once: IR, -O0, -O2, and the hand-written backend C-c C-gdebug under lldb, through dape — bound only once flan-dape.el is loaded, so flan-mode works without dape installed C-c C-dwhat the running program currently defines C-c C-vhelp on the name at point @@ -1902,6 +1916,35 @@ name, with 38 programs skipped because they do not compile on either si no main, or run forever. dune build @x86 runs it as part of the build, so a refusal cannot sit unnoticed.

+

It serves the editor now, which is what it was written for. +flan dev --x86 and flan reload --x86 compile a redefinition +through the hand-written backend, and the round trip is about half what LLVM's is — +llc was nearly all of it, and an assembler is not:

+ + + + + + + +
LLVM--x86
code generationllc 42–48msas 8.0–8.4ms
linkld 9.7–11.4msld 8.9–9.3ms
C-c C-c, at the socket62–66ms27–30ms
C-x C-e60–61ms24–25ms
+ +

Both columns were measured on one machine, whose llc is slower than the +one the 15–17ms above came from; the comparison is the point and not the absolute +numbers. What the headline hides is where the time went: ld did not move and +is now half the x86 build, and about 9ms of the round trip is the frontend checking the +program again — a seventh of the LLVM loop but a third of this one. The next millisecond +is in the linker rather than the code generator.

+ +

It requires --two-process, and refuses the merged daemon by +name. A merged host is linked -rdynamic, so it exports every Flan +body it contains, and those interpose the prelude of the LLVM-built macro module the +compiler loads into itself to expand macros. An LLVM caller lands in an x86 body +and the process dies during the first expansion, before the program has started. The +marker symbol that refuses a crossed redefinition module does not catch this, and was +never meant to: a macro module deliberately carries none. Hidden visibility on a macro +module's Flan bodies is the fix and is not built.

+

--debug is a third flag beside --dev and the optimisation level. --dev asks whether you can redefine the program while it runs; --debug asks whether you can stop it and read it. It emits DWARF, sets