Re-lands perf/h02-runtime-lto (6d373317, b62448f3) behind the speed posture. - Runtime packs gain an executable `speed` flavor whenever the host LLVM helper can run. Its static units are emitted through the helper's `runtime-unit` command (promoted unit-local symbols, object and import bitcode from one module); its SCR_DYNAMIC variants reference the release objects. Release, dev, and library flavors and the vendor archives are built exactly as before (the rebuilt macOS pack's flavors and archives are identical to the baseline's). - Speed program builds load the speed flavor's bitcode and pass it to the helper (`--import-bitcode`); release builds never do. loadRuntimeBitcode only reads a real speed flavor, never release. - The helper drops the emitter's inert sanitize_address attributes only when it imports, so release modules reach the pipeline unchanged. - Tests: runtime-pack.test.ts covers speed-variant bitcode selection, verification, and that release-flavor bitcode is never imported; native-codegen.test.ts covers helper arguments and cache keys. Release executables stay byte-identical to the stack tip with the rebuilt helper (14/14 workloads, macOS).
2.5 KiB
scriptc LLVM code-generation helper
This out-of-process helper owns LLVM assembly and object emission for
scriptc. It is built against exactly LLVM 22.1.8 and currently contains only
the AArch64 backend. The shipping @scriptc/llvm-darwin-arm64 package builds
and carries the executable; the compiler resolves that package directly and
never searches PATH for this program.
The ordinary workspace pnpm -r build does not rebuild this release artifact.
On macOS arm64, install CMake, Ninja, and Homebrew llvm@22, then build it
explicitly when working on native emission or preparing a package:
$ brew install cmake ninja llvm@22
$ pnpm --filter @scriptc/llvm-darwin-arm64 build:native
The protocol is intentionally small and versioned:
The packaged helper itself requires macOS 15 or newer because that is the minimum version of the pinned LLVM bottle it statically links. Its emitted assembly and objects separately target macOS 14 via the triple below.
scriptc-llvm-codegen version --format=json
scriptc-llvm-codegen emit --input app.ll --output app.o --filetype obj \
--target arm64-apple-macosx14.0.0 --opt-level 2 \
--relocation-model pic --diagnostic-format json --source-path app.ts
Emission uses LLVM 22's default per-module O2 pipeline, including coroutine lowering, verifies before and after optimization, and publishes through a private sibling file so a failed or interrupted request cannot truncate the requested output.
--optimization=speed program builds pass --import-bitcode <unit.bc> once per runtime-pack unit the program links. Small runtime functions reachable from the program's runtime calls are imported as available_externally so LLVM can inline them; the runtime objects remain the only definitions. The helper never runs a sanitizer pass, so with import it also drops the emitter's inert sanitize_address attributes, which would otherwise block that inlining. Without --import-bitcode the module is optimized exactly as emitted.
Runtime-pack builds emit each unit of the executable speed flavor through the helper:
scriptc-llvm-codegen runtime-unit --input unit.opt.bc --object unit.o \
--bitcode unit.bc --target x86_64-unknown-linux-gnu --tag scr_array \
[--function-sections --data-sections]
The input is the runtime compiler's optimized bitcode. The command promotes unit-local symbols to hidden <name>.scrunit.<tag> globals and writes the object and the import bitcode from that one module, so imported bodies can reference the unit's private state and helpers.