kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

commit 9380df48697dc0c4091e58e2bf7958cbcf44cfb3
parent 83dac6d332d09a32e1faa6bedcad0f7b23df8733
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Thu, 21 May 2026 08:02:11 -0700

Enable optimized toy cc coverage

Diffstat:
Mdoc/OPT.md | 31++++++++++++++++++-------------
Mdriver/cc.c | 4+---
Msrc/cg/data.c | 16++++++++++++++++
Msrc/opt/pass_emit.c | 1-
Mtest/toy/run.sh | 4++--
5 files changed, 37 insertions(+), 19 deletions(-)

diff --git a/doc/OPT.md b/doc/OPT.md @@ -416,8 +416,10 @@ The optimizer is no longer just a stub: - `src/opt/ir.c` and `src/opt/ir.h` implement the recorded IR container. - `src/opt/pass_cfg.c` implements CFG construction. - `src/opt/pass_ssa.c` implements current SSA construction. -- `test/cg/run.sh` supports `CFREE_OPT_LEVELS`; default is `0 1`, while - level `2` is opt-in today. +- `cfree cc` forwards `-O0`/`-O1`/`-O2` into `CfreeCodeOptions`, so native + frontends exercise the optimizer through the normal compile driver. +- `test/toy/run.sh` supports `CFREE_TOY_OPT_LEVELS`; default is `0 1 2`, so + `make test-toy` exercises direct, O1, and O2 paths by default. Current behavior: @@ -426,8 +428,8 @@ Current behavior: combines, runs post-RA DCE, cleans jumps/layout, and emits through the wrapped target. - Level `2` has its own scheduler entry point, but until production SSA/value - passes land it deliberately routes through the same proven lowering path as - `-O1`. + passes land it only runs the current SSA build/conventionalize/undo verifier + path before routing through the same proven lowering path as `-O1`. - `opt_regalloc(..., allow_live_range_split)` accepts the O2 policy bit, but live-range splitting is not implemented yet. - The current `opt_build_ssa` remains a shape-checking mem2reg prototype: it @@ -475,7 +477,8 @@ Keep the allocator simple but not naive: Exit criteria: -- `CFREE_OPT_LEVELS="0 1" make test-cg` passes for targeted AArch64 cases. +- `CFREE_TOY_OPT_LEVELS="0 1" make test-toy` passes for targeted AArch64 + cases. - Add focused allocation cases for call-clobber saves, stack spills, tied hard regs from inline asm, and values live through branches. @@ -553,7 +556,7 @@ that fails red without the pass or its bug fix. Exit criteria: -- `CFREE_OPT_LEVELS="0 1 2" make test-cg` passes for the relevant arch. +- `CFREE_TOY_OPT_LEVELS="0 1 2" make test-toy` passes for the relevant arch. - Pass-local dump tests prove the intended rewrite fires. ### Phase E - Inlining and Cleanup @@ -666,9 +669,9 @@ specifics belong behind `Target`, `TargetABI`, or explicit helper hooks. Targeted commands: ``` -CFREE_OPT_LEVELS="0 1" make test-cg -CFREE_OPT_LEVELS="0 1 2" make test-cg -CFREE_TEST_FILTER=<case> CFREE_OPT_LEVELS="0 1 2" make test-cg +CFREE_TOY_OPT_LEVELS="0 1 2" make test-toy +CFREE_TEST_FILTER=<case> CFREE_TOY_OPT_LEVELS="0 1 2" make test-toy +make test-opt ``` Use pass dumps for red-green tests: @@ -684,10 +687,12 @@ Use pass dumps for red-green tests: Before broad runs, redirect output to a file and inspect the failure slice: ``` -CFREE_TEST_FILTER=<case> CFREE_OPT_LEVELS="0 1 2" make test-cg >build/opt-test.log 2>&1 +CFREE_TEST_FILTER=<case> CFREE_TOY_OPT_LEVELS="0 1 2" make test-toy >build/opt-test.log 2>&1 tail -200 build/opt-test.log ``` -The full CG corpus remains the equivalence oracle: levels `1` and `2` must -produce the same observable `test_main` result as level `0`. DWARF equivalence -can start weaker, but `set_loc` forwarding must not regress line-row emission. +The full toy corpus remains the end-to-end equivalence oracle for frontend +coverage: levels `1` and `2` must produce the same observable result as level +`0`. The API and opt unit suites remain the narrower pass/CG contract oracle. +DWARF equivalence can start weaker, but `set_loc` forwarding must not regress +line-row emission. diff --git a/driver/cc.c b/driver/cc.c @@ -1865,9 +1865,7 @@ static void cc_fill_c_opts(const CcOptions* o, const CfreePreprocessOptions* pp, CfreeCCompileOptions* copts) { CfreeCCompileOptions zero = {0}; *copts = zero; - /* Accept -O flags for driver compatibility, but keep hosted cc builds on - * direct codegen until the optimizer path is robust for large C libraries. */ - copts->code.opt_level = 0; + copts->code.opt_level = o->opt_level; copts->code.debug_info = o->debug_info; copts->code.emit_c_source = o->emit_c_source ? true : false; copts->code.epoch = o->epoch; diff --git a/src/cg/data.c b/src/cg/data.c @@ -495,6 +495,8 @@ void cfree_cg_data_symdiff(CfreeCg* g, CfreeCgSym lhs, CfreeCgSym rhs, u8 pad[8]; RelocKind add_kind; RelocKind sub_kind; + const ObjSym* lhs_sym; + const ObjSym* rhs_sym; if (!g || width > sizeof(pad)) return; if (g->data_local_static_target) { compiler_panic(g->c, g->cur_loc, @@ -502,6 +504,20 @@ void cfree_cg_data_symdiff(CfreeCg* g, CfreeCgSym lhs, CfreeCgSym rhs, "is not yet supported by this target"); return; } + lhs_sym = obj_symbol_get(g->obj, (ObjSymId)lhs); + rhs_sym = obj_symbol_get(g->obj, (ObjSymId)rhs); + if (lhs_sym && rhs_sym && lhs_sym->section_id != OBJ_SEC_NONE && + lhs_sym->section_id == rhs_sym->section_id) { + u64 value = lhs_sym->value - rhs_sym->value + (u64)addend; + for (u32 i = 0; i < width; ++i) pad[i] = (u8)(value >> (i * 8u)); + if (g->data_tls_collect) { + api_data_tls_write(g, pad, width); + } else { + obj_write(g->obj, g->data_sec, pad, width); + g->data_size += width; + } + return; + } switch (width) { case 1: add_kind = R_RV_ADD8; diff --git a/src/opt/pass_emit.c b/src/opt/pass_emit.c @@ -959,7 +959,6 @@ static void collect_known_frame(Func* f, CGTarget* w, CGKnownFrameDesc* out) { continue; } if ((aux->desc.flags & CG_CALL_TAIL) == 0) out->has_call = 1; - if ((aux->desc.flags & CG_CALL_TAIL) != 0) continue; if (!w->call_stack_size) continue; u32 need = w->call_stack_size(w, &aux->desc); if (need > out->max_outgoing) out->max_outgoing = need; diff --git a/test/toy/run.sh b/test/toy/run.sh @@ -25,7 +25,7 @@ # CFREE_TEST_FILTER / CFREE_TEST_PATHS, where paths is a subset of "RLXC". # X is opt-in cross-arch cc+ld+exec for aa64, x64, and rv64. # C is opt-in C-source emit; default paths are "RL". -# CFREE_TOY_OPT_LEVELS selects optimization levels, default "0 1". +# CFREE_TOY_OPT_LEVELS selects optimization levels, default "0 1 2". set -u @@ -41,7 +41,7 @@ case "$PATHS" in *L*) RUN_L=1;; *) RUN_L=0;; esac case "$PATHS" in *X*) RUN_X=1;; *) RUN_X=0;; esac case "$PATHS" in *C*) RUN_C=1;; *) RUN_C=0;; esac TOY_CROSS_ARCHS="${CFREE_TOY_CROSS_ARCHS:-aa64 x64 rv64}" -TOY_OPT_LEVELS="${CFREE_TOY_OPT_LEVELS:-0 1}" +TOY_OPT_LEVELS="${CFREE_TOY_OPT_LEVELS:-0 1 2}" HOST_CC="${CC:-cc}" mkdir -p "$BUILD_DIR"