54 lines
2 KiB
Bash
Executable file
54 lines
2 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# Compile one W65816 translation unit, automatically falling back to the
|
|
# `basic` register allocator if the default `greedy` allocator hits the
|
|
# single-accumulator deadlock ("ran out of registers during register
|
|
# allocation").
|
|
#
|
|
# Why this exists: the 65816 has exactly one accumulator (the Acc16
|
|
# register class has a single physreg, A). greedy's region-splitting
|
|
# heuristic can manufacture two A-pinned live ranges it cannot then
|
|
# unspill, and aborts. This is a genuine hardware constraint, not a bug
|
|
# we can cheaply fix in the backend (the deadlocking vregs are greedy's
|
|
# own split products, so no pre-RA pass prevents them; verified
|
|
# 2026-06-29). `basic` regalloc serializes the two values correctly.
|
|
#
|
|
# greedy stays the default because its codegen is smaller/faster
|
|
# everywhere it succeeds; basic is used ONLY for the rare function greedy
|
|
# cannot allocate, and ONLY for that translation unit. This replaces the
|
|
# old hand-maintained per-file list (tests/lua/build.sh SLOW_FILES) so a
|
|
# newly-added register-heavy TU can never silently break the build.
|
|
#
|
|
# Usage: ccRegallocFallback.sh <clang> <clang-args...>
|
|
# The args are a normal clang `-c file -o out` compile command.
|
|
|
|
set -u
|
|
|
|
if [ "$#" -lt 1 ]; then
|
|
echo "usage: ccRegallocFallback.sh <clang> <clang-args...>" >&2
|
|
exit 2
|
|
fi
|
|
|
|
clang="$1"
|
|
shift
|
|
|
|
# First attempt with the default (greedy) allocator. Capture combined
|
|
# output so we can inspect it; a single-TU compile is quick, so buffering
|
|
# until completion is fine.
|
|
out="$("$clang" "$@" 2>&1)"
|
|
status=$?
|
|
|
|
if [ "$status" -eq 0 ]; then
|
|
# Success: pass through any warnings clang produced.
|
|
[ -n "$out" ] && printf '%s\n' "$out" >&2
|
|
exit 0
|
|
fi
|
|
|
|
# Retry with basic regalloc ONLY for the single-accumulator deadlock.
|
|
# Any other compile error is surfaced as-is.
|
|
if printf '%s' "$out" | grep -q 'ran out of registers'; then
|
|
echo " (regalloc: greedy ran out of registers; retrying with -regalloc=basic)" >&2
|
|
exec "$clang" "$@" -mllvm -regalloc=basic
|
|
fi
|
|
|
|
printf '%s\n' "$out" >&2
|
|
exit "$status"
|