badc (performance)badc is a small cross-platform optimizing C compiler, and a
compiler-as-library, that emits native binaries for five targets from any host.
It carries its own linker, DWARF emitter, inline-asm encoder, in-process JIT,
and SSA interpreter. To ensure correctness, CI runs over 80 jobs and a few
thousand tests, and fuzzing jobs run daily.
badcused to be bad when the project started out, and the name stuck.- There is some compiler-building jargon in this document here and there. You can skip it and go to the usage section.
- For the true compiler heads there is the
--dump-ssaoption, which prints each function’s SSA IR plus the register allocator’s per-value placement to stderr before lowering.
demos/ wires each project below as a smoke test;
demos/README.md says what each exercises.
Python 3.14 on all five
targets, Lua, quickjs,
TCL.sqlite3,
curl, qemu: over a thousand units per
target, self-linked, and both qemu-system-aarch64 and qemu-system-x86_64
boot Linux through UEFI firmware to a shell under TCG.chibicc,
tinycc, and the nasm /
yasm assemblers, each run against its own test suite.edk2: badc compiles the full
UEFI firmware from edk2 source into a bootable OVMF / AAVMF image, and the CI
boots run under it. efi_hello is a
single-source EFI application, its PE subsystem selected by
#pragma subsystem. kernel is a freestanding preemptive
multitasking kernel on both architectures, timer interrupts and context
switches included, Linux is the Linux kernel 7.1.10.TweetNaCl,
Monocypher, BearSSL,
miniz, bzip2.stb,
raylib with a Lode Runner game,
kissfft, the GUI demos (one
windowed program per OS family, each cross-compiled to every target), the
WDM Windows kernel driver, the NT native
binaries (nt_hello, an
IMAGE_SUBSYSTEM_NATIVE PE that runs under ntdll alone, and
nt_loader, which spawns one through
NtCreateUserProcess), and the cooperative-concurrency libraries
(libmill,
libdill,
coroutines), whose context
switches run through inline asm.uemacs, MicroEMACS built
from Linus Torvalds’ tree,
picocom, a serial terminal emulator (driven between
two pseudo-terminals when testing),
screen, GNU Screen (run as both halves of its own
client/server pair when testing),
and vim (when testing is driven in ex mode and from
keystrokes at a pseudo-terminal).It started as a Rust port of Robert Swierczek’s C compiler in four functions,
c4, and diverged enough to call the dialect
c5. Hence the c5 module and the C5Error type. c4.c ships as a test
fixture and self-hosts:
badc -O -o c4 tests/fixtures/c/c4.c # compile c4 to a native binary
./c4 hello.c # which then runs hello.c
And you can really crank the fun up with something like
badc -O --jit tests/fixtures/c/c4.c tests/fixtures/c/c4.c tests/fixtures/c/c4.c tests/fixtures/c/c4.c
to run it quadro-nested under JIT :)
It has since grown from a stack IR through a 3-operand IR to SSA with an optimizing backend.
badc can do – a short survey of badc features.#pragma-driven build
flags, the JIT, optimizations.-W options and pragmas that
select them.--interp and the
pointer-tracking safety net.no_std – using badc from Rust.This is a personal educational/research project, it has not been sponsored or suggested by anyone, i.e. it is a product of my own volition. That said, in no event I’ll be responsible for how you use this project or what happens due to that. See LICENSE for the exact terms.