summary_session-2026-10-24-separate-compilation.md 4.3 KB

Session 2026-10-24 — separate compilation (core)

V3 now builds per-unit objects. The one-shot mode remains the default for the suite/corpus.

Branch: master. Feature state: v3-separate-compilation. Gates: suite 305/305, fixpoint OK (3,806,078 bytes), corpus 519/612 compile-OK, 0 crashes.


What shipped

  • Stable symbols
    • module procedure: <Module>__<name>
    • module global: <Module>_<name>
    • string/ctor/set pools: <Module>_strN, <Module>_ctoN, <Module>_setN
    • class vtable: <Module>__<Class>__vt; methods include their class
    • nested procedures: object-local module-prefixed uid
    • external C procedures: C link name unchanged
  • Per-unit codegen
    • M2 -c Target.mod emits one .ssa; the target's own .def is found beside it automatically.
    • Library objects have no main; the program object has the only main.
    • Every object exports <Module>_init, including modules with no BEGIN body; the program calls imported inits in dependency order.
    • Top-level data is export data, so imported globals resolve.
  • Driver
    • M2 -c lowers the target .mod and its own .def (for exported data), skips imported definition units, and records imported init calls.
    • M2make --separate scans imports transitively, compiles each unit to gen_ssa/<Module>.o, and links all objects with cc + shim.
  • Classes
    • stable vtable/method symbols; a manual imported-class virtual call links and returns 42. Client objects do not duplicate imported vtables.

Tests

Added SepLib/SepProg and SepEmpty/SepEmptyProg:

  • library object contains no main;
  • program object contains main and links against only the library object (not its .mod);
  • exported data + library BEGIN works (42);
  • bodyless library still exports init and links (42).

Manual M2make cross-object class check: CLib.def/.mod + CProg.mod → virtual Area() = 42.

Limits

  • M2 -c requires imported interfaces on the command line; M2 -I import scanning is deferred. M2make --separate is the transitive resolver.
  • --separate rebuilds all objects (no incremental build/ABI marker).
  • Generics still need the generic body at the client; no separate generic-instance object emission yet.
  • The fixpoint gate still compares the one-shot compiler image, not a multi-object self-host.

Follow-up — -I and incremental objects (2026-10-24)

  • M2 -c -I dir now recursively scans target/import source files, resolves .def files (including lower-case names), topologically orders them, and parses them before the target.
  • M2make --separate now passes the target through M2 -c -I ... instead of an ever-growing explicit interface list.
  • Stale-object checks use source/interface mtimes; a newer compiler binary is treated as an ABI event; shim changes relink. A second run reports up to date.
  • Added SepResProg (M2 -c -I), M2make separate up-to-date, single-object recompile and .def-change rebuild tests.
  • Per-object self-hosting is now green. The stage-2 compiler regression was caused by building compiler units without the legacy 1-D call ABI; --m2flag -legacyopen1d plus the new bootstrap/fixpoint-separate.sh builds stage2/stage3 as objects and compares all per-object .ssa (11 objects).

Follow-up — ABI stamp and definition-only objects (2026-10-24)

  • M2make --separate now records gen_ssa/.m2abi containing the ABI version and --m2flag settings; a missing/changed stamp rebuilds all objects.
  • Modules with a .def but no .mod are compiled to gen_ssa/<Module>.o, so definition-only data and class vtables link.
  • Added CDefProg (class-only .def vtable) and M2make checks for the ABI stamp and definition-only object.
  • Suite is now 305/305.

Commits and tags

commit tag work
0adc637 v3-separate-compilation stable symbols, -c, library/program split, init list, M2make --separate, tests/docs
92d11d9 v3-separate-compilation-p1 M2 -I transitive resolution, incremental M2make objects, tests/docs
this docs commit v3-separate-compilation-summary session summary
final docs commit v3-session-2026-10-24-separate-end session tag

No push was performed.