kit

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

commit b1950955c39e11f77ff7b1c0ad2987ec0dc4c49d
parent 04a3a3a7d5a09b7fe3059e94abcb8009e9936fec
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Mon, 15 Jun 2026 22:39:24 -0700

doc/plan/O1.md harness: scripts/o1_quality.sh A/B -O1 quality measurement

Diffstat:
Ascripts/o1_quality.sh | 143+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 143 insertions(+), 0 deletions(-)

diff --git a/scripts/o1_quality.sh b/scripts/o1_quality.sh @@ -0,0 +1,143 @@ +#!/usr/bin/env bash +# o1_quality.sh -- A/B harness for the -O1 code-quality work (doc/plan/O1.md). +# +# Compiles a fixed ecosystem corpus at -O1 -c with a kit binary and reports, per +# file, the __TEXT byte size and the emitted instruction count. Optionally diffs +# against a baseline kit binary and/or against clang -O1. +# +# Usage: +# scripts/o1_quality.sh [--kit PATH] [--baseline PATH] [--clang] [--arch A] +# [--insn-mix SYM] [name ...] +# +# --kit PATH kit binary to measure (default: build/release/kit) +# --baseline PATH second kit binary; report fixed-vs-baseline deltas +# --clang also compile with clang and report kit/clang ratios +# --arch A aa64|x64|rv64 (default aa64 -> aarch64 native on Apple Si) +# --insn-mix SYM for the given symbol, dump the per-mnemonic count delta +# name ... restrict to these corpus entries (default: all) +# +# Pitfalls (see O1.md sec.1): a kit binary copied outside build/ fails with +# "support dir not found", so keep A/B binaries inside build/release/. +set -euo pipefail + +ROOT="$(cd "$(dirname "$0")/.." && pwd)" +KIT="$ROOT/build/release/kit" +BASELINE="" +DO_CLANG=0 +ARCH="aa64" +INSN_MIX="" +WANT=() + +while [ $# -gt 0 ]; do + case "$1" in + --kit) KIT="$2"; shift 2 ;; + --baseline) BASELINE="$2"; shift 2 ;; + --clang) DO_CLANG=1; shift ;; + --arch) ARCH="$2"; shift 2 ;; + --insn-mix) INSN_MIX="$2"; shift 2 ;; + -h|--help) sed -n '2,22p' "$0"; exit 0 ;; + *) WANT+=("$1"); shift ;; + esac +done + +case "$ARCH" in + aa64) KTARGET="aarch64-macos"; CTARGET="arm64-apple-macos" ;; + x64) KTARGET="x86_64-macos"; CTARGET="x86_64-apple-macos" ;; + rv64) KTARGET="riscv64-linux-gnu"; CTARGET="" ;; + *) echo "unknown --arch $ARCH" >&2; exit 1 ;; +esac + +SDK="$(xcrun --sdk macosx --show-sdk-path 2>/dev/null || true)" +WORK="$ROOT/build/o1_quality" +mkdir -p "$WORK" + +# corpus: name | relpath-under-srcdir | extra-cflags (use @SRC@ for -I srcdir) +corpus() { + cat <<EOF +lapi|lua|lapi.c|-I@SRC@ +lparser|lua|lparser.c|-I@SRC@ +lvm|lua|lvm.c|-I@SRC@ +sqlite|sqlite|sqlite3.c| +cjson|cjson|cJSON.c|-I@SRC@ +lz4|lz4|lz4.c|-I@SRC@ +miniz|miniz|miniz.c| +yyjson|yyjson|yyjson.c|-I@SRC@ +tinyexpr|tinyexpr|tinyexpr.c|-I@SRC@ +EOF +} + +text_bytes() { # $1=objfile -> __text byte count (Mach-O), 0 if absent + size -m "$1" 2>/dev/null | awk '/__text/{print $NF; found=1} END{if(!found)print 0}' +} +insn_count() { # $1=objfile -> emitted instruction count + "$KIT" objdump -d "$1" 2>/dev/null | awk '/^[[:space:]]*[0-9a-f]+:\t/{n++} END{print n+0}' +} + +compile_kit() { # $1=kitbin $2=src $3=out $4=extra + "$1" cc -O1 -std=c11 -target "$KTARGET" --sysroot "$SDK" $4 -c "$2" -o "$3" 2>>"$WORK/err.log" +} +compile_clang() { # $1=src $2=out $3=extra + clang -O1 -std=c11 -target "$CTARGET" -isysroot "$SDK" $3 -c "$1" -o "$2" 2>>"$WORK/err.log" +} + +printf '%-10s %12s %10s' "file" "kit_text" "kit_insn" +[ -n "$BASELINE" ] && printf ' %12s %8s' "base_text" "dTEXT%" +[ "$DO_CLANG" = 1 ] && printf ' %11s %8s' "clang_text" "k/clang" +printf '\n' + +: > "$WORK/err.log" +tot_k=0; tot_b=0; tot_c=0 +while IFS='|' read -r name eco rel extra; do + [ -n "$name" ] || continue + if [ "${#WANT[@]}" -gt 0 ]; then + skip=1; for w in "${WANT[@]}"; do [ "$w" = "$name" ] && skip=0; done + [ "$skip" = 1 ] && continue + fi + src_root="$("$ROOT/scripts/ecosystem.sh" srcdir "$eco" 2>/dev/null || true)" + [ -n "$src_root" ] || { printf '%-10s (not provisioned)\n' "$name"; continue; } + src="$src_root/$rel" + [ -f "$src" ] || { printf '%-10s (missing %s)\n' "$name" "$rel"; continue; } + ex="${extra//@SRC@/$src_root}" + + ko="$WORK/$name.k.o" + compile_kit "$KIT" "$src" "$ko" "$ex" || { printf '%-10s (kit FAILED)\n' "$name"; continue; } + kt="$(text_bytes "$ko")"; ki="$(insn_count "$ko")" + tot_k=$((tot_k + kt)) + printf '%-10s %12s %10s' "$name" "$kt" "$ki" + + if [ -n "$BASELINE" ]; then + bo="$WORK/$name.b.o" + if compile_kit "$BASELINE" "$src" "$bo" "$ex"; then + bt="$(text_bytes "$bo")"; tot_b=$((tot_b + bt)) + d="n/a"; [ "$bt" -gt 0 ] && d="$(awk -v k="$kt" -v b="$bt" 'BEGIN{printf "%+.2f", (k-b)*100.0/b}')" + printf ' %12s %8s' "$bt" "$d" + else + printf ' %12s %8s' "FAIL" "-" + fi + fi + if [ "$DO_CLANG" = 1 ] && [ -n "$CTARGET" ]; then + co="$WORK/$name.c.o" + if compile_clang "$src" "$co" "$ex"; then + ct="$(text_bytes "$co")"; tot_c=$((tot_c + ct)) + r="n/a"; [ "$ct" -gt 0 ] && r="$(awk -v k="$kt" -v c="$ct" 'BEGIN{printf "%.2f", k*1.0/c}')" + printf ' %11s %8s' "$ct" "$r" + else + printf ' %11s %8s' "FAIL" "-" + fi + fi + printf '\n' + + if [ -n "$INSN_MIX" ]; then + "$KIT" objdump -d "$ko" 2>/dev/null | awk -v want="$INSN_MIX" ' + $0 ~ ("<" want ">:") {inf=1; next} /^[0-9a-f]+ </{inf=0} + inf && /^[[:space:]]*[0-9a-f]+:\t/ {n=split($0,a,"\t"); split(a[3],m," "); c[m[1]]++} + END{for(k in c) printf " %-10s %d\n", k, c[k]}' | sort -k2 -rn | head -25 + fi +done < <(corpus) + +printf '%-10s %12s\n' "TOTAL" "$tot_k" +[ -n "$BASELINE" ] && [ "$tot_b" -gt 0 ] && \ + awk -v k="$tot_k" -v b="$tot_b" 'BEGIN{printf " fixed vs baseline __TEXT: %+.2f%%\n", (k-b)*100.0/b}' +[ "$DO_CLANG" = 1 ] && [ "$tot_c" -gt 0 ] && \ + awk -v k="$tot_k" -v c="$tot_c" 'BEGIN{printf " kit/clang aggregate __TEXT: %.3fx\n", k*1.0/c}' +echo " (errors, if any, in $WORK/err.log)"