Fil-C on Nix

Filnix wiki

nanofil/docs/archive/m2.md

M2: naive x86-64 SysV backend

Archived: a record of finished work, kept as written. nanofil's archive lists the others.

src/amd64.pl turns the phase-one IR into GNU as text. It is deliberately naive, because it is the reference that later instruction selection and register allocation are checked against.

Both backends build a list of assembly terms rather than text, for example ins(mov, q, [reg(rsp), reg(rbp)]), label(L) and quad(S+8), with operands in AT&T order and concrete register names (reg(eax), reg(cl)). src/asm.pl defines the vocabulary and is the only place that knows AT&T syntax. Later passes and tests can inspect instructions as terms instead of matching text.

cd nanofil/src
../bin/nanofil compile ../tests/fixtures/memory.ir > memory.s

Scheme

The output is about four times larger than qbe's. That is the price of an obviously right reference.

Testing

difftest.sh now has three variants: original (qbe on the file), printed (qbe on nanofil's printed copy) and nanofil (this backend). Each must match the interpreter. VARIANTS=nanofil selects one.

Driver memory

difftest used to evaluate every run in one forward maplist. Trealla kept every run's constraint store reachable, which peaked at about 10 GB on a 200-function file and got jobs killed. Driving the runs through findall over member reclaims each run's heap on backtracking. Peak memory is now 330 MB, and the run is a third faster.