diff --git a/CLAUDE.md b/CLAUDE.md index ad985b387..833faa19f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -310,7 +310,7 @@ Most layout is obvious from `ls`. Non-obvious ones worth knowing: - `utils/detect-dupe/` (in-repo dupe finder) and `utils/find-dupe/` (Claude-based judge that needs `daspkg install --root utils/find-dupe` + `ANTHROPIC_API_KEY`) — both also exposed as MCP tools - `utils/mcp/`, `utils/daslang-live/`, `utils/daspkg/` — in-tree tools (most also have skills under `skills/`) - `tutorials/language/` (language tour) vs `tutorials//` (per-area) — never put tutorials in `modules//tutorial/` -- **Array/dim/vector indexing lives across 5 tiers** — bug fixes (bounds checks, neg-index detection, width-aware bounds) usually need parallel edits in all of them: AOT C++ ([include/daScript/simulate/aot.h](include/daScript/simulate/aot.h)), interpreter non-fused ([include/daScript/simulate/runtime_array.h](include/daScript/simulate/runtime_array.h) + [include/daScript/simulate/simulate_nodes.h](include/daScript/simulate/simulate_nodes.h)), interpreter fused ([src/simulate/simulate_fusion_at_array.cpp](src/simulate/simulate_fusion_at_array.cpp) + [src/simulate/simulate_fusion_at.cpp](src/simulate/simulate_fusion_at.cpp)), JIT ([modules/dasLLVM/daslib/llvm_jit.das](modules/dasLLVM/daslib/llvm_jit.das)), and AST const-fold ([src/ast/ast_simulate.cpp](src/ast/ast_simulate.cpp)). Debug builds bypass the fused permutations — a fix that lands only in the fused path passes Release CI and trips Debug-ARM. Bump `LLVM_JIT_CODEGEN_VERSION` in `modules/dasLLVM/daslib/llvm_macro.das` after JIT changes to invalidate cached `.dll`s +- **Array/dim/vector indexing lives across 5 tiers** — bug fixes (bounds checks, neg-index detection, width-aware bounds) usually need parallel edits in all of them: AOT C++ ([include/daScript/simulate/aot.h](include/daScript/simulate/aot.h)), interpreter non-fused ([include/daScript/simulate/runtime_array.h](include/daScript/simulate/runtime_array.h) + [include/daScript/simulate/simulate_nodes.h](include/daScript/simulate/simulate_nodes.h)), interpreter fused ([src/simulate/simulate_fusion_at_array.cpp](src/simulate/simulate_fusion_at_array.cpp) + [src/simulate/simulate_fusion_at.cpp](src/simulate/simulate_fusion_at.cpp)), JIT ([modules/dasLLVM/daslib/llvm_jit.das](modules/dasLLVM/daslib/llvm_jit.das)), and AST const-fold ([src/ast/ast_simulate.cpp](src/ast/ast_simulate.cpp)). Debug builds bypass the fused permutations — a fix that lands only in the fused path passes Release CI and trips Debug-ARM. Bump `LLVM_JIT_CODEGEN_VERSION` in `modules/dasLLVM/daslib/llvm_jit_run.das` after JIT emitter/ABI changes to invalidate cached `.dll`s (the cache hash also folds per-function AOT hashes, so AST-level changes self-invalidate without a bump) ## MCP Server (AI Tool Integration) diff --git a/QUOTE_LOWERING.md b/QUOTE_LOWERING.md index 5249dd994..99e3a7fce 100644 --- a/QUOTE_LOWERING.md +++ b/QUOTE_LOWERING.md @@ -247,14 +247,94 @@ JIT work in scope before then is the Phase 1 diagnostic (clean `unsupported` mes replacing the misleading "Internal jit error" panic). The QuotePass gate stays `aot_macros`-only until this phase; extending it to `jit_enabled` lands here. -- [ ] Extend QuotePass gate to `jit_enabled`. -- [ ] `tests/jit_tests/` coverage for quote under `options jit` (lowered path through - LlvmJitVisitor — make-struct of handled types, `to_array_move`, by-name lookups). +- [x] Extend QuotePass gate to `jit_enabled` (2026-06-12). Two traps found on first contact, + both via `daslib/typemacro_boost`: + 1. **Wrapper return type must be the raw quote's type.** `fn.result = autoinfer` leaked + the concrete node type (`quote(0)` → `ExprConstInt?` instead of `Expression?`), + breaking `cond ? clone_expression(x) : quote(0)` (30411, cond arms must match + exactly). Fix: `fn.result = clone_type(expr._type)` — identity by construction. + 2. **Macro-module programs must not lower under the jit trigger.** Macro contexts are + never JITted (llvm_macro's `is_compiling_macros()` skip), and the lowered + construction frames overflowed the macro-context stack at apply time + (`stack overflow while calling @typemacro_boost::\`quote\`lowered\`28`). Predicate + gotcha: `is_compiling_macros()` reads `Program::isCompilingMacros`, which is only + true during `makeMacroModule`'s simulate — at infer time (when QuotePass runs) use + `prog.flags.needMacroModule` instead (set at annotation-apply, pre-infer). The + infer-time noAot-skip in ast_infer_type.cpp mirrors the same predicate. Raw quotes + reaching JIT from such modules fall back per-function via the new + DisableJitVisitor `preVisitExprQuote` (warn + disable, replacing whole-file panic). +- [x] Coverage instead of new jit_tests: lifted the `-jit` folder skips (quote, ast, + ast_match, no_aot) in tests/.das_test + the matching `--exclude`s on + jit_cache_all_tests, and un-marked `[no_jit]` in tests/template/test_push_block_list + (its stated reason — JIT can't lower ExprQuote — is gone; qmacro_block now JITs). + Folder results: quote 20/20, ast 1/1, ast_match 380/380 (2 graceful per-function + fallbacks in daslib/ast_match — macro module, stays raw by design), flatten/no_aot + 14/14, template 10/10. The gc skip was lifted too, then RESTORED — see next item. +- [x] NOT quote-related, surfaced (and re-buried) while lifting the gc skip: tests/gc is + unsound under JIT for two reasons. (1) **LLVM JIT does not implement + `force_escape_free` / `force_allocate_on_stack`** — heap grows where interp stays + flat; scope-exit free aborts "not a chunk pointer" on JIT-allocated owning nodes + under persistent_heap; nested `new Inner` make-struct field arrives null. (2) The + one Debug CI caught after the per-function `[no_jit]` round: **`heap_collect` cannot + see a heap pointer whose only reference is a local in a jitted frame** (native-stack + locals are invisible to the collector) — the object is freed as garbage, and the + test's later `delete` double-frees (Debug memory_model.h:109 assert; Release passes + by luck until the slot is reused — probe: interp prints n.x=7, jit prints n.x=-1, + with or without force_escape_free). (2) is systemic for GC-semantics tests, so the + folder-level `-jit` skip in tests/.das_test is restored (root cause in the comment) + and the scoped `[no_jit]` markers were reverted. Lift again only when the JIT spills + GC roots somewhere the collector can scan. Upstream fix is its own work item. +- [x] Pre-existing CI infra bug exposed by the gc crash (NOT this PR's doing, heals once + the gc skip is back): when the main `-jit` sweep crashes, build.yml falls back to + `--isolated-mode` — 32 worker subprocesses all spawn with `-jit -jit`, whose harness + dll hash differs from the outer run's prewarmed one → every worker cache-misses the + SAME dll path simultaneously and they race writing the same `.o`/`.dll`: "file + format not recognized" (half-written .o), "failed to set dynamic section sizes: + file truncated" (rewritten mid-link), and the llvm_jit_run.das:342 post-write + verify assert (dll swapped between write and reopen). Cost 3 collateral + typer_errors "failures" on linux Debug. Fix candidates: lock/atomic-rename in + write_dll, or prewarm the worker-flag-combination dll before fan-out. +- [x] Local full-tree `-jit` sweep caveat (NOT this PR's doing): the in-process sweep + aborts (exit 127, no diagnostic) at tests/language/table_operations.das + `ta_test_lock_panic` — a deliberate table-lock panic inside jitted code fails to + unwind to `recover` and kills the process. **Pre-existing**: reproduces with master + daslib state, and the content-addressed dll hash is identical with/without the + Phase 5 changes (same codegen input). Local-env specific (LLVM 22.1.5 Windows, + opt-level 3); master CI Windows -jit is green (different LLVM, plus the + `|| --isolated-mode` fallback built into the CI step). Local full-tree signal + obtained with `--exclude table_operations --exclude test_linq_table_source` (the + second file is just the next deliberate-panic test the abort moves to); CI is the + authoritative gate. +- [x] **Third trap, found only by the full sweep (order-dependent linq failures):** a + module that is macro-CALLED but not itself a macro module (daslib/linq_fold_decs — + plain functions invoked from linq_boost's fold macros) has `needMacroModule == + false`, so it DOES lower under the jit trigger — and its lowered quotes then + evaluate at macro-apply time on the calling macro module's macro-context stack: + `stack overflow while calling @linq_fold_decs::\`quote\`lowered\`17` → 31206 → the + consumer file fails to compile (tests/linq/test_linq_fold_terminal_select + + test_linq_from_decs). Order-dependent because the overflow margin depends on + module-cache state at compile time — single-folder runs passed, full-tree + root-form runs failed deterministically (bisect: my code at master folder set + still failed; zero-predecessor root form still failed → not contamination at all, + a per-file stack margin). FIX: `Program::makeMacroModule` sizes the MACRO context + to `max(getContextStackSize(), 1MB)` when `aot_macros || jit_enabled` — the + headroom lands exactly where lowered quotes evaluate at macro-apply time, for any + embedder, with no driver changes. First attempt was a `policies.stack = 1MB` bump + in the three jit drivers (main.cpp / dastest / jit.exe), mirroring the + `-aot-macros` flow — REGRESSION: `policies.stack` also sizes the PRODUCED + program's runtime context, so cross-compiled wasm executables tried to carve 1MB + out of wasm linear memory and trapped at runtime (CI `wasm_cross`, f2s.wasm + "thrown Wasm exception"). Reverted; the `-aot-macros` global bump keeps its + historical behavior. Durable fix remains chunking the lowered construction into + bounded frames (Phase 6 candidate) — that would let macro contexts drop the + special-casing entirely. - [ ] Decide + implement JIT-of-macro-contexts: lift the `is_compiling_macros()` skip in llvm_macro.das behind a policy. This is the compile-time payoff twin of AOT'd macro modules. Separate PR; needs its own bake time. -- [ ] `LLVM_JIT_CODEGEN_VERSION` bump only if emitters change (diagnostic-only changes - don't). +- [x] `LLVM_JIT_CODEGEN_VERSION` bump NOT needed: emitters unchanged (gate + collection + only), and the dll cache hash folds per-function AOT hashes, so lowered ASTs and + changed collection sets self-invalidate. (CLAUDE.md pointer fixed: the constant + lives in llvm_jit_run.das, not llvm_macro.das.) ## Phase 6 — extra coverage + payoff measurement diff --git a/daslib/quote.das b/daslib/quote.das index e9a0739c6..2b3c63b64 100644 --- a/daslib/quote.das +++ b/daslib/quote.das @@ -483,7 +483,10 @@ class QuoteConverter : AstVisitor { } var fn = new Function(at = expr.at, atDecl = expr.at, name := fname, flags = FunctionFlags.generated | FunctionFlags.privateFunction) - fn.result = new TypeDecl(baseType = Type.autoinfer) + // preserve the raw quote's static type (Expression?) — autoinfer would leak the + // concrete node type (e.g. ExprConstInt?) and break consumers that need type + // identity, e.g. `cond ? clone_expression(x) : quote(0)` + fn.result = expr._type != null ? clone_type(expr._type) : new TypeDecl(baseType = Type.autoinfer) var blk = new ExprBlock(at = expr.at) emplace_new(blk.list) <| new ExprReturn(at = expr.at, subexpr = conv) fn.body = blk @@ -497,9 +500,16 @@ class QuotePass : AstPassMacro { //! Pass macro that processes quoted AST expressions. def override apply(prog : ProgramPtr; mod : Module?) : bool { // Unwrapping ExprQuote is slow and inefficient, do it only if necessary. - // Triggered by the aot_macros policy (`daslang -aot -aot-macros`) or per-module - // `options aot_macros` (self-contained tests, interpreted A/B). - let lower = compiling_program().policies.aot_macros || (prog._options |> find_arg("aot_macros") ?as tBool ?? false) + // Triggered by the aot_macros policy (`daslang -aot -aot-macros`), the jit_enabled + // policy (lowered quotes codegen natively, raw ones can't), or per-module + // `options aot_macros` (self-contained tests). Macro-module programs are excluded + // from the jit trigger: macro contexts are never JITted (see llvm_macro's + // is_compiling_macros skip), and the lowered construction frames can overflow the + // macro-context stack at apply time. Raw quotes reaching JIT codegen from such + // modules fall back per-function via DisableJitVisitor. + let lower = (compiling_program().policies.aot_macros + || (compiling_program().policies.jit_enabled && !prog.flags.needMacroModule) + || (prog._options |> find_arg("aot_macros") ?as tBool ?? false)) if (!lower) return false // nothing to do var astVisitor = new QuoteConverter(mod = compiling_module()) make_visitor(*astVisitor) $(astVisitorAdapter) { diff --git a/modules/dasLLVM/daslib/llvm_jit.das b/modules/dasLLVM/daslib/llvm_jit.das index 4b9d13254..0ecb11409 100644 --- a/modules/dasLLVM/daslib/llvm_jit.das +++ b/modules/dasLLVM/daslib/llvm_jit.das @@ -3391,7 +3391,7 @@ class public LlvmJitVisitor : AstVisitor { // ExprQuote def override preVisitExprQuote(expr : ExprQuote?) : void { - unsupported(expr, "quote( ) is not jit-able without aot_macros lowering (daslib/quote)") + unsupported(expr, "raw quote( ) is not jit-able — daslib/quote lowering (jit_enabled / aot_macros gates) did not run for this module") } // ExprIfThenElse @@ -7645,6 +7645,14 @@ class public DisableJitVisitor : AstVisitor { } } + def override preVisitExprQuote(expr : ExprQuote?) : void { + // jit_enabled programs get quotes lowered by daslib/quote's QuotePass before we + // ever run; a raw one means lowering didn't fire for the defining module (macro + // modules stay raw by design) — skip the function instead of failing the file + to_log(LOG_WARNING, "LLVM JIT: raw quote( ) — daslib/quote lowering (jit_enabled / aot_macros gates) did not run for this module at {expr.at}, falling back to interpreter.\n") + disable = true + } + def override preVisitExprForBody(expr : ExprFor?) : void { for (_, ssrc in expr.iteratorVariables, expr.sources) { assume ssrc_t = ssrc._type diff --git a/skills/writing_tests.md b/skills/writing_tests.md index 45a2c32e2..aa2e8bd30 100644 --- a/skills/writing_tests.md +++ b/skills/writing_tests.md @@ -21,7 +21,7 @@ directory filter below instead.) `tests/.das_test` is a daslang script dastest compiles per run; its `can_visit_folder` pinvoke gates whole directories per mode — e.g. `no_aot/`, `ast/`, `ast_match/` are -skipped under `--use-aot` / `-jit`, module dirs (dasSQLITE, dasPUGIXML…) skip when the +skipped under `--use-aot`, module dirs (dasSQLITE, dasPUGIXML…) skip when the module isn't built in. **The filter is looked up only at the `--test` ROOT path** — `--test tests` finds and applies it, but `--test tests/flatten` looks for `tests/flatten/.das_test` (absent) and walks into `no_aot/` unfiltered, producing @@ -33,14 +33,20 @@ false `error[50101]` / JIT failures. For AOT/JIT validation, sweep `--test tests `tests/.das_test` defines `can_visit_folder(folder_name, result)` — dastest consults it per subfolder during file collection (only for the `.das_test` at the `--test ` argument; directly naming a child folder bypasses it). It gates folders on module -availability (`dasHV`, `dasSQLITE`, …) and on sweep mode by scanning argv for `-jit` / -`--use-aot` (e.g. `ast`, `ast_match`, `no_aot`, `gc`, `quote` skip under `-jit` — runtime -quote/qmacro the JIT can't codegen). Two traps: a whole-folder JIT/AOT failure usually -means a missing entry here, NOT a per-file fix; and the `jit_cache_all_tests` prewarm -target (utils/CMakeLists.txt) does NOT consult it — its `--exclude` list mirrors the -`-jit` skips manually and must be updated in the same change. Per-function `[test, no_jit]` -(tests/template/test_push_block_list.das) is the finer-grained alternative when only some -tests in a kept folder can't JIT. +availability (`dasHV`, `dasSQLITE`, …) and on sweep mode by scanning argv — `--use-aot` +skips `ast`, `ast_match`, `no_aot`; `-jit` skips only `gc` (heap_collect can't see heap +pointers whose only reference is a local in a jitted frame — native-stack locals are +invisible to the collector, so GC-semantics tests are interp-only; the other former `-jit` +skips were lifted once `jit_enabled` started triggering daslib/quote lowering). Two traps: +a whole-folder JIT/AOT failure usually means a missing entry here, NOT a per-file fix; and +the `jit_cache_all_tests` prewarm target (utils/CMakeLists.txt) does NOT consult it — its +`--exclude` list mirrors the skips manually and must be updated in the same change. +Per-function `[no_jit]` is the finer-grained alternative when only some functions in a +kept folder can't JIT — put it on the function whose CODE diverges under JIT, not just the +`[test]` wrapper (JITted callees replace their SimNode bodies, so an interpreted wrapper +still calls jitted workers). Beware Release-blind divergence: memory bugs (double-free, +reuse-after-collect) only trip the Debug memory_model.h assert, so a green local Release +sweep does NOT prove a lifted skip is sound — Debug CI is the oracle. ## Test file structure diff --git a/src/ast/ast_infer_type.cpp b/src/ast/ast_infer_type.cpp index fa25ad6b1..905c0fe91 100644 --- a/src/ast/ast_infer_type.cpp +++ b/src/ast/ast_infer_type.cpp @@ -1438,9 +1438,12 @@ namespace das { expr->type->firstType = new TypeDecl(Type::tHandle); expr->type->firstType->annotation = (TypeAnnotation *)Module::require("ast_core")->findAnnotation("Expression"); // mark quote as noAot, unless daslib/quote lowering will replace it - // (aot_macros policy or per-module `options aot_macros` — same gate as QuotePass) + // (aot_macros or jit_enabled policy, or per-module `options aot_macros` — same gate + // as QuotePass, including its macro-module exclusion for the jit trigger) if (func) { - if (!program->policies.aot_macros && !program->options.getBoolOption("aot_macros", false)) { + if (!program->policies.aot_macros + && !(program->policies.jit_enabled && !program->needMacroModule) + && !program->options.getBoolOption("aot_macros", false)) { func->noAot = true; } } diff --git a/src/ast/ast_simulate.cpp b/src/ast/ast_simulate.cpp index effde64ea..5be767ce7 100644 --- a/src/ast/ast_simulate.cpp +++ b/src/ast/ast_simulate.cpp @@ -3532,7 +3532,16 @@ namespace das void Program::makeMacroModule ( TextWriter & logs ) { isCompilingMacros = true; - thisModule->macroContext = get_context(getContextStackSize()); + int macroStackSize = getContextStackSize(); + if ( policies.aot_macros || policies.jit_enabled || options.getBoolOption("aot_macros", false) ) { + // quote lowering (daslib/quote) is active (same triggers as its QuotePass gate, + // including the per-module option): a lowered quote evaluates one large + // construction frame per quote, and macro-called functions evaluate theirs on + // THIS context's stack at macro-apply time. Size only the macro context — a + // global policies.stack bump would leak into produced exe/wasm runtime stacks. + macroStackSize = das::max(macroStackSize, 1 * 1024 * 1024); + } + thisModule->macroContext = get_context(macroStackSize); thisModule->macroContext->category = uint32_t(das::ContextCategory::macro_context); auto oldAot = policies.aot; auto oldHeap = policies.persistent_heap; diff --git a/tests/.das_test b/tests/.das_test index e8ecd3772..cf0422277 100644 --- a/tests/.das_test +++ b/tests/.das_test @@ -39,26 +39,22 @@ def can_visit_folder(folder_name : string; var result : bool?) { } } // A meta-test that requires the compiler frontend at runtime (e.g. daslib/flatten -> - // macro_boost) can't AOT-link in the full-tree batch, and one that runs qmacro at runtime - // (flatten_optimize re-entry) carries quote nodes LLVM JIT can't codegen — interp only. - if (folder_name == "no_aot") { + // macro_boost) can't AOT-link in the full-tree batch. Under -jit it runs fine: quote( ) + // nodes are lowered by daslib/quote when jit_enabled is set. + if (folder_name == "no_aot" || folder_name == "ast_match" || folder_name == "ast") { let args <- get_command_line_arguments() for (arg in args) { - if (arg == "--use-aot" || arg == "-jit") { - *result = false - return - } - } - } - if (folder_name == "ast_match" || folder_name == "ast") { - let args <- get_command_line_arguments() - for (arg in args) { - if (arg == "--use-aot" || arg == "-jit") { + if (arg == "--use-aot") { *result = false return } } } + // GC tests are interp-only under JIT: jitted frames keep locals on the native stack, + // so heap_collect can't see a heap pointer whose only reference is a jitted local and + // frees it (double-free / reuse-after-collect; Debug memory_model.h assert catches it, + // Release passes by luck). Lift only once the JIT spills GC roots somewhere the + // collector can scan. if (folder_name == "gc") { let args <- get_command_line_arguments() for (arg in args) { @@ -68,16 +64,4 @@ def can_visit_folder(folder_name : string; var result : bool?) { } } } - // The A/B baseline fixture keeps raw quote( ) nodes LLVM JIT can't codegen. - // AOT stays on (the lowered twins are the point). Lift with the JIT lowering lane. - if (folder_name == "quote") { - let args <- get_command_line_arguments() - for (arg in args) { - if (arg == "-jit") { - *result = false - return - } - } - } - } diff --git a/tests/template/test_push_block_list.das b/tests/template/test_push_block_list.das index a94c7cfde..a2515dbca 100644 --- a/tests/template/test_push_block_list.das +++ b/tests/template/test_push_block_list.das @@ -11,16 +11,10 @@ require dastest/testing_boost public // result into an ``array``, cloning each. Use in place of a // cluster of ``stmts |> push <| qmacro_expr() { single_stmt }`` calls when // emitting multi-statement snippets. -// -// All tests carry ``[no_jit]`` because ``qmacro_block`` codegens to an -// ``ExprQuote`` wrapping a multi-statement block, which the LLVM JIT does -// not lower (interp + AOT lanes handle it fine). Single-expression -// ``qmacro(...)`` calls in the peer ``tests/ast_match/test_peel_lambda_*`` -// tests DO JIT — only the block form is affected. // ── Multi-statement append ────────────────────────────────────────────── -[test, no_jit] +[test] def test_appends_all_statements(t : T?) { ast_gc_guard() { var stmts : array @@ -36,7 +30,7 @@ def test_appends_all_statements(t : T?) { // ── Single-statement (degenerate but legal) ──────────────────────────── -[test, no_jit] +[test] def test_single_statement(t : T?) { ast_gc_guard() { var stmts : array @@ -50,7 +44,7 @@ def test_single_statement(t : T?) { // ── Composes with prior + subsequent pushes ──────────────────────────── -[test, no_jit] +[test] def test_interleaves_with_other_pushes(t : T?) { ast_gc_guard() { var stmts : array @@ -71,7 +65,7 @@ def test_interleaves_with_other_pushes(t : T?) { // ── Pipe form ─────────────────────────────────────────────────────────── -[test, no_jit] +[test] def test_pipe_form(t : T?) { ast_gc_guard() { var stmts : array @@ -86,7 +80,7 @@ def test_pipe_form(t : T?) { // ── Null input is a silent no-op ──────────────────────────────────────── -[test, no_jit] +[test] def test_null_block_is_noop(t : T?) { ast_gc_guard() { var stmts : array diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt index f373b3d03..671ca4097 100644 --- a/utils/CMakeLists.txt +++ b/utils/CMakeLists.txt @@ -104,13 +104,14 @@ foreach(util ${DAS_UTILS}) endforeach() add_dependencies(all_utils_exe dastest_exe) -# Prewarm the JIT dll cache for the whole test tree, except the folders dastest -# also excludes under -jit (gc, ast_match, ast, no_aot, quote — they use runtime quote/qmacro -# the JIT can't lower). Reuses the jit_exe target built by the foreach above (bin/jit.exe, built -# with --jit-register-all-modules). Run explicitly: +# Prewarm the JIT dll cache for the whole test tree, except module-gated folders and gc +# (mirrors tests/.das_test: gc stays interp-only under -jit — heap_collect can't see +# jitted-frame locals; quote/qmacro folders prewarm fine now that jit_enabled triggers +# daslib/quote lowering). Reuses the jit_exe target built by the foreach above +# (bin/jit.exe, built with --jit-register-all-modules). Run explicitly: # ninja jit_cache_all_tests add_custom_target(jit_cache_all_tests - COMMAND ${UTIL_BIN_DIR}/jit.exe ${PROJECT_SOURCE_DIR}/tests --parallel 0 $,--jit-opt-level=0,--jit-opt-level=3> --exclude gc --exclude dasHV --exclude dasPUGIXML --exclude dasSQLITE --exclude stbimage --exclude live_host --exclude audio --exclude strudel --exclude ast_match --exclude ast --exclude no_aot --exclude quote + COMMAND ${UTIL_BIN_DIR}/jit.exe ${PROJECT_SOURCE_DIR}/tests --parallel 0 $,--jit-opt-level=0,--jit-opt-level=3> --exclude gc --exclude dasHV --exclude dasPUGIXML --exclude dasSQLITE --exclude stbimage --exclude live_host --exclude audio --exclude strudel DEPENDS jit_exe WORKING_DIRECTORY ${UTIL_BIN_DIR} COMMENT "JIT-compiling tests/ into the .jitted_scripts cache" diff --git a/utils/jit/main.das b/utils/jit/main.das index 20b276763..ff556fc3b 100644 --- a/utils/jit/main.das +++ b/utils/jit/main.das @@ -5,10 +5,9 @@ require daslib/clargs require daslib/fio require daslib/jobque_boost require daslib/strings_boost -require math require llvm/daslib/llvm_jit_cli -require llvm/daslib/llvm_jit_run +require llvm/daslib/llvm_jit_run // nolint:STYLE030 registration side effect: bakes the native llvm module into a standalone -exe build (see simulate() comment below) [CommandLineArgs] struct JitToolArgs { @@ -287,7 +286,7 @@ def jit_compile_one(input : string; tool : JitToolArgs; jit : JitCliOptions) : b // marked no-jit correctly), which a post-simulate run_jit call // would miss. `require llvm_jit_run` above bakes the native llvm // module into a standalone -exe build of this tool. - simulate(program) $(sok, context, serrors) { + simulate(program) $(sok, _context, serrors) { if (!sok) { to_log(LOG_ERROR, "jit: failed to simulate {input}\n{serrors}\n") success = false