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:
| A | scripts/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)"