Skip to content

Share frontend work across compiler test compilations#1136

Draft
mbouaziz wants to merge 7 commits intoSkipLabs:mainfrom
mbouaziz:compiler-tests
Draft

Share frontend work across compiler test compilations#1136
mbouaziz wants to merge 7 commits intoSkipLabs:mainfrom
mbouaziz:compiler-tests

Conversation

@mbouaziz
Copy link
Contributor

Summary

  • Add batch compilation mode (SKC_BATCH=1) that reuses a single SKStore context across compiler test compilations, sharing the stdlib frontend work (~93% of compilation time)
  • Add timing instrumentation (SKC_TIME_PHASES=1) with per-suite and per-component breakdown reporting
  • Default behavior (without env var) is completely unchanged

Results

  • Runtime test suite: 600s (batch, 8 workers) vs 1271s (subprocess) — ~2x speedup
  • All 1703 tests pass in both batch and non-batch modes
  • First test per worker: ~10s (full frontend), subsequent tests: ~1-2s (incremental)

Test plan

  • skargo test -j8 — all 1703 tests pass (non-batch regression)
  • SKC_BATCH=1 skargo test -j8 — all 1703 tests pass (batch mode)
  • SKC_BATCH=1 skargo test "runtime" -j1 — 230/230 pass, verify speedup
  • SKC_BATCH=1 skargo test "invalid" -j1 — invalid tests pass via subprocess fallback

🤖 Generated with Claude Code

mbouaziz and others added 7 commits March 10, 2026 15:12
Re-enable runCompilerPhase timing in skc (triggered by SKC_TIME_PHASES
env var), split the compilation pipeline into measurable phases
(frontend, IR generation, optimization, LLVM compilation, linking),
and add a timing summary to the test reporter showing per-suite
totals, slowest tests, and per-component time percentages.

Usage: SKC_TIME_PHASES=1 skargo test

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add a throwable exception class and printErrorsAndThrow() function
that formats errors the same way as printErrorsAndExit() but throws
instead of calling skipExit(). This enables batch compilation mode
where compilation failures are caught without terminating the process.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add batch_mode flag (defaults to false) and withInputFiles(),
withOutput(), withBatchMode() methods to allow per-test Config
construction in batch compilation mode.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
In the backend mapper, use printErrorsAndThrow() instead of
printErrorsAndExit() when batch_mode is set. Clear the ERRORS
global after handling to prevent leakage across batch compilations.
Pass batch_mode to runShell() for LLVM and link phases so they
throw instead of calling skipExit() on failure.

Default (non-batch) path is unchanged.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move the CLI command definition into a separate skcCommand()
function so the test harness can use it to construct Config
objects programmatically via skcCommand().parseArgs(args).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When SKC_BATCH=1 is set, worker subprocesses compile tests in-process
using a shared SKStore context instead of spawning separate skc
processes. The stdlib frontend (93% of compilation time) is computed
once per worker and cached for all subsequent compilations.

Without SKC_BATCH, behavior is identical to before (subprocess per test).

Key additions:
- batchTestJob(): replaces test_job in batch mode, runs within a
  single SKStore context
- batchValidTest/batchInvalidTest: in-process compilation variants
- runBatchTest: timing and exception handling matching SKTest.run_test
- collectBatchTests: gathers test metadata for batch processing
- Skip ensureCompatibleLLVMVersion() per-compilation in batch mode
  (checked once at worker startup)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- catchErrors() now delegates to keepErrors() in batch mode, preventing
  skipExit(2) from terminating workers during frontend error handling
- fatalError() throws CompileFailureException in batch mode instead of
  calling printErrorsAndExit
- Backend mapper stores error messages in BATCH_ERROR_MSG global instead
  of throwing from inside reactive computation (which corrupts context)
- compile() checks deferred errors after context.update() returns
- Invalid tests use subprocess path to avoid SKStore state corruption
- Fix sysroot resolution: resolve from `which skc` in PATH
- Fix parseArgs -> Cli.parseArgsFrom for test config
- Fix mutable IO.File capture: use immutable Int fd with ~> lambdas

All 1703 tests pass in both batch and non-batch modes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant